多类型服务自定义范围控制之动态服务
描述
详细描述请查看ArcGIS API 多类型服务自定义范围控制
这里只展示如何使用,效果视频也在上述文章~
动态服务
1、创建自定义动态图层
通过createSubclass()方法来创建 BaseDynamicLayer
创建自定义动态图层的原因:
• ArcGIS API for JavaScript未明确支持图像的来源
• 需要先对图像进行预处理,然后才能在视图中显示
const CustomImageOverlayLayer= BaseDynamicLayer.createSubclass({
//规定属性
properties: {
picUrl: null,
image: null,
canvas: null,
geometryExtent: null,
geometry: null,
layerid: null
}
})
2、获取当前图像地址
要请求从数据源预定义的图像,需覆盖getImageUrl() 方法,以便给它定范围,长和宽返回请求的URL。
getImageUrl: function (extent, width, height) {
//extent 视图的范围。该值由LayerView填充。
//width 视图的宽度(以像素为单位)。该值由LayerView填充。
//height 视图的高度(以像素为单位)。该值由LayerView填充。
const pUrl = this.picUrl +"/export?bbox=" +
`${extent.xmin},${extent.ymin},${extent.xmax},${extent.ymax}` +
"&bboxSR=102100&imageSR=102100" +
`&size=${width},${height}` +
"&dpi=96&format=png32&transparent=true&layers=show%3A" +
`${this.layerid}` +
"&f=image";
}
3、对图像进行预处理
根据生成的网址请求图像,绘制裁切图形并利用canvas的clip方法进行图像裁切返回canvas
return request(pUrl, {
responseType: "image",
allowImageDataAccess: true
})
.then(
function (response) {
var image = response.data; //img
var context = this.canvas.getContext("2d");
//绘制裁切图形
if (this.geometry.type == "extent") {
context.rect(
zuobiao[0].x,
zuobiao[0].y,
stretchWidth,
stretchHeight
);
} else {
context.beginPath();
for (let i = 0; i <= zuobiao.length - 1; i++) {
if (i == zuobiao.length - 1) {
strokeLine(context, [zuobiao[i], zuobiao[0]]);
} else {
strokeLine(context, [zuobiao[i], zuobiao[i + 1]]);
}
}
}
context.clip(); //裁切
context.drawImage(image, 0, 0, width, height); //被裁切的图形
return this.canvas.toDataURL("image/png");
}.bind(this)
)
.catch(error => {});
4、实例化BaseDynamicLayer
var ImageOverlayLayer = new CustomImageOverlayLayer({
id: "RasterLayer",
title: "裁切图层",
picUrl: url,
geometryExtent: geometry.extent,
geometry: geometry,
layerid: "0,1"
});
map.add(ImageOverlayLayer);
整体代码
loadModules(["esri/layers/BaseDynamicLayer", "esri/request"], {
css: true
}).then(([BaseDynamicLayer, request]) => {
//创建自定义动态图层
var baseImageOverlayLayer = BaseDynamicLayer.createSubclass({
//规定属性
properties: {
picUrl: null,
image: null,
canvas: null,
geometryExtent: null,
geometry: null,
layerid: null
},
//覆盖getImageUrl()方法以生成图像的URL
getImageUrl: function (extent, width, height) {
//extent 视图的范围。该值由LayerView填充。
//width 视图的宽度(以像素为单位)。该值由LayerView填充。
//height 视图的高度(以像素为单位)。该值由LayerView填充。
// 左上角
var lefttop = {
x: this.geometryExtent.xmin,
y: this.geometryExtent.ymax,
spatialReference: this.geometryExtent.spatialReference
};
var screen_lefttop = WaterMap.view.toScreen(lefttop);
// 右下角
var rightbottom = {
x: this.geometryExtent.xmax,
y: this.geometryExtent.ymin,
spatialReference: this.extent.spatialReference
};
var screen_rightbottom = view.toScreen(rightbottom); //转屏幕坐标
var stretchWidth = screen_rightbottom.x - screen_lefttop.x;
var stretchHeight = screen_rightbottom.y - screen_lefttop.y;
if (!this.canvas) {
this.canvas = document.createElement("canvas");
}
this.canvas.width = width;
this.canvas.height = height;
//geometry转换屏幕多边形坐标
let zuobiao = topm(this.geometry, this.extent.spatialReference);
let pUrl =
this.picUrl +
"/export?bbox=" +
`${extent.xmin},${extent.ymin},${extent.xmax},${extent.ymax}` +
"&bboxSR=102100&imageSR=102100" +
`&size=${width},${height}` +
"&dpi=96&format=png32&transparent=true&layers=show%3A" +
`${this.layerid}` +
"&f=image";
//request 根据生成的网址请求图像
return request(pUrl, {
responseType: "image",
allowImageDataAccess: true
})
.then(
function (response) {
var image = response.data; //img
var context = this.canvas.getContext("2d");
//绘制裁切图形
if (this.geometry.type == "extent") {
context.rect(
zuobiao[0].x,
zuobiao[0].y,
stretchWidth,
stretchHeight
);
} else {
context.beginPath();
for (let i = 0; i <= zuobiao.length - 1; i++) {
if (i == zuobiao.length - 1) {
strokeLine(context, [zuobiao[i], zuobiao[0]]);
} else {
strokeLine(context, [zuobiao[i], zuobiao[i + 1]]);
}
}
}
context.clip(); //裁切
context.drawImage(image, 0, 0, width, height); //被裁切的图形
return this.canvas.toDataURL("image/png");
}.bind(this)
)
.catch(error => {});
}
});
//实例化BaseDynamicLayer
var ImageOverlayLayer = new CustomImageOverlayLayer({
id: "RasterLayer",
title: "裁切图层",
picUrl: url,
geometryExtent: geometry.extent,
geometry: geometry,
layerid: "0,1"
});
map.add(ImageOverlayLayer);
});