[mkgmap-dev] How to solve/debug weird problem
From Johannes Formann johannes at formann.de on Thu Jan 13 21:32:07 GMT 2011
WanMil <wmgcnfg at 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) {
- Previous message: [mkgmap-dev] How to solve/debug weird problem
- Next message: [mkgmap-dev] How to solve/debug weird problem
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the mkgmap-dev mailing list