logo separator

[mkgmap-dev] How to solve/debug weird problem

From Johannes Formann johannes at formann.de on Fri Jan 14 21:38:28 GMT 2011

WanMil <wmgcnfg at web.de> wrote:

> > I'm quite shure, both are the latest, but when I can archive the same
> > results without the patch (as Thorsten suggested), I'll throw it away.
> 
> Your patch tells you the revision for which the patch is created:
>  > --- src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java 
> (revision 1580)
> You can see it's revision 1580 and not 1773.

You were right, stupid mistake from me.
The used patch were noch included in the repository. The really used
patch is following.


regards

diff -Nru -U1 --exclude='*.orig' mkgmap-r1716-prev/src/uk/me/parabola/mkgmap/main/StyleTester.java mkgmap-r1716/src/uk/me/parabola/mkgmap/main/StyleTester.java
--- mkgmap-r1716-prev/src/uk/me/parabola/mkgmap/main/StyleTester.java   2010-09-24 21:59:49.000000000 +0200
+++ mkgmap-r1716/src/uk/me/parabola/mkgmap/main/StyleTester.java        2010-10-20 23:13:58.000000000 +0200
@@ -29,6 +29,7 @@
 import java.util.Formatter;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
 import java.util.regex.Pattern;
@@ -275,8 +276,8 @@
                converter.convertNode(node);
        }
 
