Search in sources :

Example 1 with MultiSortKey

use of uk.me.parabola.imgfmt.app.srt.MultiSortKey in project mkgmap by openstreetmap.

the class Mdr5 method calcMdr20SortPos.

/**
 * Calculate a position when sorting by name, region, and country- This is used for MDR20.
 */
private void calcMdr20SortPos() {
    List<SortKey<Mdr5Record>> sortKeys = new ArrayList<>(allCities.size());
    Sort sort = getConfig().getSort();
    for (Mdr5Record m : allCities) {
        if (m.getName() == null)
            continue;
        // Sort by city name, region name, and country name .
        SortKey<Mdr5Record> sortKey = sort.createSortKey(m, m.getName());
        SortKey<Mdr5Record> regionKey = sort.createSortKey(null, m.getRegionName());
        SortKey<Mdr5Record> countryKey = sort.createSortKey(null, m.getCountryName());
        sortKey = new MultiSortKey<>(sortKey, regionKey, countryKey);
        sortKeys.add(sortKey);
    }
    Collections.sort(sortKeys);
    SortKey<Mdr5Record> lastKey = null;
    int pos = 0;
    for (SortKey<Mdr5Record> key : sortKeys) {
        Mdr5Record c = key.getObject();
        if (lastKey == null || key.compareTo(lastKey) != 0)
            pos++;
        c.setMdr20SortPos(pos);
        lastKey = key;
    }
}
Also used : ArrayList(java.util.ArrayList) Sort(uk.me.parabola.imgfmt.app.srt.Sort) SortKey(uk.me.parabola.imgfmt.app.srt.SortKey) MultiSortKey(uk.me.parabola.imgfmt.app.srt.MultiSortKey)

Example 2 with MultiSortKey

use of uk.me.parabola.imgfmt.app.srt.MultiSortKey in project mkgmap by openstreetmap.

the class Mdr5 method preWriteImpl.

/**
 * Called after all cities to sort and number them.
 */
public void preWriteImpl() {
    localCitySize = Utils.numberToPointerSize(maxCityIndex + 1);
    List<SortKey<Mdr5Record>> sortKeys = new ArrayList<>(allCities.size());
    Sort sort = getConfig().getSort();
    for (Mdr5Record m : allCities) {
        if (m.getName() == null)
            continue;
        // Sort by city name, region name, country name and map index.
        SortKey<Mdr5Record> sortKey = sort.createSortKey(m, m.getName());
        SortKey<Mdr5Record> regionKey = sort.createSortKey(null, m.getRegionName());
        SortKey<Mdr5Record> countryKey = sort.createSortKey(null, m.getCountryName(), m.getMapIndex());
        sortKey = new MultiSortKey<>(sortKey, regionKey, countryKey);
        sortKeys.add(sortKey);
    }
    Collections.sort(sortKeys);
    Collator collator = getConfig().getSort().getCollator();
    int count = 0;
    Mdr5Record lastCity = null;
    // We need a common area to save the mdr20 values, since there can be multiple
    // city records with the same global city index
    int[] mdr20s = new int[sortKeys.size() + 1];
    int mdr20count = 0;
    for (SortKey<Mdr5Record> key : sortKeys) {
        Mdr5Record c = key.getObject();
        c.setMdr20set(mdr20s);
        if (!c.isSameByName(collator, lastCity))
            mdr20count++;
        c.setMdr20Index(mdr20count);
        if (c.isSameByMapAndName(collator, lastCity)) {
            c.setGlobalCityIndex(count);
        } else {
            count++;
            c.setGlobalCityIndex(count);
            cities.add(c);
            lastCity = c;
        }
    }
    // calculate positions for the different road indexes
    calcMdr20SortPos();
    calcMdr21SortPos();
    calcMdr22SortPos();
}
Also used : ArrayList(java.util.ArrayList) Sort(uk.me.parabola.imgfmt.app.srt.Sort) SortKey(uk.me.parabola.imgfmt.app.srt.SortKey) MultiSortKey(uk.me.parabola.imgfmt.app.srt.MultiSortKey) Collator(java.text.Collator)

Example 3 with MultiSortKey

use of uk.me.parabola.imgfmt.app.srt.MultiSortKey in project mkgmap by openstreetmap.

the class NETFile method sortRoads.

