Search in sources :

Example 6 with MapLine

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

the class PolishMapDataSource method endSection.

/**
 * At the end of a section, we add what ever element that we have been
 * building to the map.
 */
private void endSection() {
    switch(section) {
        case S_IMG_ID:
            break;
        case S_POINT:
            if (extraAttributes != null && point.hasExtendedType())
                point.setExtTypeAttributes(makeExtTypeAttributes());
            mapper.addToBounds(point.getLocation());
            mapper.addPoint(point);
            break;
        case S_POLYLINE:
            if (points != null) {
                if (roadHelper.isRoad()) {
                    polyline.setPoints(points);
                    mapper.addRoad(roadHelper.makeRoad(polyline));
                } else {
                    if (extraAttributes != null && polyline.hasExtendedType())
                        polyline.setExtTypeAttributes(makeExtTypeAttributes());
                    final int maxPointsInLine = LineSplitterFilter.MAX_POINTS_IN_LINE;
                    if (points.size() > maxPointsInLine) {
                        List<Coord> segPoints = new ArrayList<>(maxPointsInLine);
                        for (Coord p : points) {
                            segPoints.add(p);
                            if (segPoints.size() == maxPointsInLine) {
                                MapLine seg = polyline.copy();
                                seg.setPoints(segPoints);
                                mapper.addLine(seg);
                                segPoints = new ArrayList<>(maxPointsInLine);
                                segPoints.add(p);
                            }
                        }
                        if (!segPoints.isEmpty()) {
                            polyline.setPoints(segPoints);
                            mapper.addLine(polyline);
                        }
                    } else {
                        polyline.setPoints(points);
                        mapper.addLine(polyline);
                    }
                }
            }
            break;
        case S_POLYGON:
            if (points != null) {
                if (points.get(0) != points.get(points.size() - 1)) {
                    // not closed, close it
                    points.add(points.get(0));
                }
                shape.setPoints(points);
                if (extraAttributes != null && shape.hasExtendedType())
                    shape.setExtTypeAttributes(makeExtTypeAttributes());
                mapper.addShape(shape);
            }
            break;
        case S_RESTRICTION:
            restrictionHelper.addRestriction(restriction);
            break;
        case 0:
            // ignored section
            break;
        default:
            log.warn("unexpected default in switch", section);
            break;
    }
    // Clear the section state.
    section = 0;
    endLevel = 0;
    points = null;
}
Also used : Coord(uk.me.parabola.imgfmt.app.Coord) MapLine(uk.me.parabola.mkgmap.general.MapLine) ArrayList(java.util.ArrayList) MapPoint(uk.me.parabola.mkgmap.general.MapPoint)

Example 7 with MapLine

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

the class AllElements method drawLines.

private void drawLines(MapCollector mapper, double slat, double slon, boolean hasBackground) {
    double lat = slat + 0.004;
    double lon = slon + 0.002;
    int type = 0;
    for (int x = 0; x < MAX_LINE_TYPE_X; x++) {
        for (int y = 0; y < MAX_LINE_TYPE_Y; y++) {
            MapLine line = new MapLine();
            line.setMinResolution(10);
            if (!hasBackground)
                line.setName(GType.formatType(type));
            double baseLat = lat + y * ELEMENT_SPACING;
            double baseLong = lon + x * ELEMENT_SPACING;
            List<Coord> coords = new ArrayList<Coord>();
            Coord co = new Coord(baseLat, baseLong);
            coords.add(co);
            mapper.addToBounds(co);
            if (configProps.containsKey("verbose"))
                System.out.println("Generated line " + GType.formatType(type) + " at " + co.toDegreeString());
            co = new Coord(baseLat + ELEMENT_SIZE, baseLong + ELEMENT_SIZE);
            coords.add(co);
            mapper.addToBounds(co);
            co = new Coord(baseLat + ELEMENT_SIZE, baseLong + ELEMENT_SIZE + ELEMENT_SIZE / 2);
            coords.add(co);
            mapper.addToBounds(co);
            line.setType(type);
            line.setPoints(coords);
            mapper.addLine(line);
            type++;
        }
    }
}
Also used : Coord(uk.me.parabola.imgfmt.app.Coord) MapLine(uk.me.parabola.mkgmap.general.MapLine) ArrayList(java.util.ArrayList) MapPoint(uk.me.parabola.mkgmap.general.MapPoint)

Example 8 with MapLine

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

the class StyledConverterTest method makeConverter.

private StyledConverter makeConverter(String name) throws FileNotFoundException {
    Style style = new StyleImpl(LOC, name);
    MapCollector coll = new MapCollector() {

        public void addToBounds(Coord p) {
        }

        // could save points in the same way as lines to test them
        public void addPoint(MapPoint point) {
        }

        public void addLine(MapLine line) {
            // Save line so that it can be examined in the tests.
            assertNotNull("points are not null", line.getPoints());
            lines.add(line);
        }

        public void addShape(MapShape shape) {
        }

        public void addRoad(MapRoad road) {
            lines.add(road);
        }

        public int addRestriction(GeneralRouteRestriction grr) {
            return 0;
        }

        public void addThroughRoute(int junctionNodeId, long roadIdA, long roadIdB) {
        }
    };
    return new StyledConverter(style, coll, new EnhancedProperties());
}
Also used : Coord(uk.me.parabola.imgfmt.app.Coord) EnhancedProperties(uk.me.parabola.util.EnhancedProperties) MapLine(uk.me.parabola.mkgmap.general.MapLine) MapPoint(uk.me.parabola.mkgmap.general.MapPoint) GeneralRouteRestriction(uk.me.parabola.imgfmt.app.net.GeneralRouteRestriction) Style(uk.me.parabola.mkgmap.reader.osm.Style) MapRoad(uk.me.parabola.mkgmap.general.MapRoad) MapCollector(uk.me.parabola.mkgmap.general.MapCollector) MapShape(uk.me.parabola.mkgmap.general.MapShape)

Example 9 with MapLine

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

the class MapArea method canAddSize.

/**
 * Will element fit nicely?
 * Limit to WANTED_MAX_AREA_SIZE which is smaller than MAX_XT_xxx_SIZE
 * so don't need to check down to the last detail
 *
 * @param el The element. Assume want to display it at this resolution
 * @param kind What kind of element this is: KIND_POINT/LINE/SHAPE.
 */
private boolean canAddSize(MapElement el, int kind) {
    int numPoints;
    int numElements;
    int sumSize = 0;
    for (int s : sizes) sumSize += s;
    switch(kind) {
        case POINT_KIND:
            if (getNumPoints() >= MapSplitter.MAX_NUM_POINTS)
                return false;
            // Points are predictably less than 10 bytes.
            if ((sumSize + 9) > MapSplitter.WANTED_MAX_AREA_SIZE)
                return false;
            break;
        case LINE_KIND:
            // Estimate the size taken by lines and shapes as a constant plus
            // a factor based on the number of points.
            numPoints = PredictFilterPoints.predictedMaxNumPoints(((MapLine) el).getPoints(), areaResolution, // assume MapBuilder.doRoads is true. subDiv.getZoom().getLevel() == 0 is maximum resolution
            ((MapLine) el).isRoad() && areaResolution == MAX_RESOLUTION);
            if (numPoints <= 1 && !((MapLine) el).isRoad())
                break;
            numElements = 1 + ((numPoints - 1) / LineSplitterFilter.MAX_POINTS_IN_LINE);
            if (getNumLines() + numElements > MapSplitter.MAX_NUM_LINES)
                return false;
            // very pessimistic, typically less than 2 bytes are needed for one point
            if ((sumSize + numElements * 11 + numPoints * 4) > MapSplitter.WANTED_MAX_AREA_SIZE)
                return false;
            break;
        case SHAPE_KIND:
            // Estimate the size taken by lines and shapes as a constant plus
            // a factor based on the number of points.
            numPoints = PredictFilterPoints.predictedMaxNumPoints(((MapShape) el).getPoints(), areaResolution, false);
            if (numPoints <= 3)
                break;
            numElements = 1 + ((numPoints - 1) / PolygonSplitterFilter.MAX_POINT_IN_ELEMENT);
            // very pessimistic, typically less than 2 bytes are needed for one point
            if ((sumSize + numElements * 11 + numPoints * 4) > MapSplitter.WANTED_MAX_AREA_SIZE)
                return false;
            break;
    }
    return true;
}
Also used : MapLine(uk.me.parabola.mkgmap.general.MapLine) MapShape(uk.me.parabola.mkgmap.general.MapShape) MapPoint(uk.me.parabola.mkgmap.general.MapPoint)

Example 10 with MapLine

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

the class MapArea method split.

