djevtic
djevtic

Reputation: 68

Polygon with holes in it act improperly (disappear) on high zoom

Have task to develop app with world map covered with polygon and some area should be "enabled". For that purpose i have created holes in that "world" polygon.

This is Android with use of google maps

    implementation 'com.google.android.gms:play-services-maps:17.0.0'
    implementation 'com.google.android.gms:play-services-location:17.0.0'
override fun onMapReady(map: GoogleMap?) {
        if(map != null) {
            var holes: MutableList<MutableList<LatLng>> = mutableListOf()
            //Set coordinates for future hole on map
            var hole: MutableList<LatLng> = mutableListOf()
            hole.add(LatLng(47.438741, 16.868739))
            hole.add(LatLng(47.517742, 21.331959))
            hole.add(LatLng(40.517742, 21.331959))
            hole.add(LatLng(40.438741, 16.868739))
            holes.add(hole)
            //Adding world covering polygon
            map.addPolygon(
                createPolygonWithHoles(
                    holes,
                    applicationContext
                )
            )
        }
    }


    /**
     * Adding holes on map
     */
    private fun createPolygonWithHoles(holes: List<List<LatLng>>, context: Context): PolygonOptions {
       //Creating PolygonOptions of future world polygon
        val polyOptions = PolygonOptions()
            .addAll(createBoundsOfEntireMap())
            .strokeColor(resources.getColor(android.R.color.holo_blue_bright, null))
            .fillColor(resources.getColor(android.R.color.holo_red_dark, null))
            .strokeWidth(15f)
        //Adding holes to PolygoneOptions
        holes.forEach {
            polyOptions.addHole(it)
        }
       return polyOptions
    }

/**
     * Preparing and updating bounds on maps so that it looks like we have holes on it
     */
    private fun createBoundsOfEntireMap(): List<LatLng> {
        val delta = 0.00001f

        return object : ArrayList<LatLng>() {
            init {
                add(LatLng((90 - delta).toDouble(), (-180 + delta).toDouble()))
                add(LatLng(0.0, (-180 + delta).toDouble()))
                add(LatLng((-90 + delta).toDouble(), (-180 + delta).toDouble()))
                add(LatLng((-90 + delta).toDouble(), 0.0))
                add(LatLng((-90 + delta).toDouble(), (180 - delta).toDouble()))
                add(LatLng(0.0, (180 - delta).toDouble()))
                add(LatLng((90 - delta).toDouble(), (180 - delta).toDouble()))
                add(LatLng((90 - delta).toDouble(), 0.0))
                add(LatLng((90 - delta).toDouble(), (-180 + delta).toDouble()))
            }
        }
    }

After that we have this result

World Polygon with hole

Problem starts when i zoom to last 2 zoom levels. Depending on map mood hole can be covered with polygon fill or polygon fill can disappear.

Whole world in red Polygon fill gone

Actual result should be like this on all zoom levels. enter image description here

I have tried with different map stiles, with no map stiles, different way of creating world covering polygon ....

When i create smaller polygon there is no issue.

Upvotes: 2

Views: 322

Answers (1)

Andrii Omelchenko
Andrii Omelchenko

Reputation: 13343

Probably this is because points of hole polygone is far away from visible area. You should get visible area map.getProjection().getVisibleRegion() and add holes polygons only near that area, but with as many points on borders as possible due performance. You can use SphericalUtil.interpolate() to add additional points on each hole polygone segment. Also you need code like in answers for this question to find intersection of holes polyline segments. And anyway you always can create custom MapView- based component and draw overlapped polygons on canvas manually.

Upvotes: 1

Related Questions