Moin, I have to admit, that I have didn't quite understand the processing of the action part of the style rules, when I made the first verwion of the patch. And I also have to admit, that I still do not really understand it. But nevertheless the new version of the patch seems to work for me under certain conditions.
The style syntax ist still the same as in the first version, e.g.: highway=* & surface=concrete {set surface=deleted; set mkgmap_surface=paved} [continue] My patch now works in such a way, that this line will create a normal rule (with priority), but will not create an element in the output during the conversion. The stop/continue extension will loop through the conversion, until no more output types are found (including the empty outputs). During each iteration of the loop the pre and postprocessing is done. The problem now is, that I do not understand, how this processing works, i.e. how the single actions are choosen. This does not seem to matter, if the following condition is obeserved in the preprocessing rules: Each action rule must modify the tags of the element in such a way, that the condition is not fullfilled any more, when the rule is checked again. In the above example the action "set surface=deleted" takes care of this, afterwards the condition "surface=concrete" will not be true any more. So with the patch I was able to preprocess the osm-data with the following rules, to generate a road map, which only differs between paved and unpaved surface and is limited to roads, where motor cars ar e allowed (see preproccessing rules below). Gruss Torsten # Set highway names to include the reference if there is one highway=* & mkmap_name_fixed!=* {name '${name} (${ref})' | '${ref}' | '${name}' ; set mkmap_name_fixed=yes} [continue] #set mkgmap_surface values to either paved or unpaved highway=* & surface=paved {set surface=deleted; set mkgmap_surface=paved} [continue] highway=* & surface=unpaved {set surface=deleted; set mkgmap_surface=unpaved} [continue] highway=* & surface=asphalt {set surface=deleted; set mkgmap_surface=paved} [continue] highway=* & surface=cobblestone {set surface=deleted; set mkgmap_surface=paved} [continue] highway=* & surface=concrete {set surface=deleted; set mkgmap_surface=paved} [continue] highway=* & surface=paving_stones {set surface=deleted; set mkgmap_surface=paved} [continue] highway=* & surface=metal {set surface=deleted; set mkgmap_surface=paved} [continue] highway=* & surface=wood {set surface=deleted; set mkgmap_surface=paved} [continue] highway=* & surface=grass_paver {set surface=deleted; set mkgmap_surface=unpaved} [continue] highway=* & surface=gravel {set surface=deleted; set mkgmap_surface=unpaved} [continue] highway=* & surface=pebblestone {set surface=deleted; set mkgmap_surface=unpaved} [continue] highway=* & surface=grass {set surface=deleted; set mkgmap_surface=unpaved} [continue] highway=* & surface=ground {set surface=deleted; set mkgmap_surface=unpaved} [continue] highway=* & surface=earth {set surface=deleted; set mkgmap_surface=unpaved} [continue] highway=* & surface=dirt {set surface=deleted; set mkgmap_surface=unpaved} [continue] highway=* & surface=mud {set surface=deleted; set mkgmap_surface=unpaved} [continue] highway=* & surface=sand {set surface=deleted; set mkgmap_surface=unpaved} [continue] highway=* & surface=ice_road {set surface=deleted; set mkgmap_surface=unpaved} [continue] #set access values highway=* & mkgmap_routing!=* & motorcar=yes {set mkgmap_routing=allowed; set access=deleted; set bicycle=deleted; set motorcar=deleted; set motor_vehicle=deleted; set vehicle=deleted} [continue] highway=* & mkgmap_routing!=* & motorcar=designated {set mkgmap_routing=allowed; set access=deleted; set bicycle=deleted; set motorcar=deleted; set motor_vehicle=deleted; set vehicle=deleted} [continue] highway=* & mkgmap_routing!=* & motor_vehicle=yes & motorcar!=* {set mkgmap_routing=allowed; set access=deleted; set bicycle=deleted; set motorcar=deleted; set motor_vehicle=deleted; set vehicle=deleted} [continue] highway=* & mkgmap_routing!=* & vehicle=yes & motor_vehicle!=* & motorcar!=* {set mkgmap_routing=allowed; set access=deleted; set bicycle=deleted; set motorcar=deleted; set motor_vehicle=deleted; set vehicle=deleted} [continue] highway=* & mkgmap_routing!=* & access=yes & vehicle!=* & motor_vehicle!=* & motorcar!=* {set mkgmap_routing=allowed; set access=deleted; set bicycle=deleted; set motorcar=deleted; set motor_vehicle=deleted; set vehicle=deleted} [continue] highway=* & mkgmap_routing!=* & (access=* | vehicle=* | motor_vehicle=* | motorcar=*) {set mkgmap_routing=forbidden; set access=deleted; set bicycle=deleted; set motorcar=deleted; set motor_vehicle=deleted; set vehicle=deleted} [continue] highway=* & mkgmap_routing!=* {set mkgmap_routing=allowed; set access=deleted; set bicycle=deleted; set motorcar=deleted; set motor_vehicle=deleted; set vehicle=deleted} [continue] route=* & mkgmap_routing!=* {set mkgmap_routing=allowed; set access=deleted; set bicycle=deleted; set motorcar=deleted; set motor_vehicle=deleted; set vehicle=deleted} [continue] # if the routing is not allowed we need not to continue highway=* & mkgmap_routing=forbidden {set highway=ignore} [stop] route=* & mkgmap_routing=forbidden {set route=ignore} [stop] highway=unclassified & mkgmap_surface=unpaved [0x16 road_class=1 road_speed=1 resolution 22] highway=unclassified & mkgmap_surface!=unpaved [0x06 road_class=1 road_speed=4 resolution 22] ...
Index: src/uk/me/parabola/mkgmap/osmstyle/SequenceRule.java =================================================================== --- src/uk/me/parabola/mkgmap/osmstyle/SequenceRule.java (Revision 1162) +++ src/uk/me/parabola/mkgmap/osmstyle/SequenceRule.java (Arbeitskopie) @@ -34,9 +34,9 @@ public class SequenceRule implements Rule, Iterable<Rule> { private final List<Rule> ruleList = new ArrayList<Rule>(); - public GType resolveType(Element el) { + public GType resolveType(Element el, GType pre) { for (Rule r : ruleList) { - GType type = r.resolveType(el); + GType type = r.resolveType(el, pre); if (type != null) return type; } Index: src/uk/me/parabola/mkgmap/osmstyle/TypeReader.java =================================================================== --- src/uk/me/parabola/mkgmap/osmstyle/TypeReader.java (Revision 1162) +++ src/uk/me/parabola/mkgmap/osmstyle/TypeReader.java (Arbeitskopie) @@ -23,6 +23,9 @@ } public GType readType(TokenScanner ts) { + + GType gt; + // We should have a '[' to start with Token t = ts.nextToken(); if (t == null || t.getType() == TokType.EOF) @@ -34,33 +37,73 @@ ts.skipSpace(); String type = ts.nextValue(); - if (!Character.isDigit(type.charAt(0))) - throw new SyntaxException(ts, "Garmin type number must be first. Saw '" + type + '\''); + if (Character.isDigit(type.charAt(0))) { - log.debug("gtype", type); - GType gt = new GType(kind, type); + log.debug("gtype", type); + gt = new GType(kind, type); + gt.setProcessingAndConversion(); - while (!ts.isEndOfFile()) { - ts.skipSpace(); - String w = ts.nextValue(); - if (w.equals("]")) - break; + while (!ts.isEndOfFile()) { + ts.skipSpace(); + String w = ts.nextValue(); + if (w.equals("]")) + break; - if (w.equals("level")) { - setLevel(ts, gt); - } else if (w.equals("resolution")) { - setResolution(ts, gt); - } else if (w.equals("default_name")) { - gt.setDefaultName(nextValue(ts)); - } else if (w.equals("road_class")) { - gt.setRoadClass(nextIntValue(ts)); - } else if (w.equals("road_speed")) { - gt.setRoadSpeed(nextIntValue(ts)); - } else if (w.equals("copy")) { - // reserved word. not currently used - } else { - throw new SyntaxException(ts, "Unrecognised type command '" + w + '\''); + if (w.equals("level")) { + setLevel(ts, gt); + } else if (w.equals("resolution")) { + setResolution(ts, gt); + } else if (w.equals("default_name")) { + gt.setDefaultName(nextValue(ts)); + } else if (w.equals("road_class")) { + gt.setRoadClass(nextIntValue(ts)); + } else if (w.equals("road_speed")) { + gt.setRoadSpeed(nextIntValue(ts)); + } else if (w.equals("copy")) { + // reserved word. not currently used + } else if (w.equals("continue")) { + gt.setContinue(); + } else if (w.equals("stop")) { + gt.setFinal(); + } else { + throw new SyntaxException(ts, "Unrecognised type command '" + w + '\''); + } } + + } else if (type.equals("continue")) { + + gt = new GType(kind, "0"); + gt.setContinue(); + gt.setProcessingOnly(); + + while (!ts.isEndOfFile()) { + ts.skipSpace(); + String w = ts.nextValue(); + if (w.equals("]")) { + break; + } else { + throw new SyntaxException(ts, "Unrecognised type command '" + w + '\''); + } + } + + } else if (type.equals("stop")) { + + gt = new GType(kind, "0"); + gt.setFinal(); + gt.setProcessingOnly(); + + while (!ts.isEndOfFile()) { + ts.skipSpace(); + String w = ts.nextValue(); + if (w.equals("]")) { + break; + } else { + throw new SyntaxException(ts, "Unrecognised type command '" + w + '\''); + } + } + + } else { + throw new SyntaxException(ts, "Garmin type number must be first. Saw '" + type + '\''); } gt.fixLevels(levels); Index: src/uk/me/parabola/mkgmap/osmstyle/ActionRule.java =================================================================== --- src/uk/me/parabola/mkgmap/osmstyle/ActionRule.java (Revision 1162) +++ src/uk/me/parabola/mkgmap/osmstyle/ActionRule.java (Arbeitskopie) @@ -52,7 +52,7 @@ this.type = null; } - public GType resolveType(Element el) { + public GType resolveType(Element el, GType pre) { if (expression == null || expression.eval(el)) { for (Action a : actions) a.perform(el); Index: src/uk/me/parabola/mkgmap/osmstyle/RuleSet.java =================================================================== --- src/uk/me/parabola/mkgmap/osmstyle/RuleSet.java (Revision 1162) +++ src/uk/me/parabola/mkgmap/osmstyle/RuleSet.java (Arbeitskopie) @@ -63,14 +63,14 @@ return rules.entrySet(); } - public GType resolveType(Element el) { + public GType resolveType(Element el, GType pre) { GType foundType = null; for (String tagKey : el) { Rule rule = rules.get(tagKey); if (rule != null) { - GType type = rule.resolveType(el); + GType type = rule.resolveType(el, pre); if (type != null) { - if (foundType == null || type.isBetterPriority(foundType)) { + if ((foundType == null || type.isBetterPriority(foundType)) && (pre == null || pre.isBetterPriority(type))) { foundType = type; } } Index: src/uk/me/parabola/mkgmap/osmstyle/FixedRule.java =================================================================== --- src/uk/me/parabola/mkgmap/osmstyle/FixedRule.java (Revision 1162) +++ src/uk/me/parabola/mkgmap/osmstyle/FixedRule.java (Arbeitskopie) @@ -32,7 +32,7 @@ this.gtype = gtype; } - public GType resolveType(Element el) { + public GType resolveType(Element el, GType pre) { return gtype; } Index: src/uk/me/parabola/mkgmap/osmstyle/ExpressionRule.java =================================================================== --- src/uk/me/parabola/mkgmap/osmstyle/ExpressionRule.java (Revision 1162) +++ src/uk/me/parabola/mkgmap/osmstyle/ExpressionRule.java (Arbeitskopie) @@ -28,22 +28,22 @@ * @author Steve Ratcliffe */ public class ExpressionRule implements Rule { - private final Op exression; + private final Op expression; private final GType gtype; - public ExpressionRule(Op exression, GType gtype) { - this.exression = exression; + public ExpressionRule(Op expression, GType gtype) { + this.expression = expression; this.gtype = gtype; } - public GType resolveType(Element el) { - if (exression.eval(el)) + public GType resolveType(Element el, GType pre) { + if (expression.eval(el)) return gtype; return null; } public String toString() { - return exression.toString() + ' ' + gtype; + return expression.toString() + ' ' + gtype; } } Index: src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java =================================================================== --- src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java (Revision 1162) +++ src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java (Arbeitskopie) @@ -248,26 +248,40 @@ foundType = makeGTypeFromTags(way); if(foundType == null) return; + if (!foundType.isProcessingOnly()){ + if (foundType.getFeatureKind() == GType.POLYLINE) { + if(foundType.isRoad()) + addRoad(way, foundType); + else + addLine(way, foundType); + } + else + addShape(way, foundType); + } } else { - preConvertRules(way); + do { + foundType = wayRules.resolveType(way, foundType); + if (foundType == null) + return; + + preConvertRules(way); - foundType = wayRules.resolveType(way); - if (foundType == null) - return; + if (!foundType.isProcessingOnly()){ + if (foundType.getFeatureKind() == GType.POLYLINE) { + if(foundType.isRoad()) + addRoad(way, foundType); + else + addLine(way, foundType); + } + else + addShape(way, foundType); + } - postConvertRules(way, foundType); - } + postConvertRules(way, foundType); - if (foundType.getFeatureKind() == GType.POLYLINE) { - if(foundType.isRoad() && - !MapElement.hasExtendedType(foundType.getType())) - addRoad(way, foundType); - else - addLine(way, foundType); + } while (!foundType.isFinal()); } - else - addShape(way, foundType); } /** @@ -283,18 +297,24 @@ foundType = makeGTypeFromTags(node); if(foundType == null) return; + if (!foundType.isProcessingOnly()) + addPoint(node, foundType); } else { - preConvertRules(node); + do { + foundType = nodeRules.resolveType(node, foundType); + if (foundType == null) + return; - foundType = nodeRules.resolveType(node); - if (foundType == null) - return; + preConvertRules(node); - postConvertRules(node, foundType); + if (!foundType.isProcessingOnly()) + addPoint(node, foundType); + + postConvertRules(node, foundType); + + } while (!foundType.isFinal()); } - - addPoint(node, foundType); } /** @@ -350,7 +370,7 @@ public void convertRelation(Relation relation) { // Relations never resolve to a GType and so we ignore the return // value. - relationRules.resolveType(relation); + relationRules.resolveType(relation, null); if(relation instanceof RestrictionRelation) { RestrictionRelation rr = (RestrictionRelation)relation; @@ -383,7 +403,7 @@ clipper.clipShape(shape, collector); - GType pointType = nodeRules.resolveType(way); + GType pointType = nodeRules.resolveType(way, null); if(pointType != null) shape.setPoiType(pointType.getType()); Index: src/uk/me/parabola/mkgmap/reader/osm/Rule.java =================================================================== --- src/uk/me/parabola/mkgmap/reader/osm/Rule.java (Revision 1162) +++ src/uk/me/parabola/mkgmap/reader/osm/Rule.java (Arbeitskopie) @@ -29,7 +29,8 @@ * 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. */ - public GType resolveType(Element el); + public GType resolveType(Element el, GType pre); } Index: src/uk/me/parabola/mkgmap/reader/osm/GType.java =================================================================== --- src/uk/me/parabola/mkgmap/reader/osm/GType.java (Revision 1162) +++ src/uk/me/parabola/mkgmap/reader/osm/GType.java (Arbeitskopie) @@ -39,6 +39,10 @@ private static int nextPriority = 1; private static final int PRIORITY_PUSH = 100000; + // control flag, whether this is an empty dummy element + // for processing rules + private boolean RuleWithoutConversion = false; + private final int featureKind; private final int type; @@ -58,6 +62,11 @@ private boolean road; + // control flag, whether this element defines + // the final conversion, or whether we shall search + // for further matching elements + private boolean FinalElement = true; + public GType(int featureKind, String type) { priority = nextPriority(); this.featureKind = featureKind; @@ -190,6 +199,30 @@ return road; } + public void setFinal() { + FinalElement = true; + } + + public void setContinue() { + FinalElement = false; + } + + public boolean isFinal() { + return FinalElement; + } + + public void setProcessingOnly() { + RuleWithoutConversion = true; + } + + public void setProcessingAndConversion() { + RuleWithoutConversion = false; + } + + public boolean isProcessingOnly() { + return RuleWithoutConversion; + } + public static void push() { nextPriority += PRIORITY_PUSH; }
_______________________________________________ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev