OpenLayers - lock rotation of box or rectangle geometry while modifying

有些话、适合烂在心里 提交于 2019-12-11 07:29:52

问题


Openlayers provides useful functions for drawing boxes and rectangles and also has ol.geom.Geometry.prototype.rotate(angle, anchor) for rotating a geometry around a certain anchor. Is it possible to lock the rotation of a box/rectangle while modifying it?

Using the OpenLayers example located here to draw a box with a certain rotation to illustrate the point:

I would like the box/rectangle to maintain its rotation while still being able to drag the sides longer and shorter. Is there a simple way to achieve this?


回答1:


Answering with the solution I came up with.

First of all, add the feature(s) to a ModifyInteraction so you are able to modify by dragging the corners of the feature.

this.modifyInteraction = new Modify({
    deleteCondition: eventsCondition.never,
    features: this.drawInteraction.features,
    insertVertexCondition: eventsCondition.never,
});
    this.map.addInteraction(this.modifyInteraction);

Also, add event handlers upon the events "modifystart" and "modifyend".

this.modifyInteraction.on("modifystart", this.modifyStartFunction);
this.modifyInteraction.on("modifyend", this.modifyEndFunction);

The functions for "modifystart" and "modifyend" look like this.

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

The changeFeatureFunction is below. This function is called for every single change which is done to the geometry as long as the user is still modifying/dragging one of the corners. Inside this function, I made another function to adjust the modified rectangle into a rectangle again. This "Rectanglify"-function moves the corners which are adjacent to the corner which was just moved by the user.

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

Without going into too much detail, the rectanglify-function needs to

  1. find rotation of geometry in radians
  2. inversely rotate with radians * -1 (e.g. geometry.rotate(radians * (-1), anchor) )
  3. update neighboring corners of the dragged corner (easier to do when we have a rectangle which is parallel to the x and y axes)
  4. rotate back with the rotation we found in 1

--

In order to get the rotation of the rectangle, we can do this:

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


来源:https://stackoverflow.com/questions/47391000/openlayers-lock-rotation-of-box-or-rectangle-geometry-while-modifying

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!