前面 ArcGIS Runtime SDK for Android 学习(6):绘制几何图形 中介绍的是通过代码进行几何图形的绘制,而本文讲解的是通过触控的方式进行交互式的图形绘制,并制作一个简易的绘图编辑器。
实现步骤:
1.创建Android项目
2.添加Runtime SDK依赖
3.添加权限及OpenGL ES支持
前三步本文省略,初学者可参照ArcGIS Runtime SDK for Android 入门(1):第一个地图应用程序(二维)
4.设置界面布局
布局XML代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:orientation="horizontal">
<Button
android:id="@+id/point"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="画单点" />
<Button
android:id="@+id/multipoint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="画多点" />
<Button
android:id="@+id/polyline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="画折线" />
<Button
android:id="@+id/polygon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="画多边形" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:orientation="horizontal">
<Button
android:id="@+id/freepolyline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="自由画线" />
<Button
android:id="@+id/freepolygon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="自由画多边形" />
<Button
android:id="@+id/undo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="撤销" />
<Button
android:id="@+id/redo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="重复" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="8"
android:gravity="center"
android:orientation="vertical">
<!-- MapView控件 -->
<com.esri.arcgisruntime.mapping.view.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="4"/>
<Button
android:id="@+id/stop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="停止绘制" />
</LinearLayout>
</LinearLayout>
5.编写代码:在Activity导入View.OnClickListener接口的情况下
(1)变量准备:
//调试的标志变量
private final String TAG = MainActivity.class.getSimpleName();
//Symbol(符号)变量
private SimpleMarkerSymbol mPointSymbol;
private SimpleLineSymbol mLineSymbol;
private SimpleFillSymbol mFillSymbol;
//MapView控件变量
private MapView mMapView;
//绘制编辑器变量
private SketchEditor mSketchEditor;
//用于储存绘制图形的GraphicsOverlay变量
private GraphicsOverlay mGraphicsOverlay;
//按钮变量
private Button mPointButton;
private Button mMultiPointButton;
private Button mPolylineButton;
private Button mPolygonButton;
private Button mFreehandLineButton;
private Button mFreehandPolygonButton;
private Button mStop;
private Button mRedo;
private Button mUndo;
(2)onCreate中:
// 定义用来绘制的图形的symbols,包括点线面
mPointSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.SQUARE, 0xFFFF0000, 20);
mLineSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, 0xFFFF8800, 4);
mFillSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.CROSS, 0x40FFA9A9, mLineSymbol);
// 通过layout获取MapView控件
mMapView = findViewById(R.id.mapView);
// 创建一个以地形图为底图的地图对象
ArcGISMap map = new ArcGISMap(Basemap.Type.LIGHT_GRAY_CANVAS, 34.056295, -117.195800, 16);
// 设置地图在MapView中显示
mMapView.setMap(map);
//创建用于显示绘制图形的GraphicsOverlay
mGraphicsOverlay = new GraphicsOverlay();
//将GraphicsOverlay添加到MapView上
mMapView.getGraphicsOverlays().add(mGraphicsOverlay);
// 创建一个sketch editor(绘制编辑器)对象并将它添加到MapView中
mSketchEditor = new SketchEditor();
mMapView.setSketchEditor(mSketchEditor);
// 通过layout获取按钮对象
mPointButton = findViewById(R.id.point); //画单点按钮
mMultiPointButton = findViewById(R.id.multipoint); //画多点按钮
mPolylineButton = findViewById(R.id.polyline); //画折线按钮
mPolygonButton = findViewById(R.id.polygon); //画多边形按钮
mFreehandLineButton = findViewById(R.id.freepolyline); //自由画线按钮
mFreehandPolygonButton = findViewById(R.id.freepolygon); //自由画多边形按钮
mStop=findViewById(R.id.stop);
mRedo=findViewById(R.id.redo);
mUndo=findViewById(R.id.undo);
// 添加按钮的事件监听
mPointButton.setOnClickListener(this);
mMultiPointButton.setOnClickListener(this);
mPolylineButton.setOnClickListener(this);
mPolygonButton.setOnClickListener(this);
mFreehandLineButton.setOnClickListener(this);
mFreehandPolygonButton.setOnClickListener(this);
mStop.setOnClickListener(this);
mRedo.setOnClickListener(this);
mUndo.setOnClickListener(this);
(3)按钮事件:
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.point:createModePoint();break;
case R.id.multipoint:createModeMultipoint();break;
case R.id.polyline:createModePolyline();break;
case R.id.polygon:createModePolygon();break;
case R.id.freepolyline:createModeFreehandLine();break;
case R.id.freepolygon:createModeFreehandPolygon();break;
case R.id.stop:stop();break;
case R.id.redo:redo();break;
case R.id.undo:undo();break;
}
}
(4)方法支持:
//当绘制点按钮被点击,重置其他按钮,将本按钮显示为已被点击样式,并开启绘制单点模式
private void createModePoint() {
mSketchEditor.start(SketchCreationMode.POINT);
}
//当绘制多点按钮被点击,重置其他按钮,将本按钮显示为已被点击样式,并开启绘制多点模式
private void createModeMultipoint() {
mSketchEditor.start(SketchCreationMode.MULTIPOINT);
}
//当绘制折线按钮被点击,重置其他按钮,将本按钮显示为已被点击样式,并开启绘制折线模式
private void createModePolyline() {
mSketchEditor.start(SketchCreationMode.POLYLINE);
}
//当绘制多边形按钮被点击,重置其他按钮,将本按钮显示为已被点击样式,并开启绘制多边形模式
private void createModePolygon() {
mSketchEditor.start(SketchCreationMode.POLYGON);
}
//当自由绘制线按钮被点击,重置其他按钮,将本按钮显示为已被点击样式,并开启自由绘制线模式
private void createModeFreehandLine() {
mSketchEditor.start(SketchCreationMode.FREEHAND_LINE);
}
//当自由绘制多边形按钮被点击,重置其他按钮,将本按钮显示为已被点击样式,并开启自由绘制多边形模式
private void createModeFreehandPolygon() {
mSketchEditor.start(SketchCreationMode.FREEHAND_POLYGON);
}
//当撤销按钮被电击,撤销绘制编辑器的上一个事件
private void undo() {
if (mSketchEditor.canUndo()) {
mSketchEditor.undo();
}
}
//当重复按钮被电击,重复绘制编辑器的上一个事件
private void redo() {
if (mSketchEditor.canRedo()) {
mSketchEditor.redo();
}
}
//当停止绘制按钮被点击,检查绘制是否正在进行中,如果正在进行,获取绘制的几何形状,并设置它的Symbol符号将它添加到GraphicsOverlay中
private void stop() {
if (!mSketchEditor.isSketchValid()) {
reportNotValid();
mSketchEditor.stop();
return;
}
// 在sketch editor(绘制编辑器)中获取绘制的几何形状
Geometry sketchGeometry = mSketchEditor.getGeometry();
mSketchEditor.stop();
if (sketchGeometry != null) {
// 通过绘制的几何形状创建Graphic(图形)
Graphic graphic = new Graphic(sketchGeometry);
// 基于几何形状的类型分配一个Symbol(符号)
if (graphic.getGeometry().getGeometryType() == GeometryType.POLYGON) {
graphic.setSymbol(mFillSymbol);
} else if (graphic.getGeometry().getGeometryType() == GeometryType.POLYLINE) {
graphic.setSymbol(mLineSymbol);
} else if (graphic.getGeometry().getGeometryType() == GeometryType.POINT ||
graphic.getGeometry().getGeometryType() == GeometryType.MULTIPOINT) {
graphic.setSymbol(mPointSymbol);
}
// 将Graphic添加到GraphicsOverlay中
mGraphicsOverlay.getGraphics().add(graphic);
}
}
//当绘制无效时被调用,告诉使用者为什么绘制会无效
private void reportNotValid() {
String validIf;
if (mSketchEditor.getSketchCreationMode() == SketchCreationMode.POINT) {
validIf = "Point only valid if it contains an x & y coordinate.";
} else if (mSketchEditor.getSketchCreationMode() == SketchCreationMode.MULTIPOINT) {
validIf = "Multipoint only valid if it contains at least one vertex.";
} else if (mSketchEditor.getSketchCreationMode() == SketchCreationMode.POLYLINE
|| mSketchEditor.getSketchCreationMode() == SketchCreationMode.FREEHAND_LINE) {
validIf = "Polyline only valid if it contains at least one part of 2 or more vertices.";
} else if (mSketchEditor.getSketchCreationMode() == SketchCreationMode.POLYGON
|| mSketchEditor.getSketchCreationMode() == SketchCreationMode.FREEHAND_POLYGON) {
validIf = "Polygon only valid if it contains at least one part of 3 or more vertices which form a closed ring.";
} else {
validIf = "No sketch creation mode selected.";
}
String report = "Sketch geometry invalid:\n" + validIf;
Snackbar reportSnackbar = Snackbar.make(findViewById(R.id.toolbarInclude), report, Snackbar.LENGTH_INDEFINITE);
reportSnackbar.setAction("Dismiss", view -> reportSnackbar.dismiss());
TextView snackbarTextView = reportSnackbar.getView().findViewById(android.support.design.R.id.snackbar_text);
snackbarTextView.setSingleLine(false);
reportSnackbar.show();
Log.e(TAG, report);
}
6.运行APP:可以进行几何图形的交互式绘制:
感谢luq老师的指导