Cesium可以通过ArcGisMapServerImageryProvider加载arcgis地图服务,layers属性设置图层序号进行图层过滤,但并未提供根据属性字段过滤。
目录
原理解析
查看ArcGisMapServerImageryProvider源码发现,buildImageResource方法提供了获取图片资源的方法,其中layers的实现如下:
从以上可以看出,图层过滤参数满足arcgis rest api 提供的export接口参数写法,并且最后调用的getDerivedResource方法就是采用了arcgis rest api的export接口,这个可以通过f12打开开发者工具,查看服务加载过程来验证。
export接口本身是提供了属性过滤的,因此可以修改代码来添加属性过滤,为了避免破坏源码文件,可以在外部创建一个JS扩展文件(arcgisImageryServiceExt.js)来修改ArcGisMapServerImageryProvider的原型方法达到目的。
arcgisImageryServiceExt.js代码如下:
const {
ImageryProvider,
Resource,
ArcGisMapServerImageryProvider,
GeographicProjection,
DeveloperError
} = Cesium;
let _layerDefs = null;
ArcGisMapServerImageryProvider.prototype.requestImage2 =
ArcGisMapServerImageryProvider.prototype.requestImage;
ArcGisMapServerImageryProvider.prototype.requestImage = function (
x,
y,
level,
request
) {
//>>includeStart('debug', pragmas.debug);
if (!this._ready) {
throw new DeveloperError(
"requestImage must not be called before the imagery provider is ready."
);
}
//>>includeEnd('debug');
return ImageryProvider.loadImage(
this,
buildImageResource(this, x, y, level, request)
);
};
function buildImageResource(imageryProvider, x, y, level, request) {
var resource;
if (imageryProvider._useTiles) {
resource = imageryProvider._resource.getDerivedResource({
url: "tile/" + level + "/" + y + "/" + x,
request: request,
});
} else {
var nativeRectangle = imageryProvider._tilingScheme.tileXYToNativeRectangle(
x,
y,
level
);
var bbox =
nativeRectangle.west +
"," +
nativeRectangle.south +
"," +
nativeRectangle.east +
"," +
nativeRectangle.north;
var query = {
bbox: bbox,
size: imageryProvider._tileWidth + "," + imageryProvider._tileHeight,
format: "png32",
transparent: true,
f: "image",
};
if (
imageryProvider._tilingScheme.projection instanceof GeographicProjection
) {
query.bboxSR = 4326;
query.imageSR = 4326;
} else {
query.bboxSR = 3857;
query.imageSR = 3857;
}
if (imageryProvider.layers) {
query.layers = "show:" + imageryProvider.layers;
}
//query中添加自定义自定义 的请求参数 layerDefs
if (imageryProvider.layerDefs) {
query.layerDefs = imageryProvider.layerDefs;
}
resource = imageryProvider._resource.getDerivedResource({
url: "export",
request: request,
queryParameters: query,
});
}
return resource;
}
Object.defineProperties(ArcGisMapServerImageryProvider.prototype, {
/**
* //添加一个自定义的变量 依据字段查询返回结果
* Gets the comma-separated list of layer IDs to show.
* @memberof ArcGisMapServerImageryProvider.prototype
*
* @type {json对象} 示例: layerDefs={"0":" id='0201' or name='0201' "}
*/
layerDefs: {
get: function () {
return this._layerDefs;
},
},
});
代码调用
// arcgis 服务过滤测试
var provider = new Cesium.ArcGisMapServerImageryProvider({
url: '输入arcgis服务',
layers: 0,
});
var arcgislayer = viewer.imageryLayers.addImageryProvider(provider);
// 点击过滤
$('#changeCondition').on('click', function () {
// 注意先移除旧图层
viewer.imageryLayers.remove(arcgislayer)
arcgislayer = viewer.imageryLayers.addImageryProvider(provider);
provider._layerDefs = "{0: \"NAME like '%江岸区%'\"}"
})
结果展示
(1)过滤前
(1)过滤后