From a4a90b18b7185b6bff9c91a8fc497cd3c2a62720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Wed, 20 Jun 2012 12:04:07 +0200 Subject: [PATCH 01/24] [ol.layer.XYZ] zoomForResolution is no longer private --- src/ol/layer/XYZ.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ol/layer/XYZ.js b/src/ol/layer/XYZ.js index 8550a2a57e..60dc65d660 100644 --- a/src/ol/layer/XYZ.js +++ b/src/ol/layer/XYZ.js @@ -108,7 +108,7 @@ ol.layer.XYZ.prototype.setResolutions = function(resolutions) { */ ol.layer.XYZ.prototype.getData = function(bounds, resolution) { var me = this, - zoom = me.zoomForResolution_(resolution); + zoom = me.zoomForResolution(resolution); resolution = me.resolutions_[zoom]; var boundsMinX = bounds.getMinX(), @@ -157,10 +157,9 @@ ol.layer.XYZ.prototype.getData = function(bounds, resolution) { /** * Get the zoom level (z) for the given resolution. - * @private * @param {number} resolution */ -ol.layer.XYZ.prototype.zoomForResolution_ = function(resolution) { +ol.layer.XYZ.prototype.zoomForResolution = function(resolution) { var delta = Number.POSITIVE_INFINITY, currentDelta, resolutions = this.resolutions_; From cdcf3ef5a4e014ab3fb2eb034a59d89e22feb959 Mon Sep 17 00:00:00 2001 From: Marc Jansen Date: Wed, 20 Jun 2012 12:06:55 +0200 Subject: [PATCH 02/24] remove the coordinate mixin. --- src/ol/mixins/coordinate.js | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 src/ol/mixins/coordinate.js diff --git a/src/ol/mixins/coordinate.js b/src/ol/mixins/coordinate.js deleted file mode 100644 index 599592302a..0000000000 --- a/src/ol/mixins/coordinate.js +++ /dev/null @@ -1,31 +0,0 @@ -goog.provide('ol.mixins.coordinate'); -goog.require('goog.object'); - -goog.object.extend(ol.mixins.coordinate, { - - getX : function() { - return this.x_; - }, - - getY : function() { - return this.y_; - }, - - getZ : function() { - return this.z_; - }, - - setX : function(x) { - this.x_ = x; - return this; - }, - - setY : function(y) { - this.y_ = y; - return this; - }, - setZ: function(z) { - this.z_ = z; - return this; - } -}); From 33c2e0aa30cec8ab817a592948aaec68b0a2e76d Mon Sep 17 00:00:00 2001 From: Marc Jansen Date: Wed, 20 Jun 2012 13:36:07 +0200 Subject: [PATCH 03/24] Correct the tests for geom.Point and geom.point. Add tests for the API version `ol.point()`; adjust the tests for the internal `new ol.Point()`. --- test/index.html | 1 + test/spec/api/geom/point.test.js | 134 +++++++++++++++++++++++++++++++ test/spec/ol/geom/Point.test.js | 83 ++++++++----------- 3 files changed, 169 insertions(+), 49 deletions(-) create mode 100644 test/spec/api/geom/point.test.js diff --git a/test/index.html b/test/index.html index e43d5bc22a..b271f302c1 100644 --- a/test/index.html +++ b/test/index.html @@ -17,6 +17,7 @@ + diff --git a/test/spec/api/geom/point.test.js b/test/spec/api/geom/point.test.js new file mode 100644 index 0000000000..70736921e1 --- /dev/null +++ b/test/spec/api/geom/point.test.js @@ -0,0 +1,134 @@ +describe("ol.geom.point", function() { + var pNoArgs, + pNoZ_arr, + pWithZ_arr, + p_arr, + pNoZ_obj, + pWithZ_obj, + p_obj, + proj = "EPSG:4326"; + + var instances = { + "no arguments passed": ol.geom.point(), + "one argument passed": ol.geom.point([21, 4]), + "one argument passed": ol.geom.point([21, 4, 8]), + "one argument passed": ol.geom.point([21, 4, 8, proj]), + "one argument passed": ol.geom.point({x: 21, y: 4}), + "one argument passed": ol.geom.point({x: 21, y: 4, z: 8}), + "one argument passed": ol.geom.point({x: 21, y: 4, z: 8, projection: proj}) + }; + + beforeEach(function() { + proj = ol.projection("EPSG:4326"); + instances = { + "no arguments passed": ol.geom.point(), + "one argument passed": ol.geom.point([21, 4]), + "one argument passed": ol.geom.point([21, 4, 8]), + "one argument passed": ol.geom.point([21, 4, 8, proj]), + "one argument passed": ol.geom.point({x: 21, y: 4}), + "one argument passed": ol.geom.point({x: 21, y: 4, z: 8}), + "one argument passed": ol.geom.point({x: 21, y: 4, z: 8, projection: proj}) + }; + pNoArgs = instances["no arguments passed"]; + pNoZ_arr = instances["one argument passed"]; + pWithZ_arr = instances["one argument passed"]; + p_arr = instances["one argument passed"]; + pNoZ_obj = instances["one argument passed"]; + pWithZ_obj = instances["one argument passed"]; + p_obj = instances["one argument passed"]; + }); + + afterEach(function() { + pNoArgs = null; + pNoZ_arr = pWithZ_arr = p_arr = null; + PNoZ_obj = pWithZ_obj = p_obj = null; + instances = { + "no arguments passed": ol.geom.point(), + "one argument passed": ol.geom.point([21, 4]), + "one argument passed": ol.geom.point([21, 4, 8]), + "one argument passed": ol.geom.point([21, 4, 8, proj]), + "one argument passed": ol.geom.point({x: 21, y: 4}), + "one argument passed": ol.geom.point({x: 21, y: 4, z: 8}), + "one argument passed": ol.geom.point({x: 21, y: 4, z: 8, projection: proj}) + }; + }); + + for (instancesDesc in instances) { + if (instances.hasOwnProperty(instancesDesc)) { + var instance = instances[instancesDesc]; + + it("constructs instances (" + instancesDesc + ")", function() { + expect(instance).toEqual(jasmine.any(ol.geom.Point)); + }); + + it("constructs instances of ol.geom.Geometry (" + instancesDesc + ")", function() { + expect(instance).toEqual(jasmine.any(ol.geom.Geometry)); + }); + + it("has the coordinate accessor methods (" + instancesDesc + ")", function() { + expect(instance.getX).not.toBeUndefined(); + expect(instance.getY).not.toBeUndefined(); + expect(instance.getZ).not.toBeUndefined(); + expect(instance.setX).not.toBeUndefined(); + expect(instance.setY).not.toBeUndefined(); + expect(instance.setZ).not.toBeUndefined(); + }); + + it("has the projection accessor methods (" + instancesDesc + ")", function() { + expect(instance.getProjection).not.toBeUndefined(); + expect(instance.setProjection).not.toBeUndefined(); + }); + } + } + + it("has functional getters (no arguments passed)", function(){ + expect(pNoArgs.getX()).toBe(0); + expect(pNoArgs.getY()).toBe(0); + expect(pNoArgs.getZ()).toBeUndefined(); + expect(pNoArgs.getProjection()).toBeNull(); + }); + + it("has functional getters (one argument passed)", function(){ + expect(pNoZ_arr.getX()).toBe(21); + expect(pNoZ_arr.getY()).toBe(4); + expect(pNoZ_arr.getZ()).toBeUndefined(); + expect(pNoZ_arr.getProjection()).toBeNull(); + }); + + it("has functional getters (one argument passed)", function(){ + expect(pWithZ_arr.getX()).toBe(21); + expect(pWithZ_arr.getY()).toBe(4); + expect(pWithZ_arr.getZ()).toBe(8); + expect(pWithZ_arr.getProjection()).toBeNull(); + }); + + it("has functional getters (one argument passed)", function(){ + expect(p_arr.getX()).toBe(21); + expect(p_arr.getY()).toBe(4); + expect(p_arr.getZ()).toBe(8); + expect(p_arr.getProjection()).not.toBeNull(); + expect(p_arr.getProjection()).toEqual(jasmine.any(ol.Projection)); + }); + + it("has functional getters (one argument passed)", function(){ + expect(pNoZ_obj.getX()).toBe(21); + expect(pNoZ_obj.getY()).toBe(4); + expect(pNoZ_obj.getZ()).toBeUndefined(); + expect(pNoZ_obj.getProjection()).toBeNull(); + }); + + it("has functional getters (one argument passed)", function(){ + expect(pWithZ_obj.getX()).toBe(21); + expect(pWithZ_obj.getY()).toBe(4); + expect(pWithZ_obj.getZ()).toBe(8); + expect(pWithZ_obj.getProjection()).toBeNull(); + }); + + it("has functional getters (one argument passed)", function(){ + expect(p_obj.getX()).toBe(21); + expect(p_obj.getY()).toBe(4); + expect(p_obj.getZ()).toBe(8); + expect(p_obj.getProjection()).not.toBeNull(); + expect(p_obj.getProjection()).toEqual(jasmine.any(ol.Projection)); + }); +}); diff --git a/test/spec/ol/geom/Point.test.js b/test/spec/ol/geom/Point.test.js index 0af7941f76..65103b2469 100644 --- a/test/spec/ol/geom/Point.test.js +++ b/test/spec/ol/geom/Point.test.js @@ -1,44 +1,34 @@ describe("ol.geom.Point", function() { - var pNoArgs, - pNoZ_arr, - pWithZ_arr, + var p2Args, + p3Args, + p4Args, p_arr, - pNoZ_obj, - pWithZ_obj, - p_obj, proj = "EPSG:4326"; var instances = { - "no arguments passed": ol.geom.point(), - "one argument [x,y] passed": ol.geom.point([21, 4]), - "one argument [x,y,z] passed": ol.geom.point([21, 4, 8]), - "one argument [x,y,z,projection] passed": ol.geom.point([21, 4, 8, proj]), - "one argument {x,y} passed": ol.geom.point([21, 4]), - "one argument {x,y,z} passed": ol.geom.point([21, 4, 8]), - "one argument {x,y,z,projection} passed": ol.geom.point([21, 4, 8, proj]) + "two arguments , passed": new ol.geom.Point(21, 4), + "three arguments ,, passed": new ol.geom.Point(21, 4, 8), + "four arguments ,,, passed": new ol.geom.Point(21, 4, 8, proj) }; beforeEach(function() { proj = ol.projection("EPSG:4326"); instances = { - "no arguments passed": ol.geom.point(), - "one argument [x,y] passed": ol.geom.point([21, 4]), - "one argument [x,y,z] passed": ol.geom.point([21, 4, 8]), - "one argument [x,y,z,projection] passed": ol.geom.point([21, 4, 8, proj]) + "two arguments , passed": new ol.geom.Point(21, 4), + "three arguments ,, passed": new ol.geom.Point(21, 4, 8), + "four arguments ,,, passed": new ol.geom.Point(21, 4, 8, proj) }; - pNoArgs = instances['no arguments passed']; - pNoZ = instances['one argument [x,y] passed']; - pWithZ = instances['one argument [x,y,z] passed']; - p = instances['one argument [x,y,z,projection] passed']; + p2Args = instances['two arguments , passed']; + p3Args = instances['three arguments ,, passed']; + p4Args = instances['four arguments ,,, passed']; }); afterEach(function() { - pNoArgs = pNoZ = pWithZ = p = null; + p2Args = p3Args = p4Args = null; instances = { - "no arguments passed": ol.geom.point(), - "one argument [x,y] passed": ol.geom.point([21, 4]), - "one argument [x,y,z] passed": ol.geom.point([21, 4, 8]), - "one argument [x,y,z,projection] passed": ol.geom.point([21, 4, 8, proj]) + "two arguments , passed": new ol.geom.Point(21, 4), + "three arguments ,, passed": new ol.geom.Point(21, 4, 8), + "four arguments ,,, passed": new ol.geom.Point(21, 4, 8, proj) }; }); @@ -70,32 +60,27 @@ describe("ol.geom.Point", function() { } } - it("has functional getters (no arguments passed)", function(){ - expect(pNoArgs.getX()).toBe(0); - expect(pNoArgs.getY()).toBe(0); - expect(pNoArgs.getZ()).toBeUndefined(); - expect(pNoArgs.getProjection()).toBeNull(); + it("has functional getters (two arguments , passed)", function(){ + + expect(p2Args.getX()).toBe(21); + expect(p2Args.getY()).toBe(4); + expect(p2Args.getZ()).toBeUndefined(); + expect(p2Args.getProjection()).toBeNull(); }); - it("has functional getters (one argument [x,y] passed)", function(){ - expect(pNoZ.getX()).toBe(21); - expect(pNoZ.getY()).toBe(4); - expect(pNoZ.getZ()).toBeUndefined(); - expect(pNoZ.getProjection()).toBeNull(); + it("has functional getters (three arguments ,, passed)", function(){ + expect(p3Args.getX()).toBe(21); + expect(p3Args.getY()).toBe(4); + expect(p3Args.getZ()).not.toBeUndefined(); + expect(p3Args.getZ()).toBe(8); + expect(p3Args.getProjection()).toBeNull(); }); - it("has functional getters (one argument [x,y,z] passed)", function(){ - expect(pWithZ.getX()).toBe(21); - expect(pWithZ.getY()).toBe(4); - expect(pWithZ.getZ()).toBe(8); - expect(pWithZ.getProjection()).toBeNull(); - }); - - it("has functional getters (one argument [x,y,z,projection] passed)", function(){ - expect(p.getX()).toBe(21); - expect(p.getY()).toBe(4); - expect(p.getZ()).toBe(8); - expect(p.getProjection()).not.toBeNull(); - expect(p.getProjection()).toEqual(jasmine.any(ol.Projection)); + it("has functional getters (four arguments ,,, passed)", function(){ + expect(p4Args.getX()).toBe(21); + expect(p4Args.getY()).toBe(4); + expect(p4Args.getZ()).toBe(8); + expect(p4Args.getProjection()).not.toBeNull(); + expect(p4Args.getProjection()).toBeA(ol.Projection); }); }); From 99b397bffc7932d8e4476da22a97d5cdfe539551 Mon Sep 17 00:00:00 2001 From: Mike Adair Date: Wed, 20 Jun 2012 08:29:43 -0400 Subject: [PATCH 04/24] implement getMaxRes, getMaxExtent, getResForZoom --- src/api/map.js | 27 +++++++++++++++++ src/api/projection.js | 13 +++++++- src/ol/Map.js | 63 ++++++++++++++++++++++++++++++++++++++- src/ol/Projection.js | 19 ++++++++---- test/spec/api/map.test.js | 57 +++++++++++++++++++++-------------- 5 files changed, 150 insertions(+), 29 deletions(-) diff --git a/src/api/map.js b/src/api/map.js index 173c1a703b..baffd2f4e6 100644 --- a/src/api/map.js +++ b/src/api/map.js @@ -31,6 +31,8 @@ ol.map = function(opt_arg){ var userProjection; /** @type {ol.Bounds|undefined} */ var maxExtent; + /** @type {ol.Bounds|undefined} */ + var maxRes; /** @type {Array.|undefined} */ var resolutions; /** @type {Array|undefined} */ @@ -47,6 +49,7 @@ ol.map = function(opt_arg){ projection = opt_arg['projection']; userProjection = opt_arg['userProjection']; maxExtent = opt_arg['maxExtent']; + maxRes = opt_arg['maxRes']; resolutions = opt_arg['resolutions']; layers = opt_arg['layers']; } @@ -74,6 +77,9 @@ ol.map = function(opt_arg){ if (goog.isDef(maxExtent)) { map.setMaxExtent(ol.bounds(maxExtent)); } + if (goog.isDef(maxRes)) { + map.setMaxRes(maxRes); + } if (goog.isDef(resolutions)) { map.setResolutions(resolutions); } @@ -187,3 +193,24 @@ ol.Map.prototype.maxExtent = function(opt_arg) { return this.getMaxExtent(); } }; + +/** + * @param {number=} opt_arg + * @returns {ol.Map|number|undefined} Map maximum resolution + */ +ol.Map.prototype.maxRes = function(opt_arg) { + if (arguments.length == 1 && goog.isDef(opt_arg)) { + this.setMaxRes(opt_arg); + return this; + } else { + return this.getMaxRes(); + } +}; + +/** + * @param {number} arg + * @returns {number} resolution for a given zoom level + */ +ol.Map.prototype.getResForZoom = function(arg) { + return this.getResolutionForZoom(arg); +}; diff --git a/src/api/projection.js b/src/api/projection.js index 27bf1254e4..d8ff8c9821 100644 --- a/src/api/projection.js +++ b/src/api/projection.js @@ -21,6 +21,9 @@ ol.projection = function(opt_arg){ /** @type {undefined|number} */ var units; + /** @type {undefined|Array|ol.UnreferencedBounds} */ + var extent; + if (arguments.length == 1 && goog.isDefAndNotNull(opt_arg)) { if (opt_arg instanceof ol.Projection) { return opt_arg; @@ -35,13 +38,21 @@ ol.projection = function(opt_arg){ throw new Error('Projection requires a string code.'); } units = opt_arg['units']; + extent = opt_arg['maxExtent']; } else { throw new Error('ol.projection'); } } var proj = new ol.Projection(code); - proj.setUnits(units); + if (goog.isDef(units)) { + proj.setUnits(units); + } + if (goog.isDef(extent)) { + proj.setExtent( + new ol.UnreferencedBounds(extent[0],extent[1],extent[2],extent[3]) + ); + } return proj; }; diff --git a/src/ol/Map.js b/src/ol/Map.js index 1a2462aaf2..2529f14953 100644 --- a/src/ol/Map.js +++ b/src/ol/Map.js @@ -52,6 +52,18 @@ ol.Map = function() { */ this.layers_ = null; + /** + * @private + * @type {ol.UnreferencedBounds|undefined} + */ + this.maxExtent_ = null; + + /** + * @private + * @type {number|undefined} + */ + this.maxRes_ = null; + }; /** @@ -64,7 +76,16 @@ ol.Map.prototype.DEFAULT_PROJECTION = "EPSG:3857"; @type {string} */ ol.Map.prototype.DEFAULT_USER_PROJECTION = "EPSG:4326"; - +/** + @const + @type {number} +*/ +ol.Map.ZOOM_FACTOR = 2; +/** + @const + @type {number} +*/ +ol.Map.DEFAULT_TILE_SIZE = 256; /** * @return {ol.Loc} Location. @@ -145,6 +166,39 @@ ol.Map.prototype.getMaxExtent = function() { }; +/** + * @return {number} the max resolution for the map + */ +ol.Map.prototype.getMaxRes = function() { + if (goog.isDefAndNotNull(this.maxRes_)) { + return this.maxRes_; + } else { + var extent = this.getMaxExtent(); + if (goog.isDefAndNotNull(extent)) { + var dim = Math.max( + (extent.getMaxX()-extent.getMinX()), + (extent.getMaxY()-extent.getMinY()) + ); + return dim/ol.Map.DEFAULT_TILE_SIZE; + } + } +}; + + +/** + * @param {number} zoom the zoom level being requested + * @return {number} the resolution for the map at the given zoom level + */ +ol.Map.prototype.getResolutionForZoom = function(zoom) { + if (goog.isDefAndNotNull(this.resolutions_)) { + return this.resolutions_[zoom]; + } else { + var maxRes = this.getMaxRes(); + return maxRes/Math.pow(ol.Map.ZOOM_FACTOR, zoom); + } +}; + + /** * @param {ol.Loc} center Center. */ @@ -205,6 +259,13 @@ ol.Map.prototype.setMaxExtent = function(extent) { this.maxExtent_ = extent; }; +/** + * @param {number} res the max resolution for the map + */ +ol.Map.prototype.setMaxRes = function(res) { + this.maxRes_ = res; +}; + /** */ ol.Map.prototype.destroy = function() { diff --git a/src/ol/Projection.js b/src/ol/Projection.js index 90937f0d5c..63da6b4a9f 100644 --- a/src/ol/Projection.js +++ b/src/ol/Projection.js @@ -21,15 +21,15 @@ ol.Projection = function(code) { /** * @private - * @type {!Object|undefined} + * @type {Object} */ - this.proj_ = undefined; + this.proj_ = null; /** * @private - * @type {!ol.UnreferencedBounds|undefined} + * @type {ol.UnreferencedBounds} */ - this.extent_ = undefined; + this.extent_ = null; }; @@ -65,9 +65,18 @@ ol.Projection.prototype.setUnits = function(units) { /** * Get the validity extent of the coordinate reference system. * - * @return {!ol.UnreferencedBounds|undefined} The valididty extent. + * @return {ol.UnreferencedBounds} The valididty extent. */ ol.Projection.prototype.getExtent = function() { + if (goog.isNull(this.extent_)) { + var defs = ol.Projection['defaults'][this.code_]; + if (goog.isDef(defs)) { + var ext = defs['maxExtent']; + if (goog.isDef(ext)) { + this.setExtent(new ol.UnreferencedBounds(ext[0],ext[1],ext[2],ext[3])); + } + } + } return this.extent_; }; diff --git a/test/spec/api/map.test.js b/test/spec/api/map.test.js index c7e8ada22a..db43cf884c 100644 --- a/test/spec/api/map.test.js +++ b/test/spec/api/map.test.js @@ -164,7 +164,7 @@ describe("ol.map", function() { map.destroy(); - expect(goog.isDef(map.layers)).toBe(false); + expect(goog.isDef(map.getLayers())).toBe(false); }); @@ -199,11 +199,11 @@ describe("ol.map", function() { var map = ol.map(); var extent = map.maxExtent(); - expect(extent).toBeA(ol.Bounds); - expect(extent.minX()).toBe(-20037508.34); - expect(extent.maxX()).toBe(-20037508.34); - expect(extent.minY()).toBe(20037508.34); - expect(extent.maxY()).toBe(20037508.34); + expect(extent).toBeA(ol.UnreferencedBounds); + expect(extent.getMinX()).toBe(-20037508.34); + expect(extent.getMaxX()).toBe(20037508.34); + expect(extent.getMinY()).toBe(-20037508.34); + expect(extent.getMaxY()).toBe(20037508.34); }); @@ -212,11 +212,11 @@ describe("ol.map", function() { map.maxExtent([-5,-4,7,9]); var extent = map.maxExtent(); - expect(extent).toBeA(ol.Bounds); - expect(extent.minX()).toBe(-5); - expect(extent.maxX()).toBe(-4); - expect(extent.minY()).toBe(7); - expect(extent.maxY()).toBe(9); + expect(extent).toBeA(ol.UnreferencedBounds); + expect(extent.getMinX()).toBe(-5); + expect(extent.getMaxX()).toBe(7); + expect(extent.getMinY()).toBe(-4); + expect(extent.getMaxY()).toBe(9); }); @@ -225,11 +225,11 @@ describe("ol.map", function() { map.projection("CRS:84"); var extent = map.maxExtent(); - expect(extent).toBeA(ol.Bounds); - expect(extent.minX()).toBe(-180); - expect(extent.maxX()).toBe(-90); - expect(extent.minY()).toBe(180); - expect(extent.maxY()).toBe(90); + expect(extent).toBeA(ol.UnreferencedBounds); + expect(extent.getMinX()).toBe(-180); + expect(extent.getMaxX()).toBe(180); + expect(extent.getMinY()).toBe(-90); + expect(extent.getMaxY()).toBe(90); }); @@ -244,7 +244,7 @@ describe("ol.map", function() { var map = ol.map(); var res = map.maxRes(); - expect(res.toFixed(5)).toBe(1.40625); + expect(res.toFixed(5)).toBe("156543.03391"); }); @@ -261,22 +261,35 @@ describe("ol.map", function() { it("getMaxRes returns correct for custom maxExtent", function() { var map = ol.map({ projection: ol.projection({ + code: 'foo', maxExtent: [0,0,90,90] }) }); var res = map.maxRes(); - expect(res.toFixed(7)).toBe(0.3515625); + expect(res.toFixed(7)).toBe("0.3515625"); }); - it("getResForZoom returns correct defaults", function() { + it("returns correct getResForZoom for default map", function() { var map = ol.map(); - res = map.getResForZoom(0); - expect(res.toFixed(5)).toBe(1.40625); + var res = map.getResForZoom(0); + expect(res.toFixed(5)).toBe("156543.03391"); res = map.getResForZoom(5); - expect(res.toFixed(10)).toBe(0.0439453125); + expect(res.toFixed(5)).toBe("4891.96981"); + + }); + + it("returns correct getResForZoom when resolution array is set",function() { + var map = ol.map({ + resolutions: [1,4,7,9,12] + }); + + var res = map.getResForZoom(0); + expect(res).toBe(1); + res = map.getResForZoom(3); + expect(res).toBe(9); }); From 00e25d3a62b5d26d74a894ead71815124578f02d Mon Sep 17 00:00:00 2001 From: Mike Adair Date: Wed, 20 Jun 2012 08:41:47 -0400 Subject: [PATCH 05/24] fix warnings --- src/ol/Map.js | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/ol/Map.js b/src/ol/Map.js index 2529f14953..3242bf5fd5 100644 --- a/src/ol/Map.js +++ b/src/ol/Map.js @@ -42,19 +42,19 @@ ol.Map = function() { /** * @private - * @type {Array|undefined} + * @type {Array} */ this.resolutions_ = null; /** * @private - * @type {Array|undefined} + * @type {Array} */ this.layers_ = null; /** * @private - * @type {ol.UnreferencedBounds|undefined} + * @type {ol.UnreferencedBounds} */ this.maxExtent_ = null; @@ -62,7 +62,7 @@ ol.Map = function() { * @private * @type {number|undefined} */ - this.maxRes_ = null; + this.maxRes_ = undefined; }; @@ -174,13 +174,11 @@ ol.Map.prototype.getMaxRes = function() { return this.maxRes_; } else { var extent = this.getMaxExtent(); - if (goog.isDefAndNotNull(extent)) { - var dim = Math.max( - (extent.getMaxX()-extent.getMinX()), - (extent.getMaxY()-extent.getMinY()) - ); - return dim/ol.Map.DEFAULT_TILE_SIZE; - } + var dim = Math.max( + (extent.getMaxX()-extent.getMinX()), + (extent.getMaxY()-extent.getMinY()) + ); + return dim/ol.Map.DEFAULT_TILE_SIZE; } }; @@ -253,7 +251,7 @@ ol.Map.prototype.setLayers = function(layers) { }; /** - * @param {ol.Bounds} extent the maxExtent for the map + * @param {ol.UnreferencedBounds} extent the maxExtent for the map */ ol.Map.prototype.setMaxExtent = function(extent) { this.maxExtent_ = extent; From 09a6b6c45611f936320bac6d2bc420c164dba17b Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Wed, 20 Jun 2012 14:52:17 +0200 Subject: [PATCH 06/24] Changing expectations for projection. --- src/ol/Loc.js | 6 +++--- test/spec/api/loc.test.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ol/Loc.js b/src/ol/Loc.js index 4c2cd77724..c3d4505038 100644 --- a/src/ol/Loc.js +++ b/src/ol/Loc.js @@ -33,9 +33,9 @@ ol.Loc = function(x, y, opt_z, opt_projection) { /** * @private - * @type {ol.Projection|undefined} + * @type {ol.Projection} */ - this.projection_ = opt_projection; + this.projection_ = goog.isDef(opt_projection) ? opt_projection : null; }; @@ -73,7 +73,7 @@ ol.Loc.prototype.getZ = function() { /** - * @param {ol.Projection|undefined} projection Projection. + * @param {ol.Projection} projection Projection. */ ol.Loc.prototype.setProjection = function(projection) { this.projection_ = projection; diff --git a/test/spec/api/loc.test.js b/test/spec/api/loc.test.js index 88b0aefdfa..a7bbf71168 100644 --- a/test/spec/api/loc.test.js +++ b/test/spec/api/loc.test.js @@ -58,7 +58,7 @@ describe("ol.loc", function() { var loc = ol.loc({x: 1, y: 2}); - expect(loc.projection()).toBeUndefined(); + expect(loc.projection()).toBeNull(); }); From d933404df89d963806bcf7ce2479a8772f07b502 Mon Sep 17 00:00:00 2001 From: Marc Jansen Date: Wed, 20 Jun 2012 14:58:37 +0200 Subject: [PATCH 07/24] Make Points transformable. --- src/ol/geom/Point.js | 34 ++++++++++++++++++++++++++++ test/spec/ol/geom/Point.test.js | 39 ++++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/ol/geom/Point.js b/src/ol/geom/Point.js index 983352cafb..ee9339d4c8 100644 --- a/src/ol/geom/Point.js +++ b/src/ol/geom/Point.js @@ -106,3 +106,37 @@ ol.geom.Point.prototype.setZ = function(z) { this.z_ = z; }; +/** + * Transform this point to another coordinate reference system. This + * requires that this point has a projection set already (if not, an error + * will be thrown). Returns a new point object and does not modify this + * point. + * + * @param {string|!ol.Projection} proj The destination projection. Can be + * supplied as a projection instance of a string identifier. + * @returns {!ol.geom.Point} A new location. + */ +ol.geom.Point.prototype.transform = function(proj) { + if (goog.isString(proj)) { + proj = new ol.Projection(proj); + } + return this.transform_(proj); +}; + +/** + * Transform this point to a new location given a projection object. + * + * @param {!ol.Projection} proj The destination projection. + * @returns {!ol.geom.Point} + * @private + */ +ol.geom.Point.prototype.transform_ = function(proj) { + var point = {x: this.x_, y: this.y_}; + var sourceProj = this.projection_; + if (!goog.isDefAndNotNull(sourceProj)) { + throw new Error("Cannot transform a point without a source projection."); + } + ol.Projection.transform(point, sourceProj, proj); + return new ol.geom.Point(point.x, point.y, this.z_, proj); +}; + diff --git a/test/spec/ol/geom/Point.test.js b/test/spec/ol/geom/Point.test.js index 65103b2469..35c070b25f 100644 --- a/test/spec/ol/geom/Point.test.js +++ b/test/spec/ol/geom/Point.test.js @@ -2,7 +2,6 @@ describe("ol.geom.Point", function() { var p2Args, p3Args, p4Args, - p_arr, proj = "EPSG:4326"; var instances = { @@ -57,6 +56,7 @@ describe("ol.geom.Point", function() { expect(instance.getProjection).not.toBeUndefined(); expect(instance.setProjection).not.toBeUndefined(); }); + } } @@ -83,4 +83,41 @@ describe("ol.geom.Point", function() { expect(p4Args.getProjection()).not.toBeNull(); expect(p4Args.getProjection()).toBeA(ol.Projection); }); + + it("can be transformed", function(){ + // save for later comparison + var old = { + x: p4Args.getX().toFixed(3), + y: p4Args.getY().toFixed(3) + }; + // with code only + var transformedPoint = p4Args.transform("EPSG:3857"); + + // is it still an instance of ol.geom.Point? + expect(transformedPoint).toBeA(ol.geom.Point); + // coordinates OK? + expect(transformedPoint.getX().toFixed(3)).toBe("2337709.306"); + expect(transformedPoint.getY().toFixed(3)).toBe("445640.110"); + + // with an ol.Projection + var retransformedPoint = transformedPoint.transform(new ol.Projection("EPSG:4326")); + expect(retransformedPoint).toBeA(ol.geom.Point); + + // coordinates shopulkd be the originally configured + expect(retransformedPoint.getX().toFixed(3)).toBe(old.x); + expect(retransformedPoint.getY().toFixed(3)).toBe(old.y); + }); + + it("throws an exception when you try to transform without a source projection", function(){ + + expect(function() { + p2Args.transform("EPSG:3857"); + }).toThrow(); + + expect(function() { + p3Args.transform("EPSG:3857"); + }).toThrow(); + + }); + }); From aa584e17e9b24ad1bd1a95bc1fe5529296a830f5 Mon Sep 17 00:00:00 2001 From: Mike Adair Date: Wed, 20 Jun 2012 09:02:20 -0400 Subject: [PATCH 08/24] center returned in user projection --- src/ol/Map.js | 9 ++++++++- test/index.html | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/ol/Map.js b/src/ol/Map.js index 3242bf5fd5..052f0ca334 100644 --- a/src/ol/Map.js +++ b/src/ol/Map.js @@ -91,6 +91,8 @@ ol.Map.DEFAULT_TILE_SIZE = 256; * @return {ol.Loc} Location. */ ol.Map.prototype.getCenter = function() { + var proj = this.getUserProjection(); + this.center_ = this.center_.transform(proj); return this.center_; }; @@ -201,7 +203,12 @@ ol.Map.prototype.getResolutionForZoom = function(zoom) { * @param {ol.Loc} center Center. */ ol.Map.prototype.setCenter = function(center) { - this.center_ = center; + var proj = center.getProjection(); + if (goog.isNull(proj)) { + proj = this.getUserProjection(); + center.setProjection(proj); + } + this.center_ = center.transform(this.getProjection()); }; diff --git a/test/index.html b/test/index.html index b271f302c1..3e57ae944b 100644 --- a/test/index.html +++ b/test/index.html @@ -9,7 +9,7 @@ - + From e61769c6dce9006bfe22b78bd73373122e0fa1b8 Mon Sep 17 00:00:00 2001 From: Mike Adair Date: Wed, 20 Jun 2012 09:04:51 -0400 Subject: [PATCH 09/24] put back to SIMPLE mode --- test/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/index.html b/test/index.html index 3e57ae944b..b271f302c1 100644 --- a/test/index.html +++ b/test/index.html @@ -9,7 +9,7 @@ - + From e989c61e63275007f3d08559130c8ad391dc4c97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Wed, 20 Jun 2012 15:09:30 +0200 Subject: [PATCH 10/24] make the tests run in Closure RAW mode, but leave the SIMPLE mode script tag to still catch compilation errors/warnings while running tests --- test/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/test/index.html b/test/index.html index b271f302c1..0083c74e0e 100644 --- a/test/index.html +++ b/test/index.html @@ -10,6 +10,7 @@ + From 2890a55ee73c38a3cf02defd2e91e8f01fb9f1cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Wed, 20 Jun 2012 15:13:22 +0200 Subject: [PATCH 11/24] [ol.layer.XYZ] a tiling fix --- src/ol/layer/XYZ.js | 20 ++++++++------------ test/spec/ol/layer/XYZ.test.js | 3 +-- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/ol/layer/XYZ.js b/src/ol/layer/XYZ.js index 60dc65d660..d9ff88ef89 100644 --- a/src/ol/layer/XYZ.js +++ b/src/ol/layer/XYZ.js @@ -130,26 +130,22 @@ ol.layer.XYZ.prototype.getData = function(bounds, resolution) { offsetY = Math.floor( (tileOriginY - boundsMaxY) / tileHeightGeo), - gridWidth = Math.ceil( - (boundsMaxX - boundsMinX) / tileWidthGeo), - gridHeight = Math.ceil( - (boundsMaxY - boundsMinY) / tileHeightGeo); + gridLeft = tileOriginX + tileWidthGeo * offsetX, + gridTop = tileOriginY - tileHeightGeo * offsetY; - var tiles = [], - tile, - url, - i, ii, - j, jj; - - for (i=0, ii=gridWidth; i boundsMinY) { tiles[i] = []; - for (j=0, jj=gridHeight; j Date: Wed, 20 Jun 2012 15:26:02 +0200 Subject: [PATCH 12/24] Finalizing tests for ol.Events --- src/ol/event/Events.js | 6 +- test/spec/ol/Events.test.js | 137 ++++++++++++++++++++++++++++++++++-- 2 files changed, 133 insertions(+), 10 deletions(-) diff --git a/src/ol/event/Events.js b/src/ol/event/Events.js index 81d1c13c8d..2761281fd1 100644 --- a/src/ol/event/Events.js +++ b/src/ol/event/Events.js @@ -83,7 +83,7 @@ ol.event.Events.prototype.getObject = function() { * @param {boolean} includeXY */ ol.event.Events.prototype.setIncludeXY = function(includeXY) { - this._includeXY = includeXY; + this.includeXY_ = includeXY; }; /** @@ -215,7 +215,7 @@ ol.event.Events.prototype.un = function(object) { }; /** - * Unregister a listener for an egent + * Unregister a listener for an event * * @param {string} type Name of the event to unregister * @param {Function} listener The callback function. @@ -283,7 +283,7 @@ ol.event.Events.prototype.handleBrowserEvent = function(evt) { evt.clientX = x / num; evt.clientY = y / num; } - if (this.includeXY) { + if (this.includeXY_) { var element = /** @type {!Element} */ this.element_; evt.xy = goog.style.getRelativePosition(evt, element); } diff --git a/test/spec/ol/Events.test.js b/test/spec/ol/Events.test.js index 99ae690a2f..44bac2356f 100644 --- a/test/spec/ol/Events.test.js +++ b/test/spec/ol/Events.test.js @@ -1,31 +1,154 @@ describe("ol.Events", function() { + + var count = 0, log = [], + countFn = function() {count++;}, + logFn = function(e) {log.push({scope: this, evt: e});}; it("constructs instances", function() { var events, element = document.createElement("div"); - events = new ol.event.Events("foo"); + + events = new ol.event.Events("foo"); expect(events.getObject()).toBe("foo"); - expect(events.getElement()).toBe(null); + expect(events.getElement()).toBe(null); events.destroy(); - events = new ol.event.Events("foo", element, true); + + events = new ol.event.Events("foo", element, true); expect(events.getElement()).toBe(element); - expect(events.includeXY_).toBe(true); + expect(events.includeXY_).toBe(true); events.destroy(); }); it("destroys properly", function() { var events = new ol.event.Events("foo"); - events.destroy(); + events.destroy(); expect(events.getObject()).toBe(undefined); }); + it("relays browser events and knows about pointer position", function() { + var element = document.createElement("div"), + events = new ol.event.Events("foo", element); + + //TODO Figure out a good way to deal with fixtures + element.style.position = "absolute"; + element.style.left = "5px"; + element.style.top = "10px"; + document.body.appendChild(element); + // mock dom element so we can trigger events on it + goog.object.extend(element, new goog.events.EventTarget()); + + log = []; + events.register("click", logFn); + element.dispatchEvent("click"); + expect(log.length).toBe(1); + + // detach from the element + events.setElement(); + element.dispatchEvent("click"); + expect(log.length).toBe(1); + + // attach to the element again + events.setElement(element); + events.setIncludeXY(true); + element.dispatchEvent({ + type: "click", + touches: [{clientX: 9, clientY: 22}, {clientX: 11, clientY: 18}] + }); + expect(log.length).toBe(2); + expect(log[1].evt.xy.x).toBe(5); + expect(log[1].evt.xy.y).toBe(10); + expect(log[1].evt.clientX).toBe(10); + expect(log[1].evt.clientY).toBe(20); + + events.destroy(); + document.body.removeChild(element); + }); + + it("calls listeners with a scope and an event object", function() { + var scope = {}, evt = {}, events = new ol.event.Events("foo"); + + log = []; + events.register("bar", logFn, scope); + events.triggerEvent("bar", evt); + expect(log[0].scope).toBe(scope); + expect(log[0].evt).toBe(evt); + }); + it("respects event priority", function() { var log = [], events = new ol.event.Events("foo"); + + // register a normal listener events.register("bar", function() {log.push("normal");}); + // register a priority listener events.register( - "bar", function() {log.push("priority");}, undefined, true); - events.triggerEvent("bar"); + "bar", function() {log.push("priority");}, undefined, true); + events.triggerEvent("bar"); expect(log[0]).toBe("priority"); expect(log[1]).toBe("normal"); + + events.destroy(); + }); + + it("allows to abort the event chain", function() { + var events = new ol.event.Events("foo"); + + count = 0; + // register a listener that aborts the event chain + events.register("bar", function() {count++; return false;}); + // register a listener that just does something + events.register("bar", countFn); + events.triggerEvent("bar"); + expect(count).toBe(1); + + count = 0; + // register a priority listener that just does something + events.register("bar", countFn, undefined, true); + events.triggerEvent("bar"); + expect(count).toBe(2); + + events.destroy(); + }); + + it("allows to unregister events", function() { + var events = new ol.event.Events("foo"); + + count = 0; + events.register("bar", countFn); + events.triggerEvent("bar"); + expect(count).toBe(1); + + events.unregister("bar", countFn); + events.triggerEvent("bar"); + expect(count).toBe(1); + + events.destroy(); + }); + + it("has working on() and un() convenience methods", function() { + var scope = {}, events = new ol.event.Events("foo"); + + count = 0; + log = []; + events.on({ + "bar": countFn, + "baz": logFn, + scope: scope + }); + events.triggerEvent("bar"); + expect(count).toBe(1); + events.triggerEvent("baz"); + expect(log[0].scope).toBe(scope); + + events.un({ + "bar": countFn, + "baz": logFn, + scope: scope + }); + events.triggerEvent("bar"); + events.triggerEvent("baz"); + expect(count).toBe(1); + expect(log.length).toBe(1); + + events.destroy(); }); }); From 6b8cd1216f55198d8454dbcda65cd615648127cc Mon Sep 17 00:00:00 2001 From: Marc Jansen Date: Wed, 20 Jun 2012 15:42:10 +0200 Subject: [PATCH 13/24] Easier getter/setter for geom.point. --- src/api/geom/point.js | 65 ++++++++++++++++++- test/spec/api/geom/point.test.js | 108 +++++++++++++++++++------------ 2 files changed, 132 insertions(+), 41 deletions(-) diff --git a/src/api/geom/point.js b/src/api/geom/point.js index 06cf74fe75..f4b9bd84d7 100644 --- a/src/api/geom/point.js +++ b/src/api/geom/point.js @@ -47,4 +47,67 @@ ol.geom.point = function(opt_arg){ var p = new ol.geom.Point(x,y,z,projection); return p; }; -goog.inherits(ol.geom.point, ol.geom.geometry); \ No newline at end of file +goog.inherits(ol.geom.point, ol.geom.geometry); + + +/** + * @export + * @param {number=} opt_arg X. + * @return {ol.geom.Point|number} Result. + */ +ol.geom.Point.prototype.x = function(opt_arg){ + if (arguments.length == 1 && goog.isDef(opt_arg)) { + this.setX(opt_arg); + return this; + } + else { + return this.getX(); + } +}; + + +/** + * @export + * @param {number=} opt_arg Y. + * @return {ol.geom.Point|number} Result. + */ +ol.geom.Point.prototype.y = function(opt_arg){ + if (arguments.length == 1 && goog.isDef(opt_arg)) { + this.setY(opt_arg); + return this; + } + else { + return this.getY(); + } +}; + + +/** + * @export + * @param {number=} opt_arg Z. + * @return {ol.geom.Point|number|undefined} Result. + */ +ol.geom.Point.prototype.z = function(opt_arg){ + if (arguments.length == 1 && goog.isDef(opt_arg)) { + this.setZ(opt_arg); + return this; + } + else { + return this.getZ(); + } +}; + +/** + * @export + * @param {ol.Projection=} opt_arg Projection. + * @return {ol.geom.Point|ol.Projection|undefined} Result. + */ +ol.geom.Point.prototype.projection = function(opt_arg){ + if (arguments.length == 1 && goog.isDef(opt_arg)) { + this.setProjection(ol.projection(opt_arg)); + return this; + } + else { + return this.getProjection(); + } +}; \ No newline at end of file diff --git a/test/spec/api/geom/point.test.js b/test/spec/api/geom/point.test.js index 70736921e1..8936a3aa16 100644 --- a/test/spec/api/geom/point.test.js +++ b/test/spec/api/geom/point.test.js @@ -65,70 +65,98 @@ describe("ol.geom.point", function() { expect(instance).toEqual(jasmine.any(ol.geom.Geometry)); }); - it("has the coordinate accessor methods (" + instancesDesc + ")", function() { - expect(instance.getX).not.toBeUndefined(); - expect(instance.getY).not.toBeUndefined(); - expect(instance.getZ).not.toBeUndefined(); - expect(instance.setX).not.toBeUndefined(); - expect(instance.setY).not.toBeUndefined(); - expect(instance.setZ).not.toBeUndefined(); + it("has coordinate getter/setter methods (" + instancesDesc + ")", function() { + expect(instance.x).not.toBeUndefined(); + expect(instance.y).not.toBeUndefined(); + expect(instance.z).not.toBeUndefined(); + + // always a number + expect( !isNaN( instance.x() ) ).toBe(true); + // setter returns self + expect(instance.x(47)).toBeA(ol.geom.Point); + // getter returns correct number + expect(instance.x()).toBe(47); + + // always a number + expect( !isNaN( instance.y() ) ).toBe(true); + // setter returns self + expect(instance.y(74)).toBeA(ol.geom.Point); + // getter returns correct number + expect(instance.y()).toBe(74); + + // always number or undefined + expect(instance.z() === undefined || !isNaN(instance.z()) ).toBe(true); + // setter returns self + expect(instance.z(0.074)).toBeA(ol.geom.Point); + // getter returns correct number + expect(instance.z()).toBe(0.074); + }); - it("has the projection accessor methods (" + instancesDesc + ")", function() { - expect(instance.getProjection).not.toBeUndefined(); - expect(instance.setProjection).not.toBeUndefined(); + it("has projection getter/setter methods (" + instancesDesc + ")", function() { + expect(instance.projection).not.toBeUndefined(); + + var getRes = instance.projection(); + expect(getRes === null || getRes instanceof ol.Projection).toBe(true); + + var setRes = instance.projection("EPSG:12345"); + expect(setRes instanceof ol.geom.Point).toBe(true); + + getRes = instance.projection(); + expect(getRes).toBeA(ol.Projection); + expect(getRes.code()).toEqual("EPSG:12345"); }); } } it("has functional getters (no arguments passed)", function(){ - expect(pNoArgs.getX()).toBe(0); - expect(pNoArgs.getY()).toBe(0); - expect(pNoArgs.getZ()).toBeUndefined(); - expect(pNoArgs.getProjection()).toBeNull(); + expect(pNoArgs.x()).toBe(0); + expect(pNoArgs.y()).toBe(0); + expect(pNoArgs.z()).toBeUndefined(); + expect(pNoArgs.projection()).toBeNull(); }); it("has functional getters (one argument passed)", function(){ - expect(pNoZ_arr.getX()).toBe(21); - expect(pNoZ_arr.getY()).toBe(4); - expect(pNoZ_arr.getZ()).toBeUndefined(); - expect(pNoZ_arr.getProjection()).toBeNull(); + expect(pNoZ_arr.x()).toBe(21); + expect(pNoZ_arr.y()).toBe(4); + expect(pNoZ_arr.z()).toBeUndefined(); + expect(pNoZ_arr.projection()).toBeNull(); }); it("has functional getters (one argument passed)", function(){ - expect(pWithZ_arr.getX()).toBe(21); - expect(pWithZ_arr.getY()).toBe(4); - expect(pWithZ_arr.getZ()).toBe(8); - expect(pWithZ_arr.getProjection()).toBeNull(); + expect(pWithZ_arr.x()).toBe(21); + expect(pWithZ_arr.y()).toBe(4); + expect(pWithZ_arr.z()).toBe(8); + expect(pWithZ_arr.projection()).toBeNull(); }); it("has functional getters (one argument passed)", function(){ - expect(p_arr.getX()).toBe(21); - expect(p_arr.getY()).toBe(4); - expect(p_arr.getZ()).toBe(8); - expect(p_arr.getProjection()).not.toBeNull(); - expect(p_arr.getProjection()).toEqual(jasmine.any(ol.Projection)); + expect(p_arr.x()).toBe(21); + expect(p_arr.y()).toBe(4); + expect(p_arr.z()).toBe(8); + expect(p_arr.projection()).not.toBeNull(); + expect(p_arr.projection()).toBeA(ol.Projection); }); it("has functional getters (one argument passed)", function(){ - expect(pNoZ_obj.getX()).toBe(21); - expect(pNoZ_obj.getY()).toBe(4); - expect(pNoZ_obj.getZ()).toBeUndefined(); - expect(pNoZ_obj.getProjection()).toBeNull(); + expect(pNoZ_obj.x()).toBe(21); + expect(pNoZ_obj.y()).toBe(4); + expect(pNoZ_obj.z()).toBeUndefined(); + expect(pNoZ_obj.projection()).toBeNull(); }); it("has functional getters (one argument passed)", function(){ - expect(pWithZ_obj.getX()).toBe(21); - expect(pWithZ_obj.getY()).toBe(4); - expect(pWithZ_obj.getZ()).toBe(8); - expect(pWithZ_obj.getProjection()).toBeNull(); + expect(pWithZ_obj.x()).toBe(21); + expect(pWithZ_obj.y()).toBe(4); + expect(pWithZ_obj.z()).toBe(8); + expect(pWithZ_obj.projection()).toBeNull(); }); it("has functional getters (one argument passed)", function(){ - expect(p_obj.getX()).toBe(21); - expect(p_obj.getY()).toBe(4); - expect(p_obj.getZ()).toBe(8); - expect(p_obj.getProjection()).not.toBeNull(); - expect(p_obj.getProjection()).toEqual(jasmine.any(ol.Projection)); + expect(p_obj.x()).toBe(21); + expect(p_obj.y()).toBe(4); + expect(p_obj.z()).toBe(8); + expect(p_obj.projection()).not.toBeNull(); + expect(p_obj.projection()).toEqual(jasmine.any(ol.Projection)); }); }); From d4ebe97ab1fac7c3fbbc3cce217bc90094928406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Wed, 20 Jun 2012 15:50:09 +0200 Subject: [PATCH 14/24] [test/index.html] remove the mode=RAW script tag again, it does not work anymore --- test/index.html | 1 - 1 file changed, 1 deletion(-) diff --git a/test/index.html b/test/index.html index 0083c74e0e..b271f302c1 100644 --- a/test/index.html +++ b/test/index.html @@ -10,7 +10,6 @@ - From 80f76a91e1851e5661c9b9418e65518f1a3313ea Mon Sep 17 00:00:00 2001 From: ahocevar Date: Wed, 20 Jun 2012 15:52:08 +0200 Subject: [PATCH 15/24] Always provide a proper event object. --- src/ol/event/Events.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ol/event/Events.js b/src/ol/event/Events.js index 2761281fd1..da65865929 100644 --- a/src/ol/event/Events.js +++ b/src/ol/event/Events.js @@ -242,6 +242,9 @@ ol.event.Events.prototype.triggerEvent = function(type, evt) { var returnValue, listeners = goog.events.getListeners(this, type, true) .concat(goog.events.getListeners(this, type, false)); + if (arguments.length === 1) { + evt = {type: type}; + } for (var i=0, ii=listeners.length; i Date: Wed, 20 Jun 2012 15:52:24 +0200 Subject: [PATCH 16/24] Better cleanup. --- src/ol/event/Events.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ol/event/Events.js b/src/ol/event/Events.js index da65865929..9b1702e466 100644 --- a/src/ol/event/Events.js +++ b/src/ol/event/Events.js @@ -297,6 +297,7 @@ ol.event.Events.prototype.handleBrowserEvent = function(evt) { * Destroy this Events instance. */ ol.event.Events.prototype.destroy = function() { + this.setElement(); for (var p in this) { delete this[p]; } From 66a5a8ad7a4c9fe352cba591379fac9d3efd508a Mon Sep 17 00:00:00 2001 From: ahocevar Date: Wed, 20 Jun 2012 15:53:01 +0200 Subject: [PATCH 17/24] countFn not needed - do everything with logFn. --- test/spec/ol/Events.test.js | 40 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/test/spec/ol/Events.test.js b/test/spec/ol/Events.test.js index 44bac2356f..198dc61109 100644 --- a/test/spec/ol/Events.test.js +++ b/test/spec/ol/Events.test.js @@ -1,7 +1,6 @@ describe("ol.Events", function() { - var count = 0, log = [], - countFn = function() {count++;}, + var log = [], logFn = function(e) {log.push({scope: this, evt: e});}; it("constructs instances", function() { @@ -91,19 +90,19 @@ describe("ol.Events", function() { it("allows to abort the event chain", function() { var events = new ol.event.Events("foo"); - count = 0; + log = []; // register a listener that aborts the event chain - events.register("bar", function() {count++; return false;}); + events.register("bar", function(e) {logFn(e); return false;}); // register a listener that just does something - events.register("bar", countFn); + events.register("bar", logFn); events.triggerEvent("bar"); - expect(count).toBe(1); + expect(log.length).toBe(1); - count = 0; + log = []; // register a priority listener that just does something - events.register("bar", countFn, undefined, true); + events.register("bar", logFn, undefined, true); events.triggerEvent("bar"); - expect(count).toBe(2); + expect(log.length).toBe(2); events.destroy(); }); @@ -111,14 +110,14 @@ describe("ol.Events", function() { it("allows to unregister events", function() { var events = new ol.event.Events("foo"); - count = 0; - events.register("bar", countFn); + log = []; + events.register("bar", logFn); events.triggerEvent("bar"); - expect(count).toBe(1); + expect(log.length).toBe(1); - events.unregister("bar", countFn); + events.unregister("bar", logFn); events.triggerEvent("bar"); - expect(count).toBe(1); + expect(log.length).toBe(1); events.destroy(); }); @@ -126,27 +125,26 @@ describe("ol.Events", function() { it("has working on() and un() convenience methods", function() { var scope = {}, events = new ol.event.Events("foo"); - count = 0; log = []; events.on({ - "bar": countFn, + "bar": logFn, "baz": logFn, scope: scope }); events.triggerEvent("bar"); - expect(count).toBe(1); + expect(log[0].evt.type).toBe("bar"); events.triggerEvent("baz"); - expect(log[0].scope).toBe(scope); + expect(log[1].scope).toBe(scope); + expect(log[1].evt.type).toBe("baz"); events.un({ - "bar": countFn, + "bar": logFn, "baz": logFn, scope: scope }); events.triggerEvent("bar"); events.triggerEvent("baz"); - expect(count).toBe(1); - expect(log.length).toBe(1); + expect(log.length).toBe(2); events.destroy(); }); From f74d265dec1a557f7622b219c4e43953c62bdaf1 Mon Sep 17 00:00:00 2001 From: ahocevar Date: Wed, 20 Jun 2012 16:02:41 +0200 Subject: [PATCH 18/24] Verified isSingleTouch and isMultiTouch functions. --- src/ol/event/Events.js | 8 ++++---- test/spec/ol/Events.test.js | 14 +++++++++++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/ol/event/Events.js b/src/ol/event/Events.js index 9b1702e466..981c03b119 100644 --- a/src/ol/event/Events.js +++ b/src/ol/event/Events.js @@ -11,21 +11,21 @@ goog.require('goog.style'); /** * Determine whether event was caused by a single touch * - * @param {Event} evt + * @param {!Event} evt * @return {boolean} */ ol.event.isSingleTouch = function(evt) { - return evt.touches && evt.touches.length == 1; + return !!(evt.touches && evt.touches.length == 1); }; /** * Determine whether event was caused by a multi touch * - * @param {Event} evt + * @param {!Event} evt * @return {boolean} */ ol.event.isMultiTouch = function(evt) { - return evt.touches && evt.touches.length > 1; + return !!(evt.touches && evt.touches.length > 1); }; diff --git a/test/spec/ol/Events.test.js b/test/spec/ol/Events.test.js index 198dc61109..53a7f86e93 100644 --- a/test/spec/ol/Events.test.js +++ b/test/spec/ol/Events.test.js @@ -122,7 +122,7 @@ describe("ol.Events", function() { events.destroy(); }); - it("has working on() and un() convenience methods", function() { + it("has on() and un() convenience methods", function() { var scope = {}, events = new ol.event.Events("foo"); log = []; @@ -149,4 +149,16 @@ describe("ol.Events", function() { events.destroy(); }); + it("provides an isSingleTouch() function", function() { + expect(ol.event.isSingleTouch({touches: [{}, {}]})).toBe(false); + expect(ol.event.isSingleTouch({touches: [{}]})).toBe(true); + expect(ol.event.isSingleTouch({})).toBe(false); + }); + + it("provides an isMultiTouch() function", function() { + expect(ol.event.isMultiTouch({touches: [{}, {}]})).toBe(true); + expect(ol.event.isMultiTouch({touches: [{}]})).toBe(false); + expect(ol.event.isMultiTouch({})).toBe(false); + }); + }); From 5eeb21c12516c5be79ccde56dc19ad691c146c23 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Wed, 20 Jun 2012 16:11:15 +0200 Subject: [PATCH 19/24] Disallow nowhere. --- src/api/loc.js | 19 ++++++++++++++++--- test/spec/api/loc.test.js | 11 ++++++----- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/api/loc.js b/src/api/loc.js index 0a8ce222ea..4c36d11535 100644 --- a/src/api/loc.js +++ b/src/api/loc.js @@ -22,11 +22,20 @@ ol.loc = function(opt_arg){ return opt_arg; } - var x = 0; - var y = 0; + /** @type {number|undefined} */ + var x; + + /** @type {number|undefined} */ + var y; + + /** @type {number|undefined} */ var z; + + /** @type {Object|undefined} */ var projection; + var usage = 'ol.loc accepts a coordinate array or an object with x, y, and (optional) z properties'; + if (arguments.length == 1 && goog.isDef(opt_arg)) { if (goog.isArray(opt_arg)) { x = opt_arg[0]; @@ -39,9 +48,13 @@ ol.loc = function(opt_arg){ z = opt_arg['z']; projection = opt_arg['projection']; } else { - throw new Error('ol.loc'); + throw new Error(usage); } } + + if (!goog.isNumber(x) || !goog.isNumber(y)) { + throw new Error(usage); + } if (goog.isDef(projection)) { projection = ol.projection(projection); diff --git a/test/spec/api/loc.test.js b/test/spec/api/loc.test.js index a7bbf71168..0296f15ca4 100644 --- a/test/spec/api/loc.test.js +++ b/test/spec/api/loc.test.js @@ -1,11 +1,12 @@ describe("ol.loc", function() { - it("allows empty construction", function() { - var loc; + it("doesn't allow empty construction", function() { + + expect(function() { + // nowhere + var loc = ol.loc(); + }).toThrow(); - // nowhere - loc = ol.loc(); - expect(loc).toBeA(ol.Loc); }); it("allows construction from an obj config", function() { From 7bf05964b89301296513a330b4e6329c93015303 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Wed, 20 Jun 2012 16:17:40 +0200 Subject: [PATCH 20/24] [ol.layer.XYZ] more tiling fixes, and additional tests --- src/ol/layer/XYZ.js | 24 +++++++----- test/spec/ol/layer/XYZ.test.js | 71 ++++++++++++++++++++++++++++++++-- 2 files changed, 81 insertions(+), 14 deletions(-) diff --git a/src/ol/layer/XYZ.js b/src/ol/layer/XYZ.js index d9ff88ef89..fb44ff361c 100644 --- a/src/ol/layer/XYZ.js +++ b/src/ol/layer/XYZ.js @@ -133,19 +133,23 @@ ol.layer.XYZ.prototype.getData = function(bounds, resolution) { gridLeft = tileOriginX + tileWidthGeo * offsetX, gridTop = tileOriginY - tileHeightGeo * offsetY; - var tiles = [], tile, url, i = 0, j; - while (gridTop - (i * tileHeightGeo) > boundsMinY) { - tiles[i] = []; - j = 0; - while (gridLeft + (j * tileWidthGeo) < boundsMaxX) { - url = me.url_.replace('{x}', offsetX + i + '') - .replace('{y}', offsetY + j + '') + var tiles = [], + tile, + url, + x = 0, + y = 0; + while (gridTop - (y * tileHeightGeo) > boundsMinY) { + tiles[y] = []; + while (gridLeft + (x * tileWidthGeo) < boundsMaxX) { + url = me.url_.replace('{x}', offsetX + x + '') + .replace('{y}', offsetY + y + '') .replace('{z}', zoom); tile = new ol.Tile(url); - tiles[i][j] = tile; - j++; + tiles[y][x] = tile; + x++; } - i++; + y++; + x = 0; } return new ol.TileSet(tiles, tileWidth, tileHeight, resolution); diff --git a/test/spec/ol/layer/XYZ.test.js b/test/spec/ol/layer/XYZ.test.js index d8b595fedc..e048486804 100644 --- a/test/spec/ol/layer/XYZ.test.js +++ b/test/spec/ol/layer/XYZ.test.js @@ -51,11 +51,11 @@ describe('ol.layer.XYZ', function() { expect(tile.getImg()).toBeDefined(); tile = tiles[0][1]; - expect(tile.getUrl()).toEqual('/1/0/1'); + expect(tile.getUrl()).toEqual('/1/1/0'); expect(tile.getImg()).toBeDefined(); tile = tiles[1][0]; - expect(tile.getUrl()).toEqual('/1/1/0'); + expect(tile.getUrl()).toEqual('/1/0/1'); expect(tile.getImg()).toBeDefined(); tile = tiles[1][1]; @@ -81,11 +81,11 @@ describe('ol.layer.XYZ', function() { expect(tile.getImg()).toBeDefined(); tile = tiles[0][1]; - expect(tile.getUrl()).toEqual('/1/0/1'); + expect(tile.getUrl()).toEqual('/1/1/0'); expect(tile.getImg()).toBeDefined(); tile = tiles[1][0]; - expect(tile.getUrl()).toEqual('/1/1/0'); + expect(tile.getUrl()).toEqual('/1/0/1'); expect(tile.getImg()).toBeDefined(); tile = tiles[1][1]; @@ -94,5 +94,68 @@ describe('ol.layer.XYZ', function() { }); }); + describe('extent -96,32,-32,96, resolution 0.5', function() { + + it('returns the expected data', function() { + var tileset = layer.getData( + new ol.Bounds(-96, 32, -32, 96), 0.5); + + var tiles = tileset.getTiles(); + expect(tiles.length).toEqual(1); + expect(tiles[0].length).toEqual(1); + + var tile; + + tile = tiles[0][0]; + expect(tile.getUrl()).toEqual('/1/0/0'); + expect(tile.getImg()).toBeDefined(); + }); + }); + + describe('extent -32,32,32,96, resolution 0.5', function() { + + it('returns the expected data', function() { + var tileset = layer.getData( + new ol.Bounds(-32, 32, 32, 96), 0.5); + + var tiles = tileset.getTiles(); + expect(tiles.length).toEqual(1); + expect(tiles[0].length).toEqual(2); + + var tile; + + tile = tiles[0][0]; + expect(tile.getUrl()).toEqual('/1/0/0'); + expect(tile.getImg()).toBeDefined(); + + tile = tiles[0][1]; + expect(tile.getUrl()).toEqual('/1/1/0'); + expect(tile.getImg()).toBeDefined(); + }); + }); + + describe('extent 32,-32,96,32, resolution 0.5', function() { + + it('returns the expected data', function() { + var tileset = layer.getData( + new ol.Bounds(32, -32, 96, 32), 0.5); + + var tiles = tileset.getTiles(); + expect(tiles.length).toEqual(2); + expect(tiles[0].length).toEqual(1); + expect(tiles[1].length).toEqual(1); + + var tile; + + tile = tiles[0][0]; + expect(tile.getUrl()).toEqual('/1/1/0'); + expect(tile.getImg()).toBeDefined(); + + tile = tiles[1][0]; + expect(tile.getUrl()).toEqual('/1/1/1'); + expect(tile.getImg()).toBeDefined(); + }); + }); + }); }); From b49c036ae2b5c833c85d0a3604407e528daefc71 Mon Sep 17 00:00:00 2001 From: Marc Jansen Date: Wed, 20 Jun 2012 16:49:51 +0200 Subject: [PATCH 21/24] Make the testuite configurable via URL. --- test/index.html | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/test/index.html b/test/index.html index b271f302c1..1b4edcb431 100644 --- a/test/index.html +++ b/test/index.html @@ -9,8 +9,39 @@ - - + From 025547d1996d69bb9f714090dc94e85be044efbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Wed, 20 Jun 2012 17:43:10 +0200 Subject: [PATCH 22/24] [ol.Layer.XYZ] minor changes in code comments --- src/ol/layer/XYZ.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ol/layer/XYZ.js b/src/ol/layer/XYZ.js index fb44ff361c..3d0191e7e0 100644 --- a/src/ol/layer/XYZ.js +++ b/src/ol/layer/XYZ.js @@ -8,7 +8,7 @@ goog.require('ol.TileSet'); * Class for XYZ layers. * @constructor * @param {string} url URL template. E.g. - * http://a.tile.openstreetmap.org/${z}/${x}/${y}.png. + * http://a.tile.openstreetmap.org/{z}/{x}/{y}.png. */ ol.layer.XYZ = function(url) { @@ -111,6 +111,7 @@ ol.layer.XYZ.prototype.getData = function(bounds, resolution) { zoom = me.zoomForResolution(resolution); resolution = me.resolutions_[zoom]; + // define some values used for the actual tiling var boundsMinX = bounds.getMinX(), boundsMaxX = bounds.getMaxX(), boundsMinY = bounds.getMinY(), @@ -133,6 +134,7 @@ ol.layer.XYZ.prototype.getData = function(bounds, resolution) { gridLeft = tileOriginX + tileWidthGeo * offsetX, gridTop = tileOriginY - tileHeightGeo * offsetY; + // now tile var tiles = [], tile, url, From 1ac40021bb7f1a32fc959f4f392b3c982d4472de Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Wed, 20 Jun 2012 17:43:35 +0200 Subject: [PATCH 23/24] Quoting properties for external use. --- src/ol/Loc.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ol/Loc.js b/src/ol/Loc.js index c3d4505038..f2b0e44190 100644 --- a/src/ol/Loc.js +++ b/src/ol/Loc.js @@ -117,7 +117,7 @@ ol.Loc.prototype.transform = function(proj) { if (goog.isString(proj)) { proj = new ol.Projection(proj); } - return this.transform_(proj); + return this._transform(proj); }; /** @@ -126,8 +126,8 @@ ol.Loc.prototype.transform = function(proj) { * @param {!ol.Projection} proj The destination projection. * @returns {!ol.Loc} */ -ol.Loc.prototype.transform_ = function(proj) { - var point = {x: this.x_, y: this.y_}; +ol.Loc.prototype._transform = function(proj) { + var point = {'x': this.x_, 'y': this.y_}; var sourceProj = this.projection_; if (!goog.isDefAndNotNull(sourceProj)) { throw new Error("Cannot transform a location without a source projection."); From 94fe46c5bef4d0976ea8696ab974283d1344bf24 Mon Sep 17 00:00:00 2001 From: Marc Jansen Date: Wed, 20 Jun 2012 17:43:54 +0200 Subject: [PATCH 24/24] Remove stray ')' --- test/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/index.html b/test/index.html index 1b4edcb431..2dd5c917a3 100644 --- a/test/index.html +++ b/test/index.html @@ -18,7 +18,7 @@ // // - host // where the plovr compiler is running, if not passed this defaults to the -// current host on port 9810) +// current host on port 9810 // // - mode // which mode of compilation should be applied. Common values for this are