ArcGIS Runtime SDK for Android Learning (16): Recognition of Layers in Maps by Touch

Keywords: Android SDK REST xml

This article mainly explains how to recognize the layers displayed in MapView and return messages by touching and clicking.

Implementation steps:

1. Create an Android project

2. Adding Runtime SDK dependencies

3. Adding permissions and OpenGL ES support

The first three steps are omitted. Beginners can refer to them. ArcGIS Runtime SDK for Android Learning Notes (1): First Map Application (2-D)

4. Setting up the interface layout

Layout XML code:

    <!-- MapView control -->
    <com.esri.arcgisruntime.mapping.view.MapView
            android:id="@+id/mapView"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    </com.esri.arcgisruntime.mapping.view.MapView>

5. Write code:

(1) Variable preparation:

  // Log.e's Markup Variables
  private final String TAG = MainActivity.class.getSimpleName();
  // Image Layer Variables
  private ArcGISMapImageLayer mMapImageLayer;
  // MapView control variable
  private MapView mMapView;

(2) onCreate method:

mMapView = (MapView) findViewById(R.id.mapView);
    //Create an instance of Map
    ArcGISMap map = new ArcGISMap(Basemap.createTopographic());

    // Creating Map Image Layer
    mMapImageLayer = new ArcGISMapImageLayer("https://sampleserver6.arcgisonline.com/arcgis/rest/services/SampleWorldCities/MapServer");
    mMapImageLayer.addDoneLoadingListener(new Runnable() {
      @Override public void run() {
        // Hide Continent and World layers (save only WorldCities point layers)
        mMapImageLayer.getSubLayerContents().get(1).setVisible(false);
        mMapImageLayer.getSubLayerContents().get(2).setVisible(false);
      }
    });
    map.getOperationalLayers().add(mMapImageLayer);

    // Create FeatureTable
    FeatureTable featureTable = new ServiceFeatureTable("https://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer/0");

    // Create a Featurelayer
    FeatureLayer featureLayer = new FeatureLayer(featureTable);

    // Add the created Featurelayer s to Operationallayers
    map.getOperationalLayers().add(featureLayer);

    // Set the initial viewpoint to a specific area
    map.setInitialViewpoint(
        new Viewpoint(new Point(-10977012.785807, 4514257.550369, SpatialReference.create(3857)), 68015210));

    // Add a map to the control
    mMapView.setMap(map);

    // Add a touch monitor to detect MapView
    mMapView.setOnTouchListener(new DefaultMapViewOnTouchListener(MainActivity.this, mMapView) {
      @Override public boolean onSingleTapConfirmed(MotionEvent e) {
        android.graphics.Point screenPoint = new android.graphics.Point(Math.round(e.getX()),
            Math.round(e.getY()));
        identifyResult(screenPoint);
        return true;
      }
    });

(3) The main method of identifying layers:

  // Given the screen point, the layer is identified and handleIdentify Results (... ) To deal with them.
  private void identifyResult(android.graphics.Point screenPoint) {

    final ListenableFuture<List<IdentifyLayerResult>> identifyLayerResultsFuture = mMapView
        .identifyLayersAsync(screenPoint, 12, false, 10);

    identifyLayerResultsFuture.addDoneListener(new Runnable() {
      @Override public void run() {
        try {
          List<IdentifyLayerResult> identifyLayerResults = identifyLayerResultsFuture.get();
          handleIdentifyResults(identifyLayerResults);
        } catch (InterruptedException | ExecutionException e) {
          Log.e(TAG, "Error identifying results: " + e.getMessage());
        }
      }
    });
  }

(4) Method of processing recognition results:

  // Processing the recognition result into a string and popping it up through ShowAlerDialog
  private void handleIdentifyResults(List<IdentifyLayerResult> identifyLayerResults) {
    StringBuilder message = new StringBuilder();
    int totalCount = 0;
    for (IdentifyLayerResult identifyLayerResult : identifyLayerResults) {
      int count = geoElementsCountFromResult(identifyLayerResult);
      String layerName = identifyLayerResult.getLayerContent().getName();
      message.append(layerName).append(": ").append(count);

      // add new line character if not the final element in array
      // If it is not the last element in the array, add a new line character
      if (!identifyLayerResult.equals(identifyLayerResults.get(identifyLayerResults.size() - 1))) {
        message.append("\n");
      }
      totalCount += count;
    }

    // if any elements were found show the results, else notify user that no elements were found
    // If an element is found, the recognition result is displayed, otherwise the user is notified that no element has been found.
    if (totalCount > 0) {
      showAlertDialog(message);
    } else {
      Toast.makeText(this, "No element found", Toast.LENGTH_SHORT).show();
      Log.i(TAG, "No element found.");
    }
  }

(5) The method of obtaining the number of geographical elements of the recognition result layer:

  // Get the number of geographic elements in the processed result layer
  private int geoElementsCountFromResult(IdentifyLayerResult result) {
    // Create a temporary array
    List<IdentifyLayerResult> tempResults = new ArrayList<>();
    tempResults.add(result);

    // Using Depth First Search to Handle Recursion
    int count = 0;
    int index = 0;

    while (index < tempResults.size()) {
      // Getting the result object from the array array array
      IdentifyLayerResult identifyResult = tempResults.get(index);
      // Number of Geographical Elements in Update Results
      // update count with geoElements from the result
      count += identifyResult.getElements().size();

      // If there is a result in the sublayer, add the result object after the current result
      if (identifyResult.getSublayerResults().size() > 0) {
        tempResults.add(identifyResult.getSublayerResults().get(index));
      }

      // update the count and repeat
      // Update Count Repeated Loop
      index += 1;
    }
    return count;
  }

(6) Show Alert Dialog

  //Show the message in Alert Dialog
  private void showAlertDialog(StringBuilder message) {
    Builder alertDialogBuilder = new Builder(this);
    // Set title
    alertDialogBuilder.setTitle("Number of elements found");

    // Setting up dialog message message
    alertDialogBuilder
        .setMessage(message)
        .setCancelable(false)
        .setPositiveButton("Ok", new OnClickListener() {
          @Override public void onClick(DialogInterface dialog, int id) {
          }
        });

    // Create an AlertDialog object
    AlertDialog alertDialog = alertDialogBuilder.create();
    // Display Alert Dialog
    alertDialog.show();
  }

6. Run APP: When clicking on the element layer, pop up the number of clicked geographic elements message

Thank you, Mr. luq, for your guidance.

Posted by jsnyder2k on Mon, 04 Feb 2019 14:00:16 -0800