Highlight features layer if selected search result intersect with feature layer

2535
7
Jump to solution
12-28-2020 03:55 PM
anuragmittal
Occasional Contributor

Hi,

 

I have added different features layer on map and have a working code to highlight the feature layer once user click on the map (I am using hitTest on mouse click event). But I am trying to do the same (highlight feature layer) once user searched an address and that address falls on one of feature layer. I am not able to make it work. 

Here is my code snippet 

 

 

			search.on("search-complete", function(event)
			{			
			    //take lat and long from Esri search if geometry type is point or polygon
			    let lat, longt;
			    if(event.results[0].results[0].feature.geometry.type == 'point') {
			        lat = event.results[0].results[0].feature.geometry.latitude;
			        longt = event.results[0].results[0].feature.geometry.longitude;
			    } else if(event.results[0].results[0].feature.geometry.type == 'polygon') {
			        lat = event.results[0].results[0].feature.geometry.centroid.latitude;
			        longt = event.results[0].results[0].feature.geometry.centroid.longitude;
			    }		
			   let pointVar = new Point({
			        latitude:lat,
			        longitude:longt
			    });

				view.hitTest(pointVar).then(function(response)
				{//alert("test");
					console.log(response);
					if (response && response.results.length > 0 && response.results[0].graphic && response.results[0].graphic != undefined && response.results[0].graphic.attributes != undefined ) {
						let graphic = response.results[0].graphic;
									
						view.whenLayerView(graphic.layer).then(function(lyrView){
								if (highlightSelect) {
							highlightSelect.remove();
						}
							highlightSelect = lyrView.highlight(graphic);
						});	
					}
				
				});
			}); 

 

 

 

1 Solution

Accepted Solutions
JohnGrayson
Esri Alum

You can watch for the MapView property called updating to be false.  You can directly watch this property, or for this use-case maybe use watchUtils which might be more appropriate.  The assumption is that after navigating to a search result the view will be updating, and you want to wait before interrogating via hitTest(...) or other.  You could skip this part and see if it works for your use-case, and then add it in if it doesn't quite work as you need.

 

// ALL updating PROPERTY CHANGES //
mapView.watch('updating', (updating) =>{
  console.log('Updating: ', updating);
});

// WHEN updating IS FALSE ONE TIME //
watchUtils.whenFalseOnce(mapView, 'updating', ()=> {
  console.log('View Not Updating');
});

 

 

View solution in original post

7 Replies
anuragmittal
Occasional Contributor

Hi Guys,

Even I tried emitting click event on search-complete event of search widget. But that also not working. Here is my code. 

 

search.on('search-complete', function(event){
				let lat, longt;
			    if(event.results[0].results[0].feature.geometry.type == 'point') {
			        lat = event.results[0].results[0].feature.geometry.latitude;
			        longt = event.results[0].results[0].feature.geometry.longitude;
			    } else if(event.results[0].results[0].feature.geometry.type == 'polygon') {
			        lat = event.results[0].results[0].feature.geometry.centroid.latitude;
			        longt = event.results[0].results[0].feature.geometry.centroid.longitude;
			    }		
			   let pointVar = new Point({
			        latitude:lat,
			        longitude:longt
			    });
				var scrPt = view.toScreen(pointVar);
				view.emit('click', {bubbles: true, cancelable: true,mapPoint: pointVar,screenPoint: scrPt});
			});

 

0 Kudos
JohnGrayson
Esri Alum

In your first example you pass in a Point instead of ScreenPoint to hitTest(...), and in the second example you're not calling hitTest(...), so it's hard to tell what is going on.  Do you have a very simple codepen/jsbin/other showing the issue?  

anuragmittal
Occasional Contributor

Thank you John for the reply. After using ScreenPoint to hiTest() it works only if searched location is visible on screen window. I have set zoom level to 15, so if I searched an address that's not visible on viewable screen then it doesn't work. 

Here is my updated code

			var search = new Search({
				view: view,
				//container:"searchDiv",
				popupEnabled: false, 
				resultGraphicEnabled: false,
				enableHighlight: false,
				//allPlaceholder:'#rn:msg:CUSTOM_MSG_MAP_SEARCH_PLACEHOLDER#',
				sources: [customSearchSource, cityOwnedParcelSearch, waterTreatmentPlanSearch, waterProductionWellSearch, sampleStationSearch],
				includeDefaultSources: false,
				maxResults: 8,
				maxSuggestions: 8,
			});
			
			search.on("search-complete", function(event)
			{			
			    //take lat and long from Esri search if geometry type is point or polygon
			    let lat, longt;
			    if(event.results[0].results[0].feature.geometry.type == 'point') {
			        lat = event.results[0].results[0].feature.geometry.latitude;
			        longt = event.results[0].results[0].feature.geometry.longitude;
			    } else if(event.results[0].results[0].feature.geometry.type == 'polygon') {
			        lat = event.results[0].results[0].feature.geometry.centroid.latitude;
			        longt = event.results[0].results[0].feature.geometry.centroid.longitude;
			    }		
			   let pointVar = new Point({
			        latitude:lat,
			        longitude:longt
			    });

				//selectedGraphic.geometry = webMercatorUtils.geographicToWebMercator(pointVar);
				view.hitTest(view.toScreen(pointVar)).then(function(response)
				{		
					if (response && response.results.length > 0 && response.results[0].graphic && response.results[0].graphic != undefined && response.results[0].graphic.attributes != undefined ) {
						let graphic = response.results[0].graphic;

						if (highlightSelect) {
							highlightSelect.remove();
						}
						view.whenLayerView(graphic.layer).then(function(lyrView){
							highlightSelect = lyrView.highlight(graphic);
						});	
					}
				});		 
				search.clear();

			}); 

 

 

0 Kudos
JohnGrayson
Esri Alum

Correct, hitTest(..) only works with information in the current view since it's designed to work when the user interacts with the view.  Hard to tell without a codepen/jsbin of the exact interactions going on, but here are a few possible alternatives for you to explore:

- make sure Search is configured to place the user over the found result, wait for the view to finish updating, then call hitTest(...).

- use goTo(...) to place the view over the found result, wait for the view to finish updating, then call hitTest(...).

- use goTo(...) to place the view over the found result, wait for the view to finish updating, then use fetchFeatures to get all features and not just the first one.

- ask all the individual layer(s) if they have any data at the searched location by calling queryFeatures(...).

0 Kudos
anuragmittal
Occasional Contributor

Thank you John, I was thinking the same. I can't simulate this on codepen as all API are secured. I am new to ESRI GIS. Could you please guide me how to wait for the view to finish updating?

0 Kudos
JohnGrayson
Esri Alum

You can watch for the MapView property called updating to be false.  You can directly watch this property, or for this use-case maybe use watchUtils which might be more appropriate.  The assumption is that after navigating to a search result the view will be updating, and you want to wait before interrogating via hitTest(...) or other.  You could skip this part and see if it works for your use-case, and then add it in if it doesn't quite work as you need.

 

// ALL updating PROPERTY CHANGES //
mapView.watch('updating', (updating) =>{
  console.log('Updating: ', updating);
});

// WHEN updating IS FALSE ONE TIME //
watchUtils.whenFalseOnce(mapView, 'updating', ()=> {
  console.log('View Not Updating');
});

 

 

anuragmittal
Occasional Contributor

Perfect. watchUtils worked for me. Thank you a lot.

0 Kudos