25

I've looked through the documentation of polyline and there is no option to make it dashed.

Do anybody know how to draw dashed polyline with android google map sdk v2?

Alexey Zakharov
  • 24,694
  • 42
  • 126
  • 197

4 Answers4

29

Now in Polyline you can set the pattern to be Dash, Dot or Gap simply apply the following

public static final int PATTERN_DASH_LENGTH_PX = 20;
public static final int PATTERN_GAP_LENGTH_PX = 20;
public static final PatternItem DOT = new Dot();
public static final PatternItem DASH = new Dash(PATTERN_DASH_LENGTH_PX);
public static final PatternItem GAP = new Gap(PATTERN_GAP_LENGTH_PX);
public static final List<PatternItem> PATTERN_POLYGON_ALPHA = Arrays.asList(GAP, DASH);

 private void drawDashedLeg(GoogleMap googleMap, Route route) {
    PolylineOptions polyOptions = new PolylineOptions();
    polyOptions.color(ContextCompat.getColor(getContext(), R.color.coolgrey));
    polyOptions.addAll(route.getPoints());
    polyOptions.pattern(PATTERN_POLYGON_ALPHA);
    Polyline polyline = googleMap.addPolyline(polyOptions);
    polylines.add(polyline);
}
atabouraya
  • 3,233
  • 1
  • 26
  • 31
15

It is not possible in current release. Follow this issue for updates: https://code.google.com/p/gmaps-api-issues/issues/detail?id=4633

UPDATE

Recently, Google implemented this feature for polylines in Google Maps Android API v2 and marked issue 4633 as Fixed.

See information about stroke patterns in the Shapes Guide. See an example in the Polylines and Polygons tutorial.

You can also read the corresponding blog post here:

https://maps-apis.googleblog.com/2017/02/styling-and-custom-data-for-polylines.html

xomena
  • 31,125
  • 6
  • 88
  • 117
Alexey Zakharov
  • 24,694
  • 42
  • 126
  • 197
  • This was marked as the 'accepted answer' with its "update note" saying quoted: "Google implemented this feature for polylines in Google Maps Android API v2 ... " . That is NOT TRUE. It is not extra/support nor extension for v2. What is true is they released new Map API V.10.2.1 (02/2017) that addressed the issue 4633 providing patterns (dash/dot/etc.) to Polylines. In no way that it would still support v2. To use it, you must replace the entire v2 with the new version, and possibly recode your map classes implementations. – Panini Luncher Apr 02 '17 at 17:55
  • thanks you post url https://maps-apis.googleblog.com/2017/02/styling-and-custom-data-for-polylines.html is help me and work for me. – Jatinkumar Patel Apr 11 '17 at 16:08
  • 1
    I have checked the docs but I haven't found the way to round the dashes of the polyline. Is there any way to do this? – Fazal Hussain Jun 22 '20 at 07:37
14

Alexey, I've just created a function that worked for me and I think that will help you:

public static void createDashedLine(GoogleMap map, LatLng latLngOrig, LatLng latLngDest, int color){
    double difLat = latLngDest.latitude - latLngOrig.latitude;
    double difLng = latLngDest.longitude - latLngOrig.longitude;

    double zoom = map.getCameraPosition().zoom;

    double divLat = difLat / (zoom * 2);
    double divLng = difLng / (zoom * 2);

    LatLng tmpLatOri = latLngOrig;

    for(int i = 0; i < (zoom * 2); i++){
        LatLng loopLatLng = tmpLatOri;

        if(i > 0){
            loopLatLng = new LatLng(tmpLatOri.latitude + (divLat * 0.25f), tmpLatOri.longitude + (divLng * 0.25f));
        }

        Polyline polyline = map.addPolyline(new PolylineOptions()
            .add(loopLatLng)
            .add(new LatLng(tmpLatOri.latitude + divLat, tmpLatOri.longitude + divLng))
            .color(color)
            .width(5f));

        tmpLatOri = new LatLng(tmpLatOri.latitude + divLat, tmpLatOri.longitude + divLng);
    }
}
Edgar
  • 387
  • 4
  • 13
  • hi i am using this same method its working fine.. but zooming that dashed line also getting large.. do u know while zooming also it display the same dashed line size?.. – user Aug 13 '13 at 09:14
  • 1
    @user, a solution could be the creation of a List to store all the Polylines (List) that compound our "Dashed Line" and create a method to set the width of all the Polylines in that List for every zoom in/out. – Edgar Aug 20 '13 at 19:51
  • when you have a lot of line(1k) will this method slowdown the app? – Roberto Lombardini Nov 11 '14 at 17:39
  • This mehod is slow and computational slow even on modern phones, even if it seems the only one possible with v2 api – Zorb Jul 03 '15 at 06:30
  • This works well, however, how to clear lines with updates? – portfoliobuilder Aug 31 '16 at 21:46
