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

Reply via email to