/* * Copyright (C) 2009. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 or * version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. */ package uk.me.parabola.imgfmt.app.mdr; import java.util.ArrayList; import java.util.List; import uk.me.parabola.imgfmt.app.ImgFileWriter; /** * The section MDR 1 contains a list of maps and for each map * an offset to a reverse index for that map. * * The reverse index consists of a number of sections, that I call sub-sections * here. The sub-sections are all lists of record numbers in other sections * in the MDR that contain records belonging to more than one map. * * Using the index you could extract records that belong to an individual map * from other MDR sections without having to go through them all and check * which map they belong to. * * The subsections are as follows: * * sub1 points into MDR 11 (POIs) * sub2 points into MDR 10 (POI types) * sub3 points into MDR 7 (street names) * sub4 points into MDR 5 (cities) * sub5 points into MDR 6 (zips) * sub6 points into MDR 20 * sub7 points into MDR 21 * sub8 points into MDR 22 * * @author Steve Ratcliffe */ public class Mdr1 extends MdrSection implements HasHeaderFlags { private final List<Mdr1Record> maps = new ArrayList<>(); public Mdr1(MdrConfig config) { setConfig(config); } /** * Add a map. Create an MDR1 record for it and also allocate its reverse * index if this is not for a device. * @param mapNumber The map index number. * @param index The map index. */ public void addMap(int mapNumber, int index) { assert index > 0; Mdr1Record rec = new Mdr1Record(mapNumber, getConfig()); rec.setMapIndex(index); maps.add(rec); if (!isForDevice()) { Mdr1MapIndex mapIndex = new Mdr1MapIndex(); rec.setMdrMapIndex(mapIndex); } } public void writeSubSections(ImgFileWriter writer) { if (isForDevice()) return; for (Mdr1Record rec : maps) { rec.setIndexOffset(writer.position()); Mdr1MapIndex mapIndex = rec.getMdrMapIndex(); mapIndex.writeSubSection(writer); } } /** * This is written right at the end after we know all the offsets in * the MDR 1 record. * @param writer The mdr 1 records are written out to this writer. */ public void writeSectData(ImgFileWriter writer) { boolean revIndex = (getExtraValue() & 1) != 0; for (Mdr1Record rec : maps) { writer.putInt(rec.getMapNumber()); if (revIndex) writer.putInt(rec.getIndexOffset()); } } public int getItemSize() { return isForDevice()? 4: 8; } public void setStartPosition(int sectionNumber) { if (isForDevice()) return; for (Mdr1Record mi : maps) mi.getMdrMapIndex().startSection(sectionNumber); } public void setEndPosition(int sectionNumber) { if (isForDevice()) return; for (Mdr1Record mi : maps) { mi.getMdrMapIndex().endSection(sectionNumber); } } public void setPointerSize(int sectionSize, int recordSize) { for (Mdr1Record mi : maps) { Mdr1MapIndex mapIndex = mi.getMdrMapIndex(); mapIndex.setPointerSize(sectionSize, recordSize); } } public void addPointer(int mapNumber, int recordNumber) { Mdr1MapIndex mi = maps.get(mapNumber - 1).getMdrMapIndex(); mi.addPointer(recordNumber); } /** * The number of records in this section. * * @return The number of items in the section. */ protected int numberOfItems() { return maps.size(); } public int getExtraValue() { int magic = 0; if (!isForDevice()) magic |= 1; return magic; } }