Google Maps API - different map style for polygon

后端 未结 1 722
灰色年华
灰色年华 2021-01-21 20:17

I want to achieve the effect similar to what is presented here:

inside Android google map. The polygon should have a different map style (json file) than the rest of t

相关标签:
1条回答
  • 2021-01-21 20:51

    That effect is possible with Polygon.setHoles() or PolygonOptions.addHole() methods. You should create gray transparent polygon for all map (from -90 to 90 degrees of latitude and from -180 to 180 of longitude) with holes for each of your terrain location. Something like this:

    public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
    
        private static final String TAG = MainActivity.class.getSimpleName();
        private GoogleMap mGoogleMap;
        private MapFragment mMapFragment;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mMapFragment = (MapFragment) getFragmentManager()
                    .findFragmentById(R.id.map_fragment);
            mMapFragment.getMapAsync(this);
        }
    
        @Override
        public void onMapReady(GoogleMap googleMap) {
            mGoogleMap = googleMap;
    
            List<List<LatLng>> holes = new ArrayList<>();
    
            // "hole" for Hyde Park
            List<LatLng> hole = new ArrayList<>();
            hole.add(new LatLng(51.509869, -0.191208));
            hole.add(new LatLng(51.513287, -0.158464));
            hole.add(new LatLng(51.505540, -0.151769));
            hole.add(new LatLng(51.502178, -0.174471));
            hole.add(new LatLng(51.502444, -0.187989));
            holes.add(hole);
    
            // "hole" for Regent's Park
            hole = new ArrayList<>();
            hole.add(new LatLng(51.530226, -0.167685));
            hole.add(new LatLng(51.534924, -0.163737));
            hole.add(new LatLng(51.537566, -0.151849));
            hole.add(new LatLng(51.535964, -0.146914));
            hole.add(new LatLng(51.525325, -0.145625));
            hole.add(new LatLng(51.523589, -0.155538));
            holes.add(hole);
    
            mGoogleMap.addPolygon(createPolygonWithHoles(holes));
    
            mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(51.519454, -0.168869), 14));
        }
    
        private static List<LatLng> createBoundsOfEntireMap() {
            final 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));
            }};
        }
    
        static PolygonOptions createPolygonWithHoles(List<List<LatLng>> holes) {
            PolygonOptions polyOptions = new PolygonOptions()
                    .fillColor(0x33000000)
                    .addAll(createBoundsOfEntireMap())
                    .strokeColor(0xFF000000)
                    .strokeWidth(5);
    
            for (List<LatLng> hole : holes) {
                polyOptions.addHole(hole);
            }
    
            return polyOptions;
        }
    
    }
    

    and you get something like that:

    Also you need bitmap circles as markers for polygon vertexes or draw it as Circle objects.

    Update

    For "hole-in-hole" case and "night-and-day" you should change .fillColor(0x33000000) to more dark, e.g. .fillColor(0xDD000000) and just add polygon with hole over "first" polygon. Something like this:

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mGoogleMap = googleMap;
    
        List<List<LatLng>> holes = new ArrayList<>();
    
        // "hole" for Hyde Park
        List<LatLng> hole = new ArrayList<>();
        hole.add(new LatLng(51.509869, -0.191208));
        hole.add(new LatLng(51.513287, -0.158464));
        hole.add(new LatLng(51.505540, -0.151769));
        hole.add(new LatLng(51.502178, -0.174471));
        hole.add(new LatLng(51.502444, -0.187989));
        holes.add(hole);
    
        // "hole" for Regent's Park
        hole = new ArrayList<>();
        hole.add(new LatLng(51.530226, -0.167685));
        hole.add(new LatLng(51.534924, -0.163737));
        hole.add(new LatLng(51.537566, -0.151849));
        hole.add(new LatLng(51.535964, -0.146914));
        hole.add(new LatLng(51.525325, -0.145625));
        hole.add(new LatLng(51.523589, -0.155538));
        holes.add(hole);
    
        mGoogleMap.addPolygon(createPolygonWithHoles(holes));
    
        List<LatLng> holesInHolesPoly = new ArrayList<>();
        holesInHolesPoly.add(new LatLng(51.508184, -0.177805));
        holesInHolesPoly.add(new LatLng(51.509759, -0.164373));
        holesInHolesPoly.add(new LatLng(51.504549, -0.162399));
        holesInHolesPoly.add(new LatLng(51.503453, -0.177934));
    
        List<LatLng> holesInHolesHole = new ArrayList<>();
        holesInHolesHole.add(new LatLng(51.505883, -0.172999));
        holesInHolesHole.add(new LatLng(51.507992, -0.171025));
        holesInHolesHole.add(new LatLng(51.506308, -0.169738));
    
        hole = new ArrayList<>();
        hole.add(new LatLng(51.530226, -0.167685));
    
        PolygonOptions holeInHoles = new PolygonOptions()
                .fillColor(0xDD000000)
                .addAll(holesInHolesPoly)
                .addHole(holesInHolesHole)
                .strokeColor(0xFF000000)
                .strokeWidth(5);
    
        mGoogleMap.addPolygon(holeInHoles);
    
        mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(51.519454, -0.168869), 14));
    }
    

    and you are got something like that:

    It's not a solution, but really good workaround. Or you can set "night" style for whole map and use custom TileProvider or GroundOverlay with "day" bitmap. Anyway - seems there are no "normal" way to create custom style for polygon part of the map.

    0 讨论(0)
提交回复
热议问题