diff --git a/src/ol/proj/index.js b/src/ol/proj/index.js index 5ba8582de1..44bd2880b1 100644 --- a/src/ol/proj/index.js +++ b/src/ol/proj/index.js @@ -4,8 +4,8 @@ goog.provide('ol.proj.Projection'); goog.require('ol'); goog.require('ol.extent'); -goog.require('ol.obj'); goog.require('ol.proj.Units'); +goog.require('ol.proj.transforms'); goog.require('ol.sphere.NORMAL'); @@ -23,6 +23,41 @@ ol.proj.METERS_PER_UNIT[ol.proj.Units.METERS] = 1; ol.proj.METERS_PER_UNIT[ol.proj.Units.USFEET] = 1200 / 3937; +/** + * @private + * @type {Object.} + */ +ol.proj.projections_ = {}; + + +/** + * @private + * @type {proj4} + */ +ol.proj.proj4_ = null; + + +if (ol.ENABLE_PROJ4JS) { + /** + * Register proj4. If not explicitly registered, it will be assumed that + * proj4js will be loaded in the global namespace. For example in a + * browserify ES6 environment you could use: + * + * import ol from 'openlayers'; + * import proj4 from 'proj4'; + * ol.proj.setProj4(proj4); + * + * @param {proj4} proj4 Proj4. + * @api + */ + ol.proj.setProj4 = function(proj4) { + ol.DEBUG && console.assert(typeof proj4 == 'function', + 'proj4 argument should be a function'); + ol.proj.proj4_ = proj4; + }; +} + + /** * @classdesc * Projection definition class. One of these is created for each projection @@ -93,7 +128,6 @@ ol.proj.Projection = function(options) { */ this.global_ = options.global !== undefined ? options.global : false; - /** * @private * @type {boolean} @@ -352,48 +386,6 @@ ol.proj.Projection.prototype.getPointResolution = function(resolution, point) { }; -/** - * @private - * @type {Object.} - */ -ol.proj.projections_ = {}; - - -/** - * @private - * @type {Object.>} - */ -ol.proj.transforms_ = {}; - - -/** - * @private - * @type {proj4} - */ -ol.proj.proj4_ = null; - - -if (ol.ENABLE_PROJ4JS) { - /** - * Register proj4. If not explicitly registered, it will be assumed that - * proj4js will be loaded in the global namespace. For example in a - * browserify ES6 environment you could use: - * - * import ol from 'openlayers'; - * import proj4 from 'proj4'; - * ol.proj.setProj4(proj4); - * - * @param {proj4} proj4 Proj4. - * @api - */ - ol.proj.setProj4 = function(proj4) { - ol.DEBUG && console.assert(typeof proj4 == 'function', - 'proj4 argument should be a function'); - ol.proj.proj4_ = proj4; - }; -} - - /** * Registers transformation functions that don't alter coordinates. Those allow * to transform between projections with equal meaning. @@ -406,7 +398,7 @@ ol.proj.addEquivalentProjections = function(projections) { projections.forEach(function(source) { projections.forEach(function(destination) { if (source !== destination) { - ol.proj.addTransform(source, destination, ol.proj.cloneTransform); + ol.proj.transforms.add(source, destination, ol.proj.cloneTransform); } }); }); @@ -429,8 +421,8 @@ ol.proj.addEquivalentProjections = function(projections) { ol.proj.addEquivalentTransforms = function(projections1, projections2, forwardTransform, inverseTransform) { projections1.forEach(function(projection1) { projections2.forEach(function(projection2) { - ol.proj.addTransform(projection1, projection2, forwardTransform); - ol.proj.addTransform(projection2, projection1, inverseTransform); + ol.proj.transforms.add(projection1, projection2, forwardTransform); + ol.proj.transforms.add(projection2, projection1, inverseTransform); }); }); }; @@ -445,7 +437,7 @@ ol.proj.addEquivalentTransforms = function(projections1, projections2, forwardTr */ ol.proj.addProjection = function(projection) { ol.proj.projections_[projection.getCode()] = projection; - ol.proj.addTransform(projection, projection, ol.proj.cloneTransform); + ol.proj.transforms.add(projection, projection, ol.proj.cloneTransform); }; @@ -465,7 +457,7 @@ ol.proj.addProjections = function(projections) { */ ol.proj.clearAllProjections = function() { ol.proj.projections_ = {}; - ol.proj.transforms_ = {}; + ol.proj.transforms.clear(); }; @@ -485,25 +477,6 @@ ol.proj.createProjection = function(projection, defaultCode) { }; -/** - * Registers a conversion function to convert coordinates from the source - * projection to the destination projection. - * - * @param {ol.proj.Projection} source Source. - * @param {ol.proj.Projection} destination Destination. - * @param {ol.TransformFunction} transformFn Transform. - */ -ol.proj.addTransform = function(source, destination, transformFn) { - var sourceCode = source.getCode(); - var destinationCode = destination.getCode(); - var transforms = ol.proj.transforms_; - if (!(sourceCode in transforms)) { - transforms[sourceCode] = {}; - } - transforms[sourceCode][destinationCode] = transformFn; -}; - - /** * Registers coordinate transform functions to convert coordinates between the * source projection and the destination projection. @@ -526,9 +499,9 @@ ol.proj.addTransform = function(source, destination, transformFn) { ol.proj.addCoordinateTransforms = function(source, destination, forward, inverse) { var sourceProj = ol.proj.get(source); var destProj = ol.proj.get(destination); - ol.proj.addTransform(sourceProj, destProj, + ol.proj.transforms.add(sourceProj, destProj, ol.proj.createTransformFromCoordinateTransform(forward)); - ol.proj.addTransform(destProj, sourceProj, + ol.proj.transforms.add(destProj, sourceProj, ol.proj.createTransformFromCoordinateTransform(inverse)); }; @@ -566,32 +539,6 @@ ol.proj.createTransformFromCoordinateTransform = function(transform) { }; -/** - * Unregisters the conversion function to convert coordinates from the source - * projection to the destination projection. This method is used to clean up - * cached transforms during testing. - * - * @param {ol.proj.Projection} source Source projection. - * @param {ol.proj.Projection} destination Destination projection. - * @return {ol.TransformFunction} transformFn The unregistered transform. - */ -ol.proj.removeTransform = function(source, destination) { - var sourceCode = source.getCode(); - var destinationCode = destination.getCode(); - var transforms = ol.proj.transforms_; - ol.DEBUG && console.assert(sourceCode in transforms, - 'sourceCode should be in transforms'); - ol.DEBUG && console.assert(destinationCode in transforms[sourceCode], - 'destinationCode should be in transforms of sourceCode'); - var transform = transforms[sourceCode][destinationCode]; - delete transforms[sourceCode][destinationCode]; - if (ol.obj.isEmpty(transforms[sourceCode])) { - delete transforms[sourceCode]; - } - return transform; -}; - - /** * Transforms a coordinate from longitude/latitude to a different projection. * @param {ol.Coordinate} coordinate Coordinate as longitude and latitude, i.e. @@ -704,11 +651,10 @@ ol.proj.getTransform = function(source, destination) { * @return {ol.TransformFunction} Transform function. */ ol.proj.getTransformFromProjections = function(sourceProjection, destinationProjection) { - var transforms = ol.proj.transforms_; var sourceCode = sourceProjection.getCode(); var destinationCode = destinationProjection.getCode(); - var transform; - if (ol.ENABLE_PROJ4JS && !(sourceCode in transforms && destinationCode in transforms[sourceCode])) { + var transform = ol.proj.transforms.get(sourceCode, destinationCode); + if (ol.ENABLE_PROJ4JS && !transform) { var proj4js = ol.proj.proj4_ || window['proj4']; if (typeof proj4js == 'function') { var sourceDef = proj4js.defs(sourceCode); @@ -722,13 +668,12 @@ ol.proj.getTransformFromProjections = function(sourceProjection, destinationProj ol.proj.addCoordinateTransforms(destinationProjection, sourceProjection, proj4Transform.forward, proj4Transform.inverse); } + transform = ol.proj.transforms.get(sourceCode, destinationCode); } } } - if (sourceCode in transforms && destinationCode in transforms[sourceCode]) { - transform = transforms[sourceCode][destinationCode]; - } else { - ol.DEBUG && console.assert(transform !== undefined, 'transform should be defined'); + if (!transform) { + ol.DEBUG && console.assert(transform, 'transform should be defined'); transform = ol.proj.identityTransform; } return transform; diff --git a/src/ol/proj/transforms.js b/src/ol/proj/transforms.js new file mode 100644 index 0000000000..a8a49fee81 --- /dev/null +++ b/src/ol/proj/transforms.js @@ -0,0 +1,80 @@ +goog.provide('ol.proj.transforms'); + +goog.require('ol'); +goog.require('ol.obj'); + + +/** + * @private + * @type {Object.>} + */ +ol.proj.transforms.cache_ = {}; + + +/** + * Clear the transform cache. + */ +ol.proj.transforms.clear = function() { + ol.proj.transforms.cache_ = {}; +}; + + +/** + * Registers a conversion function to convert coordinates from the source + * projection to the destination projection. + * + * @param {ol.proj.Projection} source Source. + * @param {ol.proj.Projection} destination Destination. + * @param {ol.TransformFunction} transformFn Transform. + */ +ol.proj.transforms.add = function(source, destination, transformFn) { + var sourceCode = source.getCode(); + var destinationCode = destination.getCode(); + var transforms = ol.proj.transforms.cache_; + if (!(sourceCode in transforms)) { + transforms[sourceCode] = {}; + } + transforms[sourceCode][destinationCode] = transformFn; +}; + + +/** + * Unregisters the conversion function to convert coordinates from the source + * projection to the destination projection. This method is used to clean up + * cached transforms during testing. + * + * @param {ol.proj.Projection} source Source projection. + * @param {ol.proj.Projection} destination Destination projection. + * @return {ol.TransformFunction} transformFn The unregistered transform. + */ +ol.proj.transforms.remove = function(source, destination) { + var sourceCode = source.getCode(); + var destinationCode = destination.getCode(); + var transforms = ol.proj.transforms.cache_; + ol.DEBUG && console.assert(sourceCode in transforms, + 'sourceCode should be in transforms'); + ol.DEBUG && console.assert(destinationCode in transforms[sourceCode], + 'destinationCode should be in transforms of sourceCode'); + var transform = transforms[sourceCode][destinationCode]; + delete transforms[sourceCode][destinationCode]; + if (ol.obj.isEmpty(transforms[sourceCode])) { + delete transforms[sourceCode]; + } + return transform; +}; + + +/** + * Get a transform given a source code and a destination code. + * @param {string} sourceCode The code for the source projection. + * @param {string} destinationCode The code for the destination projection. + * @return {?ol.TransformFunction} The transform function (if found). + */ +ol.proj.transforms.get = function(sourceCode, destinationCode) { + var transform = null; + var transforms = ol.proj.transforms.cache_; + if (sourceCode in transforms && destinationCode in transforms[sourceCode]) { + transform = transforms[sourceCode][destinationCode]; + } + return transform; +}; diff --git a/test/spec/ol/format/kml.test.js b/test/spec/ol/format/kml.test.js index 34437c4eb5..d899f84a68 100644 --- a/test/spec/ol/format/kml.test.js +++ b/test/spec/ol/format/kml.test.js @@ -17,6 +17,7 @@ goog.require('ol.style.Fill'); goog.require('ol.style.Icon'); goog.require('ol.proj'); goog.require('ol.proj.Projection'); +goog.require('ol.proj.transforms'); goog.require('ol.style.Stroke'); goog.require('ol.style.Style'); goog.require('ol.style.Text'); @@ -358,9 +359,9 @@ describe('ol.format.KML', function() { ''; expect(node).to.xmleql(ol.xml.parse(text)); - ol.proj.removeTransform( + ol.proj.transforms.remove( ol.proj.get('EPSG:4326'), ol.proj.get('double')); - ol.proj.removeTransform( + ol.proj.transforms.remove( ol.proj.get('double'), ol.proj.get('EPSG:4326')); }); diff --git a/test/spec/ol/proj/index.test.js b/test/spec/ol/proj/index.test.js index 373825cd80..6839299884 100644 --- a/test/spec/ol/proj/index.test.js +++ b/test/spec/ol/proj/index.test.js @@ -451,37 +451,6 @@ describe('ol.proj', function() { }); }); - describe('ol.proj.removeTransform()', function() { - - var extent = [180, -90, 180, 90]; - var units = 'degrees'; - - it('removes functions cached by addTransform', function() { - var foo = new ol.proj.Projection({ - code: 'foo', - units: units, - extent: extent - }); - var bar = new ol.proj.Projection({ - code: 'bar', - units: units, - extent: extent - }); - var transform = function(input, output, dimension) { - return input; - }; - ol.proj.addTransform(foo, bar, transform); - expect(ol.proj.transforms_).not.to.be(undefined); - expect(ol.proj.transforms_.foo).not.to.be(undefined); - expect(ol.proj.transforms_.foo.bar).to.be(transform); - - var removed = ol.proj.removeTransform(foo, bar); - expect(removed).to.be(transform); - expect(ol.proj.transforms_.foo).to.be(undefined); - }); - - }); - describe('ol.proj.transform()', function() { it('transforms a 2d coordinate', function() { diff --git a/test/spec/ol/proj/transforms.test.js b/test/spec/ol/proj/transforms.test.js new file mode 100644 index 0000000000..3ba0965038 --- /dev/null +++ b/test/spec/ol/proj/transforms.test.js @@ -0,0 +1,36 @@ +goog.provide('ol.test.proj.transforms'); + +goog.require('ol.proj.Projection'); +goog.require('ol.proj.transforms'); + + +describe('ol.proj.transforms.remove()', function() { + + var extent = [180, -90, 180, 90]; + var units = 'degrees'; + + it('removes functions cached by ol.proj.transforms.add()', function() { + var foo = new ol.proj.Projection({ + code: 'foo', + units: units, + extent: extent + }); + var bar = new ol.proj.Projection({ + code: 'bar', + units: units, + extent: extent + }); + var transform = function(input, output, dimension) { + return input; + }; + ol.proj.transforms.add(foo, bar, transform); + expect(ol.proj.transforms.cache_).not.to.be(undefined); + expect(ol.proj.transforms.cache_.foo).not.to.be(undefined); + expect(ol.proj.transforms.cache_.foo.bar).to.be(transform); + + var removed = ol.proj.transforms.remove(foo, bar); + expect(removed).to.be(transform); + expect(ol.proj.transforms.cache_.foo).to.be(undefined); + }); + +});