Вопрос:

Проверьте координаты / места внутри полигонов в открытых слоях

openlayers openlayers-5

31 просмотра

2 ответа

44 Репутация автора

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

    places.forEach(p => {
       this.isInsidePolygons(p.latitude, p.longitude)
    })

    isInsidePolygons(latitude: number, longitude: number): boolean {
                let isInsidePolygon = false;

                var coordinate = OlHelper.transformToEPSG3857([Number(longitude), Number(latitude)]);
                var shapes = this.getShapes();
                for (let i = 0; i < shapes.length; i++) {
                    let features = shapes[i].getSource().getFeatures();
                    if (!features || features.length == 0) continue;

                    for (let j = 0; j < features.length; j++) {
                        var geometry = features[j].getGeometry();
                        isInsidePolygon = geometry.intersectsCoordinate(coordinate);
                        if (isInsidePolygon) break;
                    }
                    if (isInsidePolygon) break;
                }

                return isInsidePolygon;
            }

   getShapes(): ol.layer.Vector[] {
        var shapes = [];
        this.MapControl.getLayers().forEach((layer) => {
            if (layer instanceof ol.layer.Vector) shapes.push(layer);
        });
        return shapes;
    }

Можно ли проверить все места внутри полигонов в открытых слоях за одну проверку вместо зацикливания для каждого?

Автор: user10496245 Источник Размещён: 10.06.2019 05:27

Ответы (2)


0 плюса

3855 Репутация автора

Решение
    let features = shapes[i].getSource().getFeatures();
    if (!features || features.length == 0) continue;

    for (let j = 0; j < features.length; j++) {
        var geometry = features[j].getGeometry();
        isInsidePolygon = geometry.intersectsCoordinate(coordinate);
        if (isInsidePolygon) break;
    }

может быть заменено

    isInsidePolygon = (shapes[i].getSource().getFeaturesAtCoordinate(coordinate).length > 0);

что меньше кода, но, вероятно, не намного эффективнее

Чтобы проверить фигуры на более многочисленных местах, вам нужно создать векторный источник для ваших мест. Используйте экстент формы, чтобы получить короткий список мест, и проверяйте только те, которые соответствуют геометрии формы

    let placesFeatures = [];
    places.forEach((p) => {
        placesFeatures.push(new Feature({
            geometry: new Point(fromLonLat[p.longitude, p.latitude]))
            id: [p.latitude, p.longitude].toString,
            isInsidePolygon: false
        }))
    })
    let placesSource = new VectorSource({features: placesFeatures});

    for (let i = 0; i < shapes.length; i++) {
        let features = shapes[i].getSource().getFeatures();
        if (!features || features.length == 0) continue;

        for (let j = 0; j < features.length; j++) {
            var geometry = features[j].getGeometry();
            let extent = features[j].getGeometry().getExtent();
            let candidates = placesSource.getFeaturesInExtent(geometry.getExtent());
            if (!candidates || candidates.length == 0) continue;

            for (let k = 0; k < candidates.length; k++) {
                isInsidePolygon = geometry.intersectsCoordinate(candidates[k].getGeometry().getCoordinates());
                if (isInsidePolygon) {
                    candidates[k].set('isInsidePolygon', true);
                }
            })
        }
    }

Тогда вы можете получить результаты от мест объектов в источнике

    isInsidePolygons(latitude: number, longitude: number): boolean {
        return placesSource.getFeatureById([latitude, longitude].toString()).get('isInsidePolygon');
    }
Автор: Mike Размещён: 10.06.2019 07:23

0 плюса

11 Репутация автора

Вы можете использовать turf.js , в частности, функцию pointsWithinPolygon . Начиная с многоугольника или многоугольника и списка точек, функции возвращают все точки внутри многоугольника, но сложность линейна с количеством точек. Если мы используем turf.js, вы должны конвертировать функции в GeoJSON.

let format = new ol.format.GeoJSON();
            return turf.pointsWithinPolygon(
                format.writeFeatureObject(points),
                format.writeFeatureObject(polygon)
            );

А затем прочитать особенности GeoJson

let features =  format.readFeatures(jsonFile.features);

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

Автор: SMattia Размещён: 12.06.2019 10:05
Вопросы из категории :
32x32