Hi, I am very undecided if this option is reasonable or not.
But it's easy to implement so I decided to let you test and decide yourself if it makes sense or not.
Attached patch does the trick. I haven't added an option yet so it works if add-pois-to-areas is set. For each line all points plus the middle point are added as POIs (tagged different with mkgmap:line2poitype).
For lines each POI is tagged additionally with the following tags: mkgmap:line2poi=true mkgmap:line2poitype=start|end|inner|mid Have fun! WanMil
Hi, would an 'add-pois-to-lines' option (similar to the new 'add-pois-to-areas') make sense ? I tried to create an maxspeed layer to show the maxspeeds using the highway-shields, but this didn't work well (because garmin shows the shields only for some roads). With the suggested add-pois-to-lines it would be possible to show little maxspeed icons (30) (50) etc. on the roads or to show incline-icons on roads which have an incline=* tag. Chris _______________________________________________ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Index: src/uk/me/parabola/mkgmap/reader/osm/Areas2POIHook.java =================================================================== --- src/uk/me/parabola/mkgmap/reader/osm/Areas2POIHook.java (revision 2063) +++ src/uk/me/parabola/mkgmap/reader/osm/Areas2POIHook.java (working copy) @@ -52,6 +52,8 @@ /** Name of the bool tag that is set to true if a POI is created from an area */ public static final String AREA2POI_TAG = "mkgmap:area2poi"; + public static final String LINE2POI_TAG = "mkgmap:line2poi"; + public static final String LINE2POI_TYPE_TAG = "mkgmap:line2poitype"; public boolean init(ElementSaver saver, EnhancedProperties props) { if (props.containsKey("add-pois-to-areas") == false) { @@ -166,60 +168,128 @@ log.debug("Found", labelCoords.size(), "label coords"); int ways2POI = 0; + int lines2POI = 0; for (Way w : saver.getWays().values()) { - // check if it is an area - if (w.isClosed() == false) { - continue; - } - + // check if way has any tags if (w.getTagCount() == 0) { continue; } - + // do not add POIs for polygons created by multipolygon processing if (w.isBoolTag(MultiPolygonRelation.MP_CREATED_TAG)) { log.debug("MP processed: Do not create POI for", w.toTagString()); continue; } - // get the coord where the poi is placed - Coord poiCoord = null; - // do we have some labeling coords? - if (labelCoords.size() > 0) { - int poiOrder = Integer.MAX_VALUE; - // go through all points of the way and check if one of the coords - // is a labeling coord - for (Coord c : w.getPoints()) { - Integer cOrder = labelCoords.get(c); - if (cOrder != null && cOrder.intValue() < poiOrder) { - // this coord is a labeling coord - // use it for the current way - poiCoord = c; - poiOrder = cOrder; - if (poiOrder == 0) { - // there is no higher order - break; - } + + // check if it is an area + if (w.isClosed()) { + addPOItoPolygon(w, labelCoords); + ways2POI++; + } else { + lines2POI += addPOItoLine(w); + } + } + + log.error(ways2POI+ " POIs from single areas created"); + log.error(lines2POI+ " POIs from lines created"); + } + + private void addPOItoPolygon(Way polygon, Map<Coord, Integer> labelCoords) { + // get the coord where the poi is placed + Coord poiCoord = null; + // do we have some labeling coords? + if (labelCoords.size() > 0) { + int poiOrder = Integer.MAX_VALUE; + // go through all points of the way and check if one of the coords + // is a labeling coord + for (Coord c : polygon.getPoints()) { + Integer cOrder = labelCoords.get(c); + if (cOrder != null && cOrder.intValue() < poiOrder) { + // this coord is a labeling coord + // use it for the current way + poiCoord = c; + poiOrder = cOrder; + if (poiOrder == 0) { + // there is no higher order + break; } } } - if (poiCoord == null) { - // did not find any label coord - // use the common center point of the area - poiCoord = w.getCofG(); + } + if (poiCoord == null) { + // did not find any label coord + // use the common center point of the area + poiCoord = polygon.getCofG(); + } + + Node poi = createPOI(polygon, poiCoord, AREA2POI_TAG); + saver.addNode(poi); + } + + private int addPOItoLine(Way line) { + Node startNode = createPOI(line, line.getPoints().get(0), LINE2POI_TAG); + startNode.addTag(LINE2POI_TYPE_TAG,"start"); + saver.addNode(startNode); + + Node endNode = createPOI(line, line.getPoints().get(line.getPoints().size()-1), LINE2POI_TAG); + endNode.addTag(LINE2POI_TYPE_TAG,"end"); + saver.addNode(endNode); + + int noPOIs = 2; + + if (line.getPoints().size() > 2) { + for (Coord inPoint : line.getPoints().subList(1, line.getPoints().size()-1)) { + Node innerNode = createPOI(line, inPoint, LINE2POI_TAG); + innerNode.addTag(LINE2POI_TYPE_TAG,"inner"); + saver.addNode(innerNode); + noPOIs++; + } + } + + + // calculate the middle of the line + Coord prevC = null; + double sumDist = 0.0; + ArrayList<Double> dists = new ArrayList<Double>(line.getPoints().size()-1); + for (Coord c : line.getPoints()) { + if (prevC != null) { + double dist = prevC.distance(c); + dists.add(dist); + sumDist+=dist; } - - Node poi = new Node(FakeIdGenerator.makeFakeId(), poiCoord); - poi.copyTags(w); - poi.deleteTag(MultiPolygonRelation.STYLE_FILTER_TAG); - poi.addTag(AREA2POI_TAG, "true"); - log.debug("Create POI",poi.toTagString(),"from",w.getId(),w.toTagString()); - saver.addNode(poi); - ways2POI++; + prevC = c; + } + + Coord midPoint = null; + double remMidDist = sumDist/2; + for (int midPos =0; midPos < dists.size(); midPos++) { + double nextDist = dists.get(midPos); + if (remMidDist <= nextDist) { + double frac = remMidDist/nextDist; + midPoint = line.getPoints().get(midPos).makeBetweenPoint(line.getPoints().get(midPos+1), frac); + break; + } + remMidDist -= nextDist; } + Node midNode = createPOI(line, midPoint, LINE2POI_TAG); + midNode.addTag(LINE2POI_TYPE_TAG,"mid"); + saver.addNode(midNode); + noPOIs++; + + return noPOIs; + + } + + private Node createPOI(Element source, Coord poiCoord, String poiTypeTag) { + Node poi = new Node(FakeIdGenerator.makeFakeId(), poiCoord); + poi.copyTags(source); + poi.deleteTag(MultiPolygonRelation.STYLE_FILTER_TAG); + poi.addTag(poiTypeTag, "true"); + log.debug("Create POI",poi.toTagString(),"from",source.getId(),source.toTagString()); + return poi; - log.info(ways2POI, "POIs from single areas created"); } private void addPOIsToMPs() { @@ -236,16 +306,13 @@ continue; } - Node poi = new Node(FakeIdGenerator.makeFakeId(), point); - poi.copyTags(r); + Node poi = createPOI(r, point, AREA2POI_TAG); // remove the type tag which makes only sense for relations poi.deleteTag("type"); - poi.addTag(AREA2POI_TAG, "true"); - log.debug("Create POI",poi.toTagString(),"from mp",r.getId(),r.toTagString()); saver.addNode(poi); mps2POI++; } - log.info(mps2POI, "POIs from multipolygons created"); + log.error(mps2POI+ " POIs from multipolygons created"); }
_______________________________________________ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev