Explorar o código

feat poc2.0设备服务区域

lihao1 %!s(int64=3) %!d(string=hai) anos
pai
achega
e0c12f6501
Modificáronse 23 ficheiros con 904 adicións e 55 borrados
  1. 93 0
      cadengine/src/main/java/cn/sagacloud/android/cadengine/items/AreaNodeItem.kt
  2. 4 0
      cadengine/src/main/java/cn/sagacloud/android/cadengine/items/EquipItem.kt
  3. 1 1
      cadengine/src/main/java/cn/sagacloud/android/cadengine/items/PipeNodeItem.kt
  4. 14 5
      cadengine/src/main/java/cn/sagacloud/android/cadengine/items/PointItem.kt
  5. 68 0
      cadengine/src/main/java/cn/sagacloud/android/cadengine/items/ServeAreaItem.kt
  6. BIN=BIN
      cadengine/src/main/res/drawable/equip_notdone.png
  7. BIN=BIN
      cadengine/src/main/res/drawable/equip_purple.png
  8. BIN=BIN
      cadengine/src/main/res/drawable/img.png
  9. 1 0
      demo/build.gradle
  10. 3 0
      demo/src/main/AndroidManifest.xml
  11. 1 1
      demo/src/main/java/com/framework/mvvm/model/db/entity/task/ObjectEntity.kt
  12. 48 3
      demo/src/main/java/com/sybotan/android/demo/activities/EquipDetailActivity.kt
  13. 25 3
      demo/src/main/java/com/sybotan/android/demo/activities/GraphyActivity.kt
  14. 271 0
      demo/src/main/java/com/sybotan/android/demo/activities/ServeAreaActivity.kt
  15. 7 7
      demo/src/main/java/com/sybotan/android/demo/activities/SpaceDetailActivity.kt
  16. 90 9
      demo/src/main/java/com/sybotan/android/demo/activities/SpaceMapActivity.kt
  17. 1 1
      demo/src/main/java/com/sybotan/android/demo/bean/result/Children.java
  18. 40 17
      demo/src/main/java/com/sybotan/android/demo/viewmodel/GraphyVM.kt
  19. 81 0
      demo/src/main/java/com/sybotan/android/demo/viewmodel/SpaceDetailVM.kt
  20. 5 1
      demo/src/main/java/com/sybotan/android/demo/viewmodel/SpaceMapVM.kt
  21. 37 7
      demo/src/main/res/layout/activity_equip_detail.xml
  22. 114 0
      demo/src/main/res/layout/activity_serve_area.xml
  23. BIN=BIN
      demo/src/main/res/mipmap-xhdpi/icon_wrong.png

+ 93 - 0
cadengine/src/main/java/cn/sagacloud/android/cadengine/items/AreaNodeItem.kt

