Search in sources :

Example 11 with MapShape

use of uk.me.parabola.mkgmap.general.MapShape 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 12 with MapShape

use of uk.me.parabola.mkgmap.general.MapShape in project mkgmap by openstreetmap.

the class OverviewBuilder method calcLevels.

private void calcLevels() {
    List<MapShape> shapes = overviewSource.getShapes();
    // we can write a 0x4a polygon for planet in res 16
    int maxRes = 16;
    if (wantedLevels != null)
        maxRes = wantedLevels[wantedLevels.length - 1].getBits();
    int maxSize = 0xffff << (24 - maxRes);
    for (MapShape s : shapes) {
        if (s.getType() != 0x4a)
            continue;
        int maxDimPoly = s.getBounds().getMaxDimension();
        if (maxDimPoly > maxSize) {
            int oldMaxRes = maxRes;
            while (maxDimPoly > maxSize) {
                maxRes--;
                maxSize = 0xffff << (24 - maxRes);
            }
            String[] name = s.getName().split("\u001d");
            String msg = "Tile selection (0x4a) polygon for ";
            if (name != null && name.length == 2)
                msg += "tile " + name[1].trim();
            else
                msg += s.getBounds();
            log.error(msg, "cannot be written in level 0 resolution", oldMaxRes + ", using", maxRes, "instead");
        }
    }
    if (wantedLevels == null)
        setRes(maxRes);
    else {
        // make sure that the wanted levels for the overview map
        // can store the largest 0x4a polygon at level 0
        int n = wantedLevels.length - 1;
        while (n > 0 && wantedLevels[n].getBits() > maxRes) n--;
        if (n > 0) {
            int l = 0;
            while (n >= 0) {
                wantedLevels[n] = new LevelInfo(l++, wantedLevels[n].getBits());
                n--;
            }
            wantedLevels = Arrays.copyOfRange(wantedLevels, 0, l);
            overviewSource.setMapLevels(wantedLevels);
        } else
            setRes(maxRes);
    }
}
Also used : LevelInfo(uk.me.parabola.mkgmap.general.LevelInfo) MapShape(uk.me.parabola.mkgmap.general.MapShape) Point(uk.me.parabola.imgfmt.app.trergn.Point) MapPoint(uk.me.parabola.mkgmap.general.MapPoint)

Example 13 with MapShape

use of uk.me.parabola.mkgmap.general.MapShape 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 14 with MapShape

use of uk.me.parabola.mkgmap.general.MapShape in project mkgmap by openstreetmap.

the class PolygonSubdivSizeSplitterFilter method doFilter.

/**
 * Split up polygons that exceeds the limits of a subdivision.
 *
 * @param element A map element, only polygons will be processed.
 * @param next	This is used to pass the possibly transformed element onward.
 */
public void doFilter(MapElement element, MapFilterChain next) {
    assert element instanceof MapShape;
    MapShape shape = (MapShape) element;
    if (isSizeOk(shape)) {
        // This is ok let it through and return.
        next.doFilter(element);
        return;
    }
    List<MapShape> outputs = new ArrayList<MapShape>();
    // Do an initial split
    split(shape, outputs);
    // NOTE: the end condition is changed from within the loop.
    for (int i = 0; i < outputs.size(); i++) {
        MapShape s = outputs.get(i);
        if (!isSizeOk(s)) {
            // Not small enough, so remove it and split it again.  The resulting
            // pieces will be placed at the end of the list and will be
            // picked up later on.
            outputs.set(i, null);
            split(s, outputs);
        }
    }
    // Now add all to the chain.
    for (MapShape s : outputs) {
        if (s == null)
            continue;
        next.doFilter(s);
    }
}
Also used : ArrayList(java.util.ArrayList) MapShape(uk.me.parabola.mkgmap.general.MapShape)

Example 15 with MapShape

use of uk.me.parabola.mkgmap.general.MapShape 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

MapShape (uk.me.parabola.mkgmap.general.MapShape)27 Coord (uk.me.parabola.imgfmt.app.Coord)15 MapPoint (uk.me.parabola.mkgmap.general.MapPoint)14 ArrayList (java.util.ArrayList)11 MapLine (uk.me.parabola.mkgmap.general.MapLine)10 Point (uk.me.parabola.imgfmt.app.trergn.Point)5 Area (uk.me.parabola.imgfmt.app.Area)4 MapRoad (uk.me.parabola.mkgmap.general.MapRoad)4 MapExitPoint (uk.me.parabola.mkgmap.general.MapExitPoint)3 IntArrayList (it.unimi.dsi.fastutil.ints.IntArrayList)2 Long2ObjectOpenHashMap (it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap)2 List (java.util.List)2 FilterConfig (uk.me.parabola.mkgmap.filters.FilterConfig)2 IdentityHashMap (java.util.IdentityHashMap)1 GeneralRouteRestriction (uk.me.parabola.imgfmt.app.net.GeneralRouteRestriction)1 Polygon (uk.me.parabola.imgfmt.app.trergn.Polygon)1 Subdivision (uk.me.parabola.imgfmt.app.trergn.Subdivision)1 Zoom (uk.me.parabola.imgfmt.app.trergn.Zoom)1 DouglasPeuckerFilter (uk.me.parabola.mkgmap.filters.DouglasPeuckerFilter)1 LinePreparerFilter (uk.me.parabola.mkgmap.filters.LinePreparerFilter)1