Hi Gerd

Here is the patch based on the current trunk

Ticker
On Tue, 2019-04-23 at 11:51 +0100, Ticker Berkin wrote:
> Hi
> 
> I think the mkgmap internal handling of types/subtypes of points is
> obscure.
> 
> In the points style file, the type code is always full, ie type << 8
> |
> subtype, but when the points are read back from the RGN file for the
> MDR processing, the representation is the same provided the subtype
> is
> not zero, otherwise it is just type! Logic then decides that if the
> value is <= 0xff it is because the subtype is zero.
> 
> It is simpler and much clearer to preserve the original
> representation.
> This also allows unambiguous use of type 0 with subtypes, and,
> possibly, city with subtypes.
> 
> It also allows the same function to be used to test a type for being
> in
> the 'city' range, regardless of the context. mkgmap wasn't consistent
> the ranges for the isCity test.
> 
> City POI are written in a different manner to the RGN file. The old
> range for this was:
>   type >= 0x0100 && type <= 0x1100
> which I've kept, except changing to: ...& type < 0x1200. A similar
> range was used for MDR5.
> 
> However, city POI are held in group 1 of MDR 9/10. This is used in
> Find
> > City 'By Name'. The old range was: type <= 0xf, where, if the
> > subtype
> was zero, type is right shifted by 8 (see above), non-zero subtypes
> messed up the testing. Now it uses the same range as above.
> 
> Actually neither of these ranges are correct for my Garmin devices.
> Find > City show nearby POI with types in the range 0x0100..0x0d1f,
> regardless of the img RGN or MDR. The eTrex Legend labels POIs in
> this
> range as {Large/Medium/Small} City/Town and points in the range
> 0x0e00..0x111f as "*".
> 
> Find > City 'by-name' returns POI if in group 1 of MDR 9/10. I find
> it
> a useful feature to have a POI that can be searched for but doesn't
> flood the list of nearby points.
> 
> Generally, non-zero subtypes for cities cause problems in the RGN
> structure and I've added a test for this to the style validation.
> 
> There is also a fix to --make-poi-index, but I can't detect any
> effect
> of this option.
> 
> This patch won't make any difference to the img output unless the
> there
> are points 0x1000, 0x1100.
> 
> If this patch is accepted, I'll do the equivalent to the img display
> system.
> 
> Regards
> Ticker
> _______________________________________________
> mkgmap-dev mailing list
> [email protected]
> http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Index: src/uk/me/parabola/imgfmt/app/lbl/POIIndex.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/lbl/POIIndex.java	(revision 4315)
+++ src/uk/me/parabola/imgfmt/app/lbl/POIIndex.java	(working copy)
@@ -35,7 +35,7 @@
 		this.name = name;
 		this.poiIndex = poiIndex;
 		this.group = group;
-		this.subType = subType & 0xff;
+		this.subType = subType;
 	}
 
 	void write(ImgFileWriter writer) {
Index: src/uk/me/parabola/imgfmt/app/lbl/PlacesFile.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/lbl/PlacesFile.java	(revision 4315)
+++ src/uk/me/parabola/imgfmt/app/lbl/PlacesFile.java	(working copy)
@@ -305,7 +305,7 @@
 		if (t < MIN_INDEXED_POI_TYPE || t > MAX_INDEXED_POI_TYPE) 
 			return;
 		
-		POIIndex pi = new POIIndex(name, index, group, type);
+		POIIndex pi = new POIIndex(name, index, group, type & 0xff);
 		if(poiIndex[t] == null)
 			poiIndex[t] = new ArrayList<POIIndex>();
 		poiIndex[t].add(pi);
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr10.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr10.java	(revision 4315)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr10.java	(working copy)
@@ -47,6 +47,9 @@
 		}
 	}
 
