New OpenLayers.Projection.defaults property.
This allows us to simplify the map and layer configuration, because now the projection also defines defaults for maxExtent, maxResolution and units. This change also adds transforms for SRS aliases for EPSG:4326 and centralizes axis order information in OpenLayers.Projection.defaults.
This commit is contained in:
@@ -12,7 +12,10 @@
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
<style type="text/css">
|
||||
.olControlAttribution {
|
||||
bottom: 0px
|
||||
bottom: 0px;
|
||||
left: 2px;
|
||||
right: inherit;
|
||||
width: 400px;
|
||||
}
|
||||
#map {
|
||||
height: 512px;
|
||||
@@ -42,10 +45,7 @@
|
||||
div: "map",
|
||||
projection: "EPSG:900913",
|
||||
displayProjection: "EPSG:4326",
|
||||
units: "m",
|
||||
numZoomLevels: 18,
|
||||
maxResolution: 156543.0339,
|
||||
maxExtent: [-20037508, -20037508, 20037508, 20037508],
|
||||
numZoomLevels: 18
|
||||
});
|
||||
|
||||
// create Google Mercator layers
|
||||
|
||||
@@ -473,8 +473,18 @@ OpenLayers.Layer = OpenLayers.Class({
|
||||
this.options = {};
|
||||
}
|
||||
|
||||
// allow array for extents
|
||||
if (newOptions) {
|
||||
// make sure this.projection references a projection object
|
||||
if(typeof newOptions.projection == "string") {
|
||||
newOptions.projection = new OpenLayers.Projection(newOptions.projection);
|
||||
}
|
||||
if (newOptions.projection) {
|
||||
// get maxResolution, units and maxExtent from projection defaults if
|
||||
// they are not defined already
|
||||
OpenLayers.Util.applyDefaults(newOptions,
|
||||
OpenLayers.Projection.defaults[newOptions.projection.getCode()]);
|
||||
}
|
||||
// allow array for extents
|
||||
if (newOptions.maxExtent && !(newOptions.maxExtent instanceof OpenLayers.Bounds)) {
|
||||
newOptions.maxExtent = new OpenLayers.Bounds(newOptions.maxExtent);
|
||||
}
|
||||
@@ -488,12 +498,7 @@ OpenLayers.Layer = OpenLayers.Class({
|
||||
|
||||
// add new options to this
|
||||
OpenLayers.Util.extend(this, newOptions);
|
||||
|
||||
// make sure this.projection references a projection object
|
||||
if(typeof this.projection == "string") {
|
||||
this.projection = new OpenLayers.Projection(this.projection);
|
||||
}
|
||||
|
||||
|
||||
// get the units from the projection, if we have a projection
|
||||
// and it it has units
|
||||
if(this.projection && this.projection.getUnits()) {
|
||||
@@ -633,6 +638,12 @@ OpenLayers.Layer = OpenLayers.Class({
|
||||
this.units || this.map.units;
|
||||
|
||||
this.initResolutions();
|
||||
if (!this.resolutions) {
|
||||
throw(
|
||||
"Could not calculate resolutions for layer " + this.name +
|
||||
". Configure maxResolution or resolutions or scales."
|
||||
);
|
||||
}
|
||||
|
||||
if (!this.isBaseLayer) {
|
||||
this.inRange = this.calculateInRange();
|
||||
|
||||
@@ -30,29 +30,13 @@ OpenLayers.Layer.Google.v3 = {
|
||||
*
|
||||
* (code)
|
||||
* {
|
||||
* maxExtent: new OpenLayers.Bounds(
|
||||
* -128 * 156543.03390625,
|
||||
* -128 * 156543.03390625,
|
||||
* 128 * 156543.03390625,
|
||||
* 128 * 156543.03390625
|
||||
* ),
|
||||
* sphericalMercator: true,
|
||||
* maxResolution: 156543.03390625,
|
||||
* units: "m",
|
||||
* projection: "EPSG:900913"
|
||||
* }
|
||||
* (end)
|
||||
*/
|
||||
DEFAULTS: {
|
||||
maxExtent: new OpenLayers.Bounds(
|
||||
-128 * 156543.03390625,
|
||||
-128 * 156543.03390625,
|
||||
128 * 156543.03390625,
|
||||
128 * 156543.03390625
|
||||
),
|
||||
sphericalMercator: true,
|
||||
maxResolution: 156543.03390625,
|
||||
units: "m",
|
||||
projection: "EPSG:900913"
|
||||
},
|
||||
|
||||
|
||||
@@ -56,9 +56,11 @@ OpenLayers.Layer.WMS = OpenLayers.Class(OpenLayers.Layer.Grid, {
|
||||
* Property: yx
|
||||
* {Object} Keys in this object are EPSG codes for which the axis order
|
||||
* is to be reversed (yx instead of xy, LatLon instead of LonLat), with
|
||||
* true as value. This is only relevant for WMS versions >= 1.3.0.
|
||||
* true as value. This is only relevant for WMS versions >= 1.3.0, and
|
||||
* only if yx is not set in <OpenLayers.Projection.defaults> for the
|
||||
* used projection.
|
||||
*/
|
||||
yx: {'EPSG:4326': true},
|
||||
yx: {},
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Layer.WMS
|
||||
@@ -173,8 +175,9 @@ OpenLayers.Layer.WMS = OpenLayers.Class(OpenLayers.Layer.Grid, {
|
||||
* {Boolean} true if the axis order is reversed, false otherwise.
|
||||
*/
|
||||
reverseAxisOrder: function() {
|
||||
return (parseFloat(this.params.VERSION) >= 1.3 &&
|
||||
!!this.yx[this.map.getProjectionObject().getCode()]);
|
||||
var projCode = this.map.getProjectionObject().getCode();
|
||||
return parseFloat(this.params.VERSION) >= 1.3 &&
|
||||
!!(this.yx[projCode] || OpenLayers.Projection.defaults[projCode].yx);
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* @requires OpenLayers/Util.js
|
||||
* @requires OpenLayers/Events.js
|
||||
* @requires OpenLayers/Tween.js
|
||||
* @requires OpenLayers/Projection.js
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -248,17 +249,19 @@ OpenLayers.Map = OpenLayers.Class({
|
||||
/**
|
||||
* APIProperty: projection
|
||||
* {String} Set in the map options to override the default projection
|
||||
* string this map - also set maxExtent, maxResolution, and
|
||||
* units if appropriate. Default is "EPSG:4326".
|
||||
* string this map. When using a projection other than EPSG:4326
|
||||
* (CRS:84, Geographic) or EPSG:3857 (EPSG:900913, Web Mercator),
|
||||
* also set maxExtent and maxResolution. Default is "EPSG:4326".
|
||||
*/
|
||||
projection: "EPSG:4326",
|
||||
|
||||
/**
|
||||
* APIProperty: units
|
||||
* {String} The map units. Defaults to 'degrees'. Possible values are
|
||||
* 'degrees' (or 'dd'), 'm', 'ft', 'km', 'mi', 'inches'.
|
||||
* {String} The map units. Possible values are 'degrees' (or 'dd'), 'm',
|
||||
* 'ft', 'km', 'mi', 'inches'. Only required if the projection default
|
||||
* should be overridden.
|
||||
*/
|
||||
units: 'degrees',
|
||||
units: null,
|
||||
|
||||
/**
|
||||
* APIProperty: resolutions
|
||||
@@ -271,12 +274,10 @@ OpenLayers.Map = OpenLayers.Class({
|
||||
|
||||
/**
|
||||
* APIProperty: maxResolution
|
||||
* {Float} Default max is 360 deg / 256 px, which corresponds to
|
||||
* zoom level 0 on gmaps. Specify a different value in the map
|
||||
* options if you are not using a geographic projection and
|
||||
* displaying the whole world.
|
||||
* {Float} Specify if you are not using a geographic projection or Web
|
||||
* Mercator and displaying the whole world.
|
||||
*/
|
||||
maxResolution: 1.40625,
|
||||
maxResolution: null,
|
||||
|
||||
/**
|
||||
* APIProperty: minResolution
|
||||
@@ -342,7 +343,8 @@ OpenLayers.Map = OpenLayers.Class({
|
||||
|
||||
/**
|
||||
* APIProperty: displayProjection
|
||||
* {<OpenLayers.Projection>} Requires proj4js support.Projection used by
|
||||
* {<OpenLayers.Projection>} Requires proj4js support for projections other
|
||||
* than EPSG:4326 or EPSG:900913/EPSG:3857. Projection used by
|
||||
* several controls to display data to user. If this property is set,
|
||||
* it will be set on any control which has a null displayProjection
|
||||
* property at the time the control is added to the map.
|
||||
@@ -471,8 +473,6 @@ OpenLayers.Map = OpenLayers.Class({
|
||||
this.tileSize = new OpenLayers.Size(OpenLayers.Map.TILE_WIDTH,
|
||||
OpenLayers.Map.TILE_HEIGHT);
|
||||
|
||||
this.maxExtent = new OpenLayers.Bounds(-180, -90, 180, 90);
|
||||
|
||||
this.paddingForPopups = new OpenLayers.Bounds(15, 15, 15, 15);
|
||||
|
||||
this.theme = OpenLayers._getScriptLocation() +
|
||||
@@ -481,6 +481,10 @@ OpenLayers.Map = OpenLayers.Class({
|
||||
// now override default options
|
||||
OpenLayers.Util.extend(this, options);
|
||||
|
||||
var projCode = this.projection instanceof OpenLayers.Projection ?
|
||||
this.projection.projCode : this.projection;
|
||||
OpenLayers.Util.applyDefaults(this, OpenLayers.Projection.defaults[projCode]);
|
||||
|
||||
// allow extents to be arrays
|
||||
if (this.maxExtent && !(this.maxExtent instanceof OpenLayers.Bounds)) {
|
||||
this.maxExtent = new OpenLayers.Bounds(this.maxExtent);
|
||||
|
||||
@@ -142,7 +142,7 @@ OpenLayers.Projection = OpenLayers.Class({
|
||||
|
||||
/**
|
||||
* Property: transforms
|
||||
* Transforms is an object, with from properties, each of which may
|
||||
* {Object} Transforms is an object, with from properties, each of which may
|
||||
* have a to property. This allows you to define projections without
|
||||
* requiring support for proj4js to be included.
|
||||
*
|
||||
@@ -162,6 +162,34 @@ OpenLayers.Projection = OpenLayers.Class({
|
||||
*/
|
||||
OpenLayers.Projection.transforms = {};
|
||||
|
||||
/**
|
||||
* APIProperty: defaults
|
||||
* {Object} Defaults for the SRS codes known to OpenLayers (currently
|
||||
* EPSG:4326, CRS:84, urn:ogc:def:crs:EPSG:6.6:4326, EPSG:900913, EPSG:3857,
|
||||
* EPSG:102113 and EPSG:102100). Keys are the SRS code, values are units,
|
||||
* maxExtent (the validity extent for the SRS), maxResolution (the maximum
|
||||
* resolution commonly used in grid sets for this SRS) and yx (true if this
|
||||
* SRS is known to have a reverse axis order).
|
||||
*/
|
||||
OpenLayers.Projection.defaults = {
|
||||
"EPSG:4326": {
|
||||
units: "degrees",
|
||||
maxExtent: [-180, -90, 180, 90],
|
||||
maxResolution: 1.40625,
|
||||
yx: true
|
||||
},
|
||||
"CRS:84": {
|
||||
units: "degrees",
|
||||
maxExtent: [-180, -90, 180, 90],
|
||||
maxResolution: 1.40625
|
||||
},
|
||||
"EPSG:900913": {
|
||||
units: "m",
|
||||
maxExtent: [-20037508.34, -20037508.34, 20037508.34, 20037508.34],
|
||||
maxResolution: 156543.03390625
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* APIMethod: addTransform
|
||||
* Set a custom transform method between two projections. Use this method in
|
||||
@@ -176,6 +204,12 @@ OpenLayers.Projection.transforms = {};
|
||||
* in place. The original point should be modified.
|
||||
*/
|
||||
OpenLayers.Projection.addTransform = function(from, to, method) {
|
||||
if (method === OpenLayers.Projection.nullTransform) {
|
||||
var defaults = OpenLayers.Projection.defaults[from];
|
||||
if (defaults && !OpenLayers.Projection.defaults[to]) {
|
||||
OpenLayers.Projection.defaults[to] = defaults;
|
||||
}
|
||||
}
|
||||
if(!OpenLayers.Projection.transforms[from]) {
|
||||
OpenLayers.Projection.transforms[from] = {};
|
||||
}
|
||||
@@ -235,12 +269,15 @@ OpenLayers.Projection.nullTransform = function(point) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Note: Transforms for web mercator <-> EPSG:4326
|
||||
* Note: Transforms for web mercator <-> geographic
|
||||
* OpenLayers recognizes EPSG:3857, EPSG:900913, EPSG:102113 and EPSG:102100.
|
||||
* OpenLayers originally started referring to EPSG:900913 as web mercator.
|
||||
* The EPSG has declared EPSG:3857 to be web mercator.
|
||||
* ArcGIS 10 recognizes the EPSG:3857, EPSG:102113, and EPSG:102100 as
|
||||
* equivalent. See http://blogs.esri.com/Dev/blogs/arcgisserver/archive/2009/11/20/ArcGIS-Online-moving-to-Google-_2F00_-Bing-tiling-scheme_3A00_-What-does-this-mean-for-you_3F00_.aspx#12084
|
||||
* equivalent. See http://blogs.esri.com/Dev/blogs/arcgisserver/archive/2009/11/20/ArcGIS-Online-moving-to-Google-_2F00_-Bing-tiling-scheme_3A00_-What-does-this-mean-for-you_3F00_.aspx#12084.
|
||||
* For geographic, OpenLayers recognizes EPSG:4326, CRS:84 and
|
||||
* urn:ogc:def:crs:EPSG:6.6:4326. OpenLayers also knows about the reverse axis
|
||||
* order for EPSG:4326.
|
||||
*/
|
||||
(function() {
|
||||
|
||||
@@ -258,22 +295,31 @@ OpenLayers.Projection.nullTransform = function(point) {
|
||||
return xy;
|
||||
}
|
||||
|
||||
// list of equivalent codes for web mercator
|
||||
var codes = ["EPSG:900913", "EPSG:3857", "EPSG:102113", "EPSG:102100"];
|
||||
|
||||
var add = OpenLayers.Projection.addTransform;
|
||||
var same = OpenLayers.Projection.nullTransform;
|
||||
|
||||
var i, len, code, other, j;
|
||||
for (i=0, len=codes.length; i<len; ++i) {
|
||||
code = codes[i];
|
||||
add("EPSG:4326", code, forwardMercator);
|
||||
add(code, "EPSG:4326", inverseMercator);
|
||||
for (j=i+1; j<len; ++j) {
|
||||
other = codes[j];
|
||||
add(code, other, same);
|
||||
add(other, code, same);
|
||||
function map(base, codes) {
|
||||
var add = OpenLayers.Projection.addTransform;
|
||||
var same = OpenLayers.Projection.nullTransform;
|
||||
var i, len, code, other, j;
|
||||
for (i=0, len=codes.length; i<len; ++i) {
|
||||
code = codes[i];
|
||||
add(base, code, forwardMercator);
|
||||
add(code, base, inverseMercator);
|
||||
for (j=i+1; j<len; ++j) {
|
||||
other = codes[j];
|
||||
add(code, other, same);
|
||||
add(other, code, same);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// list of equivalent codes for web mercator
|
||||
var mercator = ["EPSG:900913", "EPSG:3857", "EPSG:102113", "EPSG:102100"],
|
||||
geographic = ["CRS:84", "urn:ogc:def:crs:EPSG:6.6:4326", "EPSG:4326"],
|
||||
i;
|
||||
for (i=mercator.length-1; i>=0; --i) {
|
||||
map(mercator[i], geographic);
|
||||
}
|
||||
for (i=geographic.length-1; i>=0; --i) {
|
||||
map(geographic[i], mercator);
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
@@ -290,19 +290,19 @@
|
||||
function test_mixedParams(t) {
|
||||
t.plan(5);
|
||||
var map = new OpenLayers.Map("map", {
|
||||
getExtent: function() {return(new OpenLayers.Bounds(-180,-90,180,90));}
|
||||
}
|
||||
);
|
||||
getExtent: function() {return(new OpenLayers.Bounds(-180,-90,180,90));},
|
||||
getProjectionObject: function() {return new OpenLayers.Projection("EPSG:4326");}
|
||||
});
|
||||
|
||||
var a = new OpenLayers.Layer.WMS("dummy","http://localhost/wms", {
|
||||
layers: "a,b,c,d",
|
||||
styles: "a,b,c,d"
|
||||
});
|
||||
}, {map: map});
|
||||
|
||||
var b = new OpenLayers.Layer.WMS("dummy","http://localhost/wms", {
|
||||
layers: ["a","b","c","d"],
|
||||
styles: ["a","b","c","d"]
|
||||
});
|
||||
}, {map: map});
|
||||
|
||||
var c = new OpenLayers.Layer.WMS("dummy","http://localhost/wms", {
|
||||
layers: ["a","b","c","d"]
|
||||
@@ -310,13 +310,13 @@
|
||||
|
||||
var d = new OpenLayers.Layer.WMS("dummy","http://localhost/wms", {
|
||||
layers: "a,b,c,d"
|
||||
});
|
||||
}, {map: map});
|
||||
|
||||
var click = new OpenLayers.Control.WMSGetFeatureInfo({
|
||||
featureType: 'type',
|
||||
featureNS: 'ns',
|
||||
layers: [a, b, c, d]
|
||||
});
|
||||
}, {map: map});
|
||||
|
||||
map.addControl(click);
|
||||
|
||||
@@ -399,6 +399,7 @@
|
||||
var c = new OpenLayers.Layer.WMS(
|
||||
null, ["http://c.mirror/wms", "http://d.mirror/wms"], {layers: "c"}
|
||||
);
|
||||
map.addLayers([a, b, c]);
|
||||
|
||||
var control = new OpenLayers.Control.WMSGetFeatureInfo({
|
||||
url: "http://host/wms",
|
||||
|
||||
@@ -268,10 +268,10 @@
|
||||
map.destroy();
|
||||
|
||||
map = new OpenLayers.Map("map");
|
||||
layer = new OpenLayers.Layer("test", {projection: "EPSG:4326"});
|
||||
layer = new OpenLayers.Layer("test", {projection: "unknown"});
|
||||
map.addLayer(layer);
|
||||
t.eq(layer.alwaysInRange, true,
|
||||
"alwaysInRange true if only get projection.");
|
||||
"alwaysInRange true if unknown projection is set.");
|
||||
map.destroy();
|
||||
|
||||
map = new OpenLayers.Map("map");
|
||||
|
||||
@@ -178,7 +178,7 @@
|
||||
|
||||
var map = new OpenLayers.Map({
|
||||
div: "map",
|
||||
maxResolution: OpenLayers.Map.prototype.maxResolution / Math.pow(2, offset)
|
||||
maxResolution: OpenLayers.Projection.defaults["EPSG:4326"].maxResolution / Math.pow(2, offset)
|
||||
});
|
||||
var layer = new OpenLayers.Layer.TMS("TMS", "", {
|
||||
layername: "basic",
|
||||
@@ -200,7 +200,7 @@
|
||||
|
||||
var map = new OpenLayers.Map({
|
||||
div: "map",
|
||||
maxResolution: OpenLayers.Map.prototype.maxResolution / Math.pow(2, offset)
|
||||
maxResolution: OpenLayers.Projection.defaults["EPSG:4326"].maxResolution / Math.pow(2, offset)
|
||||
});
|
||||
var layer = new OpenLayers.Layer.TMS("TMS", "", {
|
||||
layername: "basic",
|
||||
|
||||
@@ -195,7 +195,7 @@
|
||||
|
||||
var map = new OpenLayers.Map({
|
||||
div: "map",
|
||||
maxResolution: OpenLayers.Map.prototype.maxResolution / Math.pow(2, offset)
|
||||
maxResolution: OpenLayers.Projection.defaults["EPSG:4326"].maxResolution / Math.pow(2, offset)
|
||||
});
|
||||
var layer = new OpenLayers.Layer.XYZ(name, url, {zoomOffset: offset});
|
||||
map.addLayer(layer);
|
||||
@@ -211,7 +211,7 @@
|
||||
|
||||
var map = new OpenLayers.Map({
|
||||
div: "map",
|
||||
maxResolution: OpenLayers.Map.prototype.maxResolution / Math.pow(2, offset)
|
||||
maxResolution: OpenLayers.Projection.defaults["EPSG:4326"].maxResolution / Math.pow(2, offset)
|
||||
});
|
||||
var layer = new OpenLayers.Layer.XYZ(name, url, {zoomOffset: offset});
|
||||
map.addLayer(layer);
|
||||
|
||||
@@ -302,7 +302,7 @@
|
||||
function test_fromWMSLayer(t) {
|
||||
t.plan(9);
|
||||
var map = new OpenLayers.Map("map", {
|
||||
projection: "EPSG:1234"
|
||||
projection: "CRS:84"
|
||||
});
|
||||
var layer = new OpenLayers.Layer.WMS("foo", "htttp://foo/ows",
|
||||
{layers: "topp:states"}
|
||||
@@ -312,7 +312,7 @@
|
||||
t.eq(protocol.url, "htttp://foo/ows", "url taken from wms layer");
|
||||
t.eq(protocol.featurePrefix, "topp", "feature prefix correctly extracted");
|
||||
t.eq(protocol.featureType, "states", "typeName correctly extracted");
|
||||
t.eq(protocol.srsName, "EPSG:1234", "srsName set correctly");
|
||||
t.eq(protocol.srsName, "CRS:84", "srsName set correctly");
|
||||
t.eq(protocol.version, "1.1.0", "version set correctly");
|
||||
t.eq(protocol.format.geometryName, null, "format's geometryName set to null");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user