/**
 * Split this area into several pieces. All the map elements are reallocated
 * to the appropriate subarea.  Usually this instance would now be thrown
 * away and the new sub areas used instead.
 * <p>
 * This code is dealing with a lot of factors that govern the splitting, eg:
 *  splitPolygonsIntoArea,
 *  tooSmallToDivide,
 *  item.minResolution vs. areaResolution,
 *  number/size of items and the limits of a subDivision,
 *  items that exceed maximum subDivision on their own,
 *  items that extend up to 50% outside the current area,
 *  items bigger than this.
 *
 * @param nx The number of pieces in the x (longitude) direction.
 * @param ny The number of pieces in the y direction.
 * @param bounds the bounding box that is used to create the areas.
 * @param tooSmallToDivide the area is small and data overflows; split into overflow areas
 *
 * @return An array of the new MapArea's or null if can't split.
 */
public MapArea[] split(int nx, int ny, Area bounds, boolean tooSmallToDivide) {
    int resolutionShift = MAX_RESOLUTION - areaResolution;
    Area[] areas = bounds.split(nx, ny, resolutionShift);
    if (areas == null) {
        // Failed to split!
        if (log.isDebugEnabled()) {
            // see what is here
            for (MapLine e : this.lines) if (e.getMinResolution() <= areaResolution)
                log.debug("line. locn=", e.getPoints().get(0).toOSMURL(), " type=", uk.me.parabola.mkgmap.reader.osm.GType.formatType(e.getType()), " name=", e.getName(), " min=", e.getMinResolution(), " max=", e.getMaxResolution());
            for (MapShape e : this.shapes) if (e.getMinResolution() <= areaResolution)
                log.debug("shape. locn=", e.getPoints().get(0).toOSMURL(), " type=", uk.me.parabola.mkgmap.reader.osm.GType.formatType(e.getType()), " name=", e.getName(), " min=", e.getMinResolution(), " max=", e.getMaxResolution(), " full=", e.getFullArea(), " calc=", uk.me.parabola.mkgmap.filters.ShapeMergeFilter.calcAreaSizeTestVal(e.getPoints()));
        // the main culprits are lots of bits of sea and coastline in an overview map (res 12)
        }
        return null;
    }
    MapArea[] mapAreas = new MapArea[nx * ny];
    log.info("Splitting area " + bounds + " into " + nx + "x" + ny + " pieces at resolution " + areaResolution, tooSmallToDivide);
    List<MapArea> addedAreas = new ArrayList<>();
    for (int i = 0; i < mapAreas.length; i++) {
        mapAreas[i] = new MapArea(areas[i], areaResolution, splitPolygonsIntoArea);
        if (log.isDebugEnabled())
            log.debug("area before", mapAreas[i].getBounds());
    }
    int xbaseHp = areas[0].getMinLong() << Coord.DELTA_SHIFT;
    int ybaseHp = areas[0].getMinLat() << Coord.DELTA_SHIFT;
    int dxHp = areas[0].getWidth() << Coord.DELTA_SHIFT;
    int dyHp = areas[0].getHeight() << Coord.DELTA_SHIFT;
    // Some of the work done by PolygonSubdivSizeSplitterFilter now done here
    final int maxSize = Math.min((1 << 24) - 1, Math.max(MapSplitter.MAX_DIVISION_SIZE << (MAX_RESOLUTION - areaResolution), 0x8000));
    /**
     * These constants control when an item (shape unless splitPolygonsIntoArea or line) is shifted into its own MapArea/SubDivision.
     * Generally, an item is allowed into the MapArea chosen by centre provided it is no bigger than the MapArea.
     * This means that there could be big items near the edges of the MapArea that stick out by almost half, so must
     * ensure that this doesn't cause the mapArea to exceed subDivision size limits.
     * When the MapArea get small, we don't want to shift lots if items into their own areas;
     * The *2 of LARGE_OBJECT_DIM is to keep to the same behaviour as earlier versions.
     */
    final int maxWidth = Math.max(Math.min(areas[0].getWidth(), maxSize / 2), LARGE_OBJECT_DIM * 2);
    final int maxHeight = Math.max(Math.min(areas[0].getHeight(), maxSize / 2), LARGE_OBJECT_DIM * 2);
    // and don't have a good tooSmallToDivide strategy when not splitPolygonsIntoArea.
    if (tooSmallToDivide) {
        distShapesIntoNewAreas(addedAreas, mapAreas[0]);
    } else {
        for (MapShape e : this.shapes) {
            Area shapeBounds = e.getBounds();
            if (splitPolygonsIntoArea || shapeBounds.getMaxDimension() > maxSize) {
                splitIntoAreas(mapAreas, e);
                continue;
            }
            int areaIndex = pickArea(mapAreas, e, xbaseHp, ybaseHp, nx, ny, dxHp, dyHp);
            if ((shapeBounds.getHeight() > maxHeight || shapeBounds.getWidth() > maxWidth) && !areas[areaIndex].contains(shapeBounds)) {
                // use splitIntoAreas to deal with overflow
                MapArea largeObjectArea = new MapArea(shapeBounds, areaResolution, true);
                largeObjectArea.addShape(e);
                addedAreas.add(largeObjectArea);
                continue;
            }
            mapAreas[areaIndex].addShape(e);
        }
    }
    if (tooSmallToDivide) {
        distPointsIntoNewAreas(addedAreas, mapAreas[0]);
    } else {
        for (MapPoint p : this.points) {
            int areaIndex = pickArea(mapAreas, p, xbaseHp, ybaseHp, nx, ny, dxHp, dyHp);
            mapAreas[areaIndex].addPoint(p);
        }
    }
    if (tooSmallToDivide) {
        distLinesIntoNewAreas(addedAreas, mapAreas[0]);
    } else {
        for (MapLine l : this.lines) {
            // Drop any zero sized lines.
            if (l instanceof MapRoad == false && l.getRect().height <= 0 && l.getRect().width <= 0)
                continue;
            Area lineBounds = l.getBounds();
            int areaIndex = pickArea(mapAreas, l, xbaseHp, ybaseHp, nx, ny, dxHp, dyHp);
            if ((lineBounds.getHeight() > maxHeight || lineBounds.getWidth() > maxWidth) && !areas[areaIndex].contains(lineBounds)) {
                MapArea largeObjectArea = new MapArea(lineBounds, areaResolution, false);
                largeObjectArea.addLine(l);
                addedAreas.add(largeObjectArea);
                continue;
            }
            mapAreas[areaIndex].addLine(l);
        }
    }
    if (!addedAreas.isEmpty()) {
        // combine list and array
        int pos = mapAreas.length;
        mapAreas = Arrays.copyOf(mapAreas, mapAreas.length + addedAreas.size());
        for (MapArea ma : addedAreas) {
            if (// distShapesIntoNewAreas etc didn't know how big it was going to be
            ma.getBounds() == null)
                // so set to bounds of all elements
                ma.setBounds(ma.getFullBounds());
            mapAreas[pos++] = ma;
        }
    }
    return mapAreas;
}
Also used : Area(uk.me.parabola.imgfmt.app.Area) MapLine(uk.me.parabola.mkgmap.general.MapLine) MapPoint(uk.me.parabola.mkgmap.general.MapPoint) ArrayList(java.util.ArrayList) MapRoad(uk.me.parabola.mkgmap.general.MapRoad) MapShape(uk.me.parabola.mkgmap.general.MapShape) MapPoint(uk.me.parabola.mkgmap.general.MapPoint)

