Subversion Repositories mkgmap

Rev

Rev 3408 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * 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;
        }

        /**
         * Nothing to do for this section.
         *
         * Although this section has a subsection by map index in mdr1, its record does not contain the
         * map index and so nothing needs to be re-written here.  The map index is contained in its mdr11ref.
         */

        public void relabelMaps(Mdr1 maps) {
        }
}