在上面的代码中,据我所见,您不会将kml数据传递到代码中的任何位置。要显示路由,您应该解析kml数据,即通过SAX解析器,然后在地图上显示路由标记。
请参阅下面的代码中的一个例子,但是它还没有完成-只是作为一个参考,并得到一些想法。
这是一个简单的bean,用于保存我将要解析的路由信息。package com.myapp.android.model.navigation;import java.util.ArrayList;import java.util.Iterator;public class NavigationDataSet
{ private ArrayList placemarks = new ArrayList();private Placemark currentPlacemark;private Placemark routePla
cemark;public String toString() {
String s= "";
for (Iterator iter=placemarks.iterator();iter.hasNext();) {
Placemark p = (Placemark)iter.next();
s += p.getTitle() + "\n" + p.getDescription() + "\n\n";
}
return s;}public void addCurrentPlacemark() {
placemarks.add(currentPlacemark);}public ArrayList getPlacemarks() {
return placemarks;}public void setPlacemarks(ArrayList placemarks) {
this.placemarks = placemarks;}public Placemark getCurrentPlacemark() {
return currentPlacemark;}public void setCurrentPlacemark(Placemark currentPlacemark) {
this.currentPlacemark = currentPlacemark;}public Placemark getRoutePlacemark() {
return routePlacemark;}public void setRoutePlacemark(Placemark routePlacemark) {
this.routePlacemark = routePlacemark;}}
和解析kml的SAX Handler:package com.myapp.android.model.navigation;import android.util.Log;import com.myapp.android.myapp;import org.xml.sax.Attributes;import org
.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;import com.myapp.android.model.navigation.NavigationDataSet;import com.mya
pp.android.model.navigation.Placemark;public class NavigationSaxHandler extends DefaultHandler{
// ===========================================================
// Fields
// ===========================================================
private boolean in_kmltag = false;
private boolean in_placemarktag = false;
private boolean in_nametag = false;
private boolean in_descriptiontag = false;
private boolean in_geometrycollectiontag = false;
private boolean in_linestringtag = false;
private boolean in_pointtag = false;
private boolean in_coordinatestag = false;
private StringBuffer buffer;
private NavigationDataSet navigationDataSet = new NavigationDataSet();
// ===========================================================
// Getter & Setter
// ===========================================================
public NavigationDataSet getParsedData() {
navigationDataSet.getCurrentPlacemark().setCoordinates(buffer.toString().trim());
return this.navigationDataSet;
}
// ===========================================================
// Methods
// ===========================================================
@Override
public void startDocument() throws SAXException {
this.navigationDataSet = new NavigationDataSet();
}
@Override
public void endDocument() throws SAXException {
// Nothing to do
}
/** Gets be called on opening tags like:
*
* Can provide attribute(s), when xml was like:
* */
@Override
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts) throws SAXException {
if (localName.equals("kml")) {
this.in_kmltag = true;
} else if (localName.equals("Placemark")) {
this.in_placemarktag = true;
navigationDataSet.setCurrentPlacemark(new Placemark());
} else if (localName.equals("name")) {
this.in_nametag = true;
} else if (localName.equals("description")) {
this.in_descriptiontag = true;
} else if (localName.equals("GeometryCollection")) {
this.in_geometrycollectiontag = true;
} else if (localName.equals("LineString")) {
this.in_linestringtag = true;
} else if (localName.equals("point")) {
this.in_pointtag = true;
} else if (localName.equals("coordinates")) {
buffer = new StringBuffer();
this.in_coordinatestag = true;
}
}
/** Gets be called on closing tags like:
* */
@Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (localName.equals("kml")) {
this.in_kmltag = false;
} else if (localName.equals("Placemark")) {
this.in_placemarktag = false;
if ("Route".equals(navigationDataSet.getCurrentPlacemark().getTitle()))
navigationDataSet.setRoutePlacemark(navigationDataSet.getCurrentPlacemark());
else navigationDataSet.addCurrentPlacemark();
} else if (localName.equals("name")) {
this.in_nametag = false;
} else if (localName.equals("description")) {
this.in_descriptiontag = false;
} else if (localName.equals("GeometryCollection")) {
this.in_geometrycollectiontag = false;
} else if (localName.equals("LineString")) {
this.in_linestringtag = false;
} else if (localName.equals("point")) {
this.in_pointtag = false;
} else if (localName.equals("coordinates")) {
this.in_coordinatestag = false;
}
}
/** Gets be called on the following structure:
* characters */
@Override public void characters(char ch[], int start, int length) {
if(this.in_nametag){
if (navigationDataSet.getCurrentPlacemark()==null) navigationDataSet.setCurrentPlacemark(new Placemark());
navigationDataSet.getCurrentPlacemark().setTitle(new String(ch, start, length));
} else
if(this.in_descriptiontag){
if (navigationDataSet.getCurrentPlacemark()==null) navigationDataSet.setCurrentPlacemark(new Placemark());
navigationDataSet.getCurrentPlacemark().setDescription(new String(ch, start, length));
} else
if(this.in_coordinatestag){
if (navigationDataSet.getCurrentPlacemark()==null) navigationDataSet.setCurrentPlacemark(new Placemark());
//navigationDataSet.getCurrentPlacemark().setCoordinates(new String(ch, start, length));
buffer.append(ch, start, length);
}} }
还有一个简单的Placemark bean:package com.myapp.android.model.navigation;public class Placemark {String title;String description;String coordinates;String address;
public String getTitle() {
return title;}public void setTitle(String title) {
this.title = title;}public String getDescription() {
return description;}public void setDescription(String description) {
this.description = description;}public String getCoordinates() {
return coordinates;}public void setCoordinates(String coordinates) {
this.coordinates = coordinates;}public String getAddress() {
return address;}public void setAddress(String address) {
this.address = address;}}
最后,在我的模型中调用计算的服务类:package com.myapp.android.model.navigation;import java.io.IOException;import java.io.InputStream;import java.net.URL;import java.ne
t.URLConnection;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;import com.myapp.android.myapp;import org.xml
.sax.InputSource;import org.xml.sax.XMLReader;import android.util.Log;public class MapService {public static final int MODE_ANY = 0;public
static final int MODE_CAR = 1;public static final int MODE_WALKING = 2;public static String inputStreamToString (InputStream in) throws I
OException {
StringBuffer out = new StringBuffer();
byte[] b = new byte[4096];
for (int n; (n = in.read(b)) != -1;) {
out.append(new String(b, 0, n));
}
return out.toString();}public static NavigationDataSet calculateRoute(Double startLat, Double startLng, Double targetLat, Double
targetLng, int mode) {
return calculateRoute(startLat + "," + startLng, targetLat + "," + targetLng, mode);}public static NavigationDataSet calculateRoute
(String startCoords, String targetCoords, int mode) {
String urlPedestrianMode = "http://maps.google.com/maps?" + "saddr=" + startCoords + "&daddr="
+ targetCoords + "&sll=" + startCoords + "&dirflg=w&hl=en&ie=UTF8&z=14&output=kml";
Log.d(myapp.APP, "urlPedestrianMode: "+urlPedestrianMode);
String urlCarMode = "http://maps.google.com/maps?" + "saddr=" + startCoords + "&daddr="
+ targetCoords + "&sll=" + startCoords + "&hl=en&ie=UTF8&z=14&output=kml";
Log.d(myapp.APP, "urlCarMode: "+urlCarMode);
NavigationDataSet navSet = null;
// for mode_any: try pedestrian route calculation first, if it fails, fall back to car route
if (mode==MODE_ANY||mode==MODE_WALKING) navSet = MapService.getNavigationDataSet(urlPedestrianMode);
if (mode==MODE_ANY&&navSet==null||mode==MODE_CAR) navSet = MapService.getNavigationDataSet(urlCarMode);
return navSet;}/**
* Retrieve navigation data set from either remote URL or String
* @param url
* @return navigation set
*/public static NavigationDataSet getNavigationDataSet(String url) {
// urlString = "http://192.168.1.100:80/test.kml";
Log.d(myapp.APP,"urlString -->> " + url);
NavigationDataSet navigationDataSet = null;
try
{
final URL aUrl = new URL(url);
final URLConnection conn = aUrl.openConnection();
conn.setReadTimeout(15 * 1000); // timeout for reading the google maps data: 15 secs
conn.connect();
/* Get a SAXParser from the SAXPArserFactory. */
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
/* Get the XMLReader of the SAXParser we created. */
XMLReader xr = sp.getXMLReader();
/* Create a new ContentHandler and apply it to the XML-Reader*/
NavigationSaxHandler navSax2Handler = new NavigationSaxHandler();
xr.setContentHandler(navSax2Handler);
/* Parse the xml-data from our URL. */
xr.parse(new InputSource(aUrl.openStream()));
/* Our NavigationSaxHandler now provides the parsed data to us. */
navigationDataSet = navSax2Handler.getParsedData();
/* Set the result to be displayed in our GUI. */
Log.d(myapp.APP,"navigationDataSet: "+navigationDataSet.toString());
} catch (Exception e) {
// Log.e(myapp.APP, "error with kml xml", e);
navigationDataSet = null;
}
return navigationDataSet;}}
绘图:/**
* Does the actual drawing of the route, based on the geo points provided in the nav set
*
* @param navSet Navigation set bean that holds the route information, incl. geo pos
* @param color Color in which to draw the lines
* @param mMapView01 Map view to draw onto
*/public void drawPath(NavigationDataSet navSet, int color, MapView mMapView01) {
Log.d(myapp.APP, "map color before: " + color);
// color correction for dining, make it darker
if (color == Color.parseColor("#add331")) color = Color.parseColor("#6C8715");
Log.d(myapp.APP, "map color after: " + color);
Collection overlaysToAddAgain = new ArrayList();
for (Iterator iter = mMapView01.getOverlays().iterator(); iter.hasNext();) {
Object o = iter.next();
Log.d(myapp.APP, "overlay type: " + o.getClass().getName());
if (!RouteOverlay.class.getName().equals(o.getClass().getName())) {
// mMapView01.getOverlays().remove(o);
overlaysToAddAgain.add(o);
}
}
mMapView01.getOverlays().clear();
mMapView01.getOverlays().addAll(overlaysToAddAgain);
String path = navSet.getRoutePlacemark().getCoordinates();
Log.d(myapp.APP, "path=" + path);
if (path != null && path.trim().length() > 0) {
String[] pairs = path.trim().split(" ");
Log.d(myapp.APP, "pairs.length=" + pairs.length);
String[] lngLat = pairs[0].split(","); // lngLat[0]=longitude lngLat[1]=latitude lngLat[2]=height
Log.d(myapp.APP, "lnglat =" + lngLat + ", length: " + lngLat.length);
if (lngLat.length<3) lngLat = pairs[1].split(","); // if first pair is not transferred completely, take seconds pair //TODO
try {
GeoPoint startGP = new GeoPoint((int) (Double.parseDouble(lngLat[1]) * 1E6), (int) (Double.parseDouble(lngLat[0]) * 1E6));
mMapView01.getOverlays().add(new RouteOverlay(startGP, startGP, 1));
GeoPoint gp1;
GeoPoint gp2 = startGP;
for (int i = 1; i
{
lngLat = pairs[i].split(",");
gp1 = gp2;
if (lngLat.length >= 2 && gp1.getLatitudeE6() > 0 && gp1.getLongitudeE6() > 0
&& gp2.getLatitudeE6() > 0 && gp2.getLongitudeE6() > 0) {
// for GeoPoint, first:latitude, second:longitude
gp2 = new GeoPoint((int) (Double.parseDouble(lngLat[1]) * 1E6), (int) (Double.parseDouble(lngLat[0]) * 1E6));
if (gp2.getLatitudeE6() != 22200000) {
mMapView01.getOverlays().add(new RouteOverlay(gp1, gp2, 2, color));
Log.d(myapp.APP, "draw:" + gp1.getLatitudeE6() + "/" + gp1.getLongitudeE6() + " TO " + gp2.
getLatitudeE6() + "/" + gp2.getLongitudeE6());
}
}
// Log.d(myapp.APP,"pair:" + pairs[i]);
}
//routeOverlays.add(new RouteOverlay(gp2,gp2, 3));
mMapView01.getOverlays().add(new RouteOverlay(gp2, gp2, 3));
} catch (NumberFormatException e) {
Log.e(myapp.APP, "Cannot draw route.", e);
}
}
// mMapView01.getOverlays().addAll(routeOverlays); // use the default color
mMapView01.setEnabled(true);}
这是RouteOverlay类:package com.myapp.android.activity.map.nav;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;
import android.graphics.Paint;import android.graphics.Point;import android.graphics.RectF;import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;import com.google.android.maps.Overlay;import com.google.android.maps.Projection;
public class RouteOverlay extends Overlay { private GeoPoint gp1;private GeoPoint gp2;private int mRadius=6;private int mode=0;
private int defaultColor;private String text="";private Bitmap img = null;public RouteOverlay(GeoPoint gp1,GeoPoint gp2,int mode)
{ // GeoPoint is a int. (6E)
this.gp1 = gp1;
this.gp2 = gp2;
this.mode = mode;
defaultColor = 999; // no defaultColor}public RouteOverlay(GeoPoint gp1,GeoPoint gp2,int mode, int defaultColor) {
this.gp1 = gp1;
this.gp2 = gp2;
this.mode = mode;
this.defaultColor = defaultColor;}public void setText(String t) {
this.text = t;}public void setBitmap(Bitmap bitmap) {
this.img = bitmap;}public int getMode() {
return mode;}@Overridepublic boolean draw (Canvas canvas, MapView mapView, boolean shadow, long when) {
Projection projection = mapView.getProjection();
if (shadow == false) {
Paint paint = new Paint();
paint.setAntiAlias(true);
Point point = new Point();
projection.toPixels(gp1, point);
// mode=1:start
if(mode==1) {
if(defaultColor==999)
paint.setColor(Color.BLACK); // Color.BLUE
else
paint.setColor(defaultColor);
RectF oval=new RectF(point.x - mRadius, point.y - mRadius,
point.x + mRadius, point.y + mRadius);
// start point
canvas.drawOval(oval, paint);
}
// mode=2:path
else if(mode==2) {
if(defaultColor==999)
paint.setColor(Color.RED);
else
paint.setColor(defaultColor);
Point point2 = new Point();
projection.toPixels(gp2, point2);
paint.setStrokeWidth(5);
paint.setAlpha(defaultColor==Color.parseColor("#6C8715")?220:120);
canvas.drawLine(point.x, point.y, point2.x,point2.y, paint);
}
/* mode=3:end */
else if(mode==3) {
/* the last path */
if(defaultColor==999)
paint.setColor(Color.BLACK); // Color.GREEN
else
paint.setColor(defaultColor);
Point point2 = new Point();
projection.toPixels(gp2, point2);
paint.setStrokeWidth(5);
paint.setAlpha(defaultColor==Color.parseColor("#6C8715")?220:120);
canvas.drawLine(point.x, point.y, point2.x,point2.y, paint);
RectF oval=new RectF(point2.x - mRadius,point2.y - mRadius,
point2.x + mRadius,point2.y + mRadius);
/* end point */
paint.setAlpha(255);
canvas.drawOval(oval, paint);
}
}
return super.draw(canvas, mapView, shadow, when);}}