/**
 * Sort the roads by name and remove duplicates.
 *
 * We want a list of roads such that every entry in the list is a different road. Since in osm
 * roads are frequently chopped into small pieces we have to remove the duplicates.
 * This doesn't have to be perfect, it needs to be useful when searching for roads.
 *
 * So we have a separate entry if the road is in a different city. This would probably be enough
 * except that associating streets with cities is not always very good in OSM. So I also create an
 * extra entry for each subdivision. Finally there a search for disconnected roads within the subdivision
 * with the same name.
 *
 * Performance note: The previous implementation was very, very slow when there were a large number
 * of roads with the same name. Although this was an unusual situation, when it happened it appears
 * that mkgmap has hung. This implementation takes a fraction of a second even for large numbers of
 * same named roads.
 *
 * @return A sorted list of road labels that identify all the different roads.
 */
private List<LabeledRoadDef> sortRoads() {
    List<SortKey<LabeledRoadDef>> sortKeys = new ArrayList<>(roads.size());
    Map<Label, byte[]> cache = new HashMap<>();
    for (RoadDef rd : roads) {
        Label[] labels = rd.getLabels();
        for (int i = 0; i < labels.length && labels[i] != null; ++i) {
            Label label = labels[i];
            if (label.getLength() == 0)
                continue;
            // Sort by name, city, region/country and subdivision number.
            LabeledRoadDef lrd = new LabeledRoadDef(label, rd);
            SortKey<LabeledRoadDef> nameKey = new IntegerSortKey<NETFile.LabeledRoadDef>(lrd, label.getOffset(), 0);
            // If there is a city add it to the sort.
            // what if we more than one?
            City city = (rd.getCities().isEmpty() ? null : rd.getCities().get(0));
            SortKey<LabeledRoadDef> cityKey;
            if (city != null) {
                int region = city.getRegionNumber();
                int country = city.getCountryNumber();
                cityKey = sort.createSortKey(null, city.getLabel(), (region & 0xffff) << 16 | (country & 0xffff), cache);
            } else {
                cityKey = sort.createSortKey(null, Label.NULL_OUT_LABEL, 0, cache);
            }
            SortKey<LabeledRoadDef> sortKey = new MultiSortKey<>(nameKey, cityKey, new IntegerSortKey<LabeledRoadDef>(null, rd.getStartSubdivNumber(), 0));
            sortKeys.add(sortKey);
        }
    }
    Collections.sort(sortKeys);
    List<LabeledRoadDef> out = new ArrayList<>(sortKeys.size());
    Label lastName = null;
    City lastCity = null;
    List<LabeledRoadDef> dupes = new ArrayList<>();
    // The duplicates are saved to the dupes list.
    for (SortKey<LabeledRoadDef> key : sortKeys) {
        LabeledRoadDef lrd = key.getObject();
        Label name = lrd.label;
        RoadDef road = lrd.roadDef;
        // what if we more than one?
        City city = (road.getCities().isEmpty() ? null : road.getCities().get(0));
        if (road.hasHouseNumbers() || !name.equals(lastName) || city != lastCity) {
            // process any previously collected duplicate road names and reset.
            addDisconnected(dupes, out);
            dupes = new ArrayList<>();
            lastName = name;
            lastCity = city;
        }
        dupes.add(lrd);
    }
    // Finish off the final set of duplicates.
    addDisconnected(dupes, out);
    sortByName(out);
    return out;
}
Also used : IntegerSortKey(uk.me.parabola.imgfmt.app.srt.IntegerSortKey) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Label(uk.me.parabola.imgfmt.app.Label) IntegerSortKey(uk.me.parabola.imgfmt.app.srt.IntegerSortKey) DoubleSortKey(uk.me.parabola.imgfmt.app.srt.DoubleSortKey) SortKey(uk.me.parabola.imgfmt.app.srt.SortKey) MultiSortKey(uk.me.parabola.imgfmt.app.srt.MultiSortKey) City(uk.me.parabola.imgfmt.app.lbl.City) MultiSortKey(uk.me.parabola.imgfmt.app.srt.MultiSortKey)

Aggregations

ArrayList (java.util.ArrayList)3 MultiSortKey (uk.me.parabola.imgfmt.app.srt.MultiSortKey)3 SortKey (uk.me.parabola.imgfmt.app.srt.SortKey)3 Sort (uk.me.parabola.imgfmt.app.srt.Sort)2 Collator (java.text.Collator)1 HashMap (java.util.HashMap)1 Label (uk.me.parabola.imgfmt.app.Label)1 City (uk.me.parabola.imgfmt.app.lbl.City)1 DoubleSortKey (uk.me.parabola.imgfmt.app.srt.DoubleSortKey)1 IntegerSortKey (uk.me.parabola.imgfmt.app.srt.IntegerSortKey)1