8

I have 2 markers, I would like to draw a line between them, and have a text showing the distance above the line, just like in the web version of google maps.

maps

I've already found this sample about drawing a line between 2 markers, but how do I add text above the line?

Chackle
  • 2,249
  • 18
  • 34
Tamas
  • 360
  • 1
  • 4
  • 13

2 Answers2

9

I had a situation to show the distance between two markers above the polyline.

Below is what was my requirement:

enter image description here

I managed to do it in some other way and it is quite interesting way, this way you can customize it to achieve anything.

Steps:

  1. Calculate the distance between the markers by using Location.distanceBetween() method.
  2. Create a new Layout XML file and create whatever type of UI you want to show for your text. In my case it contained only one TextView.
  3. Set the calculated distance in the TextView.
  4. Convert the XML Layout to Bitmap.
  5. Create a BitmapDescriptor from that Bitmap object.
  6. Find out the midpoint between the desired markers and add a custom marker by using the BitmapDescriptor created in last step and you are done.

Code:

To calculate distance between two markers

float[] distance1 = new float[1];
Location.distanceBetween(userMarker.getPosition().latitude, userMarker.getPosition().longitude, positionMarker.getPosition().latitude, positionMarker.getPosition().longitude, distance1);

Create Bitmap from XML Layout file

LinearLayout distanceMarkerLayout = (LinearLayout) getLayoutInflater().inflate(R.layout.distance_marker_layout, null);

distanceMarkerLayout.setDrawingCacheEnabled(true);
distanceMarkerLayout.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
distanceMarkerLayout.layout(0, 0, distanceMarkerLayout.getMeasuredWidth(), distanceMarkerLayout.getMeasuredHeight()); 
distanceMarkerLayout.buildDrawingCache(true);

TextView positionDistance = (TextView) distanceMarkerLayout.findViewById(R.id.positionDistance);

positionDistance.setText(distance1[0]+" meters");           

Bitmap flagBitmap = Bitmap.createBitmap(distanceMarkerLayout.getDrawingCache());
                distanceMarkerLayout.setDrawingCacheEnabled(false);
                BitmapDescriptor flagBitmapDescriptor = BitmapDescriptorFactory.fromBitmap(flagBitmap);

To find out mid point between two markers do something like the following:

double dLon = Math.toRadians(flagMarker.getPosition().longitude - positionMarker.getPosition().longitude);

double lat1 = Math.toRadians(positionMarker.getPosition().latitude);
double lat2 = Math.toRadians(flagMarker.getPosition().latitude);
double lon1 = Math.toRadians(positionMarker.getPosition().longitude);

double Bx = Math.cos(lat2) * Math.cos(dLon);
double By = Math.cos(lat2) * Math.sin(dLon);
double lat3 = Math.atan2(Math.sin(lat1) + Math.sin(lat2), Math.sqrt((Math.cos(lat1) + Bx) * (Math.cos(lat1) + Bx) + By * By));
double lon3 = lon1 + Math.atan2(By, Math.cos(lat1) + Bx);

lat3 = Math.toDegrees(lat3);
lon3 = Math.toDegrees(lon3);

Add a new cutom marker by using the bitmap descriptor created by us in previous steps

Marker centerOneMarker = mMap.addMarker(new MarkerOptions()
                .position(new LatLng(lat3, lon3))
                .icon(flagBitmapDescriptor));

Hope it helps you.

gprathour
  • 14,813
  • 5
  • 66
  • 90
  • Exactly what I needed, you saved my day @gprathour, Thank you. – Amitabh Sarkar Nov 24 '16 at 07:33
  • @AmitabhSarkar Welcome :) – gprathour Nov 30 '16 at 08:44
  • 1
    How the hell did it occur to you?!You're a genius. – Steve Moretz Apr 27 '19 at 19:01
  • What's with all those calculation just use (lat1 + lat2)/2 and same for lon1 and lon2 – Steve Moretz Apr 27 '19 at 19:19
  • @stevemoretz Thanks buddy! I just made out a way to do it at that time and wanted to share it so that it might help someone else also. Apart from it, as of now, I don't remember about the calculations and why those were required. If you got a better way of doing it, please feel free to share. – gprathour Apr 28 '19 at 06:31
  • @gprathour maybe you wanted to get the heading angle but you forgot?My way is rather simple you use: fun calculateMiddlePoint(a: LatLng, b: LatLng): LatLng = LatLng(((a.latitude + b.latitude) / 2), ((a.longitude + b.longitude) / 2)) and another function for calculating heading angle: fun angleFromCoordinate(fLat : LatLng,sLat : LatLng): Float =(Math.atan2(sLat.longitude - fLat.longitude, sLat.latitude - fLat.latitude) * 180 / Math.PI).toFloat() as you see they are only two lines of code :) feel free to update your answer with my code.(It's in kotlin btw) – Steve Moretz Apr 28 '19 at 08:54
  • The angle function gives you the heading you should do +90 or -90 to get the text aligned with the line.use MarkerOptions.rotation(...) For doing that I think you know that already anyway.But maybe it helps somebody else :) – Steve Moretz Apr 28 '19 at 08:56
3

One idea would be to calculate the midpoint between the two markers using their lat and long coordinates and then put an infowindow with whatever information you want to show. Or something like the following could help: Link

so_jin_ee
  • 802
  • 6
  • 7
  • 1
    Good idea, but according to the [docs](https://developers.google.com/maps/documentation/android/infowindows), only 1 infowindow can be visible at a time, and it has to be bound to a marker. So I would have to use an invisible marker, and not use any other infowindows. – Tamas Apr 28 '15 at 14:21
  • Or another idea would be custom overlays. Use texts as custom overlays on top of the lines. But I doubt that this is any easier to achieve. Unfortunately, for now, it seems that there's no supported method that attaches text to a polyline yet. – so_jin_ee Apr 28 '15 at 14:29
  • Meanwhile I've tried out the infowindow hack, and it is crazy slow. I need to update it on every drag event so it will be at the proper point, and even with just 1 textview it's really slow. ~1-2fps during drag(on galaxy tab GT-P5200). – Tamas Apr 28 '15 at 14:44
  • Please let me know if you eventually get a way better solution. I've been looking for a better answer as well. – so_jin_ee Apr 28 '15 at 14:47
  • I'll probably stick with yours (with updating the infowindow position maybe on every 5th drag even only) :) – Tamas Apr 28 '15 at 14:48