[6.0.0][Opt]更新轨迹擦除算法
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 |
Reference in New Issue
Block a user