OpenLayers源码阅读(三):ImageWMS及ImageArcGISRest
目录
前提:需要理解常见的地图服务WMS、WMTS、WFS等,针对本文,主要理解WMS服务及其GetCapabilities、GetMap、GetFeatureInfo操作即可。
说明:本文重点关注ol.source.Image部分
1、我们如何使用(
官网例子http://openlayers.org/en/v4.6.5/examples/wms-image.html?q=wms)
var layers = [
new ol.layer.Image({
extent: [-13884991, 2870341, -7455066, 6338219],
source: new ol.source.ImageWMS({
url: 'https://ahocevar.com/geoserver/wms',
params: {'LAYERS': 'topp:states'},
ratio: 1,
serverType: 'geoserver'
})
})
];
2、属性有哪些
这里重点关注以下几个属性:
- serverType:mapserver、geoserver、qgis
- imageLoadFunction:返回image url
- params:① Layers 必须;② Styles; ③ Version; ④ Width;⑤ Heigh; t⑥ Bbox ⑦CRS;⑧……(自定义key-value)
- projection
- ratio 与size of the map viewport的比率,默认是1.5
- resolutions
- url:WMS service URL
官网例子中的url:https://ahocevar.com/geoserver/wms
或者也可以定义imageLoadFunction参数
image url:https://ahocevar.com/geoserver/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&LAYERS=topp%3Astates&CRS=EPSG%3A3857&STYLES=&WIDTH=658&HEIGHT=355&BBOX=-13888944.635145342%2C2867630.7173607955%2C-7451112.364854658%2C6340929.2826392045(该地址就是标准的WMS的GetMap的操作)
3、阅读源码
3.1 imagewms.js
https://github.com/openlayers/openlayers/blob/v4.6.5/src/ol/source/imagewms.js
第一步 构造函数、定义属性信息
ol.source.ImageWMS = function(opt_options) {
var options = opt_options || {};
ol.source.Image.call(this, {
attributions: options.attributions,
logo: options.logo,
projection: options.projection,
resolutions: options.resolutions
});
/**
* @private
* @type {?string}
*/
this.crossOrigin_ =
options.crossOrigin !== undefined ? options.crossOrigin : null;
/**
* @private
* @type {string|undefined}
*/
this.url_ = options.url;
/**
* @private
* @type {ol.ImageLoadFunctionType}
*/
this.imageLoadFunction_ = options.imageLoadFunction !== undefined ?
options.imageLoadFunction : ol.source.Image.defaultImageLoadFunction;
/**
* @private
* @type {!Object}
*/
this.params_ = options.params || {};
/**
* @private
* @type {boolean}
*/
this.v13_ = true;
this.updateV13_();
/**
* @private
* @type {ol.source.WMSServerType|undefined}
*/
this.serverType_ = /** @type {ol.source.WMSServerType|undefined} */ (options.serverType);
/**
* @private
* @type {boolean}
*/
this.hidpi_ = options.hidpi !== undefined ? options.hidpi : true;
/**
* @private
* @type {ol.Image}
*/
this.image_ = null;
/**
* @private
* @type {ol.Size}
*/
this.imageSize_ = [0, 0];
/**
* @private
* @type {number}
*/
this.renderedRevision_ = 0;
/**
* @private
* @type {number}
*/
this.ratio_ = options.ratio !== undefined ? options.ratio : 1.5;
};
第二步 继承 ol.source.Image
ol.inherits(ol.source.ImageWMS, ol.source.Image);
第三步 定义方法(与属性有关、闭包)
/**
* Return the URL used for this WMS source.
* @return {string|undefined} URL.
* @api
*/
ol.source.ImageWMS.prototype.getUrl = function() {
return this.url_;
};
/**
* Set the URL to use for requests.
* @param {string|undefined} url URL.
* @api
*/
ol.source.ImageWMS.prototype.setUrl = function(url) {
if (url != this.url_) {
this.url_ = url;
this.image_ = null;
this.changed();
}
};
......
第四步 定义方法(getRequestUrl_、getGetFeatureInfoUrl )
返回image的url
方法getGetFeatureInfoUrl与getRequestUrl_ 类似,不在赘述
/**
* @param {ol.Extent} extent Extent.
* @param {ol.Size} size Size.
* @param {number} pixelRatio Pixel ratio.
* @param {ol.proj.Projection} projection Projection.
* @param {Object} params Params.
* @return {string} Request URL.
* @private
*/
ol.source.ImageWMS.prototype.getRequestUrl_ = function(extent, size, pixelRatio, projection, params) {
ol.asserts.assert(this.url_ !== undefined, 9); // `url` must be configured or set using `#setUrl()`
params[this.v13_ ? 'CRS' : 'SRS'] = projection.getCode();
if (!('STYLES' in this.params_)) {
params['STYLES'] = '';
}
if (pixelRatio != 1) {
switch (this.serverType_) {
case ol.source.WMSServerType.GEOSERVER:
var dpi = (90 * pixelRatio + 0.5) | 0;
if ('FORMAT_OPTIONS' in params) {
params['FORMAT_OPTIONS'] += ';dpi:' + dpi;
} else {
params['FORMAT_OPTIONS'] = 'dpi:' + dpi;
}
break;
case ol.source.WMSServerType.MAPSERVER:
params['MAP_RESOLUTION'] = 90 * pixelRatio;
break;
case ol.source.WMSServerType.CARMENTA_SERVER:
case ol.source.WMSServerType.QGIS:
params['DPI'] = 90 * pixelRatio;
break;
default:
ol.asserts.assert(false, 8); // Unknown `serverType` configured
break;
}
}
params['WIDTH'] = size[0];
params['HEIGHT'] = size[1];
var axisOrientation = projection.getAxisOrientation();
var bbox;
if (this.v13_ && axisOrientation.substr(0, 2) == 'ne') {
bbox = [extent[1], extent[0], extent[3], extent[2]];
} else {
bbox = extent;
}
params['BBOX'] = bbox.join(',');
return ol.uri.appendParams(/** @type {string} */ (this.url_), params);
};
过程及结果:
0: “SERVICE=WMS”
1: “VERSION=1.3.0”
2: “REQUEST=GetMap”
3: “FORMAT=image%2Fpng”
4: “TRANSPARENT=true”
5: “LAYERS=topp%3Astates”
6: “CRS=EPSG%3A3857”
7: “STYLES=”
8: “WIDTH=658”
9: “HEIGHT=355”
10: “BBOX=-13888944.635145342%2C2867630.7173607955%2C-7451112.364854658%2C6340929.2826392045”
第五步 定义方法(getImageInternal)
返回image的信息(包括url),这里要阅读ol.source.Image和ol.layer..Image
ol.source.ImageWMS.prototype.getImageInternal = function(extent, resolution, pixelRatio, projection) {
if (this.url_ === undefined) {
return null;
}
resolution = this.findNearestResolution(resolution);
if (pixelRatio != 1 && (!this.hidpi_ || this.serverType_ === undefined)) {
pixelRatio = 1;
}
var imageResolution = resolution / pixelRatio;
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, imageResolution, 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, imageResolution, 0,
[requestWidth, requestHeight]);
var image = this.image_;
if (image &&
this.renderedRevision_ == this.getRevision() &&
image.getResolution() == resolution &&
image.getPixelRatio() == pixelRatio &&
ol.extent.containsExtent(image.getExtent(), viewExtent)) {
return image;
}
var params = {
'SERVICE': 'WMS',
'VERSION': ol.DEFAULT_WMS_VERSION,
'REQUEST': 'GetMap',
'FORMAT': 'image/png',
'TRANSPARENT': true
};
ol.obj.assign(params, this.params_);
this.imageSize_[0] = Math.round(ol.extent.getWidth(requestExtent) / imageResolution);
this.imageSize_[1] = Math.round(ol.extent.getHeight(requestExtent) / imageResolution);
var url = this.getRequestUrl_(requestExtent, this.imageSize_, pixelRatio,
projection, params);
this.image_ = new ol.Image(requestExtent, resolution, pixelRatio,
url, this.crossOrigin_, this.imageLoadFunction_);
this.renderedRevision_ = this.getRevision();
ol.events.listen(this.image_, ol.events.EventType.CHANGE,
this.handleImageChange, this);
return this.image_;
};
3.2 imagearcgisrest.js
[2] https://github.com/openlayers/openlayers/blob/v4.6.5/src/ol/source/imagearcgisrest.js
基本与imagewms.js一致,除了在image的url的拼接上做了特殊的处理
//在getImageInternal中
var params = {
'F': 'image',
'FORMAT': 'PNG32',
'TRANSPARENT': true
};
ol.obj.assign(params, this.params_);
/**
* @param {ol.Extent} extent Extent.
* @param {ol.Size} size Size.
* @param {number} pixelRatio Pixel ratio.
* @param {ol.proj.Projection} projection Projection.
* @param {Object} params Params.
* @return {string} Request URL.
* @private
*/
ol.source.ImageArcGISRest.prototype.getRequestUrl_ = function(extent, size, pixelRatio, projection, params) {
// ArcGIS Server only wants the numeric portion of the projection ID.
var srid = projection.getCode().split(':').pop();
params['SIZE'] = size[0] + ',' + size[1];
params['BBOX'] = extent.join(',');
params['BBOXSR'] = srid;
params['IMAGESR'] = srid;
params['DPI'] = Math.round(90 * pixelRatio);
var url = this.url_;
var modifiedUrl = url
.replace(/MapServer\/?$/, 'MapServer/export')
.replace(/ImageServer\/?$/, 'ImageServer/exportImage');
if (modifiedUrl == url) {
ol.asserts.assert(false, 50); // `options.featureTypes` should be an Array
}
return ol.uri.appendParams(modifiedUrl, params);
};
4、总结
- imagewms主要包含:一是定义属性,二是返回image对象
- image的url等于url+params
- url中的params的拼接采用key-value的方式进行的,因此在对地图服务地址进行加密代理的话,就要有针对性的设置params;arcgis服务代理时,建议以MapServer/ImageServer结尾
例如:/WMSUrl:https://ahocevar.com/geoserver/wms?token=111222
var url = WMSUrl.substr(0,WMSUrl.indexOf("?"));
source : new ol.source.ImageWMS({
ratio: 1,
params: {
layers:"topp:states" //"show:"+layerIndex
token:"111222"
},
url: url
})
转载自:https://blog.csdn.net/u013240519/article/details/82687116