[mkgmap] 01/04: Imported Upstream version 0.0.0+svn3478
Sebastiaan Couwenberg
sebastic at moszumanska.debian.org
Tue Mar 3 23:13:48 UTC 2015
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch master
in repository mkgmap.
commit e042a28f504f79a79a17d00dccace7f64331ebcd
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Tue Mar 3 23:01:06 2015 +0100
Imported Upstream version 0.0.0+svn3478
---
resources/help/en/options | 10 ++
resources/mkgmap-version.properties | 4 +-
resources/styles/default/inc/name | 8 +
resources/styles/default/lines | 3 +-
.../parabola/imgfmt/app/labelenc/Utf8Decoder.java | 1 -
src/uk/me/parabola/imgfmt/app/mdr/Mdr20.java | 14 +-
src/uk/me/parabola/imgfmt/app/mdr/Mdr22.java | 2 +-
src/uk/me/parabola/imgfmt/app/mdr/Mdr2x.java | 41 +++--
src/uk/me/parabola/imgfmt/app/mdr/Mdr7.java | 183 +++++++++++++++++++--
src/uk/me/parabola/imgfmt/app/mdr/Mdr7Record.java | 43 +++++
src/uk/me/parabola/imgfmt/app/mdr/MdrConfig.java | 9 +
.../parabola/mkgmap/combiners/GmapsuppBuilder.java | 4 +-
.../me/parabola/mkgmap/combiners/MdrBuilder.java | 4 +-
.../parabola/mkgmap/osmstyle/RuleFileReader.java | 38 +++--
.../me/parabola/mkgmap/scan/SyntaxException.java | 2 +-
test/resources/rules/multi-or-twice.test | 18 ++
test/resources/rules/multi-or-with-and.test | 19 +++
test/resources/rules/or-at-end.test | 30 ++++
.../mkgmap/osmstyle/RuleFileReaderTest.java | 1 +
19 files changed, 376 insertions(+), 58 deletions(-)
diff --git a/resources/help/en/options b/resources/help/en/options
index f13bef2..5a978e6 100644
--- a/resources/help/en/options
+++ b/resources/help/en/options
@@ -125,6 +125,16 @@ Address search options:
same code page and sorting options (eg. --code-page, --latin1 etc) must
be used as were used to compile the individual map tiles.
+--x-split-name-index
+ A temporary option to enable indexing each part of a street name separately.
+ So for example if the street is "Aleksandra Gryglewskiego" then you will be able to
+ search for it as both "Aleksandra" and "Gryglewskiego". It will also increase the
+ size of the index. Useful in countries where searching for the first word in name
+ is not the right thing to do.
+
+ Note that this option is still experimental and there may be problems. If you find
+ any let us know!
+
--bounds=directory|zipfile
A directory or a zipfile containing the preprocessed bounds files.
Bounds files in a zipfile must be located in the zipfiles root directory.
diff --git a/resources/mkgmap-version.properties b/resources/mkgmap-version.properties
index 78cc6d5..7a0d191 100644
--- a/resources/mkgmap-version.properties
+++ b/resources/mkgmap-version.properties
@@ -1,2 +1,2 @@
-svn.version: 3436
-build.timestamp: 2015-02-02T06:43:48+0000
+svn.version: 3478
+build.timestamp: 2015-02-26T07:49:21+0000
diff --git a/resources/styles/default/inc/name b/resources/styles/default/inc/name
index f3e9d98..67f0a62 100644
--- a/resources/styles/default/inc/name
+++ b/resources/styles/default/inc/name
@@ -13,6 +13,7 @@ operator=${name} { delete operator; }
brand=${name} { delete brand; }
# None of operator, brand given
+ref=* & (operator!=* & brand!=*) & (highway=bus_stop | railway=tram_stop | railway=halt | railway=station) { name '${name} ${ref}' | '${ref}' }
ref=* & (operator!=* & brand!=*) { name '${ref} ${name}' | '${ref}' }
# Both operator and brand given
@@ -24,6 +25,13 @@ operator=* & brand=* {
}
# One of operator or brand given
+operator=* & brand!=* & (highway=bus_stop | railway=tram_stop | railway=halt | railway=station) {
+ name '${name} ${ref} ${operator}' |
+ '${name} ${operator}' |
+ '${ref} ${operator}' |
+ '${operator}'
+}
+
operator=* & brand!=* {
name '${operator}: ${ref} ${name}' |
'${operator}: ${name}' |
diff --git a/resources/styles/default/lines b/resources/styles/default/lines
index c43a29c..e2d79c0 100644
--- a/resources/styles/default/lines
+++ b/resources/styles/default/lines
@@ -163,7 +163,8 @@ power=line [0x29 resolution 21]
railway=abandoned [0x0a road_class=0 road_speed=1 resolution 22]
railway=platform [0x16 road_class=0 road_speed=0 resolution 23]
-railway=* & !(tunnel=yes) [0x14 resolution 22]
+# Railway lines, note that many devices display type 0x14 only at resolution 24
+(railway=rail | railway=tram | railway=disused | railway=subway | railway=narrow_gauge | railway=light_rail | railway=preserved) & !(tunnel=yes) [0x14 resolution 22]
(man_made=cable|(man_made=* & man_made ~ '.*pipe.*')) & area!=yes &
tunnel!=yes & location != underground
diff --git a/src/uk/me/parabola/imgfmt/app/labelenc/Utf8Decoder.java b/src/uk/me/parabola/imgfmt/app/labelenc/Utf8Decoder.java
index 73345fc..fe0ed56 100644
--- a/src/uk/me/parabola/imgfmt/app/labelenc/Utf8Decoder.java
+++ b/src/uk/me/parabola/imgfmt/app/labelenc/Utf8Decoder.java
@@ -42,7 +42,6 @@ public class Utf8Decoder implements CharacterDecoder {
public boolean addByte(int b) {
if (b == 0) {
needreset = true;
- out.write(0);
return true;
}
diff --git a/src/uk/me/parabola/imgfmt/app/mdr/Mdr20.java b/src/uk/me/parabola/imgfmt/app/mdr/Mdr20.java
index 3791d31..a2096ca 100644
--- a/src/uk/me/parabola/imgfmt/app/mdr/Mdr20.java
+++ b/src/uk/me/parabola/imgfmt/app/mdr/Mdr20.java
@@ -88,15 +88,17 @@ public class Mdr20 extends Mdr2x {
Collator collator = getConfig().getSort().getCollator();
String lastName = null;
+ String lastPartialName = null;
Mdr5Record lastCity = null;
int record = 0;
- int cityRecord = 0;
+ int cityRecord = 1;
int lastMapNumber = 0;
for (SortKey<Mdr7Record> key : keys) {
Mdr7Record street = key.getObject();
String name = street.getName();
+ String partialName = street.getPartialName();
Mdr5Record city = street.getCity();
boolean citySameByName = city.isSameByName(collator, lastCity);
@@ -104,18 +106,24 @@ public class Mdr20 extends Mdr2x {
int mapNumber = city.getMapIndex();
// Only save a single copy of each street name.
- if (!citySameByName || mapNumber != lastMapNumber || lastName == null || collator.compare(name, lastName) != 0) {
+ if (!citySameByName || mapNumber != lastMapNumber || lastName == null || lastPartialName == null
+ || !name.equals(lastName)
+ || !partialName.equals(lastPartialName))
+ {
record++;
streets.add(street);
lastName = name;
+ lastPartialName = partialName;
}
// The mdr20 value changes for each new city name
if (citySameByName) {
+ assert cityRecord!=0;
city.setMdr20(cityRecord);
} else {
// New city name, this marks the start of a new section in mdr20
+ assert cityRecord != 0;
cityRecord = record;
city.setMdr20(cityRecord);
lastCity = city;
@@ -137,6 +145,6 @@ public class Mdr20 extends Mdr2x {
* Unknown.
*/
public int getExtraValue() {
- return isForDevice() ? 0xa : 0x8800;
+ return isForDevice() ? 0xe : 0x8800;
}
}
diff --git a/src/uk/me/parabola/imgfmt/app/mdr/Mdr22.java b/src/uk/me/parabola/imgfmt/app/mdr/Mdr22.java
index 379d3b4..afd8a35 100644
--- a/src/uk/me/parabola/imgfmt/app/mdr/Mdr22.java
+++ b/src/uk/me/parabola/imgfmt/app/mdr/Mdr22.java
@@ -104,7 +104,7 @@ public class Mdr22 extends Mdr2x {
*/
public int getExtraValue() {
if (isForDevice())
- return 0x600a;
+ return 0x600e;
else
return 0x11000;
}
diff --git a/src/uk/me/parabola/imgfmt/app/mdr/Mdr2x.java b/src/uk/me/parabola/imgfmt/app/mdr/Mdr2x.java
index bade6d8..d0c1fdf 100644
--- a/src/uk/me/parabola/imgfmt/app/mdr/Mdr2x.java
+++ b/src/uk/me/parabola/imgfmt/app/mdr/Mdr2x.java
@@ -16,7 +16,6 @@ import java.util.ArrayList;
import java.util.List;
import uk.me.parabola.imgfmt.app.ImgFileWriter;
-import uk.me.parabola.imgfmt.app.Label;
/**
* Common code for 20, 21, 22 which are all lists of streets ordered in
@@ -39,30 +38,45 @@ public abstract class Mdr2x extends MdrMapSection implements HasHeaderFlags {
int size = getSizes().getStreetSizeFlagged();
boolean hasLabel = hasFlag(0x2);
+
+ String lastPartial = null;
int recordNumber = 0;
for (Mdr7Record street : streets) {
assert street.getMapIndex() == street.getCity().getMapIndex() : street.getMapIndex() + "/" + street.getCity().getMapIndex();
addIndexPointer(street.getMapIndex(), ++recordNumber);
int index = street.getIndex();
- String name = Label.stripGarminCodes(street.getName());
-
- int flag = 1;
+
+ String name = street.getName();
+
+ int repeat = 1;
if (name.equals(lastName) && sameGroup(street, prev))
- flag = 0;
- lastName = name;
- prev = street;
+ repeat = 0;
if (hasLabel) {
putMapIndex(writer, street.getMapIndex());
int offset = street.getLabelOffset();
- if (flag != 0)
+ if (repeat != 0)
+ offset |= 0x800000;
+
+ int trailing = 0;
+ String partialName = street.getPartialName();
+ if (!partialName.equals(lastPartial)) {
+ trailing |= 1;
offset |= 0x800000;
+ }
+
writer.put3(offset);
- writer.put((byte) flag);
- }
- else
- putN(writer, size, (index << 1) | flag);
+ writer.put(street.getOutNameOffset());
+
+ writer.put((byte) trailing);
+
+ lastPartial = partialName;
+ } else
+ putN(writer, size, (index << 1) | repeat);
+
+ lastName = name;
+ prev = street;
}
}
@@ -78,7 +92,8 @@ public abstract class Mdr2x extends MdrMapSection implements HasHeaderFlags {
public int getItemSize() {
int size;
if (isForDevice()) {
- size = getSizes().getMapSize() + 3 + 1;
+ // map-index, label, name-offset, 1byte flag
+ size = getSizes().getMapSize() + 3 + 1 + 1;
} else {
size = getSizes().getStreetSizeFlagged();
}
diff --git a/src/uk/me/parabola/imgfmt/app/mdr/Mdr7.java b/src/uk/me/parabola/imgfmt/app/mdr/Mdr7.java
index 6e43a30..e4f1af6 100644
--- a/src/uk/me/parabola/imgfmt/app/mdr/Mdr7.java
+++ b/src/uk/me/parabola/imgfmt/app/mdr/Mdr7.java
@@ -16,8 +16,10 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import uk.me.parabola.imgfmt.MapFailedException;
import uk.me.parabola.imgfmt.app.ImgFileWriter;
-import uk.me.parabola.imgfmt.app.Label;
+import uk.me.parabola.imgfmt.app.srt.MultiSortKey;
+import uk.me.parabola.imgfmt.app.srt.Sort;
import uk.me.parabola.imgfmt.app.srt.SortKey;
/**
@@ -27,69 +29,211 @@ import uk.me.parabola.imgfmt.app.srt.SortKey;
* @author Steve Ratcliffe
*/
public class Mdr7 extends MdrMapSection {
+ public static final int MDR7_HAS_STRING = 0x01;
+ public static final int MDR7_HAS_NAME_OFFSET = 0x20;
+ public static final int MDR7_PARTIAL_SHIFT = 6;
+ public static final int MDR7_U1 = 0x2;
+ public static final int MDR7_U2 = 0x4;
+
+ private static final int MAX_NAME_OFFSET = 127;
+
+ private final int codepage;
+ private final boolean isMulti;
+ private final boolean splitName;
+
private List<Mdr7Record> allStreets = new ArrayList<>();
private List<Mdr7Record> streets = new ArrayList<>();
+ private final int u2size = 1;
+
public Mdr7(MdrConfig config) {
setConfig(config);
+ Sort sort = config.getSort();
+ splitName = config.isSplitName();
+ codepage = sort.getCodepage();
+ isMulti = sort.isMulti();
}
public void addStreet(int mapId, String name, int lblOffset, int strOff, Mdr5Record mdrCity) {
+ // Find a name prefix, which is either a shield or a word ending 0x1e. We are treating
+ // a shield as a prefix of length one.
+ int prefix = 0;
+ if (name.charAt(0) < 7)
+ prefix = 1;
+ int sep = name.indexOf(0x1e);
+ if (sep > 0)
+ prefix = sep + 1;
+
+ // Find a name suffix which begins with 0x1f
+ sep = name.indexOf(0x1f);
+ int suffix = 0;
+ if (sep > 0)
+ suffix = sep;
+
+ // Large values can't actually work.
+ if (prefix >= MAX_NAME_OFFSET || suffix >= MAX_NAME_OFFSET)
+ return;
+
Mdr7Record st = new Mdr7Record();
st.setMapIndex(mapId);
st.setLabelOffset(lblOffset);
st.setStringOffset(strOff);
st.setName(name);
st.setCity(mdrCity);
+ st.setPrefixOffset((byte) prefix);
+ st.setSuffixOffset((byte) suffix);
allStreets.add(st);
+
+ if (!splitName)
+ return;
+
+ boolean start = false;
+ boolean inWord = false;
+
+ int c;
+ int outOffset = 0;
+
+ int end = Math.min((suffix > 0) ? suffix : name.length() - prefix - 1, MAX_NAME_OFFSET);
+ for (int nameOffset = 0; nameOffset < end; nameOffset += Character.charCount(c)) {
+ c = name.codePointAt(prefix + nameOffset);
+
+ // Don't use any word after a bracket
+ if (c == '(')
+ break;
+
+ if (!Character.isLetterOrDigit(c)) {
+ start = true;
+ inWord = false;
+ } else if (start && Character.isLetterOrDigit(c)) {
+ inWord = true;
+ }
+
+ if (start && inWord && outOffset > 0) {
+ st = new Mdr7Record();
+ st.setMapIndex(mapId);
+ st.setLabelOffset(lblOffset);
+ st.setStringOffset(strOff);
+ st.setName(name);
+ st.setCity(mdrCity);
+ st.setNameOffset((byte) nameOffset);
+ st.setOutNameOffset((byte) outOffset);
+ st.setPrefixOffset((byte) prefix);
+ st.setSuffixOffset((byte) suffix);
+ //System.out.println(st.getName() + ": add partial " + st.getPartialName());
+ allStreets.add(st);
+ start = false;
+ }
+
+ outOffset += outSize(c);
+ if (outOffset > MAX_NAME_OFFSET)
+ break;
+ }
+ }
+
+ /**
+ * Return the number of bytes that the given character will consume in the output encoded
+ * format.
+ */
+ private int outSize(int c) {
+ if (codepage == 65001) {
+ // For unicode a simple lookup gives the number of bytes.
+ if (c < 0x80) {
+ return 1;
+ } else if (c <= 0x7FF) {
+ return 2;
+ } else if (c <= 0xFFFF) {
+ return 3;
+ } else if (c <= 0x10FFFF) {
+ return 4;
+ } else {
+ throw new MapFailedException(String.format("Invalid code point: 0x%x", c));
+ }
+ } else if (!isMulti) {
+ // The traditional single byte code-pages, always one byte.
+ return 1;
+ } else {
+ // Other multi-byte code-pages (eg ms932); can't currently create index for these anyway.
+ return 0;
+ }
}
/**
* Since we change the number of records by removing some after sorting,
* we sort and de-duplicate here.
+ * This is a performance critical part of the index creation process
+ * as it requires a lot of heap to store the sort keys.
*/
protected void preWriteImpl() {
- List<SortKey<Mdr7Record>> sortedStreets = MdrUtils.sortList(getConfig().getSort(), allStreets);
+ Sort sort = getConfig().getSort();
+ List<SortKey<Mdr7Record>> sortedStreets = new ArrayList<>(allStreets.size());
+ for (Mdr7Record m : allStreets) {
+ String partialName = m.getPartialName();
+ String name = m.getName();
+ SortKey<Mdr7Record> nameKey = sort.createSortKey(m, m.getName(), m.getMapIndex());
+ SortKey<Mdr7Record> partialKey = name.equals(partialName) ? nameKey : sort.createSortKey(m, partialName);
+ MultiSortKey<Mdr7Record> sortKey = new MultiSortKey<>(partialKey, nameKey, null);
+ sortedStreets.add(sortKey);
+ }
+ Collections.sort(sortedStreets);
// De-duplicate the street names so that there is only one entry
// per map for the same name.
int recordNumber = 0;
Mdr7Record last = new Mdr7Record();
- for (SortKey<Mdr7Record> sk : sortedStreets) {
+ for (int i = 0; i < sortedStreets.size(); i++){
+ SortKey<Mdr7Record> sk = sortedStreets.get(i);
Mdr7Record r = sk.getObject();
- if (r.getMapIndex() != last.getMapIndex() || !r.getName().equals(last.getName())) {
+ if (r.getMapIndex() == last.getMapIndex()
+ && r.getName().equals(last.getName()) // currently think equals is correct, not collator.compare()
+ && r.getPartialName().equals(last.getPartialName()))
+ {
+ // This has the same name (and map number) as the previous one. Save the pointer to that one
+ // which is going into the file.
+ r.setIndex(recordNumber);
+ } else {
recordNumber++;
last = r;
r.setIndex(recordNumber);
streets.add(r);
- } else {
- // This has the same name (and map number) as the previous one. Save the pointer to that one
- // which is going into the file.
- r.setIndex(recordNumber);
}
+ // release memory
+ sortedStreets.set(i, null);
}
}
public void writeSectData(ImgFileWriter writer) {
String lastName = null;
- boolean hasStrings = hasFlag(0x1);
+ String lastPartial = null;
+ boolean hasStrings = hasFlag(MDR7_HAS_STRING);
+ boolean hasNameOffset = hasFlag(MDR7_HAS_NAME_OFFSET);
+
for (Mdr7Record s : streets) {
addIndexPointer(s.getMapIndex(), s.getIndex());
putMapIndex(writer, s.getMapIndex());
int lab = s.getLabelOffset();
- String name = Label.stripGarminCodes(s.getName());
- int trailingFlags = 0;
+ String name = s.getName();
if (!name.equals(lastName)) {
lab |= 0x800000;
lastName = name;
- trailingFlags = 1;
}
+
+ String partialName = s.getPartialName();
+ int trailingFlags = 0;
+ if (!partialName.equals(lastPartial)) {
+ trailingFlags |= 1;
+ lab |= 0x800000; // If it is not a partial repeat, then it is not a complete repeat either
+ }
+ lastPartial = partialName;
+
writer.put3(lab);
if (hasStrings)
putStringOffset(writer, s.getStringOffset());
-
- writer.put((byte) trailingFlags);
+
+ if (hasNameOffset)
+ writer.put(s.getOutNameOffset());
+
+ putN(writer, u2size, trailingFlags);
}
}
@@ -99,9 +243,11 @@ public class Mdr7 extends MdrMapSection {
*/
public int getItemSize() {
PointerSizes sizes = getSizes();
- int size = sizes.getMapSize() + 3 + 1;
+ int size = sizes.getMapSize() + 3 + u2size;
if (!isForDevice())
size += sizes.getStrOffSize();
+ if ((getExtraValue() & MDR7_HAS_NAME_OFFSET) != 0)
+ size += 1;
return size;
}
@@ -113,11 +259,12 @@ public class Mdr7 extends MdrMapSection {
* Value of 3 possibly the existence of the lbl field.
*/
public int getExtraValue() {
- int magic = 0x42;
+ int magic = MDR7_U1 | MDR7_HAS_NAME_OFFSET | (u2size << MDR7_PARTIAL_SHIFT);
+
if (isForDevice()) {
- magic |= 0x4;
+ magic |= MDR7_U2;
} else {
- magic |= 0x1; //strings
+ magic |= MDR7_HAS_STRING;
}
return magic;
diff --git a/src/uk/me/parabola/imgfmt/app/mdr/Mdr7Record.java b/src/uk/me/parabola/imgfmt/app/mdr/Mdr7Record.java
index d26af18..6a3562e 100644
--- a/src/uk/me/parabola/imgfmt/app/mdr/Mdr7Record.java
+++ b/src/uk/me/parabola/imgfmt/app/mdr/Mdr7Record.java
@@ -23,6 +23,12 @@ public class Mdr7Record extends RecordBase implements NamedRecord {
private int index;
private Mdr5Record city;
+ // For searching on partial names
+ private byte nameOffset; // offset into the name where matching should start
+ private byte outNameOffset; // offset into the encoded output name
+ private byte prefixOffset; // offset after 0x1e prefix
+ private byte suffixOffset; // offset just before 0x1f suffix
+
public int getLabelOffset() {
return labelOffset;
}
@@ -63,6 +69,43 @@ public class Mdr7Record extends RecordBase implements NamedRecord {
return city;
}
+ public void setNameOffset(byte nameOffset) {
+ this.nameOffset = nameOffset;
+ }
+
+ public byte getOutNameOffset() {
+ return outNameOffset;
+ }
+
+ public void setOutNameOffset(byte outNameOffset) {
+ this.outNameOffset = outNameOffset;
+ }
+
+ public void setPrefixOffset(byte prefixOffset) {
+ this.prefixOffset = prefixOffset;
+ }
+
+ public void setSuffixOffset(byte suffixOffset) {
+ this.suffixOffset = suffixOffset;
+ }
+
+ /**
+ * Get the name starting at the given nameOffset.
+ *
+ * To avoid creating unnecessary objects, a check is made for an offset of zero
+ * and the original name string is returned.
+ *
+ * @return A substring of name, starting at the nameOffset value.
+ */
+ public String getPartialName() {
+ if (nameOffset == 0 && prefixOffset == 0 && suffixOffset == 0)
+ return name;
+ else if ((suffixOffset & 0xff) > 0)
+ return name.substring((nameOffset & 0xff) + (prefixOffset & 0xff), (suffixOffset & 0xff));
+ else
+ return name.substring((nameOffset & 0xff) + (prefixOffset & 0xff));
+ }
+
public String toString() {
return name + " in " + city.getName();
}
diff --git a/src/uk/me/parabola/imgfmt/app/mdr/MdrConfig.java b/src/uk/me/parabola/imgfmt/app/mdr/MdrConfig.java
index 893e83f..a3bcf6e 100644
--- a/src/uk/me/parabola/imgfmt/app/mdr/MdrConfig.java
+++ b/src/uk/me/parabola/imgfmt/app/mdr/MdrConfig.java
@@ -32,6 +32,7 @@ public class MdrConfig {
private int headerLen = DEFAULT_HEADER_LEN;
private Sort sort;
private File outputDir;
+ private boolean splitName;
/**
* True if we are creating the file, rather than reading it.
@@ -87,4 +88,12 @@ public class MdrConfig {
if (outputDir != null)
this.outputDir = new File(outputDir);
}
+
+ public void setSplitName(boolean splitName) {
+ this.splitName = splitName;
+ }
+
+ public boolean isSplitName() {
+ return splitName;
+ }
}
diff --git a/src/uk/me/parabola/mkgmap/combiners/GmapsuppBuilder.java b/src/uk/me/parabola/mkgmap/combiners/GmapsuppBuilder.java
index f173a2c..8c9005a 100644
--- a/src/uk/me/parabola/mkgmap/combiners/GmapsuppBuilder.java
+++ b/src/uk/me/parabola/mkgmap/combiners/GmapsuppBuilder.java
@@ -83,6 +83,7 @@ public class GmapsuppBuilder implements Combiner {
// There is a separate MDR and SRT file for each family id in the gmapsupp
private final Map<Integer, MdrBuilder> mdrBuilderMap = new LinkedHashMap<Integer, MdrBuilder>();
private final Map<Integer, Sort> sortMap = new LinkedHashMap<Integer, Sort>();
+ private boolean splitName;
public void init(CommandArgs args) {
@@ -90,6 +91,7 @@ public class GmapsuppBuilder implements Combiner {
mapsetName = args.get("mapset-name", "OSM map set");
overallDescription = args.getDescription();
outputDir = args.getOutputDir();
+ splitName = args.get("split-name-index", false);
}
/**
@@ -106,7 +108,7 @@ public class GmapsuppBuilder implements Combiner {
return mdrBuilder;
mdrBuilder = new MdrBuilder();
- mdrBuilder.initForDevice(sort, outputDir);
+ mdrBuilder.initForDevice(sort, outputDir, splitName);
mdrBuilderMap.put(familyId, mdrBuilder);
return mdrBuilder;
}
diff --git a/src/uk/me/parabola/mkgmap/combiners/MdrBuilder.java b/src/uk/me/parabola/mkgmap/combiners/MdrBuilder.java
index 63362bd..487cfc4 100644
--- a/src/uk/me/parabola/mkgmap/combiners/MdrBuilder.java
+++ b/src/uk/me/parabola/mkgmap/combiners/MdrBuilder.java
@@ -111,6 +111,7 @@ public class MdrBuilder implements Combiner {
config.setForDevice(false);
config.setOutputDir(outputDir);
config.setSort(sort);
+ config.setSplitName(args.get("split-name-index", false));
// Wrap the MDR channel with the MDRFile object
mdrFile = new MDRFile(mdrChan, config);
@@ -128,13 +129,14 @@ public class MdrBuilder implements Combiner {
}
}
- void initForDevice(Sort sort, String outputDir) {
+ void initForDevice(Sort sort, String outputDir, boolean splitName) {
// Set the options that we are using for the mdr.
MdrConfig config = new MdrConfig();
config.setHeaderLen(568);
config.setWritable(true);
config.setForDevice(true);
config.setSort(sort);
+ config.setSplitName(splitName);
// Wrap the MDR channel with the MDRFile object
try {
diff --git a/src/uk/me/parabola/mkgmap/osmstyle/RuleFileReader.java b/src/uk/me/parabola/mkgmap/osmstyle/RuleFileReader.java
index 1d69c56..ff6b4f9 100644
--- a/src/uk/me/parabola/mkgmap/osmstyle/RuleFileReader.java
+++ b/src/uk/me/parabola/mkgmap/osmstyle/RuleFileReader.java
@@ -352,28 +352,34 @@ public class RuleFileReader {
// Transform ((first | second) & topSecond)
// into (first & topSecond) | (second & topSecond)
- Op first = op1.getFirst();
- OrOp orOp = new OrOp();
+ return distrubute(op1, top.getSecond());
+ } else {
+ // This shouldn't happen
+ throw new SyntaxException("X3:" + op1.getType());
+ }
+ return top;
+ }
- Op topSecond = top.getSecond();
+ private static OrOp distrubute(Op op1, Op topSecond) {
+ Op first = op1.getFirst();
+ OrOp orOp = new OrOp();
- AndOp and1 = new AndOp();
- and1.setFirst(first);
- and1.setSecond(topSecond);
+ BinaryOp and1 = new AndOp();
+ and1.setFirst(first);
+ and1.setSecond(topSecond);
- AndOp and2 = new AndOp();
- Op second = rearrangeExpression(op1.getSecond());
+ BinaryOp and2 = new AndOp();
+ Op second = rearrangeExpression(op1.getSecond());
+ if (second.isType(OR)) {
+ and2 = distrubute(second, topSecond);
+ } else {
and2.setFirst(second);
and2.setSecond(topSecond);
-
- orOp.setFirst(and1);
- orOp.setSecond(and2);
- return orOp;
- } else {
- // This shouldn't happen
- throw new SyntaxException("X3:" + op1.getType());
}
- return top;
+ orOp.setFirst(and1);
+ orOp.setSecond(and2);
+
+ return orOp;
}
/**
diff --git a/src/uk/me/parabola/mkgmap/scan/SyntaxException.java b/src/uk/me/parabola/mkgmap/scan/SyntaxException.java
index 66c80da..e533913 100644
--- a/src/uk/me/parabola/mkgmap/scan/SyntaxException.java
+++ b/src/uk/me/parabola/mkgmap/scan/SyntaxException.java
@@ -47,7 +47,7 @@ public class SyntaxException extends RuntimeException {
if (fileName != null)
fmt.format("(%s:%d): ", fileName, lineNumber);
- fmt.format(super.getMessage());
+ fmt.format("%s", super.getMessage());
return fmt.toString();
}
}
diff --git a/test/resources/rules/multi-or-twice.test b/test/resources/rules/multi-or-twice.test
new file mode 100644
index 0000000..30e97df
--- /dev/null
+++ b/test/resources/rules/multi-or-twice.test
@@ -0,0 +1,18 @@
+
+WAY
+highway=primary
+name=b
+a=2
+b=5
+
+<<<lines>>>
+
+(highway=secondary | a=2 | b=5) & (highway=service | a=0 | b=5) { set name='a${name}' }
+
+highway=* [0x2]
+
+<finalize>
+highway=* {name '${name}' }
+
+<<<results>>>
+WAY 1: Line 0x2, labels=[ab, null, null, null], res=24-24 (1/1),(2/2),
diff --git a/test/resources/rules/multi-or-with-and.test b/test/resources/rules/multi-or-with-and.test
new file mode 100644
index 0000000..e9d3267
--- /dev/null
+++ b/test/resources/rules/multi-or-with-and.test
@@ -0,0 +1,19 @@
+
+WAY
+highway=primary
+name=b
+c=60
+d=50
+
+<<<lines>>>
+
+(highway=primary | name=b | d=50) & highway=primary {
+ set name='a${name}'
+}
+
+highway=primary [0x2]
+
+<finalize>
+highway=* {name '${name}'}
+<<<results>>>
+WAY 1: Line 0x2, labels=[ab, null, null, null], res=24-24 (1/1),(2/2),
diff --git a/test/resources/rules/or-at-end.test b/test/resources/rules/or-at-end.test
new file mode 100644
index 0000000..3ff0d02
--- /dev/null
+++ b/test/resources/rules/or-at-end.test
@@ -0,0 +1,30 @@
+
+WAY
+highway=tertiary
+name=b
+oneway=1
+cycleway=opposite
+
+WAY 2
+highway=tertiary
+name=b
+oneway=1
+cycleway=opposite_lane
+
+
+<<<lines>>>
+highway ~ '(secondary|tertiary|unclassified|residential|minor|living_street|service)'
+ & oneway=*
+ & (cycleway=opposite | cycleway=opposite_lane | cycleway=opposite_track )
+ { set name='a${name}' }
+ [0x2 ]
+
+
+<finalize>
+highway=* {name '${name}' }
+
+<<<results>>>
+WAY 1: Line 0x2, labels=[ab, null, null, null], res=24-24 oneway (1/1),(2/2),
+WAY 2: Line 0x2, labels=[ab, null, null, null], res=24-24 oneway (1/1),(2/2),
+
+
diff --git a/test/uk/me/parabola/mkgmap/osmstyle/RuleFileReaderTest.java b/test/uk/me/parabola/mkgmap/osmstyle/RuleFileReaderTest.java
index c9423b6..99ef40c 100644
--- a/test/uk/me/parabola/mkgmap/osmstyle/RuleFileReaderTest.java
+++ b/test/uk/me/parabola/mkgmap/osmstyle/RuleFileReaderTest.java
@@ -406,6 +406,7 @@ public class RuleFileReaderTest {
type = getFirstType(rs, el);
assertNotNull(type);
+ el = el.copy(); // Copy for LinkedOp which remembers the last matched element
el.addTag("cycleway", "opposite_lane");
type = getFirstType(rs, el);
assertNotNull(type);
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/mkgmap.git
More information about the Pkg-grass-devel
mailing list