Search code examples
androidgoogle-mapsgoogle-maps-markersgoogle-polylinepolylineoptions

Position infoWindow away from overlapping polyline


I'm developing an Android application which contains an activity with google maps where I plot a path between two location with polylines. I have added markers at source and destination with infowindow showing some data, but these infowindow blocks the polyline and makes user zoom the map to see the path. Is there a way to move infowindow similar to how Uber does?Sample example of what I'm trying to achieve

Any help will be appreciated. Thank you.


Solution

  • There are really two parts to this problem: (1) establishing where you want the info window and (2) how to get it there. I will be focusing mostly on (1) and try to help with references for (2).

    (Note also there is a third problem which can be inferred from the animated gif: the infowindow for "Home" is adjusted because it is clipped in the final view - I've added an approach to this at the end.)

    One approach to (1) is to create a bounding rectangle around the path from Point A to Point B. This is a simplification of the problem which has shortcomings to be shown but is a good initial approach. There are optimizations which I think you'll soon realize to better fit the location in extreme cases.

    Use this bounding rectangle (R) to determine the minimum dimension relative to the marker anchor of interest (d1 vs d2).

    Using the mininimum dimension you can then compute a screen distance from anchor to nearest side of info window (f). From this nearest point you can then determine the anchor offset of the info window.

    First some pictures which serve several purposes: (a) identify key locations by label and (b) to start considering more complex problems:

    The simplest case is pictured here...:

    enter image description here

    ...but the the labels are bit crammed so a second looser case is pictured here:

    enter image description here

    Determining the bounding rectangle is straight forward albeit inefficient. Loop over the points of the path (from My Location to Home) and maintain the maximums and minimums of latitude and longitude (note that the -180 to 180 longitude crossover is a pervasive complexity not addressed here - just keep it in mind). This yields:

    LatLng upperLeft (maxLat, minLng)
    LatLng lowerRight (minLat, maxLng)
    

    So establishing the location of the info window of A is then:

    Compute the length (in meters) from A to side of rectangle by using Point A to (A lat, M lng) and Point A to (M lat, A Lng).  (Use `SphericalUtil.distanceBetween`)
    
    Determine the lesser of the two measurements, L.
    
    Use L (distance in meters) to compute a screen pixel equivalent S.
    
    Adjust S to offset from edge of BR (Sadj)
    
    Use Sadj (in screen pixels) to compute the Info Window offset (in screen pixels) taking into account the Info Window anchor point and the dimension of the Info Window.
    
    Set the info window anchor (which is relative to the marker coordinate system) and render.
    

    Optimization: Let's say you prefer the location of 'Home' in the 2nd picture to be something like:

    enter image description here

    Then the optimization would be to consider a smaller bounding rectangle using only some subset of the closer segments of path. So this leads to the next problem of determining when to optimize using thresholds for d1/d2. This same optimization would be used when the zoom level does not include both points; just use the points on screen to compute the bounding rectangle.

    For the third problem where "Home" is clipped after the zoom is to account for the dimensions of the infowindow when applying the bounding rectangle - this way the minimum dimension will always include the corresponding extent of the info window.