I have two Feature Layers added into a Map that I can see when I display the MapView. However, it's only the last added Feature Layer that can be processed by the Touch Listener. I cannot figure out how to make all Features Layers taken into account by the Touch Listener.
My goal is to differentiate a click on a CARTO_ETARE's feature from a click on a CARTO_PT_EAU's one.
Any help would be appreciated.
import android.Manifest;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
import com.esri.arcgisruntime.concurrent.ListenableFuture;
import com.esri.arcgisruntime.data.Feature;
import com.esri.arcgisruntime.data.FeatureQueryResult;
import com.esri.arcgisruntime.data.Geodatabase;
import com.esri.arcgisruntime.data.GeodatabaseFeatureTable;
import com.esri.arcgisruntime.data.QueryParameters;
import com.esri.arcgisruntime.geometry.Envelope;
import com.esri.arcgisruntime.geometry.Point;
import com.esri.arcgisruntime.layers.FeatureLayer;
import com.esri.arcgisruntime.mapping.ArcGISMap;
import com.esri.arcgisruntime.mapping.Basemap;
import com.esri.arcgisruntime.mapping.view.DefaultMapViewOnTouchListener;
import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
import com.esri.arcgisruntime.mapping.view.MapView;
import com.google.android.gms.tasks.OnCompleteListener;
import com.sigpau.sigpau.R;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import static com.sigpau.sigpau.R.id.mapView;
// TIP: "Invalidate caches and Restart" in Android Studio in case of debugger unreachable
public class MainActivityDemo extends AppCompatActivity implements View.OnClickListener, OnCompleteListener<Void> {
private MapView mMapView;
private static File extStorDir;
private static String extSDCardDirName;
private static String geodbFilename;
private static String mGeoDb;
private Geodatabase mGeodatabase;
// define permission to request
private final String[] reqPermission = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
private ArcGISMap mMap;
private FeatureLayer mFeatureLayer;
private ListenableFuture<FeatureQueryResult> mFuture;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// inflate MapView from layout
mMapView = (MapView) findViewById(mapView);
// create a map with the streets basemap
mMap = new ArcGISMap(Basemap.Type.TOPOGRAPHIC, 48.1119800, -1.6742900, 14);
//set an initial viewpoint
// set the map to be displayed in the MapView
mMapView.setMap(mMap);
// create the path to local data
extStorDir = Environment.getExternalStorageDirectory();
extSDCardDirName = this.getResources().getString(R.string.config_data_sdcard_offline_dir);
geodbFilename = this.getResources().getString(R.string.config_geodb_name);
// full path to data
mGeoDb = createGeoDbFilePath();
ActivityCompat.requestPermissions(MainActivityDemo.this, reqPermission, 2);
}
/**
* Handle the permissions request response
*/
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// create a new Geodatabase from local path
mGeodatabase = new Geodatabase(mGeoDb);
// load the geodatabase
mGeodatabase.loadAsync();
// add feature layer from geodatabase to the ArcGISMap
mGeodatabase.addDoneLoadingListener(new Runnable() {
@Override
public void run() {
for (GeodatabaseFeatureTable geoDbTable : mGeodatabase.getGeodatabaseFeatureTables()){
ArrayList<String> list_of_tables = new ArrayList<String>();
list_of_tables.add("CARTO_ETARE");
list_of_tables.add("CARTO_PT_EAU");
Set<String> set = new HashSet<String>(list_of_tables);
if (set.contains(geoDbTable.getTableName())) {
mFeatureLayer = new FeatureLayer(geoDbTable);
mFeatureLayer.setSelectionColor(Color.YELLOW);
mFeatureLayer.setLabelsEnabled(true);
mFeatureLayer.setSelectionWidth(10);
//featureLayer.selectFeatures();
mMap.getOperationalLayers().add(mFeatureLayer);
mMapView.setMap(mMap);
// set an on touch listener to listen for click events
mMapView.setOnTouchListener(new DefaultMapViewOnTouchListener(MainActivityDemo.this, mMapView) {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
// get the point that was clicked and convert it to a point in map coordinates
Point clickPoint = mMapView.screenToLocation(new android.graphics.Point(Math.round(e.getX()), Math.round(e.getY())));
int tolerance = 10;
double mapTolerance = tolerance * mMapView.getUnitsPerDensityIndependentPixel();
// create objects required to do a selection with a query
Envelope envelope = new Envelope(clickPoint.getX() - mapTolerance,
clickPoint.getY() - mapTolerance,
clickPoint.getX() + mapTolerance,
clickPoint.getY() + mapTolerance,
mMap.getSpatialReference());
QueryParameters query = new QueryParameters();
query.setGeometry(envelope);
// call select features
mFuture = mFeatureLayer.selectFeaturesAsync(query, FeatureLayer.SelectionMode.ADD);
// add done loading listener to fire when the selection returns
mFuture.addDoneListener(new Runnable() {
@Override
public void run() {
try {
//call get on the future to get the result
FeatureQueryResult result = mFuture.get();
// create an Iterator
Iterator<Feature> iterator = result.iterator();
Feature feature;
while (iterator.hasNext()) {
feature = iterator.next();
Map<String, Object> attributes = feature.getAttributes();
if(feature.getFeatureTable().getTableName().equals("CARTO_PT_EAU")) {
Toast.makeText(getApplicationContext(), Long.toString((Long)attributes.get("ID_PT_EAU")), Toast.LENGTH_SHORT).show();
}
else if(feature.getFeatureTable().getTableName().equals("CARTO_ETARE")) {
Toast.makeText(getApplicationContext(), Long.toString((Long)attributes.get("CARTO_ETARE")), Toast.LENGTH_SHORT).show();
}
}
} catch (Exception e) {
Log.e(getResources().getString(R.string.app_name), "Select feature failed: " + e.getMessage());
}
}
});
return super.onSingleTapConfirmed(e);
}
});
}
}
}
});
} else {
// report to user that permission was denied
Toast.makeText(MainActivityDemo.this, getResources().getString(R.string.location_permission_denied),
Toast.LENGTH_SHORT).show();
}
}
/**
* Create the mobile geodatabase file location and name structure
*/
private static String createGeoDbFilePath() {
return extStorDir.getAbsolutePath() + File.separator + extSDCardDirName + File.separator + geodbFilename;
}
}