Project

General

Profile

1
/* Copyright (c) 2006 MetaCarta, Inc., published under the BSD license.
2
 * See http://svn.openlayers.org/trunk/openlayers/license.txt for the full
3
 * text of the license. */
4

    
5
/**
6
 * @class
7
 */
8
OpenLayers.Util = new Object();
9

    
10
/**
11
 * @param {String} id
12
 * @param {OpenLayers.Pixel} px
13
 * @param {OpenLayers.Size} sz
14
 * @param {String} position
15
 * @param {String} border
16
 * @param {String} overflow
17
 */
18
OpenLayers.Util.modifyDOMElement = function(element, id, px, sz, position, 
19
                                            border, overflow) {
20

    
21
    if (id) {
22
        element.id = id;
23
    }
24
    if (px) {
25
        element.style.left = px.x + "px";
26
        element.style.top = px.y + "px";
27
    }
28
    if (sz) {
29
        element.style.width = sz.w + "px";
30
        element.style.height = sz.h + "px";
31
    }
32
    if (position) {
33
        element.style.position = position;
34
    }
35
    if (border) {
36
        element.style.border = border;
37
    }
38
    if (overflow) {
39
        element.style.overflow = overflow;
40
    }
41
};
42

    
43
/** 
44
* zIndex is NOT set
45
*
46
* @param {String} id
47
* @param {OpenLayers.Pixel} px
48
* @param {OpenLayers.Size} sz
49
* @param {String} imgURL
50
* @param {String} position
51
* @param {String} border
52
* @param {String} overflow
53
*
54
* @returns A DOM Div created with the specified attributes.
55
* @type DOMElement
56
*/
57
OpenLayers.Util.createDiv = function(id, px, sz, imgURL, position, 
58
                                     border, overflow) {
59

    
60
    var dom = document.createElement('div');
61

    
62
    //set specific properties
63
    dom.style.padding = "0";
64
    dom.style.margin = "0";
65
    if (imgURL) {
66
        dom.style.backgroundImage = 'url(' + imgURL + ')';
67
    }
68

    
69
    //set generic properties
70
    if (!id) {
71
        id = OpenLayers.Util.createUniqueID("OpenLayersDiv");
72
    }
73
    if (!position) {
74
        position = "absolute";
75
    }
76
    OpenLayers.Util.modifyDOMElement(dom, id, px, sz, 
77
                                     position, border, overflow);
78

    
79
    return dom;
80
};
81

    
82
/** 
83
* @param {String} id
84
* @param {OpenLayers.Pixel} px
85
* @param {OpenLayers.Size} sz
86
* @param {String} imgURL
87
* @param {String} position
88
* @param {String} border
89
* @param {Boolean} delayDisplay
90
*
91
* @returns A DOM Image created with the specified attributes.
92
* @type DOMElement
93
*/
94
OpenLayers.Util.createImage = function(id, px, sz, imgURL, position, border, 
95
                                       delayDisplay) {
96

    
97
    image = document.createElement("img");
98

    
99
    if(delayDisplay) {
100
        image.style.display = "none";
101
        Event.observe(image, "load", 
102
                      OpenLayers.Util.onImageLoad.bindAsEventListener(image));
103
        Event.observe(image, "error", 
104
                      OpenLayers.Util.onImageLoadError.bindAsEventListener(image));
105
        
106
    }
107
    
108
    //set special properties
109
    image.style.alt = id;
110
    image.galleryImg = "no";
111
    if (imgURL) {
112
        image.src = imgURL;
113
    }
114

    
115
    //set generic properties
116
    if (!id) {
117
        id = OpenLayers.Util.createUniqueID("OpenLayersDiv");
118
    }
119
    if (!position) {
120
        position = "relative";
121
    }
122
    OpenLayers.Util.modifyDOMElement(image, id, px, sz, position, border);
123

    
124
        
125
    return image;
126
};
127

    
128

    
129
OpenLayers.Util.onImageLoad = function() {
130
    this.style.backgroundColor = null;
131
    this.style.display = "";  
132
};
133

    
134
OpenLayers.Util.onImageLoadError = function() {
135
    this.style.backgroundColor = "pink";
136
};
137

    
138

    
139
OpenLayers.Util.alphaHack = function() {
140
    var arVersion = navigator.appVersion.split("MSIE");
141
    var version = parseFloat(arVersion[1]);
142
    
143
    return ( (document.body.filters) &&
144
                      (version >= 5.5) && (version < 7) );
145
}
146

    
147
/** 
148
* @param {DOMElement} div Div containing Alpha-adjusted Image
149
* @param {String} id
150
* @param {OpenLayers.Pixel} px
151
* @param {OpenLayers.Size} sz
152
* @param {String} imgURL
153
* @param {String} position
154
* @param {String} border
155
* @param {String} sizing 'crop', 'scale', or 'image'. Default is "scale"
156
*/ 
157
OpenLayers.Util.modifyAlphaImageDiv = function(div, id, px, sz, imgURL, 
158
                                               position, border, sizing) {
159

    
160
    OpenLayers.Util.modifyDOMElement(div, id, px, sz);
161

    
162
    var img = div.childNodes[0];
163

    
164
    if (imgURL) {
165
        img.src = imgURL;
166
    }
167
    OpenLayers.Util.modifyDOMElement(img, div.id + "_innerImage", null, sz, 
168
                                     "relative", border);
169

    
170
    if (OpenLayers.Util.alphaHack()) {
171
        div.style.display = "inline-block";
172
        if (sizing == null) {
173
            sizing = "scale";
174
        }
175
        div.style.filter = "progid:DXImageTransform.Microsoft" +
176
                           ".AlphaImageLoader(src='" + img.src + "', " +
177
                           "sizingMethod='" + sizing + "')";
178
        img.style.filter = "progid:DXImageTransform.Microsoft" +
179
                                ".Alpha(opacity=0)";
180
    }
181
};
182

    
183
/** 
184
* @param {String} id
185
* @param {OpenLayers.Pixel} px
186
* @param {OpenLayers.Size} sz
187
* @param {String} imgURL
188
* @param {String} position
189
* @param {String} border
190
* @param {String} sizing 'crop', 'scale', or 'image'. Default is "scale"
191
* @param {Boolean} delayDisplay
192
*
193
* @returns A DOM Div created with a DOM Image inside it. If the hack is 
194
*           needed for transparency in IE, it is added.
195
* @type DOMElement
196
*/ 
197
OpenLayers.Util.createAlphaImageDiv = function(id, px, sz, imgURL, 
198
                                               position, border, sizing, delayDisplay) {
199
    
200
    var div = OpenLayers.Util.createDiv();
201
    var img = OpenLayers.Util.createImage(null, null, null, null, null, null, 
202
                                          false);
203
    div.appendChild(img);
204

    
205
    if (delayDisplay) {
206
        img.style.display = "none";
207
        Event.observe(img, "load",
208
                      OpenLayers.Util.onImageLoad.bindAsEventListener(div));
209
        Event.observe(img, "error",
210
                      OpenLayers.Util.onImageLoadError.bindAsEventListener(div));
211
    }
212

    
213
    OpenLayers.Util.modifyAlphaImageDiv(div, id, px, sz, imgURL, 
214
                                        position, border, sizing);
215
    
216
    return div;
217
};
218

    
219

    
220
/** Creates a new hashtable and copies over all the keys from the 
221
*    passed-in object, but storing them under an uppercased
222
*    version of the key at which they were stored.
223
* 
224
* @param {Object} object
225
*
226
* @returns A new Object with all the same keys but uppercased
227
* @type Object
228
*/
229
OpenLayers.Util.upperCaseObject = function (object) {
230
    var uObject = new Object();
231
    for (var key in object) {
232
        uObject[key.toUpperCase()] = object[key];
233
    }
234
    return uObject;
235
};
236

    
237
/** Takes a hashtable and copies any keys that don't exist from
238
*   another hashtable, by analogy with Object.extend() from
239
*   Prototype.js.
240
*
241
* @param {Object} to
242
* @param {Object} from
243
*/
244
OpenLayers.Util.applyDefaults = function (to, from) {
245
    for (var key in from) {
246
        if (to[key] == null) {
247
            to[key] = from[key];
248
        }
249
    }
250
};
251

    
252
/**
253
* @param {Object} params
254
*
255
* @returns a concatenation of the properties of an object in 
256
*    http parameter notation. 
257
*    (ex. <i>"key1=value1&key2=value2&key3=value3"</i>)
258
* @type String
259
*/
260
OpenLayers.Util.getParameterString = function(params) {
261
    paramsArray = new Array();
262
    
263
    for (var key in params) {
264
        var value = params[key];
265
        if ((value != null) && (typeof value != 'function')) {
266
            paramsArray.push(key + "=" + value);
267
        }
268
    }
269
    
270
    return paramsArray.join("&");
271
};
272

    
273
/** 
274
* @returns The fully formatted image location string
275
* @type String
276
*/
277
OpenLayers.Util.getImagesLocation = function() {
278
    return OpenLayers._getScriptLocation() + "img/";
279
};
280

    
281

    
282

    
283
/** These could/should be made namespace aware?
284
*
285
* @param {} p
286
* @param {str} tagName
287
*
288
* @return {Array}
289
*/
290
OpenLayers.Util.getNodes=function(p, tagName) {
291
    var nodes = Try.these(
292
        function () {
293
            return OpenLayers.Util._getNodes(p.documentElement.childNodes,
294
                                            tagName);
295
        },
296
        function () {
297
            return OpenLayers.Util._getNodes(p.childNodes, tagName);
298
        }
299
    );
300
    return nodes;
301
};
302

    
303
/**
304
* @param {Array} nodes
305
* @param {str} tagName
306
*
307
* @return {Array}
308
*/
309
OpenLayers.Util._getNodes=function(nodes, tagName) {
310
    var retArray = new Array();
311
    for (var i=0;i<nodes.length;i++) {
312
        if (nodes[i].nodeName==tagName) {
313
            retArray.push(nodes[i]);
314
        }
315
    }
316

    
317
    return retArray;
318
};
319

    
320

    
321

    
322
/**
323
* @param {} parent
324
* @param {str} item
325
* @param {int} index
326
*
327
* @return {str}
328
*/
329
OpenLayers.Util.getTagText = function (parent, item, index) {
330
    var result = OpenLayers.Util.getNodes(parent, item);
331
    if (result && (result.length > 0))
332
    {
333
        if (!index) {
334
            index=0;
335
        }
336
        if (result[index].childNodes.length > 1) {
337
            return result.childNodes[1].nodeValue; 
338
        }
339
        else if (result[index].childNodes.length == 1) {
340
            return result[index].firstChild.nodeValue; 
341
        }
342
    } else { 
343
        return ""; 
344
    }
345
};
346

    
347
/**
348
 * @param {XMLNode} node
349
 * 
350
 * @returns The text value of the given node, without breaking in firefox or IE
351
 * @type String
352
 */
