Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to buffer a polyline in Android or draw a polygon around a polyline?

I am trying to put a buffer around a polyline in MapsV2 for android but I haven't find how to do it yet, I was thinking on drawing a polygon around the polyline but also haven't found anyone that have done that, is it possible?

like image 442
Christian Michell Urias Guzmán Avatar asked Sep 12 '16 16:09

Christian Michell Urias Guzmán


2 Answers

in Google's directions api (https://maps.googleapis.com/maps/api/directions/json?origin=75+9th+Ave+New+York,+NY&destination=MetLife+Stadium+1+MetLife+Stadium+Dr+East+Rutherford,+NJ+07073&key=YOUR_API_KEY ) you get one overview_polyline jsonObject, get encoded points From here, and decode it using this method:

private List<LatLng> decodePoly(String encoded) {

        List<LatLng> poly = new ArrayList<>();
        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 p = new LatLng((((double) lat / 1E5)),
                    (((double) lng / 1E5)));
            poly.add(p);
        }
        return poly;
    }

You get List of latitude and longitude, now, using google map's getMapAsync Method add this latlng in your map :

googleMap.addPolyline(new PolylineOptions().geodesic(true).addAll(latLngList));
like image 127
Vikrant Shah Avatar answered Sep 29 '22 05:09

Vikrant Shah


Do you want to draw Path on the map or Do you want to draw straight lines on the map.

In both cases you can follow below code

PolylineOptions polyLineOptions = new PolylineOptions();
ArrayList<LatLng> points = new ArrayList<>();

//Code to populate Latlng

polyLineOptions.addAll(points);
polyLineOptions.width(mActivity.getResources().getDimensionPixelSize(R.dimen._2sdp));
polyLineOptions.color(ContextCompat.getColor(mContext, Color_Resource_id));
if (polyLineOptions != null) {
    googleMap.addPolyline(polyLineOptions);
}

Above code is to draw only straight lines on Map.

Now if you wanna draw complete path on Map, You would probably need to use google direction api https://maps.googleapis.com/maps/api/directions/

You can use below class to parse response from the same to get total latlngs

public class PathJSONParser {

    public List<List<HashMap<String, String>>> parse(JSONObject jObject) {
        List<List<HashMap<String, String>>> routes = new ArrayList<>();
        JSONArray jRoutes;
        JSONArray jLegs;
        JSONArray jSteps;
        try {
            jRoutes = jObject.getJSONArray("routes");
            /** Traversing all routes */
            for (int i = 0; i < jRoutes.length(); i++) {
                jLegs = ((JSONObject) jRoutes.get(i)).getJSONArray("legs");
                List<HashMap<String, String>> path = new ArrayList<>();

                /** Traversing all legs */
                for (int j = 0; j < jLegs.length(); j++) {
                    jSteps = ((JSONObject) jLegs.get(j)).getJSONArray("steps");

                    /** Traversing all steps */
                    for (int k = 0; k < jSteps.length(); k++) {
                        String polyline;
                        polyline = (String) ((JSONObject) ((JSONObject) jSteps
                                .get(k)).get("polyline")).get("points");
                        List<LatLng> list = decodePoly(polyline);

                        /** Traversing all points */
                        for (int l = 0; l < list.size(); l++) {
                            HashMap<String, String> hm = new HashMap<>();
                            hm.put("lat",
                                    Double.toString(( list.get(l)).latitude));
                            hm.put("lng",
                                    Double.toString(( list.get(l)).longitude));
                            path.add(hm);
                        }
                    }
                    routes.add(path);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return routes;
    }

    /**
     * Method Courtesy :
     * jeffreysambells.com/2010/05/27
     * /decoding-polylines-from-google-maps-direction-api-with-java
     * */
    private List<LatLng> decodePoly(String encoded) {

        List<LatLng> poly = new ArrayList<>();
        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 p = new LatLng((((double) lat / 1E5)),
                    (((double) lng / 1E5)));
            poly.add(p);
        }
        return poly;
    }
}

And finally you can use this in your class with below code

private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String, String>>>> {

        @Override
        protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {

            JSONObject jObject;
            List<List<HashMap<String, String>>> routes = new ArrayList<>();

            try {
                jObject = new JSONObject(jsonData[0]);
                PathJSONParser parser = new PathJSONParser();
                routes = parser.parse(jObject);
            } catch (Exception e) {
                e.printStackTrace();
            }

            return routes;
        }

        @Override
        protected void onPostExecute(List<List<HashMap<String, String>>> routes) {
            if (routes != null && routes.size() > 0) {
                new DrawPoly().execute(routes);
            }

        }
    }

    private class DrawPoly extends AsyncTask<List<List<HashMap<String, String>>>,
            PolylineOptions, PolylineOptions> {

        @Override
        protected PolylineOptions doInBackground(List<List<HashMap<String, String>>>... params) {
            PolylineOptions polyLineOptions = new PolylineOptions();
            ArrayList<LatLng> points;

            if (params[0] != null && params[0].size() > 0) {
                // traversing through routes
                for (int j = 0; j < params[0].size(); j++) {
                    points = new ArrayList<>();
                    polyLineOptions = new PolylineOptions();
                    try {
                        List<HashMap<String, String>> path = params[0].get(j);
                        for (int k = 0; k < path.size(); k++) {
                            HashMap<String, String> point = path.get(k);
                            double lat = Double.parseDouble(point.get("lat"));
                            double lng = Double.parseDouble(point.get("lng"));
                            LatLng position = new LatLng(lat, lng);
                            points.add(position);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    polyLineOptions.addAll(points);
                    polyLineOptions.width(mActivity.getResources().getDimensionPixelSize(R.dimen.five));
                    polyLineOptions.color(ContextCompat.getColor(mContext, R.color.red));
                }
            }
            return polyLineOptions;
        }

        @Override
        protected void onPostExecute(PolylineOptions polyLineOptions) {
            super.onPostExecute(polyLineOptions);
            if (polyLineOptions != null) {
                googleMap.addPolyline(polyLineOptions);
            }
        }
    }

You need to make sure you are putting it in asyncTask. I hope it will work for you.

like image 39
Mushahid Khatri Avatar answered Sep 29 '22 04:09

Mushahid Khatri