1 | <!DOCTYPE html> |
---|
2 | <html> |
---|
3 | <head> |
---|
4 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> |
---|
5 | <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> |
---|
6 | <meta name="apple-mobile-web-app-capable" content="yes"> |
---|
7 | <title>Snapping & Splitting</title> |
---|
8 | <link rel="stylesheet" href="../theme/default/style.css" type="text/css"> |
---|
9 | <!--[if lte IE 6]> |
---|
10 | <link rel="stylesheet" href="../theme/default/ie6-style.css" type="text/css" /> |
---|
11 | <![endif]--> |
---|
12 | <link rel="stylesheet" href="style.css" type="text/css"> |
---|
13 | <style type="text/css"> |
---|
14 | .olControlEditingToolbar .olControlModifyFeatureItemInactive { |
---|
15 | background-position: -1px -1px; |
---|
16 | } |
---|
17 | .olControlEditingToolbar .olControlModifyFeatureItemActive { |
---|
18 | background-position: -1px -24px; |
---|
19 | } |
---|
20 | label.head { |
---|
21 | font-weight: bold; |
---|
22 | padding: 1em 0 0.1em 0; |
---|
23 | border-bottom: 1px solid gray; |
---|
24 | } |
---|
25 | td { |
---|
26 | padding: 0.25em 1em; |
---|
27 | } |
---|
28 | tr.head td { |
---|
29 | text-align: center; |
---|
30 | font-weight: bold; |
---|
31 | } |
---|
32 | </style> |
---|
33 | <script src="../lib/Firebug/firebug.js"></script> |
---|
34 | <script src="../lib/OpenLayers.js"></script> |
---|
35 | <script type="text/javascript"> |
---|
36 | |
---|
37 | OpenLayers.Feature.Vector.style['default']['strokeWidth'] = '2'; |
---|
38 | |
---|
39 | function init() { |
---|
40 | initMap(); |
---|
41 | initUI(); |
---|
42 | } |
---|
43 | |
---|
44 | var map, draw, modify, snap, split, vectors; |
---|
45 | function initMap() { |
---|
46 | |
---|
47 | map = new OpenLayers.Map('map'); |
---|
48 | var styles = new OpenLayers.StyleMap({ |
---|
49 | "default": new OpenLayers.Style(null, { |
---|
50 | rules: [ |
---|
51 | new OpenLayers.Rule({ |
---|
52 | symbolizer: { |
---|
53 | "Point": { |
---|
54 | pointRadius: 5, |
---|
55 | graphicName: "square", |
---|
56 | fillColor: "white", |
---|
57 | fillOpacity: 0.25, |
---|
58 | strokeWidth: 1, |
---|
59 | strokeOpacity: 1, |
---|
60 | strokeColor: "#333333" |
---|
61 | }, |
---|
62 | "Line": { |
---|
63 | strokeWidth: 3, |
---|
64 | strokeOpacity: 1, |
---|
65 | strokeColor: "#666666" |
---|
66 | } |
---|
67 | } |
---|
68 | }) |
---|
69 | ] |
---|
70 | }), |
---|
71 | "select": new OpenLayers.Style({ |
---|
72 | strokeColor: "#00ccff", |
---|
73 | strokeWidth: 4 |
---|
74 | }), |
---|
75 | "temporary": new OpenLayers.Style(null, { |
---|
76 | rules: [ |
---|
77 | new OpenLayers.Rule({ |
---|
78 | symbolizer: { |
---|
79 | "Point": { |
---|
80 | pointRadius: 5, |
---|
81 | graphicName: "square", |
---|
82 | fillColor: "white", |
---|
83 | fillOpacity: 0.25, |
---|
84 | strokeWidth: 1, |
---|
85 | strokeOpacity: 1, |
---|
86 | strokeColor: "#333333" |
---|
87 | }, |
---|
88 | "Line": { |
---|
89 | strokeWidth: 3, |
---|
90 | strokeOpacity: 1, |
---|
91 | strokeColor: "#00ccff" |
---|
92 | } |
---|
93 | } |
---|
94 | }) |
---|
95 | ] |
---|
96 | }) |
---|
97 | }); |
---|
98 | |
---|
99 | // allow testing of specific renderers via "?renderer=Canvas", etc |
---|
100 | var renderer = OpenLayers.Util.getParameters(window.location.href).renderer; |
---|
101 | renderer = (renderer) ? [renderer] : OpenLayers.Layer.Vector.prototype.renderers; |
---|
102 | |
---|
103 | // create three vector layers |
---|
104 | vectors = new OpenLayers.Layer.Vector("Lines", { |
---|
105 | isBaseLayer: true, |
---|
106 | strategies: [new OpenLayers.Strategy.Fixed()], |
---|
107 | protocol: new OpenLayers.Protocol.HTTP({ |
---|
108 | url: "data/roads.json", |
---|
109 | format: new OpenLayers.Format.GeoJSON() |
---|
110 | }), |
---|
111 | styleMap: styles, |
---|
112 | maxExtent: new OpenLayers.Bounds( |
---|
113 | 1549471.9221, 6403610.94, 1550001.32545, 6404015.8 |
---|
114 | ), |
---|
115 | renderers: renderer |
---|
116 | }); |
---|
117 | map.addLayer(vectors); |
---|
118 | |
---|
119 | // configure the snapping agent |
---|
120 | snap = new OpenLayers.Control.Snapping({layer: vectors}); |
---|
121 | map.addControl(snap); |
---|
122 | snap.activate(); |
---|
123 | |
---|
124 | // configure split agent |
---|
125 | split = new OpenLayers.Control.Split({ |
---|
126 | layer: vectors, |
---|
127 | source: vectors, |
---|
128 | tolerance: 0.0001, |
---|
129 | eventListeners: { |
---|
130 | aftersplit: function(event) { |
---|
131 | flashFeatures(event.features); |
---|
132 | } |
---|
133 | } |
---|
134 | }); |
---|
135 | map.addControl(split); |
---|
136 | split.activate(); |
---|
137 | |
---|
138 | // add some editing tools to a panel |
---|
139 | var panel = new OpenLayers.Control.Panel({ |
---|
140 | displayClass: "olControlEditingToolbar" |
---|
141 | }); |
---|
142 | draw = new OpenLayers.Control.DrawFeature( |
---|
143 | vectors, OpenLayers.Handler.Path, |
---|
144 | {displayClass: "olControlDrawFeaturePoint", title: "Draw Features"} |
---|
145 | ); |
---|
146 | modify = new OpenLayers.Control.ModifyFeature( |
---|
147 | vectors, {displayClass: "olControlModifyFeature", title: "Modify Features"} |
---|
148 | ); |
---|
149 | panel.addControls([ |
---|
150 | new OpenLayers.Control.Navigation({title: "Navigate"}), |
---|
151 | draw, modify |
---|
152 | ]); |
---|
153 | map.addControl(panel); |
---|
154 | |
---|
155 | map.addControl(new OpenLayers.Control.MousePosition()); |
---|
156 | |
---|
157 | map.zoomToMaxExtent(); |
---|
158 | } |
---|
159 | |
---|
160 | function flashFeatures(features, index) { |
---|
161 | if(!index) { |
---|
162 | index = 0; |
---|
163 | } |
---|
164 | var current = features[index]; |
---|
165 | if(current && current.layer === vectors) { |
---|
166 | vectors.drawFeature(features[index], "select"); |
---|
167 | } |
---|
168 | var prev = features[index-1]; |
---|
169 | if(prev && prev.layer === vectors) { |
---|
170 | vectors.drawFeature(prev, "default"); |
---|
171 | } |
---|
172 | ++index; |
---|
173 | if(index <= features.length) { |
---|
174 | window.setTimeout(function() {flashFeatures(features, index)}, 75); |
---|
175 | } |
---|
176 | } |
---|
177 | |
---|
178 | /** |
---|
179 | * Add behavior to page elements. This basically lets us set snapping |
---|
180 | * target properties with the checkboxes and text inputs. The checkboxes |
---|
181 | * toggle the target node, vertex, or edge (boolean) values. The |
---|
182 | * text inputs set the nodeTolerance, vertexTolerance, or edgeTolerance |
---|
183 | * property values. |
---|
184 | */ |
---|
185 | function initUI() { |
---|
186 | // add behavior to snap elements |
---|
187 | var snapCheck = document.getElementById("snap_toggle"); |
---|
188 | snapCheck.checked = true; |
---|
189 | snapCheck.onclick = function() { |
---|
190 | if(snapCheck.checked) { |
---|
191 | snap.activate(); |
---|
192 | document.getElementById("snap_options").style.display = "block"; |
---|
193 | } else { |
---|
194 | snap.deactivate(); |
---|
195 | document.getElementById("snap_options").style.display = "none"; |
---|
196 | } |
---|
197 | }; |
---|
198 | var target, type, tog, tol; |
---|
199 | var types = ["node", "vertex", "edge"]; |
---|
200 | var target = snap.targets[0]; |
---|
201 | for(var j=0; j<types.length; ++j) { |
---|
202 | type = types[j]; |
---|
203 | tog = document.getElementById("target_" + type); |
---|
204 | tog.checked = target[type]; |
---|
205 | tog.onclick = (function(tog, type, target) { |
---|
206 | return function() {target[type] = tog.checked;} |
---|
207 | })(tog, type, target); |
---|
208 | tol = document.getElementById("target_" + type + "Tolerance"); |
---|
209 | tol.value = target[type + "Tolerance"]; |
---|
210 | tol.onchange = (function(tol, type, target) { |
---|
211 | return function() { |
---|
212 | target[type + "Tolerance"] = Number(tol.value) || 0; |
---|
213 | } |
---|
214 | })(tol, type, target); |
---|
215 | } |
---|
216 | |
---|
217 | // add behavior to split elements |
---|
218 | var splitCheck = document.getElementById("split_toggle"); |
---|
219 | splitCheck.checked = true; |
---|
220 | splitCheck.onclick = function() { |
---|
221 | if(splitCheck.checked) { |
---|
222 | split.activate(); |
---|
223 | document.getElementById("split_options").style.display = "block"; |
---|
224 | } else { |
---|
225 | split.deactivate(); |
---|
226 | document.getElementById("split_options").style.display = "none"; |
---|
227 | } |
---|
228 | }; |
---|
229 | var edgeCheck = document.getElementById("edge_toggle"); |
---|
230 | edgeCheck.checked = split.edge; |
---|
231 | edgeCheck.onclick = function() { |
---|
232 | split.edge = edgeCheck.checked; |
---|
233 | }; |
---|
234 | |
---|
235 | document.getElementById("clear").onclick = function() { |
---|
236 | modify.deactivate(); |
---|
237 | vectors.destroyFeatures(); |
---|
238 | }; |
---|
239 | |
---|
240 | } |
---|
241 | |
---|
242 | </script> |
---|
243 | </head> |
---|
244 | <body onload="init()"> |
---|
245 | <h1 id="title">Snapping & Splitting Example</h1> |
---|
246 | <div id="tags"> |
---|
247 | vector, feature, splitting, snapping, stylemap, advanced |
---|
248 | </div> |
---|
249 | <div id="shortdesc">A demonstration snapping and splitting while editing vector features.</div> |
---|
250 | <div id="map" class="smallmap"></div> |
---|
251 | <br> |
---|
252 | <input type="checkbox" id="snap_toggle" /> |
---|
253 | <label for="snap_toggle" class="head">Enable Snapping</label> |
---|
254 | <table id="snap_options"> |
---|
255 | <tbody> |
---|
256 | <tr class="head"> |
---|
257 | <td>target</td><td>node</td><td>vertex</td><td>edge</td> |
---|
258 | </tr> |
---|
259 | <tr> |
---|
260 | <td>roads</td> |
---|
261 | <td><input type="checkbox" id="target_node" /><input id="target_nodeTolerance" type="text" size="3" /></td> |
---|
262 | <td><input type="checkbox" id="target_vertex" /><input id="target_vertexTolerance" type="text" size="3" /></td> |
---|
263 | <td><input type="checkbox" id="target_edge" /><input id="target_edgeTolerance" type="text" size="3" /></td> |
---|
264 | </tr> |
---|
265 | </tbody> |
---|
266 | </table> |
---|
267 | <br> |
---|
268 | <input type="checkbox" id="split_toggle" /> |
---|
269 | <label for="split_toggle" class="head">Enable Splitting</label> |
---|
270 | <table id="split_options"> |
---|
271 | <tbody> |
---|
272 | <tr> |
---|
273 | <td><label for="edge_toggle">edges split</label></td> |
---|
274 | <td><input type="checkbox" id="edge_toggle" /></td> |
---|
275 | </tr> |
---|
276 | </tbody> |
---|
277 | </table> |
---|
278 | <br> |
---|
279 | <button id="clear">clear</button> Clear all features. |
---|
280 | </body> |
---|
281 | </html> |
---|