How to get a listener for many Feature Layers in ArcGIS Android?

318 views Asked by At

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.

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.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(MainActivity.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")) {
                                            mPdfFilename = (String) attributes.get("COD"); 
                                        }
                                    }
                                } catch (Exception e) {
                                    Log.e(getResources().getString(R.string.app_name), "Select feature failed: " + e.getMessage());
                                }
                            }
                        });
                        return super.onSingleTapConfirmed(e);
                    }
                });
            }

        }
    }
});
1

There are 1 answers

0
falldownhill On

Your current code will only select whatever features are within mFeatureLayer per the line here

mFuture = mFeatureLayer.selectFeaturesAsync(query, FeatureLayer.SelectionMode.ADD);

which is getting overwritten each time within your loop over the Geodatabase tables so it's just holding whatever layer was added last.

I think that Identify or one of the overloads might be more suited to your purposes.

some quick example usage code is:

@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
  android.graphics.Point screenPoint = new android.graphics.Point((int) e.getX(), (int) e.getY());

  final ListenableFuture<List<IdentifyLayerResult>> identifyFuture = mMapView
      .identifyLayersAsync(screenPoint, 10, false, 10);
  identifyFuture.addDoneListener(new Runnable() {
    @Override public void run() {
      try {
        List<IdentifyLayerResult> identifyLayerResultList = identifyFuture.get();
        //if the point that the identify occurs at contains points from both layers, this should return 2 results, one for each layer
        Log.d("identifySize", String.valueOf(identifyLayerResultList.size()));
        for (IdentifyLayerResult result : identifyLayerResultList) {
          LayerContent layer = result.getLayerContent();
          //do whatever you want for the layer
          //the features are retrieved through result.getElements()

        }
      } catch (InterruptedException | ExecutionException e1) {
        e1.printStackTrace();
      }
    }
  });
  return super.onSingleTapConfirmed(e);
}