Felix,
Please try this new patch to trunk. Don't use any other of my recent
style patches as it contains all the current stuff.
This now suppresses action execution when looking for further matches.
If you want the actions to be executed anyway, add 'with_actions' (or
'withactions', both are recognised).
Also, there is a subtle change in the logic in that now if an action
rule matches but otherwise would be ignored because it's not the first
time through, resolveType() will return null so that if the action rule
is part of a sequence (which it almost certainly is) then the rule
munging engine will go on to look at the next rule in the sequence.
Without that change, I think it would always choose the first rule in
cases like this:
foo=bah { tag=val1 } [0x01 continue]
foo=bah { tag=val2 } [0x02 stop]
Anyway, see what happens.
Mark
diff --git a/src/uk/me/parabola/mkgmap/osmstyle/ActionRule.java b/src/uk/me/parabola/mkgmap/osmstyle/ActionRule.java
index 91bdbee..493d32d 100644
--- a/src/uk/me/parabola/mkgmap/osmstyle/ActionRule.java
+++ b/src/uk/me/parabola/mkgmap/osmstyle/ActionRule.java
@@ -52,12 +52,27 @@ public class ActionRule implements Rule {
this.type = null;
}
+ public GType resolveType(Element el) {
+ return resolveType(el, null);
+ }
+
public GType resolveType(Element el, GType pre) {
if (expression == null || expression.eval(el)) {
- for (Action a : actions)
- a.perform(el);
+ if (type == null || pre == null || pre.isBetterPriority(type)) {
+ // this is the first (or only) time this rule has
+ // matched so execute the actions associated with the
+ // rule
+ for (Action a : actions)
+ a.perform(el);
- return type;
+ return type;
+ }
+ else if(type.alwaysExecuteActions()) {
+ // this is not the first time the rule has matched but
+ // the user wants the actions executed anyway
+ for (Action a : actions)
+ a.perform(el);
+ }
}
return null;
}
diff --git a/src/uk/me/parabola/mkgmap/osmstyle/ExpressionRule.java b/src/uk/me/parabola/mkgmap/osmstyle/ExpressionRule.java
index b7b5248..623f2d5 100644
--- a/src/uk/me/parabola/mkgmap/osmstyle/ExpressionRule.java
+++ b/src/uk/me/parabola/mkgmap/osmstyle/ExpressionRule.java
@@ -36,6 +36,10 @@ public class ExpressionRule implements Rule {
this.gtype = gtype;
}
+ public GType resolveType(Element el) {
+ return resolveType(el, null);
+ }
+
public GType resolveType(Element el, GType pre) {
if (expression.eval(el))
return gtype;
diff --git a/src/uk/me/parabola/mkgmap/osmstyle/FixedRule.java b/src/uk/me/parabola/mkgmap/osmstyle/FixedRule.java
index 315c4ad..4ea40ed 100644
--- a/src/uk/me/parabola/mkgmap/osmstyle/FixedRule.java
+++ b/src/uk/me/parabola/mkgmap/osmstyle/FixedRule.java
@@ -32,6 +32,10 @@ public class FixedRule implements Rule {
this.gtype = gtype;
}
+ public GType resolveType(Element el) {
+ return gtype;
+ }
+
public GType resolveType(Element el, GType pre) {
return gtype;
}
diff --git a/src/uk/me/parabola/mkgmap/osmstyle/RuleSet.java b/src/uk/me/parabola/mkgmap/osmstyle/RuleSet.java
index 33ce15e..6e39800 100644
--- a/src/uk/me/parabola/mkgmap/osmstyle/RuleSet.java
+++ b/src/uk/me/parabola/mkgmap/osmstyle/RuleSet.java
@@ -63,6 +63,10 @@ public class RuleSet implements Rule {
return rules.entrySet();
}
+ public GType resolveType(Element el) {
+ return resolveType(el, null);
+ }
+
public GType resolveType(Element el, GType pre) {
GType foundType = null;
for (String tagKey : el) {
diff --git a/src/uk/me/parabola/mkgmap/osmstyle/SequenceRule.java b/src/uk/me/parabola/mkgmap/osmstyle/SequenceRule.java
index 72b5a59..8430f74 100644
--- a/src/uk/me/parabola/mkgmap/osmstyle/SequenceRule.java
+++ b/src/uk/me/parabola/mkgmap/osmstyle/SequenceRule.java
@@ -34,6 +34,10 @@ import uk.me.parabola.mkgmap.reader.osm.Rule;
public class SequenceRule implements Rule, Iterable<Rule> {
private final List<Rule> ruleList = new ArrayList<Rule>();
+ public GType resolveType(Element el) {
+ return resolveType(el, null);
+ }
+
public GType resolveType(Element el, GType pre) {
for (Rule r : ruleList) {
GType type = r.resolveType(el, pre);
diff --git a/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java b/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
index abc8941..d314fd4 100644
--- a/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
+++ b/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
@@ -276,20 +276,21 @@ public class StyledConverter implements OsmConverter {
preConvertRules(way);
do {
- foundType = wayRules.resolveType(way, foundType);
+ Way dupWay = way.duplicate();
+ foundType = wayRules.resolveType(dupWay, foundType);
if (foundType == null)
return;
- postConvertRules(way, foundType);
+ postConvertRules(dupWay, foundType);
if (foundType.getFeatureKind() == GType.POLYLINE) {
if(foundType.isRoad())
- addRoad(way, foundType);
+ addRoad(dupWay, foundType);
else
- addLine(way, foundType);
+ addLine(dupWay, foundType);
}
else
- addShape(way, foundType);
+ addShape(dupWay, foundType);
} while (!foundType.isFinal());
}
}
diff --git a/src/uk/me/parabola/mkgmap/osmstyle/TypeReader.java b/src/uk/me/parabola/mkgmap/osmstyle/TypeReader.java
index 0c5c193..f5a67af 100644
--- a/src/uk/me/parabola/mkgmap/osmstyle/TypeReader.java
+++ b/src/uk/me/parabola/mkgmap/osmstyle/TypeReader.java
@@ -62,6 +62,8 @@ public class TypeReader {
gt.setContinue();
} else if (w.equals("stop")) {
gt.setFinal();
+ } else if (w.equals("with_actions") || w.equals("withactions")) {
+ gt.alwaysExecuteActions(true);
} else {
throw new SyntaxException(ts, "Unrecognised type command '" + w + '\'');
}
diff --git a/src/uk/me/parabola/mkgmap/reader/osm/GType.java b/src/uk/me/parabola/mkgmap/reader/osm/GType.java
index 9df318d..5f66256 100644
--- a/src/uk/me/parabola/mkgmap/reader/osm/GType.java
+++ b/src/uk/me/parabola/mkgmap/reader/osm/GType.java
@@ -62,6 +62,10 @@ public class GType {
// the final conversion, or whether we shall search
// for further matching elements
private boolean FinalElement = true;
+ // by default, a rule's actions are skipped when searching for
+ // further rules to match - by setting this true, the rule's
+ // actions will always be executed
+ private boolean alwaysExecuteActions = false;
public GType(int featureKind, String type) {
priority = nextPriority();
@@ -202,6 +206,14 @@ public class GType {
public void setContinue() {
FinalElement = false;
}
+
+ public void alwaysExecuteActions(boolean aea) {
+ alwaysExecuteActions = aea;
+ }
+
+ public boolean alwaysExecuteActions() {
+ return alwaysExecuteActions;
+ }
public boolean isFinal() {
return FinalElement;
diff --git a/src/uk/me/parabola/mkgmap/reader/osm/Rule.java b/src/uk/me/parabola/mkgmap/reader/osm/Rule.java
index b709c67..f712e59 100644
--- a/src/uk/me/parabola/mkgmap/reader/osm/Rule.java
+++ b/src/uk/me/parabola/mkgmap/reader/osm/Rule.java
@@ -29,6 +29,15 @@ public interface Rule {
* represent it.
*
* @param el The element as read from an OSM xml file in 'tag' format.
+ * @return Enough information to represent this as a garmin type.
+ */
+ public GType resolveType(Element el);
+
+ /**
+ * Given the element return the garmin type that should be used to
+ * represent it.
+ *
+ * @param el The element as read from an OSM xml file in 'tag' format.
* @param pre The previous garmin type generated from the element.
* @return Enough information to represent this as a garmin type.
*/
_______________________________________________
mkgmap-dev mailing list
[email protected]
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev