diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ea56300..0416db4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -49,5 +49,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ea56300..0416db4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -49,5 +49,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
index 291a985..c41c867 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
@@ -82,14 +82,40 @@
}
//窨井类型转换
-fun String.toChinese(): String {
+fun String.toTypeName(): String {
return when (this) {
- "0" -> "全部"
- "1" -> "一级"
- "2" -> "二级"
- "3" -> "三级"
+ "1" -> "雨水井"
+ "2" -> "污水井"
+ "3" -> "燃气井"
+ "4" -> "热力井"
+ "5" -> "电力井"
+ "6" -> "交通井"
+ "7" -> "路灯井"
+ "8" -> "通信井"
+ "9" -> "监控井"
else -> {
- "未知"
+ "其他"
+ }
+ }
+}
+
+fun String.toDeptName(): String {
+ return when (this) {
+ "0" -> "顶级"
+ "1148031048115494913" -> "二院"
+ "1178242695136149506" -> "电力公司"
+ "1178242900132757506" -> "滨海热电"
+ "24" -> "燃气集团总公司"
+ "30" -> "203所"
+ "1399230677135265794" -> "厦门测试"
+ "25" -> "第一分公司"
+ "26" -> "第二分公司"
+ "27" -> "第三分公司"
+ "28" -> "第四分公司"
+ "29" -> "高压管网分公司"
+ "1143796514486353922" -> "第五分公司"
+ else -> {
+ "其他"
}
}
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ea56300..0416db4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -49,5 +49,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
index 291a985..c41c867 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
@@ -82,14 +82,40 @@
}
//窨井类型转换
-fun String.toChinese(): String {
+fun String.toTypeName(): String {
return when (this) {
- "0" -> "全部"
- "1" -> "一级"
- "2" -> "二级"
- "3" -> "三级"
+ "1" -> "雨水井"
+ "2" -> "污水井"
+ "3" -> "燃气井"
+ "4" -> "热力井"
+ "5" -> "电力井"
+ "6" -> "交通井"
+ "7" -> "路灯井"
+ "8" -> "通信井"
+ "9" -> "监控井"
else -> {
- "未知"
+ "其他"
+ }
+ }
+}
+
+fun String.toDeptName(): String {
+ return when (this) {
+ "0" -> "顶级"
+ "1148031048115494913" -> "二院"
+ "1178242695136149506" -> "电力公司"
+ "1178242900132757506" -> "滨海热电"
+ "24" -> "燃气集团总公司"
+ "30" -> "203所"
+ "1399230677135265794" -> "厦门测试"
+ "25" -> "第一分公司"
+ "26" -> "第二分公司"
+ "27" -> "第三分公司"
+ "28" -> "第四分公司"
+ "29" -> "高压管网分公司"
+ "1143796514486353922" -> "第五分公司"
+ else -> {
+ "其他"
}
}
}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
index 26f3085..4d0c818 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
@@ -1,24 +1,326 @@
package com.casic.app.smartwell.sanxi.fragment
+import android.graphics.Point
+import android.os.Bundle
+import android.util.Log
+import android.view.LayoutInflater
import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import com.amap.api.maps.AMap
+import com.amap.api.maps.AMapOptions
+import com.amap.api.maps.CameraUpdateFactory
+import com.amap.api.maps.CoordinateConverter
+import com.amap.api.maps.model.*
import com.casic.app.smartwell.sanxi.R
-import com.casic.app.smartwell.sanxi.base.BaseFragment
-import kotlinx.android.synthetic.main.include_base_title.*
+import com.casic.app.smartwell.sanxi.extensions.show
+import com.casic.app.smartwell.sanxi.extensions.showRouteOnMap
+import com.casic.app.smartwell.sanxi.extensions.toDeptName
+import com.casic.app.smartwell.sanxi.extensions.toTypeName
+import com.casic.app.smartwell.sanxi.model.WellListModel
+import com.casic.app.smartwell.sanxi.utils.Constant
+import com.casic.app.smartwell.sanxi.vm.WellViewModel
+import com.casic.app.smartwell.sanxi.widgets.EasyPopupWindow
+import com.casic.app.smartwell.sanxi.widgets.GaoDeClusterMarkerView
+import com.google.android.material.bottomsheet.BottomSheetBehavior
+import com.pengxh.app.multilib.utils.SizeUtil
+import com.pengxh.app.multilib.widget.dialog.AlertControlDialog
+import kotlinx.android.synthetic.main.fragment_home.view.*
-class HomePageFragment : BaseFragment() {
+class HomePageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener,
+ AMap.OnMarkerClickListener, AMap.InfoWindowAdapter, AMap.OnInfoWindowClickListener {
- override fun initLayoutView(): Int = R.layout.fragment_home
+ private val kTag = "HomePageFragment"
+ private lateinit var homeView: View
+ private lateinit var aMap: AMap
+ private lateinit var wellViewModel: WellViewModel
- override fun setupTopBarLayout() {
- leftBackView.visibility = View.GONE
- titleView.text = "首页"
+ /**
+ * 所有窨井列表信息集合
+ * */
+ private var wellModels: MutableList = ArrayList()
+
+ /**
+ * 所有的marker
+ */
+ private var allMarkerOptions: MutableList = ArrayList()
+
+ /**
+ * 视野内的marker
+ */
+ private var markerOptionsInView: MutableList = ArrayList()
+
+ /**
+ * 自定义Marker弹出框
+ * */
+ private var infoWindow: View? = null
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ homeView = inflater.inflate(R.layout.fragment_home, container, false)
+ homeView.titleView.text = "首页"
+ val easyPopupWindow = EasyPopupWindow(requireContext())
+ easyPopupWindow.setupPopupData(Constant.POPUP_IMAGES, Constant.POPUP_TITLES)
+ homeView.rightOptionView.setOnClickListener {
+ easyPopupWindow.setOnPopupWindowClickListener(object :
+ EasyPopupWindow.OnPopupWindowClickListener {
+ override fun onPopupClick(position: Int) {
+ when (position) {
+ 0 -> aMap.mapType = AMap.MAP_TYPE_NORMAL
+ 1 -> aMap.mapType = AMap.MAP_TYPE_SATELLITE
+ }
+ }
+ })
+ easyPopupWindow.setBackgroundDrawable(null)
+ val x: Int = homeView.rightOptionView.width - easyPopupWindow.width
+ easyPopupWindow.showAsDropDown(homeView.rightOptionView, x, 0)
+ }
+
+ //代码设置底部拉升距离
+ val bottomSheetBehavior = BottomSheetBehavior.from(homeView.bottomBehaviorLayout)
+ homeView.coordinatorLayout.post {
+ bottomSheetBehavior.isFitToContents = false
+ bottomSheetBehavior.halfExpandedRatio = 0.3f
+ bottomSheetBehavior.isHideable = false
+ bottomSheetBehavior.peekHeight = SizeUtil.dp2px(requireContext(), 30f)
+ }
+
+ //初始化vm
+ wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java)
+
+ //获取所有窨井数据
+ wellViewModel.obtainAllWell()
+ wellViewModel.allWellModel.observe(viewLifecycleOwner, {
+ if (it.code == 200) {
+ val latitudeList: MutableList = ArrayList()
+ val longitudeList: MutableList = ArrayList()
+ it.data?.forEach { well ->
+ val lat = well.latGaode.toString()
+ val lng = well.lngGaode.toString()
+ if (lat.isNotBlank() && lng.isNotBlank()) {
+ //返回true代表当前位置在大陆、港澳地区,反之不在
+ val latitude = lat.toDouble()
+ val longitude = lng.toDouble()
+ if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) {
+ //缓存所有设备详情,点击Marker时候需要
+ wellModels.add(well)
+ //分别缓存经、纬度
+ latitudeList.add(latitude)
+ longitudeList.add(longitude)
+ //将所有设备信息转化缓存为Marker点
+ allMarkerOptions.add(
+ MarkerOptions()
+ .position(LatLng(latitude, longitude))
+ .title(well.wellTypeName)
+ .snippet(well.wellName)
+ )
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度不在国内,异常经纬度 ===> [${lng},${lat}]")
+ }
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度异常,异常经纬度 ===> [${lng},${lat}]")
+ }
+ }
+ //计算所有点的中心点位置
+ val centerLatLng = LatLng(latitudeList.average(), longitudeList.average())
+ Log.d(
+ kTag,
+ "所有闸井中心点位置 ===> [${latitudeList.average()}, ${longitudeList.average()}]"
+ )
+ //移动到指定经纬度
+ val cameraPosition = CameraPosition(centerLatLng, 13f, 0f, 0f)
+ val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition)
+ aMap.animateCamera(cameraUpdate, 3000, null)
+ }
+ })
+
+ //地图初始化
+ initMap(savedInstanceState)
+ return homeView
}
- override fun initData() {
+ private fun initMap(savedInstanceState: Bundle?) {
+ homeView.mapView.onCreate(savedInstanceState)
+ aMap = homeView.mapView.map
+ aMap.mapType = AMap.MAP_TYPE_NORMAL
+ val uiSettings = aMap.uiSettings
+ uiSettings.isCompassEnabled = true
+ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER
+ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度
+ uiSettings.isRotateGesturesEnabled = false//不允许地图旋转
+
+ // 地图加载成功监听
+ aMap.addOnMapLoadedListener(this)
+ // 地图缩放监听
+ aMap.addOnCameraChangeListener(this)
+ // marker 点击事件监听
+ aMap.addOnMarkerClickListener(this)
+ // 点击marker弹出自定义popup
+ aMap.setInfoWindowAdapter(this)
+ //信息窗点击事件
+ aMap.addOnInfoWindowClickListener(this)
+ }
+
+ override fun onMapLoaded() {
+ //地图加载成功之后显示聚合点数据
+ initClustersMarkers()
+ }
+
+ override fun onCameraChange(p0: CameraPosition?) {
}
- override fun initEvent() {
+ //获取视野内的marker 根据聚合算法合成自定义的marker 显示视野内的marker
+ override fun onCameraChangeFinish(p0: CameraPosition?) {
+ //地图缩放之后显示聚合点数据
+ initClustersMarkers()
+ }
+ private fun initClustersMarkers() {
+ val proj = aMap.projection
+ val dm = resources.displayMetrics
+ var screenLocation: Point
+ markerOptionsInView.clear()
+ // 获取在当前视野内的marker
+ allMarkerOptions.forEach {
+ screenLocation = proj.toScreenLocation(it.position)
+ if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) {
+ //在当前可观区域内
+ markerOptionsInView.add(it)
+ }
+ }
+ // 自定义的聚合类MarkerCluster
+ val clustersMarkers: MutableList = ArrayList()
+ markerOptionsInView.forEach {
+ if (clustersMarkers.size == 0) {
+ //添加一个新的自定义marker
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )
+ } else {
+ var isInRange = false
+ //Kotlin foreach不能用break
+ for (view in clustersMarkers) {
+ //判断当前的marker是否在前面marker的聚合范围内 并且每个marker只会聚合一次。
+ if (view.bounds.contains(it.position)) {
+ view.addMarker(it)
+ isInRange = true
+ break
+ }
+ }
+ //如果没在任何范围内,自己单独形成一个自定义marker。在和后面的marker进行比较
+ if (!isInRange) {
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )//相距多少才聚合
+ }
+ }
+ }
+ // 设置聚合点的位置和icon
+ clustersMarkers.forEach {
+ it.setPositionAndIcon()
+ }
+ aMap.clear()
+ // 重新添加 marker
+ clustersMarkers.forEach {
+ aMap.addMarker(it.options)
+ }
+ }
+
+ override fun onMarkerClick(marker: Marker?): Boolean {
+ //显示闸井信息
+ marker?.showInfoWindow()
+ return true
+ }
+
+ override fun getInfoWindow(marker: Marker?): View? {
+ if (infoWindow == null) {
+ infoWindow = LayoutInflater.from(requireContext()).inflate(R.layout.popu_map_info, null)
+ }
+ val v = infoWindow!!
+ //反射得到popup里面的控件对象
+ val wellTypeView = v.findViewById(R.id.wellTypeView)
+ val wellCodeView = v.findViewById(R.id.wellCodeView)
+ val ownerShipView = v.findViewById(R.id.ownerShipView)
+ val locationView = v.findViewById(R.id.locationView)
+
+ //绑定数据
+ val clickedLatLng = marker?.position!!
+ for (well in wellModels) {
+ if (clickedLatLng.latitude == well.latGaode!!.toDouble()
+ && clickedLatLng.longitude == well.lngGaode!!.toDouble()
+ ) {
+ wellTypeView.text = String.format("井类型: ${well.wellType.toTypeName()}")
+ wellCodeView.text = String.format("井编号: ${well.wellCode}")
+ ownerShipView.text = String.format("权属单位: ${well.deptid.toDeptName()}")
+ locationView.text = String.format("详细位置: ${well.position}")
+ return infoWindow
+ }
+ }
+ "无法查看聚合点,请放大比例后再查看".show()
+ return null
+ }
+
+ /**
+ * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框
+ * */
+ override fun getInfoContents(p0: Marker?): View? = null
+
+ override fun onInfoWindowClick(p0: Marker?) {
+ if (p0 != null) {
+ AlertControlDialog.Builder()
+ .setContext(requireContext())
+ .setTitle("操作提示")
+ .setMessage("确定要前往吗")
+ .setNegativeButton("取消")
+ .setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ val latLng = p0.position
+ val lat = latLng.latitude.toString()
+ val lng = latLng.longitude.toString()
+ if (lat.isBlank() || lng.isBlank()) {
+ "窨井经纬度异常,无法开启导航".show()
+ return
+ }
+ Poi(p0.snippet, LatLng(lat.toDouble(), lng.toDouble()), "").showRouteOnMap(
+ requireContext()
+ )
+ }
+
+ override fun onCancelClick() {
+
+ }
+ }).build().show()
+ }
+ }
+
+ /***以下是地图生命周期管理************************************************************************/
+ override fun onResume() {
+ super.onResume()
+ homeView.mapView.onResume()
+ //每次页面切换都需要重新刷新不同状态的窨井数量
+// wellViewModel.countWellByState()
+// workOrderViewModel.countWorkOrderByState()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ homeView.mapView.onPause()
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ homeView.mapView.onSaveInstanceState(outState)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ homeView.mapView.onDestroy()
}
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ea56300..0416db4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -49,5 +49,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
index 291a985..c41c867 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
@@ -82,14 +82,40 @@
}
//窨井类型转换
-fun String.toChinese(): String {
+fun String.toTypeName(): String {
return when (this) {
- "0" -> "全部"
- "1" -> "一级"
- "2" -> "二级"
- "3" -> "三级"
+ "1" -> "雨水井"
+ "2" -> "污水井"
+ "3" -> "燃气井"
+ "4" -> "热力井"
+ "5" -> "电力井"
+ "6" -> "交通井"
+ "7" -> "路灯井"
+ "8" -> "通信井"
+ "9" -> "监控井"
else -> {
- "未知"
+ "其他"
+ }
+ }
+}
+
+fun String.toDeptName(): String {
+ return when (this) {
+ "0" -> "顶级"
+ "1148031048115494913" -> "二院"
+ "1178242695136149506" -> "电力公司"
+ "1178242900132757506" -> "滨海热电"
+ "24" -> "燃气集团总公司"
+ "30" -> "203所"
+ "1399230677135265794" -> "厦门测试"
+ "25" -> "第一分公司"
+ "26" -> "第二分公司"
+ "27" -> "第三分公司"
+ "28" -> "第四分公司"
+ "29" -> "高压管网分公司"
+ "1143796514486353922" -> "第五分公司"
+ else -> {
+ "其他"
}
}
}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
index 26f3085..4d0c818 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
@@ -1,24 +1,326 @@
package com.casic.app.smartwell.sanxi.fragment
+import android.graphics.Point
+import android.os.Bundle
+import android.util.Log
+import android.view.LayoutInflater
import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import com.amap.api.maps.AMap
+import com.amap.api.maps.AMapOptions
+import com.amap.api.maps.CameraUpdateFactory
+import com.amap.api.maps.CoordinateConverter
+import com.amap.api.maps.model.*
import com.casic.app.smartwell.sanxi.R
-import com.casic.app.smartwell.sanxi.base.BaseFragment
-import kotlinx.android.synthetic.main.include_base_title.*
+import com.casic.app.smartwell.sanxi.extensions.show
+import com.casic.app.smartwell.sanxi.extensions.showRouteOnMap
+import com.casic.app.smartwell.sanxi.extensions.toDeptName
+import com.casic.app.smartwell.sanxi.extensions.toTypeName
+import com.casic.app.smartwell.sanxi.model.WellListModel
+import com.casic.app.smartwell.sanxi.utils.Constant
+import com.casic.app.smartwell.sanxi.vm.WellViewModel
+import com.casic.app.smartwell.sanxi.widgets.EasyPopupWindow
+import com.casic.app.smartwell.sanxi.widgets.GaoDeClusterMarkerView
+import com.google.android.material.bottomsheet.BottomSheetBehavior
+import com.pengxh.app.multilib.utils.SizeUtil
+import com.pengxh.app.multilib.widget.dialog.AlertControlDialog
+import kotlinx.android.synthetic.main.fragment_home.view.*
-class HomePageFragment : BaseFragment() {
+class HomePageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener,
+ AMap.OnMarkerClickListener, AMap.InfoWindowAdapter, AMap.OnInfoWindowClickListener {
- override fun initLayoutView(): Int = R.layout.fragment_home
+ private val kTag = "HomePageFragment"
+ private lateinit var homeView: View
+ private lateinit var aMap: AMap
+ private lateinit var wellViewModel: WellViewModel
- override fun setupTopBarLayout() {
- leftBackView.visibility = View.GONE
- titleView.text = "首页"
+ /**
+ * 所有窨井列表信息集合
+ * */
+ private var wellModels: MutableList = ArrayList()
+
+ /**
+ * 所有的marker
+ */
+ private var allMarkerOptions: MutableList = ArrayList()
+
+ /**
+ * 视野内的marker
+ */
+ private var markerOptionsInView: MutableList = ArrayList()
+
+ /**
+ * 自定义Marker弹出框
+ * */
+ private var infoWindow: View? = null
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ homeView = inflater.inflate(R.layout.fragment_home, container, false)
+ homeView.titleView.text = "首页"
+ val easyPopupWindow = EasyPopupWindow(requireContext())
+ easyPopupWindow.setupPopupData(Constant.POPUP_IMAGES, Constant.POPUP_TITLES)
+ homeView.rightOptionView.setOnClickListener {
+ easyPopupWindow.setOnPopupWindowClickListener(object :
+ EasyPopupWindow.OnPopupWindowClickListener {
+ override fun onPopupClick(position: Int) {
+ when (position) {
+ 0 -> aMap.mapType = AMap.MAP_TYPE_NORMAL
+ 1 -> aMap.mapType = AMap.MAP_TYPE_SATELLITE
+ }
+ }
+ })
+ easyPopupWindow.setBackgroundDrawable(null)
+ val x: Int = homeView.rightOptionView.width - easyPopupWindow.width
+ easyPopupWindow.showAsDropDown(homeView.rightOptionView, x, 0)
+ }
+
+ //代码设置底部拉升距离
+ val bottomSheetBehavior = BottomSheetBehavior.from(homeView.bottomBehaviorLayout)
+ homeView.coordinatorLayout.post {
+ bottomSheetBehavior.isFitToContents = false
+ bottomSheetBehavior.halfExpandedRatio = 0.3f
+ bottomSheetBehavior.isHideable = false
+ bottomSheetBehavior.peekHeight = SizeUtil.dp2px(requireContext(), 30f)
+ }
+
+ //初始化vm
+ wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java)
+
+ //获取所有窨井数据
+ wellViewModel.obtainAllWell()
+ wellViewModel.allWellModel.observe(viewLifecycleOwner, {
+ if (it.code == 200) {
+ val latitudeList: MutableList = ArrayList()
+ val longitudeList: MutableList = ArrayList()
+ it.data?.forEach { well ->
+ val lat = well.latGaode.toString()
+ val lng = well.lngGaode.toString()
+ if (lat.isNotBlank() && lng.isNotBlank()) {
+ //返回true代表当前位置在大陆、港澳地区,反之不在
+ val latitude = lat.toDouble()
+ val longitude = lng.toDouble()
+ if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) {
+ //缓存所有设备详情,点击Marker时候需要
+ wellModels.add(well)
+ //分别缓存经、纬度
+ latitudeList.add(latitude)
+ longitudeList.add(longitude)
+ //将所有设备信息转化缓存为Marker点
+ allMarkerOptions.add(
+ MarkerOptions()
+ .position(LatLng(latitude, longitude))
+ .title(well.wellTypeName)
+ .snippet(well.wellName)
+ )
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度不在国内,异常经纬度 ===> [${lng},${lat}]")
+ }
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度异常,异常经纬度 ===> [${lng},${lat}]")
+ }
+ }
+ //计算所有点的中心点位置
+ val centerLatLng = LatLng(latitudeList.average(), longitudeList.average())
+ Log.d(
+ kTag,
+ "所有闸井中心点位置 ===> [${latitudeList.average()}, ${longitudeList.average()}]"
+ )
+ //移动到指定经纬度
+ val cameraPosition = CameraPosition(centerLatLng, 13f, 0f, 0f)
+ val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition)
+ aMap.animateCamera(cameraUpdate, 3000, null)
+ }
+ })
+
+ //地图初始化
+ initMap(savedInstanceState)
+ return homeView
}
- override fun initData() {
+ private fun initMap(savedInstanceState: Bundle?) {
+ homeView.mapView.onCreate(savedInstanceState)
+ aMap = homeView.mapView.map
+ aMap.mapType = AMap.MAP_TYPE_NORMAL
+ val uiSettings = aMap.uiSettings
+ uiSettings.isCompassEnabled = true
+ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER
+ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度
+ uiSettings.isRotateGesturesEnabled = false//不允许地图旋转
+
+ // 地图加载成功监听
+ aMap.addOnMapLoadedListener(this)
+ // 地图缩放监听
+ aMap.addOnCameraChangeListener(this)
+ // marker 点击事件监听
+ aMap.addOnMarkerClickListener(this)
+ // 点击marker弹出自定义popup
+ aMap.setInfoWindowAdapter(this)
+ //信息窗点击事件
+ aMap.addOnInfoWindowClickListener(this)
+ }
+
+ override fun onMapLoaded() {
+ //地图加载成功之后显示聚合点数据
+ initClustersMarkers()
+ }
+
+ override fun onCameraChange(p0: CameraPosition?) {
}
- override fun initEvent() {
+ //获取视野内的marker 根据聚合算法合成自定义的marker 显示视野内的marker
+ override fun onCameraChangeFinish(p0: CameraPosition?) {
+ //地图缩放之后显示聚合点数据
+ initClustersMarkers()
+ }
+ private fun initClustersMarkers() {
+ val proj = aMap.projection
+ val dm = resources.displayMetrics
+ var screenLocation: Point
+ markerOptionsInView.clear()
+ // 获取在当前视野内的marker
+ allMarkerOptions.forEach {
+ screenLocation = proj.toScreenLocation(it.position)
+ if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) {
+ //在当前可观区域内
+ markerOptionsInView.add(it)
+ }
+ }
+ // 自定义的聚合类MarkerCluster
+ val clustersMarkers: MutableList = ArrayList()
+ markerOptionsInView.forEach {
+ if (clustersMarkers.size == 0) {
+ //添加一个新的自定义marker
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )
+ } else {
+ var isInRange = false
+ //Kotlin foreach不能用break
+ for (view in clustersMarkers) {
+ //判断当前的marker是否在前面marker的聚合范围内 并且每个marker只会聚合一次。
+ if (view.bounds.contains(it.position)) {
+ view.addMarker(it)
+ isInRange = true
+ break
+ }
+ }
+ //如果没在任何范围内,自己单独形成一个自定义marker。在和后面的marker进行比较
+ if (!isInRange) {
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )//相距多少才聚合
+ }
+ }
+ }
+ // 设置聚合点的位置和icon
+ clustersMarkers.forEach {
+ it.setPositionAndIcon()
+ }
+ aMap.clear()
+ // 重新添加 marker
+ clustersMarkers.forEach {
+ aMap.addMarker(it.options)
+ }
+ }
+
+ override fun onMarkerClick(marker: Marker?): Boolean {
+ //显示闸井信息
+ marker?.showInfoWindow()
+ return true
+ }
+
+ override fun getInfoWindow(marker: Marker?): View? {
+ if (infoWindow == null) {
+ infoWindow = LayoutInflater.from(requireContext()).inflate(R.layout.popu_map_info, null)
+ }
+ val v = infoWindow!!
+ //反射得到popup里面的控件对象
+ val wellTypeView = v.findViewById(R.id.wellTypeView)
+ val wellCodeView = v.findViewById(R.id.wellCodeView)
+ val ownerShipView = v.findViewById(R.id.ownerShipView)
+ val locationView = v.findViewById(R.id.locationView)
+
+ //绑定数据
+ val clickedLatLng = marker?.position!!
+ for (well in wellModels) {
+ if (clickedLatLng.latitude == well.latGaode!!.toDouble()
+ && clickedLatLng.longitude == well.lngGaode!!.toDouble()
+ ) {
+ wellTypeView.text = String.format("井类型: ${well.wellType.toTypeName()}")
+ wellCodeView.text = String.format("井编号: ${well.wellCode}")
+ ownerShipView.text = String.format("权属单位: ${well.deptid.toDeptName()}")
+ locationView.text = String.format("详细位置: ${well.position}")
+ return infoWindow
+ }
+ }
+ "无法查看聚合点,请放大比例后再查看".show()
+ return null
+ }
+
+ /**
+ * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框
+ * */
+ override fun getInfoContents(p0: Marker?): View? = null
+
+ override fun onInfoWindowClick(p0: Marker?) {
+ if (p0 != null) {
+ AlertControlDialog.Builder()
+ .setContext(requireContext())
+ .setTitle("操作提示")
+ .setMessage("确定要前往吗")
+ .setNegativeButton("取消")
+ .setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ val latLng = p0.position
+ val lat = latLng.latitude.toString()
+ val lng = latLng.longitude.toString()
+ if (lat.isBlank() || lng.isBlank()) {
+ "窨井经纬度异常,无法开启导航".show()
+ return
+ }
+ Poi(p0.snippet, LatLng(lat.toDouble(), lng.toDouble()), "").showRouteOnMap(
+ requireContext()
+ )
+ }
+
+ override fun onCancelClick() {
+
+ }
+ }).build().show()
+ }
+ }
+
+ /***以下是地图生命周期管理************************************************************************/
+ override fun onResume() {
+ super.onResume()
+ homeView.mapView.onResume()
+ //每次页面切换都需要重新刷新不同状态的窨井数量
+// wellViewModel.countWellByState()
+// workOrderViewModel.countWorkOrderByState()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ homeView.mapView.onPause()
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ homeView.mapView.onSaveInstanceState(outState)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ homeView.mapView.onDestroy()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
new file mode 100644
index 0000000..4e916a9
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
@@ -0,0 +1,271 @@
+package com.casic.app.smartwell.sanxi.model;
+
+import java.util.List;
+
+public class WellListModel {
+
+ private int code;
+ private List data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public List getData() {
+ return data;
+ }
+
+ public void setData(List data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataDTO {
+ private String area;
+ private String bfzt;
+ private String bfztName;
+ private String coordinateX;
+ private String coordinateY;
+ private String deep;
+ private String deptName;
+ private String deptid;
+ private String id;
+ private String latBaidu;
+ private String latGaode;
+ private String lngBaidu;
+ private String lngGaode;
+ private String notes;
+ private String photos;
+ private String position;
+ private String staff;
+ private String tel;
+ private String ts;
+ private String valid;
+ private String watchData;
+ private String wellCode;
+ private String wellName;
+ private String wellType;
+ private String wellTypeName;
+
+ public String getArea() {
+ return area;
+ }
+
+ public void setArea(String area) {
+ this.area = area;
+ }
+
+ public String getBfzt() {
+ return bfzt;
+ }
+
+ public void setBfzt(String bfzt) {
+ this.bfzt = bfzt;
+ }
+
+ public String getBfztName() {
+ return bfztName;
+ }
+
+ public void setBfztName(String bfztName) {
+ this.bfztName = bfztName;
+ }
+
+ public String getCoordinateX() {
+ return coordinateX;
+ }
+
+ public void setCoordinateX(String coordinateX) {
+ this.coordinateX = coordinateX;
+ }
+
+ public String getCoordinateY() {
+ return coordinateY;
+ }
+
+ public void setCoordinateY(String coordinateY) {
+ this.coordinateY = coordinateY;
+ }
+
+ public String getDeep() {
+ return deep;
+ }
+
+ public void setDeep(String deep) {
+ this.deep = deep;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptid() {
+ return deptid;
+ }
+
+ public void setDeptid(String deptid) {
+ this.deptid = deptid;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getLatBaidu() {
+ return latBaidu;
+ }
+
+ public void setLatBaidu(String latBaidu) {
+ this.latBaidu = latBaidu;
+ }
+
+ public String getLatGaode() {
+ return latGaode;
+ }
+
+ public void setLatGaode(String latGaode) {
+ this.latGaode = latGaode;
+ }
+
+ public String getLngBaidu() {
+ return lngBaidu;
+ }
+
+ public void setLngBaidu(String lngBaidu) {
+ this.lngBaidu = lngBaidu;
+ }
+
+ public String getLngGaode() {
+ return lngGaode;
+ }
+
+ public void setLngGaode(String lngGaode) {
+ this.lngGaode = lngGaode;
+ }
+
+ public String getNotes() {
+ return notes;
+ }
+
+ public void setNotes(String notes) {
+ this.notes = notes;
+ }
+
+ public String getPhotos() {
+ return photos;
+ }
+
+ public void setPhotos(String photos) {
+ this.photos = photos;
+ }
+
+ public String getPosition() {
+ return position;
+ }
+
+ public void setPosition(String position) {
+ this.position = position;
+ }
+
+ public String getStaff() {
+ return staff;
+ }
+
+ public void setStaff(String staff) {
+ this.staff = staff;
+ }
+
+ public String getTel() {
+ return tel;
+ }
+
+ public void setTel(String tel) {
+ this.tel = tel;
+ }
+
+ public String getTs() {
+ return ts;
+ }
+
+ public void setTs(String ts) {
+ this.ts = ts;
+ }
+
+ public String getValid() {
+ return valid;
+ }
+
+ public void setValid(String valid) {
+ this.valid = valid;
+ }
+
+ public String getWatchData() {
+ return watchData;
+ }
+
+ public void setWatchData(String watchData) {
+ this.watchData = watchData;
+ }
+
+ public String getWellCode() {
+ return wellCode;
+ }
+
+ public void setWellCode(String wellCode) {
+ this.wellCode = wellCode;
+ }
+
+ public String getWellName() {
+ return wellName;
+ }
+
+ public void setWellName(String wellName) {
+ this.wellName = wellName;
+ }
+
+ public String getWellType() {
+ return wellType;
+ }
+
+ public void setWellType(String wellType) {
+ this.wellType = wellType;
+ }
+
+ public String getWellTypeName() {
+ return wellTypeName;
+ }
+
+ public void setWellTypeName(String wellTypeName) {
+ this.wellTypeName = wellTypeName;
+ }
+ }
+}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ea56300..0416db4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -49,5 +49,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
index 291a985..c41c867 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
@@ -82,14 +82,40 @@
}
//窨井类型转换
-fun String.toChinese(): String {
+fun String.toTypeName(): String {
return when (this) {
- "0" -> "全部"
- "1" -> "一级"
- "2" -> "二级"
- "3" -> "三级"
+ "1" -> "雨水井"
+ "2" -> "污水井"
+ "3" -> "燃气井"
+ "4" -> "热力井"
+ "5" -> "电力井"
+ "6" -> "交通井"
+ "7" -> "路灯井"
+ "8" -> "通信井"
+ "9" -> "监控井"
else -> {
- "未知"
+ "其他"
+ }
+ }
+}
+
+fun String.toDeptName(): String {
+ return when (this) {
+ "0" -> "顶级"
+ "1148031048115494913" -> "二院"
+ "1178242695136149506" -> "电力公司"
+ "1178242900132757506" -> "滨海热电"
+ "24" -> "燃气集团总公司"
+ "30" -> "203所"
+ "1399230677135265794" -> "厦门测试"
+ "25" -> "第一分公司"
+ "26" -> "第二分公司"
+ "27" -> "第三分公司"
+ "28" -> "第四分公司"
+ "29" -> "高压管网分公司"
+ "1143796514486353922" -> "第五分公司"
+ else -> {
+ "其他"
}
}
}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
index 26f3085..4d0c818 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
@@ -1,24 +1,326 @@
package com.casic.app.smartwell.sanxi.fragment
+import android.graphics.Point
+import android.os.Bundle
+import android.util.Log
+import android.view.LayoutInflater
import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import com.amap.api.maps.AMap
+import com.amap.api.maps.AMapOptions
+import com.amap.api.maps.CameraUpdateFactory
+import com.amap.api.maps.CoordinateConverter
+import com.amap.api.maps.model.*
import com.casic.app.smartwell.sanxi.R
-import com.casic.app.smartwell.sanxi.base.BaseFragment
-import kotlinx.android.synthetic.main.include_base_title.*
+import com.casic.app.smartwell.sanxi.extensions.show
+import com.casic.app.smartwell.sanxi.extensions.showRouteOnMap
+import com.casic.app.smartwell.sanxi.extensions.toDeptName
+import com.casic.app.smartwell.sanxi.extensions.toTypeName
+import com.casic.app.smartwell.sanxi.model.WellListModel
+import com.casic.app.smartwell.sanxi.utils.Constant
+import com.casic.app.smartwell.sanxi.vm.WellViewModel
+import com.casic.app.smartwell.sanxi.widgets.EasyPopupWindow
+import com.casic.app.smartwell.sanxi.widgets.GaoDeClusterMarkerView
+import com.google.android.material.bottomsheet.BottomSheetBehavior
+import com.pengxh.app.multilib.utils.SizeUtil
+import com.pengxh.app.multilib.widget.dialog.AlertControlDialog
+import kotlinx.android.synthetic.main.fragment_home.view.*
-class HomePageFragment : BaseFragment() {
+class HomePageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener,
+ AMap.OnMarkerClickListener, AMap.InfoWindowAdapter, AMap.OnInfoWindowClickListener {
- override fun initLayoutView(): Int = R.layout.fragment_home
+ private val kTag = "HomePageFragment"
+ private lateinit var homeView: View
+ private lateinit var aMap: AMap
+ private lateinit var wellViewModel: WellViewModel
- override fun setupTopBarLayout() {
- leftBackView.visibility = View.GONE
- titleView.text = "首页"
+ /**
+ * 所有窨井列表信息集合
+ * */
+ private var wellModels: MutableList = ArrayList()
+
+ /**
+ * 所有的marker
+ */
+ private var allMarkerOptions: MutableList = ArrayList()
+
+ /**
+ * 视野内的marker
+ */
+ private var markerOptionsInView: MutableList = ArrayList()
+
+ /**
+ * 自定义Marker弹出框
+ * */
+ private var infoWindow: View? = null
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ homeView = inflater.inflate(R.layout.fragment_home, container, false)
+ homeView.titleView.text = "首页"
+ val easyPopupWindow = EasyPopupWindow(requireContext())
+ easyPopupWindow.setupPopupData(Constant.POPUP_IMAGES, Constant.POPUP_TITLES)
+ homeView.rightOptionView.setOnClickListener {
+ easyPopupWindow.setOnPopupWindowClickListener(object :
+ EasyPopupWindow.OnPopupWindowClickListener {
+ override fun onPopupClick(position: Int) {
+ when (position) {
+ 0 -> aMap.mapType = AMap.MAP_TYPE_NORMAL
+ 1 -> aMap.mapType = AMap.MAP_TYPE_SATELLITE
+ }
+ }
+ })
+ easyPopupWindow.setBackgroundDrawable(null)
+ val x: Int = homeView.rightOptionView.width - easyPopupWindow.width
+ easyPopupWindow.showAsDropDown(homeView.rightOptionView, x, 0)
+ }
+
+ //代码设置底部拉升距离
+ val bottomSheetBehavior = BottomSheetBehavior.from(homeView.bottomBehaviorLayout)
+ homeView.coordinatorLayout.post {
+ bottomSheetBehavior.isFitToContents = false
+ bottomSheetBehavior.halfExpandedRatio = 0.3f
+ bottomSheetBehavior.isHideable = false
+ bottomSheetBehavior.peekHeight = SizeUtil.dp2px(requireContext(), 30f)
+ }
+
+ //初始化vm
+ wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java)
+
+ //获取所有窨井数据
+ wellViewModel.obtainAllWell()
+ wellViewModel.allWellModel.observe(viewLifecycleOwner, {
+ if (it.code == 200) {
+ val latitudeList: MutableList = ArrayList()
+ val longitudeList: MutableList = ArrayList()
+ it.data?.forEach { well ->
+ val lat = well.latGaode.toString()
+ val lng = well.lngGaode.toString()
+ if (lat.isNotBlank() && lng.isNotBlank()) {
+ //返回true代表当前位置在大陆、港澳地区,反之不在
+ val latitude = lat.toDouble()
+ val longitude = lng.toDouble()
+ if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) {
+ //缓存所有设备详情,点击Marker时候需要
+ wellModels.add(well)
+ //分别缓存经、纬度
+ latitudeList.add(latitude)
+ longitudeList.add(longitude)
+ //将所有设备信息转化缓存为Marker点
+ allMarkerOptions.add(
+ MarkerOptions()
+ .position(LatLng(latitude, longitude))
+ .title(well.wellTypeName)
+ .snippet(well.wellName)
+ )
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度不在国内,异常经纬度 ===> [${lng},${lat}]")
+ }
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度异常,异常经纬度 ===> [${lng},${lat}]")
+ }
+ }
+ //计算所有点的中心点位置
+ val centerLatLng = LatLng(latitudeList.average(), longitudeList.average())
+ Log.d(
+ kTag,
+ "所有闸井中心点位置 ===> [${latitudeList.average()}, ${longitudeList.average()}]"
+ )
+ //移动到指定经纬度
+ val cameraPosition = CameraPosition(centerLatLng, 13f, 0f, 0f)
+ val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition)
+ aMap.animateCamera(cameraUpdate, 3000, null)
+ }
+ })
+
+ //地图初始化
+ initMap(savedInstanceState)
+ return homeView
}
- override fun initData() {
+ private fun initMap(savedInstanceState: Bundle?) {
+ homeView.mapView.onCreate(savedInstanceState)
+ aMap = homeView.mapView.map
+ aMap.mapType = AMap.MAP_TYPE_NORMAL
+ val uiSettings = aMap.uiSettings
+ uiSettings.isCompassEnabled = true
+ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER
+ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度
+ uiSettings.isRotateGesturesEnabled = false//不允许地图旋转
+
+ // 地图加载成功监听
+ aMap.addOnMapLoadedListener(this)
+ // 地图缩放监听
+ aMap.addOnCameraChangeListener(this)
+ // marker 点击事件监听
+ aMap.addOnMarkerClickListener(this)
+ // 点击marker弹出自定义popup
+ aMap.setInfoWindowAdapter(this)
+ //信息窗点击事件
+ aMap.addOnInfoWindowClickListener(this)
+ }
+
+ override fun onMapLoaded() {
+ //地图加载成功之后显示聚合点数据
+ initClustersMarkers()
+ }
+
+ override fun onCameraChange(p0: CameraPosition?) {
}
- override fun initEvent() {
+ //获取视野内的marker 根据聚合算法合成自定义的marker 显示视野内的marker
+ override fun onCameraChangeFinish(p0: CameraPosition?) {
+ //地图缩放之后显示聚合点数据
+ initClustersMarkers()
+ }
+ private fun initClustersMarkers() {
+ val proj = aMap.projection
+ val dm = resources.displayMetrics
+ var screenLocation: Point
+ markerOptionsInView.clear()
+ // 获取在当前视野内的marker
+ allMarkerOptions.forEach {
+ screenLocation = proj.toScreenLocation(it.position)
+ if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) {
+ //在当前可观区域内
+ markerOptionsInView.add(it)
+ }
+ }
+ // 自定义的聚合类MarkerCluster
+ val clustersMarkers: MutableList = ArrayList()
+ markerOptionsInView.forEach {
+ if (clustersMarkers.size == 0) {
+ //添加一个新的自定义marker
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )
+ } else {
+ var isInRange = false
+ //Kotlin foreach不能用break
+ for (view in clustersMarkers) {
+ //判断当前的marker是否在前面marker的聚合范围内 并且每个marker只会聚合一次。
+ if (view.bounds.contains(it.position)) {
+ view.addMarker(it)
+ isInRange = true
+ break
+ }
+ }
+ //如果没在任何范围内,自己单独形成一个自定义marker。在和后面的marker进行比较
+ if (!isInRange) {
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )//相距多少才聚合
+ }
+ }
+ }
+ // 设置聚合点的位置和icon
+ clustersMarkers.forEach {
+ it.setPositionAndIcon()
+ }
+ aMap.clear()
+ // 重新添加 marker
+ clustersMarkers.forEach {
+ aMap.addMarker(it.options)
+ }
+ }
+
+ override fun onMarkerClick(marker: Marker?): Boolean {
+ //显示闸井信息
+ marker?.showInfoWindow()
+ return true
+ }
+
+ override fun getInfoWindow(marker: Marker?): View? {
+ if (infoWindow == null) {
+ infoWindow = LayoutInflater.from(requireContext()).inflate(R.layout.popu_map_info, null)
+ }
+ val v = infoWindow!!
+ //反射得到popup里面的控件对象
+ val wellTypeView = v.findViewById(R.id.wellTypeView)
+ val wellCodeView = v.findViewById(R.id.wellCodeView)
+ val ownerShipView = v.findViewById(R.id.ownerShipView)
+ val locationView = v.findViewById(R.id.locationView)
+
+ //绑定数据
+ val clickedLatLng = marker?.position!!
+ for (well in wellModels) {
+ if (clickedLatLng.latitude == well.latGaode!!.toDouble()
+ && clickedLatLng.longitude == well.lngGaode!!.toDouble()
+ ) {
+ wellTypeView.text = String.format("井类型: ${well.wellType.toTypeName()}")
+ wellCodeView.text = String.format("井编号: ${well.wellCode}")
+ ownerShipView.text = String.format("权属单位: ${well.deptid.toDeptName()}")
+ locationView.text = String.format("详细位置: ${well.position}")
+ return infoWindow
+ }
+ }
+ "无法查看聚合点,请放大比例后再查看".show()
+ return null
+ }
+
+ /**
+ * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框
+ * */
+ override fun getInfoContents(p0: Marker?): View? = null
+
+ override fun onInfoWindowClick(p0: Marker?) {
+ if (p0 != null) {
+ AlertControlDialog.Builder()
+ .setContext(requireContext())
+ .setTitle("操作提示")
+ .setMessage("确定要前往吗")
+ .setNegativeButton("取消")
+ .setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ val latLng = p0.position
+ val lat = latLng.latitude.toString()
+ val lng = latLng.longitude.toString()
+ if (lat.isBlank() || lng.isBlank()) {
+ "窨井经纬度异常,无法开启导航".show()
+ return
+ }
+ Poi(p0.snippet, LatLng(lat.toDouble(), lng.toDouble()), "").showRouteOnMap(
+ requireContext()
+ )
+ }
+
+ override fun onCancelClick() {
+
+ }
+ }).build().show()
+ }
+ }
+
+ /***以下是地图生命周期管理************************************************************************/
+ override fun onResume() {
+ super.onResume()
+ homeView.mapView.onResume()
+ //每次页面切换都需要重新刷新不同状态的窨井数量
+// wellViewModel.countWellByState()
+// workOrderViewModel.countWorkOrderByState()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ homeView.mapView.onPause()
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ homeView.mapView.onSaveInstanceState(outState)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ homeView.mapView.onDestroy()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
new file mode 100644
index 0000000..4e916a9
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
@@ -0,0 +1,271 @@
+package com.casic.app.smartwell.sanxi.model;
+
+import java.util.List;
+
+public class WellListModel {
+
+ private int code;
+ private List data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public List getData() {
+ return data;
+ }
+
+ public void setData(List data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataDTO {
+ private String area;
+ private String bfzt;
+ private String bfztName;
+ private String coordinateX;
+ private String coordinateY;
+ private String deep;
+ private String deptName;
+ private String deptid;
+ private String id;
+ private String latBaidu;
+ private String latGaode;
+ private String lngBaidu;
+ private String lngGaode;
+ private String notes;
+ private String photos;
+ private String position;
+ private String staff;
+ private String tel;
+ private String ts;
+ private String valid;
+ private String watchData;
+ private String wellCode;
+ private String wellName;
+ private String wellType;
+ private String wellTypeName;
+
+ public String getArea() {
+ return area;
+ }
+
+ public void setArea(String area) {
+ this.area = area;
+ }
+
+ public String getBfzt() {
+ return bfzt;
+ }
+
+ public void setBfzt(String bfzt) {
+ this.bfzt = bfzt;
+ }
+
+ public String getBfztName() {
+ return bfztName;
+ }
+
+ public void setBfztName(String bfztName) {
+ this.bfztName = bfztName;
+ }
+
+ public String getCoordinateX() {
+ return coordinateX;
+ }
+
+ public void setCoordinateX(String coordinateX) {
+ this.coordinateX = coordinateX;
+ }
+
+ public String getCoordinateY() {
+ return coordinateY;
+ }
+
+ public void setCoordinateY(String coordinateY) {
+ this.coordinateY = coordinateY;
+ }
+
+ public String getDeep() {
+ return deep;
+ }
+
+ public void setDeep(String deep) {
+ this.deep = deep;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptid() {
+ return deptid;
+ }
+
+ public void setDeptid(String deptid) {
+ this.deptid = deptid;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getLatBaidu() {
+ return latBaidu;
+ }
+
+ public void setLatBaidu(String latBaidu) {
+ this.latBaidu = latBaidu;
+ }
+
+ public String getLatGaode() {
+ return latGaode;
+ }
+
+ public void setLatGaode(String latGaode) {
+ this.latGaode = latGaode;
+ }
+
+ public String getLngBaidu() {
+ return lngBaidu;
+ }
+
+ public void setLngBaidu(String lngBaidu) {
+ this.lngBaidu = lngBaidu;
+ }
+
+ public String getLngGaode() {
+ return lngGaode;
+ }
+
+ public void setLngGaode(String lngGaode) {
+ this.lngGaode = lngGaode;
+ }
+
+ public String getNotes() {
+ return notes;
+ }
+
+ public void setNotes(String notes) {
+ this.notes = notes;
+ }
+
+ public String getPhotos() {
+ return photos;
+ }
+
+ public void setPhotos(String photos) {
+ this.photos = photos;
+ }
+
+ public String getPosition() {
+ return position;
+ }
+
+ public void setPosition(String position) {
+ this.position = position;
+ }
+
+ public String getStaff() {
+ return staff;
+ }
+
+ public void setStaff(String staff) {
+ this.staff = staff;
+ }
+
+ public String getTel() {
+ return tel;
+ }
+
+ public void setTel(String tel) {
+ this.tel = tel;
+ }
+
+ public String getTs() {
+ return ts;
+ }
+
+ public void setTs(String ts) {
+ this.ts = ts;
+ }
+
+ public String getValid() {
+ return valid;
+ }
+
+ public void setValid(String valid) {
+ this.valid = valid;
+ }
+
+ public String getWatchData() {
+ return watchData;
+ }
+
+ public void setWatchData(String watchData) {
+ this.watchData = watchData;
+ }
+
+ public String getWellCode() {
+ return wellCode;
+ }
+
+ public void setWellCode(String wellCode) {
+ this.wellCode = wellCode;
+ }
+
+ public String getWellName() {
+ return wellName;
+ }
+
+ public void setWellName(String wellName) {
+ this.wellName = wellName;
+ }
+
+ public String getWellType() {
+ return wellType;
+ }
+
+ public void setWellType(String wellType) {
+ this.wellType = wellType;
+ }
+
+ public String getWellTypeName() {
+ return wellTypeName;
+ }
+
+ public void setWellTypeName(String wellTypeName) {
+ this.wellTypeName = wellTypeName;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
index 0fb598b..d57d378 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
@@ -1,6 +1,7 @@
package com.casic.app.smartwell.sanxi.utils
import android.Manifest
+import com.casic.app.smartwell.sanxi.R
object Constant {
@@ -19,7 +20,6 @@
const val USER_DEVICE_TYPE = "userDeviceType"
const val ACCOUNT = "account"
const val PASSWORD = "password"
- const val ALARM_TYPE = "alarmType"
const val APP_AUTHORITY = "com.casic.app.smartwell.sanxi.fileprovider"
const val CANCEL_ALARM_ACTION = "cancelAlarm"
@@ -29,11 +29,11 @@
const val RADIUS_SIZE = 100 //相距多少米才聚合,单位:米
const val DISTANCE = 5 //两点间距离阈值,单位:米
+ val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
+ val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
+
// val HOME_ICONS = arrayOf(R.drawable.ic_well, R.drawable.ic_overtime, R.drawable.ic_bfcf)
val HOME_ITEMS = arrayOf("闸井管理", "超时工单", "布防撤防")
val SUB_PAGE_TITLES = arrayOf("待处理", "待确认", "处理中", "已完成")
val OVER_TIME_PAGE_TITLES = arrayOf("超时未接单", "超时未处理")
-
- // val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
- val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ea56300..0416db4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -49,5 +49,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
index 291a985..c41c867 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
@@ -82,14 +82,40 @@
}
//窨井类型转换
-fun String.toChinese(): String {
+fun String.toTypeName(): String {
return when (this) {
- "0" -> "全部"
- "1" -> "一级"
- "2" -> "二级"
- "3" -> "三级"
+ "1" -> "雨水井"
+ "2" -> "污水井"
+ "3" -> "燃气井"
+ "4" -> "热力井"
+ "5" -> "电力井"
+ "6" -> "交通井"
+ "7" -> "路灯井"
+ "8" -> "通信井"
+ "9" -> "监控井"
else -> {
- "未知"
+ "其他"
+ }
+ }
+}
+
+fun String.toDeptName(): String {
+ return when (this) {
+ "0" -> "顶级"
+ "1148031048115494913" -> "二院"
+ "1178242695136149506" -> "电力公司"
+ "1178242900132757506" -> "滨海热电"
+ "24" -> "燃气集团总公司"
+ "30" -> "203所"
+ "1399230677135265794" -> "厦门测试"
+ "25" -> "第一分公司"
+ "26" -> "第二分公司"
+ "27" -> "第三分公司"
+ "28" -> "第四分公司"
+ "29" -> "高压管网分公司"
+ "1143796514486353922" -> "第五分公司"
+ else -> {
+ "其他"
}
}
}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
index 26f3085..4d0c818 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
@@ -1,24 +1,326 @@
package com.casic.app.smartwell.sanxi.fragment
+import android.graphics.Point
+import android.os.Bundle
+import android.util.Log
+import android.view.LayoutInflater
import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import com.amap.api.maps.AMap
+import com.amap.api.maps.AMapOptions
+import com.amap.api.maps.CameraUpdateFactory
+import com.amap.api.maps.CoordinateConverter
+import com.amap.api.maps.model.*
import com.casic.app.smartwell.sanxi.R
-import com.casic.app.smartwell.sanxi.base.BaseFragment
-import kotlinx.android.synthetic.main.include_base_title.*
+import com.casic.app.smartwell.sanxi.extensions.show
+import com.casic.app.smartwell.sanxi.extensions.showRouteOnMap
+import com.casic.app.smartwell.sanxi.extensions.toDeptName
+import com.casic.app.smartwell.sanxi.extensions.toTypeName
+import com.casic.app.smartwell.sanxi.model.WellListModel
+import com.casic.app.smartwell.sanxi.utils.Constant
+import com.casic.app.smartwell.sanxi.vm.WellViewModel
+import com.casic.app.smartwell.sanxi.widgets.EasyPopupWindow
+import com.casic.app.smartwell.sanxi.widgets.GaoDeClusterMarkerView
+import com.google.android.material.bottomsheet.BottomSheetBehavior
+import com.pengxh.app.multilib.utils.SizeUtil
+import com.pengxh.app.multilib.widget.dialog.AlertControlDialog
+import kotlinx.android.synthetic.main.fragment_home.view.*
-class HomePageFragment : BaseFragment() {
+class HomePageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener,
+ AMap.OnMarkerClickListener, AMap.InfoWindowAdapter, AMap.OnInfoWindowClickListener {
- override fun initLayoutView(): Int = R.layout.fragment_home
+ private val kTag = "HomePageFragment"
+ private lateinit var homeView: View
+ private lateinit var aMap: AMap
+ private lateinit var wellViewModel: WellViewModel
- override fun setupTopBarLayout() {
- leftBackView.visibility = View.GONE
- titleView.text = "首页"
+ /**
+ * 所有窨井列表信息集合
+ * */
+ private var wellModels: MutableList = ArrayList()
+
+ /**
+ * 所有的marker
+ */
+ private var allMarkerOptions: MutableList = ArrayList()
+
+ /**
+ * 视野内的marker
+ */
+ private var markerOptionsInView: MutableList = ArrayList()
+
+ /**
+ * 自定义Marker弹出框
+ * */
+ private var infoWindow: View? = null
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ homeView = inflater.inflate(R.layout.fragment_home, container, false)
+ homeView.titleView.text = "首页"
+ val easyPopupWindow = EasyPopupWindow(requireContext())
+ easyPopupWindow.setupPopupData(Constant.POPUP_IMAGES, Constant.POPUP_TITLES)
+ homeView.rightOptionView.setOnClickListener {
+ easyPopupWindow.setOnPopupWindowClickListener(object :
+ EasyPopupWindow.OnPopupWindowClickListener {
+ override fun onPopupClick(position: Int) {
+ when (position) {
+ 0 -> aMap.mapType = AMap.MAP_TYPE_NORMAL
+ 1 -> aMap.mapType = AMap.MAP_TYPE_SATELLITE
+ }
+ }
+ })
+ easyPopupWindow.setBackgroundDrawable(null)
+ val x: Int = homeView.rightOptionView.width - easyPopupWindow.width
+ easyPopupWindow.showAsDropDown(homeView.rightOptionView, x, 0)
+ }
+
+ //代码设置底部拉升距离
+ val bottomSheetBehavior = BottomSheetBehavior.from(homeView.bottomBehaviorLayout)
+ homeView.coordinatorLayout.post {
+ bottomSheetBehavior.isFitToContents = false
+ bottomSheetBehavior.halfExpandedRatio = 0.3f
+ bottomSheetBehavior.isHideable = false
+ bottomSheetBehavior.peekHeight = SizeUtil.dp2px(requireContext(), 30f)
+ }
+
+ //初始化vm
+ wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java)
+
+ //获取所有窨井数据
+ wellViewModel.obtainAllWell()
+ wellViewModel.allWellModel.observe(viewLifecycleOwner, {
+ if (it.code == 200) {
+ val latitudeList: MutableList = ArrayList()
+ val longitudeList: MutableList = ArrayList()
+ it.data?.forEach { well ->
+ val lat = well.latGaode.toString()
+ val lng = well.lngGaode.toString()
+ if (lat.isNotBlank() && lng.isNotBlank()) {
+ //返回true代表当前位置在大陆、港澳地区,反之不在
+ val latitude = lat.toDouble()
+ val longitude = lng.toDouble()
+ if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) {
+ //缓存所有设备详情,点击Marker时候需要
+ wellModels.add(well)
+ //分别缓存经、纬度
+ latitudeList.add(latitude)
+ longitudeList.add(longitude)
+ //将所有设备信息转化缓存为Marker点
+ allMarkerOptions.add(
+ MarkerOptions()
+ .position(LatLng(latitude, longitude))
+ .title(well.wellTypeName)
+ .snippet(well.wellName)
+ )
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度不在国内,异常经纬度 ===> [${lng},${lat}]")
+ }
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度异常,异常经纬度 ===> [${lng},${lat}]")
+ }
+ }
+ //计算所有点的中心点位置
+ val centerLatLng = LatLng(latitudeList.average(), longitudeList.average())
+ Log.d(
+ kTag,
+ "所有闸井中心点位置 ===> [${latitudeList.average()}, ${longitudeList.average()}]"
+ )
+ //移动到指定经纬度
+ val cameraPosition = CameraPosition(centerLatLng, 13f, 0f, 0f)
+ val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition)
+ aMap.animateCamera(cameraUpdate, 3000, null)
+ }
+ })
+
+ //地图初始化
+ initMap(savedInstanceState)
+ return homeView
}
- override fun initData() {
+ private fun initMap(savedInstanceState: Bundle?) {
+ homeView.mapView.onCreate(savedInstanceState)
+ aMap = homeView.mapView.map
+ aMap.mapType = AMap.MAP_TYPE_NORMAL
+ val uiSettings = aMap.uiSettings
+ uiSettings.isCompassEnabled = true
+ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER
+ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度
+ uiSettings.isRotateGesturesEnabled = false//不允许地图旋转
+
+ // 地图加载成功监听
+ aMap.addOnMapLoadedListener(this)
+ // 地图缩放监听
+ aMap.addOnCameraChangeListener(this)
+ // marker 点击事件监听
+ aMap.addOnMarkerClickListener(this)
+ // 点击marker弹出自定义popup
+ aMap.setInfoWindowAdapter(this)
+ //信息窗点击事件
+ aMap.addOnInfoWindowClickListener(this)
+ }
+
+ override fun onMapLoaded() {
+ //地图加载成功之后显示聚合点数据
+ initClustersMarkers()
+ }
+
+ override fun onCameraChange(p0: CameraPosition?) {
}
- override fun initEvent() {
+ //获取视野内的marker 根据聚合算法合成自定义的marker 显示视野内的marker
+ override fun onCameraChangeFinish(p0: CameraPosition?) {
+ //地图缩放之后显示聚合点数据
+ initClustersMarkers()
+ }
+ private fun initClustersMarkers() {
+ val proj = aMap.projection
+ val dm = resources.displayMetrics
+ var screenLocation: Point
+ markerOptionsInView.clear()
+ // 获取在当前视野内的marker
+ allMarkerOptions.forEach {
+ screenLocation = proj.toScreenLocation(it.position)
+ if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) {
+ //在当前可观区域内
+ markerOptionsInView.add(it)
+ }
+ }
+ // 自定义的聚合类MarkerCluster
+ val clustersMarkers: MutableList = ArrayList()
+ markerOptionsInView.forEach {
+ if (clustersMarkers.size == 0) {
+ //添加一个新的自定义marker
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )
+ } else {
+ var isInRange = false
+ //Kotlin foreach不能用break
+ for (view in clustersMarkers) {
+ //判断当前的marker是否在前面marker的聚合范围内 并且每个marker只会聚合一次。
+ if (view.bounds.contains(it.position)) {
+ view.addMarker(it)
+ isInRange = true
+ break
+ }
+ }
+ //如果没在任何范围内,自己单独形成一个自定义marker。在和后面的marker进行比较
+ if (!isInRange) {
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )//相距多少才聚合
+ }
+ }
+ }
+ // 设置聚合点的位置和icon
+ clustersMarkers.forEach {
+ it.setPositionAndIcon()
+ }
+ aMap.clear()
+ // 重新添加 marker
+ clustersMarkers.forEach {
+ aMap.addMarker(it.options)
+ }
+ }
+
+ override fun onMarkerClick(marker: Marker?): Boolean {
+ //显示闸井信息
+ marker?.showInfoWindow()
+ return true
+ }
+
+ override fun getInfoWindow(marker: Marker?): View? {
+ if (infoWindow == null) {
+ infoWindow = LayoutInflater.from(requireContext()).inflate(R.layout.popu_map_info, null)
+ }
+ val v = infoWindow!!
+ //反射得到popup里面的控件对象
+ val wellTypeView = v.findViewById(R.id.wellTypeView)
+ val wellCodeView = v.findViewById(R.id.wellCodeView)
+ val ownerShipView = v.findViewById(R.id.ownerShipView)
+ val locationView = v.findViewById(R.id.locationView)
+
+ //绑定数据
+ val clickedLatLng = marker?.position!!
+ for (well in wellModels) {
+ if (clickedLatLng.latitude == well.latGaode!!.toDouble()
+ && clickedLatLng.longitude == well.lngGaode!!.toDouble()
+ ) {
+ wellTypeView.text = String.format("井类型: ${well.wellType.toTypeName()}")
+ wellCodeView.text = String.format("井编号: ${well.wellCode}")
+ ownerShipView.text = String.format("权属单位: ${well.deptid.toDeptName()}")
+ locationView.text = String.format("详细位置: ${well.position}")
+ return infoWindow
+ }
+ }
+ "无法查看聚合点,请放大比例后再查看".show()
+ return null
+ }
+
+ /**
+ * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框
+ * */
+ override fun getInfoContents(p0: Marker?): View? = null
+
+ override fun onInfoWindowClick(p0: Marker?) {
+ if (p0 != null) {
+ AlertControlDialog.Builder()
+ .setContext(requireContext())
+ .setTitle("操作提示")
+ .setMessage("确定要前往吗")
+ .setNegativeButton("取消")
+ .setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ val latLng = p0.position
+ val lat = latLng.latitude.toString()
+ val lng = latLng.longitude.toString()
+ if (lat.isBlank() || lng.isBlank()) {
+ "窨井经纬度异常,无法开启导航".show()
+ return
+ }
+ Poi(p0.snippet, LatLng(lat.toDouble(), lng.toDouble()), "").showRouteOnMap(
+ requireContext()
+ )
+ }
+
+ override fun onCancelClick() {
+
+ }
+ }).build().show()
+ }
+ }
+
+ /***以下是地图生命周期管理************************************************************************/
+ override fun onResume() {
+ super.onResume()
+ homeView.mapView.onResume()
+ //每次页面切换都需要重新刷新不同状态的窨井数量
+// wellViewModel.countWellByState()
+// workOrderViewModel.countWorkOrderByState()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ homeView.mapView.onPause()
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ homeView.mapView.onSaveInstanceState(outState)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ homeView.mapView.onDestroy()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
new file mode 100644
index 0000000..4e916a9
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
@@ -0,0 +1,271 @@
+package com.casic.app.smartwell.sanxi.model;
+
+import java.util.List;
+
+public class WellListModel {
+
+ private int code;
+ private List data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public List getData() {
+ return data;
+ }
+
+ public void setData(List data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataDTO {
+ private String area;
+ private String bfzt;
+ private String bfztName;
+ private String coordinateX;
+ private String coordinateY;
+ private String deep;
+ private String deptName;
+ private String deptid;
+ private String id;
+ private String latBaidu;
+ private String latGaode;
+ private String lngBaidu;
+ private String lngGaode;
+ private String notes;
+ private String photos;
+ private String position;
+ private String staff;
+ private String tel;
+ private String ts;
+ private String valid;
+ private String watchData;
+ private String wellCode;
+ private String wellName;
+ private String wellType;
+ private String wellTypeName;
+
+ public String getArea() {
+ return area;
+ }
+
+ public void setArea(String area) {
+ this.area = area;
+ }
+
+ public String getBfzt() {
+ return bfzt;
+ }
+
+ public void setBfzt(String bfzt) {
+ this.bfzt = bfzt;
+ }
+
+ public String getBfztName() {
+ return bfztName;
+ }
+
+ public void setBfztName(String bfztName) {
+ this.bfztName = bfztName;
+ }
+
+ public String getCoordinateX() {
+ return coordinateX;
+ }
+
+ public void setCoordinateX(String coordinateX) {
+ this.coordinateX = coordinateX;
+ }
+
+ public String getCoordinateY() {
+ return coordinateY;
+ }
+
+ public void setCoordinateY(String coordinateY) {
+ this.coordinateY = coordinateY;
+ }
+
+ public String getDeep() {
+ return deep;
+ }
+
+ public void setDeep(String deep) {
+ this.deep = deep;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptid() {
+ return deptid;
+ }
+
+ public void setDeptid(String deptid) {
+ this.deptid = deptid;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getLatBaidu() {
+ return latBaidu;
+ }
+
+ public void setLatBaidu(String latBaidu) {
+ this.latBaidu = latBaidu;
+ }
+
+ public String getLatGaode() {
+ return latGaode;
+ }
+
+ public void setLatGaode(String latGaode) {
+ this.latGaode = latGaode;
+ }
+
+ public String getLngBaidu() {
+ return lngBaidu;
+ }
+
+ public void setLngBaidu(String lngBaidu) {
+ this.lngBaidu = lngBaidu;
+ }
+
+ public String getLngGaode() {
+ return lngGaode;
+ }
+
+ public void setLngGaode(String lngGaode) {
+ this.lngGaode = lngGaode;
+ }
+
+ public String getNotes() {
+ return notes;
+ }
+
+ public void setNotes(String notes) {
+ this.notes = notes;
+ }
+
+ public String getPhotos() {
+ return photos;
+ }
+
+ public void setPhotos(String photos) {
+ this.photos = photos;
+ }
+
+ public String getPosition() {
+ return position;
+ }
+
+ public void setPosition(String position) {
+ this.position = position;
+ }
+
+ public String getStaff() {
+ return staff;
+ }
+
+ public void setStaff(String staff) {
+ this.staff = staff;
+ }
+
+ public String getTel() {
+ return tel;
+ }
+
+ public void setTel(String tel) {
+ this.tel = tel;
+ }
+
+ public String getTs() {
+ return ts;
+ }
+
+ public void setTs(String ts) {
+ this.ts = ts;
+ }
+
+ public String getValid() {
+ return valid;
+ }
+
+ public void setValid(String valid) {
+ this.valid = valid;
+ }
+
+ public String getWatchData() {
+ return watchData;
+ }
+
+ public void setWatchData(String watchData) {
+ this.watchData = watchData;
+ }
+
+ public String getWellCode() {
+ return wellCode;
+ }
+
+ public void setWellCode(String wellCode) {
+ this.wellCode = wellCode;
+ }
+
+ public String getWellName() {
+ return wellName;
+ }
+
+ public void setWellName(String wellName) {
+ this.wellName = wellName;
+ }
+
+ public String getWellType() {
+ return wellType;
+ }
+
+ public void setWellType(String wellType) {
+ this.wellType = wellType;
+ }
+
+ public String getWellTypeName() {
+ return wellTypeName;
+ }
+
+ public void setWellTypeName(String wellTypeName) {
+ this.wellTypeName = wellTypeName;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
index 0fb598b..d57d378 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
@@ -1,6 +1,7 @@
package com.casic.app.smartwell.sanxi.utils
import android.Manifest
+import com.casic.app.smartwell.sanxi.R
object Constant {
@@ -19,7 +20,6 @@
const val USER_DEVICE_TYPE = "userDeviceType"
const val ACCOUNT = "account"
const val PASSWORD = "password"
- const val ALARM_TYPE = "alarmType"
const val APP_AUTHORITY = "com.casic.app.smartwell.sanxi.fileprovider"
const val CANCEL_ALARM_ACTION = "cancelAlarm"
@@ -29,11 +29,11 @@
const val RADIUS_SIZE = 100 //相距多少米才聚合,单位:米
const val DISTANCE = 5 //两点间距离阈值,单位:米
+ val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
+ val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
+
// val HOME_ICONS = arrayOf(R.drawable.ic_well, R.drawable.ic_overtime, R.drawable.ic_bfcf)
val HOME_ITEMS = arrayOf("闸井管理", "超时工单", "布防撤防")
val SUB_PAGE_TITLES = arrayOf("待处理", "待确认", "处理中", "已完成")
val OVER_TIME_PAGE_TITLES = arrayOf("超时未接单", "超时未处理")
-
- // val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
- val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
index 2bb0294..3c6fea3 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
@@ -153,6 +153,12 @@
): String
/**
+ * 获取获取闸井列表-不分页,地图用
+ */
+ @GET("/overview/wellList")
+ suspend fun obtainAllWell(@Header("token") token: String): String
+
+ /**
* 根据布防状态统计闸井数量接口
*/
@GET("/well/countByBfzt")
@@ -192,12 +198,6 @@
): String
/**
- * 获取获取闸井列表-不分页,地图用
- */
- @GET("/well/list")
- suspend fun obtainAllWell(@Header("token") token: String): String
-
- /**
* 获取井下监控设备列表
*
* @param id 窨井ID
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ea56300..0416db4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -49,5 +49,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
index 291a985..c41c867 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
@@ -82,14 +82,40 @@
}
//窨井类型转换
-fun String.toChinese(): String {
+fun String.toTypeName(): String {
return when (this) {
- "0" -> "全部"
- "1" -> "一级"
- "2" -> "二级"
- "3" -> "三级"
+ "1" -> "雨水井"
+ "2" -> "污水井"
+ "3" -> "燃气井"
+ "4" -> "热力井"
+ "5" -> "电力井"
+ "6" -> "交通井"
+ "7" -> "路灯井"
+ "8" -> "通信井"
+ "9" -> "监控井"
else -> {
- "未知"
+ "其他"
+ }
+ }
+}
+
+fun String.toDeptName(): String {
+ return when (this) {
+ "0" -> "顶级"
+ "1148031048115494913" -> "二院"
+ "1178242695136149506" -> "电力公司"
+ "1178242900132757506" -> "滨海热电"
+ "24" -> "燃气集团总公司"
+ "30" -> "203所"
+ "1399230677135265794" -> "厦门测试"
+ "25" -> "第一分公司"
+ "26" -> "第二分公司"
+ "27" -> "第三分公司"
+ "28" -> "第四分公司"
+ "29" -> "高压管网分公司"
+ "1143796514486353922" -> "第五分公司"
+ else -> {
+ "其他"
}
}
}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
index 26f3085..4d0c818 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
@@ -1,24 +1,326 @@
package com.casic.app.smartwell.sanxi.fragment
+import android.graphics.Point
+import android.os.Bundle
+import android.util.Log
+import android.view.LayoutInflater
import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import com.amap.api.maps.AMap
+import com.amap.api.maps.AMapOptions
+import com.amap.api.maps.CameraUpdateFactory
+import com.amap.api.maps.CoordinateConverter
+import com.amap.api.maps.model.*
import com.casic.app.smartwell.sanxi.R
-import com.casic.app.smartwell.sanxi.base.BaseFragment
-import kotlinx.android.synthetic.main.include_base_title.*
+import com.casic.app.smartwell.sanxi.extensions.show
+import com.casic.app.smartwell.sanxi.extensions.showRouteOnMap
+import com.casic.app.smartwell.sanxi.extensions.toDeptName
+import com.casic.app.smartwell.sanxi.extensions.toTypeName
+import com.casic.app.smartwell.sanxi.model.WellListModel
+import com.casic.app.smartwell.sanxi.utils.Constant
+import com.casic.app.smartwell.sanxi.vm.WellViewModel
+import com.casic.app.smartwell.sanxi.widgets.EasyPopupWindow
+import com.casic.app.smartwell.sanxi.widgets.GaoDeClusterMarkerView
+import com.google.android.material.bottomsheet.BottomSheetBehavior
+import com.pengxh.app.multilib.utils.SizeUtil
+import com.pengxh.app.multilib.widget.dialog.AlertControlDialog
+import kotlinx.android.synthetic.main.fragment_home.view.*
-class HomePageFragment : BaseFragment() {
+class HomePageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener,
+ AMap.OnMarkerClickListener, AMap.InfoWindowAdapter, AMap.OnInfoWindowClickListener {
- override fun initLayoutView(): Int = R.layout.fragment_home
+ private val kTag = "HomePageFragment"
+ private lateinit var homeView: View
+ private lateinit var aMap: AMap
+ private lateinit var wellViewModel: WellViewModel
- override fun setupTopBarLayout() {
- leftBackView.visibility = View.GONE
- titleView.text = "首页"
+ /**
+ * 所有窨井列表信息集合
+ * */
+ private var wellModels: MutableList = ArrayList()
+
+ /**
+ * 所有的marker
+ */
+ private var allMarkerOptions: MutableList = ArrayList()
+
+ /**
+ * 视野内的marker
+ */
+ private var markerOptionsInView: MutableList = ArrayList()
+
+ /**
+ * 自定义Marker弹出框
+ * */
+ private var infoWindow: View? = null
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ homeView = inflater.inflate(R.layout.fragment_home, container, false)
+ homeView.titleView.text = "首页"
+ val easyPopupWindow = EasyPopupWindow(requireContext())
+ easyPopupWindow.setupPopupData(Constant.POPUP_IMAGES, Constant.POPUP_TITLES)
+ homeView.rightOptionView.setOnClickListener {
+ easyPopupWindow.setOnPopupWindowClickListener(object :
+ EasyPopupWindow.OnPopupWindowClickListener {
+ override fun onPopupClick(position: Int) {
+ when (position) {
+ 0 -> aMap.mapType = AMap.MAP_TYPE_NORMAL
+ 1 -> aMap.mapType = AMap.MAP_TYPE_SATELLITE
+ }
+ }
+ })
+ easyPopupWindow.setBackgroundDrawable(null)
+ val x: Int = homeView.rightOptionView.width - easyPopupWindow.width
+ easyPopupWindow.showAsDropDown(homeView.rightOptionView, x, 0)
+ }
+
+ //代码设置底部拉升距离
+ val bottomSheetBehavior = BottomSheetBehavior.from(homeView.bottomBehaviorLayout)
+ homeView.coordinatorLayout.post {
+ bottomSheetBehavior.isFitToContents = false
+ bottomSheetBehavior.halfExpandedRatio = 0.3f
+ bottomSheetBehavior.isHideable = false
+ bottomSheetBehavior.peekHeight = SizeUtil.dp2px(requireContext(), 30f)
+ }
+
+ //初始化vm
+ wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java)
+
+ //获取所有窨井数据
+ wellViewModel.obtainAllWell()
+ wellViewModel.allWellModel.observe(viewLifecycleOwner, {
+ if (it.code == 200) {
+ val latitudeList: MutableList = ArrayList()
+ val longitudeList: MutableList = ArrayList()
+ it.data?.forEach { well ->
+ val lat = well.latGaode.toString()
+ val lng = well.lngGaode.toString()
+ if (lat.isNotBlank() && lng.isNotBlank()) {
+ //返回true代表当前位置在大陆、港澳地区,反之不在
+ val latitude = lat.toDouble()
+ val longitude = lng.toDouble()
+ if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) {
+ //缓存所有设备详情,点击Marker时候需要
+ wellModels.add(well)
+ //分别缓存经、纬度
+ latitudeList.add(latitude)
+ longitudeList.add(longitude)
+ //将所有设备信息转化缓存为Marker点
+ allMarkerOptions.add(
+ MarkerOptions()
+ .position(LatLng(latitude, longitude))
+ .title(well.wellTypeName)
+ .snippet(well.wellName)
+ )
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度不在国内,异常经纬度 ===> [${lng},${lat}]")
+ }
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度异常,异常经纬度 ===> [${lng},${lat}]")
+ }
+ }
+ //计算所有点的中心点位置
+ val centerLatLng = LatLng(latitudeList.average(), longitudeList.average())
+ Log.d(
+ kTag,
+ "所有闸井中心点位置 ===> [${latitudeList.average()}, ${longitudeList.average()}]"
+ )
+ //移动到指定经纬度
+ val cameraPosition = CameraPosition(centerLatLng, 13f, 0f, 0f)
+ val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition)
+ aMap.animateCamera(cameraUpdate, 3000, null)
+ }
+ })
+
+ //地图初始化
+ initMap(savedInstanceState)
+ return homeView
}
- override fun initData() {
+ private fun initMap(savedInstanceState: Bundle?) {
+ homeView.mapView.onCreate(savedInstanceState)
+ aMap = homeView.mapView.map
+ aMap.mapType = AMap.MAP_TYPE_NORMAL
+ val uiSettings = aMap.uiSettings
+ uiSettings.isCompassEnabled = true
+ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER
+ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度
+ uiSettings.isRotateGesturesEnabled = false//不允许地图旋转
+
+ // 地图加载成功监听
+ aMap.addOnMapLoadedListener(this)
+ // 地图缩放监听
+ aMap.addOnCameraChangeListener(this)
+ // marker 点击事件监听
+ aMap.addOnMarkerClickListener(this)
+ // 点击marker弹出自定义popup
+ aMap.setInfoWindowAdapter(this)
+ //信息窗点击事件
+ aMap.addOnInfoWindowClickListener(this)
+ }
+
+ override fun onMapLoaded() {
+ //地图加载成功之后显示聚合点数据
+ initClustersMarkers()
+ }
+
+ override fun onCameraChange(p0: CameraPosition?) {
}
- override fun initEvent() {
+ //获取视野内的marker 根据聚合算法合成自定义的marker 显示视野内的marker
+ override fun onCameraChangeFinish(p0: CameraPosition?) {
+ //地图缩放之后显示聚合点数据
+ initClustersMarkers()
+ }
+ private fun initClustersMarkers() {
+ val proj = aMap.projection
+ val dm = resources.displayMetrics
+ var screenLocation: Point
+ markerOptionsInView.clear()
+ // 获取在当前视野内的marker
+ allMarkerOptions.forEach {
+ screenLocation = proj.toScreenLocation(it.position)
+ if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) {
+ //在当前可观区域内
+ markerOptionsInView.add(it)
+ }
+ }
+ // 自定义的聚合类MarkerCluster
+ val clustersMarkers: MutableList = ArrayList()
+ markerOptionsInView.forEach {
+ if (clustersMarkers.size == 0) {
+ //添加一个新的自定义marker
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )
+ } else {
+ var isInRange = false
+ //Kotlin foreach不能用break
+ for (view in clustersMarkers) {
+ //判断当前的marker是否在前面marker的聚合范围内 并且每个marker只会聚合一次。
+ if (view.bounds.contains(it.position)) {
+ view.addMarker(it)
+ isInRange = true
+ break
+ }
+ }
+ //如果没在任何范围内,自己单独形成一个自定义marker。在和后面的marker进行比较
+ if (!isInRange) {
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )//相距多少才聚合
+ }
+ }
+ }
+ // 设置聚合点的位置和icon
+ clustersMarkers.forEach {
+ it.setPositionAndIcon()
+ }
+ aMap.clear()
+ // 重新添加 marker
+ clustersMarkers.forEach {
+ aMap.addMarker(it.options)
+ }
+ }
+
+ override fun onMarkerClick(marker: Marker?): Boolean {
+ //显示闸井信息
+ marker?.showInfoWindow()
+ return true
+ }
+
+ override fun getInfoWindow(marker: Marker?): View? {
+ if (infoWindow == null) {
+ infoWindow = LayoutInflater.from(requireContext()).inflate(R.layout.popu_map_info, null)
+ }
+ val v = infoWindow!!
+ //反射得到popup里面的控件对象
+ val wellTypeView = v.findViewById(R.id.wellTypeView)
+ val wellCodeView = v.findViewById(R.id.wellCodeView)
+ val ownerShipView = v.findViewById(R.id.ownerShipView)
+ val locationView = v.findViewById(R.id.locationView)
+
+ //绑定数据
+ val clickedLatLng = marker?.position!!
+ for (well in wellModels) {
+ if (clickedLatLng.latitude == well.latGaode!!.toDouble()
+ && clickedLatLng.longitude == well.lngGaode!!.toDouble()
+ ) {
+ wellTypeView.text = String.format("井类型: ${well.wellType.toTypeName()}")
+ wellCodeView.text = String.format("井编号: ${well.wellCode}")
+ ownerShipView.text = String.format("权属单位: ${well.deptid.toDeptName()}")
+ locationView.text = String.format("详细位置: ${well.position}")
+ return infoWindow
+ }
+ }
+ "无法查看聚合点,请放大比例后再查看".show()
+ return null
+ }
+
+ /**
+ * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框
+ * */
+ override fun getInfoContents(p0: Marker?): View? = null
+
+ override fun onInfoWindowClick(p0: Marker?) {
+ if (p0 != null) {
+ AlertControlDialog.Builder()
+ .setContext(requireContext())
+ .setTitle("操作提示")
+ .setMessage("确定要前往吗")
+ .setNegativeButton("取消")
+ .setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ val latLng = p0.position
+ val lat = latLng.latitude.toString()
+ val lng = latLng.longitude.toString()
+ if (lat.isBlank() || lng.isBlank()) {
+ "窨井经纬度异常,无法开启导航".show()
+ return
+ }
+ Poi(p0.snippet, LatLng(lat.toDouble(), lng.toDouble()), "").showRouteOnMap(
+ requireContext()
+ )
+ }
+
+ override fun onCancelClick() {
+
+ }
+ }).build().show()
+ }
+ }
+
+ /***以下是地图生命周期管理************************************************************************/
+ override fun onResume() {
+ super.onResume()
+ homeView.mapView.onResume()
+ //每次页面切换都需要重新刷新不同状态的窨井数量
+// wellViewModel.countWellByState()
+// workOrderViewModel.countWorkOrderByState()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ homeView.mapView.onPause()
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ homeView.mapView.onSaveInstanceState(outState)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ homeView.mapView.onDestroy()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
new file mode 100644
index 0000000..4e916a9
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
@@ -0,0 +1,271 @@
+package com.casic.app.smartwell.sanxi.model;
+
+import java.util.List;
+
+public class WellListModel {
+
+ private int code;
+ private List data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public List getData() {
+ return data;
+ }
+
+ public void setData(List data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataDTO {
+ private String area;
+ private String bfzt;
+ private String bfztName;
+ private String coordinateX;
+ private String coordinateY;
+ private String deep;
+ private String deptName;
+ private String deptid;
+ private String id;
+ private String latBaidu;
+ private String latGaode;
+ private String lngBaidu;
+ private String lngGaode;
+ private String notes;
+ private String photos;
+ private String position;
+ private String staff;
+ private String tel;
+ private String ts;
+ private String valid;
+ private String watchData;
+ private String wellCode;
+ private String wellName;
+ private String wellType;
+ private String wellTypeName;
+
+ public String getArea() {
+ return area;
+ }
+
+ public void setArea(String area) {
+ this.area = area;
+ }
+
+ public String getBfzt() {
+ return bfzt;
+ }
+
+ public void setBfzt(String bfzt) {
+ this.bfzt = bfzt;
+ }
+
+ public String getBfztName() {
+ return bfztName;
+ }
+
+ public void setBfztName(String bfztName) {
+ this.bfztName = bfztName;
+ }
+
+ public String getCoordinateX() {
+ return coordinateX;
+ }
+
+ public void setCoordinateX(String coordinateX) {
+ this.coordinateX = coordinateX;
+ }
+
+ public String getCoordinateY() {
+ return coordinateY;
+ }
+
+ public void setCoordinateY(String coordinateY) {
+ this.coordinateY = coordinateY;
+ }
+
+ public String getDeep() {
+ return deep;
+ }
+
+ public void setDeep(String deep) {
+ this.deep = deep;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptid() {
+ return deptid;
+ }
+
+ public void setDeptid(String deptid) {
+ this.deptid = deptid;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getLatBaidu() {
+ return latBaidu;
+ }
+
+ public void setLatBaidu(String latBaidu) {
+ this.latBaidu = latBaidu;
+ }
+
+ public String getLatGaode() {
+ return latGaode;
+ }
+
+ public void setLatGaode(String latGaode) {
+ this.latGaode = latGaode;
+ }
+
+ public String getLngBaidu() {
+ return lngBaidu;
+ }
+
+ public void setLngBaidu(String lngBaidu) {
+ this.lngBaidu = lngBaidu;
+ }
+
+ public String getLngGaode() {
+ return lngGaode;
+ }
+
+ public void setLngGaode(String lngGaode) {
+ this.lngGaode = lngGaode;
+ }
+
+ public String getNotes() {
+ return notes;
+ }
+
+ public void setNotes(String notes) {
+ this.notes = notes;
+ }
+
+ public String getPhotos() {
+ return photos;
+ }
+
+ public void setPhotos(String photos) {
+ this.photos = photos;
+ }
+
+ public String getPosition() {
+ return position;
+ }
+
+ public void setPosition(String position) {
+ this.position = position;
+ }
+
+ public String getStaff() {
+ return staff;
+ }
+
+ public void setStaff(String staff) {
+ this.staff = staff;
+ }
+
+ public String getTel() {
+ return tel;
+ }
+
+ public void setTel(String tel) {
+ this.tel = tel;
+ }
+
+ public String getTs() {
+ return ts;
+ }
+
+ public void setTs(String ts) {
+ this.ts = ts;
+ }
+
+ public String getValid() {
+ return valid;
+ }
+
+ public void setValid(String valid) {
+ this.valid = valid;
+ }
+
+ public String getWatchData() {
+ return watchData;
+ }
+
+ public void setWatchData(String watchData) {
+ this.watchData = watchData;
+ }
+
+ public String getWellCode() {
+ return wellCode;
+ }
+
+ public void setWellCode(String wellCode) {
+ this.wellCode = wellCode;
+ }
+
+ public String getWellName() {
+ return wellName;
+ }
+
+ public void setWellName(String wellName) {
+ this.wellName = wellName;
+ }
+
+ public String getWellType() {
+ return wellType;
+ }
+
+ public void setWellType(String wellType) {
+ this.wellType = wellType;
+ }
+
+ public String getWellTypeName() {
+ return wellTypeName;
+ }
+
+ public void setWellTypeName(String wellTypeName) {
+ this.wellTypeName = wellTypeName;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
index 0fb598b..d57d378 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
@@ -1,6 +1,7 @@
package com.casic.app.smartwell.sanxi.utils
import android.Manifest
+import com.casic.app.smartwell.sanxi.R
object Constant {
@@ -19,7 +20,6 @@
const val USER_DEVICE_TYPE = "userDeviceType"
const val ACCOUNT = "account"
const val PASSWORD = "password"
- const val ALARM_TYPE = "alarmType"
const val APP_AUTHORITY = "com.casic.app.smartwell.sanxi.fileprovider"
const val CANCEL_ALARM_ACTION = "cancelAlarm"
@@ -29,11 +29,11 @@
const val RADIUS_SIZE = 100 //相距多少米才聚合,单位:米
const val DISTANCE = 5 //两点间距离阈值,单位:米
+ val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
+ val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
+
// val HOME_ICONS = arrayOf(R.drawable.ic_well, R.drawable.ic_overtime, R.drawable.ic_bfcf)
val HOME_ITEMS = arrayOf("闸井管理", "超时工单", "布防撤防")
val SUB_PAGE_TITLES = arrayOf("待处理", "待确认", "处理中", "已完成")
val OVER_TIME_PAGE_TITLES = arrayOf("超时未接单", "超时未处理")
-
- // val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
- val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
index 2bb0294..3c6fea3 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
@@ -153,6 +153,12 @@
): String
/**
+ * 获取获取闸井列表-不分页,地图用
+ */
+ @GET("/overview/wellList")
+ suspend fun obtainAllWell(@Header("token") token: String): String
+
+ /**
* 根据布防状态统计闸井数量接口
*/
@GET("/well/countByBfzt")
@@ -192,12 +198,6 @@
): String
/**
- * 获取获取闸井列表-不分页,地图用
- */
- @GET("/well/list")
- suspend fun obtainAllWell(@Header("token") token: String): String
-
- /**
* 获取井下监控设备列表
*
* @param id 窨井ID
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
index 35af71d..f67ccb6 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
@@ -151,6 +151,13 @@
return api.obtainOrderStatus(AuthenticationHelper.token!!)
}
+ /**
+ * 获取获取闸井列表-不分页
+ */
+ suspend fun obtainAllWell(): String {
+ return api.obtainAllWell(AuthenticationHelper.token!!)
+ }
+
// /**
// * 根据布防状态统计闸井数量接口
// */
@@ -190,13 +197,6 @@
// }
//
// /**
-// * 获取获取闸井列表-不分页
-// */
-// suspend fun obtainAllWell(): String {
-// return api.obtainAllWell(AuthenticationHelper.token!!)
-// }
-//
-// /**
// * 获取井下监控设备列表
// */
// suspend fun obtainMonitorResult(id: String): String {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ea56300..0416db4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -49,5 +49,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
index 291a985..c41c867 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
@@ -82,14 +82,40 @@
}
//窨井类型转换
-fun String.toChinese(): String {
+fun String.toTypeName(): String {
return when (this) {
- "0" -> "全部"
- "1" -> "一级"
- "2" -> "二级"
- "3" -> "三级"
+ "1" -> "雨水井"
+ "2" -> "污水井"
+ "3" -> "燃气井"
+ "4" -> "热力井"
+ "5" -> "电力井"
+ "6" -> "交通井"
+ "7" -> "路灯井"
+ "8" -> "通信井"
+ "9" -> "监控井"
else -> {
- "未知"
+ "其他"
+ }
+ }
+}
+
+fun String.toDeptName(): String {
+ return when (this) {
+ "0" -> "顶级"
+ "1148031048115494913" -> "二院"
+ "1178242695136149506" -> "电力公司"
+ "1178242900132757506" -> "滨海热电"
+ "24" -> "燃气集团总公司"
+ "30" -> "203所"
+ "1399230677135265794" -> "厦门测试"
+ "25" -> "第一分公司"
+ "26" -> "第二分公司"
+ "27" -> "第三分公司"
+ "28" -> "第四分公司"
+ "29" -> "高压管网分公司"
+ "1143796514486353922" -> "第五分公司"
+ else -> {
+ "其他"
}
}
}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
index 26f3085..4d0c818 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
@@ -1,24 +1,326 @@
package com.casic.app.smartwell.sanxi.fragment
+import android.graphics.Point
+import android.os.Bundle
+import android.util.Log
+import android.view.LayoutInflater
import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import com.amap.api.maps.AMap
+import com.amap.api.maps.AMapOptions
+import com.amap.api.maps.CameraUpdateFactory
+import com.amap.api.maps.CoordinateConverter
+import com.amap.api.maps.model.*
import com.casic.app.smartwell.sanxi.R
-import com.casic.app.smartwell.sanxi.base.BaseFragment
-import kotlinx.android.synthetic.main.include_base_title.*
+import com.casic.app.smartwell.sanxi.extensions.show
+import com.casic.app.smartwell.sanxi.extensions.showRouteOnMap
+import com.casic.app.smartwell.sanxi.extensions.toDeptName
+import com.casic.app.smartwell.sanxi.extensions.toTypeName
+import com.casic.app.smartwell.sanxi.model.WellListModel
+import com.casic.app.smartwell.sanxi.utils.Constant
+import com.casic.app.smartwell.sanxi.vm.WellViewModel
+import com.casic.app.smartwell.sanxi.widgets.EasyPopupWindow
+import com.casic.app.smartwell.sanxi.widgets.GaoDeClusterMarkerView
+import com.google.android.material.bottomsheet.BottomSheetBehavior
+import com.pengxh.app.multilib.utils.SizeUtil
+import com.pengxh.app.multilib.widget.dialog.AlertControlDialog
+import kotlinx.android.synthetic.main.fragment_home.view.*
-class HomePageFragment : BaseFragment() {
+class HomePageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener,
+ AMap.OnMarkerClickListener, AMap.InfoWindowAdapter, AMap.OnInfoWindowClickListener {
- override fun initLayoutView(): Int = R.layout.fragment_home
+ private val kTag = "HomePageFragment"
+ private lateinit var homeView: View
+ private lateinit var aMap: AMap
+ private lateinit var wellViewModel: WellViewModel
- override fun setupTopBarLayout() {
- leftBackView.visibility = View.GONE
- titleView.text = "首页"
+ /**
+ * 所有窨井列表信息集合
+ * */
+ private var wellModels: MutableList = ArrayList()
+
+ /**
+ * 所有的marker
+ */
+ private var allMarkerOptions: MutableList = ArrayList()
+
+ /**
+ * 视野内的marker
+ */
+ private var markerOptionsInView: MutableList = ArrayList()
+
+ /**
+ * 自定义Marker弹出框
+ * */
+ private var infoWindow: View? = null
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ homeView = inflater.inflate(R.layout.fragment_home, container, false)
+ homeView.titleView.text = "首页"
+ val easyPopupWindow = EasyPopupWindow(requireContext())
+ easyPopupWindow.setupPopupData(Constant.POPUP_IMAGES, Constant.POPUP_TITLES)
+ homeView.rightOptionView.setOnClickListener {
+ easyPopupWindow.setOnPopupWindowClickListener(object :
+ EasyPopupWindow.OnPopupWindowClickListener {
+ override fun onPopupClick(position: Int) {
+ when (position) {
+ 0 -> aMap.mapType = AMap.MAP_TYPE_NORMAL
+ 1 -> aMap.mapType = AMap.MAP_TYPE_SATELLITE
+ }
+ }
+ })
+ easyPopupWindow.setBackgroundDrawable(null)
+ val x: Int = homeView.rightOptionView.width - easyPopupWindow.width
+ easyPopupWindow.showAsDropDown(homeView.rightOptionView, x, 0)
+ }
+
+ //代码设置底部拉升距离
+ val bottomSheetBehavior = BottomSheetBehavior.from(homeView.bottomBehaviorLayout)
+ homeView.coordinatorLayout.post {
+ bottomSheetBehavior.isFitToContents = false
+ bottomSheetBehavior.halfExpandedRatio = 0.3f
+ bottomSheetBehavior.isHideable = false
+ bottomSheetBehavior.peekHeight = SizeUtil.dp2px(requireContext(), 30f)
+ }
+
+ //初始化vm
+ wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java)
+
+ //获取所有窨井数据
+ wellViewModel.obtainAllWell()
+ wellViewModel.allWellModel.observe(viewLifecycleOwner, {
+ if (it.code == 200) {
+ val latitudeList: MutableList = ArrayList()
+ val longitudeList: MutableList = ArrayList()
+ it.data?.forEach { well ->
+ val lat = well.latGaode.toString()
+ val lng = well.lngGaode.toString()
+ if (lat.isNotBlank() && lng.isNotBlank()) {
+ //返回true代表当前位置在大陆、港澳地区,反之不在
+ val latitude = lat.toDouble()
+ val longitude = lng.toDouble()
+ if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) {
+ //缓存所有设备详情,点击Marker时候需要
+ wellModels.add(well)
+ //分别缓存经、纬度
+ latitudeList.add(latitude)
+ longitudeList.add(longitude)
+ //将所有设备信息转化缓存为Marker点
+ allMarkerOptions.add(
+ MarkerOptions()
+ .position(LatLng(latitude, longitude))
+ .title(well.wellTypeName)
+ .snippet(well.wellName)
+ )
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度不在国内,异常经纬度 ===> [${lng},${lat}]")
+ }
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度异常,异常经纬度 ===> [${lng},${lat}]")
+ }
+ }
+ //计算所有点的中心点位置
+ val centerLatLng = LatLng(latitudeList.average(), longitudeList.average())
+ Log.d(
+ kTag,
+ "所有闸井中心点位置 ===> [${latitudeList.average()}, ${longitudeList.average()}]"
+ )
+ //移动到指定经纬度
+ val cameraPosition = CameraPosition(centerLatLng, 13f, 0f, 0f)
+ val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition)
+ aMap.animateCamera(cameraUpdate, 3000, null)
+ }
+ })
+
+ //地图初始化
+ initMap(savedInstanceState)
+ return homeView
}
- override fun initData() {
+ private fun initMap(savedInstanceState: Bundle?) {
+ homeView.mapView.onCreate(savedInstanceState)
+ aMap = homeView.mapView.map
+ aMap.mapType = AMap.MAP_TYPE_NORMAL
+ val uiSettings = aMap.uiSettings
+ uiSettings.isCompassEnabled = true
+ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER
+ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度
+ uiSettings.isRotateGesturesEnabled = false//不允许地图旋转
+
+ // 地图加载成功监听
+ aMap.addOnMapLoadedListener(this)
+ // 地图缩放监听
+ aMap.addOnCameraChangeListener(this)
+ // marker 点击事件监听
+ aMap.addOnMarkerClickListener(this)
+ // 点击marker弹出自定义popup
+ aMap.setInfoWindowAdapter(this)
+ //信息窗点击事件
+ aMap.addOnInfoWindowClickListener(this)
+ }
+
+ override fun onMapLoaded() {
+ //地图加载成功之后显示聚合点数据
+ initClustersMarkers()
+ }
+
+ override fun onCameraChange(p0: CameraPosition?) {
}
- override fun initEvent() {
+ //获取视野内的marker 根据聚合算法合成自定义的marker 显示视野内的marker
+ override fun onCameraChangeFinish(p0: CameraPosition?) {
+ //地图缩放之后显示聚合点数据
+ initClustersMarkers()
+ }
+ private fun initClustersMarkers() {
+ val proj = aMap.projection
+ val dm = resources.displayMetrics
+ var screenLocation: Point
+ markerOptionsInView.clear()
+ // 获取在当前视野内的marker
+ allMarkerOptions.forEach {
+ screenLocation = proj.toScreenLocation(it.position)
+ if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) {
+ //在当前可观区域内
+ markerOptionsInView.add(it)
+ }
+ }
+ // 自定义的聚合类MarkerCluster
+ val clustersMarkers: MutableList = ArrayList()
+ markerOptionsInView.forEach {
+ if (clustersMarkers.size == 0) {
+ //添加一个新的自定义marker
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )
+ } else {
+ var isInRange = false
+ //Kotlin foreach不能用break
+ for (view in clustersMarkers) {
+ //判断当前的marker是否在前面marker的聚合范围内 并且每个marker只会聚合一次。
+ if (view.bounds.contains(it.position)) {
+ view.addMarker(it)
+ isInRange = true
+ break
+ }
+ }
+ //如果没在任何范围内,自己单独形成一个自定义marker。在和后面的marker进行比较
+ if (!isInRange) {
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )//相距多少才聚合
+ }
+ }
+ }
+ // 设置聚合点的位置和icon
+ clustersMarkers.forEach {
+ it.setPositionAndIcon()
+ }
+ aMap.clear()
+ // 重新添加 marker
+ clustersMarkers.forEach {
+ aMap.addMarker(it.options)
+ }
+ }
+
+ override fun onMarkerClick(marker: Marker?): Boolean {
+ //显示闸井信息
+ marker?.showInfoWindow()
+ return true
+ }
+
+ override fun getInfoWindow(marker: Marker?): View? {
+ if (infoWindow == null) {
+ infoWindow = LayoutInflater.from(requireContext()).inflate(R.layout.popu_map_info, null)
+ }
+ val v = infoWindow!!
+ //反射得到popup里面的控件对象
+ val wellTypeView = v.findViewById(R.id.wellTypeView)
+ val wellCodeView = v.findViewById(R.id.wellCodeView)
+ val ownerShipView = v.findViewById(R.id.ownerShipView)
+ val locationView = v.findViewById(R.id.locationView)
+
+ //绑定数据
+ val clickedLatLng = marker?.position!!
+ for (well in wellModels) {
+ if (clickedLatLng.latitude == well.latGaode!!.toDouble()
+ && clickedLatLng.longitude == well.lngGaode!!.toDouble()
+ ) {
+ wellTypeView.text = String.format("井类型: ${well.wellType.toTypeName()}")
+ wellCodeView.text = String.format("井编号: ${well.wellCode}")
+ ownerShipView.text = String.format("权属单位: ${well.deptid.toDeptName()}")
+ locationView.text = String.format("详细位置: ${well.position}")
+ return infoWindow
+ }
+ }
+ "无法查看聚合点,请放大比例后再查看".show()
+ return null
+ }
+
+ /**
+ * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框
+ * */
+ override fun getInfoContents(p0: Marker?): View? = null
+
+ override fun onInfoWindowClick(p0: Marker?) {
+ if (p0 != null) {
+ AlertControlDialog.Builder()
+ .setContext(requireContext())
+ .setTitle("操作提示")
+ .setMessage("确定要前往吗")
+ .setNegativeButton("取消")
+ .setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ val latLng = p0.position
+ val lat = latLng.latitude.toString()
+ val lng = latLng.longitude.toString()
+ if (lat.isBlank() || lng.isBlank()) {
+ "窨井经纬度异常,无法开启导航".show()
+ return
+ }
+ Poi(p0.snippet, LatLng(lat.toDouble(), lng.toDouble()), "").showRouteOnMap(
+ requireContext()
+ )
+ }
+
+ override fun onCancelClick() {
+
+ }
+ }).build().show()
+ }
+ }
+
+ /***以下是地图生命周期管理************************************************************************/
+ override fun onResume() {
+ super.onResume()
+ homeView.mapView.onResume()
+ //每次页面切换都需要重新刷新不同状态的窨井数量
+// wellViewModel.countWellByState()
+// workOrderViewModel.countWorkOrderByState()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ homeView.mapView.onPause()
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ homeView.mapView.onSaveInstanceState(outState)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ homeView.mapView.onDestroy()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
new file mode 100644
index 0000000..4e916a9
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
@@ -0,0 +1,271 @@
+package com.casic.app.smartwell.sanxi.model;
+
+import java.util.List;
+
+public class WellListModel {
+
+ private int code;
+ private List data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public List getData() {
+ return data;
+ }
+
+ public void setData(List data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataDTO {
+ private String area;
+ private String bfzt;
+ private String bfztName;
+ private String coordinateX;
+ private String coordinateY;
+ private String deep;
+ private String deptName;
+ private String deptid;
+ private String id;
+ private String latBaidu;
+ private String latGaode;
+ private String lngBaidu;
+ private String lngGaode;
+ private String notes;
+ private String photos;
+ private String position;
+ private String staff;
+ private String tel;
+ private String ts;
+ private String valid;
+ private String watchData;
+ private String wellCode;
+ private String wellName;
+ private String wellType;
+ private String wellTypeName;
+
+ public String getArea() {
+ return area;
+ }
+
+ public void setArea(String area) {
+ this.area = area;
+ }
+
+ public String getBfzt() {
+ return bfzt;
+ }
+
+ public void setBfzt(String bfzt) {
+ this.bfzt = bfzt;
+ }
+
+ public String getBfztName() {
+ return bfztName;
+ }
+
+ public void setBfztName(String bfztName) {
+ this.bfztName = bfztName;
+ }
+
+ public String getCoordinateX() {
+ return coordinateX;
+ }
+
+ public void setCoordinateX(String coordinateX) {
+ this.coordinateX = coordinateX;
+ }
+
+ public String getCoordinateY() {
+ return coordinateY;
+ }
+
+ public void setCoordinateY(String coordinateY) {
+ this.coordinateY = coordinateY;
+ }
+
+ public String getDeep() {
+ return deep;
+ }
+
+ public void setDeep(String deep) {
+ this.deep = deep;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptid() {
+ return deptid;
+ }
+
+ public void setDeptid(String deptid) {
+ this.deptid = deptid;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getLatBaidu() {
+ return latBaidu;
+ }
+
+ public void setLatBaidu(String latBaidu) {
+ this.latBaidu = latBaidu;
+ }
+
+ public String getLatGaode() {
+ return latGaode;
+ }
+
+ public void setLatGaode(String latGaode) {
+ this.latGaode = latGaode;
+ }
+
+ public String getLngBaidu() {
+ return lngBaidu;
+ }
+
+ public void setLngBaidu(String lngBaidu) {
+ this.lngBaidu = lngBaidu;
+ }
+
+ public String getLngGaode() {
+ return lngGaode;
+ }
+
+ public void setLngGaode(String lngGaode) {
+ this.lngGaode = lngGaode;
+ }
+
+ public String getNotes() {
+ return notes;
+ }
+
+ public void setNotes(String notes) {
+ this.notes = notes;
+ }
+
+ public String getPhotos() {
+ return photos;
+ }
+
+ public void setPhotos(String photos) {
+ this.photos = photos;
+ }
+
+ public String getPosition() {
+ return position;
+ }
+
+ public void setPosition(String position) {
+ this.position = position;
+ }
+
+ public String getStaff() {
+ return staff;
+ }
+
+ public void setStaff(String staff) {
+ this.staff = staff;
+ }
+
+ public String getTel() {
+ return tel;
+ }
+
+ public void setTel(String tel) {
+ this.tel = tel;
+ }
+
+ public String getTs() {
+ return ts;
+ }
+
+ public void setTs(String ts) {
+ this.ts = ts;
+ }
+
+ public String getValid() {
+ return valid;
+ }
+
+ public void setValid(String valid) {
+ this.valid = valid;
+ }
+
+ public String getWatchData() {
+ return watchData;
+ }
+
+ public void setWatchData(String watchData) {
+ this.watchData = watchData;
+ }
+
+ public String getWellCode() {
+ return wellCode;
+ }
+
+ public void setWellCode(String wellCode) {
+ this.wellCode = wellCode;
+ }
+
+ public String getWellName() {
+ return wellName;
+ }
+
+ public void setWellName(String wellName) {
+ this.wellName = wellName;
+ }
+
+ public String getWellType() {
+ return wellType;
+ }
+
+ public void setWellType(String wellType) {
+ this.wellType = wellType;
+ }
+
+ public String getWellTypeName() {
+ return wellTypeName;
+ }
+
+ public void setWellTypeName(String wellTypeName) {
+ this.wellTypeName = wellTypeName;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
index 0fb598b..d57d378 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
@@ -1,6 +1,7 @@
package com.casic.app.smartwell.sanxi.utils
import android.Manifest
+import com.casic.app.smartwell.sanxi.R
object Constant {
@@ -19,7 +20,6 @@
const val USER_DEVICE_TYPE = "userDeviceType"
const val ACCOUNT = "account"
const val PASSWORD = "password"
- const val ALARM_TYPE = "alarmType"
const val APP_AUTHORITY = "com.casic.app.smartwell.sanxi.fileprovider"
const val CANCEL_ALARM_ACTION = "cancelAlarm"
@@ -29,11 +29,11 @@
const val RADIUS_SIZE = 100 //相距多少米才聚合,单位:米
const val DISTANCE = 5 //两点间距离阈值,单位:米
+ val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
+ val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
+
// val HOME_ICONS = arrayOf(R.drawable.ic_well, R.drawable.ic_overtime, R.drawable.ic_bfcf)
val HOME_ITEMS = arrayOf("闸井管理", "超时工单", "布防撤防")
val SUB_PAGE_TITLES = arrayOf("待处理", "待确认", "处理中", "已完成")
val OVER_TIME_PAGE_TITLES = arrayOf("超时未接单", "超时未处理")
-
- // val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
- val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
index 2bb0294..3c6fea3 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
@@ -153,6 +153,12 @@
): String
/**
+ * 获取获取闸井列表-不分页,地图用
+ */
+ @GET("/overview/wellList")
+ suspend fun obtainAllWell(@Header("token") token: String): String
+
+ /**
* 根据布防状态统计闸井数量接口
*/
@GET("/well/countByBfzt")
@@ -192,12 +198,6 @@
): String
/**
- * 获取获取闸井列表-不分页,地图用
- */
- @GET("/well/list")
- suspend fun obtainAllWell(@Header("token") token: String): String
-
- /**
* 获取井下监控设备列表
*
* @param id 窨井ID
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
index 35af71d..f67ccb6 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
@@ -151,6 +151,13 @@
return api.obtainOrderStatus(AuthenticationHelper.token!!)
}
+ /**
+ * 获取获取闸井列表-不分页
+ */
+ suspend fun obtainAllWell(): String {
+ return api.obtainAllWell(AuthenticationHelper.token!!)
+ }
+
// /**
// * 根据布防状态统计闸井数量接口
// */
@@ -190,13 +197,6 @@
// }
//
// /**
-// * 获取获取闸井列表-不分页
-// */
-// suspend fun obtainAllWell(): String {
-// return api.obtainAllWell(AuthenticationHelper.token!!)
-// }
-//
-// /**
// * 获取井下监控设备列表
// */
// suspend fun obtainMonitorResult(id: String): String {
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
index 87dd8dc..6a80a92 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
@@ -7,6 +7,7 @@
import com.casic.app.smartwell.sanxi.extensions.show
import com.casic.app.smartwell.sanxi.extensions.toErrorMessage
import com.casic.app.smartwell.sanxi.model.WellDetailModel
+import com.casic.app.smartwell.sanxi.model.WellListModel
import com.casic.app.smartwell.sanxi.utils.LoadState
import com.casic.app.smartwell.sanxi.utils.retrofit.RetrofitServiceManager
import com.google.gson.Gson
@@ -16,6 +17,7 @@
private val gson = Gson()
val detailModel = MutableLiveData()
+ val allWellModel = MutableLiveData()
fun obtainWellDetail(id: String) = launch({
loadState.value = LoadState.Loading
@@ -34,4 +36,18 @@
loadState.value = LoadState.Fail
it.printStackTrace()
})
+
+ fun obtainAllWell() = launch({
+ val response = RetrofitServiceManager.obtainAllWell()
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ allWellModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ response.toErrorMessage().show()
+ }
+ }, {
+ it.printStackTrace()
+ })
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ea56300..0416db4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -49,5 +49,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
index 291a985..c41c867 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
@@ -82,14 +82,40 @@
}
//窨井类型转换
-fun String.toChinese(): String {
+fun String.toTypeName(): String {
return when (this) {
- "0" -> "全部"
- "1" -> "一级"
- "2" -> "二级"
- "3" -> "三级"
+ "1" -> "雨水井"
+ "2" -> "污水井"
+ "3" -> "燃气井"
+ "4" -> "热力井"
+ "5" -> "电力井"
+ "6" -> "交通井"
+ "7" -> "路灯井"
+ "8" -> "通信井"
+ "9" -> "监控井"
else -> {
- "未知"
+ "其他"
+ }
+ }
+}
+
+fun String.toDeptName(): String {
+ return when (this) {
+ "0" -> "顶级"
+ "1148031048115494913" -> "二院"
+ "1178242695136149506" -> "电力公司"
+ "1178242900132757506" -> "滨海热电"
+ "24" -> "燃气集团总公司"
+ "30" -> "203所"
+ "1399230677135265794" -> "厦门测试"
+ "25" -> "第一分公司"
+ "26" -> "第二分公司"
+ "27" -> "第三分公司"
+ "28" -> "第四分公司"
+ "29" -> "高压管网分公司"
+ "1143796514486353922" -> "第五分公司"
+ else -> {
+ "其他"
}
}
}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
index 26f3085..4d0c818 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
@@ -1,24 +1,326 @@
package com.casic.app.smartwell.sanxi.fragment
+import android.graphics.Point
+import android.os.Bundle
+import android.util.Log
+import android.view.LayoutInflater
import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import com.amap.api.maps.AMap
+import com.amap.api.maps.AMapOptions
+import com.amap.api.maps.CameraUpdateFactory
+import com.amap.api.maps.CoordinateConverter
+import com.amap.api.maps.model.*
import com.casic.app.smartwell.sanxi.R
-import com.casic.app.smartwell.sanxi.base.BaseFragment
-import kotlinx.android.synthetic.main.include_base_title.*
+import com.casic.app.smartwell.sanxi.extensions.show
+import com.casic.app.smartwell.sanxi.extensions.showRouteOnMap
+import com.casic.app.smartwell.sanxi.extensions.toDeptName
+import com.casic.app.smartwell.sanxi.extensions.toTypeName
+import com.casic.app.smartwell.sanxi.model.WellListModel
+import com.casic.app.smartwell.sanxi.utils.Constant
+import com.casic.app.smartwell.sanxi.vm.WellViewModel
+import com.casic.app.smartwell.sanxi.widgets.EasyPopupWindow
+import com.casic.app.smartwell.sanxi.widgets.GaoDeClusterMarkerView
+import com.google.android.material.bottomsheet.BottomSheetBehavior
+import com.pengxh.app.multilib.utils.SizeUtil
+import com.pengxh.app.multilib.widget.dialog.AlertControlDialog
+import kotlinx.android.synthetic.main.fragment_home.view.*
-class HomePageFragment : BaseFragment() {
+class HomePageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener,
+ AMap.OnMarkerClickListener, AMap.InfoWindowAdapter, AMap.OnInfoWindowClickListener {
- override fun initLayoutView(): Int = R.layout.fragment_home
+ private val kTag = "HomePageFragment"
+ private lateinit var homeView: View
+ private lateinit var aMap: AMap
+ private lateinit var wellViewModel: WellViewModel
- override fun setupTopBarLayout() {
- leftBackView.visibility = View.GONE
- titleView.text = "首页"
+ /**
+ * 所有窨井列表信息集合
+ * */
+ private var wellModels: MutableList = ArrayList()
+
+ /**
+ * 所有的marker
+ */
+ private var allMarkerOptions: MutableList = ArrayList()
+
+ /**
+ * 视野内的marker
+ */
+ private var markerOptionsInView: MutableList = ArrayList()
+
+ /**
+ * 自定义Marker弹出框
+ * */
+ private var infoWindow: View? = null
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ homeView = inflater.inflate(R.layout.fragment_home, container, false)
+ homeView.titleView.text = "首页"
+ val easyPopupWindow = EasyPopupWindow(requireContext())
+ easyPopupWindow.setupPopupData(Constant.POPUP_IMAGES, Constant.POPUP_TITLES)
+ homeView.rightOptionView.setOnClickListener {
+ easyPopupWindow.setOnPopupWindowClickListener(object :
+ EasyPopupWindow.OnPopupWindowClickListener {
+ override fun onPopupClick(position: Int) {
+ when (position) {
+ 0 -> aMap.mapType = AMap.MAP_TYPE_NORMAL
+ 1 -> aMap.mapType = AMap.MAP_TYPE_SATELLITE
+ }
+ }
+ })
+ easyPopupWindow.setBackgroundDrawable(null)
+ val x: Int = homeView.rightOptionView.width - easyPopupWindow.width
+ easyPopupWindow.showAsDropDown(homeView.rightOptionView, x, 0)
+ }
+
+ //代码设置底部拉升距离
+ val bottomSheetBehavior = BottomSheetBehavior.from(homeView.bottomBehaviorLayout)
+ homeView.coordinatorLayout.post {
+ bottomSheetBehavior.isFitToContents = false
+ bottomSheetBehavior.halfExpandedRatio = 0.3f
+ bottomSheetBehavior.isHideable = false
+ bottomSheetBehavior.peekHeight = SizeUtil.dp2px(requireContext(), 30f)
+ }
+
+ //初始化vm
+ wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java)
+
+ //获取所有窨井数据
+ wellViewModel.obtainAllWell()
+ wellViewModel.allWellModel.observe(viewLifecycleOwner, {
+ if (it.code == 200) {
+ val latitudeList: MutableList = ArrayList()
+ val longitudeList: MutableList = ArrayList()
+ it.data?.forEach { well ->
+ val lat = well.latGaode.toString()
+ val lng = well.lngGaode.toString()
+ if (lat.isNotBlank() && lng.isNotBlank()) {
+ //返回true代表当前位置在大陆、港澳地区,反之不在
+ val latitude = lat.toDouble()
+ val longitude = lng.toDouble()
+ if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) {
+ //缓存所有设备详情,点击Marker时候需要
+ wellModels.add(well)
+ //分别缓存经、纬度
+ latitudeList.add(latitude)
+ longitudeList.add(longitude)
+ //将所有设备信息转化缓存为Marker点
+ allMarkerOptions.add(
+ MarkerOptions()
+ .position(LatLng(latitude, longitude))
+ .title(well.wellTypeName)
+ .snippet(well.wellName)
+ )
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度不在国内,异常经纬度 ===> [${lng},${lat}]")
+ }
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度异常,异常经纬度 ===> [${lng},${lat}]")
+ }
+ }
+ //计算所有点的中心点位置
+ val centerLatLng = LatLng(latitudeList.average(), longitudeList.average())
+ Log.d(
+ kTag,
+ "所有闸井中心点位置 ===> [${latitudeList.average()}, ${longitudeList.average()}]"
+ )
+ //移动到指定经纬度
+ val cameraPosition = CameraPosition(centerLatLng, 13f, 0f, 0f)
+ val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition)
+ aMap.animateCamera(cameraUpdate, 3000, null)
+ }
+ })
+
+ //地图初始化
+ initMap(savedInstanceState)
+ return homeView
}
- override fun initData() {
+ private fun initMap(savedInstanceState: Bundle?) {
+ homeView.mapView.onCreate(savedInstanceState)
+ aMap = homeView.mapView.map
+ aMap.mapType = AMap.MAP_TYPE_NORMAL
+ val uiSettings = aMap.uiSettings
+ uiSettings.isCompassEnabled = true
+ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER
+ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度
+ uiSettings.isRotateGesturesEnabled = false//不允许地图旋转
+
+ // 地图加载成功监听
+ aMap.addOnMapLoadedListener(this)
+ // 地图缩放监听
+ aMap.addOnCameraChangeListener(this)
+ // marker 点击事件监听
+ aMap.addOnMarkerClickListener(this)
+ // 点击marker弹出自定义popup
+ aMap.setInfoWindowAdapter(this)
+ //信息窗点击事件
+ aMap.addOnInfoWindowClickListener(this)
+ }
+
+ override fun onMapLoaded() {
+ //地图加载成功之后显示聚合点数据
+ initClustersMarkers()
+ }
+
+ override fun onCameraChange(p0: CameraPosition?) {
}
- override fun initEvent() {
+ //获取视野内的marker 根据聚合算法合成自定义的marker 显示视野内的marker
+ override fun onCameraChangeFinish(p0: CameraPosition?) {
+ //地图缩放之后显示聚合点数据
+ initClustersMarkers()
+ }
+ private fun initClustersMarkers() {
+ val proj = aMap.projection
+ val dm = resources.displayMetrics
+ var screenLocation: Point
+ markerOptionsInView.clear()
+ // 获取在当前视野内的marker
+ allMarkerOptions.forEach {
+ screenLocation = proj.toScreenLocation(it.position)
+ if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) {
+ //在当前可观区域内
+ markerOptionsInView.add(it)
+ }
+ }
+ // 自定义的聚合类MarkerCluster
+ val clustersMarkers: MutableList = ArrayList()
+ markerOptionsInView.forEach {
+ if (clustersMarkers.size == 0) {
+ //添加一个新的自定义marker
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )
+ } else {
+ var isInRange = false
+ //Kotlin foreach不能用break
+ for (view in clustersMarkers) {
+ //判断当前的marker是否在前面marker的聚合范围内 并且每个marker只会聚合一次。
+ if (view.bounds.contains(it.position)) {
+ view.addMarker(it)
+ isInRange = true
+ break
+ }
+ }
+ //如果没在任何范围内,自己单独形成一个自定义marker。在和后面的marker进行比较
+ if (!isInRange) {
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )//相距多少才聚合
+ }
+ }
+ }
+ // 设置聚合点的位置和icon
+ clustersMarkers.forEach {
+ it.setPositionAndIcon()
+ }
+ aMap.clear()
+ // 重新添加 marker
+ clustersMarkers.forEach {
+ aMap.addMarker(it.options)
+ }
+ }
+
+ override fun onMarkerClick(marker: Marker?): Boolean {
+ //显示闸井信息
+ marker?.showInfoWindow()
+ return true
+ }
+
+ override fun getInfoWindow(marker: Marker?): View? {
+ if (infoWindow == null) {
+ infoWindow = LayoutInflater.from(requireContext()).inflate(R.layout.popu_map_info, null)
+ }
+ val v = infoWindow!!
+ //反射得到popup里面的控件对象
+ val wellTypeView = v.findViewById(R.id.wellTypeView)
+ val wellCodeView = v.findViewById(R.id.wellCodeView)
+ val ownerShipView = v.findViewById(R.id.ownerShipView)
+ val locationView = v.findViewById(R.id.locationView)
+
+ //绑定数据
+ val clickedLatLng = marker?.position!!
+ for (well in wellModels) {
+ if (clickedLatLng.latitude == well.latGaode!!.toDouble()
+ && clickedLatLng.longitude == well.lngGaode!!.toDouble()
+ ) {
+ wellTypeView.text = String.format("井类型: ${well.wellType.toTypeName()}")
+ wellCodeView.text = String.format("井编号: ${well.wellCode}")
+ ownerShipView.text = String.format("权属单位: ${well.deptid.toDeptName()}")
+ locationView.text = String.format("详细位置: ${well.position}")
+ return infoWindow
+ }
+ }
+ "无法查看聚合点,请放大比例后再查看".show()
+ return null
+ }
+
+ /**
+ * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框
+ * */
+ override fun getInfoContents(p0: Marker?): View? = null
+
+ override fun onInfoWindowClick(p0: Marker?) {
+ if (p0 != null) {
+ AlertControlDialog.Builder()
+ .setContext(requireContext())
+ .setTitle("操作提示")
+ .setMessage("确定要前往吗")
+ .setNegativeButton("取消")
+ .setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ val latLng = p0.position
+ val lat = latLng.latitude.toString()
+ val lng = latLng.longitude.toString()
+ if (lat.isBlank() || lng.isBlank()) {
+ "窨井经纬度异常,无法开启导航".show()
+ return
+ }
+ Poi(p0.snippet, LatLng(lat.toDouble(), lng.toDouble()), "").showRouteOnMap(
+ requireContext()
+ )
+ }
+
+ override fun onCancelClick() {
+
+ }
+ }).build().show()
+ }
+ }
+
+ /***以下是地图生命周期管理************************************************************************/
+ override fun onResume() {
+ super.onResume()
+ homeView.mapView.onResume()
+ //每次页面切换都需要重新刷新不同状态的窨井数量
+// wellViewModel.countWellByState()
+// workOrderViewModel.countWorkOrderByState()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ homeView.mapView.onPause()
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ homeView.mapView.onSaveInstanceState(outState)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ homeView.mapView.onDestroy()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
new file mode 100644
index 0000000..4e916a9
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
@@ -0,0 +1,271 @@
+package com.casic.app.smartwell.sanxi.model;
+
+import java.util.List;
+
+public class WellListModel {
+
+ private int code;
+ private List data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public List getData() {
+ return data;
+ }
+
+ public void setData(List data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataDTO {
+ private String area;
+ private String bfzt;
+ private String bfztName;
+ private String coordinateX;
+ private String coordinateY;
+ private String deep;
+ private String deptName;
+ private String deptid;
+ private String id;
+ private String latBaidu;
+ private String latGaode;
+ private String lngBaidu;
+ private String lngGaode;
+ private String notes;
+ private String photos;
+ private String position;
+ private String staff;
+ private String tel;
+ private String ts;
+ private String valid;
+ private String watchData;
+ private String wellCode;
+ private String wellName;
+ private String wellType;
+ private String wellTypeName;
+
+ public String getArea() {
+ return area;
+ }
+
+ public void setArea(String area) {
+ this.area = area;
+ }
+
+ public String getBfzt() {
+ return bfzt;
+ }
+
+ public void setBfzt(String bfzt) {
+ this.bfzt = bfzt;
+ }
+
+ public String getBfztName() {
+ return bfztName;
+ }
+
+ public void setBfztName(String bfztName) {
+ this.bfztName = bfztName;
+ }
+
+ public String getCoordinateX() {
+ return coordinateX;
+ }
+
+ public void setCoordinateX(String coordinateX) {
+ this.coordinateX = coordinateX;
+ }
+
+ public String getCoordinateY() {
+ return coordinateY;
+ }
+
+ public void setCoordinateY(String coordinateY) {
+ this.coordinateY = coordinateY;
+ }
+
+ public String getDeep() {
+ return deep;
+ }
+
+ public void setDeep(String deep) {
+ this.deep = deep;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptid() {
+ return deptid;
+ }
+
+ public void setDeptid(String deptid) {
+ this.deptid = deptid;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getLatBaidu() {
+ return latBaidu;
+ }
+
+ public void setLatBaidu(String latBaidu) {
+ this.latBaidu = latBaidu;
+ }
+
+ public String getLatGaode() {
+ return latGaode;
+ }
+
+ public void setLatGaode(String latGaode) {
+ this.latGaode = latGaode;
+ }
+
+ public String getLngBaidu() {
+ return lngBaidu;
+ }
+
+ public void setLngBaidu(String lngBaidu) {
+ this.lngBaidu = lngBaidu;
+ }
+
+ public String getLngGaode() {
+ return lngGaode;
+ }
+
+ public void setLngGaode(String lngGaode) {
+ this.lngGaode = lngGaode;
+ }
+
+ public String getNotes() {
+ return notes;
+ }
+
+ public void setNotes(String notes) {
+ this.notes = notes;
+ }
+
+ public String getPhotos() {
+ return photos;
+ }
+
+ public void setPhotos(String photos) {
+ this.photos = photos;
+ }
+
+ public String getPosition() {
+ return position;
+ }
+
+ public void setPosition(String position) {
+ this.position = position;
+ }
+
+ public String getStaff() {
+ return staff;
+ }
+
+ public void setStaff(String staff) {
+ this.staff = staff;
+ }
+
+ public String getTel() {
+ return tel;
+ }
+
+ public void setTel(String tel) {
+ this.tel = tel;
+ }
+
+ public String getTs() {
+ return ts;
+ }
+
+ public void setTs(String ts) {
+ this.ts = ts;
+ }
+
+ public String getValid() {
+ return valid;
+ }
+
+ public void setValid(String valid) {
+ this.valid = valid;
+ }
+
+ public String getWatchData() {
+ return watchData;
+ }
+
+ public void setWatchData(String watchData) {
+ this.watchData = watchData;
+ }
+
+ public String getWellCode() {
+ return wellCode;
+ }
+
+ public void setWellCode(String wellCode) {
+ this.wellCode = wellCode;
+ }
+
+ public String getWellName() {
+ return wellName;
+ }
+
+ public void setWellName(String wellName) {
+ this.wellName = wellName;
+ }
+
+ public String getWellType() {
+ return wellType;
+ }
+
+ public void setWellType(String wellType) {
+ this.wellType = wellType;
+ }
+
+ public String getWellTypeName() {
+ return wellTypeName;
+ }
+
+ public void setWellTypeName(String wellTypeName) {
+ this.wellTypeName = wellTypeName;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
index 0fb598b..d57d378 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
@@ -1,6 +1,7 @@
package com.casic.app.smartwell.sanxi.utils
import android.Manifest
+import com.casic.app.smartwell.sanxi.R
object Constant {
@@ -19,7 +20,6 @@
const val USER_DEVICE_TYPE = "userDeviceType"
const val ACCOUNT = "account"
const val PASSWORD = "password"
- const val ALARM_TYPE = "alarmType"
const val APP_AUTHORITY = "com.casic.app.smartwell.sanxi.fileprovider"
const val CANCEL_ALARM_ACTION = "cancelAlarm"
@@ -29,11 +29,11 @@
const val RADIUS_SIZE = 100 //相距多少米才聚合,单位:米
const val DISTANCE = 5 //两点间距离阈值,单位:米
+ val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
+ val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
+
// val HOME_ICONS = arrayOf(R.drawable.ic_well, R.drawable.ic_overtime, R.drawable.ic_bfcf)
val HOME_ITEMS = arrayOf("闸井管理", "超时工单", "布防撤防")
val SUB_PAGE_TITLES = arrayOf("待处理", "待确认", "处理中", "已完成")
val OVER_TIME_PAGE_TITLES = arrayOf("超时未接单", "超时未处理")
-
- // val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
- val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
index 2bb0294..3c6fea3 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
@@ -153,6 +153,12 @@
): String
/**
+ * 获取获取闸井列表-不分页,地图用
+ */
+ @GET("/overview/wellList")
+ suspend fun obtainAllWell(@Header("token") token: String): String
+
+ /**
* 根据布防状态统计闸井数量接口
*/
@GET("/well/countByBfzt")
@@ -192,12 +198,6 @@
): String
/**
- * 获取获取闸井列表-不分页,地图用
- */
- @GET("/well/list")
- suspend fun obtainAllWell(@Header("token") token: String): String
-
- /**
* 获取井下监控设备列表
*
* @param id 窨井ID
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
index 35af71d..f67ccb6 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
@@ -151,6 +151,13 @@
return api.obtainOrderStatus(AuthenticationHelper.token!!)
}
+ /**
+ * 获取获取闸井列表-不分页
+ */
+ suspend fun obtainAllWell(): String {
+ return api.obtainAllWell(AuthenticationHelper.token!!)
+ }
+
// /**
// * 根据布防状态统计闸井数量接口
// */
@@ -190,13 +197,6 @@
// }
//
// /**
-// * 获取获取闸井列表-不分页
-// */
-// suspend fun obtainAllWell(): String {
-// return api.obtainAllWell(AuthenticationHelper.token!!)
-// }
-//
-// /**
// * 获取井下监控设备列表
// */
// suspend fun obtainMonitorResult(id: String): String {
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
index 87dd8dc..6a80a92 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
@@ -7,6 +7,7 @@
import com.casic.app.smartwell.sanxi.extensions.show
import com.casic.app.smartwell.sanxi.extensions.toErrorMessage
import com.casic.app.smartwell.sanxi.model.WellDetailModel
+import com.casic.app.smartwell.sanxi.model.WellListModel
import com.casic.app.smartwell.sanxi.utils.LoadState
import com.casic.app.smartwell.sanxi.utils.retrofit.RetrofitServiceManager
import com.google.gson.Gson
@@ -16,6 +17,7 @@
private val gson = Gson()
val detailModel = MutableLiveData()
+ val allWellModel = MutableLiveData()
fun obtainWellDetail(id: String) = launch({
loadState.value = LoadState.Loading
@@ -34,4 +36,18 @@
loadState.value = LoadState.Fail
it.printStackTrace()
})
+
+ fun obtainAllWell() = launch({
+ val response = RetrofitServiceManager.obtainAllWell()
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ allWellModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ response.toErrorMessage().show()
+ }
+ }, {
+ it.printStackTrace()
+ })
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt
new file mode 100644
index 0000000..4fd4702
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt
@@ -0,0 +1,77 @@
+package com.casic.app.smartwell.sanxi.widgets
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.*
+import com.casic.app.smartwell.sanxi.R
+import com.pengxh.app.multilib.utils.SizeUtil
+
+/**
+ * @description: 顶部下拉菜单
+ * @author: Pengxh
+ * @email: 290677893@qq.com
+ * @date: 2019/12/28 20:35
+ */
+class EasyPopupWindow(private val context: Context) : PopupWindow(context) {
+
+ private lateinit var clickListener: OnPopupWindowClickListener
+
+ init {
+ this.width = (SizeUtil.getScreenWidth(context) * 0.3).toInt()
+ this.height = ViewGroup.LayoutParams.WRAP_CONTENT
+ this.isOutsideTouchable = true
+ this.isFocusable = true
+ this.animationStyle = R.style.PopupAnimation
+ this.contentView = LayoutInflater.from(context).inflate(R.layout.popup_option, null, false)
+ }
+
+ fun setupPopupData(imageArray: Array, titleArray: Array) {
+ val popupListView = contentView.findViewById(R.id.popupListView)
+ popupListView.adapter = object : BaseAdapter() {
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+
+ override fun getCount(): Int = imageArray.size
+
+ override fun getItem(position: Int): Any = imageArray[position]
+
+ override fun getItemId(position: Int): Long = position.toLong()
+
+ override fun getView(position: Int, convertView: View?, viewGroup: ViewGroup): View {
+ val view: View
+ val holder: PopupWindowHolder
+ if (convertView == null) {
+ view = inflater.inflate(R.layout.item_map_popup, null)
+ holder = PopupWindowHolder()
+ holder.imageView = view.findViewById(R.id.imageView)
+ holder.titleView = view.findViewById(R.id.titleView)
+ view.tag = holder
+ } else {
+ view = convertView
+ holder = view.tag as PopupWindowHolder
+ }
+ holder.imageView.setBackgroundResource(imageArray[position])
+ holder.titleView.text = titleArray[position]
+ return view
+ }
+ }
+ popupListView.onItemClickListener = AdapterView.OnItemClickListener { _, _, i, _ ->
+ clickListener.onPopupClick(i)
+ dismiss()
+ }
+ }
+
+ interface OnPopupWindowClickListener {
+ fun onPopupClick(position: Int)
+ }
+
+ fun setOnPopupWindowClickListener(windowClickListener: OnPopupWindowClickListener) {
+ this.clickListener = windowClickListener
+ }
+
+ inner class PopupWindowHolder {
+ lateinit var imageView: ImageView
+ lateinit var titleView: TextView
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ea56300..0416db4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -49,5 +49,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
index 291a985..c41c867 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
@@ -82,14 +82,40 @@
}
//窨井类型转换
-fun String.toChinese(): String {
+fun String.toTypeName(): String {
return when (this) {
- "0" -> "全部"
- "1" -> "一级"
- "2" -> "二级"
- "3" -> "三级"
+ "1" -> "雨水井"
+ "2" -> "污水井"
+ "3" -> "燃气井"
+ "4" -> "热力井"
+ "5" -> "电力井"
+ "6" -> "交通井"
+ "7" -> "路灯井"
+ "8" -> "通信井"
+ "9" -> "监控井"
else -> {
- "未知"
+ "其他"
+ }
+ }
+}
+
+fun String.toDeptName(): String {
+ return when (this) {
+ "0" -> "顶级"
+ "1148031048115494913" -> "二院"
+ "1178242695136149506" -> "电力公司"
+ "1178242900132757506" -> "滨海热电"
+ "24" -> "燃气集团总公司"
+ "30" -> "203所"
+ "1399230677135265794" -> "厦门测试"
+ "25" -> "第一分公司"
+ "26" -> "第二分公司"
+ "27" -> "第三分公司"
+ "28" -> "第四分公司"
+ "29" -> "高压管网分公司"
+ "1143796514486353922" -> "第五分公司"
+ else -> {
+ "其他"
}
}
}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
index 26f3085..4d0c818 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
@@ -1,24 +1,326 @@
package com.casic.app.smartwell.sanxi.fragment
+import android.graphics.Point
+import android.os.Bundle
+import android.util.Log
+import android.view.LayoutInflater
import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import com.amap.api.maps.AMap
+import com.amap.api.maps.AMapOptions
+import com.amap.api.maps.CameraUpdateFactory
+import com.amap.api.maps.CoordinateConverter
+import com.amap.api.maps.model.*
import com.casic.app.smartwell.sanxi.R
-import com.casic.app.smartwell.sanxi.base.BaseFragment
-import kotlinx.android.synthetic.main.include_base_title.*
+import com.casic.app.smartwell.sanxi.extensions.show
+import com.casic.app.smartwell.sanxi.extensions.showRouteOnMap
+import com.casic.app.smartwell.sanxi.extensions.toDeptName
+import com.casic.app.smartwell.sanxi.extensions.toTypeName
+import com.casic.app.smartwell.sanxi.model.WellListModel
+import com.casic.app.smartwell.sanxi.utils.Constant
+import com.casic.app.smartwell.sanxi.vm.WellViewModel
+import com.casic.app.smartwell.sanxi.widgets.EasyPopupWindow
+import com.casic.app.smartwell.sanxi.widgets.GaoDeClusterMarkerView
+import com.google.android.material.bottomsheet.BottomSheetBehavior
+import com.pengxh.app.multilib.utils.SizeUtil
+import com.pengxh.app.multilib.widget.dialog.AlertControlDialog
+import kotlinx.android.synthetic.main.fragment_home.view.*
-class HomePageFragment : BaseFragment() {
+class HomePageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener,
+ AMap.OnMarkerClickListener, AMap.InfoWindowAdapter, AMap.OnInfoWindowClickListener {
- override fun initLayoutView(): Int = R.layout.fragment_home
+ private val kTag = "HomePageFragment"
+ private lateinit var homeView: View
+ private lateinit var aMap: AMap
+ private lateinit var wellViewModel: WellViewModel
- override fun setupTopBarLayout() {
- leftBackView.visibility = View.GONE
- titleView.text = "首页"
+ /**
+ * 所有窨井列表信息集合
+ * */
+ private var wellModels: MutableList = ArrayList()
+
+ /**
+ * 所有的marker
+ */
+ private var allMarkerOptions: MutableList = ArrayList()
+
+ /**
+ * 视野内的marker
+ */
+ private var markerOptionsInView: MutableList = ArrayList()
+
+ /**
+ * 自定义Marker弹出框
+ * */
+ private var infoWindow: View? = null
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ homeView = inflater.inflate(R.layout.fragment_home, container, false)
+ homeView.titleView.text = "首页"
+ val easyPopupWindow = EasyPopupWindow(requireContext())
+ easyPopupWindow.setupPopupData(Constant.POPUP_IMAGES, Constant.POPUP_TITLES)
+ homeView.rightOptionView.setOnClickListener {
+ easyPopupWindow.setOnPopupWindowClickListener(object :
+ EasyPopupWindow.OnPopupWindowClickListener {
+ override fun onPopupClick(position: Int) {
+ when (position) {
+ 0 -> aMap.mapType = AMap.MAP_TYPE_NORMAL
+ 1 -> aMap.mapType = AMap.MAP_TYPE_SATELLITE
+ }
+ }
+ })
+ easyPopupWindow.setBackgroundDrawable(null)
+ val x: Int = homeView.rightOptionView.width - easyPopupWindow.width
+ easyPopupWindow.showAsDropDown(homeView.rightOptionView, x, 0)
+ }
+
+ //代码设置底部拉升距离
+ val bottomSheetBehavior = BottomSheetBehavior.from(homeView.bottomBehaviorLayout)
+ homeView.coordinatorLayout.post {
+ bottomSheetBehavior.isFitToContents = false
+ bottomSheetBehavior.halfExpandedRatio = 0.3f
+ bottomSheetBehavior.isHideable = false
+ bottomSheetBehavior.peekHeight = SizeUtil.dp2px(requireContext(), 30f)
+ }
+
+ //初始化vm
+ wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java)
+
+ //获取所有窨井数据
+ wellViewModel.obtainAllWell()
+ wellViewModel.allWellModel.observe(viewLifecycleOwner, {
+ if (it.code == 200) {
+ val latitudeList: MutableList = ArrayList()
+ val longitudeList: MutableList = ArrayList()
+ it.data?.forEach { well ->
+ val lat = well.latGaode.toString()
+ val lng = well.lngGaode.toString()
+ if (lat.isNotBlank() && lng.isNotBlank()) {
+ //返回true代表当前位置在大陆、港澳地区,反之不在
+ val latitude = lat.toDouble()
+ val longitude = lng.toDouble()
+ if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) {
+ //缓存所有设备详情,点击Marker时候需要
+ wellModels.add(well)
+ //分别缓存经、纬度
+ latitudeList.add(latitude)
+ longitudeList.add(longitude)
+ //将所有设备信息转化缓存为Marker点
+ allMarkerOptions.add(
+ MarkerOptions()
+ .position(LatLng(latitude, longitude))
+ .title(well.wellTypeName)
+ .snippet(well.wellName)
+ )
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度不在国内,异常经纬度 ===> [${lng},${lat}]")
+ }
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度异常,异常经纬度 ===> [${lng},${lat}]")
+ }
+ }
+ //计算所有点的中心点位置
+ val centerLatLng = LatLng(latitudeList.average(), longitudeList.average())
+ Log.d(
+ kTag,
+ "所有闸井中心点位置 ===> [${latitudeList.average()}, ${longitudeList.average()}]"
+ )
+ //移动到指定经纬度
+ val cameraPosition = CameraPosition(centerLatLng, 13f, 0f, 0f)
+ val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition)
+ aMap.animateCamera(cameraUpdate, 3000, null)
+ }
+ })
+
+ //地图初始化
+ initMap(savedInstanceState)
+ return homeView
}
- override fun initData() {
+ private fun initMap(savedInstanceState: Bundle?) {
+ homeView.mapView.onCreate(savedInstanceState)
+ aMap = homeView.mapView.map
+ aMap.mapType = AMap.MAP_TYPE_NORMAL
+ val uiSettings = aMap.uiSettings
+ uiSettings.isCompassEnabled = true
+ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER
+ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度
+ uiSettings.isRotateGesturesEnabled = false//不允许地图旋转
+
+ // 地图加载成功监听
+ aMap.addOnMapLoadedListener(this)
+ // 地图缩放监听
+ aMap.addOnCameraChangeListener(this)
+ // marker 点击事件监听
+ aMap.addOnMarkerClickListener(this)
+ // 点击marker弹出自定义popup
+ aMap.setInfoWindowAdapter(this)
+ //信息窗点击事件
+ aMap.addOnInfoWindowClickListener(this)
+ }
+
+ override fun onMapLoaded() {
+ //地图加载成功之后显示聚合点数据
+ initClustersMarkers()
+ }
+
+ override fun onCameraChange(p0: CameraPosition?) {
}
- override fun initEvent() {
+ //获取视野内的marker 根据聚合算法合成自定义的marker 显示视野内的marker
+ override fun onCameraChangeFinish(p0: CameraPosition?) {
+ //地图缩放之后显示聚合点数据
+ initClustersMarkers()
+ }
+ private fun initClustersMarkers() {
+ val proj = aMap.projection
+ val dm = resources.displayMetrics
+ var screenLocation: Point
+ markerOptionsInView.clear()
+ // 获取在当前视野内的marker
+ allMarkerOptions.forEach {
+ screenLocation = proj.toScreenLocation(it.position)
+ if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) {
+ //在当前可观区域内
+ markerOptionsInView.add(it)
+ }
+ }
+ // 自定义的聚合类MarkerCluster
+ val clustersMarkers: MutableList = ArrayList()
+ markerOptionsInView.forEach {
+ if (clustersMarkers.size == 0) {
+ //添加一个新的自定义marker
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )
+ } else {
+ var isInRange = false
+ //Kotlin foreach不能用break
+ for (view in clustersMarkers) {
+ //判断当前的marker是否在前面marker的聚合范围内 并且每个marker只会聚合一次。
+ if (view.bounds.contains(it.position)) {
+ view.addMarker(it)
+ isInRange = true
+ break
+ }
+ }
+ //如果没在任何范围内,自己单独形成一个自定义marker。在和后面的marker进行比较
+ if (!isInRange) {
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )//相距多少才聚合
+ }
+ }
+ }
+ // 设置聚合点的位置和icon
+ clustersMarkers.forEach {
+ it.setPositionAndIcon()
+ }
+ aMap.clear()
+ // 重新添加 marker
+ clustersMarkers.forEach {
+ aMap.addMarker(it.options)
+ }
+ }
+
+ override fun onMarkerClick(marker: Marker?): Boolean {
+ //显示闸井信息
+ marker?.showInfoWindow()
+ return true
+ }
+
+ override fun getInfoWindow(marker: Marker?): View? {
+ if (infoWindow == null) {
+ infoWindow = LayoutInflater.from(requireContext()).inflate(R.layout.popu_map_info, null)
+ }
+ val v = infoWindow!!
+ //反射得到popup里面的控件对象
+ val wellTypeView = v.findViewById(R.id.wellTypeView)
+ val wellCodeView = v.findViewById(R.id.wellCodeView)
+ val ownerShipView = v.findViewById(R.id.ownerShipView)
+ val locationView = v.findViewById(R.id.locationView)
+
+ //绑定数据
+ val clickedLatLng = marker?.position!!
+ for (well in wellModels) {
+ if (clickedLatLng.latitude == well.latGaode!!.toDouble()
+ && clickedLatLng.longitude == well.lngGaode!!.toDouble()
+ ) {
+ wellTypeView.text = String.format("井类型: ${well.wellType.toTypeName()}")
+ wellCodeView.text = String.format("井编号: ${well.wellCode}")
+ ownerShipView.text = String.format("权属单位: ${well.deptid.toDeptName()}")
+ locationView.text = String.format("详细位置: ${well.position}")
+ return infoWindow
+ }
+ }
+ "无法查看聚合点,请放大比例后再查看".show()
+ return null
+ }
+
+ /**
+ * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框
+ * */
+ override fun getInfoContents(p0: Marker?): View? = null
+
+ override fun onInfoWindowClick(p0: Marker?) {
+ if (p0 != null) {
+ AlertControlDialog.Builder()
+ .setContext(requireContext())
+ .setTitle("操作提示")
+ .setMessage("确定要前往吗")
+ .setNegativeButton("取消")
+ .setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ val latLng = p0.position
+ val lat = latLng.latitude.toString()
+ val lng = latLng.longitude.toString()
+ if (lat.isBlank() || lng.isBlank()) {
+ "窨井经纬度异常,无法开启导航".show()
+ return
+ }
+ Poi(p0.snippet, LatLng(lat.toDouble(), lng.toDouble()), "").showRouteOnMap(
+ requireContext()
+ )
+ }
+
+ override fun onCancelClick() {
+
+ }
+ }).build().show()
+ }
+ }
+
+ /***以下是地图生命周期管理************************************************************************/
+ override fun onResume() {
+ super.onResume()
+ homeView.mapView.onResume()
+ //每次页面切换都需要重新刷新不同状态的窨井数量
+// wellViewModel.countWellByState()
+// workOrderViewModel.countWorkOrderByState()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ homeView.mapView.onPause()
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ homeView.mapView.onSaveInstanceState(outState)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ homeView.mapView.onDestroy()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
new file mode 100644
index 0000000..4e916a9
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
@@ -0,0 +1,271 @@
+package com.casic.app.smartwell.sanxi.model;
+
+import java.util.List;
+
+public class WellListModel {
+
+ private int code;
+ private List data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public List getData() {
+ return data;
+ }
+
+ public void setData(List data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataDTO {
+ private String area;
+ private String bfzt;
+ private String bfztName;
+ private String coordinateX;
+ private String coordinateY;
+ private String deep;
+ private String deptName;
+ private String deptid;
+ private String id;
+ private String latBaidu;
+ private String latGaode;
+ private String lngBaidu;
+ private String lngGaode;
+ private String notes;
+ private String photos;
+ private String position;
+ private String staff;
+ private String tel;
+ private String ts;
+ private String valid;
+ private String watchData;
+ private String wellCode;
+ private String wellName;
+ private String wellType;
+ private String wellTypeName;
+
+ public String getArea() {
+ return area;
+ }
+
+ public void setArea(String area) {
+ this.area = area;
+ }
+
+ public String getBfzt() {
+ return bfzt;
+ }
+
+ public void setBfzt(String bfzt) {
+ this.bfzt = bfzt;
+ }
+
+ public String getBfztName() {
+ return bfztName;
+ }
+
+ public void setBfztName(String bfztName) {
+ this.bfztName = bfztName;
+ }
+
+ public String getCoordinateX() {
+ return coordinateX;
+ }
+
+ public void setCoordinateX(String coordinateX) {
+ this.coordinateX = coordinateX;
+ }
+
+ public String getCoordinateY() {
+ return coordinateY;
+ }
+
+ public void setCoordinateY(String coordinateY) {
+ this.coordinateY = coordinateY;
+ }
+
+ public String getDeep() {
+ return deep;
+ }
+
+ public void setDeep(String deep) {
+ this.deep = deep;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptid() {
+ return deptid;
+ }
+
+ public void setDeptid(String deptid) {
+ this.deptid = deptid;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getLatBaidu() {
+ return latBaidu;
+ }
+
+ public void setLatBaidu(String latBaidu) {
+ this.latBaidu = latBaidu;
+ }
+
+ public String getLatGaode() {
+ return latGaode;
+ }
+
+ public void setLatGaode(String latGaode) {
+ this.latGaode = latGaode;
+ }
+
+ public String getLngBaidu() {
+ return lngBaidu;
+ }
+
+ public void setLngBaidu(String lngBaidu) {
+ this.lngBaidu = lngBaidu;
+ }
+
+ public String getLngGaode() {
+ return lngGaode;
+ }
+
+ public void setLngGaode(String lngGaode) {
+ this.lngGaode = lngGaode;
+ }
+
+ public String getNotes() {
+ return notes;
+ }
+
+ public void setNotes(String notes) {
+ this.notes = notes;
+ }
+
+ public String getPhotos() {
+ return photos;
+ }
+
+ public void setPhotos(String photos) {
+ this.photos = photos;
+ }
+
+ public String getPosition() {
+ return position;
+ }
+
+ public void setPosition(String position) {
+ this.position = position;
+ }
+
+ public String getStaff() {
+ return staff;
+ }
+
+ public void setStaff(String staff) {
+ this.staff = staff;
+ }
+
+ public String getTel() {
+ return tel;
+ }
+
+ public void setTel(String tel) {
+ this.tel = tel;
+ }
+
+ public String getTs() {
+ return ts;
+ }
+
+ public void setTs(String ts) {
+ this.ts = ts;
+ }
+
+ public String getValid() {
+ return valid;
+ }
+
+ public void setValid(String valid) {
+ this.valid = valid;
+ }
+
+ public String getWatchData() {
+ return watchData;
+ }
+
+ public void setWatchData(String watchData) {
+ this.watchData = watchData;
+ }
+
+ public String getWellCode() {
+ return wellCode;
+ }
+
+ public void setWellCode(String wellCode) {
+ this.wellCode = wellCode;
+ }
+
+ public String getWellName() {
+ return wellName;
+ }
+
+ public void setWellName(String wellName) {
+ this.wellName = wellName;
+ }
+
+ public String getWellType() {
+ return wellType;
+ }
+
+ public void setWellType(String wellType) {
+ this.wellType = wellType;
+ }
+
+ public String getWellTypeName() {
+ return wellTypeName;
+ }
+
+ public void setWellTypeName(String wellTypeName) {
+ this.wellTypeName = wellTypeName;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
index 0fb598b..d57d378 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
@@ -1,6 +1,7 @@
package com.casic.app.smartwell.sanxi.utils
import android.Manifest
+import com.casic.app.smartwell.sanxi.R
object Constant {
@@ -19,7 +20,6 @@
const val USER_DEVICE_TYPE = "userDeviceType"
const val ACCOUNT = "account"
const val PASSWORD = "password"
- const val ALARM_TYPE = "alarmType"
const val APP_AUTHORITY = "com.casic.app.smartwell.sanxi.fileprovider"
const val CANCEL_ALARM_ACTION = "cancelAlarm"
@@ -29,11 +29,11 @@
const val RADIUS_SIZE = 100 //相距多少米才聚合,单位:米
const val DISTANCE = 5 //两点间距离阈值,单位:米
+ val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
+ val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
+
// val HOME_ICONS = arrayOf(R.drawable.ic_well, R.drawable.ic_overtime, R.drawable.ic_bfcf)
val HOME_ITEMS = arrayOf("闸井管理", "超时工单", "布防撤防")
val SUB_PAGE_TITLES = arrayOf("待处理", "待确认", "处理中", "已完成")
val OVER_TIME_PAGE_TITLES = arrayOf("超时未接单", "超时未处理")
-
- // val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
- val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
index 2bb0294..3c6fea3 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
@@ -153,6 +153,12 @@
): String
/**
+ * 获取获取闸井列表-不分页,地图用
+ */
+ @GET("/overview/wellList")
+ suspend fun obtainAllWell(@Header("token") token: String): String
+
+ /**
* 根据布防状态统计闸井数量接口
*/
@GET("/well/countByBfzt")
@@ -192,12 +198,6 @@
): String
/**
- * 获取获取闸井列表-不分页,地图用
- */
- @GET("/well/list")
- suspend fun obtainAllWell(@Header("token") token: String): String
-
- /**
* 获取井下监控设备列表
*
* @param id 窨井ID
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
index 35af71d..f67ccb6 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
@@ -151,6 +151,13 @@
return api.obtainOrderStatus(AuthenticationHelper.token!!)
}
+ /**
+ * 获取获取闸井列表-不分页
+ */
+ suspend fun obtainAllWell(): String {
+ return api.obtainAllWell(AuthenticationHelper.token!!)
+ }
+
// /**
// * 根据布防状态统计闸井数量接口
// */
@@ -190,13 +197,6 @@
// }
//
// /**
-// * 获取获取闸井列表-不分页
-// */
-// suspend fun obtainAllWell(): String {
-// return api.obtainAllWell(AuthenticationHelper.token!!)
-// }
-//
-// /**
// * 获取井下监控设备列表
// */
// suspend fun obtainMonitorResult(id: String): String {
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
index 87dd8dc..6a80a92 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
@@ -7,6 +7,7 @@
import com.casic.app.smartwell.sanxi.extensions.show
import com.casic.app.smartwell.sanxi.extensions.toErrorMessage
import com.casic.app.smartwell.sanxi.model.WellDetailModel
+import com.casic.app.smartwell.sanxi.model.WellListModel
import com.casic.app.smartwell.sanxi.utils.LoadState
import com.casic.app.smartwell.sanxi.utils.retrofit.RetrofitServiceManager
import com.google.gson.Gson
@@ -16,6 +17,7 @@
private val gson = Gson()
val detailModel = MutableLiveData()
+ val allWellModel = MutableLiveData()
fun obtainWellDetail(id: String) = launch({
loadState.value = LoadState.Loading
@@ -34,4 +36,18 @@
loadState.value = LoadState.Fail
it.printStackTrace()
})
+
+ fun obtainAllWell() = launch({
+ val response = RetrofitServiceManager.obtainAllWell()
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ allWellModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ response.toErrorMessage().show()
+ }
+ }, {
+ it.printStackTrace()
+ })
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt
new file mode 100644
index 0000000..4fd4702
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt
@@ -0,0 +1,77 @@
+package com.casic.app.smartwell.sanxi.widgets
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.*
+import com.casic.app.smartwell.sanxi.R
+import com.pengxh.app.multilib.utils.SizeUtil
+
+/**
+ * @description: 顶部下拉菜单
+ * @author: Pengxh
+ * @email: 290677893@qq.com
+ * @date: 2019/12/28 20:35
+ */
+class EasyPopupWindow(private val context: Context) : PopupWindow(context) {
+
+ private lateinit var clickListener: OnPopupWindowClickListener
+
+ init {
+ this.width = (SizeUtil.getScreenWidth(context) * 0.3).toInt()
+ this.height = ViewGroup.LayoutParams.WRAP_CONTENT
+ this.isOutsideTouchable = true
+ this.isFocusable = true
+ this.animationStyle = R.style.PopupAnimation
+ this.contentView = LayoutInflater.from(context).inflate(R.layout.popup_option, null, false)
+ }
+
+ fun setupPopupData(imageArray: Array, titleArray: Array) {
+ val popupListView = contentView.findViewById(R.id.popupListView)
+ popupListView.adapter = object : BaseAdapter() {
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+
+ override fun getCount(): Int = imageArray.size
+
+ override fun getItem(position: Int): Any = imageArray[position]
+
+ override fun getItemId(position: Int): Long = position.toLong()
+
+ override fun getView(position: Int, convertView: View?, viewGroup: ViewGroup): View {
+ val view: View
+ val holder: PopupWindowHolder
+ if (convertView == null) {
+ view = inflater.inflate(R.layout.item_map_popup, null)
+ holder = PopupWindowHolder()
+ holder.imageView = view.findViewById(R.id.imageView)
+ holder.titleView = view.findViewById(R.id.titleView)
+ view.tag = holder
+ } else {
+ view = convertView
+ holder = view.tag as PopupWindowHolder
+ }
+ holder.imageView.setBackgroundResource(imageArray[position])
+ holder.titleView.text = titleArray[position]
+ return view
+ }
+ }
+ popupListView.onItemClickListener = AdapterView.OnItemClickListener { _, _, i, _ ->
+ clickListener.onPopupClick(i)
+ dismiss()
+ }
+ }
+
+ interface OnPopupWindowClickListener {
+ fun onPopupClick(position: Int)
+ }
+
+ fun setOnPopupWindowClickListener(windowClickListener: OnPopupWindowClickListener) {
+ this.clickListener = windowClickListener
+ }
+
+ inner class PopupWindowHolder {
+ lateinit var imageView: ImageView
+ lateinit var titleView: TextView
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt
new file mode 100644
index 0000000..28ccff3
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt
@@ -0,0 +1,102 @@
+package com.casic.app.smartwell.sanxi.widgets
+
+import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.Point
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.TextView
+import com.amap.api.maps.Projection
+import com.amap.api.maps.model.BitmapDescriptorFactory
+import com.amap.api.maps.model.LatLng
+import com.amap.api.maps.model.LatLngBounds
+import com.amap.api.maps.model.MarkerOptions
+import com.casic.app.smartwell.sanxi.R
+import com.casic.app.smartwell.sanxi.extensions.toBitmap
+import java.util.*
+
+class GaoDeClusterMarkerView(
+ private val context: Context, firstMarkers: MarkerOptions,
+ projection: Projection, gridSize: Int
+) {
+ //当前可观区域里的 聚合过之后的集合
+ private val includeMarkers: ArrayList
+
+ // 创建区域
+ val bounds: LatLngBounds
+ var options: MarkerOptions = MarkerOptions()
+
+ init {
+ val screenLocation = projection.toScreenLocation(firstMarkers.position)
+ //范围类
+ val southwestPoint = Point(screenLocation.x - gridSize, screenLocation.y + gridSize)
+ //范围类
+ val northeastPoint = Point(screenLocation.x + gridSize, screenLocation.y - gridSize)
+ bounds = LatLngBounds(
+ projection.fromScreenLocation(southwestPoint),
+ projection.fromScreenLocation(northeastPoint)
+ )
+ //设置初始化marker属性
+ options.anchor(0.5f, 1.3f)
+ .title(firstMarkers.title)
+ .position(firstMarkers.position)
+ .icon(firstMarkers.icon)
+ .snippet(firstMarkers.snippet)
+ .draggable(false)
+ includeMarkers = ArrayList()
+ includeMarkers.add(firstMarkers)
+ }
+
+ /**
+ * 添加marker
+ */
+ fun addMarker(markerOptions: MarkerOptions) {
+ includeMarkers.add(markerOptions) // 添加到列表中
+ }
+
+ /**
+ * 设置聚合点的中心位置以及图标
+ */
+ fun setPositionAndIcon() {
+ val size = includeMarkers.size
+ var lat = 0.0
+ var lng = 0.0
+ // 一个的时候
+ if (size == 1) { //设置marker单个属性
+ // 设置marker位置
+ options.position(
+ LatLng(
+ includeMarkers[0].position.latitude,
+ includeMarkers[0].position.longitude
+ )
+ )
+ } else { // 聚合的时候
+ //设置marker聚合属性
+ for (op in includeMarkers) {
+ lat += op.position.latitude
+ lng += op.position.longitude
+ }
+ // 设置marker的位置为中心位置为聚集点的平均位置
+ options.position(LatLng(lat / size, lng / size))
+ }
+ options.icon(BitmapDescriptorFactory.fromBitmap(getBitmap(size)))
+ }
+
+ /**
+ * marker视图
+ */
+ private fun getBitmap(num: Int): Bitmap? {
+ val view = LayoutInflater.from(context).inflate(R.layout.marker_gaode, null)
+ val wellCountView = view.findViewById(R.id.wellCountView)
+ return if (num > 1) {
+ wellCountView.visibility = View.VISIBLE
+ wellCountView.text = String.format("${num}个")
+ wellCountView.gravity = Gravity.CENTER
+ view.toBitmap()
+ } else {
+ wellCountView.visibility = View.GONE
+ BitmapDescriptorFactory.fromResource(R.mipmap.well_location).bitmap
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ea56300..0416db4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -49,5 +49,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
index 291a985..c41c867 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
@@ -82,14 +82,40 @@
}
//窨井类型转换
-fun String.toChinese(): String {
+fun String.toTypeName(): String {
return when (this) {
- "0" -> "全部"
- "1" -> "一级"
- "2" -> "二级"
- "3" -> "三级"
+ "1" -> "雨水井"
+ "2" -> "污水井"
+ "3" -> "燃气井"
+ "4" -> "热力井"
+ "5" -> "电力井"
+ "6" -> "交通井"
+ "7" -> "路灯井"
+ "8" -> "通信井"
+ "9" -> "监控井"
else -> {
- "未知"
+ "其他"
+ }
+ }
+}
+
+fun String.toDeptName(): String {
+ return when (this) {
+ "0" -> "顶级"
+ "1148031048115494913" -> "二院"
+ "1178242695136149506" -> "电力公司"
+ "1178242900132757506" -> "滨海热电"
+ "24" -> "燃气集团总公司"
+ "30" -> "203所"
+ "1399230677135265794" -> "厦门测试"
+ "25" -> "第一分公司"
+ "26" -> "第二分公司"
+ "27" -> "第三分公司"
+ "28" -> "第四分公司"
+ "29" -> "高压管网分公司"
+ "1143796514486353922" -> "第五分公司"
+ else -> {
+ "其他"
}
}
}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
index 26f3085..4d0c818 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
@@ -1,24 +1,326 @@
package com.casic.app.smartwell.sanxi.fragment
+import android.graphics.Point
+import android.os.Bundle
+import android.util.Log
+import android.view.LayoutInflater
import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import com.amap.api.maps.AMap
+import com.amap.api.maps.AMapOptions
+import com.amap.api.maps.CameraUpdateFactory
+import com.amap.api.maps.CoordinateConverter
+import com.amap.api.maps.model.*
import com.casic.app.smartwell.sanxi.R
-import com.casic.app.smartwell.sanxi.base.BaseFragment
-import kotlinx.android.synthetic.main.include_base_title.*
+import com.casic.app.smartwell.sanxi.extensions.show
+import com.casic.app.smartwell.sanxi.extensions.showRouteOnMap
+import com.casic.app.smartwell.sanxi.extensions.toDeptName
+import com.casic.app.smartwell.sanxi.extensions.toTypeName
+import com.casic.app.smartwell.sanxi.model.WellListModel
+import com.casic.app.smartwell.sanxi.utils.Constant
+import com.casic.app.smartwell.sanxi.vm.WellViewModel
+import com.casic.app.smartwell.sanxi.widgets.EasyPopupWindow
+import com.casic.app.smartwell.sanxi.widgets.GaoDeClusterMarkerView
+import com.google.android.material.bottomsheet.BottomSheetBehavior
+import com.pengxh.app.multilib.utils.SizeUtil
+import com.pengxh.app.multilib.widget.dialog.AlertControlDialog
+import kotlinx.android.synthetic.main.fragment_home.view.*
-class HomePageFragment : BaseFragment() {
+class HomePageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener,
+ AMap.OnMarkerClickListener, AMap.InfoWindowAdapter, AMap.OnInfoWindowClickListener {
- override fun initLayoutView(): Int = R.layout.fragment_home
+ private val kTag = "HomePageFragment"
+ private lateinit var homeView: View
+ private lateinit var aMap: AMap
+ private lateinit var wellViewModel: WellViewModel
- override fun setupTopBarLayout() {
- leftBackView.visibility = View.GONE
- titleView.text = "首页"
+ /**
+ * 所有窨井列表信息集合
+ * */
+ private var wellModels: MutableList = ArrayList()
+
+ /**
+ * 所有的marker
+ */
+ private var allMarkerOptions: MutableList = ArrayList()
+
+ /**
+ * 视野内的marker
+ */
+ private var markerOptionsInView: MutableList = ArrayList()
+
+ /**
+ * 自定义Marker弹出框
+ * */
+ private var infoWindow: View? = null
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ homeView = inflater.inflate(R.layout.fragment_home, container, false)
+ homeView.titleView.text = "首页"
+ val easyPopupWindow = EasyPopupWindow(requireContext())
+ easyPopupWindow.setupPopupData(Constant.POPUP_IMAGES, Constant.POPUP_TITLES)
+ homeView.rightOptionView.setOnClickListener {
+ easyPopupWindow.setOnPopupWindowClickListener(object :
+ EasyPopupWindow.OnPopupWindowClickListener {
+ override fun onPopupClick(position: Int) {
+ when (position) {
+ 0 -> aMap.mapType = AMap.MAP_TYPE_NORMAL
+ 1 -> aMap.mapType = AMap.MAP_TYPE_SATELLITE
+ }
+ }
+ })
+ easyPopupWindow.setBackgroundDrawable(null)
+ val x: Int = homeView.rightOptionView.width - easyPopupWindow.width
+ easyPopupWindow.showAsDropDown(homeView.rightOptionView, x, 0)
+ }
+
+ //代码设置底部拉升距离
+ val bottomSheetBehavior = BottomSheetBehavior.from(homeView.bottomBehaviorLayout)
+ homeView.coordinatorLayout.post {
+ bottomSheetBehavior.isFitToContents = false
+ bottomSheetBehavior.halfExpandedRatio = 0.3f
+ bottomSheetBehavior.isHideable = false
+ bottomSheetBehavior.peekHeight = SizeUtil.dp2px(requireContext(), 30f)
+ }
+
+ //初始化vm
+ wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java)
+
+ //获取所有窨井数据
+ wellViewModel.obtainAllWell()
+ wellViewModel.allWellModel.observe(viewLifecycleOwner, {
+ if (it.code == 200) {
+ val latitudeList: MutableList = ArrayList()
+ val longitudeList: MutableList = ArrayList()
+ it.data?.forEach { well ->
+ val lat = well.latGaode.toString()
+ val lng = well.lngGaode.toString()
+ if (lat.isNotBlank() && lng.isNotBlank()) {
+ //返回true代表当前位置在大陆、港澳地区,反之不在
+ val latitude = lat.toDouble()
+ val longitude = lng.toDouble()
+ if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) {
+ //缓存所有设备详情,点击Marker时候需要
+ wellModels.add(well)
+ //分别缓存经、纬度
+ latitudeList.add(latitude)
+ longitudeList.add(longitude)
+ //将所有设备信息转化缓存为Marker点
+ allMarkerOptions.add(
+ MarkerOptions()
+ .position(LatLng(latitude, longitude))
+ .title(well.wellTypeName)
+ .snippet(well.wellName)
+ )
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度不在国内,异常经纬度 ===> [${lng},${lat}]")
+ }
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度异常,异常经纬度 ===> [${lng},${lat}]")
+ }
+ }
+ //计算所有点的中心点位置
+ val centerLatLng = LatLng(latitudeList.average(), longitudeList.average())
+ Log.d(
+ kTag,
+ "所有闸井中心点位置 ===> [${latitudeList.average()}, ${longitudeList.average()}]"
+ )
+ //移动到指定经纬度
+ val cameraPosition = CameraPosition(centerLatLng, 13f, 0f, 0f)
+ val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition)
+ aMap.animateCamera(cameraUpdate, 3000, null)
+ }
+ })
+
+ //地图初始化
+ initMap(savedInstanceState)
+ return homeView
}
- override fun initData() {
+ private fun initMap(savedInstanceState: Bundle?) {
+ homeView.mapView.onCreate(savedInstanceState)
+ aMap = homeView.mapView.map
+ aMap.mapType = AMap.MAP_TYPE_NORMAL
+ val uiSettings = aMap.uiSettings
+ uiSettings.isCompassEnabled = true
+ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER
+ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度
+ uiSettings.isRotateGesturesEnabled = false//不允许地图旋转
+
+ // 地图加载成功监听
+ aMap.addOnMapLoadedListener(this)
+ // 地图缩放监听
+ aMap.addOnCameraChangeListener(this)
+ // marker 点击事件监听
+ aMap.addOnMarkerClickListener(this)
+ // 点击marker弹出自定义popup
+ aMap.setInfoWindowAdapter(this)
+ //信息窗点击事件
+ aMap.addOnInfoWindowClickListener(this)
+ }
+
+ override fun onMapLoaded() {
+ //地图加载成功之后显示聚合点数据
+ initClustersMarkers()
+ }
+
+ override fun onCameraChange(p0: CameraPosition?) {
}
- override fun initEvent() {
+ //获取视野内的marker 根据聚合算法合成自定义的marker 显示视野内的marker
+ override fun onCameraChangeFinish(p0: CameraPosition?) {
+ //地图缩放之后显示聚合点数据
+ initClustersMarkers()
+ }
+ private fun initClustersMarkers() {
+ val proj = aMap.projection
+ val dm = resources.displayMetrics
+ var screenLocation: Point
+ markerOptionsInView.clear()
+ // 获取在当前视野内的marker
+ allMarkerOptions.forEach {
+ screenLocation = proj.toScreenLocation(it.position)
+ if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) {
+ //在当前可观区域内
+ markerOptionsInView.add(it)
+ }
+ }
+ // 自定义的聚合类MarkerCluster
+ val clustersMarkers: MutableList = ArrayList()
+ markerOptionsInView.forEach {
+ if (clustersMarkers.size == 0) {
+ //添加一个新的自定义marker
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )
+ } else {
+ var isInRange = false
+ //Kotlin foreach不能用break
+ for (view in clustersMarkers) {
+ //判断当前的marker是否在前面marker的聚合范围内 并且每个marker只会聚合一次。
+ if (view.bounds.contains(it.position)) {
+ view.addMarker(it)
+ isInRange = true
+ break
+ }
+ }
+ //如果没在任何范围内,自己单独形成一个自定义marker。在和后面的marker进行比较
+ if (!isInRange) {
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )//相距多少才聚合
+ }
+ }
+ }
+ // 设置聚合点的位置和icon
+ clustersMarkers.forEach {
+ it.setPositionAndIcon()
+ }
+ aMap.clear()
+ // 重新添加 marker
+ clustersMarkers.forEach {
+ aMap.addMarker(it.options)
+ }
+ }
+
+ override fun onMarkerClick(marker: Marker?): Boolean {
+ //显示闸井信息
+ marker?.showInfoWindow()
+ return true
+ }
+
+ override fun getInfoWindow(marker: Marker?): View? {
+ if (infoWindow == null) {
+ infoWindow = LayoutInflater.from(requireContext()).inflate(R.layout.popu_map_info, null)
+ }
+ val v = infoWindow!!
+ //反射得到popup里面的控件对象
+ val wellTypeView = v.findViewById(R.id.wellTypeView)
+ val wellCodeView = v.findViewById(R.id.wellCodeView)
+ val ownerShipView = v.findViewById(R.id.ownerShipView)
+ val locationView = v.findViewById(R.id.locationView)
+
+ //绑定数据
+ val clickedLatLng = marker?.position!!
+ for (well in wellModels) {
+ if (clickedLatLng.latitude == well.latGaode!!.toDouble()
+ && clickedLatLng.longitude == well.lngGaode!!.toDouble()
+ ) {
+ wellTypeView.text = String.format("井类型: ${well.wellType.toTypeName()}")
+ wellCodeView.text = String.format("井编号: ${well.wellCode}")
+ ownerShipView.text = String.format("权属单位: ${well.deptid.toDeptName()}")
+ locationView.text = String.format("详细位置: ${well.position}")
+ return infoWindow
+ }
+ }
+ "无法查看聚合点,请放大比例后再查看".show()
+ return null
+ }
+
+ /**
+ * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框
+ * */
+ override fun getInfoContents(p0: Marker?): View? = null
+
+ override fun onInfoWindowClick(p0: Marker?) {
+ if (p0 != null) {
+ AlertControlDialog.Builder()
+ .setContext(requireContext())
+ .setTitle("操作提示")
+ .setMessage("确定要前往吗")
+ .setNegativeButton("取消")
+ .setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ val latLng = p0.position
+ val lat = latLng.latitude.toString()
+ val lng = latLng.longitude.toString()
+ if (lat.isBlank() || lng.isBlank()) {
+ "窨井经纬度异常,无法开启导航".show()
+ return
+ }
+ Poi(p0.snippet, LatLng(lat.toDouble(), lng.toDouble()), "").showRouteOnMap(
+ requireContext()
+ )
+ }
+
+ override fun onCancelClick() {
+
+ }
+ }).build().show()
+ }
+ }
+
+ /***以下是地图生命周期管理************************************************************************/
+ override fun onResume() {
+ super.onResume()
+ homeView.mapView.onResume()
+ //每次页面切换都需要重新刷新不同状态的窨井数量
+// wellViewModel.countWellByState()
+// workOrderViewModel.countWorkOrderByState()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ homeView.mapView.onPause()
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ homeView.mapView.onSaveInstanceState(outState)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ homeView.mapView.onDestroy()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
new file mode 100644
index 0000000..4e916a9
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
@@ -0,0 +1,271 @@
+package com.casic.app.smartwell.sanxi.model;
+
+import java.util.List;
+
+public class WellListModel {
+
+ private int code;
+ private List data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public List getData() {
+ return data;
+ }
+
+ public void setData(List data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataDTO {
+ private String area;
+ private String bfzt;
+ private String bfztName;
+ private String coordinateX;
+ private String coordinateY;
+ private String deep;
+ private String deptName;
+ private String deptid;
+ private String id;
+ private String latBaidu;
+ private String latGaode;
+ private String lngBaidu;
+ private String lngGaode;
+ private String notes;
+ private String photos;
+ private String position;
+ private String staff;
+ private String tel;
+ private String ts;
+ private String valid;
+ private String watchData;
+ private String wellCode;
+ private String wellName;
+ private String wellType;
+ private String wellTypeName;
+
+ public String getArea() {
+ return area;
+ }
+
+ public void setArea(String area) {
+ this.area = area;
+ }
+
+ public String getBfzt() {
+ return bfzt;
+ }
+
+ public void setBfzt(String bfzt) {
+ this.bfzt = bfzt;
+ }
+
+ public String getBfztName() {
+ return bfztName;
+ }
+
+ public void setBfztName(String bfztName) {
+ this.bfztName = bfztName;
+ }
+
+ public String getCoordinateX() {
+ return coordinateX;
+ }
+
+ public void setCoordinateX(String coordinateX) {
+ this.coordinateX = coordinateX;
+ }
+
+ public String getCoordinateY() {
+ return coordinateY;
+ }
+
+ public void setCoordinateY(String coordinateY) {
+ this.coordinateY = coordinateY;
+ }
+
+ public String getDeep() {
+ return deep;
+ }
+
+ public void setDeep(String deep) {
+ this.deep = deep;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptid() {
+ return deptid;
+ }
+
+ public void setDeptid(String deptid) {
+ this.deptid = deptid;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getLatBaidu() {
+ return latBaidu;
+ }
+
+ public void setLatBaidu(String latBaidu) {
+ this.latBaidu = latBaidu;
+ }
+
+ public String getLatGaode() {
+ return latGaode;
+ }
+
+ public void setLatGaode(String latGaode) {
+ this.latGaode = latGaode;
+ }
+
+ public String getLngBaidu() {
+ return lngBaidu;
+ }
+
+ public void setLngBaidu(String lngBaidu) {
+ this.lngBaidu = lngBaidu;
+ }
+
+ public String getLngGaode() {
+ return lngGaode;
+ }
+
+ public void setLngGaode(String lngGaode) {
+ this.lngGaode = lngGaode;
+ }
+
+ public String getNotes() {
+ return notes;
+ }
+
+ public void setNotes(String notes) {
+ this.notes = notes;
+ }
+
+ public String getPhotos() {
+ return photos;
+ }
+
+ public void setPhotos(String photos) {
+ this.photos = photos;
+ }
+
+ public String getPosition() {
+ return position;
+ }
+
+ public void setPosition(String position) {
+ this.position = position;
+ }
+
+ public String getStaff() {
+ return staff;
+ }
+
+ public void setStaff(String staff) {
+ this.staff = staff;
+ }
+
+ public String getTel() {
+ return tel;
+ }
+
+ public void setTel(String tel) {
+ this.tel = tel;
+ }
+
+ public String getTs() {
+ return ts;
+ }
+
+ public void setTs(String ts) {
+ this.ts = ts;
+ }
+
+ public String getValid() {
+ return valid;
+ }
+
+ public void setValid(String valid) {
+ this.valid = valid;
+ }
+
+ public String getWatchData() {
+ return watchData;
+ }
+
+ public void setWatchData(String watchData) {
+ this.watchData = watchData;
+ }
+
+ public String getWellCode() {
+ return wellCode;
+ }
+
+ public void setWellCode(String wellCode) {
+ this.wellCode = wellCode;
+ }
+
+ public String getWellName() {
+ return wellName;
+ }
+
+ public void setWellName(String wellName) {
+ this.wellName = wellName;
+ }
+
+ public String getWellType() {
+ return wellType;
+ }
+
+ public void setWellType(String wellType) {
+ this.wellType = wellType;
+ }
+
+ public String getWellTypeName() {
+ return wellTypeName;
+ }
+
+ public void setWellTypeName(String wellTypeName) {
+ this.wellTypeName = wellTypeName;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
index 0fb598b..d57d378 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
@@ -1,6 +1,7 @@
package com.casic.app.smartwell.sanxi.utils
import android.Manifest
+import com.casic.app.smartwell.sanxi.R
object Constant {
@@ -19,7 +20,6 @@
const val USER_DEVICE_TYPE = "userDeviceType"
const val ACCOUNT = "account"
const val PASSWORD = "password"
- const val ALARM_TYPE = "alarmType"
const val APP_AUTHORITY = "com.casic.app.smartwell.sanxi.fileprovider"
const val CANCEL_ALARM_ACTION = "cancelAlarm"
@@ -29,11 +29,11 @@
const val RADIUS_SIZE = 100 //相距多少米才聚合,单位:米
const val DISTANCE = 5 //两点间距离阈值,单位:米
+ val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
+ val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
+
// val HOME_ICONS = arrayOf(R.drawable.ic_well, R.drawable.ic_overtime, R.drawable.ic_bfcf)
val HOME_ITEMS = arrayOf("闸井管理", "超时工单", "布防撤防")
val SUB_PAGE_TITLES = arrayOf("待处理", "待确认", "处理中", "已完成")
val OVER_TIME_PAGE_TITLES = arrayOf("超时未接单", "超时未处理")
-
- // val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
- val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
index 2bb0294..3c6fea3 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
@@ -153,6 +153,12 @@
): String
/**
+ * 获取获取闸井列表-不分页,地图用
+ */
+ @GET("/overview/wellList")
+ suspend fun obtainAllWell(@Header("token") token: String): String
+
+ /**
* 根据布防状态统计闸井数量接口
*/
@GET("/well/countByBfzt")
@@ -192,12 +198,6 @@
): String
/**
- * 获取获取闸井列表-不分页,地图用
- */
- @GET("/well/list")
- suspend fun obtainAllWell(@Header("token") token: String): String
-
- /**
* 获取井下监控设备列表
*
* @param id 窨井ID
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
index 35af71d..f67ccb6 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
@@ -151,6 +151,13 @@
return api.obtainOrderStatus(AuthenticationHelper.token!!)
}
+ /**
+ * 获取获取闸井列表-不分页
+ */
+ suspend fun obtainAllWell(): String {
+ return api.obtainAllWell(AuthenticationHelper.token!!)
+ }
+
// /**
// * 根据布防状态统计闸井数量接口
// */
@@ -190,13 +197,6 @@
// }
//
// /**
-// * 获取获取闸井列表-不分页
-// */
-// suspend fun obtainAllWell(): String {
-// return api.obtainAllWell(AuthenticationHelper.token!!)
-// }
-//
-// /**
// * 获取井下监控设备列表
// */
// suspend fun obtainMonitorResult(id: String): String {
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
index 87dd8dc..6a80a92 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
@@ -7,6 +7,7 @@
import com.casic.app.smartwell.sanxi.extensions.show
import com.casic.app.smartwell.sanxi.extensions.toErrorMessage
import com.casic.app.smartwell.sanxi.model.WellDetailModel
+import com.casic.app.smartwell.sanxi.model.WellListModel
import com.casic.app.smartwell.sanxi.utils.LoadState
import com.casic.app.smartwell.sanxi.utils.retrofit.RetrofitServiceManager
import com.google.gson.Gson
@@ -16,6 +17,7 @@
private val gson = Gson()
val detailModel = MutableLiveData()
+ val allWellModel = MutableLiveData()
fun obtainWellDetail(id: String) = launch({
loadState.value = LoadState.Loading
@@ -34,4 +36,18 @@
loadState.value = LoadState.Fail
it.printStackTrace()
})
+
+ fun obtainAllWell() = launch({
+ val response = RetrofitServiceManager.obtainAllWell()
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ allWellModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ response.toErrorMessage().show()
+ }
+ }, {
+ it.printStackTrace()
+ })
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt
new file mode 100644
index 0000000..4fd4702
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt
@@ -0,0 +1,77 @@
+package com.casic.app.smartwell.sanxi.widgets
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.*
+import com.casic.app.smartwell.sanxi.R
+import com.pengxh.app.multilib.utils.SizeUtil
+
+/**
+ * @description: 顶部下拉菜单
+ * @author: Pengxh
+ * @email: 290677893@qq.com
+ * @date: 2019/12/28 20:35
+ */
+class EasyPopupWindow(private val context: Context) : PopupWindow(context) {
+
+ private lateinit var clickListener: OnPopupWindowClickListener
+
+ init {
+ this.width = (SizeUtil.getScreenWidth(context) * 0.3).toInt()
+ this.height = ViewGroup.LayoutParams.WRAP_CONTENT
+ this.isOutsideTouchable = true
+ this.isFocusable = true
+ this.animationStyle = R.style.PopupAnimation
+ this.contentView = LayoutInflater.from(context).inflate(R.layout.popup_option, null, false)
+ }
+
+ fun setupPopupData(imageArray: Array, titleArray: Array) {
+ val popupListView = contentView.findViewById(R.id.popupListView)
+ popupListView.adapter = object : BaseAdapter() {
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+
+ override fun getCount(): Int = imageArray.size
+
+ override fun getItem(position: Int): Any = imageArray[position]
+
+ override fun getItemId(position: Int): Long = position.toLong()
+
+ override fun getView(position: Int, convertView: View?, viewGroup: ViewGroup): View {
+ val view: View
+ val holder: PopupWindowHolder
+ if (convertView == null) {
+ view = inflater.inflate(R.layout.item_map_popup, null)
+ holder = PopupWindowHolder()
+ holder.imageView = view.findViewById(R.id.imageView)
+ holder.titleView = view.findViewById(R.id.titleView)
+ view.tag = holder
+ } else {
+ view = convertView
+ holder = view.tag as PopupWindowHolder
+ }
+ holder.imageView.setBackgroundResource(imageArray[position])
+ holder.titleView.text = titleArray[position]
+ return view
+ }
+ }
+ popupListView.onItemClickListener = AdapterView.OnItemClickListener { _, _, i, _ ->
+ clickListener.onPopupClick(i)
+ dismiss()
+ }
+ }
+
+ interface OnPopupWindowClickListener {
+ fun onPopupClick(position: Int)
+ }
+
+ fun setOnPopupWindowClickListener(windowClickListener: OnPopupWindowClickListener) {
+ this.clickListener = windowClickListener
+ }
+
+ inner class PopupWindowHolder {
+ lateinit var imageView: ImageView
+ lateinit var titleView: TextView
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt
new file mode 100644
index 0000000..28ccff3
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt
@@ -0,0 +1,102 @@
+package com.casic.app.smartwell.sanxi.widgets
+
+import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.Point
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.TextView
+import com.amap.api.maps.Projection
+import com.amap.api.maps.model.BitmapDescriptorFactory
+import com.amap.api.maps.model.LatLng
+import com.amap.api.maps.model.LatLngBounds
+import com.amap.api.maps.model.MarkerOptions
+import com.casic.app.smartwell.sanxi.R
+import com.casic.app.smartwell.sanxi.extensions.toBitmap
+import java.util.*
+
+class GaoDeClusterMarkerView(
+ private val context: Context, firstMarkers: MarkerOptions,
+ projection: Projection, gridSize: Int
+) {
+ //当前可观区域里的 聚合过之后的集合
+ private val includeMarkers: ArrayList
+
+ // 创建区域
+ val bounds: LatLngBounds
+ var options: MarkerOptions = MarkerOptions()
+
+ init {
+ val screenLocation = projection.toScreenLocation(firstMarkers.position)
+ //范围类
+ val southwestPoint = Point(screenLocation.x - gridSize, screenLocation.y + gridSize)
+ //范围类
+ val northeastPoint = Point(screenLocation.x + gridSize, screenLocation.y - gridSize)
+ bounds = LatLngBounds(
+ projection.fromScreenLocation(southwestPoint),
+ projection.fromScreenLocation(northeastPoint)
+ )
+ //设置初始化marker属性
+ options.anchor(0.5f, 1.3f)
+ .title(firstMarkers.title)
+ .position(firstMarkers.position)
+ .icon(firstMarkers.icon)
+ .snippet(firstMarkers.snippet)
+ .draggable(false)
+ includeMarkers = ArrayList()
+ includeMarkers.add(firstMarkers)
+ }
+
+ /**
+ * 添加marker
+ */
+ fun addMarker(markerOptions: MarkerOptions) {
+ includeMarkers.add(markerOptions) // 添加到列表中
+ }
+
+ /**
+ * 设置聚合点的中心位置以及图标
+ */
+ fun setPositionAndIcon() {
+ val size = includeMarkers.size
+ var lat = 0.0
+ var lng = 0.0
+ // 一个的时候
+ if (size == 1) { //设置marker单个属性
+ // 设置marker位置
+ options.position(
+ LatLng(
+ includeMarkers[0].position.latitude,
+ includeMarkers[0].position.longitude
+ )
+ )
+ } else { // 聚合的时候
+ //设置marker聚合属性
+ for (op in includeMarkers) {
+ lat += op.position.latitude
+ lng += op.position.longitude
+ }
+ // 设置marker的位置为中心位置为聚集点的平均位置
+ options.position(LatLng(lat / size, lng / size))
+ }
+ options.icon(BitmapDescriptorFactory.fromBitmap(getBitmap(size)))
+ }
+
+ /**
+ * marker视图
+ */
+ private fun getBitmap(num: Int): Bitmap? {
+ val view = LayoutInflater.from(context).inflate(R.layout.marker_gaode, null)
+ val wellCountView = view.findViewById(R.id.wellCountView)
+ return if (num > 1) {
+ wellCountView.visibility = View.VISIBLE
+ wellCountView.text = String.format("${num}个")
+ wellCountView.gravity = Gravity.CENTER
+ view.toBitmap()
+ } else {
+ wellCountView.visibility = View.GONE
+ BitmapDescriptorFactory.fromResource(R.mipmap.well_location).bitmap
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_black_transparent_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_black_transparent_radius_10.xml
new file mode 100644
index 0000000..15e6a4b
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_black_transparent_radius_10.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ea56300..0416db4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -49,5 +49,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
index 291a985..c41c867 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
@@ -82,14 +82,40 @@
}
//窨井类型转换
-fun String.toChinese(): String {
+fun String.toTypeName(): String {
return when (this) {
- "0" -> "全部"
- "1" -> "一级"
- "2" -> "二级"
- "3" -> "三级"
+ "1" -> "雨水井"
+ "2" -> "污水井"
+ "3" -> "燃气井"
+ "4" -> "热力井"
+ "5" -> "电力井"
+ "6" -> "交通井"
+ "7" -> "路灯井"
+ "8" -> "通信井"
+ "9" -> "监控井"
else -> {
- "未知"
+ "其他"
+ }
+ }
+}
+
+fun String.toDeptName(): String {
+ return when (this) {
+ "0" -> "顶级"
+ "1148031048115494913" -> "二院"
+ "1178242695136149506" -> "电力公司"
+ "1178242900132757506" -> "滨海热电"
+ "24" -> "燃气集团总公司"
+ "30" -> "203所"
+ "1399230677135265794" -> "厦门测试"
+ "25" -> "第一分公司"
+ "26" -> "第二分公司"
+ "27" -> "第三分公司"
+ "28" -> "第四分公司"
+ "29" -> "高压管网分公司"
+ "1143796514486353922" -> "第五分公司"
+ else -> {
+ "其他"
}
}
}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
index 26f3085..4d0c818 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
@@ -1,24 +1,326 @@
package com.casic.app.smartwell.sanxi.fragment
+import android.graphics.Point
+import android.os.Bundle
+import android.util.Log
+import android.view.LayoutInflater
import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import com.amap.api.maps.AMap
+import com.amap.api.maps.AMapOptions
+import com.amap.api.maps.CameraUpdateFactory
+import com.amap.api.maps.CoordinateConverter
+import com.amap.api.maps.model.*
import com.casic.app.smartwell.sanxi.R
-import com.casic.app.smartwell.sanxi.base.BaseFragment
-import kotlinx.android.synthetic.main.include_base_title.*
+import com.casic.app.smartwell.sanxi.extensions.show
+import com.casic.app.smartwell.sanxi.extensions.showRouteOnMap
+import com.casic.app.smartwell.sanxi.extensions.toDeptName
+import com.casic.app.smartwell.sanxi.extensions.toTypeName
+import com.casic.app.smartwell.sanxi.model.WellListModel
+import com.casic.app.smartwell.sanxi.utils.Constant
+import com.casic.app.smartwell.sanxi.vm.WellViewModel
+import com.casic.app.smartwell.sanxi.widgets.EasyPopupWindow
+import com.casic.app.smartwell.sanxi.widgets.GaoDeClusterMarkerView
+import com.google.android.material.bottomsheet.BottomSheetBehavior
+import com.pengxh.app.multilib.utils.SizeUtil
+import com.pengxh.app.multilib.widget.dialog.AlertControlDialog
+import kotlinx.android.synthetic.main.fragment_home.view.*
-class HomePageFragment : BaseFragment() {
+class HomePageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener,
+ AMap.OnMarkerClickListener, AMap.InfoWindowAdapter, AMap.OnInfoWindowClickListener {
- override fun initLayoutView(): Int = R.layout.fragment_home
+ private val kTag = "HomePageFragment"
+ private lateinit var homeView: View
+ private lateinit var aMap: AMap
+ private lateinit var wellViewModel: WellViewModel
- override fun setupTopBarLayout() {
- leftBackView.visibility = View.GONE
- titleView.text = "首页"
+ /**
+ * 所有窨井列表信息集合
+ * */
+ private var wellModels: MutableList = ArrayList()
+
+ /**
+ * 所有的marker
+ */
+ private var allMarkerOptions: MutableList = ArrayList()
+
+ /**
+ * 视野内的marker
+ */
+ private var markerOptionsInView: MutableList = ArrayList()
+
+ /**
+ * 自定义Marker弹出框
+ * */
+ private var infoWindow: View? = null
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ homeView = inflater.inflate(R.layout.fragment_home, container, false)
+ homeView.titleView.text = "首页"
+ val easyPopupWindow = EasyPopupWindow(requireContext())
+ easyPopupWindow.setupPopupData(Constant.POPUP_IMAGES, Constant.POPUP_TITLES)
+ homeView.rightOptionView.setOnClickListener {
+ easyPopupWindow.setOnPopupWindowClickListener(object :
+ EasyPopupWindow.OnPopupWindowClickListener {
+ override fun onPopupClick(position: Int) {
+ when (position) {
+ 0 -> aMap.mapType = AMap.MAP_TYPE_NORMAL
+ 1 -> aMap.mapType = AMap.MAP_TYPE_SATELLITE
+ }
+ }
+ })
+ easyPopupWindow.setBackgroundDrawable(null)
+ val x: Int = homeView.rightOptionView.width - easyPopupWindow.width
+ easyPopupWindow.showAsDropDown(homeView.rightOptionView, x, 0)
+ }
+
+ //代码设置底部拉升距离
+ val bottomSheetBehavior = BottomSheetBehavior.from(homeView.bottomBehaviorLayout)
+ homeView.coordinatorLayout.post {
+ bottomSheetBehavior.isFitToContents = false
+ bottomSheetBehavior.halfExpandedRatio = 0.3f
+ bottomSheetBehavior.isHideable = false
+ bottomSheetBehavior.peekHeight = SizeUtil.dp2px(requireContext(), 30f)
+ }
+
+ //初始化vm
+ wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java)
+
+ //获取所有窨井数据
+ wellViewModel.obtainAllWell()
+ wellViewModel.allWellModel.observe(viewLifecycleOwner, {
+ if (it.code == 200) {
+ val latitudeList: MutableList = ArrayList()
+ val longitudeList: MutableList = ArrayList()
+ it.data?.forEach { well ->
+ val lat = well.latGaode.toString()
+ val lng = well.lngGaode.toString()
+ if (lat.isNotBlank() && lng.isNotBlank()) {
+ //返回true代表当前位置在大陆、港澳地区,反之不在
+ val latitude = lat.toDouble()
+ val longitude = lng.toDouble()
+ if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) {
+ //缓存所有设备详情,点击Marker时候需要
+ wellModels.add(well)
+ //分别缓存经、纬度
+ latitudeList.add(latitude)
+ longitudeList.add(longitude)
+ //将所有设备信息转化缓存为Marker点
+ allMarkerOptions.add(
+ MarkerOptions()
+ .position(LatLng(latitude, longitude))
+ .title(well.wellTypeName)
+ .snippet(well.wellName)
+ )
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度不在国内,异常经纬度 ===> [${lng},${lat}]")
+ }
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度异常,异常经纬度 ===> [${lng},${lat}]")
+ }
+ }
+ //计算所有点的中心点位置
+ val centerLatLng = LatLng(latitudeList.average(), longitudeList.average())
+ Log.d(
+ kTag,
+ "所有闸井中心点位置 ===> [${latitudeList.average()}, ${longitudeList.average()}]"
+ )
+ //移动到指定经纬度
+ val cameraPosition = CameraPosition(centerLatLng, 13f, 0f, 0f)
+ val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition)
+ aMap.animateCamera(cameraUpdate, 3000, null)
+ }
+ })
+
+ //地图初始化
+ initMap(savedInstanceState)
+ return homeView
}
- override fun initData() {
+ private fun initMap(savedInstanceState: Bundle?) {
+ homeView.mapView.onCreate(savedInstanceState)
+ aMap = homeView.mapView.map
+ aMap.mapType = AMap.MAP_TYPE_NORMAL
+ val uiSettings = aMap.uiSettings
+ uiSettings.isCompassEnabled = true
+ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER
+ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度
+ uiSettings.isRotateGesturesEnabled = false//不允许地图旋转
+
+ // 地图加载成功监听
+ aMap.addOnMapLoadedListener(this)
+ // 地图缩放监听
+ aMap.addOnCameraChangeListener(this)
+ // marker 点击事件监听
+ aMap.addOnMarkerClickListener(this)
+ // 点击marker弹出自定义popup
+ aMap.setInfoWindowAdapter(this)
+ //信息窗点击事件
+ aMap.addOnInfoWindowClickListener(this)
+ }
+
+ override fun onMapLoaded() {
+ //地图加载成功之后显示聚合点数据
+ initClustersMarkers()
+ }
+
+ override fun onCameraChange(p0: CameraPosition?) {
}
- override fun initEvent() {
+ //获取视野内的marker 根据聚合算法合成自定义的marker 显示视野内的marker
+ override fun onCameraChangeFinish(p0: CameraPosition?) {
+ //地图缩放之后显示聚合点数据
+ initClustersMarkers()
+ }
+ private fun initClustersMarkers() {
+ val proj = aMap.projection
+ val dm = resources.displayMetrics
+ var screenLocation: Point
+ markerOptionsInView.clear()
+ // 获取在当前视野内的marker
+ allMarkerOptions.forEach {
+ screenLocation = proj.toScreenLocation(it.position)
+ if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) {
+ //在当前可观区域内
+ markerOptionsInView.add(it)
+ }
+ }
+ // 自定义的聚合类MarkerCluster
+ val clustersMarkers: MutableList = ArrayList()
+ markerOptionsInView.forEach {
+ if (clustersMarkers.size == 0) {
+ //添加一个新的自定义marker
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )
+ } else {
+ var isInRange = false
+ //Kotlin foreach不能用break
+ for (view in clustersMarkers) {
+ //判断当前的marker是否在前面marker的聚合范围内 并且每个marker只会聚合一次。
+ if (view.bounds.contains(it.position)) {
+ view.addMarker(it)
+ isInRange = true
+ break
+ }
+ }
+ //如果没在任何范围内,自己单独形成一个自定义marker。在和后面的marker进行比较
+ if (!isInRange) {
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )//相距多少才聚合
+ }
+ }
+ }
+ // 设置聚合点的位置和icon
+ clustersMarkers.forEach {
+ it.setPositionAndIcon()
+ }
+ aMap.clear()
+ // 重新添加 marker
+ clustersMarkers.forEach {
+ aMap.addMarker(it.options)
+ }
+ }
+
+ override fun onMarkerClick(marker: Marker?): Boolean {
+ //显示闸井信息
+ marker?.showInfoWindow()
+ return true
+ }
+
+ override fun getInfoWindow(marker: Marker?): View? {
+ if (infoWindow == null) {
+ infoWindow = LayoutInflater.from(requireContext()).inflate(R.layout.popu_map_info, null)
+ }
+ val v = infoWindow!!
+ //反射得到popup里面的控件对象
+ val wellTypeView = v.findViewById(R.id.wellTypeView)
+ val wellCodeView = v.findViewById(R.id.wellCodeView)
+ val ownerShipView = v.findViewById(R.id.ownerShipView)
+ val locationView = v.findViewById(R.id.locationView)
+
+ //绑定数据
+ val clickedLatLng = marker?.position!!
+ for (well in wellModels) {
+ if (clickedLatLng.latitude == well.latGaode!!.toDouble()
+ && clickedLatLng.longitude == well.lngGaode!!.toDouble()
+ ) {
+ wellTypeView.text = String.format("井类型: ${well.wellType.toTypeName()}")
+ wellCodeView.text = String.format("井编号: ${well.wellCode}")
+ ownerShipView.text = String.format("权属单位: ${well.deptid.toDeptName()}")
+ locationView.text = String.format("详细位置: ${well.position}")
+ return infoWindow
+ }
+ }
+ "无法查看聚合点,请放大比例后再查看".show()
+ return null
+ }
+
+ /**
+ * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框
+ * */
+ override fun getInfoContents(p0: Marker?): View? = null
+
+ override fun onInfoWindowClick(p0: Marker?) {
+ if (p0 != null) {
+ AlertControlDialog.Builder()
+ .setContext(requireContext())
+ .setTitle("操作提示")
+ .setMessage("确定要前往吗")
+ .setNegativeButton("取消")
+ .setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ val latLng = p0.position
+ val lat = latLng.latitude.toString()
+ val lng = latLng.longitude.toString()
+ if (lat.isBlank() || lng.isBlank()) {
+ "窨井经纬度异常,无法开启导航".show()
+ return
+ }
+ Poi(p0.snippet, LatLng(lat.toDouble(), lng.toDouble()), "").showRouteOnMap(
+ requireContext()
+ )
+ }
+
+ override fun onCancelClick() {
+
+ }
+ }).build().show()
+ }
+ }
+
+ /***以下是地图生命周期管理************************************************************************/
+ override fun onResume() {
+ super.onResume()
+ homeView.mapView.onResume()
+ //每次页面切换都需要重新刷新不同状态的窨井数量
+// wellViewModel.countWellByState()
+// workOrderViewModel.countWorkOrderByState()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ homeView.mapView.onPause()
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ homeView.mapView.onSaveInstanceState(outState)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ homeView.mapView.onDestroy()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
new file mode 100644
index 0000000..4e916a9
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
@@ -0,0 +1,271 @@
+package com.casic.app.smartwell.sanxi.model;
+
+import java.util.List;
+
+public class WellListModel {
+
+ private int code;
+ private List data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public List getData() {
+ return data;
+ }
+
+ public void setData(List data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataDTO {
+ private String area;
+ private String bfzt;
+ private String bfztName;
+ private String coordinateX;
+ private String coordinateY;
+ private String deep;
+ private String deptName;
+ private String deptid;
+ private String id;
+ private String latBaidu;
+ private String latGaode;
+ private String lngBaidu;
+ private String lngGaode;
+ private String notes;
+ private String photos;
+ private String position;
+ private String staff;
+ private String tel;
+ private String ts;
+ private String valid;
+ private String watchData;
+ private String wellCode;
+ private String wellName;
+ private String wellType;
+ private String wellTypeName;
+
+ public String getArea() {
+ return area;
+ }
+
+ public void setArea(String area) {
+ this.area = area;
+ }
+
+ public String getBfzt() {
+ return bfzt;
+ }
+
+ public void setBfzt(String bfzt) {
+ this.bfzt = bfzt;
+ }
+
+ public String getBfztName() {
+ return bfztName;
+ }
+
+ public void setBfztName(String bfztName) {
+ this.bfztName = bfztName;
+ }
+
+ public String getCoordinateX() {
+ return coordinateX;
+ }
+
+ public void setCoordinateX(String coordinateX) {
+ this.coordinateX = coordinateX;
+ }
+
+ public String getCoordinateY() {
+ return coordinateY;
+ }
+
+ public void setCoordinateY(String coordinateY) {
+ this.coordinateY = coordinateY;
+ }
+
+ public String getDeep() {
+ return deep;
+ }
+
+ public void setDeep(String deep) {
+ this.deep = deep;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptid() {
+ return deptid;
+ }
+
+ public void setDeptid(String deptid) {
+ this.deptid = deptid;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getLatBaidu() {
+ return latBaidu;
+ }
+
+ public void setLatBaidu(String latBaidu) {
+ this.latBaidu = latBaidu;
+ }
+
+ public String getLatGaode() {
+ return latGaode;
+ }
+
+ public void setLatGaode(String latGaode) {
+ this.latGaode = latGaode;
+ }
+
+ public String getLngBaidu() {
+ return lngBaidu;
+ }
+
+ public void setLngBaidu(String lngBaidu) {
+ this.lngBaidu = lngBaidu;
+ }
+
+ public String getLngGaode() {
+ return lngGaode;
+ }
+
+ public void setLngGaode(String lngGaode) {
+ this.lngGaode = lngGaode;
+ }
+
+ public String getNotes() {
+ return notes;
+ }
+
+ public void setNotes(String notes) {
+ this.notes = notes;
+ }
+
+ public String getPhotos() {
+ return photos;
+ }
+
+ public void setPhotos(String photos) {
+ this.photos = photos;
+ }
+
+ public String getPosition() {
+ return position;
+ }
+
+ public void setPosition(String position) {
+ this.position = position;
+ }
+
+ public String getStaff() {
+ return staff;
+ }
+
+ public void setStaff(String staff) {
+ this.staff = staff;
+ }
+
+ public String getTel() {
+ return tel;
+ }
+
+ public void setTel(String tel) {
+ this.tel = tel;
+ }
+
+ public String getTs() {
+ return ts;
+ }
+
+ public void setTs(String ts) {
+ this.ts = ts;
+ }
+
+ public String getValid() {
+ return valid;
+ }
+
+ public void setValid(String valid) {
+ this.valid = valid;
+ }
+
+ public String getWatchData() {
+ return watchData;
+ }
+
+ public void setWatchData(String watchData) {
+ this.watchData = watchData;
+ }
+
+ public String getWellCode() {
+ return wellCode;
+ }
+
+ public void setWellCode(String wellCode) {
+ this.wellCode = wellCode;
+ }
+
+ public String getWellName() {
+ return wellName;
+ }
+
+ public void setWellName(String wellName) {
+ this.wellName = wellName;
+ }
+
+ public String getWellType() {
+ return wellType;
+ }
+
+ public void setWellType(String wellType) {
+ this.wellType = wellType;
+ }
+
+ public String getWellTypeName() {
+ return wellTypeName;
+ }
+
+ public void setWellTypeName(String wellTypeName) {
+ this.wellTypeName = wellTypeName;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
index 0fb598b..d57d378 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
@@ -1,6 +1,7 @@
package com.casic.app.smartwell.sanxi.utils
import android.Manifest
+import com.casic.app.smartwell.sanxi.R
object Constant {
@@ -19,7 +20,6 @@
const val USER_DEVICE_TYPE = "userDeviceType"
const val ACCOUNT = "account"
const val PASSWORD = "password"
- const val ALARM_TYPE = "alarmType"
const val APP_AUTHORITY = "com.casic.app.smartwell.sanxi.fileprovider"
const val CANCEL_ALARM_ACTION = "cancelAlarm"
@@ -29,11 +29,11 @@
const val RADIUS_SIZE = 100 //相距多少米才聚合,单位:米
const val DISTANCE = 5 //两点间距离阈值,单位:米
+ val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
+ val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
+
// val HOME_ICONS = arrayOf(R.drawable.ic_well, R.drawable.ic_overtime, R.drawable.ic_bfcf)
val HOME_ITEMS = arrayOf("闸井管理", "超时工单", "布防撤防")
val SUB_PAGE_TITLES = arrayOf("待处理", "待确认", "处理中", "已完成")
val OVER_TIME_PAGE_TITLES = arrayOf("超时未接单", "超时未处理")
-
- // val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
- val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
index 2bb0294..3c6fea3 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
@@ -153,6 +153,12 @@
): String
/**
+ * 获取获取闸井列表-不分页,地图用
+ */
+ @GET("/overview/wellList")
+ suspend fun obtainAllWell(@Header("token") token: String): String
+
+ /**
* 根据布防状态统计闸井数量接口
*/
@GET("/well/countByBfzt")
@@ -192,12 +198,6 @@
): String
/**
- * 获取获取闸井列表-不分页,地图用
- */
- @GET("/well/list")
- suspend fun obtainAllWell(@Header("token") token: String): String
-
- /**
* 获取井下监控设备列表
*
* @param id 窨井ID
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
index 35af71d..f67ccb6 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
@@ -151,6 +151,13 @@
return api.obtainOrderStatus(AuthenticationHelper.token!!)
}
+ /**
+ * 获取获取闸井列表-不分页
+ */
+ suspend fun obtainAllWell(): String {
+ return api.obtainAllWell(AuthenticationHelper.token!!)
+ }
+
// /**
// * 根据布防状态统计闸井数量接口
// */
@@ -190,13 +197,6 @@
// }
//
// /**
-// * 获取获取闸井列表-不分页
-// */
-// suspend fun obtainAllWell(): String {
-// return api.obtainAllWell(AuthenticationHelper.token!!)
-// }
-//
-// /**
// * 获取井下监控设备列表
// */
// suspend fun obtainMonitorResult(id: String): String {
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
index 87dd8dc..6a80a92 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
@@ -7,6 +7,7 @@
import com.casic.app.smartwell.sanxi.extensions.show
import com.casic.app.smartwell.sanxi.extensions.toErrorMessage
import com.casic.app.smartwell.sanxi.model.WellDetailModel
+import com.casic.app.smartwell.sanxi.model.WellListModel
import com.casic.app.smartwell.sanxi.utils.LoadState
import com.casic.app.smartwell.sanxi.utils.retrofit.RetrofitServiceManager
import com.google.gson.Gson
@@ -16,6 +17,7 @@
private val gson = Gson()
val detailModel = MutableLiveData()
+ val allWellModel = MutableLiveData()
fun obtainWellDetail(id: String) = launch({
loadState.value = LoadState.Loading
@@ -34,4 +36,18 @@
loadState.value = LoadState.Fail
it.printStackTrace()
})
+
+ fun obtainAllWell() = launch({
+ val response = RetrofitServiceManager.obtainAllWell()
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ allWellModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ response.toErrorMessage().show()
+ }
+ }, {
+ it.printStackTrace()
+ })
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt
new file mode 100644
index 0000000..4fd4702
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt
@@ -0,0 +1,77 @@
+package com.casic.app.smartwell.sanxi.widgets
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.*
+import com.casic.app.smartwell.sanxi.R
+import com.pengxh.app.multilib.utils.SizeUtil
+
+/**
+ * @description: 顶部下拉菜单
+ * @author: Pengxh
+ * @email: 290677893@qq.com
+ * @date: 2019/12/28 20:35
+ */
+class EasyPopupWindow(private val context: Context) : PopupWindow(context) {
+
+ private lateinit var clickListener: OnPopupWindowClickListener
+
+ init {
+ this.width = (SizeUtil.getScreenWidth(context) * 0.3).toInt()
+ this.height = ViewGroup.LayoutParams.WRAP_CONTENT
+ this.isOutsideTouchable = true
+ this.isFocusable = true
+ this.animationStyle = R.style.PopupAnimation
+ this.contentView = LayoutInflater.from(context).inflate(R.layout.popup_option, null, false)
+ }
+
+ fun setupPopupData(imageArray: Array, titleArray: Array) {
+ val popupListView = contentView.findViewById(R.id.popupListView)
+ popupListView.adapter = object : BaseAdapter() {
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+
+ override fun getCount(): Int = imageArray.size
+
+ override fun getItem(position: Int): Any = imageArray[position]
+
+ override fun getItemId(position: Int): Long = position.toLong()
+
+ override fun getView(position: Int, convertView: View?, viewGroup: ViewGroup): View {
+ val view: View
+ val holder: PopupWindowHolder
+ if (convertView == null) {
+ view = inflater.inflate(R.layout.item_map_popup, null)
+ holder = PopupWindowHolder()
+ holder.imageView = view.findViewById(R.id.imageView)
+ holder.titleView = view.findViewById(R.id.titleView)
+ view.tag = holder
+ } else {
+ view = convertView
+ holder = view.tag as PopupWindowHolder
+ }
+ holder.imageView.setBackgroundResource(imageArray[position])
+ holder.titleView.text = titleArray[position]
+ return view
+ }
+ }
+ popupListView.onItemClickListener = AdapterView.OnItemClickListener { _, _, i, _ ->
+ clickListener.onPopupClick(i)
+ dismiss()
+ }
+ }
+
+ interface OnPopupWindowClickListener {
+ fun onPopupClick(position: Int)
+ }
+
+ fun setOnPopupWindowClickListener(windowClickListener: OnPopupWindowClickListener) {
+ this.clickListener = windowClickListener
+ }
+
+ inner class PopupWindowHolder {
+ lateinit var imageView: ImageView
+ lateinit var titleView: TextView
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt
new file mode 100644
index 0000000..28ccff3
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt
@@ -0,0 +1,102 @@
+package com.casic.app.smartwell.sanxi.widgets
+
+import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.Point
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.TextView
+import com.amap.api.maps.Projection
+import com.amap.api.maps.model.BitmapDescriptorFactory
+import com.amap.api.maps.model.LatLng
+import com.amap.api.maps.model.LatLngBounds
+import com.amap.api.maps.model.MarkerOptions
+import com.casic.app.smartwell.sanxi.R
+import com.casic.app.smartwell.sanxi.extensions.toBitmap
+import java.util.*
+
+class GaoDeClusterMarkerView(
+ private val context: Context, firstMarkers: MarkerOptions,
+ projection: Projection, gridSize: Int
+) {
+ //当前可观区域里的 聚合过之后的集合
+ private val includeMarkers: ArrayList
+
+ // 创建区域
+ val bounds: LatLngBounds
+ var options: MarkerOptions = MarkerOptions()
+
+ init {
+ val screenLocation = projection.toScreenLocation(firstMarkers.position)
+ //范围类
+ val southwestPoint = Point(screenLocation.x - gridSize, screenLocation.y + gridSize)
+ //范围类
+ val northeastPoint = Point(screenLocation.x + gridSize, screenLocation.y - gridSize)
+ bounds = LatLngBounds(
+ projection.fromScreenLocation(southwestPoint),
+ projection.fromScreenLocation(northeastPoint)
+ )
+ //设置初始化marker属性
+ options.anchor(0.5f, 1.3f)
+ .title(firstMarkers.title)
+ .position(firstMarkers.position)
+ .icon(firstMarkers.icon)
+ .snippet(firstMarkers.snippet)
+ .draggable(false)
+ includeMarkers = ArrayList()
+ includeMarkers.add(firstMarkers)
+ }
+
+ /**
+ * 添加marker
+ */
+ fun addMarker(markerOptions: MarkerOptions) {
+ includeMarkers.add(markerOptions) // 添加到列表中
+ }
+
+ /**
+ * 设置聚合点的中心位置以及图标
+ */
+ fun setPositionAndIcon() {
+ val size = includeMarkers.size
+ var lat = 0.0
+ var lng = 0.0
+ // 一个的时候
+ if (size == 1) { //设置marker单个属性
+ // 设置marker位置
+ options.position(
+ LatLng(
+ includeMarkers[0].position.latitude,
+ includeMarkers[0].position.longitude
+ )
+ )
+ } else { // 聚合的时候
+ //设置marker聚合属性
+ for (op in includeMarkers) {
+ lat += op.position.latitude
+ lng += op.position.longitude
+ }
+ // 设置marker的位置为中心位置为聚集点的平均位置
+ options.position(LatLng(lat / size, lng / size))
+ }
+ options.icon(BitmapDescriptorFactory.fromBitmap(getBitmap(size)))
+ }
+
+ /**
+ * marker视图
+ */
+ private fun getBitmap(num: Int): Bitmap? {
+ val view = LayoutInflater.from(context).inflate(R.layout.marker_gaode, null)
+ val wellCountView = view.findViewById(R.id.wellCountView)
+ return if (num > 1) {
+ wellCountView.visibility = View.VISIBLE
+ wellCountView.text = String.format("${num}个")
+ wellCountView.gravity = Gravity.CENTER
+ view.toBitmap()
+ } else {
+ wellCountView.visibility = View.GONE
+ BitmapDescriptorFactory.fromResource(R.mipmap.well_location).bitmap
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_black_transparent_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_black_transparent_radius_10.xml
new file mode 100644
index 0000000..15e6a4b
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_black_transparent_radius_10.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_main_color.xml b/app/src/main/res/drawable/bg_solid_layout_main_color.xml
new file mode 100644
index 0000000..e329b7d
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_main_color.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ea56300..0416db4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -49,5 +49,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
index 291a985..c41c867 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
@@ -82,14 +82,40 @@
}
//窨井类型转换
-fun String.toChinese(): String {
+fun String.toTypeName(): String {
return when (this) {
- "0" -> "全部"
- "1" -> "一级"
- "2" -> "二级"
- "3" -> "三级"
+ "1" -> "雨水井"
+ "2" -> "污水井"
+ "3" -> "燃气井"
+ "4" -> "热力井"
+ "5" -> "电力井"
+ "6" -> "交通井"
+ "7" -> "路灯井"
+ "8" -> "通信井"
+ "9" -> "监控井"
else -> {
- "未知"
+ "其他"
+ }
+ }
+}
+
+fun String.toDeptName(): String {
+ return when (this) {
+ "0" -> "顶级"
+ "1148031048115494913" -> "二院"
+ "1178242695136149506" -> "电力公司"
+ "1178242900132757506" -> "滨海热电"
+ "24" -> "燃气集团总公司"
+ "30" -> "203所"
+ "1399230677135265794" -> "厦门测试"
+ "25" -> "第一分公司"
+ "26" -> "第二分公司"
+ "27" -> "第三分公司"
+ "28" -> "第四分公司"
+ "29" -> "高压管网分公司"
+ "1143796514486353922" -> "第五分公司"
+ else -> {
+ "其他"
}
}
}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
index 26f3085..4d0c818 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
@@ -1,24 +1,326 @@
package com.casic.app.smartwell.sanxi.fragment
+import android.graphics.Point
+import android.os.Bundle
+import android.util.Log
+import android.view.LayoutInflater
import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import com.amap.api.maps.AMap
+import com.amap.api.maps.AMapOptions
+import com.amap.api.maps.CameraUpdateFactory
+import com.amap.api.maps.CoordinateConverter
+import com.amap.api.maps.model.*
import com.casic.app.smartwell.sanxi.R
-import com.casic.app.smartwell.sanxi.base.BaseFragment
-import kotlinx.android.synthetic.main.include_base_title.*
+import com.casic.app.smartwell.sanxi.extensions.show
+import com.casic.app.smartwell.sanxi.extensions.showRouteOnMap
+import com.casic.app.smartwell.sanxi.extensions.toDeptName
+import com.casic.app.smartwell.sanxi.extensions.toTypeName
+import com.casic.app.smartwell.sanxi.model.WellListModel
+import com.casic.app.smartwell.sanxi.utils.Constant
+import com.casic.app.smartwell.sanxi.vm.WellViewModel
+import com.casic.app.smartwell.sanxi.widgets.EasyPopupWindow
+import com.casic.app.smartwell.sanxi.widgets.GaoDeClusterMarkerView
+import com.google.android.material.bottomsheet.BottomSheetBehavior
+import com.pengxh.app.multilib.utils.SizeUtil
+import com.pengxh.app.multilib.widget.dialog.AlertControlDialog
+import kotlinx.android.synthetic.main.fragment_home.view.*
-class HomePageFragment : BaseFragment() {
+class HomePageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener,
+ AMap.OnMarkerClickListener, AMap.InfoWindowAdapter, AMap.OnInfoWindowClickListener {
- override fun initLayoutView(): Int = R.layout.fragment_home
+ private val kTag = "HomePageFragment"
+ private lateinit var homeView: View
+ private lateinit var aMap: AMap
+ private lateinit var wellViewModel: WellViewModel
- override fun setupTopBarLayout() {
- leftBackView.visibility = View.GONE
- titleView.text = "首页"
+ /**
+ * 所有窨井列表信息集合
+ * */
+ private var wellModels: MutableList = ArrayList()
+
+ /**
+ * 所有的marker
+ */
+ private var allMarkerOptions: MutableList = ArrayList()
+
+ /**
+ * 视野内的marker
+ */
+ private var markerOptionsInView: MutableList = ArrayList()
+
+ /**
+ * 自定义Marker弹出框
+ * */
+ private var infoWindow: View? = null
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ homeView = inflater.inflate(R.layout.fragment_home, container, false)
+ homeView.titleView.text = "首页"
+ val easyPopupWindow = EasyPopupWindow(requireContext())
+ easyPopupWindow.setupPopupData(Constant.POPUP_IMAGES, Constant.POPUP_TITLES)
+ homeView.rightOptionView.setOnClickListener {
+ easyPopupWindow.setOnPopupWindowClickListener(object :
+ EasyPopupWindow.OnPopupWindowClickListener {
+ override fun onPopupClick(position: Int) {
+ when (position) {
+ 0 -> aMap.mapType = AMap.MAP_TYPE_NORMAL
+ 1 -> aMap.mapType = AMap.MAP_TYPE_SATELLITE
+ }
+ }
+ })
+ easyPopupWindow.setBackgroundDrawable(null)
+ val x: Int = homeView.rightOptionView.width - easyPopupWindow.width
+ easyPopupWindow.showAsDropDown(homeView.rightOptionView, x, 0)
+ }
+
+ //代码设置底部拉升距离
+ val bottomSheetBehavior = BottomSheetBehavior.from(homeView.bottomBehaviorLayout)
+ homeView.coordinatorLayout.post {
+ bottomSheetBehavior.isFitToContents = false
+ bottomSheetBehavior.halfExpandedRatio = 0.3f
+ bottomSheetBehavior.isHideable = false
+ bottomSheetBehavior.peekHeight = SizeUtil.dp2px(requireContext(), 30f)
+ }
+
+ //初始化vm
+ wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java)
+
+ //获取所有窨井数据
+ wellViewModel.obtainAllWell()
+ wellViewModel.allWellModel.observe(viewLifecycleOwner, {
+ if (it.code == 200) {
+ val latitudeList: MutableList = ArrayList()
+ val longitudeList: MutableList = ArrayList()
+ it.data?.forEach { well ->
+ val lat = well.latGaode.toString()
+ val lng = well.lngGaode.toString()
+ if (lat.isNotBlank() && lng.isNotBlank()) {
+ //返回true代表当前位置在大陆、港澳地区,反之不在
+ val latitude = lat.toDouble()
+ val longitude = lng.toDouble()
+ if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) {
+ //缓存所有设备详情,点击Marker时候需要
+ wellModels.add(well)
+ //分别缓存经、纬度
+ latitudeList.add(latitude)
+ longitudeList.add(longitude)
+ //将所有设备信息转化缓存为Marker点
+ allMarkerOptions.add(
+ MarkerOptions()
+ .position(LatLng(latitude, longitude))
+ .title(well.wellTypeName)
+ .snippet(well.wellName)
+ )
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度不在国内,异常经纬度 ===> [${lng},${lat}]")
+ }
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度异常,异常经纬度 ===> [${lng},${lat}]")
+ }
+ }
+ //计算所有点的中心点位置
+ val centerLatLng = LatLng(latitudeList.average(), longitudeList.average())
+ Log.d(
+ kTag,
+ "所有闸井中心点位置 ===> [${latitudeList.average()}, ${longitudeList.average()}]"
+ )
+ //移动到指定经纬度
+ val cameraPosition = CameraPosition(centerLatLng, 13f, 0f, 0f)
+ val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition)
+ aMap.animateCamera(cameraUpdate, 3000, null)
+ }
+ })
+
+ //地图初始化
+ initMap(savedInstanceState)
+ return homeView
}
- override fun initData() {
+ private fun initMap(savedInstanceState: Bundle?) {
+ homeView.mapView.onCreate(savedInstanceState)
+ aMap = homeView.mapView.map
+ aMap.mapType = AMap.MAP_TYPE_NORMAL
+ val uiSettings = aMap.uiSettings
+ uiSettings.isCompassEnabled = true
+ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER
+ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度
+ uiSettings.isRotateGesturesEnabled = false//不允许地图旋转
+
+ // 地图加载成功监听
+ aMap.addOnMapLoadedListener(this)
+ // 地图缩放监听
+ aMap.addOnCameraChangeListener(this)
+ // marker 点击事件监听
+ aMap.addOnMarkerClickListener(this)
+ // 点击marker弹出自定义popup
+ aMap.setInfoWindowAdapter(this)
+ //信息窗点击事件
+ aMap.addOnInfoWindowClickListener(this)
+ }
+
+ override fun onMapLoaded() {
+ //地图加载成功之后显示聚合点数据
+ initClustersMarkers()
+ }
+
+ override fun onCameraChange(p0: CameraPosition?) {
}
- override fun initEvent() {
+ //获取视野内的marker 根据聚合算法合成自定义的marker 显示视野内的marker
+ override fun onCameraChangeFinish(p0: CameraPosition?) {
+ //地图缩放之后显示聚合点数据
+ initClustersMarkers()
+ }
+ private fun initClustersMarkers() {
+ val proj = aMap.projection
+ val dm = resources.displayMetrics
+ var screenLocation: Point
+ markerOptionsInView.clear()
+ // 获取在当前视野内的marker
+ allMarkerOptions.forEach {
+ screenLocation = proj.toScreenLocation(it.position)
+ if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) {
+ //在当前可观区域内
+ markerOptionsInView.add(it)
+ }
+ }
+ // 自定义的聚合类MarkerCluster
+ val clustersMarkers: MutableList = ArrayList()
+ markerOptionsInView.forEach {
+ if (clustersMarkers.size == 0) {
+ //添加一个新的自定义marker
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )
+ } else {
+ var isInRange = false
+ //Kotlin foreach不能用break
+ for (view in clustersMarkers) {
+ //判断当前的marker是否在前面marker的聚合范围内 并且每个marker只会聚合一次。
+ if (view.bounds.contains(it.position)) {
+ view.addMarker(it)
+ isInRange = true
+ break
+ }
+ }
+ //如果没在任何范围内,自己单独形成一个自定义marker。在和后面的marker进行比较
+ if (!isInRange) {
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )//相距多少才聚合
+ }
+ }
+ }
+ // 设置聚合点的位置和icon
+ clustersMarkers.forEach {
+ it.setPositionAndIcon()
+ }
+ aMap.clear()
+ // 重新添加 marker
+ clustersMarkers.forEach {
+ aMap.addMarker(it.options)
+ }
+ }
+
+ override fun onMarkerClick(marker: Marker?): Boolean {
+ //显示闸井信息
+ marker?.showInfoWindow()
+ return true
+ }
+
+ override fun getInfoWindow(marker: Marker?): View? {
+ if (infoWindow == null) {
+ infoWindow = LayoutInflater.from(requireContext()).inflate(R.layout.popu_map_info, null)
+ }
+ val v = infoWindow!!
+ //反射得到popup里面的控件对象
+ val wellTypeView = v.findViewById(R.id.wellTypeView)
+ val wellCodeView = v.findViewById(R.id.wellCodeView)
+ val ownerShipView = v.findViewById(R.id.ownerShipView)
+ val locationView = v.findViewById(R.id.locationView)
+
+ //绑定数据
+ val clickedLatLng = marker?.position!!
+ for (well in wellModels) {
+ if (clickedLatLng.latitude == well.latGaode!!.toDouble()
+ && clickedLatLng.longitude == well.lngGaode!!.toDouble()
+ ) {
+ wellTypeView.text = String.format("井类型: ${well.wellType.toTypeName()}")
+ wellCodeView.text = String.format("井编号: ${well.wellCode}")
+ ownerShipView.text = String.format("权属单位: ${well.deptid.toDeptName()}")
+ locationView.text = String.format("详细位置: ${well.position}")
+ return infoWindow
+ }
+ }
+ "无法查看聚合点,请放大比例后再查看".show()
+ return null
+ }
+
+ /**
+ * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框
+ * */
+ override fun getInfoContents(p0: Marker?): View? = null
+
+ override fun onInfoWindowClick(p0: Marker?) {
+ if (p0 != null) {
+ AlertControlDialog.Builder()
+ .setContext(requireContext())
+ .setTitle("操作提示")
+ .setMessage("确定要前往吗")
+ .setNegativeButton("取消")
+ .setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ val latLng = p0.position
+ val lat = latLng.latitude.toString()
+ val lng = latLng.longitude.toString()
+ if (lat.isBlank() || lng.isBlank()) {
+ "窨井经纬度异常,无法开启导航".show()
+ return
+ }
+ Poi(p0.snippet, LatLng(lat.toDouble(), lng.toDouble()), "").showRouteOnMap(
+ requireContext()
+ )
+ }
+
+ override fun onCancelClick() {
+
+ }
+ }).build().show()
+ }
+ }
+
+ /***以下是地图生命周期管理************************************************************************/
+ override fun onResume() {
+ super.onResume()
+ homeView.mapView.onResume()
+ //每次页面切换都需要重新刷新不同状态的窨井数量
+// wellViewModel.countWellByState()
+// workOrderViewModel.countWorkOrderByState()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ homeView.mapView.onPause()
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ homeView.mapView.onSaveInstanceState(outState)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ homeView.mapView.onDestroy()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
new file mode 100644
index 0000000..4e916a9
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
@@ -0,0 +1,271 @@
+package com.casic.app.smartwell.sanxi.model;
+
+import java.util.List;
+
+public class WellListModel {
+
+ private int code;
+ private List data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public List getData() {
+ return data;
+ }
+
+ public void setData(List data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataDTO {
+ private String area;
+ private String bfzt;
+ private String bfztName;
+ private String coordinateX;
+ private String coordinateY;
+ private String deep;
+ private String deptName;
+ private String deptid;
+ private String id;
+ private String latBaidu;
+ private String latGaode;
+ private String lngBaidu;
+ private String lngGaode;
+ private String notes;
+ private String photos;
+ private String position;
+ private String staff;
+ private String tel;
+ private String ts;
+ private String valid;
+ private String watchData;
+ private String wellCode;
+ private String wellName;
+ private String wellType;
+ private String wellTypeName;
+
+ public String getArea() {
+ return area;
+ }
+
+ public void setArea(String area) {
+ this.area = area;
+ }
+
+ public String getBfzt() {
+ return bfzt;
+ }
+
+ public void setBfzt(String bfzt) {
+ this.bfzt = bfzt;
+ }
+
+ public String getBfztName() {
+ return bfztName;
+ }
+
+ public void setBfztName(String bfztName) {
+ this.bfztName = bfztName;
+ }
+
+ public String getCoordinateX() {
+ return coordinateX;
+ }
+
+ public void setCoordinateX(String coordinateX) {
+ this.coordinateX = coordinateX;
+ }
+
+ public String getCoordinateY() {
+ return coordinateY;
+ }
+
+ public void setCoordinateY(String coordinateY) {
+ this.coordinateY = coordinateY;
+ }
+
+ public String getDeep() {
+ return deep;
+ }
+
+ public void setDeep(String deep) {
+ this.deep = deep;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptid() {
+ return deptid;
+ }
+
+ public void setDeptid(String deptid) {
+ this.deptid = deptid;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getLatBaidu() {
+ return latBaidu;
+ }
+
+ public void setLatBaidu(String latBaidu) {
+ this.latBaidu = latBaidu;
+ }
+
+ public String getLatGaode() {
+ return latGaode;
+ }
+
+ public void setLatGaode(String latGaode) {
+ this.latGaode = latGaode;
+ }
+
+ public String getLngBaidu() {
+ return lngBaidu;
+ }
+
+ public void setLngBaidu(String lngBaidu) {
+ this.lngBaidu = lngBaidu;
+ }
+
+ public String getLngGaode() {
+ return lngGaode;
+ }
+
+ public void setLngGaode(String lngGaode) {
+ this.lngGaode = lngGaode;
+ }
+
+ public String getNotes() {
+ return notes;
+ }
+
+ public void setNotes(String notes) {
+ this.notes = notes;
+ }
+
+ public String getPhotos() {
+ return photos;
+ }
+
+ public void setPhotos(String photos) {
+ this.photos = photos;
+ }
+
+ public String getPosition() {
+ return position;
+ }
+
+ public void setPosition(String position) {
+ this.position = position;
+ }
+
+ public String getStaff() {
+ return staff;
+ }
+
+ public void setStaff(String staff) {
+ this.staff = staff;
+ }
+
+ public String getTel() {
+ return tel;
+ }
+
+ public void setTel(String tel) {
+ this.tel = tel;
+ }
+
+ public String getTs() {
+ return ts;
+ }
+
+ public void setTs(String ts) {
+ this.ts = ts;
+ }
+
+ public String getValid() {
+ return valid;
+ }
+
+ public void setValid(String valid) {
+ this.valid = valid;
+ }
+
+ public String getWatchData() {
+ return watchData;
+ }
+
+ public void setWatchData(String watchData) {
+ this.watchData = watchData;
+ }
+
+ public String getWellCode() {
+ return wellCode;
+ }
+
+ public void setWellCode(String wellCode) {
+ this.wellCode = wellCode;
+ }
+
+ public String getWellName() {
+ return wellName;
+ }
+
+ public void setWellName(String wellName) {
+ this.wellName = wellName;
+ }
+
+ public String getWellType() {
+ return wellType;
+ }
+
+ public void setWellType(String wellType) {
+ this.wellType = wellType;
+ }
+
+ public String getWellTypeName() {
+ return wellTypeName;
+ }
+
+ public void setWellTypeName(String wellTypeName) {
+ this.wellTypeName = wellTypeName;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
index 0fb598b..d57d378 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
@@ -1,6 +1,7 @@
package com.casic.app.smartwell.sanxi.utils
import android.Manifest
+import com.casic.app.smartwell.sanxi.R
object Constant {
@@ -19,7 +20,6 @@
const val USER_DEVICE_TYPE = "userDeviceType"
const val ACCOUNT = "account"
const val PASSWORD = "password"
- const val ALARM_TYPE = "alarmType"
const val APP_AUTHORITY = "com.casic.app.smartwell.sanxi.fileprovider"
const val CANCEL_ALARM_ACTION = "cancelAlarm"
@@ -29,11 +29,11 @@
const val RADIUS_SIZE = 100 //相距多少米才聚合,单位:米
const val DISTANCE = 5 //两点间距离阈值,单位:米
+ val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
+ val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
+
// val HOME_ICONS = arrayOf(R.drawable.ic_well, R.drawable.ic_overtime, R.drawable.ic_bfcf)
val HOME_ITEMS = arrayOf("闸井管理", "超时工单", "布防撤防")
val SUB_PAGE_TITLES = arrayOf("待处理", "待确认", "处理中", "已完成")
val OVER_TIME_PAGE_TITLES = arrayOf("超时未接单", "超时未处理")
-
- // val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
- val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
index 2bb0294..3c6fea3 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
@@ -153,6 +153,12 @@
): String
/**
+ * 获取获取闸井列表-不分页,地图用
+ */
+ @GET("/overview/wellList")
+ suspend fun obtainAllWell(@Header("token") token: String): String
+
+ /**
* 根据布防状态统计闸井数量接口
*/
@GET("/well/countByBfzt")
@@ -192,12 +198,6 @@
): String
/**
- * 获取获取闸井列表-不分页,地图用
- */
- @GET("/well/list")
- suspend fun obtainAllWell(@Header("token") token: String): String
-
- /**
* 获取井下监控设备列表
*
* @param id 窨井ID
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
index 35af71d..f67ccb6 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
@@ -151,6 +151,13 @@
return api.obtainOrderStatus(AuthenticationHelper.token!!)
}
+ /**
+ * 获取获取闸井列表-不分页
+ */
+ suspend fun obtainAllWell(): String {
+ return api.obtainAllWell(AuthenticationHelper.token!!)
+ }
+
// /**
// * 根据布防状态统计闸井数量接口
// */
@@ -190,13 +197,6 @@
// }
//
// /**
-// * 获取获取闸井列表-不分页
-// */
-// suspend fun obtainAllWell(): String {
-// return api.obtainAllWell(AuthenticationHelper.token!!)
-// }
-//
-// /**
// * 获取井下监控设备列表
// */
// suspend fun obtainMonitorResult(id: String): String {
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
index 87dd8dc..6a80a92 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
@@ -7,6 +7,7 @@
import com.casic.app.smartwell.sanxi.extensions.show
import com.casic.app.smartwell.sanxi.extensions.toErrorMessage
import com.casic.app.smartwell.sanxi.model.WellDetailModel
+import com.casic.app.smartwell.sanxi.model.WellListModel
import com.casic.app.smartwell.sanxi.utils.LoadState
import com.casic.app.smartwell.sanxi.utils.retrofit.RetrofitServiceManager
import com.google.gson.Gson
@@ -16,6 +17,7 @@
private val gson = Gson()
val detailModel = MutableLiveData()
+ val allWellModel = MutableLiveData()
fun obtainWellDetail(id: String) = launch({
loadState.value = LoadState.Loading
@@ -34,4 +36,18 @@
loadState.value = LoadState.Fail
it.printStackTrace()
})
+
+ fun obtainAllWell() = launch({
+ val response = RetrofitServiceManager.obtainAllWell()
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ allWellModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ response.toErrorMessage().show()
+ }
+ }, {
+ it.printStackTrace()
+ })
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt
new file mode 100644
index 0000000..4fd4702
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt
@@ -0,0 +1,77 @@
+package com.casic.app.smartwell.sanxi.widgets
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.*
+import com.casic.app.smartwell.sanxi.R
+import com.pengxh.app.multilib.utils.SizeUtil
+
+/**
+ * @description: 顶部下拉菜单
+ * @author: Pengxh
+ * @email: 290677893@qq.com
+ * @date: 2019/12/28 20:35
+ */
+class EasyPopupWindow(private val context: Context) : PopupWindow(context) {
+
+ private lateinit var clickListener: OnPopupWindowClickListener
+
+ init {
+ this.width = (SizeUtil.getScreenWidth(context) * 0.3).toInt()
+ this.height = ViewGroup.LayoutParams.WRAP_CONTENT
+ this.isOutsideTouchable = true
+ this.isFocusable = true
+ this.animationStyle = R.style.PopupAnimation
+ this.contentView = LayoutInflater.from(context).inflate(R.layout.popup_option, null, false)
+ }
+
+ fun setupPopupData(imageArray: Array, titleArray: Array) {
+ val popupListView = contentView.findViewById(R.id.popupListView)
+ popupListView.adapter = object : BaseAdapter() {
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+
+ override fun getCount(): Int = imageArray.size
+
+ override fun getItem(position: Int): Any = imageArray[position]
+
+ override fun getItemId(position: Int): Long = position.toLong()
+
+ override fun getView(position: Int, convertView: View?, viewGroup: ViewGroup): View {
+ val view: View
+ val holder: PopupWindowHolder
+ if (convertView == null) {
+ view = inflater.inflate(R.layout.item_map_popup, null)
+ holder = PopupWindowHolder()
+ holder.imageView = view.findViewById(R.id.imageView)
+ holder.titleView = view.findViewById(R.id.titleView)
+ view.tag = holder
+ } else {
+ view = convertView
+ holder = view.tag as PopupWindowHolder
+ }
+ holder.imageView.setBackgroundResource(imageArray[position])
+ holder.titleView.text = titleArray[position]
+ return view
+ }
+ }
+ popupListView.onItemClickListener = AdapterView.OnItemClickListener { _, _, i, _ ->
+ clickListener.onPopupClick(i)
+ dismiss()
+ }
+ }
+
+ interface OnPopupWindowClickListener {
+ fun onPopupClick(position: Int)
+ }
+
+ fun setOnPopupWindowClickListener(windowClickListener: OnPopupWindowClickListener) {
+ this.clickListener = windowClickListener
+ }
+
+ inner class PopupWindowHolder {
+ lateinit var imageView: ImageView
+ lateinit var titleView: TextView
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt
new file mode 100644
index 0000000..28ccff3
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt
@@ -0,0 +1,102 @@
+package com.casic.app.smartwell.sanxi.widgets
+
+import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.Point
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.TextView
+import com.amap.api.maps.Projection
+import com.amap.api.maps.model.BitmapDescriptorFactory
+import com.amap.api.maps.model.LatLng
+import com.amap.api.maps.model.LatLngBounds
+import com.amap.api.maps.model.MarkerOptions
+import com.casic.app.smartwell.sanxi.R
+import com.casic.app.smartwell.sanxi.extensions.toBitmap
+import java.util.*
+
+class GaoDeClusterMarkerView(
+ private val context: Context, firstMarkers: MarkerOptions,
+ projection: Projection, gridSize: Int
+) {
+ //当前可观区域里的 聚合过之后的集合
+ private val includeMarkers: ArrayList
+
+ // 创建区域
+ val bounds: LatLngBounds
+ var options: MarkerOptions = MarkerOptions()
+
+ init {
+ val screenLocation = projection.toScreenLocation(firstMarkers.position)
+ //范围类
+ val southwestPoint = Point(screenLocation.x - gridSize, screenLocation.y + gridSize)
+ //范围类
+ val northeastPoint = Point(screenLocation.x + gridSize, screenLocation.y - gridSize)
+ bounds = LatLngBounds(
+ projection.fromScreenLocation(southwestPoint),
+ projection.fromScreenLocation(northeastPoint)
+ )
+ //设置初始化marker属性
+ options.anchor(0.5f, 1.3f)
+ .title(firstMarkers.title)
+ .position(firstMarkers.position)
+ .icon(firstMarkers.icon)
+ .snippet(firstMarkers.snippet)
+ .draggable(false)
+ includeMarkers = ArrayList()
+ includeMarkers.add(firstMarkers)
+ }
+
+ /**
+ * 添加marker
+ */
+ fun addMarker(markerOptions: MarkerOptions) {
+ includeMarkers.add(markerOptions) // 添加到列表中
+ }
+
+ /**
+ * 设置聚合点的中心位置以及图标
+ */
+ fun setPositionAndIcon() {
+ val size = includeMarkers.size
+ var lat = 0.0
+ var lng = 0.0
+ // 一个的时候
+ if (size == 1) { //设置marker单个属性
+ // 设置marker位置
+ options.position(
+ LatLng(
+ includeMarkers[0].position.latitude,
+ includeMarkers[0].position.longitude
+ )
+ )
+ } else { // 聚合的时候
+ //设置marker聚合属性
+ for (op in includeMarkers) {
+ lat += op.position.latitude
+ lng += op.position.longitude
+ }
+ // 设置marker的位置为中心位置为聚集点的平均位置
+ options.position(LatLng(lat / size, lng / size))
+ }
+ options.icon(BitmapDescriptorFactory.fromBitmap(getBitmap(size)))
+ }
+
+ /**
+ * marker视图
+ */
+ private fun getBitmap(num: Int): Bitmap? {
+ val view = LayoutInflater.from(context).inflate(R.layout.marker_gaode, null)
+ val wellCountView = view.findViewById(R.id.wellCountView)
+ return if (num > 1) {
+ wellCountView.visibility = View.VISIBLE
+ wellCountView.text = String.format("${num}个")
+ wellCountView.gravity = Gravity.CENTER
+ view.toBitmap()
+ } else {
+ wellCountView.visibility = View.GONE
+ BitmapDescriptorFactory.fromResource(R.mipmap.well_location).bitmap
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_black_transparent_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_black_transparent_radius_10.xml
new file mode 100644
index 0000000..15e6a4b
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_black_transparent_radius_10.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_main_color.xml b/app/src/main/res/drawable/bg_solid_layout_main_color.xml
new file mode 100644
index 0000000..e329b7d
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_main_color.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_radius_20.xml b/app/src/main/res/drawable/bg_solid_layout_radius_20.xml
new file mode 100644
index 0000000..0c2abfe
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_radius_20.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ea56300..0416db4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -49,5 +49,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
index 291a985..c41c867 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
@@ -82,14 +82,40 @@
}
//窨井类型转换
-fun String.toChinese(): String {
+fun String.toTypeName(): String {
return when (this) {
- "0" -> "全部"
- "1" -> "一级"
- "2" -> "二级"
- "3" -> "三级"
+ "1" -> "雨水井"
+ "2" -> "污水井"
+ "3" -> "燃气井"
+ "4" -> "热力井"
+ "5" -> "电力井"
+ "6" -> "交通井"
+ "7" -> "路灯井"
+ "8" -> "通信井"
+ "9" -> "监控井"
else -> {
- "未知"
+ "其他"
+ }
+ }
+}
+
+fun String.toDeptName(): String {
+ return when (this) {
+ "0" -> "顶级"
+ "1148031048115494913" -> "二院"
+ "1178242695136149506" -> "电力公司"
+ "1178242900132757506" -> "滨海热电"
+ "24" -> "燃气集团总公司"
+ "30" -> "203所"
+ "1399230677135265794" -> "厦门测试"
+ "25" -> "第一分公司"
+ "26" -> "第二分公司"
+ "27" -> "第三分公司"
+ "28" -> "第四分公司"
+ "29" -> "高压管网分公司"
+ "1143796514486353922" -> "第五分公司"
+ else -> {
+ "其他"
}
}
}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
index 26f3085..4d0c818 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
@@ -1,24 +1,326 @@
package com.casic.app.smartwell.sanxi.fragment
+import android.graphics.Point
+import android.os.Bundle
+import android.util.Log
+import android.view.LayoutInflater
import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import com.amap.api.maps.AMap
+import com.amap.api.maps.AMapOptions
+import com.amap.api.maps.CameraUpdateFactory
+import com.amap.api.maps.CoordinateConverter
+import com.amap.api.maps.model.*
import com.casic.app.smartwell.sanxi.R
-import com.casic.app.smartwell.sanxi.base.BaseFragment
-import kotlinx.android.synthetic.main.include_base_title.*
+import com.casic.app.smartwell.sanxi.extensions.show
+import com.casic.app.smartwell.sanxi.extensions.showRouteOnMap
+import com.casic.app.smartwell.sanxi.extensions.toDeptName
+import com.casic.app.smartwell.sanxi.extensions.toTypeName
+import com.casic.app.smartwell.sanxi.model.WellListModel
+import com.casic.app.smartwell.sanxi.utils.Constant
+import com.casic.app.smartwell.sanxi.vm.WellViewModel
+import com.casic.app.smartwell.sanxi.widgets.EasyPopupWindow
+import com.casic.app.smartwell.sanxi.widgets.GaoDeClusterMarkerView
+import com.google.android.material.bottomsheet.BottomSheetBehavior
+import com.pengxh.app.multilib.utils.SizeUtil
+import com.pengxh.app.multilib.widget.dialog.AlertControlDialog
+import kotlinx.android.synthetic.main.fragment_home.view.*
-class HomePageFragment : BaseFragment() {
+class HomePageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener,
+ AMap.OnMarkerClickListener, AMap.InfoWindowAdapter, AMap.OnInfoWindowClickListener {
- override fun initLayoutView(): Int = R.layout.fragment_home
+ private val kTag = "HomePageFragment"
+ private lateinit var homeView: View
+ private lateinit var aMap: AMap
+ private lateinit var wellViewModel: WellViewModel
- override fun setupTopBarLayout() {
- leftBackView.visibility = View.GONE
- titleView.text = "首页"
+ /**
+ * 所有窨井列表信息集合
+ * */
+ private var wellModels: MutableList = ArrayList()
+
+ /**
+ * 所有的marker
+ */
+ private var allMarkerOptions: MutableList = ArrayList()
+
+ /**
+ * 视野内的marker
+ */
+ private var markerOptionsInView: MutableList = ArrayList()
+
+ /**
+ * 自定义Marker弹出框
+ * */
+ private var infoWindow: View? = null
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ homeView = inflater.inflate(R.layout.fragment_home, container, false)
+ homeView.titleView.text = "首页"
+ val easyPopupWindow = EasyPopupWindow(requireContext())
+ easyPopupWindow.setupPopupData(Constant.POPUP_IMAGES, Constant.POPUP_TITLES)
+ homeView.rightOptionView.setOnClickListener {
+ easyPopupWindow.setOnPopupWindowClickListener(object :
+ EasyPopupWindow.OnPopupWindowClickListener {
+ override fun onPopupClick(position: Int) {
+ when (position) {
+ 0 -> aMap.mapType = AMap.MAP_TYPE_NORMAL
+ 1 -> aMap.mapType = AMap.MAP_TYPE_SATELLITE
+ }
+ }
+ })
+ easyPopupWindow.setBackgroundDrawable(null)
+ val x: Int = homeView.rightOptionView.width - easyPopupWindow.width
+ easyPopupWindow.showAsDropDown(homeView.rightOptionView, x, 0)
+ }
+
+ //代码设置底部拉升距离
+ val bottomSheetBehavior = BottomSheetBehavior.from(homeView.bottomBehaviorLayout)
+ homeView.coordinatorLayout.post {
+ bottomSheetBehavior.isFitToContents = false
+ bottomSheetBehavior.halfExpandedRatio = 0.3f
+ bottomSheetBehavior.isHideable = false
+ bottomSheetBehavior.peekHeight = SizeUtil.dp2px(requireContext(), 30f)
+ }
+
+ //初始化vm
+ wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java)
+
+ //获取所有窨井数据
+ wellViewModel.obtainAllWell()
+ wellViewModel.allWellModel.observe(viewLifecycleOwner, {
+ if (it.code == 200) {
+ val latitudeList: MutableList = ArrayList()
+ val longitudeList: MutableList = ArrayList()
+ it.data?.forEach { well ->
+ val lat = well.latGaode.toString()
+ val lng = well.lngGaode.toString()
+ if (lat.isNotBlank() && lng.isNotBlank()) {
+ //返回true代表当前位置在大陆、港澳地区,反之不在
+ val latitude = lat.toDouble()
+ val longitude = lng.toDouble()
+ if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) {
+ //缓存所有设备详情,点击Marker时候需要
+ wellModels.add(well)
+ //分别缓存经、纬度
+ latitudeList.add(latitude)
+ longitudeList.add(longitude)
+ //将所有设备信息转化缓存为Marker点
+ allMarkerOptions.add(
+ MarkerOptions()
+ .position(LatLng(latitude, longitude))
+ .title(well.wellTypeName)
+ .snippet(well.wellName)
+ )
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度不在国内,异常经纬度 ===> [${lng},${lat}]")
+ }
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度异常,异常经纬度 ===> [${lng},${lat}]")
+ }
+ }
+ //计算所有点的中心点位置
+ val centerLatLng = LatLng(latitudeList.average(), longitudeList.average())
+ Log.d(
+ kTag,
+ "所有闸井中心点位置 ===> [${latitudeList.average()}, ${longitudeList.average()}]"
+ )
+ //移动到指定经纬度
+ val cameraPosition = CameraPosition(centerLatLng, 13f, 0f, 0f)
+ val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition)
+ aMap.animateCamera(cameraUpdate, 3000, null)
+ }
+ })
+
+ //地图初始化
+ initMap(savedInstanceState)
+ return homeView
}
- override fun initData() {
+ private fun initMap(savedInstanceState: Bundle?) {
+ homeView.mapView.onCreate(savedInstanceState)
+ aMap = homeView.mapView.map
+ aMap.mapType = AMap.MAP_TYPE_NORMAL
+ val uiSettings = aMap.uiSettings
+ uiSettings.isCompassEnabled = true
+ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER
+ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度
+ uiSettings.isRotateGesturesEnabled = false//不允许地图旋转
+
+ // 地图加载成功监听
+ aMap.addOnMapLoadedListener(this)
+ // 地图缩放监听
+ aMap.addOnCameraChangeListener(this)
+ // marker 点击事件监听
+ aMap.addOnMarkerClickListener(this)
+ // 点击marker弹出自定义popup
+ aMap.setInfoWindowAdapter(this)
+ //信息窗点击事件
+ aMap.addOnInfoWindowClickListener(this)
+ }
+
+ override fun onMapLoaded() {
+ //地图加载成功之后显示聚合点数据
+ initClustersMarkers()
+ }
+
+ override fun onCameraChange(p0: CameraPosition?) {
}
- override fun initEvent() {
+ //获取视野内的marker 根据聚合算法合成自定义的marker 显示视野内的marker
+ override fun onCameraChangeFinish(p0: CameraPosition?) {
+ //地图缩放之后显示聚合点数据
+ initClustersMarkers()
+ }
+ private fun initClustersMarkers() {
+ val proj = aMap.projection
+ val dm = resources.displayMetrics
+ var screenLocation: Point
+ markerOptionsInView.clear()
+ // 获取在当前视野内的marker
+ allMarkerOptions.forEach {
+ screenLocation = proj.toScreenLocation(it.position)
+ if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) {
+ //在当前可观区域内
+ markerOptionsInView.add(it)
+ }
+ }
+ // 自定义的聚合类MarkerCluster
+ val clustersMarkers: MutableList = ArrayList()
+ markerOptionsInView.forEach {
+ if (clustersMarkers.size == 0) {
+ //添加一个新的自定义marker
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )
+ } else {
+ var isInRange = false
+ //Kotlin foreach不能用break
+ for (view in clustersMarkers) {
+ //判断当前的marker是否在前面marker的聚合范围内 并且每个marker只会聚合一次。
+ if (view.bounds.contains(it.position)) {
+ view.addMarker(it)
+ isInRange = true
+ break
+ }
+ }
+ //如果没在任何范围内,自己单独形成一个自定义marker。在和后面的marker进行比较
+ if (!isInRange) {
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )//相距多少才聚合
+ }
+ }
+ }
+ // 设置聚合点的位置和icon
+ clustersMarkers.forEach {
+ it.setPositionAndIcon()
+ }
+ aMap.clear()
+ // 重新添加 marker
+ clustersMarkers.forEach {
+ aMap.addMarker(it.options)
+ }
+ }
+
+ override fun onMarkerClick(marker: Marker?): Boolean {
+ //显示闸井信息
+ marker?.showInfoWindow()
+ return true
+ }
+
+ override fun getInfoWindow(marker: Marker?): View? {
+ if (infoWindow == null) {
+ infoWindow = LayoutInflater.from(requireContext()).inflate(R.layout.popu_map_info, null)
+ }
+ val v = infoWindow!!
+ //反射得到popup里面的控件对象
+ val wellTypeView = v.findViewById(R.id.wellTypeView)
+ val wellCodeView = v.findViewById(R.id.wellCodeView)
+ val ownerShipView = v.findViewById(R.id.ownerShipView)
+ val locationView = v.findViewById(R.id.locationView)
+
+ //绑定数据
+ val clickedLatLng = marker?.position!!
+ for (well in wellModels) {
+ if (clickedLatLng.latitude == well.latGaode!!.toDouble()
+ && clickedLatLng.longitude == well.lngGaode!!.toDouble()
+ ) {
+ wellTypeView.text = String.format("井类型: ${well.wellType.toTypeName()}")
+ wellCodeView.text = String.format("井编号: ${well.wellCode}")
+ ownerShipView.text = String.format("权属单位: ${well.deptid.toDeptName()}")
+ locationView.text = String.format("详细位置: ${well.position}")
+ return infoWindow
+ }
+ }
+ "无法查看聚合点,请放大比例后再查看".show()
+ return null
+ }
+
+ /**
+ * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框
+ * */
+ override fun getInfoContents(p0: Marker?): View? = null
+
+ override fun onInfoWindowClick(p0: Marker?) {
+ if (p0 != null) {
+ AlertControlDialog.Builder()
+ .setContext(requireContext())
+ .setTitle("操作提示")
+ .setMessage("确定要前往吗")
+ .setNegativeButton("取消")
+ .setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ val latLng = p0.position
+ val lat = latLng.latitude.toString()
+ val lng = latLng.longitude.toString()
+ if (lat.isBlank() || lng.isBlank()) {
+ "窨井经纬度异常,无法开启导航".show()
+ return
+ }
+ Poi(p0.snippet, LatLng(lat.toDouble(), lng.toDouble()), "").showRouteOnMap(
+ requireContext()
+ )
+ }
+
+ override fun onCancelClick() {
+
+ }
+ }).build().show()
+ }
+ }
+
+ /***以下是地图生命周期管理************************************************************************/
+ override fun onResume() {
+ super.onResume()
+ homeView.mapView.onResume()
+ //每次页面切换都需要重新刷新不同状态的窨井数量
+// wellViewModel.countWellByState()
+// workOrderViewModel.countWorkOrderByState()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ homeView.mapView.onPause()
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ homeView.mapView.onSaveInstanceState(outState)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ homeView.mapView.onDestroy()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
new file mode 100644
index 0000000..4e916a9
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
@@ -0,0 +1,271 @@
+package com.casic.app.smartwell.sanxi.model;
+
+import java.util.List;
+
+public class WellListModel {
+
+ private int code;
+ private List data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public List getData() {
+ return data;
+ }
+
+ public void setData(List data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataDTO {
+ private String area;
+ private String bfzt;
+ private String bfztName;
+ private String coordinateX;
+ private String coordinateY;
+ private String deep;
+ private String deptName;
+ private String deptid;
+ private String id;
+ private String latBaidu;
+ private String latGaode;
+ private String lngBaidu;
+ private String lngGaode;
+ private String notes;
+ private String photos;
+ private String position;
+ private String staff;
+ private String tel;
+ private String ts;
+ private String valid;
+ private String watchData;
+ private String wellCode;
+ private String wellName;
+ private String wellType;
+ private String wellTypeName;
+
+ public String getArea() {
+ return area;
+ }
+
+ public void setArea(String area) {
+ this.area = area;
+ }
+
+ public String getBfzt() {
+ return bfzt;
+ }
+
+ public void setBfzt(String bfzt) {
+ this.bfzt = bfzt;
+ }
+
+ public String getBfztName() {
+ return bfztName;
+ }
+
+ public void setBfztName(String bfztName) {
+ this.bfztName = bfztName;
+ }
+
+ public String getCoordinateX() {
+ return coordinateX;
+ }
+
+ public void setCoordinateX(String coordinateX) {
+ this.coordinateX = coordinateX;
+ }
+
+ public String getCoordinateY() {
+ return coordinateY;
+ }
+
+ public void setCoordinateY(String coordinateY) {
+ this.coordinateY = coordinateY;
+ }
+
+ public String getDeep() {
+ return deep;
+ }
+
+ public void setDeep(String deep) {
+ this.deep = deep;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptid() {
+ return deptid;
+ }
+
+ public void setDeptid(String deptid) {
+ this.deptid = deptid;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getLatBaidu() {
+ return latBaidu;
+ }
+
+ public void setLatBaidu(String latBaidu) {
+ this.latBaidu = latBaidu;
+ }
+
+ public String getLatGaode() {
+ return latGaode;
+ }
+
+ public void setLatGaode(String latGaode) {
+ this.latGaode = latGaode;
+ }
+
+ public String getLngBaidu() {
+ return lngBaidu;
+ }
+
+ public void setLngBaidu(String lngBaidu) {
+ this.lngBaidu = lngBaidu;
+ }
+
+ public String getLngGaode() {
+ return lngGaode;
+ }
+
+ public void setLngGaode(String lngGaode) {
+ this.lngGaode = lngGaode;
+ }
+
+ public String getNotes() {
+ return notes;
+ }
+
+ public void setNotes(String notes) {
+ this.notes = notes;
+ }
+
+ public String getPhotos() {
+ return photos;
+ }
+
+ public void setPhotos(String photos) {
+ this.photos = photos;
+ }
+
+ public String getPosition() {
+ return position;
+ }
+
+ public void setPosition(String position) {
+ this.position = position;
+ }
+
+ public String getStaff() {
+ return staff;
+ }
+
+ public void setStaff(String staff) {
+ this.staff = staff;
+ }
+
+ public String getTel() {
+ return tel;
+ }
+
+ public void setTel(String tel) {
+ this.tel = tel;
+ }
+
+ public String getTs() {
+ return ts;
+ }
+
+ public void setTs(String ts) {
+ this.ts = ts;
+ }
+
+ public String getValid() {
+ return valid;
+ }
+
+ public void setValid(String valid) {
+ this.valid = valid;
+ }
+
+ public String getWatchData() {
+ return watchData;
+ }
+
+ public void setWatchData(String watchData) {
+ this.watchData = watchData;
+ }
+
+ public String getWellCode() {
+ return wellCode;
+ }
+
+ public void setWellCode(String wellCode) {
+ this.wellCode = wellCode;
+ }
+
+ public String getWellName() {
+ return wellName;
+ }
+
+ public void setWellName(String wellName) {
+ this.wellName = wellName;
+ }
+
+ public String getWellType() {
+ return wellType;
+ }
+
+ public void setWellType(String wellType) {
+ this.wellType = wellType;
+ }
+
+ public String getWellTypeName() {
+ return wellTypeName;
+ }
+
+ public void setWellTypeName(String wellTypeName) {
+ this.wellTypeName = wellTypeName;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
index 0fb598b..d57d378 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
@@ -1,6 +1,7 @@
package com.casic.app.smartwell.sanxi.utils
import android.Manifest
+import com.casic.app.smartwell.sanxi.R
object Constant {
@@ -19,7 +20,6 @@
const val USER_DEVICE_TYPE = "userDeviceType"
const val ACCOUNT = "account"
const val PASSWORD = "password"
- const val ALARM_TYPE = "alarmType"
const val APP_AUTHORITY = "com.casic.app.smartwell.sanxi.fileprovider"
const val CANCEL_ALARM_ACTION = "cancelAlarm"
@@ -29,11 +29,11 @@
const val RADIUS_SIZE = 100 //相距多少米才聚合,单位:米
const val DISTANCE = 5 //两点间距离阈值,单位:米
+ val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
+ val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
+
// val HOME_ICONS = arrayOf(R.drawable.ic_well, R.drawable.ic_overtime, R.drawable.ic_bfcf)
val HOME_ITEMS = arrayOf("闸井管理", "超时工单", "布防撤防")
val SUB_PAGE_TITLES = arrayOf("待处理", "待确认", "处理中", "已完成")
val OVER_TIME_PAGE_TITLES = arrayOf("超时未接单", "超时未处理")
-
- // val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
- val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
index 2bb0294..3c6fea3 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
@@ -153,6 +153,12 @@
): String
/**
+ * 获取获取闸井列表-不分页,地图用
+ */
+ @GET("/overview/wellList")
+ suspend fun obtainAllWell(@Header("token") token: String): String
+
+ /**
* 根据布防状态统计闸井数量接口
*/
@GET("/well/countByBfzt")
@@ -192,12 +198,6 @@
): String
/**
- * 获取获取闸井列表-不分页,地图用
- */
- @GET("/well/list")
- suspend fun obtainAllWell(@Header("token") token: String): String
-
- /**
* 获取井下监控设备列表
*
* @param id 窨井ID
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
index 35af71d..f67ccb6 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
@@ -151,6 +151,13 @@
return api.obtainOrderStatus(AuthenticationHelper.token!!)
}
+ /**
+ * 获取获取闸井列表-不分页
+ */
+ suspend fun obtainAllWell(): String {
+ return api.obtainAllWell(AuthenticationHelper.token!!)
+ }
+
// /**
// * 根据布防状态统计闸井数量接口
// */
@@ -190,13 +197,6 @@
// }
//
// /**
-// * 获取获取闸井列表-不分页
-// */
-// suspend fun obtainAllWell(): String {
-// return api.obtainAllWell(AuthenticationHelper.token!!)
-// }
-//
-// /**
// * 获取井下监控设备列表
// */
// suspend fun obtainMonitorResult(id: String): String {
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
index 87dd8dc..6a80a92 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
@@ -7,6 +7,7 @@
import com.casic.app.smartwell.sanxi.extensions.show
import com.casic.app.smartwell.sanxi.extensions.toErrorMessage
import com.casic.app.smartwell.sanxi.model.WellDetailModel
+import com.casic.app.smartwell.sanxi.model.WellListModel
import com.casic.app.smartwell.sanxi.utils.LoadState
import com.casic.app.smartwell.sanxi.utils.retrofit.RetrofitServiceManager
import com.google.gson.Gson
@@ -16,6 +17,7 @@
private val gson = Gson()
val detailModel = MutableLiveData()
+ val allWellModel = MutableLiveData()
fun obtainWellDetail(id: String) = launch({
loadState.value = LoadState.Loading
@@ -34,4 +36,18 @@
loadState.value = LoadState.Fail
it.printStackTrace()
})
+
+ fun obtainAllWell() = launch({
+ val response = RetrofitServiceManager.obtainAllWell()
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ allWellModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ response.toErrorMessage().show()
+ }
+ }, {
+ it.printStackTrace()
+ })
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt
new file mode 100644
index 0000000..4fd4702
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt
@@ -0,0 +1,77 @@
+package com.casic.app.smartwell.sanxi.widgets
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.*
+import com.casic.app.smartwell.sanxi.R
+import com.pengxh.app.multilib.utils.SizeUtil
+
+/**
+ * @description: 顶部下拉菜单
+ * @author: Pengxh
+ * @email: 290677893@qq.com
+ * @date: 2019/12/28 20:35
+ */
+class EasyPopupWindow(private val context: Context) : PopupWindow(context) {
+
+ private lateinit var clickListener: OnPopupWindowClickListener
+
+ init {
+ this.width = (SizeUtil.getScreenWidth(context) * 0.3).toInt()
+ this.height = ViewGroup.LayoutParams.WRAP_CONTENT
+ this.isOutsideTouchable = true
+ this.isFocusable = true
+ this.animationStyle = R.style.PopupAnimation
+ this.contentView = LayoutInflater.from(context).inflate(R.layout.popup_option, null, false)
+ }
+
+ fun setupPopupData(imageArray: Array, titleArray: Array) {
+ val popupListView = contentView.findViewById(R.id.popupListView)
+ popupListView.adapter = object : BaseAdapter() {
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+
+ override fun getCount(): Int = imageArray.size
+
+ override fun getItem(position: Int): Any = imageArray[position]
+
+ override fun getItemId(position: Int): Long = position.toLong()
+
+ override fun getView(position: Int, convertView: View?, viewGroup: ViewGroup): View {
+ val view: View
+ val holder: PopupWindowHolder
+ if (convertView == null) {
+ view = inflater.inflate(R.layout.item_map_popup, null)
+ holder = PopupWindowHolder()
+ holder.imageView = view.findViewById(R.id.imageView)
+ holder.titleView = view.findViewById(R.id.titleView)
+ view.tag = holder
+ } else {
+ view = convertView
+ holder = view.tag as PopupWindowHolder
+ }
+ holder.imageView.setBackgroundResource(imageArray[position])
+ holder.titleView.text = titleArray[position]
+ return view
+ }
+ }
+ popupListView.onItemClickListener = AdapterView.OnItemClickListener { _, _, i, _ ->
+ clickListener.onPopupClick(i)
+ dismiss()
+ }
+ }
+
+ interface OnPopupWindowClickListener {
+ fun onPopupClick(position: Int)
+ }
+
+ fun setOnPopupWindowClickListener(windowClickListener: OnPopupWindowClickListener) {
+ this.clickListener = windowClickListener
+ }
+
+ inner class PopupWindowHolder {
+ lateinit var imageView: ImageView
+ lateinit var titleView: TextView
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt
new file mode 100644
index 0000000..28ccff3
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt
@@ -0,0 +1,102 @@
+package com.casic.app.smartwell.sanxi.widgets
+
+import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.Point
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.TextView
+import com.amap.api.maps.Projection
+import com.amap.api.maps.model.BitmapDescriptorFactory
+import com.amap.api.maps.model.LatLng
+import com.amap.api.maps.model.LatLngBounds
+import com.amap.api.maps.model.MarkerOptions
+import com.casic.app.smartwell.sanxi.R
+import com.casic.app.smartwell.sanxi.extensions.toBitmap
+import java.util.*
+
+class GaoDeClusterMarkerView(
+ private val context: Context, firstMarkers: MarkerOptions,
+ projection: Projection, gridSize: Int
+) {
+ //当前可观区域里的 聚合过之后的集合
+ private val includeMarkers: ArrayList
+
+ // 创建区域
+ val bounds: LatLngBounds
+ var options: MarkerOptions = MarkerOptions()
+
+ init {
+ val screenLocation = projection.toScreenLocation(firstMarkers.position)
+ //范围类
+ val southwestPoint = Point(screenLocation.x - gridSize, screenLocation.y + gridSize)
+ //范围类
+ val northeastPoint = Point(screenLocation.x + gridSize, screenLocation.y - gridSize)
+ bounds = LatLngBounds(
+ projection.fromScreenLocation(southwestPoint),
+ projection.fromScreenLocation(northeastPoint)
+ )
+ //设置初始化marker属性
+ options.anchor(0.5f, 1.3f)
+ .title(firstMarkers.title)
+ .position(firstMarkers.position)
+ .icon(firstMarkers.icon)
+ .snippet(firstMarkers.snippet)
+ .draggable(false)
+ includeMarkers = ArrayList()
+ includeMarkers.add(firstMarkers)
+ }
+
+ /**
+ * 添加marker
+ */
+ fun addMarker(markerOptions: MarkerOptions) {
+ includeMarkers.add(markerOptions) // 添加到列表中
+ }
+
+ /**
+ * 设置聚合点的中心位置以及图标
+ */
+ fun setPositionAndIcon() {
+ val size = includeMarkers.size
+ var lat = 0.0
+ var lng = 0.0
+ // 一个的时候
+ if (size == 1) { //设置marker单个属性
+ // 设置marker位置
+ options.position(
+ LatLng(
+ includeMarkers[0].position.latitude,
+ includeMarkers[0].position.longitude
+ )
+ )
+ } else { // 聚合的时候
+ //设置marker聚合属性
+ for (op in includeMarkers) {
+ lat += op.position.latitude
+ lng += op.position.longitude
+ }
+ // 设置marker的位置为中心位置为聚集点的平均位置
+ options.position(LatLng(lat / size, lng / size))
+ }
+ options.icon(BitmapDescriptorFactory.fromBitmap(getBitmap(size)))
+ }
+
+ /**
+ * marker视图
+ */
+ private fun getBitmap(num: Int): Bitmap? {
+ val view = LayoutInflater.from(context).inflate(R.layout.marker_gaode, null)
+ val wellCountView = view.findViewById(R.id.wellCountView)
+ return if (num > 1) {
+ wellCountView.visibility = View.VISIBLE
+ wellCountView.text = String.format("${num}个")
+ wellCountView.gravity = Gravity.CENTER
+ view.toBitmap()
+ } else {
+ wellCountView.visibility = View.GONE
+ BitmapDescriptorFactory.fromResource(R.mipmap.well_location).bitmap
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_black_transparent_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_black_transparent_radius_10.xml
new file mode 100644
index 0000000..15e6a4b
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_black_transparent_radius_10.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_main_color.xml b/app/src/main/res/drawable/bg_solid_layout_main_color.xml
new file mode 100644
index 0000000..e329b7d
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_main_color.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_radius_20.xml b/app/src/main/res/drawable/bg_solid_layout_radius_20.xml
new file mode 100644
index 0000000..0c2abfe
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_radius_20.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bottom_short_line.xml b/app/src/main/res/drawable/bottom_short_line.xml
new file mode 100644
index 0000000..10c9062
--- /dev/null
+++ b/app/src/main/res/drawable/bottom_short_line.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ea56300..0416db4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -49,5 +49,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
index 291a985..c41c867 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
@@ -82,14 +82,40 @@
}
//窨井类型转换
-fun String.toChinese(): String {
+fun String.toTypeName(): String {
return when (this) {
- "0" -> "全部"
- "1" -> "一级"
- "2" -> "二级"
- "3" -> "三级"
+ "1" -> "雨水井"
+ "2" -> "污水井"
+ "3" -> "燃气井"
+ "4" -> "热力井"
+ "5" -> "电力井"
+ "6" -> "交通井"
+ "7" -> "路灯井"
+ "8" -> "通信井"
+ "9" -> "监控井"
else -> {
- "未知"
+ "其他"
+ }
+ }
+}
+
+fun String.toDeptName(): String {
+ return when (this) {
+ "0" -> "顶级"
+ "1148031048115494913" -> "二院"
+ "1178242695136149506" -> "电力公司"
+ "1178242900132757506" -> "滨海热电"
+ "24" -> "燃气集团总公司"
+ "30" -> "203所"
+ "1399230677135265794" -> "厦门测试"
+ "25" -> "第一分公司"
+ "26" -> "第二分公司"
+ "27" -> "第三分公司"
+ "28" -> "第四分公司"
+ "29" -> "高压管网分公司"
+ "1143796514486353922" -> "第五分公司"
+ else -> {
+ "其他"
}
}
}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
index 26f3085..4d0c818 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
@@ -1,24 +1,326 @@
package com.casic.app.smartwell.sanxi.fragment
+import android.graphics.Point
+import android.os.Bundle
+import android.util.Log
+import android.view.LayoutInflater
import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import com.amap.api.maps.AMap
+import com.amap.api.maps.AMapOptions
+import com.amap.api.maps.CameraUpdateFactory
+import com.amap.api.maps.CoordinateConverter
+import com.amap.api.maps.model.*
import com.casic.app.smartwell.sanxi.R
-import com.casic.app.smartwell.sanxi.base.BaseFragment
-import kotlinx.android.synthetic.main.include_base_title.*
+import com.casic.app.smartwell.sanxi.extensions.show
+import com.casic.app.smartwell.sanxi.extensions.showRouteOnMap
+import com.casic.app.smartwell.sanxi.extensions.toDeptName
+import com.casic.app.smartwell.sanxi.extensions.toTypeName
+import com.casic.app.smartwell.sanxi.model.WellListModel
+import com.casic.app.smartwell.sanxi.utils.Constant
+import com.casic.app.smartwell.sanxi.vm.WellViewModel
+import com.casic.app.smartwell.sanxi.widgets.EasyPopupWindow
+import com.casic.app.smartwell.sanxi.widgets.GaoDeClusterMarkerView
+import com.google.android.material.bottomsheet.BottomSheetBehavior
+import com.pengxh.app.multilib.utils.SizeUtil
+import com.pengxh.app.multilib.widget.dialog.AlertControlDialog
+import kotlinx.android.synthetic.main.fragment_home.view.*
-class HomePageFragment : BaseFragment() {
+class HomePageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener,
+ AMap.OnMarkerClickListener, AMap.InfoWindowAdapter, AMap.OnInfoWindowClickListener {
- override fun initLayoutView(): Int = R.layout.fragment_home
+ private val kTag = "HomePageFragment"
+ private lateinit var homeView: View
+ private lateinit var aMap: AMap
+ private lateinit var wellViewModel: WellViewModel
- override fun setupTopBarLayout() {
- leftBackView.visibility = View.GONE
- titleView.text = "首页"
+ /**
+ * 所有窨井列表信息集合
+ * */
+ private var wellModels: MutableList = ArrayList()
+
+ /**
+ * 所有的marker
+ */
+ private var allMarkerOptions: MutableList = ArrayList()
+
+ /**
+ * 视野内的marker
+ */
+ private var markerOptionsInView: MutableList = ArrayList()
+
+ /**
+ * 自定义Marker弹出框
+ * */
+ private var infoWindow: View? = null
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ homeView = inflater.inflate(R.layout.fragment_home, container, false)
+ homeView.titleView.text = "首页"
+ val easyPopupWindow = EasyPopupWindow(requireContext())
+ easyPopupWindow.setupPopupData(Constant.POPUP_IMAGES, Constant.POPUP_TITLES)
+ homeView.rightOptionView.setOnClickListener {
+ easyPopupWindow.setOnPopupWindowClickListener(object :
+ EasyPopupWindow.OnPopupWindowClickListener {
+ override fun onPopupClick(position: Int) {
+ when (position) {
+ 0 -> aMap.mapType = AMap.MAP_TYPE_NORMAL
+ 1 -> aMap.mapType = AMap.MAP_TYPE_SATELLITE
+ }
+ }
+ })
+ easyPopupWindow.setBackgroundDrawable(null)
+ val x: Int = homeView.rightOptionView.width - easyPopupWindow.width
+ easyPopupWindow.showAsDropDown(homeView.rightOptionView, x, 0)
+ }
+
+ //代码设置底部拉升距离
+ val bottomSheetBehavior = BottomSheetBehavior.from(homeView.bottomBehaviorLayout)
+ homeView.coordinatorLayout.post {
+ bottomSheetBehavior.isFitToContents = false
+ bottomSheetBehavior.halfExpandedRatio = 0.3f
+ bottomSheetBehavior.isHideable = false
+ bottomSheetBehavior.peekHeight = SizeUtil.dp2px(requireContext(), 30f)
+ }
+
+ //初始化vm
+ wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java)
+
+ //获取所有窨井数据
+ wellViewModel.obtainAllWell()
+ wellViewModel.allWellModel.observe(viewLifecycleOwner, {
+ if (it.code == 200) {
+ val latitudeList: MutableList = ArrayList()
+ val longitudeList: MutableList = ArrayList()
+ it.data?.forEach { well ->
+ val lat = well.latGaode.toString()
+ val lng = well.lngGaode.toString()
+ if (lat.isNotBlank() && lng.isNotBlank()) {
+ //返回true代表当前位置在大陆、港澳地区,反之不在
+ val latitude = lat.toDouble()
+ val longitude = lng.toDouble()
+ if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) {
+ //缓存所有设备详情,点击Marker时候需要
+ wellModels.add(well)
+ //分别缓存经、纬度
+ latitudeList.add(latitude)
+ longitudeList.add(longitude)
+ //将所有设备信息转化缓存为Marker点
+ allMarkerOptions.add(
+ MarkerOptions()
+ .position(LatLng(latitude, longitude))
+ .title(well.wellTypeName)
+ .snippet(well.wellName)
+ )
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度不在国内,异常经纬度 ===> [${lng},${lat}]")
+ }
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度异常,异常经纬度 ===> [${lng},${lat}]")
+ }
+ }
+ //计算所有点的中心点位置
+ val centerLatLng = LatLng(latitudeList.average(), longitudeList.average())
+ Log.d(
+ kTag,
+ "所有闸井中心点位置 ===> [${latitudeList.average()}, ${longitudeList.average()}]"
+ )
+ //移动到指定经纬度
+ val cameraPosition = CameraPosition(centerLatLng, 13f, 0f, 0f)
+ val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition)
+ aMap.animateCamera(cameraUpdate, 3000, null)
+ }
+ })
+
+ //地图初始化
+ initMap(savedInstanceState)
+ return homeView
}
- override fun initData() {
+ private fun initMap(savedInstanceState: Bundle?) {
+ homeView.mapView.onCreate(savedInstanceState)
+ aMap = homeView.mapView.map
+ aMap.mapType = AMap.MAP_TYPE_NORMAL
+ val uiSettings = aMap.uiSettings
+ uiSettings.isCompassEnabled = true
+ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER
+ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度
+ uiSettings.isRotateGesturesEnabled = false//不允许地图旋转
+
+ // 地图加载成功监听
+ aMap.addOnMapLoadedListener(this)
+ // 地图缩放监听
+ aMap.addOnCameraChangeListener(this)
+ // marker 点击事件监听
+ aMap.addOnMarkerClickListener(this)
+ // 点击marker弹出自定义popup
+ aMap.setInfoWindowAdapter(this)
+ //信息窗点击事件
+ aMap.addOnInfoWindowClickListener(this)
+ }
+
+ override fun onMapLoaded() {
+ //地图加载成功之后显示聚合点数据
+ initClustersMarkers()
+ }
+
+ override fun onCameraChange(p0: CameraPosition?) {
}
- override fun initEvent() {
+ //获取视野内的marker 根据聚合算法合成自定义的marker 显示视野内的marker
+ override fun onCameraChangeFinish(p0: CameraPosition?) {
+ //地图缩放之后显示聚合点数据
+ initClustersMarkers()
+ }
+ private fun initClustersMarkers() {
+ val proj = aMap.projection
+ val dm = resources.displayMetrics
+ var screenLocation: Point
+ markerOptionsInView.clear()
+ // 获取在当前视野内的marker
+ allMarkerOptions.forEach {
+ screenLocation = proj.toScreenLocation(it.position)
+ if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) {
+ //在当前可观区域内
+ markerOptionsInView.add(it)
+ }
+ }
+ // 自定义的聚合类MarkerCluster
+ val clustersMarkers: MutableList = ArrayList()
+ markerOptionsInView.forEach {
+ if (clustersMarkers.size == 0) {
+ //添加一个新的自定义marker
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )
+ } else {
+ var isInRange = false
+ //Kotlin foreach不能用break
+ for (view in clustersMarkers) {
+ //判断当前的marker是否在前面marker的聚合范围内 并且每个marker只会聚合一次。
+ if (view.bounds.contains(it.position)) {
+ view.addMarker(it)
+ isInRange = true
+ break
+ }
+ }
+ //如果没在任何范围内,自己单独形成一个自定义marker。在和后面的marker进行比较
+ if (!isInRange) {
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )//相距多少才聚合
+ }
+ }
+ }
+ // 设置聚合点的位置和icon
+ clustersMarkers.forEach {
+ it.setPositionAndIcon()
+ }
+ aMap.clear()
+ // 重新添加 marker
+ clustersMarkers.forEach {
+ aMap.addMarker(it.options)
+ }
+ }
+
+ override fun onMarkerClick(marker: Marker?): Boolean {
+ //显示闸井信息
+ marker?.showInfoWindow()
+ return true
+ }
+
+ override fun getInfoWindow(marker: Marker?): View? {
+ if (infoWindow == null) {
+ infoWindow = LayoutInflater.from(requireContext()).inflate(R.layout.popu_map_info, null)
+ }
+ val v = infoWindow!!
+ //反射得到popup里面的控件对象
+ val wellTypeView = v.findViewById(R.id.wellTypeView)
+ val wellCodeView = v.findViewById(R.id.wellCodeView)
+ val ownerShipView = v.findViewById(R.id.ownerShipView)
+ val locationView = v.findViewById(R.id.locationView)
+
+ //绑定数据
+ val clickedLatLng = marker?.position!!
+ for (well in wellModels) {
+ if (clickedLatLng.latitude == well.latGaode!!.toDouble()
+ && clickedLatLng.longitude == well.lngGaode!!.toDouble()
+ ) {
+ wellTypeView.text = String.format("井类型: ${well.wellType.toTypeName()}")
+ wellCodeView.text = String.format("井编号: ${well.wellCode}")
+ ownerShipView.text = String.format("权属单位: ${well.deptid.toDeptName()}")
+ locationView.text = String.format("详细位置: ${well.position}")
+ return infoWindow
+ }
+ }
+ "无法查看聚合点,请放大比例后再查看".show()
+ return null
+ }
+
+ /**
+ * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框
+ * */
+ override fun getInfoContents(p0: Marker?): View? = null
+
+ override fun onInfoWindowClick(p0: Marker?) {
+ if (p0 != null) {
+ AlertControlDialog.Builder()
+ .setContext(requireContext())
+ .setTitle("操作提示")
+ .setMessage("确定要前往吗")
+ .setNegativeButton("取消")
+ .setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ val latLng = p0.position
+ val lat = latLng.latitude.toString()
+ val lng = latLng.longitude.toString()
+ if (lat.isBlank() || lng.isBlank()) {
+ "窨井经纬度异常,无法开启导航".show()
+ return
+ }
+ Poi(p0.snippet, LatLng(lat.toDouble(), lng.toDouble()), "").showRouteOnMap(
+ requireContext()
+ )
+ }
+
+ override fun onCancelClick() {
+
+ }
+ }).build().show()
+ }
+ }
+
+ /***以下是地图生命周期管理************************************************************************/
+ override fun onResume() {
+ super.onResume()
+ homeView.mapView.onResume()
+ //每次页面切换都需要重新刷新不同状态的窨井数量
+// wellViewModel.countWellByState()
+// workOrderViewModel.countWorkOrderByState()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ homeView.mapView.onPause()
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ homeView.mapView.onSaveInstanceState(outState)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ homeView.mapView.onDestroy()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
new file mode 100644
index 0000000..4e916a9
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
@@ -0,0 +1,271 @@
+package com.casic.app.smartwell.sanxi.model;
+
+import java.util.List;
+
+public class WellListModel {
+
+ private int code;
+ private List data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public List getData() {
+ return data;
+ }
+
+ public void setData(List data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataDTO {
+ private String area;
+ private String bfzt;
+ private String bfztName;
+ private String coordinateX;
+ private String coordinateY;
+ private String deep;
+ private String deptName;
+ private String deptid;
+ private String id;
+ private String latBaidu;
+ private String latGaode;
+ private String lngBaidu;
+ private String lngGaode;
+ private String notes;
+ private String photos;
+ private String position;
+ private String staff;
+ private String tel;
+ private String ts;
+ private String valid;
+ private String watchData;
+ private String wellCode;
+ private String wellName;
+ private String wellType;
+ private String wellTypeName;
+
+ public String getArea() {
+ return area;
+ }
+
+ public void setArea(String area) {
+ this.area = area;
+ }
+
+ public String getBfzt() {
+ return bfzt;
+ }
+
+ public void setBfzt(String bfzt) {
+ this.bfzt = bfzt;
+ }
+
+ public String getBfztName() {
+ return bfztName;
+ }
+
+ public void setBfztName(String bfztName) {
+ this.bfztName = bfztName;
+ }
+
+ public String getCoordinateX() {
+ return coordinateX;
+ }
+
+ public void setCoordinateX(String coordinateX) {
+ this.coordinateX = coordinateX;
+ }
+
+ public String getCoordinateY() {
+ return coordinateY;
+ }
+
+ public void setCoordinateY(String coordinateY) {
+ this.coordinateY = coordinateY;
+ }
+
+ public String getDeep() {
+ return deep;
+ }
+
+ public void setDeep(String deep) {
+ this.deep = deep;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptid() {
+ return deptid;
+ }
+
+ public void setDeptid(String deptid) {
+ this.deptid = deptid;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getLatBaidu() {
+ return latBaidu;
+ }
+
+ public void setLatBaidu(String latBaidu) {
+ this.latBaidu = latBaidu;
+ }
+
+ public String getLatGaode() {
+ return latGaode;
+ }
+
+ public void setLatGaode(String latGaode) {
+ this.latGaode = latGaode;
+ }
+
+ public String getLngBaidu() {
+ return lngBaidu;
+ }
+
+ public void setLngBaidu(String lngBaidu) {
+ this.lngBaidu = lngBaidu;
+ }
+
+ public String getLngGaode() {
+ return lngGaode;
+ }
+
+ public void setLngGaode(String lngGaode) {
+ this.lngGaode = lngGaode;
+ }
+
+ public String getNotes() {
+ return notes;
+ }
+
+ public void setNotes(String notes) {
+ this.notes = notes;
+ }
+
+ public String getPhotos() {
+ return photos;
+ }
+
+ public void setPhotos(String photos) {
+ this.photos = photos;
+ }
+
+ public String getPosition() {
+ return position;
+ }
+
+ public void setPosition(String position) {
+ this.position = position;
+ }
+
+ public String getStaff() {
+ return staff;
+ }
+
+ public void setStaff(String staff) {
+ this.staff = staff;
+ }
+
+ public String getTel() {
+ return tel;
+ }
+
+ public void setTel(String tel) {
+ this.tel = tel;
+ }
+
+ public String getTs() {
+ return ts;
+ }
+
+ public void setTs(String ts) {
+ this.ts = ts;
+ }
+
+ public String getValid() {
+ return valid;
+ }
+
+ public void setValid(String valid) {
+ this.valid = valid;
+ }
+
+ public String getWatchData() {
+ return watchData;
+ }
+
+ public void setWatchData(String watchData) {
+ this.watchData = watchData;
+ }
+
+ public String getWellCode() {
+ return wellCode;
+ }
+
+ public void setWellCode(String wellCode) {
+ this.wellCode = wellCode;
+ }
+
+ public String getWellName() {
+ return wellName;
+ }
+
+ public void setWellName(String wellName) {
+ this.wellName = wellName;
+ }
+
+ public String getWellType() {
+ return wellType;
+ }
+
+ public void setWellType(String wellType) {
+ this.wellType = wellType;
+ }
+
+ public String getWellTypeName() {
+ return wellTypeName;
+ }
+
+ public void setWellTypeName(String wellTypeName) {
+ this.wellTypeName = wellTypeName;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
index 0fb598b..d57d378 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
@@ -1,6 +1,7 @@
package com.casic.app.smartwell.sanxi.utils
import android.Manifest
+import com.casic.app.smartwell.sanxi.R
object Constant {
@@ -19,7 +20,6 @@
const val USER_DEVICE_TYPE = "userDeviceType"
const val ACCOUNT = "account"
const val PASSWORD = "password"
- const val ALARM_TYPE = "alarmType"
const val APP_AUTHORITY = "com.casic.app.smartwell.sanxi.fileprovider"
const val CANCEL_ALARM_ACTION = "cancelAlarm"
@@ -29,11 +29,11 @@
const val RADIUS_SIZE = 100 //相距多少米才聚合,单位:米
const val DISTANCE = 5 //两点间距离阈值,单位:米
+ val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
+ val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
+
// val HOME_ICONS = arrayOf(R.drawable.ic_well, R.drawable.ic_overtime, R.drawable.ic_bfcf)
val HOME_ITEMS = arrayOf("闸井管理", "超时工单", "布防撤防")
val SUB_PAGE_TITLES = arrayOf("待处理", "待确认", "处理中", "已完成")
val OVER_TIME_PAGE_TITLES = arrayOf("超时未接单", "超时未处理")
-
- // val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
- val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
index 2bb0294..3c6fea3 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
@@ -153,6 +153,12 @@
): String
/**
+ * 获取获取闸井列表-不分页,地图用
+ */
+ @GET("/overview/wellList")
+ suspend fun obtainAllWell(@Header("token") token: String): String
+
+ /**
* 根据布防状态统计闸井数量接口
*/
@GET("/well/countByBfzt")
@@ -192,12 +198,6 @@
): String
/**
- * 获取获取闸井列表-不分页,地图用
- */
- @GET("/well/list")
- suspend fun obtainAllWell(@Header("token") token: String): String
-
- /**
* 获取井下监控设备列表
*
* @param id 窨井ID
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
index 35af71d..f67ccb6 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
@@ -151,6 +151,13 @@
return api.obtainOrderStatus(AuthenticationHelper.token!!)
}
+ /**
+ * 获取获取闸井列表-不分页
+ */
+ suspend fun obtainAllWell(): String {
+ return api.obtainAllWell(AuthenticationHelper.token!!)
+ }
+
// /**
// * 根据布防状态统计闸井数量接口
// */
@@ -190,13 +197,6 @@
// }
//
// /**
-// * 获取获取闸井列表-不分页
-// */
-// suspend fun obtainAllWell(): String {
-// return api.obtainAllWell(AuthenticationHelper.token!!)
-// }
-//
-// /**
// * 获取井下监控设备列表
// */
// suspend fun obtainMonitorResult(id: String): String {
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
index 87dd8dc..6a80a92 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
@@ -7,6 +7,7 @@
import com.casic.app.smartwell.sanxi.extensions.show
import com.casic.app.smartwell.sanxi.extensions.toErrorMessage
import com.casic.app.smartwell.sanxi.model.WellDetailModel
+import com.casic.app.smartwell.sanxi.model.WellListModel
import com.casic.app.smartwell.sanxi.utils.LoadState
import com.casic.app.smartwell.sanxi.utils.retrofit.RetrofitServiceManager
import com.google.gson.Gson
@@ -16,6 +17,7 @@
private val gson = Gson()
val detailModel = MutableLiveData()
+ val allWellModel = MutableLiveData()
fun obtainWellDetail(id: String) = launch({
loadState.value = LoadState.Loading
@@ -34,4 +36,18 @@
loadState.value = LoadState.Fail
it.printStackTrace()
})
+
+ fun obtainAllWell() = launch({
+ val response = RetrofitServiceManager.obtainAllWell()
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ allWellModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ response.toErrorMessage().show()
+ }
+ }, {
+ it.printStackTrace()
+ })
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt
new file mode 100644
index 0000000..4fd4702
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt
@@ -0,0 +1,77 @@
+package com.casic.app.smartwell.sanxi.widgets
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.*
+import com.casic.app.smartwell.sanxi.R
+import com.pengxh.app.multilib.utils.SizeUtil
+
+/**
+ * @description: 顶部下拉菜单
+ * @author: Pengxh
+ * @email: 290677893@qq.com
+ * @date: 2019/12/28 20:35
+ */
+class EasyPopupWindow(private val context: Context) : PopupWindow(context) {
+
+ private lateinit var clickListener: OnPopupWindowClickListener
+
+ init {
+ this.width = (SizeUtil.getScreenWidth(context) * 0.3).toInt()
+ this.height = ViewGroup.LayoutParams.WRAP_CONTENT
+ this.isOutsideTouchable = true
+ this.isFocusable = true
+ this.animationStyle = R.style.PopupAnimation
+ this.contentView = LayoutInflater.from(context).inflate(R.layout.popup_option, null, false)
+ }
+
+ fun setupPopupData(imageArray: Array, titleArray: Array) {
+ val popupListView = contentView.findViewById(R.id.popupListView)
+ popupListView.adapter = object : BaseAdapter() {
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+
+ override fun getCount(): Int = imageArray.size
+
+ override fun getItem(position: Int): Any = imageArray[position]
+
+ override fun getItemId(position: Int): Long = position.toLong()
+
+ override fun getView(position: Int, convertView: View?, viewGroup: ViewGroup): View {
+ val view: View
+ val holder: PopupWindowHolder
+ if (convertView == null) {
+ view = inflater.inflate(R.layout.item_map_popup, null)
+ holder = PopupWindowHolder()
+ holder.imageView = view.findViewById(R.id.imageView)
+ holder.titleView = view.findViewById(R.id.titleView)
+ view.tag = holder
+ } else {
+ view = convertView
+ holder = view.tag as PopupWindowHolder
+ }
+ holder.imageView.setBackgroundResource(imageArray[position])
+ holder.titleView.text = titleArray[position]
+ return view
+ }
+ }
+ popupListView.onItemClickListener = AdapterView.OnItemClickListener { _, _, i, _ ->
+ clickListener.onPopupClick(i)
+ dismiss()
+ }
+ }
+
+ interface OnPopupWindowClickListener {
+ fun onPopupClick(position: Int)
+ }
+
+ fun setOnPopupWindowClickListener(windowClickListener: OnPopupWindowClickListener) {
+ this.clickListener = windowClickListener
+ }
+
+ inner class PopupWindowHolder {
+ lateinit var imageView: ImageView
+ lateinit var titleView: TextView
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt
new file mode 100644
index 0000000..28ccff3
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt
@@ -0,0 +1,102 @@
+package com.casic.app.smartwell.sanxi.widgets
+
+import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.Point
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.TextView
+import com.amap.api.maps.Projection
+import com.amap.api.maps.model.BitmapDescriptorFactory
+import com.amap.api.maps.model.LatLng
+import com.amap.api.maps.model.LatLngBounds
+import com.amap.api.maps.model.MarkerOptions
+import com.casic.app.smartwell.sanxi.R
+import com.casic.app.smartwell.sanxi.extensions.toBitmap
+import java.util.*
+
+class GaoDeClusterMarkerView(
+ private val context: Context, firstMarkers: MarkerOptions,
+ projection: Projection, gridSize: Int
+) {
+ //当前可观区域里的 聚合过之后的集合
+ private val includeMarkers: ArrayList
+
+ // 创建区域
+ val bounds: LatLngBounds
+ var options: MarkerOptions = MarkerOptions()
+
+ init {
+ val screenLocation = projection.toScreenLocation(firstMarkers.position)
+ //范围类
+ val southwestPoint = Point(screenLocation.x - gridSize, screenLocation.y + gridSize)
+ //范围类
+ val northeastPoint = Point(screenLocation.x + gridSize, screenLocation.y - gridSize)
+ bounds = LatLngBounds(
+ projection.fromScreenLocation(southwestPoint),
+ projection.fromScreenLocation(northeastPoint)
+ )
+ //设置初始化marker属性
+ options.anchor(0.5f, 1.3f)
+ .title(firstMarkers.title)
+ .position(firstMarkers.position)
+ .icon(firstMarkers.icon)
+ .snippet(firstMarkers.snippet)
+ .draggable(false)
+ includeMarkers = ArrayList()
+ includeMarkers.add(firstMarkers)
+ }
+
+ /**
+ * 添加marker
+ */
+ fun addMarker(markerOptions: MarkerOptions) {
+ includeMarkers.add(markerOptions) // 添加到列表中
+ }
+
+ /**
+ * 设置聚合点的中心位置以及图标
+ */
+ fun setPositionAndIcon() {
+ val size = includeMarkers.size
+ var lat = 0.0
+ var lng = 0.0
+ // 一个的时候
+ if (size == 1) { //设置marker单个属性
+ // 设置marker位置
+ options.position(
+ LatLng(
+ includeMarkers[0].position.latitude,
+ includeMarkers[0].position.longitude
+ )
+ )
+ } else { // 聚合的时候
+ //设置marker聚合属性
+ for (op in includeMarkers) {
+ lat += op.position.latitude
+ lng += op.position.longitude
+ }
+ // 设置marker的位置为中心位置为聚集点的平均位置
+ options.position(LatLng(lat / size, lng / size))
+ }
+ options.icon(BitmapDescriptorFactory.fromBitmap(getBitmap(size)))
+ }
+
+ /**
+ * marker视图
+ */
+ private fun getBitmap(num: Int): Bitmap? {
+ val view = LayoutInflater.from(context).inflate(R.layout.marker_gaode, null)
+ val wellCountView = view.findViewById(R.id.wellCountView)
+ return if (num > 1) {
+ wellCountView.visibility = View.VISIBLE
+ wellCountView.text = String.format("${num}个")
+ wellCountView.gravity = Gravity.CENTER
+ view.toBitmap()
+ } else {
+ wellCountView.visibility = View.GONE
+ BitmapDescriptorFactory.fromResource(R.mipmap.well_location).bitmap
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_black_transparent_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_black_transparent_radius_10.xml
new file mode 100644
index 0000000..15e6a4b
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_black_transparent_radius_10.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_main_color.xml b/app/src/main/res/drawable/bg_solid_layout_main_color.xml
new file mode 100644
index 0000000..e329b7d
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_main_color.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_radius_20.xml b/app/src/main/res/drawable/bg_solid_layout_radius_20.xml
new file mode 100644
index 0000000..0c2abfe
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_radius_20.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bottom_short_line.xml b/app/src/main/res/drawable/bottom_short_line.xml
new file mode 100644
index 0000000..10c9062
--- /dev/null
+++ b/app/src/main/res/drawable/bottom_short_line.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_change_map.xml b/app/src/main/res/drawable/ic_change_map.xml
new file mode 100644
index 0000000..c567efa
--- /dev/null
+++ b/app/src/main/res/drawable/ic_change_map.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ea56300..0416db4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -49,5 +49,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
index 291a985..c41c867 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/extensions/String.kt
@@ -82,14 +82,40 @@
}
//窨井类型转换
-fun String.toChinese(): String {
+fun String.toTypeName(): String {
return when (this) {
- "0" -> "全部"
- "1" -> "一级"
- "2" -> "二级"
- "3" -> "三级"
+ "1" -> "雨水井"
+ "2" -> "污水井"
+ "3" -> "燃气井"
+ "4" -> "热力井"
+ "5" -> "电力井"
+ "6" -> "交通井"
+ "7" -> "路灯井"
+ "8" -> "通信井"
+ "9" -> "监控井"
else -> {
- "未知"
+ "其他"
+ }
+ }
+}
+
+fun String.toDeptName(): String {
+ return when (this) {
+ "0" -> "顶级"
+ "1148031048115494913" -> "二院"
+ "1178242695136149506" -> "电力公司"
+ "1178242900132757506" -> "滨海热电"
+ "24" -> "燃气集团总公司"
+ "30" -> "203所"
+ "1399230677135265794" -> "厦门测试"
+ "25" -> "第一分公司"
+ "26" -> "第二分公司"
+ "27" -> "第三分公司"
+ "28" -> "第四分公司"
+ "29" -> "高压管网分公司"
+ "1143796514486353922" -> "第五分公司"
+ else -> {
+ "其他"
}
}
}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
index 26f3085..4d0c818 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/fragment/HomePageFragment.kt
@@ -1,24 +1,326 @@
package com.casic.app.smartwell.sanxi.fragment
+import android.graphics.Point
+import android.os.Bundle
+import android.util.Log
+import android.view.LayoutInflater
import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import com.amap.api.maps.AMap
+import com.amap.api.maps.AMapOptions
+import com.amap.api.maps.CameraUpdateFactory
+import com.amap.api.maps.CoordinateConverter
+import com.amap.api.maps.model.*
import com.casic.app.smartwell.sanxi.R
-import com.casic.app.smartwell.sanxi.base.BaseFragment
-import kotlinx.android.synthetic.main.include_base_title.*
+import com.casic.app.smartwell.sanxi.extensions.show
+import com.casic.app.smartwell.sanxi.extensions.showRouteOnMap
+import com.casic.app.smartwell.sanxi.extensions.toDeptName
+import com.casic.app.smartwell.sanxi.extensions.toTypeName
+import com.casic.app.smartwell.sanxi.model.WellListModel
+import com.casic.app.smartwell.sanxi.utils.Constant
+import com.casic.app.smartwell.sanxi.vm.WellViewModel
+import com.casic.app.smartwell.sanxi.widgets.EasyPopupWindow
+import com.casic.app.smartwell.sanxi.widgets.GaoDeClusterMarkerView
+import com.google.android.material.bottomsheet.BottomSheetBehavior
+import com.pengxh.app.multilib.utils.SizeUtil
+import com.pengxh.app.multilib.widget.dialog.AlertControlDialog
+import kotlinx.android.synthetic.main.fragment_home.view.*
-class HomePageFragment : BaseFragment() {
+class HomePageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener,
+ AMap.OnMarkerClickListener, AMap.InfoWindowAdapter, AMap.OnInfoWindowClickListener {
- override fun initLayoutView(): Int = R.layout.fragment_home
+ private val kTag = "HomePageFragment"
+ private lateinit var homeView: View
+ private lateinit var aMap: AMap
+ private lateinit var wellViewModel: WellViewModel
- override fun setupTopBarLayout() {
- leftBackView.visibility = View.GONE
- titleView.text = "首页"
+ /**
+ * 所有窨井列表信息集合
+ * */
+ private var wellModels: MutableList = ArrayList()
+
+ /**
+ * 所有的marker
+ */
+ private var allMarkerOptions: MutableList = ArrayList()
+
+ /**
+ * 视野内的marker
+ */
+ private var markerOptionsInView: MutableList = ArrayList()
+
+ /**
+ * 自定义Marker弹出框
+ * */
+ private var infoWindow: View? = null
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ homeView = inflater.inflate(R.layout.fragment_home, container, false)
+ homeView.titleView.text = "首页"
+ val easyPopupWindow = EasyPopupWindow(requireContext())
+ easyPopupWindow.setupPopupData(Constant.POPUP_IMAGES, Constant.POPUP_TITLES)
+ homeView.rightOptionView.setOnClickListener {
+ easyPopupWindow.setOnPopupWindowClickListener(object :
+ EasyPopupWindow.OnPopupWindowClickListener {
+ override fun onPopupClick(position: Int) {
+ when (position) {
+ 0 -> aMap.mapType = AMap.MAP_TYPE_NORMAL
+ 1 -> aMap.mapType = AMap.MAP_TYPE_SATELLITE
+ }
+ }
+ })
+ easyPopupWindow.setBackgroundDrawable(null)
+ val x: Int = homeView.rightOptionView.width - easyPopupWindow.width
+ easyPopupWindow.showAsDropDown(homeView.rightOptionView, x, 0)
+ }
+
+ //代码设置底部拉升距离
+ val bottomSheetBehavior = BottomSheetBehavior.from(homeView.bottomBehaviorLayout)
+ homeView.coordinatorLayout.post {
+ bottomSheetBehavior.isFitToContents = false
+ bottomSheetBehavior.halfExpandedRatio = 0.3f
+ bottomSheetBehavior.isHideable = false
+ bottomSheetBehavior.peekHeight = SizeUtil.dp2px(requireContext(), 30f)
+ }
+
+ //初始化vm
+ wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java)
+
+ //获取所有窨井数据
+ wellViewModel.obtainAllWell()
+ wellViewModel.allWellModel.observe(viewLifecycleOwner, {
+ if (it.code == 200) {
+ val latitudeList: MutableList = ArrayList()
+ val longitudeList: MutableList = ArrayList()
+ it.data?.forEach { well ->
+ val lat = well.latGaode.toString()
+ val lng = well.lngGaode.toString()
+ if (lat.isNotBlank() && lng.isNotBlank()) {
+ //返回true代表当前位置在大陆、港澳地区,反之不在
+ val latitude = lat.toDouble()
+ val longitude = lng.toDouble()
+ if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) {
+ //缓存所有设备详情,点击Marker时候需要
+ wellModels.add(well)
+ //分别缓存经、纬度
+ latitudeList.add(latitude)
+ longitudeList.add(longitude)
+ //将所有设备信息转化缓存为Marker点
+ allMarkerOptions.add(
+ MarkerOptions()
+ .position(LatLng(latitude, longitude))
+ .title(well.wellTypeName)
+ .snippet(well.wellName)
+ )
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度不在国内,异常经纬度 ===> [${lng},${lat}]")
+ }
+ } else {
+ Log.d(kTag, "${well.wellCode}闸井经纬度异常,异常经纬度 ===> [${lng},${lat}]")
+ }
+ }
+ //计算所有点的中心点位置
+ val centerLatLng = LatLng(latitudeList.average(), longitudeList.average())
+ Log.d(
+ kTag,
+ "所有闸井中心点位置 ===> [${latitudeList.average()}, ${longitudeList.average()}]"
+ )
+ //移动到指定经纬度
+ val cameraPosition = CameraPosition(centerLatLng, 13f, 0f, 0f)
+ val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition)
+ aMap.animateCamera(cameraUpdate, 3000, null)
+ }
+ })
+
+ //地图初始化
+ initMap(savedInstanceState)
+ return homeView
}
- override fun initData() {
+ private fun initMap(savedInstanceState: Bundle?) {
+ homeView.mapView.onCreate(savedInstanceState)
+ aMap = homeView.mapView.map
+ aMap.mapType = AMap.MAP_TYPE_NORMAL
+ val uiSettings = aMap.uiSettings
+ uiSettings.isCompassEnabled = true
+ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER
+ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度
+ uiSettings.isRotateGesturesEnabled = false//不允许地图旋转
+
+ // 地图加载成功监听
+ aMap.addOnMapLoadedListener(this)
+ // 地图缩放监听
+ aMap.addOnCameraChangeListener(this)
+ // marker 点击事件监听
+ aMap.addOnMarkerClickListener(this)
+ // 点击marker弹出自定义popup
+ aMap.setInfoWindowAdapter(this)
+ //信息窗点击事件
+ aMap.addOnInfoWindowClickListener(this)
+ }
+
+ override fun onMapLoaded() {
+ //地图加载成功之后显示聚合点数据
+ initClustersMarkers()
+ }
+
+ override fun onCameraChange(p0: CameraPosition?) {
}
- override fun initEvent() {
+ //获取视野内的marker 根据聚合算法合成自定义的marker 显示视野内的marker
+ override fun onCameraChangeFinish(p0: CameraPosition?) {
+ //地图缩放之后显示聚合点数据
+ initClustersMarkers()
+ }
+ private fun initClustersMarkers() {
+ val proj = aMap.projection
+ val dm = resources.displayMetrics
+ var screenLocation: Point
+ markerOptionsInView.clear()
+ // 获取在当前视野内的marker
+ allMarkerOptions.forEach {
+ screenLocation = proj.toScreenLocation(it.position)
+ if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) {
+ //在当前可观区域内
+ markerOptionsInView.add(it)
+ }
+ }
+ // 自定义的聚合类MarkerCluster
+ val clustersMarkers: MutableList = ArrayList()
+ markerOptionsInView.forEach {
+ if (clustersMarkers.size == 0) {
+ //添加一个新的自定义marker
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )
+ } else {
+ var isInRange = false
+ //Kotlin foreach不能用break
+ for (view in clustersMarkers) {
+ //判断当前的marker是否在前面marker的聚合范围内 并且每个marker只会聚合一次。
+ if (view.bounds.contains(it.position)) {
+ view.addMarker(it)
+ isInRange = true
+ break
+ }
+ }
+ //如果没在任何范围内,自己单独形成一个自定义marker。在和后面的marker进行比较
+ if (!isInRange) {
+ clustersMarkers.add(
+ GaoDeClusterMarkerView(requireContext(), it, proj, Constant.RADIUS_SIZE)
+ )//相距多少才聚合
+ }
+ }
+ }
+ // 设置聚合点的位置和icon
+ clustersMarkers.forEach {
+ it.setPositionAndIcon()
+ }
+ aMap.clear()
+ // 重新添加 marker
+ clustersMarkers.forEach {
+ aMap.addMarker(it.options)
+ }
+ }
+
+ override fun onMarkerClick(marker: Marker?): Boolean {
+ //显示闸井信息
+ marker?.showInfoWindow()
+ return true
+ }
+
+ override fun getInfoWindow(marker: Marker?): View? {
+ if (infoWindow == null) {
+ infoWindow = LayoutInflater.from(requireContext()).inflate(R.layout.popu_map_info, null)
+ }
+ val v = infoWindow!!
+ //反射得到popup里面的控件对象
+ val wellTypeView = v.findViewById(R.id.wellTypeView)
+ val wellCodeView = v.findViewById(R.id.wellCodeView)
+ val ownerShipView = v.findViewById(R.id.ownerShipView)
+ val locationView = v.findViewById(R.id.locationView)
+
+ //绑定数据
+ val clickedLatLng = marker?.position!!
+ for (well in wellModels) {
+ if (clickedLatLng.latitude == well.latGaode!!.toDouble()
+ && clickedLatLng.longitude == well.lngGaode!!.toDouble()
+ ) {
+ wellTypeView.text = String.format("井类型: ${well.wellType.toTypeName()}")
+ wellCodeView.text = String.format("井编号: ${well.wellCode}")
+ ownerShipView.text = String.format("权属单位: ${well.deptid.toDeptName()}")
+ locationView.text = String.format("详细位置: ${well.position}")
+ return infoWindow
+ }
+ }
+ "无法查看聚合点,请放大比例后再查看".show()
+ return null
+ }
+
+ /**
+ * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框
+ * */
+ override fun getInfoContents(p0: Marker?): View? = null
+
+ override fun onInfoWindowClick(p0: Marker?) {
+ if (p0 != null) {
+ AlertControlDialog.Builder()
+ .setContext(requireContext())
+ .setTitle("操作提示")
+ .setMessage("确定要前往吗")
+ .setNegativeButton("取消")
+ .setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ val latLng = p0.position
+ val lat = latLng.latitude.toString()
+ val lng = latLng.longitude.toString()
+ if (lat.isBlank() || lng.isBlank()) {
+ "窨井经纬度异常,无法开启导航".show()
+ return
+ }
+ Poi(p0.snippet, LatLng(lat.toDouble(), lng.toDouble()), "").showRouteOnMap(
+ requireContext()
+ )
+ }
+
+ override fun onCancelClick() {
+
+ }
+ }).build().show()
+ }
+ }
+
+ /***以下是地图生命周期管理************************************************************************/
+ override fun onResume() {
+ super.onResume()
+ homeView.mapView.onResume()
+ //每次页面切换都需要重新刷新不同状态的窨井数量
+// wellViewModel.countWellByState()
+// workOrderViewModel.countWorkOrderByState()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ homeView.mapView.onPause()
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ homeView.mapView.onSaveInstanceState(outState)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ homeView.mapView.onDestroy()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
new file mode 100644
index 0000000..4e916a9
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/model/WellListModel.java
@@ -0,0 +1,271 @@
+package com.casic.app.smartwell.sanxi.model;
+
+import java.util.List;
+
+public class WellListModel {
+
+ private int code;
+ private List data;
+ private String message;
+ private boolean success;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public List getData() {
+ return data;
+ }
+
+ public void setData(List data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static class DataDTO {
+ private String area;
+ private String bfzt;
+ private String bfztName;
+ private String coordinateX;
+ private String coordinateY;
+ private String deep;
+ private String deptName;
+ private String deptid;
+ private String id;
+ private String latBaidu;
+ private String latGaode;
+ private String lngBaidu;
+ private String lngGaode;
+ private String notes;
+ private String photos;
+ private String position;
+ private String staff;
+ private String tel;
+ private String ts;
+ private String valid;
+ private String watchData;
+ private String wellCode;
+ private String wellName;
+ private String wellType;
+ private String wellTypeName;
+
+ public String getArea() {
+ return area;
+ }
+
+ public void setArea(String area) {
+ this.area = area;
+ }
+
+ public String getBfzt() {
+ return bfzt;
+ }
+
+ public void setBfzt(String bfzt) {
+ this.bfzt = bfzt;
+ }
+
+ public String getBfztName() {
+ return bfztName;
+ }
+
+ public void setBfztName(String bfztName) {
+ this.bfztName = bfztName;
+ }
+
+ public String getCoordinateX() {
+ return coordinateX;
+ }
+
+ public void setCoordinateX(String coordinateX) {
+ this.coordinateX = coordinateX;
+ }
+
+ public String getCoordinateY() {
+ return coordinateY;
+ }
+
+ public void setCoordinateY(String coordinateY) {
+ this.coordinateY = coordinateY;
+ }
+
+ public String getDeep() {
+ return deep;
+ }
+
+ public void setDeep(String deep) {
+ this.deep = deep;
+ }
+
+ public String getDeptName() {
+ return deptName;
+ }
+
+ public void setDeptName(String deptName) {
+ this.deptName = deptName;
+ }
+
+ public String getDeptid() {
+ return deptid;
+ }
+
+ public void setDeptid(String deptid) {
+ this.deptid = deptid;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getLatBaidu() {
+ return latBaidu;
+ }
+
+ public void setLatBaidu(String latBaidu) {
+ this.latBaidu = latBaidu;
+ }
+
+ public String getLatGaode() {
+ return latGaode;
+ }
+
+ public void setLatGaode(String latGaode) {
+ this.latGaode = latGaode;
+ }
+
+ public String getLngBaidu() {
+ return lngBaidu;
+ }
+
+ public void setLngBaidu(String lngBaidu) {
+ this.lngBaidu = lngBaidu;
+ }
+
+ public String getLngGaode() {
+ return lngGaode;
+ }
+
+ public void setLngGaode(String lngGaode) {
+ this.lngGaode = lngGaode;
+ }
+
+ public String getNotes() {
+ return notes;
+ }
+
+ public void setNotes(String notes) {
+ this.notes = notes;
+ }
+
+ public String getPhotos() {
+ return photos;
+ }
+
+ public void setPhotos(String photos) {
+ this.photos = photos;
+ }
+
+ public String getPosition() {
+ return position;
+ }
+
+ public void setPosition(String position) {
+ this.position = position;
+ }
+
+ public String getStaff() {
+ return staff;
+ }
+
+ public void setStaff(String staff) {
+ this.staff = staff;
+ }
+
+ public String getTel() {
+ return tel;
+ }
+
+ public void setTel(String tel) {
+ this.tel = tel;
+ }
+
+ public String getTs() {
+ return ts;
+ }
+
+ public void setTs(String ts) {
+ this.ts = ts;
+ }
+
+ public String getValid() {
+ return valid;
+ }
+
+ public void setValid(String valid) {
+ this.valid = valid;
+ }
+
+ public String getWatchData() {
+ return watchData;
+ }
+
+ public void setWatchData(String watchData) {
+ this.watchData = watchData;
+ }
+
+ public String getWellCode() {
+ return wellCode;
+ }
+
+ public void setWellCode(String wellCode) {
+ this.wellCode = wellCode;
+ }
+
+ public String getWellName() {
+ return wellName;
+ }
+
+ public void setWellName(String wellName) {
+ this.wellName = wellName;
+ }
+
+ public String getWellType() {
+ return wellType;
+ }
+
+ public void setWellType(String wellType) {
+ this.wellType = wellType;
+ }
+
+ public String getWellTypeName() {
+ return wellTypeName;
+ }
+
+ public void setWellTypeName(String wellTypeName) {
+ this.wellTypeName = wellTypeName;
+ }
+ }
+}
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
index 0fb598b..d57d378 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/Constant.kt
@@ -1,6 +1,7 @@
package com.casic.app.smartwell.sanxi.utils
import android.Manifest
+import com.casic.app.smartwell.sanxi.R
object Constant {
@@ -19,7 +20,6 @@
const val USER_DEVICE_TYPE = "userDeviceType"
const val ACCOUNT = "account"
const val PASSWORD = "password"
- const val ALARM_TYPE = "alarmType"
const val APP_AUTHORITY = "com.casic.app.smartwell.sanxi.fileprovider"
const val CANCEL_ALARM_ACTION = "cancelAlarm"
@@ -29,11 +29,11 @@
const val RADIUS_SIZE = 100 //相距多少米才聚合,单位:米
const val DISTANCE = 5 //两点间距离阈值,单位:米
+ val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
+ val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
+
// val HOME_ICONS = arrayOf(R.drawable.ic_well, R.drawable.ic_overtime, R.drawable.ic_bfcf)
val HOME_ITEMS = arrayOf("闸井管理", "超时工单", "布防撤防")
val SUB_PAGE_TITLES = arrayOf("待处理", "待确认", "处理中", "已完成")
val OVER_TIME_PAGE_TITLES = arrayOf("超时未接单", "超时未处理")
-
- // val POPUP_IMAGES = arrayOf(R.drawable.ic_menu_map, R.drawable.ic_satellite)
- val POPUP_TITLES = arrayOf("标准地图", "卫星地图")
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
index 2bb0294..3c6fea3 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitService.kt
@@ -153,6 +153,12 @@
): String
/**
+ * 获取获取闸井列表-不分页,地图用
+ */
+ @GET("/overview/wellList")
+ suspend fun obtainAllWell(@Header("token") token: String): String
+
+ /**
* 根据布防状态统计闸井数量接口
*/
@GET("/well/countByBfzt")
@@ -192,12 +198,6 @@
): String
/**
- * 获取获取闸井列表-不分页,地图用
- */
- @GET("/well/list")
- suspend fun obtainAllWell(@Header("token") token: String): String
-
- /**
* 获取井下监控设备列表
*
* @param id 窨井ID
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
index 35af71d..f67ccb6 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/utils/retrofit/RetrofitServiceManager.kt
@@ -151,6 +151,13 @@
return api.obtainOrderStatus(AuthenticationHelper.token!!)
}
+ /**
+ * 获取获取闸井列表-不分页
+ */
+ suspend fun obtainAllWell(): String {
+ return api.obtainAllWell(AuthenticationHelper.token!!)
+ }
+
// /**
// * 根据布防状态统计闸井数量接口
// */
@@ -190,13 +197,6 @@
// }
//
// /**
-// * 获取获取闸井列表-不分页
-// */
-// suspend fun obtainAllWell(): String {
-// return api.obtainAllWell(AuthenticationHelper.token!!)
-// }
-//
-// /**
// * 获取井下监控设备列表
// */
// suspend fun obtainMonitorResult(id: String): String {
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
index 87dd8dc..6a80a92 100644
--- a/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/vm/WellViewModel.kt
@@ -7,6 +7,7 @@
import com.casic.app.smartwell.sanxi.extensions.show
import com.casic.app.smartwell.sanxi.extensions.toErrorMessage
import com.casic.app.smartwell.sanxi.model.WellDetailModel
+import com.casic.app.smartwell.sanxi.model.WellListModel
import com.casic.app.smartwell.sanxi.utils.LoadState
import com.casic.app.smartwell.sanxi.utils.retrofit.RetrofitServiceManager
import com.google.gson.Gson
@@ -16,6 +17,7 @@
private val gson = Gson()
val detailModel = MutableLiveData()
+ val allWellModel = MutableLiveData()
fun obtainWellDetail(id: String) = launch({
loadState.value = LoadState.Loading
@@ -34,4 +36,18 @@
loadState.value = LoadState.Fail
it.printStackTrace()
})
+
+ fun obtainAllWell() = launch({
+ val response = RetrofitServiceManager.obtainAllWell()
+ val responseCode = response.separateResponseCode()
+ if (responseCode == 200) {
+ allWellModel.value = gson.fromJson(
+ response, object : TypeToken() {}.type
+ )
+ } else {
+ response.toErrorMessage().show()
+ }
+ }, {
+ it.printStackTrace()
+ })
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt
new file mode 100644
index 0000000..4fd4702
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/EasyPopupWindow.kt
@@ -0,0 +1,77 @@
+package com.casic.app.smartwell.sanxi.widgets
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.*
+import com.casic.app.smartwell.sanxi.R
+import com.pengxh.app.multilib.utils.SizeUtil
+
+/**
+ * @description: 顶部下拉菜单
+ * @author: Pengxh
+ * @email: 290677893@qq.com
+ * @date: 2019/12/28 20:35
+ */
+class EasyPopupWindow(private val context: Context) : PopupWindow(context) {
+
+ private lateinit var clickListener: OnPopupWindowClickListener
+
+ init {
+ this.width = (SizeUtil.getScreenWidth(context) * 0.3).toInt()
+ this.height = ViewGroup.LayoutParams.WRAP_CONTENT
+ this.isOutsideTouchable = true
+ this.isFocusable = true
+ this.animationStyle = R.style.PopupAnimation
+ this.contentView = LayoutInflater.from(context).inflate(R.layout.popup_option, null, false)
+ }
+
+ fun setupPopupData(imageArray: Array, titleArray: Array) {
+ val popupListView = contentView.findViewById(R.id.popupListView)
+ popupListView.adapter = object : BaseAdapter() {
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+
+ override fun getCount(): Int = imageArray.size
+
+ override fun getItem(position: Int): Any = imageArray[position]
+
+ override fun getItemId(position: Int): Long = position.toLong()
+
+ override fun getView(position: Int, convertView: View?, viewGroup: ViewGroup): View {
+ val view: View
+ val holder: PopupWindowHolder
+ if (convertView == null) {
+ view = inflater.inflate(R.layout.item_map_popup, null)
+ holder = PopupWindowHolder()
+ holder.imageView = view.findViewById(R.id.imageView)
+ holder.titleView = view.findViewById(R.id.titleView)
+ view.tag = holder
+ } else {
+ view = convertView
+ holder = view.tag as PopupWindowHolder
+ }
+ holder.imageView.setBackgroundResource(imageArray[position])
+ holder.titleView.text = titleArray[position]
+ return view
+ }
+ }
+ popupListView.onItemClickListener = AdapterView.OnItemClickListener { _, _, i, _ ->
+ clickListener.onPopupClick(i)
+ dismiss()
+ }
+ }
+
+ interface OnPopupWindowClickListener {
+ fun onPopupClick(position: Int)
+ }
+
+ fun setOnPopupWindowClickListener(windowClickListener: OnPopupWindowClickListener) {
+ this.clickListener = windowClickListener
+ }
+
+ inner class PopupWindowHolder {
+ lateinit var imageView: ImageView
+ lateinit var titleView: TextView
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt
new file mode 100644
index 0000000..28ccff3
--- /dev/null
+++ b/app/src/main/java/com/casic/app/smartwell/sanxi/widgets/GaoDeClusterMarkerView.kt
@@ -0,0 +1,102 @@
+package com.casic.app.smartwell.sanxi.widgets
+
+import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.Point
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.TextView
+import com.amap.api.maps.Projection
+import com.amap.api.maps.model.BitmapDescriptorFactory
+import com.amap.api.maps.model.LatLng
+import com.amap.api.maps.model.LatLngBounds
+import com.amap.api.maps.model.MarkerOptions
+import com.casic.app.smartwell.sanxi.R
+import com.casic.app.smartwell.sanxi.extensions.toBitmap
+import java.util.*
+
+class GaoDeClusterMarkerView(
+ private val context: Context, firstMarkers: MarkerOptions,
+ projection: Projection, gridSize: Int
+) {
+ //当前可观区域里的 聚合过之后的集合
+ private val includeMarkers: ArrayList
+
+ // 创建区域
+ val bounds: LatLngBounds
+ var options: MarkerOptions = MarkerOptions()
+
+ init {
+ val screenLocation = projection.toScreenLocation(firstMarkers.position)
+ //范围类
+ val southwestPoint = Point(screenLocation.x - gridSize, screenLocation.y + gridSize)
+ //范围类
+ val northeastPoint = Point(screenLocation.x + gridSize, screenLocation.y - gridSize)
+ bounds = LatLngBounds(
+ projection.fromScreenLocation(southwestPoint),
+ projection.fromScreenLocation(northeastPoint)
+ )
+ //设置初始化marker属性
+ options.anchor(0.5f, 1.3f)
+ .title(firstMarkers.title)
+ .position(firstMarkers.position)
+ .icon(firstMarkers.icon)
+ .snippet(firstMarkers.snippet)
+ .draggable(false)
+ includeMarkers = ArrayList()
+ includeMarkers.add(firstMarkers)
+ }
+
+ /**
+ * 添加marker
+ */
+ fun addMarker(markerOptions: MarkerOptions) {
+ includeMarkers.add(markerOptions) // 添加到列表中
+ }
+
+ /**
+ * 设置聚合点的中心位置以及图标
+ */
+ fun setPositionAndIcon() {
+ val size = includeMarkers.size
+ var lat = 0.0
+ var lng = 0.0
+ // 一个的时候
+ if (size == 1) { //设置marker单个属性
+ // 设置marker位置
+ options.position(
+ LatLng(
+ includeMarkers[0].position.latitude,
+ includeMarkers[0].position.longitude
+ )
+ )
+ } else { // 聚合的时候
+ //设置marker聚合属性
+ for (op in includeMarkers) {
+ lat += op.position.latitude
+ lng += op.position.longitude
+ }
+ // 设置marker的位置为中心位置为聚集点的平均位置
+ options.position(LatLng(lat / size, lng / size))
+ }
+ options.icon(BitmapDescriptorFactory.fromBitmap(getBitmap(size)))
+ }
+
+ /**
+ * marker视图
+ */
+ private fun getBitmap(num: Int): Bitmap? {
+ val view = LayoutInflater.from(context).inflate(R.layout.marker_gaode, null)
+ val wellCountView = view.findViewById(R.id.wellCountView)
+ return if (num > 1) {
+ wellCountView.visibility = View.VISIBLE
+ wellCountView.text = String.format("${num}个")
+ wellCountView.gravity = Gravity.CENTER
+ view.toBitmap()
+ } else {
+ wellCountView.visibility = View.GONE
+ BitmapDescriptorFactory.fromResource(R.mipmap.well_location).bitmap
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_solid_layout_black_transparent_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_black_transparent_radius_10.xml
new file mode 100644
index 0000000..15e6a4b
--- /dev/null
+++ b/app/src/main/res/drawable/bg_solid_layout_black_transparent_radius_10.xml
@@ -0,0 +1,8 @@
+
+
+
+