This patch codes around the problems introduced by highway shields with
regard to the sorted roads:

1 - the sort order should now be much improved

2 - no duplicate symbols (shield version + non-shield version)

It also includes a fix to the label reading code so that labels with a
highway shield prefix are read in correctly when generating the MDR
file.

For me, in mapsource, road search for roads with highway shields now
works apart from motorways which don't seem to searchable - perhaps
that's deliberate on Garmin's part?


All feedback appreciated.

Mark
diff --git a/src/uk/me/parabola/imgfmt/app/Label.java b/src/uk/me/parabola/imgfmt/app/Label.java
index c7ca3a3..bbf7549 100644
--- a/src/uk/me/parabola/imgfmt/app/Label.java
+++ b/src/uk/me/parabola/imgfmt/app/Label.java
@@ -56,6 +56,16 @@ public class Label implements Comparable<Label> {
 		return text;
 	}
 
+	public String getTextSansGarminCodes() {
+		return stripGarminCodes(text);
+	}
+
+	public static String stripGarminCodes(String s) {
+		if(s == null)
+			return null;
+		return s.replaceAll("[\u0001-\u0006\u001b-\u001f]","");
+	}
+
 	/**
 	 * The offset of this label in the LBL file.  The first byte of this file
 	 * is zero and an offset of zero means that the label has a zero length/is
diff --git a/src/uk/me/parabola/imgfmt/app/labelenc/Format6Encoder.java b/src/uk/me/parabola/imgfmt/app/labelenc/Format6Encoder.java
index ec226a1..d1a267d 100644
--- a/src/uk/me/parabola/imgfmt/app/labelenc/Format6Encoder.java
+++ b/src/uk/me/parabola/imgfmt/app/labelenc/Format6Encoder.java
@@ -41,7 +41,7 @@ public class Format6Encoder extends BaseEncoder implements CharacterEncoder {
 	public static final String LETTERS =
 		" ABCDEFGHIJKLMNO" +	// 0x00-0x0F
 		"PQRSTUVWXYZxx   " +	// 0x10-0x1F
-		"0123456789xxxxxx";	// 0x20-0x2F
+		"0123456789\u0001\u0002\u0003\u0004\u0005\u0006";	// 0x20-0x2F
 
 	public static final String SYMBOLS =
 		"@!\"#$%&'()*+,-./" +	// 0x00-0x0F
diff --git a/src/uk/me/parabola/imgfmt/app/lbl/City.java b/src/uk/me/parabola/imgfmt/app/lbl/City.java
index 4fc7939..2ae6389 100644
--- a/src/uk/me/parabola/imgfmt/app/lbl/City.java
+++ b/src/uk/me/parabola/imgfmt/app/lbl/City.java
@@ -118,7 +118,7 @@ public class City implements Comparable<City> {
 		if(label != null)
 			result += label.getText();
 		if (subdivision != null)
-			result += subdivision.getNumber() + "/" + pointIndex;
+			result += " " + subdivision.getNumber() + "/" + pointIndex;
 		if(country != null)
 			result += " in country " + (0 + country.getIndex());
 		if(region != null)
diff --git a/src/uk/me/parabola/imgfmt/app/net/NETFile.java b/src/uk/me/parabola/imgfmt/app/net/NETFile.java
index 82f220b..e7abf26 100644
--- a/src/uk/me/parabola/imgfmt/app/net/NETFile.java
+++ b/src/uk/me/parabola/imgfmt/app/net/NETFile.java
@@ -18,8 +18,11 @@ package uk.me.parabola.imgfmt.app.net;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 
 import uk.me.parabola.imgfmt.Utils;
 import uk.me.parabola.imgfmt.app.BufferedImgFileWriter;
@@ -61,23 +64,44 @@ public class NETFile extends ImgFile {
 
 	public void writePost(ImgFileWriter rgn, boolean sortRoads) {
 		List<Sortable<Label, RoadDef>> sortedRoads = new ArrayList<Sortable<Label, RoadDef>>(roads.size());
+		// cleanedLabels holds "cleaned up" versions of the Label
+		// strings that are used when sorting the road names - the
+		// hope is that retrieving the String from the Map is faster than
+		// cleaning the Label text for each comparison in the sort
+		final Map<Label, String> cleanedLabels = new HashMap<Label, String>();
 
 		for (RoadDef rd : roads) {
 			rd.writeRgnOffsets(rgn);
 			if(sortRoads) {
 				Label[] l = rd.getLabels();
-				for(int i = 0; i < l.length && l[i] != null; ++i)
-					if(l[i].getLength() != 0)
+				for(int i = 0; i < l.length && l[i] != null; ++i) {
+					if(l[i].getLength() != 0) {
+						cleanedLabels.put(l[i], l[i].getTextSansGarminCodes());
+						//	System.err.println("Road " + rd + " has label " + l[i]);
 						sortedRoads.add(new Sortable<Label, RoadDef>(l[i], rd));
+					}
+				}
 			}
 		}
 
 		if(sortedRoads.size() > 0) {
-			Collections.sort(sortedRoads);
+			Collections.sort(sortedRoads, new Comparator<Sortable<Label, RoadDef>>() {
+					public int compare(Sortable<Label, RoadDef> a, Sortable<Label, RoadDef> b) {
+						// sort using cleaned versions of the labels
+						int diff = cleanedLabels.get(a.getKey()).compareToIgnoreCase(cleanedLabels.get(b.getKey()));
+						if(diff != 0)
+							return diff;
+						// the labels were the same, sort on the
+						// RoadDefs
+						return a.getValue().compareTo(b.getValue());
+					}
+				});
 			sortedRoads = simplifySortedRoads(new LinkedList<Sortable<Label, RoadDef>>(sortedRoads));
 			ImgFileWriter writer = netHeader.makeSortedRoadWriter(getWriter());
-			for(Sortable<Label, RoadDef> srd : sortedRoads)
+			for(Sortable<Label, RoadDef> srd : sortedRoads) {
+				//System.err.println("Road " + srd.getKey() + " is " + srd.getValue() + " " + srd.getValue().getCity());
 				srd.getValue().putSortedRoadEntry(writer, srd.getKey());
+			}
 			Utils.closeFile(writer);
 		}
 
@@ -95,7 +119,7 @@ public class NETFile extends ImgFile {
 	private List<Sortable<Label, RoadDef>> simplifySortedRoads(LinkedList<Sortable<Label, RoadDef>> in) {
 		List<Sortable<Label, RoadDef>> out = new ArrayList<Sortable<Label, RoadDef>>(in.size());
 		while(in.size() > 0) {
-			Label name0 = in.get(0).getKey();
+			String name0 = in.get(0).getKey().getTextSansGarminCodes();
 			RoadDef road0 = in.get(0).getValue();
 			City city0 = road0.getCity();
 			// transfer the 0'th entry to the output
@@ -104,7 +128,7 @@ public class NETFile extends ImgFile {
 			// firstly determine the entries whose name and city match
 			// name0 and city0
 			for(n = 0; (n < in.size() &&
-						name0 == in.get(n).getKey() &&
+						name0.equalsIgnoreCase(in.get(n).getKey().getTextSansGarminCodes()) &&
 						city0 == in.get(n).getValue().getCity()); ++n) {
 				// relax
 			}
diff --git a/src/uk/me/parabola/imgfmt/app/trergn/Subdivision.java b/src/uk/me/parabola/imgfmt/app/trergn/Subdivision.java
index 1202186..a2620b5 100644
--- a/src/uk/me/parabola/imgfmt/app/trergn/Subdivision.java
+++ b/src/uk/me/parabola/imgfmt/app/trergn/Subdivision.java
@@ -274,15 +274,20 @@ public class Subdivision {
 	}
 
 	public Polyline createLine(String name, String ref) {
+		// don't be tempted to "trim()" the name as it zaps the highway shields
 		Label label = lblFile.newLabel(name);
+		String nameSansGC = Label.stripGarminCodes(name);
 		Polyline pl = new Polyline(this);
 
 		pl.setLabel(label);
+
 		if(ref != null) {
 			// ref may contain multiple ids separated by ";"
 			for(String r : ref.split(";")) {
 				String tr = r.trim();
-				if(tr.length() > 0) {
+				String trSansGC = Label.stripGarminCodes(tr);
+				if(trSansGC.length() > 0 &&
+				   !trSansGC.equalsIgnoreCase(nameSansGC)) {
 					//System.err.println("Adding ref " + tr + " to road " + name);
 					pl.addRefLabel(lblFile.newLabel(tr));
 				}
_______________________________________________
mkgmap-dev mailing list
mkgmap-dev@lists.mkgmap.org.uk
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Reply via email to