[Git][debian-gis-team/mkgmap][upstream] New upstream version 0.0.0+svn4193

Bas Couwenberg gitlab at salsa.debian.org
Fri Jun 1 16:48:20 BST 2018


Bas Couwenberg pushed to branch upstream at Debian GIS Project / mkgmap


Commits:
cfb45dd8 by Bas Couwenberg at 2018-06-01T17:41:10+02:00
New upstream version 0.0.0+svn4193
- - - - -


17 changed files:

- resources/mkgmap-version.properties
- src/uk/me/parabola/imgfmt/Utils.java
- src/uk/me/parabola/imgfmt/app/dem/DEMTile.java
- src/uk/me/parabola/imgfmt/app/mdr/Mdr20.java
- src/uk/me/parabola/imgfmt/app/net/RouteCenter.java
- src/uk/me/parabola/imgfmt/app/net/RouteNode.java
- src/uk/me/parabola/imgfmt/app/trergn/RGNFileReader.java
- src/uk/me/parabola/imgfmt/app/trergn/Subdivision.java
- src/uk/me/parabola/imgfmt/app/trergn/TREFileReader.java
- src/uk/me/parabola/imgfmt/app/trergn/TREHeader.java
- src/uk/me/parabola/mkgmap/general/LevelInfo.java
- src/uk/me/parabola/mkgmap/osmstyle/RuleDetails.java
- src/uk/me/parabola/mkgmap/osmstyle/RuleIndex.java
- src/uk/me/parabola/mkgmap/osmstyle/RuleSet.java
- src/uk/me/parabola/mkgmap/reader/hgt/HGTConverter.java
- src/uk/me/parabola/mkgmap/reader/hgt/HGTReader.java
- test/uk/me/parabola/mkgmap/osmstyle/RuleSetTest.java


Changes:

=====================================
resources/mkgmap-version.properties
=====================================
--- a/resources/mkgmap-version.properties
+++ b/resources/mkgmap-version.properties
@@ -1,2 +1,2 @@
-svn.version: 4183
-build.timestamp: 2018-04-28T08:17:17+0100
+svn.version: 4193
+build.timestamp: 2018-05-31T07:29:23+0100


=====================================
src/uk/me/parabola/imgfmt/Utils.java
=====================================
--- a/src/uk/me/parabola/imgfmt/Utils.java
+++ b/src/uk/me/parabola/imgfmt/Utils.java
@@ -28,6 +28,7 @@ import java.util.Calendar;
 import java.util.Date;
 import java.util.zip.GZIPInputStream;
 
