diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index db8a60e..071a613 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -76,6 +76,9 @@ android:name="com.amap.api.v2.apikey" android:value="34064d6fa0c5ebd8ce48599386ce9c3a" /> + + + + + + (), AMap.OnMapLoadedListener, - AMap.OnCameraChangeListener, - AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { + AMap.OnCameraChangeListener, AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { private val kTag = "HomePageFragment" private lateinit var aMap: AMap + private lateinit var deviceViewModel: DeviceViewModel + private val locationHub by lazy { LocationHub.obtainInstance(requireContext()) } + private var deviceInfoModels: MutableList = ArrayList() + private var alarmInfoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 自定义Marker弹出框 + * */ + private var infoWindow: View? = null override fun initViewBinding( - inflater: LayoutInflater, - container: ViewGroup? + inflater: LayoutInflater, container: ViewGroup? ): FragmentHomeBinding { return FragmentHomeBinding.inflate(inflater, container, false) } @@ -31,11 +64,20 @@ } override fun observeRequestState() { + deviceViewModel.loadState.observe(this) { + when (it) { + is LoadState.Loading -> LoadingDialogHub.show( + requireActivity(), "数据加载中,请稍后" + ) + else -> LoadingDialogHub.dismiss() + } + } } override fun initEvent() { - + deviceViewModel.getDevices() + deviceViewModel.getAlarms() } override fun initOnCreate(savedInstanceState: Bundle?) { @@ -44,8 +86,11 @@ aMap.mapType = AMap.MAP_TYPE_SATELLITE val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 + uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER - uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 + uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜 // 地图加载成功监听 aMap.addOnMapLoadedListener(this) @@ -55,10 +100,102 @@ aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup aMap.setInfoWindowAdapter(this) + + //显示定位小蓝点 + val locationStyle = MyLocationStyle() + locationStyle.interval(2000) + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER)//定位、但不会移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + aMap.myLocationStyle = locationStyle//设置定位蓝点的Style + aMap.isMyLocationEnabled = true//设置是否显示定位小蓝点 + aMap.setOnMyLocationChangeListener { + + } + + deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] + deviceViewModel.mapDeviceResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + 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() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + deviceInfoModels.add(device) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(device.deviceName).snippet(device.wellCode) + ) + } + + //移动到指定经纬度 + val centerLatLng = LatLng(latitudeList.average(), longitudeList.average()) + val cameraPosition = CameraPosition(centerLatLng, 16f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + } + } + } + } + deviceViewModel.mapAlarmResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + it.data.forEach { alarm -> + val lat = alarm.latGaode.toString() + val lng = alarm.lngGaode.toString() + if (lat.isNotBlank() && lng.isNotBlank()) { + val latitude = lat.toDouble() + val longitude = lng.toDouble() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + alarmInfoModels.add(alarm) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(alarm.alarmContent).snippet(alarm.alarmId) + ) + } + } + } + } + } + } + + private fun moveToCurrentLocation() { + locationHub.getCurrentLocation(true, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { +// if (location != null) { +// aMap.moveCamera( +// CameraUpdateFactory.newLatLngZoom( +// LatLng(location.latitude, location.longitude), 16f +// ) +// ) +// } else { +// "当前位置信号差,无法移动地图到定位点".show(requireContext()) +// } + } + }) } override fun onMapLoaded() { - + initClustersMarkers() } override fun onCameraChange(p0: CameraPosition?) { @@ -66,15 +203,86 @@ } override fun onCameraChangeFinish(p0: CameraPosition?) { - + initClustersMarkers() } - override fun onMarkerClick(p0: Marker?): Boolean { + private fun initClustersMarkers() { + allMarkerOptions.forEach { + if (it.snippet.startsWith("GX")) { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_device).bitmap + ) + ) + } else { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_alarm).bitmap + ) + ) + } + aMap.addMarker(it) + } + } + + override fun onMarkerClick(marker: Marker?): Boolean { + //显示闸井信息 + marker?.showInfoWindow() return true } - override fun getInfoWindow(p0: Marker?): View? { + 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 wellNameView = v.findViewById(R.id.wellNameView) + val wellCodeView = v.findViewById(R.id.wellCodeView) + val wellTypeView = v.findViewById(R.id.wellTypeView) + val wellStateView = v.findViewById(R.id.wellStateView) + val deepView = v.findViewById(R.id.deepView) + val locationView = v.findViewById(R.id.locationView) + + val clickedMarker = marker?.snippet.toString() + Log.d(kTag, clickedMarker) + + if (clickedMarker.startsWith("GX")) { + //搜设备 + for (device in deviceInfoModels) { + if (clickedMarker == device.devcode) { + + Log.d(kTag, device.toJson()) + + wellNameView.text = String.format("设备名称: ${device.deviceName}") + wellCodeView.text = String.format("设备编号: ${device.devcode}") + wellTypeView.text = String.format("设备类型: ${device.deviceTypeName}") + wellStateView.text = String.format("权属单位: ${device.deptName}") + deepView.text = String.format("更新时间: ${device.realtimeData}") + locationView.text = String.format("详细位置: ${device.position}") + + return infoWindow + } + } + } else { + //搜报警 + for (alarm in alarmInfoModels) { + if (clickedMarker == alarm.alarmId) { + Log.d(kTag, alarm.toJson()) + + wellNameView.text = String.format("报警内容: ${alarm.alarmContent}") + wellCodeView.text = String.format("设备编号: ${alarm.wellCode}") + wellTypeView.text = String.format("设备类型: ${alarm.wellType.valueToType()}") +// wellStateView.text = String.format("布/撤防状态: $bfztName") + deepView.text = String.format("报警时间: ${alarm.alarmTimeDate}") + locationView.text = String.format("详细位置: ${alarm.position}") + + return infoWindow + } + } + } return null } @@ -82,12 +290,14 @@ /** * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框 * */ - override fun getInfoContents(p0: Marker?): View? = null + override fun getInfoContents(marker: Marker?): View? = null /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() binding.mapView.onResume() + //首次移动到定位点 + moveToCurrentLocation() } override fun onPause() { @@ -103,5 +313,6 @@ override fun onDestroy() { super.onDestroy() binding.mapView.onDestroy() + locationHub.stopLocation() } } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index db8a60e..071a613 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -76,6 +76,9 @@ android:name="com.amap.api.v2.apikey" android:value="34064d6fa0c5ebd8ce48599386ce9c3a" /> + + + (), AMap.OnMapLoadedListener, - AMap.OnCameraChangeListener, - AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { + AMap.OnCameraChangeListener, AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { private val kTag = "HomePageFragment" private lateinit var aMap: AMap + private lateinit var deviceViewModel: DeviceViewModel + private val locationHub by lazy { LocationHub.obtainInstance(requireContext()) } + private var deviceInfoModels: MutableList = ArrayList() + private var alarmInfoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 自定义Marker弹出框 + * */ + private var infoWindow: View? = null override fun initViewBinding( - inflater: LayoutInflater, - container: ViewGroup? + inflater: LayoutInflater, container: ViewGroup? ): FragmentHomeBinding { return FragmentHomeBinding.inflate(inflater, container, false) } @@ -31,11 +64,20 @@ } override fun observeRequestState() { + deviceViewModel.loadState.observe(this) { + when (it) { + is LoadState.Loading -> LoadingDialogHub.show( + requireActivity(), "数据加载中,请稍后" + ) + else -> LoadingDialogHub.dismiss() + } + } } override fun initEvent() { - + deviceViewModel.getDevices() + deviceViewModel.getAlarms() } override fun initOnCreate(savedInstanceState: Bundle?) { @@ -44,8 +86,11 @@ aMap.mapType = AMap.MAP_TYPE_SATELLITE val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 + uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER - uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 + uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜 // 地图加载成功监听 aMap.addOnMapLoadedListener(this) @@ -55,10 +100,102 @@ aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup aMap.setInfoWindowAdapter(this) + + //显示定位小蓝点 + val locationStyle = MyLocationStyle() + locationStyle.interval(2000) + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER)//定位、但不会移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + aMap.myLocationStyle = locationStyle//设置定位蓝点的Style + aMap.isMyLocationEnabled = true//设置是否显示定位小蓝点 + aMap.setOnMyLocationChangeListener { + + } + + deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] + deviceViewModel.mapDeviceResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + 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() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + deviceInfoModels.add(device) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(device.deviceName).snippet(device.wellCode) + ) + } + + //移动到指定经纬度 + val centerLatLng = LatLng(latitudeList.average(), longitudeList.average()) + val cameraPosition = CameraPosition(centerLatLng, 16f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + } + } + } + } + deviceViewModel.mapAlarmResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + it.data.forEach { alarm -> + val lat = alarm.latGaode.toString() + val lng = alarm.lngGaode.toString() + if (lat.isNotBlank() && lng.isNotBlank()) { + val latitude = lat.toDouble() + val longitude = lng.toDouble() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + alarmInfoModels.add(alarm) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(alarm.alarmContent).snippet(alarm.alarmId) + ) + } + } + } + } + } + } + + private fun moveToCurrentLocation() { + locationHub.getCurrentLocation(true, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { +// if (location != null) { +// aMap.moveCamera( +// CameraUpdateFactory.newLatLngZoom( +// LatLng(location.latitude, location.longitude), 16f +// ) +// ) +// } else { +// "当前位置信号差,无法移动地图到定位点".show(requireContext()) +// } + } + }) } override fun onMapLoaded() { - + initClustersMarkers() } override fun onCameraChange(p0: CameraPosition?) { @@ -66,15 +203,86 @@ } override fun onCameraChangeFinish(p0: CameraPosition?) { - + initClustersMarkers() } - override fun onMarkerClick(p0: Marker?): Boolean { + private fun initClustersMarkers() { + allMarkerOptions.forEach { + if (it.snippet.startsWith("GX")) { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_device).bitmap + ) + ) + } else { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_alarm).bitmap + ) + ) + } + aMap.addMarker(it) + } + } + + override fun onMarkerClick(marker: Marker?): Boolean { + //显示闸井信息 + marker?.showInfoWindow() return true } - override fun getInfoWindow(p0: Marker?): View? { + 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 wellNameView = v.findViewById(R.id.wellNameView) + val wellCodeView = v.findViewById(R.id.wellCodeView) + val wellTypeView = v.findViewById(R.id.wellTypeView) + val wellStateView = v.findViewById(R.id.wellStateView) + val deepView = v.findViewById(R.id.deepView) + val locationView = v.findViewById(R.id.locationView) + + val clickedMarker = marker?.snippet.toString() + Log.d(kTag, clickedMarker) + + if (clickedMarker.startsWith("GX")) { + //搜设备 + for (device in deviceInfoModels) { + if (clickedMarker == device.devcode) { + + Log.d(kTag, device.toJson()) + + wellNameView.text = String.format("设备名称: ${device.deviceName}") + wellCodeView.text = String.format("设备编号: ${device.devcode}") + wellTypeView.text = String.format("设备类型: ${device.deviceTypeName}") + wellStateView.text = String.format("权属单位: ${device.deptName}") + deepView.text = String.format("更新时间: ${device.realtimeData}") + locationView.text = String.format("详细位置: ${device.position}") + + return infoWindow + } + } + } else { + //搜报警 + for (alarm in alarmInfoModels) { + if (clickedMarker == alarm.alarmId) { + Log.d(kTag, alarm.toJson()) + + wellNameView.text = String.format("报警内容: ${alarm.alarmContent}") + wellCodeView.text = String.format("设备编号: ${alarm.wellCode}") + wellTypeView.text = String.format("设备类型: ${alarm.wellType.valueToType()}") +// wellStateView.text = String.format("布/撤防状态: $bfztName") + deepView.text = String.format("报警时间: ${alarm.alarmTimeDate}") + locationView.text = String.format("详细位置: ${alarm.position}") + + return infoWindow + } + } + } return null } @@ -82,12 +290,14 @@ /** * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框 * */ - override fun getInfoContents(p0: Marker?): View? = null + override fun getInfoContents(marker: Marker?): View? = null /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() binding.mapView.onResume() + //首次移动到定位点 + moveToCurrentLocation() } override fun onPause() { @@ -103,5 +313,6 @@ override fun onDestroy() { super.onDestroy() binding.mapView.onDestroy() + locationHub.stopLocation() } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java new file mode 100644 index 0000000..2edc0f2 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java @@ -0,0 +1,226 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapAlarmModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String alarmContent; + private String alarmId; + private String alarmTimeDate; + private String alarmType; + private String alarmValue; + private String coordinateX; + private String coordinateY; + private String deptid; + private String devcode; + private String deviceId; + private String deviceType; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String position; + private String wellCode; + private String wellId; + private String wellType; + private String wellTypeName; + + public String getAlarmContent() { + return alarmContent; + } + + public void setAlarmContent(String alarmContent) { + this.alarmContent = alarmContent; + } + + public String getAlarmId() { + return alarmId; + } + + public void setAlarmId(String alarmId) { + this.alarmId = alarmId; + } + + public String getAlarmTimeDate() { + return alarmTimeDate; + } + + public void setAlarmTimeDate(String alarmTimeDate) { + this.alarmTimeDate = alarmTimeDate; + } + + public String getAlarmType() { + return alarmType; + } + + public void setAlarmType(String alarmType) { + this.alarmType = alarmType; + } + + public String getAlarmValue() { + return alarmValue; + } + + public void setAlarmValue(String alarmValue) { + this.alarmValue = alarmValue; + } + + 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 getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + 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 getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getWellId() { + return wellId; + } + + public void setWellId(String wellId) { + this.wellId = wellId; + } + + 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 db8a60e..071a613 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -76,6 +76,9 @@ android:name="com.amap.api.v2.apikey" android:value="34064d6fa0c5ebd8ce48599386ce9c3a" /> + + + (), AMap.OnMapLoadedListener, - AMap.OnCameraChangeListener, - AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { + AMap.OnCameraChangeListener, AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { private val kTag = "HomePageFragment" private lateinit var aMap: AMap + private lateinit var deviceViewModel: DeviceViewModel + private val locationHub by lazy { LocationHub.obtainInstance(requireContext()) } + private var deviceInfoModels: MutableList = ArrayList() + private var alarmInfoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 自定义Marker弹出框 + * */ + private var infoWindow: View? = null override fun initViewBinding( - inflater: LayoutInflater, - container: ViewGroup? + inflater: LayoutInflater, container: ViewGroup? ): FragmentHomeBinding { return FragmentHomeBinding.inflate(inflater, container, false) } @@ -31,11 +64,20 @@ } override fun observeRequestState() { + deviceViewModel.loadState.observe(this) { + when (it) { + is LoadState.Loading -> LoadingDialogHub.show( + requireActivity(), "数据加载中,请稍后" + ) + else -> LoadingDialogHub.dismiss() + } + } } override fun initEvent() { - + deviceViewModel.getDevices() + deviceViewModel.getAlarms() } override fun initOnCreate(savedInstanceState: Bundle?) { @@ -44,8 +86,11 @@ aMap.mapType = AMap.MAP_TYPE_SATELLITE val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 + uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER - uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 + uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜 // 地图加载成功监听 aMap.addOnMapLoadedListener(this) @@ -55,10 +100,102 @@ aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup aMap.setInfoWindowAdapter(this) + + //显示定位小蓝点 + val locationStyle = MyLocationStyle() + locationStyle.interval(2000) + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER)//定位、但不会移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + aMap.myLocationStyle = locationStyle//设置定位蓝点的Style + aMap.isMyLocationEnabled = true//设置是否显示定位小蓝点 + aMap.setOnMyLocationChangeListener { + + } + + deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] + deviceViewModel.mapDeviceResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + 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() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + deviceInfoModels.add(device) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(device.deviceName).snippet(device.wellCode) + ) + } + + //移动到指定经纬度 + val centerLatLng = LatLng(latitudeList.average(), longitudeList.average()) + val cameraPosition = CameraPosition(centerLatLng, 16f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + } + } + } + } + deviceViewModel.mapAlarmResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + it.data.forEach { alarm -> + val lat = alarm.latGaode.toString() + val lng = alarm.lngGaode.toString() + if (lat.isNotBlank() && lng.isNotBlank()) { + val latitude = lat.toDouble() + val longitude = lng.toDouble() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + alarmInfoModels.add(alarm) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(alarm.alarmContent).snippet(alarm.alarmId) + ) + } + } + } + } + } + } + + private fun moveToCurrentLocation() { + locationHub.getCurrentLocation(true, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { +// if (location != null) { +// aMap.moveCamera( +// CameraUpdateFactory.newLatLngZoom( +// LatLng(location.latitude, location.longitude), 16f +// ) +// ) +// } else { +// "当前位置信号差,无法移动地图到定位点".show(requireContext()) +// } + } + }) } override fun onMapLoaded() { - + initClustersMarkers() } override fun onCameraChange(p0: CameraPosition?) { @@ -66,15 +203,86 @@ } override fun onCameraChangeFinish(p0: CameraPosition?) { - + initClustersMarkers() } - override fun onMarkerClick(p0: Marker?): Boolean { + private fun initClustersMarkers() { + allMarkerOptions.forEach { + if (it.snippet.startsWith("GX")) { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_device).bitmap + ) + ) + } else { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_alarm).bitmap + ) + ) + } + aMap.addMarker(it) + } + } + + override fun onMarkerClick(marker: Marker?): Boolean { + //显示闸井信息 + marker?.showInfoWindow() return true } - override fun getInfoWindow(p0: Marker?): View? { + 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 wellNameView = v.findViewById(R.id.wellNameView) + val wellCodeView = v.findViewById(R.id.wellCodeView) + val wellTypeView = v.findViewById(R.id.wellTypeView) + val wellStateView = v.findViewById(R.id.wellStateView) + val deepView = v.findViewById(R.id.deepView) + val locationView = v.findViewById(R.id.locationView) + + val clickedMarker = marker?.snippet.toString() + Log.d(kTag, clickedMarker) + + if (clickedMarker.startsWith("GX")) { + //搜设备 + for (device in deviceInfoModels) { + if (clickedMarker == device.devcode) { + + Log.d(kTag, device.toJson()) + + wellNameView.text = String.format("设备名称: ${device.deviceName}") + wellCodeView.text = String.format("设备编号: ${device.devcode}") + wellTypeView.text = String.format("设备类型: ${device.deviceTypeName}") + wellStateView.text = String.format("权属单位: ${device.deptName}") + deepView.text = String.format("更新时间: ${device.realtimeData}") + locationView.text = String.format("详细位置: ${device.position}") + + return infoWindow + } + } + } else { + //搜报警 + for (alarm in alarmInfoModels) { + if (clickedMarker == alarm.alarmId) { + Log.d(kTag, alarm.toJson()) + + wellNameView.text = String.format("报警内容: ${alarm.alarmContent}") + wellCodeView.text = String.format("设备编号: ${alarm.wellCode}") + wellTypeView.text = String.format("设备类型: ${alarm.wellType.valueToType()}") +// wellStateView.text = String.format("布/撤防状态: $bfztName") + deepView.text = String.format("报警时间: ${alarm.alarmTimeDate}") + locationView.text = String.format("详细位置: ${alarm.position}") + + return infoWindow + } + } + } return null } @@ -82,12 +290,14 @@ /** * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框 * */ - override fun getInfoContents(p0: Marker?): View? = null + override fun getInfoContents(marker: Marker?): View? = null /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() binding.mapView.onResume() + //首次移动到定位点 + moveToCurrentLocation() } override fun onPause() { @@ -103,5 +313,6 @@ override fun onDestroy() { super.onDestroy() binding.mapView.onDestroy() + locationHub.stopLocation() } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java new file mode 100644 index 0000000..2edc0f2 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java @@ -0,0 +1,226 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapAlarmModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String alarmContent; + private String alarmId; + private String alarmTimeDate; + private String alarmType; + private String alarmValue; + private String coordinateX; + private String coordinateY; + private String deptid; + private String devcode; + private String deviceId; + private String deviceType; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String position; + private String wellCode; + private String wellId; + private String wellType; + private String wellTypeName; + + public String getAlarmContent() { + return alarmContent; + } + + public void setAlarmContent(String alarmContent) { + this.alarmContent = alarmContent; + } + + public String getAlarmId() { + return alarmId; + } + + public void setAlarmId(String alarmId) { + this.alarmId = alarmId; + } + + public String getAlarmTimeDate() { + return alarmTimeDate; + } + + public void setAlarmTimeDate(String alarmTimeDate) { + this.alarmTimeDate = alarmTimeDate; + } + + public String getAlarmType() { + return alarmType; + } + + public void setAlarmType(String alarmType) { + this.alarmType = alarmType; + } + + public String getAlarmValue() { + return alarmValue; + } + + public void setAlarmValue(String alarmValue) { + this.alarmValue = alarmValue; + } + + 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 getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + 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 getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getWellId() { + return wellId; + } + + public void setWellId(String wellId) { + this.wellId = wellId; + } + + 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/smart/town/sanxi/model/MapDeviceModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java new file mode 100644 index 0000000..59b6882 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java @@ -0,0 +1,199 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapDeviceModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String coordinateX; + private String coordinateY; + private String deptName; + private String deptid; + private String devcode; + private String deviceName; + private String deviceType; + private String deviceTypeName; + private String id; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String onlineState; + private String position; + private String realtimeData; + private String wellCode; + + 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 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 getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + 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 getOnlineState() { + return onlineState; + } + + public void setOnlineState(String onlineState) { + this.onlineState = onlineState; + } + + public String getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getRealtimeData() { + return realtimeData; + } + + public void setRealtimeData(String realtimeData) { + this.realtimeData = realtimeData; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index db8a60e..071a613 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -76,6 +76,9 @@ android:name="com.amap.api.v2.apikey" android:value="34064d6fa0c5ebd8ce48599386ce9c3a" /> + + + (), AMap.OnMapLoadedListener, - AMap.OnCameraChangeListener, - AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { + AMap.OnCameraChangeListener, AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { private val kTag = "HomePageFragment" private lateinit var aMap: AMap + private lateinit var deviceViewModel: DeviceViewModel + private val locationHub by lazy { LocationHub.obtainInstance(requireContext()) } + private var deviceInfoModels: MutableList = ArrayList() + private var alarmInfoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 自定义Marker弹出框 + * */ + private var infoWindow: View? = null override fun initViewBinding( - inflater: LayoutInflater, - container: ViewGroup? + inflater: LayoutInflater, container: ViewGroup? ): FragmentHomeBinding { return FragmentHomeBinding.inflate(inflater, container, false) } @@ -31,11 +64,20 @@ } override fun observeRequestState() { + deviceViewModel.loadState.observe(this) { + when (it) { + is LoadState.Loading -> LoadingDialogHub.show( + requireActivity(), "数据加载中,请稍后" + ) + else -> LoadingDialogHub.dismiss() + } + } } override fun initEvent() { - + deviceViewModel.getDevices() + deviceViewModel.getAlarms() } override fun initOnCreate(savedInstanceState: Bundle?) { @@ -44,8 +86,11 @@ aMap.mapType = AMap.MAP_TYPE_SATELLITE val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 + uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER - uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 + uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜 // 地图加载成功监听 aMap.addOnMapLoadedListener(this) @@ -55,10 +100,102 @@ aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup aMap.setInfoWindowAdapter(this) + + //显示定位小蓝点 + val locationStyle = MyLocationStyle() + locationStyle.interval(2000) + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER)//定位、但不会移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + aMap.myLocationStyle = locationStyle//设置定位蓝点的Style + aMap.isMyLocationEnabled = true//设置是否显示定位小蓝点 + aMap.setOnMyLocationChangeListener { + + } + + deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] + deviceViewModel.mapDeviceResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + 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() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + deviceInfoModels.add(device) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(device.deviceName).snippet(device.wellCode) + ) + } + + //移动到指定经纬度 + val centerLatLng = LatLng(latitudeList.average(), longitudeList.average()) + val cameraPosition = CameraPosition(centerLatLng, 16f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + } + } + } + } + deviceViewModel.mapAlarmResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + it.data.forEach { alarm -> + val lat = alarm.latGaode.toString() + val lng = alarm.lngGaode.toString() + if (lat.isNotBlank() && lng.isNotBlank()) { + val latitude = lat.toDouble() + val longitude = lng.toDouble() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + alarmInfoModels.add(alarm) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(alarm.alarmContent).snippet(alarm.alarmId) + ) + } + } + } + } + } + } + + private fun moveToCurrentLocation() { + locationHub.getCurrentLocation(true, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { +// if (location != null) { +// aMap.moveCamera( +// CameraUpdateFactory.newLatLngZoom( +// LatLng(location.latitude, location.longitude), 16f +// ) +// ) +// } else { +// "当前位置信号差,无法移动地图到定位点".show(requireContext()) +// } + } + }) } override fun onMapLoaded() { - + initClustersMarkers() } override fun onCameraChange(p0: CameraPosition?) { @@ -66,15 +203,86 @@ } override fun onCameraChangeFinish(p0: CameraPosition?) { - + initClustersMarkers() } - override fun onMarkerClick(p0: Marker?): Boolean { + private fun initClustersMarkers() { + allMarkerOptions.forEach { + if (it.snippet.startsWith("GX")) { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_device).bitmap + ) + ) + } else { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_alarm).bitmap + ) + ) + } + aMap.addMarker(it) + } + } + + override fun onMarkerClick(marker: Marker?): Boolean { + //显示闸井信息 + marker?.showInfoWindow() return true } - override fun getInfoWindow(p0: Marker?): View? { + 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 wellNameView = v.findViewById(R.id.wellNameView) + val wellCodeView = v.findViewById(R.id.wellCodeView) + val wellTypeView = v.findViewById(R.id.wellTypeView) + val wellStateView = v.findViewById(R.id.wellStateView) + val deepView = v.findViewById(R.id.deepView) + val locationView = v.findViewById(R.id.locationView) + + val clickedMarker = marker?.snippet.toString() + Log.d(kTag, clickedMarker) + + if (clickedMarker.startsWith("GX")) { + //搜设备 + for (device in deviceInfoModels) { + if (clickedMarker == device.devcode) { + + Log.d(kTag, device.toJson()) + + wellNameView.text = String.format("设备名称: ${device.deviceName}") + wellCodeView.text = String.format("设备编号: ${device.devcode}") + wellTypeView.text = String.format("设备类型: ${device.deviceTypeName}") + wellStateView.text = String.format("权属单位: ${device.deptName}") + deepView.text = String.format("更新时间: ${device.realtimeData}") + locationView.text = String.format("详细位置: ${device.position}") + + return infoWindow + } + } + } else { + //搜报警 + for (alarm in alarmInfoModels) { + if (clickedMarker == alarm.alarmId) { + Log.d(kTag, alarm.toJson()) + + wellNameView.text = String.format("报警内容: ${alarm.alarmContent}") + wellCodeView.text = String.format("设备编号: ${alarm.wellCode}") + wellTypeView.text = String.format("设备类型: ${alarm.wellType.valueToType()}") +// wellStateView.text = String.format("布/撤防状态: $bfztName") + deepView.text = String.format("报警时间: ${alarm.alarmTimeDate}") + locationView.text = String.format("详细位置: ${alarm.position}") + + return infoWindow + } + } + } return null } @@ -82,12 +290,14 @@ /** * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框 * */ - override fun getInfoContents(p0: Marker?): View? = null + override fun getInfoContents(marker: Marker?): View? = null /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() binding.mapView.onResume() + //首次移动到定位点 + moveToCurrentLocation() } override fun onPause() { @@ -103,5 +313,6 @@ override fun onDestroy() { super.onDestroy() binding.mapView.onDestroy() + locationHub.stopLocation() } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java new file mode 100644 index 0000000..2edc0f2 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java @@ -0,0 +1,226 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapAlarmModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String alarmContent; + private String alarmId; + private String alarmTimeDate; + private String alarmType; + private String alarmValue; + private String coordinateX; + private String coordinateY; + private String deptid; + private String devcode; + private String deviceId; + private String deviceType; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String position; + private String wellCode; + private String wellId; + private String wellType; + private String wellTypeName; + + public String getAlarmContent() { + return alarmContent; + } + + public void setAlarmContent(String alarmContent) { + this.alarmContent = alarmContent; + } + + public String getAlarmId() { + return alarmId; + } + + public void setAlarmId(String alarmId) { + this.alarmId = alarmId; + } + + public String getAlarmTimeDate() { + return alarmTimeDate; + } + + public void setAlarmTimeDate(String alarmTimeDate) { + this.alarmTimeDate = alarmTimeDate; + } + + public String getAlarmType() { + return alarmType; + } + + public void setAlarmType(String alarmType) { + this.alarmType = alarmType; + } + + public String getAlarmValue() { + return alarmValue; + } + + public void setAlarmValue(String alarmValue) { + this.alarmValue = alarmValue; + } + + 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 getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + 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 getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getWellId() { + return wellId; + } + + public void setWellId(String wellId) { + this.wellId = wellId; + } + + 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/smart/town/sanxi/model/MapDeviceModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java new file mode 100644 index 0000000..59b6882 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java @@ -0,0 +1,199 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapDeviceModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String coordinateX; + private String coordinateY; + private String deptName; + private String deptid; + private String devcode; + private String deviceName; + private String deviceType; + private String deviceTypeName; + private String id; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String onlineState; + private String position; + private String realtimeData; + private String wellCode; + + 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 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 getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + 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 getOnlineState() { + return onlineState; + } + + public void setOnlineState(String onlineState) { + this.onlineState = onlineState; + } + + public String getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getRealtimeData() { + return realtimeData; + } + + public void setRealtimeData(String realtimeData) { + this.realtimeData = realtimeData; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + } +} diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt new file mode 100644 index 0000000..afdd3de --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt @@ -0,0 +1,7 @@ +package com.casic.smart.town.sanxi.util + +import com.amap.api.location.AMapLocation + +interface ILocationListener { + fun onAMapLocationGet(location: AMapLocation?) //高德定位数据 +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index db8a60e..071a613 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -76,6 +76,9 @@ android:name="com.amap.api.v2.apikey" android:value="34064d6fa0c5ebd8ce48599386ce9c3a" /> + + + (), AMap.OnMapLoadedListener, - AMap.OnCameraChangeListener, - AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { + AMap.OnCameraChangeListener, AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { private val kTag = "HomePageFragment" private lateinit var aMap: AMap + private lateinit var deviceViewModel: DeviceViewModel + private val locationHub by lazy { LocationHub.obtainInstance(requireContext()) } + private var deviceInfoModels: MutableList = ArrayList() + private var alarmInfoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 自定义Marker弹出框 + * */ + private var infoWindow: View? = null override fun initViewBinding( - inflater: LayoutInflater, - container: ViewGroup? + inflater: LayoutInflater, container: ViewGroup? ): FragmentHomeBinding { return FragmentHomeBinding.inflate(inflater, container, false) } @@ -31,11 +64,20 @@ } override fun observeRequestState() { + deviceViewModel.loadState.observe(this) { + when (it) { + is LoadState.Loading -> LoadingDialogHub.show( + requireActivity(), "数据加载中,请稍后" + ) + else -> LoadingDialogHub.dismiss() + } + } } override fun initEvent() { - + deviceViewModel.getDevices() + deviceViewModel.getAlarms() } override fun initOnCreate(savedInstanceState: Bundle?) { @@ -44,8 +86,11 @@ aMap.mapType = AMap.MAP_TYPE_SATELLITE val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 + uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER - uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 + uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜 // 地图加载成功监听 aMap.addOnMapLoadedListener(this) @@ -55,10 +100,102 @@ aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup aMap.setInfoWindowAdapter(this) + + //显示定位小蓝点 + val locationStyle = MyLocationStyle() + locationStyle.interval(2000) + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER)//定位、但不会移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + aMap.myLocationStyle = locationStyle//设置定位蓝点的Style + aMap.isMyLocationEnabled = true//设置是否显示定位小蓝点 + aMap.setOnMyLocationChangeListener { + + } + + deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] + deviceViewModel.mapDeviceResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + 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() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + deviceInfoModels.add(device) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(device.deviceName).snippet(device.wellCode) + ) + } + + //移动到指定经纬度 + val centerLatLng = LatLng(latitudeList.average(), longitudeList.average()) + val cameraPosition = CameraPosition(centerLatLng, 16f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + } + } + } + } + deviceViewModel.mapAlarmResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + it.data.forEach { alarm -> + val lat = alarm.latGaode.toString() + val lng = alarm.lngGaode.toString() + if (lat.isNotBlank() && lng.isNotBlank()) { + val latitude = lat.toDouble() + val longitude = lng.toDouble() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + alarmInfoModels.add(alarm) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(alarm.alarmContent).snippet(alarm.alarmId) + ) + } + } + } + } + } + } + + private fun moveToCurrentLocation() { + locationHub.getCurrentLocation(true, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { +// if (location != null) { +// aMap.moveCamera( +// CameraUpdateFactory.newLatLngZoom( +// LatLng(location.latitude, location.longitude), 16f +// ) +// ) +// } else { +// "当前位置信号差,无法移动地图到定位点".show(requireContext()) +// } + } + }) } override fun onMapLoaded() { - + initClustersMarkers() } override fun onCameraChange(p0: CameraPosition?) { @@ -66,15 +203,86 @@ } override fun onCameraChangeFinish(p0: CameraPosition?) { - + initClustersMarkers() } - override fun onMarkerClick(p0: Marker?): Boolean { + private fun initClustersMarkers() { + allMarkerOptions.forEach { + if (it.snippet.startsWith("GX")) { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_device).bitmap + ) + ) + } else { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_alarm).bitmap + ) + ) + } + aMap.addMarker(it) + } + } + + override fun onMarkerClick(marker: Marker?): Boolean { + //显示闸井信息 + marker?.showInfoWindow() return true } - override fun getInfoWindow(p0: Marker?): View? { + 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 wellNameView = v.findViewById(R.id.wellNameView) + val wellCodeView = v.findViewById(R.id.wellCodeView) + val wellTypeView = v.findViewById(R.id.wellTypeView) + val wellStateView = v.findViewById(R.id.wellStateView) + val deepView = v.findViewById(R.id.deepView) + val locationView = v.findViewById(R.id.locationView) + + val clickedMarker = marker?.snippet.toString() + Log.d(kTag, clickedMarker) + + if (clickedMarker.startsWith("GX")) { + //搜设备 + for (device in deviceInfoModels) { + if (clickedMarker == device.devcode) { + + Log.d(kTag, device.toJson()) + + wellNameView.text = String.format("设备名称: ${device.deviceName}") + wellCodeView.text = String.format("设备编号: ${device.devcode}") + wellTypeView.text = String.format("设备类型: ${device.deviceTypeName}") + wellStateView.text = String.format("权属单位: ${device.deptName}") + deepView.text = String.format("更新时间: ${device.realtimeData}") + locationView.text = String.format("详细位置: ${device.position}") + + return infoWindow + } + } + } else { + //搜报警 + for (alarm in alarmInfoModels) { + if (clickedMarker == alarm.alarmId) { + Log.d(kTag, alarm.toJson()) + + wellNameView.text = String.format("报警内容: ${alarm.alarmContent}") + wellCodeView.text = String.format("设备编号: ${alarm.wellCode}") + wellTypeView.text = String.format("设备类型: ${alarm.wellType.valueToType()}") +// wellStateView.text = String.format("布/撤防状态: $bfztName") + deepView.text = String.format("报警时间: ${alarm.alarmTimeDate}") + locationView.text = String.format("详细位置: ${alarm.position}") + + return infoWindow + } + } + } return null } @@ -82,12 +290,14 @@ /** * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框 * */ - override fun getInfoContents(p0: Marker?): View? = null + override fun getInfoContents(marker: Marker?): View? = null /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() binding.mapView.onResume() + //首次移动到定位点 + moveToCurrentLocation() } override fun onPause() { @@ -103,5 +313,6 @@ override fun onDestroy() { super.onDestroy() binding.mapView.onDestroy() + locationHub.stopLocation() } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java new file mode 100644 index 0000000..2edc0f2 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java @@ -0,0 +1,226 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapAlarmModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String alarmContent; + private String alarmId; + private String alarmTimeDate; + private String alarmType; + private String alarmValue; + private String coordinateX; + private String coordinateY; + private String deptid; + private String devcode; + private String deviceId; + private String deviceType; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String position; + private String wellCode; + private String wellId; + private String wellType; + private String wellTypeName; + + public String getAlarmContent() { + return alarmContent; + } + + public void setAlarmContent(String alarmContent) { + this.alarmContent = alarmContent; + } + + public String getAlarmId() { + return alarmId; + } + + public void setAlarmId(String alarmId) { + this.alarmId = alarmId; + } + + public String getAlarmTimeDate() { + return alarmTimeDate; + } + + public void setAlarmTimeDate(String alarmTimeDate) { + this.alarmTimeDate = alarmTimeDate; + } + + public String getAlarmType() { + return alarmType; + } + + public void setAlarmType(String alarmType) { + this.alarmType = alarmType; + } + + public String getAlarmValue() { + return alarmValue; + } + + public void setAlarmValue(String alarmValue) { + this.alarmValue = alarmValue; + } + + 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 getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + 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 getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getWellId() { + return wellId; + } + + public void setWellId(String wellId) { + this.wellId = wellId; + } + + 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/smart/town/sanxi/model/MapDeviceModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java new file mode 100644 index 0000000..59b6882 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java @@ -0,0 +1,199 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapDeviceModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String coordinateX; + private String coordinateY; + private String deptName; + private String deptid; + private String devcode; + private String deviceName; + private String deviceType; + private String deviceTypeName; + private String id; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String onlineState; + private String position; + private String realtimeData; + private String wellCode; + + 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 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 getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + 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 getOnlineState() { + return onlineState; + } + + public void setOnlineState(String onlineState) { + this.onlineState = onlineState; + } + + public String getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getRealtimeData() { + return realtimeData; + } + + public void setRealtimeData(String realtimeData) { + this.realtimeData = realtimeData; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + } +} diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt new file mode 100644 index 0000000..afdd3de --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt @@ -0,0 +1,7 @@ +package com.casic.smart.town.sanxi.util + +import com.amap.api.location.AMapLocation + +interface ILocationListener { + fun onAMapLocationGet(location: AMapLocation?) //高德定位数据 +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt new file mode 100644 index 0000000..ff813b9 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt @@ -0,0 +1,40 @@ +package com.casic.smart.town.sanxi.util + +import android.content.Context +import android.util.Log +import com.amap.api.location.AMapLocationClient +import com.amap.api.location.AMapLocationClientOption +import com.pengxh.kt.lite.base.BaseSingleton + +class LocationHub private constructor(context: Context) { + + companion object : BaseSingleton() { + override val creator: (Context) -> LocationHub + get() = ::LocationHub + } + + private val kTag = "LocationHub" + private val locationClient by lazy { AMapLocationClient(context) } + + fun getCurrentLocation(isOnceLocation: Boolean, listener: ILocationListener) { + val locationOption = AMapLocationClientOption() + locationOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy + locationOption.isOnceLocation = isOnceLocation + locationClient.setLocationOption(locationOption) + locationClient.setLocationListener { + if (it.errorCode == 0) { + listener.onAMapLocationGet(it) + } else { + listener.onAMapLocationGet(null) + Log.e( + kTag, "location Error, ErrCode:${it.errorCode}, errInfo:${it.errorInfo}" + ) + } + } + locationClient.startLocation() + } + + fun stopLocation() { + locationClient.stopLocation() + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index db8a60e..071a613 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -76,6 +76,9 @@ android:name="com.amap.api.v2.apikey" android:value="34064d6fa0c5ebd8ce48599386ce9c3a" /> + + + (), AMap.OnMapLoadedListener, - AMap.OnCameraChangeListener, - AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { + AMap.OnCameraChangeListener, AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { private val kTag = "HomePageFragment" private lateinit var aMap: AMap + private lateinit var deviceViewModel: DeviceViewModel + private val locationHub by lazy { LocationHub.obtainInstance(requireContext()) } + private var deviceInfoModels: MutableList = ArrayList() + private var alarmInfoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 自定义Marker弹出框 + * */ + private var infoWindow: View? = null override fun initViewBinding( - inflater: LayoutInflater, - container: ViewGroup? + inflater: LayoutInflater, container: ViewGroup? ): FragmentHomeBinding { return FragmentHomeBinding.inflate(inflater, container, false) } @@ -31,11 +64,20 @@ } override fun observeRequestState() { + deviceViewModel.loadState.observe(this) { + when (it) { + is LoadState.Loading -> LoadingDialogHub.show( + requireActivity(), "数据加载中,请稍后" + ) + else -> LoadingDialogHub.dismiss() + } + } } override fun initEvent() { - + deviceViewModel.getDevices() + deviceViewModel.getAlarms() } override fun initOnCreate(savedInstanceState: Bundle?) { @@ -44,8 +86,11 @@ aMap.mapType = AMap.MAP_TYPE_SATELLITE val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 + uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER - uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 + uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜 // 地图加载成功监听 aMap.addOnMapLoadedListener(this) @@ -55,10 +100,102 @@ aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup aMap.setInfoWindowAdapter(this) + + //显示定位小蓝点 + val locationStyle = MyLocationStyle() + locationStyle.interval(2000) + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER)//定位、但不会移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + aMap.myLocationStyle = locationStyle//设置定位蓝点的Style + aMap.isMyLocationEnabled = true//设置是否显示定位小蓝点 + aMap.setOnMyLocationChangeListener { + + } + + deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] + deviceViewModel.mapDeviceResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + 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() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + deviceInfoModels.add(device) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(device.deviceName).snippet(device.wellCode) + ) + } + + //移动到指定经纬度 + val centerLatLng = LatLng(latitudeList.average(), longitudeList.average()) + val cameraPosition = CameraPosition(centerLatLng, 16f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + } + } + } + } + deviceViewModel.mapAlarmResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + it.data.forEach { alarm -> + val lat = alarm.latGaode.toString() + val lng = alarm.lngGaode.toString() + if (lat.isNotBlank() && lng.isNotBlank()) { + val latitude = lat.toDouble() + val longitude = lng.toDouble() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + alarmInfoModels.add(alarm) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(alarm.alarmContent).snippet(alarm.alarmId) + ) + } + } + } + } + } + } + + private fun moveToCurrentLocation() { + locationHub.getCurrentLocation(true, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { +// if (location != null) { +// aMap.moveCamera( +// CameraUpdateFactory.newLatLngZoom( +// LatLng(location.latitude, location.longitude), 16f +// ) +// ) +// } else { +// "当前位置信号差,无法移动地图到定位点".show(requireContext()) +// } + } + }) } override fun onMapLoaded() { - + initClustersMarkers() } override fun onCameraChange(p0: CameraPosition?) { @@ -66,15 +203,86 @@ } override fun onCameraChangeFinish(p0: CameraPosition?) { - + initClustersMarkers() } - override fun onMarkerClick(p0: Marker?): Boolean { + private fun initClustersMarkers() { + allMarkerOptions.forEach { + if (it.snippet.startsWith("GX")) { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_device).bitmap + ) + ) + } else { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_alarm).bitmap + ) + ) + } + aMap.addMarker(it) + } + } + + override fun onMarkerClick(marker: Marker?): Boolean { + //显示闸井信息 + marker?.showInfoWindow() return true } - override fun getInfoWindow(p0: Marker?): View? { + 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 wellNameView = v.findViewById(R.id.wellNameView) + val wellCodeView = v.findViewById(R.id.wellCodeView) + val wellTypeView = v.findViewById(R.id.wellTypeView) + val wellStateView = v.findViewById(R.id.wellStateView) + val deepView = v.findViewById(R.id.deepView) + val locationView = v.findViewById(R.id.locationView) + + val clickedMarker = marker?.snippet.toString() + Log.d(kTag, clickedMarker) + + if (clickedMarker.startsWith("GX")) { + //搜设备 + for (device in deviceInfoModels) { + if (clickedMarker == device.devcode) { + + Log.d(kTag, device.toJson()) + + wellNameView.text = String.format("设备名称: ${device.deviceName}") + wellCodeView.text = String.format("设备编号: ${device.devcode}") + wellTypeView.text = String.format("设备类型: ${device.deviceTypeName}") + wellStateView.text = String.format("权属单位: ${device.deptName}") + deepView.text = String.format("更新时间: ${device.realtimeData}") + locationView.text = String.format("详细位置: ${device.position}") + + return infoWindow + } + } + } else { + //搜报警 + for (alarm in alarmInfoModels) { + if (clickedMarker == alarm.alarmId) { + Log.d(kTag, alarm.toJson()) + + wellNameView.text = String.format("报警内容: ${alarm.alarmContent}") + wellCodeView.text = String.format("设备编号: ${alarm.wellCode}") + wellTypeView.text = String.format("设备类型: ${alarm.wellType.valueToType()}") +// wellStateView.text = String.format("布/撤防状态: $bfztName") + deepView.text = String.format("报警时间: ${alarm.alarmTimeDate}") + locationView.text = String.format("详细位置: ${alarm.position}") + + return infoWindow + } + } + } return null } @@ -82,12 +290,14 @@ /** * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框 * */ - override fun getInfoContents(p0: Marker?): View? = null + override fun getInfoContents(marker: Marker?): View? = null /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() binding.mapView.onResume() + //首次移动到定位点 + moveToCurrentLocation() } override fun onPause() { @@ -103,5 +313,6 @@ override fun onDestroy() { super.onDestroy() binding.mapView.onDestroy() + locationHub.stopLocation() } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java new file mode 100644 index 0000000..2edc0f2 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java @@ -0,0 +1,226 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapAlarmModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String alarmContent; + private String alarmId; + private String alarmTimeDate; + private String alarmType; + private String alarmValue; + private String coordinateX; + private String coordinateY; + private String deptid; + private String devcode; + private String deviceId; + private String deviceType; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String position; + private String wellCode; + private String wellId; + private String wellType; + private String wellTypeName; + + public String getAlarmContent() { + return alarmContent; + } + + public void setAlarmContent(String alarmContent) { + this.alarmContent = alarmContent; + } + + public String getAlarmId() { + return alarmId; + } + + public void setAlarmId(String alarmId) { + this.alarmId = alarmId; + } + + public String getAlarmTimeDate() { + return alarmTimeDate; + } + + public void setAlarmTimeDate(String alarmTimeDate) { + this.alarmTimeDate = alarmTimeDate; + } + + public String getAlarmType() { + return alarmType; + } + + public void setAlarmType(String alarmType) { + this.alarmType = alarmType; + } + + public String getAlarmValue() { + return alarmValue; + } + + public void setAlarmValue(String alarmValue) { + this.alarmValue = alarmValue; + } + + 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 getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + 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 getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getWellId() { + return wellId; + } + + public void setWellId(String wellId) { + this.wellId = wellId; + } + + 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/smart/town/sanxi/model/MapDeviceModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java new file mode 100644 index 0000000..59b6882 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java @@ -0,0 +1,199 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapDeviceModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String coordinateX; + private String coordinateY; + private String deptName; + private String deptid; + private String devcode; + private String deviceName; + private String deviceType; + private String deviceTypeName; + private String id; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String onlineState; + private String position; + private String realtimeData; + private String wellCode; + + 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 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 getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + 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 getOnlineState() { + return onlineState; + } + + public void setOnlineState(String onlineState) { + this.onlineState = onlineState; + } + + public String getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getRealtimeData() { + return realtimeData; + } + + public void setRealtimeData(String realtimeData) { + this.realtimeData = realtimeData; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + } +} diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt new file mode 100644 index 0000000..afdd3de --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt @@ -0,0 +1,7 @@ +package com.casic.smart.town.sanxi.util + +import com.amap.api.location.AMapLocation + +interface ILocationListener { + fun onAMapLocationGet(location: AMapLocation?) //高德定位数据 +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt new file mode 100644 index 0000000..ff813b9 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt @@ -0,0 +1,40 @@ +package com.casic.smart.town.sanxi.util + +import android.content.Context +import android.util.Log +import com.amap.api.location.AMapLocationClient +import com.amap.api.location.AMapLocationClientOption +import com.pengxh.kt.lite.base.BaseSingleton + +class LocationHub private constructor(context: Context) { + + companion object : BaseSingleton() { + override val creator: (Context) -> LocationHub + get() = ::LocationHub + } + + private val kTag = "LocationHub" + private val locationClient by lazy { AMapLocationClient(context) } + + fun getCurrentLocation(isOnceLocation: Boolean, listener: ILocationListener) { + val locationOption = AMapLocationClientOption() + locationOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy + locationOption.isOnceLocation = isOnceLocation + locationClient.setLocationOption(locationOption) + locationClient.setLocationListener { + if (it.errorCode == 0) { + listener.onAMapLocationGet(it) + } else { + listener.onAMapLocationGet(null) + Log.e( + kTag, "location Error, ErrCode:${it.errorCode}, errInfo:${it.errorInfo}" + ) + } + } + locationClient.startLocation() + } + + fun stopLocation() { + locationClient.stopLocation() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt index 0e561a6..7480627 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt @@ -206,4 +206,16 @@ */ @GET("/overview/wellList") suspend fun getAllWell(@Header("token") token: String): String + + /** + * 获取设备列表-不分页,地图用 + */ + @GET("/statics/deviceList") + suspend fun getDevices(@Header("token") token: String): String + + /** + * 获取报警列表-不分页,地图用 + */ + @GET("/device/alarmList") + suspend fun getAlarms(@Header("token") token: String): String } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index db8a60e..071a613 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -76,6 +76,9 @@ android:name="com.amap.api.v2.apikey" android:value="34064d6fa0c5ebd8ce48599386ce9c3a" /> + + + (), AMap.OnMapLoadedListener, - AMap.OnCameraChangeListener, - AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { + AMap.OnCameraChangeListener, AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { private val kTag = "HomePageFragment" private lateinit var aMap: AMap + private lateinit var deviceViewModel: DeviceViewModel + private val locationHub by lazy { LocationHub.obtainInstance(requireContext()) } + private var deviceInfoModels: MutableList = ArrayList() + private var alarmInfoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 自定义Marker弹出框 + * */ + private var infoWindow: View? = null override fun initViewBinding( - inflater: LayoutInflater, - container: ViewGroup? + inflater: LayoutInflater, container: ViewGroup? ): FragmentHomeBinding { return FragmentHomeBinding.inflate(inflater, container, false) } @@ -31,11 +64,20 @@ } override fun observeRequestState() { + deviceViewModel.loadState.observe(this) { + when (it) { + is LoadState.Loading -> LoadingDialogHub.show( + requireActivity(), "数据加载中,请稍后" + ) + else -> LoadingDialogHub.dismiss() + } + } } override fun initEvent() { - + deviceViewModel.getDevices() + deviceViewModel.getAlarms() } override fun initOnCreate(savedInstanceState: Bundle?) { @@ -44,8 +86,11 @@ aMap.mapType = AMap.MAP_TYPE_SATELLITE val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 + uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER - uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 + uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜 // 地图加载成功监听 aMap.addOnMapLoadedListener(this) @@ -55,10 +100,102 @@ aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup aMap.setInfoWindowAdapter(this) + + //显示定位小蓝点 + val locationStyle = MyLocationStyle() + locationStyle.interval(2000) + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER)//定位、但不会移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + aMap.myLocationStyle = locationStyle//设置定位蓝点的Style + aMap.isMyLocationEnabled = true//设置是否显示定位小蓝点 + aMap.setOnMyLocationChangeListener { + + } + + deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] + deviceViewModel.mapDeviceResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + 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() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + deviceInfoModels.add(device) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(device.deviceName).snippet(device.wellCode) + ) + } + + //移动到指定经纬度 + val centerLatLng = LatLng(latitudeList.average(), longitudeList.average()) + val cameraPosition = CameraPosition(centerLatLng, 16f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + } + } + } + } + deviceViewModel.mapAlarmResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + it.data.forEach { alarm -> + val lat = alarm.latGaode.toString() + val lng = alarm.lngGaode.toString() + if (lat.isNotBlank() && lng.isNotBlank()) { + val latitude = lat.toDouble() + val longitude = lng.toDouble() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + alarmInfoModels.add(alarm) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(alarm.alarmContent).snippet(alarm.alarmId) + ) + } + } + } + } + } + } + + private fun moveToCurrentLocation() { + locationHub.getCurrentLocation(true, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { +// if (location != null) { +// aMap.moveCamera( +// CameraUpdateFactory.newLatLngZoom( +// LatLng(location.latitude, location.longitude), 16f +// ) +// ) +// } else { +// "当前位置信号差,无法移动地图到定位点".show(requireContext()) +// } + } + }) } override fun onMapLoaded() { - + initClustersMarkers() } override fun onCameraChange(p0: CameraPosition?) { @@ -66,15 +203,86 @@ } override fun onCameraChangeFinish(p0: CameraPosition?) { - + initClustersMarkers() } - override fun onMarkerClick(p0: Marker?): Boolean { + private fun initClustersMarkers() { + allMarkerOptions.forEach { + if (it.snippet.startsWith("GX")) { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_device).bitmap + ) + ) + } else { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_alarm).bitmap + ) + ) + } + aMap.addMarker(it) + } + } + + override fun onMarkerClick(marker: Marker?): Boolean { + //显示闸井信息 + marker?.showInfoWindow() return true } - override fun getInfoWindow(p0: Marker?): View? { + 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 wellNameView = v.findViewById(R.id.wellNameView) + val wellCodeView = v.findViewById(R.id.wellCodeView) + val wellTypeView = v.findViewById(R.id.wellTypeView) + val wellStateView = v.findViewById(R.id.wellStateView) + val deepView = v.findViewById(R.id.deepView) + val locationView = v.findViewById(R.id.locationView) + + val clickedMarker = marker?.snippet.toString() + Log.d(kTag, clickedMarker) + + if (clickedMarker.startsWith("GX")) { + //搜设备 + for (device in deviceInfoModels) { + if (clickedMarker == device.devcode) { + + Log.d(kTag, device.toJson()) + + wellNameView.text = String.format("设备名称: ${device.deviceName}") + wellCodeView.text = String.format("设备编号: ${device.devcode}") + wellTypeView.text = String.format("设备类型: ${device.deviceTypeName}") + wellStateView.text = String.format("权属单位: ${device.deptName}") + deepView.text = String.format("更新时间: ${device.realtimeData}") + locationView.text = String.format("详细位置: ${device.position}") + + return infoWindow + } + } + } else { + //搜报警 + for (alarm in alarmInfoModels) { + if (clickedMarker == alarm.alarmId) { + Log.d(kTag, alarm.toJson()) + + wellNameView.text = String.format("报警内容: ${alarm.alarmContent}") + wellCodeView.text = String.format("设备编号: ${alarm.wellCode}") + wellTypeView.text = String.format("设备类型: ${alarm.wellType.valueToType()}") +// wellStateView.text = String.format("布/撤防状态: $bfztName") + deepView.text = String.format("报警时间: ${alarm.alarmTimeDate}") + locationView.text = String.format("详细位置: ${alarm.position}") + + return infoWindow + } + } + } return null } @@ -82,12 +290,14 @@ /** * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框 * */ - override fun getInfoContents(p0: Marker?): View? = null + override fun getInfoContents(marker: Marker?): View? = null /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() binding.mapView.onResume() + //首次移动到定位点 + moveToCurrentLocation() } override fun onPause() { @@ -103,5 +313,6 @@ override fun onDestroy() { super.onDestroy() binding.mapView.onDestroy() + locationHub.stopLocation() } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java new file mode 100644 index 0000000..2edc0f2 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java @@ -0,0 +1,226 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapAlarmModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String alarmContent; + private String alarmId; + private String alarmTimeDate; + private String alarmType; + private String alarmValue; + private String coordinateX; + private String coordinateY; + private String deptid; + private String devcode; + private String deviceId; + private String deviceType; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String position; + private String wellCode; + private String wellId; + private String wellType; + private String wellTypeName; + + public String getAlarmContent() { + return alarmContent; + } + + public void setAlarmContent(String alarmContent) { + this.alarmContent = alarmContent; + } + + public String getAlarmId() { + return alarmId; + } + + public void setAlarmId(String alarmId) { + this.alarmId = alarmId; + } + + public String getAlarmTimeDate() { + return alarmTimeDate; + } + + public void setAlarmTimeDate(String alarmTimeDate) { + this.alarmTimeDate = alarmTimeDate; + } + + public String getAlarmType() { + return alarmType; + } + + public void setAlarmType(String alarmType) { + this.alarmType = alarmType; + } + + public String getAlarmValue() { + return alarmValue; + } + + public void setAlarmValue(String alarmValue) { + this.alarmValue = alarmValue; + } + + 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 getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + 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 getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getWellId() { + return wellId; + } + + public void setWellId(String wellId) { + this.wellId = wellId; + } + + 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/smart/town/sanxi/model/MapDeviceModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java new file mode 100644 index 0000000..59b6882 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java @@ -0,0 +1,199 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapDeviceModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String coordinateX; + private String coordinateY; + private String deptName; + private String deptid; + private String devcode; + private String deviceName; + private String deviceType; + private String deviceTypeName; + private String id; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String onlineState; + private String position; + private String realtimeData; + private String wellCode; + + 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 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 getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + 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 getOnlineState() { + return onlineState; + } + + public void setOnlineState(String onlineState) { + this.onlineState = onlineState; + } + + public String getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getRealtimeData() { + return realtimeData; + } + + public void setRealtimeData(String realtimeData) { + this.realtimeData = realtimeData; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + } +} diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt new file mode 100644 index 0000000..afdd3de --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt @@ -0,0 +1,7 @@ +package com.casic.smart.town.sanxi.util + +import com.amap.api.location.AMapLocation + +interface ILocationListener { + fun onAMapLocationGet(location: AMapLocation?) //高德定位数据 +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt new file mode 100644 index 0000000..ff813b9 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt @@ -0,0 +1,40 @@ +package com.casic.smart.town.sanxi.util + +import android.content.Context +import android.util.Log +import com.amap.api.location.AMapLocationClient +import com.amap.api.location.AMapLocationClientOption +import com.pengxh.kt.lite.base.BaseSingleton + +class LocationHub private constructor(context: Context) { + + companion object : BaseSingleton() { + override val creator: (Context) -> LocationHub + get() = ::LocationHub + } + + private val kTag = "LocationHub" + private val locationClient by lazy { AMapLocationClient(context) } + + fun getCurrentLocation(isOnceLocation: Boolean, listener: ILocationListener) { + val locationOption = AMapLocationClientOption() + locationOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy + locationOption.isOnceLocation = isOnceLocation + locationClient.setLocationOption(locationOption) + locationClient.setLocationListener { + if (it.errorCode == 0) { + listener.onAMapLocationGet(it) + } else { + listener.onAMapLocationGet(null) + Log.e( + kTag, "location Error, ErrCode:${it.errorCode}, errInfo:${it.errorInfo}" + ) + } + } + locationClient.startLocation() + } + + fun stopLocation() { + locationClient.stopLocation() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt index 0e561a6..7480627 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt @@ -206,4 +206,16 @@ */ @GET("/overview/wellList") suspend fun getAllWell(@Header("token") token: String): String + + /** + * 获取设备列表-不分页,地图用 + */ + @GET("/statics/deviceList") + suspend fun getDevices(@Header("token") token: String): String + + /** + * 获取报警列表-不分页,地图用 + */ + @GET("/device/alarmList") + suspend fun getAlarms(@Header("token") token: String): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt index 8d8f7fc..ca690a8 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt @@ -207,6 +207,14 @@ return smartTownApi.countDevice(AuthenticationHelper.token!!) } + suspend fun getDevices(): String { + return smartTownApi.getDevices(AuthenticationHelper.token!!) + } + + suspend fun getAlarms(): String { + return smartTownApi.getAlarms(AuthenticationHelper.token!!) + } + suspend fun queryWellInfo(deviceId: String): String { return smartTownApi.queryWellInfo(AuthenticationHelper.token!!, deviceId) } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index db8a60e..071a613 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -76,6 +76,9 @@ android:name="com.amap.api.v2.apikey" android:value="34064d6fa0c5ebd8ce48599386ce9c3a" /> + + + (), AMap.OnMapLoadedListener, - AMap.OnCameraChangeListener, - AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { + AMap.OnCameraChangeListener, AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { private val kTag = "HomePageFragment" private lateinit var aMap: AMap + private lateinit var deviceViewModel: DeviceViewModel + private val locationHub by lazy { LocationHub.obtainInstance(requireContext()) } + private var deviceInfoModels: MutableList = ArrayList() + private var alarmInfoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 自定义Marker弹出框 + * */ + private var infoWindow: View? = null override fun initViewBinding( - inflater: LayoutInflater, - container: ViewGroup? + inflater: LayoutInflater, container: ViewGroup? ): FragmentHomeBinding { return FragmentHomeBinding.inflate(inflater, container, false) } @@ -31,11 +64,20 @@ } override fun observeRequestState() { + deviceViewModel.loadState.observe(this) { + when (it) { + is LoadState.Loading -> LoadingDialogHub.show( + requireActivity(), "数据加载中,请稍后" + ) + else -> LoadingDialogHub.dismiss() + } + } } override fun initEvent() { - + deviceViewModel.getDevices() + deviceViewModel.getAlarms() } override fun initOnCreate(savedInstanceState: Bundle?) { @@ -44,8 +86,11 @@ aMap.mapType = AMap.MAP_TYPE_SATELLITE val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 + uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER - uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 + uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜 // 地图加载成功监听 aMap.addOnMapLoadedListener(this) @@ -55,10 +100,102 @@ aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup aMap.setInfoWindowAdapter(this) + + //显示定位小蓝点 + val locationStyle = MyLocationStyle() + locationStyle.interval(2000) + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER)//定位、但不会移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + aMap.myLocationStyle = locationStyle//设置定位蓝点的Style + aMap.isMyLocationEnabled = true//设置是否显示定位小蓝点 + aMap.setOnMyLocationChangeListener { + + } + + deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] + deviceViewModel.mapDeviceResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + 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() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + deviceInfoModels.add(device) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(device.deviceName).snippet(device.wellCode) + ) + } + + //移动到指定经纬度 + val centerLatLng = LatLng(latitudeList.average(), longitudeList.average()) + val cameraPosition = CameraPosition(centerLatLng, 16f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + } + } + } + } + deviceViewModel.mapAlarmResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + it.data.forEach { alarm -> + val lat = alarm.latGaode.toString() + val lng = alarm.lngGaode.toString() + if (lat.isNotBlank() && lng.isNotBlank()) { + val latitude = lat.toDouble() + val longitude = lng.toDouble() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + alarmInfoModels.add(alarm) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(alarm.alarmContent).snippet(alarm.alarmId) + ) + } + } + } + } + } + } + + private fun moveToCurrentLocation() { + locationHub.getCurrentLocation(true, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { +// if (location != null) { +// aMap.moveCamera( +// CameraUpdateFactory.newLatLngZoom( +// LatLng(location.latitude, location.longitude), 16f +// ) +// ) +// } else { +// "当前位置信号差,无法移动地图到定位点".show(requireContext()) +// } + } + }) } override fun onMapLoaded() { - + initClustersMarkers() } override fun onCameraChange(p0: CameraPosition?) { @@ -66,15 +203,86 @@ } override fun onCameraChangeFinish(p0: CameraPosition?) { - + initClustersMarkers() } - override fun onMarkerClick(p0: Marker?): Boolean { + private fun initClustersMarkers() { + allMarkerOptions.forEach { + if (it.snippet.startsWith("GX")) { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_device).bitmap + ) + ) + } else { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_alarm).bitmap + ) + ) + } + aMap.addMarker(it) + } + } + + override fun onMarkerClick(marker: Marker?): Boolean { + //显示闸井信息 + marker?.showInfoWindow() return true } - override fun getInfoWindow(p0: Marker?): View? { + 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 wellNameView = v.findViewById(R.id.wellNameView) + val wellCodeView = v.findViewById(R.id.wellCodeView) + val wellTypeView = v.findViewById(R.id.wellTypeView) + val wellStateView = v.findViewById(R.id.wellStateView) + val deepView = v.findViewById(R.id.deepView) + val locationView = v.findViewById(R.id.locationView) + + val clickedMarker = marker?.snippet.toString() + Log.d(kTag, clickedMarker) + + if (clickedMarker.startsWith("GX")) { + //搜设备 + for (device in deviceInfoModels) { + if (clickedMarker == device.devcode) { + + Log.d(kTag, device.toJson()) + + wellNameView.text = String.format("设备名称: ${device.deviceName}") + wellCodeView.text = String.format("设备编号: ${device.devcode}") + wellTypeView.text = String.format("设备类型: ${device.deviceTypeName}") + wellStateView.text = String.format("权属单位: ${device.deptName}") + deepView.text = String.format("更新时间: ${device.realtimeData}") + locationView.text = String.format("详细位置: ${device.position}") + + return infoWindow + } + } + } else { + //搜报警 + for (alarm in alarmInfoModels) { + if (clickedMarker == alarm.alarmId) { + Log.d(kTag, alarm.toJson()) + + wellNameView.text = String.format("报警内容: ${alarm.alarmContent}") + wellCodeView.text = String.format("设备编号: ${alarm.wellCode}") + wellTypeView.text = String.format("设备类型: ${alarm.wellType.valueToType()}") +// wellStateView.text = String.format("布/撤防状态: $bfztName") + deepView.text = String.format("报警时间: ${alarm.alarmTimeDate}") + locationView.text = String.format("详细位置: ${alarm.position}") + + return infoWindow + } + } + } return null } @@ -82,12 +290,14 @@ /** * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框 * */ - override fun getInfoContents(p0: Marker?): View? = null + override fun getInfoContents(marker: Marker?): View? = null /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() binding.mapView.onResume() + //首次移动到定位点 + moveToCurrentLocation() } override fun onPause() { @@ -103,5 +313,6 @@ override fun onDestroy() { super.onDestroy() binding.mapView.onDestroy() + locationHub.stopLocation() } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java new file mode 100644 index 0000000..2edc0f2 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java @@ -0,0 +1,226 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapAlarmModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String alarmContent; + private String alarmId; + private String alarmTimeDate; + private String alarmType; + private String alarmValue; + private String coordinateX; + private String coordinateY; + private String deptid; + private String devcode; + private String deviceId; + private String deviceType; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String position; + private String wellCode; + private String wellId; + private String wellType; + private String wellTypeName; + + public String getAlarmContent() { + return alarmContent; + } + + public void setAlarmContent(String alarmContent) { + this.alarmContent = alarmContent; + } + + public String getAlarmId() { + return alarmId; + } + + public void setAlarmId(String alarmId) { + this.alarmId = alarmId; + } + + public String getAlarmTimeDate() { + return alarmTimeDate; + } + + public void setAlarmTimeDate(String alarmTimeDate) { + this.alarmTimeDate = alarmTimeDate; + } + + public String getAlarmType() { + return alarmType; + } + + public void setAlarmType(String alarmType) { + this.alarmType = alarmType; + } + + public String getAlarmValue() { + return alarmValue; + } + + public void setAlarmValue(String alarmValue) { + this.alarmValue = alarmValue; + } + + 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 getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + 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 getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getWellId() { + return wellId; + } + + public void setWellId(String wellId) { + this.wellId = wellId; + } + + 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/smart/town/sanxi/model/MapDeviceModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java new file mode 100644 index 0000000..59b6882 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java @@ -0,0 +1,199 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapDeviceModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String coordinateX; + private String coordinateY; + private String deptName; + private String deptid; + private String devcode; + private String deviceName; + private String deviceType; + private String deviceTypeName; + private String id; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String onlineState; + private String position; + private String realtimeData; + private String wellCode; + + 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 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 getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + 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 getOnlineState() { + return onlineState; + } + + public void setOnlineState(String onlineState) { + this.onlineState = onlineState; + } + + public String getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getRealtimeData() { + return realtimeData; + } + + public void setRealtimeData(String realtimeData) { + this.realtimeData = realtimeData; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + } +} diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt new file mode 100644 index 0000000..afdd3de --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt @@ -0,0 +1,7 @@ +package com.casic.smart.town.sanxi.util + +import com.amap.api.location.AMapLocation + +interface ILocationListener { + fun onAMapLocationGet(location: AMapLocation?) //高德定位数据 +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt new file mode 100644 index 0000000..ff813b9 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt @@ -0,0 +1,40 @@ +package com.casic.smart.town.sanxi.util + +import android.content.Context +import android.util.Log +import com.amap.api.location.AMapLocationClient +import com.amap.api.location.AMapLocationClientOption +import com.pengxh.kt.lite.base.BaseSingleton + +class LocationHub private constructor(context: Context) { + + companion object : BaseSingleton() { + override val creator: (Context) -> LocationHub + get() = ::LocationHub + } + + private val kTag = "LocationHub" + private val locationClient by lazy { AMapLocationClient(context) } + + fun getCurrentLocation(isOnceLocation: Boolean, listener: ILocationListener) { + val locationOption = AMapLocationClientOption() + locationOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy + locationOption.isOnceLocation = isOnceLocation + locationClient.setLocationOption(locationOption) + locationClient.setLocationListener { + if (it.errorCode == 0) { + listener.onAMapLocationGet(it) + } else { + listener.onAMapLocationGet(null) + Log.e( + kTag, "location Error, ErrCode:${it.errorCode}, errInfo:${it.errorInfo}" + ) + } + } + locationClient.startLocation() + } + + fun stopLocation() { + locationClient.stopLocation() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt index 0e561a6..7480627 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt @@ -206,4 +206,16 @@ */ @GET("/overview/wellList") suspend fun getAllWell(@Header("token") token: String): String + + /** + * 获取设备列表-不分页,地图用 + */ + @GET("/statics/deviceList") + suspend fun getDevices(@Header("token") token: String): String + + /** + * 获取报警列表-不分页,地图用 + */ + @GET("/device/alarmList") + suspend fun getAlarms(@Header("token") token: String): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt index 8d8f7fc..ca690a8 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt @@ -207,6 +207,14 @@ return smartTownApi.countDevice(AuthenticationHelper.token!!) } + suspend fun getDevices(): String { + return smartTownApi.getDevices(AuthenticationHelper.token!!) + } + + suspend fun getAlarms(): String { + return smartTownApi.getAlarms(AuthenticationHelper.token!!) + } + suspend fun queryWellInfo(deviceId: String): String { return smartTownApi.queryWellInfo(AuthenticationHelper.token!!, deviceId) } diff --git a/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt b/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt index a8bad16..b77a48d 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt @@ -200,6 +200,8 @@ wellStateView.text = String.format("布/撤防状态: $bfztName") deepView.text = String.format("点位深度: ${well.deep}m") locationView.text = String.format("详细位置: ${well.position}") + + return v } } return null diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index db8a60e..071a613 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -76,6 +76,9 @@ android:name="com.amap.api.v2.apikey" android:value="34064d6fa0c5ebd8ce48599386ce9c3a" /> + + + (), AMap.OnMapLoadedListener, - AMap.OnCameraChangeListener, - AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { + AMap.OnCameraChangeListener, AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { private val kTag = "HomePageFragment" private lateinit var aMap: AMap + private lateinit var deviceViewModel: DeviceViewModel + private val locationHub by lazy { LocationHub.obtainInstance(requireContext()) } + private var deviceInfoModels: MutableList = ArrayList() + private var alarmInfoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 自定义Marker弹出框 + * */ + private var infoWindow: View? = null override fun initViewBinding( - inflater: LayoutInflater, - container: ViewGroup? + inflater: LayoutInflater, container: ViewGroup? ): FragmentHomeBinding { return FragmentHomeBinding.inflate(inflater, container, false) } @@ -31,11 +64,20 @@ } override fun observeRequestState() { + deviceViewModel.loadState.observe(this) { + when (it) { + is LoadState.Loading -> LoadingDialogHub.show( + requireActivity(), "数据加载中,请稍后" + ) + else -> LoadingDialogHub.dismiss() + } + } } override fun initEvent() { - + deviceViewModel.getDevices() + deviceViewModel.getAlarms() } override fun initOnCreate(savedInstanceState: Bundle?) { @@ -44,8 +86,11 @@ aMap.mapType = AMap.MAP_TYPE_SATELLITE val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 + uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER - uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 + uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜 // 地图加载成功监听 aMap.addOnMapLoadedListener(this) @@ -55,10 +100,102 @@ aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup aMap.setInfoWindowAdapter(this) + + //显示定位小蓝点 + val locationStyle = MyLocationStyle() + locationStyle.interval(2000) + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER)//定位、但不会移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + aMap.myLocationStyle = locationStyle//设置定位蓝点的Style + aMap.isMyLocationEnabled = true//设置是否显示定位小蓝点 + aMap.setOnMyLocationChangeListener { + + } + + deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] + deviceViewModel.mapDeviceResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + 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() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + deviceInfoModels.add(device) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(device.deviceName).snippet(device.wellCode) + ) + } + + //移动到指定经纬度 + val centerLatLng = LatLng(latitudeList.average(), longitudeList.average()) + val cameraPosition = CameraPosition(centerLatLng, 16f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + } + } + } + } + deviceViewModel.mapAlarmResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + it.data.forEach { alarm -> + val lat = alarm.latGaode.toString() + val lng = alarm.lngGaode.toString() + if (lat.isNotBlank() && lng.isNotBlank()) { + val latitude = lat.toDouble() + val longitude = lng.toDouble() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + alarmInfoModels.add(alarm) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(alarm.alarmContent).snippet(alarm.alarmId) + ) + } + } + } + } + } + } + + private fun moveToCurrentLocation() { + locationHub.getCurrentLocation(true, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { +// if (location != null) { +// aMap.moveCamera( +// CameraUpdateFactory.newLatLngZoom( +// LatLng(location.latitude, location.longitude), 16f +// ) +// ) +// } else { +// "当前位置信号差,无法移动地图到定位点".show(requireContext()) +// } + } + }) } override fun onMapLoaded() { - + initClustersMarkers() } override fun onCameraChange(p0: CameraPosition?) { @@ -66,15 +203,86 @@ } override fun onCameraChangeFinish(p0: CameraPosition?) { - + initClustersMarkers() } - override fun onMarkerClick(p0: Marker?): Boolean { + private fun initClustersMarkers() { + allMarkerOptions.forEach { + if (it.snippet.startsWith("GX")) { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_device).bitmap + ) + ) + } else { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_alarm).bitmap + ) + ) + } + aMap.addMarker(it) + } + } + + override fun onMarkerClick(marker: Marker?): Boolean { + //显示闸井信息 + marker?.showInfoWindow() return true } - override fun getInfoWindow(p0: Marker?): View? { + 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 wellNameView = v.findViewById(R.id.wellNameView) + val wellCodeView = v.findViewById(R.id.wellCodeView) + val wellTypeView = v.findViewById(R.id.wellTypeView) + val wellStateView = v.findViewById(R.id.wellStateView) + val deepView = v.findViewById(R.id.deepView) + val locationView = v.findViewById(R.id.locationView) + + val clickedMarker = marker?.snippet.toString() + Log.d(kTag, clickedMarker) + + if (clickedMarker.startsWith("GX")) { + //搜设备 + for (device in deviceInfoModels) { + if (clickedMarker == device.devcode) { + + Log.d(kTag, device.toJson()) + + wellNameView.text = String.format("设备名称: ${device.deviceName}") + wellCodeView.text = String.format("设备编号: ${device.devcode}") + wellTypeView.text = String.format("设备类型: ${device.deviceTypeName}") + wellStateView.text = String.format("权属单位: ${device.deptName}") + deepView.text = String.format("更新时间: ${device.realtimeData}") + locationView.text = String.format("详细位置: ${device.position}") + + return infoWindow + } + } + } else { + //搜报警 + for (alarm in alarmInfoModels) { + if (clickedMarker == alarm.alarmId) { + Log.d(kTag, alarm.toJson()) + + wellNameView.text = String.format("报警内容: ${alarm.alarmContent}") + wellCodeView.text = String.format("设备编号: ${alarm.wellCode}") + wellTypeView.text = String.format("设备类型: ${alarm.wellType.valueToType()}") +// wellStateView.text = String.format("布/撤防状态: $bfztName") + deepView.text = String.format("报警时间: ${alarm.alarmTimeDate}") + locationView.text = String.format("详细位置: ${alarm.position}") + + return infoWindow + } + } + } return null } @@ -82,12 +290,14 @@ /** * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框 * */ - override fun getInfoContents(p0: Marker?): View? = null + override fun getInfoContents(marker: Marker?): View? = null /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() binding.mapView.onResume() + //首次移动到定位点 + moveToCurrentLocation() } override fun onPause() { @@ -103,5 +313,6 @@ override fun onDestroy() { super.onDestroy() binding.mapView.onDestroy() + locationHub.stopLocation() } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java new file mode 100644 index 0000000..2edc0f2 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java @@ -0,0 +1,226 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapAlarmModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String alarmContent; + private String alarmId; + private String alarmTimeDate; + private String alarmType; + private String alarmValue; + private String coordinateX; + private String coordinateY; + private String deptid; + private String devcode; + private String deviceId; + private String deviceType; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String position; + private String wellCode; + private String wellId; + private String wellType; + private String wellTypeName; + + public String getAlarmContent() { + return alarmContent; + } + + public void setAlarmContent(String alarmContent) { + this.alarmContent = alarmContent; + } + + public String getAlarmId() { + return alarmId; + } + + public void setAlarmId(String alarmId) { + this.alarmId = alarmId; + } + + public String getAlarmTimeDate() { + return alarmTimeDate; + } + + public void setAlarmTimeDate(String alarmTimeDate) { + this.alarmTimeDate = alarmTimeDate; + } + + public String getAlarmType() { + return alarmType; + } + + public void setAlarmType(String alarmType) { + this.alarmType = alarmType; + } + + public String getAlarmValue() { + return alarmValue; + } + + public void setAlarmValue(String alarmValue) { + this.alarmValue = alarmValue; + } + + 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 getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + 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 getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getWellId() { + return wellId; + } + + public void setWellId(String wellId) { + this.wellId = wellId; + } + + 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/smart/town/sanxi/model/MapDeviceModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java new file mode 100644 index 0000000..59b6882 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java @@ -0,0 +1,199 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapDeviceModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String coordinateX; + private String coordinateY; + private String deptName; + private String deptid; + private String devcode; + private String deviceName; + private String deviceType; + private String deviceTypeName; + private String id; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String onlineState; + private String position; + private String realtimeData; + private String wellCode; + + 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 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 getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + 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 getOnlineState() { + return onlineState; + } + + public void setOnlineState(String onlineState) { + this.onlineState = onlineState; + } + + public String getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getRealtimeData() { + return realtimeData; + } + + public void setRealtimeData(String realtimeData) { + this.realtimeData = realtimeData; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + } +} diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt new file mode 100644 index 0000000..afdd3de --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt @@ -0,0 +1,7 @@ +package com.casic.smart.town.sanxi.util + +import com.amap.api.location.AMapLocation + +interface ILocationListener { + fun onAMapLocationGet(location: AMapLocation?) //高德定位数据 +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt new file mode 100644 index 0000000..ff813b9 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt @@ -0,0 +1,40 @@ +package com.casic.smart.town.sanxi.util + +import android.content.Context +import android.util.Log +import com.amap.api.location.AMapLocationClient +import com.amap.api.location.AMapLocationClientOption +import com.pengxh.kt.lite.base.BaseSingleton + +class LocationHub private constructor(context: Context) { + + companion object : BaseSingleton() { + override val creator: (Context) -> LocationHub + get() = ::LocationHub + } + + private val kTag = "LocationHub" + private val locationClient by lazy { AMapLocationClient(context) } + + fun getCurrentLocation(isOnceLocation: Boolean, listener: ILocationListener) { + val locationOption = AMapLocationClientOption() + locationOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy + locationOption.isOnceLocation = isOnceLocation + locationClient.setLocationOption(locationOption) + locationClient.setLocationListener { + if (it.errorCode == 0) { + listener.onAMapLocationGet(it) + } else { + listener.onAMapLocationGet(null) + Log.e( + kTag, "location Error, ErrCode:${it.errorCode}, errInfo:${it.errorInfo}" + ) + } + } + locationClient.startLocation() + } + + fun stopLocation() { + locationClient.stopLocation() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt index 0e561a6..7480627 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt @@ -206,4 +206,16 @@ */ @GET("/overview/wellList") suspend fun getAllWell(@Header("token") token: String): String + + /** + * 获取设备列表-不分页,地图用 + */ + @GET("/statics/deviceList") + suspend fun getDevices(@Header("token") token: String): String + + /** + * 获取报警列表-不分页,地图用 + */ + @GET("/device/alarmList") + suspend fun getAlarms(@Header("token") token: String): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt index 8d8f7fc..ca690a8 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt @@ -207,6 +207,14 @@ return smartTownApi.countDevice(AuthenticationHelper.token!!) } + suspend fun getDevices(): String { + return smartTownApi.getDevices(AuthenticationHelper.token!!) + } + + suspend fun getAlarms(): String { + return smartTownApi.getAlarms(AuthenticationHelper.token!!) + } + suspend fun queryWellInfo(deviceId: String): String { return smartTownApi.queryWellInfo(AuthenticationHelper.token!!, deviceId) } diff --git a/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt b/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt index a8bad16..b77a48d 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt @@ -200,6 +200,8 @@ wellStateView.text = String.format("布/撤防状态: $bfztName") deepView.text = String.format("点位深度: ${well.deep}m") locationView.text = String.format("详细位置: ${well.position}") + + return v } } return null diff --git a/app/src/main/java/com/casic/smart/town/sanxi/view/BFWellActivity.kt b/app/src/main/java/com/casic/smart/town/sanxi/view/BFWellActivity.kt index 4ae34fe..a3f1c6a 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/view/BFWellActivity.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/view/BFWellActivity.kt @@ -207,6 +207,8 @@ wellStateView.text = String.format("布/撤防状态: $bfztName") deepView.text = String.format("点位深度: ${well.deep}m") locationView.text = String.format("详细位置: ${well.position}") + + return v } } return null diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index db8a60e..071a613 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -76,6 +76,9 @@ android:name="com.amap.api.v2.apikey" android:value="34064d6fa0c5ebd8ce48599386ce9c3a" /> + + + (), AMap.OnMapLoadedListener, - AMap.OnCameraChangeListener, - AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { + AMap.OnCameraChangeListener, AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { private val kTag = "HomePageFragment" private lateinit var aMap: AMap + private lateinit var deviceViewModel: DeviceViewModel + private val locationHub by lazy { LocationHub.obtainInstance(requireContext()) } + private var deviceInfoModels: MutableList = ArrayList() + private var alarmInfoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 自定义Marker弹出框 + * */ + private var infoWindow: View? = null override fun initViewBinding( - inflater: LayoutInflater, - container: ViewGroup? + inflater: LayoutInflater, container: ViewGroup? ): FragmentHomeBinding { return FragmentHomeBinding.inflate(inflater, container, false) } @@ -31,11 +64,20 @@ } override fun observeRequestState() { + deviceViewModel.loadState.observe(this) { + when (it) { + is LoadState.Loading -> LoadingDialogHub.show( + requireActivity(), "数据加载中,请稍后" + ) + else -> LoadingDialogHub.dismiss() + } + } } override fun initEvent() { - + deviceViewModel.getDevices() + deviceViewModel.getAlarms() } override fun initOnCreate(savedInstanceState: Bundle?) { @@ -44,8 +86,11 @@ aMap.mapType = AMap.MAP_TYPE_SATELLITE val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 + uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER - uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 + uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜 // 地图加载成功监听 aMap.addOnMapLoadedListener(this) @@ -55,10 +100,102 @@ aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup aMap.setInfoWindowAdapter(this) + + //显示定位小蓝点 + val locationStyle = MyLocationStyle() + locationStyle.interval(2000) + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER)//定位、但不会移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + aMap.myLocationStyle = locationStyle//设置定位蓝点的Style + aMap.isMyLocationEnabled = true//设置是否显示定位小蓝点 + aMap.setOnMyLocationChangeListener { + + } + + deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] + deviceViewModel.mapDeviceResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + 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() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + deviceInfoModels.add(device) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(device.deviceName).snippet(device.wellCode) + ) + } + + //移动到指定经纬度 + val centerLatLng = LatLng(latitudeList.average(), longitudeList.average()) + val cameraPosition = CameraPosition(centerLatLng, 16f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + } + } + } + } + deviceViewModel.mapAlarmResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + it.data.forEach { alarm -> + val lat = alarm.latGaode.toString() + val lng = alarm.lngGaode.toString() + if (lat.isNotBlank() && lng.isNotBlank()) { + val latitude = lat.toDouble() + val longitude = lng.toDouble() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + alarmInfoModels.add(alarm) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(alarm.alarmContent).snippet(alarm.alarmId) + ) + } + } + } + } + } + } + + private fun moveToCurrentLocation() { + locationHub.getCurrentLocation(true, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { +// if (location != null) { +// aMap.moveCamera( +// CameraUpdateFactory.newLatLngZoom( +// LatLng(location.latitude, location.longitude), 16f +// ) +// ) +// } else { +// "当前位置信号差,无法移动地图到定位点".show(requireContext()) +// } + } + }) } override fun onMapLoaded() { - + initClustersMarkers() } override fun onCameraChange(p0: CameraPosition?) { @@ -66,15 +203,86 @@ } override fun onCameraChangeFinish(p0: CameraPosition?) { - + initClustersMarkers() } - override fun onMarkerClick(p0: Marker?): Boolean { + private fun initClustersMarkers() { + allMarkerOptions.forEach { + if (it.snippet.startsWith("GX")) { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_device).bitmap + ) + ) + } else { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_alarm).bitmap + ) + ) + } + aMap.addMarker(it) + } + } + + override fun onMarkerClick(marker: Marker?): Boolean { + //显示闸井信息 + marker?.showInfoWindow() return true } - override fun getInfoWindow(p0: Marker?): View? { + 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 wellNameView = v.findViewById(R.id.wellNameView) + val wellCodeView = v.findViewById(R.id.wellCodeView) + val wellTypeView = v.findViewById(R.id.wellTypeView) + val wellStateView = v.findViewById(R.id.wellStateView) + val deepView = v.findViewById(R.id.deepView) + val locationView = v.findViewById(R.id.locationView) + + val clickedMarker = marker?.snippet.toString() + Log.d(kTag, clickedMarker) + + if (clickedMarker.startsWith("GX")) { + //搜设备 + for (device in deviceInfoModels) { + if (clickedMarker == device.devcode) { + + Log.d(kTag, device.toJson()) + + wellNameView.text = String.format("设备名称: ${device.deviceName}") + wellCodeView.text = String.format("设备编号: ${device.devcode}") + wellTypeView.text = String.format("设备类型: ${device.deviceTypeName}") + wellStateView.text = String.format("权属单位: ${device.deptName}") + deepView.text = String.format("更新时间: ${device.realtimeData}") + locationView.text = String.format("详细位置: ${device.position}") + + return infoWindow + } + } + } else { + //搜报警 + for (alarm in alarmInfoModels) { + if (clickedMarker == alarm.alarmId) { + Log.d(kTag, alarm.toJson()) + + wellNameView.text = String.format("报警内容: ${alarm.alarmContent}") + wellCodeView.text = String.format("设备编号: ${alarm.wellCode}") + wellTypeView.text = String.format("设备类型: ${alarm.wellType.valueToType()}") +// wellStateView.text = String.format("布/撤防状态: $bfztName") + deepView.text = String.format("报警时间: ${alarm.alarmTimeDate}") + locationView.text = String.format("详细位置: ${alarm.position}") + + return infoWindow + } + } + } return null } @@ -82,12 +290,14 @@ /** * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框 * */ - override fun getInfoContents(p0: Marker?): View? = null + override fun getInfoContents(marker: Marker?): View? = null /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() binding.mapView.onResume() + //首次移动到定位点 + moveToCurrentLocation() } override fun onPause() { @@ -103,5 +313,6 @@ override fun onDestroy() { super.onDestroy() binding.mapView.onDestroy() + locationHub.stopLocation() } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java new file mode 100644 index 0000000..2edc0f2 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java @@ -0,0 +1,226 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapAlarmModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String alarmContent; + private String alarmId; + private String alarmTimeDate; + private String alarmType; + private String alarmValue; + private String coordinateX; + private String coordinateY; + private String deptid; + private String devcode; + private String deviceId; + private String deviceType; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String position; + private String wellCode; + private String wellId; + private String wellType; + private String wellTypeName; + + public String getAlarmContent() { + return alarmContent; + } + + public void setAlarmContent(String alarmContent) { + this.alarmContent = alarmContent; + } + + public String getAlarmId() { + return alarmId; + } + + public void setAlarmId(String alarmId) { + this.alarmId = alarmId; + } + + public String getAlarmTimeDate() { + return alarmTimeDate; + } + + public void setAlarmTimeDate(String alarmTimeDate) { + this.alarmTimeDate = alarmTimeDate; + } + + public String getAlarmType() { + return alarmType; + } + + public void setAlarmType(String alarmType) { + this.alarmType = alarmType; + } + + public String getAlarmValue() { + return alarmValue; + } + + public void setAlarmValue(String alarmValue) { + this.alarmValue = alarmValue; + } + + 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 getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + 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 getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getWellId() { + return wellId; + } + + public void setWellId(String wellId) { + this.wellId = wellId; + } + + 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/smart/town/sanxi/model/MapDeviceModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java new file mode 100644 index 0000000..59b6882 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java @@ -0,0 +1,199 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapDeviceModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String coordinateX; + private String coordinateY; + private String deptName; + private String deptid; + private String devcode; + private String deviceName; + private String deviceType; + private String deviceTypeName; + private String id; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String onlineState; + private String position; + private String realtimeData; + private String wellCode; + + 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 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 getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + 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 getOnlineState() { + return onlineState; + } + + public void setOnlineState(String onlineState) { + this.onlineState = onlineState; + } + + public String getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getRealtimeData() { + return realtimeData; + } + + public void setRealtimeData(String realtimeData) { + this.realtimeData = realtimeData; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + } +} diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt new file mode 100644 index 0000000..afdd3de --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt @@ -0,0 +1,7 @@ +package com.casic.smart.town.sanxi.util + +import com.amap.api.location.AMapLocation + +interface ILocationListener { + fun onAMapLocationGet(location: AMapLocation?) //高德定位数据 +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt new file mode 100644 index 0000000..ff813b9 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt @@ -0,0 +1,40 @@ +package com.casic.smart.town.sanxi.util + +import android.content.Context +import android.util.Log +import com.amap.api.location.AMapLocationClient +import com.amap.api.location.AMapLocationClientOption +import com.pengxh.kt.lite.base.BaseSingleton + +class LocationHub private constructor(context: Context) { + + companion object : BaseSingleton() { + override val creator: (Context) -> LocationHub + get() = ::LocationHub + } + + private val kTag = "LocationHub" + private val locationClient by lazy { AMapLocationClient(context) } + + fun getCurrentLocation(isOnceLocation: Boolean, listener: ILocationListener) { + val locationOption = AMapLocationClientOption() + locationOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy + locationOption.isOnceLocation = isOnceLocation + locationClient.setLocationOption(locationOption) + locationClient.setLocationListener { + if (it.errorCode == 0) { + listener.onAMapLocationGet(it) + } else { + listener.onAMapLocationGet(null) + Log.e( + kTag, "location Error, ErrCode:${it.errorCode}, errInfo:${it.errorInfo}" + ) + } + } + locationClient.startLocation() + } + + fun stopLocation() { + locationClient.stopLocation() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt index 0e561a6..7480627 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt @@ -206,4 +206,16 @@ */ @GET("/overview/wellList") suspend fun getAllWell(@Header("token") token: String): String + + /** + * 获取设备列表-不分页,地图用 + */ + @GET("/statics/deviceList") + suspend fun getDevices(@Header("token") token: String): String + + /** + * 获取报警列表-不分页,地图用 + */ + @GET("/device/alarmList") + suspend fun getAlarms(@Header("token") token: String): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt index 8d8f7fc..ca690a8 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt @@ -207,6 +207,14 @@ return smartTownApi.countDevice(AuthenticationHelper.token!!) } + suspend fun getDevices(): String { + return smartTownApi.getDevices(AuthenticationHelper.token!!) + } + + suspend fun getAlarms(): String { + return smartTownApi.getAlarms(AuthenticationHelper.token!!) + } + suspend fun queryWellInfo(deviceId: String): String { return smartTownApi.queryWellInfo(AuthenticationHelper.token!!, deviceId) } diff --git a/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt b/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt index a8bad16..b77a48d 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt @@ -200,6 +200,8 @@ wellStateView.text = String.format("布/撤防状态: $bfztName") deepView.text = String.format("点位深度: ${well.deep}m") locationView.text = String.format("详细位置: ${well.position}") + + return v } } return null diff --git a/app/src/main/java/com/casic/smart/town/sanxi/view/BFWellActivity.kt b/app/src/main/java/com/casic/smart/town/sanxi/view/BFWellActivity.kt index 4ae34fe..a3f1c6a 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/view/BFWellActivity.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/view/BFWellActivity.kt @@ -207,6 +207,8 @@ wellStateView.text = String.format("布/撤防状态: $bfztName") deepView.text = String.format("点位深度: ${well.deep}m") locationView.text = String.format("详细位置: ${well.position}") + + return v } } return null diff --git a/app/src/main/java/com/casic/smart/town/sanxi/view/CFWellActivity.kt b/app/src/main/java/com/casic/smart/town/sanxi/view/CFWellActivity.kt index 249a2fd..f98a065 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/view/CFWellActivity.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/view/CFWellActivity.kt @@ -208,6 +208,8 @@ wellStateView.text = String.format("布/撤防状态: $bfztName") deepView.text = String.format("点位深度: ${well.deep}m") locationView.text = String.format("详细位置: ${well.position}") + + return v } } return null diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index db8a60e..071a613 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -76,6 +76,9 @@ android:name="com.amap.api.v2.apikey" android:value="34064d6fa0c5ebd8ce48599386ce9c3a" /> + + + (), AMap.OnMapLoadedListener, - AMap.OnCameraChangeListener, - AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { + AMap.OnCameraChangeListener, AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { private val kTag = "HomePageFragment" private lateinit var aMap: AMap + private lateinit var deviceViewModel: DeviceViewModel + private val locationHub by lazy { LocationHub.obtainInstance(requireContext()) } + private var deviceInfoModels: MutableList = ArrayList() + private var alarmInfoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 自定义Marker弹出框 + * */ + private var infoWindow: View? = null override fun initViewBinding( - inflater: LayoutInflater, - container: ViewGroup? + inflater: LayoutInflater, container: ViewGroup? ): FragmentHomeBinding { return FragmentHomeBinding.inflate(inflater, container, false) } @@ -31,11 +64,20 @@ } override fun observeRequestState() { + deviceViewModel.loadState.observe(this) { + when (it) { + is LoadState.Loading -> LoadingDialogHub.show( + requireActivity(), "数据加载中,请稍后" + ) + else -> LoadingDialogHub.dismiss() + } + } } override fun initEvent() { - + deviceViewModel.getDevices() + deviceViewModel.getAlarms() } override fun initOnCreate(savedInstanceState: Bundle?) { @@ -44,8 +86,11 @@ aMap.mapType = AMap.MAP_TYPE_SATELLITE val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 + uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER - uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 + uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜 // 地图加载成功监听 aMap.addOnMapLoadedListener(this) @@ -55,10 +100,102 @@ aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup aMap.setInfoWindowAdapter(this) + + //显示定位小蓝点 + val locationStyle = MyLocationStyle() + locationStyle.interval(2000) + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER)//定位、但不会移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + aMap.myLocationStyle = locationStyle//设置定位蓝点的Style + aMap.isMyLocationEnabled = true//设置是否显示定位小蓝点 + aMap.setOnMyLocationChangeListener { + + } + + deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] + deviceViewModel.mapDeviceResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + 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() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + deviceInfoModels.add(device) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(device.deviceName).snippet(device.wellCode) + ) + } + + //移动到指定经纬度 + val centerLatLng = LatLng(latitudeList.average(), longitudeList.average()) + val cameraPosition = CameraPosition(centerLatLng, 16f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + } + } + } + } + deviceViewModel.mapAlarmResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + it.data.forEach { alarm -> + val lat = alarm.latGaode.toString() + val lng = alarm.lngGaode.toString() + if (lat.isNotBlank() && lng.isNotBlank()) { + val latitude = lat.toDouble() + val longitude = lng.toDouble() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + alarmInfoModels.add(alarm) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(alarm.alarmContent).snippet(alarm.alarmId) + ) + } + } + } + } + } + } + + private fun moveToCurrentLocation() { + locationHub.getCurrentLocation(true, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { +// if (location != null) { +// aMap.moveCamera( +// CameraUpdateFactory.newLatLngZoom( +// LatLng(location.latitude, location.longitude), 16f +// ) +// ) +// } else { +// "当前位置信号差,无法移动地图到定位点".show(requireContext()) +// } + } + }) } override fun onMapLoaded() { - + initClustersMarkers() } override fun onCameraChange(p0: CameraPosition?) { @@ -66,15 +203,86 @@ } override fun onCameraChangeFinish(p0: CameraPosition?) { - + initClustersMarkers() } - override fun onMarkerClick(p0: Marker?): Boolean { + private fun initClustersMarkers() { + allMarkerOptions.forEach { + if (it.snippet.startsWith("GX")) { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_device).bitmap + ) + ) + } else { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_alarm).bitmap + ) + ) + } + aMap.addMarker(it) + } + } + + override fun onMarkerClick(marker: Marker?): Boolean { + //显示闸井信息 + marker?.showInfoWindow() return true } - override fun getInfoWindow(p0: Marker?): View? { + 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 wellNameView = v.findViewById(R.id.wellNameView) + val wellCodeView = v.findViewById(R.id.wellCodeView) + val wellTypeView = v.findViewById(R.id.wellTypeView) + val wellStateView = v.findViewById(R.id.wellStateView) + val deepView = v.findViewById(R.id.deepView) + val locationView = v.findViewById(R.id.locationView) + + val clickedMarker = marker?.snippet.toString() + Log.d(kTag, clickedMarker) + + if (clickedMarker.startsWith("GX")) { + //搜设备 + for (device in deviceInfoModels) { + if (clickedMarker == device.devcode) { + + Log.d(kTag, device.toJson()) + + wellNameView.text = String.format("设备名称: ${device.deviceName}") + wellCodeView.text = String.format("设备编号: ${device.devcode}") + wellTypeView.text = String.format("设备类型: ${device.deviceTypeName}") + wellStateView.text = String.format("权属单位: ${device.deptName}") + deepView.text = String.format("更新时间: ${device.realtimeData}") + locationView.text = String.format("详细位置: ${device.position}") + + return infoWindow + } + } + } else { + //搜报警 + for (alarm in alarmInfoModels) { + if (clickedMarker == alarm.alarmId) { + Log.d(kTag, alarm.toJson()) + + wellNameView.text = String.format("报警内容: ${alarm.alarmContent}") + wellCodeView.text = String.format("设备编号: ${alarm.wellCode}") + wellTypeView.text = String.format("设备类型: ${alarm.wellType.valueToType()}") +// wellStateView.text = String.format("布/撤防状态: $bfztName") + deepView.text = String.format("报警时间: ${alarm.alarmTimeDate}") + locationView.text = String.format("详细位置: ${alarm.position}") + + return infoWindow + } + } + } return null } @@ -82,12 +290,14 @@ /** * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框 * */ - override fun getInfoContents(p0: Marker?): View? = null + override fun getInfoContents(marker: Marker?): View? = null /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() binding.mapView.onResume() + //首次移动到定位点 + moveToCurrentLocation() } override fun onPause() { @@ -103,5 +313,6 @@ override fun onDestroy() { super.onDestroy() binding.mapView.onDestroy() + locationHub.stopLocation() } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java new file mode 100644 index 0000000..2edc0f2 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java @@ -0,0 +1,226 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapAlarmModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String alarmContent; + private String alarmId; + private String alarmTimeDate; + private String alarmType; + private String alarmValue; + private String coordinateX; + private String coordinateY; + private String deptid; + private String devcode; + private String deviceId; + private String deviceType; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String position; + private String wellCode; + private String wellId; + private String wellType; + private String wellTypeName; + + public String getAlarmContent() { + return alarmContent; + } + + public void setAlarmContent(String alarmContent) { + this.alarmContent = alarmContent; + } + + public String getAlarmId() { + return alarmId; + } + + public void setAlarmId(String alarmId) { + this.alarmId = alarmId; + } + + public String getAlarmTimeDate() { + return alarmTimeDate; + } + + public void setAlarmTimeDate(String alarmTimeDate) { + this.alarmTimeDate = alarmTimeDate; + } + + public String getAlarmType() { + return alarmType; + } + + public void setAlarmType(String alarmType) { + this.alarmType = alarmType; + } + + public String getAlarmValue() { + return alarmValue; + } + + public void setAlarmValue(String alarmValue) { + this.alarmValue = alarmValue; + } + + 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 getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + 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 getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getWellId() { + return wellId; + } + + public void setWellId(String wellId) { + this.wellId = wellId; + } + + 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/smart/town/sanxi/model/MapDeviceModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java new file mode 100644 index 0000000..59b6882 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java @@ -0,0 +1,199 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapDeviceModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String coordinateX; + private String coordinateY; + private String deptName; + private String deptid; + private String devcode; + private String deviceName; + private String deviceType; + private String deviceTypeName; + private String id; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String onlineState; + private String position; + private String realtimeData; + private String wellCode; + + 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 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 getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + 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 getOnlineState() { + return onlineState; + } + + public void setOnlineState(String onlineState) { + this.onlineState = onlineState; + } + + public String getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getRealtimeData() { + return realtimeData; + } + + public void setRealtimeData(String realtimeData) { + this.realtimeData = realtimeData; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + } +} diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt new file mode 100644 index 0000000..afdd3de --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt @@ -0,0 +1,7 @@ +package com.casic.smart.town.sanxi.util + +import com.amap.api.location.AMapLocation + +interface ILocationListener { + fun onAMapLocationGet(location: AMapLocation?) //高德定位数据 +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt new file mode 100644 index 0000000..ff813b9 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt @@ -0,0 +1,40 @@ +package com.casic.smart.town.sanxi.util + +import android.content.Context +import android.util.Log +import com.amap.api.location.AMapLocationClient +import com.amap.api.location.AMapLocationClientOption +import com.pengxh.kt.lite.base.BaseSingleton + +class LocationHub private constructor(context: Context) { + + companion object : BaseSingleton() { + override val creator: (Context) -> LocationHub + get() = ::LocationHub + } + + private val kTag = "LocationHub" + private val locationClient by lazy { AMapLocationClient(context) } + + fun getCurrentLocation(isOnceLocation: Boolean, listener: ILocationListener) { + val locationOption = AMapLocationClientOption() + locationOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy + locationOption.isOnceLocation = isOnceLocation + locationClient.setLocationOption(locationOption) + locationClient.setLocationListener { + if (it.errorCode == 0) { + listener.onAMapLocationGet(it) + } else { + listener.onAMapLocationGet(null) + Log.e( + kTag, "location Error, ErrCode:${it.errorCode}, errInfo:${it.errorInfo}" + ) + } + } + locationClient.startLocation() + } + + fun stopLocation() { + locationClient.stopLocation() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt index 0e561a6..7480627 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt @@ -206,4 +206,16 @@ */ @GET("/overview/wellList") suspend fun getAllWell(@Header("token") token: String): String + + /** + * 获取设备列表-不分页,地图用 + */ + @GET("/statics/deviceList") + suspend fun getDevices(@Header("token") token: String): String + + /** + * 获取报警列表-不分页,地图用 + */ + @GET("/device/alarmList") + suspend fun getAlarms(@Header("token") token: String): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt index 8d8f7fc..ca690a8 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt @@ -207,6 +207,14 @@ return smartTownApi.countDevice(AuthenticationHelper.token!!) } + suspend fun getDevices(): String { + return smartTownApi.getDevices(AuthenticationHelper.token!!) + } + + suspend fun getAlarms(): String { + return smartTownApi.getAlarms(AuthenticationHelper.token!!) + } + suspend fun queryWellInfo(deviceId: String): String { return smartTownApi.queryWellInfo(AuthenticationHelper.token!!, deviceId) } diff --git a/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt b/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt index a8bad16..b77a48d 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt @@ -200,6 +200,8 @@ wellStateView.text = String.format("布/撤防状态: $bfztName") deepView.text = String.format("点位深度: ${well.deep}m") locationView.text = String.format("详细位置: ${well.position}") + + return v } } return null diff --git a/app/src/main/java/com/casic/smart/town/sanxi/view/BFWellActivity.kt b/app/src/main/java/com/casic/smart/town/sanxi/view/BFWellActivity.kt index 4ae34fe..a3f1c6a 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/view/BFWellActivity.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/view/BFWellActivity.kt @@ -207,6 +207,8 @@ wellStateView.text = String.format("布/撤防状态: $bfztName") deepView.text = String.format("点位深度: ${well.deep}m") locationView.text = String.format("详细位置: ${well.position}") + + return v } } return null diff --git a/app/src/main/java/com/casic/smart/town/sanxi/view/CFWellActivity.kt b/app/src/main/java/com/casic/smart/town/sanxi/view/CFWellActivity.kt index 249a2fd..f98a065 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/view/CFWellActivity.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/view/CFWellActivity.kt @@ -208,6 +208,8 @@ wellStateView.text = String.format("布/撤防状态: $bfztName") deepView.text = String.format("点位深度: ${well.deep}m") locationView.text = String.format("详细位置: ${well.position}") + + return v } } return null diff --git a/app/src/main/java/com/casic/smart/town/sanxi/vm/DeviceViewModel.kt b/app/src/main/java/com/casic/smart/town/sanxi/vm/DeviceViewModel.kt index d018b0c..11e0563 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/vm/DeviceViewModel.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/vm/DeviceViewModel.kt @@ -5,6 +5,8 @@ import com.casic.smart.town.sanxi.extensions.separateResponseCode import com.casic.smart.town.sanxi.extensions.toErrorMessage import com.casic.smart.town.sanxi.model.DeviceModel +import com.casic.smart.town.sanxi.model.MapAlarmModel +import com.casic.smart.town.sanxi.model.MapDeviceModel import com.casic.smart.town.sanxi.util.retrofit.RetrofitServiceManager import com.google.gson.Gson import com.google.gson.reflect.TypeToken @@ -16,6 +18,8 @@ private val gson by lazy { Gson() } val resultModel = MutableLiveData() + val mapDeviceResult = MutableLiveData() + val mapAlarmResult = MutableLiveData() fun countDevice() = launch({ val response = RetrofitServiceManager.countDevice() @@ -31,4 +35,28 @@ it.cause.toString().show(BaseApplication.get()) it.printStackTrace() }) + + fun getDevices() = launch({ + val response = RetrofitServiceManager.getDevices() + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + mapDeviceResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } + }, { + it.printStackTrace() + }) + + fun getAlarms() = launch({ + val response = RetrofitServiceManager.getAlarms() + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + mapAlarmResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } + }, { + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index db8a60e..071a613 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -76,6 +76,9 @@ android:name="com.amap.api.v2.apikey" android:value="34064d6fa0c5ebd8ce48599386ce9c3a" /> + + + (), AMap.OnMapLoadedListener, - AMap.OnCameraChangeListener, - AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { + AMap.OnCameraChangeListener, AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { private val kTag = "HomePageFragment" private lateinit var aMap: AMap + private lateinit var deviceViewModel: DeviceViewModel + private val locationHub by lazy { LocationHub.obtainInstance(requireContext()) } + private var deviceInfoModels: MutableList = ArrayList() + private var alarmInfoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 自定义Marker弹出框 + * */ + private var infoWindow: View? = null override fun initViewBinding( - inflater: LayoutInflater, - container: ViewGroup? + inflater: LayoutInflater, container: ViewGroup? ): FragmentHomeBinding { return FragmentHomeBinding.inflate(inflater, container, false) } @@ -31,11 +64,20 @@ } override fun observeRequestState() { + deviceViewModel.loadState.observe(this) { + when (it) { + is LoadState.Loading -> LoadingDialogHub.show( + requireActivity(), "数据加载中,请稍后" + ) + else -> LoadingDialogHub.dismiss() + } + } } override fun initEvent() { - + deviceViewModel.getDevices() + deviceViewModel.getAlarms() } override fun initOnCreate(savedInstanceState: Bundle?) { @@ -44,8 +86,11 @@ aMap.mapType = AMap.MAP_TYPE_SATELLITE val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 + uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER - uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 + uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜 // 地图加载成功监听 aMap.addOnMapLoadedListener(this) @@ -55,10 +100,102 @@ aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup aMap.setInfoWindowAdapter(this) + + //显示定位小蓝点 + val locationStyle = MyLocationStyle() + locationStyle.interval(2000) + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER)//定位、但不会移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + aMap.myLocationStyle = locationStyle//设置定位蓝点的Style + aMap.isMyLocationEnabled = true//设置是否显示定位小蓝点 + aMap.setOnMyLocationChangeListener { + + } + + deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] + deviceViewModel.mapDeviceResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + 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() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + deviceInfoModels.add(device) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(device.deviceName).snippet(device.wellCode) + ) + } + + //移动到指定经纬度 + val centerLatLng = LatLng(latitudeList.average(), longitudeList.average()) + val cameraPosition = CameraPosition(centerLatLng, 16f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + } + } + } + } + deviceViewModel.mapAlarmResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + it.data.forEach { alarm -> + val lat = alarm.latGaode.toString() + val lng = alarm.lngGaode.toString() + if (lat.isNotBlank() && lng.isNotBlank()) { + val latitude = lat.toDouble() + val longitude = lng.toDouble() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + alarmInfoModels.add(alarm) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(alarm.alarmContent).snippet(alarm.alarmId) + ) + } + } + } + } + } + } + + private fun moveToCurrentLocation() { + locationHub.getCurrentLocation(true, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { +// if (location != null) { +// aMap.moveCamera( +// CameraUpdateFactory.newLatLngZoom( +// LatLng(location.latitude, location.longitude), 16f +// ) +// ) +// } else { +// "当前位置信号差,无法移动地图到定位点".show(requireContext()) +// } + } + }) } override fun onMapLoaded() { - + initClustersMarkers() } override fun onCameraChange(p0: CameraPosition?) { @@ -66,15 +203,86 @@ } override fun onCameraChangeFinish(p0: CameraPosition?) { - + initClustersMarkers() } - override fun onMarkerClick(p0: Marker?): Boolean { + private fun initClustersMarkers() { + allMarkerOptions.forEach { + if (it.snippet.startsWith("GX")) { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_device).bitmap + ) + ) + } else { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_alarm).bitmap + ) + ) + } + aMap.addMarker(it) + } + } + + override fun onMarkerClick(marker: Marker?): Boolean { + //显示闸井信息 + marker?.showInfoWindow() return true } - override fun getInfoWindow(p0: Marker?): View? { + 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 wellNameView = v.findViewById(R.id.wellNameView) + val wellCodeView = v.findViewById(R.id.wellCodeView) + val wellTypeView = v.findViewById(R.id.wellTypeView) + val wellStateView = v.findViewById(R.id.wellStateView) + val deepView = v.findViewById(R.id.deepView) + val locationView = v.findViewById(R.id.locationView) + + val clickedMarker = marker?.snippet.toString() + Log.d(kTag, clickedMarker) + + if (clickedMarker.startsWith("GX")) { + //搜设备 + for (device in deviceInfoModels) { + if (clickedMarker == device.devcode) { + + Log.d(kTag, device.toJson()) + + wellNameView.text = String.format("设备名称: ${device.deviceName}") + wellCodeView.text = String.format("设备编号: ${device.devcode}") + wellTypeView.text = String.format("设备类型: ${device.deviceTypeName}") + wellStateView.text = String.format("权属单位: ${device.deptName}") + deepView.text = String.format("更新时间: ${device.realtimeData}") + locationView.text = String.format("详细位置: ${device.position}") + + return infoWindow + } + } + } else { + //搜报警 + for (alarm in alarmInfoModels) { + if (clickedMarker == alarm.alarmId) { + Log.d(kTag, alarm.toJson()) + + wellNameView.text = String.format("报警内容: ${alarm.alarmContent}") + wellCodeView.text = String.format("设备编号: ${alarm.wellCode}") + wellTypeView.text = String.format("设备类型: ${alarm.wellType.valueToType()}") +// wellStateView.text = String.format("布/撤防状态: $bfztName") + deepView.text = String.format("报警时间: ${alarm.alarmTimeDate}") + locationView.text = String.format("详细位置: ${alarm.position}") + + return infoWindow + } + } + } return null } @@ -82,12 +290,14 @@ /** * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框 * */ - override fun getInfoContents(p0: Marker?): View? = null + override fun getInfoContents(marker: Marker?): View? = null /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() binding.mapView.onResume() + //首次移动到定位点 + moveToCurrentLocation() } override fun onPause() { @@ -103,5 +313,6 @@ override fun onDestroy() { super.onDestroy() binding.mapView.onDestroy() + locationHub.stopLocation() } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java new file mode 100644 index 0000000..2edc0f2 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java @@ -0,0 +1,226 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapAlarmModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String alarmContent; + private String alarmId; + private String alarmTimeDate; + private String alarmType; + private String alarmValue; + private String coordinateX; + private String coordinateY; + private String deptid; + private String devcode; + private String deviceId; + private String deviceType; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String position; + private String wellCode; + private String wellId; + private String wellType; + private String wellTypeName; + + public String getAlarmContent() { + return alarmContent; + } + + public void setAlarmContent(String alarmContent) { + this.alarmContent = alarmContent; + } + + public String getAlarmId() { + return alarmId; + } + + public void setAlarmId(String alarmId) { + this.alarmId = alarmId; + } + + public String getAlarmTimeDate() { + return alarmTimeDate; + } + + public void setAlarmTimeDate(String alarmTimeDate) { + this.alarmTimeDate = alarmTimeDate; + } + + public String getAlarmType() { + return alarmType; + } + + public void setAlarmType(String alarmType) { + this.alarmType = alarmType; + } + + public String getAlarmValue() { + return alarmValue; + } + + public void setAlarmValue(String alarmValue) { + this.alarmValue = alarmValue; + } + + 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 getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + 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 getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getWellId() { + return wellId; + } + + public void setWellId(String wellId) { + this.wellId = wellId; + } + + 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/smart/town/sanxi/model/MapDeviceModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java new file mode 100644 index 0000000..59b6882 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java @@ -0,0 +1,199 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapDeviceModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String coordinateX; + private String coordinateY; + private String deptName; + private String deptid; + private String devcode; + private String deviceName; + private String deviceType; + private String deviceTypeName; + private String id; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String onlineState; + private String position; + private String realtimeData; + private String wellCode; + + 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 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 getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + 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 getOnlineState() { + return onlineState; + } + + public void setOnlineState(String onlineState) { + this.onlineState = onlineState; + } + + public String getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getRealtimeData() { + return realtimeData; + } + + public void setRealtimeData(String realtimeData) { + this.realtimeData = realtimeData; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + } +} diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt new file mode 100644 index 0000000..afdd3de --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt @@ -0,0 +1,7 @@ +package com.casic.smart.town.sanxi.util + +import com.amap.api.location.AMapLocation + +interface ILocationListener { + fun onAMapLocationGet(location: AMapLocation?) //高德定位数据 +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt new file mode 100644 index 0000000..ff813b9 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt @@ -0,0 +1,40 @@ +package com.casic.smart.town.sanxi.util + +import android.content.Context +import android.util.Log +import com.amap.api.location.AMapLocationClient +import com.amap.api.location.AMapLocationClientOption +import com.pengxh.kt.lite.base.BaseSingleton + +class LocationHub private constructor(context: Context) { + + companion object : BaseSingleton() { + override val creator: (Context) -> LocationHub + get() = ::LocationHub + } + + private val kTag = "LocationHub" + private val locationClient by lazy { AMapLocationClient(context) } + + fun getCurrentLocation(isOnceLocation: Boolean, listener: ILocationListener) { + val locationOption = AMapLocationClientOption() + locationOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy + locationOption.isOnceLocation = isOnceLocation + locationClient.setLocationOption(locationOption) + locationClient.setLocationListener { + if (it.errorCode == 0) { + listener.onAMapLocationGet(it) + } else { + listener.onAMapLocationGet(null) + Log.e( + kTag, "location Error, ErrCode:${it.errorCode}, errInfo:${it.errorInfo}" + ) + } + } + locationClient.startLocation() + } + + fun stopLocation() { + locationClient.stopLocation() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt index 0e561a6..7480627 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt @@ -206,4 +206,16 @@ */ @GET("/overview/wellList") suspend fun getAllWell(@Header("token") token: String): String + + /** + * 获取设备列表-不分页,地图用 + */ + @GET("/statics/deviceList") + suspend fun getDevices(@Header("token") token: String): String + + /** + * 获取报警列表-不分页,地图用 + */ + @GET("/device/alarmList") + suspend fun getAlarms(@Header("token") token: String): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt index 8d8f7fc..ca690a8 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt @@ -207,6 +207,14 @@ return smartTownApi.countDevice(AuthenticationHelper.token!!) } + suspend fun getDevices(): String { + return smartTownApi.getDevices(AuthenticationHelper.token!!) + } + + suspend fun getAlarms(): String { + return smartTownApi.getAlarms(AuthenticationHelper.token!!) + } + suspend fun queryWellInfo(deviceId: String): String { return smartTownApi.queryWellInfo(AuthenticationHelper.token!!, deviceId) } diff --git a/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt b/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt index a8bad16..b77a48d 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt @@ -200,6 +200,8 @@ wellStateView.text = String.format("布/撤防状态: $bfztName") deepView.text = String.format("点位深度: ${well.deep}m") locationView.text = String.format("详细位置: ${well.position}") + + return v } } return null diff --git a/app/src/main/java/com/casic/smart/town/sanxi/view/BFWellActivity.kt b/app/src/main/java/com/casic/smart/town/sanxi/view/BFWellActivity.kt index 4ae34fe..a3f1c6a 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/view/BFWellActivity.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/view/BFWellActivity.kt @@ -207,6 +207,8 @@ wellStateView.text = String.format("布/撤防状态: $bfztName") deepView.text = String.format("点位深度: ${well.deep}m") locationView.text = String.format("详细位置: ${well.position}") + + return v } } return null diff --git a/app/src/main/java/com/casic/smart/town/sanxi/view/CFWellActivity.kt b/app/src/main/java/com/casic/smart/town/sanxi/view/CFWellActivity.kt index 249a2fd..f98a065 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/view/CFWellActivity.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/view/CFWellActivity.kt @@ -208,6 +208,8 @@ wellStateView.text = String.format("布/撤防状态: $bfztName") deepView.text = String.format("点位深度: ${well.deep}m") locationView.text = String.format("详细位置: ${well.position}") + + return v } } return null diff --git a/app/src/main/java/com/casic/smart/town/sanxi/vm/DeviceViewModel.kt b/app/src/main/java/com/casic/smart/town/sanxi/vm/DeviceViewModel.kt index d018b0c..11e0563 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/vm/DeviceViewModel.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/vm/DeviceViewModel.kt @@ -5,6 +5,8 @@ import com.casic.smart.town.sanxi.extensions.separateResponseCode import com.casic.smart.town.sanxi.extensions.toErrorMessage import com.casic.smart.town.sanxi.model.DeviceModel +import com.casic.smart.town.sanxi.model.MapAlarmModel +import com.casic.smart.town.sanxi.model.MapDeviceModel import com.casic.smart.town.sanxi.util.retrofit.RetrofitServiceManager import com.google.gson.Gson import com.google.gson.reflect.TypeToken @@ -16,6 +18,8 @@ private val gson by lazy { Gson() } val resultModel = MutableLiveData() + val mapDeviceResult = MutableLiveData() + val mapAlarmResult = MutableLiveData() fun countDevice() = launch({ val response = RetrofitServiceManager.countDevice() @@ -31,4 +35,28 @@ it.cause.toString().show(BaseApplication.get()) it.printStackTrace() }) + + fun getDevices() = launch({ + val response = RetrofitServiceManager.getDevices() + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + mapDeviceResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } + }, { + it.printStackTrace() + }) + + fun getAlarms() = launch({ + val response = RetrofitServiceManager.getAlarms() + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + mapAlarmResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } + }, { + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/res/mipmap-xxxhdpi/map_alarm.png b/app/src/main/res/mipmap-xxxhdpi/map_alarm.png new file mode 100644 index 0000000..2b15bf5 --- /dev/null +++ b/app/src/main/res/mipmap-xxxhdpi/map_alarm.png Binary files differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index db8a60e..071a613 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -76,6 +76,9 @@ android:name="com.amap.api.v2.apikey" android:value="34064d6fa0c5ebd8ce48599386ce9c3a" /> + + + (), AMap.OnMapLoadedListener, - AMap.OnCameraChangeListener, - AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { + AMap.OnCameraChangeListener, AMap.OnMarkerClickListener, AMap.InfoWindowAdapter { private val kTag = "HomePageFragment" private lateinit var aMap: AMap + private lateinit var deviceViewModel: DeviceViewModel + private val locationHub by lazy { LocationHub.obtainInstance(requireContext()) } + private var deviceInfoModels: MutableList = ArrayList() + private var alarmInfoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 自定义Marker弹出框 + * */ + private var infoWindow: View? = null override fun initViewBinding( - inflater: LayoutInflater, - container: ViewGroup? + inflater: LayoutInflater, container: ViewGroup? ): FragmentHomeBinding { return FragmentHomeBinding.inflate(inflater, container, false) } @@ -31,11 +64,20 @@ } override fun observeRequestState() { + deviceViewModel.loadState.observe(this) { + when (it) { + is LoadState.Loading -> LoadingDialogHub.show( + requireActivity(), "数据加载中,请稍后" + ) + else -> LoadingDialogHub.dismiss() + } + } } override fun initEvent() { - + deviceViewModel.getDevices() + deviceViewModel.getAlarms() } override fun initOnCreate(savedInstanceState: Bundle?) { @@ -44,8 +86,11 @@ aMap.mapType = AMap.MAP_TYPE_SATELLITE val uiSettings = aMap.uiSettings uiSettings.isCompassEnabled = true + uiSettings.isMyLocationButtonEnabled = false//不显示默认定位按钮 + uiSettings.isScaleControlsEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER - uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 + uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜 // 地图加载成功监听 aMap.addOnMapLoadedListener(this) @@ -55,10 +100,102 @@ aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup aMap.setInfoWindowAdapter(this) + + //显示定位小蓝点 + val locationStyle = MyLocationStyle() + locationStyle.interval(2000) + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER)//定位、但不会移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + aMap.myLocationStyle = locationStyle//设置定位蓝点的Style + aMap.isMyLocationEnabled = true//设置是否显示定位小蓝点 + aMap.setOnMyLocationChangeListener { + + } + + deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] + deviceViewModel.mapDeviceResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + 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() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + deviceInfoModels.add(device) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(device.deviceName).snippet(device.wellCode) + ) + } + + //移动到指定经纬度 + val centerLatLng = LatLng(latitudeList.average(), longitudeList.average()) + val cameraPosition = CameraPosition(centerLatLng, 16f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + } + } + } + } + deviceViewModel.mapAlarmResult.observe(this) { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + it.data.forEach { alarm -> + val lat = alarm.latGaode.toString() + val lng = alarm.lngGaode.toString() + if (lat.isNotBlank() && lng.isNotBlank()) { + val latitude = lat.toDouble() + val longitude = lng.toDouble() + + //缓存所有设备详情,点击Marker时候需要 + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + alarmInfoModels.add(alarm) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions().position(LatLng(latitude, longitude)) + .title(alarm.alarmContent).snippet(alarm.alarmId) + ) + } + } + } + } + } + } + + private fun moveToCurrentLocation() { + locationHub.getCurrentLocation(true, object : ILocationListener { + override fun onAMapLocationGet(location: AMapLocation?) { +// if (location != null) { +// aMap.moveCamera( +// CameraUpdateFactory.newLatLngZoom( +// LatLng(location.latitude, location.longitude), 16f +// ) +// ) +// } else { +// "当前位置信号差,无法移动地图到定位点".show(requireContext()) +// } + } + }) } override fun onMapLoaded() { - + initClustersMarkers() } override fun onCameraChange(p0: CameraPosition?) { @@ -66,15 +203,86 @@ } override fun onCameraChangeFinish(p0: CameraPosition?) { - + initClustersMarkers() } - override fun onMarkerClick(p0: Marker?): Boolean { + private fun initClustersMarkers() { + allMarkerOptions.forEach { + if (it.snippet.startsWith("GX")) { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_device).bitmap + ) + ) + } else { + it.icon( + BitmapDescriptorFactory.fromBitmap( + BitmapDescriptorFactory.fromResource(R.mipmap.map_alarm).bitmap + ) + ) + } + aMap.addMarker(it) + } + } + + override fun onMarkerClick(marker: Marker?): Boolean { + //显示闸井信息 + marker?.showInfoWindow() return true } - override fun getInfoWindow(p0: Marker?): View? { + 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 wellNameView = v.findViewById(R.id.wellNameView) + val wellCodeView = v.findViewById(R.id.wellCodeView) + val wellTypeView = v.findViewById(R.id.wellTypeView) + val wellStateView = v.findViewById(R.id.wellStateView) + val deepView = v.findViewById(R.id.deepView) + val locationView = v.findViewById(R.id.locationView) + + val clickedMarker = marker?.snippet.toString() + Log.d(kTag, clickedMarker) + + if (clickedMarker.startsWith("GX")) { + //搜设备 + for (device in deviceInfoModels) { + if (clickedMarker == device.devcode) { + + Log.d(kTag, device.toJson()) + + wellNameView.text = String.format("设备名称: ${device.deviceName}") + wellCodeView.text = String.format("设备编号: ${device.devcode}") + wellTypeView.text = String.format("设备类型: ${device.deviceTypeName}") + wellStateView.text = String.format("权属单位: ${device.deptName}") + deepView.text = String.format("更新时间: ${device.realtimeData}") + locationView.text = String.format("详细位置: ${device.position}") + + return infoWindow + } + } + } else { + //搜报警 + for (alarm in alarmInfoModels) { + if (clickedMarker == alarm.alarmId) { + Log.d(kTag, alarm.toJson()) + + wellNameView.text = String.format("报警内容: ${alarm.alarmContent}") + wellCodeView.text = String.format("设备编号: ${alarm.wellCode}") + wellTypeView.text = String.format("设备类型: ${alarm.wellType.valueToType()}") +// wellStateView.text = String.format("布/撤防状态: $bfztName") + deepView.text = String.format("报警时间: ${alarm.alarmTimeDate}") + locationView.text = String.format("详细位置: ${alarm.position}") + + return infoWindow + } + } + } return null } @@ -82,12 +290,14 @@ /** * 此方法不能修改整个 InfoWindow 的背景和边框,无论自定义的样式是什么样,SDK 都会在最外层添加一个默认的边框 * */ - override fun getInfoContents(p0: Marker?): View? = null + override fun getInfoContents(marker: Marker?): View? = null /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() binding.mapView.onResume() + //首次移动到定位点 + moveToCurrentLocation() } override fun onPause() { @@ -103,5 +313,6 @@ override fun onDestroy() { super.onDestroy() binding.mapView.onDestroy() + locationHub.stopLocation() } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java new file mode 100644 index 0000000..2edc0f2 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapAlarmModel.java @@ -0,0 +1,226 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapAlarmModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String alarmContent; + private String alarmId; + private String alarmTimeDate; + private String alarmType; + private String alarmValue; + private String coordinateX; + private String coordinateY; + private String deptid; + private String devcode; + private String deviceId; + private String deviceType; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String position; + private String wellCode; + private String wellId; + private String wellType; + private String wellTypeName; + + public String getAlarmContent() { + return alarmContent; + } + + public void setAlarmContent(String alarmContent) { + this.alarmContent = alarmContent; + } + + public String getAlarmId() { + return alarmId; + } + + public void setAlarmId(String alarmId) { + this.alarmId = alarmId; + } + + public String getAlarmTimeDate() { + return alarmTimeDate; + } + + public void setAlarmTimeDate(String alarmTimeDate) { + this.alarmTimeDate = alarmTimeDate; + } + + public String getAlarmType() { + return alarmType; + } + + public void setAlarmType(String alarmType) { + this.alarmType = alarmType; + } + + public String getAlarmValue() { + return alarmValue; + } + + public void setAlarmValue(String alarmValue) { + this.alarmValue = alarmValue; + } + + 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 getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + 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 getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getWellId() { + return wellId; + } + + public void setWellId(String wellId) { + this.wellId = wellId; + } + + 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/smart/town/sanxi/model/MapDeviceModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java new file mode 100644 index 0000000..59b6882 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/MapDeviceModel.java @@ -0,0 +1,199 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class MapDeviceModel { + + private Integer code; + private List data; + private String message; + private Boolean success; + + public Integer getCode() { + return code; + } + + public void setCode(Integer 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 getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public static class DataModel { + private String coordinateX; + private String coordinateY; + private String deptName; + private String deptid; + private String devcode; + private String deviceName; + private String deviceType; + private String deviceTypeName; + private String id; + private String latBaidu; + private String latGaode; + private String lngBaidu; + private String lngGaode; + private String onlineState; + private String position; + private String realtimeData; + private String wellCode; + + 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 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 getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + 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 getOnlineState() { + return onlineState; + } + + public void setOnlineState(String onlineState) { + this.onlineState = onlineState; + } + + public String getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getRealtimeData() { + return realtimeData; + } + + public void setRealtimeData(String realtimeData) { + this.realtimeData = realtimeData; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + } +} diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt new file mode 100644 index 0000000..afdd3de --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/ILocationListener.kt @@ -0,0 +1,7 @@ +package com.casic.smart.town.sanxi.util + +import com.amap.api.location.AMapLocation + +interface ILocationListener { + fun onAMapLocationGet(location: AMapLocation?) //高德定位数据 +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt new file mode 100644 index 0000000..ff813b9 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/LocationHub.kt @@ -0,0 +1,40 @@ +package com.casic.smart.town.sanxi.util + +import android.content.Context +import android.util.Log +import com.amap.api.location.AMapLocationClient +import com.amap.api.location.AMapLocationClientOption +import com.pengxh.kt.lite.base.BaseSingleton + +class LocationHub private constructor(context: Context) { + + companion object : BaseSingleton() { + override val creator: (Context) -> LocationHub + get() = ::LocationHub + } + + private val kTag = "LocationHub" + private val locationClient by lazy { AMapLocationClient(context) } + + fun getCurrentLocation(isOnceLocation: Boolean, listener: ILocationListener) { + val locationOption = AMapLocationClientOption() + locationOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy + locationOption.isOnceLocation = isOnceLocation + locationClient.setLocationOption(locationOption) + locationClient.setLocationListener { + if (it.errorCode == 0) { + listener.onAMapLocationGet(it) + } else { + listener.onAMapLocationGet(null) + Log.e( + kTag, "location Error, ErrCode:${it.errorCode}, errInfo:${it.errorInfo}" + ) + } + } + locationClient.startLocation() + } + + fun stopLocation() { + locationClient.stopLocation() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt index 0e561a6..7480627 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitService.kt @@ -206,4 +206,16 @@ */ @GET("/overview/wellList") suspend fun getAllWell(@Header("token") token: String): String + + /** + * 获取设备列表-不分页,地图用 + */ + @GET("/statics/deviceList") + suspend fun getDevices(@Header("token") token: String): String + + /** + * 获取报警列表-不分页,地图用 + */ + @GET("/device/alarmList") + suspend fun getAlarms(@Header("token") token: String): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt index 8d8f7fc..ca690a8 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/util/retrofit/RetrofitServiceManager.kt @@ -207,6 +207,14 @@ return smartTownApi.countDevice(AuthenticationHelper.token!!) } + suspend fun getDevices(): String { + return smartTownApi.getDevices(AuthenticationHelper.token!!) + } + + suspend fun getAlarms(): String { + return smartTownApi.getAlarms(AuthenticationHelper.token!!) + } + suspend fun queryWellInfo(deviceId: String): String { return smartTownApi.queryWellInfo(AuthenticationHelper.token!!, deviceId) } diff --git a/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt b/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt index a8bad16..b77a48d 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/view/AllWellActivity.kt @@ -200,6 +200,8 @@ wellStateView.text = String.format("布/撤防状态: $bfztName") deepView.text = String.format("点位深度: ${well.deep}m") locationView.text = String.format("详细位置: ${well.position}") + + return v } } return null diff --git a/app/src/main/java/com/casic/smart/town/sanxi/view/BFWellActivity.kt b/app/src/main/java/com/casic/smart/town/sanxi/view/BFWellActivity.kt index 4ae34fe..a3f1c6a 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/view/BFWellActivity.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/view/BFWellActivity.kt @@ -207,6 +207,8 @@ wellStateView.text = String.format("布/撤防状态: $bfztName") deepView.text = String.format("点位深度: ${well.deep}m") locationView.text = String.format("详细位置: ${well.position}") + + return v } } return null diff --git a/app/src/main/java/com/casic/smart/town/sanxi/view/CFWellActivity.kt b/app/src/main/java/com/casic/smart/town/sanxi/view/CFWellActivity.kt index 249a2fd..f98a065 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/view/CFWellActivity.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/view/CFWellActivity.kt @@ -208,6 +208,8 @@ wellStateView.text = String.format("布/撤防状态: $bfztName") deepView.text = String.format("点位深度: ${well.deep}m") locationView.text = String.format("详细位置: ${well.position}") + + return v } } return null diff --git a/app/src/main/java/com/casic/smart/town/sanxi/vm/DeviceViewModel.kt b/app/src/main/java/com/casic/smart/town/sanxi/vm/DeviceViewModel.kt index d018b0c..11e0563 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/vm/DeviceViewModel.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/vm/DeviceViewModel.kt @@ -5,6 +5,8 @@ import com.casic.smart.town.sanxi.extensions.separateResponseCode import com.casic.smart.town.sanxi.extensions.toErrorMessage import com.casic.smart.town.sanxi.model.DeviceModel +import com.casic.smart.town.sanxi.model.MapAlarmModel +import com.casic.smart.town.sanxi.model.MapDeviceModel import com.casic.smart.town.sanxi.util.retrofit.RetrofitServiceManager import com.google.gson.Gson import com.google.gson.reflect.TypeToken @@ -16,6 +18,8 @@ private val gson by lazy { Gson() } val resultModel = MutableLiveData() + val mapDeviceResult = MutableLiveData() + val mapAlarmResult = MutableLiveData() fun countDevice() = launch({ val response = RetrofitServiceManager.countDevice() @@ -31,4 +35,28 @@ it.cause.toString().show(BaseApplication.get()) it.printStackTrace() }) + + fun getDevices() = launch({ + val response = RetrofitServiceManager.getDevices() + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + mapDeviceResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } + }, { + it.printStackTrace() + }) + + fun getAlarms() = launch({ + val response = RetrofitServiceManager.getAlarms() + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + mapAlarmResult.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } + }, { + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/res/mipmap-xxxhdpi/map_alarm.png b/app/src/main/res/mipmap-xxxhdpi/map_alarm.png new file mode 100644 index 0000000..2b15bf5 --- /dev/null +++ b/app/src/main/res/mipmap-xxxhdpi/map_alarm.png Binary files differ diff --git a/app/src/main/res/mipmap-xxxhdpi/map_device.png b/app/src/main/res/mipmap-xxxhdpi/map_device.png new file mode 100644 index 0000000..7160d97 --- /dev/null +++ b/app/src/main/res/mipmap-xxxhdpi/map_device.png Binary files differ