本文主要讲解如何通过触摸点击的方式,对MapView中显示的图层进行进行identify交互几何查询,并返回消息。
实现步骤:
1.创建Android项目
2.添加Runtime SDK依赖
3.添加权限及OpenGL ES支持
前三步本文省略,初学者可参照ArcGIS Runtime SDK for Android 入门(1):第一个地图应用程序(二维)
4.设置界面布局
布局XML代码:
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> identifyLayerResultsFuture = mMapView
.identifyLayersAsync(screenPoint, 12, false, 10);
identifyLayerResultsFuture.addDoneListener(new Runnable() {
@Override public void run() {
try {
List identifyLayerResults = identifyLayerResultsFuture.get();
handleIdentifyResults(identifyLayerResults);
} catch (InterruptedException | ExecutionException e) {
Log.e(TAG, "Error identifying results: " + e.getMessage());
}
}
});
}
(4)处理识别结果的方法:
// 将识别结果处理为一个字符串,将它通过ShowAlerDialog的方式弹出
private void handleIdentifyResults(List 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 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:当点击点要素图层时,弹出点击的地理元素个数消息