[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