diff --git a/src/ol/source/imagewms.js b/src/ol/source/imagewms.js index b2c0f3b1ca..26eaa0bb41 100644 --- a/src/ol/source/imagewms.js +++ b/src/ol/source/imagewms.js @@ -189,41 +189,27 @@ ol.source.ImageWMS.prototype.getImageInternal = function(extent, resolution, pix pixelRatio = 1; } - extent = extent.slice(); - var centerX = (extent[0] + extent[2]) / 2; - var centerY = (extent[1] + extent[3]) / 2; - var imageResolution = resolution / pixelRatio; - var imageWidth = Math.ceil(ol.extent.getWidth(extent) / imageResolution); - var imageHeight = Math.ceil(ol.extent.getHeight(extent) / imageResolution); - var halfWidth = imageWidth * imageResolution / 2; - var halfHeight = imageHeight * imageResolution / 2; - - extent[0] = centerX - halfWidth; - extent[1] = centerY - halfHeight; - extent[2] = centerX + halfWidth; - extent[3] = centerY + halfHeight; + var center = ol.extent.getCenter(extent); + var viewWidth = Math.ceil(ol.extent.getWidth(extent) / imageResolution); + var viewHeight = Math.ceil(ol.extent.getHeight(extent) / imageResolution); + var viewExtent = ol.extent.getForViewAndSize(center, resolution, 0, + [viewWidth, viewHeight]); + var requestWidth = Math.ceil(this.ratio_ * ol.extent.getWidth(extent) / imageResolution); + var requestHeight = Math.ceil(this.ratio_ * ol.extent.getHeight(extent) / imageResolution); + var requestExtent = ol.extent.getForViewAndSize(center, resolution, 0, + [requestWidth, requestHeight]); var image = this.image_; if (image && this.renderedRevision_ == this.getRevision() && image.getResolution() == resolution && image.getPixelRatio() == pixelRatio && - ol.extent.containsExtent(image.getExtent(), extent)) { + ol.extent.containsExtent(image.getExtent(), viewExtent)) { return image; } - if (this.ratio_ != 1) { - halfWidth *= this.ratio_; - halfHeight *= this.ratio_; - - extent[0] = centerX - halfWidth; - extent[1] = centerY - halfHeight; - extent[2] = centerX + halfWidth; - extent[3] = centerY + halfHeight; - } - var params = { 'SERVICE': 'WMS', 'VERSION': ol.DEFAULT_WMS_VERSION, @@ -233,13 +219,13 @@ ol.source.ImageWMS.prototype.getImageInternal = function(extent, resolution, pix }; ol.obj.assign(params, this.params_); - this.imageSize_[0] = imageWidth * this.ratio_; - this.imageSize_[1] = imageHeight * this.ratio_; + this.imageSize_[0] = Math.round(ol.extent.getWidth(requestExtent) / imageResolution); + this.imageSize_[1] = Math.round(ol.extent.getHeight(requestExtent) / imageResolution); - var url = this.getRequestUrl_(extent, this.imageSize_, pixelRatio, + var url = this.getRequestUrl_(requestExtent, this.imageSize_, pixelRatio, projection, params); - this.image_ = new ol.Image(extent, resolution, pixelRatio, + this.image_ = new ol.Image(requestExtent, resolution, pixelRatio, this.getAttributions(), url, this.crossOrigin_, this.imageLoadFunction_); this.renderedRevision_ = this.getRevision(); diff --git a/test/spec/ol/source/imagewms.test.js b/test/spec/ol/source/imagewms.test.js index 84aaa30205..3e6ca560fb 100644 --- a/test/spec/ol/source/imagewms.test.js +++ b/test/spec/ol/source/imagewms.test.js @@ -24,6 +24,30 @@ describe('ol.source.ImageWMS', function() { describe('#getImage', function() { it('returns the expected image URL', function() { + options.ratio = 1.5; + var source = new ol.source.ImageWMS(options); + var image = source.getImage([10, 20, 30.1, 39.9], resolution, pixelRatio, projection); + var uri = new URL(image.src_); + var queryData = uri.searchParams; + var extent = queryData.get('BBOX').split(',').map(Number); + var extentAspectRatio = (extent[3] - extent[1]) / (extent[2] - extent[0]); + var imageAspectRatio = Number(queryData.get('WIDTH') / Number(queryData.get('HEIGHT'))); + expect(extentAspectRatio).to.roughlyEqual(imageAspectRatio, 1e-12); + }); + + it('requests integer WIDTH and HEIGHT', function() { + options.ratio = 1.5; + var source = new ol.source.ImageWMS(options); + var image = source.getImage([10, 20, 30.1, 39.9], resolution, pixelRatio, projection); + var uri = new URL(image.src_); + var queryData = uri.searchParams; + var width = parseFloat(queryData.get('WIDTH')); + var height = parseFloat(queryData.get('HEIGHT')); + expect(width).to.be(Math.round(width)); + expect(height).to.be(Math.round(height)); + }); + + it('sets WIDTH and HEIGHT to match the aspect ratio of BBOX', function() { var source = new ol.source.ImageWMS(options); var image = source.getImage(extent, resolution, pixelRatio, projection); var uri = new URL(image.src_);