map touch listener for graphic overlay and feature layer in android sdk 100.5.0

1706
5
Jump to solution
08-04-2019 09:31 PM
AsifIsmail
New Contributor III

Hello everyone,

in my app,i have scenario where i show feature layer with some points.i have created a class that extends defaultmaptouchlistener to handle tap events. this works fine without an issue.

in some cases,my map may also have some graphic overlays which also need to be tap recognized,the problem is that the tap listener fails to recognize tap events on graphic overlays..

how do i create a single taplistener that works both for feature layer points and graphic overlays? 

0 Kudos
1 Solution

Accepted Solutions
TylerSchiewe
New Contributor II

In the "nested" approach I posted above, if you click on a graphic, features (layers) will not be queried:

if (identifyGraphicsResults.size() > 0) {
   // process the tapped graphic results (don't query features)...
} else {
   // no graphics were tapped (query features)...

If you want clicked features to have priority, you can query them in the opposite order.

If you don't want to prioritize features over graphics or vice versa, you can use the "separate" approach.

Currently, the API does not provide a way to query features and graphics simultaneously. For one, IdentifyGraphicsOverlayResult does not share a parent class with IdentifyLayerResult. So it is up to you to determine how you want to combine the queries/results. If you do need this ability, please submit a feature request.

View solution in original post

0 Kudos
5 Replies
TylerSchiewe
New Contributor II

Hi Asif,

I assume that your custom touch listener looks a bit like the one in this sample: https://github.com/Esri/arcgis-runtime-samples-android/blob/master/java/identify-graphics/src/main/j....

To get tapped graphics and features, you will need to call both mapView.identifyGraphicsOverlaysAsync and mapView.identifyLayersAsync. There isn't a method which can be used to identify both. You can either process the results in separate doneListeners or nest one inside the other, depending on what you want to do. This should happen in your onSingleTappedConfirmed method.

Separate:

// identify graphics...
final ListenableFuture<List<IdentifyGraphicsOverlayResult>> identifyGraphicsFuture = mMapView.identifyGraphicsOverlaysAsync(screenPoint, 10.0, false);
identifyGraphicsFuture.addDoneListener(new Runnable() {
	@Override
	public void run() {
		try {
			List<IdentifyGraphicsOverlayResult> identifyGraphicsResults = identifyGraphicsFuture.get();
			if (identifyGraphicsResults.size() > 0) {
			  // process the tapped graphic results...
			}
		} catch(InterruptedException | ExecutionException ie){
			ie.printStackTrace();
		}
	}
});

// identify features...
final ListenableFuture<List<IdentifyLayerResult>> identifyLayersFuture = mMapView.identifyLayersAsync(screenPoint, 10.0, false);
identifyLayersFuture.addDoneListener(new Runnable() {
  @Override
  public void run() {
	try {
		List<IdentifyLayerResult> identifyLayerResults = identifyLayersFuture.get();
		if (identifyLayerResults.size() > 0) {
		  // process the tapped feature results...
		}
	} catch(InterruptedException | ExecutionException ex){
		ex.printStackTrace();
	}
  }
});

Nested:

// identify graphics on the graphics overlay
final ListenableFuture<List<IdentifyGraphicsOverlayResult>> identifyGraphicsFuture = mMapView.identifyGraphicsOverlaysAsync(screenPoint, 10.0, false);

identifyGraphicsFuture.addDoneListener(new Runnable() {
	@Override
	public void run() {
		try {
			List<IdentifyGraphicsOverlayResult> identifyGraphicsResults = identifyGraphicsFuture.get();
			if (identifyGraphicsResults.size() > 0) {
			  // process the tapped graphic results...
			} else {
			  // no graphics were tapped, try to identify tapped features...
			  final ListenableFuture<List<IdentifyLayerResult>> identifyLayersFuture = mMapView.identifyLayersAsync(screenPoint, 10.0, false);
			  identifyLayersFuture.addDoneListener(new Runnable() {
				  @Override
				  public void run() {
					try {
						List<IdentifyLayerResult> identifyLayerResults = identifyLayersFuture.get();
						if (identifyLayerResults.size() > 0) {
						  // process the tapped feature results...
						} else {
						  // no graphics or features were tapped
						}
					} catch(InterruptedException | ExecutionException ex){
						ex.printStackTrace();
					}
				  }
			  });
			}
		} catch(InterruptedException | ExecutionException ie){
			ie.printStackTrace();
		}
	}
});‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Hope this helps.

0 Kudos
AsifIsmail
New Contributor III

so if we need to have 2 separate identifiers to identify graphics and features, i think it would be a unoptimized solution,

what if i click on graphics only, in this scenario..the other layers which are on the map are getting queried for no use right ? 

0 Kudos
TylerSchiewe
New Contributor II

In the "nested" approach I posted above, if you click on a graphic, features (layers) will not be queried:

if (identifyGraphicsResults.size() > 0) {
   // process the tapped graphic results (don't query features)...
} else {
   // no graphics were tapped (query features)...

If you want clicked features to have priority, you can query them in the opposite order.

If you don't want to prioritize features over graphics or vice versa, you can use the "separate" approach.

Currently, the API does not provide a way to query features and graphics simultaneously. For one, IdentifyGraphicsOverlayResult does not share a parent class with IdentifyLayerResult. So it is up to you to determine how you want to combine the queries/results. If you do need this ability, please submit a feature request.

0 Kudos
AsifIsmail
New Contributor III

Thanks tyler,

but what if i have more than one graphicsoverlay.. how do i differentiate them?

i mean how do i identify the tap on group of graphic layers in graphic overlay in the map ?

0 Kudos
TylerSchiewe
New Contributor II

Unfortunately, there is no API for identifying on a group of GraphicsOverlays. You can either call GeoView#identifyGraphicsOverlayAsync  on each one you are interested in or call GeoView#identifyGraphicsOverlaysAsync  and filter the results using IdentifyGraphicsOverlayResult#getGraphicsOverlay .

0 Kudos