Openlayers предоставляет полезные функции для рисования блоков и прямоугольников, а также имеет ol.geom.Geometry.prototype.rotate (angle, anchor) для вращения геометрии вокруг определенного якоря. Можно ли заблокировать вращение блока / прямоугольника при его изменении?

Используя пример OpenLayers, расположенный здесь, чтобы нарисовать прямоугольник с определенным поворотом чтобы проиллюстрировать суть дела:

Modifying a rotated box/rectangle polygon

Я хотел бы, чтобы прямоугольник / прямоугольник сохранял свое вращение, но при этом мог перетаскивать стороны длиннее и короче. Есть ли простой способ добиться этого?

2
Anders Gjerde 20 Ноя 2017 в 14:29

1 ответ

Лучший ответ

Отвечая на решение, которое я придумал.

Прежде всего, добавьте функцию (и) в 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 находится ниже. Эта функция вызывается для каждого отдельного изменения геометрии, пока пользователь все еще изменяет / перетаскивает один из углов. Внутри этой функции я сделал другую функцию, чтобы снова преобразовать измененный прямоугольник в прямоугольник. Эта функция «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. найти вращение геометрии в радианах
  2. обратный поворот на радианы * -1 (например, geometry.rotate (радианы * (-1), привязка))
  3. обновить соседние углы перетаскиваемого угла (проще сделать, когда у нас есть прямоугольник, параллельный осям x и y)
  4. повернуть назад с вращением, которое мы нашли в 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);
}
1
Anders Gjerde 5 Апр 2019 в 12:26