/* * 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.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import uk.me.parabola.imgfmt.app.ImgFileWriter; /** * POI subtype with a reference to MDR11. * These are sorted into groups based on the type, and contain the * subtype. * * The mdr9 section contains an index to this section based on the * the type groups. * * @author Steve Ratcliffe */ public class Mdr10 extends MdrMapSection { // The maximum group number. Note that this is 1 based, not 0 based. private static final int MAX_GROUP_NUMBER = 9; @SuppressWarnings({"unchecked"}) private List<Mdr10Record>[] poiTypes = new ArrayList[MAX_GROUP_NUMBER+1]; private int numberOfPois; public Mdr10(MdrConfig config) { setConfig(config); for (int i = 1; i <= MAX_GROUP_NUMBER; i++) { poiTypes[i] = new ArrayList<>(); } } public void addPoiType(Mdr11Record poi) { Mdr10Record t = new Mdr10Record(); int type = poi.getType(); t.setSubtype(MdrUtils.getSubtypeOrTypeFromFullType(type)); t.setMdr11ref(poi); int group = MdrUtils.getGroupForPoi(type); if (group == 0) return; poiTypes[group].add(t); } public void writeSectData(ImgFileWriter writer) { int count = 0; for (List<Mdr10Record> poiGroup : poiTypes) { if (poiGroup == null) continue; Collections.sort(poiGroup); String lastName = null; int lastSub = -1; for (Mdr10Record t : poiGroup) { count++; Mdr11Record mdr11ref = t.getMdr11ref(); addIndexPointer(mdr11ref.getMapIndex(), count); writer.put((byte) t.getSubtype()); int offset = mdr11ref.getRecordNumber(); // Top bit actually represents a non-repeated name. ie if // the bit is not set, then the name is the same as the previous // record. String name = mdr11ref.getName(); boolean isNew = !(name.equals(lastName) && (t.getSubtype() == lastSub)); putPoiIndex(writer, offset, isNew); lastName = name; lastSub = t.getSubtype(); } } } /** * Get a list of the group sizes along with the group index number. * @return A map that is guaranteed to iterate in the correct order for * writing mdr9. The key is the group number and the value is the * number of entries in that group. */ public Map<Integer, Integer> getGroupSizes() { Map<Integer, Integer> m = new LinkedHashMap<>(); for (int i = 1; i < MAX_GROUP_NUMBER; i++) { List<Mdr10Record> poiGroup = poiTypes[i]; if (!poiGroup.isEmpty()) m.put(i, poiGroup.size()); } return m; } /** * This does not have a record size. * @return Always zero to indicate that there is not a record size. */ public int getItemSize() { return 0; } protected int numberOfItems() { return numberOfPois; } public void setNumberOfPois(int numberOfPois) { this.numberOfPois = numberOfPois; } protected void releaseMemory() { poiTypes = null; } public int getExtraValue() { // Nothing to do here return 0; } }