diff --git a/examples/wms/main.js b/examples/wms/main.js index 4119d48eee..0372796c90 100644 --- a/examples/wms/main.js +++ b/examples/wms/main.js @@ -17,7 +17,7 @@ $(function () { wms.url( function (x, y, zoom) { // Compute the bounding box - var bb = wms.gcsTileBounds({x: x, y: y, level: zoom}, projection); + var bb = this.gcsTileBounds({x: x, y: y, level: zoom}, projection); var bbox_mercator = bb.left + ',' + bb.bottom + ',' + bb.right + ',' + bb.top; // Set the WMS server parameters diff --git a/src/d3/d3Renderer.js b/src/d3/d3Renderer.js index d02cd4d8ef..3dcd9ed326 100644 --- a/src/d3/d3Renderer.js +++ b/src/d3/d3Renderer.js @@ -189,9 +189,9 @@ var d3Renderer = function (arg) { } m_diagonal = Math.pow(width * width + height * height, 0.5); m_corners = { - upperLeft: map.displayToGcs({'x': 0, 'y': 0}, null), - lowerRight: map.displayToGcs({'x': width, 'y': height}, null), - center: map.displayToGcs({'x': width / 2, 'y': height / 2}, null) + upperLeft: map.displayToGcs({x: 0, y: 0}, null), + lowerRight: map.displayToGcs({x: width, y: height}, null), + center: map.displayToGcs({x: width / 2, y: height / 2}, null) }; } diff --git a/src/map.js b/src/map.js index 59c7debdb6..45dba89d6f 100644 --- a/src/map.js +++ b/src/map.js @@ -123,6 +123,7 @@ var map = function (arg) { m_clampBoundsY, m_clampZoom, m_animationQueue = arg.animationQueue || [], + m_autoResize = arg.autoResize === undefined ? true : arg.autoResize, m_origin; /* Compute the maximum bounds on our map projection. By default, x ranges @@ -147,11 +148,12 @@ var map = function (arg) { m_maxBounds.right - m_maxBounds.left) / 256); m_camera.viewport = { - width: m_width, height: m_height, - left: m_node.offset().left, top: m_node.offset().top + width: m_width, + height: m_height, + left: m_node.offset().left, + top: m_node.offset().top }; arg.center = util.normalizeCoordinates(arg.center); - arg.autoResize = arg.autoResize === undefined ? true : arg.autoResize; m_clampBoundsX = arg.clampBoundsX === undefined ? false : arg.clampBoundsX; m_clampBoundsY = arg.clampBoundsY === undefined ? true : arg.clampBoundsY; m_clampZoom = arg.clampZoom === undefined ? true : arg.clampZoom; @@ -180,6 +182,62 @@ var map = function (arg) { return Math.pow(2, -zoom) * m_unitsPerPixel; }; + //////////////////////////////////////////////////////////////////////////// + /** + * Get/set the animation queue. Two maps can share a single animation queue + * to ensure synchronized animations. When setting, the animation queue will + * merge values from the existing queue into the new queue. + * + * @param {array} [queue] The animation queue to use. + * @returns {array|this} The current animation queue or the current map. + */ + //////////////////////////////////////////////////////////////////////////// + this.animationQueue = function (queue) { + if (queue === undefined) { + return m_animationQueue; + } + if (queue !== m_animationQueue) { + if (m_animationQueue.length) { + /* If the specified queue already has data in, don't copy the 0th + * element of the existing queue, since the 0th element is always the + * actual requestAnimationFrame reference. In this case, cancel the + * existing requestAnimationFrame. By using a property of window, + * tests can override this if needed. */ + if (queue.length && queue[0] !== m_animationQueue[0]) { + window['cancelAnimationFrame'](m_animationQueue[0]); + } + for (var i = queue.length ? 1 : 0; i < m_animationQueue.length; i += 1) { + queue.push(m_animationQueue[i]); + } + } + m_animationQueue = queue; + } + return this; + }; + + //////////////////////////////////////////////////////////////////////////// + /** + * Get/set the autoResize flag. + * + * @param {boolean} [autoResize] Truthy to automaticaly resize the map when + * the size of the browser window changes. + * @returns {boolean|this} The current state of autoResize or the current map. + */ + //////////////////////////////////////////////////////////////////////////// + this.autoResize = function (autoResize) { + if (autoResize === undefined) { + return m_autoResize; + } + if (autoResize !== m_autoResize) { + $(window).off('resize', resizeSelf); + m_autoResize = autoResize; + if (m_autoResize) { + $(window).on('resize', resizeSelf); + } + } + return this; + }; + //////////////////////////////////////////////////////////////////////////// /** * Get/set the `clampBoundsX` setting. If changed, adjust the bounds of the @@ -653,8 +711,10 @@ var map = function (arg) { m_this.zoom(newZoom); } m_this.camera().viewport = { - width: m_width, height: m_height, - left: m_node.offset().left, top: m_node.offset().top + width: m_width, + height: m_height, + left: m_node.offset().left, + top: m_node.offset().top }; m_this.center(oldCenter); @@ -1053,7 +1113,7 @@ var map = function (arg) { * * @param {array} p0 An array of numbers to interpolate from. * @param {array} p1 An array of numbers to interpolate to. - * @return {function} A function that, given `t`, returns an array of + * @returns {function} A function that, given `t`, returns an array of * interpolated values. * @private */ @@ -1804,7 +1864,7 @@ var map = function (arg) { * with the correct aspect ratio. * * @param {geo.geoBounds} bounds A desired bounds. - * @return {object} Multiplicative aspect ratio correction with x and y + * @returns {object} Multiplicative aspect ratio correction with x and y * values. * @private */ @@ -1977,7 +2037,7 @@ var map = function (arg) { * @param {boolean} noRangeLimit If falsy, ensure that the rotation is in the * range [0, 2*PI). If it is very close to zero, it is snapped to zero. * If true, the rotation can have any value. - * @return {number} the validated rotation + * @returns {number} the validated rotation * @private */ function fix_rotation(rotation, ignoreRotationFunc, noRangeLimit) { @@ -2020,6 +2080,8 @@ var map = function (arg) { * Specifically, the map's `maxBounds` can be shifted so that they lie no * further than the center of the bounds (rather than being forced to be * at the edge). + * @returns {geo.geoBounds} The adjusted bounds. This may be the same object + * passed in `bounds`. * @private */ function fix_bounds(bounds, rotation, delta, ignoreClampBounds) { @@ -2225,8 +2287,8 @@ var map = function (arg) { this.interactor(arg.interactor || mapInteractor({discreteZoom: m_discreteZoom})); } - if (arg.autoResize) { - $(window).resize(resizeSelf); + if (m_autoResize) { + $(window).on('resize', resizeSelf); } // attach attribution updates to layer events diff --git a/src/osmLayer.js b/src/osmLayer.js index f126f9a74d..2a2a3c14e5 100644 --- a/src/osmLayer.js +++ b/src/osmLayer.js @@ -56,8 +56,9 @@ module.exports = (function () { queue: this._queue, overlap: this._options.tileOverlap, scale: this._options.tileScale, - url: this._options.url(urlParams.x, urlParams.y, urlParams.level || 0, - this._options.subdomains) + url: this._options.url.call( + this, urlParams.x, urlParams.y, urlParams.level || 0, + this._options.subdomains) }); }.bind(this); }; diff --git a/src/registry.js b/src/registry.js index b66f94318b..cb94a440cc 100644 --- a/src/registry.js +++ b/src/registry.js @@ -280,6 +280,7 @@ util.createLayer = function (name, map, arg) { $.extend(true, options, arg); } layer = layers[name](options); + layer.layerName = name; layer._init(); return layer; } else { diff --git a/src/tileLayer.js b/src/tileLayer.js index efab5ab1c8..14fe593afa 100644 --- a/src/tileLayer.js +++ b/src/tileLayer.js @@ -446,8 +446,9 @@ module.exports = (function () { index: index, size: {x: this._options.tileWidth, y: this._options.tileHeight}, queue: this._queue, - url: this._options.url(urlParams.x, urlParams.y, urlParams.level || 0, - this._options.subdomains) + url: this._options.url.call( + this, urlParams.x, urlParams.y, urlParams.level || 0, + this._options.subdomains) }); }; diff --git a/tests/cases/map.js b/tests/cases/map.js index bcd2de31c1..608d58a4b4 100644 --- a/tests/cases/map.js +++ b/tests/cases/map.js @@ -139,6 +139,32 @@ describe('geo.core.map', function () { expect(m.unitsPerPixel()).toBeCloseTo(200000 * 16); expect(m.unitsPerPixel(4)).toBeCloseTo(200000); }); + it('animationQueue', function () { + mockAnimationFrame(); + var m = create_map(), queue = [], queue2 = [], + queue3 = [window.requestAnimationFrame(function () { })]; + expect(m.animationQueue()).toEqual([]); + expect(m.animationQueue()).not.toBe(queue); + expect(m.animationQueue(queue)).toBe(m); + expect(m.animationQueue()).toBe(queue); + m.scheduleAnimationFrame(function () { }); + expect(queue.length).toBe(2); + expect(m.animationQueue(queue2)).toBe(m); + expect(queue2.length).toBe(2); + expect(queue2).toEqual(queue); + expect(m.animationQueue(queue3)).toBe(m); + expect(queue3.length).toBe(2); + expect(queue3).not.toEqual(queue2); + unmockAnimationFrame(); + }); + it('autoResize', function () { + var m = create_map(); + expect(m.autoResize()).toBe(true); + expect(m.autoResize(false)).toBe(m); + expect(m.autoResize()).toBe(false); + expect(m.autoResize(true)).toBe(m); + expect(m.autoResize()).toBe(true); + }); it('gcs and ingcs', function () { var m = create_map(), units = m.unitsPerPixel(), bounds; var error = console.error; diff --git a/tests/cases/osmLayer.js b/tests/cases/osmLayer.js index c15ab6bd2e..312617b0e8 100644 --- a/tests/cases/osmLayer.js +++ b/tests/cases/osmLayer.js @@ -123,7 +123,7 @@ describe('geo.core.osmLayer', function () { describe('default osmLayer', function () { describe('html', function () { - var layer; + var layer, lastThis; it('creation', function () { map = create_map(); layer = map.createLayer('osm', {renderer: null, url: '/testdata/white.jpg'}); @@ -143,6 +143,19 @@ describe('geo.core.osmLayer', function () { waitForIt('.geo-tile-container', function () { return map.node().find('.geo-tile-container').length > 0; }); + it('tile function', function () { + map.deleteLayer(layer); + layer = map.createLayer('osm', {renderer: null, mapOpacity: 0.5, url: function (x, y, z) { + lastThis = this; + return '/testdata/white.jpg'; + }}); + }); + waitForIt('.geo-tile-container', function () { + return map.node().find('.geo-tile-container').length > 0; + }); + it('tile function test', function () { + expect(lastThis).toBe(layer); + }); /* The follow is a test of tileLayer as attached to a map. We don't * currently expose the tileLayer class directly to the createLayer * function, so some testing is done here */ diff --git a/tests/cases/tileLayer.js b/tests/cases/tileLayer.js index 428374b290..9b2b9fc357 100644 --- a/tests/cases/tileLayer.js +++ b/tests/cases/tileLayer.js @@ -957,14 +957,18 @@ describe('geo.tileLayer', function () { }); it('_getTile', function () { + var lastThis; var t, l = geo.tileLayer({ map: map(), tileWidth: 110, tileHeight: 120, - url: function (x, y, z) { return {x: x, y: y, level: z}; } + url: function (x, y, z) { + lastThis = this; + return {x: x, y: y, level: z}; + } }); - t = l._getTile({x: 1, y: 1, level: 0}, {x: 0, y: 0, level: 0}); + expect(lastThis).toBe(l); expect(t._url).toEqual({x: 0, y: 0, level: 0}); expect(t.size).toEqual({x: 110, y: 120}); expect(t.index).toEqual({x: 1, y: 1, level: 0});