diff --git a/externs/olx.js b/externs/olx.js index 16fba8a9be..9406898b7a 100644 --- a/externs/olx.js +++ b/externs/olx.js @@ -1373,7 +1373,7 @@ olx.control.RotateOptions.prototype.render; /** - * Function called when the control is clicked. This will override the + * Function called when the control is clicked. This will override the * default resetNorth. * @type {function()|undefined} * @api @@ -4935,7 +4935,6 @@ olx.source.StamenOptions.prototype.url; * @typedef {{attributions: (Array.|undefined), * crossOrigin: (null|string|undefined), * imageExtent: (ol.Extent), - * imageSize: (ol.Size|undefined), * imageLoadFunction: (ol.ImageLoadFunctionType|undefined), * logo: (string|olx.LogoOptions|undefined), * projection: ol.proj.ProjectionLike, @@ -4974,14 +4973,6 @@ olx.source.ImageStaticOptions.prototype.crossOrigin; olx.source.ImageStaticOptions.prototype.imageExtent; -/** - * Size of the image in pixels. - * @type {ol.Size|undefined} - * @api stable - */ -olx.source.ImageStaticOptions.prototype.imageSize; - - /** * Optional function to load an image given a URL. * @type {ol.TileLoadFunctionType|undefined} diff --git a/src/ol/image.js b/src/ol/image.js index 39bfcfe5ac..398f2af1ec 100644 --- a/src/ol/image.js +++ b/src/ol/image.js @@ -35,7 +35,7 @@ ol.Image = function(extent, resolution, pixelRatio, attributions, src, /** * @private - * @type {Image} + * @type {HTMLCanvasElement|Image|HTMLVideoElement} */ this.image_ = new Image(); if (crossOrigin) { @@ -44,7 +44,7 @@ ol.Image = function(extent, resolution, pixelRatio, attributions, src, /** * @private - * @type {Object.} + * @type {Object.} */ this.imageByContext_ = {}; @@ -142,6 +142,14 @@ ol.Image.prototype.load = function() { }; +/** + * @param {HTMLCanvasElement|Image|HTMLVideoElement} image Image. + */ +ol.Image.prototype.setImage = function(image) { + this.image_ = image; +}; + + /** * Discards event handlers which listen for load completion or errors. * diff --git a/src/ol/source/imagestaticsource.js b/src/ol/source/imagestaticsource.js index f6e57ce82d..cd95f93799 100644 --- a/src/ol/source/imagestaticsource.js +++ b/src/ol/source/imagestaticsource.js @@ -4,6 +4,7 @@ goog.require('goog.events'); goog.require('goog.events.EventType'); goog.require('ol.Image'); goog.require('ol.ImageLoadFunctionType'); +goog.require('ol.ImageState'); goog.require('ol.extent'); goog.require('ol.proj'); goog.require('ol.source.Image'); @@ -26,12 +27,6 @@ ol.source.ImageStatic = function(options) { var imageExtent = options.imageExtent; - var resolution, resolutions; - if (options.imageSize !== undefined) { - resolution = ol.extent.getHeight(imageExtent) / options.imageSize[1]; - resolutions = [resolution]; - } - var crossOrigin = options.crossOrigin !== undefined ? options.crossOrigin : null; @@ -42,16 +37,34 @@ ol.source.ImageStatic = function(options) { goog.base(this, { attributions: attributions, logo: options.logo, - projection: ol.proj.get(options.projection), - resolutions: resolutions + projection: ol.proj.get(options.projection) }); /** * @private * @type {ol.Image} */ - this.image_ = new ol.Image(imageExtent, resolution, 1, attributions, + this.image_ = new ol.Image(imageExtent, undefined, 1, attributions, options.url, crossOrigin, imageLoadFunction); + + goog.events.listen(this.image_, goog.events.EventType.CHANGE, function() { + if (this.image_.getState() == ol.ImageState.LOADED) { + var image = this.image_.getImage(); + var resolution = ol.extent.getHeight(imageExtent) / image.height; + var pxWidth = Math.ceil(ol.extent.getWidth(imageExtent) / resolution); + var pxHeight = Math.ceil(ol.extent.getHeight(imageExtent) / resolution); + if (pxWidth !== image.width || pxHeight !== image.height) { + var canvas = /** @type {HTMLCanvasElement} */ + (document.createElement('canvas')); + canvas.width = pxWidth; + canvas.height = pxHeight; + var context = canvas.getContext('2d'); + context.drawImage(image, 0, 0, canvas.width, canvas.height); + this.image_.setImage(canvas); + } + } + }, false, this); + goog.events.listen(this.image_, goog.events.EventType.CHANGE, this.handleImageChange, false, this); diff --git a/test/spec/ol/source/imagestaticsource.test.js b/test/spec/ol/source/imagestaticsource.test.js index 126341cc9b..a180ba4ece 100644 --- a/test/spec/ol/source/imagestaticsource.test.js +++ b/test/spec/ol/source/imagestaticsource.test.js @@ -14,14 +14,32 @@ describe('ol.source.ImageStatic', function() { describe('#getImage', function() { + it('scales image to fit imageExtent', function(done) { + var source = new ol.source.ImageStatic({ + url: 'spec/ol/source/images/12-655-1583.png', + imageExtent: [ + -13629027.891360067, 4539747.983913189, + -13619243.951739565, 4559315.863154193], + projection: projection + }); + + source.on('imageloadend', function(event) { + expect(image.getImage().width).to.be(128); + expect(image.getImage().height).to.be(256); + done(); + }); + + var image = source.getImage(extent, resolution, pixelRatio, projection); + image.load(); + }); + it('triggers image load events', function(done) { var source = new ol.source.ImageStatic({ url: 'spec/ol/source/images/12-655-1583.png', imageExtent: [ -13629027.891360067, 4539747.983913189, -13619243.951739565, 4549531.923533691], - projection: projection, - imageSize: [256, 256] + projection: projection }); var imageloadstart = sinon.spy(); diff --git a/test_rendering/spec/ol/layer/expected/image-scaled.png b/test_rendering/spec/ol/layer/expected/image-scaled.png new file mode 100644 index 0000000000..a1b50feb2a Binary files /dev/null and b/test_rendering/spec/ol/layer/expected/image-scaled.png differ diff --git a/test_rendering/spec/ol/layer/image.test.js b/test_rendering/spec/ol/layer/image.test.js index 8c3c6bbdc7..18166be2b6 100644 --- a/test_rendering/spec/ol/layer/image.test.js +++ b/test_rendering/spec/ol/layer/image.test.js @@ -82,6 +82,31 @@ describe('ol.rendering.layer.Image', function() { }); }); }); + + describe('single image layer - scaled', function() { + var source; + + beforeEach(function() { + source = new ol.source.ImageStatic({ + url: 'spec/ol/data/tiles/osm/5/5/12.png', + imageExtent: ol.proj.transformExtent( + [-123, 37, -122, 38], 'EPSG:4326', 'EPSG:3857') + }); + }); + + afterEach(function() { + disposeMap(map); + }); + + it('renders correctly', function(done) { + map = createMap('canvas'); + waitForImages([source], {}, function() { + expectResemble(map, 'spec/ol/layer/expected/image-scaled.png', + IMAGE_TOLERANCE, done); + }); + }); + }); + }); goog.require('goog.object');