package eu.geopaparazzi.library.routing.openrouteservice; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.sql.Date; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import eu.geopaparazzi.library.database.GPLog; import eu.geopaparazzi.library.gps.IGpsLogDbHelper; @SuppressWarnings("nls") public class OpenRouteServiceHandler { public static enum Preference { Fastest, Shortest, Bicycle // shortest == pedestrian } public static enum Language { en, it, de, fr, es } private float[] routePoints = null; private String distance = ""; private String uom = ""; private String errorMessage = null; private String urlString; public OpenRouteServiceHandler( double fromLat, double fromLon, double toLat, double toLon, Preference pref, Language lang ) throws Exception { StringBuilder urlSB = new StringBuilder(); urlSB.append("http://openls.geog.uni-heidelberg.de/osm/eu/routing?"); urlSB.append("start=");// from urlSB.append(fromLon); urlSB.append(","); urlSB.append(fromLat); urlSB.append("&end=");// to urlSB.append(toLon); urlSB.append(","); urlSB.append(toLat); urlSB.append("&preference="); urlSB.append(pref.toString()); urlSB.append("&language="); urlSB.append(lang.toString()); /* * TODO check the openrouteservce docs, which seem to be wrong or outdated. */ // if (noMotorWays != null) { // urlString.append("&noMotorways=="); // urlString.append(noMotorWays.toString()); // } // if (noTollways != null) { // urlString.append("&noTollways="); // urlString.append(noTollways.toString()); // } urlString = urlSB.toString(); URL url = new URL(urlString); URLConnection connection = url.openConnection(); DocumentBuilder dom = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document doc = dom.parse(new InputSource(new InputStreamReader(connection.getInputStream()))); /* * extract route length */ NodeList routeSummaryList = doc.getElementsByTagName("xls:RouteSummary"); //$NON-NLS-1$ for( int i = 0; i < routeSummaryList.getLength(); i++ ) { Node routeSummaryNode = routeSummaryList.item(i); NodeList totalDistance = ((Element) routeSummaryNode).getElementsByTagName("xls:TotalDistance"); //$NON-NLS-1$ Node item = totalDistance.item(0); distance = ((Element) item).getAttribute("value"); uom = ((Element) item).getAttribute("uom"); } /* * extract route */ NodeList routeGeometryList = doc.getElementsByTagName("xls:RouteGeometry"); //$NON-NLS-1$ int routeGeometryListLength = routeGeometryList.getLength(); for( int i = 0; i < routeGeometryListLength; i++ ) { Node gmlLinestring = routeGeometryList.item(i); NodeList gmlPoslist = ((Element) gmlLinestring).getElementsByTagName("gml:pos"); //$NON-NLS-1$ int length = gmlPoslist.getLength(); routePoints = new float[length * 2]; int index = 0; for( int j = 0; j < length; j++ ) { String text = gmlPoslist.item(j).getFirstChild().getNodeValue(); int s = text.indexOf(' '); try { double lon = Double.parseDouble(text.substring(0, s)); double lat = Double.parseDouble(text.substring(s + 1)); routePoints[index++] = (float) lon; routePoints[index++] = (float) lat; } catch (NumberFormatException nfe) { } } } if (routeGeometryListLength == 0) { NodeList errorList = doc.getElementsByTagName("xls:ErrorList"); //$NON-NLS-1$ for( int i = 0; i < errorList.getLength(); i++ ) { Node errorNode = errorList.item(i); NodeList errors = ((Element) errorNode).getElementsByTagName("xls:Error"); //$NON-NLS-1$ Node error = errors.item(0); errorMessage = ((Element) error).getAttribute("message"); } } } public String getErrorMessage() { return errorMessage; } public String getUsedUrlString() { return urlString; } public float[] getRoutePoints() { return routePoints; } public String getDistance() { return distance; } public String getUom() { return uom; } public void dumpInDatabase( String name, Context context, IGpsLogDbHelper logDumper ) throws Exception { SQLiteDatabase sqliteDatabase = logDumper.getDatabase(context); Date now = new Date(new java.util.Date().getTime()); long newLogId = logDumper.addGpsLog(context, now, now, name, 1, "blue", true); //$NON-NLS-1$ sqliteDatabase.beginTransaction(); try { Date nowPlus10Secs = now; String path = ""; if (path != null && path.trim().length() > 0) { String[] pairs = path.trim().split(" "); try { for( int i = 1; i < pairs.length; i++ ) // the last one would be crash { String[] lngLat = pairs[i].split(","); double lon = Double.parseDouble(lngLat[0]); double lat = Double.parseDouble(lngLat[1]); double altim = 0; if (lngLat.length > 2) { altim = Double.parseDouble(lngLat[2]); } // dummy time increment nowPlus10Secs = new Date(nowPlus10Secs.getTime() + 10000); logDumper.addGpsLogDataPoint(sqliteDatabase, newLogId, lon, lat, altim, nowPlus10Secs); } } catch (NumberFormatException e) { GPLog.error(this, "Cannot draw route.", e); } } sqliteDatabase.setTransactionSuccessful(); } catch (Exception e) { throw new IOException(e.getLocalizedMessage()); } finally { sqliteDatabase.endTransaction(); } } }