繁体   English   中英

android如何在谷歌地图上用中间点绘制从起点到目的地的路线?

[英]how to draw route from start point to destination point with intermediate points on google map in android?

我有起点,中间点和终点。 起点和终点现在是相同的,我想覆盖所有点并到达Android中Google地图上的同一终点,所以这将是可能的。 谢谢您的进阶...。

为了绘制一条从A到B的路线,我使用以下代码(不幸的是,我不记得我从哪里得到的,但功劳却不归我所有):

public class GMapV2Direction {

    private final static String TAG = "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)
            throws InterruptedException, ExecutionException, TimeoutException {
        final 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(TAG, url);

        try {
            Log.d(TAG, "Fetching directions");
            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) {
            Log.e(TAG, e.getMessage(), e);
        }
        return null;
    }

    public String getDurationText(Document doc) {
        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();
    }

    public int getDurationValue(Document doc) {
        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());
    }

    public String getDistanceText(Document doc) {
        NodeList nl1 = doc.getElementsByTagName("distance");
        Node node1 = nl1.item(0);
        NodeList nl2 = node1.getChildNodes();
        Node node2 = nl2.item(getNodeIndex(nl2, "text"));
        Log.i("DistanceText", node2.getTextContent());
        return node2.getTextContent();
    }

    public int getDistanceValue(Document doc) {
        NodeList nl1 = doc.getElementsByTagName("distance");
        Node node1 = nl1.item(0);
        NodeList nl2 = node1.getChildNodes();
        Node node2 = nl2.item(getNodeIndex(nl2, "value"));
        Log.i("DistanceValue", node2.getTextContent());
        return Integer.parseInt(node2.getTextContent());
    }

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

    public String getEndAddress(Document doc) {
        NodeList nl1 = doc.getElementsByTagName("end_address");
        Node node1 = nl1.item(0);
        Log.i("StartAddress", node1.getTextContent());
        return node1.getTextContent();
    }

    public String getCopyRights(Document doc) {
        NodeList nl1 = doc.getElementsByTagName("copyrights");
        Node node1 = nl1.item(0);
        Log.i("CopyRights", node1.getTextContent());
        return node1.getTextContent();
    }

    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;
    }
}

要使用它,我使用以下代码(对googlemaps的调用是我已经实现的代码模块,但是如果您解析GoogleMap对象,则应该能够绘制路线,AddressHolder也是如此,后者仅提供目标位置) :

private void addDirectionsToMap(GoogleMap map, AddressHolder addressHolder,
        boolean zoomToBounds) {

    Log.i(TAG, "addDirectionsToMap");

    Location lastLocation = location.getLastLocation();

    if (lastLocation == null) {
        // TODO res/string
        Toast.makeText(context, "Unable to get device position",
                Toast.LENGTH_LONG).show();
        return;
    }

    map.setTrafficEnabled(getPreferences().showTraffic());
    map.setMapType(getPreferences().getMapType());

    googlemaps.addLocationPin(lastLocation);
    googlemaps.addAddressPin(addressHolder);

    new GetDirectionsTask(zoomToBounds).execute(
            new LatLng(lastLocation.getLatitude(), lastLocation
                    .getLongitude()), addressHolder.position);

}

private class GetDirectionsTask extends
        AsyncTask<LatLng, Integer, List<LatLng>> {

    private boolean zoomToBounds;

    public GetDirectionsTask(boolean zoomToBounds) {
        this.zoomToBounds = zoomToBounds;
    }

    // Before running code in separate thread
    @Override protected void onPreExecute() {
        // Create a new progress dialog.
        // progressDialog = new ProgressDialog(context);
        // progressDialog.setMessage("Henter rute...");
        // progressDialog.setCancelable(false);
        // progressDialog.setIndeterminate(true);
        // progressDialog.show();

    }

    // The code to be executed in a background thread.
    @Override protected List<LatLng> doInBackground(LatLng... position) {
        LatLng fromPosition = position[0];
        LatLng toPosition = position[1];

        GMapV2Direction md = new GMapV2Direction();

        List<LatLng> directionPoints = null;
        Document doc;
        try {
            doc = md.getDocument(fromPosition, toPosition,
                    GMapV2Direction.MODE_DRIVING);

            if (doc != null) {
                directionPoints = md.getDirection(doc);
            } else {
                Log.d(TAG, "Directions document was null");
            }
        } catch (InterruptedException e) {
            Log.e(TAG, e.getMessage(), e);
        } catch (ExecutionException e) {
            Log.e(TAG, e.getMessage(), e);
        } catch (TimeoutException e) {
            Log.e(TAG, e.getMessage(), e);
        }
        return directionPoints;
    }

    // Update the progress
    @Override protected void onProgressUpdate(Integer... values) {
        // set the current progress of the progress dialog
        // progressDialog.setProgress(values[0]);
    }

    // after executing the code in the thread
    @Override protected void onPostExecute(List<LatLng> directionPoint) {
        // close the progress dialog
        // progressDialog.dismiss();
        final GoogleMap map = googlemaps.getMap();

        if (directionPoint == null)
            return;
        if (map == null)
            return;

        PolylineOptions rectLine = new PolylineOptions().width(3).color(
                Color.RED);

        LatLngBounds.Builder builder = new LatLngBounds.Builder();

        for (int i = 0; i < directionPoint.size(); i++) {
            rectLine.add(directionPoint.get(i));

            builder.include(directionPoint.get(i));
        }

        map.addPolyline(rectLine);

        final LatLngBounds bounds = builder.build();

        final int padding = 50; // offset from edges of the
        // map in pixels

        if (zoomToBounds) {
            try {
                googlemaps.zoomWithBounds(bounds, padding);
            } catch (Exception e) {

                // if map is just created we have to wait for it to be ready

                map.setOnCameraChangeListener(new OnCameraChangeListener() {

                    @Override public void onCameraChange(CameraPosition arg0) {
                        // Move camera.

                        googlemaps.zoomWithBounds(bounds, padding);

                        // Remove listener to prevent position reset on
                        // camera move.
                        map.setOnCameraChangeListener(null);

                    }
                });
            }
        }

    }
}

尚未尝试将此代码用于多条路线,但无法通过获取路线A-> B,B-> C,最后是C-> A来查看导致此路线不起作用的任何原因。

我不知道是否可能,但是您可以在Google Maps中绘制地图,放置点,然后绘制具有所需路径的线。 导出到kml文件并在您的应用程序中使用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM