Richard Greenwood
Richard Greenwood

Reputation: 1004

how to detect when a vertex is added

I need to detect when a vertex has been added to a line as it is being drawn or edited. The way I'm doing it now works, but seems pretty clumsy so I'm wondering if I'm overlooking an "observable" event or if there is a more elegant way of catching new vertices.

What I'm doing now is adding my own property to the feature which keeps track of how many vertices there were and then checking it against the actual number of vertices on each 'change' event, basically:

draw.on('drawstart',
  function(evt) {
    var sketch = evt.feature;
    var sketchGeom = sketch.getGeometry();
    // the 'change' event will will fired by mouse move or mouse click
    sketchGeom.on('change', function(evt) {
      // check the actual number of verticies against
      // my 'nodeCount' to see if the 'change' event
      // has created a vertex
    });
    sketchGeom.set('nodeCount', 1);  // add my own property to track the number of verticies
  },
  this);

The other approach that I've seen is to watch for map clicks rather than watch for changes to the feature, but this doesn't fit into my flow as well as watching the 'change' event.

So is there a 'vertexAdded' event or something similar that I've overlooked?

EDIT: Based on Mike's suggestion I've modified my code somewhat below, it still feels kludgy. I'm adding my own 'nodeCount' property to the geometry which I increment on mouse-clicks. Then I can check my 'nodeCount' property against the geometry's actual length. If OL has added a vertex due to a mouse-move then the geometry's length will be greater than my count and I know I'm dealing with a mouse-move, otherwise they are equal and I know I'm dealing with a click.

var draw = new Draw({  // import Draw from 'ol/interaction/Draw.js';
  source: source,
  type: 'LineString',
  condition: function(evt) {
    var res = noModifierKeys(evt);  // import {noModifierKeys} from 'ol/events/condition.js';
    var features = draw.getOverlay().getSource().getFeatures();
    if (res && features.length) {
      let geom = features[0].getGeometry();
      geom.set('nodeCount', geom.getCoordinates().length); // add my own property
    }
    return res;
  }
});

draw.on('drawstart',
  function(evt) {
    var sketchGeom = evt.feature.getGeometry();
    // the 'change' event will be fired by mouse-move or mouse-click
    sketchGeom.on('change', function(evt) {
      let geom = evt.target;
      let verticesLength = geom.getCoordinates().length;
      let nodeCount = geom.get('nodeCount') // fetch my property

      if (verticesLength === nodeCount) { // a new vertex has been created by a mouse click
        // handle a mouse-click
      } else if (verticesLength > nodeCount) { // a new vertex has been created by mouse move (not by a click, which would have incremented nodeCount)
        // handle a mouse-move
      }
      // do things that are common to mouse-move and mouse-click
    });
  },
this);

Upvotes: 0

Views: 457

Answers (1)

Mike
Mike

Reputation: 17897

You could wrap the default condition function in your own function to catch any clicks which add vertices. In OL5 the sketch feature can be obtained via getOverlay()

  var draw = new ol.interaction.Draw({
    source: source,
    type: 'LineString',
    condition: function(evt) {
      var res = ol.events.condition.noModifierKeys(evt);
      var features = draw.getOverlay().getSource().getFeatures();
      if (res && features.length) {
        console.log(features[0].getGeometry().getCoordinates().length);
      }
      return res;
    }
  });

Upvotes: 1

Related Questions