Android显示两个地理点之间的行车方向路线

时间:2012-08-08 10:19:42

标签: android routes direction geopoints

我已经用Google搜索了2-3天,但我无法为我的问题找到完美的解决方案。

我需要显示两个地理点之间的路线(不是直线但需要显示行驶方向的路线) 但我无法找到任何解决方案。 我在this question找到了解决方案。

但我猜解决方案也无效。如果你能帮助我,那就太好了。

我找到了解决方案寻找答案...

3 个答案:

答案 0 :(得分:4)

我正在使用此

 String url = RoadProvider.getUrl(fromLat, fromLon, toLat, toLon);
 InputStream is = getConnection(url);
 mRoad = RoadProvider.getRoute(is);
 mHandler.sendEmptyMessage(0);

并在处理程序中

 MapOverlay mapOverlay = new MapOverlay(mRoad, mapView);
 List<Overlay> listOfOverlays = mapView.getOverlays();
 listOfOverlays.add(mapOverlay);

这里是roadprovider.java

package com.singPost;

import java.io.IOException;
import java.io.InputStream;
import java.util.Stack;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class RoadProvider 
{

        public static Road getRoute(InputStream is) 
        {
                KMLHandler handler = new KMLHandler();
                try {
                        SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
                        parser.parse(is, handler);
                } catch (ParserConfigurationException e) {
                        e.printStackTrace();
                } catch (SAXException e) {
                        e.printStackTrace();
                } catch (IOException e) {
                        e.printStackTrace();
                }
                return handler.mRoad;
        }

        public static String getUrl(double fromLat, double fromLon, double toLat, double toLon) 
        {
            // connect to map web service
                StringBuffer urlString = new StringBuffer();
                urlString.append("http://maps.google.com/maps?f=d&hl=en");
                urlString.append("&saddr=");// from
                urlString.append(Double.toString(fromLat));
                urlString.append(",");
                urlString.append(Double.toString(fromLon));
                urlString.append("&daddr=");// to
                urlString.append(Double.toString(toLat));
                urlString.append(",");
                urlString.append(Double.toString(toLon));
                urlString.append("&ie=UTF8&0&om=0&output=kml");
                return urlString.toString();
        }
}

class KMLHandler extends DefaultHandler {
        Road mRoad;
        boolean isPlacemark;
        boolean isRoute;
        boolean isItemIcon;
        private Stack mCurrentElement = new Stack();
        private String mString;

        public KMLHandler() {
                mRoad = new Road();
        }

        public void startElement(String uri, String localName, String name,
                        Attributes attributes) throws SAXException {
                mCurrentElement.push(localName);
                if (localName.equalsIgnoreCase("Placemark")) {
                        isPlacemark = true;
                        mRoad.mPoints = addPoint(mRoad.mPoints);
                } else if (localName.equalsIgnoreCase("ItemIcon")) {
                        if (isPlacemark)
                                isItemIcon = true;
                }
                mString = new String();
        }

        public void characters(char[] ch, int start, int length)
                        throws SAXException {
                String chars = new String(ch, start, length).trim();
                mString = mString.concat(chars);
        }

