由于项目的要求,地图需要按照用户权限显示对应的区域,这里我们所使用的地图服务是指切片类型的服务,根据Arcgis api我们知道MapImageLayer可以控制子图层的显隐,子图层的定义查询:
var layer = new MapImageLayer({
url: "https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer",
sublayers: [
{
id: 3,
visible: false
},
{
id: 0,
visible: true,
definitionExpression: "pop2000 > 100000"
}
]
});
类似的FeatureLayer同样具备definitionExpression,这些方法都可以根据用户权限控制数据的展示,今天我们要讨论的并不是这两种类型,而是切片类型的服务如何根据不规则形状显示,为什么要进行不规则的显示呢,打个比方,我们的切片服务为完整的全市域的切片,而在实际应用中需要针对城市某个区域进行显示,这时就要依据区划范围面进行不规则显示了,便于用户权限的控制。
那么切片类型的服务如何控制?
方式一:控制范围坐标Extent,当地图范围变化时,判断与显示范围的关系,强制用户拖拽超出范围,这个方法的弊端是Extent是矩形。
方式二:地图遮罩,发布遮挡范围面,这个效果较为直观,但是毕竟是又添加了一层服务,在地图拖拽的空隙会漏出遮挡面下的区域内容,而且还会出现卡顿等问题。
方式三:CSS遮罩,这也是本文较为推荐的方式
脱离api的思考方式,选择在地图控件的上方,叠加一层不透明的div,根据显示范围将div裁切出空洞进而显示出地图部分,优点在于CSS3可以按照不规则点进行裁切,缺点是通过样式的控制过于简单,数据仍然能够被获取。
给出CSS3的代码示例,API采用的为4.6(3.X的效果可能更佳,api提供的接口更丰富,这里主要是监控地图Extent的变化)
ClipPath:function(geo_hn){//输入为geometry的范围图形
var _self = this;
var centergeo = geo_hn.extent.clone();//clone后不会对原图形更改
gConfig.initExtent = centergeo.expand(1.2);
_self.mapView.goTo({target:gConfig.initExtent}).then(function () {
var scale = _self.mapView.scale;
_self.mapView.constraints.minScale = scale*1.5;//限定地图的缩放
watchUtils.init(_self.mapView,'extent',function(extent,oldextent){//动态监测地图范围变化
var polygonscreen = "polygon(100% 0,0 0,0 50%,";
for(var i=0;i<geo_hn.rings[0].length;i++){//将坐标点位转换为屏幕坐标
var xymap = geo_hn.rings[0][i];
var screenxt =_self.mapView.toScreen({x:xymap[0],y:xymap[1],spatialReference:_self.mapView.spatialReference});
polygonscreen+=screenxt.x+"px "+screenxt.y+"px,";
}
polygonscreen += "0 50%,0 100%,100% 100%)";
$("#regiondivl").css("-webkit-clip-path",polygonscreen);//css3输入一串坐标就可以裁切div了,这里为了挖洞,从右上角开始到右下角结束,只要图形点顺时针排列就可以挖洞了
})
});
}
相应的html:
<div id="mapDiv" style="position:relative;background:url(plug-in/mapviews/assets/gw2.png);">
</div>
<div id="regiondivl" class ='shadediv'></div>
.shadediv{
position: absolute;
top:0px;
left:0px;
width:100%;
height:100%;
z-index:990;
background:url(../assets/gw2.png);//这个背景图片也可以换成纯色,只要和地图底色一致就可以
}
效果图:
总结:在最终呈现的效果上,css的效果最佳,同时也存在一个问题,当范围面点位过多时,地图拖拽缩放会有一些延迟,我们的做法是将范围面做简化处理,40~50个点位还是可以保障图形的基本特别,同时减轻css裁切的负担。