[Git][debian-gis-team/mkgmap][upstream] New upstream version 0.0.0+svn4585
Bas Couwenberg
gitlab at salsa.debian.org
Thu Oct 1 05:11:38 BST 2020
Bas Couwenberg pushed to branch upstream at Debian GIS Project / mkgmap
Commits:
c04a3895 by Bas Couwenberg at 2020-10-01T05:47:17+02:00
New upstream version 0.0.0+svn4585
- - - - -
19 changed files:
- doc/styles/internal-tags.txt
- doc/styles/rules.txt
- resources/mkgmap-version.properties
- src/org/openstreetmap/osmosis/core/filter/common/PolygonFileReader.java
- src/uk/me/parabola/imgfmt/app/mdr/MDRFile.java
- src/uk/me/parabola/imgfmt/app/net/RoadDef.java
- src/uk/me/parabola/imgfmt/app/trergn/TREHeader.java
- src/uk/me/parabola/mkgmap/build/MapArea.java
- src/uk/me/parabola/mkgmap/build/MapSplitter.java
- src/uk/me/parabola/mkgmap/combiners/FileInfo.java
- − src/uk/me/parabola/mkgmap/filters/PolygonSplitterBase.java
- src/uk/me/parabola/mkgmap/filters/PolygonSplitterFilter.java
- − src/uk/me/parabola/mkgmap/filters/PolygonSubdivSizeSplitterFilter.java
- src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
- src/uk/me/parabola/mkgmap/reader/osm/HighwayHooks.java
- src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java
- src/uk/me/parabola/util/Java2DConverter.java
- test/resources/rules/continue.test
- test/resources/rules/oneway.test
Changes:
=====================================
doc/styles/internal-tags.txt
=====================================
@@ -120,6 +120,7 @@ is used to assign the country location.
| +mkgmap:area2poi+ | The value is +true+ if the POI is derived from a polygon | 'add-pois-to-areas'
| +mkgmap:line2poi+ | The value is +true+ if the POI is derived from a line | 'add-pois-to-lines'
| +mkgmap:line2poitype+ | The tag is set for each POI generated from a line. Possible values are: +start+, +end+, +mid+, +inner+. | 'add-pois-to-lines'
+| +mkgmap:from-node:attname+ | The attribute is set for each POI generated from a line. These are the original attributes of the node (part of the line) from which the point was generated | 'add-pois-to-lines'
| +mkgmap:way-length+ | The tag is set for each POI generated from a line. It gives the way length rounded to meters. | 'add-pois-to-lines'
| +mkgmap:exit_hint+ | +true+ for the part on link roads that should contain information about the exit | 'process-exits'
| +mkgmap:exit_hint_name+ | The +name+ tag value of the links exit node | 'process-exits'
=====================================
doc/styles/rules.txt
=====================================
@@ -1043,3 +1043,23 @@ the Garmin POI will be _7, Alya Street, Lagos, 90210 open 09.00-17.00_.
====
+.Mountain Passes depending on the way they belong to
+====
+[source]
+ mkgmap:from-node:mountain_pass=yes & highway=* & highway!=path & highway!=track
+ {set mkgmap:label:1='${mkgmap:from-node:name}'} [0x5208 resolution 24-14]
+
+Note: This only works if you activated --add-pois-to-lines.
+When you activate this option, all points of a line (a way in OpenStreetMap) generate a point.
+
+Those points attributes are those from OpenStreetMap's way. The specific node's
+attributes are set as mkgmap:from-node:attribute_name. For instance, here,
+all points from a way are available to a "points" rule. We're looking for
+mountain passes, but only if they can be reached by something else than a path
+or a track. So we match all points that belong to a way that's not a path or a
+track, and where the original point is tagged as a mountain pass.
+
+Please note that if the point is part of several ways, you'll get duplicates
+(you could use --nearby-poi-rules to solve this).
+
+====
=====================================
resources/mkgmap-version.properties
=====================================
@@ -1,2 +1,2 @@
-svn.version: 4566
-build.timestamp: 2020-09-04T12:01:12+0100
+svn.version: 4585
+build.timestamp: 2020-09-23T08:42:20+0100
=====================================
src/org/openstreetmap/osmosis/core/filter/common/PolygonFileReader.java
=====================================
@@ -301,7 +301,10 @@ public class PolygonFileReader {
if (tokenCount < 2) {
throw new OsmosisRuntimeException("Could not find two coordinates on line (" + coordinateLine + ").");
}
-
+ if (results[0] > 180 || results[0] < -180)
+ throw new OsmosisRuntimeException("Invalid longitude " + results[0] + " on line (" + coordinateLine + ").");
+ if (results[1] > 90 || results[1] < -90)
+ throw new OsmosisRuntimeException("Invalid latitude " + results[1] + " on line (" + coordinateLine + ").");
return results;
}
=====================================
src/uk/me/parabola/imgfmt/app/mdr/MDRFile.java
=====================================
@@ -370,7 +370,9 @@ public class MDRFile extends ImgFile {
// The following do not have mdr1 subsections
//writeSection(writer, 8, mdr8);
writeSection(writer, 9, mdr9);
- writeSection(writer, 12, mdr12);
+ if (!isMulti) {
+ writeSection(writer, 12, mdr12);
+ }
writeSection(writer, 13, mdr13);
writeSection(writer, 14, mdr14);
writeSection(writer, 15, mdr15);
=====================================
src/uk/me/parabola/imgfmt/app/net/RoadDef.java
=====================================
@@ -36,6 +36,7 @@ import uk.me.parabola.imgfmt.app.lbl.Zip;
import uk.me.parabola.imgfmt.app.trergn.Polyline;
import uk.me.parabola.log.Logger;
import uk.me.parabola.mkgmap.general.CityInfo;
+import uk.me.parabola.mkgmap.general.MapLine;
import uk.me.parabola.mkgmap.general.ZipCodeInfo;
/**
@@ -62,6 +63,7 @@ import uk.me.parabola.mkgmap.general.ZipCodeInfo;
public class RoadDef {
private static final Logger log = Logger.getLogger(RoadDef.class);
public static final int MAX_NUMBER_NODES = 0x3ff;
+ public static final int MAX_NUMBER_POLYLINES = 0x7f;
public static final int NET_FLAG_NODINFO = 0x40;
public static final int NET_FLAG_ADDRINFO = 0x10;
@@ -335,7 +337,8 @@ public class RoadDef {
for (int i = 0; i <= maxlevel; i++) {
List<RoadIndex> l = roadIndexes.get(i);
int b = (l == null) ? 0 : l.size();
- assert b < 0x80 : "too many polylines at level " + i;
+ if (b > MAX_NUMBER_POLYLINES)
+ throw new MapFailedException("Too many polylines for road " + this + " at level " + i);
if (i == maxlevel)
b |= 0x80;
writer.put1u(b);
=====================================
src/uk/me/parabola/imgfmt/app/trergn/TREHeader.java
=====================================
@@ -17,6 +17,9 @@
package uk.me.parabola.imgfmt.app.trergn;
import uk.me.parabola.imgfmt.Utils;
+
+import java.io.IOException;
+
import uk.me.parabola.imgfmt.ReadFailedException;
import uk.me.parabola.imgfmt.app.Area;
import uk.me.parabola.imgfmt.app.CommonHeader;
@@ -104,7 +107,9 @@ public class TREHeader extends CommonHeader {
* @param reader The header is read from here.
*/
protected void readFileHeader(ImgFileReader reader) throws ReadFailedException {
- assert reader.position() == COMMON_HEADER_LEN;
+ if (reader.position() != COMMON_HEADER_LEN) {
+ throw new ReadFailedException("Reader position not at expected header length", new IOException());
+ }
int maxLat = reader.get3s();
int maxLon = reader.get3s();
int minLat = reader.get3s();
=====================================
src/uk/me/parabola/mkgmap/build/MapArea.java
=====================================
@@ -31,7 +31,6 @@ import uk.me.parabola.mkgmap.filters.LineSizeSplitterFilter;
import uk.me.parabola.mkgmap.filters.LineSplitterFilter;
import uk.me.parabola.mkgmap.filters.MapFilterChain;
import uk.me.parabola.mkgmap.filters.PolygonSplitterFilter;
-import uk.me.parabola.mkgmap.filters.PolygonSubdivSizeSplitterFilter;
import uk.me.parabola.mkgmap.filters.PredictFilterPoints;
import uk.me.parabola.mkgmap.general.MapDataSource;
import uk.me.parabola.mkgmap.general.MapElement;
@@ -54,7 +53,6 @@ import uk.me.parabola.util.ShapeSplitter;
public class MapArea implements MapDataSource {
private static final Logger log = Logger.getLogger(MapArea.class);
- private static final int INITIAL_CAPACITY = 100;
private static final int MAX_RESOLUTION = 24;
private static final int LARGE_OBJECT_DIM = 8192;
@@ -77,9 +75,9 @@ public class MapArea implements MapDataSource {
private int maxLon = Integer.MIN_VALUE;
// The contents of the area.
- private final List<MapPoint> points = new ArrayList<>(INITIAL_CAPACITY);
- private final List<MapLine> lines = new ArrayList<>(INITIAL_CAPACITY);
- private final List<MapShape> shapes = new ArrayList<>(INITIAL_CAPACITY);
+ private final List<MapPoint> points = new ArrayList<>();
+ private final List<MapLine> lines = new ArrayList<>();
+ private final List<MapShape> shapes = new ArrayList<>();
// amount of space required for the contents
private final int[] sizes = new int[NUM_KINDS];
@@ -130,25 +128,10 @@ public class MapArea implements MapDataSource {
* @param resolution The current resolution of the layer.
*/
private void addPolygons(MapDataSource src, final int resolution) {
- MapFilterChain chain = element -> addShape((MapShape) element);
-
- PolygonSubdivSizeSplitterFilter filter = new PolygonSubdivSizeSplitterFilter();
- FilterConfig config = new FilterConfig();
- config.setResolution(resolution);
- config.setBounds(bounds);
- filter.init(config);
-
for (MapShape s : src.getShapes()) {
if (s.getMaxResolution() < resolution)
continue;
- if (splitPolygonsIntoArea || this.bounds.isEmpty() || this.bounds.contains(s.getBounds()))
- // if splitPolygonsIntoArea, don't want to have other splitting as well.
- // PolygonSubdivSizeSplitterFilter is a bit drastic - filters by both size and number of points
- // so use splitPolygonsIntoArea logic for this as well. This is fine as long as there
- // aren't bits of the shape outside the initial area.
- addShape(s);
- else
- filter.doFilter(s, chain);
+ addShape(s);
}
}
@@ -544,13 +527,13 @@ public class MapArea implements MapDataSource {
*/
private void addSize(MapElement el, int kind) {
- int res = el.getMinResolution();
+ final int res = el.getMinResolution();
if (res > areaResolution || res > MAX_RESOLUTION)
return;
++splittableCount;
- int numPoints;
- int numElements;
+ final int numPoints;
+ final int numElements;
switch (kind) {
case POINT_KIND:
@@ -612,8 +595,8 @@ public class MapArea implements MapDataSource {
*/
private boolean canAddSize(MapElement el, int kind) {
- int numPoints;
- int numElements;
+ final int numPoints;
+ final int numElements;
int sumSize = 0;
for (int s : sizes)
sumSize += s;
=====================================
src/uk/me/parabola/mkgmap/build/MapSplitter.java
=====================================
@@ -41,10 +41,10 @@ public class MapSplitter {
// staying safely inside it however.
public static final int MAX_DIVISION_SIZE = 0x7fff;
- // The maximum region size. Note that the offset to the start of a section
+ // Not a real limit. Note that the offset to the start of a section
// has to fit into 16 bits, the end of the last section could be beyond the
// 16 bit limit. Leave a little room for the region pointers
- public static final int MAX_RGN_SIZE = 0xfff8;
+ public static final int MAX_RGN_OFFSET_SIZE = 0xfff8;
// The maximum number of lines. NET points to lines in subdivision
// using bytes.
@@ -140,39 +140,35 @@ public class MapSplitter {
String padding = depth + " ";
log.info(padding.substring(0, (depth + 1) * 2) +
bounds.getWidth() + "x" + bounds.getHeight() +
- ", points = " + area.getNumPoints() + "/" + sizes[MapArea.POINT_KIND] +
- ", lines = " + area.getNumLines() + "/" + sizes[MapArea.LINE_KIND] +
- ", shapes = " + area.getNumShapes() + "/" + sizes[MapArea.SHAPE_KIND]);
+ ", points = " + area.getNumPoints() + "/" + sizes[MapArea.POINT_KIND] + "/" + sizes[MapArea.XT_POINT_KIND] +
+ ", lines = " + area.getNumLines() + "/" + sizes[MapArea.LINE_KIND] + "/" + sizes[MapArea.XT_LINE_KIND] +
+ ", shapes = " + area.getNumShapes() + "/" + sizes[MapArea.SHAPE_KIND] + "/" + sizes[MapArea.XT_SHAPE_KIND]);
}
boolean wantSplit = false;
boolean mustSplit = false;
- if (area.getNumLines() > MAX_NUM_LINES ||
- area.getNumPoints() > MAX_NUM_POINTS ||
- (sizes[MapArea.POINT_KIND] +
- sizes[MapArea.LINE_KIND] +
- sizes[MapArea.SHAPE_KIND]) > MAX_RGN_SIZE ||
- sizes[MapArea.XT_POINT_KIND] > MAX_XT_POINTS_SIZE ||
- sizes[MapArea.XT_LINE_KIND] > MAX_XT_LINES_SIZE ||
- sizes[MapArea.XT_SHAPE_KIND] > MAX_XT_SHAPES_SIZE)
+ if (area.getNumLines() > MAX_NUM_LINES || area.getNumPoints() > MAX_NUM_POINTS
+ || (sizes[MapArea.POINT_KIND] + sizes[MapArea.LINE_KIND]) > MAX_RGN_OFFSET_SIZE
+ || sizes[MapArea.XT_POINT_KIND] > MAX_XT_POINTS_SIZE
+ || sizes[MapArea.XT_LINE_KIND] > MAX_XT_LINES_SIZE
+ || sizes[MapArea.XT_SHAPE_KIND] > MAX_XT_SHAPES_SIZE)
mustSplit = true;
else if (bounds.getMaxDimension() > (MIN_DIMENSION << shift)) {
int sumSize = 0;
for (int s : sizes)
sumSize += s;
if (sumSize > WANTED_MAX_AREA_SIZE) {
- // area has more bytes than wanted, and large enough to split
- log.debug("splitting area because data size is larger than wanted:", sumSize);
+ // area has more bytes than wanted, and is large enough to split
+ log.debug("splitting area because estimated data size is larger than wanted:", sumSize);
wantSplit = true;
}
}
if (wantSplit || mustSplit) {
if (!area.canSplit()) {
- if (mustSplit)
- log.error("Single item predicted to exceed subdivision", area.getBounds().getCenter().toOSMURL());
- else
+ if (!mustSplit) {
log.info("Single item larger that WANTED_MAX_AREA_SIZE", area.getBounds().getCenter().toOSMURL());
+ }
} else if (bounds.getMaxDimension() > (MIN_DIMENSION << shift)) {
log.debug("splitting area in half", area, mustSplit, wantSplit);
MapArea[] sublist;
=====================================
src/uk/me/parabola/mkgmap/combiners/FileInfo.java
=====================================
@@ -26,6 +26,7 @@ import java.util.Locale;
import java.util.Objects;
import uk.me.parabola.imgfmt.FileSystemParam;
+import uk.me.parabola.imgfmt.ReadFailedException;
import uk.me.parabola.imgfmt.Utils;
import uk.me.parabola.imgfmt.app.Area;
import uk.me.parabola.imgfmt.app.BufferedImgFileReader;
@@ -152,16 +153,19 @@ public class FileInfo {
String ext = end < 3 ? "" : inputName.substring(end - 3).toUpperCase(Locale.ENGLISH);
FileInfo info;
- if (Objects.equals(ext, "IMG")) {
- info = imgInfo(inputName);
- } else if ("TYP".equals(ext)) {
- info = fileInfo(inputName, TYP_KIND);
- } else if (KNOWN_FILE_TYPE_EXT.contains(ext)) {
- info = fileInfo(inputName, APP_KIND);
- } else {
- info = new FileInfo(inputName, UNKNOWN_KIND);
+ try {
+ if (Objects.equals(ext, "IMG")) {
+ info = imgInfo(inputName);
+ } else if ("TYP".equals(ext)) {
+ info = fileInfo(inputName, TYP_KIND);
+ } else if (KNOWN_FILE_TYPE_EXT.contains(ext)) {
+ info = fileInfo(inputName, APP_KIND);
+ } else {
+ info = new FileInfo(inputName, UNKNOWN_KIND);
+ }
+ } catch (AssertionError | ReadFailedException e) {
+ throw new ReadFailedException("Could not read file " + inputName, e);
}
-
return info;
}
=====================================
src/uk/me/parabola/mkgmap/filters/PolygonSplitterBase.java deleted
=====================================
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2007 Steve Ratcliffe
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License 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.
- *
- *
- * Author: Steve Ratcliffe
- * Create date: Dec 6, 2007
- */
-package uk.me.parabola.mkgmap.filters;
-
-import java.util.List;
-import java.util.ArrayList;
-
-import uk.me.parabola.util.ShapeSplitter;
-import uk.me.parabola.imgfmt.app.Area;
-import uk.me.parabola.imgfmt.app.Coord;
-import uk.me.parabola.mkgmap.general.MapShape;
-
-/**
- * @author Steve Ratcliffe
- */
-public class PolygonSplitterBase extends BaseFilter {
- protected static final int MAX_SIZE = 0xffff; // larger value causes problem in delta encoding of lines
- protected int shift;
- protected int resolution;
-
- @Override
- public void init(FilterConfig config) {
- shift = config.getShift();
- resolution = config.getResolution();
- }
-
- /**
- * Split the given shape and place the resulting shapes in the outputs list.
- * @param shape The original shape (that is too big).
- * @param outputs The output list.
- */
- protected void split(MapShape shape, List<MapShape> outputs) {
- int dividingLine = 0;
- boolean isLongitude = false;
- Area bounds = shape.getBounds();
- if (bounds.getWidth() > bounds.getHeight()) {
- isLongitude = true;
- Area[] tmpAreas = bounds.split(2, 1, shift);
- dividingLine = tmpAreas != null ? tmpAreas[0].getMaxLong() : (bounds.getMinLong() + bounds.getWidth() / 2);
- } else {
- Area[] tmpAreas = bounds.split(1, 2, shift);
- dividingLine = tmpAreas != null ? tmpAreas[0].getMaxLat() : (bounds.getMinLat() + bounds.getHeight() / 2);
- }
- List<List<Coord>> subShapePoints = new ArrayList<>();
- ShapeSplitter.splitShape(shape.getPoints(), dividingLine << Coord.DELTA_SHIFT, isLongitude, subShapePoints, subShapePoints, null);
- for (List<Coord> subShape : subShapePoints) {
- MapShape s = shape.copy();
- s.setPoints(subShape);
- outputs.add(s);
- }
- }
-
-}
=====================================
src/uk/me/parabola/mkgmap/filters/PolygonSplitterFilter.java
=====================================
@@ -16,8 +16,11 @@
*/
package uk.me.parabola.mkgmap.filters;
+import uk.me.parabola.imgfmt.app.Area;
+import uk.me.parabola.imgfmt.app.Coord;
import uk.me.parabola.mkgmap.general.MapElement;
import uk.me.parabola.mkgmap.general.MapShape;
+import uk.me.parabola.util.ShapeSplitter;
import java.util.ArrayList;
import java.util.List;
@@ -27,9 +30,40 @@ import java.util.List;
*
* @author Gerd Petermann
*/
-public class PolygonSplitterFilter extends PolygonSplitterBase implements MapFilter {
-
+public class PolygonSplitterFilter implements MapFilter {
public static final int MAX_POINT_IN_ELEMENT = 250;
+ private int shift;
+
+ @Override
+ public void init(FilterConfig config) {
+ shift = config.getShift();
+ }
+
+ /**
+ * Split the given shape and place the resulting shapes in the outputs list.
+ * @param shape The original shape (that is too big).
+ * @param outputs The output list.
+ */
+ private void split(MapShape shape, List<MapShape> outputs) {
+ int dividingLine = 0;
+ boolean isLongitude = false;
+ Area bounds = shape.getBounds();
+ if (bounds.getWidth() > bounds.getHeight()) {
+ isLongitude = true;
+ Area[] tmpAreas = bounds.split(2, 1, shift);
+ dividingLine = tmpAreas != null ? tmpAreas[0].getMaxLong() : (bounds.getMinLong() + bounds.getWidth() / 2);
+ } else {
+ Area[] tmpAreas = bounds.split(1, 2, shift);
+ dividingLine = tmpAreas != null ? tmpAreas[0].getMaxLat() : (bounds.getMinLat() + bounds.getHeight() / 2);
+ }
+ List<List<Coord>> subShapePoints = new ArrayList<>();
+ ShapeSplitter.splitShape(shape.getPoints(), dividingLine << Coord.DELTA_SHIFT, isLongitude, subShapePoints, subShapePoints, null);
+ for (List<Coord> subShape : subShapePoints) {
+ MapShape s = shape.copy();
+ s.setPoints(subShape);
+ outputs.add(s);
+ }
+ }
/**
* This filter splits a polygon if any of the subsequent filters throws a
@@ -41,7 +75,6 @@ public class PolygonSplitterFilter extends PolygonSplitterBase implements MapFil
*/
@Override
public void doFilter(MapElement element, MapFilterChain next) {
- assert element instanceof MapShape;
MapShape shape = (MapShape) element;
try {
=====================================
src/uk/me/parabola/mkgmap/filters/PolygonSubdivSizeSplitterFilter.java deleted
=====================================
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2010, 2011.
- *
- * 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.mkgmap.filters;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import uk.me.parabola.log.Logger;
-import uk.me.parabola.mkgmap.build.MapSplitter;
-import uk.me.parabola.mkgmap.general.MapElement;
-import uk.me.parabola.mkgmap.general.MapShape;
-
-/**
- * Split polygon so that it does not exceed the limits of a subdivision. The plan
- * here is simple, if its too big, then cut it in half. As we always cut the largest
- * dimension, then we will soon enough have cut it down to be small enough.
- *
- * @author WanMil
- */
-public class PolygonSubdivSizeSplitterFilter extends PolygonSplitterBase implements MapFilter {
- private static final Logger log = Logger.getLogger(PolygonSubdivSizeSplitterFilter.class);
-
- private int maxSize;
-
- /**
- * Get the scale factor so that we don't over split.
- *
- * @param config configuration information, giving parameters of the map level
- * that is being produced through this filter.
- */
- @Override
- public void init(FilterConfig config) {
- int shift = config.getShift();
- if (shift > 15)
- shift = 16;
- // allow a size of 0x8000 to avoid splitting of generated precomp-sea polygons
- maxSize = Math.min((1<<24)-1, Math.max(MAX_SIZE << shift, 0x8000));
- }
-
- /**
- * 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.
- */
- @Override
- 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<>();
-
- // Do an initial split
- split(shape, outputs);
-
- // Now check that all the resulting parts are also small enough.
- // 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);
- }
- }
-
- private boolean isSizeOk(MapShape shape) {
- // do not cut the background shape
- if (shape.getType() == 0x4a)
- return true;
-
- // Estimate the size taken by lines and shapes as a constant plus
- // a factor based on the number of points.
- int numPoints = shape.getPoints().size();
- int numElements = 1 + ((numPoints - 1) / PolygonSplitterFilter.MAX_POINT_IN_ELEMENT);
- int size = numElements * 11 + numPoints * 4;
-
- if (shape.hasExtendedType()) {
- if (size > MapSplitter.MAX_XT_SHAPES_SIZE) {
- log.debug("XTSize larger than", MapSplitter.MAX_XT_SHAPES_SIZE);
- return false;
- }
- } else if (size > MapSplitter.MAX_RGN_SIZE) {
- log.debug("RGN Size larger than", MapSplitter.MAX_RGN_SIZE);
- return false;
- }
- int maxDim = shape.getBounds().getMaxDimension();
- if (maxDim > maxSize){
- log.debug("Size ", maxDim," larger than ", maxSize);
- return false;
- }
- return true;
- }
-
-}
=====================================
src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
=====================================
@@ -42,11 +42,13 @@ import uk.me.parabola.imgfmt.app.Exit;
import uk.me.parabola.imgfmt.app.Label;
import uk.me.parabola.imgfmt.app.net.AccessTagsAndBits;
import uk.me.parabola.imgfmt.app.net.GeneralRouteRestriction;
+import uk.me.parabola.imgfmt.app.net.RoadDef;
import uk.me.parabola.imgfmt.app.trergn.ExtTypeAttributes;
import uk.me.parabola.imgfmt.app.trergn.MapObject;
import uk.me.parabola.log.Logger;
import uk.me.parabola.mkgmap.build.LocatorConfig;
import uk.me.parabola.mkgmap.filters.LineSizeSplitterFilter;
+import uk.me.parabola.mkgmap.filters.LineSplitterFilter;
import uk.me.parabola.mkgmap.general.AreaClipper;
import uk.me.parabola.mkgmap.general.Clipper;
import uk.me.parabola.mkgmap.general.LineAdder;
@@ -108,6 +110,10 @@ public class StyledConverter implements OsmConverter {
// limit arc lengths to what can be handled by RouteArc
private static final int MAX_ARC_LENGTH = 20450000; // (1 << 22) * 16 / 3.2808 ~ 20455030*/
+
+ // limit number of points so that a single road doesn't have too many polylines
+ private static final int MAX_ROAD_POINTS = (RoadDef.MAX_NUMBER_POLYLINES - 2) * LineSplitterFilter.MAX_POINTS_IN_LINE;
+
/** Number of routing nodes in way, possibly could be increased, not a hard limit in IMG format.
* See also RoadDef.MAX_NUMBER_NODES.
@@ -300,7 +306,7 @@ public class StyledConverter implements OsmConverter {
boolean wasReversed = false;
String oneWay = way.getTag(TK_ONEWAY);
if (oneWay != null){
- if("-1".equals(oneWay) || "reverse".equals(oneWay)) {
+ if("-1".equals(oneWay)) {
// it's a oneway street in the reverse direction
// so reverse the order of the nodes and change
// the oneway tag to "yes"
@@ -322,7 +328,10 @@ public class StyledConverter implements OsmConverter {
if (cw.isRoad()){
roads.add(cw);
numRoads++;
- if (!cw.isFerry()) {
+ // ignore driving side for oneway roads, ferries and roads that
+ // don't allow motor vehicles
+ if (!cw.isOneway() && !cw.isFerry()
+ && (cw.getAccess() & ~(AccessTagsAndBits.FOOT | AccessTagsAndBits.BIKE)) != 0) {
String countryIso = LocatorConfig.get().getCountryISOCode(way.getTag(TKM_COUNTRY));
if (countryIso != null) {
boolean drivingSideIsLeft = LocatorConfig.get().getDriveOnLeftFlag(countryIso);
@@ -1723,7 +1732,13 @@ public class StyledConverter implements OsmConverter {
wayBBox.addPoint(nextP);
- if ((arcLength + d) > MAX_ARC_LENGTH) {
+ if (i >= MAX_ROAD_POINTS) {
+ trailingWay = splitWayAt(way, i);
+ // this will have truncated the current Way's
+ // points so the loop will now terminate
+ if (log.isInfoEnabled())
+ log.info("Splitting way", debugWayName, "at", points.get(i).toOSMURL(), "to limit the total number of points");
+ } else if ((arcLength + d) > MAX_ARC_LENGTH) {
if (i <= 0)
log.error("internal error: long arc segment was not split", debugWayName);
assert i > 0 : "long arc segment was not split";
=====================================
src/uk/me/parabola/mkgmap/reader/osm/HighwayHooks.java
=====================================
@@ -153,10 +153,7 @@ public class HighwayHooks implements OsmReadingHooks {
if (makeOppositeCycleways && !"cycleway".equals(highway)){
String onewayTag = way.getTag("oneway");
- boolean oneway = way.tagIsLikeYes("oneway");
- if (!oneway && onewayTag != null && ("-1".equals(onewayTag) || "reverse".equals(onewayTag)))
- oneway = true;
- if (oneway){
+ if (way.tagIsLikeYes("oneway") || "-1".equals(onewayTag)){
String cycleway = way.getTag("cycleway");
// we have a oneway street, check if it allows bicycles to travel in opposite direction
if ("no".equals(way.getTag("oneway:bicycle"))
=====================================
src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java
=====================================
@@ -36,6 +36,7 @@ import java.util.Queue;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
+import java.util.stream.Collectors;
import uk.me.parabola.imgfmt.app.Coord;
import uk.me.parabola.log.Logger;
@@ -600,31 +601,48 @@ public class MultiPolygonRelation extends Relation {
ListIterator<JoinedWay> wayIter = wayList.listIterator();
while (wayIter.hasNext()) {
JoinedWay w = wayIter.next();
- boolean remove = true;
- // check all points
- for (Coord c : w.getPoints()) {
- if (tileBounds.contains(c)) {
- // if one point is in the bounding box the way should not be removed
- remove = false;
- break;
- }
- }
-
- // check if the polygon contains the complete bounding box
- if (remove && w.getBounds().contains(tileArea.getBounds())) {
- remove = false;
- }
- if (remove) {
+ if (isFullyOutsideBBox(w)) {
if (log.isDebugEnabled()) {
- log.debug("Remove way", w.getId(),
- "because it is completely outside the bounding box.");
+ if (w.originalWays.size() == 1) {
+ log.debug(this.getId(), ": Ignoring way", w.originalWays.get(0).getId(),
+ "because it is completely outside the bounding box.");
+ } else {
+ log.debug(this.getId(), ": Ignoring joined ways",
+ w.originalWays.stream().map(way -> Long.toString(way.getId()))
+ .collect(Collectors.joining(",")),
+ "because they are completely outside the bounding box.");
+ }
}
wayIter.remove();
}
}
}
+ private boolean isFullyOutsideBBox(JoinedWay w) {
+ if (!w.getBounds().intersects(tileArea.getBounds())) {
+ return true;
+ }
+
+ // check if the polygon bbox contains the complete tile bounds
+ if (w.getBounds().contains(tileArea.getBounds())) {
+ return false;
+ }
+
+ // check if any point is inside tile bounds
+ if (w.getPoints().stream().anyMatch(tileBounds::contains))
+ return false;
+
+ // check if any line segment of the polygon crosses the tile bounds
+ for (int i = 0; i < w.getPoints().size() - 1; i++) {
+ if (lineCutsBbox(w.getPoints().get(i), w.getPoints().get(i + 1))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+
/**
* Find all polygons that are not contained by any other polygon.
*
=====================================
src/uk/me/parabola/util/Java2DConverter.java
=====================================
@@ -377,6 +377,7 @@ public class Java2DConverter {
return Java2DConverter.AreaDegreesToMapUnit(polygonInDegrees);
} catch (Exception e) {
log.error("cannot read polygon file", polygonFile);
+ log.error(e);
}
return null;
}
=====================================
test/resources/rules/continue.test
=====================================
@@ -10,10 +10,10 @@ highway=secondary
abc=yes
<<<lines>>>
-highway=primary & abc=yes { set oneway=reverse; } [0x1 road_class=1 continue]
+highway=primary & abc=yes { set oneway=-1; } [0x1 road_class=1 continue]
highway=primary [0x2 road_class=1]
-highway=secondary & abc=yes { set oneway=reverse; } [0x3 road_class=2 continue
+highway=secondary & abc=yes { set oneway=-1; } [0x3 road_class=2 continue
with_actions]
highway=secondary [0x4 road_class=2]
=====================================
test/resources/rules/oneway.test
=====================================
@@ -4,10 +4,6 @@ oneway=yes
WAY 2
highway=secondary
-oneway=reverse
-
-WAY 3
-highway=secondary
oneway=-1
<<<lines>>>
@@ -17,4 +13,3 @@ highway=secondary [0x3 road_class=2 road_speed=2]
<<<results>>>
WAY 1: Road 0x2, labels=[null, null, null, null], res=24-24 oneway (1/1),(2/2), road class=2 speed=2
WAY 2: Road 0x3, labels=[null, null, null, null], res=24-24 oneway (2/2),(1/1), road class=2 speed=2
-WAY 3: Road 0x3, labels=[null, null, null, null], res=24-24 oneway (2/2),(1/1), road class=2 speed=2
View it on GitLab: https://salsa.debian.org/debian-gis-team/mkgmap/-/commit/c04a3895485b012c4a1be9d1bd7501b6750a0289
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/mkgmap/-/commit/c04a3895485b012c4a1be9d1bd7501b6750a0289
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20201001/5165d88d/attachment-0001.html>
More information about the Pkg-grass-devel
mailing list