天天看點

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)
						}
						
		     }
           

以上示例隻是一種方式,不一定完美,或許有其他方式。

繼續閱讀