Search in sources :

Example 81 with Coord

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

the class MapBuilder method prepShapesForMerge.

/**
 * for the overview map:
 * Make sure that all {@link Coord} instances are
 * identical when they are equal.
 * @param shapes the list of shapes
 */
private static void prepShapesForMerge(List<MapShape> shapes) {
    Long2ObjectOpenHashMap<Coord> coordMap = new Long2ObjectOpenHashMap<>();
    for (MapShape s : shapes) {
        List<Coord> points = s.getPoints();
        int n = points.size();
        for (int i = 0; i < n; i++) {
            Coord co = points.get(i);
            Coord repl = coordMap.get(Utils.coord2Long(co));
            if (repl == null)
                coordMap.put(Utils.coord2Long(co), co);
            else
                points.set(i, repl);
        }
    }
    return;
}
Also used : Coord(uk.me.parabola.imgfmt.app.Coord) Long2ObjectOpenHashMap(it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap) MapShape(uk.me.parabola.mkgmap.general.MapShape) MapPoint(uk.me.parabola.mkgmap.general.MapPoint) MapExitPoint(uk.me.parabola.mkgmap.general.MapExitPoint) Point(uk.me.parabola.imgfmt.app.trergn.Point)

Example 82 with Coord

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

the class MapBuilder method preserveHorizontalAndVerticalLines.

/**
 * Preserve shape points which a) lie on the shape boundary or
 * b) which appear multiple times in the shape (excluding the start
 * point which should always be identical to the end point).
 * The preserved points are kept treated specially in the
 * Line-Simplification-Filters, this should avoid artifacts like
 * white triangles in the sea for lower resolutions.
 * @param res the current resolution
 * @param shapes list of shapes
 */
private static void preserveHorizontalAndVerticalLines(int res, List<MapShape> shapes) {
    if (res == 24)
        return;
    for (MapShape shape : shapes) {
        if (shape.getMinResolution() > res)
            continue;
        int minLat = shape.getBounds().getMinLat();
        int maxLat = shape.getBounds().getMaxLat();
        int minLon = shape.getBounds().getMinLong();
        int maxLon = shape.getBounds().getMaxLong();
        List<Coord> points = shape.getPoints();
        int n = shape.getPoints().size();
        IdentityHashMap<Coord, Coord> coords = new IdentityHashMap<>(n);
        Coord first = points.get(0);
        Coord prev = first;
        Coord last = first;
        for (int i = 1; i < points.size(); ++i) {
            last = points.get(i);
            // to connect holes
            if (coords.get(last) == null) {
                coords.put(last, last);
            } else {
                if (!last.preserved()) {
                    last.preserved(true);
                }
            }
            // on the bbox of the shape.
            if (last.getLatitude() == prev.getLatitude() && (last.getLatitude() == minLat || last.getLatitude() == maxLat) || last.getLongitude() == prev.getLongitude() && (last.getLongitude() == minLon || last.getLongitude() == maxLon)) {
                last.preserved(true);
                prev.preserved(true);
            }
            prev = last;
        }
    }
}
Also used : Coord(uk.me.parabola.imgfmt.app.Coord) IdentityHashMap(java.util.IdentityHashMap) MapShape(uk.me.parabola.mkgmap.general.MapShape) MapPoint(uk.me.parabola.mkgmap.general.MapPoint) MapExitPoint(uk.me.parabola.mkgmap.general.MapExitPoint) Point(uk.me.parabola.imgfmt.app.trergn.Point)

Example 83 with Coord

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

the class OverviewBuilder method readShapes.

/**
 * Read the polygons from the .img file and add them to the overview map.
 * We read from the least detailed level (apart from the empty one).
 *
 * @param mapReader Map reader on the detailed .img file.
 */
