天天看点

ArcGIS API For JavaScript(3)之点击查询多个地图服务图层时实现infoWindow默认第一个展示最顶层服务数据的一种方法

场景还原:

客户的一个奇葩需求。

当多个服务数据在同位置上有重叠覆盖的情况时,希望第一个优先展示最顶层服务数据的属性信息。

当我们在地图上进行点选或者进行其他范围选择时,如果需要将当前地图上加载的所有地图服务都查询并使用InfoWindow进行展示时,infoWindow虽然可以通过数字显示总共查询到的要素个数,通过点击下一个可以切换,但由于查询的执行是异步的,默认是无法确保查询的第一个要素为最顶层服务的数据。

需要解决的问题:

可考虑在所有查询执行完毕后进行截获,重置InfoWindow中展示的第一个要素或者重置infoWindow中的所有查询要素。

本文只讲解重置InfoWindow中展示的第一个要素为最顶层要素。

这里有个问题是由于需要等待所有查询执行完毕后,才进行跳转,可能查询结果多时会出现延迟跳转。

以下通过infoWindow.deferreds来实现在展示前的预处理。

示例代码如下:

//判断当前是否有需要查询的图层
					var hasVisibleLayes=false;
					if(Object.keys(ConfigData.layers).length != 0){
						for(var item in ConfigData.layers){
							var layerInfos=ConfigData.layers[item].layerInfos;
							if (layerInfos != null && layerInfos.length > 0) {
                                let visibleLayers = ConfigData.layers[item].visibleLayers;
								if(visibleLayers.length>0){
									hasVisibleLayes=true;
									break;
								}
							}
						}
					}
				if(hasVisibleLayes){
						var features=[];
						//判断当前infoWindow是否有正在执行的查询    
          
         if(_layerControlObj._map.infoWindow&&_layerControlObj._map.infoWindow.deferreds){
								 //查找当前infowindow正在执行延迟查询的所有服务
								_layerControlObj._map.infoWindow.deferreds.forEach(s=>s.addCallbacks(function(response){
									//console.log(response);
									//features.push([...response]);

									if(response&&response.length>0){
										response.forEach(r=>features.push(r));
									}
						//如果所有查询执行完毕,进行数据合并	
		if(_layerControlObj._map.infoWindow.deferreds==null||_layerControlObj._map.infoWindow.deferreds.length==0){
										if(features.length>0){
                            //查询地图上加载的所有可见图层,用于确定最顶层图层是哪个?
											 let layers = _layerControlObj._map.getLayersVisibleAtScale(_layerControlObj._map.getScale());
											 var reverseLayers = [...layers];
											 reverseLayers.reverse();
											 var newFeatures = [];
											 if (reverseLayers && reverseLayers.length > 0) {
											 for (var i = 0; i < reverseLayers.length; i++) {
											 var list = features.filter(s => s._layer.id.indexOf(reverseLayers[i].id)>-1)
											 if (list && list.length > 0) {
											 newFeatures = [...list];
											 break;
											 }
											 }
											 }
											 if(newFeatures.length>0){
												 var index=features.findIndex(s=>s==newFeatures[0]);
												 _layerControlObj.isFirst=false;
												 //重新显示最顶层第一个要素
												 _layerControlObj._map.infoWindow.select(index);
											 }
											 else{
												 _layerControlObj.isFirst=false;
												 //重新显示第一个要素
												 _layerControlObj._map.infoWindow.select(0);
											 }
										
										}
										
									}
								}))
						}
						else{
							time = setInterval(lang.hitch(_layerControlObj, function () {
								 if(_layerControlObj._map.infoWindow&&_layerControlObj._map.infoWindow.deferreds){
									 clearTimeout(time);
									 //查找当前infowindow正在执行延迟查询的所有服务
								_layerControlObj._map.infoWindow.deferreds.forEach(s=>s.addCallbacks(function(response){
									//console.log(response);
									//features.push([...response]);
									if(response&&response.length>0){
										response.forEach(r=>features.push(r));
									}
									if(_layerControlObj._map.infoWindow.deferreds==null||_layerControlObj._map.infoWindow.deferreds.length==0){
										if(features.length>0){
											 let layers = _layerControlObj._map.getLayersVisibleAtScale(_layerControlObj._map.getScale());
											 var reverseLayers = [...layers];
											 reverseLayers.reverse();
											 var newFeatures = [];
											 if (reverseLayers && reverseLayers.length > 0) {
											 for (var i = 0; i < reverseLayers.length; i++) {
											 var list = features.filter(s => s._layer.id.indexOf(reverseLayers[i].id)>-1)
											 if (list && list.length > 0) {
											 newFeatures = [...list];
											 break;
											 }
											 }
											 }
											  if(newFeatures.length>0){
												 var index=features.findIndex(s=>s==newFeatures[0]);
												 _layerControlObj.isFirst=false;
												 //重新显示最顶层第一个要素
												 _layerControlObj._map.infoWindow.select(index);
											 }
											 else{
												 _layerControlObj.isFirst=false;
												 //重新显示第一个要素
												 _layerControlObj._map.infoWindow.select(0);
											 }
										
										}
										
									}
								}))
								
							}
						 }),10)
						}
						
		     }
           

以上示例只是一种方式,不一定完美,或许有其他方式。

继续阅读