Hi Gerd

I hadn't rebuilt after taking your patch. You had removed a declaration
of bounds, exposing a different one.

Patch attached.

Ticker


On Sat, 2021-01-23 at 10:27 +0000, Gerd Petermann wrote:
> Hi Ticker,
> 
> I used mkgmap r4597  patched with overview-v5.patch on the output of
> splitter with Rankos split command:
> E:\rj-mp-split>java -jar d:\mkgmap\dist\mkgmap.jar 80100004.osm.pbf
> Time started: Sat Jan 23 11:23:51 CET 2021
> Number of MapFailedExceptions: 0
> Exception in thread "main" java.lang.NullPointerException: Cannot
> invoke "uk.me.parabola.imgfmt.app.Area.getMaxDimension()" because
> "detailTileBounds" is null
>         at
> uk.me.parabola.mkgmap.combiners.OverviewBuilder.checkFixRes(OverviewB
> uilder.java:146)
>         at
> uk.me.parabola.mkgmap.combiners.OverviewBuilder.addMapCoverageArea(Ov
> erviewBuilder.java:397)
>         at
> uk.me.parabola.mkgmap.combiners.OverviewBuilder.readFileIntoOverview(
> OverviewBuilder.java:264)
>         at
> uk.me.parabola.mkgmap.combiners.OverviewBuilder.onMapEnd(OverviewBuil
> der.java:89)
>         at uk.me.parabola.mkgmap.main.Main.endOptions(Main.java:649)
>         at
> uk.me.parabola.mkgmap.CommandArgsReader.readArgs(CommandArgsReader.ja
> va:125)
>         at uk.me.parabola.mkgmap.main.Main.mainStart(Main.java:144)
>         at uk.me.parabola.mkgmap.main.Main.main(Main.java:115)
> 
> 
> No such exception with unpatched mkgmap.
> 
> Gerd
> 
> ________________________________________
> Von: mkgmap-dev <mkgmap-dev-boun...@lists.mkgmap.org.uk> im Auftrag
> von Ticker Berkin <rwb-mkg...@jagit.co.uk>
> Gesendet: Samstag, 23. Januar 2021 11:20
> An: Development list for mkgmap
> Betreff: Re: [mkgmap-dev] Tiles pruned in DEM map
> 
> Hi Gerd
> 
> I've just tried this and don't get a problem (with or without -ea)
> 
> I used Ranko's osm.pbf, splitter-r595 and my development mkgmap which
> is trunk + overview patch + couple of trivial changes.
> 
> Where were you getting the exception?
> 
> Ticker
> 
> 
> On Sat, 2021-01-23 at 07:18 +0000, Gerd Petermann wrote:
> > Hi Ticker,
> > 
> > I just got a NullPointerException looking at the example from
> > Ranko.
> > Happens when I create a map without any option, just
> > java -jar mkgmap.jar 80100004.osm.pbf
> > 
> > Gerd
> 
> _______________________________________________
> mkgmap-dev mailing list
> mkgmap-dev@lists.mkgmap.org.uk
> http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
> _______________________________________________
> mkgmap-dev mailing list
> mkgmap-dev@lists.mkgmap.org.uk
> http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Index: src/uk/me/parabola/imgfmt/app/map/Map.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/map/Map.java	(revision 4597)
+++ src/uk/me/parabola/imgfmt/app/map/Map.java	(working copy)
@@ -70,6 +70,7 @@
 	private NETFile netFile;
 	private NODFile nodFile;
 	private DEMFile demFile;
