From 8188b17daa35dcdefb9ac74b7501042c222b93b1 Mon Sep 17 00:00:00 2001 From: Alexey Pelykh Date: Sun, 18 Mar 2012 16:16:57 +0200 Subject: [PATCH] Added OSRM usage --- .../osmand/swing/DataExtractionSettings.java | 8 + .../src/net/osmand/swing/MapRouterLayer.java | 153 +++++++++++++++++- .../swing/OsmExtractionPreferencesDialog.java | 25 +++ .../osmand/swing/swing_messages.properties | 1 + 4 files changed, 179 insertions(+), 8 deletions(-) diff --git a/DataExtractionOSM/src/net/osmand/swing/DataExtractionSettings.java b/DataExtractionOSM/src/net/osmand/swing/DataExtractionSettings.java index 54b1278edc..b37aacc62b 100644 --- a/DataExtractionOSM/src/net/osmand/swing/DataExtractionSettings.java +++ b/DataExtractionOSM/src/net/osmand/swing/DataExtractionSettings.java @@ -172,6 +172,14 @@ public class DataExtractionSettings { preferences.put("cityAdminLevel", s); } + public String getOsrmServerAddress(){ + return preferences.get("osrmServerAddress", "http://127.0.0.1:5000"); + } + + public void setOsrmServerAddress(String s){ + preferences.put("osrmServerAddress", s); + } + public boolean isSupressWarningsForDuplicatedId(){ return preferences.getBoolean("supress_duplicated_id", true); } diff --git a/DataExtractionOSM/src/net/osmand/swing/MapRouterLayer.java b/DataExtractionOSM/src/net/osmand/swing/MapRouterLayer.java index a933239228..a349959151 100644 --- a/DataExtractionOSM/src/net/osmand/swing/MapRouterLayer.java +++ b/DataExtractionOSM/src/net/osmand/swing/MapRouterLayer.java @@ -45,6 +45,10 @@ import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONTokener; + public class MapRouterLayer implements MapPanelLayer { @@ -102,7 +106,7 @@ public class MapRouterLayer implements MapPanelLayer { } }; menu.add(end); - Action route = new AbstractAction("Calculate YOURS route") { + Action route_YOURS = new AbstractAction("Calculate YOURS route") { private static final long serialVersionUID = 507156107455281238L; @Override @@ -110,7 +114,7 @@ public class MapRouterLayer implements MapPanelLayer { new Thread(){ @Override public void run() { - List ways = route(startRoute, endRoute); + List ways = route_YOURS(startRoute, endRoute); DataTileManager points = new DataTileManager(); points.setZoom(11); for(Way w : ways){ @@ -122,8 +126,8 @@ public class MapRouterLayer implements MapPanelLayer { }.start(); } }; - menu.add(route); - Action altroute = new AbstractAction("Calculate CloudMade route") { + menu.add(route_YOURS); + Action route_CloudMate = new AbstractAction("Calculate CloudMade route") { private static final long serialVersionUID = 507156107455281238L; @Override @@ -131,7 +135,7 @@ public class MapRouterLayer implements MapPanelLayer { new Thread() { @Override public void run() { - List ways = alternateRoute(startRoute, endRoute); + List ways = route_CloudMate(startRoute, endRoute); DataTileManager points = new DataTileManager(); points.setZoom(11); for (Way w : ways) { @@ -143,7 +147,28 @@ public class MapRouterLayer implements MapPanelLayer { }.start(); } }; - menu.add(altroute); + menu.add(route_CloudMate); + Action route_OSRM = new AbstractAction("Calculate OSRM route") { + private static final long serialVersionUID = 2292361745482584520L; + + @Override + public void actionPerformed(ActionEvent e) { + new Thread() { + @Override + public void run() { + List ways = route_OSRM(startRoute, endRoute); + DataTileManager points = new DataTileManager(); + points.setZoom(11); + for (Way w : ways) { + LatLon n = w.getLatLon(); + points.registerObject(n.getLatitude(), n.getLongitude(), w); + } + map.setPoints(points); + } + }.start(); + } + }; + menu.add(route_OSRM); Action selfRoute = new AbstractAction("Calculate OsmAnd route") { private static final long serialVersionUID = 507156107455281238L; @@ -186,7 +211,7 @@ public class MapRouterLayer implements MapPanelLayer { // 5. max_heigtht, max_width, min_speed, ... // 6. incline ? - public static List route(LatLon start, LatLon end){ + public static List route_YOURS(LatLon start, LatLon end){ List res = new ArrayList(); long time = System.currentTimeMillis(); System.out.println("Route from " + start + " to " + end); @@ -258,7 +283,7 @@ public class MapRouterLayer implements MapPanelLayer { - public List alternateRoute(LatLon start, LatLon end) { + public List route_CloudMate(LatLon start, LatLon end) { List res = new ArrayList(); long time = System.currentTimeMillis(); System.out.println("Cloud made route from " + start + " to " + end); @@ -333,6 +358,118 @@ public class MapRouterLayer implements MapPanelLayer { return res; } + private static Double[] decodeGooglePolylinesFlow(String encodedData) { + final List decodedValues = new ArrayList(); + int rawDecodedValue = 0; + int carriage = 0; + for (int x = 0, xx = encodedData.length(); x < xx; ++x) { + int i = encodedData.charAt(x); + i -= 63; + int _5_bits = i << (32 - 5) >>> (32 - 5); + rawDecodedValue |= _5_bits << carriage; + carriage += 5; + boolean isLast = (i & (1 << 5)) == 0; + if (isLast) { + boolean isNegative = (rawDecodedValue & 1) == 1; + rawDecodedValue >>>= 1; + if (isNegative) { + rawDecodedValue = ~rawDecodedValue; + } + decodedValues.add(((double)rawDecodedValue) / 1e5); + carriage = 0; + rawDecodedValue = 0; + } + } + return decodedValues.toArray(new Double[decodedValues.size()]); + } + public static List route_OSRM(LatLon start, LatLon end){ + List res = new ArrayList(); + long time = System.currentTimeMillis(); + System.out.println("Route from " + start + " to " + end); + if (start != null && end != null) { + try { + StringBuilder uri = new StringBuilder(); + uri.append(DataExtractionSettings.getSettings().getOsrmServerAddress()); + uri.append("/viaroute?"); + uri.append("&loc=").append(start.getLatitude()).append(",").append(start.getLongitude()); + uri.append("&loc=").append(end.getLatitude()).append(",").append(end.getLongitude()); + uri.append("&output=json"); + uri.append("&instructions=false"); + uri.append("&geomformat=cmp"); + + URL url = new URL(uri.toString()); + URLConnection connection = url.openConnection(); + StringBuilder content = new StringBuilder(); + BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + { + String s = null; + boolean fist = true; + while ((s = reader.readLine()) != null) { + if (fist) { + fist = false; + } + content.append(s).append("\n"); + } + System.out.println(content); + } + + final JSONObject jsonContent = (JSONObject)new JSONTokener(content.toString()).nextValue(); + + // Encoded as https://developers.google.com/maps/documentation/utilities/polylinealgorithm + final String routeGeometry = jsonContent.getString("route_geometry"); + final Double[] route = decodeGooglePolylinesFlow(routeGeometry); + double latitude = 0.0; + double longitude = 0.0; + Way w = new Way(-1); + for(int routePointIdx = 0; routePointIdx < route.length / 2; routePointIdx++) { + latitude += route[routePointIdx * 2 + 0]; + longitude += route[routePointIdx * 2 + 1]; + + w.addNode(new net.osmand.osm.Node(latitude, longitude, -1)); + } + + if (!w.getNodes().isEmpty()) { + res.add(w); + } + + /*DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dom = factory.newDocumentBuilder(); + Document doc = dom.parse(new InputSource(new StringReader(content.toString()))); + NodeList list = doc.getElementsByTagName("coordinates"); + for(int i=0; i selfRoute(LatLon start, LatLon end) { List res = new ArrayList(); long time = System.currentTimeMillis(); diff --git a/DataExtractionOSM/src/net/osmand/swing/OsmExtractionPreferencesDialog.java b/DataExtractionOSM/src/net/osmand/swing/OsmExtractionPreferencesDialog.java index 3f800ada6f..e5ba2c5079 100644 --- a/DataExtractionOSM/src/net/osmand/swing/OsmExtractionPreferencesDialog.java +++ b/DataExtractionOSM/src/net/osmand/swing/OsmExtractionPreferencesDialog.java @@ -33,6 +33,7 @@ public class OsmExtractionPreferencesDialog extends JDialog { private JTextField mapZooms; private JTextField lineSmoothness; private JTextField cityAdminLevel; + private JTextField osrmServerAddress; private JTextField renderingTypesFile; private JTextField pathToObfRoutingFile; @@ -143,6 +144,27 @@ public class OsmExtractionPreferencesDialog extends JDialog { constr.gridx = 1; constr.gridy = 2; l.setConstraints(cityAdminLevel, constr); + + label = new JLabel(Messages.getString("OsmExtractionPreferencesDialog.OSRM.SERVER.ADDRESS")); + panel.add(label); + constr = new GridBagConstraints(); + constr.ipadx = 5; + constr.gridx = 0; + constr.gridy = 3; + constr.anchor = GridBagConstraints.WEST; + l.setConstraints(label, constr); + + osrmServerAddress = new JTextField(); + + osrmServerAddress.setText(DataExtractionSettings.getSettings().getOsrmServerAddress()); + panel.add(osrmServerAddress); + constr = new GridBagConstraints(); + constr.weightx = 1; + constr.fill = GridBagConstraints.HORIZONTAL; + constr.ipadx = 5; + constr.gridx = 1; + constr.gridy = 3; + l.setConstraints(osrmServerAddress, constr); // supressWarning = new JCheckBox(); // supressWarning.setText(Messages.getString("OsmExtractionPreferencesDialog.DUPLICATED.ID")); //$NON-NLS-1$ @@ -314,6 +336,9 @@ public class OsmExtractionPreferencesDialog extends JDialog { if(!settings.getCityAdminLevel().equals(cityAdminLevel.getText())){ settings.setCityAdminLevel(cityAdminLevel.getText()); } + if(!settings.getOsrmServerAddress().equals(osrmServerAddress.getText())){ + settings.setOsrmServerAddress(osrmServerAddress.getText()); + } // if(settings.isSupressWarningsForDuplicatedId() != supressWarning.isSelected()){ // settings.setSupressWarningsForDuplicatedId (supressWarning.isSelected()); // } diff --git a/DataExtractionOSM/src/net/osmand/swing/swing_messages.properties b/DataExtractionOSM/src/net/osmand/swing/swing_messages.properties index 1c08e379b1..469d56ecf4 100644 --- a/DataExtractionOSM/src/net/osmand/swing/swing_messages.properties +++ b/DataExtractionOSM/src/net/osmand/swing/swing_messages.properties @@ -38,6 +38,7 @@ OsmExtractionPreferencesDialog.INTERNET.TO.DOWNLOAD.FILES=Use internet to downlo OsmExtractionPreferencesDialog.LOAD.WHOLE.OSM=Load whole osm info (to save valid osm file - use in JOSM...) OsmExtractionPreferencesDialog.NAME.SUFFIXES=Street name suffixes (av., avenue) OsmExtractionPreferencesDialog.NORMALIZE.STREETS=Normalizing streets +OsmExtractionPreferencesDialog.OSRM.SERVER.ADDRESS=OSRM server address and port OsmExtractionPreferencesDialog.OK=OK OsmExtractionPreferencesDialog.PREFERENCES=Preferences OsmExtractionPreferencesDialog.CANCEL=Cancel