On 30/03/11 22:41, Dermot McNally wrote:
It looks like we may not be out of the woods yet on this one - with
the latest patch, trying to build a map of Ireland (from the Geofabrik
extract) fails, where it had succeeded before. Single tile, no
splitting:
java.lang.ArrayIndexOutOfBoundsException: 36
at
uk.me.parabola.imgfmt.app.srt.SrtSortKey.compareTo(SrtSortKey.java:41)
Thanks for trying out the patch. That is indeed a problem, please try
the updated patch attached.
Best wishes
..Steve
Index: src/uk/me/parabola/imgfmt/app/Label.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/Label.java (revision 1650)
+++ src/uk/me/parabola/imgfmt/app/Label.java (revision )
@@ -56,10 +56,6 @@
return text;
}
- public String getTextSansGarminCodes() {
- return stripGarminCodes(text);
- }
-
// highway shields and "thin" separators
private final static Pattern SHIELDS = Pattern.compile("[\u0001-\u0006\u001b-\u001c]");
Index: test/uk/me/parabola/imgfmt/app/srt/SortTest.java
===================================================================
--- test/uk/me/parabola/imgfmt/app/srt/SortTest.java (revision 1873)
+++ test/uk/me/parabola/imgfmt/app/srt/SortTest.java (revision )
@@ -47,7 +47,7 @@
@Test
public void testDifferentLengths() {
- SortKey<Object> k1 = sort.createSortKey(null, "aabb");
+ SortKey<Object> k1 = sort.createSortKey(null, "aabbbb");
SortKey<Object> k2 = sort.createSortKey(null, "aab");
assertEquals(1, k1.compareTo(k2));
@@ -158,6 +158,11 @@
assertEquals(-1, collator.compare("AA", "AAA"));
}
+ @Test
+ public void testIgnorableCharacters() {
+ checkOrder("aa", "\004aa");
+ }
+
private void checkOrder(int i1, int i2) {
String s = "aaa";
SortKey<Object> k1 = sort.createSortKey(null, s, i1);
Index: src/uk/me/parabola/imgfmt/app/srt/Sort.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/srt/Sort.java (revision 1873)
+++ src/uk/me/parabola/imgfmt/app/srt/Sort.java (revision )
@@ -93,22 +93,42 @@
ByteBuffer out = encoder.encode(inb);
byte[] bval = out.array();
byte[] key = new byte[bval.length * 3 + 3];
- int length = bval.length;
- for (int i = 0; i < length; i++) {
- int b = bval[i] & 0xff;
- key[i] = primary[b];
- key[length + 1 + i] = secondary[b];
- key[2*length + 2 + i] = tertiary[b];
- }
- key[length] = 0;
- key[2 * length + 1] = 0;
- key[3 * length + 2] = 0;
+
+ int start = fillKey(primary, bval, key, 0);
+ start = fillKey(secondary, bval, key, start);
+ fillKey(tertiary, bval, key, start);
+
return new SrtSortKey<T>(object, key, second);
} catch (CharacterCodingException e) {
return new SrtSortKey<T>(object, ZERO_KEY);
}
}
+ /**
+ * Fill in the output key for a given strength.
+ *
+ * @param sortPositions An array giving the sort position for each of the 256 characters.
+ * @param input The input string in a particular 8 bit codepage.
+ * @param outKey The output sort key.
+ * @param start The index into the output key to start at.
+ * @return The next position in the output key.
+ */
+ private int fillKey(byte[] sortPositions, byte[] input, byte[] outKey, int start) {
+ int index = start;
+ for (byte inb : input) {
+ int b = inb & 0xff;
+
+ // I am guessing that a sort position of 0 means that the character is ignorable at this
+ // strength. In other words it is as if it is not present in the string. This appears to
+ // be true for shield symbols, but perhaps not for other kinds of control characters.
+ if (sortPositions[b] != 0)
+ outKey[index++] = sortPositions[b];
+ }
+
+ outKey[index++] = '\0';
+ return index;
+ }
+
public <T> SortKey<T> createSortKey(T object, String s) {
return createSortKey(object, s, 0);
}
Index: src/uk/me/parabola/imgfmt/app/net/NETFile.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/net/NETFile.java (revision 1870)
+++ src/uk/me/parabola/imgfmt/app/net/NETFile.java (revision )
@@ -71,8 +71,7 @@
Label[] l = rd.getLabels();
for(int i = 0; i < l.length && l[i] != null; ++i) {
if(l[i].getLength() != 0) {
- String cleanName = l[i].getTextSansGarminCodes();
- SortKey<LabeledRoadDef> sortKey = sort.createSortKey(new LabeledRoadDef(l[i], rd), cleanName);
+ SortKey<LabeledRoadDef> sortKey = sort.createSortKey(new LabeledRoadDef(l[i], rd), l[i].getText());
sortKeys.add(sortKey);
}
}
@@ -107,7 +106,7 @@
List<LabeledRoadDef> out = new ArrayList<LabeledRoadDef>(in.size());
while(!in.isEmpty()) {
LabeledRoadDef firstLabeledRoadDef = in.get(0).getObject();
- String name0 = firstLabeledRoadDef.label.getTextSansGarminCodes();
+ String name0 = firstLabeledRoadDef.label.getText();
RoadDef road0 = firstLabeledRoadDef.roadDef;
City city0 = road0.getCity();
@@ -119,7 +118,7 @@
// firstly determine the entries whose name and city match
// name0 and city0
for(n = 0; (n < in.size() &&
- name0.equalsIgnoreCase(in.get(n).getObject().label.getTextSansGarminCodes()) &&
+ name0.equalsIgnoreCase(in.get(n).getObject().label.getText()) &&
city0 == in.get(n).getObject().roadDef.getCity()); ++n) {
// relax
}
Index: src/uk/me/parabola/imgfmt/app/srt/SrtSortKey.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/srt/SrtSortKey.java (revision 1870)
+++ src/uk/me/parabola/imgfmt/app/srt/SrtSortKey.java (revision )
@@ -36,9 +36,11 @@
}
public int compareTo(SortKey<T> o) {
- for (int i = 0; i < this.key.length; i++) {
+ SrtSortKey<T> other = (SrtSortKey<T>) o;
+ int length = Math.min(this.key.length, other.key.length);
+ for (int i = 0; i < length; i++) {
int k1 = this.key[i] & 0xff;
- int k2 = ((SrtSortKey) o).key[i] & 0xff;
+ int k2 = other.key[i] & 0xff;
if (k1 < k2) {
return -1;
} else if (k1 > k2) {
@@ -46,9 +48,14 @@
}
}
- if (second == ((SrtSortKey) o).second)
+ if (this.key.length < other.key.length)
+ return -1;
+ else if (this.key.length > other.key.length)
+ return 1;
+
+ if (second == other.second)
return 0;
- else if (second < ((SrtSortKey) o).second)
+ else if (second < other.second)
return -1;
else
return 1;
Index: src/uk/me/parabola/imgfmt/app/mdr/MDRFile.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/MDRFile.java (revision 1870)
+++ src/uk/me/parabola/imgfmt/app/mdr/MDRFile.java (revision )
@@ -203,7 +203,8 @@
String cleanName = cleanUpName(name);
int strOff = createString(cleanName);
- // XXX not sure: we sort on the dirty name (ie with the Garmin shield codes).
+ // We sort on the dirty name (ie with the Garmin shield codes) although those codes do not
+ // affect the sort order. The string for mdr15 does not include the shield codes.
mdr7.addStreet(currentMap, name, lab.getOffset(), strOff, mdrCity);
}
}
_______________________________________________
mkgmap-dev mailing list
[email protected]
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev