Многоугольник с отверстиями в нем действует неправильно (исчезает) при большом увеличении - PullRequest
1 голос
/ 08 апреля 2020

Задача разработать приложение с картой мира, покрытой многоугольником, и некоторая область должна быть «включена». Для этого я создал дыры в этом многоугольнике мира.

Это Android с использованием карт Google

    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()))
            }
        }
    }

После этого у нас получится

World Polygon with hole

Проблема начинается, когда я увеличиваю до последних 2 уровней увеличения. В зависимости от карты настроение отверстие может быть покрыто многоугольной заливкой, или многоугольная заливка может исчезнуть.

Whole world in red Polygon fill gone

Фактический результат должен быть таким на всех уровнях масштабирования. enter image description here

Я пробовал с разными стилями карты, без стилей карты, другой способ создания мира, охватывающего многоугольник ....

Когда я создаю меньший многоугольник нет проблем.

1 Ответ

1 голос
/ 10 апреля 2020

Возможно, это связано с тем, что точки многоугольника отверстия находятся далеко от видимой области. Вы должны получить видимую область map.getProjection().getVisibleRegion() и добавить многоугольники отверстий только вблизи этой области, но с максимально возможным количеством точек на границах из-за производительности. Вы можете использовать SphericalUtil.interpolate(), чтобы добавить дополнительные точки на каждый сегмент многоугольника отверстия. Также вам нужен код как в ответах на этот вопрос, чтобы найти пересечение отрезков ломаной линии. И в любом случае вы всегда можете создавать собственные компоненты на основе MapView и рисовать перекрывающиеся полигоны на холсте вручную.

...