java 生成kml文件_如何使用kml文件在地图上绘制路径?

本文介绍如何使用Java解析KML文件并在地图上绘制路径。通过SAX解析器解析KML数据,创建NavigationDataSet Bean和NavigationSaxHandler来处理数据,最后在地图上展示路线。
摘要由CSDN通过智能技术生成

在上面的代码中,据我所见,您不会将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);}}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值