新增国内经纬度转换

This commit is contained in:
yezhiqiu
2026-03-10 17:46:23 +08:00
parent 8b128e58cb
commit f5001f3349
14 changed files with 424 additions and 206 deletions

View File

@@ -30,7 +30,7 @@ android {
targetSdkVersion 35
versionCode 2110
// versionName "2.1.10"
versionName "2.1.10-Beta1"
versionName "2.1.10-Beta5"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

View File

@@ -18,12 +18,12 @@ import com.abbidot.tracker.constant.ConstantString
import com.abbidot.tracker.constant.GetResultCallback
import com.abbidot.tracker.databinding.ActivityDebugBinding
import com.abbidot.tracker.dialog.CommonListDialog
import com.abbidot.tracker.util.LonAndLatUtil
import com.abbidot.tracker.util.ViewUtil
import com.abbidot.tracker.vm.DataViewModel
import com.abbidot.tracker.vm.MapViewModel
import com.abbidot.tracker.vm.TrackerInfoViewModel
import com.qmuiteam.qmui.widget.QMUITopBar
import com.qmuiteam.qmui.widget.grouplist.QMUICommonListItemView
class DebugActivity : BaseActivity<ActivityDebugBinding>(ActivityDebugBinding::inflate),
ChangePetListDialogAdapter.OnChangeClickListener {
@@ -63,8 +63,7 @@ class DebugActivity : BaseActivity<ActivityDebugBinding>(ActivityDebugBinding::i
mContext, mViewBinding.qiNuoTestRecyclerView, mAdapter, bottom = 20
)
initQMUICommonListItemView(mViewBinding.switchBaseUrl)
initQMUICommonListItemView(mViewBinding.switchOnlyGoogleMap)
initQMUICommonListItemView()
LogUtil.e("${mPetList?.size}")
if (null == mPetList) {
@@ -87,28 +86,29 @@ class DebugActivity : BaseActivity<ActivityDebugBinding>(ActivityDebugBinding::i
mMapViewModel.getMapDeviceStatus(mPetList!![mPetSelectPosition].deviceId)
}
private fun initQMUICommonListItemView(view: QMUICommonListItemView) {
when (view) {
mViewBinding.switchBaseUrl -> {
mViewBinding.switchBaseUrl.let {
it.text = "国内服务器"
it.switch.isChecked = MMKVUtil.getBoolean(MMKVKey.DebugIp, true)
it.switch.setOnCheckedChangeListener { _, isChecked ->
MMKVUtil.putBoolean(MMKVKey.DebugIp, isChecked)
showToast("修改成功,注销登录并重启APP生效")
}
}
private fun initQMUICommonListItemView() {
mViewBinding.switchBaseUrl.let {
it.text = "国内服务器"
it.switch.isChecked = MMKVUtil.getBoolean(MMKVKey.DebugIp, true)
it.switch.setOnCheckedChangeListener { _, isChecked ->
MMKVUtil.putBoolean(MMKVKey.DebugIp, isChecked)
showToast("修改成功,注销登录并重启APP生效")
}
mViewBinding.switchOnlyGoogleMap -> {
mViewBinding.switchOnlyGoogleMap.let {
it.text = "只启用谷歌地图"
it.switch.isChecked = MMKVUtil.getBoolean(MMKVKey.OnlyGoogleMap, false)
it.switch.setOnCheckedChangeListener { _, isChecked ->
MMKVUtil.putBoolean(MMKVKey.OnlyGoogleMap, isChecked)
showToast("修改成功,重启APP生效")
}
}
}
mViewBinding.switchOnlyGoogleMap.let {
it.text = "只启用谷歌地图"
it.switch.isChecked = MMKVUtil.getBoolean(MMKVKey.OnlyGoogleMap, false)
it.switch.setOnCheckedChangeListener { _, isChecked ->
MMKVUtil.putBoolean(MMKVKey.OnlyGoogleMap, isChecked)
showToast("修改成功,重启APP生效")
}
}
mViewBinding.switchGoogleLatLonConversion.let {
it.text = "谷歌地图经纬度转换"
it.switch.isChecked = MMKVUtil.getBoolean(MMKVKey.isGpsToGCJ02, false)
it.switch.setOnCheckedChangeListener { _, isChecked ->
MMKVUtil.putBoolean(MMKVKey.isGpsToGCJ02, isChecked)
showToast("修改成功,下次刷新位置生效")
}
}
}
@@ -148,12 +148,23 @@ class DebugActivity : BaseActivity<ActivityDebugBinding>(ActivityDebugBinding::i
data.latLonUpdateTime * 1000, Utils.DATE_FORMAT_PATTERN_CN2
)
ViewUtil.instance.addMenuBean(mMutableList, "经纬度上报时间", time)
ViewUtil.instance.addMenuBean(
mMutableList, "longitude", data.longitude.toString()
)
ViewUtil.instance.addMenuBean(
mMutableList, "latitude", data.latitude.toString()
)
if (MMKVUtil.getBoolean(MMKVKey.isGpsToGCJ02)) {
val convertLatLon =
LonAndLatUtil.convertFromWGS84ToGCJ02(data.latitude, data.longitude)
ViewUtil.instance.addMenuBean(
mMutableList, "longitude", convertLatLon[1].toString()
)
ViewUtil.instance.addMenuBean(
mMutableList, "latitude", convertLatLon[0].toString()
)
} else {
ViewUtil.instance.addMenuBean(
mMutableList, "longitude", data.longitude.toString()
)
ViewUtil.instance.addMenuBean(
mMutableList, "latitude", data.latitude.toString()
)
}
ViewUtil.instance.addMenuBean(
mMutableList, "安全围栏中inSafeZone(0=是)", data.inSafeZone.toString()
)
@@ -170,7 +181,9 @@ class DebugActivity : BaseActivity<ActivityDebugBinding>(ActivityDebugBinding::i
mMutableList, "gps信号gnssSignal", data.gpsSignal.toString()
)
ViewUtil.instance.addMenuBean(
mMutableList, "设备开关机状态(0关1开2眠3电)", data.powerSwitch.toString()
mMutableList,
"设备开关机状态(0关1开2眠3电)",
data.powerSwitch.toString()
)
ViewUtil.instance.addMenuBean(
mMutableList, "电量batteryLevel", data.batteryLevel.toString()

View File

@@ -82,6 +82,7 @@ class AddWifiPowerZone3Activity :
ViewUtil.instance.setRecyclerViewDecorationLinearLayoutManager(
mContext, rvAddWifiZone3WifiNetwork, mWiFiListAdapter
)
lavAddWifiZone3Anim.setAnimation("lottie/dfu_loading.json")
}
//查找是否连接了蓝牙
@@ -108,6 +109,9 @@ class AddWifiPowerZone3Activity :
mRightImageButton?.let {
it.isEnabled = false
mAnimatorSet = ViewUtil.instance.viewRotationAnimator(it, true)
mViewBinding.rvAddWifiZone3WifiNetwork.visibility = View.GONE
mViewBinding.lavAddWifiZone3Anim.playAnimation()
mViewBinding.lavAddWifiZone3Anim.visibility = View.VISIBLE
}
mWiFiListAdapter.setData(null)
SRBleUtil.instance.writeData(
@@ -205,6 +209,9 @@ class AddWifiPowerZone3Activity :
mWiFiListAdapter.setData(wifiList.wifi, true)
showLoading(false)
mViewBinding.rvAddWifiZone3WifiNetwork.visibility = View.VISIBLE
mViewBinding.lavAddWifiZone3Anim.cancelAnimation()
mViewBinding.lavAddWifiZone3Anim.visibility = View.GONE
} catch (_: Exception) {
sendWiFiCmd()
}

View File

@@ -41,6 +41,7 @@ import com.abbidot.tracker.dialog.SelectMapTypeDialog
import com.abbidot.tracker.ui.activity.HomeV2Activity
import com.abbidot.tracker.ui.activity.map.LiveActivityV3
import com.abbidot.tracker.ui.common.map.HomeMapCommonV3
import com.abbidot.tracker.util.LonAndLatUtil
import com.abbidot.tracker.util.Util
import com.abbidot.tracker.util.ViewUtil
import com.abbidot.tracker.util.bluetooth.SRBleCmdUtil
@@ -175,7 +176,7 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
override fun onResume() {
super.onResume()
isMoveCamera = true
if (mShowCenterLocationType == ConstantInt.PetLocationType) isMoveCamera = true
getHomeV2Activity()?.apply {
//其他页面是否选择了宠物
if (mCurrentShowPetPos != mSelectPetPosition) {
@@ -562,6 +563,9 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
}
mHomeMapCommon.switchShowLocation(ConstantInt.UserLocationType)
} else {
//判断是否国内经纬度,需要坐标转换
val isOutOfChina = LonAndLatUtil.isLocationOutOfChina(latitude, longitude)
MMKVUtil.putBoolean(MMKVKey.isGpsToGCJ02, !isOutOfChina)
mHomeMapCommon.refreshPetCurrentLocation(latitude, longitude, isMoveCamera)
isMoveCamera = false
}

View File

@@ -5,6 +5,7 @@ import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Point
import android.location.Location
import android.os.Bundle
import android.view.LayoutInflater
@@ -273,16 +274,17 @@ abstract class BaseGoogleMapFragment :
* 移动到某个位置 为中心点
*/
fun moveCameraLocation(latLng: LatLng, isAnimMoveCamera: Boolean = false) {
val newLatLng = toGCJ02LatLon(latLng)
mGoogleMap?.apply {
//animateCamera使用动画
if (isAnimMoveCamera) {
animateCamera(
CameraUpdateFactory.newLatLngZoom(latLng, mGoogleMapZoom),
CameraUpdateFactory.newLatLngZoom(newLatLng, mGoogleMapZoom),
mAnimMoveDurationMs,
null
)
} else {
moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, mGoogleMapZoom))
moveCamera(CameraUpdateFactory.newLatLngZoom(newLatLng, mGoogleMapZoom))
}
}
}
@@ -298,13 +300,18 @@ abstract class BaseGoogleMapFragment :
* 切换用户和宠物的位置居中显示,移动摄像头中心
*/
fun switchShowLocation(@ConstantInt type: Int) {
val latLng = if (type == ConstantInt.PetLocationType) {
if (type == ConstantInt.PetLocationType) {
//刷新下用户当前的位置
getLastLocation()
mPetLatLng
} else mUserLatLng
latLng?.apply {
moveCameraLocation(this)
mPetLatLng?.let {
moveCameraLocation(it)
}
} else {
mGoogleMap?.apply {
mUserLatLng?.let {
moveCamera(CameraUpdateFactory.newLatLngZoom(it, mGoogleMapZoom))
}
}
}
}
@@ -314,10 +321,11 @@ abstract class BaseGoogleMapFragment :
fun moveAnimateCameraLocation(
latLng: LatLng, moveCameraCallback: GoogleMap.CancelableCallback?
) {
val newLatLng = toGCJ02LatLon(latLng)
//1秒动画执行时间
mGoogleMap?.apply {
animateCamera(
CameraUpdateFactory.newLatLngZoom(latLng, mGoogleMapZoom),
CameraUpdateFactory.newLatLngZoom(newLatLng, mGoogleMapZoom),
mAnimMoveDurationMs,
moveCameraCallback
)
@@ -334,6 +342,18 @@ abstract class BaseGoogleMapFragment :
mPetHeadIconBitmap = null
}
fun latLngToScreenLocation(latLng: LatLng): Point {
val points = Point(0, 0)
mGoogleMap?.apply {
val newLatLng = toGCJ02LatLon(latLng)
projection.toScreenLocation(newLatLng).let {
points.x = it.x
points.y = it.y
}
}
return points
}
/**
* 设置宠物头像地图Marker
*/
@@ -345,8 +365,8 @@ abstract class BaseGoogleMapFragment :
mPetHeadIconBitmap =
GoogleBitmapHelper.headToBitmap(mContext!!, headBgResId, mPetHeadUrl, mPetType)
}
val markerOptions = MarkerOptions().position(latLng)
val newLatLng = toGCJ02LatLon(latLng)
val markerOptions = MarkerOptions().position(newLatLng)
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(mPetHeadIconBitmap!!))
mMarker?.remove()
mGoogleMap?.apply {
@@ -447,8 +467,9 @@ abstract class BaseGoogleMapFragment :
isDraggable: Boolean = false
): Marker? {
ImageUtil.getBitmapFromDrawableAndSvg(mContext!!, imageTypeResId)?.apply {
val newLatLng = toGCJ02LatLon(latLng)
val imageTypeMarker =
MarkerOptions().position(latLng).icon(BitmapDescriptorFactory.fromBitmap(this))
MarkerOptions().position(newLatLng).icon(BitmapDescriptorFactory.fromBitmap(this))
imageTypeMarker.let {
//图像上将置于标记的 LatLng 位置的点。该点默认为图像底部的中间位置。
if (anchorCenter) it.anchor(it.anchorU, it.anchorV / 2)
@@ -483,9 +504,11 @@ abstract class BaseGoogleMapFragment :
) {
if (null == mGoogleMap) return
val newLatLng = toGCJ02LatLon(center)
val circleFence = mGoogleMap!!.addCircle(
CircleOptions().center(center).radius(radius).strokeWidth(AppUtils.dpToPx(1).toFloat())
.fillColor(fillColor).strokeColor(strokeColor)
CircleOptions().center(newLatLng).radius(radius)
.strokeWidth(AppUtils.dpToPx(1).toFloat()).fillColor(fillColor)
.strokeColor(strokeColor)
)
if (isDashedPattern) {
@@ -523,9 +546,18 @@ abstract class BaseGoogleMapFragment :
isDashedPattern: Boolean = false
) {
mGoogleMap?.apply {
val newLatLngList = if (MMKVUtil.getBoolean(MMKVKey.isGpsToGCJ02)) {
val conLatLngList = mutableListOf<LatLng>()
for (latLng in points) {
conLatLngList.add(toGCJ02LatLon(latLng))
}
conLatLngList
} else {
points
}
//构造PolygonOptions
val polygonOptions =
PolygonOptions().addAll(points).strokeWidth(AppUtils.dpToPx(1).toFloat())
PolygonOptions().addAll(newLatLngList).strokeWidth(AppUtils.dpToPx(1).toFloat())
.fillColor(fillColor).strokeColor(strokeColor)
if (isDashedPattern) {
@@ -571,11 +603,11 @@ abstract class BaseGoogleMapFragment :
fillColor: Int = ContextCompat.getColor(mContext!!, R.color.select_color4),
isDashedPattern: Boolean = true
) {
if (imageTypeResId > 0) addImageMarker(
LatLng(
fencesBean.latitudeCenter, fencesBean.longitudeCenter
), imageTypeResId
)
if (imageTypeResId > 0) {
addImageMarker(
LatLng(fencesBean.latitudeCenter, fencesBean.longitudeCenter), imageTypeResId
)
}
addRectFence(fencesBean, strokeColor, fillColor, isDashedPattern)
}
@@ -711,9 +743,18 @@ abstract class BaseGoogleMapFragment :
*/
fun addSinglePolyline(googleMap: GoogleMap, latLngList: MutableList<LatLng>) {
if (latLngList.size > 1) {
val newLatLngList = if (MMKVUtil.getBoolean(MMKVKey.isGpsToGCJ02)) {
val conLatLngList = mutableListOf<LatLng>()
for (latLng in latLngList) {
conLatLngList.add(toGCJ02LatLon(latLng))
}
conLatLngList
} else {
latLngList
}
//先黄黑线
getPolylineOptions(4f, R.color.txt_button).let {
it.addAll(latLngList)
getPolylineOptions(8f, R.color.line_stroke_color).let {
it.addAll(newLatLngList)
googleMap.addPolyline(it).apply {
startCap = RoundCap()
endCap = RoundCap()
@@ -727,8 +768,8 @@ abstract class BaseGoogleMapFragment :
// polyline.pattern = pattern
//再画黄线
getPolylineOptions(3.5f, R.color.select_color2).let {
it.addAll(latLngList)
getPolylineOptions(5f, R.color.rote_line_color).let {
it.addAll(newLatLngList)
googleMap.addPolyline(it).apply {
startCap = RoundCap()
endCap = RoundCap()
@@ -748,10 +789,11 @@ abstract class BaseGoogleMapFragment :
* 每加个点就画一次
*/
fun addPolyline(googleMap: GoogleMap, latLng: LatLng) {
val newLatLng = toGCJ02LatLon(latLng)
//先黑线
if (null == mBlackPolyline) {
getPolylineOptions(4f, R.color.txt_button).let {
it.add(latLng)
getPolylineOptions(4f, R.color.white).let {
it.add(newLatLng)
mBlackPolyline = googleMap.addPolyline(it).apply {
endCap = RoundCap()
//连接类型,可以指定棱台或圆角
@@ -760,7 +802,7 @@ abstract class BaseGoogleMapFragment :
}
} else {
val blackPoints = mBlackPolyline!!.points
blackPoints.add(latLng)
blackPoints.add(newLatLng)
mBlackPolyline!!.points = blackPoints
}
@@ -771,8 +813,8 @@ abstract class BaseGoogleMapFragment :
//再画黄线
if (null == mYellowPolyline) {
getPolylineOptions(3.5f, R.color.btn_yellow_color).let {
it.add(latLng)
getPolylineOptions(3.5f, R.color.blue_color).let {
it.add(newLatLng)
mYellowPolyline = googleMap.addPolyline(it).apply {
//起点线帽图片,refWidth数值越小图片越大
startCap = CustomCap(
@@ -785,7 +827,7 @@ abstract class BaseGoogleMapFragment :
}
} else {
val yellowPoints = mYellowPolyline!!.points
yellowPoints.add(latLng)
yellowPoints.add(newLatLng)
mYellowPolyline!!.points = yellowPoints
}
@@ -797,44 +839,44 @@ abstract class BaseGoogleMapFragment :
* 需要1个点的经纬度
* 每加个点就画一次
*/
fun addPolyLines(googleMap: GoogleMap, latLngList: MutableList<LatLng>) {
//先黑线
if (null == mBlackPolyline) {
getPolylineOptions(4f, R.color.txt_button).let {
it.addAll(latLngList)
mBlackPolyline = googleMap.addPolyline(it).apply {
endCap = RoundCap()
//连接类型,可以指定棱台或圆角
jointType = JointType.ROUND
}
}
} else {
val blackPoints = mBlackPolyline!!.points
blackPoints.addAll(latLngList)
mBlackPolyline!!.points = blackPoints
}
//再画黄线
if (null == mYellowPolyline) {
getPolylineOptions(3.5f, R.color.btn_yellow_color).let {
it.addAll(latLngList)
mYellowPolyline = googleMap.addPolyline(it).apply {
//起点线帽图片,refWidth数值越小图片越大
startCap = CustomCap(
BitmapDescriptorFactory.fromResource(R.drawable.map_live_start),
QMUIDisplayHelper.dpToPx(3).toFloat()
)
endCap = RoundCap()
jointType = JointType.ROUND
}
}
} else {
val yellowPoints = mYellowPolyline!!.points
yellowPoints.addAll(latLngList)
mYellowPolyline!!.points = yellowPoints
}
LogUtil.e("点的个数:${mBlackPolyline?.points?.size},${mYellowPolyline?.points?.size}")
}
// fun addPolyLines(googleMap: GoogleMap, latLngList: MutableList<LatLng>) {
// //先黑线
// if (null == mBlackPolyline) {
// getPolylineOptions(4f, R.color.txt_button).let {
// it.addAll(latLngList)
// mBlackPolyline = googleMap.addPolyline(it).apply {
// endCap = RoundCap()
// //连接类型,可以指定棱台或圆角
// jointType = JointType.ROUND
// }
// }
// } else {
// val blackPoints = mBlackPolyline!!.points
// blackPoints.addAll(latLngList)
// mBlackPolyline!!.points = blackPoints
// }
//
// //再画黄线
// if (null == mYellowPolyline) {
// getPolylineOptions(3.5f, R.color.btn_yellow_color).let {
// it.addAll(latLngList)
// mYellowPolyline = googleMap.addPolyline(it).apply {
// //起点线帽图片,refWidth数值越小图片越大
// startCap = CustomCap(
// BitmapDescriptorFactory.fromResource(R.drawable.map_live_start),
// QMUIDisplayHelper.dpToPx(3).toFloat()
// )
// endCap = RoundCap()
// jointType = JointType.ROUND
// }
// }
// } else {
// val yellowPoints = mYellowPolyline!!.points
// yellowPoints.addAll(latLngList)
// mYellowPolyline!!.points = yellowPoints
// }
// LogUtil.e("点的个数:${mBlackPolyline?.points?.size},${mYellowPolyline?.points?.size}")
// }
override fun onMapReady(googleMap: GoogleMap) {
LogUtil.e("谷歌地图加载好了")
@@ -966,7 +1008,7 @@ abstract class BaseGoogleMapFragment :
// val padding = width / 8
val builder = LatLngBounds.Builder()
for (item in points) {
builder.include(item)
builder.include(toGCJ02LatLon(item))
}
//根据经纬度来设置缩放级别
// mCameraUpdate = CameraUpdateFactory.newLatLngBounds(
@@ -1063,7 +1105,8 @@ abstract class BaseGoogleMapFragment :
* 设置Marker弹窗消息的位置
*/
fun setMarkerInfoViewOffset(markerInfoView: MapMarkerInfoView, latLng: LatLng) {
mGoogleMap?.projection?.toScreenLocation(latLng)?.let {
val newLatLng = toGCJ02LatLon(latLng)
mGoogleMap?.projection?.toScreenLocation(newLatLng)?.let {
ViewUtil.instance.viewShow(markerInfoView)
markerInfoView.setOffsetXY(it.x, it.y - AppUtils.dpToPx(56))
}
@@ -1075,7 +1118,8 @@ abstract class BaseGoogleMapFragment :
fun setMapDeviceBatteryOffset(
viewGroup: ViewGroup, latLng: LatLng, mapDeviceBean: MapDeviceBean
) {
mGoogleMap?.projection?.toScreenLocation(latLng)?.let {
val newLatLng = toGCJ02LatLon(latLng)
mGoogleMap?.projection?.toScreenLocation(newLatLng)?.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(
@@ -1094,6 +1138,31 @@ abstract class BaseGoogleMapFragment :
}
}
/**
* 转换国内火星坐标
*/
fun toGCJ02LatLon(latLng: LatLng): LatLng {
return if (MMKVUtil.getBoolean(MMKVKey.isGpsToGCJ02)) {
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)) {
val convertLatLon = LonAndLatUtil.convertFromGCJ02ToWGS84(
latLng.latitude, latLng.longitude
)
LatLng(convertLatLon[0], convertLatLon[1])
} else latLng
}
/**
* 定位成功返回
*/

View File

@@ -77,7 +77,8 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
setOnCameraMoveListener {
mFencesBean.let {
resetFencesViewCentre(LatLng(it.latitudeCenter, it.longitudeCenter))
val latLng = LatLng(it.latitudeCenter, it.longitudeCenter)
resetFencesViewCentre(latLng)
}
//监听地图放大缩小操作
@@ -89,8 +90,13 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
}
setOnMapLongClickListener {
resetFencesViewCentre(it)
// mapOkAndDistancePointLatLng(500)
toGpsLatLon(it).let { n ->
mFencesBean.let { f ->
f.latitudeCenter = n.latitude
f.longitudeCenter = n.longitude
}
resetFencesViewCentre(n)
}
}
}
@@ -127,7 +133,8 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
* 重新设置围栏控件的中心点位置
*/
fun resetFencesViewCentre(centreLatLng: LatLng) {
mGoogleMap?.projection?.toScreenLocation(centreLatLng)?.apply {
val newLatLng = toGCJ02LatLon(centreLatLng)
mGoogleMap?.projection?.toScreenLocation(newLatLng)?.apply {
mFencesCircleView.setCentreXY(this)
mFencesRectView.setCentreXY(this)
mFencesPolygonView.setCentreXY(this)
@@ -198,8 +205,6 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
}
private fun getLatLngAndCalDistance(): Array<String> {
// 经纬度转换为手机坐标点
// val x = mGoogleMap!!.projection.toScreenLocation(it).x
if (null == mGoogleMap) return arrayOf("0", "0")
return when (mFencesBean.fenceShapeType) {
@@ -225,15 +230,20 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
val showDistance = getShowDistance(distanceInt)
LogUtil.e("getLatLngAndCalDistance,$distanceInt,$showDistance")
mFencesBean.apply {
latitudeCenter = centreLatLng.latitude
longitudeCenter = centreLatLng.longitude
ancillaryLatitude = endLatLng.latitude
ancillaryLongitude = endLatLng.longitude
ancillaryOtherLatitude = startLatLng.latitude
ancillaryOtherLongitude = startLatLng.longitude
toGpsLatLon(centreLatLng).let {
latitudeCenter = it.latitude
longitudeCenter = it.longitude
}
toGpsLatLon(endLatLng).let {
ancillaryLatitude = it.latitude
ancillaryLongitude = it.longitude
}
toGpsLatLon(startLatLng).let {
ancillaryOtherLatitude = it.latitude
ancillaryOtherLongitude = it.longitude
}
}
arrayOf(
// Utils.formatDecimal(distance, 2)
distanceInt.toString(), showDistance.toString()
)
}
@@ -270,16 +280,26 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
val heightDistance = rectHeightDistance.toInt()
val showHeightDistance = getShowDistance(heightDistance)
mFencesBean.apply {
latitudeCenter = centreLatLng.latitude
longitudeCenter = centreLatLng.longitude
latitudeA = rectALatLng.latitude
longitudeA = rectALatLng.longitude
latitudeB = rectBLatLng.latitude
longitudeB = rectBLatLng.longitude
latitudeC = rectCLatLng.latitude
longitudeC = rectCLatLng.longitude
latitudeD = rectDLatLng.latitude
longitudeD = rectDLatLng.longitude
toGpsLatLon(centreLatLng).let {
latitudeCenter = it.latitude
longitudeCenter = it.longitude
}
toGpsLatLon(rectALatLng).let {
latitudeA = it.latitude
longitudeA = it.longitude
}
toGpsLatLon(rectBLatLng).let {
latitudeB = it.latitude
longitudeB = it.longitude
}
toGpsLatLon(rectCLatLng).let {
latitudeC = it.latitude
longitudeC = it.longitude
}
toGpsLatLon(rectDLatLng).let {
latitudeD = it.latitude
longitudeD = it.longitude
}
}
//长度和高度
arrayOf(
@@ -291,8 +311,9 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
}
else -> {
val centreLatLng = mFencesPolygonView.getPolygonCentrePoint()
.let { mGoogleMap!!.projection.fromScreenLocation(it) }
val centreLatLng = mFencesPolygonView.getPolygonCentrePoint().let {
mGoogleMap!!.projection.fromScreenLocation(it)
}
val polygonALatLng =
mFencesPolygonView.getPolygonABCDEFPoint(FencesPolygonView.POINT_A).let {
mGoogleMap!!.projection.fromScreenLocation(it)
@@ -318,20 +339,34 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
mGoogleMap!!.projection.fromScreenLocation(it)
}
mFencesBean.apply {
latitudeCenter = centreLatLng.latitude
longitudeCenter = centreLatLng.longitude
latitudeA = polygonALatLng.latitude
longitudeA = polygonALatLng.longitude
latitudeB = polygonBLatLng.latitude
longitudeB = polygonBLatLng.longitude
latitudeC = polygonCLatLng.latitude
longitudeC = polygonCLatLng.longitude
latitudeD = polygonDLatLng.latitude
longitudeD = polygonDLatLng.longitude
latitudeE = polygonELatLng.latitude
longitudeE = polygonELatLng.longitude
latitudeF = polygonFLatLng.latitude
longitudeF = polygonFLatLng.longitude
toGpsLatLon(centreLatLng).let {
latitudeCenter = it.latitude
longitudeCenter = it.longitude
}
toGpsLatLon(polygonALatLng).let {
latitudeA = it.latitude
longitudeA = it.longitude
}
toGpsLatLon(polygonBLatLng).let {
latitudeB = it.latitude
longitudeB = it.longitude
}
toGpsLatLon(polygonCLatLng).let {
latitudeC = it.latitude
longitudeC = it.longitude
}
toGpsLatLon(polygonDLatLng).let {
latitudeD = it.latitude
longitudeD = it.longitude
}
toGpsLatLon(polygonELatLng).let {
latitudeE = it.latitude
longitudeE = it.longitude
}
toGpsLatLon(polygonFLatLng).let {
latitudeF = it.latitude
longitudeF = it.longitude
}
}
//多边形,不需要计算距离
arrayOf("0")
@@ -394,10 +429,10 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
mFencesBean.apply {
mFencesCircleView.let {
it.visibility = View.VISIBLE
val pointCentre = mGoogleMap!!.projection.toScreenLocation(
val pointCentre = latLngToScreenLocation(
LatLng(latitudeCenter, longitudeCenter)
)
val pointLineEnd = mGoogleMap!!.projection.toScreenLocation(
val pointLineEnd = latLngToScreenLocation(
LatLng(ancillaryLatitude, ancillaryLongitude)
)
val radius = abs(pointLineEnd.x - pointCentre.x).toFloat()
@@ -437,13 +472,13 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
mFencesBean.apply {
mFencesRectView.let {
it.visibility = View.VISIBLE
val pointCentre = mGoogleMap!!.projection.toScreenLocation(
val pointCentre = latLngToScreenLocation(
LatLng(latitudeCenter, longitudeCenter)
)
val pointA = mGoogleMap!!.projection.toScreenLocation(LatLng(latitudeA, longitudeA))
val pointB = mGoogleMap!!.projection.toScreenLocation(LatLng(latitudeB, longitudeB))
val pointC = mGoogleMap!!.projection.toScreenLocation(LatLng(latitudeC, longitudeC))
val pointD = mGoogleMap!!.projection.toScreenLocation(LatLng(latitudeD, longitudeD))
val pointA = latLngToScreenLocation(LatLng(latitudeA, longitudeA))
val pointB = latLngToScreenLocation(LatLng(latitudeB, longitudeB))
val pointC = latLngToScreenLocation(LatLng(latitudeC, longitudeC))
val pointD = latLngToScreenLocation(LatLng(latitudeD, longitudeD))
it.setRectABCDXYPoint(pointCentre, pointA, pointB, pointC, pointD)
//矩形大小变了,其他形状的围栏也要改变大小
@@ -476,15 +511,15 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
mFencesBean.apply {
mFencesPolygonView.let {
it.visibility = View.VISIBLE
val pointCentre = mGoogleMap!!.projection.toScreenLocation(
val pointCentre = latLngToScreenLocation(
LatLng(latitudeCenter, longitudeCenter)
)
val pointA = mGoogleMap!!.projection.toScreenLocation(LatLng(latitudeA, longitudeA))
val pointB = mGoogleMap!!.projection.toScreenLocation(LatLng(latitudeB, longitudeB))
val pointC = mGoogleMap!!.projection.toScreenLocation(LatLng(latitudeC, longitudeC))
val pointD = mGoogleMap!!.projection.toScreenLocation(LatLng(latitudeD, longitudeD))
val pointE = mGoogleMap!!.projection.toScreenLocation(LatLng(latitudeE, longitudeE))
val pointF = mGoogleMap!!.projection.toScreenLocation(LatLng(latitudeF, longitudeF))
val pointA = latLngToScreenLocation(LatLng(latitudeA, longitudeA))
val pointB = latLngToScreenLocation(LatLng(latitudeB, longitudeB))
val pointC = latLngToScreenLocation(LatLng(latitudeC, longitudeC))
val pointD = latLngToScreenLocation(LatLng(latitudeD, longitudeD))
val pointE = latLngToScreenLocation(LatLng(latitudeE, longitudeE))
val pointF = latLngToScreenLocation(LatLng(latitudeF, longitudeF))
it.setPolygonABCDEFPoint(
pointCentre, pointA, pointB, pointC, pointD, pointE, pointF
)

View File

@@ -263,7 +263,8 @@ class HistoryDataGoogleMapFragment : BaseGoogleMapFragment() {
// )
for (i in 0 until mLatLngList.size) {
val numberMarker = MarkerOptions().position(mLatLngList[i]).icon(
val newLatLng = toGCJ02LatLon(mLatLngList[i])
val numberMarker = MarkerOptions().position(newLatLng).icon(
BitmapDescriptorFactory.fromBitmap(
GoogleBitmapHelper.imageUpNumberBitmap(
mContext!!,
@@ -290,7 +291,8 @@ class HistoryDataGoogleMapFragment : BaseGoogleMapFragment() {
fun setPetMarkerLatLng(latLng: LatLng) {
if (::mPetIconDescriptor.isInitialized) {
mGoogleMap?.apply {
mMarkerOptions.position(latLng).icon(mPetIconDescriptor)
val newLatLng = toGCJ02LatLon(latLng)
mMarkerOptions.position(newLatLng).icon(mPetIconDescriptor)
mMarker?.remove()
mMarker = addMarker(mMarkerOptions)
//显示最上面,层级最高

View File

@@ -1,5 +1,6 @@
package com.abbidot.tracker.util
import android.graphics.PointF
import kotlin.math.abs
import kotlin.math.cos
import kotlin.math.sin
@@ -22,6 +23,94 @@ class LonAndLatUtil {
private const val a = 6378245.0
private const val ee = 0.00669342162296594323
/**
* 判断是不是在中国
* 用引射线法判断 点是否在多边形内部
* 算法参考http://www.cnblogs.com/luxiaoxun/p/3722358.html
*/
private val polygonOfChina: MutableList<PointF> by lazy {
mutableListOf(
PointF(49.150669f, 87.415081f),
PointF(48.366450179f, 85.75270853f),
PointF(47.0253058185f, 85.3847443554f),
PointF(45.240655f, 82.5214f),
PointF(44.8957121295f, 79.9392351487f),
PointF(43.1166843846f, 80.6751253982f),
PointF(41.870169f, 79.688216f),
PointF(39.289619f, 73.617108f),
PointF(34.230343f, 78.91553f),
PointF(31.023886f, 79.062708f),
PointF(27.99898f, 88.702892f),
PointF(27.179359f, 88.997248f),
PointF(28.096917f, 89.73314f),
PointF(26.91578f, 92.161583f),
PointF(28.194764f, 96.098605f),
PointF(27.409476f, 98.674227f),
PointF(23.90855f, 97.570389f),
PointF(24.077583f, 98.78461f),
PointF(22.137564f, 99.189351f),
PointF(21.139895f, 101.764972f),
PointF(22.274622f, 101.728178f),
PointF(23.264194f, 105.370843f),
PointF(22.71912f, 106.695448f),
PointF(21.9945711661f, 106.7256731791f),
PointF(21.484705f, 108.020053f),
PointF(20.447844f, 109.381453f),
PointF(18.668985f, 108.240821f),
PointF(17.401734f, 109.933372f),
PointF(19.508567f, 111.405156f),
PointF(21.2716775175f, 111.2514995205f),
PointF(21.9936323233f, 113.4625292629f),
PointF(22.1818312942f, 113.4258358111f),
PointF(22.2249729295f, 113.5913115f),
PointF(22.4501912753f, 113.894684449f),
PointF(22.5959159322f, 114.3623797842f),
PointF(22.433461f, 114.519474f),
PointF(22.9680954377f, 116.8326939975f),
PointF(25.378822f, 119.966798f),
PointF(28.3261276204f, 121.7724402562f),
PointF(31.988361f, 123.880823f),
PointF(39.87597f, 124.469537f),
PointF(41.735089f, 126.953172f),
PointF(41.514216f, 128.314572f),
PointF(42.984208179f, 131.0676468344f),
PointF(45.269081f, 131.846853f),
PointF(45.060837f, 133.061074f),
PointF(48.448026f, 135.011188f),
PointF(48.00548f, 131.66288f),
PointF(50.227074f, 127.689064f),
PointF(53.351607f, 125.371004f),
PointF(53.417604f, 119.925404f),
PointF(47.559081f, 115.142107f),
PointF(47.133937f, 119.115923f),
PointF(44.825646f, 111.278675f),
PointF(42.529356f, 109.254972f),
PointF(43.259816f, 97.296729f),
PointF(45.424762f, 90.968059f),
PointF(47.807557f, 90.673702f),
PointF(49.150669f, 87.415081f)
)
}
fun isLocationOutOfChina(latitude: Double, longitude: Double): Boolean {
val point = PointF(latitude.toFloat(), longitude.toFloat())
var oddFlag = false
var j = polygonOfChina.size - 1
for (i in polygonOfChina.indices) {
val polygonPointi = polygonOfChina[i]
val polygonPointj = polygonOfChina[j]
if ((polygonPointi.y < point.y && polygonPointj.y >= point.y) || (polygonPointj.y < point.y && polygonPointi.y >= point.y)) {
if (polygonPointi.x <= point.x || polygonPointj.x <= point.x) {
oddFlag =
oddFlag xor ((polygonPointi.x + (point.y - polygonPointi.y) / (polygonPointj.y - polygonPointi.y) * (polygonPointj.x - polygonPointi.x)) < point.x)
}
}
j = i
}
return !oddFlag
}
/**
* GPS坐标(WGS84)转火星GCJ02坐标
* @return

View File

@@ -17,45 +17,6 @@ import com.google.android.gms.maps.model.LatLng
* @description:
*/
class FencesMapViewModel : ViewModel() {
/**
* 获取围栏间最大距离
*/
// fun getFencesDistance(fencesBean: FencesBean): Double {
// var distance = 0.0
// fencesBean.apply {
// when (fenceShapeType) {
// ConstantInt.CircleShapeType -> distance = radius
// ConstantInt.RectangleShapeType -> distance = minOf(shortDistance, longDistance)
// ConstantInt.PolygonShapeType -> {
// val distanceA = Util.measureLatLonDistance(
// latitudeCenter, longitudeCenter, latitudeA, longitudeA
// )
// val distanceB = Util.measureLatLonDistance(
// latitudeCenter, longitudeCenter, latitudeB, longitudeB
// )
// val distanceC = Util.measureLatLonDistance(
// latitudeCenter, longitudeCenter, latitudeC, longitudeC
// )
// val distanceD = Util.measureLatLonDistance(
// latitudeCenter, longitudeCenter, latitudeD, longitudeD
// )
// val distanceE = Util.measureLatLonDistance(
// latitudeCenter, longitudeCenter, latitudeE, longitudeE
// )
// val distanceF = Util.measureLatLonDistance(
// latitudeCenter, longitudeCenter, latitudeF, longitudeF
// )
// distance =
// minOf(distanceA, distanceB, distanceC, distanceD, distanceE, distanceF)
// }
// }
// }
//
// if (distance == 0.0) distance = 150.0
// return distance
// }
/**
* 设置地图围栏数据
*/

View File

@@ -3,8 +3,10 @@ package com.abbidot.tracker.vm
import android.text.TextUtils
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
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.tracker.util.LonAndLatUtil
import com.baidu.mapapi.model.LatLng
import com.baidu.mapapi.search.geocode.GeoCodeResult
@@ -71,8 +73,12 @@ class GeoCoderViewModel : ViewModel() {
if (AppUtils.isChina(AppUtils.SWITCH_MAP_TYPE)) {
baiduMapReverseGeocoder(latitude, longitude)
} else {
// baiduMapReverseGeocoder(latitude, longitude)
mapBoxReverseGeocoder(latitude, longitude)
if (MMKVUtil.getBoolean(MMKVKey.isGpsToGCJ02)) {
val convertLatLon = LonAndLatUtil.convertFromWGS84ToGCJ02(latitude, longitude)
mapBoxReverseGeocoder(convertLatLon[0], convertLatLon[1])
} else {
mapBoxReverseGeocoder(latitude, longitude)
}
}
}

View File

@@ -44,4 +44,18 @@
android:paddingBottom="@dimen/dp_16"
android:scrollbarThumbVertical="@drawable/shape50_yellow_color_bg"
android:scrollbars="vertical" />
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lav_add_wifi_zone3_anim"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_50"
app:lottie_loop="true" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>

View File

@@ -14,16 +14,25 @@
<com.qmuiteam.qmui.widget.grouplist.QMUICommonListItemView
android:id="@+id/switch_base_url"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_50"
android:layout_marginBottom="@dimen/dp_6"
android:layout_height="@dimen/dp_38"
android:layout_marginBottom="@dimen/dp_2"
android:background="@drawable/selector_shape6_gray_bg_pressed"
app:qmui_accessory_type="switcher" />
<com.qmuiteam.qmui.widget.grouplist.QMUICommonListItemView
android:id="@+id/switch_only_google_map"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_50"
android:layout_marginBottom="@dimen/dp_16"
android:layout_height="@dimen/dp_38"
android:layout_marginBottom="@dimen/dp_2"
android:background="@drawable/selector_shape6_gray_bg_pressed"
app:qmui_accessory_type="switcher" />
<com.qmuiteam.qmui.widget.grouplist.QMUICommonListItemView
android:id="@+id/switch_google_lat_lon_conversion"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_38"
android:visibility="gone"
android:layout_marginBottom="@dimen/dp_6"
android:background="@drawable/selector_shape6_gray_bg_pressed"
app:qmui_accessory_type="switcher" />
@@ -31,14 +40,14 @@
android:id="@+id/ll_debug_pet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dp_8"
android:layout_marginBottom="@dimen/dp_6"
android:gravity="center">
<include
android:id="@+id/debug_pet_head"
layout="@layout/layout_head_image_view"
android:layout_width="@dimen/dp_50"
android:layout_height="@dimen/dp_50" />
android:layout_width="@dimen/dp_30"
android:layout_height="@dimen/dp_30" />
<com.abbidot.tracker.widget.TypefaceTextView
android:id="@+id/debug_pet_name"
@@ -46,6 +55,7 @@
android:layout_width="wrap_content"
android:layout_marginStart="@dimen/dp_6"
android:drawableEnd="@drawable/ico_sw_dowm_br"
android:textSize="@dimen/textSize14"
app:typeface="@string/roboto_regular_font" />
</androidx.appcompat.widget.LinearLayoutCompat>

View File

@@ -372,4 +372,7 @@
<color name="grey_color_64">#64000000</color>
<color name="grey_color_90">#F9FFE3</color>
<color name="grey_color">#A6A6A6</color>
<color name="blue_color">#26A8FF</color>
<color name="line_stroke_color">#077B4A</color>
<color name="rote_line_color">#00C478</color>
</resources>

View File

@@ -34,6 +34,7 @@ import androidx.annotation.StringDef
MMKVKey.MealType,
MMKVKey.isExistNewInvite,
MMKVKey.OnlyGoogleMap,
MMKVKey.isGpsToGCJ02,
MMKVKey.MapType,
MMKVKey.ShowFence,
MMKVKey.isCrash,
@@ -81,6 +82,8 @@ annotation class MMKVKey {
//只使用谷歌地图
const val OnlyGoogleMap = "onlyGoogleMap"
//是否gps坐标转换火星坐标
const val isGpsToGCJ02 = "gpsToGCJ02"
const val MapShowDefaultLat = "mapDefaultLat"
const val MapShowDefaultLon = "mapDefaultLon"
@@ -95,12 +98,14 @@ annotation class MMKVKey {
//套餐类型
const val MealType = "mealType"
//套餐是否可用
const val AvailableOrder = "availableOrder"
//是否分享的
const val Shared = "shared"
const val isCrash = "isCrash"
//首次检查蓝牙是否开关
const val isFirstCheckBleOpen = "isFirstCheckBleOpen"
}