2

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.

djevtic
  • 68
  • 5

1 Answers1

1

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.

Andrii Omelchenko
  • 13,183
  • 12
  • 43
  • 79
  • @djevtic Which exactly variant do you solve the problem with? – Andrii Omelchenko Apr 22 '20 at 13:32
  • Unfortunately with neither of them. Both of them are good solutions but not for use-case i had. I made smaller polygon which don't cover whole world but just areas which are important to me (Europe and North America) and made holes in it. Set edges of polygons to transparent and added additional polygons which will cover rest of the world. Added holes as usual just had to add additional polygon on top of already existing hole of same size to be able to create borders. This approach is .... questionable but it worked for me and didn't made negative impact of application performance. – djevtic May 07 '20 at 06:24