tengo la siguiente situacion:
El polígono base es donde definí que se deben dibujar todos los demás polígonos.
Cuando se usa la interacción de dibujo, establecer la opción de condición es suficiente para limitar dónde se coloca el punto en el mapa (en mi caso, el polígono base).
El problema es cuando los estoy modificando. Puedo arrastrar un vértice fuera del polígono base y quiero deshabilitar ese comportamiento, pero no puedo encontrar ninguna solución para eso.
Si uso la misma opción de condición de la interacción dibujar en la interacción modificar, deshabilita el arrastre solo después de colocar el vértice.
Entonces, mi problema se reduce a deshabilitar el arrastre fuera de un polígono específico para cualquier polígono dentro de él.
Edición 1: al final terminé con esto:
const constrainGeometry = (feature: RenderFeature | Feature<Geometry>) => { const geometry = feature.getGeometry() as Polygon | undefined; if (feature instanceof RenderFeature || geometry === undefined) { return geometry; } const coordinates = geometry.getCoordinates()[0].map((coordinate) => { const boundingGeometry = props.boundingFeature.getGeometry(); if (boundingGeometry) { if (boundingGeometry.intersectsCoordinate(coordinate)) { return coordinate; } else { return boundingGeometry.getClosestPoint(coordinate); } } else { return coordinate; } }); return new Polygon([coordinates]); };No he encontrado una buena solución para trabajar con TS, pero por el momento parece estar bien.
No hay ninguna condición que se aplique al arrastrar. Puede diseñar su característica con una geometría restringida y establecer esa geometría al final de la modificación.
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.8.1/css/ol.css" type="text/css"> <style> html, body, .map { margin: 0; padding: 0; width: 100%; height: 100%; } </style> <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.8.1/build/ol.js"></script> </head> <body> <div id="map" class="map"></div> <script type="text/javascript"> const boundingPolygon = ol.geom.Polygon.fromCircle( new ol.geom.Circle([0, 0], 1e6), 5 ); const constrainGeometry = function(feature) { const geometry = feature.getGeometry(); if (geometry.getType() === 'Polygon') { coordinates = geometry.getCoordinates()[0].map(function(coordinate) { if (boundingPolygon.intersectsCoordinate(coordinate)) { return coordinate; } else { return boundingPolygon.getClosestPoint(coordinate); } }); return new ol.geom.Polygon([coordinates]); } else { return geometry; } } const style = new ol.style.Style({ geometry: constrainGeometry, fill: new ol.style.Fill({ color: 'rgba(255, 255, 255, 0.2)', }), stroke: new ol.style.Stroke({ color: '#ffcc33', width: 2, }), image: new ol.style.Circle({ radius: 7, fill: new ol.style.Fill({ color: '#ffcc33', }), }), }); const vector1 = new ol.layer.Vector({ source: new ol.source.Vector({ features: [ new ol.Feature(boundingPolygon) ] }) }); const vector2 = new ol.layer.Vector({ source: new ol.source.Vector({ features: [ new ol.Feature(ol.geom.Polygon.fromExtent([-5e5, -5e5, 5e5, 5e5])) ] }), style: style }); const map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }), vector1, vector2 ], view: new ol.View({ center: [0, 0], zoom: 4 }) }); const modify = new ol.interaction.Modify({ source: vector2.getSource() }); modify.on('modifyend', function (event) { event.features.forEach(function (feature) { feature.setGeometry(constrainGeometry(feature)); }); }); map.addInteraction(modify); </script> </body> </html>