带有图标和文本的标记

Marker with icon and text

我在 openlayers 地图中首先显示带有图标的标记,当放大某些缩放级别时,文本显示为图标下方的叠加层,但它工作不流畅。请在下面找到我的代码:

var distance = heatMap ? 14 : 40;
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
});

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

    if (!feature || !resolution) return;

    let finalStyle: ol.style.Style;
    let features = <ol.Feature[]>feature.get("features");

    if (self.MapControl.getView().getZoom() > 12) {
        this.displayPopOver(features);
    } else {
        this.removePopOver(features);
    }

    if (features.length === 1) {
        const color = self.getIconColorSinglePlace(feature.get("features")[0]);
        finalStyle = (<any>window).styleCache[color];
        if (!finalStyle) {
            finalStyle = new ol.style.Style({
                image: new ol.style.Circle({
                    radius: 10,
                    fill: new ol.style.Fill({ color: `#${color}` }),
                    stroke: new ol.style.Stroke({
                        color: 'white', width: 2
                    })
                })
            });
            (<any>window).styleCache[color] = finalStyle;
        }
    }
    else if (features.length > 1) {
        if (resolution > 1) {
            finalStyle = self.getStyleForCluster(features.length);
        }
        else self.displayOverlapping(features);
    }

    return finalStyle;
}

// display name attached to marker
displayPopOver = (features: ol.Feature[]) => {
    if (features) {
        features.forEach((feature, index) => {
            // show popover overlay for each record
            this.popoverOverlay(feature, index);
        });
    }
};

// add pop overlay to display entity name
popoverOverlay = (feature, index) => {
    var element = document.createElement('div');
    element.style.cssText = 'margin-left: -50px; margin-top:5px;';
    element.innerHTML = (feature && feature.get('name').length > 0) ? feature.get('name') : '';

    let overlay = new ol.Overlay({
        id: index + 'featureName',
        element: element
    });

    const coordinate = (<any>feature.getGeometry()).getCoordinates();
    overlay.setPosition(coordinate);
    this.MapControl.addOverlay(overlay);
};

// remove all entity name attached to marker when zoom level below 10
removePopOver = (features: ol.Feature[]) => {
    if (features) {
        let overlays = <ol.Overlay[]>[];

        features.forEach((feature, index) => {
            this.MapControl.getOverlays().forEach(overlay => {
                if (overlay.getId() === index + 'featureName')
                    overlays.push(overlay);
            });
        });

        this.deleteOverlays(overlays);
    }
};

我想让它变得流畅和完美,但在我当前的代码中,有时它会减慢地图的速度。我可以使用样式文本而不是覆盖,但问题是功能具有需要循环管理的功能,因此我无法使用 feature.get 来获取功能名称。

您可以轻松地将文本显示为单个功能样式中的标签。当特征被聚类时,为每个特征显示弹出窗口没有意义,它违背了聚类的目的,因为它们会相互遮挡和聚类..

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) {
        const color = self.getIconColorSinglePlace(feature.get("features")[0]);
        finalStyle = (<any>window).styleCache[color];
        if (!finalStyle) {
            finalStyle = new ol.style.Style({
                image: new ol.style.Circle({
                    radius: 10,
                    fill: new ol.style.Fill({ color: `#${color}` }),
                    stroke: new ol.style.Stroke({
                        color: 'white', width: 2
                    })
                }),
                text: new ol.style.Text({
                    // add font and other options
                })
            });
            (<any>window).styleCache[color] = finalStyle;
        }
        let label = '';
        if (resolution < map.getView().getResolutionForZoom(12)) {
          label = feature.get("features")[0].get('name');
        }
        finalStyle.getText().setText(label);
    }
    else if (features.length > 1) {
        if (resolution > 1) {
            finalStyle = self.getStyleForCluster(features.length);
        }
        else self.displayOverlapping(features);
    }

    return finalStyle;
}