OpenLayers - 在修改时锁定框或矩形几何体的旋转
OpenLayers - lock rotation of box or rectangle geometry while modifying
Openlayers 提供了绘制方框和矩形的有用函数,还有 ol.geom.Geometry.prototype.rotate(angle, anchor) 用于围绕特定锚点旋转几何体。 box/rectangle修改的时候可以锁定旋转吗?
用位于here的OpenLayers例子画一个有一定旋转度的方框来说明:
我希望 box/rectangle 保持其旋转,同时仍然能够将边拖得更长或更短。有没有简单的方法可以做到这一点?
回答我想出的解决方案。
首先,将特征添加到 ModifyInteraction,这样您就可以通过拖动特征的角来进行修改。
this.modifyInteraction = new Modify({
deleteCondition: eventsCondition.never,
features: this.drawInteraction.features,
insertVertexCondition: eventsCondition.never,
});
this.map.addInteraction(this.modifyInteraction);
此外,在事件 "modifystart" 和 "modifyend" 上添加事件处理程序。
this.modifyInteraction.on("modifystart", this.modifyStartFunction);
this.modifyInteraction.on("modifyend", this.modifyEndFunction);
"modifystart" 和 "modifyend" 的函数如下所示。
private modifyStartFunction(event) {
const features = event.features;
const feature = features.getArray()[0];
this.featureAtModifyStart = feature.clone();
this.draggedCornerAtModifyStart = "";
feature.on("change", this.changeFeatureFunction);
}
private modifyEndFunction(event) {
const features = event.features;
const feature = features.getArray()[0];
feature.un("change", this.changeFeatureFunction);
// removing and adding feature to force reindexing
// of feature's snappable edges in OpenLayers
this.drawInteraction.features.clear();
this.drawInteraction.features.push(feature);
this.dispatchRettighetModifyEvent(feature);
}
changeFeatureFunction 如下。只要用户仍然是 modifying/dragging 个角落之一,对几何体所做的每一次更改都会调用此函数。在这个函数里面,我又做了一个函数,将修改后的矩形再次调整为矩形。此 "Rectanglify" 函数移动与用户刚刚移动的角相邻的角。
private changeFeatureFunction(event) {
let feature = event.target;
let geometry = feature.getGeometry();
// Removing change event temporarily to avoid infinite recursion
feature.un("change", this.changeFeatureFunction);
this.rectanglifyModifiedGeometry(geometry);
// Reenabling change event
feature.on("change", this.changeFeatureFunction);
}
无需过多赘述,rectanglify 函数需要
- 找到以弧度为单位的几何旋转
- 以弧度 * -1 反向旋转(例如 geometry.rotate(radians * (-1), anchor) )
- 更新拖动角的相邻角(当我们有一个平行于 x 轴和 y 轴的矩形时更容易做到)
- 以我们在 1
中找到的旋转向后旋转
--
为了得到矩形的旋转,我们可以这样做:
export function getRadiansFromRectangle(feature: Feature): number {
const coords = getCoordinates(feature);
const point1 = coords[0];
const point2 = coords[1];
const deltaY = (point2[1] as number) - (point1[1] as number);
const deltaX = (point2[0] as number) - (point1[0] as number);
return Math.atan2(deltaY, deltaX);
}
Openlayers 提供了绘制方框和矩形的有用函数,还有 ol.geom.Geometry.prototype.rotate(angle, anchor) 用于围绕特定锚点旋转几何体。 box/rectangle修改的时候可以锁定旋转吗?
用位于here的OpenLayers例子画一个有一定旋转度的方框来说明:
我希望 box/rectangle 保持其旋转,同时仍然能够将边拖得更长或更短。有没有简单的方法可以做到这一点?
回答我想出的解决方案。
首先,将特征添加到 ModifyInteraction,这样您就可以通过拖动特征的角来进行修改。
this.modifyInteraction = new Modify({
deleteCondition: eventsCondition.never,
features: this.drawInteraction.features,
insertVertexCondition: eventsCondition.never,
});
this.map.addInteraction(this.modifyInteraction);
此外,在事件 "modifystart" 和 "modifyend" 上添加事件处理程序。
this.modifyInteraction.on("modifystart", this.modifyStartFunction);
this.modifyInteraction.on("modifyend", this.modifyEndFunction);
"modifystart" 和 "modifyend" 的函数如下所示。
private modifyStartFunction(event) {
const features = event.features;
const feature = features.getArray()[0];
this.featureAtModifyStart = feature.clone();
this.draggedCornerAtModifyStart = "";
feature.on("change", this.changeFeatureFunction);
}
private modifyEndFunction(event) {
const features = event.features;
const feature = features.getArray()[0];
feature.un("change", this.changeFeatureFunction);
// removing and adding feature to force reindexing
// of feature's snappable edges in OpenLayers
this.drawInteraction.features.clear();
this.drawInteraction.features.push(feature);
this.dispatchRettighetModifyEvent(feature);
}
changeFeatureFunction 如下。只要用户仍然是 modifying/dragging 个角落之一,对几何体所做的每一次更改都会调用此函数。在这个函数里面,我又做了一个函数,将修改后的矩形再次调整为矩形。此 "Rectanglify" 函数移动与用户刚刚移动的角相邻的角。
private changeFeatureFunction(event) {
let feature = event.target;
let geometry = feature.getGeometry();
// Removing change event temporarily to avoid infinite recursion
feature.un("change", this.changeFeatureFunction);
this.rectanglifyModifiedGeometry(geometry);
// Reenabling change event
feature.on("change", this.changeFeatureFunction);
}
无需过多赘述,rectanglify 函数需要
- 找到以弧度为单位的几何旋转
- 以弧度 * -1 反向旋转(例如 geometry.rotate(radians * (-1), anchor) )
- 更新拖动角的相邻角(当我们有一个平行于 x 轴和 y 轴的矩形时更容易做到)
- 以我们在 1 中找到的旋转向后旋转
--
为了得到矩形的旋转,我们可以这样做:
export function getRadiansFromRectangle(feature: Feature): number {
const coords = getCoordinates(feature);
const point1 = coords[0];
const point2 = coords[1];
const deltaY = (point2[1] as number) - (point1[1] as number);
const deltaX = (point2[0] as number) - (point1[0] as number);
return Math.atan2(deltaY, deltaX);
}