WanMil <wmgc...@web.de> wrote:

Hello WanMil,


> what do you mean with "branch"?

I mean a branch of the original "Radkarte". The original author has more or
less abandoned to update the map, so I had startet buildig a map every week
an tweeked a bit the style.

> Which mkgmap release do you use before you apply your patches?

Always trunk/the latest. A svn checkout/update is included in the
build process.

> Can you post the patches here?

At the End of the Message or there:
http://bazaar.launchpad.net/%7Eluckyguess/radkarte/main/annotate/head%3A/generate_ways_from_relations.patch

> Can you explain why you need the generate_ways_from_relations.patch and 
> what that starts_with.patch does?

The "generate_ways_from_relations.patch" is used to give cycleroutes good 
attributes (road_class, speed), so they were preferred over normal roads, 
independed on which roads they actually run. (But dependent on the network 
different, rcn other than ncn and so on).

The starts_with.patch prefixes the POI names, but I could disable it too.
A new map ist currently generatet only with the 
generate_ways_from_relations.patch
an the debug patch from Steve.

> I propose to have a deep look on your patches because we didn't receive 
> any similar complaint on this mailing list before.

I guess the patch must have something to do witch it too, but I don't have
enough knowledge of the mkgmap-internals to dig it out alone.

regards

Johannes



Index: uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java     (revision 1580)
+++ src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java     (working copy)
@@ -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.Map.Entry;
 import java.util.Properties;
@@ -49,6 +51,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;
@@ -173,6 +176,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"));
 
@@ -442,10 +453,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;
@@ -463,6 +502,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());
Index: src/uk/me/parabola/mkgmap/reader/osm/OsmConverter.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/OsmConverter.java      (revision 1580)
+++ src/uk/me/parabola/mkgmap/reader/osm/OsmConverter.java      (working copy)
@@ -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
Index: src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java        
(revision 1580)
+++ src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java        
(working copy)
@@ -623,7 +623,7 @@
 
                long start = System.currentTimeMillis();
                for (Relation r : relationMap.values())
-                       converter.convertRelation(r);
+                       converter.convertRelation(r, wayMap);
 
                for (Node n : nodeMap.values())
                        converter.convertNode(n);
Index: src/uk/me/parabola/mkgmap/reader/osm/GType.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/GType.java     (revision 1580)
+++ src/uk/me/parabola/mkgmap/reader/osm/GType.java     (working copy)
@@ -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;
        }
Index: src/uk/me/parabola/mkgmap/main/StyleTester.java
===================================================================
--- src/uk/me/parabola/mkgmap/main/StyleTester.java     (revision 1580)
+++ src/uk/me/parabola/mkgmap/main/StyleTester.java     (working copy)
@@ -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.regex.Pattern;
 
@@ -273,8 +274,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) {

_______________________________________________
mkgmap-dev mailing list
mkgmap-dev@lists.mkgmap.org.uk
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Reply via email to