private void readShapes(MapReader mapReader) {
    Zoom[] levels = mapReader.getLevels();
    for (int l = 1; l < levels.length; l++) {
        int min = levels[l].getLevel();
        int res = levels[l].getResolution();
        List<Polygon> list = mapReader.shapesForLevel(min, MapReader.WITH_EXT_TYPE_DATA);
        for (Polygon shape : list) {
            if (log.isDebugEnabled())
                log.debug("got polygon", shape);
            if (shape.getType() == 0x4b) {
                hasBackground = true;
            }
            MapShape ms = new MapShape();
            List<Coord> points = shape.getPoints();
            if (log.isDebugEnabled())
                log.debug("polygon point list", points);
            if (points.size() < 3)
                continue;
            ms.setType(shape.getType());
            if (shape.getLabel() != null)
                ms.setName(shape.getLabel().getText());
            ms.setMaxResolution(res);
            ms.setMinResolution(res);
            ms.setPoints(points);
            overviewSource.addShape(ms);
        }
    }
}
Also used : Coord(uk.me.parabola.imgfmt.app.Coord) Zoom(uk.me.parabola.imgfmt.app.trergn.Zoom) Polygon(uk.me.parabola.imgfmt.app.trergn.Polygon) MapShape(uk.me.parabola.mkgmap.general.MapShape) Point(uk.me.parabola.imgfmt.app.trergn.Point) MapPoint(uk.me.parabola.mkgmap.general.MapPoint)

Example 84 with Coord

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

the class PredictFilterPoints method predictedMaxNumPoints.

public static int predictedMaxNumPoints(List<Coord> points, int resolution, boolean checkPreserved) {
    // see RemoveObsoletePointsFilter, RoundCoordsFilter, ... for comments on preserved and resolution
    // %%% checkPreserved = config.getLevel() == 0 && config.isRoutable() && line.isRoad()){
    // final int shift = 30 - resolution; // NB getting highPrec
    // final int half = 1 << (shift - 1); // 0.5 shifted
    // final int mask = ~((1 << shift) - 1); // to remove fraction bits
    // best use same info as filters
    final int shift = 24 - resolution;
    int half;
    int mask;
    if (shift == 0) {
        half = 0;
        mask = ~0;
    } else {
        // 0.5 shifted
        half = 1 << (shift - 1);
        // to remove fraction bits
        mask = ~((1 << shift) - 1);
    }
    int numPoints = 0;
    int lastLat = 0, lastLon = 0;
    for (Coord p : points) {
        // final int lat = (p.getHighPrecLat() + half) & mask;
        // final int lon = (p.getHighPrecLon() + half) & mask;
        final int lat = (p.getLatitude() + half) & mask;
        final int lon = (p.getLongitude() + half) & mask;
        if (numPoints == 0)
            // always have one/first point
            numPoints = 1;
        else {
            if (lat != lastLat || lon != lastLon || (checkPreserved && (p instanceof CoordNode || p.preserved())))
                ++numPoints;
        }
        lastLat = lat;
        lastLon = lon;
    }
    // true shapes will have >3 points, lines >1
    return numPoints;
}
Also used : Coord(uk.me.parabola.imgfmt.app.Coord) CoordNode(uk.me.parabola.imgfmt.app.CoordNode)

Example 85 with Coord

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

the class RemoveObsoletePointsFilter method doFilter.

/**
 * @param element A map element that will be a line or a polygon.
 * @param next This is used to pass the possibly transformed element onward.
 */
public void doFilter(MapElement element, MapFilterChain next) {
    MapLine line = (MapLine) element;
    List<Coord> points = line.getPoints();
    int numPoints = points.size();
    if (numPoints <= 1) {
        return;
    }
    int requiredPoints = (line instanceof MapShape) ? 4 : 2;
    List<Coord> newPoints = new ArrayList<Coord>(numPoints);
    while (true) {
        boolean removedSpike = false;
        numPoints = points.size();
        Coord lastP = points.get(0);
        newPoints.add(lastP);
        for (int i = 1; i < numPoints; i++) {
            Coord newP = points.get(i);
            int last = newPoints.size() - 1;
            lastP = newPoints.get(last);
            if (lastP.equals(newP)) {
                // coordinates to the last point or is preserved
                if (checkPreserved && line.isRoad()) {
                    if (newP.preserved() == false)
                        continue;
                    else if (lastP.preserved() == false) {
                        // replace last
                        newPoints.set(last, newP);
                    }
                } else
                    continue;
            }
            if (newPoints.size() > 1) {
                switch(Utils.isStraight(newPoints.get(last - 1), lastP, newP)) {
                    case Utils.STRICTLY_STRAIGHT:
                        if (checkPreserved && lastP.preserved() && line.isRoad()) {
                        // keep it
                        } else {
                            log.debug("found three consecutive points on strictly straight line");
                            newPoints.set(last, newP);
                            continue;
                        }
                        break;
                    case Utils.STRAIGHT_SPIKE:
                        if (line instanceof MapShape) {
                            log.debug("removing spike");
                            newPoints.remove(last);
                            removedSpike = true;
                            if (newPoints.get(last - 1).equals(newP))
                                continue;
                        }
                        break;
                    default:
                        break;
                }
            }
            newPoints.add(newP);
        }
        if (!removedSpike || newPoints.size() < requiredPoints)
            break;
        points = newPoints;
        newPoints = new ArrayList<Coord>(points.size());
    }
    if (line instanceof MapShape) {
        // in a shape are identical.
        while (newPoints.size() > 3) {
            int nPoints = newPoints.size();
            switch(Utils.isStraight(newPoints.get(newPoints.size() - 2), newPoints.get(0), newPoints.get(1))) {
                case Utils.STRAIGHT_SPIKE:
                    newPoints.remove(0);
                    newPoints.set(newPoints.size() - 1, newPoints.get(0));
                    if (newPoints.get(newPoints.size() - 2).equals(newPoints.get(newPoints.size() - 1)))
                        newPoints.remove(newPoints.size() - 1);
                    break;
                case Utils.STRICTLY_STRAIGHT:
                    newPoints.remove(newPoints.size() - 1);
                    newPoints.set(0, newPoints.get(newPoints.size() - 1));
                    break;
            }
            if (nPoints == newPoints.size())
                break;
        }
    }
    if (newPoints.size() != line.getPoints().size()) {
        if (line instanceof MapShape && newPoints.size() <= 3 || newPoints.size() <= 1)
            return;
        MapLine newLine = line.copy();
        newLine.setPoints(newPoints);
        next.doFilter(newLine);
    } else {
        // no need to create new object
        next.doFilter(line);
    }
}
Also used : Coord(uk.me.parabola.imgfmt.app.Coord) MapLine(uk.me.parabola.mkgmap.general.MapLine) ArrayList(java.util.ArrayList) MapShape(uk.me.parabola.mkgmap.general.MapShape)

Aggregations

Coord (uk.me.parabola.imgfmt.app.Coord)178 ArrayList (java.util.ArrayList)71 Way (uk.me.parabola.mkgmap.reader.osm.Way)31 MapPoint (uk.me.parabola.mkgmap.general.MapPoint)27 List (java.util.List)23 MapLine (uk.me.parabola.mkgmap.general.MapLine)16 Area (uk.me.parabola.imgfmt.app.Area)15 MapShape (uk.me.parabola.mkgmap.general.MapShape)15 CoordNode (uk.me.parabola.imgfmt.app.CoordNode)13 MapExitPoint (uk.me.parabola.mkgmap.general.MapExitPoint)13 Node (uk.me.parabola.mkgmap.reader.osm.Node)13 HashMap (java.util.HashMap)12 IdentityHashMap (java.util.IdentityHashMap)11 Test (org.junit.Test)11 MapRoad (uk.me.parabola.mkgmap.general.MapRoad)9 Long2ObjectOpenHashMap (it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap)8 Area (java.awt.geom.Area)8 HashSet (java.util.HashSet)8 IntArrayList (it.unimi.dsi.fastutil.ints.IntArrayList)5 LinkedHashMap (java.util.LinkedHashMap)5