带有图标和文字的标记

时间:2019-05-24 08:50:42

标签: openlayers openlayers-5

我首先在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来获取功能名称。

1 个答案:

答案 0 :(得分:0)

您可以轻松地在各个要素的样式中将文本显示为标签。在对要素进行聚类时,为每个要素显示弹出窗口是没有意义的,它破坏了聚类的目的,因为它们会使彼此和聚类模糊不清。

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;
}