Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
251 views
in Technique[技术] by (71.8m points)

android google maps Polygon add circle hole

hi currently im working on a google maps app.

and i want the following effect:

enter image description here

To do this i was thing of first creating a polygon overlay over the country, following by adding a hole to this polygon for the highlighted area with a certain KM radius, so that it shrinks and expands when zooming.

Now i know how to create a polygon;

mMap.addPolygon(new PolygonOptions().addAll(sCountryBorder).fillColor(0xcc000000));

Now i want to add a hole to this polygon, but i dont know how to generate a circular hole with the correct radius.

mMap.addPolygon(new PolygonOptions().addAll(sCountryBorder).fillColor(0xcc000000).addHole({CIRCULAR_HOLE}));

I know it is possible to create a circle with a certain radius in Google maps is it also possible to somehow convert this into an Array of LatLng objects?

mMap.addCircle(new CircleOptions()
                        .center(newLocation)
                        .radius(mRadius.size)
                        .strokeWidth(0)
                        .fillColor(getResources().getColor(R.color.transparant)));
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Unfortunately, Google Maps library doesn't let to get an array of LatLng of the circle. So you need to draw a circle yourself.

Basically, you need to provide a method that will create a hole (circle) for a polygon which fills your map.

There are 3 steps.

1 step is to build a method that will create a polygon that covers an entire map.

private static List<LatLng> createOuterBounds() {
    float delta = 0.01f;

    return new ArrayList<LatLng>() {{
        add(new LatLng(90 - delta, -180 + delta));
        add(new LatLng(0, -180 + delta));
        add(new LatLng(-90 + delta, -180 + delta));
        add(new LatLng(-90 + delta, 0));
        add(new LatLng(-90 + delta, 180 - delta));
        add(new LatLng(0, 180 - delta));
        add(new LatLng(90 - delta, 180 - delta));
        add(new LatLng(90 - delta, 0));
        add(new LatLng(90 - delta, -180 + delta));
    }};
}

2 step is to create a method that will return an Iterable with LatLngs of the circle.

private static Iterable<LatLng> createHole(LatLng center, int radius) {
    int points = 50; // number of corners of inscribed polygon

    double radiusLatitude = Math.toDegrees(radius / (float) EARTH_RADIUS);
    double radiusLongitude = radiusLatitude / Math.cos(Math.toRadians(center.latitude));

    List<LatLng> result = new ArrayList<>(points);

    double anglePerCircleRegion = 2 * Math.PI / points;

    for (int i = 0; i < points; i++) {
        double theta = i * anglePerCircleRegion;
        double latitude = center.latitude + (radiusLatitude * Math.sin(theta));
        double longitude = center.longitude + (radiusLongitude * Math.cos(theta));

        result.add(new LatLng(latitude, longitude));
    }

    return result;
}

3 and the last step is to use these methods for PolygonOptions creation.

static PolygonOptions createPolygonWithCircle(Context context, LatLng center, int radius) {
    return new PolygonOptions()
        .fillColor(ContextCompat.getColor(context, R.color.grey_500_transparent))
        .addAll(createOuterBounds())
        .addHole(createHole(center, radius))
        .strokeWidth(0);
}

I have also created a demo repository which contains an app which draws a needed circle. https://github.com/AntonyGolovin/Google-Map-mask. All needed logic is contained in MapHelper.java class.

Result:

Screenshot


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...