353
OpenLayers.Util.getXmlNodeValue = function(node) {
354
    var val = null;
355
    Try.these( 
356
        function() {
357
            val = node.text;
358
            if (!val)
359
                val = node.textContent;
360
        }, 
361
        function() {
362
            val = node.textContent;
363
        }); 
364
    return val;
365
};
366

    
367
/** 
368
* @param {Event} evt
369
* @param {HTMLDivElement} div
370
*
371
* @return {boolean}
372
*/
373
OpenLayers.Util.mouseLeft = function (evt, div) {
374
    // start with the element to which the mouse has moved
375
    var target = (evt.relatedTarget) ? evt.relatedTarget : evt.toElement;
376
    // walk up the DOM tree.
377
    while (target != div && target != null) {
378
        target = target.parentNode;
379
    }
380
    // if the target we stop at isn't the div, then we've left the div.
381
    return (target != div);
382
};
383

    
384
OpenLayers.Util.rad = function(x) {return x*Math.PI/180;};
385
OpenLayers.Util.distVincenty=function(p1, p2) {
386
    var a = 6378137, b = 6356752.3142,  f = 1/298.257223563;
387
    var L = OpenLayers.Util.rad(p2.lon - p1.lon);
388
    var U1 = Math.atan((1-f) * Math.tan(OpenLayers.Util.rad(p1.lat)));
389
    var U2 = Math.atan((1-f) * Math.tan(OpenLayers.Util.rad(p2.lat)));
390
    var sinU1 = Math.sin(U1), cosU1 = Math.cos(U1);
391
    var sinU2 = Math.sin(U2), cosU2 = Math.cos(U2);
392
    var lambda = L, lambdaP = 2*Math.PI;
393
    var iterLimit = 20;
394
    while (Math.abs(lambda-lambdaP) > 1e-12 && --iterLimit>0) {
395
        var sinLambda = Math.sin(lambda), cosLambda = Math.cos(lambda);
396
        var sinSigma = Math.sqrt((cosU2*sinLambda) * (cosU2*sinLambda) +
397
        (cosU1*sinU2-sinU1*cosU2*cosLambda) * (cosU1*sinU2-sinU1*cosU2*cosLambda));
398
        if (sinSigma==0) return 0;  // co-incident points
399
        var cosSigma = sinU1*sinU2 + cosU1*cosU2*cosLambda;
400
        var sigma = Math.atan2(sinSigma, cosSigma);
401
        var alpha = Math.asin(cosU1 * cosU2 * sinLambda / sinSigma);
402
        var cosSqAlpha = Math.cos(alpha) * Math.cos(alpha);
403
        var cos2SigmaM = cosSigma - 2*sinU1*sinU2/cosSqAlpha;
404
        var C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));