9

I created the following function to draw dotted polyline with a list of LatLng points. This algorithm creates lines of 0.002 kms (followed by 0.002 kms meter gaps) irrespective of zoom. This is useful when you don't want to re-plot polylines when zoom changes.

private void drawDashedPolyLine(GoogleMap mMap, ArrayList<LatLng> listOfPoints, int color) {
    /* Boolean to control drawing alternate lines */
    boolean added = false;
    for (int i = 0; i < listOfPoints.size() - 1 ; i++) {
        /* Get distance between current and next point */
        double distance = getConvertedDistance(listOfPoints.get(i),listOfPoints.get(i + 1));

        /* If distance is less than 0.002 kms */
        if (distance < 0.002) {
            if (!added) {
                mMap.addPolyline(new PolylineOptions()
                        .add(listOfPoints.get(i))
                        .add(listOfPoints.get(i + 1))
                        .color(color));
                added = true;
            } else {/* Skip this piece */
                added = false;
            }
        } else {
            /* Get how many divisions to make of this line */
            int countOfDivisions = (int) ((distance/0.002));

            /* Get difference to add per lat/lng */
            double latdiff = (listOfPoints.get(i+1).latitude - listOfPoints
                    .get(i).latitude) / countOfDivisions;
            double lngdiff = (listOfPoints.get(i + 1).longitude - listOfPoints
                    .get(i).longitude) / countOfDivisions;

            /* Last known indicates start point of polyline. Initialized to ith point */
            LatLng lastKnowLatLng = new LatLng(listOfPoints.get(i).latitude, listOfPoints.get(i).longitude);
            for (int j = 0; j < countOfDivisions; j++) {

                /* Next point is point + diff */
                LatLng nextLatLng = new LatLng(lastKnowLatLng.latitude + latdiff, lastKnowLatLng.longitude + lngdiff);
                if (!added) {
                    mMap.addPolyline(new PolylineOptions()
                    .add(lastKnowLatLng)
                    .add(nextLatLng)
                    .color(color));
                    added = true;
                } else {
                    added = false;
                }
                lastKnowLatLng = nextLatLng;
            }
        }
    }
}

private double getConvertedDistance(LatLng latlng1, LatLng latlng2) {
    double distance = DistanceUtil.distance(latlng1.latitude,
            latlng1.longitude,
            latlng2.latitude,
            latlng2.longitude);
    BigDecimal bd = new BigDecimal(distance);
    BigDecimal res = bd.setScale(3, RoundingMode.DOWN);
    return res.doubleValue();
}

Util class to calculate distance between two LatLng:

public class DistanceUtil {

    public static double distance(double lat1, double lon1, double lat2,
        double lon2) {

    if ((lat1 == lat2) && (lon1 == lon2)) {
        return 0;
    } else
        return distance(lat1, lon1, lat2, lon2, 'K');
    }

    public static double distance(double lat1, double lon1, double lat2,
        double lon2, char unit) {
        double theta = lon1 - lon2;
        double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2))
            + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2))
            * Math.cos(deg2rad(theta));
        dist = Math.acos(dist);
        dist = rad2deg(dist);
        dist = dist * 60 * 1.1515;
        if (unit == 'K') {
            dist = dist * 1.609344;
        } else if (unit == 'N') {
            dist = dist * 0.8684;
        }
        return (dist);
    }

    private static double deg2rad(double deg) {
        return (deg * Math.PI / 180.0);
    }

    private static double rad2deg(double rad) {
        return (rad * 180.0 / Math.PI);
    }
}

Note: The above algorithm generates very large number of polylines which may take time to render. It is useful only when the list of points is small.

Swati Pardeshi
  • 599
  • 9
  • 12
  • I use you algo with 0.02 km and incremented int k in the loop: if (k%2==0) {addPopyline..} to get b/w dotted line – djdance Nov 22 '16 at 12:22