source: ether_iasi/trunk/web/resources/js/OpenLayers-2.12/lib/OpenLayers/Layer/Bing.js @ 738

Last change on this file since 738 was 738, checked in by vmipsl, 11 years ago

OpenLayers?

File size: 10.3 KB
Line 
1/* Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for
2 * full list of contributors). Published under the 2-clause BSD license.
3 * See license.txt in the OpenLayers distribution or repository for the
4 * full text of the license. */
5
6/**
7 * @requires OpenLayers/Layer/XYZ.js
8 */
9
10/**
11 * Class: OpenLayers.Layer.Bing
12 * Bing layer using direct tile access as provided by Bing Maps REST Services.
13 * See http://msdn.microsoft.com/en-us/library/ff701713.aspx for more
14 * information. Note: Terms of Service compliant use requires the map to be
15 * configured with an <OpenLayers.Control.Attribution> control and the
16 * attribution placed on or near the map.
17 *
18 * Inherits from:
19 *  - <OpenLayers.Layer.XYZ>
20 */
21OpenLayers.Layer.Bing = OpenLayers.Class(OpenLayers.Layer.XYZ, {
22
23    /**
24     * Property: key
25     * {String} API key for Bing maps, get your own key
26     *     at http://bingmapsportal.com/ .
27     */
28    key: null,
29
30    /**
31     * Property: serverResolutions
32     * {Array} the resolutions provided by the Bing servers.
33     */
34    serverResolutions: [
35        156543.03390625, 78271.516953125, 39135.7584765625,
36        19567.87923828125, 9783.939619140625, 4891.9698095703125,
37        2445.9849047851562, 1222.9924523925781, 611.4962261962891,
38        305.74811309814453, 152.87405654907226, 76.43702827453613,
39        38.218514137268066, 19.109257068634033, 9.554628534317017,
40        4.777314267158508, 2.388657133579254, 1.194328566789627,
41        0.5971642833948135, 0.29858214169740677, 0.14929107084870338,
42        0.07464553542435169
43    ],
44   
45    /**
46     * Property: attributionTemplate
47     * {String}
48     */
49    attributionTemplate: '<span class="olBingAttribution ${type}">' +
50         '<div><a target="_blank" href="http://www.bing.com/maps/">' +
51         '<img src="${logo}" /></a></div>${copyrights}' +
52         '<a style="white-space: nowrap" target="_blank" '+
53         'href="http://www.microsoft.com/maps/product/terms.html">' +
54         'Terms of Use</a></span>',
55
56    /**
57     * Property: metadata
58     * {Object} Metadata for this layer, as returned by the callback script
59     */
60    metadata: null,
61   
62    /**
63     * APIProperty: type
64     * {String} The layer identifier.  Any non-birdseye imageryType
65     *     from http://msdn.microsoft.com/en-us/library/ff701716.aspx can be
66     *     used.  Default is "Road".
67     */
68    type: "Road",
69   
70    /**
71     * APIProperty: culture
72     * {String} The culture identifier.  See http://msdn.microsoft.com/en-us/library/ff701709.aspx
73     * for the definition and the possible values.  Default is "en-US".
74     */
75    culture: "en-US",
76   
77    /**
78     * APIProperty: metadataParams
79     * {Object} Optional url parameters for the Get Imagery Metadata request
80     * as described here: http://msdn.microsoft.com/en-us/library/ff701716.aspx
81     */
82    metadataParams: null,
83
84    /** APIProperty: tileOptions
85     *  {Object} optional configuration options for <OpenLayers.Tile> instances
86     *  created by this Layer. Default is
87     *
88     *  (code)
89     *  {crossOriginKeyword: 'anonymous'}
90     *  (end)
91     */
92    tileOptions: null,
93
94    /**
95     * Constructor: OpenLayers.Layer.Bing
96     * Create a new Bing layer.
97     *
98     * Example:
99     * (code)
100     * var road = new OpenLayers.Layer.Bing({
101     *     name: "My Bing Aerial Layer",
102     *     type: "Aerial",
103     *     key: "my-api-key-here",
104     * });
105     * (end)
106     *
107     * Parameters:
108     * options - {Object} Configuration properties for the layer.
109     *
110     * Required configuration properties:
111     * key - {String} Bing Maps API key for your application. Get one at
112     *     http://bingmapsportal.com/.
113     * type - {String} The layer identifier.  Any non-birdseye imageryType
114     *     from http://msdn.microsoft.com/en-us/library/ff701716.aspx can be
115     *     used.
116     *
117     * Any other documented layer properties can be provided in the config object.
118     */
119    initialize: function(options) {
120        options = OpenLayers.Util.applyDefaults({
121            sphericalMercator: true
122        }, options);
123        var name = options.name || "Bing " + (options.type || this.type);
124       
125        var newArgs = [name, null, options];
126        OpenLayers.Layer.XYZ.prototype.initialize.apply(this, newArgs);
127        this.tileOptions = OpenLayers.Util.extend({
128            crossOriginKeyword: 'anonymous'
129        }, this.options.tileOptions);
130        this.loadMetadata(); 
131    },
132
133    /**
134     * Method: loadMetadata
135     */
136    loadMetadata: function() {
137        this._callbackId = "_callback_" + this.id.replace(/\./g, "_");
138        // link the processMetadata method to the global scope and bind it
139        // to this instance
140        window[this._callbackId] = OpenLayers.Function.bind(
141            OpenLayers.Layer.Bing.processMetadata, this
142        );
143        var params = OpenLayers.Util.applyDefaults({
144            key: this.key,
145            jsonp: this._callbackId,
146            include: "ImageryProviders"
147        }, this.metadataParams);
148        var url = "http://dev.virtualearth.net/REST/v1/Imagery/Metadata/" +
149            this.type + "?" + OpenLayers.Util.getParameterString(params);
150        var script = document.createElement("script");
151        script.type = "text/javascript";
152        script.src = url;
153        script.id = this._callbackId;
154        document.getElementsByTagName("head")[0].appendChild(script);
155    },
156   
157    /**
158     * Method: initLayer
159     *
160     * Sets layer properties according to the metadata provided by the API
161     */
162    initLayer: function() {
163        var res = this.metadata.resourceSets[0].resources[0];
164        var url = res.imageUrl.replace("{quadkey}", "${quadkey}");
165        url = url.replace("{culture}", this.culture);
166        this.url = [];
167        for (var i=0; i<res.imageUrlSubdomains.length; ++i) {
168            this.url.push(url.replace("{subdomain}", res.imageUrlSubdomains[i]));
169        }
170        this.addOptions({
171            maxResolution: Math.min(
172                this.serverResolutions[res.zoomMin],
173                this.maxResolution || Number.POSITIVE_INFINITY
174            ),
175            numZoomLevels: Math.min(
176                res.zoomMax + 1 - res.zoomMin, this.numZoomLevels
177            )
178        }, true);
179    },
180
181    /**
182     * Method: getURL
183     *
184     * Paramters:
185     * bounds - {<OpenLayers.Bounds>}
186     */
187    getURL: function(bounds) {
188        if (!this.url) {
189            return;
190        }
191        var xyz = this.getXYZ(bounds), x = xyz.x, y = xyz.y, z = xyz.z;
192        var quadDigits = [];
193        for (var i = z; i > 0; --i) {
194            var digit = '0';
195            var mask = 1 << (i - 1);
196            if ((x & mask) != 0) {
197                digit++;
198            }
199            if ((y & mask) != 0) {
200                digit++;
201                digit++;
202            }
203            quadDigits.push(digit);
204        }
205        var quadKey = quadDigits.join("");
206        var url = this.selectUrl('' + x + y + z, this.url);
207
208        return OpenLayers.String.format(url, {'quadkey': quadKey});
209    },
210   
211    /**
212     * Method: updateAttribution
213     * Updates the attribution according to the requirements outlined in
214     * http://gis.638310.n2.nabble.com/Bing-imagery-td5789168.html
215     */
216    updateAttribution: function() {
217        var metadata = this.metadata;
218        if (!metadata.resourceSets || !this.map || !this.map.center) {
219            return;
220        }
221        var res = metadata.resourceSets[0].resources[0];
222        var extent = this.map.getExtent().transform(
223            this.map.getProjectionObject(),
224            new OpenLayers.Projection("EPSG:4326")
225        );
226        var providers = res.imageryProviders,
227            zoom = OpenLayers.Util.indexOf(this.serverResolutions,
228                                           this.getServerResolution()),
229            copyrights = "", provider, i, ii, j, jj, bbox, coverage;
230        for (i=0,ii=providers.length; i<ii; ++i) {
231            provider = providers[i];
232            for (j=0,jj=provider.coverageAreas.length; j<jj; ++j) {
233                coverage = provider.coverageAreas[j];
234                // axis order provided is Y,X
235                bbox = OpenLayers.Bounds.fromArray(coverage.bbox, true);
236                if (extent.intersectsBounds(bbox) &&
237                        zoom <= coverage.zoomMax && zoom >= coverage.zoomMin) {
238                    copyrights += provider.attribution + " ";
239                }
240            }
241        }
242        this.attribution = OpenLayers.String.format(this.attributionTemplate, {
243            type: this.type.toLowerCase(),
244            logo: metadata.brandLogoUri,
245            copyrights: copyrights
246        });
247        this.map && this.map.events.triggerEvent("changelayer", {
248            layer: this,
249            property: "attribution"
250        });
251    },
252   
253    /**
254     * Method: setMap
255     */
256    setMap: function() {
257        OpenLayers.Layer.XYZ.prototype.setMap.apply(this, arguments);
258        this.updateAttribution();
259        this.map.events.register("moveend", this, this.updateAttribution);
260    },
261   
262    /**
263     * APIMethod: clone
264     *
265     * Parameters:
266     * obj - {Object}
267     *
268     * Returns:
269     * {<OpenLayers.Layer.Bing>} An exact clone of this <OpenLayers.Layer.Bing>
270     */
271    clone: function(obj) {
272        if (obj == null) {
273            obj = new OpenLayers.Layer.Bing(this.options);
274        }
275        //get all additions from superclasses
276        obj = OpenLayers.Layer.XYZ.prototype.clone.apply(this, [obj]);
277        // copy/set any non-init, non-simple values here
278        return obj;
279    },
280   
281    /**
282     * Method: destroy
283     */
284    destroy: function() {
285        this.map &&
286            this.map.events.unregister("moveend", this, this.updateAttribution);
287        OpenLayers.Layer.XYZ.prototype.destroy.apply(this, arguments);
288    },
289   
290    CLASS_NAME: "OpenLayers.Layer.Bing"
291});
292
293/**
294 * Function: OpenLayers.Layer.Bing.processMetadata
295 * This function will be bound to an instance, linked to the global scope with
296 * an id, and called by the JSONP script returned by the API.
297 *
298 * Parameters:
299 * metadata - {Object} metadata as returned by the API
300 */
301OpenLayers.Layer.Bing.processMetadata = function(metadata) {
302    this.metadata = metadata;
303    this.initLayer();
304    var script = document.getElementById(this._callbackId);
305    script.parentNode.removeChild(script);
306    window[this._callbackId] = undefined; // cannot delete from window in IE
307    delete this._callbackId;
308};
Note: See TracBrowser for help on using the repository browser.