【发布时间】: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