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?
Solved! Go to Solution.
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.
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.
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 ?
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.
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 ?
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 .