Prechádzať zdrojové kódy

1、标志页面功能开发完成,初始化标志图片角度BUG解决
2、测量长度工具思路确定,尚未进行功能开发及完善

不会爬树的猴 2 rokov pred
rodič
commit
2e77d23eba

+ 104 - 3
app/src/main/java/com/cr/cruav/AvMain.kt

@@ -58,6 +58,12 @@ class AvMain : CrActivity(), View.OnClickListener {
     // define: 2023/4/17 涂鸦页面
     private var fragmentDoodle: FragmentDoodle? = null
 
+    // define: 2023/4/18 标志页面
+    private var fragmentMark: FragmentMark? = null
+
+    // define: 2023/4/21 工具页面
+    private var fragmentTools:FragmentTools? = null
+
 
     /**
      * 入口函数
@@ -81,7 +87,7 @@ class AvMain : CrActivity(), View.OnClickListener {
         tools_set.setOnClickListener(this)
         tools_layer.setOnClickListener(this)
         tools_doodle.setOnClickListener(this)
-        tools_ico.setOnClickListener(this)
+        tools_mark.setOnClickListener(this)
         tools_wx.setOnClickListener(this)
         tools_tools.setOnClickListener(this)
     }
@@ -120,6 +126,20 @@ class AvMain : CrActivity(), View.OnClickListener {
         fragmentDoodle = FragmentDoodle()
         fragmentDoodle?.setListener(doodleListener)
         fragmentDoodle?.let {
+            addFragment(it, R.id.av_frm_left_panel)
+            hideFragment(it)
+        }
+        // todo: 2023/4/18 初始化标志页面
+        fragmentMark = FragmentMark()
+        fragmentMark?.setListener(markListener)
+        fragmentMark?.let {
+            addFragment(it, R.id.av_frm_left_panel)
+            hideFragment(it)
+        }
+        // todo: 2023/4/21 初始化工具页面
+        fragmentTools = FragmentTools()
+        fragmentTools?.let {
+            it.setListener(toolsListener)
             addFragment(it,R.id.av_frm_left_panel)
             hideFragment(it)
         }
@@ -224,16 +244,22 @@ class AvMain : CrActivity(), View.OnClickListener {
                 showFragment(fragmentLayerControl!!)
                 fragmentLayerControl?.initPage()
             }
-            R.id.tools_doodle->{
+            R.id.tools_doodle -> {
                 showFragment(fragmentDoodle!!)
             }
+            R.id.tools_mark->{
+                showFragment(fragmentMark!!)
+            }
+            R.id.tools_tools->{
+                showFragment(fragmentTools!!)
+            }
         }
     }
 
     /**
      * 涂鸦页面操作监听
      */
-    private val doodleListener = object:FragmentDoodle.OnOperationListener{
+    private val doodleListener = object : FragmentDoodle.OnOperationListener {
         // todo: 2023/4/17 开启绘制
         override fun onStartDraw() {
             CrApplication.getEventBus().post(EventMap(MapAction.MapTapDrawDoodle))
@@ -273,6 +299,81 @@ class AvMain : CrActivity(), View.OnClickListener {
         override fun onDelete() {
             CrApplication.getEventBus().post(EventMap(MapAction.EventDoodleDelete))
         }
+    }
+
+    /**
+     * 标志页面操作监听
+     */
+    private val markListener = object : FragmentMark.OnOperationListener {
+        // todo: 2023/4/17 开启绘制
+        override fun onStartDraw() {
+            CrApplication.getEventBus().post(EventMap(MapAction.MapTapAppendMark,fragmentMark))
+        }
+
+        // todo: 2023/4/17 停止绘制
+        override fun onStopDraw() {
+            CrApplication.getEventBus().post(EventMap(MapAction.EventStopSketch))
+        }
+
+        // todo: 2023/4/17 开启选择
+        override fun onSelect() {
+            CrApplication.getEventBus().post(EventMap(MapAction.MapTapSelectMark))
+        }
+
+        // todo: 2023/4/17 关闭选择
+        override fun onStopSelect() {
+            CrApplication.getEventBus().post(EventMap(MapAction.EventStopTouch))
+        }
+
+        // todo: 2023/4/17 清除
+        override fun onClear() {
+            CrApplication.getEventBus().post(EventMap(MapAction.EventMarkClear))
+        }
+
+        // todo: 2023/4/17 保存
+        override fun onSave() {
+            CrApplication.getEventBus().post(EventMap(MapAction.EventMarkSave))
+        }
+
+        // todo: 2023/4/17 删除全部
+        override fun onRemove() {
+            CrApplication.getEventBus().post(EventMap(MapAction.EventMarkRemove))
+        }
+
+        // todo: 2023/4/17 移除选择
+        override fun onDelete() {
+            CrApplication.getEventBus().post(EventMap(MapAction.EventMarkDelete))
+        }
+    }
+
+    /**
+     * 工具监听
+     */
+    private var toolsListener = object:FragmentTools.OnOperationListener{
+        // todo: 2023/4/21 长度测量
+        override fun onMeasureLength() {
+            CrApplication.getEventBus().post(EventMap(MapAction.EventSurveyLength))
+        }
+
+        // todo: 2023/4/21 面积测量
+        override fun onMeasureArea() {
+
+        }
+
+        // todo: 2023/4/21 清除测量内容
+        override fun onMeasureClear() {
+
+        }
+
+        // todo: 2023/4/21 获取经纬度位置
+        override fun onGetLocation() {
+
+        }
+
+        // todo: 2023/4/21 地图定位
+        override fun onToLocation() {
+
+        }
 
     }
 

+ 8 - 3
app/src/main/java/com/cr/map/EventMap.kt

@@ -7,15 +7,20 @@ package com.cr.map
  * 描述:地图事件
  */
 class EventMap @JvmOverloads constructor(
-    action:MapAction
-){
+    action: MapAction,
+    owner: Any? = null
+) {
     // define: 2023/4/17 事件动作
-    var action:MapAction?= null
+    var action: MapAction? = null
+
+    // define: 2023/4/19 动作的拥有者
+    var owner: Any? = null
 
     /**
      * 初始化
      */
     init {
         this.action = action
+        this.owner = owner
     }
 }

+ 1 - 1
app/src/main/java/com/cr/map/EventMarkChange.kt

@@ -14,7 +14,7 @@ class EventMarkChange constructor() {
     var markDrawable: Int = -1
 
     // define: 2023/4/13 符号旋转角度
-    var markAngle:Float = 0f
+    var markAngle:Int = 0
 
     /**
      * 初始化方法

+ 29 - 4
app/src/main/java/com/cr/map/MapAction.kt

@@ -30,12 +30,12 @@ enum class MapAction {
     /**
      * 添加标志动作
      */
-    MapTapAppendICO,
+    MapTapAppendMark,
 
     /**
      * 选择标志动作
      */
-    MapTapSelectICO,
+    MapTapSelectMark,
 
     /**
      * 添加违建点动作
@@ -50,12 +50,17 @@ enum class MapAction {
     /**
      * 长度测量动作
      */
-    MapTapSurveyLength,
+    EventSurveyLength,
 
     /**
      * 面积测量动作
      */
-    MapTapSurveyArea,
+    EventSurveyArea,
+
+    /**
+     * 清除测量内容
+     */
+    EventSurveyClear,
 
     /**
      * 删除违建点动作
@@ -118,6 +123,26 @@ enum class MapAction {
     EventDoodleDelete,
 
     /**
+     * 清除标志
+     */
+    EventMarkClear,
+
+    /**
+     * 保存标志
+     */
+    EventMarkSave,
+
+    /**
+     * 删除全部标志
+     */
+    EventMarkRemove,
+
+    /**
+     * 删除标志
+     */
+    EventMarkDelete,
+
+    /**
      * 停止草图编辑
      */
     EventStopSketch,

+ 22 - 6
app/src/main/java/com/cr/map/MapTouch.kt

@@ -7,9 +7,7 @@ import com.esri.arcgisruntime.ArcGISRuntimeException
 import com.esri.arcgisruntime.data.Feature
 import com.esri.arcgisruntime.geometry.Point
 import com.esri.arcgisruntime.geometry.SpatialReference
-import com.esri.arcgisruntime.layers.FeatureLayer
 import com.esri.arcgisruntime.layers.Layer
-import com.esri.arcgisruntime.mapping.GeoElement
 import com.esri.arcgisruntime.mapping.view.DefaultMapViewOnTouchListener
 import com.esri.arcgisruntime.mapping.view.MapView
 
@@ -26,8 +24,11 @@ class MapTouch constructor(context: Context, mapView: MapView) :
      * Touch回调
      */
     interface TouchListener {
-        // todo: 2023/4/18 涂鸦选择
-        fun onDoodleSelect(feature: Feature?)
+        // todo: 2023/4/18 选择
+        fun onSelect(feature: Feature?, layer: Layer)
+
+        // todo: 2023/4/19 添加标志
+        fun onMarkAppend(mapPoint:Point)
     }
 
 
@@ -64,9 +65,16 @@ class MapTouch constructor(context: Context, mapView: MapView) :
     // todo: 2023/4/18 重写点击事件
     override fun onSingleTapUp(e: MotionEvent?): Boolean {
         when (action) {
-            MapAction.MapTapSelectDoodle -> {
+            // todo: 2023/4/19 选择涂鸦
+            MapAction.MapTapSelectDoodle,
+            MapAction.MapTapSelectMark-> {
                 identifyLayer(e!!.x.toInt(), e.y.toInt())
             }
+            // todo: 2023/4/19 添加标志
+            MapAction.MapTapAppendMark->{
+                var mapPoint = mapView?.screenToLocation(android.graphics.Point(e!!.x.toInt(),e.y.toInt()))
+                if(listener != null) listener?.onMarkAppend(mapPoint!!)
+            }
         }
         return true
     }
@@ -89,7 +97,7 @@ class MapTouch constructor(context: Context, mapView: MapView) :
             } catch (e: ArcGISRuntimeException) {
                 showError("查询错误!")
             }finally {
-                if (listener != null) listener?.onDoodleSelect(feature)
+                if (listener != null) listener?.onSelect(feature,queryLayer!!)
             }
         })
     }
@@ -129,6 +137,14 @@ class MapTouch constructor(context: Context, mapView: MapView) :
     }
 
     /**
+     * 设置动作
+     * @param action MapAction 动作
+     */
+    fun setAction(action:MapAction){
+        this.action = action
+    }
+
+    /**
      * 设置监听
      * @param listener TouchListener 监听
      */

+ 6 - 6
app/src/main/java/com/cr/pages/FragmentDoodle.kt

@@ -187,12 +187,12 @@ class FragmentDoodle : CrNavigationFragment(), CrButton.OnClickListener, OnCheck
      * @param event EventAction
      */
     @Subscribe
-    fun onAction(event:EventAction){
+    fun onAction(event:EventDoodleAction){
         when(event.action){
-            EventAction.CLOSE_DRAW->{
+            EventDoodleAction.CLOSE_DRAW->{
                 switchDraw?.isChecked = false
             }
-            EventAction.CLOSE_SELECT->{
+            EventDoodleAction.CLOSE_SELECT->{
                 switchSelect?.isChecked = false
             }
         }
@@ -209,13 +209,13 @@ class FragmentDoodle : CrNavigationFragment(), CrButton.OnClickListener, OnCheck
     }
 
     // todo: 2023/4/17 订阅事件类
-    class EventAction@JvmOverloads constructor(
+    class EventDoodleAction@JvmOverloads constructor(
         action:Int
     ){
         // define: 2023/4/17 定义动作常量
         companion object{
-            val CLOSE_DRAW:Int = 0
-            val CLOSE_SELECT:Int = 1
+            const val CLOSE_DRAW:Int = 0
+            const val CLOSE_SELECT:Int = 1
         }
         // define: 2023/4/17 定义动作
         var action:Int = -1

+ 247 - 53
app/src/main/java/com/cr/pages/FragmentMap.kt

@@ -14,22 +14,18 @@ import com.cr.cruav.R
 import com.cr.data.CrUtil
 import com.cr.dialog.DialogNormal
 import com.cr.map.*
-import com.esri.arcgisruntime.ArcGISRuntimeEnvironment
 import com.esri.arcgisruntime.arcgisservices.LabelDefinition
 import com.esri.arcgisruntime.data.Feature
 import com.esri.arcgisruntime.data.FeatureTable
 import com.esri.arcgisruntime.data.Geodatabase
 import com.esri.arcgisruntime.data.QueryParameters
 import com.esri.arcgisruntime.data.ServiceFeatureTable
-import com.esri.arcgisruntime.geometry.Geometry
-import com.esri.arcgisruntime.geometry.Point
-import com.esri.arcgisruntime.geometry.PointBuilder
-import com.esri.arcgisruntime.geometry.PolylineBuilder
+import com.esri.arcgisruntime.geometry.*
 import com.esri.arcgisruntime.layers.ArcGISMapImageLayer
 import com.esri.arcgisruntime.layers.ArcGISTiledLayer
 import com.esri.arcgisruntime.layers.FeatureLayer
+import com.esri.arcgisruntime.layers.Layer
 import com.esri.arcgisruntime.mapping.ArcGISMap
-import com.esri.arcgisruntime.mapping.GeoElement
 import com.esri.arcgisruntime.mapping.view.*
 import com.esri.arcgisruntime.symbology.*
 import com.google.gson.JsonObject
@@ -110,9 +106,6 @@ class FragmentMap : CrAnimationFragment() {
     // todo: 2023/4/13 标志相关
     private var markChange: EventMarkChange? = null
 
-    // todo: 2023/4/13 动作相关
-    private var mapAction: MapAction? = null
-
     // todo: 2023/4/14 绘制图层
     private var gLayerIco: GraphicsOverlay? = null // define: 2023/4/13 标志图层
     private var gLayerDoodle: GraphicsOverlay? = null // define: 2023/4/13 涂鸦图层
@@ -141,8 +134,8 @@ class FragmentMap : CrAnimationFragment() {
     private var feaSelectCase: Feature? = null // define: 2023/4/13 选中的案件点
 
     // todo: 2023/4/14 编辑图层
-    private var fTableICO: FeatureTable? = null // define: 2023/4/14 永久标志表
-    private var fLayerICO: FeatureLayer? = null // define: 2023/4/14 永久标志图层
+    private var fTableMark: FeatureTable? = null // define: 2023/4/14 永久标志表
+    private var fLayerMark: FeatureLayer? = null // define: 2023/4/14 永久标志图层
     private var fTableMedia: FeatureTable? = null // define: 2023/4/14 媒体表
     private var fLayerMedia: FeatureLayer? = null // define: 2023/4/14 媒体图层
     private var fTableDoodle: FeatureTable? = null // define: 2023/4/14 永久涂鸦表
@@ -201,9 +194,7 @@ class FragmentMap : CrAnimationFragment() {
             itView.backgroundGrid.gridLineColor = Color.argb(0, 255, 255, 255)
             // todo: 2023/4/17 设置草图编辑
             sketchEditor = SketchEditor()
-            sketchEditor?.sketchEditConfiguration?.let {
-                it.isAllowPartSelection = false
-            }
+            setSketchEditor()
             itView.sketchEditor = sketchEditor
             // todo: 2023/4/18 Touch事件初始化
             mapTouch = MapTouch(context!!, itView)
@@ -215,18 +206,65 @@ class FragmentMap : CrAnimationFragment() {
     }
 
     /**
+     * 草图编辑工具监听
+     */
+    private var sketchGeometryChangeListener =
+        SketchGeometryChangedListener { p0 -> // todo: 2023/4/21 计算测试
+            if(p0!!.geometry.geometryType == GeometryType.POLYLINE){
+                var polyline = p0.geometry as Polyline
+                var pointCollection = PointCollection(SpatialReference.create(3857))
+                for(point in polyline.parts[0].points){
+                    pointCollection.add(point)
+                    if(pointCollection.size >=2){
+                        var polyline = Polyline(pointCollection)
+                        var lineLength = GeometryEngine.length(polyline)
+                        CrUtil.print("长度$lineLength")
+                    }
+                }
+            }
+        }
+
+    private var sketchSelectedVertexChangedListener = SelectedVertexChangedListener { CrUtil.print("选择节点变化") }
+
+    /**
+     * 设置草图编辑器
+     */
+    private fun setSketchEditor(){
+        // todo: 2023/4/21 获取样式
+        var sketchStyle:SketchStyle = sketchEditor!!.sketchStyle
+        // todo: 2023/4/21 设置点符号样式
+        var markerSymbol = SimpleMarkerSymbol()
+        markerSymbol.size = 10f
+        markerSymbol.color = Color.RED
+        markerSymbol.style = SimpleMarkerSymbol.Style.CIRCLE
+
+        // todo: 2023/4/21 设置样式
+        sketchStyle.vertexSymbol = markerSymbol
+        // todo: 2023/4/21 启用
+        sketchEditor?.sketchStyle = sketchStyle
+
+    }
+
+    /**
      * Touch监听
      */
     private var touchListener = object : MapTouch.TouchListener {
-        // todo: 2023/4/18 涂鸦选择回调
-        override fun onDoodleSelect(feature: Feature?) {
-            if (feature != null) {
-                // todo: 2023/4/18 高亮显示
-                focusFeature(fLayerDoodle!!, feature)
-            } else {
-                unfocusFeature(fLayerDoodle!!)
+        // todo: 2023/4/21 选择
+        override fun onSelect(feature: Feature?, layer: Layer) {
+            if (layer is FeatureLayer) {
+                if (feature != null) {
+                    // todo: 2023/4/18 高亮显示
+                    focusFeature(layer!!, feature)
+                } else {
+                    unfocusFeature(layer!!)
+                }
             }
         }
+
+        // todo: 2023/4/19 标志添加回调
+        override fun onMarkAppend(mapPoint: Point) {
+            markAppend(mapPoint)
+        }
     }
 
     /**
@@ -241,6 +279,8 @@ class FragmentMap : CrAnimationFragment() {
         addBaseGeoDatabaseToMap()
         // todo: 2023/4/14 添加可编辑矢量数据
         addEditGeoDatabaseToMap()
+        // todo: 2023/4/19 添加动态图层
+        addGraphicOverlayToMap()
 
         // todo: 2023/4/13 定位地图中心点
         setMapCenter(118.709, 35.219, 5000.0);
@@ -319,15 +359,15 @@ class FragmentMap : CrAnimationFragment() {
         // todo: 2023/4/14 数据加载完监听
         geoDatabase.addDoneLoadingListener(Runnable {
             // todo: 2023/4/14 初始化标志图层
-            fTableICO = geoDatabase.getGeodatabaseFeatureTable("ico84")
-            fLayerICO = FeatureLayer(fTableICO)
-            fLayerICO!!.name = LAYER_NAME_ICO
-            fLayerICO!!.isVisible = true
-            mMap!!.operationalLayers.add(fLayerICO)
+            fTableMark = geoDatabase.getGeodatabaseFeatureTable("ico84")
+            fLayerMark = FeatureLayer(fTableMark)
+            fLayerMark!!.name = LAYER_NAME_ICO
+            fLayerMark!!.isVisible = true
+            mMap!!.operationalLayers.add(fLayerMark)
             LayerManager.getInstance().addLayer(
                 LayerModel(
-                    fLayerICO!!.name,
-                    fLayerICO!!.isVisible, LayerType.LAYER_TYPE_FEATURE_EDIT, fLayerICO!!
+                    fLayerMark!!.name,
+                    fLayerMark!!.isVisible, LayerType.LAYER_TYPE_FEATURE_EDIT, fLayerMark!!
                 ), LayerManager.LayerGroup.LAYER_NAME_DAILY
             )
             // todo: 2023/4/14  初始化涂鸦图层
@@ -381,6 +421,15 @@ class FragmentMap : CrAnimationFragment() {
     }
 
     /**
+     * 添加动态图层到地图
+     */
+    private fun addGraphicOverlayToMap() {
+        // todo: 2023/4/19 初始化动态标志图层
+        gLayerIco = GraphicsOverlay()
+        appendGraphicOverlay(gLayerIco!!, LAYER_NAME_TEMP_ICO)
+    }
+
+    /**
      * 编辑图层符号话
      */
     private fun editLayerRenderer() {
@@ -392,7 +441,7 @@ class FragmentMap : CrAnimationFragment() {
         val icoSymbol: PictureMarkerSymbol =
             createPictureMarkerSymbol(R.drawable.ico_ty1, 30f, 30f)
         val icoRenderer = SimpleRenderer(icoSymbol)
-        fLayerICO?.renderer = icoRenderer
+        fLayerMark?.renderer = icoRenderer
         // todo: 2023/4/14  违建符号化
         val mediaRenderer = UniqueValueRenderer()
         val mediaSymbolYes: PictureMarkerSymbol = createPictureMarkerSymbol(
@@ -495,6 +544,28 @@ class FragmentMap : CrAnimationFragment() {
     }
 
     /**
+     * 向地图中添加动态绘制图层
+     * @param layer GraphicsOverlay 动态绘制图层
+     * @param layerName String 图层名称
+     */
+    private fun appendGraphicOverlay(layer: GraphicsOverlay, layerName: String) {
+        // todo: 2023/4/19 设置该图层显示
+        layer.isVisible = true
+        mapView?.graphicsOverlays?.let {
+            it.add(layer)
+            LayerManager.getInstance().addLayer(
+                LayerModel(
+                    layerName,
+                    layer.isVisible,
+                    LayerType.LAYER_TYPE_GRAPHIC,
+                    layer
+                ), LayerManager.LayerGroup.LAYER_NAME_DRAW
+            )
+        }
+
+    }
+
+    /**
      * 创建图片符号
      * @param drawable Int 图片资源Id
      * @param width Float 宽度
@@ -580,14 +651,14 @@ class FragmentMap : CrAnimationFragment() {
     /**
      * 清除全部选择
      */
-    private fun unfocusAllFeature(){
-        for(layer in mMap!!.operationalLayers){
-            if(layer is FeatureLayer){
+    private fun unfocusAllFeature() {
+        for (layer in mMap!!.operationalLayers) {
+            if (layer is FeatureLayer) {
                 layer.clearSelection()
             }
         }
 
-        for(overLayer in mapView!!.graphicsOverlays){
+        for (overLayer in mapView!!.graphicsOverlays) {
             overLayer.clearSelection()
         }
     }
@@ -622,7 +693,7 @@ class FragmentMap : CrAnimationFragment() {
                         DialogNormal(context!!, "提示", "涂鸦保存成功!").show()
                         sketchEditor?.stop()
                         CrApplication.getEventBus()
-                            .post(FragmentDoodle.EventAction(FragmentDoodle.EventAction.CLOSE_DRAW))
+                            .post(FragmentDoodle.EventDoodleAction(FragmentDoodle.EventDoodleAction.CLOSE_DRAW))
                     }
                 } catch (e: InterruptedException) {
                     DialogNormal(context!!, "警告", e.message!!).show()
@@ -634,9 +705,10 @@ class FragmentMap : CrAnimationFragment() {
     }
 
     /**
-     * 删除全部涂鸦
+     * 删除数据表中的全部数据
+     * @param delTable FeatureTable 数据表
      */
-    private fun doodleRemove() {
+    private fun removeAllFeatureByTable(delTable: FeatureTable) {
         var dialog = DialogNormal(context!!, "警告", "删除后无法恢复,是否删除?")
         dialog.setButtonsText("是", "否")
         dialog.setListener(object : DialogNormal.DialogNormalListener {
@@ -644,24 +716,24 @@ class FragmentMap : CrAnimationFragment() {
             override fun completion() {
                 var params = QueryParameters()
                 params.whereClause = "1=1"
-                var queryAsync = fTableDoodle?.queryFeaturesAsync(params)
+                var queryAsync = delTable?.queryFeaturesAsync(params)
                 queryAsync?.addDoneListener(Runnable {
                     try {
                         if (queryAsync.isDone) {
-                            var deleteAsync = fTableDoodle?.deleteFeaturesAsync(queryAsync.get())
+                            var deleteAsync = delTable?.deleteFeaturesAsync(queryAsync.get())
                             deleteAsync?.addDoneListener(Runnable {
                                 try {
                                     if (deleteAsync.isDone) {
-                                        DialogNormal(context!!, "提示", "删除成功!").show()
+                                        showInformation("删除成功!")
                                     }
                                 } catch (e: java.lang.IllegalArgumentException) {
-                                    DialogNormal(context!!, "错误", "删除错误!").show()
+                                    showError("删除错误!")
                                 }
                             })
                         }
 
                     } catch (e: java.lang.IllegalArgumentException) {
-                        DialogNormal(context!!, "错误", "查询错误!").show()
+                        showError("删除错误!")
                     }
                 })
             }
@@ -676,24 +748,25 @@ class FragmentMap : CrAnimationFragment() {
     }
 
     /**
-     * 删除选择涂鸦
+     * 删除图层中选中的要素
+     * @param layer FeatureLayer 图层
      */
-    private fun doodleDelete() {
+    private fun doodleSelectFeature(layer: FeatureLayer) {
         var dialog = DialogNormal(context!!, "警告", "删除后无法恢复,是否删除?")
         dialog.setButtonsText("是", "否")
         dialog.setListener(object : DialogNormal.DialogNormalListener {
             override fun completion() {
-                var sAsync = fLayerDoodle!!.selectedFeaturesAsync
+                var sAsync = layer!!.selectedFeaturesAsync
                 sAsync.addDoneListener(Runnable {
-                    if (sAsync.isDone){
+                    if (sAsync.isDone) {
                         var result = sAsync.get()
-                        var dAsync = fTableDoodle!!.deleteFeaturesAsync(result)
-                        dAsync.addDoneListener(Runnable{
+                        var dAsync = layer.featureTable.deleteFeaturesAsync(result)
+                        dAsync.addDoneListener(Runnable {
                             try {
-                                if(dAsync.isDone){
+                                if (dAsync.isDone) {
                                     DialogNormal(context!!, "提示", "删除成功!").show()
                                 }
-                            }catch (e:java.lang.IllegalArgumentException){
+                            } catch (e: java.lang.IllegalArgumentException) {
                                 DialogNormal(context!!, "错误", "删除错误!").show()
                             }
                         })
@@ -708,6 +781,91 @@ class FragmentMap : CrAnimationFragment() {
     }
 
     /**
+     * 添加标志
+     * @param mapPoint Point 地图点
+     */
+    private fun markAppend(mapPoint: Point) {
+        if (markChange == null) return
+        var markSymbol = createPictureMarkerSymbol(markChange!!.markDrawable, 0f, 0f)
+        // todo: 2023/4/19 设置偏移
+        markSymbol.offsetX = -1 * markSymbol.width / 2
+        markSymbol.angle = markChange!!.markAngle.toFloat()
+        // todo: 2023/4/19 创建要素
+        var markGraphic = Graphic(mapPoint, markSymbol)
+        gLayerIco?.graphics?.add(markGraphic)
+        CrUtil.showMessage("标志添加成功!")
+    }
+
+    /**
+     * 保存标志
+     */
+    private fun markSave() {
+        gLayerIco?.let {
+            var features: MutableList<Feature> = mutableListOf()
+            for (graphic in it.graphics) {
+                var feature = fTableMark?.createFeature()
+                feature?.geometry = graphic.geometry
+                features.add(feature!!)
+            }
+            var addAsync = fTableMark?.addFeaturesAsync(features)
+            addAsync?.addDoneListener(Runnable {
+                try {
+                    if (addAsync.isDone) {
+                        showInformation("保存成功!")
+                        gLayerIco?.graphics?.clear()
+                    }
+                } catch (e: java.lang.IllegalArgumentException) {
+                    showError("保存错误!")
+                }
+            })
+        }
+    }
+
+    /**
+     * 测量长度
+     */
+    private fun measureLength(){
+        CrUtil.showMessage("地图上点击开始测量!")
+        sketchEditor?.let {
+            it.stop()
+            // todo: 2023/4/21 设置编辑模式
+            var model = SketchEditConfiguration()
+            model.isAllowPartSelection = false
+            model.isContextMenuEnabled = false
+            model.isRequireSelectionBeforeDrag = true
+            it.start(SketchCreationMode.POLYLINE,model)
+
+            it.opacity = 1.0f
+            // todo: 2023/4/21 设置监听
+            it.addGeometryChangedListener(sketchGeometryChangeListener)
+        }
+    }
+
+    /**
+     * 显示警告信息
+     * @param warning String 警告消息
+     */
+    private fun showWarning(warning: String) {
+        DialogNormal(context!!, "警告", warning).show()
+    }
+
+    /**
+     * 显示错误信息
+     * @param error String 错误消息
+     */
+    private fun showError(error: String) {
+        DialogNormal(context!!, "错误", error).show()
+    }
+
+    /**
+     * 显示提示信息
+     * @param information String 提示消息
+     */
+    private fun showInformation(information: String) {
+        DialogNormal(context!!, "提示", information).show()
+    }
+
+    /**
      * 订阅地图事件执行动作
      * @param event EventMap 事件
      */
@@ -733,11 +891,11 @@ class FragmentMap : CrAnimationFragment() {
             }
             // todo: 2023/4/17 全部删除保存的涂鸦
             MapAction.EventDoodleRemove -> {
-                doodleRemove()
+                removeAllFeatureByTable(fTableDoodle!!)
             }
             // todo: 2023/4/18 删除选择涂鸦
             MapAction.EventDoodleDelete -> {
-                doodleDelete()
+                doodleSelectFeature(fLayerDoodle!!)
             }
             // todo: 2023/4/18 选择涂鸦
             MapAction.MapTapSelectDoodle -> {
@@ -745,10 +903,46 @@ class FragmentMap : CrAnimationFragment() {
                 mapTouch?.setQueryLayer(fLayerDoodle!!, MapAction.MapTapSelectDoodle)
             }
             // todo: 2023/4/18 停止Touch
-            MapAction.EventStopTouch->{
-                mapTouch?.setQueryLayer(null,null)
+            MapAction.EventStopTouch -> {
+                mapTouch?.setQueryLayer(null, null)
                 unfocusAllFeature()
             }
+            // todo: 2023/4/19 绘制标志
+            MapAction.MapTapAppendMark -> {
+                CrUtil.showMessage("地图上单击创建标志!")
+                if (event.owner is FragmentMark) {
+                    markChange = (event.owner as FragmentMark).getMark()
+                    mapTouch?.setAction(MapAction.MapTapAppendMark)
+                }
+            }
+            // todo: 2023/4/19 清除标志
+            MapAction.EventMarkClear -> {
+                gLayerIco?.let {
+                    it.graphics?.clear()
+                    CrUtil.showMessage("标志清除完成!")
+                }
+            }
+            // todo: 2023/4/19 标志保存
+            MapAction.EventMarkSave -> {
+                markSave()
+            }
+            // todo: 2023/4/19 删除保存的全部标志
+            MapAction.EventMarkRemove -> {
+                removeAllFeatureByTable(fTableMark!!)
+            }
+            // todo: 2023/4/21 选择标志
+            MapAction.MapTapSelectMark -> {
+                CrUtil.showMessage("地图上点击需要选择的标志")
+                mapTouch?.setQueryLayer(fLayerMark!!, MapAction.MapTapSelectMark)
+            }
+            // todo: 2023/4/21 删除选择的标志
+            MapAction.EventMarkDelete->{
+                doodleSelectFeature(fLayerMark!!)
+            }
+            // todo: 2023/4/21 开始测量
+            MapAction.EventSurveyLength->{
+                measureLength()
+            }
         }
     }
 

+ 357 - 0
app/src/main/java/com/cr/pages/FragmentMark.kt

@@ -0,0 +1,357 @@
+package com.cr.pages
+
+import android.graphics.Color
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.ViewTreeObserver.OnGlobalLayoutListener
+import android.widget.CompoundButton
+import android.widget.CompoundButton.OnCheckedChangeListener
+import android.widget.ImageView
+import android.widget.Switch
+import com.bigkoo.pickerview.adapter.ArrayWheelAdapter
+import com.contrarywind.listener.OnItemSelectedListener
+import com.cr.cruav.CrApplication
+import com.cr.cruav.R
+import com.cr.data.CrUtil
+import com.cr.event.BarAction
+import com.cr.event.EventFragmentBarAction
+import com.cr.map.EventMarkChange
+import com.cr.view.CrViewWheel
+import com.cr.widget.CrButton
+import com.squareup.otto.Subscribe
+import dji.v5.utils.common.ContextUtil
+
+/**
+ * 操作系统:MAC系统
+ * 创建者:王成
+ * 创建日期:2023/4/17 09:12
+ * 描述:标志操作页面
+ */
+class FragmentMark : CrNavigationFragment(), CrButton.OnClickListener, OnCheckedChangeListener{
+    /**
+     * 操作监听接口
+     */
+    interface OnOperationListener {
+        // todo: 2023/4/17 开启绘制
+        fun onStartDraw()
+
+        // todo: 2023/4/17 停止绘制
+        fun onStopDraw()
+
+        // todo: 2023/4/17 开启选择
+        fun onSelect()
+
+        // todo: 2023/4/17 停止选择
+        fun onStopSelect()
+
+        // todo: 2023/4/17 清除
+        fun onClear()
+
+        // todo: 2023/4/17 保存
+        fun onSave()
+
+        // todo: 2023/4/17 删除全部
+        fun onRemove()
+
+        // todo: 2023/4/17 移除
+        fun onDelete()
+    }
+
+    private var btnClear: CrButton? = null // define: 2023/4/17 清除临时绘制的涂鸦
+    private var btnSave: CrButton? = null  // define: 2023/4/17 保存临时绘制的涂鸦
+    private var btnRemove: CrButton? = null // define: 2023/4/17 全部删除永久保存的涂鸦
+    private var btnDelete: CrButton? = null // define: 2023/4/17 删除选择的涂鸦
+    private var switchDraw: Switch? = null  // define: 2023/4/17 开启绘制
+    private var switchSelect: Switch? = null // define: 2023/4/17 开启选择
+    private var imageView:ImageView?= null  // define: 2023/4/18 图片
+    private var wheelAngle:CrViewWheel?=null // define: 2023/4/18 角度选择器
+    private var wheelType:CrViewWheel?=null // define: 2023/4/18 类型选择器
+
+    private var mAngleItems:MutableList<Int> = mutableListOf()  // define: 2023/4/18 角度集合
+    private var mTypeItems:MutableList<EventMarkChange> = mutableListOf()  // define: 2023/4/18 类型集合
+
+    private var markChange:EventMarkChange?= EventMarkChange()  // define: 2023/4/18 选中符号
+
+    // define: 2023/4/17 操作监听
+    private var listener: OnOperationListener? = null
+
+    // define: 2023/4/21 图片尺寸
+    private var imgWidth:Int = 0
+    private var imgHeight:Int = 0
+
+    /**
+     * 创建视图
+     * @param inflater LayoutInflater
+     * @param container ViewGroup?
+     * @param savedInstanceState Bundle?
+     * @return View?
+     */
+    override fun onCreateView(
+        inflater: LayoutInflater,
+        container: ViewGroup?,
+        savedInstanceState: Bundle?
+    ): View? {
+        // todo: 2023/4/17 订阅监听
+        CrApplication.getEventBus().register(this)
+        self = this
+        mainView = inflater.inflate(R.layout.frag_mark, null)
+        // todo: 2023/4/17 设置导航栏
+        setBar(R.id.nv)
+        // todo: 2023/4/17 设置展现方式
+        setAnimationDirection(AnimationDirection.LEFT)
+        // todo: 2023/4/17 关联控件
+        joinControls()
+        return mainView
+    }
+
+    /**
+     * 重写挂载控件
+     */
+    override fun joinControls() {
+        // todo: 2023/4/17 挂载控件
+        switchDraw = mainView?.findViewById(R.id.mark_on_draw)
+        switchSelect = mainView?.findViewById(R.id.mark_on_select)
+        btnClear = mainView?.findViewById(R.id.mark_clear)
+        btnSave = mainView?.findViewById(R.id.mark_save)
+        btnRemove = mainView?.findViewById(R.id.mark_remove)
+        btnDelete = mainView?.findViewById(R.id.mark_delete)
+        imageView = mainView?.findViewById(R.id.mark_ico)
+        wheelAngle = mainView?.findViewById(R.id.mark_angle)
+        wheelType = mainView?.findViewById(R.id.mark_type)
+        // todo: 2023/4/17 设置监听
+        btnClear?.setListener(this)
+        btnSave?.setListener(this)
+        btnRemove?.setListener(this)
+        btnDelete?.setListener(this)
+        switchDraw?.setOnCheckedChangeListener(this)
+        switchSelect?.setOnCheckedChangeListener(this)
+        // todo: 2023/4/18 选择器初始化
+        wheelAngle?.setTextColorCenter(Color.YELLOW) // TODO: 4/17/21 设置选中项颜色
+        wheelAngle?.setItemsVisibleCount(3)
+        wheelAngle?.setTextSize(CrUtil.getDimens(R.dimen.sp_6))
+        wheelAngle?.setTypeface(CrUtil.getFont(ContextUtil.getContext()))
+        wheelAngle?.setCyclic(false) // TODO: 6/9/21 禁止循环
+        wheelAngle?.setOnItemSelectedListener(angleListener)
+
+        wheelType?.setTextColorCenter(Color.YELLOW) // TODO: 4/17/21 设置选中项颜色
+        wheelType?.setItemsVisibleCount(3)
+        wheelType?.setTextSize(CrUtil.getDimens(R.dimen.sp_6))
+        wheelType?.setTypeface(CrUtil.getFont(ContextUtil.getContext()))
+        wheelType?.setCyclic(false) // TODO: 6/9/21 禁止循环
+        wheelType?.setOnItemSelectedListener(typeListener)
+
+        // todo: 2023/4/21 给ImageView挂载事件
+        imageView?.viewTreeObserver?.addOnGlobalLayoutListener {
+            imgWidth = imageView!!.width
+            imgHeight = imageView!!.height
+            setMark()
+        }
+
+        // todo: 2023/4/18 页面初始化
+        initPage()
+    }
+
+    /**
+     * 关闭页面
+     */
+    override fun dismiss() {
+        CrApplication.getEventBus().post(EventFragmentBarAction(self!!, BarAction.ACTION_DISMISS))
+    }
+
+    /**
+     * 视图点击事件
+     * @param view View
+     */
+    override fun onClick(view: View) {
+        when (view?.id) {
+            R.id.mark_clear -> {
+                if (listener != null) listener?.onClear()
+            }
+            R.id.mark_save -> {
+                if (listener != null) listener?.onSave()
+            }
+            R.id.mark_remove -> {
+                if (listener != null) listener?.onRemove()
+            }
+            R.id.mark_delete -> {
+                if (listener != null) listener?.onDelete()
+            }
+        }
+    }
+
+    /**
+     * 开关事件
+     * @param view CompoundButton
+     * @param isChecked Boolean
+     */
+    override fun onCheckedChanged(view: CompoundButton?, isChecked: Boolean) {
+        when (view?.id) {
+            R.id.mark_on_draw -> {
+                if (isChecked) {
+                    if (listener != null) {
+                        listener?.onStopSelect()
+                        listener?.onStartDraw()
+                    }
+                    switchSelect?.isChecked = false
+                }else{
+                    if (listener != null) listener?.onStopDraw()
+                }
+
+            }
+            R.id.mark_on_select -> {
+                if (isChecked) {
+                    if (listener != null) {
+                        listener?.onStopDraw()
+                        listener?.onSelect()
+                    }
+                    switchDraw?.isChecked = false
+                } else{
+                    if (listener != null) listener?.onStopSelect()
+                }
+            }
+        }
+    }
+
+    /**
+     * 重写页面初始化
+     */
+    override fun initPage() {
+        switchDraw?.isChecked = false
+        switchSelect?.isChecked = false
+        // todo: 2023/4/18 符号初始化
+        markChange?.markName = "红色箭头"
+        markChange?.markDrawable = R.drawable.ico_draw_red
+        markChange?.markAngle = 50
+        // todo: 2023/4/18 角度初始化
+        for(angle in 1 until 36){
+            mAngleItems.add(angle*10)
+        }
+        wheelAngle?.adapter = ArrayWheelAdapter(mAngleItems)
+        // todo: 2023/4/18 初始化角度选择
+        wheelAngle?.setSelectItem(markChange?.markAngle)
+        // todo: 2023/4/18 符号样式初始化
+        mTypeItems.add(EventMarkChange("红色箭头",R.drawable.ico_draw_red))
+        mTypeItems.add(EventMarkChange("绿色箭头",R.drawable.ico_draw_green))
+        mTypeItems.add(EventMarkChange("蓝色箭头",R.drawable.ico_draw_blue))
+        mTypeItems.add(EventMarkChange("通用标志",R.drawable.ico_ty))
+        var typeItems:MutableList<String> = mutableListOf()
+        for(item in mTypeItems){
+            typeItems.add(item.markName)
+        }
+        wheelType?.adapter = ArrayWheelAdapter(typeItems)
+        wheelType?.setSelectItem(markChange?.markName)
+    }
+
+    /**
+     * 角度选择监听器
+     */
+    private val angleListener = OnItemSelectedListener { index ->
+        var angle = mAngleItems[index]
+        markChange?.markAngle = angle
+        setMark()
+    }
+
+    /**
+     * 类型选择监听器
+     */
+    private val typeListener = OnItemSelectedListener { index ->
+        var item = mTypeItems[index]
+        markChange?.markName = item.markName
+        markChange?.markDrawable = item.markDrawable
+        setMark()
+    }
+
+    /**
+     * 设置符号
+     */
+    private fun setMark(){
+        // todo: 2023/4/18 设置符号
+        imageView?.setImageDrawable(context!!.getDrawable(markChange!!.markDrawable))
+        // todo: 2023/4/18 设置角度
+        setAngle(markChange!!.markAngle)
+    }
+
+    /**
+     * 设置角度
+     * @param angle Int
+     */
+    private fun setAngle(angle:Int){
+        imageView?.pivotX = (imgWidth/2).toFloat()
+        imageView?.pivotY = (imgHeight/2).toFloat()
+        imageView?.rotation = angle.toFloat()
+    }
+
+    /**
+     * 设置操作监听
+     * @param listener OnOperationListener 操作监听
+     */
+    fun setListener(listener: OnOperationListener) {
+        this.listener = listener
+    }
+
+    /**
+     * 获取当前符号
+     * @return EventMarkChange?
+     */
+    fun getMark():EventMarkChange?{
+        return markChange
+    }
+
+    /**
+     * 订阅事件执行
+     * @param event EventAction
+     */
+    @Subscribe
+    fun onAction(event:EventMarkAction){
+        when(event.action){
+            EventMarkAction.CLOSE_DRAW->{
+                switchDraw?.isChecked = false
+            }
+            EventMarkAction.CLOSE_SELECT->{
+                switchSelect?.isChecked = false
+            }
+        }
+    }
+
+    // todo: 2023/4/17 生命周期
+    /**
+     * 销毁
+     */
+    override fun onDestroy() {
+        // todo: 2023/4/17 解除订阅监听
+        CrApplication.getEventBus().unregister(this)
+        super.onDestroy()
+    }
+
+    /**
+     * 显示隐藏监听
+     * @param hidden Boolean
+     */
+    override fun onHiddenChanged(hidden: Boolean) {
+       if(!hidden){
+           //setMark()
+       }
+    }
+
+    // todo: 2023/4/17 订阅事件类
+    class EventMarkAction@JvmOverloads constructor(
+        action:Int
+    ){
+        // define: 2023/4/17 定义动作常量
+        companion object{
+            const val CLOSE_DRAW:Int = 0
+            const val CLOSE_SELECT:Int = 1
+        }
+        // define: 2023/4/17 定义动作
+        var action:Int = -1
+
+        /**
+         * 初始化
+         */
+        init {
+            this.action = action
+        }
+    }
+}

+ 135 - 0
app/src/main/java/com/cr/pages/FragmentTools.kt

@@ -0,0 +1,135 @@
+package com.cr.pages
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import com.cr.cruav.CrApplication
+import com.cr.cruav.R
+import com.cr.event.BarAction
+import com.cr.event.EventFragmentBarAction
+import com.cr.widget.CrButton
+
+/**
+ * 操作系统:MAC系统
+ * 创建者:王成
+ * 创建日期:2023/4/21 10:08
+ * 描述:工具箱页面
+ */
+class FragmentTools:CrNavigationFragment() ,CrButton.OnClickListener{
+    /**
+     * 监听接口
+     */
+    interface OnOperationListener{
+        // todo: 2023/4/21 测量长度
+        fun onMeasureLength()
+
+        // todo: 2023/4/21 测量面积
+        fun onMeasureArea()
+
+        // todo: 2023/4/21 清除测量内容
+        fun onMeasureClear()
+
+        // todo: 2023/4/21 获取经纬度位置
+        fun onGetLocation()
+
+        // todo: 2023/4/21 定位到地图
+        fun onToLocation()
+    }
+    // todo: 2023/4/21 控件定义
+    private var btnMeasureLength:CrButton? = null // define: 2023/4/21 长度测量按钮
+    private var btnMeasureArea:CrButton? = null // define: 2023/4/21 面积测量按钮
+    private var btnMeasureClear:CrButton? = null // define: 2023/4/21 清除测量内容按钮
+    private var btnGetLocation:CrButton? = null // define: 2023/4/21 获取经纬度按钮
+    private var btnToLocation:CrButton? = null // define: 2023/4/21 经纬度定位按钮
+
+    // todo: 2023/4/21 定义监听 自行实现
+    private var listener:OnOperationListener? = null
+
+    /**
+     * 创建页面
+     * @param inflater LayoutInflater
+     * @param container ViewGroup?
+     * @param savedInstanceState Bundle?
+     * @return View?
+     */
+    override fun onCreateView(
+        inflater: LayoutInflater,
+        container: ViewGroup?,
+        savedInstanceState: Bundle?
+    ): View? {
+        self = this
+        mainView = inflater.inflate(R.layout.frag_tools,null)
+        // todo: 2023/4/21 设置导航栏
+        setBar(R.id.nv)
+        // todo: 2023/4/21 设置展现方式
+        setAnimationDirection(AnimationDirection.LEFT)
+        // todo: 2023/4/21 挂载控件
+        initControls()
+        // todo: 2023/4/21 返回
+        return mainView
+    }
+
+    /**
+     * 重写挂载控件
+     */
+    override fun initControls() {
+        // todo: 2023/4/21 挂载控件
+        btnMeasureLength = mainView?.findViewById(R.id.tools_measure_length)
+        btnMeasureArea = mainView?.findViewById(R.id.tools_measure_area)
+        btnMeasureClear = mainView?.findViewById(R.id.tools_measure_clear)
+        btnGetLocation = mainView?.findViewById(R.id.tools_get_location)
+        btnToLocation = mainView?.findViewById(R.id.tools_to_location)
+
+        // todo: 2023/4/21 设置监听
+        btnMeasureLength?.setListener(this)
+        btnMeasureArea?.setListener(this)
+        btnMeasureClear?.setListener(this)
+        btnGetLocation?.setListener(this)
+        btnToLocation?.setListener(this)
+    }
+
+    /**
+     * 关闭页面
+     */
+    override fun dismiss() {
+        CrApplication.getEventBus().post(EventFragmentBarAction(self!!, BarAction.ACTION_DISMISS))
+    }
+
+    /**
+     * 视图点击事件
+     * @param view View
+     */
+    override fun onClick(view: View) {
+        when(view?.id){
+            // todo: 2023/4/21 长度测量
+            R.id.tools_measure_length->{
+                if(listener != null) listener?.onMeasureLength()
+            }
+            // todo: 2023/4/21 面积测量
+            R.id.tools_measure_area->{
+                if(listener != null) listener?.onMeasureArea()
+            }
+            // todo: 2023/4/21 清除测量内容
+            R.id.tools_measure_clear->{
+                if(listener != null) listener?.onMeasureClear()
+            }
+            // todo: 2023/4/21 获取地图位置
+            R.id.tools_get_location->{
+                if(listener != null) listener?.onGetLocation()
+            }
+            // todo: 2023/4/21 地图定位
+            R.id.tools_to_location->{
+                if(listener != null) listener?.onToLocation()
+            }
+        }
+    }
+
+    /**
+     * 设置监听
+     * @param listener OnOperationListener
+     */
+    fun setListener(listener: OnOperationListener){
+        this.listener = listener
+    }
+}

+ 1 - 1
app/src/main/java/com/cr/pages/FragmentTopInfo.kt

@@ -91,7 +91,7 @@ open class FragmentTopInfo : Fragment() {
     override fun onResume() {
         super.onResume()
         // todo: 2023/3/9 初始化订阅
-        initObserver()
+//        initObserver()
     }
 
     /**

+ 9 - 0
app/src/main/java/com/cr/view/CrViewWheel.kt

@@ -30,4 +30,13 @@ class CrViewWheel@JvmOverloads constructor(
         }
         return super.onTouchEvent(event);
     }
+
+    fun setSelectItem(item:Any?){
+        for(index in 0 until this.adapter.itemsCount){
+            if(this.adapter.getItem(index).equals(item)){
+                this.currentItem = index
+                break;
+            }
+        }
+    }
 }

+ 1 - 1
app/src/main/java/com/cr/viewmodel/CrFlightControlVM.kt

@@ -31,7 +31,7 @@ class CrFlightControlVM : CrViewModel() {
      * 初始化
      */
     init {
-        flightControlInfo.value = CrFlightControlInfo()
+        flightControlInfo.postValue(CrFlightControlInfo())
         flightControlInfo.value?.batteryPercent = 0
         flightControlInfo.value?.gpsCount = DEFAULT_STR
         flightControlInfo.value?.productName = DEFAULT_STR

+ 175 - 0
app/src/main/res/layout/frag_mark.xml

@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@drawable/shape_back_fragment"
+        android:orientation="vertical">
+
+        <com.cr.widget.CrNavigationBarWidget
+            android:id="@+id/nv"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="0"
+            app:crTitle="@string/nv_title_ico"
+            app:isDismiss="true"
+            app:isGotoBack="false" />
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
+            <!--左侧部分-->
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:orientation="vertical"
+                android:layout_weight="1">
+                <ScrollView
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent">
+                    <LinearLayout
+                        android:layout_width="match_parent"
+                        android:layout_height="match_parent"
+                        android:orientation="vertical">
+                        <LinearLayout style="@style/view_tools_line_row">
+
+                            <TextView
+                                style="@style/view_tools_line_row_title"
+                                android:layout_width="match_parent"
+                                android:layout_weight="1"
+                                android:text="@string/frag_mark_title_on_draw" />
+
+                            <Switch
+                                android:id="@+id/mark_on_draw"
+                                style="@style/item_layer_padding"
+                                android:thumb="@drawable/switch_thumb"
+                                android:track="@drawable/switch_track" />
+                        </LinearLayout>
+
+                        <View style="@style/view_split_h2" />
+
+                        <com.cr.widget.CrButton
+                            android:id="@+id/mark_clear"
+                            style="@style/view_tools_line_row_button"
+                            app:crLeftResource="@string/ico_clear"
+                            app:crTitle="@string/frag_mark_title_clear" />
+
+                        <View style="@style/view_split_h2" />
+
+                        <com.cr.widget.CrButton
+                            android:id="@+id/mark_save"
+                            style="@style/view_tools_line_row_button"
+                            app:crLeftResource="@string/ico_save"
+                            app:crTitle="@string/frag_mark_title_save" />
+
+                        <View style="@style/view_split_h2" />
+
+                        <com.cr.widget.CrButton
+                            android:id="@+id/mark_remove"
+                            style="@style/view_tools_line_row_button"
+                            app:crLeftResource="@string/ico_remove"
+                            app:crTitle="@string/frag_mark_title_remove" />
+
+                        <View style="@style/view_split_h2" />
+
+                        <LinearLayout
+                            style="@style/view_tools_line_row"
+                            android:layout_width="match_parent">
+
+                            <TextView
+                                style="@style/view_tools_line_row_title"
+                                android:text="@string/frag_mark_title_on_select" />
+
+                            <Switch
+                                android:id="@+id/mark_on_select"
+                                style="@style/item_layer_padding"
+                                android:thumb="@drawable/switch_thumb"
+                                android:track="@drawable/switch_track" />
+                        </LinearLayout>
+
+                        <View style="@style/view_split_h2" />
+
+                        <com.cr.widget.CrButton
+                            android:id="@+id/mark_delete"
+                            style="@style/view_tools_line_row_button"
+                            app:crLeftResource="@string/ico_delete"
+                            app:crTitle="@string/frag_mark_title_on_delete" />
+                    </LinearLayout>
+                </ScrollView>
+            </LinearLayout>
+            <View style="@style/view_split_v1"/>
+            <!--右侧部分-->
+            <LinearLayout
+                android:layout_width="@dimen/cr_80_dp"
+                android:layout_height="match_parent"
+                android:orientation="vertical">
+                <ScrollView
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent">
+                    <LinearLayout
+                        android:layout_width="match_parent"
+                        android:layout_height="match_parent"
+                        android:orientation="vertical">
+                        <LinearLayout
+                            style="@style/view_tools_line_row"
+                            android:layout_width="match_parent">
+
+                            <TextView
+                                style="@style/view_tools_line_row_title"
+                                android:text="@string/frag_mark_title_image"
+                                android:textColor="@color/white"/>
+                        </LinearLayout>
+
+                        <ImageView
+                            android:id="@+id/mark_ico"
+                            android:layout_width="@dimen/cr_40_dp"
+                            android:layout_height="@dimen/cr_40_dp"
+                            android:scaleType="fitCenter"
+                            android:src="@drawable/ico_draw_red"
+                            android:layout_gravity="center"
+                            android:layout_marginTop="@dimen/cr_10_dp"
+                            android:layout_marginBottom="@dimen/cr_10_dp"/>
+
+                        <View style="@style/view_split_h2" />
+
+                        <LinearLayout
+                            style="@style/view_tools_line_row"
+                            android:layout_width="match_parent">
+
+                            <TextView
+                                style="@style/view_tools_line_row_title"
+                                android:text="@string/frag_mark_title_rotate"
+                                android:textColor="@color/white"/>
+                        </LinearLayout>
+
+                        <com.cr.view.CrViewWheel
+                            android:id="@+id/mark_angle"
+                            android:layout_width="match_parent"
+                            android:layout_height="@dimen/cr_40_dp" />
+
+                        <View style="@style/view_split_h2" />
+
+                        <LinearLayout
+                            style="@style/view_tools_line_row"
+                            android:layout_width="match_parent">
+
+                            <TextView
+                                style="@style/view_tools_line_row_title"
+                                android:text="@string/frag_mark_title_type"
+                                android:textColor="@color/white"/>
+                        </LinearLayout>
+
+                        <com.cr.view.CrViewWheel
+                            android:id="@+id/mark_type"
+                            android:layout_width="match_parent"
+                            android:layout_height="@dimen/cr_40_dp" />
+                    </LinearLayout>
+                </ScrollView>
+            </LinearLayout>
+        </LinearLayout>
+    </LinearLayout>
+</LinearLayout>

+ 45 - 0
app/src/main/res/layout/frag_tools.xml

@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@drawable/shape_back_fragment">
+    <com.cr.widget.CrNavigationBarWidget
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:crTitle="@string/nv_title_tools"
+        app:isGotoBack="false"
+        app:isDismiss="true"
+        android:id="@+id/nv"
+        android:layout_weight="0"/>
+    <com.cr.widget.CrButton
+        style="@style/view_tools_line_row_button"
+        app:crTitle="@string/frag_tools_measure_length"
+        app:crLeftResource = "@string/ico_clear"
+        android:id="@+id/tools_measure_length"/>
+    <View style="@style/view_split_h2"/>
+    <com.cr.widget.CrButton
+        style="@style/view_tools_line_row_button"
+        app:crTitle="@string/frag_tools_measure_area"
+        app:crLeftResource = "@string/ico_save"
+        android:id="@+id/tools_measure_area"/>
+    <View style="@style/view_split_h2"/>
+    <com.cr.widget.CrButton
+        style="@style/view_tools_line_row_button"
+        app:crTitle="@string/frag_tools_measure_clear"
+        app:crLeftResource = "@string/ico_remove"
+        android:id="@+id/tools_measure_clear"/>
+    <View style="@style/view_split_h2"/>
+    <com.cr.widget.CrButton
+        style="@style/view_tools_line_row_button"
+        app:crTitle="@string/frag_tools_get_location"
+        app:crLeftResource = "@string/ico_remove"
+        android:id="@+id/tools_get_location"/>
+    <View style="@style/view_split_h2"/>
+    <com.cr.widget.CrButton
+        style="@style/view_tools_line_row_button"
+        app:crTitle="@string/frag_tools_to_location"
+        app:crLeftResource = "@string/ico_remove"
+        android:id="@+id/tools_to_location"/>
+</LinearLayout>

+ 1 - 1
app/src/main/res/layout/tools_top.xml

@@ -26,7 +26,7 @@
     </LinearLayout>
     <LinearLayout
         style="@style/tools_top_panel"
-        android:id="@+id/tools_ico">
+        android:id="@+id/tools_mark">
         <ImageView
             style="@style/tools_image"
             android:src="@drawable/tools_startico"/>

+ 1 - 1
app/src/main/res/values/attr.xml

@@ -19,6 +19,6 @@
         <!--文本颜色-->
         <attr name="crTextColor" format="color"/>
         <!--背景-->
-        <attr name="crClickGround" format="reference"/>
+<!--        <attr name="crClickGround" format="reference"/>-->
     </declare-styleable>
 </resources>

+ 19 - 0
app/src/main/res/values/strings.xml

@@ -76,6 +76,7 @@
     <string name="nv_title_download">数据下载</string>
     <string name="nv_title_ty">涂鸦</string>
     <string name="nv_title_ico">标志</string>
+    <string name="nv_title_tools">工具箱</string>
     <string name="nv_title_case_tools">图斑编辑</string>
     <string name="nv_title_upload_main">违建点信息编辑、分享及上传</string>
     <string name="nv_title_image_editor">图片编辑</string>
@@ -96,6 +97,24 @@
     <string name="frag_doodle_title_on_select">选择涂鸦</string>
     <string name="frag_doodle_title_on_delete">删除涂鸦</string>
 
+    <!--标志页面相关-->
+    <string name="frag_mark_title_rotate">旋转角度</string>
+    <string name="frag_mark_title_type">图片类型</string>
+    <string name="frag_mark_title_image">标志图片</string>
+    <string name="frag_mark_title_on_draw">开启绘制</string>
+    <string name="frag_mark_title_clear">清除标志</string>
+    <string name="frag_mark_title_save">保存标志</string>
+    <string name="frag_mark_title_remove">全部删除</string>
+    <string name="frag_mark_title_on_select">选择标志</string>
+    <string name="frag_mark_title_on_delete">删除标志</string>
+
+    <!--工具箱页面相关-->
+    <string name="frag_tools_measure_length">长度测量</string>
+    <string name="frag_tools_measure_area">面积测量</string>
+    <string name="frag_tools_measure_clear">清除测量内容</string>
+    <string name="frag_tools_get_location">获取经纬度</string>
+    <string name="frag_tools_to_location">经纬度定位</string>
+
     <!--字体-->
     <string name="ico_nv_left" translatable="false">&#xe60b;</string>
     <string name="ico_nv_right" translatable="false">&#xe81a;</string>