Reputation: 11
I am trying to draw a Rectangle and increase it size that it stays rectified. The corner of the rectangle can be selected and moved. The two adjacent corner are automatically moved that the polygon/rectangle is still rectified. After the rectangle is modified it is correctly drawn, but none of the adjacent corner are selectable anymore. If the mouse is place where the old position of the corners were, the corner can be selected and moved
I am working with the modify Interaction and it looks like if am changing the geometry of the feature, the Interaction does not recognice it. I am not sure how I can update the feature for the Interaction.
My starting point was this stackoverflow code here: OpenLayers - lock rotation of box or rectangle geometry while modifying.
Here is my “playground” code for my Reactcomponent. I added all code, because I am not sure, if am doing something wrong during the initialziaton of the map:
import React, { useEffect, useState } from 'react';
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import LayerVector from 'ol/layer/Vector';
import Collection from 'ol/Collection';
import SourceVector from 'ol/source/Vector';
import OSM from 'ol/source/OSM'
import { fromLonLat} from 'ol/proj'
//Fancy CSS
import 'ol/ol.css';
//Draw Box https://openlayers.org/en/latest/examples/draw-shapes.html?q=poly
import Draw, { createBox } from 'ol/interaction/Draw';
import { Modify } from 'ol/interaction'
import { never } from 'ol/events/condition';
function Map() {
const mapsize = {
height: '10%vp',
width: '100%',
};
var old_coords;
useEffect(() => {
var collection = new Collection();
var source = new SourceVector({
feature: collection
// wrapX: false
});
//default OpenStreetMap layer
var raster = new TileLayer({ source: new OSM() });
//drawing Rectangle
var draw = new Draw({
source: source,
type: 'Circle',
geometryFunction: createBox()
});
draw.on("drawend", function (e) {
draw.setActive(false);
old_coords = e.feature.getGeometry().getCoordinates()[0];
});
// create feature layer and vector source
var layerVector = new LayerVector({
source: source,
});
// create map object with feature layer
var map = new Map({
target: 'map',
layers: [raster, layerVector],
view: new View({
center: fromLonLat([-0.164794921875, 51.481382896100996]),
zoom: 13,
})
});
// Only the corner can be modified
var modify = new Modify({
source: source,
insertVertexCondition: never,
});
modify.on('modifystart', function (event) {
var feature = event.features.getArray()[0];
feature.on("change", changeFeatureFunction);
});
modify.on('modifyend', function (event) {
old_coords = event.features.getArray()[0].getGeometry().getCoordinates()[0];
})
map.addInteraction(draw);
map.addInteraction(modify);
}, [])
function changeFeatureFunction(event) {
let feature = event.target;
let geometry = feature.getGeometry();
const coords = geometry.getCoordinates()[0];
// Removing change event temporarily to avoid infinite recursion
feature.un("change", changeFeatureFunction);
var new_coords = rectanglifyModifiedGeometry(coords);
feature.getGeometry().setCoordinates([[...new_coords]]);
feature.on("change", changeFeatureFunction);
}
function rectanglifyModifiedGeometry(coords) {
var new_coords = [...coords];
//Bottom Left
if (!SameCoordinate(coords[0], old_coords[0])) {
console.log("first Coordinates has been change");
new_coords[3][0] = new_coords[0][0]
new_coords[1][1] = new_coords[0][1]
}
//Bottom Right
else if (!SameCoordinate(coords[1], old_coords[1])) {
console.log("second Coordinates has been change");
new_coords[0][1] = new_coords[1][1]
new_coords[2][0] = new_coords[1][0]
}
//Top Right
else if (!SameCoordinate(coords[2], old_coords[2])) {
console.log("third Coordinates has been change");
new_coords[1][0] = new_coords[2][0]
new_coords[3][1] = new_coords[2][1]
}
//Top Left
else if (!SameCoordinate(coords[3], old_coords[3])) {
console.log("fourth Coordinates has been change");
new_coords[2][1] = new_coords[3][1]
new_coords[0][0] = new_coords[3][0]
}
old_coords = coords;
new_coords.length = 4;
return new_coords
}
function SameCoordinate(point1, point2) {
return (point1[0] === point2[0]) && (point1[1] === point2[1])
}
return (
<div id="dummycontainer" >
<div id="map" >
</div>
</div>
)
}
export default Map;
Upvotes: 1
Views: 1227
Reputation: 17962
Your new coordinates are invalid as the first and last should be the same to close the polygon, so a rectangle needs 5 pairs of coordinates.
replace
new_coords.length = 4;
with
new_coords[4][0] = new_coords[0][0]
new_coords[4][1] = new_coords[0][1]
A better way to avoid recursion is to use
feature.once("change", changeFeatureFunction);
Upvotes: 0