405
        lambdaP = lambda;
406
        lambda = L + (1-C) * f * Math.sin(alpha) *
407
        (sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));
408
    }
409
    if (iterLimit==0) return NaN  // formula failed to converge
410
    var uSq = cosSqAlpha * (a*a - b*b) / (b*b);
411
    var A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));
412
    var B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)));
413
    var deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
414
        B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));
415
    var s = b*A*(sigma-deltaSigma);
416
    var d = s.toFixed(3)/1000; // round to 1mm precision
417
    return d;
418
};
419
    
420
OpenLayers.Util.getArgs = function() {
421
    var args = new Object();
422
    var query = location.search.substring(1);  // Get query string.
423
    var pairs = query.split("&");              // Break at ampersand. //+pjl
424

    
425
    for(var i = 0; i < pairs.length; i++) {
426
        var pos = pairs[i].indexOf('=');       // Look for "name=value".
427
        if (pos == -1) continue;               // If not found, skip.
428
        var argname = pairs[i].substring(0,pos);  // Extract the name.
429
        var value = pairs[i].substring(pos+1); // Extract the value.
430
        args[argname] = unescape(value);          // Store as a property.
431
    }
432
    return args;                               // Return the object.
433
};
434

    
435
/**
436
 * @param {String} prefix String to prefix random id. If null, default
437
 *                         is "id_"
438
 * 
439
 * @returns A unique id string, built on the passed in prefix
440
 * @type String
441
 */
