使用场景
使用arcgis api在网页上加载影像图层时,影像服务因为需要根据影像单景id来过滤图层,没办法在发布服务的时候做切片处理,此时影像速度加载过慢,想要优化加载速度。查询良久后无果,自暴自弃浑水摸鱼半天过后,向组里的大佬请教,大佬给我指了一条路说去吧小伙子,这是我去年开拓出来的路,路上遇到啥不懂的随时问。感动,这就是大佬么,还是抱大腿快乐嗷(废柴猫猫流泪跳起冲向前方.gif)。这是大佬的csdn账号https://blog.csdn.net/zmskra?type=blog,易智瑞的webgis开发大佬,webgis开发相关的问题有需要可以去找大佬付费咨询
思路
使用arcgis api中提供的BaseTileLayer相关内容,参考了arcgis官网的以下内容后:
1、Custom TileLayer的例子:https://developers.arcgis.com/javascript/latest/sample-code/layers-custom-tilelayer/
2、TileInfo的文档:https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-TileInfo.html
技术路线为:使用BaseTileLayer提供的createSubclass()创建自定义切片图层方法,在前端页面中用切片的形式加载影像图层
实例
技术框架:vue2 + arcgis api for js
0、初始化地图
this.map = new Map({
// basemap: basemap,
// layers: [],
});
const params = {
container: 'viewDiv',
zoom: 5,
center: [110, 35],
map: this.map,
constraints: {
maxZoom: 18,
minZoom: 4
},
};
//2维
this.activeView = new MapView(params);
//3维
this.activeView = new SceneView(params);
1、要加载动态切片,首先要确认当前坐标系以及切片方案,这里我用的是两种,都列上去了
const refList = [
{
name: '3857',
wkid: 102100,
latestWkid: 3857,
origin: {x:-20037508.342787,y:20037508.342787},
size: [256, 256],
format: 'jpgpng',
lods: [
{levelValue: 0,level:0,resolution:156543.03392800014,scale:591657527.591555},
{levelValue: 1,level:1,resolution:78271.51696399994,scale:295828763.795777},
{levelValue: 2,level:2,resolution:39135.75848200009,scale:147914381.897889},
{levelValue: 3,level:3,resolution:19567.87924099992,scale:73957190.948944},
{levelValue: 4,level:4,resolution:9783.93962049996,scale:36978595.474472},
{levelValue: 5,level:5,resolution:4891.96981024998,scale:18489297.737236},
{levelValue: 6,level:6,resolution:2445.98490512499,scale:9244648.868618},
{levelValue: 7,level:7,resolution:1222.992452562495,scale:4622324.434309},
{levelValue: 8,level:8,resolution:611.4962262813797,scale:2311162.217155},
{levelValue: 9,level:9,resolution:305.74811314055756,scale:1155581.108577},
{levelValue: 10,level:10,resolution:152.87405657041106,scale:577790.554289},
{levelValue: 11,level:11,resolution:76.43702828507324,scale:288895.277144},
{levelValue: 12,level:12,resolution:38.21851414253662,scale:144447.638572},
{levelValue: 13,level:13,resolution:19.10925707126831,scale:72223.819286},
{levelValue: 14,level:14,resolution:9.554628535634155,scale:36111.909643},
{levelValue: 15,level:15,resolution:4.77731426794937,scale:18055.954822},
{levelValue: 16,level:16,resolution:2.388657133974685,scale:9027.977411},
{levelValue: 17,level:17,resolution:1.1943285668550503,scale:4513.988705},
{levelValue: 18,level:18,resolution:0.5971642835598172,scale:2256.994353},
{levelValue: 19,level:19,resolution:0.29858214164761665,scale:1128.497176},
{levelValue: 20,level:20,resolution:0.14929107082380833,scale:564.248588},
{levelValue: 21,level:21,resolution:0.07464553541190416,scale:282.124294},
{levelValue: 22,level:22,resolution:0.03732276770595208,scale:141.062147},
{levelValue: 23,level:23,resolution:0.01866138385297604,scale:71.5310735}
]
},
{
name: '4326',
wkid: 4326,
latestWkid: 4326,
origin: {x:-180,y:90},
size: [256, 256],
format: 'jpgpng',
lods: [
{levelValue: 0,level:0,resolution:0.703125013115789,scale:2.95497598570834E8},
{levelValue: 1,level:1,resolution:0.3515625065578945,scale:1.47748799285417E8},
{levelValue: 2,level:2,resolution:0.17578125327894775,scale:7.38743996427087E7},
{levelValue: 3,level:3,resolution:0.08789062663947399,scale:3.69371998213544E7},
{levelValue: 4,level:4,resolution:0.043945313319736994,scale:1.84685999106772E7},
{levelValue: 5,level:5,resolution:0.021972656659868472,scale:9234299.95533859},
{levelValue: 6,level:6,resolution:0.010986328329934226,scale:4617149.97766929},
{levelValue: 7,level:7,resolution:0.005493164164967124,scale:2308574.98883465},
{levelValue: 8,level:8,resolution:0.0027465820824835504,scale:1154287.49441732},
{levelValue: 9,level:9,resolution:0.0013732910412417797,scale:577143.747208662},
{levelValue: 10,level:10,resolution:0.0006866455206208899,scale:288571.873604331},
{levelValue: 11,level:11,resolution:0.0003433227603104438,scale:144285.936802165},
{levelValue: 12,level:12,resolution:0.0001716613801552224,scale:72142.9684010827},
{levelValue: 13,level:13,resolution:0.00008583069007761132,scale:36071.4842005414},
{levelValue: 14,level:14,resolution:0.00004291534503880566,scale:18035.7421002707},
{levelValue: 15,level:15,resolution:0.000021457672519402802,scale:9017.87105013534},
{levelValue: 16,level:16,resolution:0.000010728836259701402,scale:4508.93552506767},
{levelValue: 17,level:17,resolution:0.000005364418129850701,scale:2254.467762533835},
{levelValue: 18,level:18,resolution:0.0000026822090649253505,scale:1127.2338812669175},
{levelValue: 19,level:19,resolution:0.0000013411045324626752,scale:563.6169406334587},
{levelValue: 20,level:20,resolution:0.0000006705522662313376,scale:281.80847031672937},
{levelValue: 21,level:21,resolution:0.0000003352761331156688,scale:140.90423515836468},
{levelValue: 22,level:22,resolution:0.0000001676380665578344,scale:70.45211757918234},
{levelValue: 23,level:23,resolution:0.0000000838190332789172,scale:35.22605878959117}
]
}
]
2、项目中引入所需模块
import refList from "../js/refLod"
import esriRequest from "@arcgis/core/request"
import BaseTileLayer from "@arcgis/core/layers/BaseTileLayer.js"
import TileInfo from "@arcgis/core/layers/support/TileInfo"
3、构造图层函数
async tileimageLayer(url, id, lockRasterIds, nowRef) {
const _self = this;
let teLayer = null;
const tileimageLayer = BaseTileLayer.createSubclass({
properties: {
urlTemplate: null
},
getTileUrl: function (level, row, col) {
// console.log("getTileUrl里的this",this);
const lt_x = this.tileInfo.origin.x +
col * this.tileInfo.lods[level].resolution
* this.tileInfo.size[0],
lt_y = this.tileInfo.origin.y -
row * this.tileInfo.lods[level].resolution
* this.tileInfo.size[1],
rb_x = this.tileInfo.origin.x +
(col + 1) *
this.tileInfo.lods[level].resolution *
this.tileInfo.size[0],
rb_y = this.tileInfo.origin.y -
(row + 1) *
this.tileInfo.lods[level].resolution *
this.tileInfo.size[1],
bbox = lt_x + "," + rb_y + "," + rb_x + "," + lt_y,
content = {
bbox: bbox,
size: this.tileInfo.size[0] + "," + this.tileInfo.size[1],
dpi: this.tileInfo["dpi"],
format: this.tileInfo["format"],
bboxSR: this.bboxSR,
imageSR: this.imageSR,
// pixelType:this.pixelType,
// noData:"0,0,0",
mosaicRule:JSON.stringify({
"mosaicMethod":"esriMosaicLockRaster",
"lockRasterIds":this.lockRasterIds,
}),
transparent: true,
f: "image",
};
return content;
},
fetchTile: function (level, row, col) {
const content = this.getTileUrl(level, row, col);
return esriRequest(this.urlTemplate + "/exportImage", {
responseType: "image",
query: content,
// body:content,
allowImageDataAccess: true,
}).then(response => {
const image = response.data,
width = this.tileInfo.size[0],
height = this.tileInfo.size[0],
canvas = document.createElement("canvas"),
context = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
context.drawImage(image, 0, 0, width, height);
return canvas;
})
},
}),
tileInfo = TileInfo.create({
dpi: 96,
format: nowRef.format,
size: nowRef.origin.size,
origin: {
x: nowRef.origin.x,
y: nowRef.origin.y,
type: 'Point',
spatialReference: {
wkid: nowRef.wkid
}
},
spatialReference: {
wkid: nowRef.wkid
},
lods: nowRef.lods
});
teLayer = new tileimageLayer({
title: "raster Layer",
id: id,
urlTemplate: url,
tileInfo: tileInfo,
bboxSR: nowRef.wkid,
imageSR: nowRef.wkid,
lockRasterIds: lockRasterIds,
ascending: true,
})
return teLayer;
},
4、使用函数生成图层并加载
//首先选出来当前场景的坐标系
const nowRef = refList.find(l => {
return l.wkid == this.activeView.spatialReference.wkid
})
//id是从影像服务中查询到的单景影像的objectId
const raster = this.tileimageLayer(url, "imgLayer", [id], nowRef)
this.map.add(raster, 0);
5、打完收功