+	/**
+	 * display MdrCheck.java:toType() needs to be in-step with this
+	 */
 	public void addPoiType(Mdr11Record poi) {
 		Mdr10Record t = new Mdr10Record();
 
@@ -56,7 +59,7 @@
 		if (group == 0)
 			return;
 		if (group == 1)
-			t.setSubtype(fullType);
+			t.setSubtype(MdrUtils.getTypeFromFullType(fullType)); // cities
 		else {
 			t.setSubtype(MdrUtils.getSubtypeFromFullType(fullType));
 		}
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr4.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr4.java	(revision 4315)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr4.java	(working copy)
@@ -52,12 +52,9 @@
 
 	public void addType(int type) {
 		Mdr4Record r = new Mdr4Record();
-		if (type <= 0xff)
-			r.setType(type);
-		else {
-			r.setType((type >> 8) & 0xff);
-			r.setSubtype(type & 0xff);
-		}
+		r.setType((type >> 8) & 0xff);
+		r.setSubtype(type & 0xff);
+
 		r.setUnknown(0);
 
 		poiTypes.add(r);
Index: src/uk/me/parabola/imgfmt/app/mdr/MdrUtils.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/MdrUtils.java	(revision 4315)
+++ src/uk/me/parabola/imgfmt/app/mdr/MdrUtils.java	(working copy)
@@ -16,6 +16,7 @@
 import java.util.Collections;
 import java.util.List;
 
+import uk.me.parabola.mkgmap.general.MapPoint;
 import uk.me.parabola.imgfmt.app.srt.Sort;
 import uk.me.parabola.imgfmt.app.srt.SortKey;
 
@@ -34,33 +35,38 @@
 	 *
 	 * Not entirely sure about how this works yet.
 	 * @param fullType The primary type of the object.
-	 * @return The group number.  This is a number between 1 and 9 (and later
-	 * perhaps higher numbers such as 0x40, so do not assume there are no
-	 * gaps).
-	 * Group / Filed under
-	 * 1 Cities
-	 * 2 Food & Drink
-	 * 3 Lodging
-	 * 4-5 Recreation / Entertainment / Attractions
-	 * 6 Shopping
-	 * 7 Auto Services
-	 * 8 Community
-	 * 9 ?
-	 * 
+	 * @return The group number.  This is a number between 1 and MAX_GROUP, later
+	 * might be as high as 0x40, so do not assume there are no gaps.
+	 *
+	 * Group Type   Filed under
+	 *  1    	Cities	(actual range defined by isCityType)
+	 *  2    0x2a   Food and Drink
+	 *  3    0x2b   Lodgings
+	 *  4    0x2c   Attractions/Recreation/Community
+	 *  5    0x2d   Entertainment/Recreation
+	 *  6    0x2e   Shopping
+	 *  7    0x2f   Auto/Transport/Community/Other
+	 *  8    0x30   Civic
+	 *  9    0x28   Island. Reason for having this is no longer known
+         * 10  unused
+	 * 11    0x64   Geographic > Manmade Places
+	 * 12    0x65   Geographic > Water Features
+	 * 13    0x66   Geographic > Land Features
+	 *
+	 * display MdrCheck.java:toType() needs to be in-step with this
 	 */
 	public static int getGroupForPoi(int fullType) {
 		// We group pois based on their type.  This may not be the final thoughts on this.
 		int type = getTypeFromFullType(fullType);
 		int group = 0;
-		if (fullType <= 0xf)
+		if (MapPoint.isCityType(fullType))
 			group = 1;
-		else if (type >= 0x2a && type <= 0x30) { 
-			group = type - 0x28;
-		} else if (type == 0x28) {
+		else if (type >= 0x2a && type <= 0x30)
+			group = type - 0x2a + 2;
+		else if (type == 0x28)
 			group = 9;
-		} else if (type >= 0x64 && type <= 0x66) {
-			group = type - 0x59;
-		}
+		else if (type >= 0x64 && type <= 0x66)
+			group = type - 0x64 + 11;
 		assert group >= 0 && group <= MAX_GROUP : "invalid group " + Integer.toHexString(group);
 		return group;
 	}
@@ -70,10 +76,7 @@
 	}
 
 	public static int getTypeFromFullType(int fullType) {
-		if ((fullType & 0xfff00) > 0)
-			return (fullType>>8) & 0xfff;
-		else
-			return fullType & 0xff;
+		return (fullType>>8) & 0xfff;
 	}
 
 	/**
@@ -82,7 +85,7 @@
 	 * @return If there is a subtype, then it is returned, else 0.
 	 */
 	public static int getSubtypeFromFullType(int fullType) {
-		return fullType < 0xff ? 0 : fullType & 0xff;
+		return fullType & 0xff;
 	}
 
 	/**
@@ -115,10 +118,8 @@
 	 */
 	public static int fullTypeToNaturalType(int ftype) {
 		int type = getTypeFromFullType(ftype);
-		int sub = 0;
-		if ((ftype & ~0xff) != 0)
-			sub = ftype & 0x1f;
-
+		int sub = getSubtypeFromFullType(ftype);
+		assert sub <= 0x1f: "Subtype doesn't fit into 5 bits: " + uk.me.parabola.mkgmap.reader.osm.GType.formatType(ftype);
 		return type << 5 | sub;
 	}
 }
Index: src/uk/me/parabola/imgfmt/app/trergn/Point.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/trergn/Point.java	(revision 4315)
+++ src/uk/me/parabola/imgfmt/app/trergn/Point.java	(working copy)
@@ -50,13 +50,11 @@
 		boolean hasSubtype = false;
 		int type = getType();
 		int subtype = 0;
-		if (type > 0xff) {
-			if((type & 0xff) != 0) {
-			    hasSubtype = true;
-			    subtype = type & 0xff;
-			}
-			type >>= 8;
+		if ((type & 0xff) != 0) {
+			hasSubtype = true;
+			subtype = type & 0xff;
 		}
+		type >>= 8;
 
 		file.put1u(type);
 
Index: src/uk/me/parabola/imgfmt/app/trergn/RGNFileReader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/trergn/RGNFileReader.java	(revision 4315)
+++ src/uk/me/parabola/imgfmt/app/trergn/RGNFileReader.java	(working copy)
@@ -127,13 +127,13 @@
 			p.setDeltaLong(reader.get2s());
 			p.setDeltaLat(reader.get2s());
 
+			t <<= 8;
 			if (hasSubtype) {
 				int st = reader.get1u();
-				p.setType((t << 8) | st);
+				t |= st;
 				//p.setHasSubtype(true);
-			} else {
-				p.setType(t);
 			}
+			p.setType(t);
 
 			p.setNumber(number++);
 			points.add(p);
Index: src/uk/me/parabola/mkgmap/combiners/MdrBuilder.java
===================================================================
--- src/uk/me/parabola/mkgmap/combiners/MdrBuilder.java	(revision 4315)
+++ src/uk/me/parabola/mkgmap/combiners/MdrBuilder.java	(working copy)
@@ -47,6 +47,7 @@
 import uk.me.parabola.imgfmt.sys.ImgFS;
 import uk.me.parabola.mkgmap.CommandArgs;
 import uk.me.parabola.mkgmap.srt.SrtTextReader;
+import uk.me.parabola.mkgmap.general.MapPoint;
 
 /**
  * Create the global index file.  This consists of an img file containing
@@ -266,7 +267,7 @@
 
 			Mdr5Record mdrCity = null;
 			boolean isCity;
-			if (p.getType() >= 0x1 && p.getType() <= 0x11) {
+			if (MapPoint.isCityType(p.getType())) {
 				// This is itself a city, it gets a reference to its own MDR 5 record.
 				// and we also use it to set the name of the city.
 				mdrCity = maps.cities.get((p.getSubdiv().getNumber() << 8) + p.getNumber());
Index: src/uk/me/parabola/mkgmap/general/MapPoint.java
===================================================================
--- src/uk/me/parabola/mkgmap/general/MapPoint.java	(revision 4315)
+++ src/uk/me/parabola/mkgmap/general/MapPoint.java	(working copy)
@@ -64,7 +64,7 @@
 
 	public static boolean isCityType(int type)
 	{
-		return type >= 0x0100 && type <= 0x1100;
+		return type >= 0x0100 && type < 0x1200;
 	}
 
 	public boolean isExit() {
Index: src/uk/me/parabola/mkgmap/reader/osm/GType.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/GType.java	(revision 4315)
+++ src/uk/me/parabola/mkgmap/reader/osm/GType.java	(working copy)
@@ -21,6 +21,7 @@
 import uk.me.parabola.imgfmt.ExitException;
 import uk.me.parabola.log.Logger;
 import uk.me.parabola.mkgmap.general.LevelInfo;
+import uk.me.parabola.mkgmap.general.MapPoint;
 
 /**
  * Holds the garmin type of an element and all the information that
@@ -66,8 +67,13 @@
 			else if (featureKind == FeatureKind.POLYGON && (type> 0x7f || type == 0x4a))
 				return false;
 			else if (featureKind == FeatureKind.POINT){
-				if (type < 0x0100 || (type & 0x00ff) > 0x1f) 
+				if (type < 0x0100)
 					return false;
+				int subtype = type & 0xff;
+ 				if (subtype > 0x1f)
+					return false;
+				if (MapPoint.isCityType(type) && subtype != 0)
+					return false;
 			}
 		}
 		return true;
Index: src/uk/me/parabola/mkgmap/reader/polish/PolishMapDataSource.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/polish/PolishMapDataSource.java	(revision 4315)
+++ src/uk/me/parabola/mkgmap/reader/polish/PolishMapDataSource.java	(working copy)
@@ -412,12 +412,13 @@
 	private void point(String name, String value) {
 		if (name.equals("Type")) {
 			int type = Integer.decode(value);
+			if (type <= 0xff)
+				type <<= 8;
 			point.setType(type);
 		} else if (name.equals("SubType")) {
 			int subtype = Integer.decode(value);
 			int type = point.getType();
-			if (type <= 0xff)
-				point.setType((type << 8) | subtype);
+			point.setType(type | subtype);
 		} else if (name.startsWith("Data") || name.startsWith("Origin")) {
 			Coord co = makeCoord(value);
 			setResolution(point, name);
_______________________________________________
mkgmap-dev mailing list
[email protected]
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Reply via email to