442
OpenLayers.Util.createUniqueID = function(prefix) {
443
    if (prefix == null) {
444
        prefix = "id_";
445
    }
446
    return prefix + Math.round(Math.random() * 10000);        
447
};
448

    
449
/** Constant inches per unit 
450
 *    -- borrowed from MapServer mapscale.c
451
 * 
452
 * @type Object */
453
OpenLayers.INCHES_PER_UNIT = { 
454
    'inches': 1.0,
455
    'ft': 12.0,
456
    'mi': 63360.0,
457
    'm': 39.3701,
458
    'km': 39370.1,
459
    'dd': 4374754
460
};
461
OpenLayers.INCHES_PER_UNIT["in"]= OpenLayers.INCHES_PER_UNIT.inches;
462
OpenLayers.INCHES_PER_UNIT["degrees"] = OpenLayers.INCHES_PER_UNIT.dd;
463

    
464
/** A sensible default 
465
 * @type int */
466
OpenLayers.DOTS_PER_INCH = 72;
467

    
468
/**
469
 * @param {float} scale
470
 * 
471
 * @returns A normalized scale value, in 1 / X format. 
472
 *          This means that if a value less than one ( already 1/x) is passed
473
 *          in, it just returns scale directly. Otherwise, it returns 
474
 *          1 / scale
475
 * @type float
476
 */
477
OpenLayers.Util.normalizeScale = function (scale) {
478
    var normScale = (scale > 1.0) ? (1.0 / scale) 
479
                                  : scale;
480
    return normScale;
481
};
482

    
483
/**
484
 * @param {float} scale
485
 * @param {String} units Index into OpenLayers.INCHES_PER_UNIT hashtable.
486
 *                       Default is degrees
487
 * 
488
 * @returns The corresponding resolution given passed-in scale and unit 
489
 *          parameters.
490
 * @type float
491
 */
492
OpenLayers.Util.getResolutionFromScale = function (scale, units) {
493

    
494
    if (units == null) {
495
        units = "degrees";
496
    }
497

    
498
    var normScale = OpenLayers.Util.normalizeScale(scale);
499

    
500
    var resolution = 1 / (normScale * OpenLayers.INCHES_PER_UNIT[units]
501
                                    * OpenLayers.DOTS_PER_INCH);
502
    return resolution;
503
};
(13-13/13)