Refactor ol.source.ImageWMS URL logic
* Always request images of integer WIDTH and HEIGHT * Match BBOX to requested size * Handle integer-only DPIs in GeoServer
This commit is contained in:
@@ -1,43 +1,48 @@
|
||||
// FIXME factor out v13 calculation
|
||||
|
||||
goog.provide('ol.source.ImageWMS');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.object');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.uri.utils');
|
||||
goog.require('ol.Image');
|
||||
goog.require('ol.ImageUrlFunction');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.source.Image');
|
||||
goog.require('ol.source.wms');
|
||||
goog.require('ol.source.wms.ServerType');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.source.Image}
|
||||
* @param {olx.source.ImageWMSOptions} options Options.
|
||||
* @param {olx.source.ImageWMSOptions=} opt_options Options.
|
||||
* @todo stability experimental
|
||||
*/
|
||||
ol.source.ImageWMS = function(options) {
|
||||
ol.source.ImageWMS = function(opt_options) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object}
|
||||
*/
|
||||
this.params_ = options.params;
|
||||
|
||||
var imageUrlFunction = goog.isDef(options.url) ?
|
||||
ol.ImageUrlFunction.createFromParamsFunction(
|
||||
options.url, this.params_, ol.source.wms.getUrl) :
|
||||
ol.ImageUrlFunction.nullImageUrlFunction;
|
||||
var options = goog.isDef(opt_options) ? opt_options : {};
|
||||
|
||||
goog.base(this, {
|
||||
attributions: options.attributions,
|
||||
crossOrigin: options.crossOrigin,
|
||||
extent: options.extent,
|
||||
projection: options.projection,
|
||||
resolutions: options.resolutions,
|
||||
imageUrlFunction: imageUrlFunction
|
||||
resolutions: options.resolutions
|
||||
});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.url_ = options.url;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object}
|
||||
*/
|
||||
this.params_ = options.params;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.source.wms.ServerType|undefined}
|
||||
@@ -81,8 +86,16 @@ ol.source.ImageWMS.prototype.getParams = function() {
|
||||
*/
|
||||
ol.source.ImageWMS.prototype.getImage =
|
||||
function(extent, resolution, pixelRatio, projection) {
|
||||
|
||||
if (!goog.isDef(this.url_)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
resolution = this.findNearestResolution(resolution);
|
||||
pixelRatio = this.hidpi_ ? pixelRatio : 1;
|
||||
|
||||
if (pixelRatio != 1 && (!this.hidpi_ || !goog.isDef(this.serverType_))) {
|
||||
pixelRatio = 1;
|
||||
}
|
||||
|
||||
var image = this.image_;
|
||||
if (!goog.isNull(image) &&
|
||||
@@ -92,20 +105,83 @@ ol.source.ImageWMS.prototype.getImage =
|
||||
return image;
|
||||
}
|
||||
|
||||
extent = extent.slice();
|
||||
ol.extent.scaleFromCenter(extent, this.ratio_);
|
||||
var width = (extent[2] - extent[0]) / resolution;
|
||||
var height = (extent[3] - extent[1]) / resolution;
|
||||
var size = [width * pixelRatio, height * pixelRatio];
|
||||
var params = {
|
||||
'SERVICE': 'WMS',
|
||||
'VERSION': '1.3.0',
|
||||
'REQUEST': 'GetMap',
|
||||
'FORMAT': 'image/png',
|
||||
'TRANSPARENT': true
|
||||
};
|
||||
goog.object.extend(params, this.params_);
|
||||
|
||||
if (goog.isDef(this.serverType_) && pixelRatio > 1) {
|
||||
var param = ol.source.wms.getDpiParam(this.serverType_, pixelRatio);
|
||||
goog.object.extend(this.params_, param);
|
||||
var v13 = goog.string.compareVersions(
|
||||
goog.object.get(params, 'VERSION'), '1.3') >= 0;
|
||||
|
||||
params[v13 ? 'CRS' : 'SRS'] = projection.getCode();
|
||||
|
||||
if (!('STYLES' in this.params_)) {
|
||||
goog.object.set(params, 'STYLES', new String(''));
|
||||
}
|
||||
|
||||
this.image_ = this.createImage(
|
||||
extent, resolution, pixelRatio, size, projection);
|
||||
if (pixelRatio != 1) {
|
||||
switch (this.serverType_) {
|
||||
case ol.source.wms.ServerType.GEOSERVER:
|
||||
var dpi = (90 * pixelRatio + 0.5) | 0;
|
||||
goog.object.set(params, 'FORMAT_OPTIONS', 'dpi:' + dpi);
|
||||
break;
|
||||
case ol.source.wms.ServerType.MAPSERVER:
|
||||
goog.object.set(params, 'MAP_RESOLUTION', 90 * pixelRatio);
|
||||
break;
|
||||
case ol.source.wms.ServerType.QGIS:
|
||||
goog.object.set(params, 'DPI', 90 * pixelRatio);
|
||||
break;
|
||||
default:
|
||||
goog.asserts.fail();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
extent = extent.slice();
|
||||
var centerX = (extent[0] + extent[2]) / 2;
|
||||
var centerY = (extent[1] + extent[3]) / 2;
|
||||
if (this.ratio_ != 1) {
|
||||
var halfWidth = this.ratio_ * (extent[2] - extent[0]) / 2;
|
||||
var halfHeight = this.ratio_ * (extent[3] - extent[1]) / 2;
|
||||
extent[0] = centerX - halfWidth;
|
||||
extent[1] = centerY - halfHeight;
|
||||
extent[2] = centerX + halfWidth;
|
||||
extent[3] = centerY + halfHeight;
|
||||
}
|
||||
|
||||
var imageResolution = resolution / pixelRatio;
|
||||
|
||||
// Compute an integer width and height.
|
||||
var width = Math.ceil((extent[2] - extent[0]) / imageResolution);
|
||||
goog.object.set(params, 'WIDTH', width);
|
||||
var height = Math.ceil((extent[3] - extent[1]) / imageResolution);
|
||||
goog.object.set(params, 'HEIGHT', height);
|
||||
|
||||
// Modify the extent to match the integer width and height.
|
||||
extent[0] = centerX - imageResolution * width / 2;
|
||||
extent[2] = centerX + imageResolution * width / 2;
|
||||
extent[1] = centerY - imageResolution * height / 2;
|
||||
extent[3] = centerY + imageResolution * height / 2;
|
||||
|
||||
var axisOrientation = projection.getAxisOrientation();
|
||||
var bbox;
|
||||
if (v13 && axisOrientation.substr(0, 2) == 'ne') {
|
||||
bbox = [extent[1], extent[0], extent[3], extent[2]];
|
||||
} else {
|
||||
bbox = extent;
|
||||
}
|
||||
goog.object.set(params, 'BBOX', bbox.join(','));
|
||||
|
||||
var url = goog.uri.utils.appendParamsFromMap(this.url_, params);
|
||||
|
||||
this.image_ = new ol.Image(extent, resolution, pixelRatio, url,
|
||||
this.crossOrigin, this.getAttributions());
|
||||
return this.image_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user