Просмотр исходного кода

照片编辑功能完成,包括照片的编辑的重绘、回退、保存、恢复(包含数据库逻辑)

不会爬树的猴 1 год назад
Родитель
Сommit
09f8e05b46

+ 3 - 0
app/src/main/java/com/cr/adapter/LayerAdapter.kt

@@ -9,6 +9,7 @@ import android.widget.ImageView
 import android.widget.Switch
 import android.widget.TextView
 import com.cr.cruav.R
+import com.cr.map.LayerManager
 import com.cr.map.LayerModel
 import com.cr.map.LayerType
 import com.esri.arcgisruntime.layers.ArcGISMapImageSublayer
@@ -134,6 +135,8 @@ class LayerAdapter@JvmOverloads constructor(
                 sLayer.isVisible = layerModel.isVisible
             }
         }
+        // todo: 2023/9/27 存储图层可见状态
+        LayerManager.getInstance().saveLayerVisible(layerModel.name!!,layerModel.isVisible)
     }
 
     /**

+ 30 - 0
app/src/main/java/com/cr/common/CrFileManager.kt

@@ -82,6 +82,36 @@ class CrFileManager {
         }
 
         /**
+         * 获取没有扩展名的文件名称
+         * @param fileAllPath String 文件全路径
+         * @return String? 不含扩展名的文件名
+         */
+        fun getFileNoExtensionName(fileAllPath:String):String?{
+            val start = fileAllPath.lastIndexOf("/")
+            val end = fileAllPath.lastIndexOf(".")
+            return if (start != -1 && end != -1) {
+                fileAllPath.substring(start + 1, end)
+            } else {
+                null
+            }
+        }
+
+        /**
+         * 获取路径文件的括展名
+         * @param fileAllPath String 文件全路径
+         * @return String? 扩展名
+         */
+        fun getExtensionName(fileAllPath: String):String?{
+            val start = fileAllPath.lastIndexOf(".")
+            val end = fileAllPath.length
+            return if (start != -1 && end != -1) {
+                fileAllPath.substring(start + 1, end)
+            } else {
+                null
+            }
+        }
+
+        /**
          * 截取文件的路径
          * @param fileAllPath 文件全路径
          * @return 文件路径不含文件名及扩展名

+ 41 - 0
app/src/main/java/com/cr/common/CrSaveManager.kt

@@ -42,6 +42,7 @@ class CrSaveManager {
         var self = CrSaveManager()
     }
 
+
     /**
      * 获取地图是否自动居中
      * @return Boolean
@@ -51,6 +52,46 @@ class CrSaveManager {
     }
 
     /**
+     * 保存boolean类型key
+     * @param key String
+     * @param value Boolean
+     */
+    fun saveBooleanKey(key:String,value:Boolean){
+        var editor:SharedPreferences.Editor = preferences!!.edit();
+        editor.putBoolean(key,value);
+        editor.commit()
+    }
+
+    /**
+     * 获取boolean类型key
+     * @param key String
+     * @return Boolean
+     */
+    fun getBooleanKey(key:String):Boolean{
+        return preferences!!.getBoolean(key,false)
+    }
+
+    /**
+     * 保存string类型key
+     * @param key String
+     * @param value Boolean
+     */
+    fun saveStringKey(key:String,value:String){
+        var editor:SharedPreferences.Editor = preferences!!.edit();
+        editor.putString(key,value);
+        editor.commit()
+    }
+
+    /**
+     * 获取string类型key
+     * @param key String
+     * @return Boolean
+     */
+    fun getStringKey(key:String):String?{
+        return preferences!!.getString(key,null)
+    }
+
+    /**
      * 设置地图是否自动居中
      * @param isCenter Boolean
      */

+ 73 - 2
app/src/main/java/com/cr/common/DataManager.kt

@@ -1,5 +1,6 @@
 package com.cr.common
 
+import com.cr.data.CrUtil
 import com.cr.map.CaseModel
 import com.cr.map.LayerConfigModel
 import com.cr.map.LayerModel
@@ -15,6 +16,8 @@ class DataManager {
     // todo: 2023/4/3 静态方法及属性封装
     companion object {
         private const val TABLE_AIR_LINE: String = "AIRLINE"  // define: 2023/9/19 航线表
+        private const val TABLE_IMAGE_EDIT:String = "INAGEEDIT"  // define: 2023/9/28 照片编辑表
+        private const val TABLE_WAY_IMAGES:String = "WAYIMAGES"  // define: 2023/9/28 照片存储表
 
         /**
          * 获取网络服务连接信息
@@ -184,9 +187,9 @@ class DataManager {
         /**
          * 添加案件点照片
          * @param model CaseModel 案件点模型
-         * @param callback iCompletion 完成回调
+         * @param callback iCompletion? 完成回调
          */
-        fun appAppendImages(model: CaseModel, callback: ICompletion<String>) {
+        fun appAppendImages(model: CaseModel, callback: ICompletion<String>?) {
             // todo: 2023/6/19 先查询是否已经存在
             var SQL = String.format(
                 "select * from WAYIMAGES where wayid='%s' and imgname='%s'",
@@ -216,6 +219,34 @@ class DataManager {
         }
 
         /**
+         * 替换照片名称
+         * @param caseId String 案件Id
+         * @param oldName String 旧名称
+         * @param newName String 新名称
+         * @param callback ICompletion<String> 回调
+         */
+        fun replaceImageName(caseId:String, oldName:String, newName: String, callback: ICompletion<String>){
+            CrUtil.print("caseId = $caseId 名称=$oldName")
+            // todo: 2023/9/28 先查询是否存在
+            val strWhere = String.format("wayid = '%s' and (imgname = '%s' or imgname='%s')",caseId,oldName,newName)
+            val sql = String.format("select * from %s where %s", TABLE_WAY_IMAGES,strWhere)
+            val qList = DatabaseAppUAVManager.getInstance().query(sql)
+            if(qList.isNotEmpty()){
+                // todo: 2023/9/28 更新
+                var valueMap = HashMap<String,String>()
+                valueMap["imgname"] = newName
+                val isOk = DatabaseAppUAVManager.getInstance().update(TABLE_WAY_IMAGES,valueMap,strWhere)
+                if(isOk){
+                    callback.onCompletion(CompletionModel(true,"","更新成功!"))
+                }else{
+                    callback.onCompletion(CompletionModel(false,"","更新失败!"))
+                }
+            }else{
+                callback.onCompletion(CompletionModel(false,"","照片未曾编辑过!"))
+            }
+        }
+
+        /**
          * 根据案件Id查询案件照片的详细信息
          * @param caseId String 案件Id
          * @param callback iCompletion<List<String>> 回调
@@ -421,5 +452,45 @@ class DataManager {
             val sqlWhere = String.format("flag='%s'", userId)
             return DatabaseAppUAVManager.getInstance().delete(TABLE_AIR_LINE,sqlWhere)
         }
+
+        /**
+         * 插入编辑照片数据
+         * @param oldName String 原照片
+         * @param newName String 新照片
+         * @return Boolean 是否成功
+         */
+        fun appendEditImage(oldName:String,newName:String):Boolean{
+            // todo: 2023/9/28 先查询是否存在
+            val strWhere = String.format("oldimage = '%s'",oldName)
+            val sql = String.format("select * from %s where %s", TABLE_IMAGE_EDIT,strWhere)
+            val qlist = DatabaseAppUAVManager.getInstance().query(sql)
+            return if(qlist.isNotEmpty()){
+                // todo: 2023/9/28 需要更新
+                var valueMap = HashMap<String,String>()
+                valueMap["newimage"] = newName
+                DatabaseAppUAVManager.getInstance().update(TABLE_IMAGE_EDIT,valueMap,strWhere)
+            }else{
+                var valueMap = HashMap<String,String>()
+                valueMap["newimage"] = newName
+                valueMap["oldimage"] = oldName
+                DatabaseAppUAVManager.getInstance().insert(TABLE_IMAGE_EDIT,valueMap)
+            }
+        }
+
+        /**
+         * 查询编辑后照片对应的源照片
+         * @param newName String 源照片
+         * @return String? 编辑后的照片名字
+         */
+        fun queryEditImage(newName: String):String?{
+            // todo: 2023/9/28 先查询是否存在
+            val strWhere = String.format("newimage = '%s'",newName)
+            val sql = String.format("select * from %s where %s", TABLE_IMAGE_EDIT,strWhere)
+            val qlist = DatabaseAppUAVManager.getInstance().query(sql)
+            if(qlist.isNotEmpty()){
+                return qlist[0]["oldimage"]
+            }
+            return null
+        }
     }
 }

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

@@ -541,7 +541,7 @@ class AvMain : CrActivity(), View.OnClickListener {
 
     override fun onPause() {
         super.onPause()
-        callExitSystem()
+//        callExitSystem()
     }
 
     /**

+ 39 - 7
app/src/main/java/com/cr/map/LayerManager.kt

@@ -1,5 +1,7 @@
 package com.cr.map
 
+import com.cr.common.CrSaveManager
+
 /**
  * 操作系统:MAC系统
  * 创建者:王成
@@ -62,15 +64,23 @@ class LayerManager {
      * 初始化
      */
     init {
-        mapLayers?.put(LAYER_NAME_DAILY, mutableListOf())
-        mapLayers?.put(LAYER_NAME_BASE, mutableListOf())
-        mapLayers?.put(LAYER_NAME_HISTORY, mutableListOf())
-        mapLayers?.put(LAYER_NAME_DRAW, mutableListOf())
-        mapLayers?.put(LAYER_NAME_AIR, mutableListOf())
+        mapLayers[LAYER_NAME_DAILY] = mutableListOf()
+        mapLayers[LAYER_NAME_BASE] = mutableListOf()
+        mapLayers[LAYER_NAME_HISTORY] = mutableListOf()
+        mapLayers[LAYER_NAME_DRAW] = mutableListOf()
+        mapLayers[LAYER_NAME_AIR] = mutableListOf()
     }
 
-    // todo: 2023/4/13 添加图层
-    fun addLayer(layer:LayerModel,group:LayerGroup){
+    /**
+     * 添加图层
+     * @param layer LayerModel 图层模型
+     * @param group LayerGroup 图层所属组
+     * @return Boolean 默认是否可见
+     */
+    fun addLayer(layer:LayerModel,group:LayerGroup):Boolean{
+        // todo: 2023/9/27 获取图层可见性
+        val isVisible = getLayerVisible(layer.name!!,layer.isVisible)
+        layer.isVisible = isVisible
         when(group){
             LayerGroup.LAYER_NAME_BASE->
                 mapLayers[LAYER_NAME_BASE]?.add(layer)
@@ -83,6 +93,8 @@ class LayerManager {
             LayerGroup.LAYER_NAME_AIR->
                 mapLayers[LAYER_NAME_AIR]?.add(layer)
         }
+        // todo: 2023/9/27 添加图层模型的同时返回图层当前可见性
+        return isVisible
     }
 
     /**
@@ -104,4 +116,24 @@ class LayerManager {
         }
         return resList
     }
+
+    /**
+     * 存储图层可见性
+     * @param layerName String
+     * @param isVisible Boolean
+     */
+    fun saveLayerVisible(layerName:String,isVisible:Boolean){
+        // todo: 2023/9/27 可见存储1 不可见存储0
+        CrSaveManager.getInstance().saveStringKey(layerName,if(isVisible) "1" else "0")
+    }
+
+    /**
+     * 获取图层可见性
+     * @param layerName String
+     * @return Boolean
+     */
+    fun getLayerVisible(layerName: String,isVisible: Boolean):Boolean{
+        val resVisible = CrSaveManager.getInstance().getStringKey(layerName)
+        return resVisible?.equals("1") ?: isVisible
+    }
 }

+ 5 - 0
app/src/main/java/com/cr/map/MapAction.kt

@@ -181,4 +181,9 @@ enum class MapAction {
      * 输入定位位置到地图
      */
     EventInputLocationToMap,
+
+    /**
+     * 案件上传成功
+     */
+    EventCaseUploadSuccess,
 }

+ 57 - 21
app/src/main/java/com/cr/pages/FragmentImageEditor.kt

@@ -1,7 +1,5 @@
 package com.cr.pages
 
-import android.graphics.BitmapFactory
-import android.os.Build
 import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
@@ -9,12 +7,12 @@ import android.view.ViewGroup
 import android.widget.LinearLayout
 import android.widget.SeekBar
 import android.widget.TextView
-import androidx.annotation.RequiresApi
+import com.cr.common.CrColorManager
+import com.cr.common.CrFileManager
+import com.cr.common.DataManager
 import com.cr.cruav.R
+import com.cr.data.CrUtil
 import com.cr.view.CrImageEditor
-import kotlinx.android.synthetic.main.frag_image_editor.*
-import java.io.File
-import java.io.FileInputStream
 
 /**
  * 操作系统:MAC系统
@@ -23,6 +21,16 @@ import java.io.FileInputStream
  * 描述:图片编辑页面
  */
 class FragmentImageEditor : CrNavigationFragment(), View.OnClickListener {
+    /**
+     * 对外接口
+     */
+    interface IChangeListener{
+        // todo: 2023/9/28 保存照片
+        fun onSave(oldName:String,newName:String)
+
+        // todo: 2023/9/28 恢复
+        fun onRecover(oldName:String,newName:String)
+    }
     // define: 2023/6/20 图片编辑器
     private var imageEditor: CrImageEditor? = null
 
@@ -46,6 +54,9 @@ class FragmentImageEditor : CrNavigationFragment(), View.OnClickListener {
     // define: 2023/6/20 图片路径
     private var imagePath: String? = null
 
+    // todo: 2023/9/28 监听
+    private var listener:IChangeListener?= null // define: 2023/9/28 监听
+
     /**
      * 初始化
      * @param inflater LayoutInflater
@@ -114,9 +125,11 @@ class FragmentImageEditor : CrNavigationFragment(), View.OnClickListener {
             imageEditor?.crSetLineWidth(p1.toFloat())
         }
 
+        // todo: 2023/9/28 开始变化
         override fun onStartTrackingTouch(p0: SeekBar?) {
         }
 
+        // todo: 2023/9/28 停止变化
         override fun onStopTrackingTouch(p0: SeekBar?) {
         }
 
@@ -129,31 +142,51 @@ class FragmentImageEditor : CrNavigationFragment(), View.OnClickListener {
     override fun onClick(view: View?) {
         when (view?.id) {
             R.id.btn_line_color1 -> {
-                imageEditor?.crSetLineColor(self?.context!!.getColor(R.color.line_1))
+                imageEditor?.crSetLineColor(CrColorManager.getColor(R.color.line_1))
             }
             R.id.btn_line_color2 -> {
-                imageEditor?.crSetLineColor(self?.context!!.getColor(R.color.line_2))
+                imageEditor?.crSetLineColor(CrColorManager.getColor(R.color.line_2))
             }
             R.id.btn_line_color3 -> {
-                imageEditor?.crSetLineColor(self?.context!!.getColor(R.color.line_3))
+                imageEditor?.crSetLineColor(CrColorManager.getColor(R.color.line_3))
             }
             R.id.btn_line_color4 -> {
-                imageEditor?.crSetLineColor(self?.context!!.getColor(R.color.line_4))
+                imageEditor?.crSetLineColor(CrColorManager.getColor(R.color.line_4))
             }
             R.id.btn_line_color5 -> {
-                imageEditor?.crSetLineColor(self?.context!!.getColor(R.color.line_5))
+                imageEditor?.crSetLineColor(CrColorManager.getColor(R.color.line_5))
             }
             R.id.btn_back -> {
-
+                // todo: 2023/9/28 回退一步
+                imageEditor?.crSetUndo()
             }
             R.id.btn_reset -> {
-
+                // todo: 2023/9/28 重绘
+                imageEditor?.crReset()
             }
             R.id.btn_save -> {
-
+                // todo: 2023/9/28 保存文件
+                var fileName = imageEditor?.crSaveImage()
+                if(fileName != null){
+                    // todo: 2023/9/28 反馈
+                    val oldName = CrFileManager.getFileName(this.imagePath!!)
+                    this.listener?.onSave(oldName!!,fileName)
+                }else{
+                    showError("保存失败")
+                }
             }
             R.id.btn_recover -> {
-
+                // todo: 2023/9/28 找到原来的照片
+                val imgName = CrFileManager.getFileName(this.imagePath!!)
+                val oldName = DataManager.queryEditImage(imgName!!)
+                if(oldName == null){
+                    showError("文件已不存在,无法恢复!")
+                }else{
+                    this.imagePath = String.format("%s%s",CrUtil.IMAGE_PATH,oldName)
+                    // todo: 2023/9/28 反馈
+                    this.listener?.onRecover(oldName!!,imgName)
+                }
+                crSetImage(this.imagePath!!)
             }
         }
     }
@@ -163,12 +196,7 @@ class FragmentImageEditor : CrNavigationFragment(), View.OnClickListener {
      */
     private fun showImage() {
         imagePath?.let {
-            var file = File(it)
-            if (file.exists()) {
-                var fis = FileInputStream(it)
-                var bitmap = BitmapFactory.decodeStream(fis)
-                imageEditor?.setImageBitmap(bitmap!!)
-            }
+            imageEditor?.crSetBitmap(it)
         }
     }
 
@@ -181,4 +209,12 @@ class FragmentImageEditor : CrNavigationFragment(), View.OnClickListener {
         // todo: 2023/6/20 显示图片
         showImage()
     }
+
+    /**
+     * 设置监听
+     * @param listener IChangeListener 监听
+     */
+    fun crSetChangeListener(listener:IChangeListener){
+        this.listener = listener
+    }
 }

+ 114 - 34
app/src/main/java/com/cr/pages/FragmentMap.kt

@@ -415,10 +415,8 @@ class FragmentMap : CrAnimationFragment() {
         for (model in tileLayers) {
             var layer = ArcGISTiledLayer(model.url)
             layer.name = model.name
-            layer.isVisible = model.isVisible
-            mMap?.operationalLayers?.add(layer)
-            // todo: 2023/4/13 添加到配置
-            LayerManager.getInstance().addLayer(
+            // todo: 2023/4/13 添加到配置 同时获取可见性
+            val isVisible = LayerManager.getInstance().addLayer(
                 LayerModel(
                     model.name!!,
                     model.isVisible,
@@ -426,6 +424,8 @@ class FragmentMap : CrAnimationFragment() {
                     layer
                 ), LayerManager.LayerGroup.LAYER_NAME_DAILY
             )
+            layer.isVisible = isVisible
+            mMap?.operationalLayers?.add(layer)
         }
     }
 
@@ -443,10 +443,8 @@ class FragmentMap : CrAnimationFragment() {
                 var table = tables[vLayer.lyrIdx]
                 var layer = FeatureLayer(table)
                 layer.name = vLayer.lyrName
-                layer.isVisible = vLayer.isVisible
-                mMap?.operationalLayers?.add(layer)
-                // todo: 2023/4/13 添加到配置信息
-                LayerManager.getInstance().addLayer(
+                // todo: 2023/4/13 添加到配置信息 同时获取可见性
+                val isVisible = LayerManager.getInstance().addLayer(
                     LayerModel(
                         vLayer.lyrName,
                         vLayer.isVisible,
@@ -454,6 +452,8 @@ class FragmentMap : CrAnimationFragment() {
                         layer
                     ), LayerManager.LayerGroup.LAYER_NAME_BASE
                 )
+                layer.isVisible = isVisible
+                mMap?.operationalLayers?.add(layer)
             }
         })
         // todo: 2023/4/13 加载数据集
@@ -472,57 +472,61 @@ class FragmentMap : CrAnimationFragment() {
             fTableMark = geoDatabase.getGeodatabaseFeatureTable("ico84")
             fLayerMark = FeatureLayer(fTableMark)
             fLayerMark!!.name = LAYER_NAME_ICO
-            fLayerMark!!.isVisible = true
-            mMap!!.operationalLayers.add(fLayerMark)
-            LayerManager.getInstance().addLayer(
+            // todo: 2023/9/27 添加图层配置并获取默认可见性
+            val isVisibleMark = LayerManager.getInstance().addLayer(
                 LayerModel(
                     fLayerMark!!.name,
-                    fLayerMark!!.isVisible, LayerType.LAYER_TYPE_FEATURE_EDIT, fLayerMark!!
+                    true, LayerType.LAYER_TYPE_FEATURE_EDIT, fLayerMark!!
                 ), LayerManager.LayerGroup.LAYER_NAME_DAILY
             )
+            fLayerMark!!.isVisible = isVisibleMark
+            mMap!!.operationalLayers.add(fLayerMark)
             // todo: 2023/4/14  初始化涂鸦图层
             fTableDoodle = geoDatabase.getGeodatabaseFeatureTable("ty84")
             fLayerDoodle = FeatureLayer(fTableDoodle)
             fLayerDoodle!!.name = LAYER_NAME_DOODLE
-            fLayerDoodle!!.isVisible = true
-            mMap!!.operationalLayers.add(fLayerDoodle)
-            LayerManager.getInstance().addLayer(
+            // todo: 2023/9/27 添加图层配置 并获取默认可见性
+            val isVisibleDoodle = LayerManager.getInstance().addLayer(
                 LayerModel(
                     fLayerDoodle!!.name,
-                    fLayerDoodle!!.isVisible, LayerType.LAYER_TYPE_FEATURE_EDIT, fLayerDoodle!!
+                    true, LayerType.LAYER_TYPE_FEATURE_EDIT, fLayerDoodle!!
                 ), LayerManager.LayerGroup.LAYER_NAME_DAILY
             )
+            fLayerDoodle!!.isVisible = isVisibleDoodle
+            mMap!!.operationalLayers.add(fLayerDoodle)
             // todo: 2023/4/14  初始化媒体点图层
             fTableMedia = geoDatabase.getGeodatabaseFeatureTable("media84")
             fLayerMedia = FeatureLayer(fTableMedia)
             fLayerMedia!!.name = LAYER_NAME_MEDIA
-            fLayerMedia!!.isVisible = true
-            mMap!!.operationalLayers.add(fLayerMedia)
-            LayerManager.getInstance().addLayer(
+            // todo: 2023/9/27 添加图层配置 并获取默认可见性
+            val isVisibleMedia = LayerManager.getInstance().addLayer(
                 LayerModel(
                     fLayerMedia!!.name,
-                    fLayerMedia!!.isVisible, LayerType.LAYER_TYPE_FEATURE_EDIT, fLayerMedia!!
+                    true, LayerType.LAYER_TYPE_FEATURE_EDIT, fLayerMedia!!
                 ), LayerManager.LayerGroup.LAYER_NAME_DAILY
             )
+            fLayerMedia!!.isVisible = isVisibleMedia
+            mMap!!.operationalLayers.add(fLayerMedia)
             // todo: 2023/4/14  初始化违建面图层
             fTableCasePolygon = geoDatabase.getGeodatabaseFeatureTable("sbwj84")
             fLayerCasePolygon = FeatureLayer(fTableCasePolygon)
             fLayerCasePolygon!!.name = LAYER_NAME_CASE
-            fLayerCasePolygon!!.isVisible = true
             // todo: 2023/4/14 给图层添加标注
             val labelDefinition: LabelDefinition =
                 createLabelDefinition(Color.BLUE, 12.0f, "round(\$feature.MJ,2) + '亩';")
             fLayerCasePolygon!!.labelDefinitions.add(labelDefinition)
             fLayerCasePolygon!!.isLabelsEnabled = true
-            mMap!!.operationalLayers.add(fLayerCasePolygon)
-            LayerManager.getInstance().addLayer(
+            // todo: 2023/9/27 添加图层配置 并获取默认可见性
+            val isVisibleCase = LayerManager.getInstance().addLayer(
                 LayerModel(
                     fLayerCasePolygon!!.name,
-                    fLayerCasePolygon!!.isVisible,
+                    true,
                     LayerType.LAYER_TYPE_FEATURE_EDIT,
                     fLayerCasePolygon!!
                 ), LayerManager.LayerGroup.LAYER_NAME_DAILY
             )
+            fLayerCasePolygon!!.isVisible = isVisibleCase
+            mMap!!.operationalLayers.add(fLayerCasePolygon)
             // todo: 2023/4/14 可编辑数据符号化
             editLayerRenderer()
         })
@@ -652,19 +656,19 @@ class FragmentMap : CrAnimationFragment() {
         layerName: String,
         group: LayerManager.LayerGroup
     ) {
-        // todo: 2023/8/17 设置可见
-        layer.isVisible = true
-        // todo: 2023/8/17 加入到地图中
-        mapView?.graphicsOverlays!!.add(layer)
         // todo: 2023/8/17 加入到图层控制中
-        LayerManager.getInstance().addLayer(
+        val isVisible = LayerManager.getInstance().addLayer(
             LayerModel(
                 layerName,
-                layer.isVisible,
+                true,
                 LayerType.LAYER_TYPE_GRAPHIC,
                 layer
             ), group
         )
+        // todo: 2023/8/17 设置可见
+        layer.isVisible = isVisible
+        // todo: 2023/8/17 加入到地图中
+        mapView?.graphicsOverlays!!.add(layer)
     }
 
     /**
@@ -788,17 +792,18 @@ class FragmentMap : CrAnimationFragment() {
      */
     private fun appendGraphicOverlay(layer: GraphicsOverlay, layerName: String) {
         // todo: 2023/4/19 设置该图层显示
-        layer.isVisible = true
         mapView?.graphicsOverlays?.let {
-            it.add(layer)
-            LayerManager.getInstance().addLayer(
+            // todo: 2023/9/27 添加图层配置 并获取默认可见性
+            val isVisible = LayerManager.getInstance().addLayer(
                 LayerModel(
                     layerName,
-                    layer.isVisible,
+                    true,
                     LayerType.LAYER_TYPE_GRAPHIC,
                     layer
                 ), LayerManager.LayerGroup.LAYER_NAME_DRAW
             )
+            layer.isVisible = isVisible
+            it.add(layer)
         }
     }
 
@@ -2039,6 +2044,75 @@ class FragmentMap : CrAnimationFragment() {
         }
     }
 
+    /**
+     * 案件上传成功后,更新案件点并删除案件面数据
+     * @param caseModel CaseModel 更新成功的案件模型
+     */
+    private fun updateCaseAndDelPolygonBecauseUploadSuccess(caseModel:CaseModel){
+        // todo: 2023/9/27 创建查询条件
+        var queryParams = QueryParameters()
+        queryParams.whereClause = String.format("%s='%s'", FIELD_CASE_NAME,caseModel.name)
+        // todo: 2023/9/27 开始查询
+        val asyncQuery = fTableMedia?.queryFeaturesAsync(queryParams)
+        asyncQuery?.addDoneListener{
+            if(asyncQuery.isDone){
+                var result = asyncQuery.get().iterator()
+                if (result.hasNext()){
+                    var feature = result.next()
+                    feature.attributes[FIELD_CASE_ISUP] = MEDIA_TYPE_WJ_YES
+                    feature.attributes[FIELD_CASE_RQ] = CrUnitManager.toSystemYMDHMSDate()
+                    // todo: 2023/9/27 更新
+                    updateCasePointAttributeByFeature(feature)
+                }
+            }
+        }
+    }
+
+    /**
+     * 更新案件点属性
+     * @param feature Feature
+     */
+    private fun updateCasePointAttributeByFeature(feature:Feature){
+        val updateAsync = fTableMedia?.updateFeatureAsync(feature)
+        updateAsync?.addDoneListener{
+            if(updateAsync.isDone){
+                // todo: 2023/9/27 更新完成 删除关联面
+                deleteCasePolygonFeatureByFeature(feature)
+            }
+        }
+    }
+
+    /**
+     * 删除案件点关联的案件面(通过空间相交分析)
+     * @param feature Feature 案件点要素
+     */
+    private fun deleteCasePolygonFeatureByFeature(feature:Feature){
+        // todo: 2023/9/27 创建查询条件
+        var queryParams = QueryParameters();
+        queryParams.whereClause = "1=1"
+        queryParams.geometry = feature.geometry
+        queryParams.spatialRelationship = QueryParameters.SpatialRelationship.INTERSECTS
+        // todo: 2023/9/27 查询
+        val asyncQuery = fTableCasePolygon?.queryFeaturesAsync(queryParams)
+        asyncQuery?.addDoneListener{
+            if(asyncQuery.isDone){
+                // todo: 2023/9/27 查询完成后 删除
+                val result = asyncQuery.get().iterator()
+                val delFeatures = mutableListOf<Feature>()
+                while (result.hasNext()){
+                    delFeatures.add(result.next())
+                }
+                val asyncDelete = fTableCasePolygon?.deleteFeaturesAsync(delFeatures)
+                asyncDelete?.addDoneListener{
+                    if(asyncDelete.isDone){
+                        // todo: 2023/9/27 删除成功
+                        showInformation("地图案件已更新!")
+                    }
+                }
+            }
+        }
+    }
+
 
     /**
      * 订阅地图事件执行动作
@@ -2188,6 +2262,12 @@ class FragmentMap : CrAnimationFragment() {
                 CrUtil.showToast("地图上选择需要上传或分享的案件!")
                 mapTouch?.setAction(MapAction.MapTapCaseWxAndUpload)
             }
+            // todo: 2023/9/27 案件上传成功
+            MapAction.EventCaseUploadSuccess->{
+               var caseModel =  event.owner as CaseModel
+                // todo: 2023/9/27 更新案件点为已上传 删除面对象
+                updateCaseAndDelPolygonBecauseUploadSuccess(caseModel)
+            }
         }
     }
 

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

@@ -20,6 +20,8 @@ import com.cr.data.CrConfig
 import com.cr.data.CrUtil
 import com.cr.dialog.DialogLoadingUtil
 import com.cr.map.CaseModel
+import com.cr.map.EventMap
+import com.cr.map.MapAction
 import com.cr.models.SelModel
 import com.cr.models.SubmitCaseModel
 import com.cr.network.NetManager
@@ -386,7 +388,10 @@ class FragmentUploadAction : CrNavigationFragment(), View.OnClickListener {
                 // todo: 2023/8/28 上传完成
                 override fun onSuccess(message: String) {
                     DialogLoadingUtil.dismiss()
-                    showInformation(message)
+                    // todo: 2023/9/27 通知地图更新
+                    CrApplication.getEventBus().post(EventMap(MapAction.EventCaseUploadSuccess,joinCase))
+                    // todo: 2023/9/27 底部信息
+                    setMessage(message)
                 }
             })
     }

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

@@ -6,12 +6,14 @@ import android.view.View
 import android.view.ViewGroup
 import androidx.viewpager2.widget.ViewPager2
 import com.cr.adapter.CrPageAdapter
+import com.cr.common.DataManager
 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.CaseModel
+import com.cr.models.CompletionModel
+import com.cr.models.ICompletion
 
 /**
  * 操作系统:MAC系统
@@ -117,6 +119,7 @@ class FragmentUploadCase : CrNavigationFragment() {
             nvBar?.crSetVisible(backIsVisible = true, dismissIsVisible = false)
             // todo: 2023/6/20 初始化照片编辑页面
             fragmentImageEditor = FragmentImageEditor()
+            fragmentImageEditor?.crSetChangeListener(imageEditorListener)
             adapter?.addFragment(fragmentImageEditor!!)
             // todo: 2023/6/20 设置显示的照片
             fragmentImageEditor?.crSetImage(imagePath)
@@ -139,6 +142,46 @@ class FragmentUploadCase : CrNavigationFragment() {
     }
 
     /**
+     * 照片编辑监听
+     */
+    private val imageEditorListener = object:FragmentImageEditor.IChangeListener{
+        // todo: 2023/9/28 保存
+        override fun onSave(oldName:String,newName:String) {
+            // todo: 2023/9/28 保存到编辑表
+            if(DataManager.appendEditImage(oldName,newName)){
+                DataManager.replaceImageName(joinCase!!.name!!,oldName,newName,object:ICompletion<String>{
+                    override fun onCompletion(completion: CompletionModel<String>) {
+                        if(completion.isSuccess){
+                            // todo: 2023/9/28 保存成功
+                            showInformation("照片编辑保存成功!")
+                            fragmentUploadCaseMain?.crSetJoinCase(joinCase!!)
+                        }else{
+                            showError("错误" + completion.message)
+                        }
+                    }
+                })
+            }else{
+                showError("编辑数据保存失败!")
+            }
+        }
+
+        // todo: 2023/9/28 恢复
+        override fun onRecover(oldName:String,newName:String) {
+            DataManager.replaceImageName(joinCase!!.name!!,newName,oldName,object:ICompletion<String>{
+                override fun onCompletion(completion: CompletionModel<String>) {
+                    if(completion.isSuccess){
+                        // todo: 2023/9/28 保存成功
+                        showInformation("照片恢复成功!")
+                        fragmentUploadCaseMain?.crSetJoinCase(joinCase!!)
+                    }else{
+                        showError(completion.message)
+                    }
+                }
+            })
+        }
+    }
+
+    /**
      * 设置关联的案件
      * @param joinCase CaseModel 关联案件
      */

+ 8 - 8
app/src/main/java/com/cr/pages/FragmentUploadCaseMain.kt

@@ -162,7 +162,7 @@ class FragmentUploadCaseMain : CrNavigationFragment(), View.OnClickListener {
         // todo: 2023/6/20 查询数据库中数据
         DataManager.appQueryImages(this.joinCase!!.name!!, object : ICompletion<List<String>> {
             override fun onCompletion(completion: CompletionModel<List<String>>) {
-                if (completion.isSuccess == true) {
+                if (completion.isSuccess) {
                     // todo: 2023/8/25 进行判断
                     if (completion.result!!.size > 1) {
                         checkCaseCaptureData()
@@ -188,7 +188,7 @@ class FragmentUploadCaseMain : CrNavigationFragment(), View.OnClickListener {
         if (isExists) {
             showConfirm("截图文件已存在,是否直接使用?", arrayOf("是","否"),object:ICompletion<String>{
                 override fun onCompletion(completion: CompletionModel<String>) {
-                    if(completion.isSuccess == true){
+                    if(completion.isSuccess){
                         sendListener()
                     }else{
                         // todo: 2023/8/25 发送截屏事件
@@ -231,7 +231,7 @@ class FragmentUploadCaseMain : CrNavigationFragment(), View.OnClickListener {
         // todo: 2023/6/20 查询数据库中数据
         DataManager.appQueryImages(this.joinCase!!.name!!, object : ICompletion<List<String>> {
             override fun onCompletion(completion: CompletionModel<List<String>>) {
-                if (completion.isSuccess == true) {
+                if (completion.isSuccess) {
                     // todo: 2023/6/20 更新显示
                     lblCaseImageCount?.text = String.format("取证照片[%s]张", completion.result!!.size)
                     // todo: 2023/6/20 追加到照片浏览器中
@@ -255,9 +255,9 @@ class FragmentUploadCaseMain : CrNavigationFragment(), View.OnClickListener {
         if (requestCode == OPEN_ALBUM && resultCode == RESULT_OK) {
             var imagePath: String? = null
             imagePath = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-                CrPictureManager.handleImageAfterKitKat(context!!, data!!)
+                CrPictureManager.handleImageAfterKitKat(CrApplication.getContext(), data!!)
             } else {
-                CrPictureManager.handleImageBeforeKitKat(context!!, data!!)
+                CrPictureManager.handleImageBeforeKitKat(CrApplication.getContext(), data!!)
             }
             if (imagePath != null) {
                 // todo: 2023/6/16 转存文件
@@ -272,7 +272,7 @@ class FragmentUploadCaseMain : CrNavigationFragment(), View.OnClickListener {
                     model.imgName = fileName
                     DataManager.appAppendImages(model, object : ICompletion<String> {
                         override fun onCompletion(completion: CompletionModel<String>) {
-                            if (completion.isSuccess == true) {
+                            if (completion.isSuccess) {
                                 // todo: 2023/6/20 添加到照片容器
                                 imageBrowser?.crAppendImage(newFilePath)
                                 // todo: 2023/6/20 刷新照片熟练
@@ -280,7 +280,7 @@ class FragmentUploadCaseMain : CrNavigationFragment(), View.OnClickListener {
                                     joinCase!!.name!!,
                                     object : ICompletion<List<String>> {
                                         override fun onCompletion(completion: CompletionModel<List<String>>) {
-                                            if (completion.isSuccess == true) {
+                                            if (completion.isSuccess) {
                                                 // todo: 2023/6/20 更新显示
                                                 lblCaseImageCount?.text = String.format(
                                                     "取证照片[%s]张",
@@ -315,7 +315,7 @@ class FragmentUploadCaseMain : CrNavigationFragment(), View.OnClickListener {
             // todo: 2023/8/25 追加图片
             DataManager.appQueryImages(this.joinCase!!.name!!, object : ICompletion<List<String>> {
                 override fun onCompletion(completion: CompletionModel<List<String>>) {
-                    if (completion.isSuccess == true) {
+                    if (completion.isSuccess) {
                         for(imgName in completion.result!!){
                             itCase.imgArray?.add(imgName)
                         }

+ 171 - 32
app/src/main/java/com/cr/view/CrImageEditor.kt

@@ -7,7 +7,13 @@ import android.view.GestureDetector
 import android.view.MotionEvent
 import android.view.ScaleGestureDetector
 import androidx.appcompat.widget.AppCompatImageView
+import androidx.core.graphics.drawable.toBitmap
+import com.cr.common.CrFileManager
 import com.cr.cruav.R
+import com.cr.data.CrUtil
+import java.io.File
+import java.io.FileInputStream
+import java.io.FileOutputStream
 
 /**
  * 操作系统:MAC系统
@@ -19,29 +25,35 @@ class CrImageEditor @JvmOverloads constructor(
     context: Context,
     attrs: AttributeSet? = null
 ) : AppCompatImageView(context, attrs) {
-    // define: 2023/6/20 缩放
-    private var mScaleGestureDetector: ScaleGestureDetector? = null
+    // todo: 2023/8/26 视图尺寸定义
+    private var viewWidth: Int = 0  // define: 2023/8/26 视图宽度
+    private var viewHeight: Int = 0  // define: 2023/8/26 视图高度
 
-    // define: 2023/6/20 平移
-    private var mGestureDetector: GestureDetector? = null
+    // todo: 2023/9/28 监听事件
+    private var mScaleGestureDetector: ScaleGestureDetector? = null // define: 2023/6/20 缩放
+    private var mGestureDetector: GestureDetector? = null  // define: 2023/6/20 平移
 
     // todo: 2023/6/20 缩放平移矩阵
     private var mCurrentMatrix = Matrix()
 
-    // todo: 2023/6/20 最小缩放
-    private var mCenterX: Float? = 0f
+    // todo: 2023/9/28 变量定义
+    private var mCenterX: Float? = 0f  // define: 2023/9/28 : 2023/6/20 最小缩放
     private var mCenterY: Float? = 0f
-
-    // todo: 2023/6/20 点击位置点集合
-    private var drawPoints = mutableListOf<PointF>()
-
-    // todo: 2023/6/21 绘制点集合
-    private var downPoints = mutableListOf<PointF>()
+    private var drawPoints = mutableListOf<PointF>() // define: 2023/6/20 绘制点集合
+    private var downPoints = mutableListOf<PointF>()  // define: 2023/6/21 点击点集合
 
     // todo: 2023/6/20 画笔
     private var drawPointPaint = Paint()
     private var drawLinePaint = Paint()
 
+    // todo: 2023/9/28 展示文件定义
+    private var fileAllPath: String? = null  // define: 2023/9/28 全路径
+    private var fileName: String? = null  // define: 2023/9/28 不含扩展名的文件名
+    private var extensionName: String? = null // define: 2023/9/28 扩展名
+
+    // todo: 2023/9/28 显示图
+    private var viewBitmap: Bitmap? = null
+
     /**
      * 缩放监听
      */
@@ -82,13 +94,11 @@ class CrImageEditor @JvmOverloads constructor(
         // todo: 2023/6/20 单击确认
         override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
             // todo: 2023/6/20 单击绘制一个点 试试
-            e?.let {
-                var point = PointF(it.x, it.y)
-                // todo: 2023/6/21 由于缩放后点击,点击位置已经经过矩阵变换,为统一在重绘时变换,需要逆向变换一次
-                downPoints.add(calculateInversePointF(point, mCurrentMatrix))
-                // todo: 2023/6/21 重绘
-                invalidate()
-            }
+            val point = PointF(e.x, e.y)
+            // todo: 2023/6/21 由于缩放后点击,点击位置已经经过矩阵变换,为统一在重绘时变换,需要逆向变换一次
+            downPoints.add(calculateInversePointF(point, mCurrentMatrix))
+            // todo: 2023/6/21 重绘
+            invalidate()
             return true
         }
 
@@ -167,6 +177,18 @@ class CrImageEditor @JvmOverloads constructor(
     }
 
     /**
+     * 重置
+     * @param widthMeasureSpec Int
+     * @param heightMeasureSpec Int
+     */
+    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
+        // todo: 2023/8/26 获取视图宽度和高度 单位是像素
+        this.viewWidth = MeasureSpec.getSize(widthMeasureSpec)
+        this.viewHeight = MeasureSpec.getSize(heightMeasureSpec)
+    }
+
+    /**
      * 绘制
      * @param canvas Canvas
      */
@@ -181,23 +203,49 @@ class CrImageEditor @JvmOverloads constructor(
         for (point in downPoints) {
             drawPoints.add(calculatePointF(point, mCurrentMatrix))
         }
+        // todo: 2023/6/20 绘制点
+        drawPoint(canvas,drawPoints)
+        // todo: 2023/9/28 绘制线
+        drawLine(canvas,drawPoints)
+    }
 
+    /**
+     * 绘制点
+     * @param canvas Canvas? 画布
+     * @param points List<PointF> 数据集合
+     */
+    private fun drawPoint(canvas: Canvas?,points:List<PointF>) {
         // todo: 2023/6/20 绘制点
-        for (point in drawPoints) {
+        for (point in points) {
             canvas?.drawPoint(point.x, point.y, drawPointPaint)
         }
+    }
+
+    /**
+     * 绘制线
+     * @param canvas Canvas? 画布
+     * @param points List<PointF> 数据集合
+     */
+    private fun drawLine(canvas: Canvas?,points:List<PointF>) {
         // todo: 2023/6/20 绘制线
-        if (drawPoints.size > 1) {
-            var points = mutableListOf<Float>()
-            for (i in 0 until drawPoints.size - 1) {
-                var point1 = drawPoints[i]
-                var point2 = drawPoints[i + 1]
-                points.add(point1.x)
-                points.add(point1.y)
-                points.add(point2.x)
-                points.add(point2.y)
+        if (points.size > 1) {
+            var dPoints = mutableListOf<Float>()
+            for (i in 0 until points.size - 1) {
+                var point1 = points[i]
+                var point2 = points[i + 1]
+                dPoints.add(point1.x)
+                dPoints.add(point1.y)
+                dPoints.add(point2.x)
+                dPoints.add(point2.y)
+            }
+            // todo: 2023/9/28 闭合线
+            if (points.size > 2) {
+                dPoints.add(points.last().x)
+                dPoints.add(points.last().y)
+                dPoints.add(points.first().x)
+                dPoints.add(points.first().y)
             }
-            canvas?.drawLines(points.toFloatArray(), drawLinePaint)
+            canvas?.drawLines(dPoints.toFloatArray(), drawLinePaint)
         }
     }
 
@@ -219,7 +267,7 @@ class CrImageEditor @JvmOverloads constructor(
      * 设置线的宽度
      * @param width Float 线的宽度
      */
-    fun crSetLineWidth(width:Float){
+    fun crSetLineWidth(width: Float) {
         drawLinePaint.strokeWidth = width
         // todo: 2023/6/26 重绘
         invalidate()
@@ -229,9 +277,100 @@ class CrImageEditor @JvmOverloads constructor(
      * 设置线的颜色
      * @param color Int 线的颜色
      */
-    fun crSetLineColor(color:Int){
+    fun crSetLineColor(color: Int) {
         drawLinePaint.color = color
         // todo: 2023/6/26 重绘
         invalidate()
     }
+
+    /**
+     * 回退撤销一步
+     */
+    fun crSetUndo() {
+        if (this.downPoints.size > 0) {
+            this.downPoints.removeLast()
+            invalidate()
+        }
+    }
+
+    /**
+     * 重绘
+     */
+    fun crReset() {
+        this.downPoints.clear()
+        invalidate()
+    }
+
+    /**
+     * 设置显示的图片
+     * @param fileAllPath String 全路径
+     */
+    fun crSetBitmap(fileAllPath: String) {
+        this.fileAllPath = fileAllPath
+        this.fileName = CrFileManager.getFileNoExtensionName(fileAllPath)
+        this.extensionName = CrFileManager.getExtensionName(fileAllPath)
+        // todo: 2023/9/28 设置显示图片
+        var file = File(fileAllPath)
+        if (file.exists()) {
+            val fis = FileInputStream(fileAllPath)
+            viewBitmap = BitmapFactory.decodeStream(fis)
+            this.setImageBitmap(viewBitmap!!)
+        }
+    }
+
+    /**
+     * 保存图片
+     * @return String? 返回保存的图片名称
+     */
+    fun crSaveImage(): String? {
+        viewBitmap?.let {
+            // todo: 2023/9/28 为了保证最终保存的绘制内容与图片对应 需要通过矩阵进行变换
+            var matrix = Matrix()  // todo: 2023/9/28 定义一个矩阵
+            // todo: 2023/9/28 计算缩放比例
+            if(viewWidth<viewHeight) {
+                // todo: 2023/9/28 进行缩放
+                val imgScale = (it.width*1.0f)/(viewWidth*1.0f)
+                matrix.postScale(imgScale,imgScale)
+                // todo: 2023/9/28 平移
+                val imgTranslate = (viewHeight*imgScale - it.height)*0.5f
+                matrix.postTranslate(0f,-1*imgTranslate)
+            } else{
+                // todo: 2023/9/28 进行缩放
+                val imgScale = (it.height*1.0f)/(viewHeight*1.0f)
+                matrix.postScale(imgScale,imgScale)
+                // todo: 2023/9/28 平移
+                val imgTranslate = (viewWidth*imgScale - it.width)*0.5f
+                matrix.postTranslate(-1*imgTranslate,0f)
+            }
+            // todo: 2023/9/28 创建一个bitmap
+            var saveBitmap = Bitmap.createBitmap(it.width,it.height,it.config)
+            // todo: 2023/9/28 创建一个画布
+            var canvas = Canvas(saveBitmap)
+            // todo: 2023/9/28 绘制图片
+            val picturePaint = Paint()
+            canvas.drawBitmap(it,0f,0f,picturePaint)
+            // todo: 2023/6/21 变换
+            var dPoints = mutableListOf<PointF>()
+            for (point in downPoints) {
+                val resPoint = calculatePointF(point, matrix)
+                dPoints.add(resPoint)
+            }
+            // todo: 2023/9/28 绘制线
+            drawLine(canvas,dPoints)
+            // todo: 2023/9/28 保存
+            val outFileName = "${this.fileName}_new.${this.extensionName}"
+            val outFilePath = "${CrUtil.IMAGE_PATH}${outFileName}"
+            // todo: 2023/9/28 如果文件存在 先删除
+            var file = File(outFilePath)
+            if(file.exists()){
+                file.delete()
+            }
+            val outFileStream = FileOutputStream(outFilePath)
+            saveBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outFileStream)
+            outFileStream.flush()
+            outFileStream.close()
+            return outFileName
+        }
+        return null
+    }
 }

+ 13 - 9
app/src/main/res/layout/item_layercontrol.xml

@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical">
@@ -8,7 +9,7 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:textSize="@dimen/sp_12"
-        android:text="分组"
+        android:text="@string/default_value"
         android:layout_margin="8dp"
         android:textStyle="bold"
         android:textColor="@color/yellow"
@@ -17,10 +18,10 @@
         android:layout_width="match_parent"
         android:layout_height="@dimen/cr_22_dp"
         android:orientation="vertical"
-        android:layout_marginLeft="@dimen/cr_5_dp">
+        android:layout_marginStart="@dimen/cr_5_dp">
         <LinearLayout
             android:layout_width="match_parent"
-            android:layout_height="match_parent"
+            android:layout_height="0dp"
             android:gravity="center_vertical"
             android:layout_weight="1">
             <ImageView
@@ -31,27 +32,30 @@
                 android:id="@+id/item_layer_img"/>
             <TextView
                 style="@style/item_layer_name"
-                android:text="影像图"
+                android:text="@string/default_value"
                 android:layout_weight="1"
                 android:id="@+id/item_layer_name"
-                android:layout_marginLeft="@dimen/cr_5_dp"/>
+                android:layout_marginStart="@dimen/cr_5_dp"
+                tools:ignore="NestedWeights" />
             <TextView
                 style="@style/item_layer_label"
-                android:text="显示/隐藏"/>
+                android:text="@string/layer_control_title_visible"/>
             <Switch
                 style="@style/item_layer_padding"
                 android:track="@drawable/switch_smart_track"
                 android:thumb="@drawable/switch_smart_thumb"
-                android:id="@+id/item_layer_on_visible"/>
+                android:id="@+id/item_layer_on_visible"
+                tools:ignore="UseSwitchCompatOrMaterialXml" />
             <TextView
                 style="@style/item_layer_label"
-                android:text="标注"
+                android:text="@string/layer_control_title_label"
                 android:id="@+id/item_layer_lbl"/>
             <Switch
                 style="@style/item_layer_padding"
                 android:track="@drawable/switch_smart_track"
                 android:thumb="@drawable/switch_smart_thumb"
-                android:id="@+id/item_layer_on_label"/>
+                android:id="@+id/item_layer_on_label"
+                tools:ignore="UseSwitchCompatOrMaterialXml" />
         </LinearLayout>
         <View style="@style/view_split_h1"/>
     </LinearLayout>

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

@@ -22,7 +22,7 @@
             android:layout_alignParentBottom="true"
             android:layout_marginBottom="@dimen/cr_10_dp"
             android:id="@+id/wg_indicator"
-            app:cr_count="1"
+            app:cr_count="0"
             app:cr_index="0"/>
     </LinearLayout>
 </androidx.constraintlayout.widget.ConstraintLayout>

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

@@ -6,7 +6,7 @@
     <dimen name="switch_offset">1.2dp</dimen>
 
     <dimen name="switch_smart_width">14dp</dimen>
-    <dimen name="switch_smart_height">8dp</dimen>
+    <dimen name="switch_smart_height">10dp</dimen>
     <dimen name="switch_smart_offset">1.2dp</dimen>
 
     <dimen name="common_padding">2dp</dimen>

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

@@ -239,6 +239,10 @@
     <string name="set_title_simple">模拟飞行</string>
     <string name="set_title_set_ip_and_com">设置网络Ip和端口</string>
 
+    <!--图层相关-->
+    <string name="layer_control_title_visible">显/隐</string>
+    <string name="layer_control_title_label">标注</string>
+
     <!--字体-->
     <string name="ico_nv_left" translatable="false">&#xe60b;</string>
     <string name="ico_nv_right" translatable="false">&#xe81a;</string>