[OpenLayers-Commits] r4179 - in sandbox/camptocamp/feature: examples lib/OpenLayers/Handler
commits at openlayers.org
commits at openlayers.org
Mon Sep 3 08:54:20 EDT 2007
Author: fredj
Date: 2007-09-03 08:54:19 -0400 (Mon, 03 Sep 2007)
New Revision: 4179
Modified:
sandbox/camptocamp/feature/examples/modify-feature.html
sandbox/camptocamp/feature/lib/OpenLayers/Handler/Path.js
sandbox/camptocamp/feature/lib/OpenLayers/Handler/Snapping.js
Log:
snap to edges
Modified: sandbox/camptocamp/feature/examples/modify-feature.html
===================================================================
--- sandbox/camptocamp/feature/examples/modify-feature.html 2007-09-03 09:54:37 UTC (rev 4178)
+++ sandbox/camptocamp/feature/examples/modify-feature.html 2007-09-03 12:54:19 UTC (rev 4179)
@@ -42,7 +42,7 @@
panel = new OpenLayers.Control.Panel({'displayClass': 'olControlEditingToolbar'});
- var snapVertex = {method: 'vertex', layers: [vectors]};
+ var snapVertex = {methods: ['vertex', 'edge'], layers: [vectors]};
controls = {
point: new OpenLayers.Control.DrawFeature(vectors,
Modified: sandbox/camptocamp/feature/lib/OpenLayers/Handler/Path.js
===================================================================
--- sandbox/camptocamp/feature/lib/OpenLayers/Handler/Path.js 2007-09-03 09:54:37 UTC (rev 4178)
+++ sandbox/camptocamp/feature/lib/OpenLayers/Handler/Path.js 2007-09-03 12:54:19 UTC (rev 4179)
@@ -170,7 +170,6 @@
this.lastDown = evt.xy;
var snapped = this.snappingHandler.getPoint(this.map.getLonLatFromPixel(evt.xy));
-
this.point.geometry.x = snapped.lon;
this.point.geometry.y = snapped.lat;
@@ -200,7 +199,10 @@
var snapped = this.snappingHandler.getPoint(cursor);
if (!cursor.equals(snapped)) {
- this.pointStyle = OpenLayers.Handler.Snapping.style.vertex;
+ var style = this.snappingHandler.getPointStyle();
+ if (style) {
+ this.pointStyle = style;
+ }
} else {
this.pointStyle = OpenLayers.Feature.Vector.style['default'];
}
Modified: sandbox/camptocamp/feature/lib/OpenLayers/Handler/Snapping.js
===================================================================
--- sandbox/camptocamp/feature/lib/OpenLayers/Handler/Snapping.js 2007-09-03 09:54:37 UTC (rev 4178)
+++ sandbox/camptocamp/feature/lib/OpenLayers/Handler/Snapping.js 2007-09-03 12:54:19 UTC (rev 4179)
@@ -8,7 +8,6 @@
* - snap to fixed grid with pixel or geographic size
*/
-
/**
* @requires OpenLayers/Handler.js
*
@@ -18,29 +17,28 @@
/**
* Property: method
- * {String} the snapping method
+ * {Array(String)} the snapping method
*/
- method: '',
+ methods: ['vertex', 'edge'],
/**
* Property: layers
* {Array(<OpenLayers.Layer.Vector>} the layers where are the features to snap to
- * Only applicable if this.method is 'vertex' or 'edge'
*/
layers: [],
/**
* Property: tolerance en pixel unit
- * {<OpenLayers.Size>}
+ * {Integer}
*/
- tolerancePix: new OpenLayers.Size(10, 10),
+ tolerancePix: 10,
/**
- * Property: tolerance en geographic unit
- * {<OpenLayers.Size>}
+ * Property: snapToSelf
+ * {Boolean}
*/
- toleranceGeo: null,
+ snapToSelf: true,
initialize: function(control, callbacks, options) {
OpenLayers.Handler.prototype.initialize.apply(this, arguments);
@@ -54,18 +52,31 @@
* {<OpenLayers.LonLat>}
*/
getPoint: function(lonlat) {
+ var result = null;
- switch(this.method) {
+ for (var i = 0; i < this.methods.length; i++) {
+ switch (this.methods[i]) {
case 'vertex':
- return this.snapToVertex(lonlat);
- break;
-
- default:
- return this.noSnapping(lonlat);
- break;
+ result = this.snapToVertex(lonlat);
+ break;
+ case 'edge':
+ result = this.snapToEdges(lonlat);
+ break;
+ }
+ if (result) {
+ this.method = this.methods[i];
+ break;
+ } else {
+ this.method = '';
+ }
}
+ return result ? result : this.noSnapping(lonlat);
},
+ getPointStyle: function() {
+ return OpenLayers.Handler.Snapping.style[this.method];
+ },
+
/*
* Parameters:
* lonlat - {<OpenLayers.LonLat>}
@@ -90,23 +101,79 @@
var vertices = [];
for (var i = 0; i < this.layers.length; i++) {
for (var j = 0; j < this.layers[i].features.length; j++) {
- if (this.layers[i].features[j].atPoint(lonlat,
- this.toleranceGeo.w,
- this.toleranceGeo.h)) {
+ if (this.layers[i].features[j].atPoint(lonlat, this.toleranceGeo, this.toleranceGeo)) {
vertices = vertices.concat(this.layers[i].features[j].getVertices());
}
}
}
-
for (var i = 0; i < vertices.length; i++) {
- if (vertices[i].atPoint(lonlat, this.toleranceGeo.h, this.toleranceGeo.h)) {
+ if (vertices[i].atPoint(lonlat, this.toleranceGeo, this.toleranceGeo)) {
return new OpenLayers.LonLat(vertices[i].x, vertices[i].y);
}
}
// no snapping point found
- return this.noSnapping(lonlat);
+ return null;
},
+ snapToEdges: function(lonlat) {
+ this.getToleranceGeo();
+
+ var edges = [];
+ for (var i = 0; i < this.layers.length; i++) {
+ for (var j = 0; j < this.layers[i].features.length; j++) {
+ if (this.layers[i].features[j].atPoint(lonlat, this.toleranceGeo, this.toleranceGeo)) {
+ edges = edges.concat(this.layers[i].features[j].getEdges());
+ }
+ }
+ }
+
+ var minimum = null;
+ for (var i = 0; i < edges.length; i++) {
+ var point = new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat);
+ var result = this.distanceToLine(point, edges[i]);
+
+ if (result) {
+ if (result.distance < this.toleranceGeo) {
+ if (!minimum) {
+ minimum = result;
+ }
+ if (result.distance < minimum.distance) {
+ minimum = result;
+ }
+ }
+ }
+ }
+ if (minimum) {
+
+ return new OpenLayers.LonLat(minimum.cross.x, minimum.cross.y);
+ } else {
+ return null;
+ }
+ },
+
+
+ // see: http://local.wasp.uwa.edu.au/~pbourke/geometry/pointline/source.c
+ distanceToLine: function(point, line) {
+ var start = line.components[0];
+ var stop = line.components[1];
+
+ var lineSize = start.distanceTo(stop);
+
+ var U = (((point.x - start.x) * (stop.x - start.x)) +
+ ((point.y - start.y) * (stop.y - start.y))) / (lineSize * lineSize);
+ if (U < 0.0 || U > 1.0) {
+ // closest point does not fall within the line segment
+ return null;
+ } else {
+ var x = start.x + U * (stop.x - start.x);
+ var y = start.y + U * (stop.y - start.y);
+ var cross = new OpenLayers.Geometry.Point(x, y);
+
+ return {distance: point.distanceTo(cross),
+ cross: cross}
+ }
+ },
+
/*
* Return:
* {<OpenLayers.LonLat>}
@@ -114,10 +181,9 @@
getToleranceGeo: function() {
var resolution = this.map.getResolution();
if (!this.toleranceGeo || resolution != this.resolution) {
-
+
this.resolution = resolution;
- this.toleranceGeo = new OpenLayers.Size(this.tolerancePix.w * this.resolution,
- this.tolerancePix.h * this.resolution);
+ this.toleranceGeo = this.tolerancePix * this.resolution;
}
return this.toleranceGeo;
}
@@ -126,7 +192,7 @@
OpenLayers.Handler.Snapping.style = {
'vertex' : {
fillColor: "#0000ff",
- fillOpacity: 0.4,
+ fillOpacity: 0.4,
hoverFillColor: "white",
hoverFillOpacity: 0.8,
strokeColor: "#0000ff",
@@ -140,5 +206,23 @@
hoverPointRadius: 1,
hoverPointUnit: "%",
pointerEvents: "visiblePainted"
+ },
+ 'edge' : {
+ fillColor: "#ff0000",
+ fillOpacity: 0.4,
+ hoverFillColor: "white",
+ hoverFillOpacity: 0.8,
+ strokeColor: "#ff0000",
+ strokeOpacity: 1,
+ strokeWidth: 1,
+ strokeLinecap: "round",
+ hoverStrokeColor: "red",
+ hoverStrokeOpacity: 1,
+ hoverStrokeWidth: 0.2,
+ pointRadius: 6,
+ hoverPointRadius: 1,
+ hoverPointUnit: "%",
+ pointerEvents: "visiblePainted"
}
-}
\ No newline at end of file
+
+}
More information about the Commits
mailing list