        public void endElement(String uri, String localName, String name)
                        throws SAXException {
                if (mString.length() > 0) {
                        if (localName.equalsIgnoreCase("name")) {
                                if (isPlacemark) {
                                        isRoute = mString.equalsIgnoreCase("Route");
                                        if (!isRoute) {
                                                mRoad.mPoints[mRoad.mPoints.length - 1].mName = mString;
                                        }
                                } else {
                                        mRoad.mName = mString;
                                }
                        } else if (localName.equalsIgnoreCase("color") && !isPlacemark) {
                                mRoad.mColor = Integer.parseInt(mString, 16);
                        } else if (localName.equalsIgnoreCase("width") && !isPlacemark) {
                                mRoad.mWidth = Integer.parseInt(mString);
                        } else if (localName.equalsIgnoreCase("description")) {
                                if (isPlacemark) {
                                        String description = cleanup(mString);
                                        if (!isRoute)
                                                mRoad.mPoints[mRoad.mPoints.length - 1].mDescription = description;
                                        else
                                                mRoad.mDescription = description;
                                }
                        } else if (localName.equalsIgnoreCase("href")) {
                                if (isItemIcon) {
                                        mRoad.mPoints[mRoad.mPoints.length - 1].mIconUrl = mString;
                                }
                        } else if (localName.equalsIgnoreCase("coordinates")) {
                                if (isPlacemark) {
                                        if (!isRoute) {
                                                String[] xyParsed = split(mString, ",");
                                                double lon = Double.parseDouble(xyParsed[0]);
                                                double lat = Double.parseDouble(xyParsed[1]);
                                                mRoad.mPoints[mRoad.mPoints.length - 1].mLatitude = lat;
                                                mRoad.mPoints[mRoad.mPoints.length - 1].mLongitude = lon;
                                        } else {
                                                String[] coodrinatesParsed = split(mString, " ");
                                                int lenNew = coodrinatesParsed.length;
                                                int lenOld = mRoad.mRoute.length;
                                                double[][] temp = new double[lenOld + lenNew][2];
                                                for (int i = 0; i < lenOld; i++) {
                                                        temp[i] = mRoad.mRoute[i];
                                                }
                                                for (int i = 0; i < lenNew; i++) {
                                                        String[] xyParsed = split(coodrinatesParsed[i], ",");
                                                        for (int j = 0; j < 2 && j < xyParsed.length; j++)
                                                                temp[lenOld + i][j] = Double
                                                                                .parseDouble(xyParsed[j]);
                                                }
                                                mRoad.mRoute = temp;
                                        }
                                }
                        }
                }
                mCurrentElement.pop();
                if (localName.equalsIgnoreCase("Placemark")) {
                        isPlacemark = false;
                        if (isRoute)
                                isRoute = false;
                } else if (localName.equalsIgnoreCase("ItemIcon")) {
                        if (isItemIcon)
                                isItemIcon = false;
                }
        }

        private String cleanup(String value) {
                String remove = "<br/>";
                int index = value.indexOf(remove);
                if (index != -1)
                        value = value.substring(0, index);
                remove = "&#160;";
                index = value.indexOf(remove);
                int len = remove.length();
                while (index != -1) {
                        value = value.substring(0, index).concat(
                                        value.substring(index + len, value.length()));
                        index = value.indexOf(remove);
                }
                return value;
        }

        public Point2[] addPoint(Point2[] points)
        {
                Point2[] result = new Point2[points.length + 1];
                for (int i = 0; i < points.length; i++)
                        result[i] = points[i];
                result[points.length] = new Point2();
                return result;
        }

        private static String[] split(String strString, String strDelimiter)
        {
                String[] strArray;
                int iOccurrences = 0;
                int iIndexOfInnerString = 0;
                int iIndexOfDelimiter = 0;
                int iCounter = 0;
                if (strString == null) 
                {
                        throw new IllegalArgumentException("Input string cannot be null.");
                }
                if (strDelimiter.length() <= 0 || strDelimiter == null) 
                {
                        throw new IllegalArgumentException("Delimeter cannot be null or empty.");
                }
                if (strString.startsWith(strDelimiter))
                {
                        strString = strString.substring(strDelimiter.length());
                }
                if (!strString.endsWith(strDelimiter))
                {
                        strString += strDelimiter;
                }
                while ((iIndexOfDelimiter = strString.indexOf(strDelimiter,
                                iIndexOfInnerString)) != -1) 
                {
                        iOccurrences += 1;
                        iIndexOfInnerString = iIndexOfDelimiter + strDelimiter.length();
                }
                strArray = new String[iOccurrences];
                iIndexOfInnerString = 0;
                iIndexOfDelimiter = 0;
                while ((iIndexOfDelimiter = strString.indexOf(strDelimiter,
                                iIndexOfInnerString)) != -1) 
                {
                        strArray[iCounter] = strString.substring(iIndexOfInnerString,
                                        iIndexOfDelimiter);
                        iIndexOfInnerString = iIndexOfDelimiter + strDelimiter.length();
                        iCounter += 1;
                }

                return strArray;
        }
}

答案 1 :(得分:1)

嘿伙计我发现链接中的问题

Google停止以KML格式提供API响应

同样的解决方案是here

答案 2 :(得分:1)

这对我来说很有意义:
这不是我的代码,我从stackoverflow的一个很好的答案中得到了它,但我现在找不到这个答案,所以这里是代码:

将此课程添加到您的项目中:

package ...;

import java.io.InputStream;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.google.android.gms.maps.model.LatLng;

