Search code examples
androidgoogle-mapspolygoninfowindowgoogle-maps-api-2

How to manage InfoWindows for polygons on Android Google Maps API v2


I'm looking for a way to manage Info Windows (open, close, set content) for polygons, just like it's done for markers
I can probably listen for onClick event and put a some hidden marker there and open an InfoWindow for that marker. There is a problem finding a polygon to retrieve an InfoWindow content though.
There is a more elegant solution?


Solution

  • I have been working out in a solution similar to your problem.

    As you said, the main problem is how to get if LatLng coordinate got from OnMapLongClickListener() is inside a polygon.

    There is a popular algorithm you can use for doing this called Point-in-polygon algorithm.. This is a adaptation for Java of this algorithm.

    private boolean containsInPolygon(LatLng latLng, Polygon polygon) {
    
        boolean oddTransitions = false;
        List<VerticesPolygon> verticesPolygon = polygon.getVertices();
        float[] polyY, polyX;
        float x = (float) (latLng.latitude);
        float y = (float) (latLng.longitude);
    
        // Create arrays for vertices coordinates
        polyY = new float[verticesPolygon.size()];
        polyX = new float[verticesPolygon.size()];
        for (int i=0; i<verticesPolygon.size() ; i++) {
            VerticesPolygon verticePolygon = verticesPolygon.get(i);
            polyY[i] = (float) (verticePolygon.getVertice().getLongitude());
            polyX[i] = (float) (verticePolygon.getVertice().getLatitude());
        }
        // Check if a virtual infinite line cross each arc of the polygon
        for (int i = 0, j = verticesPolygon.size() - 1; i < verticesPolygon.size(); j = i++) {
            if ((polyY[i] < y && polyY[j] >= y)
                    || (polyY[j] < y && polyY[i] >= y)
                    && (polyX[i] <= x || polyX[j] <= x)) {
                if (polyX[i] + (y - polyY[i]) / (polyY[j] - polyY[i])
                        * (polyX[j] - polyX[i]) < x) {
                    // The line cross this arc
                    oddTransitions = !oddTransitions;
                }
            }
        }
        // Return odd-even number of intersecs
        return oddTransitions;
    }
    

    Finally, create a CustomInfoWindowsAdapter for managing what you want to show.