简体   繁体   中英

How to draw dashed polyline with android google map sdk v2?

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?

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

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

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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