+	private boolean isOverviewCombined;
 
 	// Use createMap() or loadMap() instead of creating a map directly.
 	private Map() {
@@ -89,7 +90,7 @@
 	 * @throws FileNotWritableException If the file cannot
 	 * be opened for write.
 	 */
-	public static Map createMap(String mapname, String outputdir, FileSystemParam params, String mapnumber, Sort sort)
+	public static Map createMap(String mapname, String outputdir, FileSystemParam params, String mapnumber, Sort sort, boolean overviewCombined)
 			throws FileExistsException, FileNotWritableException
 	{
 		Map m = new Map();
@@ -103,6 +104,7 @@
 		m.rgnFile = new RGNFile(m.fileSystem.create(mapnumber + ".RGN"));
 		m.treFile = new TREFile(m.fileSystem.create(mapnumber + ".TRE"));
 		m.lblFile = new LBLFile(m.fileSystem.create(mapnumber + ".LBL"), sort);
+		m.isOverviewCombined = overviewCombined;
 
 		int mapid;
 		try {
@@ -118,8 +120,9 @@
 	}
 
 	public void config(EnhancedProperties props) {
+		boolean isOverviewComponent = OverviewBuilder.isOverviewImg(mapName);
 		// we don't want routing info in the overview map (for now)
-		if (!OverviewBuilder.isOverviewImg(mapName)){
+		if (!isOverviewComponent && !isOverviewCombined) {
 			try {
 				if (props.containsKey("route") || props.containsKey("net") || props.containsKey("housenumbers")) {
 					addNet();
@@ -130,6 +133,11 @@
 			} catch (FileExistsException e) {
 				log.warn("Could not add NET and/or NOD sections");
 			}
+			// this sets things like draw-priority/transparent/custom
+			// and not relevant to overview maps
+			treFile.config(props);
+		}
+		if (!isOverviewComponent) { // allow dem on final overview but not in the ovm_
 			if (props.containsKey("dem")) {
 				try {
 					addDem();
@@ -138,7 +146,6 @@
 				}
 			}
 		}
-		treFile.config(props);
 	}
 
 	private void addNet() throws FileExistsException {
Index: src/uk/me/parabola/mkgmap/build/MapBuilder.java
===================================================================
--- src/uk/me/parabola/mkgmap/build/MapBuilder.java	(revision 4597)
+++ src/uk/me/parabola/mkgmap/build/MapBuilder.java	(working copy)
@@ -74,7 +74,6 @@
 import uk.me.parabola.log.Logger;
 import uk.me.parabola.mkgmap.CommandArgs;
 import uk.me.parabola.mkgmap.Version;
-import uk.me.parabola.mkgmap.combiners.OverviewBuilder;
 import uk.me.parabola.mkgmap.filters.BaseFilter;
 import uk.me.parabola.mkgmap.filters.DouglasPeuckerFilter;
 import uk.me.parabola.mkgmap.filters.FilterConfig;
@@ -127,6 +126,9 @@
 	
 	private static final int MIN_SIZE_LINE = 1;
 
+	private final boolean isOverviewComponent;
+	private final boolean isOverviewCombined;
+
 	private final java.util.Map<MapPoint,POIRecord> poimap = new HashMap<>();
 	private final java.util.Map<MapPoint,City> cityMap = new HashMap<>();
 	private List<String> mapInfo = new ArrayList<>();
@@ -175,10 +177,20 @@
 	private HGTConverter.InterpolationMethod demInterpolationMethod;
 	
 
-	public MapBuilder() {
+	/**
+	 * Construct a new MapBuilder.
+	 * 
+	 * @param overviewComponent set to {@code true} if the map is a work file that
+	 *                          is later used as input for the OverviewBuilder
+	 * @param overviewCombined  set to {@code true} if the map is the combined
+	 *                          overview map
+	 */
+	public MapBuilder(boolean overviewComponent, boolean overviewCombined) {
 		regionName = null;
 		locationAutofill = Collections.emptySet();
 		locator = new Locator();
+		this.isOverviewComponent = overviewComponent;
+		this.isOverviewCombined = overviewCombined;
 	}
 
 	public void config(EnhancedProperties props) {
@@ -218,7 +230,7 @@
 			driveOnLeft = false;
 		orderByDecreasingArea = props.getProperty("order-by-decreasing-area", false);
 		pathsToHGT = props.getProperty("dem", null);
-		demDists = parseDemDists(props.getProperty("dem-dists", "-1"));
+		String demDistStr = props.getProperty("dem-dists", "-1");
 		demOutsidePolygonHeight = (short) props.getProperty("dem-outside-polygon", HGTReader.UNDEF);
 		String demPolygonFile = props.getProperty("dem-poly", null);
 		if (demPolygonFile != null) {
@@ -239,6 +251,18 @@
 			throw new IllegalArgumentException("invalid argument for option dem-interpolation: '" + ipm + 
 					"' supported are 'bilinear', 'bicubic', or 'auto'");
 		}
+
+		if (isOverviewCombined) { // some alternate options, some invalid etc
+			demDistStr = props.getProperty("overview-dem-dist", "-1");
+			mergeLines = true;
+			if (orderByDecreasingArea) {
+				orderByDecreasingArea = false;
+				mergeShapes = false;  // shape order in ovm_ imgs must be preserved to have the effect of above 
+			} else {
+				mergeShapes = true;
+			}
+		}
+		demDists = parseDemDists(demDistStr);
 	}
 
 	private static List<Integer> parseDemDists(String demDists) {
@@ -339,7 +363,7 @@
 					demArea = demPolygon;
 				}
 			} 
-			if (demArea == null && src instanceof OverviewMapDataSource) {
+			if (demArea == null && isOverviewCombined) {
 				Path2D demPoly = ((OverviewMapDataSource) src).getTileAreaPath();
 				if (demPoly != null) {
 					demArea = new java.awt.geom.Area(demPoly);
@@ -732,12 +756,11 @@
 		// The top level has to cover the whole map without subdividing, so
 		// do a special check to make sure.
 		LevelInfo[] levels = null;
-		if (src instanceof OverviewMapDataSource) {
-			mergeLines = true;
-			prepShapesForMerge(src.getShapes());
-			mergeShapes = true;
+		if (isOverviewCombined) {
+			if (mergeShapes)
+				prepShapesForMerge(src.getShapes());
 			levels = src.mapLevels();
-		} else if (OverviewBuilder.isOverviewImg(map.getFilename())) {
+		} else if (isOverviewComponent) {
 			levels = src.overviewMapLevels();
 		} else {
 			levels = src.mapLevels();
@@ -967,7 +990,7 @@
 	private void processInfo(Map map, LoadableMapDataSource src) {
 		// The bounds of the map.
 		map.setBounds(src.getBounds());
-		if (!(src instanceof OverviewMapDataSource))
+		if (!isOverviewCombined)
 			poiDisplayFlags |= TREHeader.POI_FLAG_DETAIL;
 			
 		poiDisplayFlags |= src.getPoiDispFlag();
Index: src/uk/me/parabola/mkgmap/combiners/OverviewBuilder.java
===================================================================
--- src/uk/me/parabola/mkgmap/combiners/OverviewBuilder.java	(revision 4597)
+++ src/uk/me/parabola/mkgmap/combiners/OverviewBuilder.java	(working copy)
@@ -65,8 +65,9 @@
 	private LevelInfo[] wantedLevels;
 	private Area bounds;
 	private boolean hasBackground;
-	private EnhancedProperties demProps = new EnhancedProperties();
-	
+	private EnhancedProperties overviewProps = new EnhancedProperties();
+	private int maxRes = 16; // we can write a 0x4a polygon for planet in res 16.
+
 	public OverviewBuilder() {
 		this.overviewSource = new OverviewMapDataSource();
 	}
@@ -77,13 +78,7 @@
 		overviewMapnumber = args.get("overview-mapnumber", "63240000");
 		
 		outputDir = args.getOutputDir();
-		String demDist = args.getProperties().getProperty("overview-dem-dist");
-		String hgtPath = args.getProperties().getProperty("dem");
-		if (hgtPath != null && demDist != null && !"0".equals(demDist.trim())) {
-			demProps = new EnhancedProperties(args.getProperties());
-			demProps.setProperty("dem-dists", demDist);
-			demProps.setProperty("order-by-decreasing-area", "no");
-		}
+		overviewProps = new EnhancedProperties(args.getProperties());
 	}
 
 	public void onMapEnd(FileInfo finfo) {
@@ -99,7 +94,12 @@
 
 	public void onFinish() {
 		if (!hasBackground) {
+			List<MapShape> shapes = overviewSource.getShapes();
+			int inx = shapes.size();
 			overviewSource.addBackground();
+			// for --order-by-decreasing-area, need the background to be first:
+			if (shapes.size() > inx) // something was added
+				shapes.add(0, shapes.remove(inx));
 		}
 		calcLevels();
 		writeOverviewMap();
@@ -113,31 +113,6 @@
 	}
 
 	private void calcLevels() {
-		int maxRes = 16; // we can write a 0x4a polygon for planet in res 16
-		if (wantedLevels != null)
-			maxRes = wantedLevels[wantedLevels.length-1].getBits();
-		int maxSize = 0xffff << (24 - maxRes);
-		for (MapShape s : overviewSource.getShapes()){
-			if (s.getType() != 0x4a)
-				continue;
-			int maxDimPoly = s.getBounds().getMaxDimension();
-			if (maxDimPoly > maxSize){
-				int oldMaxRes = maxRes; 
-				while (maxDimPoly > maxSize){
-					maxRes--;
-					maxSize = 0xffff << (24 - maxRes);
-				}
-				final String[] name = s.getName().split("\u001d");
-				final String msg = "Tile selection (0x4a) polygon for";
-				final String msg2;
-				if (name.length == 2)
-					msg2 = "tile " + name[1].trim();
-				else 
-					msg2 = s.getBounds().toString(); 
-				log.error(msg, msg2, "cannot be written in level 0 resolution", oldMaxRes + ", using", maxRes, "instead");
-				
-			}
-		}
 		if (wantedLevels == null)
 			setRes(maxRes);
 		else {
@@ -160,6 +135,32 @@
 		}
 	}
 
+ 	/**
+	 * Adjust {@code maxRes} value.
+	 * @param detailTileBounds tile bounds (of ovm_ file)
+	 * @param tileName tile name
+	 */
+	private int checkFixRes(Area detailTileBounds, String tileName) {
+		int newMaxRes = maxRes;
+		int maxSize = 0xffff << (24 - newMaxRes);
+		int maxDimPoly = detailTileBounds.getMaxDimension();
+		if (maxDimPoly > maxSize) {
+			int oldMaxRes = newMaxRes;
+			while (maxDimPoly > maxSize) {
+				newMaxRes--;
+				maxSize = 0xffff << (24 - newMaxRes);
+			}
+			final String msg = "Tile selection (0x4a) polygon for";
+			final String msg2;
+			if (tileName != null)
+				msg2 = "tile " + tileName;
+			else
+				msg2 = detailTileBounds.toString();
+			log.error(msg, msg2, "cannot be written in level 0 resolution", oldMaxRes + ", using", newMaxRes, "instead");
+		}
+		return newMaxRes;
+	}
+
 	/**
 	 * Write out the overview map.
 	 */
@@ -167,7 +168,7 @@
 		if (overviewSource.mapLevels() == null)
 			return;
 		
-		MapBuilder mb = new MapBuilder();
+		MapBuilder mb = new MapBuilder(false, true);
 		mb.setEnableLineCleanFilters(false);
 
 		FileSystemParam params = new FileSystemParam();
@@ -181,12 +182,10 @@
 				codepage = 0; // should not happen
 			}
 			Sort sort = SrtTextReader.sortForCodepage(codepage);
-			Map map = Map.createMap(overviewMapname, outputDir, params, overviewMapnumber, sort);
-			if (!demProps.isEmpty()) {
-				map.config(demProps);
-				mb.config(demProps);
-			}
-			
+			Map map = Map.createMap(overviewMapname, outputDir, params, overviewMapnumber, sort, true);
+			map.config(overviewProps);
+			mb.config(overviewProps);
+
 			if (encodingType != null){
 				map.getLblFile().setEncoder(encodingType, codepage);
 			}
@@ -205,8 +204,6 @@
 	 * @param finfo Information about an individual map.
 	 */
 	private void readFileIntoOverview(FileInfo finfo) throws FileNotFoundException {
-		addMapCoverageArea(finfo);
-
 		MapReader mapReader = null;
 		String filename = finfo.getFilename();
 		if (codepage == null){
@@ -216,7 +213,7 @@
 			System.err.println("WARNING: input file " + filename + " has different code page " + finfo.getCodePage());
 		}
 
-		try{
+		try {
 			mapReader = new MapReader(filename);
 
 			if (encodingType == null){
@@ -262,7 +259,9 @@
 					mapLevels[0] = new LevelInfo(levels[1].getLevel(), levels[1].getResolution());
 				}
 				wantedLevels = mapLevels;
+				maxRes = wantedLevels[wantedLevels.length-1].getBits();
 			}
+			addMapCoverageArea(finfo);
 			if (isOverviewImg(filename)){
 				readPoints(mapReader);
 				readLines(mapReader);
@@ -277,12 +276,11 @@
 
 	/**
 	 * Read the points 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 readPoints(MapReader mapReader) {
-		Area bounds = overviewSource.getBounds();
+		Area sourceBounds = overviewSource.getBounds();
 		Zoom[] levels = mapReader.getLevels();
 		for (int l = 1; l < levels.length; l++){
 			int min = levels[l].getLevel();
@@ -291,7 +289,7 @@
 			for (Point point: pointList) {
 				if (log.isDebugEnabled())
 					log.debug("got point", point);
-				if (!bounds.contains(point.getLocation())){
+				if (!sourceBounds.contains(point.getLocation())){
 					if (log.isDebugEnabled())
 						log.debug(point, "dropped, is outside of tile boundary");
 					continue;
@@ -312,7 +310,6 @@
 
 	/**
 	 * Read the lines 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.
 	 */
@@ -348,7 +345,6 @@
 
 	/**
 	 * 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.
 	 */
@@ -389,6 +385,8 @@
 	 * Add an area that shows the area covered by a detailed map.  This can
 	 * be an arbitary shape, although at the current time we only support
 	 * rectangles.
+	 * Also build up full overview path (not ness. rectangle) for DEM
+	 * and check/decrease resolution if necessary
 	 *
 	 * @param finfo Information about a detail map.
 	 */
@@ -395,9 +393,9 @@
 	private void addMapCoverageArea(FileInfo finfo) {
 		Area bounds = finfo.getBounds();
 		List<Coord> points = bounds.toCoords();
-		for (Coord co: points){
-			overviewSource.addToBounds(co);
-		}
+		points.forEach(overviewSource::addToBounds);
+		overviewSource.addToTileAreaPath(points);
+		maxRes = checkFixRes(bounds, finfo.getMapname());
 		// Create the tile coverage rectangle
 		MapShape bg = new MapShape();
 		bg.setType(0x4a);
@@ -438,7 +436,7 @@
 		String fname = new File(name).getName();
 		if (fname.startsWith(OVERVIEW_PREFIX))
 			return fname.substring(OVERVIEW_PREFIX.length());
-		else return name;
+		return name;
 	}
 	
 	private static List<String> creMsgList(List<String[]> msgs){
Index: src/uk/me/parabola/mkgmap/main/AbstractTestMap.java
===================================================================
--- src/uk/me/parabola/mkgmap/main/AbstractTestMap.java	(revision 4597)
+++ src/uk/me/parabola/mkgmap/main/AbstractTestMap.java	(working copy)
@@ -55,7 +55,7 @@
 
 		Map map;
 		try {
-			map = Map.createMap("32860003", ".", params, "32860003", SrtTextReader.sortForCodepage(1252));
+			map = Map.createMap("32860003", ".", params, "32860003", SrtTextReader.sortForCodepage(1252), false);
 		} catch (FileExistsException e) {
 			throw new ExitException("File exists already", e);
 		} catch (FileNotWritableException e) {
Index: src/uk/me/parabola/mkgmap/main/MapMaker.java
===================================================================
--- src/uk/me/parabola/mkgmap/main/MapMaker.java	(revision 4597)
+++ src/uk/me/parabola/mkgmap/main/MapMaker.java	(working copy)
@@ -94,7 +94,7 @@
 	 *
 	 * @param args User supplied arguments.
 	 * @param src The data source to load.
-	 * @param mapNameExt 
+	 * @param mapNamePrefix prefix for output file (e.g. ovm_ for overview map component files)
 	 * @return The output filename for the map.
 	 */
 	private String makeMap(CommandArgs args, LoadableMapDataSource src, String mapNamePrefix) {
@@ -107,10 +107,10 @@
 		params.setMapDescription(args.getDescription());
 		log.info("Started making", args.getMapname(), "(" + args.getDescription() + ")");
 		try {
-			Map map = Map.createMap(mapNamePrefix + args.getMapname(), args.getOutputDir(), params, args.getMapname(), sort);
+			Map map = Map.createMap(mapNamePrefix + args.getMapname(), args.getOutputDir(), params, args.getMapname(), sort, false);
 			setOptions(map, args);
 
-			MapBuilder builder = new MapBuilder();
+			MapBuilder builder = new MapBuilder(OverviewBuilder.OVERVIEW_PREFIX.equals(mapNamePrefix), false);
 			builder.config(args.getProperties());
 			builder.makeMap(map, src);
 
Index: src/uk/me/parabola/mkgmap/reader/overview/OverviewMapDataSource.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/overview/OverviewMapDataSource.java	(revision 4597)
+++ src/uk/me/parabola/mkgmap/reader/overview/OverviewMapDataSource.java	(working copy)
@@ -55,6 +55,10 @@
 		return tileAreaPath;
 	}
 
+	public void addToTileAreaPath(List<Coord> points) {
+		tileAreaPath.append(Java2DConverter.createPath2D(points), false);
+	}
+
 	/**
 	 * This is a fake source of data and is not read from a file, so always
 	 * return false here.
@@ -158,10 +162,6 @@
 	 */
 	public void addShape(MapShape shape) {
 		mapper.addShape(shape);
-		if (shape.getType() == 0x4a) {
-			tileAreaPath.append(Java2DConverter.createPath2D(shape.getPoints()),false);
-			
-		}
 	}
 
 	public void addRoad(MapRoad road) {
_______________________________________________
mkgmap-dev mailing list
mkgmap-dev@lists.mkgmap.org.uk
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Reply via email to