diff --git a/brouter-core/pom.xml b/brouter-core/pom.xml
index 43b909f..eb6ffcb 100644
--- a/brouter-core/pom.xml
+++ b/brouter-core/pom.xml
@@ -37,5 +37,10 @@
junit
test
+
+ org.apache.commons
+ commons-text
+ 1.8
+
diff --git a/brouter-core/src/main/java/btools/router/OsmTrack.java b/brouter-core/src/main/java/btools/router/OsmTrack.java
index 9a2c7ed..9d8a2e1 100644
--- a/brouter-core/src/main/java/btools/router/OsmTrack.java
+++ b/brouter-core/src/main/java/btools/router/OsmTrack.java
@@ -26,6 +26,7 @@ import btools.mapaccess.MatchedWaypoint;
import btools.mapaccess.OsmPos;
import btools.util.CompactLongMap;
import btools.util.FrozenLongMap;
+import org.apache.commons.text.StringEscapeUtils;
public final class OsmTrack
{
@@ -39,6 +40,8 @@ public final class OsmTrack
public boolean showspeed;
+ public List pois = new ArrayList();
+
private static class OsmPathElementHolder
{
public OsmPathElement node;
@@ -534,13 +537,23 @@ public final class OsmTrack
}
}
+ for( int i=0; i<=pois.size() - 1; i++ )
+ {
+ OsmNodeNamed poi = pois.get(i);
+ sb.append( " \n" )
+ .append( " " ).append( StringEscapeUtils.escapeXml10(poi.name) ).append( "\n" )
+ .append( " \n" );
+ }
+
if ( exportWaypoints )
{
for( int i=0; i<=matchedWaypoints.size() - 1; i++ )
{
- sb.append( " \n" )
- .append( " " ).append( matchedWaypoints.get(i).name ).append( "\n" );
+ MatchedWaypoint wt = matchedWaypoints.get(i);
+ sb.append( " \n" )
+ .append( " " ).append( StringEscapeUtils.escapeXml10(wt.name) ).append( "\n" );
if(i == 0)
{
sb.append( " from\n" );
@@ -637,40 +650,27 @@ public final class OsmTrack
sb.append( " \n" );
sb.append( " \n" );
sb.append( " \n" );
- if ( exportWaypoints )
+ if ( exportWaypoints || !pois.isEmpty() )
{
+ if (!pois.isEmpty()) {
sb.append( " \n" );
- sb.append( " start\n" );
- sb.append( " \n" );
- sb.append( " " + matchedWaypoints.get(0).name + "\n" );
- sb.append( " \n" );
- sb.append( " " + formatILon(matchedWaypoints.get(0).waypoint.ilon) + "," + formatILat(matchedWaypoints.get(0).waypoint.ilat) + "\n" );
- sb.append( " \n" );
- sb.append( " \n" );
- sb.append( " \n" );
- if (matchedWaypoints.size() > 2) {
- sb.append( " \n" );
- sb.append( " via\n" );
- for( int i=1; i<=matchedWaypoints.size() - 2; i++ )
- {
- sb.append( " \n" );
- sb.append( " " + matchedWaypoints.get(i).name + "\n" );
- sb.append( " \n" );
- sb.append( " " + formatILon(matchedWaypoints.get(i).waypoint.ilon) + "," + formatILat(matchedWaypoints.get(i).waypoint.ilat) + "\n" );
- sb.append( " \n" );
- sb.append( " \n" );
- }
- sb.append( " \n" );
+ sb.append(" poi\n");
+ for (int i = 0; i < pois.size(); i++) {
+ OsmNodeNamed poi = pois.get(i);
+ createPlaceMark(sb, poi.name, poi.ilat, poi.ilon);
}
- sb.append( " \n" );
- sb.append( " end\n" );
- sb.append( " \n" );
- sb.append( " " + matchedWaypoints.get(matchedWaypoints.size() - 1).name + "\n" );
- sb.append( " \n" );
- sb.append( " " + formatILon(matchedWaypoints.get(matchedWaypoints.size() - 1).waypoint.ilon) + "," + formatILat(matchedWaypoints.get(matchedWaypoints.size() - 1).waypoint.ilat) + "\n" );
- sb.append( " \n" );
- sb.append( " \n" );
- sb.append( " \n" );
+ sb.append(" \n");
+ }
+
+ if (exportWaypoints)
+ {
+ int size = matchedWaypoints.size();
+ createFolder(sb, "start", matchedWaypoints.subList(0, 1));
+ if (matchedWaypoints.size() > 2) {
+ createFolder(sb, "via", matchedWaypoints.subList(1, size - 1));
+ }
+ createFolder(sb, "end", matchedWaypoints.subList(size - 1, size));
+ }
}
sb.append( " \n" );
sb.append( "\n" );
@@ -678,6 +678,25 @@ public final class OsmTrack
return sb.toString();
}
+ private void createFolder(StringBuilder sb, String type, List waypoints) {
+ sb.append( " \n" );
+ sb.append( " " + type + "\n" );
+ for (int i = 0; i < waypoints.size(); i++) {
+ MatchedWaypoint wp = waypoints.get(i);
+ createPlaceMark(sb, wp.name, wp.waypoint.ilat, wp.waypoint.ilon);
+ }
+ sb.append( " \n" );
+ }
+
+ private void createPlaceMark(StringBuilder sb, String name, int ilat, int ilon) {
+ sb.append(" \n");
+ sb.append(" " + StringEscapeUtils.escapeXml10(name) + "\n");
+ sb.append(" \n");
+ sb.append(" " + formatILon(ilon) + "," + formatILat(ilat) + "\n");
+ sb.append(" \n");
+ sb.append(" \n");
+ }
+
public List iternity;
public String formatAsGeoJson()
@@ -773,45 +792,40 @@ public final class OsmTrack
sb.append( " ]\n" );
sb.append( " }\n" );
- if ( exportWaypoints )
+ if ( exportWaypoints || !pois.isEmpty())
{
- sb.append( " },\n" );
- for( int i=0; i<=matchedWaypoints.size() - 1; i++ )
- {
- sb.append( " {\n" );
- sb.append( " \"type\": \"Feature\",\n" );
- sb.append( " \"properties\": {\n" );
- sb.append( " \"name\": \"" + matchedWaypoints.get(i).name + "\",\n" );
- if(i == 0)
- {
- sb.append( " \"type\": \"from\"\n" );
- }
- else if (i == matchedWaypoints.size() - 1)
- {
- sb.append( " \"type\": \"to\"\n" );
- }
- else
- sb.append( " \"type\": \"via\"\n" );
- {
- }
- sb.append( " },\n" );
- sb.append( " \"geometry\": {\n" );
- sb.append( " \"type\": \"Point\",\n" );
- sb.append( " \"coordinates\": [\n" );
- sb.append( " " + formatILon(matchedWaypoints.get(i).waypoint.ilon) + ",\n" );
- sb.append( " " + formatILat(matchedWaypoints.get(i).waypoint.ilat) + "\n" );
- sb.append( " ]\n" );
- sb.append( " }\n" );
- if (i < matchedWaypoints.size() - 1) {
- sb.append( " },\n" );
- }
- else {
- sb.append( " }\n" );
- }
+ sb.append( " },\n" );
+ for( int i=0; i<=pois.size() - 1; i++ )
+ {
+ OsmNodeNamed poi = pois.get(i);
+ addFeature(sb, "poi", poi.name, poi.ilat, poi.ilon);
+ if (i < matchedWaypoints.size() - 1) {
+ sb.append(",");
}
+ sb.append( " \n" );
+ }
+ if (exportWaypoints) {
+ for (int i = 0; i <= matchedWaypoints.size() - 1; i++) {
+ String type;
+ if (i == 0) {
+ type = "from";
+ } else if (i == matchedWaypoints.size() - 1) {
+ type = "to";
+ } else {
+ type = "via";
+ }
+
+ MatchedWaypoint wp = matchedWaypoints.get(i);
+ addFeature(sb, type, wp.name, wp.waypoint.ilat, wp.waypoint.ilon);
+ if (i < matchedWaypoints.size() - 1) {
+ sb.append(",");
+ }
+ sb.append(" \n");
+ }
+ }
}
else {
- sb.append( " }\n" );
+ sb.append( " }\n" );
}
sb.append( " ]\n" );
sb.append( "}\n" );
@@ -819,6 +833,23 @@ public final class OsmTrack
return sb.toString();
}
+ private void addFeature(StringBuilder sb, String type, String name, int ilat, int ilon) {
+ sb.append( " {\n" );
+ sb.append( " \"type\": \"Feature\",\n" );
+ sb.append( " \"properties\": {\n" );
+ sb.append( " \"name\": \"" + StringEscapeUtils.escapeJson(name) + "\",\n" );
+ sb.append( " \"type\": \"" + type + "\"\n" );
+ sb.append( " },\n" );
+ sb.append( " \"geometry\": {\n" );
+ sb.append( " \"type\": \"Point\",\n" );
+ sb.append( " \"coordinates\": [\n" );
+ sb.append( " " + formatILon(ilon) + ",\n" );
+ sb.append( " " + formatILat(ilat) + "\n" );
+ sb.append( " ]\n" );
+ sb.append( " }\n" );
+ sb.append( " }" );
+ }
+
private int getVNode( int i )
{
MessageData m1 = i+1 < nodes.size() ? nodes.get(i+1).message : null;
@@ -841,18 +872,18 @@ public final class OsmTrack
public String getFormattedTime2()
{
- int seconds = (int)(getTotalSeconds() + 0.5);
- int hours = seconds/3600;
- int minutes = (seconds - hours * 3600) / 60;
- seconds = seconds - hours * 3600 - minutes * 60;
- String time = "";
- if (hours != 0)
- time = "" + hours + "h ";
- if (minutes != 0)
- time = time + minutes + "m ";
- if (seconds != 0)
- time = time + seconds + "s";
- return time;
+ int seconds = (int)(getTotalSeconds() + 0.5);
+ int hours = seconds/3600;
+ int minutes = (seconds - hours * 3600) / 60;
+ seconds = seconds - hours * 3600 - minutes * 60;
+ String time = "";
+ if (hours != 0)
+ time = "" + hours + "h ";
+ if (minutes != 0)
+ time = time + minutes + "m ";
+ if (seconds != 0)
+ time = time + seconds + "s";
+ return time;
}
public String getFormattedEnergy()
diff --git a/brouter-core/src/main/java/btools/router/RoutingContext.java b/brouter-core/src/main/java/btools/router/RoutingContext.java
index be0fe55..78dccd3 100644
--- a/brouter-core/src/main/java/btools/router/RoutingContext.java
+++ b/brouter-core/src/main/java/btools/router/RoutingContext.java
@@ -21,7 +21,7 @@ import btools.util.CheapRuler;
public final class RoutingContext
{
- public void setAlternativeIdx( int idx )
+ public void setAlternativeIdx(int idx )
{
alternativeIdx = idx;
}
@@ -188,6 +188,8 @@ public final class RoutingContext
bikerPower = expctxGlobal.getVariableValue( "bikerPower", 100.f );
}
+ public List poipoints;
+
public List nogopoints = null;
private List keepnogopoints = null;
diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java
index 4be519b..4dcc23a 100644
--- a/brouter-core/src/main/java/btools/router/RoutingEngine.java
+++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java
@@ -446,6 +446,7 @@ public class RoutingEngine extends Thread
totaltrack.appendTrack( seg );
lastTracks[i] = seg;
}
+ if (routingContext.poipoints != null) totaltrack.pois = routingContext.poipoints;
totaltrack.matchedWaypoints = matchedWaypoints;
return totaltrack;
}
diff --git a/brouter-server/src/main/java/btools/server/request/ServerHandler.java b/brouter-server/src/main/java/btools/server/request/ServerHandler.java
index 62a2bce..023ee50 100644
--- a/brouter-server/src/main/java/btools/server/request/ServerHandler.java
+++ b/brouter-server/src/main/java/btools/server/request/ServerHandler.java
@@ -1,5 +1,6 @@
package btools.server.request;
+import btools.mapaccess.OsmNode;
import btools.router.OsmNodeNamed;
import btools.router.OsmNogoPolygon;
import btools.router.OsmTrack;
@@ -25,10 +26,11 @@ import java.util.List;
* format = [kml|gpx|geojson] (optional, default gpx)
* trackname = name used for filename and format specific trackname (optional, default brouter)
* exportWaypoints = 1 to export them (optional, default is no export)
+ * pois = lon,lat,name|... (optional)
*
* Example URLs:
* {@code http://localhost:17777/brouter?lonlats=8.799297,49.565883|8.811764,49.563606&nogos=&profile=trekking&alternativeidx=0&format=gpx}
- * {@code http://localhost:17777/brouter?lonlats=1.1,1.2|2.1,2.2|3.1,3.2|4.1,4.2&nogos=-1.1,-1.2,1|-2.1,-2.2,2&profile=shortest&alternativeidx=1&format=kml&trackname=Ride}
+ * {@code http://localhost:17777/brouter?lonlats=1.1,1.2|2.1,2.2|3.1,3.2|4.1,4.2&nogos=-1.1,-1.2,1|-2.1,-2.2,2&profile=shortest&alternativeidx=1&format=kml&trackname=Ride&pois=1.1,2.1,Barner Bar}
*
*/
public class ServerHandler extends RequestHandler {
@@ -62,6 +64,9 @@ public class ServerHandler extends RequestHandler {
rc.setAlternativeIdx(Integer.parseInt(params.get( "alternativeidx" )));
+ List poisList = readPoisList();
+ rc.poipoints = poisList;
+
List nogoList = readNogoList();
List nogoPolygonsList = readNogoPolygons();
@@ -226,6 +231,29 @@ public class ServerHandler extends RequestHandler {
return n;
}
+ private List readPoisList()
+ {
+ // lon,lat,name|...
+ String pois = params.get( "pois" );
+ if ( pois == null ) return null;
+
+ String[] lonLatNameList = pois.split("\\|");
+
+ List poisList = new ArrayList();
+ for (int i = 0; i < lonLatNameList.length; i++)
+ {
+ String[] lonLatName = lonLatNameList[i].split(",");
+
+ OsmNodeNamed n = new OsmNodeNamed();
+ n.ilon = (int)( ( Double.parseDouble(lonLatName[0]) + 180. ) *1000000. + 0.5);
+ n.ilat = (int)( ( Double.parseDouble(lonLatName[1]) + 90. ) *1000000. + 0.5);
+ n.name = lonLatName[2];
+ poisList.add(n);
+ }
+
+ return poisList;
+ }
+
private List readNogoList()
{
// lon,lat,radius|...