/* * Copyright (C) 2011. * * 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; /** * Common code for 20, 21, 22 which are all lists of streets ordered in * different ways. * * @author Steve Ratcliffe */ public abstract class Mdr2x extends MdrMapSection implements HasHeaderFlags { protected List<Mdr7Record> streets = new ArrayList<>(); /** * Write out the contents of this section. * * @param writer Where to write it. */ public void writeSectData(ImgFileWriter writer) { String lastName = null; Mdr7Record prev = null; int size = getSizes().getStreetSizeFlagged(); boolean hasLabel = hasFlag(0x2); String lastPartial = null; int recordNumber = 0; for (Mdr7Record street : streets) { assert street.getMapIndex() == street.getCity().getMapIndex() : street.getMapIndex() + "/" + street.getCity().getMapIndex(); addIndexPointer(street.getMapIndex(), ++recordNumber); int index = street.getIndex(); String name = street.getName(); int repeat = 1; if (name.equals(lastName) && sameGroup(street, prev)) repeat = 0; if (hasLabel) { putMapIndex(writer, street.getMapIndex()); int offset = street.getLabelOffset(); if (repeat != 0) offset |= 0x800000; int trailing = 0; String partialName = street.getPartialName(); if (!partialName.equals(lastPartial)) { trailing |= 1; offset |= 0x800000; } writer.put3(offset); writer.put(street.getOutNameOffset()); writer.put((byte) trailing); lastPartial = partialName; } else putN(writer, size, (index << 1) | repeat); lastName = name; prev = street; } } /** * The size of a record in the section. * * For these sections there is one field that is an index into the * streets with an extra bit for a flag. * * In the device configuration, then there is a label and a flag, just like * for mdr7. */ public int getItemSize() { int size; if (isForDevice()) { // map-index, label, name-offset, 1byte flag size = getSizes().getMapSize() + 3 + 1 + 1; } else { size = getSizes().getStreetSizeFlagged(); } return size; } /** * The number of records in this section. * * @return The number of items in the section. */ protected int numberOfItems() { return streets.size(); } protected void releaseMemory() { streets = null; } /** * These sections are divided into groups based on city, region or country. This routine is * implemented to return true if the two streets are in the same group. * * It is not clear if this is needed for region or country. * @param street1 The first street. * @param street2 The street to compare against. * @return True if the streets are in the same group (city, region etc). */ protected abstract boolean sameGroup(Mdr7Record street1, Mdr7Record street2); }