【问题标题】:OpenLayers 5 clicking on feature does not find it but clicking below the feature doesOpenLayers 5点击功能没有找到它,但点击功能下方
【发布时间】:2019-08-27 04:52:45
【问题描述】:

地图使用自定义样式呈现特征。单击显示特征的地图会触发单击事件,但未找到该特征。如果单击地图略低于显示的样式,则可以找到该特征。这也不是每次都有效。部分代码来自使用 OpenLayers 4.5 的项目。

我正在按照此处提供的指南使用 OpenLayers 和 ReactJs https://taylor.callsen.me/using-reactflux-with-openlayers-3-and-other-third-party-libraries/

我尝试使用标准样式,但也有同样的问题。我也尝试注释掉'projection: "EPSG:3857"' 行,但这没有任何区别。

import React, { Component } from "react";
import * as ol from "ol";
import * as layer from "ol/layer";
import * as source from "ol/source";
import * as geom from "ol/geom";
import * as style from "ol/style";
import * as extent from "ol/extent";
import "ol/ol.css";

class MapWrapper extends Component {
    constructor(props) {
        super(props);
        this.state = {
            center: [-483760, 7480740],
            zoom: 8,
            rotation: 0,
            circleRadius: 10,
            circleBorder: 1,
            circleBorderColor: "#212121"
        };
    }

    componentDidMount() {
        let featureSource = new source.Vector({
            projection: "EPSG:3857",
            features: this.getFeatures()
        });

        let clusterSource = new source.Cluster({
            distance: 16,
            projection: "EPSG:3857",
            source: featureSource
        });

        let clusterLayer = new layer.Vector({
            projection: "EPSG:3857",
            source: clusterSource,
            style: cluster => this.getClusterStyle(cluster)
        });

        let map = new ol.Map({
            target: this.refs.mapContainer,
            layers: [
                new layer.Tile({
                    projection: "EPSG:3857",
                    source: new source.OSM()
                }),
                clusterLayer
            ],
            view: new ol.View({
                projection: "EPSG:3857",
                center: this.state.center,
                zoom: this.state.zoom,
                rotation: this.state.rotation
            })
        });

        this.setState({
            map: map,
            clusterSource: clusterSource
        });

        map.on("click", this.handleMapClick.bind(this));
    }

    componentDidUpdate(prevProps, prevState) {
        if (prevProps.data.length !== this.props.data.length) {
            let featureSource = this.state.clusterSource.getSource();
            featureSource.clear();
            featureSource.addFeatures(this.getFeatures());
        }
    }

    getFeatures() {
        let features = [];
        // let data = [{"id":1,"x":-483760,"y":7480740},{"id":2,"x":-483760,"y":7480840}]
        this.props.data.forEach(element => {
            let feature = new ol.Feature({
                geometry: new geom.Point([element.x, element.y]),
                attributes: { ...element }
            });
            feature.setStyle([
                new style.Style({
                    image: new style.Circle({
                        radius: this.state.circleRadius,
                        stroke: new style.Stroke({
                            color: this.state.circleBorderColor,
                            width: this.state.circleBorder
                        }),
                        fill: new style.Fill({
                            color: "#fff"
                        })
                    })
                }),
                new style.Style({
                    rotateWithView: true,
                    textAlign: "center",
                    text: new style.Text({
                        text: "?"
                    })
                })
            ]);
            features.push(feature);
        });

        return features;
    }

    getClusterStyle(cluster) {
        let clusterSize = cluster.get("features").length;

        if (clusterSize > 1) {
            return new style.Style({
                image: new style.Circle({
                    radius: this.state.circleRadius,
                    stroke: new style.Stroke({
                        color: this.state.circleBorderColor,
                        width: this.state.circleBorder
                    }),
                    fill: new style.Fill({
                        color: "#ff9900"
                    })
                }),
                text: new style.Text({
                    text: clusterSize.toString(),
                    fill: new style.Fill({
                        color: this.state.circleBorderColor
                    })
                })
            });
        } else {
            return cluster.get("features")[0].getStyle();
        }
    }

    handleMapClick(event) {
        this.state.map.forEachFeatureAtPixel(event.pixel, (cluster, layer) => {
            let markers = cluster.get("features");

            if (markers.length == 1) {
                setTimeout(() => {
                    console.log(markers[0].getProperties().attributes));
                }, 300);
            } else {
                var extentObj = extent.createEmpty();
                markers.forEach(marker => {
                    extent.extend(extentObj, marker.getGeometry().getExtent());
                });
                this.state.map.getView().fit(extentObj, this.state.map.getSize());
                this.state.map.getView().setZoom(this.state.map.getView().getZoom() - 1);
            }
        });
    }

    render() {
        return <div ref="mapContainer" style={{ height: "100%" }} />;
    }
}

export default MapWrapper;

预期的结果是通过单击其显示的样式来找到该特征。

【问题讨论】:

    标签: reactjs openlayers-5


    【解决方案1】:

    我不知道您是否解决了您的问题,但我遇到了同样的问题,并且某些事件使您的地图倾斜,因此您需要更新尺寸。我用过这个功能

    function updateSize() {
       map.updateSize();
       map.renderSync();
    }
    

    对我来说,我只是在 pointerMove 函数和打印函数中调用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-28
      • 1970-01-01
      相关资源
      最近更新 更多