Merge pull request #197 from alexey-pelykh/osrmIntegration
Added OSRM usage
This commit is contained in:
commit
a2841587bb
4 changed files with 179 additions and 8 deletions
|
@ -172,6 +172,14 @@ public class DataExtractionSettings {
|
||||||
preferences.put("cityAdminLevel", s);
|
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(){
|
public boolean isSupressWarningsForDuplicatedId(){
|
||||||
return preferences.getBoolean("supress_duplicated_id", true);
|
return preferences.getBoolean("supress_duplicated_id", true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,10 @@ import org.w3c.dom.NodeList;
|
||||||
import org.xml.sax.InputSource;
|
import org.xml.sax.InputSource;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.json.JSONTokener;
|
||||||
|
|
||||||
|
|
||||||
public class MapRouterLayer implements MapPanelLayer {
|
public class MapRouterLayer implements MapPanelLayer {
|
||||||
|
|
||||||
|
@ -102,7 +106,7 @@ public class MapRouterLayer implements MapPanelLayer {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
menu.add(end);
|
menu.add(end);
|
||||||
Action route = new AbstractAction("Calculate YOURS route") {
|
Action route_YOURS = new AbstractAction("Calculate YOURS route") {
|
||||||
private static final long serialVersionUID = 507156107455281238L;
|
private static final long serialVersionUID = 507156107455281238L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -110,7 +114,7 @@ public class MapRouterLayer implements MapPanelLayer {
|
||||||
new Thread(){
|
new Thread(){
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
List<Way> ways = route(startRoute, endRoute);
|
List<Way> ways = route_YOURS(startRoute, endRoute);
|
||||||
DataTileManager<Way> points = new DataTileManager<Way>();
|
DataTileManager<Way> points = new DataTileManager<Way>();
|
||||||
points.setZoom(11);
|
points.setZoom(11);
|
||||||
for(Way w : ways){
|
for(Way w : ways){
|
||||||
|
@ -122,8 +126,8 @@ public class MapRouterLayer implements MapPanelLayer {
|
||||||
}.start();
|
}.start();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
menu.add(route);
|
menu.add(route_YOURS);
|
||||||
Action altroute = new AbstractAction("Calculate CloudMade route") {
|
Action route_CloudMate = new AbstractAction("Calculate CloudMade route") {
|
||||||
private static final long serialVersionUID = 507156107455281238L;
|
private static final long serialVersionUID = 507156107455281238L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -131,7 +135,7 @@ public class MapRouterLayer implements MapPanelLayer {
|
||||||
new Thread() {
|
new Thread() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
List<Way> ways = alternateRoute(startRoute, endRoute);
|
List<Way> ways = route_CloudMate(startRoute, endRoute);
|
||||||
DataTileManager<Way> points = new DataTileManager<Way>();
|
DataTileManager<Way> points = new DataTileManager<Way>();
|
||||||
points.setZoom(11);
|
points.setZoom(11);
|
||||||
for (Way w : ways) {
|
for (Way w : ways) {
|
||||||
|
@ -143,7 +147,28 @@ public class MapRouterLayer implements MapPanelLayer {
|
||||||
}.start();
|
}.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<Way> ways = route_OSRM(startRoute, endRoute);
|
||||||
|
DataTileManager<Way> points = new DataTileManager<Way>();
|
||||||
|
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") {
|
Action selfRoute = new AbstractAction("Calculate OsmAnd route") {
|
||||||
private static final long serialVersionUID = 507156107455281238L;
|
private static final long serialVersionUID = 507156107455281238L;
|
||||||
|
|
||||||
|
@ -186,7 +211,7 @@ public class MapRouterLayer implements MapPanelLayer {
|
||||||
// 5. max_heigtht, max_width, min_speed, ...
|
// 5. max_heigtht, max_width, min_speed, ...
|
||||||
// 6. incline ?
|
// 6. incline ?
|
||||||
|
|
||||||
public static List<Way> route(LatLon start, LatLon end){
|
public static List<Way> route_YOURS(LatLon start, LatLon end){
|
||||||
List<Way> res = new ArrayList<Way>();
|
List<Way> res = new ArrayList<Way>();
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
System.out.println("Route from " + start + " to " + end);
|
System.out.println("Route from " + start + " to " + end);
|
||||||
|
@ -258,7 +283,7 @@ public class MapRouterLayer implements MapPanelLayer {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public List<Way> alternateRoute(LatLon start, LatLon end) {
|
public List<Way> route_CloudMate(LatLon start, LatLon end) {
|
||||||
List<Way> res = new ArrayList<Way>();
|
List<Way> res = new ArrayList<Way>();
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
System.out.println("Cloud made route from " + start + " to " + end);
|
System.out.println("Cloud made route from " + start + " to " + end);
|
||||||
|
@ -333,6 +358,118 @@ public class MapRouterLayer implements MapPanelLayer {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Double[] decodeGooglePolylinesFlow(String encodedData) {
|
||||||
|
final List<Double> decodedValues = new ArrayList<Double>();
|
||||||
|
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<Way> route_OSRM(LatLon start, LatLon end){
|
||||||
|
List<Way> res = new ArrayList<Way>();
|
||||||
|
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<list.getLength(); i++){
|
||||||
|
Node item = list.item(i);
|
||||||
|
String str = item.getTextContent();
|
||||||
|
int st = 0;
|
||||||
|
int next = 0;
|
||||||
|
Way w = new Way(-1);
|
||||||
|
while((next = str.indexOf('\n', st)) != -1){
|
||||||
|
String coordinate = str.substring(st, next + 1);
|
||||||
|
int s = coordinate.indexOf(',');
|
||||||
|
if (s != -1) {
|
||||||
|
try {
|
||||||
|
double lon = Double.parseDouble(coordinate.substring(0, s));
|
||||||
|
double lat = Double.parseDouble(coordinate.substring(s + 1));
|
||||||
|
w.addNode(new net.osmand.osm.Node(lat, lon, -1));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
st = next + 1;
|
||||||
|
}
|
||||||
|
if(!w.getNodes().isEmpty()){
|
||||||
|
res.add(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
}*/
|
||||||
|
} catch (IOException e) {
|
||||||
|
ExceptionHandler.handle(e);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
ExceptionHandler.handle(e);
|
||||||
|
}
|
||||||
|
System.out.println("Finding routes " + res.size() + " " + (System.currentTimeMillis() - time) + " ms");
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
public List<Way> selfRoute(LatLon start, LatLon end) {
|
public List<Way> selfRoute(LatLon start, LatLon end) {
|
||||||
List<Way> res = new ArrayList<Way>();
|
List<Way> res = new ArrayList<Way>();
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
|
|
|
@ -33,6 +33,7 @@ public class OsmExtractionPreferencesDialog extends JDialog {
|
||||||
private JTextField mapZooms;
|
private JTextField mapZooms;
|
||||||
private JTextField lineSmoothness;
|
private JTextField lineSmoothness;
|
||||||
private JTextField cityAdminLevel;
|
private JTextField cityAdminLevel;
|
||||||
|
private JTextField osrmServerAddress;
|
||||||
private JTextField renderingTypesFile;
|
private JTextField renderingTypesFile;
|
||||||
private JTextField pathToObfRoutingFile;
|
private JTextField pathToObfRoutingFile;
|
||||||
|
|
||||||
|
@ -143,6 +144,27 @@ public class OsmExtractionPreferencesDialog extends JDialog {
|
||||||
constr.gridx = 1;
|
constr.gridx = 1;
|
||||||
constr.gridy = 2;
|
constr.gridy = 2;
|
||||||
l.setConstraints(cityAdminLevel, constr);
|
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 = new JCheckBox();
|
||||||
// supressWarning.setText(Messages.getString("OsmExtractionPreferencesDialog.DUPLICATED.ID")); //$NON-NLS-1$
|
// 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())){
|
if(!settings.getCityAdminLevel().equals(cityAdminLevel.getText())){
|
||||||
settings.setCityAdminLevel(cityAdminLevel.getText());
|
settings.setCityAdminLevel(cityAdminLevel.getText());
|
||||||
}
|
}
|
||||||
|
if(!settings.getOsrmServerAddress().equals(osrmServerAddress.getText())){
|
||||||
|
settings.setOsrmServerAddress(osrmServerAddress.getText());
|
||||||
|
}
|
||||||
// if(settings.isSupressWarningsForDuplicatedId() != supressWarning.isSelected()){
|
// if(settings.isSupressWarningsForDuplicatedId() != supressWarning.isSelected()){
|
||||||
// settings.setSupressWarningsForDuplicatedId (supressWarning.isSelected());
|
// settings.setSupressWarningsForDuplicatedId (supressWarning.isSelected());
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -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.LOAD.WHOLE.OSM=Load whole osm info (to save valid osm file - use in JOSM...)
|
||||||
OsmExtractionPreferencesDialog.NAME.SUFFIXES=Street name suffixes (av., avenue)
|
OsmExtractionPreferencesDialog.NAME.SUFFIXES=Street name suffixes (av., avenue)
|
||||||
OsmExtractionPreferencesDialog.NORMALIZE.STREETS=Normalizing streets
|
OsmExtractionPreferencesDialog.NORMALIZE.STREETS=Normalizing streets
|
||||||
|
OsmExtractionPreferencesDialog.OSRM.SERVER.ADDRESS=OSRM server address and port
|
||||||
OsmExtractionPreferencesDialog.OK=OK
|
OsmExtractionPreferencesDialog.OK=OK
|
||||||
OsmExtractionPreferencesDialog.PREFERENCES=Preferences
|
OsmExtractionPreferencesDialog.PREFERENCES=Preferences
|
||||||
OsmExtractionPreferencesDialog.CANCEL=Cancel
|
OsmExtractionPreferencesDialog.CANCEL=Cancel
|
||||||
|
|
Loading…
Reference in a new issue