1.map页和直播适配百度地图

2.历史轨迹适配百度地图
This commit is contained in:
2026-08-14 11:19:38 +08:00
parent 0692d1e08b
commit 567088bb87
16 changed files with 656 additions and 228 deletions

View File

@@ -4,7 +4,7 @@
<selectionStates> <selectionStates>
<SelectionState runConfigName="app"> <SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" /> <option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2026-07-29T04:01:42.827217400Z"> <DropdownSelection timestamp="2026-08-11T09:47:57.797377200Z">
<Target type="DEFAULT_BOOT"> <Target type="DEFAULT_BOOT">
<handle> <handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=3A251FDJH000CE" /> <DeviceId pluginId="PhysicalDevice" identifier="serial=3A251FDJH000CE" />

View File

@@ -40,6 +40,7 @@ open class BaseMapCommon {
baiduMapFragment: BaseBaiduMapFragment?, googleMapFragment: BaseGoogleMapFragment? baiduMapFragment: BaseBaiduMapFragment?, googleMapFragment: BaseGoogleMapFragment?
) { ) {
googleMapFragment?.getLastLocation() googleMapFragment?.getLastLocation()
//百度地图定位成功后,每隔60秒刷新用户位置,无需重复调用
} }
/** /**

View File

@@ -59,14 +59,14 @@ interface INetworkService {
// const val BASE_URL = "http://ec2-3-101-8-36.us-west-1.compute.amazonaws.com:8090/abbidot/" // const val BASE_URL = "http://ec2-3-101-8-36.us-west-1.compute.amazonaws.com:8090/abbidot/"
// const val BASE_URL = "http://www.xiaopandev.com:8090/abbidot/" // const val BASE_URL = "http://www.xiaopandev.com:8090/abbidot/"
//亚马逊服务器(国外ip) //亚马逊正式服务器
const val BASE_URL_ABROAD = "https://aws.abbidot.com/abbidot/" const val BASE_URL_ABROAD = "https://aws.abbidot.com/abbidot/"
//设备透传
const val BASE_URL_BLE = "https://ab-server.abbidot.com/"
//测试服务器 //测试服务器
const val BASE_URL_TEST = "https://aws.abbidot.com:8443/abbidot/" const val BASE_URL_TEST = "https://aws.abbidot.com:8443/abbidot/"
//设备透传
const val BASE_URL_BLE = "https://ab-server.abbidot.com/"
// const val BASE_URL_TEST = "http://aws.abbidot.com:8089/abbidot/" // const val BASE_URL_TEST = "http://aws.abbidot.com:8089/abbidot/"
// const val BASE_URL_ABROAD = "http://192.168.0.220:8080/abbidot/" // const val BASE_URL_ABROAD = "http://192.168.0.220:8080/abbidot/"

View File

@@ -31,6 +31,7 @@ import com.abbidot.tracker.util.ThirdPartyUtil
import com.abbidot.tracker.util.Util import com.abbidot.tracker.util.Util
import com.abbidot.tracker.util.bluetooth.SRBleUtil import com.abbidot.tracker.util.bluetooth.SRBleUtil
import com.abbidot.tracker.vm.CountDownTimerViewModel import com.abbidot.tracker.vm.CountDownTimerViewModel
import com.baidu.location.LocationClient
import com.baidu.mapapi.CoordType import com.baidu.mapapi.CoordType
import com.baidu.mapapi.SDKInitializer import com.baidu.mapapi.SDKInitializer
import com.hjq.toast.Toaster import com.hjq.toast.Toaster
@@ -201,7 +202,7 @@ class SplashActivity : QMUIActivity() {
//同意协议 //同意协议
SDKInitializer.setAgreePrivacy(application, true) SDKInitializer.setAgreePrivacy(application, true)
// LocationClient.setAgreePrivacy(true); LocationClient.setAgreePrivacy(true)
//在使用SDK各组件之前初始化context信息,传入ApplicationContext //在使用SDK各组件之前初始化context信息,传入ApplicationContext
SDKInitializer.initialize(application) SDKInitializer.initialize(application)
//自4.3.0起,百度地图SDK所有接口均支持百度坐标和国测局坐标,用此方法设置您使用的坐标类型. //自4.3.0起,百度地图SDK所有接口均支持百度坐标和国测局坐标,用此方法设置您使用的坐标类型.

View File

@@ -1029,7 +1029,7 @@ class LiveActivityV3 : BaseActivity<ActivityLiveV3Binding>(ActivityLiveV3Binding
) )
liveDataBean.livePoints?.apply { liveDataBean.livePoints?.apply {
if (size > 0) { if (isNotEmpty()) {
mMapLiveViewModel.mGetPetLivePointTimeStamp = mMapLiveViewModel.mGetPetLivePointTimeStamp =
System.currentTimeMillis() / 1000 System.currentTimeMillis() / 1000
//只有一个点的时候,不用休眠 //只有一个点的时候,不用休眠
@@ -1078,7 +1078,7 @@ class LiveActivityV3 : BaseActivity<ActivityLiveV3Binding>(ActivityLiveV3Binding
} }
/** /**
* 直播画线 * 蓝牙直播画线
*/ */
private fun liveDrawLines(trackList: MutableList<HistoryDataBean>) { private fun liveDrawLines(trackList: MutableList<HistoryDataBean>) {
mHomeMapCommon.addTrackLines(trackList) mHomeMapCommon.addTrackLines(trackList)

View File

@@ -31,8 +31,9 @@ class HistoryDataMapCommon : BaseMapCommon() {
mapLoadOk: () -> Unit mapLoadOk: () -> Unit
): Fragment { ): Fragment {
return if (AppUtils.isChina(AppUtils.SWITCH_MAP_TYPE)) { return if (AppUtils.isChina(AppUtils.SWITCH_MAP_TYPE)) {
mHistoryDataBaiduMapFragment = mHistoryDataBaiduMapFragment = HistoryDataBaiduMapFragment.newInstance(
HistoryDataBaiduMapFragment.newInstance(context, geoCoderViewModel, mapLoadOk) context, markerInfoView, geoCoderViewModel, verticalTopToBottomSeekBar, mapLoadOk
)
mHistoryDataBaiduMapFragment!! mHistoryDataBaiduMapFragment!!
} else { } else {
mHistoryDataGoogleMapFragment = HistoryDataGoogleMapFragment.newInstance( mHistoryDataGoogleMapFragment = HistoryDataGoogleMapFragment.newInstance(
@@ -54,6 +55,7 @@ class HistoryDataMapCommon : BaseMapCommon() {
mHistoryDataGoogleMapFragment!!.setPetBean(petBean) mHistoryDataGoogleMapFragment!!.setPetBean(petBean)
} }
if (null != mHistoryDataBaiduMapFragment) { if (null != mHistoryDataBaiduMapFragment) {
mHistoryDataBaiduMapFragment!!.setPetBean(petBean)
} }
} }
@@ -103,7 +105,7 @@ class HistoryDataMapCommon : BaseMapCommon() {
} }
fun setLatLngData(data: MutableList<HistoryDataBean>) { fun setLatLngData(data: MutableList<HistoryDataBean>) {
if (data.size == 0) return if (data.isEmpty()) return
try { try {
if (null != mHistoryDataBaiduMapFragment) { if (null != mHistoryDataBaiduMapFragment) {
mHistoryDataBaiduMapFragment!!.setLatLngData(data) mHistoryDataBaiduMapFragment!!.setLatLngData(data)
@@ -129,6 +131,7 @@ class HistoryDataMapCommon : BaseMapCommon() {
fun setPetUserLatLng() { fun setPetUserLatLng() {
if (null != mHistoryDataBaiduMapFragment) { if (null != mHistoryDataBaiduMapFragment) {
// mHistoryDataBaiduMapFragment!!.setPetUserLatLng()
} else if (null != mHistoryDataGoogleMapFragment) { } else if (null != mHistoryDataGoogleMapFragment) {
mHistoryDataGoogleMapFragment?.apply { mHistoryDataGoogleMapFragment?.apply {
mUserLatLng?.let { mUserLatLng?.let {

View File

@@ -37,7 +37,12 @@ class HomeMapCommonV3 @Inject constructor() : BaseMapCommon() {
mapLoadOk: () -> Unit mapLoadOk: () -> Unit
): Fragment { ): Fragment {
return if (AppUtils.isChina(AppUtils.SWITCH_MAP_TYPE)) { return if (AppUtils.isChina(AppUtils.SWITCH_MAP_TYPE)) {
mHomeMapBaiduMapFragment = HomeMapBaiduMapFragment.newInstance(context, mapLoadOk) mHomeMapBaiduMapFragment = HomeMapBaiduMapFragment.newInstance(
context, locationLayoutViewBinding,
deviceBatteryLayout,
petAddressTimeFormat,
isGeocode, mapLoadOk
)
mHomeMapBaiduMapFragment!! mHomeMapBaiduMapFragment!!
} else { } else {
mHomeMapGoogleMapFragment = HomeMapGoogleMapFragmentV3.newInstance( mHomeMapGoogleMapFragment = HomeMapGoogleMapFragmentV3.newInstance(
@@ -90,6 +95,8 @@ class HomeMapCommonV3 @Inject constructor() : BaseMapCommon() {
} }
fun refreshPetCurrentLocation(latitude: Double, longitude: Double, isMoveCamera: Boolean) { fun refreshPetCurrentLocation(latitude: Double, longitude: Double, isMoveCamera: Boolean) {
MMKVUtil.putDouble(MMKVKey.MapShowDefaultLat, latitude)
MMKVUtil.putDouble(MMKVKey.MapShowDefaultLon, longitude)
if (null != mHomeMapBaiduMapFragment) { if (null != mHomeMapBaiduMapFragment) {
mHomeMapBaiduMapFragment?.apply { mHomeMapBaiduMapFragment?.apply {
refreshPetCurrentLocation( refreshPetCurrentLocation(
@@ -97,8 +104,6 @@ class HomeMapCommonV3 @Inject constructor() : BaseMapCommon() {
) )
} }
} else if (null != mHomeMapGoogleMapFragment) { } else if (null != mHomeMapGoogleMapFragment) {
MMKVUtil.putDouble(MMKVKey.MapShowDefaultLat, latitude)
MMKVUtil.putDouble(MMKVKey.MapShowDefaultLon, longitude)
mHomeMapGoogleMapFragment?.apply { mHomeMapGoogleMapFragment?.apply {
refreshPetCurrentLocation( refreshPetCurrentLocation(
LatLng(latitude, longitude), needMoveCamera = isMoveCamera LatLng(latitude, longitude), needMoveCamera = isMoveCamera
@@ -153,6 +158,9 @@ class HomeMapCommonV3 @Inject constructor() : BaseMapCommon() {
*/ */
fun addTrackLines(trackList: MutableList<HistoryDataBean>) { fun addTrackLines(trackList: MutableList<HistoryDataBean>) {
if (null != mHomeMapBaiduMapFragment) { if (null != mHomeMapBaiduMapFragment) {
trackList[trackList.size - 1].let {
mHomeMapBaiduMapFragment!!.addLine(it.latitude, it.longitude)
}
} else if (null != mHomeMapGoogleMapFragment) { } else if (null != mHomeMapGoogleMapFragment) {
mHomeMapGoogleMapFragment!!.addLines(trackList) mHomeMapGoogleMapFragment!!.addLines(trackList)
} }
@@ -176,6 +184,7 @@ class HomeMapCommonV3 @Inject constructor() : BaseMapCommon() {
*/ */
fun startRippleCircleAnim() { fun startRippleCircleAnim() {
if (null != mHomeMapBaiduMapFragment) { if (null != mHomeMapBaiduMapFragment) {
mHomeMapBaiduMapFragment!!.startRippleCircleAnim()
} else if (null != mHomeMapGoogleMapFragment) { } else if (null != mHomeMapGoogleMapFragment) {
mHomeMapGoogleMapFragment!!.startRippleCircleAnim() mHomeMapGoogleMapFragment!!.startRippleCircleAnim()
} }
@@ -183,14 +192,17 @@ class HomeMapCommonV3 @Inject constructor() : BaseMapCommon() {
fun greenRippleCircleAnim() { fun greenRippleCircleAnim() {
mHomeMapGoogleMapFragment?.greenRippleCircleAnim() mHomeMapGoogleMapFragment?.greenRippleCircleAnim()
mHomeMapBaiduMapFragment?.greenRippleCircleAnim()
} }
fun clearRippleCircleAnim() { fun clearRippleCircleAnim() {
mHomeMapGoogleMapFragment?.clearRippleCircleAnim() mHomeMapGoogleMapFragment?.clearRippleCircleAnim()
mHomeMapBaiduMapFragment?.clearRippleCircleAnim()
} }
fun setMarkerInfoViewOffset() { fun setMarkerInfoViewOffset() {
if (null != mHomeMapBaiduMapFragment) { if (null != mHomeMapBaiduMapFragment) {
mHomeMapBaiduMapFragment!!.setMarkerInfoViewOffset()
} else if (null != mHomeMapGoogleMapFragment) { } else if (null != mHomeMapGoogleMapFragment) {
mHomeMapGoogleMapFragment!!.setMarkerInfoViewOffset() mHomeMapGoogleMapFragment!!.setMarkerInfoViewOffset()
} }
@@ -198,22 +210,26 @@ class HomeMapCommonV3 @Inject constructor() : BaseMapCommon() {
fun addUserAndPetLine() { fun addUserAndPetLine() {
mHomeMapGoogleMapFragment?.addUserAndPetLine() mHomeMapGoogleMapFragment?.addUserAndPetLine()
mHomeMapBaiduMapFragment?.addUserAndPetLine()
} }
fun removeUserAndPetLine() { fun removeUserAndPetLine() {
mHomeMapGoogleMapFragment?.removeUserAndPetLine() mHomeMapGoogleMapFragment?.removeUserAndPetLine()
mHomeMapBaiduMapFragment?.removeUserAndPetLine()
} }
suspend fun showOtherPetHeadMarker( suspend fun showOtherPetHeadMarker(
petList: MutableList<PetBean>, headBgResId: Int = R.drawable.pic_map_gps_avatar petList: MutableList<PetBean>, headBgResId: Int = R.drawable.pic_map_gps_avatar
) { ) {
if (petList.size > 0) { if (petList.isNotEmpty()) {
mHomeMapGoogleMapFragment?.showOtherPetHeadMarker(petList, headBgResId) mHomeMapGoogleMapFragment?.showOtherPetHeadMarker(petList, headBgResId)
mHomeMapBaiduMapFragment?.showOtherPetHeadMarker(petList, headBgResId)
} }
} }
fun clearOtherPetHeadMarker() { fun clearOtherPetHeadMarker() {
mHomeMapGoogleMapFragment?.clearOtherPetHeadMarker() mHomeMapGoogleMapFragment?.clearOtherPetHeadMarker()
mHomeMapBaiduMapFragment?.clearOtherPetHeadMarker()
} }
// fun getAddressShowMarkerInfoWindow(historyDataBean: HistoryDataBean) { // fun getAddressShowMarkerInfoWindow(historyDataBean: HistoryDataBean) {

View File

@@ -13,19 +13,24 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.abbidot.baselibrary.constant.MMKVKey
import com.abbidot.baselibrary.util.AppUtils import com.abbidot.baselibrary.util.AppUtils
import com.abbidot.baselibrary.util.LogUtil import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.baselibrary.util.MMKVUtil
import com.abbidot.tracker.MyApplication import com.abbidot.tracker.MyApplication
import com.abbidot.tracker.R import com.abbidot.tracker.R
import com.abbidot.tracker.base.BaseFragment import com.abbidot.tracker.base.BaseFragment
import com.abbidot.tracker.bean.FencesBean import com.abbidot.tracker.bean.FencesBean
import com.abbidot.tracker.bean.HistoryDataBean import com.abbidot.tracker.bean.HistoryDataBean
import com.abbidot.tracker.bean.MapDeviceBean
import com.abbidot.tracker.constant.ConstantInt import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.databinding.FragmentBaseBaiduMapBinding import com.abbidot.tracker.databinding.FragmentBaseBaiduMapBinding
import com.abbidot.tracker.ui.fragment.map.googlemap.GoogleBitmapHelper import com.abbidot.tracker.ui.fragment.map.googlemap.GoogleBitmapHelper
import com.abbidot.tracker.util.ImageUtil import com.abbidot.tracker.util.ImageUtil
import com.abbidot.tracker.util.LonAndLatUtil import com.abbidot.tracker.util.LonAndLatUtil
import com.abbidot.tracker.util.Util.Companion.safeRecycle import com.abbidot.tracker.util.Util.Companion.safeRecycle
import com.abbidot.tracker.util.ViewUtil
import com.abbidot.tracker.widget.MapMarkerInfoView
import com.abbidot.tracker.widget.TypefaceTextView import com.abbidot.tracker.widget.TypefaceTextView
import com.baidu.location.BDAbstractLocationListener import com.baidu.location.BDAbstractLocationListener
import com.baidu.location.BDLocation import com.baidu.location.BDLocation
@@ -50,7 +55,6 @@ import com.baidu.mapapi.map.Stroke
import com.baidu.mapapi.map.TextureMapView import com.baidu.mapapi.map.TextureMapView
import com.baidu.mapapi.model.LatLng import com.baidu.mapapi.model.LatLng
import com.baidu.mapapi.utils.DistanceUtil import com.baidu.mapapi.utils.DistanceUtil
import com.qmuiteam.qmui.util.QMUIDisplayHelper
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlin.math.abs import kotlin.math.abs
@@ -223,21 +227,6 @@ abstract class BaseBaiduMapFragment :
mPetHeadIconBitmap = null mPetHeadIconBitmap = null
} }
/**
* @param needConvertGCJ02 是否需要转换GCJ02坐标
*/
fun getBaiduMapLatLng(
lat: Double, lon: Double, needConvertGCJ02: Boolean = true
): LatLng {
val latLng = if (needConvertGCJ02) {
val convertLonLat = LonAndLatUtil.convertFromWGS84ToGCJ02(lat, lon)
LatLng(convertLonLat[0], convertLonLat[1])
} else {
LatLng(lat, lon)
}
return latLng
}
/** /**
* 设置宠物头像地图Marker * 设置宠物头像地图Marker
*/ */
@@ -247,20 +236,6 @@ abstract class BaseBaiduMapFragment :
needConvertGCJ02: Boolean = true, needConvertGCJ02: Boolean = true,
headBgResId: Int = R.drawable.pic_map_gps_avatar headBgResId: Int = R.drawable.pic_map_gps_avatar
) { ) {
// val mapKey = if (TextUtils.isEmpty(mPetHeadUrl)) "pet_default_head"
// else mPetHeadUrl.substring(mPetHeadUrl.lastIndexOf("/") + 1, mPetHeadUrl.length)
// var bitmapDescriptor = MyApplication.mapPetHeadHashMap[mapKey]
// if (null == bitmapDescriptor || bitmapDescriptor !is BitmapDescriptor) {
// if (null == mPetHeadIconBitmap) {
// //设置头像
// mPetHeadIconBitmap =
// GoogleBitmapHelper.headToBitmap(mContext!!, headBgResId, mPetHeadUrl, mPetType)
// }
// bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(mPetHeadIconBitmap!!)
// //保存在内存中,提高显示速度
// MyApplication.mapPetHeadHashMap[mapKey] = bitmapDescriptor
// }
val bitmapDescriptor = val bitmapDescriptor =
getMarkerBitmapDescriptor(mContext!!, mPetHeadUrl, mPetType, headBgResId) getMarkerBitmapDescriptor(mContext!!, mPetHeadUrl, mPetType, headBgResId)
mMarker?.remove() mMarker?.remove()
@@ -274,7 +249,7 @@ abstract class BaseBaiduMapFragment :
mMarker = mBaiduMap!!.addOverlay(option) mMarker = mBaiduMap!!.addOverlay(option)
} }
private suspend fun getMarkerBitmapDescriptor( suspend fun getMarkerBitmapDescriptor(
context: Context, context: Context,
headUrl: String, headUrl: String,
petType: Int, petType: Int,
@@ -351,7 +326,7 @@ abstract class BaseBaiduMapFragment :
//是否需要移动到地图中心点 //是否需要移动到地图中心点
if (needMoveCamera) { if (needMoveCamera) {
//animateCamera使用动画 //animateCamera使用动画
moveCameraLocation(lat, lon, isAnimMoveCamera = isAnimMoveCamera) moveCameraLocation(lat, lon, needConvertGCJ02, isAnimMoveCamera)
} }
//刷新当前位置ok //刷新当前位置ok
@@ -665,18 +640,24 @@ abstract class BaseBaiduMapFragment :
} }
if (needBlackPolyline) { if (needBlackPolyline) {
val blackOverlayOptions = PolylineOptions().width(QMUIDisplayHelper.dpToPx(4)) //先黄黑线
.color(ContextCompat.getColor(mContext!!, R.color.txt_button)).points(latLngList) getPolylineOptions(8f, R.color.line_stroke_color).let {
mBlackPolyline?.remove() it.isGeodesic(true)
//在地图上绘制折线 it.points(latLngList)
mBlackPolyline = baiduMap.addOverlay(blackOverlayOptions) mBlackPolyline?.remove()
} //在地图上绘制折线
mBlackPolyline = baiduMap.addOverlay(it)
}
}
//设置折线的属性 //设置折线的属性
val yellowOverlayOptions = PolylineOptions().width(QMUIDisplayHelper.dpToPx(3)) //再画黄线
.color(ContextCompat.getColor(mContext!!, R.color.select_color2)).points(latLngList) getPolylineOptions(5f, R.color.rote_line_color).let {
mYellowPolyline?.remove() it.isGeodesic(true)
mYellowPolyline = baiduMap.addOverlay(yellowOverlayOptions) it.points(latLngList)
mYellowPolyline?.remove()
mYellowPolyline = baiduMap.addOverlay(it)
}
//添加起始点图片 //添加起始点图片
if (startCapImageRes > 0) { if (startCapImageRes > 0) {
//构建MarkerOption,用于在地图上添加Marker //构建MarkerOption,用于在地图上添加Marker
@@ -688,6 +669,14 @@ abstract class BaseBaiduMapFragment :
} }
} }
/**
* 获取地图画线的PolylineOptions
*/
fun getPolylineOptions(widthDp: Float, lineColorRes: Int): PolylineOptions {
return PolylineOptions().clickable(false).width(AppUtils.dpToPx(widthDp))
.color(ContextCompat.getColor(mContext!!, lineColorRes))
}
/** /**
* 清空所有图层 * 清空所有图层
*/ */
@@ -700,6 +689,7 @@ abstract class BaseBaiduMapFragment :
* 开始定位,请求用户当前的位置 * 开始定位,请求用户当前的位置
*/ */
fun startLocation(locationPeriod: Int = 1, needStopLocation: Boolean = true) { fun startLocation(locationPeriod: Int = 1, needStopLocation: Boolean = true) {
if (null != mLocationClient) return
initSensorEvent(mContext!!) initSensorEvent(mContext!!)
//定位初始化 //定位初始化
mLocationClient = LocationClient(mContext) mLocationClient = LocationClient(mContext)
@@ -724,9 +714,21 @@ abstract class BaseBaiduMapFragment :
// 此处设置开发者获取到的方向信息,顺时针0-360 // 此处设置开发者获取到的方向信息,顺时针0-360
.direction(location.direction).latitude(location.latitude) .direction(location.direction).latitude(location.latitude)
.longitude(location.longitude).build() .longitude(location.longitude).build()
LogUtil.e("百度定位成功: ${location.latitude}, ${location.longitude}")
mBaiduMap!!.setMyLocationData(locData) mBaiduMap!!.setMyLocationData(locData)
if (needStopLocation) stopLocation() if (needStopLocation) stopLocation()
location.city //转换为gps经纬度
LonAndLatUtil.convertFromGCJ02ToWGS84(location.latitude, location.longitude).let {
MMKVUtil.putDouble(MMKVKey.UserGpsLat, it[0])
MMKVUtil.putDouble(MMKVKey.UserGpsLon, it[1])
//Android 百度定位 SDK 中,location.getSpeed() 返回的单位是 公里/小时(km/h)。
//注意:
//只有 GNSS/卫星定位结果通常才有速度信息。
//非 GNSS 定位时可能没有有效速度,默认值是 0.0f。
//可先用 location.hasSpeed() 判断是否包含速度信息。
//保存速度单位是米/秒(m/s)`
MMKVUtil.putFloat(MMKVKey.UserGpsSpeed, (location.speed / 3.6f))
}
mUserLatLng = LatLng(location.latitude, location.longitude) mUserLatLng = LatLng(location.latitude, location.longitude)
locationSuccess(location) locationSuccess(location)
} }
@@ -872,6 +874,73 @@ abstract class BaseBaiduMapFragment :
return 21f - i return 21f - i
} }
/**
* 设置Marker弹窗设备电量的位置
*/
fun setMapDeviceBatteryOffset(
viewGroup: ViewGroup, latLng: LatLng, mapDeviceBean: MapDeviceBean
) {
mBaiduMap?.projection?.toScreenLocation(latLng)?.let {
viewGroup.x = it.x.toFloat() - viewGroup.width / 2 + AppUtils.dpToPx(5)
viewGroup.y = it.y.toFloat() - AppUtils.dpToPx(56) - viewGroup.height
if (mapDeviceBean.canShowBattery && !mapDeviceBean.isCloseBattery) ViewUtil.instance.viewShow(
viewGroup
)
}
}
/**
* 设置Marker弹窗消息的位置
*/
fun setMarkerInfoViewOffset(markerInfoView: MapMarkerInfoView, latLng: LatLng) {
mBaiduMap?.projection?.toScreenLocation(latLng)?.let {
ViewUtil.instance.viewShow(markerInfoView)
markerInfoView.setOffsetXY(it.x, it.y - AppUtils.dpToPx(56))
}
}
/**
* @param needConvertGCJ02 是否需要转换GCJ02坐标/国内火星坐标
*/
fun getBaiduMapLatLng(
lat: Double, lon: Double, needConvertGCJ02: Boolean = true
): LatLng {
val latLng = if (needConvertGCJ02) {
val convertLonLat = LonAndLatUtil.convertFromWGS84ToGCJ02(lat, lon)
LatLng(convertLonLat[0], convertLonLat[1])
} else {
LatLng(lat, lon)
}
return latLng
}
/**
* 转换国内火星坐标
*/
fun toGCJ02LatLon(latLng: LatLng): LatLng {
return if (MMKVUtil.getBoolean(MMKVKey.isGpsToGCJ02, true)) {
val convertLatLon =
LonAndLatUtil.convertFromWGS84ToGCJ02(latLng.latitude, latLng.longitude)
LatLng(convertLatLon[0], convertLatLon[1])
} else {
latLng
}
}
/**
* 转换GPS坐标
*/
fun toGpsLatLon(latLng: LatLng): LatLng {
return if (MMKVUtil.getBoolean(MMKVKey.isGpsToGCJ02, true)) {
val convertLatLon = LonAndLatUtil.convertFromGCJ02ToWGS84(
latLng.latitude, latLng.longitude
)
LatLng(convertLatLon[0], convertLatLon[1])
} else latLng
}
/** /**
* 定位成功返回 * 定位成功返回
*/ */

View File

@@ -1,25 +1,28 @@
package com.abbidot.tracker.ui.fragment.map.baidumap package com.abbidot.tracker.ui.fragment.map.baidumap
import android.content.Context import android.content.Context
import android.graphics.Point
import android.graphics.Typeface import android.graphics.Typeface
import androidx.lifecycle.lifecycleScope import android.view.MotionEvent
import androidx.appcompat.widget.AppCompatSeekBar
import androidx.core.view.isVisible
import com.abbidot.baselibrary.constant.MMKVKey import com.abbidot.baselibrary.constant.MMKVKey
import com.abbidot.baselibrary.util.LogUtil import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.baselibrary.util.MMKVUtil import com.abbidot.baselibrary.util.MMKVUtil
import com.abbidot.tracker.R import com.abbidot.tracker.R
import com.abbidot.tracker.bean.HistoryDataBean import com.abbidot.tracker.bean.HistoryDataBean
import com.abbidot.tracker.bean.PetBean
import com.abbidot.tracker.constant.ConstantInt import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.ui.fragment.map.googlemap.GoogleBitmapHelper import com.abbidot.tracker.ui.fragment.map.googlemap.GoogleBitmapHelper
import com.abbidot.tracker.util.ViewUtil import com.abbidot.tracker.util.ViewUtil
import com.abbidot.tracker.vm.GeoCoderViewModel import com.abbidot.tracker.vm.GeoCoderViewModel
import com.abbidot.tracker.widget.MapMarkerInfoView
import com.baidu.mapapi.map.BaiduMap import com.baidu.mapapi.map.BaiduMap
import com.baidu.mapapi.map.BitmapDescriptor import com.baidu.mapapi.map.BitmapDescriptor
import com.baidu.mapapi.map.BitmapDescriptorFactory import com.baidu.mapapi.map.BitmapDescriptorFactory
import com.baidu.mapapi.map.MapStatus
import com.baidu.mapapi.map.MarkerOptions import com.baidu.mapapi.map.MarkerOptions
import com.baidu.mapapi.model.LatLng import com.baidu.mapapi.model.LatLng
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
/** /**
*Created by .yzq on 2022/6/28/028. *Created by .yzq on 2022/6/28/028.
@@ -31,12 +34,11 @@ class HistoryDataBaiduMapFragment : BaseBaiduMapFragment() {
// private val mScreenshotsViewModel: ScreenshotsViewModel by viewModels() // private val mScreenshotsViewModel: ScreenshotsViewModel by viewModels()
private lateinit var mGeoCoderViewModel: GeoCoderViewModel private lateinit var mGeoCoderViewModel: GeoCoderViewModel
// private lateinit var mHistoryDataActivity: HistoryDataActivity private lateinit var mMarkerInfoView: MapMarkerInfoView
private lateinit var mVerticalTopToBottomSeekBar: AppCompatSeekBar
private var mLatLngList = mutableListOf<LatLng>() private var mLatLngList = mutableListOf<LatLng>()
private var mPetIconDescriptor: BitmapDescriptor? = null private var mMarkerOptions: MarkerOptions? = null
private lateinit var mMarkerOptions: MarkerOptions
//字体 //字体
private var mTypeface = Typeface.DEFAULT private var mTypeface = Typeface.DEFAULT
@@ -45,20 +47,27 @@ class HistoryDataBaiduMapFragment : BaseBaiduMapFragment() {
private var isMapSnapshot = true private var isMapSnapshot = true
private lateinit var mMapLoadOk: () -> Unit private lateinit var mMapLoadOk: () -> Unit
private var mCurLatLng: LatLng? = null
private var mPetBean: PetBean? = null
companion object { companion object {
@JvmStatic @JvmStatic
fun newInstance( fun newInstance(
context: Context, geoCoderViewModel: GeoCoderViewModel, mapLoadOk: () -> Unit context: Context,
markerInfoView: MapMarkerInfoView,
geoCoderViewModel: GeoCoderViewModel,
verticalTopToBottomSeekBar: AppCompatSeekBar,
mapLoadOk: () -> Unit
) = HistoryDataBaiduMapFragment().apply { ) = HistoryDataBaiduMapFragment().apply {
mContext = context mContext = context
mGeoCoderViewModel = geoCoderViewModel mGeoCoderViewModel = geoCoderViewModel
mVerticalTopToBottomSeekBar = verticalTopToBottomSeekBar
mMarkerInfoView = markerInfoView
mMapLoadOk = mapLoadOk mMapLoadOk = mapLoadOk
} }
} }
override fun initData() { override fun initData() {
// mHistoryDataActivity = mActivity as HistoryDataActivity
super.initData() super.initData()
mTypeface = mTypeface =
@@ -66,10 +75,75 @@ class HistoryDataBaiduMapFragment : BaseBaiduMapFragment() {
} }
override fun onMapLoadOk(baiduMap: BaiduMap) { override fun onMapLoadOk(baiduMap: BaiduMap) {
// val today = Utils.getCurrentTime(Utils.DATE_FORMAT_PATTERN) //点击地图任意地方都不消失自定义头部地点布局
// mHistoryDataActivity.mDataDetailViewModel.getHistoryByDay( // startLocation(60, false)
// mHistoryDataActivity, mHistoryDataActivity.mPet.deviceId, today
// ) baiduMap.apply {
// setOnMarkerClickListener { m ->
// //点击数字大头针回到该位置
// if (m != mMarker) {
// val index = m.tag
// if (index is Int) {
// mVerticalTopToBottomSeekBar.progress = index
// mMarker?.let {
// it.position = m.position
// }
// slideStopChanged(index)
// }
// true
// } else false
// }
setOnMapGestureListener(object : BaiduMap.onMapGestureListener {
override fun onMapScroll(p0: Point?, p1: Point?, p2: MapStatus?): Boolean {
//平移
resetMarkerInfoViewOffset()
return false
}
override fun onMapDoubleTouch(p0: Point?, p1: MapStatus?): Boolean {
//双击放大
LogUtil.e("onMapDoubleTouch")
return false
}
override fun onMapTwoClick(p0: Point?, p1: Point?, p2: MapStatus?): Boolean {
//双指点击缩小
LogUtil.e("onMapTwoClick")
resetMarkerInfoViewOffset()
return false
}
override fun onMapKneading(p0: Point?, p1: Point?, p2: MapStatus?): Boolean {
LogUtil.e("onMapKneading")
//监听地图放大缩小操作
if (getBaiduMapZoom() != mapStatus.zoom) {
setBaiduMapZoom(mapStatus.zoom)
}
resetMarkerInfoViewOffset()
return false
}
override fun onMapOverLooking(p0: Point?, p1: Point?, p2: MapStatus?): Boolean {
LogUtil.e("onMapOverLooking")
return false
}
override fun onMapFling(
p0: MotionEvent?, p1: Float, p2: Float, p3: MapStatus?
): Boolean {
//惯性抛出手势
LogUtil.e("onMapFling1")
return false
}
override fun onMapStatusChangeFinish(p0: MapStatus?) {
resetMarkerInfoViewOffset()
LogUtil.e("onMapStatusChangeFinish")
}
})
}
//变量是否初始化 //变量是否初始化
if (::mMapLoadOk.isInitialized) mMapLoadOk() if (::mMapLoadOk.isInitialized) mMapLoadOk()
} }
@@ -80,7 +154,7 @@ class HistoryDataBaiduMapFragment : BaseBaiduMapFragment() {
fun setLatLngData(data: MutableList<HistoryDataBean>) { fun setLatLngData(data: MutableList<HistoryDataBean>) {
mBaiduMap?.clear() mBaiduMap?.clear()
if (data.size == 0) return if (data.isEmpty()) return
var maxLat = data[0].latitude var maxLat = data[0].latitude
var maxLon = data[0].longitude var maxLon = data[0].longitude
@@ -104,35 +178,69 @@ class HistoryDataBaiduMapFragment : BaseBaiduMapFragment() {
setBaiduMapZoom(zoom + 1) setBaiduMapZoom(zoom + 1)
val maxIndex = data.size - 1 val maxIndex = data.size - 1
mGeoCoderViewModel.getLatLonAddress( mCurLatLng = mLatLngList[maxIndex]
mLatLngList[maxIndex].latitude, mLatLngList[maxIndex].longitude, false
)
val type = MMKVUtil.getInt(MMKVKey.LineSelectPosition, ConstantInt.Line) val type = MMKVUtil.getInt(MMKVKey.LineSelectPosition, ConstantInt.Line)
if (type == ConstantInt.Line) { if (type == ConstantInt.Line) {
addSetLine() addSetLine()
} else { } else {
addSetNumber() addSetNumber()
} }
mGeoCoderViewModel.getLatLonAddress(
mLatLngList[maxIndex].latitude, mLatLngList[maxIndex].longitude, false
)
setMarkerInfoViewOffset(mMarkerInfoView, mLatLngList[maxIndex])
} }
suspend fun setPetBean(petBean: PetBean) {
if (mPetBean?.petId == petBean.petId) {
return
}
try {
petBean.apply {
val bitmapDescriptor =
getMarkerBitmapDescriptor(mContext!!, mPetHeadUrl, petType)
//构建MarkerOption,用于在地图上添加Marker
mMarkerOptions =
MarkerOptions().animateType(MarkerOptions.MarkerAnimateType.grow).zIndex(99)
.icon(bitmapDescriptor as BitmapDescriptor)
mPetBean = this
}
} catch (e: Exception) {
LogUtil.e("setPetBean 异常了$e")
}
}
fun resetMarkerInfoViewOffset() {
mCurLatLng?.let {
if (mMarkerInfoView.isVisible) setMarkerInfoViewOffset(mMarkerInfoView, it)
}
}
/** /**
* 滑动改变 * 滑动改变
*/ */
fun slideChanged(progress: Int) { fun slideChanged(progress: Int) {
mMarkerOptions = MarkerOptions().position(mLatLngList[progress]).icon(mPetIconDescriptor) if (progress < mLatLngList.size) setPetMarkerLatLng(mLatLngList[progress])
mMarker?.remove()
mMarker = mBaiduMap!!.addOverlay(mMarkerOptions)
} }
/** /**
* 停止滑动 * 停止滑动
*/ */
fun slideStopChanged(progress: Int) { fun slideStopChanged(progress: Int) {
if (mLatLngList.size > 0) { if (mLatLngList.isNotEmpty()) {
moveCameraLocation(
mLatLngList[progress].latitude, mLatLngList[progress].longitude,
needConvertGCJ02 = false,
isAnimMoveCamera = true
)
mGeoCoderViewModel.getLatLonAddress( mGeoCoderViewModel.getLatLonAddress(
mLatLngList[progress].latitude, mLatLngList[progress].longitude, false mLatLngList[progress].latitude, mLatLngList[progress].longitude, false
) )
mCurLatLng = mLatLngList[progress]
setMarkerInfoViewOffset(mMarkerInfoView, mLatLngList[progress])
} }
} }
@@ -145,28 +253,18 @@ class HistoryDataBaiduMapFragment : BaseBaiduMapFragment() {
* 画线 * 画线
*/ */
fun addSetLine() { fun addSetLine() {
lifecycleScope.launch { val size = mLatLngList.size
withContext(Dispatchers.IO) { if (size == 0) return
getPetIcon() mBaiduMap?.let {
} it.clear()
val size = mLatLngList.size moveCameraLocation(
if (size == 0) return@launch mLatLngList[size - 1].latitude,
mBaiduMap?.let { mLatLngList[size - 1].longitude,
it.clear() needConvertGCJ02 = false
moveCameraLocation( )
mLatLngList[size - 1].latitude, addPolyline(it, mLatLngList, false, startCapImageRes = 0)
mLatLngList[size - 1].longitude,
needConvertGCJ02 = false
)
addPolyline(it, mLatLngList, false, startCapImageRes = 0)
mMarkerOptions = setPetMarkerLatLng(mLatLngList[size - 1])
MarkerOptions().position(mLatLngList[size - 1]).icon(mPetIconDescriptor)
mMarker?.remove()
mMarker = it.addOverlay(mMarkerOptions)
mapSnapshot()
}
} }
} }
@@ -174,54 +272,32 @@ class HistoryDataBaiduMapFragment : BaseBaiduMapFragment() {
* 设置显示数字 * 设置显示数字
*/ */
fun addSetNumber() { fun addSetNumber() {
lifecycleScope.launch { val size = mLatLngList.size
withContext(Dispatchers.IO) { if (size == 0) return
getPetIcon() mBaiduMap?.let {
} it.clear()
val size = mLatLngList.size
if (size == 0) return@launch
mBaiduMap?.let {
it.clear()
moveCameraLocation( moveCameraLocation(
mLatLngList[size - 1].latitude, mLatLngList[size - 1].latitude,
mLatLngList[size - 1].longitude, mLatLngList[size - 1].longitude,
needConvertGCJ02 = false needConvertGCJ02 = false
) )
for (i in 0 until mLatLngList.size) { for (i in 0 until mLatLngList.size) {
it.addOverlay( it.addOverlay(
MarkerOptions().position(mLatLngList[i]).icon( MarkerOptions().position(mLatLngList[i]).icon(
BitmapDescriptorFactory.fromBitmap( BitmapDescriptorFactory.fromBitmap(
GoogleBitmapHelper.imageUpNumberBitmap( GoogleBitmapHelper.imageUpNumberBitmap(
mContext!!, mContext!!,
R.drawable.pic_history_location, R.drawable.pic_history_location,
(i + 1).toString(), (i + 1).toString(),
mTypeface mTypeface
)
) )
) )
) )
} )
mMarkerOptions =
MarkerOptions().position(mLatLngList[size - 1]).icon(mPetIconDescriptor)
mMarker?.remove()
mMarker = it.addOverlay(mMarkerOptions)
mapSnapshot()
} }
} setPetMarkerLatLng(mLatLngList[size - 1])
}
/**
* 获取宠物头像
*/
private suspend fun getPetIcon() {
if (null == mPetIconDescriptor) {
// val bitmap = ImageUtil.getImageBitmapByUrl(mContext!!, mHistoryDataActivity.mPet.imgurl)
// mPetIconDescriptor = BitmapDescriptorFactory.fromBitmap(bitmap)
// bitmap.recycle()
mPetIconDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.pic_avatar_df)
} }
} }
@@ -240,4 +316,19 @@ class HistoryDataBaiduMapFragment : BaseBaiduMapFragment() {
// }, 1000) // }, 1000)
} }
} }
/**
* 设置宠物Marker经纬度
*/
fun setPetMarkerLatLng(latLng: LatLng) {
mBaiduMap?.apply {
//显示最上面,层级最高,默认值 0f
mMarkerOptions?.let {
it.position(latLng)
mMarker?.remove()
mMarker = addOverlay(it)
}
// setUserMarker()
}
}
} }

View File

@@ -1,15 +1,41 @@
package com.abbidot.tracker.ui.fragment.map.baidumap package com.abbidot.tracker.ui.fragment.map.baidumap
import android.animation.ValueAnimator
import android.content.Context import android.content.Context
import android.graphics.Point
import android.text.TextUtils
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.animation.LinearInterpolator
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import com.abbidot.baselibrary.constant.MMKVKey
import com.abbidot.baselibrary.util.AppUtils
import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.baselibrary.util.MMKVUtil
import com.abbidot.baselibrary.util.Utils import com.abbidot.baselibrary.util.Utils
import com.abbidot.tracker.R import com.abbidot.tracker.R
import com.abbidot.tracker.bean.HistoryDataBean import com.abbidot.tracker.bean.HistoryDataBean
import com.abbidot.tracker.bean.MapDeviceBean import com.abbidot.tracker.bean.MapDeviceBean
import com.abbidot.tracker.bean.PetBean
import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.databinding.LayoutPetLocationInfoBinding
import com.abbidot.tracker.util.Util import com.abbidot.tracker.util.Util
import com.abbidot.tracker.util.ViewUtil
import com.abbidot.tracker.vm.GeoCoderViewModel import com.abbidot.tracker.vm.GeoCoderViewModel
import com.baidu.location.BDLocation
import com.baidu.mapapi.map.BaiduMap import com.baidu.mapapi.map.BaiduMap
import com.baidu.mapapi.map.BitmapDescriptor
import com.baidu.mapapi.map.CircleOptions
import com.baidu.mapapi.map.MapStatus
import com.baidu.mapapi.map.MarkerOptions
import com.baidu.mapapi.map.Overlay
import com.baidu.mapapi.map.PolylineDottedLineType
import com.baidu.mapapi.map.Stroke
import com.baidu.mapapi.model.LatLng import com.baidu.mapapi.model.LatLng
import kotlin.math.pow
/** /**
@@ -24,23 +50,47 @@ class HomeMapBaiduMapFragment : BaseBaiduMapFragment() {
//宠物当前位置信息 //宠物当前位置信息
var mDecPetAddressData: HistoryDataBean? = null var mDecPetAddressData: HistoryDataBean? = null
private var mMapDeviceBean: MapDeviceBean? = null private var mMapDeviceBean: MapDeviceBean? = null
private lateinit var mMapLoadOk :() -> Unit private lateinit var mMapLoadOk: () -> Unit
private var mPetAddressTimeFormat = Utils.DATE_FORMAT_PATTERN_EN11
//是否需要反编译地理位置
private var isReverseGeocode = false
private lateinit var mPetLocationLayoutBinding: LayoutPetLocationInfoBinding
private lateinit var mDeviceBatteryLayout: ViewGroup
//启动动画移动地图摄像机 //启动动画移动地图摄像机
private var isMoveCamera = true private var isMoveCamera = true
//已经转换好的经纬度坐标 //是否是地图摄像头移动了
private val mLatLngList = mutableListOf<LatLng>() private var isMapCameraMove = false
private var mRippleCircle: Overlay? = null
private var mValueAnimator: ValueAnimator? = null
private var mRippleCirclePercent = 0.0
private var mRippleCircleRadius = 200
/** /**
*是否显示信息窗(弹窗覆盖物InfoWindow) * 水波纹圆的颜色
*/ */
private var isShowInfoWindow = false private var mRippleCircleColor: Int = R.color.black10
private val mOtherPetMarkerList = mutableListOf<Overlay?>()
companion object { companion object {
@JvmStatic @JvmStatic
fun newInstance(context: Context,mapLoadOk: () -> Unit) = HomeMapBaiduMapFragment().apply { fun newInstance(
context: Context,
locationLayoutViewBinding: LayoutPetLocationInfoBinding,
deviceBatteryLayout: ViewGroup,
petAddressTimeFormat: String,
isGeocode: Boolean,
mapLoadOk: () -> Unit
) = HomeMapBaiduMapFragment().apply {
mContext = context mContext = context
mDeviceBatteryLayout = deviceBatteryLayout
mPetLocationLayoutBinding = locationLayoutViewBinding
isReverseGeocode = isGeocode
mPetAddressTimeFormat = petAddressTimeFormat
mMapLoadOk = mapLoadOk mMapLoadOk = mapLoadOk
} }
} }
@@ -55,62 +105,152 @@ class HomeMapBaiduMapFragment : BaseBaiduMapFragment() {
//保存地理信息,方便传参给导航页面 //保存地理信息,方便传参给导航页面
if (null == mDecPetAddressData) mDecPetAddressData = HistoryDataBean() if (null == mDecPetAddressData) mDecPetAddressData = HistoryDataBean()
var timeString = ""
mMapDeviceBean?.apply { mMapDeviceBean?.apply {
// timeString = String.format( val timeString = Utils.formatTime(latLonUpdateTime * 1000, mPetAddressTimeFormat)
// getString(R.string.map_current_update_time), mDecPetAddressData?.let { history ->
// DateUtils.getRelativeTimeSpanString(updateTime * 1000) //更新位置时间
// ) history.dayTime = timeString
timeString = Utils.formatTime(updateTime * 1000, Utils.DATE_FORMAT_PATTERN_EN6) //详细位置
} history.address = it
//传递位置信息给InfoWindowAdapter窗口
// mMarker?.tag = history
mDecPetAddressData?.apply { // showMarkerInfoWindow(history)
//更新位置时间
dayTime = timeString if (TextUtils.isEmpty(it)) {
//详细位置 mPetLocationLayoutBinding.root.visibility = View.INVISIBLE
address = it } else {
ViewUtil.instance.viewShow(mPetLocationLayoutBinding.root)
}
val address =
if (inWifiZone == ConstantInt.Type1 && !TextUtils.isEmpty(wifiZoneName)) {
"$wifiZoneName · $it"
} else {
String.format(mContext!!.getString(R.string.txt_near), it)
}
mPetLocationLayoutBinding.let { layout ->
layout.tvPetLocationReverseGeocode.text = address
layout.tvPetLocationUpdateTime.text = timeString
layout.tvPetLocationUpdateTimeFormat.visibility =
if (powerSwitch == ConstantInt.Type2) View.GONE
else {
if (Util.isTimeoutReport(latLonUpdateTime, gnssInterval)) {
layout.tvPetLocationUpdateTimeFormat.text = String.format(
getString(R.string.txt_location_ago),
Utils.getTimeDifference(
latLonUpdateTime * 1000, System.currentTimeMillis()
)
)
View.VISIBLE
} else View.GONE
}
}
}
} }
showMarkerInfoWindow(mDecPetAddressData!!)
} }
} }
override fun onMapLoadOk(baiduMap: BaiduMap) { override fun onMapLoadOk(baiduMap: BaiduMap) {
//开启地图的定位图层
// baiduMap.isMyLocationEnabled = true
startLocation(60, false) startLocation(60, false)
// val locationConfiguration =
// MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL, true, null)
// //自定义精度圈边框颜色
// baiduMap.setMyLocationConfiguration(locationConfiguration)
// initFenceList() mBaiduMap?.apply {
setOnMarkerClickListener { marker ->
if (marker == mMarker) {
mMapDeviceBean?.let {
if (it.canShowBattery) {
mDeviceBatteryLayout.visibility =
if (mDeviceBatteryLayout.isVisible) {
it.isCloseBattery = true
View.GONE
} else {
it.isCloseBattery = false
View.VISIBLE
}
}
}
true
}
false
}
// mBaiduMap?.setOnMarkerClickListener { setOnMapRenderCallbadk {
// if (!isShowInfoWindow) { //地图渲染完成
// startReverseGeocode() setMarkerInfoViewOffset()
// } else { }
// baiduMap.hideInfoWindow()
// } setOnMapGestureListener(object : BaiduMap.onMapGestureListener {
// isShowInfoWindow = !isShowInfoWindow override fun onMapScroll(p0: Point?, p1: Point?, p2: MapStatus?): Boolean {
// false //平移
// } setMarkerInfoViewOffset()
return false
}
override fun onMapDoubleTouch(p0: Point?, p1: MapStatus?): Boolean {
//双击放大
LogUtil.e("onMapDoubleTouch")
return false
}
override fun onMapTwoClick(p0: Point?, p1: Point?, p2: MapStatus?): Boolean {
//双指点击缩小
LogUtil.e("onMapTwoClick")
setMarkerInfoViewOffset()
return false
}
override fun onMapKneading(p0: Point?, p1: Point?, p2: MapStatus?): Boolean {
LogUtil.e("onMapKneading")
//监听地图放大缩小操作
if (getBaiduMapZoom() != mapStatus.zoom) {
setBaiduMapZoom(mapStatus.zoom)
}
setMarkerInfoViewOffset()
return false
}
override fun onMapOverLooking(p0: Point?, p1: Point?, p2: MapStatus?): Boolean {
LogUtil.e("onMapOverLooking")
return false
}
override fun onMapFling(
p0: MotionEvent?, p1: Float, p2: Float, p3: MapStatus?
): Boolean {
//惯性抛出手势
LogUtil.e("onMapFling1")
return false
}
override fun onMapStatusChangeFinish(p0: MapStatus?) {
setMarkerInfoViewOffset()
LogUtil.e("onMapStatusChangeFinish")
}
})
}
//变量是否初始化 //变量是否初始化
if (::mMapLoadOk.isInitialized) mMapLoadOk() if (::mMapLoadOk.isInitialized) mMapLoadOk()
} }
override fun locationSuccess(location: BDLocation?) {
location?.apply {
if (MMKVUtil.getBoolean(MMKVKey.ShowDashedLine)) {
addUserAndPetLine()
}
}
}
/** /**
* 画线 * 画线
*/ */
fun addLine(lat: Double, lon: Double) { fun addLine(lat: Double, lon: Double) {
val convertLonLat = getBaiduMapLatLng(lat, lon) val convertLonLat = getBaiduMapLatLng(lat, lon)
mLatLngList.add(convertLonLat) // mLatLngList.add(convertLonLat)
addPolyline(mBaiduMap!!, mLatLngList, startCapImageRes = R.drawable.map_live_start) // addPolyline(mBaiduMap!!, mLatLngList, startCapImageRes = R.drawable.map_live_start)
refreshPetCurrentLocation( refreshPetCurrentLocation(convertLonLat, needMoveCamera = isMoveCamera)
convertLonLat,
needMoveCamera = isMoveCamera,
)
isMoveCamera = false isMoveCamera = false
} }
@@ -137,12 +277,149 @@ class HomeMapBaiduMapFragment : BaseBaiduMapFragment() {
} }
} }
fun setMarkerInfoViewOffset() {
mPetLatLng?.apply {
mMapDeviceBean?.let {
setMapDeviceBatteryOffset(
mDeviceBatteryLayout, this, it
)
}
}
}
private var mUserAndPetLine: Overlay? = null
/**
* 画用户和宠物之间的虚线
*/
fun addUserAndPetLine() {
mBaiduMap?.apply {
mUserLatLng?.let { u ->
mPetLatLng?.let { p ->
mUserAndPetLine?.remove()
val latLngList: MutableList<LatLng> = mutableListOf()
latLngList.add(p)
latLngList.add(u)
getPolylineOptions(1.5f, R.color.blue_color9).let {
it.points(latLngList)
it.dottedLine(true)
it.dottedLineType(PolylineDottedLineType.DOTTED_LINE_CIRCLE_RECTANGLE)
mUserAndPetLine = addOverlay(it)
}
}
}
}
}
fun removeUserAndPetLine() {
mUserAndPetLine?.remove()
}
/**
* 初始化并添加水波纹圆
*/
private fun addRippleCircle() {
mPetLatLng?.apply {
mBaiduMap?.let {
mRippleCircle?.remove()
val sColor = ContextCompat.getColor(mContext!!, mRippleCircleColor)
mRippleCircle = it.addOverlay(
CircleOptions().center(this)
.radius((mRippleCircleRadius * mRippleCirclePercent).toInt()).stroke(
Stroke(AppUtils.dpToPx(1), sColor)
).fillColor(sColor)
)
}
}
}
/**
* 设置水波纹动画
*/
private fun setRippleCircleAnim() {
if (null == mValueAnimator) {
mValueAnimator = ViewUtil.instance.setValueAnimator(
0.0, 100.0, 2000, LinearInterpolator()
) {
mRippleCirclePercent = it.animatedValue as Float / 100.0
addRippleCircle()
}?.apply {
repeatMode = ValueAnimator.RESTART
repeatCount = ValueAnimator.INFINITE
}
} else {
mValueAnimator?.apply {
if (!isRunning) start()
}
}
}
/**
* 开始水波纹动画
*/
fun startRippleCircleAnim() {
mPetLatLng?.apply {
//一像素对应几米
val pxDis = 2.0.pow(17.0 - getBaiduMapZoom())
mRippleCircleRadius = (pxDis * 150).toInt()
setRippleCircleAnim()
}
}
/**
* 直播开始之后,改变绿色波纹动画
*/
fun greenRippleCircleAnim() {
mRippleCircleColor = R.color.select_color5
startRippleCircleAnim()
}
fun clearRippleCircleAnim() {
mValueAnimator?.cancel()
mRippleCircle?.remove()
mRippleCircle = null
}
/**
* 显示其他宠物的头像Marker
*/
suspend fun showOtherPetHeadMarker(
petList: MutableList<PetBean>, headBgResId: Int = R.drawable.pic_map_gps_avatar
) {
clearOtherPetHeadMarker()
if (MMKVUtil.getBoolean(MMKVKey.ShowAllPet)) {
for (pet in petList) {
val bitmapDescriptor = getMarkerBitmapDescriptor(
mContext!!, pet.imgurl, pet.petType, headBgResId
)
val newLatLng = getBaiduMapLatLng(pet.latitude, pet.longitude)
val markerOptions = MarkerOptions().position(newLatLng)
markerOptions.icon(bitmapDescriptor as BitmapDescriptor)
mBaiduMap?.apply {
mOtherPetMarkerList.add(addOverlay(markerOptions))
}
}
}
}
/**
* 清空其他宠物的头像Marker
*/
fun clearOtherPetHeadMarker() {
for (m in mOtherPetMarkerList) {
m?.remove()
}
mOtherPetMarkerList.clear()
}
override fun onRefreshPetCurrentLocationOk(baiduMap: BaiduMap) { override fun onRefreshPetCurrentLocationOk(baiduMap: BaiduMap) {
// if (isShowInfoWindow) { if (null == mMarker) return
// isShowInfoWindow = false
// baiduMap.hideInfoWindow()
// }
startReverseGeocode() startReverseGeocode()
} }
override fun onDetach() {
super.onDetach()
clearRippleCircleAnim()
}
} }

View File

@@ -392,20 +392,6 @@ abstract class BaseGoogleMapFragment :
private suspend fun setPetHeadMarker( private suspend fun setPetHeadMarker(
latLng: LatLng, headBgResId: Int = R.drawable.pic_map_gps_avatar latLng: LatLng, headBgResId: Int = R.drawable.pic_map_gps_avatar
) { ) {
// val mapKey = if (TextUtils.isEmpty(mPetHeadUrl)) "pet_default_head"
// else mPetHeadUrl.substring(mPetHeadUrl.lastIndexOf("/") + 1, mPetHeadUrl.length)
// var bitmapDescriptor = MyApplication.mapPetHeadHashMap[mapKey]
// if (null == bitmapDescriptor || bitmapDescriptor !is BitmapDescriptor) {
// if (null == mPetHeadIconBitmap) {
// //设置头像
// mPetHeadIconBitmap =
// GoogleBitmapHelper.headToBitmap(mContext!!, headBgResId, mPetHeadUrl, mPetType)
// }
// bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(mPetHeadIconBitmap!!)
// //保存在内存中,提高显示速度
// MyApplication.mapPetHeadHashMap[mapKey] = bitmapDescriptor
// }
val bitmapDescriptor = GoogleBitmapHelper.getMarkerBitmapDescriptor( val bitmapDescriptor = GoogleBitmapHelper.getMarkerBitmapDescriptor(
mContext!!, mPetHeadUrl, mPetType, headBgResId mContext!!, mPetHeadUrl, mPetType, headBgResId
) )

View File

@@ -9,7 +9,6 @@ import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.DrawableCompat import androidx.core.graphics.drawable.DrawableCompat
import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.tracker.MyApplication import com.abbidot.tracker.MyApplication
import com.abbidot.tracker.R import com.abbidot.tracker.R
import com.abbidot.tracker.constant.ConstantInt import com.abbidot.tracker.constant.ConstantInt
@@ -195,7 +194,7 @@ object GoogleBitmapHelper {
bitmap?.let { bitmap?.let {
bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(it) bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(it)
//保存在内存中,提高显示速度 //保存在内存中,提高显示速度
MyApplication.mapPetHeadHashMap[mapKey] = bitmapDescriptor as BitmapDescriptor MyApplication.mapPetHeadHashMap[mapKey] = bitmapDescriptor
} }
} }
} finally { } finally {

View File

@@ -1,16 +1,13 @@
package com.abbidot.tracker.ui.fragment.map.googlemap package com.abbidot.tracker.ui.fragment.map.googlemap
import android.content.Context import android.content.Context
import android.graphics.BitmapFactory
import android.graphics.Typeface import android.graphics.Typeface
import android.text.TextUtils
import androidx.appcompat.widget.AppCompatSeekBar import androidx.appcompat.widget.AppCompatSeekBar
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.abbidot.baselibrary.constant.MMKVKey import com.abbidot.baselibrary.constant.MMKVKey
import com.abbidot.baselibrary.util.AppUtils import com.abbidot.baselibrary.util.AppUtils
import com.abbidot.baselibrary.util.LogUtil import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.baselibrary.util.MMKVUtil import com.abbidot.baselibrary.util.MMKVUtil
import com.abbidot.tracker.MyApplication
import com.abbidot.tracker.R import com.abbidot.tracker.R
import com.abbidot.tracker.bean.HistoryDataBean import com.abbidot.tracker.bean.HistoryDataBean
import com.abbidot.tracker.bean.PetBean import com.abbidot.tracker.bean.PetBean
@@ -130,28 +127,16 @@ class HistoryDataGoogleMapFragment : BaseGoogleMapFragment() {
} }
suspend fun setPetBean(petBean: PetBean) { suspend fun setPetBean(petBean: PetBean) {
if (petBean == mPetBean) { if (mPetBean?.petId == petBean.petId) {
return return
} }
mPetBean = petBean
try { try {
mPetBean?.apply { petBean.apply {
val mapKey = if (TextUtils.isEmpty(imgurl)) "pet_default_head" val bitmapDescriptor =
else imgurl.substring(imgurl.lastIndexOf("/") + 1, imgurl.length) GoogleBitmapHelper.getMarkerBitmapDescriptor(mContext!!, mPetHeadUrl, petType)
var bitmapDescriptor = MyApplication.mapPetHeadHashMap[mapKey]
if (null == bitmapDescriptor || bitmapDescriptor !is BitmapDescriptor) {
var bitmap = GoogleBitmapHelper.headToBitmap(
mContext!!, R.drawable.pic_map_gps_avatar, imgurl, petType
)
if (null == bitmap) bitmap = BitmapFactory.decodeResource(
mContext!!.resources, R.drawable.icon_location_svg
)
bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(bitmap!!)
//保存在内存中,提高显示速度
MyApplication.mapPetHeadHashMap[mapKey] = bitmapDescriptor
}
mPetIconDescriptor = bitmapDescriptor mPetIconDescriptor = bitmapDescriptor
mMarker?.setIcon(mPetIconDescriptor) mMarker?.setIcon(mPetIconDescriptor)
mPetBean = this
} }
} catch (e: Exception) { } catch (e: Exception) {
LogUtil.e("setPetBean 异常了$e") LogUtil.e("setPetBean 异常了$e")

View File

@@ -51,9 +51,9 @@ class HomeMapGoogleMapFragmentV3 : BaseGoogleMapFragment() {
//启动动画移动地图摄像机 //启动动画移动地图摄像机
private var isMoveCamera = true private var isMoveCamera = true
private var mUserAndPetLine: Polyline? = null private var mUserAndPetLine: Polyline? = null
private var mRippleCircle: Circle? = null private var mRippleCircle: Circle? = null
private var mValueAnimator: ValueAnimator? = null private var mValueAnimator: ValueAnimator? = null
private var mRippleCirclePercent = 0.0 private var mRippleCirclePercent = 0.0
private var mRippleCircleRadius = 200 private var mRippleCircleRadius = 200
@@ -387,8 +387,7 @@ class HomeMapGoogleMapFragmentV3 : BaseGoogleMapFragment() {
val markerOptions = MarkerOptions().position(newLatLng) val markerOptions = MarkerOptions().position(newLatLng)
markerOptions.icon(bitmapDescriptor) markerOptions.icon(bitmapDescriptor)
mGoogleMap?.apply { mGoogleMap?.apply {
mOtherPetMarkerList.add(addMarker(markerOptions)?.apply { mOtherPetMarkerList.add(addMarker(markerOptions))
})
} }
} }
} }

View File

@@ -96,6 +96,7 @@ annotation class MMKVKey {
//手机Gps定位信息 //手机Gps定位信息
const val UserGpsLat = "userGpsLat" const val UserGpsLat = "userGpsLat"
const val UserGpsLon = "userGpsLon" const val UserGpsLon = "userGpsLon"
//单位是米/秒(m/s)
const val UserGpsSpeed = "userGpsSpeed" const val UserGpsSpeed = "userGpsSpeed"
//地图模式类型 //地图模式类型

View File

@@ -94,7 +94,7 @@ class AppUtils {
* 是否是国内 * 是否是国内
*/ */
fun isChina(type: String = SWITCH_PAGE_TYPE): Boolean { fun isChina(type: String = SWITCH_PAGE_TYPE): Boolean {
return false return true
if (isDebug()) { if (isDebug()) {
if (type == SWITCH_MAP_TYPE && MMKVUtil.getBoolean(MMKVKey.OnlyGoogleMap, false)) { if (type == SWITCH_MAP_TYPE && MMKVUtil.getBoolean(MMKVKey.OnlyGoogleMap, false)) {
//只启用谷歌地图 //只启用谷歌地图