snap to vertices or edges
This commit is contained in:
@@ -3098,7 +3098,9 @@ olx.interaction.SelectOptions.prototype.wrapX;
|
||||
* @typedef {{
|
||||
* features: (ol.Collection.<ol.Feature>|undefined),
|
||||
* pixelTolerance: (number|undefined),
|
||||
* source: (ol.source.Vector|undefined)
|
||||
* source: (ol.source.Vector|undefined),
|
||||
* edge: (boolean|undefined),
|
||||
* vertex: (boolean|undefined)
|
||||
* }}
|
||||
* @api
|
||||
*/
|
||||
@@ -3112,6 +3114,21 @@ olx.interaction.SnapOptions;
|
||||
*/
|
||||
olx.interaction.SnapOptions.prototype.features;
|
||||
|
||||
/**
|
||||
* Snap to edges. Default is `true`.
|
||||
* @type {boolean|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.interaction.SnapOptions.prototype.edge;
|
||||
|
||||
|
||||
/**
|
||||
* Snap to vertices. Default is `true`.
|
||||
* @type {boolean|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.interaction.SnapOptions.prototype.vertex;
|
||||
|
||||
|
||||
/**
|
||||
* Pixel tolerance for considering the pointer close enough to a segment or
|
||||
|
||||
@@ -61,6 +61,18 @@ ol.interaction.Snap = function(opt_options) {
|
||||
*/
|
||||
this.source_ = options.source ? options.source : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.vertex_ = options.vertex !== undefined ? options.vertex : true;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.edge_ = options.edge !== undefined ? options.edge : true;
|
||||
|
||||
/**
|
||||
* @type {ol.Collection.<ol.Feature>}
|
||||
* @private
|
||||
@@ -374,30 +386,50 @@ ol.interaction.Snap.prototype.snapTo = function(pixel, pixelCoordinate, map) {
|
||||
var snapped = false;
|
||||
var vertex = null;
|
||||
var vertexPixel = null;
|
||||
var dist, pixel1, pixel2, squaredDist1, squaredDist2;
|
||||
if (segments.length > 0) {
|
||||
this.pixelCoordinate_ = pixelCoordinate;
|
||||
segments.sort(this.sortByDistance_);
|
||||
var closestSegment = segments[0].segment;
|
||||
if (this.vertex_ && !this.edge_) {
|
||||
pixel1 = map.getPixelFromCoordinate(closestSegment[0]);
|
||||
pixel2 = map.getPixelFromCoordinate(closestSegment[1]);
|
||||
squaredDist1 = ol.coordinate.squaredDistance(pixel, pixel1);
|
||||
squaredDist2 = ol.coordinate.squaredDistance(pixel, pixel2);
|
||||
dist = Math.sqrt(Math.min(squaredDist1, squaredDist2));
|
||||
snappedToVertex = dist <= this.pixelTolerance_;
|
||||
if (snappedToVertex) {
|
||||
snapped = true;
|
||||
vertex = squaredDist1 > squaredDist2 ?
|
||||
closestSegment[1] : closestSegment[0];
|
||||
vertexPixel = map.getPixelFromCoordinate(vertex);
|
||||
}
|
||||
} else if (this.edge_) {
|
||||
vertex = (ol.coordinate.closestOnSegment(pixelCoordinate,
|
||||
closestSegment));
|
||||
vertexPixel = map.getPixelFromCoordinate(vertex);
|
||||
if (Math.sqrt(ol.coordinate.squaredDistance(pixel, vertexPixel)) <=
|
||||
this.pixelTolerance_) {
|
||||
snapped = true;
|
||||
var pixel1 = map.getPixelFromCoordinate(closestSegment[0]);
|
||||
var pixel2 = map.getPixelFromCoordinate(closestSegment[1]);
|
||||
var squaredDist1 = ol.coordinate.squaredDistance(vertexPixel, pixel1);
|
||||
var squaredDist2 = ol.coordinate.squaredDistance(vertexPixel, pixel2);
|
||||
var dist = Math.sqrt(Math.min(squaredDist1, squaredDist2));
|
||||
if (this.vertex_) {
|
||||
pixel1 = map.getPixelFromCoordinate(closestSegment[0]);
|
||||
pixel2 = map.getPixelFromCoordinate(closestSegment[1]);
|
||||
squaredDist1 = ol.coordinate.squaredDistance(vertexPixel, pixel1);
|
||||
squaredDist2 = ol.coordinate.squaredDistance(vertexPixel, pixel2);
|
||||
dist = Math.sqrt(Math.min(squaredDist1, squaredDist2));
|
||||
snappedToVertex = dist <= this.pixelTolerance_;
|
||||
if (snappedToVertex) {
|
||||
vertex = squaredDist1 > squaredDist2 ?
|
||||
closestSegment[1] : closestSegment[0];
|
||||
vertexPixel = map.getPixelFromCoordinate(vertex);
|
||||
vertexPixel = [Math.round(vertexPixel[0]), Math.round(vertexPixel[1])];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (snapped) {
|
||||
vertexPixel = [Math.round(vertexPixel[0]), Math.round(vertexPixel[1])];
|
||||
}
|
||||
}
|
||||
return /** @type {ol.interaction.Snap.ResultType} */ ({
|
||||
snapped: snapped,
|
||||
vertex: vertex,
|
||||
|
||||
@@ -64,6 +64,42 @@ describe('ol.interaction.Snap', function() {
|
||||
expect(event.coordinate).to.eql([0, 0]);
|
||||
});
|
||||
|
||||
it('snaps to edges only', function() {
|
||||
var point = new ol.Feature(new ol.geom.LineString([[-10, 0], [10, 0]]));
|
||||
var snapInteraction = new ol.interaction.Snap({
|
||||
features: new ol.Collection([point]),
|
||||
pixelTolerance: 5,
|
||||
vertex: false
|
||||
});
|
||||
snapInteraction.setMap(map);
|
||||
|
||||
var event = {
|
||||
pixel: [7 + width / 2, height / 2 - 4],
|
||||
coordinate: [7, 4],
|
||||
map: map
|
||||
};
|
||||
ol.interaction.Snap.handleEvent_.call(snapInteraction, event);
|
||||
expect(event.coordinate).to.eql([7, 0]);
|
||||
});
|
||||
|
||||
it('snaps to vertices only', function() {
|
||||
var point = new ol.Feature(new ol.geom.LineString([[-10, 0], [10, 0]]));
|
||||
var snapInteraction = new ol.interaction.Snap({
|
||||
features: new ol.Collection([point]),
|
||||
pixelTolerance: 5,
|
||||
edge: false
|
||||
});
|
||||
snapInteraction.setMap(map);
|
||||
|
||||
var event = {
|
||||
pixel: [7 + width / 2, height / 2 - 4],
|
||||
coordinate: [7, 4],
|
||||
map: map
|
||||
};
|
||||
ol.interaction.Snap.handleEvent_.call(snapInteraction, event);
|
||||
expect(event.coordinate).to.eql([10, 0]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -73,4 +109,5 @@ goog.require('ol.Feature');
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.interaction.Snap');
|
||||
|
||||
Reference in New Issue
Block a user