Search code examples
javaandroidgoogle-mapsdistancearea

Android Google Map how to check if user is in marker rectangle region


I am using Google Maps, and want to be able to detect if a user is in the rectangle of a Marker (placed on a map), using the user's current location. I have the user's current location coordinates (latitude and longitude) and the marker's coordinates but do not know how to calculate whether the user is in the area.


Solution

  • The short answer is to use the PolyUtil.containsLocation using the rectangle corner points (centered on the marker) and the user's location:

    boolean isWithin = PolyUtil.containsLocation(userPt, rectanglePts, true);
    

    Here is docs on map utils. And the PolyUtil java docs

    Here is a code fragment demonstrating. Note the rectangle rotation is handled by the utility so it need not be aligned to the coordinate system. In fact it doesn't even need to be a rectangle.

    (I chose to use circles for display purposes but can be replaced with markers.):

    In this example, the marker is drawn as a circle in green, the containing rectangle and two arbitrary points (possible user locations) to show result of calculation (RED=in, BLUE=out).

    // Create rectangle coordinates 
    LatLng upperLeft = new LatLng(39.274659,-77.639552);
    LatLng upperRight = SphericalUtil.computeOffset(upperLeft, 12000, 120);
    LatLng lowerRight = SphericalUtil.computeOffset(upperRight, 5000, 210);
    LatLng lowerLeft = SphericalUtil.computeOffset(lowerRight, 12000, 300);
    
    // Make a list for the polygon
    List<LatLng> polygonPts = new ArrayList<>();
        polygonPts.add(upperLeft);
        polygonPts.add(upperRight);
        polygonPts.add(lowerRight);
        polygonPts.add(lowerLeft);
    
    // Draw rectangle
    mMap.addPolygon(new PolygonOptions().addAll(polygonPts).geodesic(true).strokeColor(Color.BLACK));
    
    // Draw marker (center of rectangle)
    LatLng mPos = SphericalUtil.computeOffset(SphericalUtil.computeOffset(upperLeft,6000,120),2500, 210);
    
    // Now add a circle to represent the marker - circles display nicer
    mMap.addCircle(new CircleOptions().center(mPos).fillColor(Color.GREEN).radius(300).strokeWidth(1));
    
    
    // Add two points and compute whether they are inside or outside rectangle and
    // set color based on that (RED=inside BLUE=outside)
    LatLng circleInside = SphericalUtil.computeOffset(mPos,1000, 320);
    LatLng circleOutside = SphericalUtil.computeOffset(mPos,4000, 45);
    
    // Determine if point is inside rectangle and set color accordingly.
    int insideCircleColor = (PolyUtil.containsLocation(circleInside, polygonPts, true) ? Color.RED : Color.BLUE);
    int outsideCircleColor = (PolyUtil.containsLocation(circleOutside, polygonPts, true) ? Color.RED : Color.BLUE);
    
    // Add to map
    mMap.addCircle(new CircleOptions().center(SphericalUtil.computeOffset(circleInside,1000, 320)).fillColor(insideCircleColor).radius(200).strokeWidth(1));
    mMap.addCircle(new CircleOptions().center(SphericalUtil.computeOffset(circleOutside,1000, 320)).fillColor(outsideCircleColor).radius(200).strokeWidth(1));
    
    // and zoom to center
    mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(mPos, 12.0f));
    

    And display:

    enter image description here