Пользовательский интерфейс блокируется при увеличении / уменьшении с маркерами в интеграции openlayers - PullRequest
0 голосов
/ 17 апреля 2019

Я включил openlayers в свой проект angularJs / Typescript с картой bing для разработки клиентского приложения ms Dynamics CRM. Я использую это приложение в качестве офлайн-HTML в полевой службе мобильной CRM.

У меня есть около 5 тыс. Записей в качестве маркеров на карте, но когда я увеличиваю / уменьшаю масштаб, карта зависает, что означает, что все действия блокируются в течение 10-20 секунд, что, я думаю, ужасно.

Вот мелкий код:

this.ClusterSource = new ol.source.Cluster({
     distance: distance,
     source: vectorSource
});

var vectorLayer = new ol.layer.Vector({
    renderMode: 'image',
    source: this.ClusterSource,
    style: this.styleFunction,
    zIndex: 9999
});


self.MapControl.addLayer(vectorLayer);  

styleFunction = (feature, resolution) => {
    let self = this;

    if (!feature || !resolution) return;

        let finalStyle: ol.style.Style;
        let features = <ol.Feature[]>feature.get("features");
        if (features.length === 1) {
            finalStyle = new ol.style.Style({
                image: new ol.style.Icon({ src: 
                self.getIconForSinglePlace(feature.get("features")[0]) })
            });
        } else if (features.length > 1) {
            if (resolution > 1) finalStyle = 
                self.getStyleForCluster(features.length);
            else self.displayOverlapping(features);
        }

        return finalStyle;
    }



    getStyleForCluster = (size: number): ol.style.Style => {
        let clusterStyle = (<any>window).styleCache[size];
        if (!clusterStyle) {
            clusterStyle = new ol.style.Style({
                image: new ol.style.Circle({
                    radius: (Math.log(size) / Math.log(10)) * 3 + 10,
                    fill: new ol.style.Fill({
                        color: this.getFillColorForPlace(size)
                    })
                }),
                text: new ol.style.Text({
                    text: size.toString(),
                    fill: new ol.style.Fill({
                        color: "#fff"
                    })
                })
            });
            (<any>window).styleCache[size] = clusterStyle;
        }
        return clusterStyle;
    }

    getIconForSinglePlace(feature: any) {
        return feature.get("metadata").icon
            ? feature.get("metadata").icon
            : 
  `../images/pushpins/${feature.get("metadata").Color.substring(1)}.png`;
    }

    // this function call for duplicate position of markers
    displayOverlapping = (features: ol.Feature[]) => {
        if (features) {
            let coordinates = (<any>features[0].getGeometry()).getCoordinates();
            let points = this.generatePointsCircle(features.length, coordinates);

            let multiLineString = new ol.geom.MultiLineString([]);
            multiLineString.setCoordinates([]);

            features.forEach((feature, index) => {
                multiLineString.appendLineString(new ol.geom.LineString([coordinates, points[index]]));
                feature.setGeometry(new ol.geom.Point(points[index]));
            });
        }
    };

Я ищу предложение от экспертов.

1 Ответ

0 голосов
/ 17 апреля 2019

Вы должны кэшировать свои стили отдельных элементов так же, как вы кэшируете стили кластера.

    if (features.length === 1) {
        let src = self.getIconForSinglePlace(feature.get("features")[0]);
        finalStyle = (<any>window).styleCache[src];
        if (!finalStyle) {
            finalStyle = new ol.style.Style({
                image: new ol.style.Icon({ src: src })
            });
            (<any>window).styleCache[src] = finalStyle;
        }
...