diff --git a/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt b/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt index deac8ac..84754fe 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt @@ -1,23 +1,48 @@ package com.casic.smart.town.sanxi.fragment +import android.graphics.Point import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions +import com.amap.api.maps.CameraUpdateFactory +import com.amap.api.maps.CoordinateConverter +import com.amap.api.maps.model.BitmapDescriptorFactory +import com.amap.api.maps.model.CameraPosition +import com.amap.api.maps.model.LatLng +import com.amap.api.maps.model.MarkerOptions import com.casic.smart.town.sanxi.R +import com.casic.smart.town.sanxi.model.VideoModel import com.casic.smart.town.sanxi.view.MonitorRecordActivity +import com.casic.smart.town.sanxi.vm.VideoViewModel import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_monitor.view.* -class MonitorPageFragment : Fragment() { +class MonitorPageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener { private val kTag = "HomePageFragment" private lateinit var monitorView: View private lateinit var aMap: AMap + private lateinit var videoViewModel: VideoViewModel + + /** + * 所有视频设备列表信息集合 + * */ + private var videoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 视野内的marker + */ + private var markerOptionsInView: MutableList = ArrayList() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -29,6 +54,46 @@ monitorView.rightOperateView.setOnClickListener { requireContext().navigatePageTo() } + + videoViewModel = ViewModelProvider(this)[VideoViewModel::class.java] + videoViewModel.queryVideoCameraList() + videoViewModel.resultModel.observe(requireActivity(), { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + it.data?.forEach { video -> + val lat = video.latitude.toString() + val lng = video.longitude.toString() + if (lat.isNotBlank() && lng.isNotBlank()) { + //返回true代表当前位置在大陆、港澳地区,反之不在 + val latitude = lat.toDouble() + val longitude = lng.toDouble() + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + //缓存所有设备详情,点击Marker时候需要 + videoModels.add(video) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions() + .position(LatLng(latitude, longitude)) + .title(video.name) + .snippet(video.code) + ) + } + + //计算所有点的中心点位置 + val centerLatLng = LatLng(latitudeList.average(), longitudeList.average()) + //移动到指定经纬度 + val cameraPosition = CameraPosition(centerLatLng, 16f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate, 2000, null) + } + } + } + }) return monitorView } @@ -42,9 +107,9 @@ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 // 地图加载成功监听 -// aMap.addOnMapLoadedListener(this) + aMap.addOnMapLoadedListener(this) // 地图缩放监听 -// aMap.addOnCameraChangeListener(this) + aMap.addOnCameraChangeListener(this) // marker 点击事件监听 // aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup @@ -53,6 +118,37 @@ // aMap.addOnInfoWindowClickListener(this) } + override fun onMapLoaded() { + //地图加载成功之后显示聚合点数据 + initClustersMarkers() + } + + override fun onCameraChange(p0: CameraPosition?) { + + } + + override fun onCameraChangeFinish(p0: CameraPosition?) { + initClustersMarkers() + } + + private fun initClustersMarkers() { + val proj = aMap.projection + val dm = resources.displayMetrics + var screenLocation: Point + markerOptionsInView.clear() + // 获取在当前视野内的marker + allMarkerOptions.forEach { + screenLocation = proj.toScreenLocation(it.position) + if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) { + it.icon(BitmapDescriptorFactory.fromBitmap(BitmapDescriptorFactory.fromResource(R.mipmap.map_pin).bitmap)) + markerOptionsInView.add(it) + } + } + markerOptionsInView.forEach { + aMap.addMarker(it) + } + } + /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() diff --git a/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt b/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt index deac8ac..84754fe 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt @@ -1,23 +1,48 @@ package com.casic.smart.town.sanxi.fragment +import android.graphics.Point import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions +import com.amap.api.maps.CameraUpdateFactory +import com.amap.api.maps.CoordinateConverter +import com.amap.api.maps.model.BitmapDescriptorFactory +import com.amap.api.maps.model.CameraPosition +import com.amap.api.maps.model.LatLng +import com.amap.api.maps.model.MarkerOptions import com.casic.smart.town.sanxi.R +import com.casic.smart.town.sanxi.model.VideoModel import com.casic.smart.town.sanxi.view.MonitorRecordActivity +import com.casic.smart.town.sanxi.vm.VideoViewModel import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_monitor.view.* -class MonitorPageFragment : Fragment() { +class MonitorPageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener { private val kTag = "HomePageFragment" private lateinit var monitorView: View private lateinit var aMap: AMap + private lateinit var videoViewModel: VideoViewModel + + /** + * 所有视频设备列表信息集合 + * */ + private var videoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 视野内的marker + */ + private var markerOptionsInView: MutableList = ArrayList() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -29,6 +54,46 @@ monitorView.rightOperateView.setOnClickListener { requireContext().navigatePageTo() } + + videoViewModel = ViewModelProvider(this)[VideoViewModel::class.java] + videoViewModel.queryVideoCameraList() + videoViewModel.resultModel.observe(requireActivity(), { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + it.data?.forEach { video -> + val lat = video.latitude.toString() + val lng = video.longitude.toString() + if (lat.isNotBlank() && lng.isNotBlank()) { + //返回true代表当前位置在大陆、港澳地区,反之不在 + val latitude = lat.toDouble() + val longitude = lng.toDouble() + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + //缓存所有设备详情,点击Marker时候需要 + videoModels.add(video) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions() + .position(LatLng(latitude, longitude)) + .title(video.name) + .snippet(video.code) + ) + } + + //计算所有点的中心点位置 + val centerLatLng = LatLng(latitudeList.average(), longitudeList.average()) + //移动到指定经纬度 + val cameraPosition = CameraPosition(centerLatLng, 16f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate, 2000, null) + } + } + } + }) return monitorView } @@ -42,9 +107,9 @@ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 // 地图加载成功监听 -// aMap.addOnMapLoadedListener(this) + aMap.addOnMapLoadedListener(this) // 地图缩放监听 -// aMap.addOnCameraChangeListener(this) + aMap.addOnCameraChangeListener(this) // marker 点击事件监听 // aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup @@ -53,6 +118,37 @@ // aMap.addOnInfoWindowClickListener(this) } + override fun onMapLoaded() { + //地图加载成功之后显示聚合点数据 + initClustersMarkers() + } + + override fun onCameraChange(p0: CameraPosition?) { + + } + + override fun onCameraChangeFinish(p0: CameraPosition?) { + initClustersMarkers() + } + + private fun initClustersMarkers() { + val proj = aMap.projection + val dm = resources.displayMetrics + var screenLocation: Point + markerOptionsInView.clear() + // 获取在当前视野内的marker + allMarkerOptions.forEach { + screenLocation = proj.toScreenLocation(it.position) + if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) { + it.icon(BitmapDescriptorFactory.fromBitmap(BitmapDescriptorFactory.fromResource(R.mipmap.map_pin).bitmap)) + markerOptionsInView.add(it) + } + } + markerOptionsInView.forEach { + aMap.addMarker(it) + } + } + /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() diff --git a/app/src/main/java/com/casic/smart/town/sanxi/model/VideoModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/VideoModel.java new file mode 100644 index 0000000..a313487 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/VideoModel.java @@ -0,0 +1,91 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class VideoModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private String code; + private String road; + private String latitude; + private String name; + private String longitude; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getRoad() { + return road; + } + + public void setRoad(String road) { + this.road = road; + } + + public String getLatitude() { + return latitude; + } + + public void setLatitude(String latitude) { + this.latitude = latitude; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLongitude() { + return longitude; + } + + public void setLongitude(String longitude) { + this.longitude = longitude; + } + } +} diff --git a/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt b/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt index deac8ac..84754fe 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt @@ -1,23 +1,48 @@ package com.casic.smart.town.sanxi.fragment +import android.graphics.Point import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions +import com.amap.api.maps.CameraUpdateFactory +import com.amap.api.maps.CoordinateConverter +import com.amap.api.maps.model.BitmapDescriptorFactory +import com.amap.api.maps.model.CameraPosition +import com.amap.api.maps.model.LatLng +import com.amap.api.maps.model.MarkerOptions import com.casic.smart.town.sanxi.R +import com.casic.smart.town.sanxi.model.VideoModel import com.casic.smart.town.sanxi.view.MonitorRecordActivity +import com.casic.smart.town.sanxi.vm.VideoViewModel import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_monitor.view.* -class MonitorPageFragment : Fragment() { +class MonitorPageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener { private val kTag = "HomePageFragment" private lateinit var monitorView: View private lateinit var aMap: AMap + private lateinit var videoViewModel: VideoViewModel + + /** + * 所有视频设备列表信息集合 + * */ + private var videoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 视野内的marker + */ + private var markerOptionsInView: MutableList = ArrayList() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -29,6 +54,46 @@ monitorView.rightOperateView.setOnClickListener { requireContext().navigatePageTo() } + + videoViewModel = ViewModelProvider(this)[VideoViewModel::class.java] + videoViewModel.queryVideoCameraList() + videoViewModel.resultModel.observe(requireActivity(), { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + it.data?.forEach { video -> + val lat = video.latitude.toString() + val lng = video.longitude.toString() + if (lat.isNotBlank() && lng.isNotBlank()) { + //返回true代表当前位置在大陆、港澳地区,反之不在 + val latitude = lat.toDouble() + val longitude = lng.toDouble() + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + //缓存所有设备详情,点击Marker时候需要 + videoModels.add(video) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions() + .position(LatLng(latitude, longitude)) + .title(video.name) + .snippet(video.code) + ) + } + + //计算所有点的中心点位置 + val centerLatLng = LatLng(latitudeList.average(), longitudeList.average()) + //移动到指定经纬度 + val cameraPosition = CameraPosition(centerLatLng, 16f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate, 2000, null) + } + } + } + }) return monitorView } @@ -42,9 +107,9 @@ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 // 地图加载成功监听 -// aMap.addOnMapLoadedListener(this) + aMap.addOnMapLoadedListener(this) // 地图缩放监听 -// aMap.addOnCameraChangeListener(this) + aMap.addOnCameraChangeListener(this) // marker 点击事件监听 // aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup @@ -53,6 +118,37 @@ // aMap.addOnInfoWindowClickListener(this) } + override fun onMapLoaded() { + //地图加载成功之后显示聚合点数据 + initClustersMarkers() + } + + override fun onCameraChange(p0: CameraPosition?) { + + } + + override fun onCameraChangeFinish(p0: CameraPosition?) { + initClustersMarkers() + } + + private fun initClustersMarkers() { + val proj = aMap.projection + val dm = resources.displayMetrics + var screenLocation: Point + markerOptionsInView.clear() + // 获取在当前视野内的marker + allMarkerOptions.forEach { + screenLocation = proj.toScreenLocation(it.position) + if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) { + it.icon(BitmapDescriptorFactory.fromBitmap(BitmapDescriptorFactory.fromResource(R.mipmap.map_pin).bitmap)) + markerOptionsInView.add(it) + } + } + markerOptionsInView.forEach { + aMap.addMarker(it) + } + } + /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() diff --git a/app/src/main/java/com/casic/smart/town/sanxi/model/VideoModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/VideoModel.java new file mode 100644 index 0000000..a313487 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/VideoModel.java @@ -0,0 +1,91 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class VideoModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private String code; + private String road; + private String latitude; + private String name; + private String longitude; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getRoad() { + return road; + } + + public void setRoad(String road) { + this.road = road; + } + + public String getLatitude() { + return latitude; + } + + public void setLatitude(String latitude) { + this.latitude = latitude; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLongitude() { + return longitude; + } + + public void setLongitude(String longitude) { + this.longitude = longitude; + } + } +} 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 8b286d1..04c0e58 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 @@ -91,4 +91,7 @@ @Header("token") token: String, @Query("deviceId") deviceId: String ): String + + @GET("/monitor/list") + suspend fun queryVideoCameraList(@Header("token") token: String): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt b/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt index deac8ac..84754fe 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt @@ -1,23 +1,48 @@ package com.casic.smart.town.sanxi.fragment +import android.graphics.Point import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions +import com.amap.api.maps.CameraUpdateFactory +import com.amap.api.maps.CoordinateConverter +import com.amap.api.maps.model.BitmapDescriptorFactory +import com.amap.api.maps.model.CameraPosition +import com.amap.api.maps.model.LatLng +import com.amap.api.maps.model.MarkerOptions import com.casic.smart.town.sanxi.R +import com.casic.smart.town.sanxi.model.VideoModel import com.casic.smart.town.sanxi.view.MonitorRecordActivity +import com.casic.smart.town.sanxi.vm.VideoViewModel import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_monitor.view.* -class MonitorPageFragment : Fragment() { +class MonitorPageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener { private val kTag = "HomePageFragment" private lateinit var monitorView: View private lateinit var aMap: AMap + private lateinit var videoViewModel: VideoViewModel + + /** + * 所有视频设备列表信息集合 + * */ + private var videoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 视野内的marker + */ + private var markerOptionsInView: MutableList = ArrayList() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -29,6 +54,46 @@ monitorView.rightOperateView.setOnClickListener { requireContext().navigatePageTo() } + + videoViewModel = ViewModelProvider(this)[VideoViewModel::class.java] + videoViewModel.queryVideoCameraList() + videoViewModel.resultModel.observe(requireActivity(), { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + it.data?.forEach { video -> + val lat = video.latitude.toString() + val lng = video.longitude.toString() + if (lat.isNotBlank() && lng.isNotBlank()) { + //返回true代表当前位置在大陆、港澳地区,反之不在 + val latitude = lat.toDouble() + val longitude = lng.toDouble() + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + //缓存所有设备详情,点击Marker时候需要 + videoModels.add(video) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions() + .position(LatLng(latitude, longitude)) + .title(video.name) + .snippet(video.code) + ) + } + + //计算所有点的中心点位置 + val centerLatLng = LatLng(latitudeList.average(), longitudeList.average()) + //移动到指定经纬度 + val cameraPosition = CameraPosition(centerLatLng, 16f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate, 2000, null) + } + } + } + }) return monitorView } @@ -42,9 +107,9 @@ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 // 地图加载成功监听 -// aMap.addOnMapLoadedListener(this) + aMap.addOnMapLoadedListener(this) // 地图缩放监听 -// aMap.addOnCameraChangeListener(this) + aMap.addOnCameraChangeListener(this) // marker 点击事件监听 // aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup @@ -53,6 +118,37 @@ // aMap.addOnInfoWindowClickListener(this) } + override fun onMapLoaded() { + //地图加载成功之后显示聚合点数据 + initClustersMarkers() + } + + override fun onCameraChange(p0: CameraPosition?) { + + } + + override fun onCameraChangeFinish(p0: CameraPosition?) { + initClustersMarkers() + } + + private fun initClustersMarkers() { + val proj = aMap.projection + val dm = resources.displayMetrics + var screenLocation: Point + markerOptionsInView.clear() + // 获取在当前视野内的marker + allMarkerOptions.forEach { + screenLocation = proj.toScreenLocation(it.position) + if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) { + it.icon(BitmapDescriptorFactory.fromBitmap(BitmapDescriptorFactory.fromResource(R.mipmap.map_pin).bitmap)) + markerOptionsInView.add(it) + } + } + markerOptionsInView.forEach { + aMap.addMarker(it) + } + } + /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() diff --git a/app/src/main/java/com/casic/smart/town/sanxi/model/VideoModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/VideoModel.java new file mode 100644 index 0000000..a313487 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/VideoModel.java @@ -0,0 +1,91 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class VideoModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private String code; + private String road; + private String latitude; + private String name; + private String longitude; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getRoad() { + return road; + } + + public void setRoad(String road) { + this.road = road; + } + + public String getLatitude() { + return latitude; + } + + public void setLatitude(String latitude) { + this.latitude = latitude; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLongitude() { + return longitude; + } + + public void setLongitude(String longitude) { + this.longitude = longitude; + } + } +} 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 8b286d1..04c0e58 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 @@ -91,4 +91,7 @@ @Header("token") token: String, @Query("deviceId") deviceId: String ): String + + @GET("/monitor/list") + suspend fun queryVideoCameraList(@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 43c3d7d..21a194e 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 @@ -93,4 +93,8 @@ suspend fun queryWellInfo(deviceId: String): String { return smartTownApi.queryWellInfo(AuthenticationHelper.token!!, deviceId) } + + suspend fun queryVideoCameraList(): String { + return smartTownApi.queryVideoCameraList(AuthenticationHelper.token!!) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt b/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt index deac8ac..84754fe 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt @@ -1,23 +1,48 @@ package com.casic.smart.town.sanxi.fragment +import android.graphics.Point import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions +import com.amap.api.maps.CameraUpdateFactory +import com.amap.api.maps.CoordinateConverter +import com.amap.api.maps.model.BitmapDescriptorFactory +import com.amap.api.maps.model.CameraPosition +import com.amap.api.maps.model.LatLng +import com.amap.api.maps.model.MarkerOptions import com.casic.smart.town.sanxi.R +import com.casic.smart.town.sanxi.model.VideoModel import com.casic.smart.town.sanxi.view.MonitorRecordActivity +import com.casic.smart.town.sanxi.vm.VideoViewModel import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_monitor.view.* -class MonitorPageFragment : Fragment() { +class MonitorPageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener { private val kTag = "HomePageFragment" private lateinit var monitorView: View private lateinit var aMap: AMap + private lateinit var videoViewModel: VideoViewModel + + /** + * 所有视频设备列表信息集合 + * */ + private var videoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 视野内的marker + */ + private var markerOptionsInView: MutableList = ArrayList() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -29,6 +54,46 @@ monitorView.rightOperateView.setOnClickListener { requireContext().navigatePageTo() } + + videoViewModel = ViewModelProvider(this)[VideoViewModel::class.java] + videoViewModel.queryVideoCameraList() + videoViewModel.resultModel.observe(requireActivity(), { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + it.data?.forEach { video -> + val lat = video.latitude.toString() + val lng = video.longitude.toString() + if (lat.isNotBlank() && lng.isNotBlank()) { + //返回true代表当前位置在大陆、港澳地区,反之不在 + val latitude = lat.toDouble() + val longitude = lng.toDouble() + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + //缓存所有设备详情,点击Marker时候需要 + videoModels.add(video) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions() + .position(LatLng(latitude, longitude)) + .title(video.name) + .snippet(video.code) + ) + } + + //计算所有点的中心点位置 + val centerLatLng = LatLng(latitudeList.average(), longitudeList.average()) + //移动到指定经纬度 + val cameraPosition = CameraPosition(centerLatLng, 16f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate, 2000, null) + } + } + } + }) return monitorView } @@ -42,9 +107,9 @@ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 // 地图加载成功监听 -// aMap.addOnMapLoadedListener(this) + aMap.addOnMapLoadedListener(this) // 地图缩放监听 -// aMap.addOnCameraChangeListener(this) + aMap.addOnCameraChangeListener(this) // marker 点击事件监听 // aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup @@ -53,6 +118,37 @@ // aMap.addOnInfoWindowClickListener(this) } + override fun onMapLoaded() { + //地图加载成功之后显示聚合点数据 + initClustersMarkers() + } + + override fun onCameraChange(p0: CameraPosition?) { + + } + + override fun onCameraChangeFinish(p0: CameraPosition?) { + initClustersMarkers() + } + + private fun initClustersMarkers() { + val proj = aMap.projection + val dm = resources.displayMetrics + var screenLocation: Point + markerOptionsInView.clear() + // 获取在当前视野内的marker + allMarkerOptions.forEach { + screenLocation = proj.toScreenLocation(it.position) + if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) { + it.icon(BitmapDescriptorFactory.fromBitmap(BitmapDescriptorFactory.fromResource(R.mipmap.map_pin).bitmap)) + markerOptionsInView.add(it) + } + } + markerOptionsInView.forEach { + aMap.addMarker(it) + } + } + /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() diff --git a/app/src/main/java/com/casic/smart/town/sanxi/model/VideoModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/VideoModel.java new file mode 100644 index 0000000..a313487 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/VideoModel.java @@ -0,0 +1,91 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class VideoModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private String code; + private String road; + private String latitude; + private String name; + private String longitude; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getRoad() { + return road; + } + + public void setRoad(String road) { + this.road = road; + } + + public String getLatitude() { + return latitude; + } + + public void setLatitude(String latitude) { + this.latitude = latitude; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLongitude() { + return longitude; + } + + public void setLongitude(String longitude) { + this.longitude = longitude; + } + } +} 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 8b286d1..04c0e58 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 @@ -91,4 +91,7 @@ @Header("token") token: String, @Query("deviceId") deviceId: String ): String + + @GET("/monitor/list") + suspend fun queryVideoCameraList(@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 43c3d7d..21a194e 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 @@ -93,4 +93,8 @@ suspend fun queryWellInfo(deviceId: String): String { return smartTownApi.queryWellInfo(AuthenticationHelper.token!!, deviceId) } + + suspend fun queryVideoCameraList(): String { + return smartTownApi.queryVideoCameraList(AuthenticationHelper.token!!) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/view/DeviceOnMapActivity.kt b/app/src/main/java/com/casic/smart/town/sanxi/view/DeviceOnMapActivity.kt index c31f25d..54803f8 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/view/DeviceOnMapActivity.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/view/DeviceOnMapActivity.kt @@ -1,17 +1,18 @@ package com.casic.smart.town.sanxi.view +import android.graphics.Point import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.ViewModelProvider import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions import com.amap.api.maps.CameraUpdateFactory -import com.amap.api.maps.CoordinateConverter import com.amap.api.maps.model.BitmapDescriptorFactory import com.amap.api.maps.model.CameraPosition import com.amap.api.maps.model.LatLng import com.amap.api.maps.model.MarkerOptions import com.casic.smart.town.sanxi.R +import com.casic.smart.town.sanxi.model.WellInfoModel import com.casic.smart.town.sanxi.util.LoadingDialogHub import com.casic.smart.town.sanxi.vm.WellViewModel import com.gyf.immersionbar.ImmersionBar @@ -23,12 +24,28 @@ import kotlinx.android.synthetic.main.activity_device_on_map.* import kotlinx.android.synthetic.main.include_base_title.* -class DeviceOnMapActivity : AppCompatActivity() { +class DeviceOnMapActivity : AppCompatActivity(), AMap.OnMapLoadedListener, + AMap.OnCameraChangeListener { private val kTag = "DeviceOnMapActivity" private lateinit var wellViewModel: WellViewModel private lateinit var aMap: AMap + /** + * 所有视频设备列表信息集合 + * */ + private var wellInfoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 视野内的marker + */ + private var markerOptionsInView: MutableList = ArrayList() + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_device_on_map) @@ -52,31 +69,42 @@ wellViewModel.queryWellInfo(deviceId) wellViewModel.wellResultModel.observe(this, { if (it.code == 200) { - val lat = it.data.latGaode.toString() - val lng = it.data.lngGaode.toString() + val wellInfo = it.data + + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + val lat = wellInfo.latGaode.toString() + val lng = wellInfo.lngGaode.toString() if (lat.isNotBlank() && lng.isNotBlank()) { - //返回true代表当前位置在大陆、港澳地区,反之不在 val latitude = lat.toDouble() val longitude = lng.toDouble() - if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { - val latLng = LatLng(latitude, longitude) - //移动到指定经纬度 - val cameraPosition = CameraPosition(latLng, 16f, 0f, 0f) - val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) - aMap.animateCamera(cameraUpdate, 2000, null) - aMap.addMarker( - MarkerOptions() - .position(latLng) - .icon( - BitmapDescriptorFactory.fromBitmap( - BitmapDescriptorFactory.fromResource(R.mipmap.map_pin).bitmap - ) - ) - .title("") - .snippet("") - ) + //有的数据经纬度是反的 + val latLng = if (latitude > longitude) { + LatLng(longitude, latitude) + } else { + LatLng(latitude, longitude) } + + //缓存所有井详情,点击Marker时候需要 + wellInfoModels.add(wellInfo) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions() + .position(latLng) + .title(wellInfo.wellTypeName) + .snippet(wellInfo.wellCode) + ) + + + //移动到指定经纬度 + val cameraPosition = CameraPosition(latLng, 15f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate, 2000, null) } else { "经纬度异常".show(this) } @@ -92,6 +120,41 @@ uiSettings.isCompassEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 + + // 地图加载成功监听 + aMap.addOnMapLoadedListener(this) + // 地图缩放监听 + aMap.addOnCameraChangeListener(this) + } + + override fun onMapLoaded() { + initClustersMarkers() + } + + override fun onCameraChange(p0: CameraPosition?) { + + } + + override fun onCameraChangeFinish(p0: CameraPosition?) { + initClustersMarkers() + } + + private fun initClustersMarkers() { + val proj = aMap.projection + val dm = resources.displayMetrics + var screenLocation: Point + markerOptionsInView.clear() + // 获取在当前视野内的marker + allMarkerOptions.forEach { + screenLocation = proj.toScreenLocation(it.position) + if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) { + it.icon(BitmapDescriptorFactory.fromBitmap(BitmapDescriptorFactory.fromResource(R.mipmap.map_pin).bitmap)) + markerOptionsInView.add(it) + } + } + markerOptionsInView.forEach { + aMap.addMarker(it) + } } /***以下是地图生命周期管理************************************************************************/ diff --git a/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt b/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt index deac8ac..84754fe 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt @@ -1,23 +1,48 @@ package com.casic.smart.town.sanxi.fragment +import android.graphics.Point import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions +import com.amap.api.maps.CameraUpdateFactory +import com.amap.api.maps.CoordinateConverter +import com.amap.api.maps.model.BitmapDescriptorFactory +import com.amap.api.maps.model.CameraPosition +import com.amap.api.maps.model.LatLng +import com.amap.api.maps.model.MarkerOptions import com.casic.smart.town.sanxi.R +import com.casic.smart.town.sanxi.model.VideoModel import com.casic.smart.town.sanxi.view.MonitorRecordActivity +import com.casic.smart.town.sanxi.vm.VideoViewModel import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_monitor.view.* -class MonitorPageFragment : Fragment() { +class MonitorPageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener { private val kTag = "HomePageFragment" private lateinit var monitorView: View private lateinit var aMap: AMap + private lateinit var videoViewModel: VideoViewModel + + /** + * 所有视频设备列表信息集合 + * */ + private var videoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 视野内的marker + */ + private var markerOptionsInView: MutableList = ArrayList() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -29,6 +54,46 @@ monitorView.rightOperateView.setOnClickListener { requireContext().navigatePageTo() } + + videoViewModel = ViewModelProvider(this)[VideoViewModel::class.java] + videoViewModel.queryVideoCameraList() + videoViewModel.resultModel.observe(requireActivity(), { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + it.data?.forEach { video -> + val lat = video.latitude.toString() + val lng = video.longitude.toString() + if (lat.isNotBlank() && lng.isNotBlank()) { + //返回true代表当前位置在大陆、港澳地区,反之不在 + val latitude = lat.toDouble() + val longitude = lng.toDouble() + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + //缓存所有设备详情,点击Marker时候需要 + videoModels.add(video) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions() + .position(LatLng(latitude, longitude)) + .title(video.name) + .snippet(video.code) + ) + } + + //计算所有点的中心点位置 + val centerLatLng = LatLng(latitudeList.average(), longitudeList.average()) + //移动到指定经纬度 + val cameraPosition = CameraPosition(centerLatLng, 16f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate, 2000, null) + } + } + } + }) return monitorView } @@ -42,9 +107,9 @@ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 // 地图加载成功监听 -// aMap.addOnMapLoadedListener(this) + aMap.addOnMapLoadedListener(this) // 地图缩放监听 -// aMap.addOnCameraChangeListener(this) + aMap.addOnCameraChangeListener(this) // marker 点击事件监听 // aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup @@ -53,6 +118,37 @@ // aMap.addOnInfoWindowClickListener(this) } + override fun onMapLoaded() { + //地图加载成功之后显示聚合点数据 + initClustersMarkers() + } + + override fun onCameraChange(p0: CameraPosition?) { + + } + + override fun onCameraChangeFinish(p0: CameraPosition?) { + initClustersMarkers() + } + + private fun initClustersMarkers() { + val proj = aMap.projection + val dm = resources.displayMetrics + var screenLocation: Point + markerOptionsInView.clear() + // 获取在当前视野内的marker + allMarkerOptions.forEach { + screenLocation = proj.toScreenLocation(it.position) + if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) { + it.icon(BitmapDescriptorFactory.fromBitmap(BitmapDescriptorFactory.fromResource(R.mipmap.map_pin).bitmap)) + markerOptionsInView.add(it) + } + } + markerOptionsInView.forEach { + aMap.addMarker(it) + } + } + /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() diff --git a/app/src/main/java/com/casic/smart/town/sanxi/model/VideoModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/VideoModel.java new file mode 100644 index 0000000..a313487 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/VideoModel.java @@ -0,0 +1,91 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class VideoModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private String code; + private String road; + private String latitude; + private String name; + private String longitude; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getRoad() { + return road; + } + + public void setRoad(String road) { + this.road = road; + } + + public String getLatitude() { + return latitude; + } + + public void setLatitude(String latitude) { + this.latitude = latitude; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLongitude() { + return longitude; + } + + public void setLongitude(String longitude) { + this.longitude = longitude; + } + } +} 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 8b286d1..04c0e58 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 @@ -91,4 +91,7 @@ @Header("token") token: String, @Query("deviceId") deviceId: String ): String + + @GET("/monitor/list") + suspend fun queryVideoCameraList(@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 43c3d7d..21a194e 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 @@ -93,4 +93,8 @@ suspend fun queryWellInfo(deviceId: String): String { return smartTownApi.queryWellInfo(AuthenticationHelper.token!!, deviceId) } + + suspend fun queryVideoCameraList(): String { + return smartTownApi.queryVideoCameraList(AuthenticationHelper.token!!) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/view/DeviceOnMapActivity.kt b/app/src/main/java/com/casic/smart/town/sanxi/view/DeviceOnMapActivity.kt index c31f25d..54803f8 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/view/DeviceOnMapActivity.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/view/DeviceOnMapActivity.kt @@ -1,17 +1,18 @@ package com.casic.smart.town.sanxi.view +import android.graphics.Point import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.ViewModelProvider import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions import com.amap.api.maps.CameraUpdateFactory -import com.amap.api.maps.CoordinateConverter import com.amap.api.maps.model.BitmapDescriptorFactory import com.amap.api.maps.model.CameraPosition import com.amap.api.maps.model.LatLng import com.amap.api.maps.model.MarkerOptions import com.casic.smart.town.sanxi.R +import com.casic.smart.town.sanxi.model.WellInfoModel import com.casic.smart.town.sanxi.util.LoadingDialogHub import com.casic.smart.town.sanxi.vm.WellViewModel import com.gyf.immersionbar.ImmersionBar @@ -23,12 +24,28 @@ import kotlinx.android.synthetic.main.activity_device_on_map.* import kotlinx.android.synthetic.main.include_base_title.* -class DeviceOnMapActivity : AppCompatActivity() { +class DeviceOnMapActivity : AppCompatActivity(), AMap.OnMapLoadedListener, + AMap.OnCameraChangeListener { private val kTag = "DeviceOnMapActivity" private lateinit var wellViewModel: WellViewModel private lateinit var aMap: AMap + /** + * 所有视频设备列表信息集合 + * */ + private var wellInfoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 视野内的marker + */ + private var markerOptionsInView: MutableList = ArrayList() + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_device_on_map) @@ -52,31 +69,42 @@ wellViewModel.queryWellInfo(deviceId) wellViewModel.wellResultModel.observe(this, { if (it.code == 200) { - val lat = it.data.latGaode.toString() - val lng = it.data.lngGaode.toString() + val wellInfo = it.data + + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + val lat = wellInfo.latGaode.toString() + val lng = wellInfo.lngGaode.toString() if (lat.isNotBlank() && lng.isNotBlank()) { - //返回true代表当前位置在大陆、港澳地区,反之不在 val latitude = lat.toDouble() val longitude = lng.toDouble() - if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { - val latLng = LatLng(latitude, longitude) - //移动到指定经纬度 - val cameraPosition = CameraPosition(latLng, 16f, 0f, 0f) - val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) - aMap.animateCamera(cameraUpdate, 2000, null) - aMap.addMarker( - MarkerOptions() - .position(latLng) - .icon( - BitmapDescriptorFactory.fromBitmap( - BitmapDescriptorFactory.fromResource(R.mipmap.map_pin).bitmap - ) - ) - .title("") - .snippet("") - ) + //有的数据经纬度是反的 + val latLng = if (latitude > longitude) { + LatLng(longitude, latitude) + } else { + LatLng(latitude, longitude) } + + //缓存所有井详情,点击Marker时候需要 + wellInfoModels.add(wellInfo) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions() + .position(latLng) + .title(wellInfo.wellTypeName) + .snippet(wellInfo.wellCode) + ) + + + //移动到指定经纬度 + val cameraPosition = CameraPosition(latLng, 15f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate, 2000, null) } else { "经纬度异常".show(this) } @@ -92,6 +120,41 @@ uiSettings.isCompassEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 + + // 地图加载成功监听 + aMap.addOnMapLoadedListener(this) + // 地图缩放监听 + aMap.addOnCameraChangeListener(this) + } + + override fun onMapLoaded() { + initClustersMarkers() + } + + override fun onCameraChange(p0: CameraPosition?) { + + } + + override fun onCameraChangeFinish(p0: CameraPosition?) { + initClustersMarkers() + } + + private fun initClustersMarkers() { + val proj = aMap.projection + val dm = resources.displayMetrics + var screenLocation: Point + markerOptionsInView.clear() + // 获取在当前视野内的marker + allMarkerOptions.forEach { + screenLocation = proj.toScreenLocation(it.position) + if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) { + it.icon(BitmapDescriptorFactory.fromBitmap(BitmapDescriptorFactory.fromResource(R.mipmap.map_pin).bitmap)) + markerOptionsInView.add(it) + } + } + markerOptionsInView.forEach { + aMap.addMarker(it) + } } /***以下是地图生命周期管理************************************************************************/ diff --git a/app/src/main/java/com/casic/smart/town/sanxi/vm/VideoViewModel.kt b/app/src/main/java/com/casic/smart/town/sanxi/vm/VideoViewModel.kt new file mode 100644 index 0000000..63b29ff --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/vm/VideoViewModel.kt @@ -0,0 +1,32 @@ +package com.casic.smart.town.sanxi.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.smart.town.sanxi.base.BaseApplication +import com.casic.smart.town.sanxi.extensions.separateResponseCode +import com.casic.smart.town.sanxi.extensions.toErrorMessage +import com.casic.smart.town.sanxi.model.VideoModel +import com.casic.smart.town.sanxi.util.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel + +class VideoViewModel : BaseViewModel() { + private val gson by lazy { Gson() } + val resultModel = MutableLiveData() + + fun queryVideoCameraList() = launch({ + val response = RetrofitServiceManager.queryVideoCameraList() + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + resultModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt b/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt index deac8ac..84754fe 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/fragment/MonitorPageFragment.kt @@ -1,23 +1,48 @@ package com.casic.smart.town.sanxi.fragment +import android.graphics.Point import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions +import com.amap.api.maps.CameraUpdateFactory +import com.amap.api.maps.CoordinateConverter +import com.amap.api.maps.model.BitmapDescriptorFactory +import com.amap.api.maps.model.CameraPosition +import com.amap.api.maps.model.LatLng +import com.amap.api.maps.model.MarkerOptions import com.casic.smart.town.sanxi.R +import com.casic.smart.town.sanxi.model.VideoModel import com.casic.smart.town.sanxi.view.MonitorRecordActivity +import com.casic.smart.town.sanxi.vm.VideoViewModel import com.pengxh.kt.lite.extensions.navigatePageTo -import com.pengxh.kt.lite.extensions.show import kotlinx.android.synthetic.main.fragment_monitor.view.* -class MonitorPageFragment : Fragment() { +class MonitorPageFragment : Fragment(), AMap.OnMapLoadedListener, AMap.OnCameraChangeListener { private val kTag = "HomePageFragment" private lateinit var monitorView: View private lateinit var aMap: AMap + private lateinit var videoViewModel: VideoViewModel + + /** + * 所有视频设备列表信息集合 + * */ + private var videoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 视野内的marker + */ + private var markerOptionsInView: MutableList = ArrayList() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -29,6 +54,46 @@ monitorView.rightOperateView.setOnClickListener { requireContext().navigatePageTo() } + + videoViewModel = ViewModelProvider(this)[VideoViewModel::class.java] + videoViewModel.queryVideoCameraList() + videoViewModel.resultModel.observe(requireActivity(), { + if (it.code == 200) { + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + it.data?.forEach { video -> + val lat = video.latitude.toString() + val lng = video.longitude.toString() + if (lat.isNotBlank() && lng.isNotBlank()) { + //返回true代表当前位置在大陆、港澳地区,反之不在 + val latitude = lat.toDouble() + val longitude = lng.toDouble() + if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { + //缓存所有设备详情,点击Marker时候需要 + videoModels.add(video) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions() + .position(LatLng(latitude, longitude)) + .title(video.name) + .snippet(video.code) + ) + } + + //计算所有点的中心点位置 + val centerLatLng = LatLng(latitudeList.average(), longitudeList.average()) + //移动到指定经纬度 + val cameraPosition = CameraPosition(centerLatLng, 16f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate, 2000, null) + } + } + } + }) return monitorView } @@ -42,9 +107,9 @@ uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 // 地图加载成功监听 -// aMap.addOnMapLoadedListener(this) + aMap.addOnMapLoadedListener(this) // 地图缩放监听 -// aMap.addOnCameraChangeListener(this) + aMap.addOnCameraChangeListener(this) // marker 点击事件监听 // aMap.addOnMarkerClickListener(this) // 点击marker弹出自定义popup @@ -53,6 +118,37 @@ // aMap.addOnInfoWindowClickListener(this) } + override fun onMapLoaded() { + //地图加载成功之后显示聚合点数据 + initClustersMarkers() + } + + override fun onCameraChange(p0: CameraPosition?) { + + } + + override fun onCameraChangeFinish(p0: CameraPosition?) { + initClustersMarkers() + } + + private fun initClustersMarkers() { + val proj = aMap.projection + val dm = resources.displayMetrics + var screenLocation: Point + markerOptionsInView.clear() + // 获取在当前视野内的marker + allMarkerOptions.forEach { + screenLocation = proj.toScreenLocation(it.position) + if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) { + it.icon(BitmapDescriptorFactory.fromBitmap(BitmapDescriptorFactory.fromResource(R.mipmap.map_pin).bitmap)) + markerOptionsInView.add(it) + } + } + markerOptionsInView.forEach { + aMap.addMarker(it) + } + } + /***以下是地图生命周期管理************************************************************************/ override fun onResume() { super.onResume() diff --git a/app/src/main/java/com/casic/smart/town/sanxi/model/VideoModel.java b/app/src/main/java/com/casic/smart/town/sanxi/model/VideoModel.java new file mode 100644 index 0000000..a313487 --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/model/VideoModel.java @@ -0,0 +1,91 @@ +package com.casic.smart.town.sanxi.model; + +import java.util.List; + +public class VideoModel { + + private int code; + private List data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataModel { + private String code; + private String road; + private String latitude; + private String name; + private String longitude; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getRoad() { + return road; + } + + public void setRoad(String road) { + this.road = road; + } + + public String getLatitude() { + return latitude; + } + + public void setLatitude(String latitude) { + this.latitude = latitude; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLongitude() { + return longitude; + } + + public void setLongitude(String longitude) { + this.longitude = longitude; + } + } +} 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 8b286d1..04c0e58 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 @@ -91,4 +91,7 @@ @Header("token") token: String, @Query("deviceId") deviceId: String ): String + + @GET("/monitor/list") + suspend fun queryVideoCameraList(@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 43c3d7d..21a194e 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 @@ -93,4 +93,8 @@ suspend fun queryWellInfo(deviceId: String): String { return smartTownApi.queryWellInfo(AuthenticationHelper.token!!, deviceId) } + + suspend fun queryVideoCameraList(): String { + return smartTownApi.queryVideoCameraList(AuthenticationHelper.token!!) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smart/town/sanxi/view/DeviceOnMapActivity.kt b/app/src/main/java/com/casic/smart/town/sanxi/view/DeviceOnMapActivity.kt index c31f25d..54803f8 100644 --- a/app/src/main/java/com/casic/smart/town/sanxi/view/DeviceOnMapActivity.kt +++ b/app/src/main/java/com/casic/smart/town/sanxi/view/DeviceOnMapActivity.kt @@ -1,17 +1,18 @@ package com.casic.smart.town.sanxi.view +import android.graphics.Point import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.ViewModelProvider import com.amap.api.maps.AMap import com.amap.api.maps.AMapOptions import com.amap.api.maps.CameraUpdateFactory -import com.amap.api.maps.CoordinateConverter import com.amap.api.maps.model.BitmapDescriptorFactory import com.amap.api.maps.model.CameraPosition import com.amap.api.maps.model.LatLng import com.amap.api.maps.model.MarkerOptions import com.casic.smart.town.sanxi.R +import com.casic.smart.town.sanxi.model.WellInfoModel import com.casic.smart.town.sanxi.util.LoadingDialogHub import com.casic.smart.town.sanxi.vm.WellViewModel import com.gyf.immersionbar.ImmersionBar @@ -23,12 +24,28 @@ import kotlinx.android.synthetic.main.activity_device_on_map.* import kotlinx.android.synthetic.main.include_base_title.* -class DeviceOnMapActivity : AppCompatActivity() { +class DeviceOnMapActivity : AppCompatActivity(), AMap.OnMapLoadedListener, + AMap.OnCameraChangeListener { private val kTag = "DeviceOnMapActivity" private lateinit var wellViewModel: WellViewModel private lateinit var aMap: AMap + /** + * 所有视频设备列表信息集合 + * */ + private var wellInfoModels: MutableList = ArrayList() + + /** + * 所有的marker + */ + private var allMarkerOptions: MutableList = ArrayList() + + /** + * 视野内的marker + */ + private var markerOptionsInView: MutableList = ArrayList() + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_device_on_map) @@ -52,31 +69,42 @@ wellViewModel.queryWellInfo(deviceId) wellViewModel.wellResultModel.observe(this, { if (it.code == 200) { - val lat = it.data.latGaode.toString() - val lng = it.data.lngGaode.toString() + val wellInfo = it.data + + val latitudeList: MutableList = ArrayList() + val longitudeList: MutableList = ArrayList() + + val lat = wellInfo.latGaode.toString() + val lng = wellInfo.lngGaode.toString() if (lat.isNotBlank() && lng.isNotBlank()) { - //返回true代表当前位置在大陆、港澳地区,反之不在 val latitude = lat.toDouble() val longitude = lng.toDouble() - if (CoordinateConverter.isAMapDataAvailable(latitude, longitude)) { - val latLng = LatLng(latitude, longitude) - //移动到指定经纬度 - val cameraPosition = CameraPosition(latLng, 16f, 0f, 0f) - val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) - aMap.animateCamera(cameraUpdate, 2000, null) - aMap.addMarker( - MarkerOptions() - .position(latLng) - .icon( - BitmapDescriptorFactory.fromBitmap( - BitmapDescriptorFactory.fromResource(R.mipmap.map_pin).bitmap - ) - ) - .title("") - .snippet("") - ) + //有的数据经纬度是反的 + val latLng = if (latitude > longitude) { + LatLng(longitude, latitude) + } else { + LatLng(latitude, longitude) } + + //缓存所有井详情,点击Marker时候需要 + wellInfoModels.add(wellInfo) + //分别缓存经、纬度 + latitudeList.add(latitude) + longitudeList.add(longitude) + //将所有设备信息转化缓存为Marker点 + allMarkerOptions.add( + MarkerOptions() + .position(latLng) + .title(wellInfo.wellTypeName) + .snippet(wellInfo.wellCode) + ) + + + //移动到指定经纬度 + val cameraPosition = CameraPosition(latLng, 15f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate, 2000, null) } else { "经纬度异常".show(this) } @@ -92,6 +120,41 @@ uiSettings.isCompassEnabled = true uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 + + // 地图加载成功监听 + aMap.addOnMapLoadedListener(this) + // 地图缩放监听 + aMap.addOnCameraChangeListener(this) + } + + override fun onMapLoaded() { + initClustersMarkers() + } + + override fun onCameraChange(p0: CameraPosition?) { + + } + + override fun onCameraChangeFinish(p0: CameraPosition?) { + initClustersMarkers() + } + + private fun initClustersMarkers() { + val proj = aMap.projection + val dm = resources.displayMetrics + var screenLocation: Point + markerOptionsInView.clear() + // 获取在当前视野内的marker + allMarkerOptions.forEach { + screenLocation = proj.toScreenLocation(it.position) + if (screenLocation.x >= 0 && screenLocation.y >= 0 && screenLocation.x <= dm.widthPixels && screenLocation.y <= dm.heightPixels) { + it.icon(BitmapDescriptorFactory.fromBitmap(BitmapDescriptorFactory.fromResource(R.mipmap.map_pin).bitmap)) + markerOptionsInView.add(it) + } + } + markerOptionsInView.forEach { + aMap.addMarker(it) + } } /***以下是地图生命周期管理************************************************************************/ diff --git a/app/src/main/java/com/casic/smart/town/sanxi/vm/VideoViewModel.kt b/app/src/main/java/com/casic/smart/town/sanxi/vm/VideoViewModel.kt new file mode 100644 index 0000000..63b29ff --- /dev/null +++ b/app/src/main/java/com/casic/smart/town/sanxi/vm/VideoViewModel.kt @@ -0,0 +1,32 @@ +package com.casic.smart.town.sanxi.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.smart.town.sanxi.base.BaseApplication +import com.casic.smart.town.sanxi.extensions.separateResponseCode +import com.casic.smart.town.sanxi.extensions.toErrorMessage +import com.casic.smart.town.sanxi.model.VideoModel +import com.casic.smart.town.sanxi.util.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel + +class VideoViewModel : BaseViewModel() { + private val gson by lazy { Gson() } + val resultModel = MutableLiveData() + + fun queryVideoCameraList() = launch({ + val response = RetrofitServiceManager.queryVideoCameraList() + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + resultModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/res/mipmap-xxxhdpi/map_pin.png b/app/src/main/res/mipmap-xxxhdpi/map_pin.png index 674c628..62ff399 100644 --- a/app/src/main/res/mipmap-xxxhdpi/map_pin.png +++ b/app/src/main/res/mipmap-xxxhdpi/map_pin.png Binary files differ