On Mon, Dec 14, 2009 at 11:41:05PM +0200, Marko Mäkelä wrote:
> Yet another solution would be to have a special syntax of variable
> substitution that would bypass the valueTags, say, $(var) instead of ${var}:
>
> (type=boundary | type=multipolygon) & boundary=administrative & name=*
> { apply
> {
> set mkgmap:boundary_name='$(mkgmap:boundary_name)/${name}' | '${name}';
> }
> }
I implemented this (see the attached patch). It was easier than I thought,
and the runtime penalty should be low.
Unless someone complains, I will commit this patch tomorrow.
Marko
Index: src/uk/me/parabola/mkgmap/osmstyle/actions/EchoAction.java
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/actions/EchoAction.java (revision 1436)
+++ src/uk/me/parabola/mkgmap/osmstyle/actions/EchoAction.java (working copy)
@@ -30,7 +30,7 @@ public class EchoAction implements Actio
}
public void perform(Element el) {
- String e = value.build(el);
+ String e = value.build(el, el);
System.err.println(el.getId() + ": " + e);
}
}
Index: src/uk/me/parabola/mkgmap/osmstyle/actions/NameAction.java
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/actions/NameAction.java (revision 1436)
+++ src/uk/me/parabola/mkgmap/osmstyle/actions/NameAction.java (working copy)
@@ -46,7 +46,7 @@ public class NameAction implements Actio
return;
for (ValueBuilder vb : names) {
- String s = vb.build(el);
+ String s = vb.build(el, el);
if (s != null) {
el.setName(s);
break;
Index: src/uk/me/parabola/mkgmap/osmstyle/actions/AddTagAction.java
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/actions/AddTagAction.java (revision 1436)
+++ src/uk/me/parabola/mkgmap/osmstyle/actions/AddTagAction.java (working copy)
@@ -54,7 +54,7 @@ public class AddTagAction implements Act
Element tags = valueTags!=null? valueTags: el;
for (ValueBuilder value : values) {
- String newval = value.build(tags);
+ String newval = value.build(tags, el);
if (newval != null) {
el.addTag(tag, newval);
break;
Index: src/uk/me/parabola/mkgmap/osmstyle/actions/ValueBuilder.java
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/actions/ValueBuilder.java (revision 1436)
+++ src/uk/me/parabola/mkgmap/osmstyle/actions/ValueBuilder.java (working copy)
@@ -44,25 +44,26 @@ public class ValueBuilder {
* you to make conditional replacements.
*
* @param el Used as a source of tags.
+ * @param lel Used as a source of local tags.
* @return The built string if all required tags are available. If any
* are missing then it returns null.
*/
- public String build(Element el) {
+ public String build(Element el, Element lel) {
// Check early for no match and return early
for (ValueItem item : items) {
- if (item.getValue(el) == null)
+ if (item.getValue(el, lel) == null)
return null;
}
// If we get here we can build the final string. A common case
// is that there is just one, so return it directly.
if (items.size() == 1)
- return items.get(0).getValue(el);
+ return items.get(0).getValue(el, lel);
// OK we have to construct the result.
StringBuilder sb = new StringBuilder();
for (ValueItem item : items)
- sb.append(item.getValue(el));
+ sb.append(item.getValue(el, lel));
return sb.toString();
}
@@ -86,37 +87,41 @@ public class ValueBuilder {
return;
}
- int state = 0;
+ char state = '\0';
StringBuilder text = new StringBuilder();
StringBuilder tagname = null;
for (char c : in.toCharArray()) {
switch (state) {
- case 0:
+ case '\0':
if (c == '$') {
- state = 1;
+ state = '$';
} else
text.append(c);
break;
- case 1:
- if (c == '{') {
+ case '$':
+ switch (c) {
+ case '{':
+ case '(':
if (text.length() > 0) {
items.add(new ValueItem(text.toString()));
text.setLength(0);
}
tagname = new StringBuilder();
- state = 2;
- } else {
- state = 0;
+ state = (c == '{') ? '}' : ')';
+ break;
+ default:
+ state = '\0';
text.append('$');
text.append(c);
}
break;
- case 2:
- if (c == '}') {
+ case '}':
+ case ')':
+ if (c == state) {
//noinspection ConstantConditions
assert tagname != null;
- addTagValue(tagname.toString());
- state = 0;
+ addTagValue(tagname.toString(), c == ')');
+ state = '\0';
tagname = null;
} else {
tagname.append(c);
@@ -131,16 +136,16 @@ public class ValueBuilder {
items.add(new ValueItem(text.toString()));
}
- private void addTagValue(String tagname) {
+ private void addTagValue(String tagname, boolean is_local) {
ValueItem item = new ValueItem();
if (tagname.contains("|")) {
String[] parts = tagname.split("\\|");
assert parts.length > 1;
- item.setTagname(parts[0]);
+ item.setTagname(parts[0], is_local);
for (int i = 1; i < parts.length; i++)
addFilter(item, parts[i]);
} else {
- item.setTagname(tagname);
+ item.setTagname(tagname, is_local);
}
items.add(item);
}
Index: src/uk/me/parabola/mkgmap/osmstyle/actions/ValueItem.java
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/actions/ValueItem.java (revision 1436)
+++ src/uk/me/parabola/mkgmap/osmstyle/actions/ValueItem.java (working copy)
@@ -26,6 +26,7 @@ import uk.me.parabola.mkgmap.reader.osm.
*/
public class ValueItem {
private String tagname;
+ private boolean tagname_is_local;
private ValueFilter filter;
private String value;
@@ -36,12 +37,13 @@ public class ValueItem {
this.value = value;
}
- public String getValue(Element el) {
+ public String getValue(Element el, Element local_el) {
if (tagname == null && value != null)
return value; // already known
-
+
if (tagname != null) {
- String tagval = el.getTag(tagname);
+ Element e = tagname_is_local ? local_el : el;
+ String tagval = e.getTag(tagname);
if (filter != null)
value = filter.filter(tagval);
else
@@ -58,15 +60,20 @@ public class ValueItem {
filter.add(f);
}
- public void setTagname(String tagname) {
+ public void setTagname(String tagname, boolean local) {
this.tagname = tagname;
+ this.tagname_is_local = local;
}
public String toString() {
- if (tagname != null) {
+ if (tagname == null)
+ return value;
+ if (tagname_is_local) {
+ // TODO: don't ignore filter.
+ return "$(" + tagname + ")";
+ } else {
// TODO: don't ignore filter.
return "${" + tagname + "}";
- } else
- return value;
+ }
}
}
Index: resources/styles/default/relations
===================================================================
--- resources/styles/default/relations (revision 1436)
+++ resources/styles/default/relations (working copy)
@@ -1,7 +1,22 @@
-
-#
-# You can have rules for relations. Usually you will set tags on the
-# elements that make up the relation.
+# -------------------------------------------------------------------
+# This is the default mkgmap style file for applying rules on
+# OSM relations. Usually you will set tags on the
+# elements that make up the relation, and the tags will be
+# processed by the rules defined in the "points" or "lines" files.
#
+# Any line prefaced with # is a comment and will not be applied.
+# Each line is a rule, of the generalised format:
+# OSM_tag(s)_to_match [Garmin_type_code resolution]
+# See http://wiki.openstreetmap.org/wiki/Mkgmap/help/style_rules
+# and http://wiki.openstreetmap.org/wiki/Mkgmap/help/Custom_styles
+# for more information.
+
# eg. type=route & route=bus { apply { set route=bus; add rn='${route_no}' ; }}
#
+
+(type=boundary | type=multipolygon) & boundary=administrative & name=*
+{ apply
+ {
+ set mkgmap:boundary_name='$(mkgmap:boundary_name)/${name}' | '${name}';
+ }
+}
Index: resources/styles/default/lines
===================================================================
--- resources/styles/default/lines (revision 1436)
+++ resources/styles/default/lines (working copy)
@@ -113,7 +113,7 @@ man_made=pipeline {name '${operator}'} [
# The following boundary styles are after the highway rules because ways
# are frequently tagged with both and we want the highway to take priority.
boundary=administrative
-{ name
+{ name '${mkgmap:boundary_name}' |
'${left:country}/${right:country}' |
'${left:state}/${right:state}' |
'${left:district}/${right:district}' |
_______________________________________________
mkgmap-dev mailing list
[email protected]
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev