diff --git a/externs/proj4js.js b/externs/proj4js.js index 1eab482820..0dd711eb63 100644 --- a/externs/proj4js.js +++ b/externs/proj4js.js @@ -52,6 +52,12 @@ Proj4js.Point.prototype.y; Proj4js.Proj = function(srsCode, opt_callback) {}; +/** + * @type {string} + */ +Proj4js.Proj.prototype.axis; + + /** * @type {string} */ diff --git a/src/ol/map.js b/src/ol/map.js index ad1fa4d8c0..922636b5d7 100644 --- a/src/ol/map.js +++ b/src/ol/map.js @@ -58,6 +58,7 @@ goog.require('ol.interaction.TouchPan'); goog.require('ol.interaction.TouchRotateAndZoom'); goog.require('ol.interaction.condition'); goog.require('ol.layer.Layer'); +goog.require('ol.projection.addCommonProjections'); goog.require('ol.renderer.Map'); goog.require('ol.renderer.canvas.Map'); goog.require('ol.renderer.canvas.SUPPORTED'); @@ -1027,3 +1028,6 @@ ol.RendererHints.createFromQueryData = function(opt_queryData) { return ol.DEFAULT_RENDERER_HINTS; } }; + + +ol.projection.addCommonProjections(); diff --git a/src/ol/parser/ogc/wmtscapabilities_v1_0_0.js b/src/ol/parser/ogc/wmtscapabilities_v1_0_0.js index cade9332f8..a18a1648c4 100644 --- a/src/ol/parser/ogc/wmtscapabilities_v1_0_0.js +++ b/src/ol/parser/ogc/wmtscapabilities_v1_0_0.js @@ -76,9 +76,10 @@ ol.parser.ogc.WMTSCapabilities_v1_0_0 = function() { 'TopLeftCorner': function(node, obj) { var topLeftCorner = this.getChildValue(node); var coords = topLeftCorner.split(' '); - var axis = ol.Projection.getFromCode(obj['supportedCRS']).getAxis(); + var axisOrientation = + ol.Projection.getFromCode(obj['supportedCRS']).getAxisOrientation(); obj['topLeftCorner'] = ol.Coordinate.fromProjectedArray( - [parseFloat(coords[0]), parseFloat(coords[1])], axis); + [parseFloat(coords[0]), parseFloat(coords[1])], axisOrientation); }, 'TileWidth': function(node, obj) { obj['tileWidth'] = parseInt(this.getChildValue(node), 10); diff --git a/src/ol/projection.exports b/src/ol/projection.exports index b10eb8e13c..1e26a7360e 100644 --- a/src/ol/projection.exports +++ b/src/ol/projection.exports @@ -5,6 +5,7 @@ @exportProperty ol.Projection.getTransformFromCodes @exportProperty ol.Projection.transform @exportProperty ol.Projection.transformWithCodes +@exportProperty ol.Projection.prototype.getAxisOrientation @exportProperty ol.Projection.prototype.getCode @exportProperty ol.Projection.prototype.getExtent @exportProperty ol.Projection.prototype.getUnits diff --git a/src/ol/projection.js b/src/ol/projection.js index 3e1692d01c..77579ff574 100644 --- a/src/ol/projection.js +++ b/src/ol/projection.js @@ -36,9 +36,9 @@ ol.ProjectionUnits = { * @param {string} code Code. * @param {ol.ProjectionUnits} units Units. * @param {ol.Extent} extent Extent. - * @param {string=} opt_axis Axis order. + * @param {string=} opt_axisOrientation Axis orientation. */ -ol.Projection = function(code, units, extent, opt_axis) { +ol.Projection = function(code, units, extent, opt_axisOrientation) { /** * @private @@ -62,7 +62,8 @@ ol.Projection = function(code, units, extent, opt_axis) { * @private * @type {string} */ - this.axis_ = opt_axis || 'enu'; + this.axisOrientation_ = goog.isDef(opt_axisOrientation) ? + opt_axisOrientation : 'enu'; }; @@ -92,10 +93,10 @@ ol.Projection.prototype.getUnits = function() { /** - * @return {string} Axis. + * @return {string} Axis orientation. */ -ol.Projection.prototype.getAxis = function() { - return this.axis_; +ol.Projection.prototype.getAxisOrientation = function() { + return this.axisOrientation_; }; @@ -110,7 +111,7 @@ ol.Proj4jsProjection = function(code, proj4jsProj) { var units = /** @type {ol.ProjectionUnits} */ (proj4jsProj.units); - goog.base(this, code, units, null); + goog.base(this, code, units, null, proj4jsProj.axis); /** * @private @@ -156,9 +157,8 @@ ol.Projection.transforms_ = {}; * to transform between projections with equal meaning. * * @param {Array.} projections Projections. - * @private */ -ol.Projection.addEquivalentProjections_ = function(projections) { +ol.Projection.addEquivalentProjections = function(projections) { ol.Projection.addProjections(projections); goog.array.forEach(projections, function(source) { goog.array.forEach(projections, function(destination) { @@ -181,9 +181,8 @@ ol.Projection.addEquivalentProjections_ = function(projections) { * projection in projection1 to any projection in projection2. * @param {ol.TransformFunction} inverseTransform Transform from any projection * in projection2 to any projection in projection1.. - * @private */ -ol.Projection.addEquivalentTransforms_ = +ol.Projection.addEquivalentTransforms = function(projections1, projections2, forwardTransform, inverseTransform) { goog.array.forEach(projections1, function(projection1) { goog.array.forEach(projections2, function(projection2) { @@ -228,6 +227,18 @@ ol.Projection.addProjections = function(projections) { }; +/** + * FIXME empty description for jsdoc + */ +ol.Projection.clearAllProjections = function() { + if (ol.ENABLE_PROJ4JS) { + ol.Projection.proj4jsProjections_ = {}; + } + ol.Projection.projections_ = {}; + ol.Projection.transforms_ = {}; +}; + + /** * @param {ol.Projection|string|undefined} projection Projection. * @param {string} defaultCode Default code. @@ -462,143 +473,3 @@ ol.Projection.transformWithCodes = sourceCode, destinationCode); return transformFn(point); }; - - -/** - * @const - * @type {number} - */ -ol.Projection.EPSG_3857_RADIUS = 6378137; - - -/** - * Transformation from EPSG:4326 to EPSG:3857. - * - * @param {ol.Coordinate} point Point. - * @return {ol.Coordinate} Point. - */ -ol.Projection.forwardSphericalMercator = function(point) { - var x = ol.Projection.EPSG_3857_RADIUS * Math.PI * point.x / 180; - var y = ol.Projection.EPSG_3857_RADIUS * - Math.log(Math.tan(Math.PI * (point.y + 90) / 360)); - return new ol.Coordinate(x, y); -}; - - -/** - * Transformation from EPSG:3857 to EPSG:4326. - * - * @param {ol.Coordinate} point Point. - * @return {ol.Coordinate} Point. - */ -ol.Projection.inverseSphericalMercator = function(point) { - var x = 180 * point.x / (ol.Projection.EPSG_3857_RADIUS * Math.PI); - var y = 360 * Math.atan( - Math.exp(point.y / ol.Projection.EPSG_3857_RADIUS)) / Math.PI - 90; - return new ol.Coordinate(x, y); -}; - - -/** - * @const - * @type {number} - */ -ol.Projection.EPSG_3857_HALF_SIZE = Math.PI * ol.Projection.EPSG_3857_RADIUS; - - -/** - * @const - * @type {ol.Extent} - */ -ol.Projection.EPSG_3857_EXTENT = new ol.Extent( - -ol.Projection.EPSG_3857_HALF_SIZE, - -ol.Projection.EPSG_3857_HALF_SIZE, - ol.Projection.EPSG_3857_HALF_SIZE, - ol.Projection.EPSG_3857_HALF_SIZE); - - -/** - * Lists several projection codes with the same meaning as EPSG:3857. - * - * @private - * @type {Array.} - */ -ol.Projection.EPSG_3857_LIKE_CODES_ = [ - 'EPSG:3857', - 'EPSG:102100', - 'EPSG:102113', - 'EPSG:900913' -]; - - -/** - * Projections equal to EPSG:3857. - * - * @const - * @private - * @type {Array.} - */ -ol.Projection.EPSG_3857_LIKE_PROJECTIONS_ = goog.array.map( - ol.Projection.EPSG_3857_LIKE_CODES_, - function(code) { - return new ol.Projection( - code, - ol.ProjectionUnits.METERS, - ol.Projection.EPSG_3857_EXTENT); - }); - - -/** - * Extent of the EPSG:4326 projection which is the whole world. - * - * @const - * @private - * @type {ol.Extent} - */ -ol.Projection.EPSG_4326_EXTENT_ = new ol.Extent(-180, -90, 180, 90); - - -/** - * Several projection code with the same meaning as EPSG:4326. - * @private - * @type {Array.} - */ -ol.Projection.EPSG_4326_LIKE_CODES_ = [ - 'CRS:84', - 'urn:ogc:def:crs:OGC:1.3:CRS84', - 'EPSG:4326', - 'urn:ogc:def:crs:EPSG:6.6:4326' -]; - - -/** - * Projections equal to EPSG:4326. - * - * @const - * @type {Array.} - */ -ol.Projection.EPSG_4326_LIKE_PROJECTIONS = goog.array.map( - ol.Projection.EPSG_4326_LIKE_CODES_, - function(code) { - return new ol.Projection( - code, - ol.ProjectionUnits.DEGREES, - ol.Projection.EPSG_4326_EXTENT_, - code === 'CRS:84' || code === 'urn:ogc:def:crs:OGC:1.3:CRS84' ? - 'enu' : 'neu'); - }); - - -// Add transformations that don't alter coordinates to convert within set of -// projections with equal meaning. -ol.Projection.addEquivalentProjections_( - ol.Projection.EPSG_3857_LIKE_PROJECTIONS_); -ol.Projection.addEquivalentProjections_( - ol.Projection.EPSG_4326_LIKE_PROJECTIONS); -// Add transformations to convert EPSG:4326 like coordinates to EPSG:3857 like -// coordinates and back. -ol.Projection.addEquivalentTransforms_( - ol.Projection.EPSG_4326_LIKE_PROJECTIONS, - ol.Projection.EPSG_3857_LIKE_PROJECTIONS_, - ol.Projection.forwardSphericalMercator, - ol.Projection.inverseSphericalMercator); diff --git a/src/ol/projection/common.js b/src/ol/projection/common.js new file mode 100644 index 0000000000..ff45f1fe76 --- /dev/null +++ b/src/ol/projection/common.js @@ -0,0 +1,23 @@ +goog.provide('ol.projection.addCommonProjections'); + +goog.require('ol.Projection'); +goog.require('ol.projection.EPSG3857'); +goog.require('ol.projection.EPSG4326'); + + +/** + * FIXME empty description for jsdoc + */ +ol.projection.addCommonProjections = function() { + // Add transformations that don't alter coordinates to convert within set of + // projections with equal meaning. + ol.Projection.addEquivalentProjections(ol.projection.EPSG3857.PROJECTIONS); + ol.Projection.addEquivalentProjections(ol.projection.EPSG4326.PROJECTIONS); + // Add transformations to convert EPSG:4326 like coordinates to EPSG:3857 like + // coordinates and back. + ol.Projection.addEquivalentTransforms( + ol.projection.EPSG4326.PROJECTIONS, + ol.projection.EPSG3857.PROJECTIONS, + ol.projection.EPSG3857.fromEPSG4326, + ol.projection.EPSG3857.toEPSG4326); +}; diff --git a/src/ol/projection/epsg3857.js b/src/ol/projection/epsg3857.js new file mode 100644 index 0000000000..39b2bf81d0 --- /dev/null +++ b/src/ol/projection/epsg3857.js @@ -0,0 +1,97 @@ +goog.provide('ol.projection.EPSG3857'); + +goog.require('goog.array'); +goog.require('ol.Coordinate'); +goog.require('ol.Extent'); +goog.require('ol.Projection'); +goog.require('ol.ProjectionUnits'); + + + +/** + * @constructor + * @extends {ol.Projection} + * @param {string} code Code. + */ +ol.projection.EPSG3857 = function(code) { + goog.base( + this, code, ol.ProjectionUnits.METERS, ol.projection.EPSG3857.EXTENT); +}; +goog.inherits(ol.projection.EPSG3857, ol.Projection); + + +/** + * @const + * @type {number} + */ +ol.projection.EPSG3857.RADIUS = 6378137; + + +/** + * @const + * @type {number} + */ +ol.projection.EPSG3857.HALF_SIZE = Math.PI * ol.projection.EPSG3857.RADIUS; + + +/** + * @const + * @type {ol.Extent} + */ +ol.projection.EPSG3857.EXTENT = new ol.Extent( + -ol.projection.EPSG3857.HALF_SIZE, -ol.projection.EPSG3857.HALF_SIZE, + ol.projection.EPSG3857.HALF_SIZE, ol.projection.EPSG3857.HALF_SIZE); + + +/** + * Lists several projection codes with the same meaning as EPSG:3857. + * + * @type {Array.} + */ +ol.projection.EPSG3857.CODES = [ + 'EPSG:3857', + 'EPSG:102100', + 'EPSG:102113', + 'EPSG:900913' +]; + + +/** + * Projections equal to EPSG:3857. + * + * @const + * @type {Array.} + */ +ol.projection.EPSG3857.PROJECTIONS = goog.array.map( + ol.projection.EPSG3857.CODES, + function(code) { + return new ol.projection.EPSG3857(code); + }); + + +/** + * Transformation from EPSG:4326 to EPSG:3857. + * + * @param {ol.Coordinate} point Point. + * @return {ol.Coordinate} Point. + */ +ol.projection.EPSG3857.fromEPSG4326 = function(point) { + var x = ol.projection.EPSG3857.RADIUS * Math.PI * point.x / 180; + var y = ol.projection.EPSG3857.RADIUS * + Math.log(Math.tan(Math.PI * (point.y + 90) / 360)); + return new ol.Coordinate(x, y); +}; + + +/** + * Transformation from EPSG:3857 to EPSG:4326. + * + * @param {ol.Coordinate} point Point. + * @return {ol.Coordinate} Point. + */ +ol.projection.EPSG3857.toEPSG4326 = function(point) { + var x = 180 * point.x / (ol.projection.EPSG3857.RADIUS * Math.PI); + var y = 360 * Math.atan( + Math.exp(point.y / ol.projection.EPSG3857.RADIUS)) / Math.PI - 90; + return new ol.Coordinate(x, y); +}; diff --git a/src/ol/projection/epsg4326.js b/src/ol/projection/epsg4326.js new file mode 100644 index 0000000000..d426ec65f8 --- /dev/null +++ b/src/ol/projection/epsg4326.js @@ -0,0 +1,42 @@ +goog.provide('ol.projection.EPSG4326'); + +goog.require('ol.Extent'); +goog.require('ol.Projection'); +goog.require('ol.ProjectionUnits'); + + + +/** + * @constructor + * @extends {ol.Projection} + * @param {string} code Code. + * @param {string=} opt_axisOrientation Axis orientation. + */ +ol.projection.EPSG4326 = function(code, opt_axisOrientation) { + goog.base(this, code, ol.ProjectionUnits.DEGREES, + ol.projection.EPSG4326.EXTENT, opt_axisOrientation); +}; +goog.inherits(ol.projection.EPSG4326, ol.Projection); + + +/** + * Extent of the EPSG:4326 projection which is the whole world. + * + * @const + * @type {ol.Extent} + */ +ol.projection.EPSG4326.EXTENT = new ol.Extent(-180, -90, 180, 90); + + +/** + * Projections equal to EPSG:4326. + * + * @const + * @type {Array.} + */ +ol.projection.EPSG4326.PROJECTIONS = [ + new ol.projection.EPSG4326('CRS:84'), + new ol.projection.EPSG4326('EPSG:4326', 'neu'), + new ol.projection.EPSG4326('urn:ogc:def:crs:EPSG:6.6:4326', 'neu'), + new ol.projection.EPSG4326('urn:ogc:def:crs:OGC:1.3:CRS84') +]; diff --git a/src/ol/tilegrid/xyztilegrid.js b/src/ol/tilegrid/xyztilegrid.js index d7afe077d9..a6c1467880 100644 --- a/src/ol/tilegrid/xyztilegrid.js +++ b/src/ol/tilegrid/xyztilegrid.js @@ -1,9 +1,9 @@ goog.provide('ol.tilegrid.XYZ'); goog.require('ol.Coordinate'); -goog.require('ol.Projection'); goog.require('ol.Size'); goog.require('ol.TileRange'); +goog.require('ol.projection.EPSG3857'); goog.require('ol.tilegrid.TileGrid'); @@ -17,14 +17,14 @@ ol.tilegrid.XYZ = function(xyzOptions) { var resolutions = new Array(xyzOptions.maxZoom + 1); var z; - var size = 2 * ol.Projection.EPSG_3857_HALF_SIZE / ol.DEFAULT_TILE_SIZE; + var size = 2 * ol.projection.EPSG3857.HALF_SIZE / ol.DEFAULT_TILE_SIZE; for (z = 0; z <= xyzOptions.maxZoom; ++z) { resolutions[z] = size / Math.pow(2, z); } goog.base(this, { - origin: new ol.Coordinate(-ol.Projection.EPSG_3857_HALF_SIZE, - ol.Projection.EPSG_3857_HALF_SIZE), + origin: new ol.Coordinate(-ol.projection.EPSG3857.HALF_SIZE, + ol.projection.EPSG3857.HALF_SIZE), resolutions: resolutions, tileSize: new ol.Size(ol.DEFAULT_TILE_SIZE, ol.DEFAULT_TILE_SIZE) });