[6.0.0][Opt]更新轨迹擦除算法

This commit is contained in:
chenfufeng
2023-08-14 19:51:01 +08:00
committed by zhongchao
parent be3f3cc90a
commit 45e2961646
5 changed files with 192 additions and 45 deletions

View File

@@ -5,7 +5,9 @@ import android.util.Log
import com.amap.api.maps.CoordinateConverter
import com.amap.api.maps.model.LatLng
import com.mogo.eagle.core.utilcode.util.CoordinateUtils
import com.mogo.eagle.core.utilcode.util.DrivingDirectionUtils
import com.mogo.eagle.core.utilcode.util.DrivingDirectionUtils.getAngleDiff
import com.mogo.eagle.core.utilcode.util.DrivingDirectionUtils.getLineAngle
import com.mogo.eagle.core.utilcode.util.LocationUtils
import io.reactivex.Observable
import io.reactivex.ObservableOnSubscribe
import io.reactivex.android.schedulers.AndroidSchedulers
@@ -132,54 +134,94 @@ object MarkerDrawerManager {
var currentIndex = 0 //记录疑似点
// 是否超过200KM
var isLongDistance = false
if (routePoints.isNotEmpty()) {
//基础点
val baseLatLng = routePoints[0]
newPoints.add(LatLng(baseLatLng.latitude, baseLatLng.longitude))
var baseDiffDis = CoordinateUtils.calculateLineDistance(
realLon, realLat, baseLatLng.longitude, baseLatLng.latitude
) // lon,lat, prelon, prelat
if (baseDiffDis > 200000) {
isLongDistance = true
}
val size = routePoints.size
for (i in 1 until size) {
val latLng = routePoints[i]
// 深拷贝数据用于高德地图上轨迹线的绘制
newPoints.add(LatLng(latLng.latitude, latLng.longitude))
if (isLongDistance) continue
val diff = CoordinateUtils.calculateLineDistance(
realLon, realLat, latLng.longitude, latLng.latitude
)
if (baseDiffDis > diff) {
baseDiffDis = diff
// 距离最近的时候判断是否走过
if (DrivingDirectionUtils.getDegreeOfCar2Poi2(
realLon,
realLat,
var distance = 0.0
var tmpDistance: Double
var angle = 0.0
routePoints.forEachIndexed { index, latLng ->
newPoints.add(LatLng(latLng.latitude, latLng.longitude))
when (index) {
0 -> {
distance = LocationUtils.pointToLine(
latLng.longitude,
latLng.latitude,
routePoints[index + 1].longitude,
routePoints[index + 1].latitude,
realLon,
realLat
)
if (distance > 200000) {
isLongDistance = true
}
}
routePoints.size - 1 -> {}
else -> {
// 车到两轨迹点距离最短(距离这条路最近)
tmpDistance = LocationUtils.pointToLine(
latLng.longitude,
latLng.latitude,
routePoints[index + 1].longitude,
routePoints[index + 1].latitude,
realLon,
realLat
)
if (tmpDistance <= distance) {
// 车此刻运动方向与两轨迹点朝向的夹角小于90(结合距离线段最近则车在两点之间意味着已走过第index个轨迹点)
angle = getLineAngle(
latLng.longitude,
latLng.latitude,
heading
) >= 90
) {
currentIndex = i
routePoints[index + 1].longitude,
routePoints[index + 1].latitude
)
if (getAngleDiff(angle, heading) < 90) {
if (index < currentIndex) {
return@forEachIndexed
} else {
distance = tmpDistance
currentIndex = index
}
}
}
}
}
Log.d("MarkerDrawerManager", "当次计算已走过的点的索引为:$currentIndex,存储的上次索引为:$lastArrivedIndex, ,起点为:(${newPoints[0].longitude},${newPoints[0].latitude}),终点为:(${newPoints.last().longitude},${newPoints.last().latitude})")
if (!isLongDistance) {
// 过滤缓存的非当次轨迹的索引,并且出现车已走过索引跳跃过大时视为无效复用上一次计算结果
if (currentIndex < lastArrivedIndex || (lastArrivedIndex >= 0 && currentIndex - lastArrivedIndex >= 10)) {
if (lastArrivedIndex < size) {
currentIndex = lastArrivedIndex
}
} else {
lastArrivedIndex = currentIndex
}
if (size >= 2) {
newPoints.add(currentIndex + 1, LatLng(realLat, realLon))
return currentIndex + 1
}
}
Log.d(
"MarkerDrawerManager", "起点为:(${newPoints[0].longitude},${newPoints[0].latitude}),终点为:(${newPoints.last().longitude},${newPoints.last().latitude})"
)
if (!isLongDistance && currentIndex > 0) {
val size = routePoints.size
// // 对于非法结果,需要纠正
// if (currentIndex < lastArrivedIndex || (lastArrivedIndex > 0 && currentIndex - lastArrivedIndex > 5)) {
// val lastNextIndex = lastArrivedIndex + 1
// var isLastNextArrived = false
// if (lastNextIndex in 0 until size) {
// if (DrivingDirectionUtils.getDegreeOfCar2Poi2(
// realLon,
// realLat,
// routePoints[lastNextIndex].longitude,
// routePoints[lastNextIndex].latitude,
// heading
// ) >= 90
// ) {
// isLastNextArrived = true
// }
// }
//
// if (isLastNextArrived) {
// currentIndex = lastNextIndex
// lastArrivedIndex = currentIndex
// } else {
// if (lastArrivedIndex in 0 until size) {
// currentIndex = lastArrivedIndex
// }
// }
// } else {
// lastArrivedIndex = currentIndex
// }
if (size >= 2) {
Log.d("MarkerDrawerManager", "最终绘制的已走过index为:$currentIndex,车所在位置为:${currentIndex + 1}")
newPoints.add(currentIndex + 1, LatLng(realLat, realLon))
return currentIndex + 1
}
}
return 0

View File

@@ -88,6 +88,7 @@ class OverMapView @JvmOverloads constructor(
private var mContext: Context? = null
private var mTilt = 0f
private var overLayerView: TextView? = null
@Volatile
private var isMapLoaded = false
@@ -112,10 +113,18 @@ class OverMapView @JvmOverloads constructor(
var arrivedBitmap: BitmapDescriptor? = null
var unArrivedBitmap: BitmapDescriptor? = null
var transparentBitmap: BitmapDescriptor? = null
private val pointBitmap by lazy {
BitmapDescriptorFactory.fromResource(R.drawable.loc_azure_bg)
}
private val markerOptionsList by lazy {
ArrayList<MarkerOptions>()
}
private var isDebug = true
// 绘制轨迹线的集合
private val textureList: MutableList<BitmapDescriptor?> = ArrayList()
private val texIndexList: MutableList<Int> = ArrayList()
@Volatile
private var mLocation: MogoLocation? = null
private var isFirstLocation = true
@@ -123,6 +132,7 @@ class OverMapView @JvmOverloads constructor(
var currMarkerList: ArrayList<Marker>? = null
var siteMarkerList: ArrayList<Marker>? = null
var siteNameList: ArrayList<Marker>? = null
private var pointMarkers: ArrayList<Marker>? = null
@Volatile
private var isFirst = true
@@ -148,6 +158,7 @@ class OverMapView @JvmOverloads constructor(
private const val DRAW_POLY_LINE = 1
private const val DRAW_CAR_LOCATION = 2
private const val CLEAR_POLY_LINE = 3
private const val CLEAR_POINT_MARKERS = 4
private const val DRAW_V2X_MARKERS = 1
private const val DISPLAY_OVER_VIEW = 2
@@ -235,6 +246,16 @@ class OverMapView @JvmOverloads constructor(
overLayerView?.visibility = View.GONE
}
fun setDebugMode(isDebug: Boolean) {
this.isDebug = isDebug
if (!isDebug) {
Message.obtain().apply {
what = CLEAR_POINT_MARKERS
frequentHandler?.sendMessage(this)
}
}
}
/**
* siteLatLngs: 高德坐标集合
* bitmap: Marker对应的图片
@@ -362,6 +383,10 @@ class OverMapView @JvmOverloads constructor(
what = CLEAR_POLY_LINE
frequentHandler?.sendMessage(this)
}
Message.obtain().apply {
what = CLEAR_POINT_MARKERS
frequentHandler?.sendMessage(this)
}
mStartMarker?.isVisible = false
mEndMarker?.isVisible = false
@@ -778,6 +803,7 @@ class OverMapView @JvmOverloads constructor(
* @param locIndex
*/
private fun realDrawPolyline(coordinates: List<LatLng>, locIndex: Int) {
val drawPointMarkers = isDebug && pointMarkers.isNullOrEmpty()
val time = System.currentTimeMillis()
if (textureList.size > 0) {
textureList.clear()
@@ -785,6 +811,7 @@ class OverMapView @JvmOverloads constructor(
if (texIndexList.size > 0) {
texIndexList.clear()
}
if (drawPointMarkers) markerOptionsList.clear()
if (isClearArrived) {
textureList.add(transparentBitmap)// index:0
} else {
@@ -793,7 +820,15 @@ class OverMapView @JvmOverloads constructor(
}
// 未走过的纹理
textureList.add(unArrivedBitmap)// index:1
for (i in coordinates.indices) {
if (drawPointMarkers) {
markerOptionsList.add(MarkerOptions().also {
it.icon(pointBitmap)
it.anchor(0.5f, 0.5f)
it.position(coordinates[i])
})
}
// 线段数比点数少一个
if (i == 0) continue
if (i <= locIndex) {
@@ -802,6 +837,9 @@ class OverMapView @JvmOverloads constructor(
texIndexList.add(1)
}
}
if (drawPointMarkers) {
pointMarkers = mAMap?.addMarkers(markerOptionsList, false)
}
if (mCoveredPolyline != null) {
mCoveredPolyline!!.options.customTextureList = textureList
mCoveredPolyline!!.options.customTextureIndex = texIndexList
@@ -863,7 +901,8 @@ class OverMapView @JvmOverloads constructor(
//设置希望展示的地图缩放级别
Log.d(TAG, "切换视角展示车,定位为:${mLocation!!.longitude},${mLocation!!.latitude}")
val cameraPosition = CameraPosition.Builder()
.target(LatLng(mLocation!!.latitude, mLocation!!.longitude)).tilt(mTilt).zoom(zoomLevel.toFloat()).build()
.target(LatLng(mLocation!!.latitude, mLocation!!.longitude)).tilt(mTilt)
.zoom(zoomLevel.toFloat()).build()
mAMap!!.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
}
}
@@ -1006,6 +1045,13 @@ class OverMapView @JvmOverloads constructor(
mCoveredPolyline?.points = emptyList()
}
private fun realClearPointMarkers() {
pointMarkers?.forEach {
it.destroy()
}
pointMarkers = null
}
private fun realClearSitePolyline() {
mSitePolyline?.points = emptyList()
}
@@ -1165,16 +1211,23 @@ class OverMapView @JvmOverloads constructor(
realDrawPolyline(first, second)
}
}
DRAW_CAR_LOCATION -> {
removeMessages(DRAW_CAR_LOCATION)
(msg.obj as MogoLocation).apply {
realDrawCarMarker(this)
}
}
CLEAR_POLY_LINE -> {
removeMessages(CLEAR_POLY_LINE)
realClearPolyline()
}
CLEAR_POINT_MARKERS -> {
removeMessages(CLEAR_POINT_MARKERS)
realClearPointMarkers()
}
}
}
}
@@ -1192,57 +1245,68 @@ class OverMapView @JvmOverloads constructor(
realDrawSitePolyline(first, second)
}
}
DRAW_V2X_MARKERS -> {
removeMessages(DRAW_V2X_MARKERS)
(msg.obj as ArrayList<MarkerOptions>).apply {
realDrawV2XMarkers(this)
}
}
DISPLAY_OVER_VIEW -> {
removeMessages(DISPLAY_OVER_VIEW)
realDisplayOverView()
}
INCLUDE_SITES_OVER_VIEW -> {
removeMessages(INCLUDE_SITES_OVER_VIEW)
(msg.obj as List<LatLng>).also {
realIncludeSitePointsAndRefresh(it)
}
}
DRAW_START_AND_END -> {
removeMessages(DRAW_START_AND_END)
(msg.obj as List<LatLng>).also {
realDrawStartAndEndMarker(it)
}
}
CLEAR_SITE_POLYLINE -> {
removeMessages(CLEAR_SITE_POLYLINE)
MarkerDrawerManager.isStopCalculate = false
realClearSitePolyline()
}
CLEAR_V2X_MARKERS -> {
removeMessages(CLEAR_V2X_MARKERS)
realClearV2XMarkers()
}
DRAW_SITE_NAME -> {
removeMessages(DRAW_SITE_NAME)
(msg.obj as ArrayList<MarkerOptions>).also {
realDrawSiteNames(it)
}
}
CLEAR_SITE_NAME -> {
removeMessages(CLEAR_SITE_NAME)
realClearSiteNameViews()
}
DRAW_SITE_MARKER -> {
(msg.obj as ArrayList<MarkerOptions>).also {
realDrawSiteMarkers(it)
}
removeMessages(DRAW_SITE_MARKER)
}
CLEAR_SITE_MARKER -> {
removeMessages(CLEAR_SITE_MARKER)
realClearSiteMarkers()
}
DRAW_INF_STRUCTURE -> {
removeMessages(DRAW_INF_STRUCTURE)
(msg.obj as ArrayList<MarkerOptions>).also {

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB