Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

173
Views
Example of limiting a vertex from being dragged outside a polygon in OpenLayers6

I have the following situation:

The base polygon is where I defined that all other polygons should be drawn.

When using the draw interaction, setting the condition option is enought to limit where the point is placed on the map (in my case, the base polygon).

The problem is when I'm modifying them. I can drag a vertex outside the base polygon and I want to disable that behaviour but I can't find any solution to that.

If I use the same condition option from the draw interaction on the modify interaction, it disables the dragging only after the vertex was placed.

So my problem comes down to disabling drag outside a specified polygon for any polygon inside it.

Edit 1: In the end I've ended up with this:

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

Haven't found a good solution of working with TS but for the moment seems ok.

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

There is no condition which applies while dragging. You could style your feature with a constrained geometry, and set that geometry at the end of the modify.

<!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>

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!