Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I draw a curved dashed line in Google Maps Android?

In Google Maps from browser which has the curved dashed line look like this: enter image description here

But when I implement Google Maps in my own Android project, it didn't show this line

enter image description here

How can I draw this line?

like image 615
Tấn Nguyên Avatar asked Apr 09 '17 10:04

Tấn Nguyên


People also ask

What is a dashed line on Google Maps?

Disputed boundaries are displayed as a dashed gray line. The places involved don't agree on a boundary.


1 Answers

You can implement the curved dashed polyline between two points. For this purpose you can use Google Maps Android API Utility Library that has SphericalUtil class and apply some math in your code to create a polyline.

You have to include the utility library in your gradle as

compile 'com.google.maps.android:android-maps-utils:0.5'.

Please have a look at my sample Activity and function showCurvedPolyline (LatLng p1, LatLng p2, double k) that constructs dashed curved polyline between two points. The last parameter k defines curvature of the polyline, it can be >0 and <=1. In my example I used k=0.5

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

private GoogleMap mMap;
private LatLng sydney1;
private LatLng sydney2;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
}

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    mMap.getUiSettings().setZoomControlsEnabled(true);

    // Add a marker in Sydney and move the camera
    sydney1 = new LatLng(-33.904438,151.249852);
    sydney2 = new LatLng(-33.905823,151.252422);

    mMap.addMarker(new MarkerOptions().position(sydney1)
            .draggable(false).visible(true).title("Marker in Sydney 1"));
    mMap.addMarker(new MarkerOptions().position(sydney2)
            .draggable(false).visible(true).title("Marker in Sydney 2"));

    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney1, 16F));

    this.showCurvedPolyline(sydney1,sydney2, 0.5);
}

private void showCurvedPolyline (LatLng p1, LatLng p2, double k) {
    //Calculate distance and heading between two points
    double d = SphericalUtil.computeDistanceBetween(p1,p2);
    double h = SphericalUtil.computeHeading(p1, p2);

    //Midpoint position
    LatLng p = SphericalUtil.computeOffset(p1, d*0.5, h);

    //Apply some mathematics to calculate position of the circle center
    double x = (1-k*k)*d*0.5/(2*k);
    double r = (1+k*k)*d*0.5/(2*k);

    LatLng c = SphericalUtil.computeOffset(p, x, h + 90.0);

    //Polyline options
    PolylineOptions options = new PolylineOptions();
    List<PatternItem> pattern = Arrays.<PatternItem>asList(new Dash(30), new Gap(20));

    //Calculate heading between circle center and two points
    double h1 = SphericalUtil.computeHeading(c, p1);
    double h2 = SphericalUtil.computeHeading(c, p2);

    //Calculate positions of points on circle border and add them to polyline options
    int numpoints = 100;
    double step = (h2 -h1) / numpoints;

    for (int i=0; i < numpoints; i++) {
        LatLng pi = SphericalUtil.computeOffset(c, r, h1 + i * step);
        options.add(pi);
    }

    //Draw polyline
    mMap.addPolyline(options.width(10).color(Color.MAGENTA).geodesic(false).pattern(pattern));
}

}

You can download a sample project with complete code from GitHub

https://github.com/xomena-so/so43305664

Just replace my API key with yours in the app/src/debug/res/values/google_maps_api.xml

enter image description here

like image 73
xomena Avatar answered Oct 06 '22 00:10

xomena