1 | /** |
---|
2 | * @requires OpenLayers/BaseTypes/Class.js |
---|
3 | * @requires OpenLayers/Util.js |
---|
4 | * @requires OpenLayers/Control.js |
---|
5 | * @requires OpenLayers/Format.js |
---|
6 | * @requires OpenLayers/Request.js |
---|
7 | * @requires OpenLayers/Layer/WMS.js |
---|
8 | * @requires OpenLayers/Layer/MapServer.js |
---|
9 | * @requires OpenLayers/Tile.js |
---|
10 | * @requires OpenLayers/Request/XMLHttpRequest.js |
---|
11 | * @requires OpenLayers/Layer/Vector.js |
---|
12 | * @requires OpenLayers/Layer/Markers.js |
---|
13 | * @requires OpenLayers/Console.js |
---|
14 | * @requires OpenLayers/Lang.js |
---|
15 | * @requires OpenLayers/Feature.js |
---|
16 | * @requires OpenLayers/Layer/EventPane.js |
---|
17 | * @requires OpenLayers/Layer/FixedZoomLevels.js |
---|
18 | * @requires OpenLayers/Layer/SphericalMercator.js |
---|
19 | * @requires OpenLayers/Protocol.js |
---|
20 | * @requires OpenLayers/Format/JSON.js |
---|
21 | * @requires OpenLayers/Format/WKT.js |
---|
22 | * @requires OpenLayers/Format/XML.js |
---|
23 | * @requires OpenLayers/Geometry.js |
---|
24 | * @requires OpenLayers/Renderer/Elements.js |
---|
25 | */ |
---|
26 | |
---|
27 | /** |
---|
28 | * About: Deprecated |
---|
29 | * The deprecated.js script includes all methods, properties, and constructors |
---|
30 | * that are not supported as part of the long-term API. If you use any of |
---|
31 | * these, you have to explicitly include this script in your application. |
---|
32 | * |
---|
33 | * For example: |
---|
34 | * (code) |
---|
35 | * <script src="deprecated.js" type="text/javascript"></script> |
---|
36 | * (end) |
---|
37 | * |
---|
38 | * You are strongly encouraged to avoid using deprecated functionality. The |
---|
39 | * documentation here should point you to the supported alternatives. |
---|
40 | */ |
---|
41 | |
---|
42 | /** |
---|
43 | * Namespace: OpenLayers.Class |
---|
44 | */ |
---|
45 | |
---|
46 | /** |
---|
47 | * Property: isPrototype |
---|
48 | * *Deprecated*. This is no longer needed and will be removed at 3.0. |
---|
49 | */ |
---|
50 | OpenLayers.Class.isPrototype = function () {}; |
---|
51 | |
---|
52 | /** |
---|
53 | * APIFunction: OpenLayers.create |
---|
54 | * *Deprecated*. Old method to create an OpenLayers style class. Use the |
---|
55 | * <OpenLayers.Class> constructor instead. |
---|
56 | * |
---|
57 | * Returns: |
---|
58 | * An OpenLayers class |
---|
59 | */ |
---|
60 | OpenLayers.Class.create = function() { |
---|
61 | return function() { |
---|
62 | if (arguments && arguments[0] != OpenLayers.Class.isPrototype) { |
---|
63 | this.initialize.apply(this, arguments); |
---|
64 | } |
---|
65 | }; |
---|
66 | }; |
---|
67 | |
---|
68 | /** |
---|
69 | * APIFunction: inherit |
---|
70 | * *Deprecated*. Old method to inherit from one or more OpenLayers style |
---|
71 | * classes. Use the <OpenLayers.Class> constructor instead. |
---|
72 | * |
---|
73 | * Parameters: |
---|
74 | * class - One or more classes can be provided as arguments |
---|
75 | * |
---|
76 | * Returns: |
---|
77 | * An object prototype |
---|
78 | */ |
---|
79 | OpenLayers.Class.inherit = function (P) { |
---|
80 | var C = function() { |
---|
81 | P.call(this); |
---|
82 | }; |
---|
83 | var newArgs = [C].concat(Array.prototype.slice.call(arguments)); |
---|
84 | OpenLayers.inherit.apply(null, newArgs); |
---|
85 | return C.prototype; |
---|
86 | }; |
---|
87 | |
---|
88 | /** |
---|
89 | * Namespace: OpenLayers.Util |
---|
90 | */ |
---|
91 | |
---|
92 | /** |
---|
93 | * Function: clearArray |
---|
94 | * *Deprecated*. This function will disappear in 3.0. |
---|
95 | * Please use "array.length = 0" instead. |
---|
96 | * |
---|
97 | * Parameters: |
---|
98 | * array - {Array} |
---|
99 | */ |
---|
100 | OpenLayers.Util.clearArray = function(array) { |
---|
101 | OpenLayers.Console.warn( |
---|
102 | OpenLayers.i18n( |
---|
103 | "methodDeprecated", {'newMethod': 'array = []'} |
---|
104 | ) |
---|
105 | ); |
---|
106 | array.length = 0; |
---|
107 | }; |
---|
108 | |
---|
109 | /** |
---|
110 | * Function: setOpacity |
---|
111 | * *Deprecated*. This function has been deprecated. Instead, please use |
---|
112 | * <OpenLayers.Util.modifyDOMElement> |
---|
113 | * or |
---|
114 | * <OpenLayers.Util.modifyAlphaImageDiv> |
---|
115 | * |
---|
116 | * Set the opacity of a DOM Element |
---|
117 | * Note that for this function to work in IE, elements must "have layout" |
---|
118 | * according to: |
---|
119 | * http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/haslayout.asp |
---|
120 | * |
---|
121 | * Parameters: |
---|
122 | * element - {DOMElement} Set the opacity on this DOM element |
---|
123 | * opacity - {Float} Opacity value (0.0 - 1.0) |
---|
124 | */ |
---|
125 | OpenLayers.Util.setOpacity = function(element, opacity) { |
---|
126 | OpenLayers.Util.modifyDOMElement(element, null, null, null, |
---|
127 | null, null, null, opacity); |
---|
128 | }; |
---|
129 | |
---|
130 | /** |
---|
131 | * Function: safeStopPropagation |
---|
132 | * *Deprecated*. This function has been deprecated. Please use directly |
---|
133 | * <OpenLayers.Event.stop> passing 'true' as the 2nd |
---|
134 | * argument (preventDefault) |
---|
135 | * |
---|
136 | * Safely stop the propagation of an event *without* preventing |
---|
137 | * the default browser action from occurring. |
---|
138 | * |
---|
139 | * Parameters: |
---|
140 | * evt - {Event} |
---|
141 | */ |
---|
142 | OpenLayers.Util.safeStopPropagation = function(evt) { |
---|
143 | OpenLayers.Event.stop(evt, true); |
---|
144 | }; |
---|
145 | |
---|
146 | /** |
---|
147 | * Function: getArgs |
---|
148 | * *Deprecated*. Will be removed in 3.0. Please use instead |
---|
149 | * <OpenLayers.Util.getParameters> |
---|
150 | * |
---|
151 | * Parameters: |
---|
152 | * url - {String} Optional url used to extract the query string. |
---|
153 | * If null, query string is taken from page location. |
---|
154 | * |
---|
155 | * Returns: |
---|
156 | * {Object} An object of key/value pairs from the query string. |
---|
157 | */ |
---|
158 | OpenLayers.Util.getArgs = function(url) { |
---|
159 | OpenLayers.Console.warn( |
---|
160 | OpenLayers.i18n( |
---|
161 | "methodDeprecated", {'newMethod': 'OpenLayers.Util.getParameters'} |
---|
162 | ) |
---|
163 | ); |
---|
164 | return OpenLayers.Util.getParameters(url); |
---|
165 | }; |
---|
166 | |
---|
167 | /** |
---|
168 | * Namespace: OpenLayers.Ajax |
---|
169 | */ |
---|
170 | |
---|
171 | /** |
---|
172 | * Function: OpenLayers.nullHandler |
---|
173 | * @param {} request |
---|
174 | */ |
---|
175 | OpenLayers.nullHandler = function(request) { |
---|
176 | OpenLayers.Console.userError(OpenLayers.i18n("unhandledRequest", {'statusText':request.statusText})); |
---|
177 | }; |
---|
178 | |
---|
179 | /** |
---|
180 | * APIFunction: OpenLayers.loadURL |
---|
181 | * Background load a document. |
---|
182 | * *Deprecated*. Use <OpenLayers.Request.GET> method instead. |
---|
183 | * |
---|
184 | * Parameters: |
---|
185 | * uri - {String} URI of source doc |
---|
186 | * params - {String} or {Object} GET params. Either a string in the form |
---|
187 | * "?hello=world&foo=bar" (do not forget the leading question mark) |
---|
188 | * or an object in the form {'hello': 'world', 'foo': 'bar} |
---|
189 | * caller - {Object} object which gets callbacks |
---|
190 | * onComplete - {Function} Optional callback for success. The callback |
---|
191 | * will be called with this set to caller and will receive the request |
---|
192 | * object as an argument. Note that if you do not specify an onComplete |
---|
193 | * function, <OpenLayers.nullHandler> will be called (which pops up a |
---|
194 | * user friendly error message dialog). |
---|
195 | * onFailure - {Function} Optional callback for failure. In the event of |
---|
196 | * a failure, the callback will be called with this set to caller and will |
---|
197 | * receive the request object as an argument. Note that if you do not |
---|
198 | * specify an onComplete function, <OpenLayers.nullHandler> will be called |
---|
199 | * (which pops up a user friendly error message dialog). |
---|
200 | * |
---|
201 | * Returns: |
---|
202 | * {<OpenLayers.Request.XMLHttpRequest>} The request object. To abort loading, |
---|
203 | * call request.abort(). |
---|
204 | */ |
---|
205 | OpenLayers.loadURL = function(uri, params, caller, |
---|
206 | onComplete, onFailure) { |
---|
207 | |
---|
208 | if(typeof params == 'string') { |
---|
209 | params = OpenLayers.Util.getParameters(params); |
---|
210 | } |
---|
211 | var success = (onComplete) ? onComplete : OpenLayers.nullHandler; |
---|
212 | var failure = (onFailure) ? onFailure : OpenLayers.nullHandler; |
---|
213 | |
---|
214 | return OpenLayers.Request.GET({ |
---|
215 | url: uri, params: params, |
---|
216 | success: success, failure: failure, scope: caller |
---|
217 | }); |
---|
218 | }; |
---|
219 | |
---|
220 | /** |
---|
221 | * Function: OpenLayers.parseXMLString |
---|
222 | * Parse XML into a doc structure |
---|
223 | * |
---|
224 | * Parameters: |
---|
225 | * text - {String} |
---|
226 | * |
---|
227 | * Returns: |
---|
228 | * {?} Parsed AJAX Responsev |
---|
229 | */ |
---|
230 | OpenLayers.parseXMLString = function(text) { |
---|
231 | |
---|
232 | //MS sucks, if the server is bad it dies |
---|
233 | var index = text.indexOf('<'); |
---|
234 | if (index > 0) { |
---|
235 | text = text.substring(index); |
---|
236 | } |
---|
237 | |
---|
238 | var ajaxResponse = OpenLayers.Util.Try( |
---|
239 | function() { |
---|
240 | var xmldom = new ActiveXObject('Microsoft.XMLDOM'); |
---|
241 | xmldom.loadXML(text); |
---|
242 | return xmldom; |
---|
243 | }, |
---|
244 | function() { |
---|
245 | return new DOMParser().parseFromString(text, 'text/xml'); |
---|
246 | }, |
---|
247 | function() { |
---|
248 | var req = new XMLHttpRequest(); |
---|
249 | req.open("GET", "data:" + "text/xml" + |
---|
250 | ";charset=utf-8," + encodeURIComponent(text), false); |
---|
251 | if (req.overrideMimeType) { |
---|
252 | req.overrideMimeType("text/xml"); |
---|
253 | } |
---|
254 | req.send(null); |
---|
255 | return req.responseXML; |
---|
256 | } |
---|
257 | ); |
---|
258 | |
---|
259 | return ajaxResponse; |
---|
260 | }; |
---|
261 | |
---|
262 | OpenLayers.Ajax = { |
---|
263 | |
---|
264 | /** |
---|
265 | * Method: emptyFunction |
---|
266 | */ |
---|
267 | emptyFunction: function () {}, |
---|
268 | |
---|
269 | /** |
---|
270 | * Method: getTransport |
---|
271 | * |
---|
272 | * Returns: |
---|
273 | * {Object} Transport mechanism for whichever browser we're in, or false if |
---|
274 | * none available. |
---|
275 | */ |
---|
276 | getTransport: function() { |
---|
277 | return OpenLayers.Util.Try( |
---|
278 | function() {return new XMLHttpRequest();}, |
---|
279 | function() {return new ActiveXObject('Msxml2.XMLHTTP');}, |
---|
280 | function() {return new ActiveXObject('Microsoft.XMLHTTP');} |
---|
281 | ) || false; |
---|
282 | }, |
---|
283 | |
---|
284 | /** |
---|
285 | * Property: activeRequestCount |
---|
286 | * {Integer} |
---|
287 | */ |
---|
288 | activeRequestCount: 0 |
---|
289 | }; |
---|
290 | |
---|
291 | /** |
---|
292 | * Namespace: OpenLayers.Ajax.Responders |
---|
293 | * {Object} |
---|
294 | */ |
---|
295 | OpenLayers.Ajax.Responders = { |
---|
296 | |
---|
297 | /** |
---|
298 | * Property: responders |
---|
299 | * {Array} |
---|
300 | */ |
---|
301 | responders: [], |
---|
302 | |
---|
303 | /** |
---|
304 | * Method: register |
---|
305 | * |
---|
306 | * Parameters: |
---|
307 | * responderToAdd - {?} |
---|
308 | */ |
---|
309 | register: function(responderToAdd) { |
---|
310 | for (var i = 0; i < this.responders.length; i++){ |
---|
311 | if (responderToAdd == this.responders[i]){ |
---|
312 | return; |
---|
313 | } |
---|
314 | } |
---|
315 | this.responders.push(responderToAdd); |
---|
316 | }, |
---|
317 | |
---|
318 | /** |
---|
319 | * Method: unregister |
---|
320 | * |
---|
321 | * Parameters: |
---|
322 | * responderToRemove - {?} |
---|
323 | */ |
---|
324 | unregister: function(responderToRemove) { |
---|
325 | OpenLayers.Util.removeItem(this.reponders, responderToRemove); |
---|
326 | }, |
---|
327 | |
---|
328 | /** |
---|
329 | * Method: dispatch |
---|
330 | * |
---|
331 | * Parameters: |
---|
332 | * callback - {?} |
---|
333 | * request - {?} |
---|
334 | * transport - {?} |
---|
335 | */ |
---|
336 | dispatch: function(callback, request, transport) { |
---|
337 | var responder; |
---|
338 | for (var i = 0; i < this.responders.length; i++) { |
---|
339 | responder = this.responders[i]; |
---|
340 | |
---|
341 | if (responder[callback] && |
---|
342 | typeof responder[callback] == 'function') { |
---|
343 | try { |
---|
344 | responder[callback].apply(responder, |
---|
345 | [request, transport]); |
---|
346 | } catch (e) {} |
---|
347 | } |
---|
348 | } |
---|
349 | } |
---|
350 | }; |
---|
351 | |
---|
352 | OpenLayers.Ajax.Responders.register({ |
---|
353 | /** |
---|
354 | * Function: onCreate |
---|
355 | */ |
---|
356 | onCreate: function() { |
---|
357 | OpenLayers.Ajax.activeRequestCount++; |
---|
358 | }, |
---|
359 | |
---|
360 | /** |
---|
361 | * Function: onComplete |
---|
362 | */ |
---|
363 | onComplete: function() { |
---|
364 | OpenLayers.Ajax.activeRequestCount--; |
---|
365 | } |
---|
366 | }); |
---|
367 | |
---|
368 | /** |
---|
369 | * Class: OpenLayers.Ajax.Base |
---|
370 | */ |
---|
371 | OpenLayers.Ajax.Base = OpenLayers.Class({ |
---|
372 | |
---|
373 | /** |
---|
374 | * Constructor: OpenLayers.Ajax.Base |
---|
375 | * |
---|
376 | * Parameters: |
---|
377 | * options - {Object} |
---|
378 | */ |
---|
379 | initialize: function(options) { |
---|
380 | this.options = { |
---|
381 | method: 'post', |
---|
382 | asynchronous: true, |
---|
383 | contentType: 'application/xml', |
---|
384 | parameters: '' |
---|
385 | }; |
---|
386 | OpenLayers.Util.extend(this.options, options || {}); |
---|
387 | |
---|
388 | this.options.method = this.options.method.toLowerCase(); |
---|
389 | |
---|
390 | if (typeof this.options.parameters == 'string') { |
---|
391 | this.options.parameters = |
---|
392 | OpenLayers.Util.getParameters(this.options.parameters); |
---|
393 | } |
---|
394 | } |
---|
395 | }); |
---|
396 | |
---|
397 | /** |
---|
398 | * Class: OpenLayers.Ajax.Request |
---|
399 | * *Deprecated*. Use <OpenLayers.Request> method instead. |
---|
400 | * |
---|
401 | * Inherit: |
---|
402 | * - <OpenLayers.Ajax.Base> |
---|
403 | */ |
---|
404 | OpenLayers.Ajax.Request = OpenLayers.Class(OpenLayers.Ajax.Base, { |
---|
405 | |
---|
406 | /** |
---|
407 | * Property: _complete |
---|
408 | * |
---|
409 | * {Boolean} |
---|
410 | */ |
---|
411 | _complete: false, |
---|
412 | |
---|
413 | /** |
---|
414 | * Constructor: OpenLayers.Ajax.Request |
---|
415 | * |
---|
416 | * Parameters: |
---|
417 | * url - {String} |
---|
418 | * options - {Object} |
---|
419 | */ |
---|
420 | initialize: function(url, options) { |
---|
421 | OpenLayers.Ajax.Base.prototype.initialize.apply(this, [options]); |
---|
422 | |
---|
423 | if (OpenLayers.ProxyHost && OpenLayers.String.startsWith(url, "http")) { |
---|
424 | url = OpenLayers.ProxyHost + encodeURIComponent(url); |
---|
425 | } |
---|
426 | |
---|
427 | this.transport = OpenLayers.Ajax.getTransport(); |
---|
428 | this.request(url); |
---|
429 | }, |
---|
430 | |
---|
431 | /** |
---|
432 | * Method: request |
---|
433 | * |
---|
434 | * Parameters: |
---|
435 | * url - {String} |
---|
436 | */ |
---|
437 | request: function(url) { |
---|
438 | this.url = url; |
---|
439 | this.method = this.options.method; |
---|
440 | var params = OpenLayers.Util.extend({}, this.options.parameters); |
---|
441 | |
---|
442 | if (this.method != 'get' && this.method != 'post') { |
---|
443 | // simulate other verbs over post |
---|
444 | params['_method'] = this.method; |
---|
445 | this.method = 'post'; |
---|
446 | } |
---|
447 | |
---|
448 | this.parameters = params; |
---|
449 | |
---|
450 | if (params = OpenLayers.Util.getParameterString(params)) { |
---|
451 | // when GET, append parameters to URL |
---|
452 | if (this.method == 'get') { |
---|
453 | this.url += ((this.url.indexOf('?') > -1) ? '&' : '?') + params; |
---|
454 | } else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { |
---|
455 | params += '&_='; |
---|
456 | } |
---|
457 | } |
---|
458 | try { |
---|
459 | var response = new OpenLayers.Ajax.Response(this); |
---|
460 | if (this.options.onCreate) { |
---|
461 | this.options.onCreate(response); |
---|
462 | } |
---|
463 | |
---|
464 | OpenLayers.Ajax.Responders.dispatch('onCreate', |
---|
465 | this, |
---|
466 | response); |
---|
467 | |
---|
468 | this.transport.open(this.method.toUpperCase(), |
---|
469 | this.url, |
---|
470 | this.options.asynchronous); |
---|
471 | |
---|
472 | if (this.options.asynchronous) { |
---|
473 | window.setTimeout( |
---|
474 | OpenLayers.Function.bind(this.respondToReadyState, this, 1), |
---|
475 | 10); |
---|
476 | } |
---|
477 | |
---|
478 | this.transport.onreadystatechange = |
---|
479 | OpenLayers.Function.bind(this.onStateChange, this); |
---|
480 | this.setRequestHeaders(); |
---|
481 | |
---|
482 | this.body = this.method == 'post' ? |
---|
483 | (this.options.postBody || params) : null; |
---|
484 | this.transport.send(this.body); |
---|
485 | |
---|
486 | // Force Firefox to handle ready state 4 for synchronous requests |
---|
487 | if (!this.options.asynchronous && |
---|
488 | this.transport.overrideMimeType) { |
---|
489 | this.onStateChange(); |
---|
490 | } |
---|
491 | } catch (e) { |
---|
492 | this.dispatchException(e); |
---|
493 | } |
---|
494 | }, |
---|
495 | |
---|
496 | /** |
---|
497 | * Method: onStateChange |
---|
498 | */ |
---|
499 | onStateChange: function() { |
---|
500 | var readyState = this.transport.readyState; |
---|
501 | if (readyState > 1 && !((readyState == 4) && this._complete)) { |
---|
502 | this.respondToReadyState(this.transport.readyState); |
---|
503 | } |
---|
504 | }, |
---|
505 | |
---|
506 | /** |
---|
507 | * Method: setRequestHeaders |
---|
508 | */ |
---|
509 | setRequestHeaders: function() { |
---|
510 | var headers = { |
---|
511 | 'X-Requested-With': 'XMLHttpRequest', |
---|
512 | 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*', |
---|
513 | 'OpenLayers': true |
---|
514 | }; |
---|
515 | |
---|
516 | if (this.method == 'post') { |
---|
517 | headers['Content-type'] = this.options.contentType + |
---|
518 | (this.options.encoding ? '; charset=' + this.options.encoding : ''); |
---|
519 | |
---|
520 | /* Force "Connection: close" for older Mozilla browsers to work |
---|
521 | * around a bug where XMLHttpRequest sends an incorrect |
---|
522 | * Content-length header. See Mozilla Bugzilla #246651. |
---|
523 | */ |
---|
524 | if (this.transport.overrideMimeType && |
---|
525 | (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) { |
---|
526 | headers['Connection'] = 'close'; |
---|
527 | } |
---|
528 | } |
---|
529 | // user-defined headers |
---|
530 | if (typeof this.options.requestHeaders == 'object') { |
---|
531 | var extras = this.options.requestHeaders; |
---|
532 | |
---|
533 | if (typeof extras.push == 'function') { |
---|
534 | for (var i = 0, length = extras.length; i < length; i += 2) { |
---|
535 | headers[extras[i]] = extras[i+1]; |
---|
536 | } |
---|
537 | } else { |
---|
538 | for (var i in extras) { |
---|
539 | headers[i] = extras[i]; |
---|
540 | } |
---|
541 | } |
---|
542 | } |
---|
543 | |
---|
544 | for (var name in headers) { |
---|
545 | this.transport.setRequestHeader(name, headers[name]); |
---|
546 | } |
---|
547 | }, |
---|
548 | |
---|
549 | /** |
---|
550 | * Method: success |
---|
551 | * |
---|
552 | * Returns: |
---|
553 | * {Boolean} - |
---|
554 | */ |
---|
555 | success: function() { |
---|
556 | var status = this.getStatus(); |
---|
557 | return !status || (status >=200 && status < 300); |
---|
558 | }, |
---|
559 | |
---|
560 | /** |
---|
561 | * Method: getStatus |
---|
562 | * |
---|
563 | * Returns: |
---|
564 | * {Integer} - Status |
---|
565 | */ |
---|
566 | getStatus: function() { |
---|
567 | try { |
---|
568 | return this.transport.status || 0; |
---|
569 | } catch (e) { |
---|
570 | return 0; |
---|
571 | } |
---|
572 | }, |
---|
573 | |
---|
574 | /** |
---|
575 | * Method: respondToReadyState |
---|
576 | * |
---|
577 | * Parameters: |
---|
578 | * readyState - {?} |
---|
579 | */ |
---|
580 | respondToReadyState: function(readyState) { |
---|
581 | var state = OpenLayers.Ajax.Request.Events[readyState]; |
---|
582 | var response = new OpenLayers.Ajax.Response(this); |
---|
583 | |
---|
584 | if (state == 'Complete') { |
---|
585 | try { |
---|
586 | this._complete = true; |
---|
587 | (this.options['on' + response.status] || |
---|
588 | this.options['on' + (this.success() ? 'Success' : 'Failure')] || |
---|
589 | OpenLayers.Ajax.emptyFunction)(response); |
---|
590 | } catch (e) { |
---|
591 | this.dispatchException(e); |
---|
592 | } |
---|
593 | |
---|
594 | var contentType = response.getHeader('Content-type'); |
---|
595 | } |
---|
596 | |
---|
597 | try { |
---|
598 | (this.options['on' + state] || |
---|
599 | OpenLayers.Ajax.emptyFunction)(response); |
---|
600 | OpenLayers.Ajax.Responders.dispatch('on' + state, |
---|
601 | this, |
---|
602 | response); |
---|
603 | } catch (e) { |
---|
604 | this.dispatchException(e); |
---|
605 | } |
---|
606 | |
---|
607 | if (state == 'Complete') { |
---|
608 | // avoid memory leak in MSIE: clean up |
---|
609 | this.transport.onreadystatechange = OpenLayers.Ajax.emptyFunction; |
---|
610 | } |
---|
611 | }, |
---|
612 | |
---|
613 | /** |
---|
614 | * Method: getHeader |
---|
615 | * |
---|
616 | * Parameters: |
---|
617 | * name - {String} Header name |
---|
618 | * |
---|
619 | * Returns: |
---|
620 | * {?} - response header for the given name |
---|
621 | */ |
---|
622 | getHeader: function(name) { |
---|
623 | try { |
---|
624 | return this.transport.getResponseHeader(name); |
---|
625 | } catch (e) { |
---|
626 | return null; |
---|
627 | } |
---|
628 | }, |
---|
629 | |
---|
630 | /** |
---|
631 | * Method: dispatchException |
---|
632 | * If the optional onException function is set, execute it |
---|
633 | * and then dispatch the call to any other listener registered |
---|
634 | * for onException. |
---|
635 | * |
---|
636 | * If no optional onException function is set, we suspect that |
---|
637 | * the user may have also not used |
---|
638 | * OpenLayers.Ajax.Responders.register to register a listener |
---|
639 | * for the onException call. To make sure that something |
---|
640 | * gets done with this exception, only dispatch the call if there |
---|
641 | * are listeners. |
---|
642 | * |
---|
643 | * If you explicitly want to swallow exceptions, set |
---|
644 | * request.options.onException to an empty function (function(){}) |
---|
645 | * or register an empty function with <OpenLayers.Ajax.Responders> |
---|
646 | * for onException. |
---|
647 | * |
---|
648 | * Parameters: |
---|
649 | * exception - {?} |
---|
650 | */ |
---|
651 | dispatchException: function(exception) { |
---|
652 | var handler = this.options.onException; |
---|
653 | if(handler) { |
---|
654 | // call options.onException and alert any other listeners |
---|
655 | handler(this, exception); |
---|
656 | OpenLayers.Ajax.Responders.dispatch('onException', this, exception); |
---|
657 | } else { |
---|
658 | // check if there are any other listeners |
---|
659 | var listener = false; |
---|
660 | var responders = OpenLayers.Ajax.Responders.responders; |
---|
661 | for (var i = 0; i < responders.length; i++) { |
---|
662 | if(responders[i].onException) { |
---|
663 | listener = true; |
---|
664 | break; |
---|
665 | } |
---|
666 | } |
---|
667 | if(listener) { |
---|
668 | // call all listeners |
---|
669 | OpenLayers.Ajax.Responders.dispatch('onException', this, exception); |
---|
670 | } else { |
---|
671 | // let the exception through |
---|
672 | throw exception; |
---|
673 | } |
---|
674 | } |
---|
675 | } |
---|
676 | }); |
---|
677 | |
---|
678 | /** |
---|
679 | * Property: Events |
---|
680 | * {Array(String)} |
---|
681 | */ |
---|
682 | OpenLayers.Ajax.Request.Events = |
---|
683 | ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; |
---|
684 | |
---|
685 | /** |
---|
686 | * Class: OpenLayers.Ajax.Response |
---|
687 | */ |
---|
688 | OpenLayers.Ajax.Response = OpenLayers.Class({ |
---|
689 | |
---|
690 | /** |
---|
691 | * Property: status |
---|
692 | * |
---|
693 | * {Integer} |
---|
694 | */ |
---|
695 | status: 0, |
---|
696 | |
---|
697 | |
---|
698 | /** |
---|
699 | * Property: statusText |
---|
700 | * |
---|
701 | * {String} |
---|
702 | */ |
---|
703 | statusText: '', |
---|
704 | |
---|
705 | /** |
---|
706 | * Constructor: OpenLayers.Ajax.Response |
---|
707 | * |
---|
708 | * Parameters: |
---|
709 | * request - {Object} |
---|
710 | */ |
---|
711 | initialize: function(request) { |
---|
712 | this.request = request; |
---|
713 | var transport = this.transport = request.transport, |
---|
714 | readyState = this.readyState = transport.readyState; |
---|
715 | |
---|
716 | if ((readyState > 2 && |
---|
717 | !(!!(window.attachEvent && !window.opera))) || |
---|
718 | readyState == 4) { |
---|
719 | this.status = this.getStatus(); |
---|
720 | this.statusText = this.getStatusText(); |
---|
721 | this.responseText = transport.responseText == null ? |
---|
722 | '' : String(transport.responseText); |
---|
723 | } |
---|
724 | |
---|
725 | if(readyState == 4) { |
---|
726 | var xml = transport.responseXML; |
---|
727 | this.responseXML = xml === undefined ? null : xml; |
---|
728 | } |
---|
729 | }, |
---|
730 | |
---|
731 | /** |
---|
732 | * Method: getStatus |
---|
733 | */ |
---|
734 | getStatus: OpenLayers.Ajax.Request.prototype.getStatus, |
---|
735 | |
---|
736 | /** |
---|
737 | * Method: getStatustext |
---|
738 | * |
---|
739 | * Returns: |
---|
740 | * {String} - statusText |
---|
741 | */ |
---|
742 | getStatusText: function() { |
---|
743 | try { |
---|
744 | return this.transport.statusText || ''; |
---|
745 | } catch (e) { |
---|
746 | return ''; |
---|
747 | } |
---|
748 | }, |
---|
749 | |
---|
750 | /** |
---|
751 | * Method: getHeader |
---|
752 | */ |
---|
753 | getHeader: OpenLayers.Ajax.Request.prototype.getHeader, |
---|
754 | |
---|
755 | /** |
---|
756 | * Method: getResponseHeader |
---|
757 | * |
---|
758 | * Returns: |
---|
759 | * {?} - response header for given name |
---|
760 | */ |
---|
761 | getResponseHeader: function(name) { |
---|
762 | return this.transport.getResponseHeader(name); |
---|
763 | } |
---|
764 | }); |
---|
765 | |
---|
766 | |
---|
767 | /** |
---|
768 | * Function: getElementsByTagNameNS |
---|
769 | * |
---|
770 | * Parameters: |
---|
771 | * parentnode - {?} |
---|
772 | * nsuri - {?} |
---|
773 | * nsprefix - {?} |
---|
774 | * tagname - {?} |
---|
775 | * |
---|
776 | * Returns: |
---|
777 | * {?} |
---|
778 | */ |
---|
779 | OpenLayers.Ajax.getElementsByTagNameNS = function(parentnode, nsuri, |
---|
780 | nsprefix, tagname) { |
---|
781 | var elem = null; |
---|
782 | if (parentnode.getElementsByTagNameNS) { |
---|
783 | elem = parentnode.getElementsByTagNameNS(nsuri, tagname); |
---|
784 | } else { |
---|
785 | elem = parentnode.getElementsByTagName(nsprefix + ':' + tagname); |
---|
786 | } |
---|
787 | return elem; |
---|
788 | }; |
---|
789 | |
---|
790 | |
---|
791 | /** |
---|
792 | * Function: serializeXMLToString |
---|
793 | * Wrapper function around XMLSerializer, which doesn't exist/work in |
---|
794 | * IE/Safari. We need to come up with a way to serialize in those browser: |
---|
795 | * for now, these browsers will just fail. #535, #536 |
---|
796 | * |
---|
797 | * Parameters: |
---|
798 | * xmldom {XMLNode} xml dom to serialize |
---|
799 | * |
---|
800 | * Returns: |
---|
801 | * {?} |
---|
802 | */ |
---|
803 | OpenLayers.Ajax.serializeXMLToString = function(xmldom) { |
---|
804 | var serializer = new XMLSerializer(); |
---|
805 | var data = serializer.serializeToString(xmldom); |
---|
806 | return data; |
---|
807 | }; |
---|
808 | |
---|
809 | /** |
---|
810 | * Namespace: OpenLayers.Element |
---|
811 | */ |
---|
812 | OpenLayers.Util.extend(OpenLayers.Element, { |
---|
813 | |
---|
814 | /** |
---|
815 | * APIFunction: hide |
---|
816 | * *Deprecated*. Hide element(s) passed in |
---|
817 | * |
---|
818 | * Parameters: |
---|
819 | * element - {DOMElement} Actually user can pass any number of elements |
---|
820 | */ |
---|
821 | hide: function() { |
---|
822 | OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated", { |
---|
823 | newMethod: "element.style.display = 'none';" |
---|
824 | })); |
---|
825 | |
---|
826 | for (var i=0, len=arguments.length; i<len; i++) { |
---|
827 | var element = OpenLayers.Util.getElement(arguments[i]); |
---|
828 | if (element) { |
---|
829 | element.style.display = 'none'; |
---|
830 | } |
---|
831 | } |
---|
832 | }, |
---|
833 | |
---|
834 | /** |
---|
835 | * APIFunction: show |
---|
836 | * *Deprecated*. Show element(s) passed in |
---|
837 | * |
---|
838 | * Parameters: |
---|
839 | * element - {DOMElement} Actually user can pass any number of elements |
---|
840 | */ |
---|
841 | show: function() { |
---|
842 | OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated", { |
---|
843 | newMethod: "element.style.display = '';" |
---|
844 | })); |
---|
845 | |
---|
846 | for (var i=0, len=arguments.length; i<len; i++) { |
---|
847 | var element = OpenLayers.Util.getElement(arguments[i]); |
---|
848 | if (element) { |
---|
849 | element.style.display = ''; |
---|
850 | } |
---|
851 | } |
---|
852 | }, |
---|
853 | |
---|
854 | /** |
---|
855 | * APIFunction: getDimensions |
---|
856 | * *Deprecated*. Returns dimensions of the element passed in. |
---|
857 | * |
---|
858 | * Parameters: |
---|
859 | * element - {DOMElement} |
---|
860 | * |
---|
861 | * Returns: |
---|
862 | * {Object} Object with 'width' and 'height' properties which are the |
---|
863 | * dimensions of the element passed in. |
---|
864 | */ |
---|
865 | getDimensions: function(element) { |
---|
866 | element = OpenLayers.Util.getElement(element); |
---|
867 | if (OpenLayers.Element.getStyle(element, 'display') != 'none') { |
---|
868 | return {width: element.offsetWidth, height: element.offsetHeight}; |
---|
869 | } |
---|
870 | |
---|
871 | // All *Width and *Height properties give 0 on elements with display none, |
---|
872 | // so enable the element temporarily |
---|
873 | var els = element.style; |
---|
874 | var originalVisibility = els.visibility; |
---|
875 | var originalPosition = els.position; |
---|
876 | var originalDisplay = els.display; |
---|
877 | els.visibility = 'hidden'; |
---|
878 | els.position = 'absolute'; |
---|
879 | els.display = ''; |
---|
880 | var originalWidth = element.clientWidth; |
---|
881 | var originalHeight = element.clientHeight; |
---|
882 | els.display = originalDisplay; |
---|
883 | els.position = originalPosition; |
---|
884 | els.visibility = originalVisibility; |
---|
885 | return {width: originalWidth, height: originalHeight}; |
---|
886 | } |
---|
887 | |
---|
888 | }); |
---|
889 | |
---|
890 | if (!String.prototype.startsWith) { |
---|
891 | /** |
---|
892 | * APIMethod: String.startsWith |
---|
893 | * *Deprecated*. Whether or not a string starts with another string. |
---|
894 | * |
---|
895 | * Parameters: |
---|
896 | * sStart - {String} The string we're testing for. |
---|
897 | * |
---|
898 | * Returns: |
---|
899 | * {Boolean} Whether or not this string starts with the string passed in. |
---|
900 | */ |
---|
901 | String.prototype.startsWith = function(sStart) { |
---|
902 | OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated", |
---|
903 | {'newMethod':'OpenLayers.String.startsWith'})); |
---|
904 | return OpenLayers.String.startsWith(this, sStart); |
---|
905 | }; |
---|
906 | } |
---|
907 | |
---|
908 | if (!String.prototype.contains) { |
---|
909 | /** |
---|
910 | * APIMethod: String.contains |
---|
911 | * *Deprecated*. Whether or not a string contains another string. |
---|
912 | * |
---|
913 | * Parameters: |
---|
914 | * str - {String} The string that we're testing for. |
---|
915 | * |
---|
916 | * Returns: |
---|
917 | * {Boolean} Whether or not this string contains with the string passed in. |
---|
918 | */ |
---|
919 | String.prototype.contains = function(str) { |
---|
920 | OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated", |
---|
921 | {'newMethod':'OpenLayers.String.contains'})); |
---|
922 | return OpenLayers.String.contains(this, str); |
---|
923 | }; |
---|
924 | } |
---|
925 | |
---|
926 | if (!String.prototype.trim) { |
---|
927 | /** |
---|
928 | * APIMethod: String.trim |
---|
929 | * *Deprecated*. Removes leading and trailing whitespace characters from a string. |
---|
930 | * |
---|
931 | * Returns: |
---|
932 | * {String} A trimmed version of the string - all leading and |
---|
933 | * trailing spaces removed |
---|
934 | */ |
---|
935 | String.prototype.trim = function() { |
---|
936 | OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated", |
---|
937 | {'newMethod':'OpenLayers.String.trim'})); |
---|
938 | return OpenLayers.String.trim(this); |
---|
939 | }; |
---|
940 | } |
---|
941 | |
---|
942 | if (!String.prototype.camelize) { |
---|
943 | /** |
---|
944 | * APIMethod: String.camelize |
---|
945 | * *Deprecated*. Camel-case a hyphenated string. |
---|
946 | * Ex. "chicken-head" becomes "chickenHead", and |
---|
947 | * "-chicken-head" becomes "ChickenHead". |
---|
948 | * |
---|
949 | * Returns: |
---|
950 | * {String} The string, camelized |
---|
951 | */ |
---|
952 | String.prototype.camelize = function() { |
---|
953 | OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated", |
---|
954 | {'newMethod':'OpenLayers.String.camelize'})); |
---|
955 | return OpenLayers.String.camelize(this); |
---|
956 | }; |
---|
957 | } |
---|
958 | |
---|
959 | if (!Function.prototype.bind) { |
---|
960 | /** |
---|
961 | * APIMethod: Function.bind |
---|
962 | * *Deprecated*. Bind a function to an object. |
---|
963 | * Method to easily create closures with 'this' altered. |
---|
964 | * |
---|
965 | * Parameters: |
---|
966 | * object - {Object} the this parameter |
---|
967 | * |
---|
968 | * Returns: |
---|
969 | * {Function} A closure with 'this' altered to the first |
---|
970 | * argument. |
---|
971 | */ |
---|
972 | Function.prototype.bind = function() { |
---|
973 | OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated", |
---|
974 | {'newMethod':'OpenLayers.Function.bind'})); |
---|
975 | // new function takes the same arguments with this function up front |
---|
976 | Array.prototype.unshift.apply(arguments, [this]); |
---|
977 | return OpenLayers.Function.bind.apply(null, arguments); |
---|
978 | }; |
---|
979 | } |
---|
980 | |
---|
981 | if (!Function.prototype.bindAsEventListener) { |
---|
982 | /** |
---|
983 | * APIMethod: Function.bindAsEventListener |
---|
984 | * *Deprecated*. Bind a function to an object, and configure it to receive the |
---|
985 | * event object as first parameter when called. |
---|
986 | * |
---|
987 | * Parameters: |
---|
988 | * object - {Object} A reference to this. |
---|
989 | * |
---|
990 | * Returns: |
---|
991 | * {Function} |
---|
992 | */ |
---|
993 | Function.prototype.bindAsEventListener = function(object) { |
---|
994 | OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated", |
---|
995 | {'newMethod':'OpenLayers.Function.bindAsEventListener'})); |
---|
996 | return OpenLayers.Function.bindAsEventListener(this, object); |
---|
997 | }; |
---|
998 | } |
---|
999 | |
---|
1000 | // FIXME: Remove this in 3.0. In 3.0, Event.stop will no longer be provided |
---|
1001 | // by OpenLayers. |
---|
1002 | if (window.Event) { |
---|
1003 | OpenLayers.Util.applyDefaults(window.Event, OpenLayers.Event); |
---|
1004 | } else { |
---|
1005 | var Event = OpenLayers.Event; |
---|
1006 | } |
---|
1007 | |
---|
1008 | /** |
---|
1009 | * Namespace: OpenLayers.Tile |
---|
1010 | */ |
---|
1011 | OpenLayers.Util.extend(OpenLayers.Tile.prototype, { |
---|
1012 | /** |
---|
1013 | * Method: getBoundsFromBaseLayer |
---|
1014 | * Take the pixel locations of the corner of the tile, and pass them to |
---|
1015 | * the base layer and ask for the location of those pixels, so that |
---|
1016 | * displaying tiles over Google works fine. |
---|
1017 | * |
---|
1018 | * Parameters: |
---|
1019 | * position - {<OpenLayers.Pixel>} |
---|
1020 | * |
---|
1021 | * Returns: |
---|
1022 | * bounds - {<OpenLayers.Bounds>} |
---|
1023 | */ |
---|
1024 | getBoundsFromBaseLayer: function(position) { |
---|
1025 | var msg = OpenLayers.i18n('reprojectDeprecated', |
---|
1026 | {'layerName':this.layer.name}); |
---|
1027 | OpenLayers.Console.warn(msg); |
---|
1028 | var topLeft = this.layer.map.getLonLatFromLayerPx(position); |
---|
1029 | var bottomRightPx = position.clone(); |
---|
1030 | bottomRightPx.x += this.size.w; |
---|
1031 | bottomRightPx.y += this.size.h; |
---|
1032 | var bottomRight = this.layer.map.getLonLatFromLayerPx(bottomRightPx); |
---|
1033 | // Handle the case where the base layer wraps around the date line. |
---|
1034 | // Google does this, and it breaks WMS servers to request bounds in |
---|
1035 | // that fashion. |
---|
1036 | if (topLeft.lon > bottomRight.lon) { |
---|
1037 | if (topLeft.lon < 0) { |
---|
1038 | topLeft.lon = -180 - (topLeft.lon+180); |
---|
1039 | } else { |
---|
1040 | bottomRight.lon = 180+bottomRight.lon+180; |
---|
1041 | } |
---|
1042 | } |
---|
1043 | var bounds = new OpenLayers.Bounds(topLeft.lon, |
---|
1044 | bottomRight.lat, |
---|
1045 | bottomRight.lon, |
---|
1046 | topLeft.lat); |
---|
1047 | return bounds; |
---|
1048 | } |
---|
1049 | }); |
---|
1050 | |
---|
1051 | /** |
---|
1052 | * Class: OpenLayers.Control.MouseDefaults |
---|
1053 | * This class is DEPRECATED in 2.4 and will be removed by 3.0. |
---|
1054 | * If you need this functionality, use <OpenLayers.Control.Navigation> |
---|
1055 | * instead!!! |
---|
1056 | * |
---|
1057 | * Inherits from: |
---|
1058 | * - <OpenLayers.Control> |
---|
1059 | */ |
---|
1060 | OpenLayers.Control.MouseDefaults = OpenLayers.Class(OpenLayers.Control, { |
---|
1061 | |
---|
1062 | /** WARNING WARNING WARNING!!! |
---|
1063 | This class is DEPRECATED in 2.4 and will be removed by 3.0. |
---|
1064 | If you need this functionality, use Control.Navigation instead!!! */ |
---|
1065 | |
---|
1066 | /** |
---|
1067 | * Property: performedDrag |
---|
1068 | * {Boolean} |
---|
1069 | */ |
---|
1070 | performedDrag: false, |
---|
1071 | |
---|
1072 | /** |
---|
1073 | * Property: wheelObserver |
---|
1074 | * {Function} |
---|
1075 | */ |
---|
1076 | wheelObserver: null, |
---|
1077 | |
---|
1078 | /** |
---|
1079 | * Constructor: OpenLayers.Control.MouseDefaults |
---|
1080 | */ |
---|
1081 | initialize: function() { |
---|
1082 | OpenLayers.Control.prototype.initialize.apply(this, arguments); |
---|
1083 | }, |
---|
1084 | |
---|
1085 | /** |
---|
1086 | * APIMethod: destroy |
---|
1087 | */ |
---|
1088 | destroy: function() { |
---|
1089 | |
---|
1090 | if (this.handler) { |
---|
1091 | this.handler.destroy(); |
---|
1092 | } |
---|
1093 | this.handler = null; |
---|
1094 | |
---|
1095 | this.map.events.un({ |
---|
1096 | "click": this.defaultClick, |
---|
1097 | "dblclick": this.defaultDblClick, |
---|
1098 | "mousedown": this.defaultMouseDown, |
---|
1099 | "mouseup": this.defaultMouseUp, |
---|
1100 | "mousemove": this.defaultMouseMove, |
---|
1101 | "mouseout": this.defaultMouseOut, |
---|
1102 | scope: this |
---|
1103 | }); |
---|
1104 | |
---|
1105 | //unregister mousewheel events specifically on the window and document |
---|
1106 | OpenLayers.Event.stopObserving(window, "DOMMouseScroll", |
---|
1107 | this.wheelObserver); |
---|
1108 | OpenLayers.Event.stopObserving(window, "mousewheel", |
---|
1109 | this.wheelObserver); |
---|
1110 | OpenLayers.Event.stopObserving(document, "mousewheel", |
---|
1111 | this.wheelObserver); |
---|
1112 | this.wheelObserver = null; |
---|
1113 | |
---|
1114 | OpenLayers.Control.prototype.destroy.apply(this, arguments); |
---|
1115 | }, |
---|
1116 | |
---|
1117 | /** |
---|
1118 | * Method: draw |
---|
1119 | */ |
---|
1120 | draw: function() { |
---|
1121 | this.map.events.on({ |
---|
1122 | "click": this.defaultClick, |
---|
1123 | "dblclick": this.defaultDblClick, |
---|
1124 | "mousedown": this.defaultMouseDown, |
---|
1125 | "mouseup": this.defaultMouseUp, |
---|
1126 | "mousemove": this.defaultMouseMove, |
---|
1127 | "mouseout": this.defaultMouseOut, |
---|
1128 | scope: this |
---|
1129 | }); |
---|
1130 | |
---|
1131 | this.registerWheelEvents(); |
---|
1132 | |
---|
1133 | }, |
---|
1134 | |
---|
1135 | /** |
---|
1136 | * Method: registerWheelEvents |
---|
1137 | */ |
---|
1138 | registerWheelEvents: function() { |
---|
1139 | |
---|
1140 | this.wheelObserver = OpenLayers.Function.bindAsEventListener( |
---|
1141 | this.onWheelEvent, this |
---|
1142 | ); |
---|
1143 | |
---|
1144 | //register mousewheel events specifically on the window and document |
---|
1145 | OpenLayers.Event.observe(window, "DOMMouseScroll", this.wheelObserver); |
---|
1146 | OpenLayers.Event.observe(window, "mousewheel", this.wheelObserver); |
---|
1147 | OpenLayers.Event.observe(document, "mousewheel", this.wheelObserver); |
---|
1148 | }, |
---|
1149 | |
---|
1150 | /** |
---|
1151 | * Method: defaultClick |
---|
1152 | * |
---|
1153 | * Parameters: |
---|
1154 | * evt - {Event} |
---|
1155 | * |
---|
1156 | * Returns: |
---|
1157 | * {Boolean} |
---|
1158 | */ |
---|
1159 | defaultClick: function (evt) { |
---|
1160 | if (!OpenLayers.Event.isLeftClick(evt)) { |
---|
1161 | return; |
---|
1162 | } |
---|
1163 | var notAfterDrag = !this.performedDrag; |
---|
1164 | this.performedDrag = false; |
---|
1165 | return notAfterDrag; |
---|
1166 | }, |
---|
1167 | |
---|
1168 | /** |
---|
1169 | * Method: defaultDblClick |
---|
1170 | * |
---|
1171 | * Parameters: |
---|
1172 | * evt - {Event} |
---|
1173 | */ |
---|
1174 | defaultDblClick: function (evt) { |
---|
1175 | var newCenter = this.map.getLonLatFromViewPortPx( evt.xy ); |
---|
1176 | this.map.setCenter(newCenter, this.map.zoom + 1); |
---|
1177 | OpenLayers.Event.stop(evt); |
---|
1178 | return false; |
---|
1179 | }, |
---|
1180 | |
---|
1181 | /** |
---|
1182 | * Method: defaultMouseDown |
---|
1183 | * |
---|
1184 | * Parameters: |
---|
1185 | * evt - {Event} |
---|
1186 | */ |
---|
1187 | defaultMouseDown: function (evt) { |
---|
1188 | if (!OpenLayers.Event.isLeftClick(evt)) { |
---|
1189 | return; |
---|
1190 | } |
---|
1191 | this.mouseDragStart = evt.xy.clone(); |
---|
1192 | this.performedDrag = false; |
---|
1193 | if (evt.shiftKey) { |
---|
1194 | this.map.div.style.cursor = "crosshair"; |
---|
1195 | this.zoomBox = OpenLayers.Util.createDiv('zoomBox', |
---|
1196 | this.mouseDragStart, |
---|
1197 | null, |
---|
1198 | null, |
---|
1199 | "absolute", |
---|
1200 | "2px solid red"); |
---|
1201 | this.zoomBox.style.backgroundColor = "white"; |
---|
1202 | this.zoomBox.style.filter = "alpha(opacity=50)"; // IE |
---|
1203 | this.zoomBox.style.opacity = "0.50"; |
---|
1204 | this.zoomBox.style.fontSize = "1px"; |
---|
1205 | this.zoomBox.style.zIndex = this.map.Z_INDEX_BASE["Popup"] - 1; |
---|
1206 | this.map.viewPortDiv.appendChild(this.zoomBox); |
---|
1207 | } |
---|
1208 | document.onselectstart = OpenLayers.Function.False; |
---|
1209 | OpenLayers.Event.stop(evt); |
---|
1210 | }, |
---|
1211 | |
---|
1212 | /** |
---|
1213 | * Method: defaultMouseMove |
---|
1214 | * |
---|
1215 | * Parameters: |
---|
1216 | * evt - {Event} |
---|
1217 | */ |
---|
1218 | defaultMouseMove: function (evt) { |
---|
1219 | // record the mouse position, used in onWheelEvent |
---|
1220 | this.mousePosition = evt.xy.clone(); |
---|
1221 | |
---|
1222 | if (this.mouseDragStart != null) { |
---|
1223 | if (this.zoomBox) { |
---|
1224 | var deltaX = Math.abs(this.mouseDragStart.x - evt.xy.x); |
---|
1225 | var deltaY = Math.abs(this.mouseDragStart.y - evt.xy.y); |
---|
1226 | this.zoomBox.style.width = Math.max(1, deltaX) + "px"; |
---|
1227 | this.zoomBox.style.height = Math.max(1, deltaY) + "px"; |
---|
1228 | if (evt.xy.x < this.mouseDragStart.x) { |
---|
1229 | this.zoomBox.style.left = evt.xy.x+"px"; |
---|
1230 | } |
---|
1231 | if (evt.xy.y < this.mouseDragStart.y) { |
---|
1232 | this.zoomBox.style.top = evt.xy.y+"px"; |
---|
1233 | } |
---|
1234 | } else { |
---|
1235 | var deltaX = this.mouseDragStart.x - evt.xy.x; |
---|
1236 | var deltaY = this.mouseDragStart.y - evt.xy.y; |
---|
1237 | var size = this.map.getSize(); |
---|
1238 | var newXY = new OpenLayers.Pixel(size.w / 2 + deltaX, |
---|
1239 | size.h / 2 + deltaY); |
---|
1240 | var newCenter = this.map.getLonLatFromViewPortPx( newXY ); |
---|
1241 | this.map.setCenter(newCenter, null, true); |
---|
1242 | this.mouseDragStart = evt.xy.clone(); |
---|
1243 | this.map.div.style.cursor = "move"; |
---|
1244 | } |
---|
1245 | this.performedDrag = true; |
---|
1246 | } |
---|
1247 | }, |
---|
1248 | |
---|
1249 | /** |
---|
1250 | * Method: defaultMouseUp |
---|
1251 | * |
---|
1252 | * Parameters: |
---|
1253 | * evt - {<OpenLayers.Event>} |
---|
1254 | */ |
---|
1255 | defaultMouseUp: function (evt) { |
---|
1256 | if (!OpenLayers.Event.isLeftClick(evt)) { |
---|
1257 | return; |
---|
1258 | } |
---|
1259 | if (this.zoomBox) { |
---|
1260 | this.zoomBoxEnd(evt); |
---|
1261 | } else { |
---|
1262 | if (this.performedDrag) { |
---|
1263 | this.map.setCenter(this.map.center); |
---|
1264 | } |
---|
1265 | } |
---|
1266 | document.onselectstart=null; |
---|
1267 | this.mouseDragStart = null; |
---|
1268 | this.map.div.style.cursor = ""; |
---|
1269 | }, |
---|
1270 | |
---|
1271 | /** |
---|
1272 | * Method: defaultMouseOut |
---|
1273 | * |
---|
1274 | * Parameters: |
---|
1275 | * evt - {Event} |
---|
1276 | */ |
---|
1277 | defaultMouseOut: function (evt) { |
---|
1278 | if (this.mouseDragStart != null && |
---|
1279 | OpenLayers.Util.mouseLeft(evt, this.map.viewPortDiv)) { |
---|
1280 | if (this.zoomBox) { |
---|
1281 | this.removeZoomBox(); |
---|
1282 | } |
---|
1283 | this.mouseDragStart = null; |
---|
1284 | } |
---|
1285 | }, |
---|
1286 | |
---|
1287 | |
---|
1288 | /** |
---|
1289 | * Method: defaultWheelUp |
---|
1290 | * User spun scroll wheel up |
---|
1291 | * |
---|
1292 | */ |
---|
1293 | defaultWheelUp: function(evt) { |
---|
1294 | if (this.map.getZoom() <= this.map.getNumZoomLevels()) { |
---|
1295 | this.map.setCenter(this.map.getLonLatFromPixel(evt.xy), |
---|
1296 | this.map.getZoom() + 1); |
---|
1297 | } |
---|
1298 | }, |
---|
1299 | |
---|
1300 | /** |
---|
1301 | * Method: defaultWheelDown |
---|
1302 | * User spun scroll wheel down |
---|
1303 | */ |
---|
1304 | defaultWheelDown: function(evt) { |
---|
1305 | if (this.map.getZoom() > 0) { |
---|
1306 | this.map.setCenter(this.map.getLonLatFromPixel(evt.xy), |
---|
1307 | this.map.getZoom() - 1); |
---|
1308 | } |
---|
1309 | }, |
---|
1310 | |
---|
1311 | /** |
---|
1312 | * Method: zoomBoxEnd |
---|
1313 | * Zoombox function. |
---|
1314 | */ |
---|
1315 | zoomBoxEnd: function(evt) { |
---|
1316 | if (this.mouseDragStart != null) { |
---|
1317 | if (Math.abs(this.mouseDragStart.x - evt.xy.x) > 5 || |
---|
1318 | Math.abs(this.mouseDragStart.y - evt.xy.y) > 5) { |
---|
1319 | var start = this.map.getLonLatFromViewPortPx( this.mouseDragStart ); |
---|
1320 | var end = this.map.getLonLatFromViewPortPx( evt.xy ); |
---|
1321 | var top = Math.max(start.lat, end.lat); |
---|
1322 | var bottom = Math.min(start.lat, end.lat); |
---|
1323 | var left = Math.min(start.lon, end.lon); |
---|
1324 | var right = Math.max(start.lon, end.lon); |
---|
1325 | var bounds = new OpenLayers.Bounds(left, bottom, right, top); |
---|
1326 | this.map.zoomToExtent(bounds); |
---|
1327 | } else { |
---|
1328 | var end = this.map.getLonLatFromViewPortPx( evt.xy ); |
---|
1329 | this.map.setCenter(new OpenLayers.LonLat( |
---|
1330 | (end.lon), |
---|
1331 | (end.lat) |
---|
1332 | ), this.map.getZoom() + 1); |
---|
1333 | } |
---|
1334 | this.removeZoomBox(); |
---|
1335 | } |
---|
1336 | }, |
---|
1337 | |
---|
1338 | /** |
---|
1339 | * Method: removeZoomBox |
---|
1340 | * Remove the zoombox from the screen and nullify our reference to it. |
---|
1341 | */ |
---|
1342 | removeZoomBox: function() { |
---|
1343 | this.map.viewPortDiv.removeChild(this.zoomBox); |
---|
1344 | this.zoomBox = null; |
---|
1345 | }, |
---|
1346 | |
---|
1347 | |
---|
1348 | /** |
---|
1349 | * Mouse ScrollWheel code thanks to http://adomas.org/javascript-mouse-wheel/ |
---|
1350 | */ |
---|
1351 | |
---|
1352 | |
---|
1353 | /** |
---|
1354 | * Method: onWheelEvent |
---|
1355 | * Catch the wheel event and handle it xbrowserly |
---|
1356 | * |
---|
1357 | * Parameters: |
---|
1358 | * e - {Event} |
---|
1359 | */ |
---|
1360 | onWheelEvent: function(e){ |
---|
1361 | |
---|
1362 | // first determine whether or not the wheeling was inside the map |
---|
1363 | var inMap = false; |
---|
1364 | var elem = OpenLayers.Event.element(e); |
---|
1365 | while(elem != null) { |
---|
1366 | if (this.map && elem == this.map.div) { |
---|
1367 | inMap = true; |
---|
1368 | break; |
---|
1369 | } |
---|
1370 | elem = elem.parentNode; |
---|
1371 | } |
---|
1372 | |
---|
1373 | if (inMap) { |
---|
1374 | |
---|
1375 | var delta = 0; |
---|
1376 | if (!e) { |
---|
1377 | e = window.event; |
---|
1378 | } |
---|
1379 | if (e.wheelDelta) { |
---|
1380 | delta = e.wheelDelta/120; |
---|
1381 | if (window.opera && window.opera.version() < 9.2) { |
---|
1382 | delta = -delta; |
---|
1383 | } |
---|
1384 | } else if (e.detail) { |
---|
1385 | delta = -e.detail / 3; |
---|
1386 | } |
---|
1387 | if (delta) { |
---|
1388 | // add the mouse position to the event because mozilla has a bug |
---|
1389 | // with clientX and clientY (see https://bugzilla.mozilla.org/show_bug.cgi?id=352179) |
---|
1390 | // getLonLatFromViewPortPx(e) returns wrong values |
---|
1391 | e.xy = this.mousePosition; |
---|
1392 | |
---|
1393 | if (delta < 0) { |
---|
1394 | this.defaultWheelDown(e); |
---|
1395 | } else { |
---|
1396 | this.defaultWheelUp(e); |
---|
1397 | } |
---|
1398 | } |
---|
1399 | |
---|
1400 | //only wheel the map, not the window |
---|
1401 | OpenLayers.Event.stop(e); |
---|
1402 | } |
---|
1403 | }, |
---|
1404 | |
---|
1405 | CLASS_NAME: "OpenLayers.Control.MouseDefaults" |
---|
1406 | }); |
---|
1407 | |
---|
1408 | /** |
---|
1409 | * Class: OpenLayers.Control.MouseToolbar |
---|
1410 | * This class is DEPRECATED in 2.4 and will be removed by 3.0. |
---|
1411 | * If you need this functionality, use <OpenLayers.Control.NavToolbar> |
---|
1412 | * instead!!! |
---|
1413 | */ |
---|
1414 | OpenLayers.Control.MouseToolbar = OpenLayers.Class( |
---|
1415 | OpenLayers.Control.MouseDefaults, { |
---|
1416 | |
---|
1417 | /** |
---|
1418 | * Property: mode |
---|
1419 | */ |
---|
1420 | mode: null, |
---|
1421 | /** |
---|
1422 | * Property: buttons |
---|
1423 | */ |
---|
1424 | buttons: null, |
---|
1425 | |
---|
1426 | /** |
---|
1427 | * APIProperty: direction |
---|
1428 | * {String} 'vertical' or 'horizontal' |
---|
1429 | */ |
---|
1430 | direction: "vertical", |
---|
1431 | |
---|
1432 | /** |
---|
1433 | * Property: buttonClicked |
---|
1434 | * {String} |
---|
1435 | */ |
---|
1436 | buttonClicked: null, |
---|
1437 | |
---|
1438 | /** |
---|
1439 | * Constructor: OpenLayers.Control.MouseToolbar |
---|
1440 | * |
---|
1441 | * Parameters: |
---|
1442 | * position - {<OpenLayers.Pixel>} |
---|
1443 | * direction - {String} |
---|
1444 | */ |
---|
1445 | initialize: function(position, direction) { |
---|
1446 | OpenLayers.Control.prototype.initialize.apply(this, arguments); |
---|
1447 | this.position = new OpenLayers.Pixel(OpenLayers.Control.MouseToolbar.X, |
---|
1448 | OpenLayers.Control.MouseToolbar.Y); |
---|
1449 | if (position) { |
---|
1450 | this.position = position; |
---|
1451 | } |
---|
1452 | if (direction) { |
---|
1453 | this.direction = direction; |
---|
1454 | } |
---|
1455 | this.measureDivs = []; |
---|
1456 | }, |
---|
1457 | |
---|
1458 | /** |
---|
1459 | * APIMethod: destroy |
---|
1460 | */ |
---|
1461 | destroy: function() { |
---|
1462 | for( var btnId in this.buttons) { |
---|
1463 | var btn = this.buttons[btnId]; |
---|
1464 | btn.map = null; |
---|
1465 | btn.events.destroy(); |
---|
1466 | } |
---|
1467 | OpenLayers.Control.MouseDefaults.prototype.destroy.apply(this, |
---|
1468 | arguments); |
---|
1469 | }, |
---|
1470 | |
---|
1471 | /** |
---|
1472 | * Method: draw |
---|
1473 | */ |
---|
1474 | draw: function() { |
---|
1475 | OpenLayers.Control.prototype.draw.apply(this, arguments); |
---|
1476 | OpenLayers.Control.MouseDefaults.prototype.draw.apply(this, arguments); |
---|
1477 | this.buttons = {}; |
---|
1478 | var sz = new OpenLayers.Size(28,28); |
---|
1479 | var centered = new OpenLayers.Pixel(OpenLayers.Control.MouseToolbar.X,0); |
---|
1480 | this._addButton("zoombox", "drag-rectangle-off.png", "drag-rectangle-on.png", centered, sz, "Shift->Drag to zoom to area"); |
---|
1481 | centered = centered.add((this.direction == "vertical" ? 0 : sz.w), (this.direction == "vertical" ? sz.h : 0)); |
---|
1482 | this._addButton("pan", "panning-hand-off.png", "panning-hand-on.png", centered, sz, "Drag the map to pan."); |
---|
1483 | centered = centered.add((this.direction == "vertical" ? 0 : sz.w), (this.direction == "vertical" ? sz.h : 0)); |
---|
1484 | this.switchModeTo("pan"); |
---|
1485 | |
---|
1486 | return this.div; |
---|
1487 | }, |
---|
1488 | |
---|
1489 | /** |
---|
1490 | * Method: _addButton |
---|
1491 | */ |
---|
1492 | _addButton:function(id, img, activeImg, xy, sz, title) { |
---|
1493 | var imgLocation = OpenLayers.Util.getImageLocation(img); |
---|
1494 | var activeImgLocation = OpenLayers.Util.getImageLocation(activeImg); |
---|
1495 | // var btn = new ol.AlphaImage("_"+id, imgLocation, xy, sz); |
---|
1496 | var btn = OpenLayers.Util.createAlphaImageDiv( |
---|
1497 | "OpenLayers_Control_MouseToolbar_" + id, |
---|
1498 | xy, sz, imgLocation, "absolute"); |
---|
1499 | |
---|
1500 | //we want to add the outer div |
---|
1501 | this.div.appendChild(btn); |
---|
1502 | btn.imgLocation = imgLocation; |
---|
1503 | btn.activeImgLocation = activeImgLocation; |
---|
1504 | |
---|
1505 | btn.events = new OpenLayers.Events(this, btn, null, true); |
---|
1506 | btn.events.on({ |
---|
1507 | "mousedown": this.buttonDown, |
---|
1508 | "mouseup": this.buttonUp, |
---|
1509 | "dblclick": OpenLayers.Event.stop, |
---|
1510 | scope: this |
---|
1511 | }); |
---|
1512 | btn.action = id; |
---|
1513 | btn.title = title; |
---|
1514 | btn.alt = title; |
---|
1515 | btn.map = this.map; |
---|
1516 | |
---|
1517 | //we want to remember/reference the outer div |
---|
1518 | this.buttons[id] = btn; |
---|
1519 | return btn; |
---|
1520 | }, |
---|
1521 | |
---|
1522 | /** |
---|
1523 | * Method: buttonDown |
---|
1524 | * |
---|
1525 | * Parameters: |
---|
1526 | * evt - {Event} |
---|
1527 | */ |
---|
1528 | buttonDown: function(evt) { |
---|
1529 | if (!OpenLayers.Event.isLeftClick(evt)) { |
---|
1530 | return; |
---|
1531 | } |
---|
1532 | this.buttonClicked = evt.element.action; |
---|
1533 | OpenLayers.Event.stop(evt); |
---|
1534 | }, |
---|
1535 | |
---|
1536 | /** |
---|
1537 | * Method: buttonUp |
---|
1538 | * |
---|
1539 | * Parameters: |
---|
1540 | * evt - {Event} |
---|
1541 | */ |
---|
1542 | buttonUp: function(evt) { |
---|
1543 | if (!OpenLayers.Event.isLeftClick(evt)) { |
---|
1544 | return; |
---|
1545 | } |
---|
1546 | if (this.buttonClicked != null) { |
---|
1547 | if (this.buttonClicked == evt.element.action) { |
---|
1548 | this.switchModeTo(evt.element.action); |
---|
1549 | } |
---|
1550 | OpenLayers.Event.stop(evt); |
---|
1551 | this.buttonClicked = null; |
---|
1552 | } |
---|
1553 | }, |
---|
1554 | |
---|
1555 | /** |
---|
1556 | * Method: defaultDblClick |
---|
1557 | * |
---|
1558 | * Parameters: |
---|
1559 | * evt - {Event} |
---|
1560 | */ |
---|
1561 | defaultDblClick: function (evt) { |
---|
1562 | this.switchModeTo("pan"); |
---|
1563 | this.performedDrag = false; |
---|
1564 | var newCenter = this.map.getLonLatFromViewPortPx( evt.xy ); |
---|
1565 | this.map.setCenter(newCenter, this.map.zoom + 1); |
---|
1566 | OpenLayers.Event.stop(evt); |
---|
1567 | return false; |
---|
1568 | }, |
---|
1569 | |
---|
1570 | /** |
---|
1571 | * Method: defaultMouseDown |
---|
1572 | * |
---|
1573 | * Parameters: |
---|
1574 | * evt - {Event} |
---|
1575 | */ |
---|
1576 | defaultMouseDown: function (evt) { |
---|
1577 | if (!OpenLayers.Event.isLeftClick(evt)) { |
---|
1578 | return; |
---|
1579 | } |
---|
1580 | this.mouseDragStart = evt.xy.clone(); |
---|
1581 | this.performedDrag = false; |
---|
1582 | this.startViaKeyboard = false; |
---|
1583 | if (evt.shiftKey && this.mode !="zoombox") { |
---|
1584 | this.switchModeTo("zoombox"); |
---|
1585 | this.startViaKeyboard = true; |
---|
1586 | } else if (evt.altKey && this.mode !="measure") { |
---|
1587 | this.switchModeTo("measure"); |
---|
1588 | } else if (!this.mode) { |
---|
1589 | this.switchModeTo("pan"); |
---|
1590 | } |
---|
1591 | |
---|
1592 | switch (this.mode) { |
---|
1593 | case "zoombox": |
---|
1594 | this.map.div.style.cursor = "crosshair"; |
---|
1595 | this.zoomBox = OpenLayers.Util.createDiv('zoomBox', |
---|
1596 | this.mouseDragStart, |
---|
1597 | null, |
---|
1598 | null, |
---|
1599 | "absolute", |
---|
1600 | "2px solid red"); |
---|
1601 | this.zoomBox.style.backgroundColor = "white"; |
---|
1602 | this.zoomBox.style.filter = "alpha(opacity=50)"; // IE |
---|
1603 | this.zoomBox.style.opacity = "0.50"; |
---|
1604 | this.zoomBox.style.fontSize = "1px"; |
---|
1605 | this.zoomBox.style.zIndex = this.map.Z_INDEX_BASE["Popup"] - 1; |
---|
1606 | this.map.viewPortDiv.appendChild(this.zoomBox); |
---|
1607 | this.performedDrag = true; |
---|
1608 | break; |
---|
1609 | case "measure": |
---|
1610 | var distance = ""; |
---|
1611 | if (this.measureStart) { |
---|
1612 | var measureEnd = this.map.getLonLatFromViewPortPx(this.mouseDragStart); |
---|
1613 | distance = OpenLayers.Util.distVincenty(this.measureStart, measureEnd); |
---|
1614 | distance = Math.round(distance * 100) / 100; |
---|
1615 | distance = distance + "km"; |
---|
1616 | this.measureStartBox = this.measureBox; |
---|
1617 | } |
---|
1618 | this.measureStart = this.map.getLonLatFromViewPortPx(this.mouseDragStart);; |
---|
1619 | this.measureBox = OpenLayers.Util.createDiv(null, |
---|
1620 | this.mouseDragStart.add( |
---|
1621 | -2-parseInt(this.map.layerContainerDiv.style.left), |
---|
1622 | -2-parseInt(this.map.layerContainerDiv.style.top)), |
---|
1623 | null, |
---|
1624 | null, |
---|
1625 | "absolute"); |
---|
1626 | this.measureBox.style.width="4px"; |
---|
1627 | this.measureBox.style.height="4px"; |
---|
1628 | this.measureBox.style.fontSize = "1px"; |
---|
1629 | this.measureBox.style.backgroundColor="red"; |
---|
1630 | this.measureBox.style.zIndex = this.map.Z_INDEX_BASE["Popup"] - 1; |
---|
1631 | this.map.layerContainerDiv.appendChild(this.measureBox); |
---|
1632 | if (distance) { |
---|
1633 | this.measureBoxDistance = OpenLayers.Util.createDiv(null, |
---|
1634 | this.mouseDragStart.add( |
---|
1635 | -2-parseInt(this.map.layerContainerDiv.style.left), |
---|
1636 | 2-parseInt(this.map.layerContainerDiv.style.top)), |
---|
1637 | null, |
---|
1638 | null, |
---|
1639 | "absolute"); |
---|
1640 | |
---|
1641 | this.measureBoxDistance.innerHTML = distance; |
---|
1642 | this.measureBoxDistance.style.zIndex = this.map.Z_INDEX_BASE["Popup"] - 1; |
---|
1643 | this.map.layerContainerDiv.appendChild(this.measureBoxDistance); |
---|
1644 | this.measureDivs.push(this.measureBoxDistance); |
---|
1645 | } |
---|
1646 | this.measureBox.style.zIndex = this.map.Z_INDEX_BASE["Popup"] - 1; |
---|
1647 | this.map.layerContainerDiv.appendChild(this.measureBox); |
---|
1648 | this.measureDivs.push(this.measureBox); |
---|
1649 | break; |
---|
1650 | default: |
---|
1651 | this.map.div.style.cursor = "move"; |
---|
1652 | break; |
---|
1653 | } |
---|
1654 | document.onselectstart = OpenLayers.Function.False; |
---|
1655 | OpenLayers.Event.stop(evt); |
---|
1656 | }, |
---|
1657 | |
---|
1658 | /** |
---|
1659 | * Method: switchModeTo |
---|
1660 | * |
---|
1661 | * Parameters: |
---|
1662 | * mode - {String} |
---|
1663 | */ |
---|
1664 | switchModeTo: function(mode) { |
---|
1665 | if (mode != this.mode) { |
---|
1666 | |
---|
1667 | |
---|
1668 | if (this.mode && this.buttons[this.mode]) { |
---|
1669 | OpenLayers.Util.modifyAlphaImageDiv(this.buttons[this.mode], null, null, null, this.buttons[this.mode].imgLocation); |
---|
1670 | } |
---|
1671 | if (this.mode == "measure" && mode != "measure") { |
---|
1672 | for(var i=0, len=this.measureDivs.length; i<len; i++) { |
---|
1673 | if (this.measureDivs[i]) { |
---|
1674 | this.map.layerContainerDiv.removeChild(this.measureDivs[i]); |
---|
1675 | } |
---|
1676 | } |
---|
1677 | this.measureDivs = []; |
---|
1678 | this.measureStart = null; |
---|
1679 | } |
---|
1680 | this.mode = mode; |
---|
1681 | if (this.buttons[mode]) { |
---|
1682 | OpenLayers.Util.modifyAlphaImageDiv(this.buttons[mode], null, null, null, this.buttons[mode].activeImgLocation); |
---|
1683 | } |
---|
1684 | switch (this.mode) { |
---|
1685 | case "zoombox": |
---|
1686 | this.map.div.style.cursor = "crosshair"; |
---|
1687 | break; |
---|
1688 | default: |
---|
1689 | this.map.div.style.cursor = ""; |
---|
1690 | break; |
---|
1691 | } |
---|
1692 | |
---|
1693 | } |
---|
1694 | }, |
---|
1695 | |
---|
1696 | /** |
---|
1697 | * Method: leaveMode |
---|
1698 | */ |
---|
1699 | leaveMode: function() { |
---|
1700 | this.switchModeTo("pan"); |
---|
1701 | }, |
---|
1702 | |
---|
1703 | /** |
---|
1704 | * Method: defaultMouseMove |
---|
1705 | * |
---|
1706 | * Parameters: |
---|
1707 | * evt - {Event} |
---|
1708 | */ |
---|
1709 | defaultMouseMove: function (evt) { |
---|
1710 | if (this.mouseDragStart != null) { |
---|
1711 | switch (this.mode) { |
---|
1712 | case "zoombox": |
---|
1713 | var deltaX = Math.abs(this.mouseDragStart.x - evt.xy.x); |
---|
1714 | var deltaY = Math.abs(this.mouseDragStart.y - evt.xy.y); |
---|
1715 | this.zoomBox.style.width = Math.max(1, deltaX) + "px"; |
---|
1716 | this.zoomBox.style.height = Math.max(1, deltaY) + "px"; |
---|
1717 | if (evt.xy.x < this.mouseDragStart.x) { |
---|
1718 | this.zoomBox.style.left = evt.xy.x+"px"; |
---|
1719 | } |
---|
1720 | if (evt.xy.y < this.mouseDragStart.y) { |
---|
1721 | this.zoomBox.style.top = evt.xy.y+"px"; |
---|
1722 | } |
---|
1723 | break; |
---|
1724 | default: |
---|
1725 | var deltaX = this.mouseDragStart.x - evt.xy.x; |
---|
1726 | var deltaY = this.mouseDragStart.y - evt.xy.y; |
---|
1727 | var size = this.map.getSize(); |
---|
1728 | var newXY = new OpenLayers.Pixel(size.w / 2 + deltaX, |
---|
1729 | size.h / 2 + deltaY); |
---|
1730 | var newCenter = this.map.getLonLatFromViewPortPx( newXY ); |
---|
1731 | this.map.setCenter(newCenter, null, true); |
---|
1732 | this.mouseDragStart = evt.xy.clone(); |
---|
1733 | } |
---|
1734 | this.performedDrag = true; |
---|
1735 | } |
---|
1736 | }, |
---|
1737 | |
---|
1738 | /** |
---|
1739 | * Method: defaultMouseUp |
---|
1740 | * |
---|
1741 | * Parameters: |
---|
1742 | * evt - {Event} |
---|
1743 | */ |
---|
1744 | defaultMouseUp: function (evt) { |
---|
1745 | if (!OpenLayers.Event.isLeftClick(evt)) { |
---|
1746 | return; |
---|
1747 | } |
---|
1748 | switch (this.mode) { |
---|
1749 | case "zoombox": |
---|
1750 | this.zoomBoxEnd(evt); |
---|
1751 | if (this.startViaKeyboard) { |
---|
1752 | this.leaveMode(); |
---|
1753 | } |
---|
1754 | break; |
---|
1755 | case "pan": |
---|
1756 | if (this.performedDrag) { |
---|
1757 | this.map.setCenter(this.map.center); |
---|
1758 | } |
---|
1759 | } |
---|
1760 | document.onselectstart = null; |
---|
1761 | this.mouseDragStart = null; |
---|
1762 | this.map.div.style.cursor = "default"; |
---|
1763 | }, |
---|
1764 | |
---|
1765 | /** |
---|
1766 | * Method: defaultMouseOut |
---|
1767 | * |
---|
1768 | * Parameters: |
---|
1769 | * evt - {Event} |
---|
1770 | */ |
---|
1771 | defaultMouseOut: function (evt) { |
---|
1772 | if (this.mouseDragStart != null |
---|
1773 | && OpenLayers.Util.mouseLeft(evt, this.map.viewPortDiv)) { |
---|
1774 | if (this.zoomBox) { |
---|
1775 | this.removeZoomBox(); |
---|
1776 | if (this.startViaKeyboard) { |
---|
1777 | this.leaveMode(); |
---|
1778 | } |
---|
1779 | } |
---|
1780 | this.mouseDragStart = null; |
---|
1781 | this.map.div.style.cursor = "default"; |
---|
1782 | } |
---|
1783 | }, |
---|
1784 | |
---|
1785 | /** |
---|
1786 | * Method: defaultClick |
---|
1787 | * |
---|
1788 | * Parameters: |
---|
1789 | * evt - {Event} |
---|
1790 | */ |
---|
1791 | defaultClick: function (evt) { |
---|
1792 | if (this.performedDrag) { |
---|
1793 | this.performedDrag = false; |
---|
1794 | return false; |
---|
1795 | } |
---|
1796 | }, |
---|
1797 | |
---|
1798 | CLASS_NAME: "OpenLayers.Control.MouseToolbar" |
---|
1799 | }); |
---|
1800 | |
---|
1801 | OpenLayers.Control.MouseToolbar.X = 6; |
---|
1802 | OpenLayers.Control.MouseToolbar.Y = 300; |
---|
1803 | |
---|
1804 | /** |
---|
1805 | * Class: OpenLayers.Layer.Grid |
---|
1806 | */ |
---|
1807 | |
---|
1808 | OpenLayers.Util.extend(OpenLayers.Layer.Grid.prototype, { |
---|
1809 | |
---|
1810 | /** |
---|
1811 | * Method: getGridBounds |
---|
1812 | * Deprecated. This function will be removed in 3.0. Please use |
---|
1813 | * getTilesBounds() instead. |
---|
1814 | * |
---|
1815 | * Returns: |
---|
1816 | * {<OpenLayers.Bounds>} A Bounds object representing the bounds of all the |
---|
1817 | * currently loaded tiles (including those partially or not at all seen |
---|
1818 | * onscreen) |
---|
1819 | */ |
---|
1820 | getGridBounds: function() { |
---|
1821 | var msg = "The getGridBounds() function is deprecated. It will be " + |
---|
1822 | "removed in 3.0. Please use getTilesBounds() instead."; |
---|
1823 | OpenLayers.Console.warn(msg); |
---|
1824 | return this.getTilesBounds(); |
---|
1825 | } |
---|
1826 | }); |
---|
1827 | |
---|
1828 | /** |
---|
1829 | * Class: OpenLayers.Format.XML |
---|
1830 | */ |
---|
1831 | OpenLayers.Util.extend(OpenLayers.Format.XML.prototype, { |
---|
1832 | |
---|
1833 | /** |
---|
1834 | * APIMethod: concatChildValues |
---|
1835 | * *Deprecated*. Use <getChildValue> instead. |
---|
1836 | * |
---|
1837 | * Concatenate the value of all child nodes if any exist, or return an |
---|
1838 | * optional default string. Returns an empty string if no children |
---|
1839 | * exist and no default value is supplied. Not optimized for large |
---|
1840 | * numbers of child nodes. |
---|
1841 | * |
---|
1842 | * Parameters: |
---|
1843 | * node - {DOMElement} The element used to look for child values. |
---|
1844 | * def - {String} Optional string to return in the event that no |
---|
1845 | * child exist. |
---|
1846 | * |
---|
1847 | * Returns: |
---|
1848 | * {String} The concatenated value of all child nodes of the given node. |
---|
1849 | */ |
---|
1850 | concatChildValues: function(node, def) { |
---|
1851 | var value = ""; |
---|
1852 | var child = node.firstChild; |
---|
1853 | var childValue; |
---|
1854 | while(child) { |
---|
1855 | childValue = child.nodeValue; |
---|
1856 | if(childValue) { |
---|
1857 | value += childValue; |
---|
1858 | } |
---|
1859 | child = child.nextSibling; |
---|
1860 | } |
---|
1861 | if(value == "" && def != undefined) { |
---|
1862 | value = def; |
---|
1863 | } |
---|
1864 | return value; |
---|
1865 | } |
---|
1866 | |
---|
1867 | }); |
---|
1868 | |
---|
1869 | /** |
---|
1870 | * Class: OpenLayers.Layer.WMS.Post |
---|
1871 | * Instances of OpenLayers.Layer.WMS.Post are used to retrieve data from OGC |
---|
1872 | * Web Mapping Services via HTTP-POST (application/x-www-form-urlencoded). |
---|
1873 | * Create a new WMS layer with the <OpenLayers.Layer.WMS.Post> constructor. |
---|
1874 | * |
---|
1875 | * *Deprecated*. Instead of this layer, use <OpenLayers.Layer.WMS> with |
---|
1876 | * <OpenLayers.Tile.Image.maxGetUrlLength> configured in the layer's |
---|
1877 | * <OpenLayers.Layer.WMS.tileOptions>. |
---|
1878 | * |
---|
1879 | * Inherits from: |
---|
1880 | * - <OpenLayers.Layer.WMS> |
---|
1881 | */ |
---|
1882 | OpenLayers.Layer.WMS.Post = OpenLayers.Class(OpenLayers.Layer.WMS, { |
---|
1883 | |
---|
1884 | /** |
---|
1885 | * APIProperty: unsupportedBrowsers |
---|
1886 | * {Array} Array with browsers, which should use the HTTP-GET protocol |
---|
1887 | * instead of HTTP-POST for fetching tiles from a WMS . |
---|
1888 | * Defaults to ["mozilla", "firefox", "opera"], because Opera is not able |
---|
1889 | * to show transparent images in IFrames and Firefox/Mozilla has some ugly |
---|
1890 | * effects of viewport-shaking when panning the map. Both browsers, Opera |
---|
1891 | * and Firefox/Mozilla, have no problem with long urls, which is the reason |
---|
1892 | * for using POST instead of GET. The strings to pass to this array are |
---|
1893 | * the ones returned by <OpenLayers.BROWSER_NAME>. |
---|
1894 | */ |
---|
1895 | unsupportedBrowsers: ["mozilla", "firefox", "opera"], |
---|
1896 | |
---|
1897 | /** |
---|
1898 | * Property: SUPPORTED_TRANSITIONS |
---|
1899 | * {Array} |
---|
1900 | * no supported transitions for this type of layer, because it is not |
---|
1901 | * possible to modify the initialized tiles (iframes) |
---|
1902 | */ |
---|
1903 | SUPPORTED_TRANSITIONS: [], |
---|
1904 | |
---|
1905 | /** |
---|
1906 | * Property: usePost |
---|
1907 | * {Boolean} |
---|
1908 | */ |
---|
1909 | usePost: null, |
---|
1910 | |
---|
1911 | /** |
---|
1912 | * Constructor: OpenLayers.Layer.WMS.Post |
---|
1913 | * Creates a new WMS layer object. |
---|
1914 | * |
---|
1915 | * Example: |
---|
1916 | * (code) |
---|
1917 | * var wms = new OpenLayers.Layer.WMS.Post( |
---|
1918 | * "NASA Global Mosaic", |
---|
1919 | * "http://wms.jpl.nasa.gov/wms.cgi", |
---|
1920 | * {layers: "modis, global_mosaic"}); |
---|
1921 | * (end) |
---|
1922 | * |
---|
1923 | * Parameters: |
---|
1924 | * name - {String} A name for the layer |
---|
1925 | * url - {String} Base url for the WMS |
---|
1926 | * (e.g. http://wms.jpl.nasa.gov/wms.cgi) |
---|
1927 | * params - {Object} An object with key/value pairs representing the |
---|
1928 | * GetMap query string parameters and parameter values. |
---|
1929 | * options - {Object} Hashtable of extra options to tag onto the layer. |
---|
1930 | */ |
---|
1931 | initialize: function(name, url, params, options) { |
---|
1932 | var newArguments = []; |
---|
1933 | newArguments.push(name, url, params, options); |
---|
1934 | OpenLayers.Layer.WMS.prototype.initialize.apply(this, newArguments); |
---|
1935 | |
---|
1936 | this.usePost = OpenLayers.Util.indexOf( |
---|
1937 | this.unsupportedBrowsers, OpenLayers.BROWSER_NAME) == -1; |
---|
1938 | }, |
---|
1939 | |
---|
1940 | /** |
---|
1941 | * Method: addTile |
---|
1942 | * addTile creates a tile, initializes it and adds it as iframe to the |
---|
1943 | * layer div. |
---|
1944 | * |
---|
1945 | * Parameters: |
---|
1946 | * bounds - {<OpenLayers.Bounds>} |
---|
1947 | * position - {<OpenLayers.Pixel>} |
---|
1948 | * |
---|
1949 | * Returns: |
---|
1950 | * {<OpenLayers.Tile.Image.IFrame>} The added OpenLayers.Tile.Image.IFrame |
---|
1951 | */ |
---|
1952 | addTile: function(bounds,position) { |
---|
1953 | return new OpenLayers.Tile.Image( |
---|
1954 | this, position, bounds, null, this.tileSize, { |
---|
1955 | maxGetUrlLength: this.usePost ? 0 : null |
---|
1956 | }); |
---|
1957 | }, |
---|
1958 | |
---|
1959 | CLASS_NAME: 'OpenLayers.Layer.WMS.Post' |
---|
1960 | }); |
---|
1961 | |
---|
1962 | /** |
---|
1963 | * Class: OpenLayers.Layer.WMS.Untiled |
---|
1964 | * *Deprecated*. To be removed in 3.0. Instead use OpenLayers.Layer.WMS and |
---|
1965 | * pass the option 'singleTile' as true. |
---|
1966 | * |
---|
1967 | * Inherits from: |
---|
1968 | * - <OpenLayers.Layer.WMS> |
---|
1969 | */ |
---|
1970 | OpenLayers.Layer.WMS.Untiled = OpenLayers.Class(OpenLayers.Layer.WMS, { |
---|
1971 | |
---|
1972 | /** |
---|
1973 | * APIProperty: singleTile |
---|
1974 | * {singleTile} Always true for untiled. |
---|
1975 | */ |
---|
1976 | singleTile: true, |
---|
1977 | |
---|
1978 | /** |
---|
1979 | * Constructor: OpenLayers.Layer.WMS.Untiled |
---|
1980 | * |
---|
1981 | * Parameters: |
---|
1982 | * name - {String} |
---|
1983 | * url - {String} |
---|
1984 | * params - {Object} |
---|
1985 | * options - {Object} |
---|
1986 | */ |
---|
1987 | initialize: function(name, url, params, options) { |
---|
1988 | OpenLayers.Layer.WMS.prototype.initialize.apply(this, arguments); |
---|
1989 | |
---|
1990 | var msg = "The OpenLayers.Layer.WMS.Untiled class is deprecated and " + |
---|
1991 | "will be removed in 3.0. Instead, you should use the " + |
---|
1992 | "normal OpenLayers.Layer.WMS class, passing it the option " + |
---|
1993 | "'singleTile' as true."; |
---|
1994 | OpenLayers.Console.warn(msg); |
---|
1995 | }, |
---|
1996 | |
---|
1997 | /** |
---|
1998 | * Method: clone |
---|
1999 | * Create a clone of this layer |
---|
2000 | * |
---|
2001 | * Returns: |
---|
2002 | * {<OpenLayers.Layer.WMS.Untiled>} An exact clone of this layer |
---|
2003 | */ |
---|
2004 | clone: function (obj) { |
---|
2005 | |
---|
2006 | if (obj == null) { |
---|
2007 | obj = new OpenLayers.Layer.WMS.Untiled(this.name, |
---|
2008 | this.url, |
---|
2009 | this.params, |
---|
2010 | this.getOptions()); |
---|
2011 | } |
---|
2012 | |
---|
2013 | //get all additions from superclasses |
---|
2014 | obj = OpenLayers.Layer.WMS.prototype.clone.apply(this, [obj]); |
---|
2015 | |
---|
2016 | // copy/set any non-init, non-simple values here |
---|
2017 | |
---|
2018 | return obj; |
---|
2019 | }, |
---|
2020 | |
---|
2021 | CLASS_NAME: "OpenLayers.Layer.WMS.Untiled" |
---|
2022 | }); |
---|
2023 | |
---|
2024 | /** |
---|
2025 | * Class: OpenLayers.Layer.MapServer.Untiled |
---|
2026 | * *Deprecated*. To be removed in 3.0. Instead use OpenLayers.Layer.MapServer |
---|
2027 | * and pass the option 'singleTile' as true. |
---|
2028 | * |
---|
2029 | * Inherits from: |
---|
2030 | * - <OpenLayers.Layer.MapServer> |
---|
2031 | */ |
---|
2032 | OpenLayers.Layer.MapServer.Untiled = OpenLayers.Class(OpenLayers.Layer.MapServer, { |
---|
2033 | |
---|
2034 | /** |
---|
2035 | * APIProperty: singleTile |
---|
2036 | * {singleTile} Always true for untiled. |
---|
2037 | */ |
---|
2038 | singleTile: true, |
---|
2039 | |
---|
2040 | /** |
---|
2041 | * Constructor: OpenLayers.Layer.MapServer.Untiled |
---|
2042 | * |
---|
2043 | * Parameters: |
---|
2044 | * name - {String} |
---|
2045 | * url - {String} |
---|
2046 | * params - {Object} |
---|
2047 | * options - {Object} |
---|
2048 | */ |
---|
2049 | initialize: function(name, url, params, options) { |
---|
2050 | OpenLayers.Layer.MapServer.prototype.initialize.apply(this, arguments); |
---|
2051 | |
---|
2052 | var msg = "The OpenLayers.Layer.MapServer.Untiled class is deprecated and " + |
---|
2053 | "will be removed in 3.0. Instead, you should use the " + |
---|
2054 | "normal OpenLayers.Layer.MapServer class, passing it the option " + |
---|
2055 | "'singleTile' as true."; |
---|
2056 | OpenLayers.Console.warn(msg); |
---|
2057 | }, |
---|
2058 | |
---|
2059 | /** |
---|
2060 | * Method: clone |
---|
2061 | * Create a clone of this layer |
---|
2062 | * |
---|
2063 | * Returns: |
---|
2064 | * {<OpenLayers.Layer.MapServer.Untiled>} An exact clone of this layer |
---|
2065 | */ |
---|
2066 | clone: function (obj) { |
---|
2067 | |
---|
2068 | if (obj == null) { |
---|
2069 | obj = new OpenLayers.Layer.MapServer.Untiled(this.name, |
---|
2070 | this.url, |
---|
2071 | this.params, |
---|
2072 | this.getOptions()); |
---|
2073 | } |
---|
2074 | |
---|
2075 | //get all additions from superclasses |
---|
2076 | obj = OpenLayers.Layer.MapServer.prototype.clone.apply(this, [obj]); |
---|
2077 | |
---|
2078 | // copy/set any non-init, non-simple values here |
---|
2079 | |
---|
2080 | return obj; |
---|
2081 | }, |
---|
2082 | |
---|
2083 | CLASS_NAME: "OpenLayers.Layer.MapServer.Untiled" |
---|
2084 | }); |
---|
2085 | |
---|
2086 | /** |
---|
2087 | * Class: OpenLayers.Tile.WFS |
---|
2088 | * Instances of OpenLayers.Tile.WFS are used to manage the image tiles |
---|
2089 | * used by various layers. Create a new image tile with the |
---|
2090 | * <OpenLayers.Tile.WFS> constructor. |
---|
2091 | * |
---|
2092 | * Inherits from: |
---|
2093 | * - <OpenLayers.Tile> |
---|
2094 | */ |
---|
2095 | OpenLayers.Tile.WFS = OpenLayers.Class(OpenLayers.Tile, { |
---|
2096 | |
---|
2097 | /** |
---|
2098 | * Property: features |
---|
2099 | * {Array(<OpenLayers.Feature>)} list of features in this tile |
---|
2100 | */ |
---|
2101 | features: null, |
---|
2102 | |
---|
2103 | /** |
---|
2104 | * Property: url |
---|
2105 | * {String} |
---|
2106 | */ |
---|
2107 | url: null, |
---|
2108 | |
---|
2109 | /** |
---|
2110 | * Property: request |
---|
2111 | * {<OpenLayers.Request.XMLHttpRequest>} |
---|
2112 | */ |
---|
2113 | request: null, |
---|
2114 | |
---|
2115 | /** TBD 3.0 - reorder the parameters to the init function to put URL |
---|
2116 | * as last, so we can continue to call tile.initialize() |
---|
2117 | * without changing the arguments. |
---|
2118 | * |
---|
2119 | * Constructor: OpenLayers.Tile.WFS |
---|
2120 | * Constructor for a new <OpenLayers.Tile.WFS> instance. |
---|
2121 | * |
---|
2122 | * Parameters: |
---|
2123 | * layer - {<OpenLayers.Layer>} layer that the tile will go in. |
---|
2124 | * position - {<OpenLayers.Pixel>} |
---|
2125 | * bounds - {<OpenLayers.Bounds>} |
---|
2126 | * url - {<String>} |
---|
2127 | * size - {<OpenLayers.Size>} |
---|
2128 | */ |
---|
2129 | initialize: function(layer, position, bounds, url, size) { |
---|
2130 | OpenLayers.Tile.prototype.initialize.apply(this, arguments); |
---|
2131 | this.url = url; |
---|
2132 | this.features = []; |
---|
2133 | }, |
---|
2134 | |
---|
2135 | /** |
---|
2136 | * APIMethod: destroy |
---|
2137 | * nullify references to prevent circular references and memory leaks |
---|
2138 | */ |
---|
2139 | destroy: function() { |
---|
2140 | OpenLayers.Tile.prototype.destroy.apply(this, arguments); |
---|
2141 | this.destroyAllFeatures(); |
---|
2142 | this.features = null; |
---|
2143 | this.url = null; |
---|
2144 | if(this.request) { |
---|
2145 | this.request.abort(); |
---|
2146 | //this.request.destroy(); |
---|
2147 | this.request = null; |
---|
2148 | } |
---|
2149 | }, |
---|
2150 | |
---|
2151 | /** |
---|
2152 | * Method: clear |
---|
2153 | * Clear the tile of any bounds/position-related data so that it can |
---|
2154 | * be reused in a new location. |
---|
2155 | */ |
---|
2156 | clear: function() { |
---|
2157 | this.destroyAllFeatures(); |
---|
2158 | }, |
---|
2159 | |
---|
2160 | /** |
---|
2161 | * Method: draw |
---|
2162 | * Check that a tile should be drawn, and load features for it. |
---|
2163 | */ |
---|
2164 | draw:function() { |
---|
2165 | if (OpenLayers.Tile.prototype.draw.apply(this, arguments)) { |
---|
2166 | if (this.isLoading) { |
---|
2167 | //if already loading, send 'reload' instead of 'loadstart'. |
---|
2168 | this.events.triggerEvent("reload"); |
---|
2169 | } else { |
---|
2170 | this.isLoading = true; |
---|
2171 | this.events.triggerEvent("loadstart"); |
---|
2172 | } |
---|
2173 | this.loadFeaturesForRegion(this.requestSuccess); |
---|
2174 | } |
---|
2175 | }, |
---|
2176 | |
---|
2177 | /** |
---|
2178 | * Method: loadFeaturesForRegion |
---|
2179 | * Abort any pending requests and issue another request for data. |
---|
2180 | * |
---|
2181 | * Input are function pointers for what to do on success and failure. |
---|
2182 | * |
---|
2183 | * Parameters: |
---|
2184 | * success - {function} |
---|
2185 | * failure - {function} |
---|
2186 | */ |
---|
2187 | loadFeaturesForRegion:function(success, failure) { |
---|
2188 | if(this.request) { |
---|
2189 | this.request.abort(); |
---|
2190 | } |
---|
2191 | this.request = OpenLayers.Request.GET({ |
---|
2192 | url: this.url, |
---|
2193 | success: success, |
---|
2194 | failure: failure, |
---|
2195 | scope: this |
---|
2196 | }); |
---|
2197 | }, |
---|
2198 | |
---|
2199 | /** |
---|
2200 | * Method: requestSuccess |
---|
2201 | * Called on return from request succcess. Adds results via |
---|
2202 | * layer.addFeatures in vector mode, addResults otherwise. |
---|
2203 | * |
---|
2204 | * Parameters: |
---|
2205 | * request - {<OpenLayers.Request.XMLHttpRequest>} |
---|
2206 | */ |
---|
2207 | requestSuccess:function(request) { |
---|
2208 | if (this.features) { |
---|
2209 | var doc = request.responseXML; |
---|
2210 | if (!doc || !doc.documentElement) { |
---|
2211 | doc = request.responseText; |
---|
2212 | } |
---|
2213 | if (this.layer.vectorMode) { |
---|
2214 | this.layer.addFeatures(this.layer.formatObject.read(doc)); |
---|
2215 | } else { |
---|
2216 | var xml = new OpenLayers.Format.XML(); |
---|
2217 | if (typeof doc == "string") { |
---|
2218 | doc = xml.read(doc); |
---|
2219 | } |
---|
2220 | var resultFeatures = xml.getElementsByTagNameNS( |
---|
2221 | doc, "http://www.opengis.net/gml", "featureMember" |
---|
2222 | ); |
---|
2223 | this.addResults(resultFeatures); |
---|
2224 | } |
---|
2225 | } |
---|
2226 | if (this.events) { |
---|
2227 | this.events.triggerEvent("loadend"); |
---|
2228 | } |
---|
2229 | |
---|
2230 | //request produced with success, we can delete the request object. |
---|
2231 | //this.request.destroy(); |
---|
2232 | this.request = null; |
---|
2233 | }, |
---|
2234 | |
---|
2235 | /** |
---|
2236 | * Method: addResults |
---|
2237 | * Construct new feature via layer featureClass constructor, and add to |
---|
2238 | * this.features. |
---|
2239 | * |
---|
2240 | * Parameters: |
---|
2241 | * results - {Object} |
---|
2242 | */ |
---|
2243 | addResults: function(results) { |
---|
2244 | for (var i=0; i < results.length; i++) { |
---|
2245 | var feature = new this.layer.featureClass(this.layer, |
---|
2246 | results[i]); |
---|
2247 | this.features.push(feature); |
---|
2248 | } |
---|
2249 | }, |
---|
2250 | |
---|
2251 | |
---|
2252 | /** |
---|
2253 | * Method: destroyAllFeatures |
---|
2254 | * Iterate through and call destroy() on each feature, removing it from |
---|
2255 | * the local array |
---|
2256 | */ |
---|
2257 | destroyAllFeatures: function() { |
---|
2258 | while(this.features.length > 0) { |
---|
2259 | var feature = this.features.shift(); |
---|
2260 | feature.destroy(); |
---|
2261 | } |
---|
2262 | }, |
---|
2263 | |
---|
2264 | CLASS_NAME: "OpenLayers.Tile.WFS" |
---|
2265 | } |
---|
2266 | ); |
---|
2267 | |
---|
2268 | /** |
---|
2269 | * Class: OpenLayers.Feature.WFS |
---|
2270 | * WFS handling class, for use as a featureClass on the WFS layer for handling |
---|
2271 | * 'point' WFS types. Good for subclassing when creating a custom WFS like |
---|
2272 | * XML application. |
---|
2273 | * |
---|
2274 | * Inherits from: |
---|
2275 | * - <OpenLayers.Feature> |
---|
2276 | */ |
---|
2277 | OpenLayers.Feature.WFS = OpenLayers.Class(OpenLayers.Feature, { |
---|
2278 | |
---|
2279 | /** |
---|
2280 | * Constructor: OpenLayers.Feature.WFS |
---|
2281 | * Create a WFS feature. |
---|
2282 | * |
---|
2283 | * Parameters: |
---|
2284 | * layer - {<OpenLayers.Layer>} |
---|
2285 | * xmlNode - {XMLNode} |
---|
2286 | */ |
---|
2287 | initialize: function(layer, xmlNode) { |
---|
2288 | var newArguments = arguments; |
---|
2289 | var data = this.processXMLNode(xmlNode); |
---|
2290 | newArguments = new Array(layer, data.lonlat, data); |
---|
2291 | OpenLayers.Feature.prototype.initialize.apply(this, newArguments); |
---|
2292 | this.createMarker(); |
---|
2293 | this.layer.addMarker(this.marker); |
---|
2294 | }, |
---|
2295 | |
---|
2296 | /** |
---|
2297 | * Method: destroy |
---|
2298 | * nullify references to prevent circular references and memory leaks |
---|
2299 | */ |
---|
2300 | destroy: function() { |
---|
2301 | if (this.marker != null) { |
---|
2302 | this.layer.removeMarker(this.marker); |
---|
2303 | } |
---|
2304 | OpenLayers.Feature.prototype.destroy.apply(this, arguments); |
---|
2305 | }, |
---|
2306 | |
---|
2307 | /** |
---|
2308 | * Method: processXMLNode |
---|
2309 | * When passed an xmlNode, parses it for a GML point, and passes |
---|
2310 | * back an object describing that point. |
---|
2311 | * |
---|
2312 | * For subclasses of Feature.WFS, this is the feature to change. |
---|
2313 | * |
---|
2314 | * Parameters: |
---|
2315 | * xmlNode - {XMLNode} |
---|
2316 | * |
---|
2317 | * Returns: |
---|
2318 | * {Object} Data Object with 'id', 'lonlat', and private properties set |
---|
2319 | */ |
---|
2320 | processXMLNode: function(xmlNode) { |
---|
2321 | //this should be overridden by subclasses |
---|
2322 | // must return an Object with 'id' and 'lonlat' values set |
---|
2323 | var point = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode, "http://www.opengis.net/gml", "gml", "Point"); |
---|
2324 | var text = OpenLayers.Util.getXmlNodeValue(OpenLayers.Ajax.getElementsByTagNameNS(point[0], "http://www.opengis.net/gml","gml", "coordinates")[0]); |
---|
2325 | var floats = text.split(","); |
---|
2326 | return {lonlat: new OpenLayers.LonLat(parseFloat(floats[0]), |
---|
2327 | parseFloat(floats[1])), |
---|
2328 | id: null}; |
---|
2329 | |
---|
2330 | }, |
---|
2331 | |
---|
2332 | CLASS_NAME: "OpenLayers.Feature.WFS" |
---|
2333 | }); |
---|
2334 | |
---|
2335 | |
---|
2336 | /** |
---|
2337 | * Class: OpenLayers.Layer.WFS |
---|
2338 | * *Deprecated*. To be removed in 3.0. Instead use OpenLayers.Layer.Vector |
---|
2339 | * with a Protocol.WFS and one or more Strategies. |
---|
2340 | * |
---|
2341 | * Inherits from: |
---|
2342 | * - <OpenLayers.Layer.Vector> |
---|
2343 | * - <OpenLayers.Layer.Markers> |
---|
2344 | */ |
---|
2345 | OpenLayers.Layer.WFS = OpenLayers.Class( |
---|
2346 | OpenLayers.Layer.Vector, OpenLayers.Layer.Markers, { |
---|
2347 | |
---|
2348 | /** |
---|
2349 | * APIProperty: isBaseLayer |
---|
2350 | * {Boolean} WFS layer is not a base layer by default. |
---|
2351 | */ |
---|
2352 | isBaseLayer: false, |
---|
2353 | |
---|
2354 | /** |
---|
2355 | * Property: tile |
---|
2356 | * {<OpenLayers.Tile.WFS>} |
---|
2357 | */ |
---|
2358 | tile: null, |
---|
2359 | |
---|
2360 | /** |
---|
2361 | * APIProperty: ratio |
---|
2362 | * {Float} The ratio property determines the size of the serverside query |
---|
2363 | * relative to the map viewport size. By default, we load an area twice |
---|
2364 | * as big as the map, to allow for panning without immediately reload. |
---|
2365 | * Setting this to 1 will cause the area of the WFS request to match |
---|
2366 | * the map area exactly. It is recommended to set this to some number |
---|
2367 | * at least slightly larger than 1, otherwise accidental clicks can |
---|
2368 | * cause a data reload, by moving the map only 1 pixel. |
---|
2369 | */ |
---|
2370 | ratio: 2, |
---|
2371 | |
---|
2372 | /** |
---|
2373 | * Property: DEFAULT_PARAMS |
---|
2374 | * {Object} Hashtable of default key/value parameters |
---|
2375 | */ |
---|
2376 | DEFAULT_PARAMS: { service: "WFS", |
---|
2377 | version: "1.0.0", |
---|
2378 | request: "GetFeature" |
---|
2379 | }, |
---|
2380 | |
---|
2381 | /** |
---|
2382 | * APIProperty: featureClass |
---|
2383 | * {<OpenLayers.Feature>} If featureClass is defined, an old-style markers |
---|
2384 | * based WFS layer is created instead of a new-style vector layer. If |
---|
2385 | * sent, this should be a subclass of OpenLayers.Feature |
---|
2386 | */ |
---|
2387 | featureClass: null, |
---|
2388 | |
---|
2389 | /** |
---|
2390 | * APIProperty: format |
---|
2391 | * {<OpenLayers.Format>} The format you want the data to be parsed with. |
---|
2392 | * Must be passed in the constructor. Should be a class, not an instance. |
---|
2393 | * This option can only be used if no featureClass is passed / vectorMode |
---|
2394 | * is false: if a featureClass is passed, then this parameter is ignored. |
---|
2395 | */ |
---|
2396 | format: null, |
---|
2397 | |
---|
2398 | /** |
---|
2399 | * Property: formatObject |
---|
2400 | * {<OpenLayers.Format>} Internally created/managed format object, used by |
---|
2401 | * the Tile to parse data. |
---|
2402 | */ |
---|
2403 | formatObject: null, |
---|
2404 | |
---|
2405 | /** |
---|
2406 | * APIProperty: formatOptions |
---|
2407 | * {Object} Hash of options which should be passed to the format when it is |
---|
2408 | * created. Must be passed in the constructor. |
---|
2409 | */ |
---|
2410 | formatOptions: null, |
---|
2411 | |
---|
2412 | /** |
---|
2413 | * Property: vectorMode |
---|
2414 | * {Boolean} Should be calculated automatically. Determines whether the |
---|
2415 | * layer is in vector mode or marker mode. |
---|
2416 | */ |
---|
2417 | vectorMode: true, |
---|
2418 | |
---|
2419 | /** |
---|
2420 | * APIProperty: encodeBBOX |
---|
2421 | * {Boolean} Should the BBOX commas be encoded? The WMS spec says 'no', |
---|
2422 | * but some services want it that way. Default false. |
---|
2423 | */ |
---|
2424 | encodeBBOX: false, |
---|
2425 | |
---|
2426 | /** |
---|
2427 | * APIProperty: extractAttributes |
---|
2428 | * {Boolean} Should the WFS layer parse attributes from the retrieved |
---|
2429 | * GML? Defaults to false. If enabled, parsing is slower, but |
---|
2430 | * attributes are available in the attributes property of |
---|
2431 | * layer features. |
---|
2432 | */ |
---|
2433 | extractAttributes: false, |
---|
2434 | |
---|
2435 | /** |
---|
2436 | * Constructor: OpenLayers.Layer.WFS |
---|
2437 | * |
---|
2438 | * Parameters: |
---|
2439 | * name - {String} |
---|
2440 | * url - {String} |
---|
2441 | * params - {Object} |
---|
2442 | * options - {Object} Hashtable of extra options to tag onto the layer |
---|
2443 | */ |
---|
2444 | initialize: function(name, url, params, options) { |
---|
2445 | if (options == undefined) { options = {}; } |
---|
2446 | |
---|
2447 | if (options.featureClass || |
---|
2448 | !OpenLayers.Layer.Vector || |
---|
2449 | !OpenLayers.Feature.Vector) { |
---|
2450 | this.vectorMode = false; |
---|
2451 | } |
---|
2452 | |
---|
2453 | // Uppercase params |
---|
2454 | params = OpenLayers.Util.upperCaseObject(params); |
---|
2455 | |
---|
2456 | // Turn off error reporting, browsers like Safari may work |
---|
2457 | // depending on the setup, and we don't want an unneccesary alert. |
---|
2458 | OpenLayers.Util.extend(options, {'reportError': false}); |
---|
2459 | var newArguments = []; |
---|
2460 | newArguments.push(name, options); |
---|
2461 | OpenLayers.Layer.Vector.prototype.initialize.apply(this, newArguments); |
---|
2462 | if (!this.renderer || !this.vectorMode) { |
---|
2463 | this.vectorMode = false; |
---|
2464 | if (!options.featureClass) { |
---|
2465 | options.featureClass = OpenLayers.Feature.WFS; |
---|
2466 | } |
---|
2467 | OpenLayers.Layer.Markers.prototype.initialize.apply(this, |
---|
2468 | newArguments); |
---|
2469 | } |
---|
2470 | |
---|
2471 | if (this.params && this.params.typename && !this.options.typename) { |
---|
2472 | this.options.typename = this.params.typename; |
---|
2473 | } |
---|
2474 | |
---|
2475 | if (!this.options.geometry_column) { |
---|
2476 | this.options.geometry_column = "the_geom"; |
---|
2477 | } |
---|
2478 | |
---|
2479 | this.params = OpenLayers.Util.applyDefaults( |
---|
2480 | params, |
---|
2481 | OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS) |
---|
2482 | ); |
---|
2483 | this.url = url; |
---|
2484 | }, |
---|
2485 | |
---|
2486 | |
---|
2487 | /** |
---|
2488 | * APIMethod: destroy |
---|
2489 | */ |
---|
2490 | destroy: function() { |
---|
2491 | if (this.vectorMode) { |
---|
2492 | OpenLayers.Layer.Vector.prototype.destroy.apply(this, arguments); |
---|
2493 | } else { |
---|
2494 | OpenLayers.Layer.Markers.prototype.destroy.apply(this, arguments); |
---|
2495 | } |
---|
2496 | if (this.tile) { |
---|
2497 | this.tile.destroy(); |
---|
2498 | } |
---|
2499 | this.tile = null; |
---|
2500 | |
---|
2501 | this.ratio = null; |
---|
2502 | this.featureClass = null; |
---|
2503 | this.format = null; |
---|
2504 | |
---|
2505 | if (this.formatObject && this.formatObject.destroy) { |
---|
2506 | this.formatObject.destroy(); |
---|
2507 | } |
---|
2508 | this.formatObject = null; |
---|
2509 | |
---|
2510 | this.formatOptions = null; |
---|
2511 | this.vectorMode = null; |
---|
2512 | this.encodeBBOX = null; |
---|
2513 | this.extractAttributes = null; |
---|
2514 | }, |
---|
2515 | |
---|
2516 | /** |
---|
2517 | * Method: setMap |
---|
2518 | * |
---|
2519 | * Parameters: |
---|
2520 | * map - {<OpenLayers.Map>} |
---|
2521 | */ |
---|
2522 | setMap: function(map) { |
---|
2523 | if (this.vectorMode) { |
---|
2524 | OpenLayers.Layer.Vector.prototype.setMap.apply(this, arguments); |
---|
2525 | |
---|
2526 | var options = { |
---|
2527 | 'extractAttributes': this.extractAttributes |
---|
2528 | }; |
---|
2529 | |
---|
2530 | OpenLayers.Util.extend(options, this.formatOptions); |
---|
2531 | if (this.map && !this.projection.equals(this.map.getProjectionObject())) { |
---|
2532 | options.externalProjection = this.projection; |
---|
2533 | options.internalProjection = this.map.getProjectionObject(); |
---|
2534 | } |
---|
2535 | |
---|
2536 | this.formatObject = this.format ? new this.format(options) : new OpenLayers.Format.GML(options); |
---|
2537 | } else { |
---|
2538 | OpenLayers.Layer.Markers.prototype.setMap.apply(this, arguments); |
---|
2539 | } |
---|
2540 | }, |
---|
2541 | |
---|
2542 | /** |
---|
2543 | * Method: moveTo |
---|
2544 | * |
---|
2545 | * Parameters: |
---|
2546 | * bounds - {<OpenLayers.Bounds>} |
---|
2547 | * zoomChanged - {Boolean} |
---|
2548 | * dragging - {Boolean} |
---|
2549 | */ |
---|
2550 | moveTo:function(bounds, zoomChanged, dragging) { |
---|
2551 | if (this.vectorMode) { |
---|
2552 | OpenLayers.Layer.Vector.prototype.moveTo.apply(this, arguments); |
---|
2553 | } else { |
---|
2554 | OpenLayers.Layer.Markers.prototype.moveTo.apply(this, arguments); |
---|
2555 | } |
---|
2556 | |
---|
2557 | // don't load wfs features while dragging, wait for drag end |
---|
2558 | if (dragging) { |
---|
2559 | // TBD try to hide the vector layer while dragging |
---|
2560 | // this.setVisibility(false); |
---|
2561 | // this will probably help for panning performances |
---|
2562 | return false; |
---|
2563 | } |
---|
2564 | |
---|
2565 | if ( zoomChanged ) { |
---|
2566 | if (this.vectorMode) { |
---|
2567 | this.renderer.clear(); |
---|
2568 | } |
---|
2569 | } |
---|
2570 | |
---|
2571 | //DEPRECATED - REMOVE IN 3.0 |
---|
2572 | // don't load data if current zoom level doesn't match |
---|
2573 | if (this.options.minZoomLevel) { |
---|
2574 | OpenLayers.Console.warn(OpenLayers.i18n('minZoomLevelError')); |
---|
2575 | |
---|
2576 | if (this.map.getZoom() < this.options.minZoomLevel) { |
---|
2577 | return null; |
---|
2578 | } |
---|
2579 | } |
---|
2580 | |
---|
2581 | if (bounds == null) { |
---|
2582 | bounds = this.map.getExtent(); |
---|
2583 | } |
---|
2584 | |
---|
2585 | var firstRendering = (this.tile == null); |
---|
2586 | |
---|
2587 | //does the new bounds to which we need to move fall outside of the |
---|
2588 | // current tile's bounds? |
---|
2589 | var outOfBounds = (!firstRendering && |
---|
2590 | !this.tile.bounds.containsBounds(bounds)); |
---|
2591 | |
---|
2592 | if (zoomChanged || firstRendering || (!dragging && outOfBounds)) { |
---|
2593 | //determine new tile bounds |
---|
2594 | var center = bounds.getCenterLonLat(); |
---|
2595 | var tileWidth = bounds.getWidth() * this.ratio; |
---|
2596 | var tileHeight = bounds.getHeight() * this.ratio; |
---|
2597 | var tileBounds = |
---|
2598 | new OpenLayers.Bounds(center.lon - (tileWidth / 2), |
---|
2599 | center.lat - (tileHeight / 2), |
---|
2600 | center.lon + (tileWidth / 2), |
---|
2601 | center.lat + (tileHeight / 2)); |
---|
2602 | |
---|
2603 | //determine new tile size |
---|
2604 | var tileSize = this.map.getSize(); |
---|
2605 | tileSize.w = tileSize.w * this.ratio; |
---|
2606 | tileSize.h = tileSize.h * this.ratio; |
---|
2607 | |
---|
2608 | //determine new position (upper left corner of new bounds) |
---|
2609 | var ul = new OpenLayers.LonLat(tileBounds.left, tileBounds.top); |
---|
2610 | var pos = this.map.getLayerPxFromLonLat(ul); |
---|
2611 | |
---|
2612 | //formulate request url string |
---|
2613 | var url = this.getFullRequestString(); |
---|
2614 | |
---|
2615 | var params = null; |
---|
2616 | |
---|
2617 | // Cant combine "filter" and "BBOX". This is a cheap hack to help |
---|
2618 | // people out who can't migrate to the WFS protocol immediately. |
---|
2619 | var filter = this.params.filter || this.params.FILTER; |
---|
2620 | if (filter) { |
---|
2621 | params = {FILTER: filter}; |
---|
2622 | } |
---|
2623 | else { |
---|
2624 | params = {BBOX: this.encodeBBOX ? tileBounds.toBBOX() |
---|
2625 | : tileBounds.toArray()}; |
---|
2626 | } |
---|
2627 | |
---|
2628 | if (this.map && !this.projection.equals(this.map.getProjectionObject())) { |
---|
2629 | var projectedBounds = tileBounds.clone(); |
---|
2630 | projectedBounds.transform(this.map.getProjectionObject(), |
---|
2631 | this.projection); |
---|
2632 | if (!filter){ |
---|
2633 | params.BBOX = this.encodeBBOX ? projectedBounds.toBBOX() |
---|
2634 | : projectedBounds.toArray(); |
---|
2635 | } |
---|
2636 | } |
---|
2637 | |
---|
2638 | url += "&" + OpenLayers.Util.getParameterString(params); |
---|
2639 | |
---|
2640 | if (!this.tile) { |
---|
2641 | this.tile = new OpenLayers.Tile.WFS(this, pos, tileBounds, |
---|
2642 | url, tileSize); |
---|
2643 | this.addTileMonitoringHooks(this.tile); |
---|
2644 | this.tile.draw(); |
---|
2645 | } else { |
---|
2646 | if (this.vectorMode) { |
---|
2647 | this.destroyFeatures(); |
---|
2648 | this.renderer.clear(); |
---|
2649 | } else { |
---|
2650 | this.clearMarkers(); |
---|
2651 | } |
---|
2652 | this.removeTileMonitoringHooks(this.tile); |
---|
2653 | this.tile.destroy(); |
---|
2654 | |
---|
2655 | this.tile = null; |
---|
2656 | this.tile = new OpenLayers.Tile.WFS(this, pos, tileBounds, |
---|
2657 | url, tileSize); |
---|
2658 | this.addTileMonitoringHooks(this.tile); |
---|
2659 | this.tile.draw(); |
---|
2660 | } |
---|
2661 | } |
---|
2662 | }, |
---|
2663 | |
---|
2664 | /** |
---|
2665 | * Method: addTileMonitoringHooks |
---|
2666 | * This function takes a tile as input and adds the appropriate hooks to |
---|
2667 | * the tile so that the layer can keep track of the loading tile |
---|
2668 | * (making sure to check that the tile is always the layer's current |
---|
2669 | * tile before taking any action). |
---|
2670 | * |
---|
2671 | * Parameters: |
---|
2672 | * tile - {<OpenLayers.Tile>} |
---|
2673 | */ |
---|
2674 | addTileMonitoringHooks: function(tile) { |
---|
2675 | tile.onLoadStart = function() { |
---|
2676 | //if this is the the layer's current tile, then trigger |
---|
2677 | // a 'loadstart' |
---|
2678 | if (this == this.layer.tile) { |
---|
2679 | this.layer.events.triggerEvent("loadstart"); |
---|
2680 | } |
---|
2681 | }; |
---|
2682 | tile.events.register("loadstart", tile, tile.onLoadStart); |
---|
2683 | |
---|
2684 | tile.onLoadEnd = function() { |
---|
2685 | //if this is the the layer's current tile, then trigger |
---|
2686 | // a 'tileloaded' and 'loadend' |
---|
2687 | if (this == this.layer.tile) { |
---|
2688 | this.layer.events.triggerEvent("tileloaded"); |
---|
2689 | this.layer.events.triggerEvent("loadend"); |
---|
2690 | } |
---|
2691 | }; |
---|
2692 | tile.events.register("loadend", tile, tile.onLoadEnd); |
---|
2693 | tile.events.register("unload", tile, tile.onLoadEnd); |
---|
2694 | }, |
---|
2695 | |
---|
2696 | /** |
---|
2697 | * Method: removeTileMonitoringHooks |
---|
2698 | * This function takes a tile as input and removes the tile hooks |
---|
2699 | * that were added in addTileMonitoringHooks() |
---|
2700 | * |
---|
2701 | * Parameters: |
---|
2702 | * tile - {<OpenLayers.Tile>} |
---|
2703 | */ |
---|
2704 | removeTileMonitoringHooks: function(tile) { |
---|
2705 | tile.unload(); |
---|
2706 | tile.events.un({ |
---|
2707 | "loadstart": tile.onLoadStart, |
---|
2708 | "loadend": tile.onLoadEnd, |
---|
2709 | "unload": tile.onLoadEnd, |
---|
2710 | scope: tile |
---|
2711 | }); |
---|
2712 | }, |
---|
2713 | |
---|
2714 | /** |
---|
2715 | * Method: onMapResize |
---|
2716 | * Call the onMapResize method of the appropriate parent class. |
---|
2717 | */ |
---|
2718 | onMapResize: function() { |
---|
2719 | if(this.vectorMode) { |
---|
2720 | OpenLayers.Layer.Vector.prototype.onMapResize.apply(this, |
---|
2721 | arguments); |
---|
2722 | } else { |
---|
2723 | OpenLayers.Layer.Markers.prototype.onMapResize.apply(this, |
---|
2724 | arguments); |
---|
2725 | } |
---|
2726 | }, |
---|
2727 | |
---|
2728 | /** |
---|
2729 | * Method: display |
---|
2730 | * Call the display method of the appropriate parent class. |
---|
2731 | */ |
---|
2732 | display: function() { |
---|
2733 | if(this.vectorMode) { |
---|
2734 | OpenLayers.Layer.Vector.prototype.display.apply(this, |
---|
2735 | arguments); |
---|
2736 | } else { |
---|
2737 | OpenLayers.Layer.Markers.prototype.display.apply(this, |
---|
2738 | arguments); |
---|
2739 | } |
---|
2740 | }, |
---|
2741 | |
---|
2742 | /** |
---|
2743 | * APIMethod: mergeNewParams |
---|
2744 | * Modify parameters for the layer and redraw. |
---|
2745 | * |
---|
2746 | * Parameters: |
---|
2747 | * newParams - {Object} |
---|
2748 | */ |
---|
2749 | mergeNewParams:function(newParams) { |
---|
2750 | var upperParams = OpenLayers.Util.upperCaseObject(newParams); |
---|
2751 | var newArguments = [upperParams]; |
---|
2752 | return OpenLayers.Layer.HTTPRequest.prototype.mergeNewParams.apply(this, |
---|
2753 | newArguments); |
---|
2754 | }, |
---|
2755 | |
---|
2756 | /** |
---|
2757 | * APIMethod: clone |
---|
2758 | * |
---|
2759 | * Parameters: |
---|
2760 | * obj - {Object} |
---|
2761 | * |
---|
2762 | * Returns: |
---|
2763 | * {<OpenLayers.Layer.WFS>} An exact clone of this OpenLayers.Layer.WFS |
---|
2764 | */ |
---|
2765 | clone: function (obj) { |
---|
2766 | |
---|
2767 | if (obj == null) { |
---|
2768 | obj = new OpenLayers.Layer.WFS(this.name, |
---|
2769 | this.url, |
---|
2770 | this.params, |
---|
2771 | this.getOptions()); |
---|
2772 | } |
---|
2773 | |
---|
2774 | //get all additions from superclasses |
---|
2775 | if (this.vectorMode) { |
---|
2776 | obj = OpenLayers.Layer.Vector.prototype.clone.apply(this, [obj]); |
---|
2777 | } else { |
---|
2778 | obj = OpenLayers.Layer.Markers.prototype.clone.apply(this, [obj]); |
---|
2779 | } |
---|
2780 | |
---|
2781 | // copy/set any non-init, non-simple values here |
---|
2782 | |
---|
2783 | return obj; |
---|
2784 | }, |
---|
2785 | |
---|
2786 | /** |
---|
2787 | * APIMethod: getFullRequestString |
---|
2788 | * combine the layer's url with its params and these newParams. |
---|
2789 | * |
---|
2790 | * Add the SRS parameter from 'projection' -- this is probably |
---|
2791 | * more eloquently done via a setProjection() method, but this |
---|
2792 | * works for now and always. |
---|
2793 | * |
---|
2794 | * Parameters: |
---|
2795 | * newParams - {Object} |
---|
2796 | * altUrl - {String} Use this as the url instead of the layer's url |
---|
2797 | */ |
---|
2798 | getFullRequestString:function(newParams, altUrl) { |
---|
2799 | var projectionCode = this.projection.getCode() || this.map.getProjection(); |
---|
2800 | this.params.SRS = (projectionCode == "none") ? null : projectionCode; |
---|
2801 | |
---|
2802 | return OpenLayers.Layer.Grid.prototype.getFullRequestString.apply( |
---|
2803 | this, arguments); |
---|
2804 | }, |
---|
2805 | |
---|
2806 | /** |
---|
2807 | * APIMethod: commit |
---|
2808 | * Write out the data to a WFS server. |
---|
2809 | */ |
---|
2810 | commit: function() { |
---|
2811 | if (!this.writer) { |
---|
2812 | var options = {}; |
---|
2813 | if (this.map && !this.projection.equals(this.map.getProjectionObject())) { |
---|
2814 | options.externalProjection = this.projection; |
---|
2815 | options.internalProjection = this.map.getProjectionObject(); |
---|
2816 | } |
---|
2817 | |
---|
2818 | this.writer = new OpenLayers.Format.WFS(options,this); |
---|
2819 | } |
---|
2820 | |
---|
2821 | var data = this.writer.write(this.features); |
---|
2822 | |
---|
2823 | OpenLayers.Request.POST({ |
---|
2824 | url: this.url, |
---|
2825 | data: data, |
---|
2826 | success: this.commitSuccess, |
---|
2827 | failure: this.commitFailure, |
---|
2828 | scope: this |
---|
2829 | }); |
---|
2830 | }, |
---|
2831 | |
---|
2832 | /** |
---|
2833 | * Method: commitSuccess |
---|
2834 | * Called when the Ajax request returns a response |
---|
2835 | * |
---|
2836 | * Parameters: |
---|
2837 | * response - {XmlNode} from server |
---|
2838 | */ |
---|
2839 | commitSuccess: function(request) { |
---|
2840 | var response = request.responseText; |
---|
2841 | if (response.indexOf('SUCCESS') != -1) { |
---|
2842 | this.commitReport(OpenLayers.i18n("commitSuccess", {'response':response})); |
---|
2843 | |
---|
2844 | for(var i = 0; i < this.features.length; i++) { |
---|
2845 | this.features[i].state = null; |
---|
2846 | } |
---|
2847 | // TBD redraw the layer or reset the state of features |
---|
2848 | // foreach features: set state to null |
---|
2849 | } else if (response.indexOf('FAILED') != -1 || |
---|
2850 | response.indexOf('Exception') != -1) { |
---|
2851 | this.commitReport(OpenLayers.i18n("commitFailed", {'response':response})); |
---|
2852 | } |
---|
2853 | }, |
---|
2854 | |
---|
2855 | /** |
---|
2856 | * Method: commitFailure |
---|
2857 | * Called when the Ajax request fails |
---|
2858 | * |
---|
2859 | * Parameters: |
---|
2860 | * response - {XmlNode} from server |
---|
2861 | */ |
---|
2862 | commitFailure: function(request) {}, |
---|
2863 | |
---|
2864 | /** |
---|
2865 | * APIMethod: commitReport |
---|
2866 | * Called with a 'success' message if the commit succeeded, otherwise |
---|
2867 | * a failure message, and the full request text as a second parameter. |
---|
2868 | * Override this function to provide custom transaction reporting. |
---|
2869 | * |
---|
2870 | * string - {String} reporting string |
---|
2871 | * response - {String} full XML response |
---|
2872 | */ |
---|
2873 | commitReport: function(string, response) { |
---|
2874 | OpenLayers.Console.userError(string); |
---|
2875 | }, |
---|
2876 | |
---|
2877 | |
---|
2878 | /** |
---|
2879 | * APIMethod: refresh |
---|
2880 | * Refreshes all the features of the layer |
---|
2881 | */ |
---|
2882 | refresh: function() { |
---|
2883 | if (this.tile) { |
---|
2884 | if (this.vectorMode) { |
---|
2885 | this.renderer.clear(); |
---|
2886 | this.features.length = 0; |
---|
2887 | } else { |
---|
2888 | this.clearMarkers(); |
---|
2889 | this.markers.length = 0; |
---|
2890 | } |
---|
2891 | this.tile.draw(); |
---|
2892 | } |
---|
2893 | }, |
---|
2894 | |
---|
2895 | /** |
---|
2896 | * APIMethod: getDataExtent |
---|
2897 | * Calculates the max extent which includes all of the layer data. |
---|
2898 | * |
---|
2899 | * Returns: |
---|
2900 | * {<OpenLayers.Bounds>} |
---|
2901 | */ |
---|
2902 | getDataExtent: function () { |
---|
2903 | var extent; |
---|
2904 | //get all additions from superclasses |
---|
2905 | if (this.vectorMode) { |
---|
2906 | extent = OpenLayers.Layer.Vector.prototype.getDataExtent.apply(this); |
---|
2907 | } else { |
---|
2908 | extent = OpenLayers.Layer.Markers.prototype.getDataExtent.apply(this); |
---|
2909 | } |
---|
2910 | |
---|
2911 | return extent; |
---|
2912 | }, |
---|
2913 | |
---|
2914 | /** |
---|
2915 | * APIMethod: setOpacity |
---|
2916 | * Call the setOpacity method of the appropriate parent class to set the |
---|
2917 | * opacity. |
---|
2918 | * |
---|
2919 | * Parameters: |
---|
2920 | * opacity - {Float} |
---|
2921 | */ |
---|
2922 | setOpacity: function (opacity) { |
---|
2923 | if (this.vectorMode) { |
---|
2924 | OpenLayers.Layer.Vector.prototype.setOpacity.apply(this, [opacity]); |
---|
2925 | } else { |
---|
2926 | OpenLayers.Layer.Markers.prototype.setOpacity.apply(this, [opacity]); |
---|
2927 | } |
---|
2928 | }, |
---|
2929 | |
---|
2930 | CLASS_NAME: "OpenLayers.Layer.WFS" |
---|
2931 | }); |
---|
2932 | |
---|
2933 | /** |
---|
2934 | * Class: OpenLayers.Layer.VirtualEarth |
---|
2935 | * *Deprecated*. Use <OpenLayers.Layer.Bing> instead. |
---|
2936 | * |
---|
2937 | * Instances of OpenLayers.Layer.VirtualEarth are used to display the data from |
---|
2938 | * the Bing Maps AJAX Control (see e.g. |
---|
2939 | * http://msdn.microsoft.com/library/bb429619.aspx). Create a VirtualEarth |
---|
2940 | * layer with the <OpenLayers.Layer.VirtualEarth> constructor. |
---|
2941 | * |
---|
2942 | * Inherits from: |
---|
2943 | * - <OpenLayers.Layer.EventPane> |
---|
2944 | * - <OpenLayers.Layer.FixedZoomLevels> |
---|
2945 | */ |
---|
2946 | OpenLayers.Layer.VirtualEarth = OpenLayers.Class( |
---|
2947 | OpenLayers.Layer.EventPane, |
---|
2948 | OpenLayers.Layer.FixedZoomLevels, { |
---|
2949 | |
---|
2950 | /** |
---|
2951 | * Constant: MIN_ZOOM_LEVEL |
---|
2952 | * {Integer} 1 |
---|
2953 | */ |
---|
2954 | MIN_ZOOM_LEVEL: 1, |
---|
2955 | |
---|
2956 | /** |
---|
2957 | * Constant: MAX_ZOOM_LEVEL |
---|
2958 | * {Integer} 19 |
---|
2959 | */ |
---|
2960 | MAX_ZOOM_LEVEL: 19, |
---|
2961 | |
---|
2962 | /** |
---|
2963 | * Constant: RESOLUTIONS |
---|
2964 | * {Array(Float)} Hardcode these resolutions so that they are more closely |
---|
2965 | * tied with the standard wms projection |
---|
2966 | */ |
---|
2967 | RESOLUTIONS: [ |
---|
2968 | 1.40625, |
---|
2969 | 0.703125, |
---|
2970 | 0.3515625, |
---|
2971 | 0.17578125, |
---|
2972 | 0.087890625, |
---|
2973 | 0.0439453125, |
---|
2974 | 0.02197265625, |
---|
2975 | 0.010986328125, |
---|
2976 | 0.0054931640625, |
---|
2977 | 0.00274658203125, |
---|
2978 | 0.001373291015625, |
---|
2979 | 0.0006866455078125, |
---|
2980 | 0.00034332275390625, |
---|
2981 | 0.000171661376953125, |
---|
2982 | 0.0000858306884765625, |
---|
2983 | 0.00004291534423828125, |
---|
2984 | 0.00002145767211914062, |
---|
2985 | 0.00001072883605957031, |
---|
2986 | 0.00000536441802978515 |
---|
2987 | ], |
---|
2988 | |
---|
2989 | /** |
---|
2990 | * APIProperty: type |
---|
2991 | * {VEMapType} |
---|
2992 | */ |
---|
2993 | type: null, |
---|
2994 | |
---|
2995 | /** |
---|
2996 | * APIProperty: wrapDateLine |
---|
2997 | * {Boolean} Allow user to pan forever east/west. Default is true. |
---|
2998 | * Setting this to false only restricts panning if |
---|
2999 | * <sphericalMercator> is true. |
---|
3000 | */ |
---|
3001 | wrapDateLine: true, |
---|
3002 | |
---|
3003 | /** |
---|
3004 | * APIProperty: sphericalMercator |
---|
3005 | * {Boolean} Should the map act as a mercator-projected map? This will |
---|
3006 | * cause all interactions with the map to be in the actual map |
---|
3007 | * projection, which allows support for vector drawing, overlaying |
---|
3008 | * other maps, etc. |
---|
3009 | */ |
---|
3010 | sphericalMercator: false, |
---|
3011 | |
---|
3012 | /** |
---|
3013 | * APIProperty: animationEnabled |
---|
3014 | * {Boolean} If set to true, the transition between zoom levels will be |
---|
3015 | * animated. Set to false to match the zooming experience of other |
---|
3016 | * layer types. Default is true. |
---|
3017 | */ |
---|
3018 | animationEnabled: true, |
---|
3019 | |
---|
3020 | /** |
---|
3021 | * Constructor: OpenLayers.Layer.VirtualEarth |
---|
3022 | * Creates a new instance of a OpenLayers.Layer.VirtualEarth. If you use an |
---|
3023 | * instance of OpenLayers.Layer.VirtualEarth in you map, you should set |
---|
3024 | * the <OpenLayers.Map> option restrictedExtent to a meaningful value, |
---|
3025 | * e.g.: |
---|
3026 | * (code) |
---|
3027 | * var map = new OpenLayers.Map( 'map', { |
---|
3028 | * // other map options |
---|
3029 | * restrictedExtent : OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508) |
---|
3030 | * } ); |
---|
3031 | * |
---|
3032 | * var veLayer = new OpenLayers.Layer.VirtualEarth ( |
---|
3033 | * "Virtual Earth Layer" |
---|
3034 | * ); |
---|
3035 | * |
---|
3036 | * map.addLayer( veLayer ); |
---|
3037 | * (end) |
---|
3038 | * |
---|
3039 | * Parameters: |
---|
3040 | * name - {String} |
---|
3041 | * options - {Object} |
---|
3042 | */ |
---|
3043 | initialize: function(name, options) { |
---|
3044 | OpenLayers.Layer.EventPane.prototype.initialize.apply(this, arguments); |
---|
3045 | OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this, |
---|
3046 | arguments); |
---|
3047 | if(this.sphericalMercator) { |
---|
3048 | OpenLayers.Util.extend(this, OpenLayers.Layer.SphericalMercator); |
---|
3049 | this.initMercatorParameters(); |
---|
3050 | } |
---|
3051 | }, |
---|
3052 | |
---|
3053 | /** |
---|
3054 | * Method: loadMapObject |
---|
3055 | */ |
---|
3056 | loadMapObject:function() { |
---|
3057 | |
---|
3058 | // create div and set to same size as map |
---|
3059 | var veDiv = OpenLayers.Util.createDiv(this.name); |
---|
3060 | var sz = this.map.getSize(); |
---|
3061 | veDiv.style.width = sz.w + "px"; |
---|
3062 | veDiv.style.height = sz.h + "px"; |
---|
3063 | this.div.appendChild(veDiv); |
---|
3064 | |
---|
3065 | try { // crash prevention |
---|
3066 | this.mapObject = new VEMap(this.name); |
---|
3067 | } catch (e) { } |
---|
3068 | |
---|
3069 | if (this.mapObject != null) { |
---|
3070 | try { // this is to catch a Mozilla bug without falling apart |
---|
3071 | |
---|
3072 | // The fourth argument is whether the map is 'fixed' -- not |
---|
3073 | // draggable. See: |
---|
3074 | // http://blogs.msdn.com/virtualearth/archive/2007/09/28/locking-a-virtual-earth-map.aspx |
---|
3075 | // |
---|
3076 | this.mapObject.LoadMap(null, null, this.type, true); |
---|
3077 | this.mapObject.AttachEvent("onmousedown", OpenLayers.Function.True); |
---|
3078 | |
---|
3079 | } catch (e) { } |
---|
3080 | this.mapObject.HideDashboard(); |
---|
3081 | if(typeof this.mapObject.SetAnimationEnabled == "function") { |
---|
3082 | this.mapObject.SetAnimationEnabled(this.animationEnabled); |
---|
3083 | } |
---|
3084 | } |
---|
3085 | |
---|
3086 | //can we do smooth panning? this is an unpublished method, so we need |
---|
3087 | // to be careful |
---|
3088 | if ( !this.mapObject || |
---|
3089 | !this.mapObject.vemapcontrol || |
---|
3090 | !this.mapObject.vemapcontrol.PanMap || |
---|
3091 | (typeof this.mapObject.vemapcontrol.PanMap != "function")) { |
---|
3092 | |
---|
3093 | this.dragPanMapObject = null; |
---|
3094 | } |
---|
3095 | |
---|
3096 | }, |
---|
3097 | |
---|
3098 | /** |
---|
3099 | * Method: onMapResize |
---|
3100 | */ |
---|
3101 | onMapResize: function() { |
---|
3102 | this.mapObject.Resize(this.map.size.w, this.map.size.h); |
---|
3103 | }, |
---|
3104 | |
---|
3105 | /** |
---|
3106 | * APIMethod: getWarningHTML |
---|
3107 | * |
---|
3108 | * Returns: |
---|
3109 | * {String} String with information on why layer is broken, how to get |
---|
3110 | * it working. |
---|
3111 | */ |
---|
3112 | getWarningHTML:function() { |
---|
3113 | return OpenLayers.i18n( |
---|
3114 | "getLayerWarning", {'layerType':'VE', 'layerLib':'VirtualEarth'} |
---|
3115 | ); |
---|
3116 | }, |
---|
3117 | |
---|
3118 | |
---|
3119 | |
---|
3120 | /************************************ |
---|
3121 | * * |
---|
3122 | * MapObject Interface Controls * |
---|
3123 | * * |
---|
3124 | ************************************/ |
---|
3125 | |
---|
3126 | |
---|
3127 | // Get&Set Center, Zoom |
---|
3128 | |
---|
3129 | /** |
---|
3130 | * APIMethod: setMapObjectCenter |
---|
3131 | * Set the mapObject to the specified center and zoom |
---|
3132 | * |
---|
3133 | * Parameters: |
---|
3134 | * center - {Object} MapObject LonLat format |
---|
3135 | * zoom - {int} MapObject zoom format |
---|
3136 | */ |
---|
3137 | setMapObjectCenter: function(center, zoom) { |
---|
3138 | this.mapObject.SetCenterAndZoom(center, zoom); |
---|
3139 | }, |
---|
3140 | |
---|
3141 | /** |
---|
3142 | * APIMethod: getMapObjectCenter |
---|
3143 | * |
---|
3144 | * Returns: |
---|
3145 | * {Object} The mapObject's current center in Map Object format |
---|
3146 | */ |
---|
3147 | getMapObjectCenter: function() { |
---|
3148 | return this.mapObject.GetCenter(); |
---|
3149 | }, |
---|
3150 | |
---|
3151 | /** |
---|
3152 | * APIMethod: dragPanMapObject |
---|
3153 | * |
---|
3154 | * Parameters: |
---|
3155 | * dX - {Integer} |
---|
3156 | * dY - {Integer} |
---|
3157 | */ |
---|
3158 | dragPanMapObject: function(dX, dY) { |
---|
3159 | this.mapObject.vemapcontrol.PanMap(dX, -dY); |
---|
3160 | }, |
---|
3161 | |
---|
3162 | /** |
---|
3163 | * APIMethod: getMapObjectZoom |
---|
3164 | * |
---|
3165 | * Returns: |
---|
3166 | * {Integer} The mapObject's current zoom, in Map Object format |
---|
3167 | */ |
---|
3168 | getMapObjectZoom: function() { |
---|
3169 | return this.mapObject.GetZoomLevel(); |
---|
3170 | }, |
---|
3171 | |
---|
3172 | |
---|
3173 | // LonLat - Pixel Translation |
---|
3174 | |
---|
3175 | /** |
---|
3176 | * APIMethod: getMapObjectLonLatFromMapObjectPixel |
---|
3177 | * |
---|
3178 | * Parameters: |
---|
3179 | * moPixel - {Object} MapObject Pixel format |
---|
3180 | * |
---|
3181 | * Returns: |
---|
3182 | * {Object} MapObject LonLat translated from MapObject Pixel |
---|
3183 | */ |
---|
3184 | getMapObjectLonLatFromMapObjectPixel: function(moPixel) { |
---|
3185 | //the conditional here is to test if we are running the v6 of VE |
---|
3186 | return (typeof VEPixel != 'undefined') |
---|
3187 | ? this.mapObject.PixelToLatLong(moPixel) |
---|
3188 | : this.mapObject.PixelToLatLong(moPixel.x, moPixel.y); |
---|
3189 | }, |
---|
3190 | |
---|
3191 | /** |
---|
3192 | * APIMethod: getMapObjectPixelFromMapObjectLonLat |
---|
3193 | * |
---|
3194 | * Parameters: |
---|
3195 | * moLonLat - {Object} MapObject LonLat format |
---|
3196 | * |
---|
3197 | * Returns: |
---|
3198 | * {Object} MapObject Pixel transtlated from MapObject LonLat |
---|
3199 | */ |
---|
3200 | getMapObjectPixelFromMapObjectLonLat: function(moLonLat) { |
---|
3201 | return this.mapObject.LatLongToPixel(moLonLat); |
---|
3202 | }, |
---|
3203 | |
---|
3204 | |
---|
3205 | /************************************ |
---|
3206 | * * |
---|
3207 | * MapObject Primitives * |
---|
3208 | * * |
---|
3209 | ************************************/ |
---|
3210 | |
---|
3211 | |
---|
3212 | // LonLat |
---|
3213 | |
---|
3214 | /** |
---|
3215 | * APIMethod: getLongitudeFromMapObjectLonLat |
---|
3216 | * |
---|
3217 | * Parameters: |
---|
3218 | * moLonLat - {Object} MapObject LonLat format |
---|
3219 | * |
---|
3220 | * Returns: |
---|
3221 | * {Float} Longitude of the given MapObject LonLat |
---|
3222 | */ |
---|
3223 | getLongitudeFromMapObjectLonLat: function(moLonLat) { |
---|
3224 | return this.sphericalMercator ? |
---|
3225 | this.forwardMercator(moLonLat.Longitude, moLonLat.Latitude).lon : |
---|
3226 | moLonLat.Longitude; |
---|
3227 | }, |
---|
3228 | |
---|
3229 | /** |
---|
3230 | * APIMethod: getLatitudeFromMapObjectLonLat |
---|
3231 | * |
---|
3232 | * Parameters: |
---|
3233 | * moLonLat - {Object} MapObject LonLat format |
---|
3234 | * |
---|
3235 | * Returns: |
---|
3236 | * {Float} Latitude of the given MapObject LonLat |
---|
3237 | */ |
---|
3238 | getLatitudeFromMapObjectLonLat: function(moLonLat) { |
---|
3239 | return this.sphericalMercator ? |
---|
3240 | this.forwardMercator(moLonLat.Longitude, moLonLat.Latitude).lat : |
---|
3241 | moLonLat.Latitude; |
---|
3242 | }, |
---|
3243 | |
---|
3244 | /** |
---|
3245 | * APIMethod: getMapObjectLonLatFromLonLat |
---|
3246 | * |
---|
3247 | * Parameters: |
---|
3248 | * lon - {Float} |
---|
3249 | * lat - {Float} |
---|
3250 | * |
---|
3251 | * Returns: |
---|
3252 | * {Object} MapObject LonLat built from lon and lat params |
---|
3253 | */ |
---|
3254 | getMapObjectLonLatFromLonLat: function(lon, lat) { |
---|
3255 | var veLatLong; |
---|
3256 | if(this.sphericalMercator) { |
---|
3257 | var lonlat = this.inverseMercator(lon, lat); |
---|
3258 | veLatLong = new VELatLong(lonlat.lat, lonlat.lon); |
---|
3259 | } else { |
---|
3260 | veLatLong = new VELatLong(lat, lon); |
---|
3261 | } |
---|
3262 | return veLatLong; |
---|
3263 | }, |
---|
3264 | |
---|
3265 | // Pixel |
---|
3266 | |
---|
3267 | /** |
---|
3268 | * APIMethod: getXFromMapObjectPixel |
---|
3269 | * |
---|
3270 | * Parameters: |
---|
3271 | * moPixel - {Object} MapObject Pixel format |
---|
3272 | * |
---|
3273 | * Returns: |
---|
3274 | * {Integer} X value of the MapObject Pixel |
---|
3275 | */ |
---|
3276 | getXFromMapObjectPixel: function(moPixel) { |
---|
3277 | return moPixel.x; |
---|
3278 | }, |
---|
3279 | |
---|
3280 | /** |
---|
3281 | * APIMethod: getYFromMapObjectPixel |
---|
3282 | * |
---|
3283 | * Parameters: |
---|
3284 | * moPixel - {Object} MapObject Pixel format |
---|
3285 | * |
---|
3286 | * Returns: |
---|
3287 | * {Integer} Y value of the MapObject Pixel |
---|
3288 | */ |
---|
3289 | getYFromMapObjectPixel: function(moPixel) { |
---|
3290 | return moPixel.y; |
---|
3291 | }, |
---|
3292 | |
---|
3293 | /** |
---|
3294 | * APIMethod: getMapObjectPixelFromXY |
---|
3295 | * |
---|
3296 | * Parameters: |
---|
3297 | * x - {Integer} |
---|
3298 | * y - {Integer} |
---|
3299 | * |
---|
3300 | * Returns: |
---|
3301 | * {Object} MapObject Pixel from x and y parameters |
---|
3302 | */ |
---|
3303 | getMapObjectPixelFromXY: function(x, y) { |
---|
3304 | //the conditional here is to test if we are running the v6 of VE |
---|
3305 | return (typeof VEPixel != 'undefined') ? new VEPixel(x, y) |
---|
3306 | : new Msn.VE.Pixel(x, y); |
---|
3307 | }, |
---|
3308 | |
---|
3309 | CLASS_NAME: "OpenLayers.Layer.VirtualEarth" |
---|
3310 | }); |
---|
3311 | |
---|
3312 | /* |
---|
3313 | * Copyright 2007, Google Inc. |
---|
3314 | * |
---|
3315 | * Redistribution and use in source and binary forms, with or without |
---|
3316 | * modification, are permitted provided that the following conditions are met: |
---|
3317 | * |
---|
3318 | * 1. Redistributions of source code must retain the above copyright notice, |
---|
3319 | * this list of conditions and the following disclaimer. |
---|
3320 | * 2. Redistributions in binary form must reproduce the above copyright notice, |
---|
3321 | * this list of conditions and the following disclaimer in the documentation |
---|
3322 | * and/or other materials provided with the distribution. |
---|
3323 | * 3. Neither the name of Google Inc. nor the names of its contributors may be |
---|
3324 | * used to endorse or promote products derived from this software without |
---|
3325 | * specific prior written permission. |
---|
3326 | * |
---|
3327 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
---|
3328 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
---|
3329 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
---|
3330 | * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
---|
3331 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
---|
3332 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
---|
3333 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
---|
3334 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
---|
3335 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
---|
3336 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
---|
3337 | * |
---|
3338 | * Sets up google.gears.*, which is *the only* supported way to access Gears. |
---|
3339 | * |
---|
3340 | * Circumvent this file at your own risk! |
---|
3341 | * |
---|
3342 | * In the future, Gears may automatically define google.gears.* without this |
---|
3343 | * file. Gears may use these objects to transparently fix bugs and compatibility |
---|
3344 | * issues. Applications that use the code below will continue to work seamlessly |
---|
3345 | * when that happens. |
---|
3346 | */ |
---|
3347 | |
---|
3348 | (function() { |
---|
3349 | // We are already defined. Hooray! |
---|
3350 | if (window.google && google.gears) { |
---|
3351 | return; |
---|
3352 | } |
---|
3353 | |
---|
3354 | var factory = null; |
---|
3355 | |
---|
3356 | // Firefox |
---|
3357 | if (typeof GearsFactory != 'undefined') { |
---|
3358 | factory = new GearsFactory(); |
---|
3359 | } else { |
---|
3360 | // IE |
---|
3361 | try { |
---|
3362 | factory = new ActiveXObject('Gears.Factory'); |
---|
3363 | // privateSetGlobalObject is only required and supported on WinCE. |
---|
3364 | if (factory.getBuildInfo().indexOf('ie_mobile') != -1) { |
---|
3365 | factory.privateSetGlobalObject(this); |
---|
3366 | } |
---|
3367 | } catch (e) { |
---|
3368 | // Safari |
---|
3369 | if ((typeof navigator.mimeTypes != 'undefined') |
---|
3370 | && navigator.mimeTypes["application/x-googlegears"]) { |
---|
3371 | factory = document.createElement("object"); |
---|
3372 | factory.style.display = "none"; |
---|
3373 | factory.width = 0; |
---|
3374 | factory.height = 0; |
---|
3375 | factory.type = "application/x-googlegears"; |
---|
3376 | document.documentElement.appendChild(factory); |
---|
3377 | } |
---|
3378 | } |
---|
3379 | } |
---|
3380 | |
---|
3381 | // *Do not* define any objects if Gears is not installed. This mimics the |
---|
3382 | // behavior of Gears defining the objects in the future. |
---|
3383 | if (!factory) { |
---|
3384 | return; |
---|
3385 | } |
---|
3386 | |
---|
3387 | // Now set up the objects, being careful not to overwrite anything. |
---|
3388 | // |
---|
3389 | // Note: In Internet Explorer for Windows Mobile, you can't add properties to |
---|
3390 | // the window object. However, global objects are automatically added as |
---|
3391 | // properties of the window object in all browsers. |
---|
3392 | if (!window.google) { |
---|
3393 | google = {}; |
---|
3394 | } |
---|
3395 | |
---|
3396 | if (!google.gears) { |
---|
3397 | google.gears = {factory: factory}; |
---|
3398 | } |
---|
3399 | })(); |
---|
3400 | |
---|
3401 | /** |
---|
3402 | * Class: OpenLayers.Protocol.SQL |
---|
3403 | * Abstract SQL protocol class. Not to be instantiated directly. Use |
---|
3404 | * one of the SQL protocol subclasses instead. |
---|
3405 | * |
---|
3406 | * Inherits from: |
---|
3407 | * - <OpenLayers.Protocol> |
---|
3408 | */ |
---|
3409 | OpenLayers.Protocol.SQL = OpenLayers.Class(OpenLayers.Protocol, { |
---|
3410 | |
---|
3411 | /** |
---|
3412 | * APIProperty: databaseName |
---|
3413 | * {String} |
---|
3414 | */ |
---|
3415 | databaseName: 'ol', |
---|
3416 | |
---|
3417 | /** |
---|
3418 | * APIProperty: tableName |
---|
3419 | * Name of the database table into which Features should be saved. |
---|
3420 | */ |
---|
3421 | tableName: "ol_vector_features", |
---|
3422 | |
---|
3423 | /** |
---|
3424 | * Property: postReadFiltering |
---|
3425 | * {Boolean} Whether the filter (if there's one) must be applied after |
---|
3426 | * the features have been read from the database; for example the |
---|
3427 | * BBOX strategy passes the read method a BBOX spatial filter, if |
---|
3428 | * postReadFiltering is true every feature read from the database |
---|
3429 | * will go through the BBOX spatial filter, which can be costly; |
---|
3430 | * defaults to true. |
---|
3431 | */ |
---|
3432 | postReadFiltering: true, |
---|
3433 | |
---|
3434 | /** |
---|
3435 | * Constructor: OpenLayers.Protocol.SQL |
---|
3436 | */ |
---|
3437 | initialize: function(options) { |
---|
3438 | OpenLayers.Protocol.prototype.initialize.apply(this, [options]); |
---|
3439 | }, |
---|
3440 | |
---|
3441 | /** |
---|
3442 | * APIMethod: destroy |
---|
3443 | * Clean up the protocol. |
---|
3444 | */ |
---|
3445 | destroy: function() { |
---|
3446 | OpenLayers.Protocol.prototype.destroy.apply(this); |
---|
3447 | }, |
---|
3448 | |
---|
3449 | /** |
---|
3450 | * APIMethod: supported |
---|
3451 | * This should be overridden by specific subclasses |
---|
3452 | * |
---|
3453 | * Returns: |
---|
3454 | * {Boolean} Whether or not the browser supports the SQL backend |
---|
3455 | */ |
---|
3456 | supported: function() { |
---|
3457 | return false; |
---|
3458 | }, |
---|
3459 | |
---|
3460 | /** |
---|
3461 | * Method: evaluateFilter |
---|
3462 | * If postReadFiltering is true evaluate the filter against the feature |
---|
3463 | * and return the result of the evaluation, otherwise return true. |
---|
3464 | * |
---|
3465 | * Parameters: |
---|
3466 | * {<OpenLayers.Feature.Vector>} The feature. |
---|
3467 | * {<OpenLayers.Filter>} The filter. |
---|
3468 | * |
---|
3469 | * Returns: |
---|
3470 | * {Boolean} true if postReadFiltering if false, the result of the |
---|
3471 | * filter evaluation otherwise. |
---|
3472 | */ |
---|
3473 | evaluateFilter: function(feature, filter) { |
---|
3474 | return filter && this.postReadFiltering ? |
---|
3475 | filter.evaluate(feature) : true; |
---|
3476 | }, |
---|
3477 | |
---|
3478 | CLASS_NAME: "OpenLayers.Protocol.SQL" |
---|
3479 | }); |
---|
3480 | |
---|
3481 | /** |
---|
3482 | * Class: OpenLayers.Protocol.SQL.Gears |
---|
3483 | * This Protocol stores feature in the browser via the Gears Database module |
---|
3484 | * <http://code.google.com/apis/gears/api_database.html>. |
---|
3485 | * |
---|
3486 | * The main advantage is that all the read, create, update and delete operations |
---|
3487 | * can be done offline. |
---|
3488 | * |
---|
3489 | * Inherits from: |
---|
3490 | * - <OpenLayers.Protocol.SQL> |
---|
3491 | */ |
---|
3492 | OpenLayers.Protocol.SQL.Gears = OpenLayers.Class(OpenLayers.Protocol.SQL, { |
---|
3493 | |
---|
3494 | /** |
---|
3495 | * Property: FID_PREFIX |
---|
3496 | * {String} |
---|
3497 | */ |
---|
3498 | FID_PREFIX: '__gears_fid__', |
---|
3499 | |
---|
3500 | /** |
---|
3501 | * Property: NULL_GEOMETRY |
---|
3502 | * {String} |
---|
3503 | */ |
---|
3504 | NULL_GEOMETRY: '__gears_null_geometry__', |
---|
3505 | |
---|
3506 | /** |
---|
3507 | * Property: NULL_FEATURE_STATE |
---|
3508 | * {String} |
---|
3509 | */ |
---|
3510 | NULL_FEATURE_STATE: '__gears_null_feature_state__', |
---|
3511 | |
---|
3512 | /** |
---|
3513 | * Property: jsonParser |
---|
3514 | * {<OpenLayers.Format.JSON>} |
---|
3515 | */ |
---|
3516 | jsonParser: null, |
---|
3517 | |
---|
3518 | /** |
---|
3519 | * Property: wktParser |
---|
3520 | * {<OpenLayers.Format.WKT>} |
---|
3521 | */ |
---|
3522 | wktParser: null, |
---|
3523 | |
---|
3524 | /** |
---|
3525 | * Property: fidRegExp |
---|
3526 | * {RegExp} Regular expression to know whether a feature was |
---|
3527 | * created in offline mode. |
---|
3528 | */ |
---|
3529 | fidRegExp: null, |
---|
3530 | |
---|
3531 | /** |
---|
3532 | * Property: saveFeatureState |
---|
3533 | * {Boolean} Whether to save the feature state (<OpenLayers.State>) |
---|
3534 | * into the database, defaults to true. |
---|
3535 | */ |
---|
3536 | saveFeatureState: true, |
---|
3537 | |
---|
3538 | /** |
---|
3539 | * Property: typeOfFid |
---|
3540 | * {String} The type of the feature identifier, either "number" or |
---|
3541 | * "string", defaults to "string". |
---|
3542 | */ |
---|
3543 | typeOfFid: "string", |
---|
3544 | |
---|
3545 | /** |
---|
3546 | * Property: db |
---|
3547 | * {GearsDatabase} |
---|
3548 | */ |
---|
3549 | db: null, |
---|
3550 | |
---|
3551 | /** |
---|
3552 | * Constructor: OpenLayers.Protocol.SQL.Gears |
---|
3553 | */ |
---|
3554 | initialize: function(options) { |
---|
3555 | if (!this.supported()) { |
---|
3556 | return; |
---|
3557 | } |
---|
3558 | OpenLayers.Protocol.SQL.prototype.initialize.apply(this, [options]); |
---|
3559 | this.jsonParser = new OpenLayers.Format.JSON(); |
---|
3560 | this.wktParser = new OpenLayers.Format.WKT(); |
---|
3561 | |
---|
3562 | this.fidRegExp = new RegExp('^' + this.FID_PREFIX); |
---|
3563 | this.initializeDatabase(); |
---|
3564 | |
---|
3565 | |
---|
3566 | }, |
---|
3567 | |
---|
3568 | /** |
---|
3569 | * Method: initializeDatabase |
---|
3570 | */ |
---|
3571 | initializeDatabase: function() { |
---|
3572 | this.db = google.gears.factory.create('beta.database'); |
---|
3573 | this.db.open(this.databaseName); |
---|
3574 | this.db.execute( |
---|
3575 | "CREATE TABLE IF NOT EXISTS " + this.tableName + |
---|
3576 | " (fid TEXT UNIQUE, geometry TEXT, properties TEXT," + |
---|
3577 | " state TEXT)"); |
---|
3578 | }, |
---|
3579 | |
---|
3580 | /** |
---|
3581 | * APIMethod: destroy |
---|
3582 | * Clean up the protocol. |
---|
3583 | */ |
---|
3584 | destroy: function() { |
---|
3585 | this.db.close(); |
---|
3586 | this.db = null; |
---|
3587 | |
---|
3588 | this.jsonParser = null; |
---|
3589 | this.wktParser = null; |
---|
3590 | |
---|
3591 | OpenLayers.Protocol.SQL.prototype.destroy.apply(this); |
---|
3592 | }, |
---|
3593 | |
---|
3594 | /** |
---|
3595 | * APIMethod: supported |
---|
3596 | * Determine whether a browser supports Gears |
---|
3597 | * |
---|
3598 | * Returns: |
---|
3599 | * {Boolean} The browser supports Gears |
---|
3600 | */ |
---|
3601 | supported: function() { |
---|
3602 | return !!(window.google && google.gears); |
---|
3603 | }, |
---|
3604 | |
---|
3605 | /** |
---|
3606 | * APIMethod: read |
---|
3607 | * Read all features from the database and return a |
---|
3608 | * <OpenLayers.Protocol.Response> instance. If the options parameter |
---|
3609 | * contains a callback attribute, the function is called with the response |
---|
3610 | * as a parameter. |
---|
3611 | * |
---|
3612 | * Parameters: |
---|
3613 | * options - {Object} Optional object for configuring the request; it |
---|
3614 | * can have the {Boolean} property "noFeatureStateReset" which |
---|
3615 | * specifies if the state of features read from the Gears |
---|
3616 | * database must be reset to null, if "noFeatureStateReset" |
---|
3617 | * is undefined or false then each feature's state is reset |
---|
3618 | * to null, if "noFeatureStateReset" is true the feature state |
---|
3619 | * is preserved. |
---|
3620 | * |
---|
3621 | * Returns: |
---|
3622 | * {<OpenLayers.Protocol.Response>} An <OpenLayers.Protocol.Response> |
---|
3623 | * object. |
---|
3624 | */ |
---|
3625 | read: function(options) { |
---|
3626 | OpenLayers.Protocol.prototype.read.apply(this, arguments); |
---|
3627 | options = OpenLayers.Util.applyDefaults(options, this.options); |
---|
3628 | |
---|
3629 | var feature, features = []; |
---|
3630 | var rs = this.db.execute("SELECT * FROM " + this.tableName); |
---|
3631 | while (rs.isValidRow()) { |
---|
3632 | feature = this.unfreezeFeature(rs); |
---|
3633 | if (this.evaluateFilter(feature, options.filter)) { |
---|
3634 | if (!options.noFeatureStateReset) { |
---|
3635 | feature.state = null; |
---|
3636 | } |
---|
3637 | features.push(feature); |
---|
3638 | } |
---|
3639 | rs.next(); |
---|
3640 | } |
---|
3641 | rs.close(); |
---|
3642 | |
---|
3643 | var resp = new OpenLayers.Protocol.Response({ |
---|
3644 | code: OpenLayers.Protocol.Response.SUCCESS, |
---|
3645 | requestType: "read", |
---|
3646 | features: features |
---|
3647 | }); |
---|
3648 | |
---|
3649 | if (options && options.callback) { |
---|
3650 | options.callback.call(options.scope, resp); |
---|
3651 | } |
---|
3652 | |
---|
3653 | return resp; |
---|
3654 | }, |
---|
3655 | |
---|
3656 | /** |
---|
3657 | * Method: unfreezeFeature |
---|
3658 | * |
---|
3659 | * Parameters: |
---|
3660 | * row - {ResultSet} |
---|
3661 | * |
---|
3662 | * Returns: |
---|
3663 | * {<OpenLayers.Feature.Vector>} |
---|
3664 | */ |
---|
3665 | unfreezeFeature: function(row) { |
---|
3666 | var feature; |
---|
3667 | var wkt = row.fieldByName('geometry'); |
---|
3668 | if (wkt == this.NULL_GEOMETRY) { |
---|
3669 | feature = new OpenLayers.Feature.Vector(); |
---|
3670 | } else { |
---|
3671 | feature = this.wktParser.read(wkt); |
---|
3672 | } |
---|
3673 | |
---|
3674 | feature.attributes = this.jsonParser.read( |
---|
3675 | row.fieldByName('properties')); |
---|
3676 | |
---|
3677 | feature.fid = this.extractFidFromField(row.fieldByName('fid')); |
---|
3678 | |
---|
3679 | var state = row.fieldByName('state'); |
---|
3680 | if (state == this.NULL_FEATURE_STATE) { |
---|
3681 | state = null; |
---|
3682 | } |
---|
3683 | feature.state = state; |
---|
3684 | |
---|
3685 | return feature; |
---|
3686 | }, |
---|
3687 | |
---|
3688 | /** |
---|
3689 | * Method: extractFidFromField |
---|
3690 | * |
---|
3691 | * Parameters: |
---|
3692 | * field - {String} |
---|
3693 | * |
---|
3694 | * Returns |
---|
3695 | * {String} or {Number} The fid. |
---|
3696 | */ |
---|
3697 | extractFidFromField: function(field) { |
---|
3698 | if (!field.match(this.fidRegExp) && this.typeOfFid == "number") { |
---|
3699 | field = parseFloat(field); |
---|
3700 | } |
---|
3701 | return field; |
---|
3702 | }, |
---|
3703 | |
---|
3704 | /** |
---|
3705 | * APIMethod: create |
---|
3706 | * Create new features into the database. |
---|
3707 | * |
---|
3708 | * Parameters: |
---|
3709 | * features - {Array({<OpenLayers.Feature.Vector>})} or |
---|
3710 | * {<OpenLayers.Feature.Vector>} The features to create in |
---|
3711 | * the database. |
---|
3712 | * options - {Object} Optional object for configuring the request. |
---|
3713 | * |
---|
3714 | * Returns: |
---|
3715 | * {<OpenLayers.Protocol.Response>} An <OpenLayers.Protocol.Response> |
---|
3716 | * object. |
---|
3717 | */ |
---|
3718 | create: function(features, options) { |
---|
3719 | options = OpenLayers.Util.applyDefaults(options, this.options); |
---|
3720 | |
---|
3721 | var resp = this.createOrUpdate(features); |
---|
3722 | resp.requestType = "create"; |
---|
3723 | |
---|
3724 | if (options && options.callback) { |
---|
3725 | options.callback.call(options.scope, resp); |
---|
3726 | } |
---|
3727 | |
---|
3728 | return resp; |
---|
3729 | }, |
---|
3730 | |
---|
3731 | /** |
---|
3732 | * APIMethod: update |
---|
3733 | * Construct a request updating modified feature. |
---|
3734 | * |
---|
3735 | * Parameters: |
---|
3736 | * features - {Array({<OpenLayers.Feature.Vector>})} or |
---|
3737 | * {<OpenLayers.Feature.Vector>} The features to update in |
---|
3738 | * the database. |
---|
3739 | * options - {Object} Optional object for configuring the request. |
---|
3740 | * |
---|
3741 | * Returns: |
---|
3742 | * {<OpenLayers.Protocol.Response>} An <OpenLayers.Protocol.Response> |
---|
3743 | * object. |
---|
3744 | */ |
---|
3745 | update: function(features, options) { |
---|
3746 | options = OpenLayers.Util.applyDefaults(options, this.options); |
---|
3747 | |
---|
3748 | var resp = this.createOrUpdate(features); |
---|
3749 | resp.requestType = "update"; |
---|
3750 | |
---|
3751 | if (options && options.callback) { |
---|
3752 | options.callback.call(options.scope, resp); |
---|
3753 | } |
---|
3754 | |
---|
3755 | return resp; |
---|
3756 | }, |
---|
3757 | |
---|
3758 | /** |
---|
3759 | * Method: createOrUpdate |
---|
3760 | * Construct a request for updating or creating features in the |
---|
3761 | * database. |
---|
3762 | * |
---|
3763 | * Parameters: |
---|
3764 | * features - {Array({<OpenLayers.Feature.Vector>})} or |
---|
3765 | * {<OpenLayers.Feature.Vector>} The feature to create or update |
---|
3766 | * in the database. |
---|
3767 | * |
---|
3768 | * Returns: |
---|
3769 | * {<OpenLayers.Protocol.Response>} An <OpenLayers.Protocol.Response> |
---|
3770 | * object. |
---|
3771 | */ |
---|
3772 | createOrUpdate: function(features) { |
---|
3773 | if (!(OpenLayers.Util.isArray(features))) { |
---|
3774 | features = [features]; |
---|
3775 | } |
---|
3776 | |
---|
3777 | var i, len = features.length, feature; |
---|
3778 | var insertedFeatures = new Array(len); |
---|
3779 | |
---|
3780 | for (i = 0; i < len; i++) { |
---|
3781 | feature = features[i]; |
---|
3782 | var params = this.freezeFeature(feature); |
---|
3783 | this.db.execute( |
---|
3784 | "REPLACE INTO " + this.tableName + |
---|
3785 | " (fid, geometry, properties, state)" + |
---|
3786 | " VALUES (?, ?, ?, ?)", |
---|
3787 | params); |
---|
3788 | |
---|
3789 | var clone = feature.clone(); |
---|
3790 | clone.fid = this.extractFidFromField(params[0]); |
---|
3791 | insertedFeatures[i] = clone; |
---|
3792 | } |
---|
3793 | |
---|
3794 | return new OpenLayers.Protocol.Response({ |
---|
3795 | code: OpenLayers.Protocol.Response.SUCCESS, |
---|
3796 | features: insertedFeatures, |
---|
3797 | reqFeatures: features |
---|
3798 | }); |
---|
3799 | }, |
---|
3800 | |
---|
3801 | /** |
---|
3802 | * Method: freezeFeature |
---|
3803 | * |
---|
3804 | * Parameters: |
---|
3805 | * feature - {<OpenLayers.Feature.Vector>} |
---|
3806 | * state - {String} The feature state to store in the database. |
---|
3807 | * |
---|
3808 | * Returns: |
---|
3809 | * {Array} |
---|
3810 | */ |
---|
3811 | freezeFeature: function(feature) { |
---|
3812 | // 2 notes: |
---|
3813 | // - fid might not be a string |
---|
3814 | // - getFeatureStateForFreeze needs the feature fid to it's stored |
---|
3815 | // in the feature here |
---|
3816 | feature.fid = feature.fid != null ? |
---|
3817 | "" + feature.fid : OpenLayers.Util.createUniqueID(this.FID_PREFIX); |
---|
3818 | |
---|
3819 | var geometry = feature.geometry != null ? |
---|
3820 | feature.geometry.toString() : this.NULL_GEOMETRY; |
---|
3821 | |
---|
3822 | var properties = this.jsonParser.write(feature.attributes); |
---|
3823 | |
---|
3824 | var state = this.getFeatureStateForFreeze(feature); |
---|
3825 | |
---|
3826 | return [feature.fid, geometry, properties, state]; |
---|
3827 | }, |
---|
3828 | |
---|
3829 | /** |
---|
3830 | * Method: getFeatureStateForFreeze |
---|
3831 | * Get the state of the feature to store into the database. |
---|
3832 | * |
---|
3833 | * Parameters: |
---|
3834 | * feature - {<OpenLayers.Feature.Vector>} The feature. |
---|
3835 | * |
---|
3836 | * Returns |
---|
3837 | * {String} The state |
---|
3838 | */ |
---|
3839 | getFeatureStateForFreeze: function(feature) { |
---|
3840 | var state; |
---|
3841 | if (!this.saveFeatureState) { |
---|
3842 | state = this.NULL_FEATURE_STATE; |
---|
3843 | } else if (this.createdOffline(feature)) { |
---|
3844 | // if the feature was created in offline mode, its |
---|
3845 | // state must remain INSERT |
---|
3846 | state = OpenLayers.State.INSERT; |
---|
3847 | } else { |
---|
3848 | state = feature.state; |
---|
3849 | } |
---|
3850 | return state; |
---|
3851 | }, |
---|
3852 | |
---|
3853 | /** |
---|
3854 | * APIMethod: delete |
---|
3855 | * Delete features from the database. |
---|
3856 | * |
---|
3857 | * Parameters: |
---|
3858 | * features - {Array({<OpenLayers.Feature.Vector>})} or |
---|
3859 | * {<OpenLayers.Feature.Vector>} |
---|
3860 | * options - {Object} Optional object for configuring the request. |
---|
3861 | * This object is modified and should not be reused. |
---|
3862 | * |
---|
3863 | * Returns: |
---|
3864 | * {<OpenLayers.Protocol.Response>} An <OpenLayers.Protocol.Response> |
---|
3865 | * object. |
---|
3866 | */ |
---|
3867 | "delete": function(features, options) { |
---|
3868 | if (!(OpenLayers.Util.isArray(features))) { |
---|
3869 | features = [features]; |
---|
3870 | } |
---|
3871 | |
---|
3872 | options = OpenLayers.Util.applyDefaults(options, this.options); |
---|
3873 | |
---|
3874 | var i, len, feature; |
---|
3875 | for (i = 0, len = features.length; i < len; i++) { |
---|
3876 | feature = features[i]; |
---|
3877 | |
---|
3878 | // if saveFeatureState is set to true and if the feature wasn't created |
---|
3879 | // in offline mode we don't delete it in the database but just update |
---|
3880 | // it state column |
---|
3881 | if (this.saveFeatureState && !this.createdOffline(feature)) { |
---|
3882 | var toDelete = feature.clone(); |
---|
3883 | toDelete.fid = feature.fid; |
---|
3884 | if (toDelete.geometry) { |
---|
3885 | toDelete.geometry.destroy(); |
---|
3886 | toDelete.geometry = null; |
---|
3887 | } |
---|
3888 | toDelete.state = feature.state; |
---|
3889 | this.createOrUpdate(toDelete); |
---|
3890 | } else { |
---|
3891 | this.db.execute( |
---|
3892 | "DELETE FROM " + this.tableName + |
---|
3893 | " WHERE fid = ?", [feature.fid]); |
---|
3894 | } |
---|
3895 | } |
---|
3896 | |
---|
3897 | var resp = new OpenLayers.Protocol.Response({ |
---|
3898 | code: OpenLayers.Protocol.Response.SUCCESS, |
---|
3899 | requestType: "delete", |
---|
3900 | reqFeatures: features |
---|
3901 | }); |
---|
3902 | |
---|
3903 | if (options && options.callback) { |
---|
3904 | options.callback.call(options.scope, resp); |
---|
3905 | } |
---|
3906 | |
---|
3907 | return resp; |
---|
3908 | }, |
---|
3909 | |
---|
3910 | /** |
---|
3911 | * Method: createdOffline |
---|
3912 | * Returns true if the feature had a feature id when it was created in |
---|
3913 | * the Gears database, false otherwise; this is determined by |
---|
3914 | * checking the form of the feature's fid value. |
---|
3915 | * |
---|
3916 | * Parameters: |
---|
3917 | * feature - {<OpenLayers.Feature.Vector>} |
---|
3918 | * |
---|
3919 | * Returns: |
---|
3920 | * {Boolean} |
---|
3921 | */ |
---|
3922 | createdOffline: function(feature) { |
---|
3923 | return (typeof feature.fid == "string" && |
---|
3924 | !!(feature.fid.match(this.fidRegExp))); |
---|
3925 | }, |
---|
3926 | |
---|
3927 | /** |
---|
3928 | * APIMethod: commit |
---|
3929 | * Go over the features and for each take action |
---|
3930 | * based on the feature state. Possible actions are create, |
---|
3931 | * update and delete. |
---|
3932 | * |
---|
3933 | * Parameters: |
---|
3934 | * features - {Array({<OpenLayers.Feature.Vector>})} |
---|
3935 | * options - {Object} Object whose possible keys are "create", "update", |
---|
3936 | * "delete", "callback" and "scope", the values referenced by the |
---|
3937 | * first three are objects as passed to the "create", "update", and |
---|
3938 | * "delete" methods, the value referenced by the "callback" key is |
---|
3939 | * a function which is called when the commit operation is complete |
---|
3940 | * using the scope referenced by the "scope" key. |
---|
3941 | * |
---|
3942 | * Returns: |
---|
3943 | * {Array({<OpenLayers.Protocol.Response>})} An array of |
---|
3944 | * <OpenLayers.Protocol.Response> objects, one per request made |
---|
3945 | * to the database. |
---|
3946 | */ |
---|
3947 | commit: function(features, options) { |
---|
3948 | var opt, resp = [], nRequests = 0, nResponses = 0; |
---|
3949 | |
---|
3950 | function callback(resp) { |
---|
3951 | if (++nResponses < nRequests) { |
---|
3952 | resp.last = false; |
---|
3953 | } |
---|
3954 | this.callUserCallback(options, resp); |
---|
3955 | } |
---|
3956 | |
---|
3957 | var feature, toCreate = [], toUpdate = [], toDelete = []; |
---|
3958 | for (var i = features.length - 1; i >= 0; i--) { |
---|
3959 | feature = features[i]; |
---|
3960 | switch (feature.state) { |
---|
3961 | case OpenLayers.State.INSERT: |
---|
3962 | toCreate.push(feature); |
---|
3963 | break; |
---|
3964 | case OpenLayers.State.UPDATE: |
---|
3965 | toUpdate.push(feature); |
---|
3966 | break; |
---|
3967 | case OpenLayers.State.DELETE: |
---|
3968 | toDelete.push(feature); |
---|
3969 | break; |
---|
3970 | } |
---|
3971 | } |
---|
3972 | if (toCreate.length > 0) { |
---|
3973 | nRequests++; |
---|
3974 | opt = OpenLayers.Util.applyDefaults( |
---|
3975 | {"callback": callback, "scope": this}, |
---|
3976 | options.create |
---|
3977 | ); |
---|
3978 | resp.push(this.create(toCreate, opt)); |
---|
3979 | } |
---|
3980 | if (toUpdate.length > 0) { |
---|
3981 | nRequests++; |
---|
3982 | opt = OpenLayers.Util.applyDefaults( |
---|
3983 | {"callback": callback, "scope": this}, |
---|
3984 | options.update |
---|
3985 | ); |
---|
3986 | resp.push(this.update(toUpdate, opt)); |
---|
3987 | } |
---|
3988 | if (toDelete.length > 0) { |
---|
3989 | nRequests++; |
---|
3990 | opt = OpenLayers.Util.applyDefaults( |
---|
3991 | {"callback": callback, "scope": this}, |
---|
3992 | options["delete"] |
---|
3993 | ); |
---|
3994 | resp.push(this["delete"](toDelete, opt)); |
---|
3995 | } |
---|
3996 | |
---|
3997 | return resp; |
---|
3998 | }, |
---|
3999 | |
---|
4000 | /** |
---|
4001 | * Method: clear |
---|
4002 | * Removes all rows of the table. |
---|
4003 | */ |
---|
4004 | clear: function() { |
---|
4005 | this.db.execute("DELETE FROM " + this.tableName); |
---|
4006 | }, |
---|
4007 | |
---|
4008 | /** |
---|
4009 | * Method: callUserCallback |
---|
4010 | * This method is called from within commit each time a request is made |
---|
4011 | * to the database, it is responsible for calling the user-supplied |
---|
4012 | * callbacks. |
---|
4013 | * |
---|
4014 | * Parameters: |
---|
4015 | * options - {Object} The map of options passed to the commit call. |
---|
4016 | * resp - {<OpenLayers.Protocol.Response>} |
---|
4017 | */ |
---|
4018 | callUserCallback: function(options, resp) { |
---|
4019 | var opt = options[resp.requestType]; |
---|
4020 | if (opt && opt.callback) { |
---|
4021 | opt.callback.call(opt.scope, resp); |
---|
4022 | } |
---|
4023 | if (resp.last && options.callback) { |
---|
4024 | options.callback.call(options.scope); |
---|
4025 | } |
---|
4026 | }, |
---|
4027 | |
---|
4028 | CLASS_NAME: "OpenLayers.Protocol.SQL.Gears" |
---|
4029 | }); |
---|
4030 | |
---|
4031 | /** |
---|
4032 | * Class: OpenLayers.Layer.Yahoo |
---|
4033 | * |
---|
4034 | * Inherits from: |
---|
4035 | * - <OpenLayers.Layer.EventPane> |
---|
4036 | * - <OpenLayers.Layer.FixedZoomLevels> |
---|
4037 | */ |
---|
4038 | OpenLayers.Layer.Yahoo = OpenLayers.Class( |
---|
4039 | OpenLayers.Layer.EventPane, OpenLayers.Layer.FixedZoomLevels, { |
---|
4040 | |
---|
4041 | /** |
---|
4042 | * Constant: MIN_ZOOM_LEVEL |
---|
4043 | * {Integer} 0 |
---|
4044 | */ |
---|
4045 | MIN_ZOOM_LEVEL: 0, |
---|
4046 | |
---|
4047 | /** |
---|
4048 | * Constant: MAX_ZOOM_LEVEL |
---|
4049 | * {Integer} 17 |
---|
4050 | */ |
---|
4051 | MAX_ZOOM_LEVEL: 17, |
---|
4052 | |
---|
4053 | /** |
---|
4054 | * Constant: RESOLUTIONS |
---|
4055 | * {Array(Float)} Hardcode these resolutions so that they are more closely |
---|
4056 | * tied with the standard wms projection |
---|
4057 | */ |
---|
4058 | RESOLUTIONS: [ |
---|
4059 | 1.40625, |
---|
4060 | 0.703125, |
---|
4061 | 0.3515625, |
---|
4062 | 0.17578125, |
---|
4063 | 0.087890625, |
---|
4064 | 0.0439453125, |
---|
4065 | 0.02197265625, |
---|
4066 | 0.010986328125, |
---|
4067 | 0.0054931640625, |
---|
4068 | 0.00274658203125, |
---|
4069 | 0.001373291015625, |
---|
4070 | 0.0006866455078125, |
---|
4071 | 0.00034332275390625, |
---|
4072 | 0.000171661376953125, |
---|
4073 | 0.0000858306884765625, |
---|
4074 | 0.00004291534423828125, |
---|
4075 | 0.00002145767211914062, |
---|
4076 | 0.00001072883605957031 |
---|
4077 | ], |
---|
4078 | |
---|
4079 | /** |
---|
4080 | * APIProperty: type |
---|
4081 | * {YahooMapType} |
---|
4082 | */ |
---|
4083 | type: null, |
---|
4084 | |
---|
4085 | /** |
---|
4086 | * APIProperty: wrapDateLine |
---|
4087 | * {Boolean} Allow user to pan forever east/west. Default is true. |
---|
4088 | * Setting this to false only restricts panning if |
---|
4089 | * <sphericalMercator> is true. |
---|
4090 | */ |
---|
4091 | wrapDateLine: true, |
---|
4092 | |
---|
4093 | /** |
---|
4094 | * APIProperty: sphericalMercator |
---|
4095 | * {Boolean} Should the map act as a mercator-projected map? This will |
---|
4096 | * cause all interactions with the map to be in the actual map projection, |
---|
4097 | * which allows support for vector drawing, overlaying other maps, etc. |
---|
4098 | */ |
---|
4099 | sphericalMercator: false, |
---|
4100 | |
---|
4101 | /** |
---|
4102 | * Constructor: OpenLayers.Layer.Yahoo |
---|
4103 | * |
---|
4104 | * Parameters: |
---|
4105 | * name - {String} |
---|
4106 | * options - {Object} |
---|
4107 | */ |
---|
4108 | initialize: function(name, options) { |
---|
4109 | OpenLayers.Layer.EventPane.prototype.initialize.apply(this, arguments); |
---|
4110 | OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this, |
---|
4111 | arguments); |
---|
4112 | if(this.sphericalMercator) { |
---|
4113 | OpenLayers.Util.extend(this, OpenLayers.Layer.SphericalMercator); |
---|
4114 | this.initMercatorParameters(); |
---|
4115 | } |
---|
4116 | }, |
---|
4117 | |
---|
4118 | /** |
---|
4119 | * Method: loadMapObject |
---|
4120 | */ |
---|
4121 | loadMapObject:function() { |
---|
4122 | try { //do not crash! |
---|
4123 | var size = this.getMapObjectSizeFromOLSize(this.map.getSize()); |
---|
4124 | this.mapObject = new YMap(this.div, this.type, size); |
---|
4125 | this.mapObject.disableKeyControls(); |
---|
4126 | this.mapObject.disableDragMap(); |
---|
4127 | |
---|
4128 | //can we do smooth panning? (moveByXY is not an API function) |
---|
4129 | if ( !this.mapObject.moveByXY || |
---|
4130 | (typeof this.mapObject.moveByXY != "function" ) ) { |
---|
4131 | |
---|
4132 | this.dragPanMapObject = null; |
---|
4133 | } |
---|
4134 | } catch(e) {} |
---|
4135 | }, |
---|
4136 | |
---|
4137 | /** |
---|
4138 | * Method: onMapResize |
---|
4139 | * |
---|
4140 | */ |
---|
4141 | onMapResize: function() { |
---|
4142 | try { |
---|
4143 | var size = this.getMapObjectSizeFromOLSize(this.map.getSize()); |
---|
4144 | this.mapObject.resizeTo(size); |
---|
4145 | } catch(e) {} |
---|
4146 | }, |
---|
4147 | |
---|
4148 | |
---|
4149 | /** |
---|
4150 | * APIMethod: setMap |
---|
4151 | * Overridden from EventPane because we need to remove this yahoo event |
---|
4152 | * pane which prohibits our drag and drop, and we can only do this |
---|
4153 | * once the map has been loaded and centered. |
---|
4154 | * |
---|
4155 | * Parameters: |
---|
4156 | * map - {<OpenLayers.Map>} |
---|
4157 | */ |
---|
4158 | setMap: function(map) { |
---|
4159 | OpenLayers.Layer.EventPane.prototype.setMap.apply(this, arguments); |
---|
4160 | |
---|
4161 | this.map.events.register("moveend", this, this.fixYahooEventPane); |
---|
4162 | }, |
---|
4163 | |
---|
4164 | /** |
---|
4165 | * Method: fixYahooEventPane |
---|
4166 | * The map has been centered, so the mysterious yahoo eventpane has been |
---|
4167 | * added. we remove it so that it doesnt mess with *our* event pane. |
---|
4168 | */ |
---|
4169 | fixYahooEventPane: function() { |
---|
4170 | var yahooEventPane = OpenLayers.Util.getElement("ygddfdiv"); |
---|
4171 | if (yahooEventPane != null) { |
---|
4172 | if (yahooEventPane.parentNode != null) { |
---|
4173 | yahooEventPane.parentNode.removeChild(yahooEventPane); |
---|
4174 | } |
---|
4175 | this.map.events.unregister("moveend", this, |
---|
4176 | this.fixYahooEventPane); |
---|
4177 | } |
---|
4178 | }, |
---|
4179 | |
---|
4180 | /** |
---|
4181 | * APIMethod: getWarningHTML |
---|
4182 | * |
---|
4183 | * Returns: |
---|
4184 | * {String} String with information on why layer is broken, how to get |
---|
4185 | * it working. |
---|
4186 | */ |
---|
4187 | getWarningHTML:function() { |
---|
4188 | return OpenLayers.i18n( |
---|
4189 | "getLayerWarning", {'layerType':'Yahoo', 'layerLib':'Yahoo'} |
---|
4190 | ); |
---|
4191 | }, |
---|
4192 | |
---|
4193 | /********************************************************/ |
---|
4194 | /* */ |
---|
4195 | /* Translation Functions */ |
---|
4196 | /* */ |
---|
4197 | /* The following functions translate GMaps and OL */ |
---|
4198 | /* formats for Pixel, LonLat, Bounds, and Zoom */ |
---|
4199 | /* */ |
---|
4200 | /********************************************************/ |
---|
4201 | |
---|
4202 | |
---|
4203 | // |
---|
4204 | // TRANSLATION: MapObject Zoom <-> OpenLayers Zoom |
---|
4205 | // |
---|
4206 | |
---|
4207 | /** |
---|
4208 | * APIMethod: getOLZoomFromMapObjectZoom |
---|
4209 | * |
---|
4210 | * Parameters: |
---|
4211 | * gZoom - {Integer} |
---|
4212 | * |
---|
4213 | * Returns: |
---|
4214 | * {Integer} An OpenLayers Zoom level, translated from the passed in gZoom |
---|
4215 | * Returns null if null value is passed in. |
---|
4216 | */ |
---|
4217 | getOLZoomFromMapObjectZoom: function(moZoom) { |
---|
4218 | var zoom = null; |
---|
4219 | if (moZoom != null) { |
---|
4220 | zoom = OpenLayers.Layer.FixedZoomLevels.prototype.getOLZoomFromMapObjectZoom.apply(this, [moZoom]); |
---|
4221 | zoom = 18 - zoom; |
---|
4222 | } |
---|
4223 | return zoom; |
---|
4224 | }, |
---|
4225 | |
---|
4226 | /** |
---|
4227 | * APIMethod: getMapObjectZoomFromOLZoom |
---|
4228 | * |
---|
4229 | * Parameters: |
---|
4230 | * olZoom - {Integer} |
---|
4231 | * |
---|
4232 | * Returns: |
---|
4233 | * {Integer} A MapObject level, translated from the passed in olZoom |
---|
4234 | * Returns null if null value is passed in |
---|
4235 | */ |
---|
4236 | getMapObjectZoomFromOLZoom: function(olZoom) { |
---|
4237 | var zoom = null; |
---|
4238 | if (olZoom != null) { |
---|
4239 | zoom = OpenLayers.Layer.FixedZoomLevels.prototype.getMapObjectZoomFromOLZoom.apply(this, [olZoom]); |
---|
4240 | zoom = 18 - zoom; |
---|
4241 | } |
---|
4242 | return zoom; |
---|
4243 | }, |
---|
4244 | |
---|
4245 | /************************************ |
---|
4246 | * * |
---|
4247 | * MapObject Interface Controls * |
---|
4248 | * * |
---|
4249 | ************************************/ |
---|
4250 | |
---|
4251 | |
---|
4252 | // Get&Set Center, Zoom |
---|
4253 | |
---|
4254 | /** |
---|
4255 | * APIMethod: setMapObjectCenter |
---|
4256 | * Set the mapObject to the specified center and zoom |
---|
4257 | * |
---|
4258 | * Parameters: |
---|
4259 | * center - {Object} MapObject LonLat format |
---|
4260 | * zoom - {int} MapObject zoom format |
---|
4261 | */ |
---|
4262 | setMapObjectCenter: function(center, zoom) { |
---|
4263 | this.mapObject.drawZoomAndCenter(center, zoom); |
---|
4264 | }, |
---|
4265 | |
---|
4266 | /** |
---|
4267 | * APIMethod: getMapObjectCenter |
---|
4268 | * |
---|
4269 | * Returns: |
---|
4270 | * {Object} The mapObject's current center in Map Object format |
---|
4271 | */ |
---|
4272 | getMapObjectCenter: function() { |
---|
4273 | return this.mapObject.getCenterLatLon(); |
---|
4274 | }, |
---|
4275 | |
---|
4276 | /** |
---|
4277 | * APIMethod: dragPanMapObject |
---|
4278 | * |
---|
4279 | * Parameters: |
---|
4280 | * dX - {Integer} |
---|
4281 | * dY - {Integer} |
---|
4282 | */ |
---|
4283 | dragPanMapObject: function(dX, dY) { |
---|
4284 | this.mapObject.moveByXY({ |
---|
4285 | 'x': -dX, |
---|
4286 | 'y': dY |
---|
4287 | }); |
---|
4288 | }, |
---|
4289 | |
---|
4290 | /** |
---|
4291 | * APIMethod: getMapObjectZoom |
---|
4292 | * |
---|
4293 | * Returns: |
---|
4294 | * {Integer} The mapObject's current zoom, in Map Object format |
---|
4295 | */ |
---|
4296 | getMapObjectZoom: function() { |
---|
4297 | return this.mapObject.getZoomLevel(); |
---|
4298 | }, |
---|
4299 | |
---|
4300 | |
---|
4301 | // LonLat - Pixel Translation |
---|
4302 | |
---|
4303 | /** |
---|
4304 | * APIMethod: getMapObjectLonLatFromMapObjectPixel |
---|
4305 | * |
---|
4306 | * Parameters: |
---|
4307 | * moPixel - {Object} MapObject Pixel format |
---|
4308 | * |
---|
4309 | * Returns: |
---|
4310 | * {Object} MapObject LonLat translated from MapObject Pixel |
---|
4311 | */ |
---|
4312 | getMapObjectLonLatFromMapObjectPixel: function(moPixel) { |
---|
4313 | return this.mapObject.convertXYLatLon(moPixel); |
---|
4314 | }, |
---|
4315 | |
---|
4316 | /** |
---|
4317 | * APIMethod: getMapObjectPixelFromMapObjectLonLat |
---|
4318 | * |
---|
4319 | * Parameters: |
---|
4320 | * moLonLat - {Object} MapObject LonLat format |
---|
4321 | * |
---|
4322 | * Returns: |
---|
4323 | * {Object} MapObject Pixel transtlated from MapObject LonLat |
---|
4324 | */ |
---|
4325 | getMapObjectPixelFromMapObjectLonLat: function(moLonLat) { |
---|
4326 | return this.mapObject.convertLatLonXY(moLonLat); |
---|
4327 | }, |
---|
4328 | |
---|
4329 | |
---|
4330 | /************************************ |
---|
4331 | * * |
---|
4332 | * MapObject Primitives * |
---|
4333 | * * |
---|
4334 | ************************************/ |
---|
4335 | |
---|
4336 | |
---|
4337 | // LonLat |
---|
4338 | |
---|
4339 | /** |
---|
4340 | * APIMethod: getLongitudeFromMapObjectLonLat |
---|
4341 | * |
---|
4342 | * Parameters: |
---|
4343 | * moLonLat - {Object} MapObject LonLat format |
---|
4344 | * |
---|
4345 | * Returns: |
---|
4346 | * {Float} Longitude of the given MapObject LonLat |
---|
4347 | */ |
---|
4348 | getLongitudeFromMapObjectLonLat: function(moLonLat) { |
---|
4349 | return this.sphericalMercator ? |
---|
4350 | this.forwardMercator(moLonLat.Lon, moLonLat.Lat).lon : |
---|
4351 | moLonLat.Lon; |
---|
4352 | }, |
---|
4353 | |
---|
4354 | /** |
---|
4355 | * APIMethod: getLatitudeFromMapObjectLonLat |
---|
4356 | * |
---|
4357 | * Parameters: |
---|
4358 | * moLonLat - {Object} MapObject LonLat format |
---|
4359 | * |
---|
4360 | * Returns: |
---|
4361 | * {Float} Latitude of the given MapObject LonLat |
---|
4362 | */ |
---|
4363 | getLatitudeFromMapObjectLonLat: function(moLonLat) { |
---|
4364 | return this.sphericalMercator ? |
---|
4365 | this.forwardMercator(moLonLat.Lon, moLonLat.Lat).lat : |
---|
4366 | moLonLat.Lat; |
---|
4367 | }, |
---|
4368 | |
---|
4369 | /** |
---|
4370 | * APIMethod: getMapObjectLonLatFromLonLat |
---|
4371 | * |
---|
4372 | * Parameters: |
---|
4373 | * lon - {Float} |
---|
4374 | * lat - {Float} |
---|
4375 | * |
---|
4376 | * Returns: |
---|
4377 | * {Object} MapObject LonLat built from lon and lat params |
---|
4378 | */ |
---|
4379 | getMapObjectLonLatFromLonLat: function(lon, lat) { |
---|
4380 | var yLatLong; |
---|
4381 | if(this.sphericalMercator) { |
---|
4382 | var lonlat = this.inverseMercator(lon, lat); |
---|
4383 | yLatLong = new YGeoPoint(lonlat.lat, lonlat.lon); |
---|
4384 | } else { |
---|
4385 | yLatLong = new YGeoPoint(lat, lon); |
---|
4386 | } |
---|
4387 | return yLatLong; |
---|
4388 | }, |
---|
4389 | |
---|
4390 | // Pixel |
---|
4391 | |
---|
4392 | /** |
---|
4393 | * APIMethod: getXFromMapObjectPixel |
---|
4394 | * |
---|
4395 | * Parameters: |
---|
4396 | * moPixel - {Object} MapObject Pixel format |
---|
4397 | * |
---|
4398 | * Returns: |
---|
4399 | * {Integer} X value of the MapObject Pixel |
---|
4400 | */ |
---|
4401 | getXFromMapObjectPixel: function(moPixel) { |
---|
4402 | return moPixel.x; |
---|
4403 | }, |
---|
4404 | |
---|
4405 | /** |
---|
4406 | * APIMethod: getYFromMapObjectPixel |
---|
4407 | * |
---|
4408 | * Parameters: |
---|
4409 | * moPixel - {Object} MapObject Pixel format |
---|
4410 | * |
---|
4411 | * Returns: |
---|
4412 | * {Integer} Y value of the MapObject Pixel |
---|
4413 | */ |
---|
4414 | getYFromMapObjectPixel: function(moPixel) { |
---|
4415 | return moPixel.y; |
---|
4416 | }, |
---|
4417 | |
---|
4418 | /** |
---|
4419 | * APIMethod: getMapObjectPixelFromXY |
---|
4420 | * |
---|
4421 | * Parameters: |
---|
4422 | * x - {Integer} |
---|
4423 | * y - {Integer} |
---|
4424 | * |
---|
4425 | * Returns: |
---|
4426 | * {Object} MapObject Pixel from x and y parameters |
---|
4427 | */ |
---|
4428 | getMapObjectPixelFromXY: function(x, y) { |
---|
4429 | return new YCoordPoint(x, y); |
---|
4430 | }, |
---|
4431 | |
---|
4432 | // Size |
---|
4433 | |
---|
4434 | /** |
---|
4435 | * APIMethod: getMapObjectSizeFromOLSize |
---|
4436 | * |
---|
4437 | * Parameters: |
---|
4438 | * olSize - {<OpenLayers.Size>} |
---|
4439 | * |
---|
4440 | * Returns: |
---|
4441 | * {Object} MapObject Size from olSize parameter |
---|
4442 | */ |
---|
4443 | getMapObjectSizeFromOLSize: function(olSize) { |
---|
4444 | return new YSize(olSize.w, olSize.h); |
---|
4445 | }, |
---|
4446 | |
---|
4447 | CLASS_NAME: "OpenLayers.Layer.Yahoo" |
---|
4448 | }); |
---|
4449 | |
---|
4450 | /** |
---|
4451 | * Class: OpenLayers.Layer.GML |
---|
4452 | * Create a vector layer by parsing a GML file. The GML file is |
---|
4453 | * passed in as a parameter. |
---|
4454 | * *Deprecated*. To be removed in 3.0. Instead use OpenLayers.Layer.Vector |
---|
4455 | * with Protocol.HTTP and Strategy.Fixed. Provide the protocol with a |
---|
4456 | * format parameter to get the parser you want for your data. |
---|
4457 | * |
---|
4458 | * Inherits from: |
---|
4459 | * - <OpenLayers.Layer.Vector> |
---|
4460 | */ |
---|
4461 | OpenLayers.Layer.GML = OpenLayers.Class(OpenLayers.Layer.Vector, { |
---|
4462 | |
---|
4463 | /** |
---|
4464 | * Property: loaded |
---|
4465 | * {Boolean} Flag for whether the GML data has been loaded yet. |
---|
4466 | */ |
---|
4467 | loaded: false, |
---|
4468 | |
---|
4469 | /** |
---|
4470 | * APIProperty: format |
---|
4471 | * {<OpenLayers.Format>} The format you want the data to be parsed with. |
---|
4472 | */ |
---|
4473 | format: null, |
---|
4474 | |
---|
4475 | /** |
---|
4476 | * APIProperty: formatOptions |
---|
4477 | * {Object} Hash of options which should be passed to the format when it is |
---|
4478 | * created. Must be passed in the constructor. |
---|
4479 | */ |
---|
4480 | formatOptions: null, |
---|
4481 | |
---|
4482 | /** |
---|
4483 | * Constructor: OpenLayers.Layer.GML |
---|
4484 | * Load and parse a single file on the web, according to the format |
---|
4485 | * provided via the 'format' option, defaulting to GML. |
---|
4486 | * |
---|
4487 | * Parameters: |
---|
4488 | * name - {String} |
---|
4489 | * url - {String} URL of a GML file. |
---|
4490 | * options - {Object} Hashtable of extra options to tag onto the layer. |
---|
4491 | */ |
---|
4492 | initialize: function(name, url, options) { |
---|
4493 | var newArguments = []; |
---|
4494 | newArguments.push(name, options); |
---|
4495 | OpenLayers.Layer.Vector.prototype.initialize.apply(this, newArguments); |
---|
4496 | this.url = url; |
---|
4497 | }, |
---|
4498 | |
---|
4499 | /** |
---|
4500 | * APIMethod: setVisibility |
---|
4501 | * Set the visibility flag for the layer and hide/show&redraw accordingly. |
---|
4502 | * Fire event unless otherwise specified |
---|
4503 | * GML will be loaded if the layer is being made visible for the first |
---|
4504 | * time. |
---|
4505 | * |
---|
4506 | * Parameters: |
---|
4507 | * visible - {Boolean} Whether or not to display the layer |
---|
4508 | * (if in range) |
---|
4509 | * noEvent - {Boolean} |
---|
4510 | */ |
---|
4511 | setVisibility: function(visibility, noEvent) { |
---|
4512 | OpenLayers.Layer.Vector.prototype.setVisibility.apply(this, arguments); |
---|
4513 | if(this.visibility && !this.loaded){ |
---|
4514 | // Load the GML |
---|
4515 | this.loadGML(); |
---|
4516 | } |
---|
4517 | }, |
---|
4518 | |
---|
4519 | /** |
---|
4520 | * Method: moveTo |
---|
4521 | * If layer is visible and GML has not been loaded, load GML, then load GML |
---|
4522 | * and call OpenLayers.Layer.Vector.moveTo() to redraw at the new location. |
---|
4523 | * |
---|
4524 | * Parameters: |
---|
4525 | * bounds - {Object} |
---|
4526 | * zoomChanged - {Object} |
---|
4527 | * minor - {Object} |
---|
4528 | */ |
---|
4529 | moveTo:function(bounds, zoomChanged, minor) { |
---|
4530 | OpenLayers.Layer.Vector.prototype.moveTo.apply(this, arguments); |
---|
4531 | // Wait until initialisation is complete before loading GML |
---|
4532 | // otherwise we can get a race condition where the root HTML DOM is |
---|
4533 | // loaded after the GML is paited. |
---|
4534 | // See http://trac.openlayers.org/ticket/404 |
---|
4535 | if(this.visibility && !this.loaded){ |
---|
4536 | this.loadGML(); |
---|
4537 | } |
---|
4538 | }, |
---|
4539 | |
---|
4540 | /** |
---|
4541 | * Method: loadGML |
---|
4542 | */ |
---|
4543 | loadGML: function() { |
---|
4544 | if (!this.loaded) { |
---|
4545 | this.events.triggerEvent("loadstart"); |
---|
4546 | OpenLayers.Request.GET({ |
---|
4547 | url: this.url, |
---|
4548 | success: this.requestSuccess, |
---|
4549 | failure: this.requestFailure, |
---|
4550 | scope: this |
---|
4551 | }); |
---|
4552 | this.loaded = true; |
---|
4553 | } |
---|
4554 | }, |
---|
4555 | |
---|
4556 | /** |
---|
4557 | * Method: setUrl |
---|
4558 | * Change the URL and reload the GML |
---|
4559 | * |
---|
4560 | * Parameters: |
---|
4561 | * url - {String} URL of a GML file. |
---|
4562 | */ |
---|
4563 | setUrl:function(url) { |
---|
4564 | this.url = url; |
---|
4565 | this.destroyFeatures(); |
---|
4566 | this.loaded = false; |
---|
4567 | this.loadGML(); |
---|
4568 | }, |
---|
4569 | |
---|
4570 | /** |
---|
4571 | * Method: requestSuccess |
---|
4572 | * Process GML after it has been loaded. |
---|
4573 | * Called by initialize() and loadUrl() after the GML has been loaded. |
---|
4574 | * |
---|
4575 | * Parameters: |
---|
4576 | * request - {String} |
---|
4577 | */ |
---|
4578 | requestSuccess:function(request) { |
---|
4579 | var doc = request.responseXML; |
---|
4580 | |
---|
4581 | if (!doc || !doc.documentElement) { |
---|
4582 | doc = request.responseText; |
---|
4583 | } |
---|
4584 | |
---|
4585 | var options = {}; |
---|
4586 | |
---|
4587 | OpenLayers.Util.extend(options, this.formatOptions); |
---|
4588 | if (this.map && !this.projection.equals(this.map.getProjectionObject())) { |
---|
4589 | options.externalProjection = this.projection; |
---|
4590 | options.internalProjection = this.map.getProjectionObject(); |
---|
4591 | } |
---|
4592 | |
---|
4593 | var gml = this.format ? new this.format(options) : new OpenLayers.Format.GML(options); |
---|
4594 | this.addFeatures(gml.read(doc)); |
---|
4595 | this.events.triggerEvent("loadend"); |
---|
4596 | }, |
---|
4597 | |
---|
4598 | /** |
---|
4599 | * Method: requestFailure |
---|
4600 | * Process a failed loading of GML. |
---|
4601 | * Called by initialize() and loadUrl() if there was a problem loading GML. |
---|
4602 | * |
---|
4603 | * Parameters: |
---|
4604 | * request - {String} |
---|
4605 | */ |
---|
4606 | requestFailure: function(request) { |
---|
4607 | OpenLayers.Console.userError('Error in loading GML file ' + this.url); |
---|
4608 | this.events.triggerEvent("loadend"); |
---|
4609 | }, |
---|
4610 | |
---|
4611 | CLASS_NAME: "OpenLayers.Layer.GML" |
---|
4612 | }); |
---|
4613 | |
---|
4614 | /** |
---|
4615 | * Class: OpenLayers.Geometry.Rectangle |
---|
4616 | * This class is *not supported*, and probably isn't what you're looking for. |
---|
4617 | * Instead, most users probably want something like: |
---|
4618 | * (code) |
---|
4619 | * var poly = new OpenLayers.Bounds(0,0,10,10).toGeometry(); |
---|
4620 | * (end) |
---|
4621 | * This will create a rectangular Polygon geometry. |
---|
4622 | * |
---|
4623 | * Inherits: |
---|
4624 | * - <OpenLayers.Geometry> |
---|
4625 | */ |
---|
4626 | |
---|
4627 | OpenLayers.Geometry.Rectangle = OpenLayers.Class(OpenLayers.Geometry, { |
---|
4628 | |
---|
4629 | /** |
---|
4630 | * Property: x |
---|
4631 | * {Float} |
---|
4632 | */ |
---|
4633 | x: null, |
---|
4634 | |
---|
4635 | /** |
---|
4636 | * Property: y |
---|
4637 | * {Float} |
---|
4638 | */ |
---|
4639 | y: null, |
---|
4640 | |
---|
4641 | /** |
---|
4642 | * Property: width |
---|
4643 | * {Float} |
---|
4644 | */ |
---|
4645 | width: null, |
---|
4646 | |
---|
4647 | /** |
---|
4648 | * Property: height |
---|
4649 | * {Float} |
---|
4650 | */ |
---|
4651 | height: null, |
---|
4652 | |
---|
4653 | /** |
---|
4654 | * Constructor: OpenLayers.Geometry.Rectangle |
---|
4655 | * |
---|
4656 | * Parameters: |
---|
4657 | * points - {Array(<OpenLayers.Geometry.Point>)} |
---|
4658 | */ |
---|
4659 | initialize: function(x, y, width, height) { |
---|
4660 | OpenLayers.Geometry.prototype.initialize.apply(this, arguments); |
---|
4661 | |
---|
4662 | this.x = x; |
---|
4663 | this.y = y; |
---|
4664 | |
---|
4665 | this.width = width; |
---|
4666 | this.height = height; |
---|
4667 | }, |
---|
4668 | |
---|
4669 | /** |
---|
4670 | * Method: calculateBounds |
---|
4671 | * Recalculate the bounds for the geometry. |
---|
4672 | */ |
---|
4673 | calculateBounds: function() { |
---|
4674 | this.bounds = new OpenLayers.Bounds(this.x, this.y, |
---|
4675 | this.x + this.width, |
---|
4676 | this.y + this.height); |
---|
4677 | }, |
---|
4678 | |
---|
4679 | |
---|
4680 | /** |
---|
4681 | * APIMethod: getLength |
---|
4682 | * |
---|
4683 | * Returns: |
---|
4684 | * {Float} The length of the geometry |
---|
4685 | */ |
---|
4686 | getLength: function() { |
---|
4687 | var length = (2 * this.width) + (2 * this.height); |
---|
4688 | return length; |
---|
4689 | }, |
---|
4690 | |
---|
4691 | /** |
---|
4692 | * APIMethod: getArea |
---|
4693 | * |
---|
4694 | * Returns: |
---|
4695 | * {Float} The area of the geometry |
---|
4696 | */ |
---|
4697 | getArea: function() { |
---|
4698 | var area = this.width * this.height; |
---|
4699 | return area; |
---|
4700 | }, |
---|
4701 | |
---|
4702 | CLASS_NAME: "OpenLayers.Geometry.Rectangle" |
---|
4703 | }); |
---|
4704 | |
---|
4705 | /** |
---|
4706 | * Class: OpenLayers.Renderer.NG |
---|
4707 | * |
---|
4708 | * Inherits from: |
---|
4709 | * - <OpenLayers.Renderer.Elements> |
---|
4710 | */ |
---|
4711 | OpenLayers.Renderer.NG = OpenLayers.Class(OpenLayers.Renderer.Elements, { |
---|
4712 | |
---|
4713 | /** |
---|
4714 | * Constant: labelNodeType |
---|
4715 | * {String} The node type for text label containers. To be defined by |
---|
4716 | * subclasses. |
---|
4717 | */ |
---|
4718 | labelNodeType: null, |
---|
4719 | |
---|
4720 | /** |
---|
4721 | * Constructor: OpenLayers.Renderer.NG |
---|
4722 | * |
---|
4723 | * Parameters: |
---|
4724 | * containerID - {String} |
---|
4725 | * options - {Object} options for this renderer. Supported options are: |
---|
4726 | * * yOrdering - {Boolean} Whether to use y-ordering |
---|
4727 | * * zIndexing - {Boolean} Whether to use z-indexing. Will be ignored |
---|
4728 | * if yOrdering is set to true. |
---|
4729 | */ |
---|
4730 | |
---|
4731 | /** |
---|
4732 | * Method: updateDimensions |
---|
4733 | * To be extended by subclasses - here we set positioning related styles |
---|
4734 | * on HTML elements, subclasses have to do the same for renderer specific |
---|
4735 | * elements (e.g. viewBox, width and height of the rendererRoot) |
---|
4736 | * |
---|
4737 | * Parameters: |
---|
4738 | * zoomChanged - {Boolean} Has the zoom changed? If so, subclasses may have |
---|
4739 | * to update feature styles/dimensions. |
---|
4740 | */ |
---|
4741 | updateDimensions: function(zoomChanged) { |
---|
4742 | var mapExtent = this.map.getExtent(); |
---|
4743 | var renderExtent = mapExtent.scale(3); |
---|
4744 | this.setExtent(renderExtent, true); |
---|
4745 | var res = this.getResolution(); |
---|
4746 | var div = this.rendererRoot.parentNode; |
---|
4747 | var layerLeft = parseFloat(div.parentNode.style.left); |
---|
4748 | var layerTop = parseFloat(div.parentNode.style.top); |
---|
4749 | div.style.left = ((renderExtent.left - mapExtent.left) / res - layerLeft) + "px"; |
---|
4750 | div.style.top = ((mapExtent.top - renderExtent.top) / res - layerTop) + "px"; |
---|
4751 | }, |
---|
4752 | |
---|
4753 | /** |
---|
4754 | * Method: resize |
---|
4755 | */ |
---|
4756 | setSize: function() { |
---|
4757 | this.map.getExtent() && this.updateDimensions(); |
---|
4758 | }, |
---|
4759 | |
---|
4760 | /** |
---|
4761 | * Method: drawFeature |
---|
4762 | * Draw the feature. The optional style argument can be used |
---|
4763 | * to override the feature's own style. This method should only |
---|
4764 | * be called from layer.drawFeature(). |
---|
4765 | * |
---|
4766 | * Parameters: |
---|
4767 | * feature - {<OpenLayers.Feature.Vector>} |
---|
4768 | * style - {<Object>} |
---|
4769 | * |
---|
4770 | * Returns: |
---|
4771 | * {Boolean} true if the feature has been drawn completely, false if not, |
---|
4772 | * undefined if the feature had no geometry |
---|
4773 | */ |
---|
4774 | drawFeature: function(feature, style) { |
---|
4775 | if(style == null) { |
---|
4776 | style = feature.style; |
---|
4777 | } |
---|
4778 | if (feature.geometry) { |
---|
4779 | var rendered = this.drawGeometry(feature.geometry, style, feature.id); |
---|
4780 | if(rendered !== false && style.label) { |
---|
4781 | var location = feature.geometry.getCentroid(); |
---|
4782 | this.drawText(feature.id, style, location); |
---|
4783 | } else { |
---|
4784 | this.removeText(feature.id); |
---|
4785 | } |
---|
4786 | return rendered; |
---|
4787 | } |
---|
4788 | }, |
---|
4789 | |
---|
4790 | /** |
---|
4791 | * Method: drawText |
---|
4792 | * Function for drawing text labels. |
---|
4793 | * This method is only called by the renderer itself. |
---|
4794 | * |
---|
4795 | * Parameters: |
---|
4796 | * featureId - {String|DOMElement} |
---|
4797 | * style - {Object} |
---|
4798 | * location - {<OpenLayers.Geometry.Point>}, will be modified inline |
---|
4799 | * |
---|
4800 | * Returns: |
---|
4801 | * {DOMElement} container holding the text label (to be populated by |
---|
4802 | * subclasses) |
---|
4803 | */ |
---|
4804 | drawText: function(featureId, style, location) { |
---|
4805 | var label; |
---|
4806 | if (typeof featureId !== "string") { |
---|
4807 | label = featureId; |
---|
4808 | } else { |
---|
4809 | label = this.nodeFactory(featureId + this.LABEL_ID_SUFFIX, this.labelNodeType); |
---|
4810 | label._featureId = featureId; |
---|
4811 | } |
---|
4812 | label._style = style; |
---|
4813 | label._x = location.x; |
---|
4814 | label._y = location.y; |
---|
4815 | if(style.labelXOffset || style.labelYOffset) { |
---|
4816 | var xOffset = isNaN(style.labelXOffset) ? 0 : style.labelXOffset; |
---|
4817 | var yOffset = isNaN(style.labelYOffset) ? 0 : style.labelYOffset; |
---|
4818 | var res = this.getResolution(); |
---|
4819 | location.move(xOffset*res, yOffset*res); |
---|
4820 | } |
---|
4821 | |
---|
4822 | if(label.parentNode !== this.textRoot) { |
---|
4823 | this.textRoot.appendChild(label); |
---|
4824 | } |
---|
4825 | |
---|
4826 | return label; |
---|
4827 | }, |
---|
4828 | |
---|
4829 | CLASS_NAME: "OpenLayers.Renderer.NG" |
---|
4830 | }); |
---|
4831 | |
---|
4832 | // Monkey-patching Layer.Vector for Renderer.NG support |
---|
4833 | (function() { |
---|
4834 | var moveTo = OpenLayers.Layer.Vector.prototype.moveTo; |
---|
4835 | OpenLayers.Layer.Vector.prototype.moveTo = function(bounds, zoomChanged, dragging) { |
---|
4836 | if (OpenLayers.Renderer.NG && this.renderer instanceof OpenLayers.Renderer.NG) { |
---|
4837 | OpenLayers.Layer.prototype.moveTo.apply(this, arguments); |
---|
4838 | dragging || this.renderer.updateDimensions(zoomChanged); |
---|
4839 | if (!this.drawn) { |
---|
4840 | this.drawn = true; |
---|
4841 | var feature; |
---|
4842 | for(var i=0, len=this.features.length; i<len; i++) { |
---|
4843 | this.renderer.locked = (i !== (len - 1)); |
---|
4844 | feature = this.features[i]; |
---|
4845 | this.drawFeature(feature); |
---|
4846 | } |
---|
4847 | } |
---|
4848 | } else { |
---|
4849 | moveTo.apply(this, arguments); |
---|
4850 | } |
---|
4851 | } |
---|
4852 | var redraw = OpenLayers.Layer.Vector.prototype.redraw; |
---|
4853 | OpenLayers.Layer.Vector.prototype.redraw = function() { |
---|
4854 | if (OpenLayers.Renderer.NG && this.renderer instanceof OpenLayers.Renderer.NG) { |
---|
4855 | this.drawn = false; |
---|
4856 | } |
---|
4857 | redraw.apply(this, arguments); |
---|
4858 | } |
---|
4859 | })(); |
---|
4860 | |
---|
4861 | /** |
---|
4862 | * Class: OpenLayers.Renderer.SVG2 |
---|
4863 | * |
---|
4864 | * Inherits from: |
---|
4865 | * - <OpenLayers.Renderer.NG> |
---|
4866 | */ |
---|
4867 | OpenLayers.Renderer.SVG2 = OpenLayers.Class(OpenLayers.Renderer.NG, { |
---|
4868 | |
---|
4869 | /** |
---|
4870 | * Property: xmlns |
---|
4871 | * {String} |
---|
4872 | */ |
---|
4873 | xmlns: "http://www.w3.org/2000/svg", |
---|
4874 | |
---|
4875 | /** |
---|
4876 | * Property: xlinkns |
---|
4877 | * {String} |
---|
4878 | */ |
---|
4879 | xlinkns: "http://www.w3.org/1999/xlink", |
---|
4880 | |
---|
4881 | /** |
---|
4882 | * Property: symbolMetrics |
---|
4883 | * {Object} Cache for symbol metrics according to their svg coordinate |
---|
4884 | * space. This is an object keyed by the symbol's id, and values are |
---|
4885 | * an object with size, x and y properties. |
---|
4886 | */ |
---|
4887 | symbolMetrics: null, |
---|
4888 | |
---|
4889 | /** |
---|
4890 | * Constant: labelNodeType |
---|
4891 | * {String} The node type for text label containers. |
---|
4892 | */ |
---|
4893 | labelNodeType: "g", |
---|
4894 | |
---|
4895 | /** |
---|
4896 | * Constructor: OpenLayers.Renderer.SVG2 |
---|
4897 | * |
---|
4898 | * Parameters: |
---|
4899 | * containerID - {String} |
---|
4900 | */ |
---|
4901 | initialize: function(containerID) { |
---|
4902 | if (!this.supported()) { |
---|
4903 | return; |
---|
4904 | } |
---|
4905 | OpenLayers.Renderer.Elements.prototype.initialize.apply(this, |
---|
4906 | arguments); |
---|
4907 | |
---|
4908 | this.symbolMetrics = {}; |
---|
4909 | }, |
---|
4910 | |
---|
4911 | /** |
---|
4912 | * APIMethod: supported |
---|
4913 | * |
---|
4914 | * Returns: |
---|
4915 | * {Boolean} Whether or not the browser supports the SVG renderer |
---|
4916 | */ |
---|
4917 | supported: function() { |
---|
4918 | var svgFeature = "http://www.w3.org/TR/SVG11/feature#"; |
---|
4919 | return (document.implementation && |
---|
4920 | (document.implementation.hasFeature("org.w3c.svg", "1.0") || |
---|
4921 | document.implementation.hasFeature(svgFeature + "SVG", "1.1") || |
---|
4922 | document.implementation.hasFeature(svgFeature + "BasicStructure", "1.1") )); |
---|
4923 | }, |
---|
4924 | |
---|
4925 | /** |
---|
4926 | * Method: updateDimensions |
---|
4927 | * |
---|
4928 | * Parameters: |
---|
4929 | * zoomChanged - {Boolean} |
---|
4930 | */ |
---|
4931 | updateDimensions: function(zoomChanged) { |
---|
4932 | OpenLayers.Renderer.NG.prototype.updateDimensions.apply(this, arguments); |
---|
4933 | |
---|
4934 | var res = this.getResolution(); |
---|
4935 | |
---|
4936 | var width = this.extent.getWidth(); |
---|
4937 | var height = this.extent.getHeight(); |
---|
4938 | |
---|
4939 | var extentString = [ |
---|
4940 | this.extent.left, |
---|
4941 | -this.extent.top, |
---|
4942 | width, |
---|
4943 | height |
---|
4944 | ].join(" "); |
---|
4945 | this.rendererRoot.setAttributeNS(null, "viewBox", extentString); |
---|
4946 | this.rendererRoot.setAttributeNS(null, "width", width / res); |
---|
4947 | this.rendererRoot.setAttributeNS(null, "height", height / res); |
---|
4948 | |
---|
4949 | if (zoomChanged === true) { |
---|
4950 | // update styles for the new resolution |
---|
4951 | var i, len; |
---|
4952 | var nodes = this.vectorRoot.childNodes; |
---|
4953 | for (i=0, len=nodes.length; i<len; ++i) { |
---|
4954 | this.setStyle(nodes[i]); |
---|
4955 | } |
---|
4956 | var textNodes = this.textRoot.childNodes; |
---|
4957 | var label; |
---|
4958 | for (i=0, len=textNodes.length; i<len; ++i) { |
---|
4959 | label = textNodes[i]; |
---|
4960 | this.drawText(label, label._style, |
---|
4961 | new OpenLayers.Geometry.Point(label._x, label._y) |
---|
4962 | ); |
---|
4963 | } |
---|
4964 | } |
---|
4965 | }, |
---|
4966 | |
---|
4967 | /** |
---|
4968 | * Method: getNodeType |
---|
4969 | * |
---|
4970 | * Parameters: |
---|
4971 | * geometry - {<OpenLayers.Geometry>} |
---|
4972 | * style - {Object} |
---|
4973 | * |
---|
4974 | * Returns: |
---|
4975 | * {String} The corresponding node type for the specified geometry |
---|
4976 | */ |
---|
4977 | getNodeType: function(geometry, style) { |
---|
4978 | var nodeType = null; |
---|
4979 | switch (geometry.CLASS_NAME) { |
---|
4980 | case "OpenLayers.Geometry.Point": |
---|
4981 | if (style.externalGraphic) { |
---|
4982 | nodeType = "image"; |
---|
4983 | } else if (this.isComplexSymbol(style.graphicName)) { |
---|
4984 | nodeType = "svg"; |
---|
4985 | } else { |
---|
4986 | nodeType = "circle"; |
---|
4987 | } |
---|
4988 | break; |
---|
4989 | case "OpenLayers.Geometry.Rectangle": |
---|
4990 | nodeType = "rect"; |
---|
4991 | break; |
---|
4992 | case "OpenLayers.Geometry.LineString": |
---|
4993 | nodeType = "polyline"; |
---|
4994 | break; |
---|
4995 | case "OpenLayers.Geometry.LinearRing": |
---|
4996 | nodeType = "polygon"; |
---|
4997 | break; |
---|
4998 | case "OpenLayers.Geometry.Polygon": |
---|
4999 | case "OpenLayers.Geometry.Curve": |
---|
5000 | nodeType = "path"; |
---|
5001 | break; |
---|
5002 | default: |
---|
5003 | break; |
---|
5004 | } |
---|
5005 | return nodeType; |
---|
5006 | }, |
---|
5007 | |
---|
5008 | /** |
---|
5009 | * Method: setStyle |
---|
5010 | * Use to set all the style attributes to a SVG node. |
---|
5011 | * |
---|
5012 | * Takes care to adjust stroke width and point radius to be |
---|
5013 | * resolution-relative |
---|
5014 | * |
---|
5015 | * Parameters: |
---|
5016 | * node - {SVGDomElement} An SVG element to decorate |
---|
5017 | * style - {Object} |
---|
5018 | * options - {Object} Currently supported options include |
---|
5019 | * 'isFilled' {Boolean} and |
---|
5020 | * 'isStroked' {Boolean} |
---|
5021 | */ |
---|
5022 | setStyle: function(node, style, options) { |
---|
5023 | style = style || node._style; |
---|
5024 | options = options || node._options; |
---|
5025 | var resolution = this.getResolution(); |
---|
5026 | var r = node._radius; |
---|
5027 | var widthFactor = resolution; |
---|
5028 | if (node._geometryClass == "OpenLayers.Geometry.Point" && r) { |
---|
5029 | node.style.visibility = ""; |
---|
5030 | if (style.graphic === false) { |
---|
5031 | node.style.visibility = "hidden"; |
---|
5032 | } else if (style.externalGraphic) { |
---|
5033 | |
---|
5034 | if (style.graphicTitle) { |
---|
5035 | node.setAttributeNS(null, "title", style.graphicTitle); |
---|
5036 | //Standards-conformant SVG |
---|
5037 | // Prevent duplicate nodes. See issue https://github.com/openlayers/openlayers/issues/92 |
---|
5038 | var titleNode = node.getElementsByTagName("title"); |
---|
5039 | if (titleNode.length > 0) { |
---|
5040 | titleNode[0].firstChild.textContent = style.graphicTitle; |
---|
5041 | } else { |
---|
5042 | var label = this.nodeFactory(null, "title"); |
---|
5043 | label.textContent = style.graphicTitle; |
---|
5044 | node.appendChild(label); |
---|
5045 | } |
---|
5046 | } |
---|
5047 | if (style.graphicWidth && style.graphicHeight) { |
---|
5048 | node.setAttributeNS(null, "preserveAspectRatio", "none"); |
---|
5049 | } |
---|
5050 | var width = style.graphicWidth || style.graphicHeight; |
---|
5051 | var height = style.graphicHeight || style.graphicWidth; |
---|
5052 | width = width ? width : style.pointRadius*2; |
---|
5053 | height = height ? height : style.pointRadius*2; |
---|
5054 | width *= resolution; |
---|
5055 | height *= resolution; |
---|
5056 | |
---|
5057 | var xOffset = (style.graphicXOffset != undefined) ? |
---|
5058 | style.graphicXOffset * resolution : -(0.5 * width); |
---|
5059 | var yOffset = (style.graphicYOffset != undefined) ? |
---|
5060 | style.graphicYOffset * resolution : -(0.5 * height); |
---|
5061 | |
---|
5062 | var opacity = style.graphicOpacity || style.fillOpacity; |
---|
5063 | |
---|
5064 | node.setAttributeNS(null, "x", node._x + xOffset); |
---|
5065 | node.setAttributeNS(null, "y", node._y + yOffset); |
---|
5066 | node.setAttributeNS(null, "width", width); |
---|
5067 | node.setAttributeNS(null, "height", height); |
---|
5068 | node.setAttributeNS(this.xlinkns, "href", style.externalGraphic); |
---|
5069 | node.setAttributeNS(null, "style", "opacity: "+opacity); |
---|
5070 | node.onclick = OpenLayers.Renderer.SVG2.preventDefault; |
---|
5071 | } else if (this.isComplexSymbol(style.graphicName)) { |
---|
5072 | // the symbol viewBox is three times as large as the symbol |
---|
5073 | var offset = style.pointRadius * 3 * resolution; |
---|
5074 | var size = offset * 2; |
---|
5075 | var src = this.importSymbol(style.graphicName); |
---|
5076 | widthFactor = this.symbolMetrics[src.id].size * 3 / size * resolution; |
---|
5077 | |
---|
5078 | // remove the node from the dom before we modify it. This |
---|
5079 | // prevents various rendering issues in Safari and FF |
---|
5080 | var parent = node.parentNode; |
---|
5081 | var nextSibling = node.nextSibling; |
---|
5082 | if(parent) { |
---|
5083 | parent.removeChild(node); |
---|
5084 | } |
---|
5085 | |
---|
5086 | // The more appropriate way to implement this would be use/defs, |
---|
5087 | // but due to various issues in several browsers, it is safer to |
---|
5088 | // copy the symbols instead of referencing them. |
---|
5089 | // See e.g. ticket http://trac.osgeo.org/openlayers/ticket/2985 |
---|
5090 | // and this email thread |
---|
5091 | // http://osgeo-org.1803224.n2.nabble.com/Select-Control-Ctrl-click-on-Feature-with-a-graphicName-opens-new-browser-window-tc5846039.html |
---|
5092 | node.firstChild && node.removeChild(node.firstChild); |
---|
5093 | node.appendChild(src.firstChild.cloneNode(true)); |
---|
5094 | node.setAttributeNS(null, "viewBox", src.getAttributeNS(null, "viewBox")); |
---|
5095 | |
---|
5096 | node.setAttributeNS(null, "width", size); |
---|
5097 | node.setAttributeNS(null, "height", size); |
---|
5098 | node.setAttributeNS(null, "x", node._x - offset); |
---|
5099 | node.setAttributeNS(null, "y", node._y - offset); |
---|
5100 | |
---|
5101 | // now that the node has all its new properties, insert it |
---|
5102 | // back into the dom where it was |
---|
5103 | if(nextSibling) { |
---|
5104 | parent.insertBefore(node, nextSibling); |
---|
5105 | } else if(parent) { |
---|
5106 | parent.appendChild(node); |
---|
5107 | } |
---|
5108 | } else { |
---|
5109 | node.setAttributeNS(null, "r", style.pointRadius * resolution); |
---|
5110 | } |
---|
5111 | |
---|
5112 | var rotation = style.rotation; |
---|
5113 | if (rotation !== undefined || node._rotation !== undefined) { |
---|
5114 | node._rotation = rotation; |
---|
5115 | rotation |= 0; |
---|
5116 | if (node.nodeName !== "svg") { |
---|
5117 | node.setAttributeNS(null, "transform", |
---|
5118 | ["rotate(", rotation, node._x, node._y, ")"].join(" ") |
---|
5119 | ); |
---|
5120 | } else { |
---|
5121 | var metrics = this.symbolMetrics[src.id]; |
---|
5122 | node.firstChild.setAttributeNS(null, "transform", |
---|
5123 | ["rotate(", rotation, metrics.x, metrics.y, ")"].join(" ") |
---|
5124 | ); |
---|
5125 | } |
---|
5126 | } |
---|
5127 | } |
---|
5128 | |
---|
5129 | if (options.isFilled) { |
---|
5130 | node.setAttributeNS(null, "fill", style.fillColor); |
---|
5131 | node.setAttributeNS(null, "fill-opacity", style.fillOpacity); |
---|
5132 | } else { |
---|
5133 | node.setAttributeNS(null, "fill", "none"); |
---|
5134 | } |
---|
5135 | |
---|
5136 | if (options.isStroked) { |
---|
5137 | node.setAttributeNS(null, "stroke", style.strokeColor); |
---|
5138 | node.setAttributeNS(null, "stroke-opacity", style.strokeOpacity); |
---|
5139 | node.setAttributeNS(null, "stroke-width", style.strokeWidth * widthFactor); |
---|
5140 | node.setAttributeNS(null, "stroke-linecap", style.strokeLinecap || "round"); |
---|
5141 | // Hard-coded linejoin for now, to make it look the same as in VML. |
---|
5142 | // There is no strokeLinejoin property yet for symbolizers. |
---|
5143 | node.setAttributeNS(null, "stroke-linejoin", "round"); |
---|
5144 | style.strokeDashstyle && node.setAttributeNS(null, |
---|
5145 | "stroke-dasharray", this.dashStyle(style, widthFactor)); |
---|
5146 | } else { |
---|
5147 | node.setAttributeNS(null, "stroke", "none"); |
---|
5148 | } |
---|
5149 | |
---|
5150 | if (style.pointerEvents) { |
---|
5151 | node.setAttributeNS(null, "pointer-events", style.pointerEvents); |
---|
5152 | } |
---|
5153 | |
---|
5154 | if (style.cursor != null) { |
---|
5155 | node.setAttributeNS(null, "cursor", style.cursor); |
---|
5156 | } |
---|
5157 | |
---|
5158 | return node; |
---|
5159 | }, |
---|
5160 | |
---|
5161 | /** |
---|
5162 | * Method: dashStyle |
---|
5163 | * |
---|
5164 | * Parameters: |
---|
5165 | * style - {Object} |
---|
5166 | * widthFactor - {Number} |
---|
5167 | * |
---|
5168 | * Returns: |
---|
5169 | * {String} A SVG compliant 'stroke-dasharray' value |
---|
5170 | */ |
---|
5171 | dashStyle: function(style, widthFactor) { |
---|
5172 | var w = style.strokeWidth * widthFactor; |
---|
5173 | var str = style.strokeDashstyle; |
---|
5174 | switch (str) { |
---|
5175 | case 'solid': |
---|
5176 | return 'none'; |
---|
5177 | case 'dot': |
---|
5178 | return [widthFactor, 4 * w].join(); |
---|
5179 | case 'dash': |
---|
5180 | return [4 * w, 4 * w].join(); |
---|
5181 | case 'dashdot': |
---|
5182 | return [4 * w, 4 * w, widthFactor, 4 * w].join(); |
---|
5183 | case 'longdash': |
---|
5184 | return [8 * w, 4 * w].join(); |
---|
5185 | case 'longdashdot': |
---|
5186 | return [8 * w, 4 * w, widthFactor, 4 * w].join(); |
---|
5187 | default: |
---|
5188 | var parts = OpenLayers.String.trim(str).split(/\s+/g); |
---|
5189 | for (var i=0, ii=parts.length; i<ii; i++) { |
---|
5190 | parts[i] = parts[i] * widthFactor; |
---|
5191 | } |
---|
5192 | return parts.join(); |
---|
5193 | } |
---|
5194 | }, |
---|
5195 | |
---|
5196 | /** |
---|
5197 | * Method: createNode |
---|
5198 | * |
---|
5199 | * Parameters: |
---|
5200 | * type - {String} Kind of node to draw |
---|
5201 | * id - {String} Id for node |
---|
5202 | * |
---|
5203 | * Returns: |
---|
5204 | * {DOMElement} A new node of the given type and id |
---|
5205 | */ |
---|
5206 | createNode: function(type, id) { |
---|
5207 | var node = document.createElementNS(this.xmlns, type); |
---|
5208 | if (id) { |
---|
5209 | node.setAttributeNS(null, "id", id); |
---|
5210 | } |
---|
5211 | return node; |
---|
5212 | }, |
---|
5213 | |
---|
5214 | /** |
---|
5215 | * Method: nodeTypeCompare |
---|
5216 | * |
---|
5217 | * Parameters: |
---|
5218 | * node - {SVGDomElement} An SVG element |
---|
5219 | * type - {String} Kind of node |
---|
5220 | * |
---|
5221 | * Returns: |
---|
5222 | * {Boolean} Whether or not the specified node is of the specified type |
---|
5223 | */ |
---|
5224 | nodeTypeCompare: function(node, type) { |
---|
5225 | return (type == node.nodeName); |
---|
5226 | }, |
---|
5227 | |
---|
5228 | /** |
---|
5229 | * Method: createRenderRoot |
---|
5230 | * |
---|
5231 | * Returns: |
---|
5232 | * {DOMElement} The specific render engine's root element |
---|
5233 | */ |
---|
5234 | createRenderRoot: function() { |
---|
5235 | return this.nodeFactory(this.container.id + "_svgRoot", "svg"); |
---|
5236 | }, |
---|
5237 | |
---|
5238 | /** |
---|
5239 | * Method: createRoot |
---|
5240 | * |
---|
5241 | * Parameters: |
---|
5242 | * suffix - {String} suffix to append to the id |
---|
5243 | * |
---|
5244 | * Returns: |
---|
5245 | * {DOMElement} |
---|
5246 | */ |
---|
5247 | createRoot: function(suffix) { |
---|
5248 | return this.nodeFactory(this.container.id + suffix, "g"); |
---|
5249 | }, |
---|
5250 | |
---|
5251 | /** |
---|
5252 | * Method: createDefs |
---|
5253 | * |
---|
5254 | * Returns: |
---|
5255 | * {DOMElement} The element to which we'll add the symbol definitions |
---|
5256 | */ |
---|
5257 | createDefs: function() { |
---|
5258 | var defs = this.nodeFactory(this.container.id + "_defs", "defs"); |
---|
5259 | this.rendererRoot.appendChild(defs); |
---|
5260 | return defs; |
---|
5261 | }, |
---|
5262 | |
---|
5263 | /************************************** |
---|
5264 | * * |
---|
5265 | * GEOMETRY DRAWING FUNCTIONS * |
---|
5266 | * * |
---|
5267 | **************************************/ |
---|
5268 | |
---|
5269 | /** |
---|
5270 | * Method: drawPoint |
---|
5271 | * This method is only called by the renderer itself. |
---|
5272 | * |
---|
5273 | * Parameters: |
---|
5274 | * node - {DOMElement} |
---|
5275 | * geometry - {<OpenLayers.Geometry>} |
---|
5276 | * |
---|
5277 | * Returns: |
---|
5278 | * {DOMElement} or false if the renderer could not draw the point |
---|
5279 | */ |
---|
5280 | drawPoint: function(node, geometry) { |
---|
5281 | return this.drawCircle(node, geometry, 1); |
---|
5282 | }, |
---|
5283 | |
---|
5284 | /** |
---|
5285 | * Method: drawCircle |
---|
5286 | * This method is only called by the renderer itself. |
---|
5287 | * |
---|
5288 | * Parameters: |
---|
5289 | * node - {DOMElement} |
---|
5290 | * geometry - {<OpenLayers.Geometry>} |
---|
5291 | * radius - {Float} |
---|
5292 | * |
---|
5293 | * Returns: |
---|
5294 | * {DOMElement} or false if the renderer could not draw the circle |
---|
5295 | */ |
---|
5296 | drawCircle: function(node, geometry, radius) { |
---|
5297 | var x = geometry.x; |
---|
5298 | var y = -geometry.y; |
---|
5299 | node.setAttributeNS(null, "cx", x); |
---|
5300 | node.setAttributeNS(null, "cy", y); |
---|
5301 | node._x = x; |
---|
5302 | node._y = y; |
---|
5303 | node._radius = radius; |
---|
5304 | return node; |
---|
5305 | }, |
---|
5306 | |
---|
5307 | /** |
---|
5308 | * Method: drawLineString |
---|
5309 | * This method is only called by the renderer itself. |
---|
5310 | * |
---|
5311 | * Parameters: |
---|
5312 | * node - {DOMElement} |
---|
5313 | * geometry - {<OpenLayers.Geometry>} |
---|
5314 | * |
---|
5315 | * Returns: |
---|
5316 | * {DOMElement} or null if the renderer could not draw all components of |
---|
5317 | * the linestring, or false if nothing could be drawn |
---|
5318 | */ |
---|
5319 | drawLineString: function(node, geometry) { |
---|
5320 | var path = this.getComponentsString(geometry.components); |
---|
5321 | node.setAttributeNS(null, "points", path); |
---|
5322 | return node; |
---|
5323 | }, |
---|
5324 | |
---|
5325 | /** |
---|
5326 | * Method: drawLinearRing |
---|
5327 | * This method is only called by the renderer itself. |
---|
5328 | * |
---|
5329 | * Parameters: |
---|
5330 | * node - {DOMElement} |
---|
5331 | * geometry - {<OpenLayers.Geometry>} |
---|
5332 | * |
---|
5333 | * Returns: |
---|
5334 | * {DOMElement} or null if the renderer could not draw all components |
---|
5335 | * of the linear ring, or false if nothing could be drawn |
---|
5336 | */ |
---|
5337 | drawLinearRing: function(node, geometry) { |
---|
5338 | var path = this.getComponentsString(geometry.components); |
---|
5339 | node.setAttributeNS(null, "points", path); |
---|
5340 | return node; |
---|
5341 | }, |
---|
5342 | |
---|
5343 | /** |
---|
5344 | * Method: drawPolygon |
---|
5345 | * This method is only called by the renderer itself. |
---|
5346 | * |
---|
5347 | * Parameters: |
---|
5348 | * node - {DOMElement} |
---|
5349 | * geometry - {<OpenLayers.Geometry>} |
---|
5350 | * |
---|
5351 | * Returns: |
---|
5352 | * {DOMElement} or null if the renderer could not draw all components |
---|
5353 | * of the polygon, or false if nothing could be drawn |
---|
5354 | */ |
---|
5355 | drawPolygon: function(node, geometry) { |
---|
5356 | var d = []; |
---|
5357 | var draw = true; |
---|
5358 | var complete = true; |
---|
5359 | var linearRingResult, path; |
---|
5360 | for (var j=0, len=geometry.components.length; j<len; j++) { |
---|
5361 | d.push("M"); |
---|
5362 | path = this.getComponentsString( |
---|
5363 | geometry.components[j].components, " "); |
---|
5364 | d.push(path); |
---|
5365 | } |
---|
5366 | d.push("z"); |
---|
5367 | node.setAttributeNS(null, "d", d.join(" ")); |
---|
5368 | node.setAttributeNS(null, "fill-rule", "evenodd"); |
---|
5369 | return node; |
---|
5370 | }, |
---|
5371 | |
---|
5372 | /** |
---|
5373 | * Method: drawRectangle |
---|
5374 | * This method is only called by the renderer itself. |
---|
5375 | * |
---|
5376 | * Parameters: |
---|
5377 | * node - {DOMElement} |
---|
5378 | * geometry - {<OpenLayers.Geometry>} |
---|
5379 | * |
---|
5380 | * Returns: |
---|
5381 | * {DOMElement} or false if the renderer could not draw the rectangle |
---|
5382 | */ |
---|
5383 | drawRectangle: function(node, geometry) { |
---|
5384 | node.setAttributeNS(null, "x", geometry.x); |
---|
5385 | node.setAttributeNS(null, "y", -geometry.y); |
---|
5386 | node.setAttributeNS(null, "width", geometry.width); |
---|
5387 | node.setAttributeNS(null, "height", geometry.height); |
---|
5388 | return node; |
---|
5389 | }, |
---|
5390 | |
---|
5391 | /** |
---|
5392 | * Method: drawText |
---|
5393 | * Function for drawing text labels. |
---|
5394 | * This method is only called by the renderer itself. |
---|
5395 | * |
---|
5396 | * Parameters: |
---|
5397 | * featureId - {String|DOMElement} |
---|
5398 | * style - {Object} |
---|
5399 | * location - {<OpenLayers.Geometry.Point>}, will be modified inline |
---|
5400 | * |
---|
5401 | * Returns: |
---|
5402 | * {DOMElement} container holding the text label |
---|
5403 | */ |
---|
5404 | drawText: function(featureId, style, location) { |
---|
5405 | var g = OpenLayers.Renderer.NG.prototype.drawText.apply(this, arguments); |
---|
5406 | var text = g.firstChild || |
---|
5407 | this.nodeFactory(featureId + this.LABEL_ID_SUFFIX + "_text", "text"); |
---|
5408 | |
---|
5409 | var res = this.getResolution(); |
---|
5410 | text.setAttributeNS(null, "x", location.x / res); |
---|
5411 | text.setAttributeNS(null, "y", - location.y / res); |
---|
5412 | g.setAttributeNS(null, "transform", "scale(" + res + ")"); |
---|
5413 | |
---|
5414 | if (style.fontColor) { |
---|
5415 | text.setAttributeNS(null, "fill", style.fontColor); |
---|
5416 | } |
---|
5417 | if (style.fontOpacity) { |
---|
5418 | text.setAttributeNS(null, "opacity", style.fontOpacity); |
---|
5419 | } |
---|
5420 | if (style.fontFamily) { |
---|
5421 | text.setAttributeNS(null, "font-family", style.fontFamily); |
---|
5422 | } |
---|
5423 | if (style.fontSize) { |
---|
5424 | text.setAttributeNS(null, "font-size", style.fontSize); |
---|
5425 | } |
---|
5426 | if (style.fontWeight) { |
---|
5427 | text.setAttributeNS(null, "font-weight", style.fontWeight); |
---|
5428 | } |
---|
5429 | if (style.fontStyle) { |
---|
5430 | text.setAttributeNS(null, "font-style", style.fontStyle); |
---|
5431 | } |
---|
5432 | if (style.labelSelect === true) { |
---|
5433 | text.setAttributeNS(null, "pointer-events", "visible"); |
---|
5434 | text._featureId = featureId; |
---|
5435 | } else { |
---|
5436 | text.setAttributeNS(null, "pointer-events", "none"); |
---|
5437 | } |
---|
5438 | var align = style.labelAlign || OpenLayers.Renderer.defaultSymbolizer.labelAlign; |
---|
5439 | text.setAttributeNS(null, "text-anchor", |
---|
5440 | OpenLayers.Renderer.SVG2.LABEL_ALIGN[align[0]] || "middle"); |
---|
5441 | |
---|
5442 | if (OpenLayers.IS_GECKO === true) { |
---|
5443 | text.setAttributeNS(null, "dominant-baseline", |
---|
5444 | OpenLayers.Renderer.SVG2.LABEL_ALIGN[align[1]] || "central"); |
---|
5445 | } |
---|
5446 | |
---|
5447 | var labelRows = style.label.split('\n'); |
---|
5448 | var numRows = labelRows.length; |
---|
5449 | while (text.childNodes.length > numRows) { |
---|
5450 | text.removeChild(text.lastChild); |
---|
5451 | } |
---|
5452 | for (var i = 0; i < numRows; i++) { |
---|
5453 | var tspan = text.childNodes[i] || |
---|
5454 | this.nodeFactory(featureId + this.LABEL_ID_SUFFIX + "_tspan_" + i, "tspan"); |
---|
5455 | if (style.labelSelect === true) { |
---|
5456 | tspan._featureId = featureId; |
---|
5457 | } |
---|
5458 | if (OpenLayers.IS_GECKO === false) { |
---|
5459 | tspan.setAttributeNS(null, "baseline-shift", |
---|
5460 | OpenLayers.Renderer.SVG2.LABEL_VSHIFT[align[1]] || "-35%"); |
---|
5461 | } |
---|
5462 | tspan.setAttribute("x", location.x / res); |
---|
5463 | if (i == 0) { |
---|
5464 | var vfactor = OpenLayers.Renderer.SVG2.LABEL_VFACTOR[align[1]]; |
---|
5465 | if (vfactor == null) { |
---|
5466 | vfactor = -.5; |
---|
5467 | } |
---|
5468 | tspan.setAttribute("dy", (vfactor*(numRows-1)) + "em"); |
---|
5469 | } else { |
---|
5470 | tspan.setAttribute("dy", "1em"); |
---|
5471 | } |
---|
5472 | tspan.textContent = (labelRows[i] === '') ? ' ' : labelRows[i]; |
---|
5473 | if (!tspan.parentNode) { |
---|
5474 | text.appendChild(tspan); |
---|
5475 | } |
---|
5476 | } |
---|
5477 | |
---|
5478 | if (!text.parentNode) { |
---|
5479 | g.appendChild(text); |
---|
5480 | } |
---|
5481 | |
---|
5482 | return g; |
---|
5483 | }, |
---|
5484 | |
---|
5485 | /** |
---|
5486 | * Method: getComponentString |
---|
5487 | * |
---|
5488 | * Parameters: |
---|
5489 | * components - {Array(<OpenLayers.Geometry.Point>)} Array of points |
---|
5490 | * separator - {String} character between coordinate pairs. Defaults to "," |
---|
5491 | * |
---|
5492 | * Returns: |
---|
5493 | * {Object} hash with properties "path" (the string created from the |
---|
5494 | * components and "complete" (false if the renderer was unable to |
---|
5495 | * draw all components) |
---|
5496 | */ |
---|
5497 | getComponentsString: function(components, separator) { |
---|
5498 | var len = components.length; |
---|
5499 | var strings = new Array(len); |
---|
5500 | for (var i=0; i<len; i++) { |
---|
5501 | strings[i] = this.getShortString(components[i]); |
---|
5502 | } |
---|
5503 | |
---|
5504 | return strings.join(separator || ","); |
---|
5505 | }, |
---|
5506 | |
---|
5507 | /** |
---|
5508 | * Method: getShortString |
---|
5509 | * |
---|
5510 | * Parameters: |
---|
5511 | * point - {<OpenLayers.Geometry.Point>} |
---|
5512 | * |
---|
5513 | * Returns: |
---|
5514 | * {String} or false if point is outside the valid range |
---|
5515 | */ |
---|
5516 | getShortString: function(point) { |
---|
5517 | return point.x + "," + (-point.y); |
---|
5518 | }, |
---|
5519 | |
---|
5520 | /** |
---|
5521 | * Method: importSymbol |
---|
5522 | * add a new symbol definition from the rendererer's symbol hash |
---|
5523 | * |
---|
5524 | * Parameters: |
---|
5525 | * graphicName - {String} name of the symbol to import |
---|
5526 | * |
---|
5527 | * Returns: |
---|
5528 | * {DOMElement} - the imported symbol |
---|
5529 | */ |
---|
5530 | importSymbol: function (graphicName) { |
---|
5531 | if (!this.defs) { |
---|
5532 | // create svg defs tag |
---|
5533 | this.defs = this.createDefs(); |
---|
5534 | } |
---|
5535 | var id = this.container.id + "-" + graphicName; |
---|
5536 | |
---|
5537 | // check if symbol already exists in the defs |
---|
5538 | var existing = document.getElementById(id); |
---|
5539 | if (existing != null) { |
---|
5540 | return existing; |
---|
5541 | } |
---|
5542 | |
---|
5543 | var symbol = OpenLayers.Renderer.symbol[graphicName]; |
---|
5544 | if (!symbol) { |
---|
5545 | throw new Error(graphicName + ' is not a valid symbol name'); |
---|
5546 | } |
---|
5547 | |
---|
5548 | var symbolNode = this.nodeFactory(id, "symbol"); |
---|
5549 | var node = this.nodeFactory(null, "polygon"); |
---|
5550 | symbolNode.appendChild(node); |
---|
5551 | var symbolExtent = new OpenLayers.Bounds( |
---|
5552 | Number.MAX_VALUE, Number.MAX_VALUE, 0, 0); |
---|
5553 | |
---|
5554 | var points = []; |
---|
5555 | var x,y; |
---|
5556 | for (var i=0, len=symbol.length; i<len; i=i+2) { |
---|
5557 | x = symbol[i]; |
---|
5558 | y = symbol[i+1]; |
---|
5559 | symbolExtent.left = Math.min(symbolExtent.left, x); |
---|
5560 | symbolExtent.bottom = Math.min(symbolExtent.bottom, y); |
---|
5561 | symbolExtent.right = Math.max(symbolExtent.right, x); |
---|
5562 | symbolExtent.top = Math.max(symbolExtent.top, y); |
---|
5563 | points.push(x, ",", y); |
---|
5564 | } |
---|
5565 | |
---|
5566 | node.setAttributeNS(null, "points", points.join(" ")); |
---|
5567 | |
---|
5568 | var width = symbolExtent.getWidth(); |
---|
5569 | var height = symbolExtent.getHeight(); |
---|
5570 | // create a viewBox three times as large as the symbol itself, |
---|
5571 | // to allow for strokeWidth being displayed correctly at the corners. |
---|
5572 | var viewBox = [symbolExtent.left - width, |
---|
5573 | symbolExtent.bottom - height, width * 3, height * 3]; |
---|
5574 | symbolNode.setAttributeNS(null, "viewBox", viewBox.join(" ")); |
---|
5575 | this.symbolMetrics[id] = { |
---|
5576 | size: Math.max(width, height), |
---|
5577 | x: symbolExtent.getCenterLonLat().lon, |
---|
5578 | y: symbolExtent.getCenterLonLat().lat |
---|
5579 | }; |
---|
5580 | |
---|
5581 | this.defs.appendChild(symbolNode); |
---|
5582 | return symbolNode; |
---|
5583 | }, |
---|
5584 | |
---|
5585 | /** |
---|
5586 | * Method: getFeatureIdFromEvent |
---|
5587 | * |
---|
5588 | * Parameters: |
---|
5589 | * evt - {Object} An <OpenLayers.Event> object |
---|
5590 | * |
---|
5591 | * Returns: |
---|
5592 | * {String} A feature id or undefined. |
---|
5593 | */ |
---|
5594 | getFeatureIdFromEvent: function(evt) { |
---|
5595 | var featureId = OpenLayers.Renderer.Elements.prototype.getFeatureIdFromEvent.apply(this, arguments); |
---|
5596 | if(!featureId) { |
---|
5597 | var target = evt.target; |
---|
5598 | featureId = target.parentNode && target != this.rendererRoot ? |
---|
5599 | target.parentNode._featureId : undefined; |
---|
5600 | } |
---|
5601 | return featureId; |
---|
5602 | }, |
---|
5603 | |
---|
5604 | CLASS_NAME: "OpenLayers.Renderer.SVG2" |
---|
5605 | }); |
---|
5606 | |
---|
5607 | /** |
---|
5608 | * Constant: OpenLayers.Renderer.SVG2.LABEL_ALIGN |
---|
5609 | * {Object} |
---|
5610 | */ |
---|
5611 | OpenLayers.Renderer.SVG2.LABEL_ALIGN = { |
---|
5612 | "l": "start", |
---|
5613 | "r": "end", |
---|
5614 | "b": "bottom", |
---|
5615 | "t": "hanging" |
---|
5616 | }; |
---|
5617 | |
---|
5618 | /** |
---|
5619 | * Constant: OpenLayers.Renderer.SVG2.LABEL_VSHIFT |
---|
5620 | * {Object} |
---|
5621 | */ |
---|
5622 | OpenLayers.Renderer.SVG2.LABEL_VSHIFT = { |
---|
5623 | // according to |
---|
5624 | // http://www.w3.org/Graphics/SVG/Test/20061213/htmlObjectHarness/full-text-align-02-b.html |
---|
5625 | // a baseline-shift of -70% shifts the text exactly from the |
---|
5626 | // bottom to the top of the baseline, so -35% moves the text to |
---|
5627 | // the center of the baseline. |
---|
5628 | "t": "-70%", |
---|
5629 | "b": "0" |
---|
5630 | }; |
---|
5631 | |
---|
5632 | /** |
---|
5633 | * Constant: OpenLayers.Renderer.SVG2.LABEL_VFACTOR |
---|
5634 | * {Object} |
---|
5635 | */ |
---|
5636 | OpenLayers.Renderer.SVG2.LABEL_VFACTOR = { |
---|
5637 | "t": 0, |
---|
5638 | "b": -1 |
---|
5639 | }; |
---|
5640 | |
---|
5641 | /** |
---|
5642 | * Function: OpenLayers.Renderer.SVG2.preventDefault |
---|
5643 | * Used to prevent default events (especially opening images in a new tab on |
---|
5644 | * ctrl-click) from being executed for externalGraphic and graphicName symbols |
---|
5645 | */ |
---|
5646 | OpenLayers.Renderer.SVG2.preventDefault = function(e) { |
---|
5647 | e.preventDefault && e.preventDefault(); |
---|
5648 | }; |
---|