+import uk.me.parabola.imgfmt.app.ImgFileWriter;
 import uk.me.parabola.imgfmt.app.Coord;
 /**
  * Some miscellaneous functions that are used within the .img code.
@@ -443,4 +444,12 @@ public class Utils {
 			return 4;
 	}
 
+	public static void put3sLongitude(ImgFileWriter writer, int longitude) {
+		// handle special case, write -180/-8388608 instead of 180/8388608 to avoid assertion
+		if (longitude == Utils.MAX_LON_MAP_UNITS)
+			writer.put3s(Utils.MIN_LON_MAP_UNITS);
+		else
+			writer.put3s(longitude);
+	}
+
 }


=====================================
src/uk/me/parabola/imgfmt/app/dem/DEMTile.java
=====================================
--- a/src/uk/me/parabola/imgfmt/app/dem/DEMTile.java
+++ b/src/uk/me/parabola/imgfmt/app/dem/DEMTile.java
@@ -411,39 +411,49 @@ public class DEMTile {
 		}
 	}
 	
-	/**
-	 * 
-	 * @param oldsum
-	 * @param elemcount
-	 * @param newdata
-	 * @return
-	 */
-	private static int evalSumSpec(int oldsum, int elemcount, int newdata) {
-        /*
-        D < -2 – (ls + 3*k)/2   -1 – ls – k	
-        D < 0 – (ls + k)/2      2*(d + k) + 3	
-        D < 2 – (ls – k)/2      2*d – 1	
-        D < 4 – (ls – 3*k)/2    2*(d – k) - 5	
-                                1 – ls + k	
-      */
-
-		int v = 0;
-
-		if (newdata < -2 - ((oldsum + 3 * elemcount) >> 1)) {
-			v = -1 - oldsum - elemcount;
-		} else if (newdata < -((oldsum + elemcount) >> 1)) {
-			v = 2 * (newdata + elemcount) + 3;
-		} else if (newdata < 2 - ((oldsum - elemcount) >> 1)) {
-			v = 2 * newdata - 1;
-		} else if (newdata < 4 - ((oldsum - 3 * elemcount) >> 1)) {
-			v = 2 * (newdata - elemcount) - 5;
-		} else {
-			v = 1 - oldsum + elemcount;
+	private static int evaluateData(int oldsum, int elemcount, int newdata, int region) {
+		switch (region) {
+		case 0:
+			return -1 - oldsum - elemcount;
+		case 1:
+			return 2 * (newdata + elemcount) + 3;
+		case 2:
+			return 2 * newdata - 1;
+		case 3:
+			return 2 * (newdata - elemcount) - 5;
+		default:
+			return 1 - oldsum + elemcount;
 		}
-//		System.out.println(oldsum + " " + elemcount + " " + newdata + " -> " + v);
-		return v;
 	}
 
+	private static int getEvaluateDataRegion(int oldsum, int elemcount, int newdata) {
+		if (elemcount < 63) {
+			if (newdata < -2 - ((oldsum + 3 * elemcount) >> 1)) {
+				return 0;
+			} else if (newdata < -((oldsum + elemcount) >> 1)) {
+				return 1;
+			} else if (newdata < 2 - ((oldsum - elemcount) >> 1)) {
+				return 2;
+			} else if (newdata < 4 - ((oldsum - 3 * elemcount) >> 1)) {
+				return 3;
+			} else {
+				return 4;
+			}
+		} else {
+			if (newdata < -2 - ((oldsum + 3 * elemcount) >> 1)) {
+				return 0;
+			} else if (newdata < -((oldsum + elemcount) >> 1) - 1) {
+				// special case in if !
+				return 1;
+			} else if (newdata < 2 - ((oldsum - elemcount) >> 1)) {
+				return 2;
+			} else if (newdata < 4 - ((oldsum - 3 * elemcount) >> 1)) {
+				return 3;
+			} else {
+				return 4;
+			}
+		}
+	}
 
 	/**
 	 * This class keeps statistics about the previously encoded values and tries to predict the next value.
@@ -584,36 +594,43 @@ public class DEMTile {
 		
 		private void processVal(int delta1) {
 			if (type == CalcType.CALC_STD) {
-					
 				// calculate threshold sum hybrid 
 				sumH += delta1 > 0 ? delta1 : -delta1;
 				if (sumH + unitDelta  + 1 >= 0xffff)
 					sumH -= 0x10000;
 
 				// calculate threshold sum for length encoding
+				int evalRegion = -1;
 				int workData = delta1;
 				if (elemCount == 63) {
-					// special case
-					if (sumL > 0) { // pos. SumL
-						if ((sumL + 1) % 4 == 0) {
-							if (workData % 2 != 0)
-								workData--;
-						} else {
-							if (workData % 2 == 0)
-								workData--;
+					evalRegion = getEvaluateDataRegion(sumL, elemCount, delta1);
+					boolean datagerade = delta1 % 2 == 0;
+					boolean sumL1 = (sumL - 1) % 4 == 0;
+
+					switch (evalRegion) {
+					case 0:
+					case 2:
+					case 4:
+						if ((sumL1 && !datagerade) || (!sumL1 && datagerade)) {
+							workData++;
 						}
-
-					} else { // neg. SumL
-						if ((sumL - 1) % 4 == 0) {
-							if (workData % 2 != 0)
-								workData++;
-						} else {
-							if (workData % 2 == 0)
-								workData++;
+						break;
+					case 1:
+						workData++;
+						if ((sumL1 && !datagerade) || (!sumL1 && datagerade)) {
+							workData++;
 						}
+						break;
+					case 3:
+						if ((sumL1 && datagerade) || (!sumL1 && !datagerade)) {
+							workData--;
+						}
+						break;
 					}
 				}
-				int eval = evalSumSpec(sumL, elemCount, workData);
+				if (evalRegion < 0)
+					evalRegion = getEvaluateDataRegion(sumL, elemCount, workData);
+				int eval = evaluateData(sumL, elemCount, workData, evalRegion);
 				sumL += eval;
 
 				// now update elem counter
@@ -624,9 +641,6 @@ public class DEMTile {
 					sumH = ((sumH - unitDelta) >> 1) - 1;
 					
 					sumL /= 2;
-					if (sumL % 2 != 0) {
-						sumL++;
-					}
 				}
 
 				// calculate new hunit


=====================================
src/uk/me/parabola/imgfmt/app/mdr/Mdr20.java
=====================================
--- a/src/uk/me/parabola/imgfmt/app/mdr/Mdr20.java
+++ b/src/uk/me/parabola/imgfmt/app/mdr/Mdr20.java
@@ -72,7 +72,7 @@ public class Mdr20 extends Mdr2x {
 			boolean citySameByName = lastCity != null && city.getMdr20SortPos() == lastCity.getMdr20SortPos();
 			int rr = street.checkRepeat(lastStreet, collator);
 			// Only save a single copy of each street name.
-			if (!citySameByName || rr != 3) {
+			if (!citySameByName || rr != 3 || lastStreet.getIndex() != street.getIndex()) {
 				record++;
 				streets.add(street);
 			}


=====================================
src/uk/me/parabola/imgfmt/app/net/RouteCenter.java
=====================================
--- a/src/uk/me/parabola/imgfmt/app/net/RouteCenter.java
+++ b/src/uk/me/parabola/imgfmt/app/net/RouteCenter.java
@@ -16,6 +16,7 @@ package uk.me.parabola.imgfmt.app.net;
 
 import java.util.List;
 
+import uk.me.parabola.imgfmt.Utils;
 import uk.me.parabola.imgfmt.app.Area;
 import uk.me.parabola.imgfmt.app.Coord;
 import uk.me.parabola.imgfmt.app.ImgFileWriter;
@@ -134,7 +135,7 @@ public class RouteCenter {
 
 		// Write the tables header
 		writer.put1u(tabC.getFormat());
-		writer.put3s(centralPoint.getLongitude());
+		Utils.put3sLongitude(writer, centralPoint.getLongitude());
 		writer.put3s(centralPoint.getLatitude());
 		writer.put1u(tabA.getNumberOfItems());
 		writer.put1u(tabB.getNumberOfItems());


=====================================
src/uk/me/parabola/imgfmt/app/net/RouteNode.java
=====================================
--- a/src/uk/me/parabola/imgfmt/app/net/RouteNode.java
+++ b/src/uk/me/parabola/imgfmt/app/net/RouteNode.java
@@ -20,6 +20,8 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+
+import uk.me.parabola.imgfmt.Utils;
 import uk.me.parabola.imgfmt.app.Coord;
 import uk.me.parabola.imgfmt.app.CoordNode;
 import uk.me.parabola.imgfmt.app.ImgFileWriter;
@@ -253,7 +255,7 @@ public class RouteNode implements Comparable<RouteNode> {
 	public void writeNod3OrNod4(ImgFileWriter writer) {
 		assert isBoundary() : "trying to write nod3 for non-boundary node";
 
-		writer.put3s(coord.getLongitude());
+		Utils.put3sLongitude(writer, coord.getLongitude());
 		writer.put3s(coord.getLatitude()); 
 		writer.put3u(offsetNod1);
 	}


=====================================
src/uk/me/parabola/imgfmt/app/trergn/RGNFileReader.java
=====================================
--- a/src/uk/me/parabola/imgfmt/app/trergn/RGNFileReader.java
+++ b/src/uk/me/parabola/imgfmt/app/trergn/RGNFileReader.java
@@ -152,8 +152,8 @@ public class RGNFileReader extends ImgReader {
 			Point p = new Point(sd);
 
 			int type = reader.get1u() << 8;
-			byte b = reader.get();
-			type |= 0x10000  +  (b & 0x1f);
+			int b = reader.get1u();
+			type |= 0x10000 + (b & 0x1f);
 			p.setType(type);
 			p.setDeltaLong(reader.get2s());
 			p.setDeltaLat(reader.get2s());
@@ -262,7 +262,7 @@ public class RGNFileReader extends ImgReader {
 	 * @param line The line or shape that is to be populated.
 	 */
 	private void readLineCommon(ImgFileReader reader, Subdivision div, Polyline line) {
-		byte type = reader.get();
+		int type = reader.get1u();
 		if (line instanceof Polygon)
 			line.setType(type & 0x7f);
 		else {
@@ -293,7 +293,7 @@ public class RGNFileReader extends ImgReader {
 		else
 			len = reader.get2u();
 
-		int base = reader.get();
+		int base = reader.get1u();
 
 		byte[] bitstream = reader.get(len);
 		BitReader br = new BitReader(bitstream);
@@ -309,12 +309,11 @@ public class RGNFileReader extends ImgReader {
 	 * @param line The line or shape that is to be populated.
 	 */
 	private void readLineCommonExtType(ImgFileReader reader, Subdivision div, Polyline line) {
-		int type = reader.get1u();
-		type <<= 8;
+		int type = reader.get1u() << 8;
 		int b1 = reader.get1u();
 		boolean hasExtraBytes = (b1 & 0x80) != 0;
 		boolean hasLabel = (b1 & 0x20) != 0;
-		type |= 0x10000  + (b1 & 0x1f);
+		type |= 0x10000 + (b1 & 0x1f);
 		line.setType(type);
 		line.setDeltaLong(reader.get2s());
 		line.setDeltaLat(reader.get2s());


=====================================
src/uk/me/parabola/imgfmt/app/trergn/Subdivision.java
=====================================
--- a/src/uk/me/parabola/imgfmt/app/trergn/Subdivision.java
+++ b/src/uk/me/parabola/imgfmt/app/trergn/Subdivision.java
@@ -269,7 +269,7 @@ public class Subdivision {
 		log.debug("write subdiv", latitude, longitude);
 		file.put3u(startRgnPointer);
 		file.put1u(getType());
-		file.put3s(longitude);
+		Utils.put3sLongitude(file, longitude);
 		file.put3s(latitude);
 		
 		assert width <= 0x7fff;


=====================================
src/uk/me/parabola/imgfmt/app/trergn/TREFileReader.java
=====================================
--- a/src/uk/me/parabola/imgfmt/app/trergn/TREFileReader.java
+++ b/src/uk/me/parabola/imgfmt/app/trergn/TREFileReader.java
@@ -228,7 +228,7 @@ public class TREFileReader extends ImgReader {
 		long pos = sect.getPosition();
 		while (pos < sect.getEndPos()) {
 			reader.position(pos);
-			int offset = reader.get3s();
+			int offset = reader.get3u();
 			Label label = lblReader.fetchLabel(offset);
 			if (label != null) {
 				msgs.add(label.getText());


=====================================
src/uk/me/parabola/imgfmt/app/trergn/TREHeader.java
=====================================
--- a/src/uk/me/parabola/imgfmt/app/trergn/TREHeader.java
+++ b/src/uk/me/parabola/imgfmt/app/trergn/TREHeader.java
@@ -163,13 +163,9 @@ public class TREHeader extends CommonHeader {
 	 */
 	protected void writeFileHeader(ImgFileWriter writer) {
 		writer.put3s(area.getMaxLat());
-		// handle special case, write -180 instead of 180 to avoid assertion
-		if (area.getMaxLong() == Utils.MAX_LON_MAP_UNITS)
-			writer.put3s(Utils.MIN_LON_MAP_UNITS);
-		else
-			writer.put3s(area.getMaxLong());
+		Utils.put3sLongitude(writer, area.getMaxLong());
 		writer.put3s(area.getMinLat());
-		writer.put3s(area.getMinLong());
+		writer.put3s(area.getMinLong());  // minLong cant be +180
 
 		writer.put4(getMapLevelsPos());
 		writer.put4(getMapLevelsSize());


=====================================
src/uk/me/parabola/mkgmap/general/LevelInfo.java
=====================================
--- a/src/uk/me/parabola/mkgmap/general/LevelInfo.java
+++ b/src/uk/me/parabola/mkgmap/general/LevelInfo.java
@@ -70,7 +70,7 @@ public class LevelInfo implements Comparable<LevelInfo> {
 				if (key < 0 || key > 16)
 					throw new ExitException("Error: Level value out of range 0-16: " + s + " in levels specification " + levelSpec);
 				int value = Integer.parseInt(keyVal[1]);
-				if (value <= 0 || value > 24)
+				if (value < 0 || value > 24)
 					throw new ExitException("Error: Resolution value out of range 0-24: " + s + " in levels specification " + levelSpec);
 				levels[count] = new LevelInfo(key, value);
 			} catch (NumberFormatException e) {


=====================================
src/uk/me/parabola/mkgmap/osmstyle/RuleDetails.java
=====================================
--- a/src/uk/me/parabola/mkgmap/osmstyle/RuleDetails.java
+++ b/src/uk/me/parabola/mkgmap/osmstyle/RuleDetails.java
@@ -42,4 +42,9 @@ class RuleDetails {
 	public Set<String> getChangingTags() {
 		return changingTags;
 	}
+	
+	@Override
+	public String toString() {
+		return "keystring=\"" + keystring + "\" " + rule.toString();
+	}
 }


=====================================
src/uk/me/parabola/mkgmap/osmstyle/RuleIndex.java
=====================================
--- a/src/uk/me/parabola/mkgmap/osmstyle/RuleIndex.java
+++ b/src/uk/me/parabola/mkgmap/osmstyle/RuleIndex.java
@@ -15,19 +15,19 @@ package uk.me.parabola.mkgmap.osmstyle;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.BitSet;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Optional;
 import java.util.Set;
 
 import uk.me.parabola.mkgmap.osmstyle.eval.Op;
 import uk.me.parabola.mkgmap.reader.osm.Rule;
 import uk.me.parabola.mkgmap.reader.osm.TagDict;
-import uk.me.parabola.util.MultiHashMap;
 
 /**
  * An index to reduce the number of rules that have to be executed.
@@ -72,21 +72,21 @@ public class RuleIndex {
 	private boolean inited;
 
 	private class TagHelper{
-		// This is an index of all rules that start with EXISTS (A=*) or (A=B)
-		final BitSet checked;
+		// This is an index of all rules that start with EXISTS (A=*)
+		final BitSet exists;
 		// This is an index of all rules that start with EQUALS (A=B) 
 		Map<String, BitSet> tagVals;
 		
-		public TagHelper(BitSet checked){
-			this.checked = checked;
+		public TagHelper(BitSet exits){
+			this.exists = exits;
 		}
 
 		public void addTag(String val, BitSet value) {
 			if (tagVals == null)
 				tagVals = new HashMap<>();
-			if (checked != null){	
+			if (exists != null){	
 				BitSet merged = new BitSet();
-				merged.or(checked);
+				merged.or(exists);
 				merged.or(value);
 				tagVals.put(val, merged);
 			} else
@@ -100,8 +100,8 @@ public class RuleIndex {
 					return (BitSet) set.clone();
 				}
 			} 
-			if (checked != null)
-				return (BitSet) checked.clone();
+			if (exists != null)
+				return (BitSet) exists.clone();
 			return new BitSet();
 		}
 	}
@@ -163,23 +163,14 @@ public class RuleIndex {
 	public void prepare() {
 		if (inited)
 			return;
+		// This is an index of all rules that start with EXISTS (A=*)
+		Map<String, BitSet> existKeys = new HashMap<String, BitSet>();
 		// This is an index of all rules that start with EQUALS (A=B)
 		Map<String, BitSet> tagVals = new HashMap<String, BitSet>();
 		
 		// This is an index of all rules by the tag name (A).
 		Map<String, BitSet> tagnames = new HashMap<String, BitSet>();
 
-		// Maps a rule number to the tags that might be changed by that rule
-		Map<Integer, List<String>> changeTags = new HashMap<Integer, List<String>>();
-		
-		// Collection of possibly changed or added tags were the new value is
-		// NOT known (e.g. set x=$y)
-		Set<String> modOrAddedTagKeys = new HashSet<>();
-
-		// Collection of possibly changed or added tags were the new value is
-		// known (e.g. set x=1)
-		MultiHashMap<String, String> modOrAddedTags = new MultiHashMap<>();
-
 		// remove unnecessary rules
 		filterRules();
 
@@ -187,99 +178,78 @@ public class RuleIndex {
 			int ruleNumber = i;
 			RuleDetails rd = ruleDetails.get(i);
 			String keystring = rd.getKeystring();
-			Set<String> changeableTags = rd.getChangingTags();
 
 			if (keystring.endsWith("=*")) {
 				String key = keystring.substring(0, keystring.length() - 2);
+				addNumberToMap(existKeys, key, ruleNumber);
 				addNumberToMap(tagnames, key, ruleNumber);
 			} else {
 				addNumberToMap(tagVals, keystring, ruleNumber);
-				// check if any of the previous rules may have changed the tag
 				int ind = keystring.indexOf('=');
-				assert ind >= 0 : "rule index: error in keystring " + keystring; 
-				String key = keystring.substring(0, ind);
-				boolean needed = (modOrAddedTagKeys.contains(key));
-				if (!needed) {
-					List<String> values = modOrAddedTags.get(key);
-					if (values.contains(keystring.substring(ind + 1)))
-						needed = true;
-				}
-				if (needed) {
+				if (ind >= 0) {
+					String key = keystring.substring(0, ind);
 					addNumberToMap(tagnames, key, ruleNumber);
+				} else {
+					assert false: "rule index: no = in keystring " + keystring;	
 				}
 			}
-			addChangables(changeTags, changeableTags, ruleNumber);
-			for (String ent : changeableTags) {
-				int ind = ent.indexOf('=');
+		}
+		
+		// find the additional rules which might be triggered as a result of actions changing tags.
+		Map<Integer, BitSet> additionalRules = new LinkedHashMap<>();
+		for (int i = 0; i < ruleDetails.size(); i++) {
+			int ruleNumber = i;
+			RuleDetails rd = ruleDetails.get(i);
+			final Set<String> changeableTags = rd.getChangingTags();
+			BitSet addedRules = new BitSet();
+			for (String s : changeableTags) {
+				int ind = s.indexOf('=');
 				if (ind >= 0) {
-					modOrAddedTags.add(ent.substring(0, ind), ent.substring(ind + 1));
+					BitSet set = tagVals.get(s);
+					if (set != null) {
+						addedRules.or(set);
+					}
+
+					// Exists rules can also be triggered, so add them too.
+					String key = s.substring(0, ind);
+					BitSet set1 = existKeys.get(key);
+					if (set1 != null) {
+						addedRules.or(set1);
+					}
 				} else {
-					modOrAddedTagKeys.add(ent);
+					BitSet set = tagnames.get(s);
+					if (set != null)
+						addedRules.or(set);
 				}
 			}
+			// Only rules after the current one can be affected 
+			addedRules.clear(0, ruleNumber);
+			if (!addedRules.isEmpty()) {
+				additionalRules.put(ruleNumber, addedRules);
+			}
 		}
 		
-		for (Map.Entry<Integer, List<String>> ent : changeTags.entrySet()) {
-			int ruleNumber = ent.getKey();
-			List<String> changeTagList = ent.getValue();
-
-			// When we add new rules, we may, in turn get more changeable tags
-			// which will force us to run again to find more rules that could
-			// be executed.  So save rules that we find here.
-			Set<String> newChanged = new HashSet<String>(changeTagList);
-			// we have to find all rules that might be now matched
-			do {
-				for (String s : new ArrayList<String>(newChanged)) {
-					BitSet set;
-
-					// If we know the value that could be set, then we can restrict to
-					// rules that would match that value.  Otherwise we look for any
-					// rule using the tag, no matter what the value.
-					int ind = s.indexOf('=');
-					if (ind >= 0) {
-						String key = s.substring(0, ind);
-						set = tagnames.get(key);
-					} else {
-						set = tagnames.get(s);
-					}
-
-					if (set != null && !set.isEmpty()) {
-						// create copy that can be safely modified
-						BitSet tmp  = new BitSet();
-						tmp.or(set);
-						set = tmp;
-						
-						for (int i = set.nextSetBit(0); i >= 0; i = set.nextSetBit(i + 1)) {
-							// Only rules after this one can be affected
-							if (i > ruleNumber) {
-								newChanged.addAll(ruleDetails.get(i).getChangingTags());
-							} else {
-								set.clear(i);
-							}
-						}
-
-						// Find every rule number set that contains the rule number that we
-						// are examining and add all the newly found rules to each such set.
-						for (Map<String, BitSet> m : Arrays.asList(tagVals, tagnames)) {
-							Collection<BitSet> bitSets = m.values();
-							for (BitSet bi : bitSets) {
-								if (bi.get(ruleNumber)) {
-									// contains the rule that we are looking at so we must
-									// also add the rules in the set we found.
-									bi.or(set);
-								}
-							}
-						}
+		// now add all the additional rules to the existing sets
+		for (Entry<Integer, BitSet> e : additionalRules.entrySet()) {
+			int ruleNumber = e.getKey();
+			BitSet addSet = e.getValue();
+			// Find every rule number set that contains the rule number that we
+			// are examining and add all the newly found rules to each such set.
+			for (Map<String, BitSet> m : Arrays.asList(existKeys, tagVals, tagnames)) {
+				for (Entry<String, BitSet> e2 : m.entrySet()) {
+					BitSet bi = e2.getValue();
+					if (bi.get(ruleNumber)) {
+						// contains the rule that we are looking at so we must
+						// also add the rules in the set we found.
+						bi.or(addSet);
 					}
 				}
-
-				newChanged.removeAll(changeTagList);
-				changeTagList.addAll(newChanged);
-			} while (!newChanged.isEmpty());
+			}
+			
 		}
-
+		
 		// compress the index: create one hash map with one entry for each key
-		for (Map.Entry<String, BitSet> entry  : tagnames.entrySet()){
+		for (Map.Entry<String, BitSet> entry  : existKeys.entrySet()){
 			Short skey = TagDict.getInstance().xlate(entry.getKey());
 			tagKeyMap.put(skey, new TagHelper(entry.getValue()));
 		}
@@ -374,25 +344,6 @@ public class RuleIndex {
 		set.set(ruleNumber);
 	}
 
-	/**
-	 * For each rule number, we maintain a list of tags that might be
-	 * changed by that rule.
-	 * @param changeTags 
-	 * @param changeableTags The tags that might be changed if the rule is
-	 * matched.
-	 * @param ruleNumber The rule number.
-	 */
-	private static void addChangables(Map<Integer, List<String>> changeTags, Set<String> changeableTags, int ruleNumber) {
-		if(changeableTags.isEmpty())
-			return;
-		List<String> tags = changeTags.get(ruleNumber);
-		if (tags == null) {
-			tags = new ArrayList<String>();
-			changeTags.put(ruleNumber, tags);
-		}
-		tags.addAll(changeableTags);
-	}
-
 	public List<RuleDetails> getRuleDetails() {
 		return ruleDetails;
 	}


=====================================
src/uk/me/parabola/mkgmap/osmstyle/RuleSet.java
=====================================
--- a/src/uk/me/parabola/mkgmap/osmstyle/RuleSet.java
+++ b/src/uk/me/parabola/mkgmap/osmstyle/RuleSet.java
@@ -307,5 +307,20 @@ public class RuleSet implements Rule, Iterable<Rule> {
 		return false;
 	}
 
+	public BitSet getRules(Element el) {
+		if (!compiled || cacheId == Integer.MAX_VALUE)
+			compile();
+		// new element, invalidate all caches
+		cacheId++;
+
+		// Get all the rules that could match from the index.  
+		BitSet candidates = new BitSet();
+		for (Entry<Short, String> tagEntry : el.getFastTagEntryIterator()) {
+			BitSet rules = index.getRulesForTag(tagEntry.getKey(), tagEntry.getValue());
+			if (rules != null && !rules.isEmpty() )
+				candidates.or(rules);
+		}
+		return candidates;
+	}
 	
 } 


=====================================
src/uk/me/parabola/mkgmap/reader/hgt/HGTConverter.java
=====================================
--- a/src/uk/me/parabola/mkgmap/reader/hgt/HGTConverter.java
+++ b/src/uk/me/parabola/mkgmap/reader/hgt/HGTConverter.java
@@ -39,13 +39,14 @@ public class HGTConverter {
 	private int pointsDistanceLat;
 	private int pointsDistanceLon;
 	private boolean useComplexInterpolation;
-	private double[][] eleArray;  
+	private final double[][] eleArray = new double[4][4];
 	private int statPoints;
 	private int statBicubic;
 	private int statBilinear;
 	private int statVoid;
 	private int statRdrNull;
 	private int statRdrRes;
+	
 	private InterpolationMethod interpolationMethod = InterpolationMethod.Bicubic;
 
 	public enum InterpolationMethod {
@@ -146,8 +147,8 @@ public class HGTConverter {
 		statPoints++;
 		if (useComplexInterpolation) {
 			// bicubic (Catmull-Rom) interpolation with 16 points
-			eleArray = fillArray(rdr, row, col, xLeft, yBottom);
-			if (eleArray != null) {
+			boolean filled = fillArray(rdr, row, col, xLeft, yBottom);
+			if (filled) {
 				h = (short) Math.round(bicubicInterpolation(eleArray, qx, qy));
 				statBicubic++;
 			}
@@ -181,7 +182,7 @@ public class HGTConverter {
 	 * Fill 16 values of HGT near required coordinates
 	 * can use HGTreaders near the current one
 	 */
-	private double[][] fillArray(HGTReader rdr, int row, int col, int xLeft, int yBottom) {
+	private boolean fillArray(HGTReader rdr, int row, int col, int xLeft, int yBottom) {
 		int res = rdr.getRes();
 		int minX = 0;
 		int minY = 0;
@@ -192,62 +193,61 @@ public class HGTConverter {
 		// check borders
 		if (xLeft == 0) {
 			if (col <= 0)
-				return null;
+				return false;
 			minX = 1;
 			inside = false;
 		} else if (xLeft == res - 1) {
 			if (col + 1 >= readers[0].length)
-				return null;
+				return false;
 			maxX = 2;
 			inside = false;
 		}
 		if (yBottom == 0) {
 			if (row <= 0)
-				return null;
+				return false;
 			minY = 1;
 			inside = false;
 		} else if (yBottom == res - 1) {
 			if (row + 1 >= readers.length)
-				return null;
+				return false;
 			maxY = 2;
 			inside = false;
 		}
 
 		// fill data from current reader
-		double[][] eleArray = new double[4][4];
 		short h;
 		for (int x = minX; x <= maxX; x++) {
 			for (int y = minY; y <= maxY; y++) {
 				h = rdr.ele(xLeft + x - 1, yBottom + y - 1);
 				if (h == HGTReader.UNDEF)
-					return null;
+					return false;
 				eleArray[x][y] = h;
 			}
 		}
 
 		if (inside) // no need to check borders again
-			return eleArray;
+			return true;
 
 		// fill data from adjacent readers, down and up
 		if (xLeft > 0 && xLeft < res - 1) {
 			if (yBottom == 0) { // bottom edge
 				HGTReader rdrBB = prepReader(res, row - 1, col);
 				if (rdrBB == null)
-					return null;
+					return false;
 				for (int x = 0; x <= 3; x++) {
 					h = rdrBB.ele(xLeft + x - 1, res - 1);
 					if (h == HGTReader.UNDEF)
-						return null;
+						return false;
 					eleArray[x][0] = h;
 				}
 			} else if (yBottom == res - 1) { // top edge
 				HGTReader rdrTT = prepReader(res, row + 1, col);
 				if (rdrTT == null)
-					return null;
+					return false;
 				for (int x = 0; x <= 3; x++) {
 					h = rdrTT.ele(xLeft + x - 1, 1);
 					if (h == HGTReader.UNDEF)
-						return null;
+						return false;
 					eleArray[x][3] = h;
 				}
 			}
@@ -258,21 +258,21 @@ public class HGTConverter {
 			if (xLeft == 0) { // left edgge
 				HGTReader rdrLL = prepReader(res, row, col - 1);
 				if (rdrLL == null)
-					return null;
+					return false;
 				for (int y = 0; y <= 3; y++) {
 					h = rdrLL.ele(res - 1, yBottom + y - 1);
 					if (h == HGTReader.UNDEF)
-						return null;
+						return false;
 					eleArray[0][y] = h;
 				}
 			} else if (xLeft == res - 1) { // right edge
 				HGTReader rdrRR = prepReader(res, row, col + 1);
 				if (rdrRR == null)
-					return null;
+					return false;
 				for (int y = 0; y <= 3; y++) {
 					h = rdrRR.ele(1, yBottom + y - 1);
 					if (h == HGTReader.UNDEF)
-						return null;
+						return false;
 					eleArray[3][y] = h;
 				}
 			}
@@ -283,122 +283,122 @@ public class HGTConverter {
 			if (yBottom == 0) { // left bottom corner
 				HGTReader rdrLL = prepReader(res, row, col - 1);
 				if (rdrLL == null)
-					return null;
+					return false;
 				for (int y = 1; y <= 3; y++) {
 					h = rdrLL.ele(res - 1, yBottom + y - 1);
 					if (h == HGTReader.UNDEF)
-						return null;
+						return false;
 					eleArray[0][y] = h;
 				}
 
 				HGTReader rdrBB = prepReader(res, row - 1, col);
 				if (rdrBB == null)
-					return null;
+					return false;
 				for (int x = 1; x <= 3; x++) {
 					h = rdrBB.ele(xLeft + x - 1, res - 1);
 					if (h == HGTReader.UNDEF)
-						return null;
+						return false;
 					eleArray[x][0] = h;
 				}
 
 				HGTReader rdrLB = prepReader(res, row - 1, col - 1);
 				if (rdrLB == null)
-					return null;
+					return false;
 				h = rdrLB.ele(res - 1, res - 1);
 				if (h == HGTReader.UNDEF)
-					return null;
+					return false;
 				eleArray[0][0] = h;
 			} else if (yBottom == res - 1) { // left top corner
 				HGTReader rdrLL = prepReader(res, row, col - 1);
 				if (rdrLL == null)
-					return null;
+					return false;
 				for (int y = 0; y <= 2; y++) {
 					h = rdrLL.ele(res - 1, yBottom + y - 1);
 					if (h == HGTReader.UNDEF)
-						return null;
+						return false;
 					eleArray[0][y] = h;
 				}
 
 				HGTReader rdrTT = prepReader(res, row + 1, col);
 				if (rdrTT == null)
-					return null;
+					return false;
 				for (int x = 1; x <= 3; x++) {
 					h = rdrTT.ele(xLeft + x - 1, 1);
 					if (h == HGTReader.UNDEF)
-						return null;
+						return false;
 					eleArray[x][3] = h;
 				}
 
 				HGTReader rdrLT = prepReader(res, row + 1, col - 1);
 				if (rdrLT == null)
-					return null;
+					return false;
 				h = rdrLT.ele(res - 1, 1);
 				if (h == HGTReader.UNDEF)
-					return null;
+					return false;
 				eleArray[0][3] = h;
 			}
 		} else if (xLeft == res - 1) {
 			if (yBottom == 0) { // right bottom corner
 				HGTReader rdrRR = prepReader(res, row, col + 1);
 				if (rdrRR == null)
-					return null;
+					return false;
 				for (int y = 1; y <= 3; y++) {
 					h = rdrRR.ele(1, yBottom + y - 1);
 					if (h == HGTReader.UNDEF)
-						return null;
+						return false;
 					eleArray[3][y] = h;
 				}
 
 				HGTReader rdrBB = prepReader(res, row - 1, col);
 				if (rdrBB == null)
-					return null;
+					return false;
 				for (int x = 0; x <= 2; x++) {
 					h = rdrBB.ele(xLeft + x - 1, res - 1);
 					if (h == HGTReader.UNDEF)
-						return null;
+						return false;
 					eleArray[x][0] = h;
 				}
 
 				HGTReader rdrRB = prepReader(res, row - 1, col + 1);
 				if (rdrRB == null)
-					return null;
+					return false;
 				h = rdrRB.ele(1, res - 1);
 				if (h == HGTReader.UNDEF)
-					return null;
+					return false;
 				eleArray[3][0] = h;
 			} else if (yBottom == res - 1) { // right top corner
 				HGTReader rdrRR = prepReader(res, row, col + 1);
 				if (rdrRR == null)
-					return null;
+					return false;
 				for (int y = 0; y <= 2; y++) {
 					h = rdrRR.ele(1, yBottom + y - 1);
 					if (h == HGTReader.UNDEF)
-						return null;
+						return false;
 					eleArray[3][y] = h;
 				}
 
 				HGTReader rdrTT = prepReader(res, row + 1, col);
 				if (rdrTT == null)
-					return null;
+					return false;
 				for (int x = 0; x <= 2; x++) {
 					h = rdrTT.ele(xLeft + x - 1, 1);
 					if (h == HGTReader.UNDEF)
-						return null;
+						return false;
 					eleArray[x][3] = h;
 				}
 
 				HGTReader rdrRT = prepReader(res, row + 1, col + 1);
 				if (rdrRT == null)
-					return null;
+					return false;
 				h = rdrRT.ele(1, 1);
 				if (h == HGTReader.UNDEF)
-					return null;
+					return false;
 				eleArray[3][3] = h;
 			}
 		}
 
 		// all 16 values present
-		return eleArray;
+		return true;
 	}
 
 	/**
@@ -665,13 +665,13 @@ public class HGTConverter {
 	 * @param qy value from 0 .. 1 gives relative y position in matrix
 	 */
 	private static double bicubicInterpolation(double[][] p, double qx, double qy) {
-		double[] arr = new double[4];
+		final double[] arr = new double[4];
 
-			arr[0] = cubicInterpolation(p[0], qy);
-			arr[1] = cubicInterpolation(p[1], qy);
-			arr[2] = cubicInterpolation(p[2], qy);
-			arr[3] = cubicInterpolation(p[3], qy);
-			return cubicInterpolation(arr, qx);
+		arr[0] = cubicInterpolation(p[0], qy);
+		arr[1] = cubicInterpolation(p[1], qy);
+		arr[2] = cubicInterpolation(p[2], qy);
+		arr[3] = cubicInterpolation(p[3], qy);
+		return cubicInterpolation(arr, qx);
 	}
 
 }


=====================================
src/uk/me/parabola/mkgmap/reader/hgt/HGTReader.java
=====================================
--- a/src/uk/me/parabola/mkgmap/reader/hgt/HGTReader.java
+++ b/src/uk/me/parabola/mkgmap/reader/hgt/HGTReader.java
@@ -171,12 +171,14 @@ public class HGTReader {
 	 * @param name wanted file
 	 */
 	private void checkZip(String fName, String name) {
-		try(ZipFile zipFile = new ZipFile(fName)){
+		File f = new File(fName);
+		if (!f.exists())
+			return;
+		try(ZipFile zipFile = new ZipFile(f)){
 			ZipEntry entry = findZipEntry(zipFile, name);
 			if (entry != null){
 				res = calcRes(entry.getSize(), entry.getName());
 			}
-		} catch (FileNotFoundException e) {
 		} catch (IOException exp) {
 			log.error("failed to get size for file", name, "from", fName);
 		}


=====================================
test/uk/me/parabola/mkgmap/osmstyle/RuleSetTest.java
=====================================
--- a/test/uk/me/parabola/mkgmap/osmstyle/RuleSetTest.java
+++ b/test/uk/me/parabola/mkgmap/osmstyle/RuleSetTest.java
@@ -14,6 +14,7 @@
 package uk.me.parabola.mkgmap.osmstyle;
 
 import java.util.ArrayList;
+import java.util.BitSet;
 import java.util.List;
 
 import uk.me.parabola.mkgmap.reader.osm.Element;
@@ -367,6 +368,33 @@ public class RuleSetTest {
 		assertEquals("first element", 0x1f, list.get(0).getType());
 	}
 	
+	@Test
+	public void testIndexWithOddOrder() {
+		RuleSet rs = makeRuleSet("a=* {set b=1}" +
+				"b=1 {set c=1}" +
+				"d=2 {set c=2}" + 
+				"c=* {set a=2}" +
+				"c=1 {set d=2}" +
+				"c=2 {set d=1}" +
+				"d=1 [0x10401 resolution 24]" + 
+				"d=2 [0x10402 resolution 24]" 
+		);
+		
+		Way el = new Way(1);
+		el.addTag("a", "1");
+		
+		BitSet candidates = rs.getRules(el);
+		BitSet expected = new BitSet();
+		expected.flip(0,8);
+		expected.clear(2);
+		expected.clear(5);
+		expected.clear(6);
+		assertEquals("candidates", expected, candidates);
+		List<GType> list = resolveList(rs, el);
+		assertEquals("first element", 0x10402, list.get(0).getType());
+		
+	}
+	
 	private List<GType> resolveList(RuleSet rs, Way el) {
 		final List<GType> list = new ArrayList<GType>();
 		rs.resolveType(el, new TypeResult() {



View it on GitLab: https://salsa.debian.org/debian-gis-team/mkgmap/commit/cfb45dd8707b51e133a00812d173e3a90739cf68

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/mkgmap/commit/cfb45dd8707b51e133a00812d173e3a90739cf68
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/20180601/9ab049fe/attachment-0001.html>


More information about the Pkg-grass-devel mailing list