import android.content.Context;
import android.util.Log;

public class GMapV2Direction {
public final static String MODE_DRIVING = "driving";
public final static String MODE_WALKING = "walking";

public GMapV2Direction() {
}

public Document getDocument(LatLng start, LatLng end, String mode) {
    String url = "http://maps.googleapis.com/maps/api/directions/xml?"
            + "origin=" + start.latitude + "," + start.longitude
            + "&destination=" + end.latitude + "," + end.longitude
            + "&sensor=false&units=metric&mode=driving";
    Log.d("url", url);
    try {
        HttpClient httpClient = new DefaultHttpClient();
        HttpContext localContext = new BasicHttpContext();
        HttpPost httpPost = new HttpPost(url);
        HttpResponse response = httpClient.execute(httpPost, localContext);
        InputStream in = response.getEntity().getContent();
        DocumentBuilder builder = DocumentBuilderFactory.newInstance()
                .newDocumentBuilder();
        Document doc = builder.parse(in);
        return doc;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

public String getDurationText(Document doc) {
    try {

        NodeList nl1 = doc.getElementsByTagName("duration");
        Node node1 = nl1.item(0);
        NodeList nl2 = node1.getChildNodes();
        Node node2 = nl2.item(getNodeIndex(nl2, "text"));
        Log.i("DurationText", node2.getTextContent());
        return node2.getTextContent();
    } catch (Exception e) {
        return "0";
    }
}

public int getDurationValue(Document doc) {
    try {
        NodeList nl1 = doc.getElementsByTagName("duration");
        Node node1 = nl1.item(0);
        NodeList nl2 = node1.getChildNodes();
        Node node2 = nl2.item(getNodeIndex(nl2, "value"));
        Log.i("DurationValue", node2.getTextContent());
        return Integer.parseInt(node2.getTextContent());
    } catch (Exception e) {
        return -1;
    }
}

public String getDistanceText(Document doc) {
    /*
     * while (en.hasMoreElements()) { type type = (type) en.nextElement();
     * 
     * }
     */

    try {
        NodeList nl1;
        nl1 = doc.getElementsByTagName("distance");

        Node node1 = nl1.item(nl1.getLength() - 1);
        NodeList nl2 = null;
        nl2 = node1.getChildNodes();
        Node node2 = nl2.item(getNodeIndex(nl2, "value"));
        Log.d("DistanceText", node2.getTextContent());
        return node2.getTextContent();
    } catch (Exception e) {
        return "-1";
    }

    /*
     * NodeList nl1; if(doc.getElementsByTagName("distance")!=null){ nl1=
     * doc.getElementsByTagName("distance");
     * 
     * Node node1 = nl1.item(nl1.getLength() - 1); NodeList nl2 = null; if
     * (node1.getChildNodes() != null) { nl2 = node1.getChildNodes(); Node
     * node2 = nl2.item(getNodeIndex(nl2, "value")); Log.d("DistanceText",
     * node2.getTextContent()); return node2.getTextContent(); } else return
     * "-1";} else return "-1";
     */
}

public int getDistanceValue(Document doc) {
    try {
        NodeList nl1 = doc.getElementsByTagName("distance");
        Node node1 = null;
        node1 = nl1.item(nl1.getLength() - 1);
        NodeList nl2 = node1.getChildNodes();
        Node node2 = nl2.item(getNodeIndex(nl2, "value"));
        Log.i("DistanceValue", node2.getTextContent());
        return Integer.parseInt(node2.getTextContent());
    } catch (Exception e) {
        return -1;
    }
    /*
     * NodeList nl1 = doc.getElementsByTagName("distance"); Node node1 =
     * null; if (nl1.getLength() > 0) node1 = nl1.item(nl1.getLength() - 1);
     * if (node1 != null) { NodeList nl2 = node1.getChildNodes(); Node node2
     * = nl2.item(getNodeIndex(nl2, "value")); Log.i("DistanceValue",
     * node2.getTextContent()); return
     * Integer.parseInt(node2.getTextContent()); } else return 0;
     */
}

public String getStartAddress(Document doc) {
    try {
        NodeList nl1 = doc.getElementsByTagName("start_address");
        Node node1 = nl1.item(0);
        Log.i("StartAddress", node1.getTextContent());
        return node1.getTextContent();
    } catch (Exception e) {
        return "-1";
    }

}

public String getEndAddress(Document doc) {
    try {
        NodeList nl1 = doc.getElementsByTagName("end_address");
        Node node1 = nl1.item(0);
        Log.i("StartAddress", node1.getTextContent());
        return node1.getTextContent();
    } catch (Exception e) {
        return "-1";        
}
}
public String getCopyRights(Document doc) {
    try {
        NodeList nl1 = doc.getElementsByTagName("copyrights");
        Node node1 = nl1.item(0);
        Log.i("CopyRights", node1.getTextContent());
        return node1.getTextContent();
    } catch (Exception e) {
    return "-1";
    }

}

public ArrayList<LatLng> getDirection(Document doc) {
    NodeList nl1, nl2, nl3;
    ArrayList<LatLng> listGeopoints = new ArrayList<LatLng>();
    nl1 = doc.getElementsByTagName("step");
    if (nl1.getLength() > 0) {
        for (int i = 0; i < nl1.getLength(); i++) {
            Node node1 = nl1.item(i);
            nl2 = node1.getChildNodes();

            Node locationNode = nl2
                    .item(getNodeIndex(nl2, "start_location"));
            nl3 = locationNode.getChildNodes();
            Node latNode = nl3.item(getNodeIndex(nl3, "lat"));
            double lat = Double.parseDouble(latNode.getTextContent());
            Node lngNode = nl3.item(getNodeIndex(nl3, "lng"));
            double lng = Double.parseDouble(lngNode.getTextContent());
            listGeopoints.add(new LatLng(lat, lng));

            locationNode = nl2.item(getNodeIndex(nl2, "polyline"));
            nl3 = locationNode.getChildNodes();
            latNode = nl3.item(getNodeIndex(nl3, "points"));
            ArrayList<LatLng> arr = decodePoly(latNode.getTextContent());
            for (int j = 0; j < arr.size(); j++) {
                listGeopoints.add(new LatLng(arr.get(j).latitude, arr
                        .get(j).longitude));
            }

            locationNode = nl2.item(getNodeIndex(nl2, "end_location"));
            nl3 = locationNode.getChildNodes();
            latNode = nl3.item(getNodeIndex(nl3, "lat"));
            lat = Double.parseDouble(latNode.getTextContent());
            lngNode = nl3.item(getNodeIndex(nl3, "lng"));
            lng = Double.parseDouble(lngNode.getTextContent());
            listGeopoints.add(new LatLng(lat, lng));
        }
    }

    return listGeopoints;
}

private int getNodeIndex(NodeList nl, String nodename) {
    for (int i = 0; i < nl.getLength(); i++) {
        if (nl.item(i).getNodeName().equals(nodename))
            return i;
    }
    return -1;
}

private ArrayList<LatLng> decodePoly(String encoded) {
    ArrayList<LatLng> poly = new ArrayList<LatLng>();
    int index = 0, len = encoded.length();
    int lat = 0, lng = 0;
    while (index < len) {
        int b, shift = 0, result = 0;
        do {
            b = encoded.charAt(index++) - 63;
            result |= (b & 0x1f) << shift;
            shift += 5;
        } while (b >= 0x20);
        int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
        lat += dlat;
        shift = 0;
        result = 0;
        do {
            b = encoded.charAt(index++) - 63;
            result |= (b & 0x1f) << shift;
            shift += 5;
        } while (b >= 0x20);
        int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
        lng += dlng;

        LatLng position = new LatLng((double) lat / 1E5, (double) lng / 1E5);
        poly.add(position);
    }
    return poly;
}
}

然后根据您的需要使用此课程: 例如绘制方向:

md = new GMapV2Direction();
mMap = ((SupportMapFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.map)).getMap();
Document doc = md.getDocument(sourcePosition, destPosition,
                    GMapV2Direction.MODE_DRIVING);

ArrayList<LatLng> directionPoint = md.getDirection(doc);
            PolylineOptions rectLine = new PolylineOptions().width(3).color(
                    Color.RED);

            for (int i = 0; i < directionPoint.size(); i++) {
                rectLine.add(directionPoint.get(i));
            }
            Polyline polylin = mMap.addPolyline(rectLine);

sourcePosition,destPosition来自LatLng类型,你给他们想要的点。我在这里写了我认为可能有用的代码部分,欢迎任何问题。