@@ -26,6 +26,37 @@ ol.coordinate.add = function(coordinate, delta) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the point closest to the passed coordinate on the passed circle.
|
||||
*
|
||||
* @param {ol.Coordinate} coordinate The coordinate.
|
||||
* @param {ol.geom.Circle} circle The circle.
|
||||
* @return {ol.Coordinate} Closest point on the circumference
|
||||
*/
|
||||
ol.coordinate.closestOnCircle = function(coordinate, circle) {
|
||||
var r = circle.getRadius();
|
||||
var center = circle.getCenter();
|
||||
var x0 = center[0];
|
||||
var y0 = center[1];
|
||||
var x1 = coordinate[0];
|
||||
var y1 = coordinate[1];
|
||||
|
||||
var dx = x1 - x0;
|
||||
var dy = y1 - y0;
|
||||
if (dx === 0 && dy === 0) {
|
||||
dx = 1;
|
||||
}
|
||||
var d = Math.sqrt(dx * dx + dy * dy);
|
||||
|
||||
var x, y;
|
||||
|
||||
x = x0 + r * dx / d;
|
||||
y = y0 + r * dy / d;
|
||||
|
||||
return [x, y];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the point closest to the passed coordinate on the passed segment.
|
||||
* This is the foot of the perpendicular of the coordinate to the segment when
|
||||
|
||||
@@ -8,6 +8,8 @@ goog.require('ol.events');
|
||||
goog.require('ol.events.EventType');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.functions');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.geom.Polygon');
|
||||
goog.require('ol.interaction.Pointer');
|
||||
goog.require('ol.obj');
|
||||
goog.require('ol.source.Vector');
|
||||
@@ -142,7 +144,8 @@ ol.interaction.Snap = function(opt_options) {
|
||||
'MultiPoint': this.writeMultiPointGeometry_,
|
||||
'MultiLineString': this.writeMultiLineStringGeometry_,
|
||||
'MultiPolygon': this.writeMultiPolygonGeometry_,
|
||||
'GeometryCollection': this.writeGeometryCollectionGeometry_
|
||||
'GeometryCollection': this.writeGeometryCollectionGeometry_,
|
||||
'Circle': this.writeCircleGeometry_
|
||||
};
|
||||
};
|
||||
ol.inherits(ol.interaction.Snap, ol.interaction.Pointer);
|
||||
@@ -345,6 +348,15 @@ ol.interaction.Snap.prototype.snapTo = function(pixel, pixelCoordinate, map) {
|
||||
var box = ol.extent.boundingExtent([lowerLeft, upperRight]);
|
||||
|
||||
var segments = this.rBush_.getInExtent(box);
|
||||
|
||||
// If snapping on vertices only, don't consider circles
|
||||
if (this.vertex_ && !this.edge_) {
|
||||
segments = segments.filter(function(segment) {
|
||||
return segment.feature.getGeometry().getType() !==
|
||||
ol.geom.GeometryType.CIRCLE;
|
||||
});
|
||||
}
|
||||
|
||||
var snappedToVertex = false;
|
||||
var snapped = false;
|
||||
var vertex = null;
|
||||
@@ -354,6 +366,8 @@ ol.interaction.Snap.prototype.snapTo = function(pixel, pixelCoordinate, map) {
|
||||
this.pixelCoordinate_ = pixelCoordinate;
|
||||
segments.sort(this.sortByDistance_);
|
||||
var closestSegment = segments[0].segment;
|
||||
var isCircle = segments[0].feature.getGeometry().getType() ===
|
||||
ol.geom.GeometryType.CIRCLE;
|
||||
if (this.vertex_ && !this.edge_) {
|
||||
pixel1 = map.getPixelFromCoordinate(closestSegment[0]);
|
||||
pixel2 = map.getPixelFromCoordinate(closestSegment[1]);
|
||||
@@ -368,12 +382,17 @@ ol.interaction.Snap.prototype.snapTo = function(pixel, pixelCoordinate, map) {
|
||||
vertexPixel = map.getPixelFromCoordinate(vertex);
|
||||
}
|
||||
} else if (this.edge_) {
|
||||
vertex = (ol.coordinate.closestOnSegment(pixelCoordinate,
|
||||
closestSegment));
|
||||
if (isCircle) {
|
||||
vertex = ol.coordinate.closestOnCircle(pixelCoordinate,
|
||||
/** @type {ol.geom.Circle} */ (segments[0].feature.getGeometry()));
|
||||
} else {
|
||||
vertex = (ol.coordinate.closestOnSegment(pixelCoordinate,
|
||||
closestSegment));
|
||||
}
|
||||
vertexPixel = map.getPixelFromCoordinate(vertex);
|
||||
if (ol.coordinate.distance(pixel, vertexPixel) <= this.pixelTolerance_) {
|
||||
snapped = true;
|
||||
if (this.vertex_) {
|
||||
if (this.vertex_ && !isCircle) {
|
||||
pixel1 = map.getPixelFromCoordinate(closestSegment[0]);
|
||||
pixel2 = map.getPixelFromCoordinate(closestSegment[1]);
|
||||
squaredDist1 = ol.coordinate.squaredDistance(vertexPixel, pixel1);
|
||||
@@ -410,6 +429,26 @@ ol.interaction.Snap.prototype.updateFeature_ = function(feature) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Feature} feature Feature
|
||||
* @param {ol.geom.Circle} geometry Geometry.
|
||||
* @private
|
||||
*/
|
||||
ol.interaction.Snap.prototype.writeCircleGeometry_ = function(feature, geometry) {
|
||||
var polygon = ol.geom.Polygon.fromCircle(geometry);
|
||||
var coordinates = polygon.getCoordinates()[0];
|
||||
var i, ii, segment, segmentData;
|
||||
for (i = 0, ii = coordinates.length - 1; i < ii; ++i) {
|
||||
segment = coordinates.slice(i, i + 2);
|
||||
segmentData = /** @type {ol.SnapSegmentDataType} */ ({
|
||||
feature: feature,
|
||||
segment: segment
|
||||
});
|
||||
this.rBush_.insert(ol.extent.boundingExtent(segment), segmentData);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Feature} feature Feature
|
||||
* @param {ol.geom.GeometryCollection} geometry Geometry.
|
||||
|
||||
Reference in New Issue
Block a user