Aggregations

MapLine (uk.me.parabola.mkgmap.general.MapLine)29 Coord (uk.me.parabola.imgfmt.app.Coord)16 MapPoint (uk.me.parabola.mkgmap.general.MapPoint)15 ArrayList (java.util.ArrayList)12 MapShape (uk.me.parabola.mkgmap.general.MapShape)10 MapRoad (uk.me.parabola.mkgmap.general.MapRoad)6 MapExitPoint (uk.me.parabola.mkgmap.general.MapExitPoint)4 Point (uk.me.parabola.imgfmt.app.trergn.Point)3 CoordNode (uk.me.parabola.imgfmt.app.CoordNode)2 FilterConfig (uk.me.parabola.mkgmap.filters.FilterConfig)2 Area (uk.me.parabola.imgfmt.app.Area)1 City (uk.me.parabola.imgfmt.app.lbl.City)1 LBLFile (uk.me.parabola.imgfmt.app.lbl.LBLFile)1 Zip (uk.me.parabola.imgfmt.app.lbl.Zip)1 GeneralRouteRestriction (uk.me.parabola.imgfmt.app.net.GeneralRouteRestriction)1 Numbers (uk.me.parabola.imgfmt.app.net.Numbers)1 ExtTypeAttributes (uk.me.parabola.imgfmt.app.trergn.ExtTypeAttributes)1 Polyline (uk.me.parabola.imgfmt.app.trergn.Polyline)1 Subdivision (uk.me.parabola.imgfmt.app.trergn.Subdivision)1 Zoom (uk.me.parabola.imgfmt.app.trergn.Zoom)1