ArcGIS Runtime SDK for Android 入门(16):对地图中的图层进行identify交互几何查询

        本文主要讲解如何通过触摸点击的方式,对MapView中显示的图层进行进行identify交互几何查询,并返回消息。

实现步骤:

1.创建Android项目   

2.添加Runtime SDK依赖   

3.添加权限及OpenGL ES支持

前三步本文省略,初学者可参照ArcGIS Runtime SDK for Android 入门(1):第一个地图应用程序(二维)

4.设置界面布局

布局XML代码:

    <!-- MapView控件 -->
    <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.编写代码:

(1)变量准备:

  // Log.e的标志变量
  private final String TAG = MainActivity.class.getSimpleName();
  // 影像图层变量
  private ArcGISMapImageLayer mMapImageLayer;
  // MapView控件变量
  private MapView mMapView;

(2)onCreate方法:

mMapView = (MapView) findViewById(R.id.mapView);
    //创建一个Map的实例
    ArcGISMap map = new ArcGISMap(Basemap.createTopographic());

    // 创建地图影像图层
    mMapImageLayer = new ArcGISMapImageLayer("https://sampleserver6.arcgisonline.com/arcgis/rest/services/SampleWorldCities/MapServer");
    mMapImageLayer.addDoneLoadingListener(new Runnable() {
      @Override public void run() {
        // 隐藏Continent和World两个图层(仅保存WorldCities点图层)
        mMapImageLayer.getSubLayerContents().get(1).setVisible(false);
        mMapImageLayer.getSubLayerContents().get(2).setVisible(false);
      }
    });
    map.getOperationalLayers().add(mMapImageLayer);

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

    // 创建Featurelayer
    FeatureLayer featureLayer = new FeatureLayer(featureTable);

    // 将创建的Featurelayer添加到Operationallayers中
    map.getOperationalLayers().add(featureLayer);

    // 设置初始视点为一个特定的地区
    map.setInitialViewpoint(
        new Viewpoint(new Point(-10977012.785807, 4514257.550369, SpatialReference.create(3857)), 68015210));

    // 将地图添加到控件中
    mMapView.setMap(map);

    // 添加一个检测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)识别图层的主方法:

  // 给定的屏幕点的情况下对图层执行识别,并调用handleIdentifyResults(…)来处理它们。
  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)处理识别结果的方法:

  // 将识别结果处理为一个字符串,将它通过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);

      // 如果不是数组中的最后元素,则添加新的行字符
      if (!identifyLayerResult.equals(identifyLayerResults.get(identifyLayerResults.size() - 1))) {
        message.append("\n");
      }
      totalCount += count;
    }

    // 如果有元素被发现则展示识别结果,否则通知用户没有元素被找到
    if (totalCount > 0) {
      showAlertDialog(message);
    } else {
      Toast.makeText(this, "No element found", Toast.LENGTH_SHORT).show();
      Log.i(TAG, "No element found.");
    }
  }

(5)获取识别结果图层地理元素个数方法:

  // 在处理后的结果图层中获取地理元素的个数
  private int geoElementsCountFromResult(IdentifyLayerResult result) {
    // 创建一个临时的数组
    List<IdentifyLayerResult> tempResults = new ArrayList<>();
    tempResults.add(result);

    // 使用深度优先搜索方法来处理递归
    int count = 0;
    int index = 0;

    while (index < tempResults.size()) {
      // 从array数组中获取结果对象
      IdentifyLayerResult identifyResult = tempResults.get(index);
      // 更新结果中的地理元素数量
      // update count with geoElements from the result
      count += identifyResult.getElements().size();

      // 如果子图层中有结果,在当前的结果后面添加结果对象
      if (identifyResult.getSublayerResults().size() > 0) {
        tempResults.add(identifyResult.getSublayerResults().get(index));
      }

      // update the count and repeat
      // 更新计数重复循环
      index += 1;
    }
    return count;
  }

(6)展示AlertDialog

  //在AlertDialog中展示消息
  private void showAlertDialog(StringBuilder message) {
    Builder alertDialogBuilder = new Builder(this);
    // 设置标题
    alertDialogBuilder.setTitle("Number of elements found");

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

    // 创建AlertDialog对象
    AlertDialog alertDialog = alertDialogBuilder.create();
    // 显示AlertDialog
    alertDialog.show();
  }

6.运行APP:当点击点要素图层时,弹出点击的地理元素个数消息

感谢luq老师的指导

猜你喜欢

转载自blog.csdn.net/smart3s/article/details/81119506
今日推荐