|
import java.io.BufferedReader; |
|
import java.io.InputStreamReader; |
|
import java.io.OutputStreamWriter; |
|
import java.io.StringReader; |
|
import java.net.URL; |
|
import java.net.URLConnection; |
|
import java.util.ArrayList; |
|
|
|
import javax.xml.parsers.SAXParserFactory; |
|
|
|
import org.osmdroid.tileprovider.util.CloudmadeUtil; |
|
import org.osmdroid.views.overlay.PathOverlay; |
|
import org.xml.sax.Attributes; |
|
import org.xml.sax.InputSource; |
|
import org.xml.sax.SAXException; |
|
import org.xml.sax.XMLReader; |
|
import org.xml.sax.helpers.DefaultHandler; |
|
|
|
import android.content.Context; |
|
import android.graphics.Point; |
|
|
|
public class BlueLine extends PathOverlay { |
|
String CMURL; |
|
|
|
public BlueLine(int lineColor, Context ctx) { |
|
super(lineColor, ctx); |
|
getPaint().setStrokeWidth(5f); |
|
CloudmadeUtil.retrieveCloudmadeKey(ctx); |
|
//prebuild the URL http://routes.cloudmade.com/YOUR-API-KEY-GOES-HERE/api/0.3/PARAMS-GO-HERE |
|
CMURL = "http://routes.cloudmade.com/" + CloudmadeUtil.getCloudmadeKey() + "/api/0.3/"; |
|
} |
|
|
|
double endLat, endLng; |
|
|
|
public void showDirectionsToPredefinedLocation(double startLat, double startLng, boolean shortest, String lang, boolean metric) throws Exception { |
|
showDirections(startLat, startLng, endLat, endLng, shortest, lang, metric); |
|
} |
|
|
|
/** |
|
* Request directions from a point to another point. |
|
* Line is drawn automatically in the draw method, need to just request directions and parse the XML into the List of Point's. |
|
* @param startLat Latitude of starting point |
|
* @param startLng Longitude of starting point |
|
* @param endLat Latitude of ending point |
|
* @param endLng Longitude of ending point |
|
* @param shortest Whether select shortest or fastest route |
|
* @param lang 2-char ISO code of the language of directions |
|
* @param metric Whether use metric or imperial system |
|
* @throws Exception |
|
*/ |
|
public void showDirections(double startLat, double startLng, double endLat, double endLng, boolean shortest, String lang, boolean metric) throws Exception { |
|
/* |
|
* Query up the routing service to figure out the turn points |
|
* documentation for cloudmade routing service http://developers.cloudmade.com/wiki/routing-http-api/Documentation |
|
*/ |
|
//add PARAMS to the URL |
|
//start_point,[transit_point1,...,transit_pointN],end_point/route_type[/route_type_modifier].output_format[?lang=(Two letter ISO 3166-1 code)][&units=(km|miles)] |
|
CMURL += startLat + "," + startLng + "," + endLat + "," + endLng |
|
+ "/car/" + (shortest? "shortest" : "fastest") + ".gpx?lang=" + lang + "&units=" + (metric? "km" : "miles"); |
|
//fetch directions and parse returned XML |
|
String directionsXML = getContent(CMURL, null, "UTF8"); |
|
//parse XML |
|
TurnPointsParser parser = new TurnPointsParser(); |
|
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); |
|
xmlReader.setContentHandler(parser); |
|
if(!"".equals(directionsXML)) { |
|
xmlReader.parse(new InputSource(new StringReader(directionsXML))); |
|
} |
|
} |
|
|
|
public class TurnPointsParser extends DefaultHandler { |
|
|
|
public static final String ROOT_ELEMENT = "wpt"; |
|
ArrayList<Point> tempPoints = new ArrayList<Point>(); |
|
|
|
@Override |
|
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { |
|
if(qName.equals(ROOT_ELEMENT)) { |
|
try { |
|
int late6 = degreesToMicrodegrees(Double.parseDouble(atts.getValue("lat"))); |
|
int lnge6 = degreesToMicrodegrees(Double.parseDouble(atts.getValue("lon"))); |
|
tempPoints.add(new Point(late6, lnge6)); |
|
} |
|
catch(Exception e) { |
|
e.printStackTrace(); |
|
} |
|
} |
|
} |
|
|
|
@Override |
|
public void endDocument() { |
|
setPoints(tempPoints); |
|
} |
|
} |
|
|
|
void setPoints(ArrayList<Point> points) { |
|
clearPath(); |
|
for(Point p : points) { |
|
addPoint(p.x, p.y); |
|
} |
|
} |
|
|
|
/** |
|
* Fetch the content of service at the given URL with provided parameters. |
|
* Also transcode the input into UTF-8 according to specified charset used by the service. |
|
* @param serviceUrl |
|
* @param requestParams |
|
* @param serviceCharset |
|
* @return String with fetched content |
|
* @throws Exception |
|
*/ |
|
public static String getContent(String serviceUrl, String requestParams, String serviceCharset) throws Exception { |
|
URL service = new URL(serviceUrl); |
|
URLConnection serviceConnection = service.openConnection(); |
|
serviceConnection.setDoOutput(true); |
|
//write request to the connection |
|
OutputStreamWriter request = new OutputStreamWriter(serviceConnection.getOutputStream()); |
|
if (requestParams != null) { |
|
request.write(requestParams); |
|
} |
|
request.flush(); |
|
//read returned output |
|
BufferedReader in = |
|
new BufferedReader(new InputStreamReader(serviceConnection.getInputStream(), serviceCharset)); |
|
String inputLine; |
|
String returnedContent = ""; |
|
while ((inputLine = in.readLine()) != null) { |
|
returnedContent += inputLine; |
|
} |
|
in.close(); |
|
request.close(); |
|
return returnedContent; |
|
} |
|
|
|
public static final double MICRODEGREES_COEFF = 1E6; |
|
|
|
public static int degreesToMicrodegrees(double degrees) { |
|
return (int) (degrees * MICRODEGREES_COEFF); |
|
} |
|
|
|
public static double microdegreesToDegrees(int microdegrees) { |
|
return (double) microdegrees / (double) MICRODEGREES_COEFF; |
|
} |
|
|
|
public void setEndLat(double endLat) { |
|
this.endLat = endLat; |
|
} |
|
|
|
public void setEndLng(double endLng) { |
|
this.endLng = endLng; |
|
} |
|
|
|
} |