前言
ArcGIS API如同国内用的不多,除了设计院以外,大多数还是用的百度和高德API。
ArcGIS API的文档是全英文,因而分享一些小性能的实现思路。
需要
ArcGIS中,新增加的图层永远在最下面,就像这样:
而在业务逻辑上,有时咱们须要某个图层置顶。
比方用来统计面积大小的图层,如果它被其余图层笼罩掉,就不能失常的统计面积和显示被选中的地块了:
本文就来解决这个问题
先说原理,非常简单,应用到生命周期钩子函数。
尝试的其余办法
首先尝试了add图层是能不能手动设置order,也就是给它设置的地位很高,比方100:
为了便于交换,咱们临时把这个图层叫做areaSumLayer
。
// 业务上须要置顶的图层let areaSumLayer: GraphicsLayer// 增加图层时设置的很高map.add(areaSumLayer,100);
事实上这样不行,因为后面提到它的逻辑是:“新增加的图层永远在最下面”
即便以前的图层设置的很高,新图层还会更高,比方地位在101。
因而咱们的思路是:
无奈在创立areaSumLayer
时保障它当前是置顶的
而是在创立其余图层时保护一下areaSumLayer
的地位
生命周期钩子
什么是生命周期?所有的前端组件都应用了这个思维。生命周期指的是从一个组件从创立到沦亡的过程。
拿前端框架Angular举例,最常见的包含:
- ngOnInit(): 组件创立
- ngOnChanges(): 绑定的数据发生变化时
- ngOnDestoryed(): 组件销毁
https://angular.cn/guide/lifecycle-hooks
或者VUE中:
- created(): 组件创立
- mounted(): 组件渲染结束
- beforeUpdate():产生变更前
- updated(): 产生变更
- unmounted(): 组件登记
https://cn.vuejs.org/guide/essentials/lifecycle.html
这些生命周期钩子是在框架开发者编写时就写好的,要应用这些周期函数,只须要用回调的形式,传入一个咱们本人写好的办法,这个办法会在适当的机会(生命周期产生时)被主动调用,用到的就是订阅者-观察者模式。
ArcGIS API
接下来看看ArcGIS的图层有什么生命周期(官网称之为事件event):
https://developers.arcgis.com/javascript/latest/api-reference...
- before-add:增加前
- after-add:增加后
- before-changes:变更前
- change:变更
- after-changes:变更后
- before-remove:销毁前
- after-remove:销毁后
有这么多生命周期,而咱们的业务上用到的是增加后,也就是“当新图层增加后,咱们手动的更新一下须要置顶的areaSumLayer
图层。
after-add是这样用的:
https://developers.arcgis.com/javascript/latest/api-reference...
map.layers.on("after-add", function(event){ console.log(event.item.id);});
- map.layers.on是开启监听,map就是Map类创立的对象
- "after-add"是监听的事件类型,咱们须要监听增加图层之后的事件
- event是本人写的回调函数中的变量
- 办法体是咱们要在回调时执行的操作
失常状况下,当有新的图层被增加进来时,控制台就会输入它的ID。
接下来是寻找:areaSumLayer
有没有曾经被增加
须要用到collection汇合的find办法:
https://developers.arcgis.com/javascript/latest/api-reference...
find办法是寻找某个图层在不在图层汇合中,应用的还是回调函数:
// 如果此时图层汇合中有面积的图层 if (map.layers.find(function (layer) { return layer.id === areaSumLayer.id })){ console.log("true"); }
逐条解释:
咱们定义了一个办法:
function (layer) { return layer.id === areaSumLayer.id}
- layer是回调时的变量,能够轻易写,但要和办法体中对应
- 办法的内容就是:判断回调变量的图层id和咱们的id是否相等,如果相等,阐明咱们要查问的图层在这个汇合中,返回true
接下来解决“调整图层程序”的步骤:
// 从新增加面积图层map.remove(areaSumLayer);map.add(areaSumLayer);
- 就是先暗藏再从新增加
因而合起来就变成了这样:
/** * 地图生命周期 * 当图层创立后,把预览图片的图层从新增加一下,使其永远置顶 */ map.layers.on('after-add', (event) => { // 如果此时图层汇合中有areaSumLayer图层 if (map.layers.find(function (layer) { return layer.id === areaSumLayer.id })) { // 从新增加areaSumLayer图层 map.remove(areaSumLayer); map.add(areaSumLayer); } })
此时,只有有别的图层增加结束,钩子函数就会从新把areaSumLayer
置顶。
但当初有个问题:如果新增加的图层就是areaSumLayer
呢?还会触发这个钩子函数吗?
答案是:会产生死循环。
解决这个问题很简略,先从event中把刚刚增加的图层id获取到:
// 刚刚增加的图层id,为了避免死循环let justAddedId = event.item.id;
此时,如果justAddedId等于areaSumLayer的id,就阐明方才增加的就是areaSumLayer图层,就不必再执行调整操作了。
最终的代码:
/** * 地图生命周期 * 当图层创立后,把预览图片的图层从新增加一下,使其永远置顶 */ map.layers.on('after-add', (event) => { // 获取刚刚增加的图层id,为了避免死循环 let justAddedId = event.item.id; // 如果此时图层汇合中有areaSumLayer图层 if (map.layers.find(function (layer) { return layer.id === areaSumLayer.id // 并且刚增加的图层不是areaSumLayer图层 }) && (justAddedId != areaSumLayer.id)) { // 从新增加areaSumLayer图层 map.remove(areaSumLayer); map.add(areaSumLayer); } })
总结
当我刚接手这个性能的时候,我甚至没有残缺的看一遍ArcGIS的文档(又是英文,又特地长,文档内容比Angular都多)。
但所有框架的思维都是相通的,编程编的就是思维,依据其余框架的教训就能够推断ArcGIS肯定有相似的办法,再去文档中查问即可。