Draw path on the map

Asked

Viewed 2,940 times

11

How do I draw a particular path using the Google Maps V2 API? What I want is something more or less like this: I inform the street A and the street B and get the drawing of the path between these two streets. I don’t want API to give me a hint about the best way but the exact way.

In the image taken from Google Maps I used the mouse to create the path between Av. Rio Negro and Rua Bom Jesus. It’s something like the show I’m looking to develop.

inserir a descrição da imagem aqui

2 answers

10


I have something more or less like this: a class Gmapv2direction.java with the method getDocument, that will make me the consultation to Google Maps API to directions and returns me the XML, besides other useful methods you may also need such as distance, time, route instructions and etc.

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

    public GMapV2Direction() {
    }

    public Document getDocument(String start, String end, String mode) {
        try {
            String startAddress = URLEncoder.encode(start, "utf-8");
            String endAddress = URLEncoder.encode(end, "utf-8");

            String url = "http://maps.googleapis.com/maps/api/directions/xml?"
                    + "origin=" + startAddress
                    + "&destination=" + endAddress
                    + "&sensor=true&mode=" + mode;

            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 boolean statusDirection(Document doc) {
        NodeList nl1 = doc.getElementsByTagName("status");
        Node node1 = nl1.item(0);

        return node1.getTextContent().equalsIgnoreCase("OK");
    }

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

    public ArrayList<String> getTextDirections(Document doc) {
        NodeList nl1, nl2;
        ArrayList<String> listText = new ArrayList<String>();
        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, "html_instructions"));

                listText.add(stripHtml(locationNode.getTextContent()));
            }
        }

        return listText;
    }

    private String stripHtml(String html) {
        return Html.fromHtml(html).toString();
    }

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

And here is mine Activity, searching the route, drawing it on the map and focusing only on the place where we are interested:

public class RouteActivity extends Activity {
    private GoogleMap map;
    private GMapV2Direction directionService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.directions);

        map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map))
                .getMap();

        TraceRoute trace = new TraceRoute();
        trace.execute("av afonso pena, 5000, belo horizonte", "rua rio de janeiro, 1278, belo horizonte");
    }

    private class TraceRoute extends AsyncTask<String, Integer, String> {
        private Document doc;

        @Override
        protected String doInBackground(String... params) {
            directionService = new GMapV2Direction();

            if (params.length == 2) {
                String start = params[0];
                String end = params[1];

                doc = directionService.getDocument(start, end,
                        GMapV2Direction.MODE_DRIVING);
            }

            return null;
        }

        @Override
        protected void onPostExecute(String result) {
            if (directionService.statusDirection(doc)) {
                map.clear();

                int minLat = Integer.MAX_VALUE;
                int maxLat = Integer.MIN_VALUE;
                int minLon = Integer.MAX_VALUE;
                int maxLon = Integer.MIN_VALUE;

                int lat;
                int lng;

                ArrayList<LatLng> directionPoint = directionService.getDirection(doc);
                PolylineOptions rectLine = new PolylineOptions().width(7)
                        .color(Color.argb(128, 0, 0, 255));

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

                    lat = (int) (directionPoint.get(i).latitude * 1E6);
                    lng = (int) (directionPoint.get(i).longitude * 1E6);

                    maxLat = Math.max(lat, maxLat);
                    minLat = Math.min(lat, minLat);
                    maxLon = Math.max(lng, maxLon);
                    minLon = Math.min(lng, minLon);
                }

                map.addPolyline(rectLine);

                double latitudeToGo = (maxLat + minLat) / 1E6 / 2;
                double longitudeToGo = (maxLon + minLon) / 1E6 / 2;

                CameraUpdate center = CameraUpdateFactory.newLatLng(new LatLng(latitudeToGo, longitudeToGo));
                map.moveCamera(center);

                final LatLng southWestLatLon = new LatLng(minLat / 1E6, minLon / 1E6);
                final LatLng northEastLatLon = new LatLng(maxLat / 1E6, maxLon / 1E6);

                map.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
                    @Override
                    public void onCameraChange(CameraPosition arg0) {
                        map.moveCamera(CameraUpdateFactory.newLatLngBounds(new LatLngBounds(southWestLatLon, northEastLatLon), 70));
                        map.setOnCameraChangeListener(null);
                    }
                });
            }
        }
    }
}

Of course you can improve, have a separate class from your Activity and etc, but these are the basic steps. See if that satisfies your question and tell us.

  • Thank you, Paulo. It worked great.

2

This module can help you

Simply instantiate the object and pass the Googlemap object constructor, initial and final Latlng.

import com.tyczj.mapnavigator.Navigator;
Navigator navigator =  new Navigator(googleMap,start,end);
navigator.findDirections(false);

Mapnavigator

Browser other questions tagged

You are not signed in. Login or sign up in order to post.