1 /* Copyright (c) 2011 by MapQuery Contributors (see AUTHORS for
2 * full list of contributors). Published under the MIT license.
3 * See https://github.com/mapquery/mapquery/blob/master/LICENSE for the
4 * full text of the license. */
7 # jquery.mapquery.core.js
8 The main MapQuery file. It contains the MapQuery constructor, the MapQuery.Map
9 constructor and the MapQuery.Layer constructor.
12 ### *$('selector')*.`mapQuery([options])`
14 ####**Description**: initialise MapQuery and associate it with
17 **options** an object of key-value pairs with options for the map. Possible
20 * **layers** (array of MapQuery.Layer *or* MapQuery.Layer): Either an array
21 * or a single layer that should be added to the map
22 * **center** ({position: [x,y], zoom: z(int), box: [llx,lly,urx,ury]}):
23 * Initially go to a certain location. At least one layer (in the `layers`
24 * option) needs to be specified.
26 > Returns: $('selector') (jQuery object)
29 We can initialise MapQuery without any options, or for instance pass in a layer
30 object. The mapQuery function returns a jQuery object, to access the mapQuery object retrieve
31 the 'mapQuery' data object.
33 var map = $('#map').mapQuery(); //create an empty map
34 var map = $('#map').mapQuery({layers:[{type:'osm'}]); //create a map with osm
36 var mq = map.data('mapQuery'); //get the MapQuery object
38 $.MapQuery = $.MapQuery || {};
46 The MapQuery.Map object. It is automatically constructed from the options
47 given in the `mapQuery([options])` constructor. The Map object is refered
48 to as _map_ in the documentation.
50 $.MapQuery.Map = function(element, options) {
52 //If there are a maxExtent and a projection other than Spherical Mercator
53 //automagically set maxResolution if it is not set
54 //TODO smo 20110614: put maxExtent and maxResolution setting in the
55 //proper option building routine
57 if(!options.maxResolution&&options.maxExtent&&options.projection){
58 options.maxResolution = (options.maxExtent[2]-options.maxExtent[0])/256;
60 this.options = $.extend({}, new $.fn.mapQuery.defaults.map(), options);
62 this.element = element;
63 // TODO vmx 20110609: do proper options building
64 // TODO SMO 20110616: make sure that all projection strings are uppercase
65 // smo 20110620: you need the exact map options in the overviewmap widget
66 // as such we need to preserve them
67 this.olMapOptions = $.extend({}, this.options);
68 delete this.olMapOptions.layers;
69 delete this.olMapOptions.maxExtent;
70 delete this.olMapOptions.zoomToMaxExtent;
71 //TODO SMO20110630 the maxExtent is in mapprojection, decide whether or
72 //not we need to change it to displayProjection
73 this.maxExtent = this.options.maxExtent;
74 this.olMapOptions.maxExtent = new OpenLayers.Bounds(
75 this.maxExtent[0],this.maxExtent[1],this.maxExtent[2],this.maxExtent[3]);
78 OpenLayers.IMAGE_RELOAD_ATTEMPTS = 3;
79 OpenLayers.Util.onImageLoadErrorColor = "transparent";
81 // create the OpenLayers Map
82 this.olMap = new OpenLayers.Map(this.element[0], this.olMapOptions);
84 //OpenLayers doesn't want to return a maxExtent when there is no baselayer
85 //set (eg on an empty map, so we create a fake baselayer
86 this.olMap.addLayer(new OpenLayers.Layer('fake', {baseLayer: true}));
88 // Keep IDs of vector layer for select feature control
89 this.vectorLayers = [];
90 this.selectFeatureControl = null;
91 // Counts up to create unique IDs
94 element.data('mapQuery', this);
97 // To bind and trigger jQuery events
99 // create triggers for all OpenLayers map events
101 $.each(this.olMap.EVENT_TYPES, function(i, evt) {
102 events[evt] = function() {
103 self.events.trigger(evt, arguments);
106 this.olMap.events.on(events);
108 // Add layers to the map
109 if (this.options.layers!==undefined) {
110 this.layers(this.options.layers);
111 // You can only go to some location if there were layers added
112 if (this.options.center!==undefined) {
113 this.center(this.options.center);
117 // zoom to the maxExtent of the map if no precise location was specified
118 if (this.options.zoomToMaxExtent && this.options.center===undefined) {
119 this.olMap.zoomToMaxExtent();
123 $.MapQuery.Map.prototype = {
125 ###*map*.`layers([options])`
127 ####**Description**: get/set the layers of the map
129 **options** an object of key-value pairs with options to create one or
132 >Returns: [layer] (array of MapQuery.Layer)
135 The `.layers()` method allows us to attach layers to a mapQuery object. It takes
136 an options object with layer options. To add multiple layers, create an array of
137 layer options objects. If an options object is given, it will return the
138 resulting layer(s). We can also use it to retrieve all layers currently attached
142 var osm = map.layers({type:'osm'}); //add an osm layer to the map
143 var layers = map.layers(); //get all layers of the map
146 layers: function(options) {
147 //var o = $.extend({}, options);
149 switch(arguments.length) {
151 return this._allLayers();
153 if (!$.isArray(options)) {
154 return this._addLayer(options);
157 return $.map(options, function(layer) {
158 return self._addLayer(layer);
163 throw('wrong argument number');
166 // Returns all layers as an array, sorted by there order in the map. First
167 // element in the array is the topmost layer
168 _allLayers: function() {
170 $.each(this.layersList, function(id, layer) {
171 var item = [layer.position(), layer];
174 var sorted = layers.sort( function compare(a, b) {
177 var result = $.map(sorted, function(item) {
180 return result.reverse();
182 _addLayer: function(options) {
183 var id = this._createId();
184 var layer = new $.MapQuery.Layer(this, id, options);
185 this.layersList[id] = layer;
186 if (layer.isVector) {
187 this.vectorLayers.push(id);
189 this._updateSelectFeatureControl(this.vectorLayers);
190 this.events.trigger('mqAddLayer',layer);
193 // Creates a new unique ID for a layer
194 _createId: function() {
195 return 'mapquery' + this.idCounter++;
197 _removeLayer: function(id) {
198 // remove id from vectorlayer if it is there list
199 this.vectorLayers = $.grep(this.vectorLayers, function(elem) {
202 this._updateSelectFeatureControl(this.vectorLayers);
203 this.events.trigger('mqRemoveLayer',id);
204 delete this.layersList[id];
205 // XXX vmx: shouldn't the layer be destroyed() properly?
209 ###*map*.`center([options])`
211 ####**Description**: get/set the extent, zoom and position of the map
213 **position** the position as [x,y] in displayProjection (default EPSG:4326)
215 **zoom** the zoomlevel as integer to zoom the map to
216 **box** an array with the lower left x, lower left y, upper right x,
217 upper right y to zoom the map to,
218 this will take precedent when conflicting with any of the above values
219 **projection** the projection the coordinates are in, default is
220 the displayProjection
222 >Returns: {position: [x,y], zoom: z(int), box: [llx,lly,urx,ury]}
225 The `.center()` method allows us to move to map to a specific zoom level,
226 specific position or a specific extent. We can specify the projection of the
227 coordinates to override the displayProjection. For instance you want to show
228 the coordinates in 4326, but you have a dataset in EPSG:28992
229 (dutch projection). We can also retrieve the current zoomlevel, position and
230 extent from the map. The coordinates are returned in displayProjection.
233 var center = map.center(); //get the current zoom, position and extent
234 map.center({zoom:4}); //zoom to zoomlevel 4
235 map.center({position:[5,52]}); //pan to point 5,52
236 map.center(box:[-180,-90,180,90]); //zoom to the box -180,-900,180,90
237 //pan to point 125000,485000 in dutch projection
238 map.center({position:[125000,485000],projection:'EPSG:28992'});
240 center: function (options) {
243 // Determine source projection
244 var sourceProjection = null;
247 if(options && options.projection) {
248 sourceProjection = options.projection.CLASS_NAME ===
249 'OpenLayers.Projection' ? options.projection :
250 new OpenLayers.Projection(options.projection);
252 var displayProjection = this.olMap.displayProjection;
253 if(!displayProjection) {
255 sourceProjection = new OpenLayers.Projection('EPSG:4326');
257 sourceProjection = displayProjection.CLASS_NAME ===
258 'OpenLayers.Projection' ? displayProjection :
259 new OpenLayers.Projection(displayProjection);
263 // Get the current position
264 if (arguments.length===0) {
265 position = this.olMap.getCenter();
266 zoom = this.olMap.getZoom();
267 box = this.olMap.getExtent();
268 mapProjection = this.olMap.getProjectionObject();
271 if (!mapProjection.equals(sourceProjection)) {
272 position.transform(mapProjection, sourceProjection);
274 box.transform(mapProjection,sourceProjection);
275 box = box!==null ? box.toArray() : [];
277 position: [position.lon, position.lat],
278 zoom: this.olMap.getZoom(),
283 // Zoom to the extent of the box
284 if (options.box!==undefined) {
285 mapProjection = this.olMap.getProjectionObject();
286 box = new OpenLayers.Bounds(
287 options.box[0], options.box[1],options.box[2], options.box[3]);
288 if (!mapProjection.equals(sourceProjection)) {
289 box.transform(sourceProjection,mapProjection);
291 this.olMap.zoomToExtent(box);
294 // Only zoom is given
295 else if (options.position===undefined) {
296 this.olMap.zoomTo(options.zoom);
298 // Position is given, zoom maybe as well
300 position = new OpenLayers.LonLat(options.position[0],
301 options.position[1]);
302 mapProjection = this.olMap.getProjectionObject();
303 if (!mapProjection.equals(sourceProjection)) {
304 position.transform(sourceProjection, mapProjection);
306 // options.zoom might be undefined, so we are good to
308 this.olMap.setCenter(position, options.zoom);
311 _updateSelectFeatureControl: function(layerIds) {
312 var vectorLayers = [];
313 var layersList = this.layersList;
314 if (this.selectFeatureControl!==null) {
315 this.selectFeatureControl.deactivate();
316 this.selectFeatureControl.destroy();
318 $.each(layerIds, function() {
319 vectorLayers.push(layersList[this].olLayer);
321 this.selectFeatureControl = new OpenLayers.Control.SelectFeature(
323 this.olMap.addControl(this.selectFeatureControl);
324 this.selectFeatureControl.activate();
327 this.events.bind.apply(this.events, arguments);
330 this.events.one.apply(this.events, arguments);
332 destroy: function() {
333 this.olMap.destroy();
334 this.element.removeData('mapQuery');
343 The MapQuery.Layer object. It is constructed with layer options object in the
344 map.`layers([options])` function or by passing a `layer:{options}` object in
345 the `mapQuery()` constructor. The Layer object is refered to as _layer_ in the
348 $.MapQuery.Layer = function(map, id, options) {
351 // apply default options that are not specific to a layer
354 this.label = options.label || this.id;
355 // a reference to the map object is needed as it stores e.g. the list
356 // of all layers (and we need to keep track of it, if we delete a
360 // true if this layer is a vector layer
361 this.isVector = false;
363 // to bind and trigger jQuery events
366 // create the actual layer based on the options
367 // Returns layer and final options for the layer (for later re-use,
368 // e.g. zoomToMaxExtent).
369 var res = $.MapQuery.Layer.types[options.type.toLowerCase()].call(
371 this.olLayer = res.layer;
372 this.options = res.options;
374 // create triggers for all OpenLayers layer events
376 $.each(this.olLayer.EVENT_TYPES, function(i, evt) {
377 events[evt] = function() {
378 self.events.trigger(evt, arguments);
379 self.map.events.trigger(evt, arguments);
382 this.olLayer.events.on(events);
384 this.map.olMap.addLayer(this.olLayer);
387 $.MapQuery.Layer.prototype = {
389 ###*layer*.`down([delta])`
391 ####**Description**: move the layer down in the layer stack of the map
393 **delta** the amount of layers the layer has to move down in the layer
396 >Returns layer (MapQuery.Layer)
399 The `.down()` method is a shortcut method for `.position(pos)` which makes
400 it easier to move a layer down in the layerstack relative to its current
401 position. It takes an integer and will try to move the layer down the number of
402 places given. If delta is bigger than the current position in the stack, it
403 will put the layer at the bottom.
406 layer.down(); //move layer 1 place down
407 layer.down(3); //move layer 3 places down
410 down: function(delta) {
412 var pos = this.position();
414 if (pos<0) {pos = 0;}
418 // NOTE vmx: this would be pretty cool, but it's not easily possible
419 // you could use $.each($.geojq.layer())) instead, this is for pure
421 each: function () {},
423 ###*layer*.`remove()`
425 ####**Description**: remove the layer from the map
427 >Returns: id (string)
430 The `.remove()` method allows us to remove a layer from the map.
431 It returns an id to allow widgets to remove their references to the
434 var id = layer.remove(); //remove this layer
439 this.map.olMap.removeLayer(this.olLayer);
440 // remove references to this layer that are stored in the
442 return this.map._removeLayer(this.id);
445 ###*layer*.`position([position])`
447 ####**Description**: get/set the `position` of the layer in the layer
450 **position** an integer setting the new position of the layer in the layer stack
452 >Returns: position (integer)
455 The `.position()` method allows us to change the position of the layer in the
456 layer stack. It will take into account the hidden baselayer that is used by
457 OpenLayers. The lowest layer is position 0. If no position is given, it will
458 return the current postion.
461 var pos = layer.position(); //get position of layer in the layer stack
462 layer.position(2); //put layer on position 2 in the layer stack
465 position: function(pos) {
466 if (pos===undefined) {
467 return this.map.olMap.getLayerIndex(this.olLayer)-1;
470 return this.map.olMap.setLayerIndex(this.olLayer, pos+1);
474 ###*layer*.`up([delta])`
476 ####**Description**: move the layer up in the layer stack of the map
478 **delta** the amount of layers the layer has to move up in the layer
481 >Returns: layer (MapQuery.Layer)
484 The `.up()` method is a shortcut method for `.position(pos)` which makes
485 it easier to move a layer up in the layerstack relative to its current
486 position. It takes an integer and will move the layer up the number of places
491 layer.up(); //move layer 1 place up
492 layer.up(3); //move layer 3 places up
494 up: function(delta) {
496 var pos = this.position();
502 ###*layer*.`visible([visible])`
504 ####**Description**: get/set the `visible` state of the layer
506 **visible** a boolean setting the visibiliyu of the layer
508 >Returns: visible (boolean)
511 The `.visible()` method allows us to change the visibility of the layer.
512 If no visible is given, it will return the current visibility.
515 var vis = layer.visible(); //get the visibility of layer
516 layer.visible(true); //set visibility of layer to true
519 visible: function(vis) {
520 if (vis===undefined) {
521 return this.olLayer.getVisibility();
524 this.olLayer.setVisibility(vis);
529 ###*layer*.`opacity([opacity])`
531 ####**Description**: get/set the `opacity` of the layer
533 **position** a float [0-1] setting the opacity of the layer
535 >Returns: opacity (float)
538 The `.opacity()` method allows us to change the opacity of the layer.
539 If no opacity is given, it will return the current opacity.
542 var opac = layer.opacity(); //get opacity of layer
543 layer.opacity(0.7); //set opacity of layer to 0.7
546 opacity: function(opac) {
547 if (opac===undefined) {
548 // this.olLayer.opacity can be null if never
549 // set so return the visibility
550 var value = this.olLayer.opacity ?
551 this.olLayer.opacity : this.olLayer.getVisibility();
555 this.olLayer.setOpacity(opac);
559 // every event gets the layer passed in
561 this.events.bind.apply(this.events, arguments);
564 this.events.one.apply(this.events, arguments);
568 $.fn.mapQuery = function(options) {
569 return this.each(function() {
570 var instance = $.data(this, 'mapQuery');
572 $.data(this, 'mapQuery', new $.MapQuery.Map($(this), options));
577 $.extend($.MapQuery.Layer, {
580 ###*layer* `{type:bing}`
582 ####**Description**: create a Bing maps layer
584 **view** a string ['road','hybrid','satellite'] to define which Bing maps
585 layer to use (default road)
586 **key** Bing Maps API key for your application. Get you own at
587 http://bingmapsportal.com/
588 **label** string with the name of the layer
592 type:'bing', //create a bing maps layer
593 view:'satellite', //use the bing satellite layer
594 key:'ArAGGPJ16xm0RX' //the Bing maps API key
598 bing: function(options) {
599 var o = $.extend(true, {}, $.fn.mapQuery.defaults.layer.all,
600 $.fn.mapQuery.defaults.layer.bing,
605 view = 'Road'; break;
607 view = 'AerialWithLabels'; break;
609 view = 'Aerial'; break;
612 layer: new OpenLayers.Layer.Bing({type:view,key:o.key}),
616 //Not sure this one is worth pursuing works with ecwp:// & jpip:// urls
617 //See ../lib/NCSOpenLayersECWP.js
618 ecwp: function(options) {
619 var o = $.extend(true, {}, $.fn.mapQuery.defaults.layer.all,
620 $.fn.mapQuery.defaults.layer.raster,
623 layer: new OpenLayers.Layer.ECWP(o.label, o.url, o),
628 ###*layer* `{type:google}`
630 ####**Description**: create a Google maps layer
632 **view** a string ['road','hybrid','satellite'] to define which Google maps
633 layer to use (default road)
634 **label** string with the name of the layer
637 *Note* you need to include the google maps v3 API in your application by adding
638 `<script src="http://maps.google.com/maps/api/js?v=3.5&sensor=false"type="text/javascript"></script>`
642 type:'google', //create a google maps layer
643 view:'hybrid' //use the google hybridlayer
647 google: function(options) {
648 var o = $.extend(true, {}, $.fn.mapQuery.defaults.layer.all,
649 $.fn.mapQuery.defaults.layer.google,
654 view = google.maps.MapTypeId.ROADMAP; break;
656 view = google.maps.MapTypeId.TERRAIN; break;
658 view = google.maps.MapTypeId.HYBRID; break;
660 view = google.maps.MapTypeId.SATELLITE; break;
663 layer: new OpenLayers.Layer.Google({type:view}),
668 ###*layer* `{type:vector}`
670 ####**Description**: create a vector layer
672 **label** string with the name of the layer
676 type:'vector' //create a vector layer
680 vector: function(options) {
681 var o = $.extend(true, {}, $.fn.mapQuery.defaults.layer.all,
682 $.fn.mapQuery.defaults.layer.vector,
684 this.isVector = true;
686 layer: new OpenLayers.Layer.Vector(o.label),
691 ###*layer* `{type:json}`
693 ####**Description**: create a JSON layer
695 **url** a string pointing to the location of the JSON data
696 **strategies** a string ['bbox','cluster','filter','fixed','paging','refresh','save']
697 stating which update strategy should be used (default fixed)
698 (see also http://dev.openlayers.org/apidocs/files/OpenLayers/Strategy-js.html)
699 **projection** a string with the projection of the JSON data (default EPSG:4326)
700 **styleMap** {object} the style to be used to render the JSON data
701 **label** string with the name of the layer
706 url: 'data/reservate.json',
711 json: function(options) {
712 var o = $.extend(true, {}, $.fn.mapQuery.defaults.layer.all,
713 $.fn.mapQuery.defaults.layer.vector,
715 this.isVector = true;
717 for (var i in o.strategies) {
718 if(o.strategies.hasOwnProperty(i)) {
719 switch(o.strategies[i].toLowerCase()) {
721 strategies.push(new OpenLayers.Strategy.BBOX());
724 strategies.push(new OpenLayers.Strategy.Cluster());
727 strategies.push(new OpenLayers.Strategy.Filter());
730 strategies.push(new OpenLayers.Strategy.Fixed());
733 strategies.push(new OpenLayers.Strategy.Paging());
736 strategies.push(new OpenLayers.Strategy.Refresh());
739 strategies.push(new OpenLayers.Strategy.Save());
745 // only use JSONP if we use http(s)
746 if (o.url.match(/^https?:\/\//)!==null &&
747 !$.MapQuery.util.sameOrigin(o.url)) {
755 protocol: new OpenLayers.Protocol[protocol]({
757 format: new OpenLayers.Format.GeoJSON()
759 strategies: strategies,
760 projection: o.projection || 'EPSG:4326',
764 layer: new OpenLayers.Layer.Vector(o.label, params),
769 ###*layer* `{type:osm}`
771 ####**Description**: create an OpenStreetMap layer
774 **label** string with the name of the layer
775 **url** A single URL (string) or an array of URLs to OSM-like server like
777 **attribution** A string to put some attribution on the map
782 'http://a.tile.cloudmade.com/<yourapikey>/999/256/${z}/${x}/${y}.png',
783 'http://b.tile.cloudmade.com/<yourapikey>/999/256/${z}/${x}/${y}.png',
784 'http://c.tile.cloudmade.com/<yourapikey>/999/256/${z}/${x}/${y}.png'
786 attribution: "Data © 2009 <a href='http://openstreetmap.org/'>
787 OpenStreetMap</a>. Rendering © 2009
788 <a href='http://cloudmade.com'>CloudMade</a>."
792 osm: function(options) {
793 var o = $.extend(true, {}, $.fn.mapQuery.defaults.layer.all,
794 $.fn.mapQuery.defaults.layer.osm,
796 var label = options.label || undefined;
797 var url = options.url || undefined;
799 layer: new OpenLayers.Layer.OSM(label, url, o),
804 ###*layer* `{type:wms}`
806 ####**Description**: create a WMS layer
808 **url** a string pointing to the location of the WMS service
809 **layers** a string with the name of the WMS layer(s)
810 **format** a string with format of the WMS image (default image/jpeg)
811 **transparent** a boolean for requesting images with transparency
812 **label** string with the name of the layer
817 url:'http://vmap0.tiles.osgeo.org/wms/vmap0',
822 wms: function(options) {
823 var o = $.extend(true, {}, $.fn.mapQuery.defaults.layer.all,
824 $.fn.mapQuery.defaults.layer.raster,
828 transparent: o.transparent,
832 layer: new OpenLayers.Layer.WMS(o.label, o.url, params, o),
836 //TODO complete this documentation
838 ###*layer* `{type:wmts}`
840 ####**Description**: create a WMTS (tiling) layer
842 **url** a string pointing to the location of the WMTS service
843 **layer** a string with the name of the WMTS layer
844 **matrixSet** a string with one of the advertised matrix set identifiers
845 **style** a string with one of the advertised layer styles
846 **label** string with the name of the layer
854 wmts: function(options) {
855 var o = $.extend(true, {}, $.fn.mapQuery.defaults.layer.all,
856 $.fn.mapQuery.defaults.layer.wmts);
857 //smo 20110614 the maxExtent is set here with OpenLayers.Bounds
858 if (options.sphericalMercator===true) {
860 maxExtent: new OpenLayers.Bounds(
861 -128 * 156543.0339, -128 * 156543.0339,
862 128 * 156543.0339, 128 * 156543.0339),
863 maxResolution: 156543.0339,
865 projection: 'EPSG:900913',
869 $.extend(true, o, options);
870 // use by default all options that were passed in for the final
871 // openlayers layer consrtuctor
872 var params = $.extend(true, {}, o);
874 // remove trailing slash
875 if (params.url.charAt(params.url.length-1)==='/') {
876 params.url = params.url.slice(0, params.url.length-1);
878 // if no options that influence the URL where set, extract them
879 // from the given URL
880 if (o.layer===undefined && o.matrixSet===undefined &&
881 o.style===undefined) {
882 var url = $.MapQuery.util.parseUri(params.url);
883 var urlParts = url.path.split('/');
884 var wmtsPath = urlParts.slice(urlParts.length-3);
885 params.url = url.protocol ? url.protocol + '//' : '';
886 params.url += url.authority +
887 // remove WMTS version (1.0.0) as well
888 urlParts.slice(0, urlParts.length-4).join('/');
889 params.layer = wmtsPath[0];
890 params.style = wmtsPath[1];
891 params.matrixSet = wmtsPath[2];
894 layer: new OpenLayers.Layer.WMTS(params),
901 // default options for the map and layers
902 $.fn.mapQuery.defaults = {
903 // The controls for the map are per instance, therefore it need to
904 // be an function that can be initiated per instance
907 // Remove quirky moveTo behavior, probably not a good idea in the
911 // Since OL2.11 the Navigation control includes touch navigation as well
912 new OpenLayers.Control.Navigation({
919 new OpenLayers.Control.ArgParser(),
920 new OpenLayers.Control.Attribution(),
921 new OpenLayers.Control.KeyboardDefaults()
924 maxExtent: [-128*156543.0339,
928 maxResolution: 156543.0339,
930 projection: 'EPSG:900913',
931 displayProjection: 'EPSG:4326',
932 zoomToMaxExtent: true,
939 //in general it is kinda pointless to load tiles outside a maxextent
940 displayOutsideMaxExtent: false
943 transitionEffect: 'resize',
945 sphericalMercator: true
948 transitionEffect: 'resize',
950 sphericalMercator: true
953 transitionEffect: 'resize',
954 sphericalMercator: true
957 // options for raster layers
961 // options for vector layers
962 strategies: ['fixed']
965 format: 'image/jpeg',
966 requestEncoding: 'REST',
967 sphericalMercator: false
972 // Some utility functions
974 $.MapQuery.util = {};
975 // http://blog.stevenlevithan.com/archives/parseuri (2010-12-18)
977 // (c) Steven Levithan <stevenlevithan.com>
979 // Edited to include the colon in the protocol, just like it is
980 // with window.location.protocol
981 $.MapQuery.util.parseUri = function (str) {
982 var o = $.MapQuery.util.parseUri.options,
983 m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
987 while (i--) {uri[o.key[i]] = m[i] || "";}
990 uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
991 if ($1) {uri[o.q.name][$1] = $2;}
996 $.MapQuery.util.parseUri.options = {
998 key: ["source", "protocol", "authority", "userInfo", "user",
999 "password", "host", "port", "relative", "path", "directory",
1000 "file", "query", "anchor"],
1003 parser: /(?:^|&)([^&=]*)=?([^&]*)/g
1006 strict: /^(?:([^:\/?#]+:))?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
1007 loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+:))?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
1010 // Checks whether a URL conforms to the same origin policy or not
1011 $.MapQuery.util.sameOrigin = function(url) {
1012 var parsed = $.MapQuery.util.parseUri(url);
1013 parsed.protocol = parsed.protocol || 'file:';
1014 parsed.port = parsed.port || "80";
1017 domain: document.domain,
1018 port: window.location.port,
1019 protocol: window.location.protocol
1021 current.port = current.port || "80";
1023 return parsed.protocol===current.protocol &&
1024 parsed.port===current.port &&
1025 // the current domain is a suffix of the parsed domain
1026 parsed.host.match(current.domain + '$')!==null;