我已经使用 Select 交互和 Draw 交互实现了 OpenLayers 6,我在它们之间切换。
我们可以假设用户只绘制多边形(三点或更多的几何图形)。
我希望绘制的多边形在完成后被选中。
因此,我在 Draw 交互上监听“drawend”,将绘制交互设置为非活动,将选择交互设置为活动,但是我需要将选定的特征设置为仅绘制的特征。
到目前为止,我所拥有的只是我想出的这个笨重的 hack:
// Find the center point of the drawn feature (EPSG:3857)
const featureCenter: [number, number] = this._getCenterOfExtent(geometry.getExtent());
// Get the local pixel coordinate for the feature's center
const pixel: Pixel = this._map.getPixelFromCoordinate(featureCenter);
// Create a new MapBrowserEvent registering a 'click' on this local pixel coordinate
const mbEvent: MapBrowserEvent = new MapBrowserEvent('click', this._map, new MouseEvent('click', {
bubbles: true,
cancelable: true,
clientX: pixel[0],
clientY: pixel[1]
}));
// Turn off multi-polygon selection on our Select Interaction. We only want the top polygon at this spot.
this._registeredSelector.setProperties({
multi: false
});
// Trigger the 'click' event on the map
this._map.dispatchEvent(mbEvent);
不幸的是,这并不总是有效。我在我的 Select 交互中监听“点击”,它在强行触发点击后触发。但是,有时,该事件具有 Point、LineString 和 Polygon 的多个几何形状。很多时候,它甚至在selected
数组中都没有 Polygon 几何图形。其他时候,它在数组中有一个附近的 Polygon 几何体selected
,而不是我们上次绘制的那个。
是否有强制触发选择特定特征的 OpenLayers 原生方法?
另外,这是我的_getCenterOfExtent
方法:
/* EXPECTS EPSG:3857 */
private _getCenterOfExtent(extent: Extent):[number, number] {
return [
extent[0] + (extent[2]-extent[0])/2,
extent[1] + (extent[3]-extent[1])/2
];
}
更新
对窗口对象使用我的点击事件的屏幕坐标似乎比在地图上尝试客户端坐标更准确。此外,我发现以编程方式切换multi
Select Interaction 并没有实际工作,至少不是我尝试的方式。我切换到始终使用单选,这应该可以满足我们的需求。
const bbox: ClientRect | DOMRect = this._map.getTargetElement().getBoundingClientRect();
let mbEvent: MapBrowserEvent | undefined;
if (bbox) {
pixel[0] += bbox.left;
pixel[1] += bbox.top;
mbEvent = new MapBrowserEvent('click', this._map, new MouseEvent('click', {
view: window,
bubbles: true,
cancelable: true,
screenX: pixel[0],
screenY: pixel[1]
}));
} else {
mbEvent = new MapBrowserEvent('click', this._map, new MouseEvent('click', {
bubbles: true,
cancelable: true,
clientX: pixel[0],
clientY: pixel[1]
}));
}
this._map.dispatchEvent(mbEvent);