package com.casic.smarttube.view import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.widget.TextView 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.CameraPosition import com.amap.api.maps.model.LatLng import com.amap.api.maps.model.Marker import com.amap.api.maps.model.MarkerOptions import com.amap.api.services.core.LatLonPoint import com.amap.api.services.geocoder.GeocodeResult import com.amap.api.services.geocoder.GeocodeSearch import com.amap.api.services.geocoder.RegeocodeQuery import com.amap.api.services.geocoder.RegeocodeResult import com.casic.smarttube.R import com.casic.smarttube.databinding.ActivityGroupDeviceMapBinding import com.casic.smarttube.extensions.initImmersionBar import com.casic.smarttube.model.MapDeviceModel import com.casic.smarttube.utils.RouteOnMap import com.casic.smarttube.vm.DeviceViewModel import com.casic.smarttube.vm.ProjectGroupViewModel import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.extensions.wrapLine import com.pengxh.kt.lite.utils.ActivityStackManager import com.pengxh.kt.lite.utils.LiteKitConstant import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertControlDialog class GroupDeviceMapActivity : KotlinBaseActivity<ActivityGroupDeviceMapBinding>(), AMap.OnCameraChangeListener, AMap.OnMarkerClickListener, AMap.InfoWindowAdapter, AMap.OnInfoWindowClickListener, AMap.OnMapClickListener { private val context = this private val geocoderSearch by lazy { GeocodeSearch(this) } private lateinit var aMap: AMap private lateinit var groupViewModel: ProjectGroupViewModel private lateinit var deviceViewModel: DeviceViewModel private var clickedMarker: Marker? = null /** * 自定义Marker弹出框 * */ private var infoView: View? = null /** * 所有设备列表信息集合 * */ private var deviceModels: MutableList<MapDeviceModel.DataModel> = ArrayList() override fun initViewBinding(): ActivityGroupDeviceMapBinding { return ActivityGroupDeviceMapBinding.inflate(layoutInflater) } override fun observeRequestState() { binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) } override fun setupTopBarLayout() { binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { override fun onLeftClick() { finish() } override fun onRightClick() { } }) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) val groupId = intent.getStringExtra(LiteKitConstant.INTENT_PARAM_KEY)!! //地图初始化 initMap(savedInstanceState) deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] deviceViewModel.mapDeviceData.observe(this) { if (it.code == 200) { it.data.forEach { device -> val lat = device.latGaode.toString() val lng = device.lngGaode.toString() if (lat.isNotBlank() && lng.isNotBlank()) { val latitude = lat.toDouble() val longitude = lng.toDouble() if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { //缓存所有设备详情,点击Marker时候需要 deviceModels.add(device) } } } } } deviceViewModel.getMapDeviceList(this) groupViewModel = ViewModelProvider(this)[ProjectGroupViewModel::class.java] groupViewModel.groupDeviceData.observe(this) { if (it.code == 200) { val allMarkerOptions = ArrayList<MarkerOptions>() val latitudeList = ArrayList<Double>() val longitudeList = ArrayList<Double>() it.data.forEach { device -> val lat = device.latGaode.toString() val lng = device.lngGaode.toString() if (lat.isNotBlank() && lng.isNotBlank()) { val latitude = lat.toDouble() val longitude = lng.toDouble() if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { //分别缓存经、纬度 latitudeList.add(latitude) longitudeList.add(longitude) //将所有设备信息转化缓存为Marker点 val latLng = LatLng(latitude, longitude) allMarkerOptions.add(MarkerOptions().position(latLng)) } } } allMarkerOptions.forEach { marker -> aMap.addMarker(marker) } val latLng = LatLng(latitudeList[0], longitudeList[0]) val cameraPosition = CameraPosition(latLng, 14f, 0f, 0f) val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) aMap.animateCamera(cameraUpdate, 1500, null) } } groupViewModel.getDeviceListByGroup(this, groupId) } override fun initEvent() { } private fun initMap(savedInstanceState: Bundle?) { binding.mapView.onCreate(savedInstanceState) aMap = binding.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.addOnCameraChangeListener(this) // marker 点击事件监听 aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup aMap.setInfoWindowAdapter(this) //信息窗点击事件 aMap.addOnInfoWindowClickListener(this) //地图点击事件,用于隐藏infoWindow aMap.setOnMapClickListener(this) } override fun onCameraChange(cameraPosition: CameraPosition?) { } override fun onCameraChangeFinish(cameraPosition: CameraPosition?) { } override fun onMarkerClick(marker: Marker?): Boolean { marker?.apply { clickedMarker = this if (isInfoWindowShown) { hideInfoWindow() } else { showInfoWindow() } } return true } override fun onMapClick(p0: LatLng?) { clickedMarker?.apply { if (isInfoWindowShown) { hideInfoWindow() } } } override fun getInfoWindow(marker: Marker?): View? { if (infoView == null) { infoView = LayoutInflater.from(this).inflate(R.layout.popu_map_info, null) } marker?.apply { renderWindow(this, infoView!!) } return infoView } private fun renderWindow(marker: Marker, view: View) { //反射得到popup里面的控件对象 val deviceCodeView = view.findViewById<TextView>(R.id.deviceCodeView) val deviceModelView = view.findViewById<TextView>(R.id.deviceModelView) val deviceValueView = view.findViewById<TextView>(R.id.deviceValueView) val updateTimeView = view.findViewById<TextView>(R.id.updateTimeView) val locationView = view.findViewById<TextView>(R.id.locationView) //绑定数据 val clicked = marker.position deviceModels.forEach { device -> if (clicked.latitude == device.latGaode!!.toDouble() && clicked.longitude == device.lngGaode!!.toDouble()) { deviceCodeView.text = String.format("设备编号: ${device.devcode}") deviceModelView.text = String.format("设备模型: ${device.modelName}") deviceViewModel.lastDataData.observe(this) { if (it.code == 200) { deviceValueView.text = String.format("最新浓度: ${it.data.strength}") updateTimeView.text = String.format("更新时间: ${it.data.uptime}") } else { deviceValueView.text = String.format("最新浓度: 未知") updateTimeView.text = String.format("更新时间: 未知") } } //获取设备最新浓度信息 deviceViewModel.getTubeLastData(context, device.groupId, device.devcode) if (device.latGaode.isBlank() || device.lngGaode.isBlank()) { locationView.text = "经纬度异常,无法查看具体位置" } else { val point = LatLonPoint(device.latGaode.toDouble(), device.lngGaode.toDouble()) val queryParam = RegeocodeQuery(point, 200f, GeocodeSearch.AMAP) geocoderSearch.getFromLocationAsyn(queryParam) geocoderSearch.setOnGeocodeSearchListener(object : GeocodeSearch.OnGeocodeSearchListener { override fun onRegeocodeSearched(result: RegeocodeResult?, rCode: Int) { if (rCode == 1000) { val address = result?.regeocodeAddress?.formatAddress locationView.text = String.format("详细位置: ${address?.wrapLine(14)}") } } override fun onGeocodeSearched(result: GeocodeResult?, rCode: Int) { } }) } } } } /** * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框 * */ override fun getInfoContents(p0: Marker?): View? = null override fun onInfoWindowClick(marker: Marker?) { marker?.apply { AlertControlDialog.Builder().setContext(context).setTitle("操作提示") .setMessage("确定要前往吗").setNegativeButton("取消").setPositiveButton("确定") .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { val lat = position.latitude.toString() val lng = position.longitude.toString() if (lat.isBlank() || lng.isBlank()) { "窨井经纬度异常,无法开启导航".show(context) return } RouteOnMap.startNavigation(context, snippet, position) } override fun onCancelClick() { } }).build().show() } } /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() binding.mapView.onResume() } override fun onPause() { super.onPause() binding.mapView.onPause() } override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) binding.mapView.onSaveInstanceState(outState) } override fun onDestroy() { super.onDestroy() binding.mapView.onDestroy() } }