-       public void convertRelation(Relation relation) {
-               converter.convertRelation(relation);
+       public void convertRelation(Relation relation, Map<Long, Way> wayMap) {
+               converter.convertRelation(relation, wayMap);
        }
 
        public void setBoundingBox(Area bbox) {
diff -Nru -U1 --exclude='*.orig' mkgmap-r1716-prev/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java mkgmap-r1716/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
--- mkgmap-r1716-prev/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java   2010-09-26 22:23:54.000000000 +0200
+++ mkgmap-r1716/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java        2010-10-20 23:13:58.000000000 +0200
@@ -19,8 +19,10 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.IdentityHashMap;
 import java.util.List;
+import java.util.ListIterator;
 import java.util.Map;
 import java.util.Properties;
 import java.util.regex.Pattern;
@@ -50,6 +52,7 @@
 import uk.me.parabola.mkgmap.general.RoadNetwork;
 import uk.me.parabola.mkgmap.reader.osm.CoordPOI;
 import uk.me.parabola.mkgmap.reader.osm.Element;
+import uk.me.parabola.mkgmap.reader.osm.FakeIdGenerator;
 import uk.me.parabola.mkgmap.reader.osm.GType;
 import uk.me.parabola.mkgmap.reader.osm.Node;
 import uk.me.parabola.mkgmap.reader.osm.OsmConverter;
@@ -180,6 +183,14 @@
 
        private static final Pattern commaPattern = Pattern.compile(",");
 
+       private String makeKeyFromGType(GType type) {
+               String key = String.valueOf(type.getFeatureKind()) + "," + String.valueOf(type.getType()) + "," + String.valueOf(type.getMinResolution())
+                       + "," + String.valueOf(type.getMaxResolution());
+               if (type.isRoad())
+                       key += "," + String.valueOf(type.getRoadClass()) + "," + String.valueOf(type.getRoadSpeed());
+               return key;
+       }
+
        private GType makeGTypeFromTags(Element element) {
                String[] vals = commaPattern.split(element.getTag("mkgmap:gtype"));
 
@@ -460,10 +471,38 @@
         *
         * @param relation The relation to convert.
         */
-       public void convertRelation(Relation relation) {
-               // Relations never resolve to a GType and so we ignore the return
-               // value.
-               relationRules.resolveType(relation, TypeResult.NULL_RESULT);
+       public void convertRelation(Relation relation, final Map<Long, Way> wayMap) {
+               // If the relation resolves to a GType of a way then add that way to the map
+               preConvertRules(relation);
+               relationRules.resolveType(relation, new TypeResult() {
+                       public void add(Element el, GType type) {
+                               Relation relation = (Relation) el;
+                               postConvertRules(relation, type);
+
+                               // Create a hash set from the relation elements. This makes sure that each element
+                               // occurs at most once.
+                               HashSet<Element> elements = new HashSet(relation.getElements().size());
+                               for (Map.Entry<String,Element> mapEntry : relation.getElements()) {
+                                       elements.add(mapEntry.getValue());
+                               }
+
+                               // Extract all the ways that belong to the relation
+                               List<Way> ways = new ArrayList<Way>(elements.size());
+                               for (Element ele : elements) {
+                                       if (ele instanceof Way)
+                                               addWayToListAndChainIfPossible(ways, (Way) ele, type.isRoad()); // care about oneways if it is a road
+                               }
+
+                               for (Way w : ways) {
+                                       w.setName(relation.getName());
+                                       // Using mkgmap:gtype way to promote the attributes, so that the generated ways can go through the same
+                                       // process as the ways that come directly from the osm data
+                                       type.setFeatureKind(GType.POLYLINE);
+                                       w.addTag("mkgmap:gtype",makeKeyFromGType(type));
+                                       wayMap.put(FakeIdGenerator.makeFakeId(),w);
+                               }
+                       }
+               });
 
                if(relation instanceof RestrictionRelation) {
                        RestrictionRelation rr = (RestrictionRelation)relation;
@@ -481,6 +520,133 @@
                }
        }
 
+       private void addWayToListAndChainIfPossible(List<Way> ways, Way newWay, boolean careAboutOneways) {
+               outer_loop: for (;;) {
+                       List<Coord> newWayCoords = newWay.getPoints();
+                       int newWayNumPoints = newWayCoords.size();
+                       if (newWayNumPoints == 0) return;
+       
+                       Coord newWayFirstCoord = newWayCoords.get(0);
+                       Coord newWayLastCoord = newWayCoords.get(newWayNumPoints-1);
+       
+                       ListIterator<Way> listIterator = ways.listIterator();
+                       while (listIterator.hasNext()) {
+                               Way existantWay = listIterator.next();
+                               List<Coord> existantWayCoords = existantWay.getPoints();
+                               int existantWayNumPoints = existantWayCoords.size();
+                               if (existantWayNumPoints == 0) continue;
+       
+                               Coord existantWayFirstCoord = existantWayCoords.get(0);
+                               Coord existantWayLastCoord = existantWayCoords.get(existantWayNumPoints-1);
+       
+                               // Test coordinates to see whether two way can be chained together
+                               // If they are chained together the only tag we will copy is the oneway tag (if we care about them).
+                               // Access tags will have to be set by the relation!
+                               // TODO: Handle the oneway=-1 tag in a useful way, now it prevents chaining of the ways.
+       
+                               // Both ways share the same first point. So the new way is connected in reverse, but if we care about oneways
+                               // then only if none of them is one.
+                               if (existantWayFirstCoord.equals(newWayFirstCoord) 
+                                       && (!careAboutOneways || (!existantWay.isBoolTag("oneway") && !newWay.isBoolTag("oneway")))) {
+       
+                                       Way replacementWay = new Way(existantWay.getId());
+
+                                       // Add points of new way in reverse
+                                       ListIterator<Coord> newWayCoordIterator = newWayCoords.listIterator(newWayNumPoints);
+                                       while (newWayCoordIterator.hasPrevious()) {
+                                               replacementWay.addPoint(newWayCoordIterator.previous());
+                                       }
+                                       // And of the existant way in order (starting from the second point)
+                                       ListIterator<Coord> existantWayCoordIterator = existantWayCoords.listIterator(1);
+                                       while (existantWayCoordIterator.hasNext()) {
+                                               replacementWay.addPoint(existantWayCoordIterator.next());
+                                       }
+                                       // Remove the existant way that was chained to the new way and start the search again.
+                                       listIterator.remove();
+                                       newWay = replacementWay;
+                                       continue outer_loop;
+                               // The last point of the existant way is the same as the first point of the new way, so they are
+                               // connected in order, but if we care about oneways then only if they either both have the oneway tag or both have not.
+                               } else if (existantWayLastCoord.equals(newWayFirstCoord)
+                                       && (!careAboutOneways || !(existantWay.isBoolTag("oneway") ^ newWay.isBoolTag("oneway")))) {
+       
+                                       Way replacementWay = new Way(existantWay.getId());
+                                       if (careAboutOneways) {
+                                               String onewayValue = existantWay.getTag("oneway");
+                                               if (onewayValue != null)
+                                                       replacementWay.addTag("oneway",onewayValue);
+                                       }
+
+                                       // Add points of existant way in order
+                                       ListIterator<Coord> existantWayCoordIterator = existantWayCoords.listIterator();
+                                       while (existantWayCoordIterator.hasNext()) {
+                                               replacementWay.addPoint(existantWayCoordIterator.next());
+                                       }
+                                       // And of the new way also in order (starting from the second point)
+                                       ListIterator<Coord> newWayCoordIterator = newWayCoords.listIterator(1);
+                                       while (newWayCoordIterator.hasNext()) {
+                                               replacementWay.addPoint(newWayCoordIterator.next());
+                                       }
+                                       // Remove the existant way that was chained to the new way and start the search again.
+                                       listIterator.remove();
+                                       newWay = replacementWay;
+                                       continue outer_loop;
+                               // The first point of the existant way is the same as the last point of the new way, so connect them,
+                               // but starting with the new way and if we care about oneways then only if they either both have the
+                               // oneway tag or both have not.
+                               } else if (existantWayFirstCoord.equals(newWayLastCoord)
+                                       && (!careAboutOneways || (!(existantWay.isBoolTag("oneway") ^ newWay.isBoolTag("oneway"))))) {
+       
+                                       Way replacementWay = new Way(existantWay.getId());
+                                       if (careAboutOneways) {
+                                               String onewayValue = existantWay.getTag("oneway");
+                                               if (onewayValue != null)
+                                                       replacementWay.addTag("oneway",onewayValue);
+                                       }
+
+                                       // Add points of the new way in order
+                                       ListIterator<Coord> newWayCoordIterator = newWayCoords.listIterator();
+                                       while (newWayCoordIterator.hasNext()) {
+                                               replacementWay.addPoint(newWayCoordIterator.next());
+                                       }
+                                       // And of the existant way also in order (starting from the second point)
+                                       ListIterator<Coord> existantWayCoordIterator = existantWayCoords.listIterator(1);
+                                       while (existantWayCoordIterator.hasNext()) {
+                                               replacementWay.addPoint(existantWayCoordIterator.next());
+                                       }
+                                       // Remove the existant way that was chained to the new way and start the search again.
+                                       listIterator.remove();
+                                       newWay = replacementWay;
+                                       continue outer_loop;
+                               // The last points of the existant and the new way are the same. So the new way is connected in reverse,
+                               // but if we care about oneways than only if neither of them has the oneway tag set.
+                               } else if (existantWayLastCoord.equals(newWayLastCoord)
+                                       && (!careAboutOneways || (!existantWay.isBoolTag("oneway") && !newWay.isBoolTag("oneway")))) {
+       
+                                       Way replacementWay = new Way(existantWay.getId());
+
+                                       // Add points of existant way in order
+                                       ListIterator<Coord> existantWayCoordIterator = existantWayCoords.listIterator();
+                                       while (existantWayCoordIterator.hasNext()) {
+                                               replacementWay.addPoint(existantWayCoordIterator.next());
+                                       }
+                                       // And of the new way in reverse (starting from the second last point)
+                                       ListIterator<Coord> newWayCoordIterator = newWayCoords.listIterator(newWayNumPoints-1);
+                                       while (newWayCoordIterator.hasPrevious()) {
+                                               replacementWay.addPoint(newWayCoordIterator.previous());
+                                       }
+                                       // Remove the existant way that was chained to the new way and start the search again.
+                                       listIterator.remove();
+                                       newWay = replacementWay;
+                                       continue outer_loop;
+                               }
+                       }
+                       // If we get here no way was found anymore that we could chain to. Add the way and return.
+                       ways.add(newWay);
+                       return;
+               }
+       }
+
        private void addLine(Way way, GType gt) {
                List<Coord> wayPoints = way.getPoints();
                List<Coord> points = new ArrayList<Coord>(wayPoints.size());
diff -Nru -U1 --exclude='*.orig' mkgmap-r1716-prev/src/uk/me/parabola/mkgmap/reader/osm/ElementSaver.java mkgmap-r1716/src/uk/me/parabola/mkgmap/reader/osm/ElementSaver.java
--- mkgmap-r1716-prev/src/uk/me/parabola/mkgmap/reader/osm/ElementSaver.java    2010-09-26 22:23:54.000000000 +0200
+++ mkgmap-r1716/src/uk/me/parabola/mkgmap/reader/osm/ElementSaver.java 2010-10-20 23:15:33.000000000 +0200
@@ -220,7 +220,7 @@
                coordMap = null;
 
                for (Relation r : relationMap.values())
-                       converter.convertRelation(r);
+                       converter.convertRelation(r,wayMap);
 
                for (Node n : nodeMap.values())
                        converter.convertNode(n);
diff -Nru -U1 --exclude='*.orig' mkgmap-r1716-prev/src/uk/me/parabola/mkgmap/reader/osm/GType.java mkgmap-r1716/src/uk/me/parabola/mkgmap/reader/osm/GType.java
--- mkgmap-r1716-prev/src/uk/me/parabola/mkgmap/reader/osm/GType.java   2010-02-05 16:36:26.000000000 +0100
+++ mkgmap-r1716/src/uk/me/parabola/mkgmap/reader/osm/GType.java        2010-10-20 23:13:58.000000000 +0200
@@ -34,7 +34,7 @@
        public static final int POLYLINE = 2;
        public static final int POLYGON = 3;
 
-       private final int featureKind;
+       private int featureKind;
        private final int type;
 
        private int minResolution = 24;
@@ -79,6 +79,10 @@
                }
        }
 
+       public void setFeatureKind(int featureKind) {
+               this.featureKind = featureKind;
+       }
+
        public int getFeatureKind() {
                return featureKind;
        }
diff -Nru -U1 --exclude='*.orig' mkgmap-r1716-prev/src/uk/me/parabola/mkgmap/reader/osm/OsmConverter.java mkgmap-r1716/src/uk/me/parabola/mkgmap/reader/osm/OsmConverter.java
--- mkgmap-r1716-prev/src/uk/me/parabola/mkgmap/reader/osm/OsmConverter.java    2010-09-24 21:59:49.000000000 +0200
+++ mkgmap-r1716/src/uk/me/parabola/mkgmap/reader/osm/OsmConverter.java 2010-10-20 23:13:58.000000000 +0200
@@ -16,6 +16,8 @@
  */
 package uk.me.parabola.mkgmap.reader.osm;
 
+import java.util.Map;
+
 import uk.me.parabola.imgfmt.app.Area;
 
 /**
@@ -52,7 +54,7 @@
         *
         * @param relation The relation to convert.
         */
-       public void convertRelation(Relation relation);
+       public void convertRelation(Relation relation, Map<Long, Way> wayMap);
 
        /**
         * Set the bounding box for this map.  This should be set before any other




More information about the mkgmap-dev mailing list