@@ -0,0 +1,93 @@
+package cn.sagacloud.android.cadengine.items
+
+import android.graphics.*
+import cn.sagacloud.android.cadengine.Opt
+import cn.sagacloud.android.cadengine.types.PipeLine
+import cn.sagacloud.android.cadengine.types.Point
+import com.sybotan.android.graphy.SGraphyItem
+import com.sybotan.android.graphy.SMotionEvent
+import com.sybotan.android.graphy.enums.SGraphyItemFlag
+import java.util.*
+import kotlin.collections.ArrayList
+
+/**
+ * Created by lihao.
+ * Date: 2021/6/7
+ * 区域节点
+ */
+class AreaNodeItem(val data: PointF, parent: SGraphyItem? = null) : SGraphyItem(parent) {
+    /** 画笔 */
+    val paint = Paint()
+    val mPaint_inner = Paint()
+
+    val outPaint = Paint()
+
+    var x: Float = 0f
+    var y: Float = 0f
+    lateinit var onScroll: OnScroll
+
+    init {
+        try {
+//            flags = EnumSet.of(SGraphyItemFlag.ItemIsMovable, SGraphyItemFlag.ItemIsSelectable, SGraphyItemFlag.ItemIsFocusable)
+
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        outPaint.style = Paint.Style.STROKE
+        outPaint.strokeJoin = Paint.Join.ROUND
+        outPaint.isAntiAlias = true
+        outPaint.color = Color.rgb(0x66, 0x66, 0xff)
+        outPaint.strokeWidth = 150f
+        x = data.x
+        y = data.y
+
+        //内圈
+        mPaint_inner.color = Color.RED
+        mPaint_inner.isAntiAlias = true
+        mPaint_inner.style = Paint.Style.FILL
+    } // Constructor
+
+    override fun boundingRect(): RectF {
+        return RectF(data.x - 600f, -data.y - 600f, data.x + 600f, -data.y + 600f)
+    }
+
+    override fun onScroll(e1: SMotionEvent, e2: SMotionEvent, distanceX: Float, distanceY: Float): Boolean {
+        val fx = pos.x - distanceX * scale.x
+        val fy = pos.y - distanceY * scale.y
+        x = data.x + fx
+        y = data.y - fy
+        moveTo(pos.x - distanceX * scale.x, pos.y - distanceY * scale.y)
+        onScroll.onScroll(data.x + fx, data.y + fy)
+        return true
+
+
+//        moveTo(pos.x - distanceX * scale.x, pos.y - distanceY * scale.y)
+
+//        onScroll.onScroll(data.x + pos.x - distanceX * scale.x, data.y - pos.y - distanceY * scale.y)
+//        onScroll.onScroll(data.x, data.y)
+
+
+
+//        return super.onScroll(e1, e2, distanceX, distanceY)
+    }
+
+    interface OnScroll {
+        fun onScroll(x: Float, y: Float)
+    }
+
+    fun setOnScrollListener(onScroll: OnScroll) {
+        this.onScroll = onScroll
+    }
+
+
+    /**
+     * Item绘制操作
+     *
+     * @param   canvas          画布
+     * @param   rect            绘制区域
+     */
+    override fun onDraw(canvas: Canvas) {
+        canvas.drawCircle(data.x, -data.y, 120f, mPaint_inner)
+    } // Function onDraw()
+
+}

+ 4 - 0
cadengine/src/main/java/cn/sagacloud/android/cadengine/items/EquipItem.kt

@@ -31,6 +31,7 @@ class EquipItem(
     val mPaint_center = Paint()
     var mDefaultScale = 0f
     var mRedBitmap: Bitmap
+    var mPurpleBitmap: Bitmap
     var mBlueBitmap: Bitmap
     var mGreenBitmap: Bitmap
     var myellowBitmap: Bitmap
@@ -47,6 +48,7 @@ class EquipItem(
         mGreenBitmap = BitmapFactory.decodeResource(context.resources, R.drawable.equip_green)
 
         mRedBitmap = BitmapFactory.decodeResource(context.resources, R.drawable.equip_red)
+        mPurpleBitmap = BitmapFactory.decodeResource(context.resources, R.drawable.equip_notdone)
         myellowBitmap = BitmapFactory.decodeResource(context.resources, R.drawable.yellow_equip)
 
 
@@ -92,6 +94,8 @@ class EquipItem(
             canvas.drawBitmap(mRedBitmap, matrix, mPaint_center)
         } else if (data.equipState == 4) {
             canvas.drawBitmap(myellowBitmap, matrix, mPaint_center)
+        }  else if (data.equipState == 5) {
+            canvas.drawBitmap(mPurpleBitmap, matrix, mPaint_center)
         } else {
             canvas.drawBitmap(mBlueBitmap, matrix, mPaint_center)
         }

+ 1 - 1
cadengine/src/main/java/cn/sagacloud/android/cadengine/items/PipeNodeItem.kt

@@ -86,7 +86,7 @@ class PipeNodeItem(val data: PointF, parent: SGraphyItem? = null) : SGraphyItem(
      * @param   rect            绘制区域
      */
     override fun onDraw(canvas: Canvas) {
-        canvas.drawCircle(data.x, -data.y, 40f, mPaint_inner)
+        canvas.drawCircle(data.x, -data.y, 120f, mPaint_inner)
     } // Function onDraw()
 
 }

+ 14 - 5
cadengine/src/main/java/cn/sagacloud/android/cadengine/items/PointItem.kt

@@ -56,15 +56,18 @@ class PointItem(val data: Point, parent: SGraphyItem? = null, defaultScale: Floa
     private var maxY = 0f
 
     init {
-//        flags = EnumSet.of(
-//            SGraphyItemFlag.ItemIsMovable,
-//            SGraphyItemFlag.ItemIsSelectable,
-//            SGraphyItemFlag.ItemIsFocusable
-//        )
+        if (data.points.size != 1 && data.points.size != 0) {
+            flags = EnumSet.of(
+                SGraphyItemFlag.ItemIsMovable,
+                SGraphyItemFlag.ItemIsSelectable,
+                SGraphyItemFlag.ItemIsFocusable
+            )
+        }
         if (defaultScale != null) {
             mDefaultScale = defaultScale
         }
         /** 按时 */
+        /** 按时 */
         not_overTime_inner.color = Color.parseColor("#ffffff")
         not_overTime_inner.isAntiAlias = true
         not_overTime_inner.style = Paint.Style.FILL
@@ -74,6 +77,8 @@ class PointItem(val data: Point, parent: SGraphyItem? = null, defaultScale: Floa
         not_overTime_outer.style = Paint.Style.FILL
 
         /** 逾期 */
+
+        /** 逾期 */
         overTime_inner.color = Color.parseColor("#ffffff")
         overTime_inner.isAntiAlias = true
         overTime_inner.style = Paint.Style.FILL
@@ -83,6 +88,8 @@ class PointItem(val data: Point, parent: SGraphyItem? = null, defaultScale: Floa
         overTime_outer.style = Paint.Style.FILL
 
         /** 承接查验复核中 */
+
+        /** 承接查验复核中 */
         checkReviewing_inner.color = Color.parseColor("#ffffff")
         checkReviewing_inner.isAntiAlias = true
         checkReviewing_inner.style = Paint.Style.FILL
@@ -92,6 +99,8 @@ class PointItem(val data: Point, parent: SGraphyItem? = null, defaultScale: Floa
         checkReviewing_outer.style = Paint.Style.FILL
 
         /** 新建 */
+
+        /** 新建 */
         //中圈
         mPaint_center.color = Color.parseColor("#ffffff")
         mPaint_center.isAntiAlias = true

+ 68 - 0
cadengine/src/main/java/cn/sagacloud/android/cadengine/items/ServeAreaItem.kt

@@ -0,0 +1,68 @@
+package cn.sagacloud.android.cadengine.items
+
+import android.graphics.*
+import cn.sagacloud.android.cadengine.Opt
+import cn.sagacloud.android.cadengine.types.PipeLine
+import cn.sagacloud.android.cadengine.types.Point
+import com.sybotan.android.graphy.SGraphyItem
+import com.sybotan.android.graphy.SMotionEvent
+import com.sybotan.android.graphy.enums.SGraphyItemFlag
+import java.util.*
+import kotlin.collections.ArrayList
+
+/**
+ * Created by lihao.
+ * Date: 2021/6/7
+ * 服务区域图形
+ */
+class ServeAreaItem(datas: ArrayList<PointF>, parent: SGraphyItem? = null) :
+    SGraphyItem(parent) {
+    /** 画笔 */
+    val paint = Paint()
+    val innerPaint = Paint()
+    val path = Path()
+
+    init {
+        try {
+//            flags = EnumSet.of(SGraphyItemFlag.ItemIsMovable, SGraphyItemFlag.ItemIsSelectable, SGraphyItemFlag.ItemIsFocusable)
+
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        paint.style = Paint.Style.STROKE
+        paint.strokeJoin = Paint.Join.ROUND
+        paint.isAntiAlias = true
+        paint.color = Color.rgb(0x66, 0x66, 0xff)
+        paint.strokeWidth = 150f
+
+        innerPaint.color = Color.parseColor("#33ffb6c1")
+        innerPaint.isAntiAlias = true
+        innerPaint.style = Paint.Style.FILL
+
+        val data1 = datas[0]
+        val data2 = datas[1]
+        path.moveTo(data1.x, -data1.y)
+        path.lineTo(data1.x, -data2.y)
+        path.lineTo(data2.x, -data2.y)
+        path.lineTo(data2.x, -data1.y)
+        path.close()
+    } // Constructor
+
+    override fun boundingRect(): RectF {
+//        return RectF(data.x - 200f, -data.y - 200f, data.x + 200f, -data.y + 200f)
+        return RectF()
+    }
+
+
+    /**
+     * Item绘制操作
+     *
+     * @param   canvas          画布
+     * @param   rect            绘制区域
+     */
+    override fun onDraw(canvas: Canvas) {
+        canvas.drawPath(path, paint)
+        canvas.drawPath(path, innerPaint)
+    } // Function onDraw()
+
+}

BIN=BIN
cadengine/src/main/res/drawable/equip_notdone.png


BIN=BIN
cadengine/src/main/res/drawable/equip_purple.png


BIN=BIN
cadengine/src/main/res/drawable/img.png


+ 1 - 0
demo/build.gradle

@@ -271,4 +271,5 @@ dependencies {
     debugImplementation 'com.amitshekhar.android:debug-db:1.0.4'
     //屏幕适配
 //    implementation 'me.jessyan:autosize:1.2.1'
+    implementation 'com.rm:rmswitch:1.2.2'
 }

+ 3 - 0
demo/src/main/AndroidManifest.xml

@@ -108,6 +108,9 @@
         <activity
             android:name=".activities.SpaceMapActivity"
             android:exported="true" />
+        <activity
+            android:name=".activities.ServeAreaActivity"
+            android:exported="true" />
     </application>
 
 </manifest>

+ 1 - 1
demo/src/main/java/com/framework/mvvm/model/db/entity/task/ObjectEntity.kt

@@ -84,5 +84,5 @@ data class StrInfosforBuild(
 data class StrInfosforEquip(
     val location: PointZ,
     var zRegion: String,
-    var equipCheck: Boolean
+    var equipCheck: Any
 )

+ 48 - 3
demo/src/main/java/com/sybotan/android/demo/activities/EquipDetailActivity.kt

@@ -3,6 +3,7 @@ package com.sybotan.android.demo.activities
 import android.content.Context
 import android.content.Intent
 import android.graphics.Color
+import android.graphics.PointF
 import android.os.Bundle
 import android.text.TextUtils
 import android.util.Log
@@ -23,6 +24,9 @@ import com.framework.mvvm.model.db.entity.task.*
 import com.framework.mvvm.model.db.entity.dict.EquipmentEntity
 import com.google.gson.Gson
 import com.google.gson.reflect.TypeToken
+import com.rm.rmswitch.RMSwitch
+import com.rm.rmswitch.RMTristateSwitch
+import com.sybotan.android.demo.activities.poc.RelationActivity
 import com.sybotan.android.demo.adapter.PictureAdapter
 import com.sybotan.android.demo.adapter.PipeExpandAdapter
 import com.sybotan.android.demo.adapter.RelationExpandAdapter
@@ -37,6 +41,7 @@ import com.sybotan.android.demo.tools.*
 import com.sybotan.android.demo.tools.LocalDataOperation.*
 import com.sybotan.android.demo.view.*
 import com.sybotan.android.demo.viewmodel.GraphyVM
+import com.sybotan.base.extensions.toInt
 import com.yuyh.library.imgsel.ImageLoader
 import com.yuyh.library.imgsel.ImgSelConfig
 import com.yuyh.library.imgsel.utils.LogUtils
@@ -66,12 +71,14 @@ class EquipDetailActivity : BaseActivity(), View.OnTouchListener {
     private lateinit var localName: ListItemView
     private lateinit var localId: ListItemView
     private lateinit var location: ListItemView
-    private lateinit var doneSwitch: SwitchCompat
+    private lateinit var serveArea: ListItemView
+    private lateinit var doneSwitch: RMTristateSwitch
     private lateinit var height: ListItemView
     private lateinit var locationWhere: ListItemView
     private lateinit var equipClass: ListItemView
     private lateinit var root: NestedScrollView
     private lateinit var btnSubmit: TextView
+    private lateinit var stateName: TextView
     private lateinit var expandLvPipe: SuperExpandableListView
     private lateinit var expandLvRelation: SuperExpandableListView
     private lateinit var pictureAdapter: PictureAdapter
@@ -90,6 +97,9 @@ class EquipDetailActivity : BaseActivity(), View.OnTouchListener {
     private lateinit var floorId: String
     private lateinit var projectId: String
     private lateinit var deviceId: String
+    private lateinit var floorMap: String
+    private var scale: Float = 0f
+    private lateinit var centerPoint: PointF
     private lateinit var uuid: String
 
     /** viewModel */
@@ -122,12 +132,16 @@ class EquipDetailActivity : BaseActivity(), View.OnTouchListener {
         position = bundle?.getSerializable("position") as? Position
         projectId = bundle?.getString("projectId")!!
         deviceId = bundle?.getString("deviceId", "")
+        floorMap = bundle.getString("floorMap")!!
+        scale = bundle.getFloat("scale", 0f)
+        centerPoint = bundle.getParcelable("centerPoint")!!
         uuid = IdGenerator.getId(projectId, IdGenerator.EQUIPMENT)
         recycler = findViewById(R.id.recycler)
         height = findViewById(R.id.height)
         locationWhere = findViewById(R.id.locationWhere)
         equipClass = findViewById(R.id.equipClass)
         location = findViewById(R.id.location)
+        serveArea = findViewById(R.id.serveArea)
         doneSwitch = findViewById(R.id.doneSwitch)
         viewRecycler = findViewById(R.id.viewRecycler)
         mtextContent = findViewById(R.id.mtextContent)
@@ -137,6 +151,7 @@ class EquipDetailActivity : BaseActivity(), View.OnTouchListener {
         btnSubmit = findViewById(R.id.btnSubmit)
         expandLvPipe = findViewById(R.id.expandLvPipe)
         expandLvRelation = findViewById(R.id.expandLvRelation)
+        stateName = findViewById(R.id.stateName)
         expandLvPipe.setGroupIndicator(null)
         expandLvPipe.divider = null
         expandLvRelation.setGroupIndicator(null)
@@ -156,6 +171,19 @@ class EquipDetailActivity : BaseActivity(), View.OnTouchListener {
         height.setTvRight(position!!.z.offset)
         locationWhere.setTvRight(position!!.z.region)
         location.setTvRight("(x=${position!!.x},y=${position!!.y})")
+        doneSwitch.addSwitchObserver { switchView, state ->
+            when (state) {
+                RMSwitch.STATE_LEFT -> {
+                    stateName.setText("待完善")
+                }
+                RMSwitch.STATE_MIDDLE -> {
+                    stateName.setText("")
+                }
+                RMSwitch.STATE_RIGHT -> {
+                    stateName.setText("已完成")
+                }
+            }
+        }
         equipClass.setOnClickListener {
             dialog.show()
         }
@@ -179,7 +207,7 @@ class EquipDetailActivity : BaseActivity(), View.OnTouchListener {
                 equipEntity!!,
                 localNameString.text.toString(),
                 localIdString.text.toString(),
-                doneSwitch.isChecked, position!!
+                doneSwitch.state, position!!
             )
         }
         findViewById<ImageView>(R.id.back).setOnClickListener { finish() }
@@ -190,6 +218,20 @@ class EquipDetailActivity : BaseActivity(), View.OnTouchListener {
                 finish()
             }
         }
+        serveArea.setOnClickListener {
+            val intent = Intent(this, ServeAreaActivity::class.java)
+            val bundle = Bundle()
+            bundle.putString("buildingId", buildingId)
+            bundle.putString("floorId", floorId)
+            bundle.putString("projectId", projectId)
+            bundle.putFloat("scale", scale)
+            bundle.putString("floorMap", floorMap)
+            bundle.putParcelable("centerPoint", centerPoint)
+            val id = if (TextUtils.isEmpty(deviceId)) uuid else deviceId
+            bundle.putString("deviceId", id)
+            intent.putExtra("params", bundle)
+            startActivity(intent)
+        }
     }
 
     //重写onTouch方法
@@ -256,7 +298,10 @@ class EquipDetailActivity : BaseActivity(), View.OnTouchListener {
                         }
                         if (staticInfoAdapter.hashMap != null && staticInfoAdapter.hashMap.get("equipCheck") != null) {
                             val boo = staticInfoAdapter.hashMap.get("equipCheck")
-                            doneSwitch.isChecked = boo!!.toString().equals("true")
+                            if (boo is Double || boo is Int) {
+                                doneSwitch.state =
+                                    staticInfoAdapter.hashMap.get("equipCheck")!!.toInt()!!
+                            }
                         }
                         if (staticInfoAdapter.hashMap != null && staticInfoAdapter.hashMap.get("zRegion") != null) {
                             val zRegion = staticInfoAdapter.hashMap.get("zRegion")

+ 25 - 3
demo/src/main/java/com/sybotan/android/demo/activities/GraphyActivity.kt

@@ -619,7 +619,7 @@ class GraphyActivity : BaseActivity(), ICaptureStatusListener, ICameraChangedCal
                                 2.0
                             ) + Math.pow(Math.abs(y - point.data.mY).toDouble(), 2.0)
                         ).toInt()
-                        if (sqrt < realDistance) {
+                        if (!hasChooseEquip && sqrt < realDistance) {
                             hasChooseEquip = true
                             equipDetail.alpha = 1f
                             equipDelete.alpha = 1f
@@ -644,6 +644,17 @@ class GraphyActivity : BaseActivity(), ICaptureStatusListener, ICameraChangedCal
                                 bundle.putString("floorId", floorId)
                                 bundle.putString("deviceId", point.data.deviceId)
                                 bundle.putString("projectId", projectId)
+                                bundle.putString("floorMap", floorMap)
+                                bundle.putFloat("scale", scene.view!!.scale)
+                                bundle.putParcelable(
+                                    "centerPoint",
+                                    graphyView.mapToScene(
+                                        PointF(
+                                            graphyView.width / 2f,
+                                            graphyView.height / 2f
+                                        )
+                                    )
+                                )
                                 intent.putExtra("equip", bundle)
                                 startActivityForResult(intent, REQUEST_CODE_EQUIP)
                             }
@@ -762,7 +773,7 @@ class GraphyActivity : BaseActivity(), ICaptureStatusListener, ICameraChangedCal
                 } else*/
 
                 //绘制管道业务
-                 if ("pipe".equals(scene.type)) {
+                if ("pipe".equals(scene.type)) {
                     var pipe = PipeLine()
                     var pointf = PointF()
                     pointf.x = x
@@ -779,7 +790,7 @@ class GraphyActivity : BaseActivity(), ICaptureStatusListener, ICameraChangedCal
                         scene.addItem(item)
                     }
 
-                }  else if ("equip".equals(scene.type)) {
+                } else if ("equip".equals(scene.type)) {
                     scene.point.mX = x
                     scene.point.mY = y
 
@@ -1062,6 +1073,17 @@ class GraphyActivity : BaseActivity(), ICaptureStatusListener, ICameraChangedCal
                 bundle.putString("buildingId", buildingId)
                 bundle.putString("floorId", floorId)
                 bundle.putString("projectId", projectId)
+                bundle.putString("floorMap", floorMap)
+                bundle.putFloat("scale", scene.view!!.scale)
+                bundle.putParcelable(
+                    "centerPoint",
+                    graphyView.mapToScene(
+                        PointF(
+                            graphyView.width / 2f,
+                            graphyView.height / 2f
+                        )
+                    )
+                )
                 intent.putExtra("equip", bundle)
                 startActivityForResult(intent, REQUEST_CODE_EQUIP)
             }

+ 271 - 0
demo/src/main/java/com/sybotan/android/demo/activities/ServeAreaActivity.kt

@@ -0,0 +1,271 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *               iFHS7.
+ *              ;BBMBMBMc                  rZMBMBR              BMB
+ *              MBEr:;PBM,               7MBMMEOBB:             BBB                       RBW
+ *     XK:      BO     SB.     :SZ       MBM.       c;;     ir  BBM :FFr       :SSF:    ;xBMB:r   iuGXv.    i:. iF2;
+ *     DBBM0r.  :D     S7   ;XMBMB       GMBMu.     MBM:   BMB  MBMBBBMBMS   WMBMBMBBK  MBMBMBM  BMBRBMBW  .MBMBMBMBB
+ *      :JMRMMD  ..    ,  1MMRM1;         ;MBMBBR:   MBM  ;MB:  BMB:   MBM. RMBr   sBMH   BM0         UMB,  BMB.  KMBv
+ *     ;.   XOW  B1; :uM: 1RE,   i           .2BMBs  rMB. MBO   MBO    JMB; MBB     MBM   BBS    7MBMBOBM:  MBW   :BMc
+ *     OBRJ.SEE  MRDOWOR, 3DE:7OBM       .     ;BMB   RMR7BM    BMB    MBB. BMB    ,BMR  .BBZ   MMB   rMB,  BMM   rMB7
+ *     :FBRO0D0  RKXSXPR. JOKOOMPi       BMBSSWBMB;    BMBB:    MBMB0ZMBMS  .BMBOXRBMB    MBMDE RBM2;SMBM;  MBB   xBM2
+ *         iZGE  O0SHSPO. uGZ7.          sBMBMBDL      :BMO     OZu:BMBK,     rRBMB0;     ,EBMB  xBMBr:ER.  RDU   :OO;
+ *     ,BZ, 1D0  RPSFHXR. xWZ .SMr                  . .BBB
+ *      :0BMRDG  RESSSKR. 2WOMBW;                   BMBMR
+ *         i0BM: SWKHKGO  MBDv
+ *           .UB  OOGDM. MK,                                          Copyright (c) 2015-2019.  斯伯坦机器人
+ *              ,  XMW  ..
+ *                  r                                                                     All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+package com.sybotan.android.demo.activities
+
+import android.annotation.SuppressLint
+import android.graphics.Color
+import android.graphics.PointF
+import android.os.Bundle
+import android.widget.TextView
+import android.widget.Toast
+import android.widget.*
+import androidx.appcompat.widget.AppCompatEditText
+import androidx.appcompat.widget.LinearLayoutCompat
+import androidx.core.content.ContextCompat
+import androidx.recyclerview.widget.GridLayoutManager
+import cn.sagacloud.android.cadengine.FloorScene
+import cn.sagacloud.android.cadengine.Lasso
+import cn.sagacloud.android.cadengine.Opt
+import cn.sagacloud.android.cadengine.items.*
+import cn.sagacloud.android.cadengine.types.*
+import cn.sagacloud.android.cadengine.types.Space
+import com.bumptech.glide.Glide
+import com.google.gson.Gson
+import com.google.gson.JsonArray
+import com.google.gson.JsonElement
+import com.google.gson.JsonObject
+import com.google.gson.reflect.TypeToken
+import com.sybotan.android.demo.R
+import com.sybotan.android.demo.adapter.PictureAdapter
+import com.sybotan.android.demo.bean.result.*
+import com.sybotan.android.demo.graphy.GraphyHelper
+import com.sybotan.android.demo.retrofit.Constant
+import com.sybotan.android.demo.tools.*
+import com.sybotan.android.demo.view.MaxHeightRecyclerView
+import com.sybotan.android.demo.viewmodel.GraphyVM
+import com.sybotan.android.demo.viewmodel.SpaceMapVM
+import com.sybotan.android.graphy.SGraphyView
+import com.yuyh.library.imgsel.ImageLoader
+import com.yuyh.library.imgsel.ImgSelConfig
+import com.zbar.lib.CaptureActivity
+import io.reactivex.ObservableEmitter
+import org.jetbrains.anko.doAsync
+import org.jetbrains.anko.uiThread
+import org.json.JSONException
+import org.json.JSONObject
+import org.kodein.di.DI
+import org.kodein.di.DIAware
+import org.kodein.di.android.closestDI
+import java.io.*
+import java.util.*
+import kotlin.collections.ArrayList
+import kotlin.math.abs
+import kotlin.math.pow
+import kotlin.math.sqrt
+
+/**
+ * 设备服务区域绘制
+ */
+class ServeAreaActivity : BaseActivity(), DIAware {
+
+    override val di: DI by closestDI()
+
+    /** viewModel */
+    lateinit var spaceMapVM: SpaceMapVM
+
+    /** 建筑Id */
+    private lateinit var buildingId: String
+
+    /** 楼层Id */
+    private lateinit var floorId: String
+    private lateinit var projectId: String
+    private lateinit var deviceId: String
+    private var scale: Float = 0f
+    private lateinit var area: ServeAreaItem
+    private lateinit var centerPoint: PointF
+
+    /** 楼层地图 */
+    private lateinit var floorMap: String
+
+    val scene = FloorScene()
+    private val gson = Gson()
+    private var hasMove = false
+    private val points = ArrayList<PointF>()
+    private val items = ArrayList<AreaNodeItem>()
+
+    private lateinit var graphyView: SGraphyView
+    private lateinit var close: TextView
+    private lateinit var save: TextView
+    val graphyHelper: GraphyHelper = GraphyHelper(scene, this)
+
+    /**
+     * 创建Activity时的回调函数
+     *
+     * @param   savedInstanceState
+     */
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_serve_area)
+        initView()
+
+        /** 初始化数据 */
+        initData()
+        graphyView.scene = scene
+
+        /** 点击监听 */
+        initListener()
+        /** 图形点击-poc业务 */
+        initSingleTopUp()
+        /** 网络请求回调处理 */
+        initViewModel()
+
+        return
+    } // Function onCreate()
+
+
+    private fun initView() {
+        graphyView = findViewById(R.id.graphyView)
+        close = findViewById(R.id.close)
+        save = findViewById(R.id.save)
+    }
+
+    /**
+     * 初始化数据
+     */
+    private fun initData() {
+        val floor = intent.getBundleExtra("params")!!
+        buildingId = floor.getString("buildingId", "")!!
+        floorId = floor.getString("floorId", "")!!
+        floorMap = floor.getString("floorMap", "")!!
+        projectId = floor.getString("projectId", "")!!
+        deviceId = floor.getString("deviceId", "")!!
+        scale = floor.getFloat("scale")!!
+        centerPoint = floor.getParcelable("centerPoint")!!
+    }
+
+
+    /**
+     * 图形点击事件
+     * */
+    private fun initSingleTopUp() {
+        scene.setOnSingleTopUp(object : FloorScene.OnSingleTopUp {
+            @SuppressLint("SetJavaScriptEnabled")
+            override fun onSingUp(x: Float, y: Float) {
+                if (points.size < 2) {
+                    val point = PointF(x, -y)
+                    points.add(point)
+                    val item = AreaNodeItem(point)
+                    item.zOrder = 100000f
+                    scene.addItem(item)
+                    items.add(item)
+                    item.setOnScrollListener(object : AreaNodeItem.OnScroll {
+                        override fun onScroll(x: Float, y: Float) {
+                            hasMove = true
+                            scene.removeItem(area)
+                            val newData = ArrayList<PointF>()
+                            for (it in items) {
+                                newData.add(PointF(it.x, it.y))
+                            }
+                            area = ServeAreaItem(newData)
+                            area.zOrder = 100000f
+                            scene.addItem(area)
+                        }
+                    })
+                }
+                if (points.size == 2 && !hasMove) {
+                    area = ServeAreaItem(points)
+                    area.zOrder = 100000f
+                    scene.addItem(area)
+                }
+            }
+        })
+    }
+
+    /**
+     * 页面全部监听事件
+     */
+    private fun initListener() {
+        close.setOnClickListener { finish() }
+        save.setOnClickListener { spaceMapVM.insServeArea() }
+
+    }
+
+    /**
+     * 初始化viewModel
+     */
+    private fun initViewModel() {
+        spaceMapVM = SpaceMapVM(this.application, { name, params ->
+            when (name) {
+                /** 加载地图 */
+                SpaceMapVM.MAP_LOAD -> {
+                    val floorOfflineData = gson.fromJson(params.toString(), FloorData::class.java)
+                    doAsync {
+                        scene.loadData(floorOfflineData)
+                        uiThread {
+                            graphyView.setCenterPoint(centerPoint, scale)
+//                            graphyView.setCenterPoint(PointF(1f,1f), 0f)
+                        }
+                    }
+//                    graphyView.fitSceneToView()
+                }
+                /** 查询空间和任务 */
+                GraphyVM.SPACE_JOB -> {
+                    for (item in scene.tunableSpaceList) {
+                        scene.removeItem(item)
+                    }
+                    scene.tunableSpaceList.clear()
+                    val list = params as (List<SpaceJobModel>)
+                    for (model in list) {
+                        if (model.outline != null && !model.outline!!.isEmpty()) {
+                            val space = Space()
+                            space.outLine = model.outline.get(0)
+                            space.name = model.name
+                            val nameItem = SpaceNameItem(space)
+                            nameItem.zOrder = 99999f
+                            nameItem.isVisible = scene.isShowSpace
+                            scene.spaceNameList.add(nameItem)
+                            scene.addItem(nameItem)
+
+                            val tunableSpace = TunableSpace()
+                            tunableSpace.apply {
+                                outLine = model.outline.get(0)
+                                objectEntity = gson.toJson(model.objectEntity)
+                                this.name = model.name
+                                jobStatus = model.job
+                                id = model.id
+                                localName = model.localName
+                            }
+                            val item = TunableSpaceItem(tunableSpace, null)
+                            scene.choseSpace?.let {
+                                if (tunableSpace.id.equals(scene.choseSpace!!.data.id)) {
+                                    item.paint.color = Opt.spaceChoseColor
+                                    item.outPaint.color = Color.rgb(0xbd, 0xe8, 0xfe)
+                                }
+                            }
+                            item.isVisible = true
+                            item.zOrder = 99996f
+                            scene.tunableSpaceList.add(item)
+                            scene.addItem(item)
+                        }
+                    }
+                }
+
+            }
+        }, this, buildingId, floorId, projectId)
+        spaceMapVM.getMap()
+//        spaceMapVM.getSpaceJob()
+    }
+
+
+} // Class GraphyActivity

+ 7 - 7
demo/src/main/java/com/sybotan/android/demo/activities/SpaceDetailActivity.kt

@@ -24,7 +24,7 @@ import com.sybotan.android.demo.tools.LocalDataOperation
 import com.sybotan.android.demo.tools.PictureUtils
 import com.sybotan.android.demo.tools.ToastUtils
 import com.sybotan.android.demo.tools.UploadImage
-import com.sybotan.android.demo.viewmodel.GraphyVM
+import com.sybotan.android.demo.viewmodel.SpaceDetailVM
 import com.yuyh.library.imgsel.ImageLoader
 import com.yuyh.library.imgsel.ImgSelConfig
 import io.reactivex.ObservableEmitter
@@ -56,7 +56,7 @@ class SpaceDetailActivity : BaseActivity() {
     private val REQUEST_CODE_PIC = 0X102
 
     /** viewModel */
-    lateinit var graphyVM: GraphyVM
+    lateinit var spaceVM: SpaceDetailVM
     var list = ArrayList<Infos>()
 
     // 自定义图片加载器
@@ -86,13 +86,13 @@ class SpaceDetailActivity : BaseActivity() {
             this.info = it
         }
         recycler.adapter = staticInfoAdapter
-        graphyVM = GraphyVM(this.application, { name, params ->
+        spaceVM = SpaceDetailVM(this.application, { name, params ->
             when (name) {
-                GraphyVM.SPACE_INFO -> {
+                SpaceDetailVM.SPACE_INFO -> {
                     list.addAll(params as ArrayList<Infos>)
                     staticInfoAdapter.notifyDataSetChanged()
                 }
-                GraphyVM.SPACE_INFOS -> {
+                SpaceDetailVM.SPACE_INFOS -> {
                     if (params != null) {
                         staticInfoAdapter.hashMap = params as HashMap<String, Any>?
                         if (staticInfoAdapter.hashMap != null && staticInfoAdapter.hashMap.get("Photos") != null) {
@@ -106,7 +106,7 @@ class SpaceDetailActivity : BaseActivity() {
                 }
             }
         }, this, buildingId, floorId, projectId)
-        graphyVM.getInfosConfig(spaceId)
+        spaceVM.getInfosConfig(spaceId)
     }
 
     private fun initView() {
@@ -122,7 +122,7 @@ class SpaceDetailActivity : BaseActivity() {
         recycler.layoutManager = LinearLayoutManager(this)
         staticInfoAdapter = StaticInfoAdapter(this, list)
         btnSubmit.setOnClickListener {
-            graphyVM.refreshObject(space, staticInfoAdapter.hashMap)
+            spaceVM.refreshObject(space, staticInfoAdapter.hashMap)
         }
         findViewById<ImageView>(R.id.back).setOnClickListener { finish() }
     }

+ 90 - 9
demo/src/main/java/com/sybotan/android/demo/activities/SpaceMapActivity.kt

@@ -48,6 +48,9 @@ import cn.sagacloud.android.cadengine.types.*
 import cn.sagacloud.android.cadengine.types.Space
 import com.bumptech.glide.Glide
 import com.google.gson.Gson
+import com.google.gson.JsonArray
+import com.google.gson.JsonElement
+import com.google.gson.JsonObject
 import com.google.gson.reflect.TypeToken
 import com.sybotan.android.demo.R
 import com.sybotan.android.demo.adapter.PictureAdapter
@@ -122,6 +125,7 @@ class SpaceMapActivity : BaseActivity(), DIAware {
      */
     private val problemDot = Point()
     var addPoint: PointItem? = null
+    var oprateItem: PointItem? = null
 
     /**
      * 问题图片列表
@@ -315,10 +319,12 @@ class SpaceMapActivity : BaseActivity(), DIAware {
                 //查看模式下,判断问题点选中逻辑
                 if ("normal" == scene.type) {
                     realDistance = distance * scene.defaultPointScale / graphyView.scale
+                    removeDrawingLine()
+                    scene.drawingPipeItemList.clear()
                     var hasChoose = false
                     for (point in scene.pointItemList) {
                         if (!CommonUtils.IsNull(point.data.points.size) && point.data.points.size > 1) {
-                            val dist = 500.00
+                            var dist = 500.00
                             for (index in 0..point.data.points.size - 2) {
                                 val point1 = point.data.points[index]
                                 val point2 = point.data.points[index + 1]
@@ -326,6 +332,10 @@ class SpaceMapActivity : BaseActivity(), DIAware {
                                 //point3到(point1与point2的连线)的最短距离
                                 val h = Lasso.beeline(point1, point2, point3)
                                 if (h < dist) {
+                                    if (oprateItem != null) {
+                                        scene.addItem(oprateItem!!)
+                                        oprateItem = null
+                                    }
                                     hasChoose = true
                                     problemRg.visibility = View.GONE
                                     lineRb.setOnCheckedChangeListener { _, _ ->
@@ -343,10 +353,34 @@ class SpaceMapActivity : BaseActivity(), DIAware {
                                         item.isVisible = true
                                         item.zOrder = 100000f
                                         scene.drawingPipeItemList.add(item)
-
+                                        val pipeNodeItem = graphyHelper.addPipeNode(pointf)
+                                        pipeNodeItem.setOnScrollListener(object :
+                                            PipeNodeItem.OnScroll {
+                                            override fun onScroll(x: Float, y: Float) {
+                                                this@SpaceMapActivity.oprateItem = point
+                                                scene.removeItem(point)
+                                                for (item in scene.drawingPipeItemList) {
+                                                    scene.removeItem(item)
+                                                }
+                                                for (item in scene.pipeItemList) {
+                                                    scene.removeItem(item)
+                                                }
+                                                scene.drawingPipeItemList.clear()
+                                                val newData = PipeLine()
+                                                for (node in scene.pipeNodeList) {
+                                                    val po = PointF()
+                                                    po.x = node.x
+                                                    po.y = node.y
+                                                    newData.points!!.add(po)
+                                                }
+                                                val item = PipeLineItem(newData, null)
+                                                scene.drawingPipeItemList.add(item)
+                                                graphyHelper.addPipeline(newData)
+                                            }
+                                        })
                                     }
                                     showDotDetail(point)
-                                    break
+                                    return
 
                                 }
 
@@ -363,6 +397,7 @@ class SpaceMapActivity : BaseActivity(), DIAware {
 
                                 }
                                 pointRb.isChecked = true
+                                spaceMapVM.getProblem(scene.choseSpace)
                                 showDotDetail(point)
                                 break
                             }
@@ -468,6 +503,28 @@ class SpaceMapActivity : BaseActivity(), DIAware {
                         itemPipe.zOrder = 100000f
                         scene.addItem(itemPipe)
                     }
+                    val pipeNodeItem = graphyHelper.addPipeNode(pointf)
+                    pipeNodeItem.setOnScrollListener(object : PipeNodeItem.OnScroll {
+                        override fun onScroll(x: Float, y: Float) {
+                            for (item in scene.drawingPipeItemList) {
+                                scene.removeItem(item)
+                            }
+                            for (item in scene.pipeItemList) {
+                                scene.removeItem(item)
+                            }
+                            scene.drawingPipeItemList.clear()
+                            val newData = PipeLine()
+                            for (node in scene.pipeNodeList) {
+                                val po = PointF()
+                                po.x = node.x
+                                po.y = node.y
+                                newData.points!!.add(po)
+                            }
+                            val item = PipeLineItem(newData, null)
+                            scene.drawingPipeItemList.add(item)
+                            graphyHelper.addPipeline(newData)
+                        }
+                    })
 
                     //绘制二维码
                 } else if ("qrcode" == scene.type) {
@@ -498,8 +555,7 @@ class SpaceMapActivity : BaseActivity(), DIAware {
                         spaceMapVM.getProblem(scene.choseSpace)
                         /** 跳转空间详情 */
                         addSpaceDetail.setOnClickListener {
-                            val intent =
-                                Intent(this@SpaceMapActivity, SpaceDetailActivity::class.java)
+                            val intent = Intent(this@SpaceMapActivity, SpaceDetailActivity::class.java)
                             val bundle = Bundle()
                             bundle.putString("buildingId", buildingId)
                             bundle.putString("floorId", floorId)
@@ -518,8 +574,7 @@ class SpaceMapActivity : BaseActivity(), DIAware {
                         }
                         /** 跳转空间详情 */
                         addSpaceDetail2.setOnClickListener {
-                            val intent =
-                                Intent(this@SpaceMapActivity, SpaceDetailActivity::class.java)
+                            val intent = Intent(this@SpaceMapActivity, SpaceDetailActivity::class.java)
                             val bundle = Bundle()
                             bundle.putString("buildingId", buildingId)
                             bundle.putString("floorId", floorId)
@@ -610,8 +665,12 @@ class SpaceMapActivity : BaseActivity(), DIAware {
                     for (item in scene.drawingPipeItemList) {
                         scene.removeItem(item)
                     }
-                    scene.pipeLineList.clear()
                     scene.drawingPipeItemList.clear()
+                    for (item in scene.pipeNodeList) {
+                        scene.removeItem(item)
+                    }
+                    scene.pipeNodeList.clear()
+                    scene.pipeLineList.clear()
                 }
             }
             //画线
@@ -885,6 +944,7 @@ class SpaceMapActivity : BaseActivity(), DIAware {
                     }
                 }
                 spaceMapVM.getSpaceJob()
+                removeDrawingLine()
             }
         }
 
@@ -897,8 +957,13 @@ class SpaceMapActivity : BaseActivity(), DIAware {
             for (item in scene.drawingPipeItemList) {
                 scene.removeItem(item)
             }
+            if (oprateItem != null) {
+                scene.addItem(oprateItem!!)
+                oprateItem = null
+            }
             scene.drawingPipeItemList.clear()
             scene.pipeLineList.clear()
+            removeDrawingLine()
             scene.type = "normal"
             problemLl.visibility = View.GONE
             spaceStructure.visibility = View.VISIBLE
@@ -911,7 +976,7 @@ class SpaceMapActivity : BaseActivity(), DIAware {
                 return@setOnClickListener
             }
             if (point == null) {
-                if (lineRb.isChecked && (CommonUtils.IsNull(scene.drawingPipeItemList) || scene.drawingPipeItemList.size == 1)) {
+                if (lineRb.isChecked && (CommonUtils.IsNull(scene.drawingPipeItemList) || (scene.drawingPipeItemList.size == 1 && scene.drawingPipeItemList[0].data.points.size <= 1))) {
                     ToastUtils.showMyToast("请扎点")
                     return@setOnClickListener
                 }
@@ -930,6 +995,8 @@ class SpaceMapActivity : BaseActivity(), DIAware {
                 scene.removeItem(item)
             }
             scene.pipeLineList.clear()
+            removeDrawingLine()
+            oprateItem = null
             scene.drawingPipeItemList.clear()
             scene.type = "normal"
             problemLl.visibility = View.GONE
@@ -937,6 +1004,20 @@ class SpaceMapActivity : BaseActivity(), DIAware {
     }
 
     /**
+     * 清空正在绘制的线型问题
+     */
+    private fun removeDrawingLine() {
+        for (item in scene.pipeNodeList) {
+            scene.removeItem(item)
+        }
+        scene.pipeNodeList.clear()
+        for (item in scene.pipeItemList) {
+            scene.removeItem(item)
+        }
+        scene.pipeItemList.clear()
+    }
+
+    /**
      * 回调
      */
     override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {

+ 1 - 1
demo/src/main/java/com/sybotan/android/demo/bean/result/Children.java

@@ -13,6 +13,6 @@ public class Children {
     public String name;
     public String position;
     public String remark;
-    //1-蓝 2-绿 3-红
+    //1-蓝 2-绿 3-红 4-黄 5-紫
     public int type;
 }

+ 40 - 17
demo/src/main/java/com/sybotan/android/demo/viewmodel/GraphyVM.kt

@@ -6,8 +6,6 @@ import android.graphics.PointF
 import android.text.TextUtils
 import androidx.lifecycle.viewModelScope
 import cn.sagacloud.android.cadengine.Lasso
-import cn.sagacloud.android.cadengine.items.PipeLineItem
-import cn.sagacloud.android.cadengine.items.PointItem
 import cn.sagacloud.android.cadengine.items.SpaceItem
 import cn.sagacloud.android.cadengine.items.TunableSpaceItem
 import cn.sagacloud.android.cadengine.types.*
@@ -17,9 +15,9 @@ import com.framework.mvvm.model.db.entity.dict.EquipmentEntity
 import com.framework.mvvm.model.db.entity.dict.PipeConfigEntity
 import com.framework.mvvm.model.db.entity.dict.RelConfigEntity
 import com.framework.mvvm.model.repository.AdmRepository
-import com.sybotan.android.demo.bean.result.ProblemsModel
 import com.google.gson.Gson
 import com.google.gson.reflect.TypeToken
+import com.rm.rmswitch.RMTristateSwitch
 import com.sybotan.android.demo.activities.BaseActivity
 import com.sybotan.android.demo.bean.request.*
 import com.sybotan.android.demo.bean.result.*
@@ -32,16 +30,15 @@ import com.sybotan.android.demo.tools.CommonUtils
 import com.sybotan.android.demo.tools.ToastUtils
 import com.sybotan.base.utils.SJsonUtil
 import kotlinx.coroutines.launch
-import org.json.JSONObject
 import org.kodein.di.DI
 import org.kodein.di.DIAware
 import org.kodein.di.android.x.closestDI
 import org.kodein.di.instance
-import java.text.SimpleDateFormat
 import java.util.*
 import kotlin.collections.ArrayList
 import kotlin.collections.HashMap
 import com.sybotan.android.demo.bean.*
+import com.sybotan.base.extensions.toInt
 
 
 /**
@@ -203,12 +200,25 @@ class GraphyVM(
                         child.name = equip.name
                         val strInfo = gson.fromJson(equip.strInfos, StrInfosforEquip::class.java)
                         val eqProblems = repo.getEqProblem(equip.id)
-                        if (eqProblems != null && !TextUtils.isEmpty(eqProblems.id)) {
-                            child.type = 3
-                        } else if (strInfo.equipCheck) {
-                            child.type = 2
+                        //1-蓝 2-绿 3-红
+                        if (eqProblems == null || TextUtils.isEmpty(eqProblems.id)) {
+                            if (strInfo.equipCheck is Double || strInfo.equipCheck is Int) {
+                                when {
+                                    strInfo.equipCheck.toInt() == RMTristateSwitch.STATE_LEFT -> {
+                                        child.type = 5
+                                    }
+                                    strInfo.equipCheck.toInt() == RMTristateSwitch.STATE_MIDDLE -> {
+                                        child.type = 1
+                                    }
+                                    strInfo.equipCheck.toInt() == RMTristateSwitch.STATE_RIGHT -> {
+                                        child.type = 2
+                                    }
+                                }
+                            } else {
+                                child.type = 1
+                            }
                         } else {
-                            child.type = 1
+                            child.type = 3
                         }
                         val position = Position()
                         position.x = strInfo.location.x.toString()
@@ -231,12 +241,25 @@ class GraphyVM(
                     child.name = equip.name
                     val strInfo = gson.fromJson(equip.strInfos, StrInfosforEquip::class.java)
                     val eqProblems = repo.getEqProblem(equip.id)
-                    if (eqProblems != null && !TextUtils.isEmpty(eqProblems.id)) {
-                        child.type = 3
-                    } else if (strInfo.equipCheck) {
-                        child.type = 2
+                    if (eqProblems == null || TextUtils.isEmpty(eqProblems.id)) {
+                        //type 1-蓝 2-绿 3-红 4-黄 5-紫
+                        if (strInfo.equipCheck is Double || strInfo.equipCheck is Int) {
+                            when {
+                                strInfo.equipCheck.toInt() == RMTristateSwitch.STATE_LEFT -> {
+                                    child.type = 5
+                                }
+                                strInfo.equipCheck.toInt() == RMTristateSwitch.STATE_MIDDLE -> {
+                                    child.type = 1
+                                }
+                                strInfo.equipCheck.toInt() == RMTristateSwitch.STATE_RIGHT -> {
+                                    child.type = 2
+                                }
+                            }
+                        } else {
+                            child.type = 1
+                        }
                     } else {
-                        child.type = 1
+                        child.type = 3
                     }
                     val position = Position()
                     position.x = strInfo.location.x.toString()
@@ -419,14 +442,14 @@ class GraphyVM(
         equipEntity: EquipmentEntity,
         localName: String,
         localId: String,
-        checked: Boolean,
+        checked: Int,
         position: Position
     ) {
         viewModelScope.launch {
             val objects = repo.getObjects()
             if (!CommonUtils.IsNull(objects)) {
                 for (obj in objects) {
-                    if (!TextUtils.isEmpty(obj.localId) && obj.localId!!.toUpperCase()
+                    if (deviceId != obj.id && !TextUtils.isEmpty(obj.localId) && obj.localId!!.toUpperCase()
                             .equals(localId.toUpperCase())
                     ) {
                         ToastUtils.showMyToast("已有此编码的设备")

+ 81 - 0
demo/src/main/java/com/sybotan/android/demo/viewmodel/SpaceDetailVM.kt

@@ -0,0 +1,81 @@
+package com.sybotan.android.demo.viewmodel
+
+import android.app.Activity.RESULT_OK
+import android.app.Application
+import androidx.lifecycle.viewModelScope
+import cn.sagacloud.android.cadengine.types.*
+import com.framework.mvvm.model.db.entity.*
+import com.framework.mvvm.model.db.entity.task.Infos
+import com.framework.mvvm.model.repository.AdmRepository
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.sybotan.android.demo.activities.BaseActivity
+import com.sybotan.android.demo.retrofit.BaseViewModelInterface
+import kotlinx.coroutines.launch
+import org.kodein.di.DI
+import org.kodein.di.DIAware
+import org.kodein.di.android.x.closestDI
+import org.kodein.di.instance
+import kotlin.collections.HashMap
+
+
+/**
+ * Created by lihao.
+ * Date: 2021/6/9
+ * 空间详情
+ */
+class SpaceDetailVM(
+    app: Application,
+    b: BaseViewModelInterface?, activity: BaseActivity?, //建筑id
+    private val buildingId: String, //楼层id
+    private val floorId: String,
+    private val projectId: String
+) : BaseViewModel(app, b, activity), DIAware {
+    private val gson = Gson()
+
+    override val di: DI by closestDI()
+    private val repo: AdmRepository by instance()
+
+    /**
+     * SPACE_INFO 静态信息点配置
+     * SPACE_INFOS 对象静态信息的值
+     */
+    fun getInfosConfig(spaceId: String) {
+        viewModelScope.launch {
+            val infosConfig = repo.getInfosConfigByObjType("space")
+            val strInfos = infosConfig[0].strInfos
+            val infoList = gson.fromJson<List<Infos>>(
+                strInfos,
+                object : TypeToken<List<Infos?>?>() {}.type
+            )
+            val spaceObject = repo.getObject(spaceId)
+            val infos = gson.fromJson(spaceObject!!.strInfos, HashMap::class.java)
+            mEmitter.SendDircetive(SPACE_INFOS, infos)
+            mEmitter.SendDircetive(SPACE_INFO, infoList)
+        }
+    }
+
+    /**
+     * 更新空间信息点值
+     */
+    fun refreshObject(space: TunableSpace, hashMap: HashMap<String, Any>) {
+        viewModelScope.launch {
+            val spaceObj = repo.getObject(space.id!!)
+            spaceObj!!.strInfos = gson.toJson(hashMap)
+            spaceObj.state = "1"
+            repo.insObject(spaceObj)
+            mActivity.setResult(RESULT_OK)
+            mActivity.finish()
+        }
+    }
+
+
+    companion object {
+        //静态信息点配置
+        const val SPACE_INFO = "SPACE_INFO"
+
+        //对象静态信息点值
+        const val SPACE_INFOS = "SPACE_INFOS"
+    }
+
+}

+ 5 - 1
demo/src/main/java/com/sybotan/android/demo/viewmodel/SpaceMapVM.kt

@@ -238,7 +238,7 @@ class SpaceMapVM(
                     val promodel = ProblemsModel()
                     promodel.content = problem.message
                     promodel.floorId = floorId
-                    promodel.spaceId = choseSpace!!.data.id
+//                    promodel.spaceId = choseSpace!!.data.id
                     promodel.id = problem.id
 
                     val geomList = gson.fromJson<List<PointF>>(
@@ -401,6 +401,10 @@ class SpaceMapVM(
         }
     }
 
+    fun insServeArea() {
+
+    }
+
 
     companion object {
         const val MAP_LOAD = "MAP_LOAD"

+ 37 - 7
demo/src/main/res/layout/activity_equip_detail.xml

@@ -42,19 +42,20 @@
             app:Type="0" />
 
         <com.sybotan.android.demo.view.ListItemView
-            android:visibility="gone"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:visibility="gone"
             app:LeftText="现场记录"
             app:Type="4" />
 
         <com.sybotan.android.demo.view.ListItemView
-            android:visibility="gone"
             android:id="@+id/localName"
             android:layout_width="match_parent"
             android:layout_height="44dp"
             android:layout_marginTop="10dp"
+            android:visibility="gone"
             app:Type="1" />
+
         <com.sybotan.android.demo.view.ListItemView
             android:id="@+id/localId"
             android:layout_width="match_parent"
@@ -64,6 +65,13 @@
 
         <include layout="@layout/view_mtext" />
 
+        <com.sybotan.android.demo.view.ListItemView
+            android:id="@+id/serveArea"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            app:LeftText="对象服务区域"
+            app:Type="0" />
+
         <include layout="@layout/view_picture" />
 
         <LinearLayout
@@ -81,12 +89,34 @@
                 android:textColor="@color/gray_272727"
                 android:textSize="15sp" />
 
-            <androidx.appcompat.widget.SwitchCompat
-                android:id="@+id/doneSwitch"
+            <TextView
+                android:id="@+id/stateName"
                 android:layout_width="wrap_content"
-                android:layout_height="match_parent"
-                android:paddingLeft="10dp"
-                android:paddingRight="16dp" />
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="16sp"
+                android:layout_marginRight="5dp"
+                android:text=""
+                android:textColor="@color/gray_272727"
+                android:textSize="15sp" />
+
+            <com.rm.rmswitch.RMTristateSwitch
+                android:id="@+id/doneSwitch"
+                android:layout_width="60dp"
+                android:layout_height="30dp"
+                android:layout_marginRight="16dp"
+                app:enabled="true"
+                app:forceAspectRatio="false"
+                app:state="middle"
+                app:switchBkgLeftColor="@color/red_200"
+                app:switchBkgMiddleColor="@color/grey_200"
+                app:switchBkgRightColor="@color/green_200"
+                app:switchDesign="large"
+                app:switchToggleLeftColor="@color/red_200"
+                app:switchToggleLeftImage="@mipmap/icon_wrong"
+                app:switchToggleMiddleColor="@color/grey_200"
+                app:switchToggleMiddleImage="@drawable/ic_uncheck"
+                app:switchToggleRightColor="@color/green_200"
+                app:switchToggleRightImage="@drawable/ic_checked" />
         </LinearLayout>
 
         <include layout="@layout/static_info" />

+ 114 - 0
demo/src/main/res/layout/activity_serve_area.xml

@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ *********************************************************************************************************************
+  ~
+  ~               iFHS7.
+  ~              ;BBMBMBMc                  rZMBMBR              BMB
+  ~              MBEr:;PBM,               7MBMMEOBB:             BBB                       RBW
+  ~     XK:      BO     SB.     :SZ       MBM.       c;;     ir  BBM :FFr       :SSF:    ;xBMB:r   iuGXv.    i:. iF2;
+  ~     DBBM0r.  :D     S7   ;XMBMB       GMBMu.     MBM:   BMB  MBMBBBMBMS   WMBMBMBBK  MBMBMBM  BMBRBMBW  .MBMBMBMBB
+  ~      :JMRMMD  ..    ,  1MMRM1;         ;MBMBBR:   MBM  ;MB:  BMB:   MBM. RMBr   sBMH   BM0         UMB,  BMB.  KMBv
+  ~     ;.   XOW  B1; :uM: 1RE,   i           .2BMBs  rMB. MBO   MBO    JMB; MBB     MBM   BBS    7MBMBOBM:  MBW   :BMc
+  ~     OBRJ.SEE  MRDOWOR, 3DE:7OBM       .     ;BMB   RMR7BM    BMB    MBB. BMB    ,BMR  .BBZ   MMB   rMB,  BMM   rMB7
+  ~     :FBRO0D0  RKXSXPR. JOKOOMPi       BMBSSWBMB;    BMBB:    MBMB0ZMBMS  .BMBOXRBMB    MBMDE RBM2;SMBM;  MBB   xBM2
+  ~         iZGE  O0SHSPO. uGZ7.          sBMBMBDL      :BMO     OZu:BMBK,     rRBMB0;     ,EBMB  xBMBr:ER.  RDU   :OO;
+  ~     ,BZ, 1D0  RPSFHXR. xWZ .SMr                  . .BBB
+  ~      :0BMRDG  RESSSKR. 2WOMBW;                   BMBMR
+  ~         i0BM: SWKHKGO  MBDv
+  ~           .UB  OOGDM. MK,                                          Copyright (c) 2015-2019.  斯伯坦机器人
+  ~              ,  XMW  ..
+  ~                  r                                                                     All rights reserved.
+  ~
+  ~ *********************************************************************************************************************
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/white"
+    android:orientation="vertical"
+    tools:context="com.sybotan.android.demo.activities.GraphyActivity">
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1">
+
+        <com.sybotan.android.graphy.SGraphyView
+            android:id="@+id/graphyView"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_marginBottom="5dp" />
+
+    </RelativeLayout>
+
+    <androidx.appcompat.widget.LinearLayoutCompat
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:paddingTop="20dp"
+        android:paddingBottom="20dp">
+
+        <RadioGroup
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center_horizontal"
+            android:orientation="horizontal">
+
+            <RadioButton
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:checked="true"
+                android:paddingLeft="10dp"
+                android:text="矩形"
+                android:textColor="@color/black_272727"
+                android:textSize="16sp" />
+
+            <RadioButton
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="40dp"
+                android:paddingLeft="10dp"
+                android:text="圆形"
+                android:textColor="@color/black_272727"
+                android:textSize="16sp" />
+        </RadioGroup>
+
+        <androidx.appcompat.widget.LinearLayoutCompat
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="20dp"
+            android:layout_marginTop="20dp"
+            android:layout_marginRight="20dp"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/close"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:background="@drawable/bg_grey_e6e6e6"
+                android:gravity="center"
+                android:paddingTop="8dp"
+                android:paddingBottom="8dp"
+                android:text="关闭"
+                android:textColor="@color/black_272727"
+                android:textSize="16sp" />
+
+            <TextView
+                android:id="@+id/save"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="36dp"
+                android:layout_weight="1"
+                android:background="@drawable/bg_blue_3bacb2"
+                android:gravity="center"
+                android:paddingTop="8dp"
+                android:paddingBottom="8dp"
+                android:text="保存"
+                android:textColor="@color/white_ffffff"
+                android:textSize="16sp" />
+        </androidx.appcompat.widget.LinearLayoutCompat>
+    </androidx.appcompat.widget.LinearLayoutCompat>
+</LinearLayout>

BIN=BIN
demo/src/main/res/mipmap-xhdpi/icon_wrong.png