OpenLayers OpenLayers

Ticket #954: Point.js-diff

File Point.js-diff, 7.3 kB (added by jachym, 1 year ago)

Snapping while digitization

Line 
1 --- Handler/Point.js    2007-09-03 08:03:57.174606707 +0200
2 +++ /home/jachym/public_html/openlayers/HSLayers/Point.js   2007-09-03 13:43:14.062679646 +0200
3 @@ -55,6 +55,12 @@
4      lastUp: null,
5  
6      /**
7 +     * Property: snapDist
8 +     * {Integer} Snapping distance in pixel. If <= 0, no snapping is done
9 +     */
10 +    snapDist: 0,
11 +
12 +    /**
13       * Constructor: OpenLayers.Handler.Point
14       * Create a new point handler.
15       *
16 @@ -75,6 +81,9 @@
17          this.style = OpenLayers.Util.extend(OpenLayers.Feature.Vector.style['default'], {});
18  
19          OpenLayers.Handler.prototype.initialize.apply(this, arguments);
20 +        if (this.snapDist) {
21 +            this.style.pointRadius = this.snapDist;
22 +        }
23      },
24      
25      /**
26 @@ -90,6 +99,19 @@
27          var options = {displayInLayerSwitcher: false};
28          this.layer = new OpenLayers.Layer.Vector(this.CLASS_NAME, options);
29          this.map.addLayer(this.layer);
30 +
31 +        // cursor
32 +        this.map.div.style.cursor = "crosshair";
33 +
34 +        // snap circle
35 +        if (this.snapDist) {
36 +            this.drawing = true;
37 +            var lonlat = this.map.getLonLatFromPixel({x:0,y:0});
38 +            this.createFeature();
39 +            this.point.geometry.x = lonlat.lon;
40 +            this.point.geometry.y = lonlat.lat;
41 +        }
42 +
43          return true;
44      },
45      
46 @@ -117,6 +139,7 @@
47          this.map.removeLayer(this.layer, false);
48          this.layer.destroy();
49          this.layer = null;
50 +        this.map.div.style.cursor = "auto";
51          return true;
52      },
53      
54 @@ -141,6 +164,14 @@
55          this.mouseDown = false;
56          this.lastDown = null;
57          this.lastUp = null;
58 +
59 +        if (this.snapDist) {
60 +            this.drawing = true;
61 +            var lonlat = this.map.getLonLatFromPixel({x:0,y:0});
62 +            this.createFeature();
63 +            this.point.geometry.x = lonlat.lon;
64 +            this.point.geometry.y = lonlat.lat;
65 +        }
66      },
67  
68      /**
69 @@ -203,6 +234,11 @@
70       * {Boolean} Allow event propagation
71       */
72      mousedown: function(evt) {
73 +
74 +        evt = this.snap(evt);
75 +
76 +        this.layer.redraw();
77 +
78          // check keyboard modifiers
79          if(!this.checkModifiers(evt)) {
80              return true;
81 @@ -265,5 +301,165 @@
82          }
83      },
84  
85 +
86 +    /**
87 +     * Method: snap
88 +     * Snap digitized point to nearest vertex/underlying data
89 +     * Return new event
90 +     *
91 +     * Parameters:
92 +     * evt - {Event} The browser event
93 +     *
94 +     * Return:
95 +     * {Event} Original event with new coordinates
96 +     */
97 +    snap: function(evt) {
98 +            var diff = Math.pow(this.snapDist,2); // minimal difference (initialized to power of snap distance)
99 +            var pixel = null;                // temporary OpenLayers.Pixel
100 +            var maxidx = 1;                  // maximal value geometry index - 1 for lines, 2 for polygons
101 +
102 +            /*
103 +             * Are we supposed to snap?
104 +             */
105 +            if (this.snapDist <= 0) {
106 +                return evt;
107 +            }
108 +
109 +            /*
110 +             * Set maximal index of vertex for polygons
111 +             */
112 +            if (this.layer.name == "OpenLayers.Handler.Polygon") {
113 +                maxidx = 2;
114 +            }
115 +
116 +            /*
117 +             * Snap to current digitized line or polygon to itself
118 +             */
119 +            if (this.line && this.line.geometry) {
120 +
121 +                /* for each point in current feature */
122 +                for (var i = 0; i < this.line.geometry.components.length-maxidx; ++i) {
123 +                    var tmppixel = this.map.getPixelFromLonLat(
124 +                                            new OpenLayers.LonLat(
125 +                                                        this.line.geometry.components[i].x,
126 +                                                        this.line.geometry.components[i].y));
127 +
128 +
129 +                    /* does it fit to threshold */
130 +                    if (Math.abs(tmppixel.x-evt.xy.x) < this.snapDist &&
131 +                        Math.abs(tmppixel.y-evt.xy.y)< this.snapDist) {
132 +
133 +                        /* search for smallest difference */
134 +                        var tmpdiff = Math.sqrt(Math.pow(Math.abs(tmppixel.x-evt.xy.x),2)+Math.pow(Math.abs(tmppixel.y-evt.xy.y),2));
135 +                        if ( tmpdiff < diff) {
136 +                            pixel = tmppixel;
137 +                            diff = tmpdiff;
138 +                        }
139 +                    }
140 +                }
141 +            }
142 +
143 +            /* Return this event, if snaped */
144 +            if (pixel) {
145 +                evt.xy = pixel;
146 +                this.mousemove(evt);
147 +                return evt;
148 +            }
149 +
150 +            /*
151 +             * Snap to existing featuers in same layer
152 +             */
153 +            for (var i in this.control.layer.features) {
154 +                this.diff = Math.pow(this.snapDist,2);
155 +                var feature = this.control.layer.features[i];
156 +                var pixel = this.findVertex(feature.geometry,evt);
157 +            }
158 +
159 +            if (pixel) {
160 +                evt.xy = pixel;
161 +                this.mousemove(evt);
162 +                return evt;
163 +            }
164 +
165 +            evt = this.customSnap(evt);
166 +
167 +            return evt;
168 +    },
169 +
170 +    /**
171 +     * Method: findVertex
172 +     * Finds closesed vertex/point according to event's xy coordinatates
173 +     * Return pixel
174 +     *
175 +     * Parameters:
176 +     * evt - {Event} The browser event
177 +     * geometry - {Geometry} Geometry, in the vertex is to be searched (polygon/line/point)
178 +     *
179 +     * Return:
180 +     * {Pixel} OpenLayers.Pixel of closesed vertex
181 +     */
182 +    findVertex: function (geometry,evt,pixel) {
183 +       
184 +        if (geometry.componentTypes) {
185 +            for (var i = 0; i < geometry.components.length; i++) {
186 +               pixel =  this.findVertex(geometry.components[i],evt,pixel);
187 +            }
188 +            return pixel;
189 +        }
190 +
191 +        var lonlat = new OpenLayers.LonLat();
192 +        var tmppixel = this.layer.map.getPixelFromLonLat(new OpenLayers.LonLat(
193 +                                geometry.x,geometry.y
194 +                                ));
195 +        /* does it fit to threshold? */
196 +        if (Math.abs(tmppixel.x-evt.xy.x) < this.snapDist &&
197 +            Math.abs(tmppixel.y-evt.xy.y)< this.snapDist) {
198 +
199 +            /* search for smallest difference */
200 +            var tmpdiff = Math.sqrt(Math.pow(Math.abs(tmppixel.x-evt.xy.x),2)+Math.pow(Math.abs(tmppixel.y-evt.xy.y),2));
201 +            if ( tmpdiff < this.diff) {
202 +                pixel = tmppixel;
203 +                this.diff = tmpdiff;
204 +            }
205 +        }   
206 +        return pixel;
207 +
208 +    },
209 +
210 +    /**
211 +     * Method: customSnap
212 +     * This method gives you possibility to add custom snapping function, like requesting nearest points using e.g. server scripts
213 +     * Return The browser event
214 +     *
215 +     * Parameters:
216 +     * evt - {Event} The browser event
217 +     *
218 +     * Return:
219 +     * {Event} The browser event
220 +     */
221 +    customSnap: function (evt) {
222 +       
223 +        return evt;
224 +
225 +    },
226 +           
227 +    /**
228 +     * Method: setSnapDist
229 +     * Return The browser event
230 +     *
231 +     * Parameters:
232 +     * evt - {Event} The browser event
233 +     *
234 +     * Return:
235 +     * {Event} The browser event
236 +     */
237 +    setSnapDist: function (dist) {
238 +       
239 +        this.snapDist = dist;
240 +        this.style.pointRadius = this.snapDist;
241 +        return evt;
242 +
243 +    },
244 +
245      CLASS_NAME: "OpenLayers.Handler.Point"
246  });