[3.2.0][Opt]区分高低频数据,每次移除已堆积的同类或互斥的数据

This commit is contained in:
chenfufeng
2023-06-09 22:16:16 +08:00
parent ce7bdb1c0a
commit 0ca0d10efb
2 changed files with 498 additions and 288 deletions

View File

@@ -12,6 +12,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import mogo.telematics.pad.MessagePad
import java.util.Collections
import java.util.concurrent.TimeUnit
/**
@@ -23,11 +24,12 @@ object MarkerDrawerManager {
fun onLocationChanged(planningPoints: List<LatLng>, locIndex: Int)
}
@Volatile
private var routeWipeDisposable: CompositeDisposable? = null
// 自主画线的所有高德坐标系的轨迹点
val planningPoints by lazy {
ArrayList<LatLng>()
Collections.synchronizedList(ArrayList<LatLng>())
}
@Volatile
@@ -38,6 +40,9 @@ object MarkerDrawerManager {
var callback: Callback? = null
@Volatile
var isStopCalculate: Boolean = false
fun startLoopCalCarLocation() {
routeWipeDisposable = CompositeDisposable()
getLoopCalCarObservable().delay(800L, TimeUnit.MILLISECONDS, true)
@@ -77,7 +82,7 @@ object MarkerDrawerManager {
lat: Double,
heading: Double
) {
if (routePoints != null && routePoints.isNotEmpty()) {
if (!isStopCalculate && routePoints != null && routePoints.isNotEmpty()) {
val newPointList = ArrayList<LatLng>()
val locationIndex: Int =
getCarLocationIndex(routePoints, newPointList, lon, lat, heading)
@@ -91,16 +96,12 @@ object MarkerDrawerManager {
*/
fun updateGDRoutePoints(routePoints: List<LatLng>?) {
if (routePoints == null || routePoints.isEmpty()) return
synchronized(this) {
planningPoints.clear()
planningPoints.addAll(routePoints)
}
planningPoints.clear()
planningPoints.addAll(routePoints)
}
fun resetStatus() {
synchronized(this) {
planningPoints.clear()
}
planningPoints.clear()
lastArrivedIndex = -1
}
@@ -121,7 +122,6 @@ object MarkerDrawerManager {
* @param realLat
* @return 返回已经到达点的index
*/
@Synchronized
private fun getCarLocationIndex(
routePoints: List<LatLng>,
newPoints: MutableList<LatLng>,
@@ -166,7 +166,10 @@ object MarkerDrawerManager {
}
}
}
Log.d("MarkerDrawerManager", "当次计算已走过的点的索引为:$currentIndex,存储的上次索引为:$lastArrivedIndex, ,起点为:(${newPoints[0].longitude},${newPoints[0].latitude}),终点为:(${newPoints.last().longitude},${newPoints.last().latitude})")
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)) {

View File

@@ -5,6 +5,10 @@ import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.os.Bundle
import android.os.Handler
import android.os.HandlerThread
import android.os.Looper
import android.os.Message
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
@@ -12,7 +16,6 @@ import android.view.MotionEvent
import android.view.View
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.annotation.MainThread
import androidx.core.graphics.drawable.toBitmap
import ch.hsr.geohash.GeoHash
import com.amap.api.maps.*
@@ -46,7 +49,6 @@ import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import me.jessyan.autosize.utils.AutoSizeUtils
import mogo.telematics.pad.MessagePad
import mogo.v2x.MogoV2X
import java.util.concurrent.Executors
import kotlin.math.pow
/**
@@ -118,24 +120,43 @@ class OverMapView @JvmOverloads constructor(
var siteMarkerList: ArrayList<Marker>? = null
var siteNameList: ArrayList<Marker>? = null
@Volatile
private var isInit = false
@Volatile
private var isFirst = true
@Volatile
private var lastTime = 0L
// 用来绘制轨迹线
private val singlePool by lazy {
Executors.newSingleThreadExecutor()
}
/**
* 高频的
*/
private var frequentHandler: FrequentHandler? = null
/**
* 低频的
*/
private var nonFrequentHandler: NonFrequentHandler? = null
@Volatile
private var allPoints: List<LatLng>? = null
companion object {
const val TAG = "OverMapView"
private const val TAG = "OverMapView"
private const val DRAW_POLY_LINE = 1
private const val DRAW_CAR_LOCATION = 2
private const val CLEAR_POLY_LINE = 3
private const val DRAW_V2X_MARKERS = 1
private const val DISPLAY_OVER_VIEW = 2
private const val INCLUDE_SITES_OVER_VIEW = 3
private const val DRAW_SITE_LINE = 4
private const val DRAW_START_AND_END = 5
private const val CLEAR_SITE_POLYLINE = 6
private const val CLEAR_V2X_MARKERS = 7
private const val DRAW_SITE_NAME = 8
private const val CLEAR_SITE_NAME = 9
private const val DRAW_SITE_MARKER = 10
private const val CLEAR_SITE_MARKER = 11
private const val DRAW_INF_STRUCTURE = 12
}
init {
@@ -233,8 +254,10 @@ class OverMapView @JvmOverloads constructor(
)
markerOptionsList.add(markerOption)
}
singlePool.execute {
siteMarkerList = mAMap!!.addMarkers(markerOptionsList, false)
Message.obtain().apply {
what = DRAW_SITE_MARKER
obj = markerOptionsList
nonFrequentHandler?.sendMessage(this)
}
}
@@ -253,19 +276,17 @@ class OverMapView @JvmOverloads constructor(
)
markerOptionsList.add(markerOption)
}
singlePool.execute {
siteMarkerList = mAMap!!.addMarkers(markerOptionsList, false)
Message.obtain().apply {
what = DRAW_SITE_MARKER
obj = markerOptionsList
nonFrequentHandler?.sendMessage(this)
}
}
fun clearSiteMarkers() {
singlePool.execute {
if (siteMarkerList != null) {
for (marker in siteMarkerList!!) {
marker.destroy()
}
siteMarkerList = null
}
Message.obtain().apply {
what = CLEAR_SITE_MARKER
nonFrequentHandler?.sendMessage(this)
}
}
@@ -285,8 +306,10 @@ class OverMapView @JvmOverloads constructor(
)
markerOptionsList.add(markerOption)
}
singlePool.execute {
siteNameList = mAMap!!.addMarkers(markerOptionsList, false)
Message.obtain().apply {
what = DRAW_SITE_NAME
obj = markerOptionsList
nonFrequentHandler?.sendMessage(this)
}
}
@@ -294,12 +317,10 @@ class OverMapView @JvmOverloads constructor(
* 更新站点信息Bitmap展示
*/
fun updateSiteNameView(index: Int, bitmap: Bitmap) {
singlePool.execute {
if (siteNameList != null && index in 0 until siteNameList!!.size) {
val siteNameMarker = siteNameList!![index]
siteNameMarker.options.icon(BitmapDescriptorFactory.fromBitmap(bitmap))
siteNameMarker.position = siteNameMarker.position
}
if (siteNameList != null && index in 0 until siteNameList!!.size) {
val siteNameMarker = siteNameList!![index]
siteNameMarker.options.icon(BitmapDescriptorFactory.fromBitmap(bitmap))
siteNameMarker.position = siteNameMarker.position
}
}
@@ -323,13 +344,9 @@ class OverMapView @JvmOverloads constructor(
* 清除站点名
*/
fun clearSiteNameViews() {
singlePool.execute {
if (siteNameList != null) {
for (marker in siteNameList!!) {
marker.destroy()
}
siteNameList = null
}
Message.obtain().apply {
what = CLEAR_SITE_NAME
nonFrequentHandler?.sendMessage(this)
}
}
@@ -337,22 +354,17 @@ class OverMapView @JvmOverloads constructor(
* 清空线路并隐藏起、终点
*/
fun clearCustomPolyline() {
singlePool.execute {
if (mBottomPolyline != null) {
mBottomPolyline!!.remove()
}
if (mCoveredPolyline != null) {
mCoveredPolyline!!.remove()
}
mStartMarker?.isVisible = false
mEndMarker?.isVisible = false
Message.obtain().apply {
what = CLEAR_POLY_LINE
frequentHandler?.sendMessage(this)
}
mStartMarker?.isVisible = false
mEndMarker?.isVisible = false
MarkerDrawerManager.stopLoopCalCarLocation()
ThreadUtils.getIoPool().execute {
MarkerDrawerManager.resetStatus()
}
isInit = false
}
@SuppressLint("UseCompatLoadingForDrawables")
@@ -388,7 +400,7 @@ class OverMapView @JvmOverloads constructor(
private fun initAMapView(context: Context) {
Log.d(TAG, "initAMapView")
mCameraUpdate = CameraUpdateFactory.zoomTo(zoomLevel.toFloat())
mAMap = mMapView!!.map
mAMap = mMapView?.map
mCustomMapStyleOptions = CustomMapStyleOptions()
if (!mapStylePath.isNullOrEmpty() && !mapStyleExtraPath.isNullOrEmpty()) {
@@ -429,6 +441,22 @@ class OverMapView @JvmOverloads constructor(
}
})
CallerV2XListenerManager.addListener(TAG, this)
initHandlers()
callback = object : MarkerDrawerManager.Callback {
override fun onLocationChanged(points: List<LatLng>, locIndex: Int) {
if (points.isNotEmpty()) {
// 每1s刷新一下轨迹线
if (isFirst) {
Log.d(TAG, "第一次!")
isFirst = false
allPoints = points
displayCustomOverView()
drawStartAndEndMarker(points)
}
drawPolyLine(points, locIndex)
}
}
}
}
private fun setUpMap() {
@@ -481,6 +509,16 @@ class OverMapView @JvmOverloads constructor(
}
}
private fun initHandlers() {
val frequentThread = HandlerThread("frequent_drawer")
frequentThread.start()
frequentHandler = FrequentHandler(frequentThread.looper)
val nonFrequentThread = HandlerThread("non_frequent_drawer")
nonFrequentThread.start()
nonFrequentHandler = NonFrequentHandler(nonFrequentThread.looper)
}
fun handlePlanningData(locationList: List<MessagePad.Location>?) {
if (locationList.isNullOrEmpty()) {
Log.d(TAG, "全局路径规划轨迹为空")
@@ -496,42 +534,32 @@ class OverMapView @JvmOverloads constructor(
// 转成高德定位对象并存储
val planningPointList = change2GDPoints(list, mContext!!)
updateGDRoutePoints(planningPointList)
synchronized(this::class.java) {
if (!isInit) {
var timeStamp = 0L
callback = object : MarkerDrawerManager.Callback {
override fun onLocationChanged(points: List<LatLng>, locIndex: Int) {
if (points.isNotEmpty()) {
// 每1s刷新一下轨迹线
singlePool.execute {
if (isFirst) {
Log.d(TAG, "第一次!")
isFirst = false
allPoints = points
displayCustomOverView()
drawStartAndEndMarker(points)
}
timeStamp = System.currentTimeMillis()
drawPolyline(points, locIndex)
Log.d(TAG, "绘制轨迹线的时间为:${System.currentTimeMillis() - timeStamp}ms")
}
}
}
}
startLoopCalCarLocation()
isInit = true
}
}
// 开始循环计算车已走过的轨迹点
startLoopCalCarLocation()
if (geoHashInfMap.isNullOrEmpty()) {
UiThreadHandler.postDelayed({
singlePool.execute {
drawInfrastructureMarkers(locationList)
}
drawInfrastructureMarkers(locationList)
}, 1000, UiThreadHandler.MODE.QUEUE)
} else {
singlePool.execute {
drawInfrastructureMarkers(locationList)
}
drawInfrastructureMarkers(locationList)
}
}
/**
* 绘制全局轨迹线
*/
fun drawPolyLine(coordinates: List<LatLng>, locIndex: Int) {
Message.obtain().apply {
what = DRAW_POLY_LINE
obj = Pair(coordinates, locIndex)
frequentHandler?.sendMessage(this)
}
}
fun clearV2XMarkers() {
Message.obtain().apply {
what = CLEAR_V2X_MARKERS
nonFrequentHandler?.sendMessage(this)
}
}
@@ -570,13 +598,11 @@ class OverMapView @JvmOverloads constructor(
}
}
if (markerOptionsList.size > 0) {
drawV2XMarkers(markerOptionsList)
}
}
fun drawV2XMarkers(markerOptionsList: ArrayList<MarkerOptions>?) {
singlePool.execute {
currMarkerList = mAMap!!.addMarkers(markerOptionsList, false)
Message.obtain().apply {
what = DRAW_V2X_MARKERS
obj = markerOptionsList
nonFrequentHandler?.sendMessage(this)
}
}
}
@@ -592,23 +618,16 @@ class OverMapView @JvmOverloads constructor(
return bitmap
}
fun clearV2XMarkers() {
singlePool.execute {
if (currMarkerList != null) {
for (marker in currMarkerList!!) {
marker.destroy()
}
currMarkerList = null
}
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
// 注册定位监听
CallerChassisLocationGCJ02ListenerManager.removeListener(TAG)
CallerPlanningRottingListenerManager.removeListener(TAG)
CallerV2XListenerManager.removeListener(TAG)
frequentHandler?.looper?.quitSafely()
nonFrequentHandler?.looper?.quitSafely()
frequentHandler = null
nonFrequentHandler = null
}
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
@@ -669,68 +688,20 @@ class OverMapView @JvmOverloads constructor(
posInfMap[latLng] = structureList
markerOptionsList.add(markerOption)
}
mAMap!!.addMarkers(markerOptionsList, false)
mAMap!!.setOnMarkerClickListener { marker: Marker ->
val infList: List<Infrastructure>? = posInfMap[marker.position]
// 如果是摄像头
if (infList != null) {
showVideoDialog(infList)
return@setOnMarkerClickListener true
}
false
Message.obtain().apply {
what = DRAW_INF_STRUCTURE
obj = markerOptionsList
nonFrequentHandler?.sendMessage(this)
}
}
private fun getBitmap(count: Int): Bitmap {
val marker = MakerWithCount(context)
marker.setCount(count)
marker.measure(
MeasureSpec.makeMeasureSpec(AutoSizeUtils.dp2px(mContext, 116f), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(AutoSizeUtils.dp2px(mContext, 116f), MeasureSpec.EXACTLY)
)
marker.layout(0, 0, marker.measuredWidth, marker.measuredHeight)
val bitmap = Bitmap.createBitmap(marker.width, marker.height, Bitmap.Config.ARGB_8888)
marker.draw(Canvas(bitmap))
return bitmap
}
/**
* 进入自定义全览模式
*/
fun displayCustomOverView() {
singlePool.execute {
val linePointsLatLng = allPoints
if (linePointsLatLng != null && linePointsLatLng.size > 1 && mLocation != null) {
//圈定地图显示范围
//存放经纬度
val boundsBuilder = LatLngBounds.Builder()
for (i in linePointsLatLng.indices) {
boundsBuilder.include(linePointsLatLng[i])
}
val currentLatLng = LatLng(mLocation!!.latitude, mLocation!!.longitude)
boundsBuilder.include(currentLatLng)
val cameraPosition = CameraPosition.Builder().tilt(mTilt).build()
//第二个参数为四周留空宽度
if (mAMap != null) {
mAMap!!.moveCamera(
CameraUpdateFactory.newLatLngBoundsRect(
boundsBuilder.build(),
AutoSizeUtils.dp2px(context, leftPadding.toFloat()),
AutoSizeUtils.dp2px(context, rightPadding.toFloat()),
AutoSizeUtils.dp2px(context, topPadding.toFloat()),
AutoSizeUtils.dp2px(context, bottomPadding.toFloat())
)
)
mAMap!!.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
}
} else {
if (mCarMarker != null && mAMap != null) {
//设置希望展示的地图缩放级别
val cameraPosition = CameraPosition.Builder()
.target(mCarMarker!!.position).tilt(mTilt).zoom(zoomLevel.toFloat()).build()
mAMap!!.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
}
}
Message.obtain().apply {
what = DISPLAY_OVER_VIEW
nonFrequentHandler?.sendMessage(this)
}
}
@@ -739,45 +710,74 @@ class OverMapView @JvmOverloads constructor(
*
* @param location
*/
private fun drawCarMarker(location: MogoLocation?) {
fun drawCarMarker(location: MogoLocation?) {
if (location == null) return
singlePool.execute {
if (mCarMarker != null) {
val currentLatLng = LatLng(location.latitude, location.longitude)
mCarMarker!!.rotateAngle = (360 - location.heading).toFloat()
mCarMarker!!.position = currentLatLng
mCarMarker!!.setToTop()
if (mCompassMarker != null) {
mCompassMarker!!.rotateAngle = (360 - location.heading).toFloat()
mCompassMarker!!.position = currentLatLng
}
}
Message.obtain().apply {
what = DRAW_CAR_LOCATION
obj = location
frequentHandler?.sendMessage(this)
}
}
/**
* 绘制起始点、终点
*/
private fun drawStartAndEndMarker(coordinates: List<LatLng>) {
mStartMarker?.isVisible = false
mEndMarker?.isVisible = false
if (coordinates.size > 2) {
// 设置开始结束Marker位置
val startLatLng = LatLng(coordinates[0].latitude, coordinates[0].longitude)
val endLatLng = LatLng(
coordinates[coordinates.size - 1].latitude,
coordinates[coordinates.size - 1].longitude
)
Log.d(
TAG,
"绘制起终点,起点为:(${startLatLng.longitude},${startLatLng.latitude}),终点为:(${endLatLng.longitude},${endLatLng.latitude})"
)
mStartMarker?.position = startLatLng
mEndMarker?.position = endLatLng
mStartMarker?.isVisible = true
mEndMarker?.isVisible = true
} else {
Log.d(TAG, "不绘制起终点")
fun drawStartAndEndMarker(coordinates: List<LatLng>) {
Message.obtain().apply {
what = DRAW_START_AND_END
obj = coordinates
nonFrequentHandler?.sendMessage(this)
}
}
/**
* 绘制站点轨迹线
*/
fun drawSitePolyline(coordinates: List<LatLng>?, bitmap: Bitmap) {
if (coordinates.isNullOrEmpty()) return
clearSitePolyline()
val textureList = arrayListOf<BitmapDescriptor>()
val texIndexList = arrayListOf<Int>()
for (i in coordinates.indices) {
// 线段数比点数少一个
if (i == 0) continue
textureList.add(BitmapDescriptorFactory.fromBitmap(bitmap))
texIndexList.add(i - 1)
}
if (mAMap != null) {
//设置线段纹理
val polylineOptions = PolylineOptions()
polylineOptions.addAll(coordinates)
polylineOptions.width(14f) //线段宽度
polylineOptions.lineCapType(PolylineOptions.LineCapType.LineCapRound)
polylineOptions.customTextureList = textureList
polylineOptions.customTextureIndex = texIndexList
// 绘制线
Message.obtain().apply {
what = DRAW_SITE_LINE
nonFrequentHandler?.sendMessage(this)
}
}
}
/**
* 清除已选站点的轨迹线
*/
fun clearSitePolyline() {
Message.obtain().apply {
what = CLEAR_SITE_POLYLINE
nonFrequentHandler?.sendMessage(this)
}
}
/**
* 站点轨迹集合被包含在地图显示范围内
*/
fun includeSitePointsAndUpdateCamera(coordinates: List<LatLng>?) {
Message.obtain().apply {
what = INCLUDE_SITES_OVER_VIEW
obj = coordinates
nonFrequentHandler?.sendMessage(this)
}
}
@@ -787,7 +787,8 @@ class OverMapView @JvmOverloads constructor(
* @param coordinates
* @param locIndex
*/
private fun drawPolyline(coordinates: List<LatLng>, locIndex: Int) {
private fun realDrawPolyline(coordinates: List<LatLng>, locIndex: Int) {
val time = System.currentTimeMillis()
if (textureList.size > 0) {
textureList.clear()
}
@@ -824,112 +825,216 @@ class OverMapView @JvmOverloads constructor(
polylineOptions.customTextureIndex = texIndexList
// 绘制线
mBottomPolyline = mCoveredPolyline
mCoveredPolyline = mAMap!!.addPolyline(polylineOptions)
mCoveredPolyline = mAMap?.addPolyline(polylineOptions)
if (mBottomPolyline != null) {
mBottomPolyline!!.remove()
mBottomPolyline = null
}
}
Log.d(TAG, "绘制全局轨迹线耗时为:${System.currentTimeMillis() - time}ms")
}
/**
* 绘制站点轨迹线
*/
fun drawSitePolyline(coordinates: List<LatLng>?, bitmap: Bitmap) {
if (coordinates.isNullOrEmpty()) return
singlePool.execute {
if (mSitePolyline != null) {
mSitePolyline!!.remove()
}
val textureList = arrayListOf<BitmapDescriptor>()
val texIndexList = arrayListOf<Int>()
for (i in coordinates.indices) {
// 线段数比点数少一个
if (i == 0) continue
textureList.add(BitmapDescriptorFactory.fromBitmap(bitmap))
texIndexList.add(i - 1)
}
if (mAMap != null) {
//设置线段纹理
val polylineOptions = PolylineOptions()
polylineOptions.addAll(coordinates)
polylineOptions.width(14f) //线段宽度
polylineOptions.lineCapType(PolylineOptions.LineCapType.LineCapRound)
polylineOptions.customTextureList = textureList
polylineOptions.customTextureIndex = texIndexList
// 绘制线
mSitePolyline = mAMap!!.addPolyline(polylineOptions)
}
}
private fun realDrawSiteNames(markerOptionsList: ArrayList<MarkerOptions>) {
siteNameList = mAMap?.addMarkers(markerOptionsList, false)
}
/**
* 清除已选站点的轨迹线
*/
fun clearSitePolyline() {
singlePool.execute {
if (mSitePolyline != null) {
mSitePolyline!!.remove()
}
}
}
/**
* 站点轨迹集合被包含在地图显示范围内
*/
fun includeSitePointsAndUpdateCamera(coordinates: List<LatLng>?) {
singlePool.execute {
val linePointsLatLng = allPoints
private fun realDisplayOverView() {
val linePointsLatLng = allPoints
if (linePointsLatLng != null && linePointsLatLng.size > 1 && mLocation != null) {
//圈定地图显示范围
//存放经纬度
val boundsBuilder = LatLngBounds.Builder()
var isOnlyCarLocation = true
if (linePointsLatLng != null && linePointsLatLng.size > 1) {
// 圈定地图显示范围(自动驾驶轨迹)
for (i in linePointsLatLng.indices) {
boundsBuilder.include(linePointsLatLng[i])
}
isOnlyCarLocation = false
for (i in linePointsLatLng.indices) {
boundsBuilder.include(linePointsLatLng[i])
}
if (mLocation != null) {
// 自车坐标
boundsBuilder.include(LatLng(mLocation!!.latitude, mLocation!!.longitude))
}
coordinates?.let {
// 站点轨迹被包含在地图显示范围内
for (i in it.indices) {
boundsBuilder.include(it[i])
}
isOnlyCarLocation = false
}
if (!isOnlyCarLocation) {
val cameraPosition = CameraPosition.Builder().tilt(mTilt).build()
//第二个参数为四周留空宽度
if (mAMap != null) {
mAMap!!.moveCamera(
CameraUpdateFactory.newLatLngBoundsRect(
boundsBuilder.build(),
AutoSizeUtils.dp2px(context, leftPadding.toFloat()),
AutoSizeUtils.dp2px(context, rightPadding.toFloat()),
AutoSizeUtils.dp2px(context, topPadding.toFloat()),
AutoSizeUtils.dp2px(context, bottomPadding.toFloat())
)
val currentLatLng = LatLng(mLocation!!.latitude, mLocation!!.longitude)
boundsBuilder.include(currentLatLng)
val cameraPosition = CameraPosition.Builder().tilt(mTilt).build()
//第二个参数为四周留空宽度
if (mAMap != null) {
mAMap!!.moveCamera(
CameraUpdateFactory.newLatLngBoundsRect(
boundsBuilder.build(),
AutoSizeUtils.dp2px(context, leftPadding.toFloat()),
AutoSizeUtils.dp2px(context, rightPadding.toFloat()),
AutoSizeUtils.dp2px(context, topPadding.toFloat()),
AutoSizeUtils.dp2px(context, bottomPadding.toFloat())
)
mAMap!!.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
}
} else {
)
mAMap!!.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
}
} else {
if (mCarMarker != null && mAMap != null) {
//设置希望展示的地图缩放级别
if (mCarMarker != null && mAMap != null) {
val cameraPosition = CameraPosition.Builder()
.target(mCarMarker!!.position).tilt(mTilt).zoom(zoomLevel.toFloat()).build()
mAMap!!.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
}
val cameraPosition = CameraPosition.Builder()
.target(mCarMarker!!.position).tilt(mTilt).zoom(zoomLevel.toFloat()).build()
mAMap!!.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
}
}
}
private fun realDrawCarMarker(location: MogoLocation?) {
if (location == null) return
if (mCarMarker != null) {
val currentLatLng = LatLng(location.latitude, location.longitude)
mCarMarker!!.rotateAngle = (360 - location.heading).toFloat()
mCarMarker!!.position = currentLatLng
mCarMarker!!.setToTop()
if (mCompassMarker != null) {
mCompassMarker!!.rotateAngle = (360 - location.heading).toFloat()
mCompassMarker!!.position = currentLatLng
}
}
}
fun realDrawStartAndEndMarker(coordinates: List<LatLng>) {
mStartMarker?.isVisible = false
mEndMarker?.isVisible = false
if (coordinates.size > 2) {
// 设置开始结束Marker位置
val startLatLng = LatLng(coordinates[0].latitude, coordinates[0].longitude)
val endLatLng = LatLng(
coordinates[coordinates.size - 1].latitude,
coordinates[coordinates.size - 1].longitude
)
Log.d(
TAG,
"绘制起终点,起点为:(${startLatLng.longitude},${startLatLng.latitude}),终点为:(${endLatLng.longitude},${endLatLng.latitude})"
)
mStartMarker?.position = startLatLng
mEndMarker?.position = endLatLng
mStartMarker?.isVisible = true
mEndMarker?.isVisible = true
} else {
Log.d(TAG, "不绘制起终点")
}
}
fun realDrawV2XMarkers(markerOptionsList: ArrayList<MarkerOptions>?) {
currMarkerList = mAMap?.addMarkers(markerOptionsList, false)
}
fun realDrawInfStructures(markerOptionsList: ArrayList<MarkerOptions>) {
mAMap?.addMarkers(markerOptionsList, false)
mAMap?.setOnMarkerClickListener { marker: Marker ->
val infList: List<Infrastructure>? = posInfMap[marker.position]
// 如果是摄像头
if (infList != null) {
showVideoDialog(infList)
return@setOnMarkerClickListener true
}
false
}
}
private fun realIncludeSitePointsAndRefresh(coordinates: List<LatLng>?) {
val linePointsLatLng = allPoints
val boundsBuilder = LatLngBounds.Builder()
var isOnlyCarLocation = true
if (linePointsLatLng != null && linePointsLatLng.size > 1) {
// 圈定地图显示范围(自动驾驶轨迹)
for (i in linePointsLatLng.indices) {
boundsBuilder.include(linePointsLatLng[i])
}
isOnlyCarLocation = false
}
if (mLocation != null) {
// 自车坐标
boundsBuilder.include(LatLng(mLocation!!.latitude, mLocation!!.longitude))
}
coordinates?.let {
// 站点轨迹被包含在地图显示范围内
for (i in it.indices) {
boundsBuilder.include(it[i])
}
isOnlyCarLocation = false
}
if (!isOnlyCarLocation) {
val cameraPosition = CameraPosition.Builder().tilt(mTilt).build()
//第二个参数为四周留空宽度
if (mAMap != null) {
mAMap!!.moveCamera(
CameraUpdateFactory.newLatLngBoundsRect(
boundsBuilder.build(),
AutoSizeUtils.dp2px(context, leftPadding.toFloat()),
AutoSizeUtils.dp2px(context, rightPadding.toFloat()),
AutoSizeUtils.dp2px(context, topPadding.toFloat()),
AutoSizeUtils.dp2px(context, bottomPadding.toFloat())
)
)
mAMap!!.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
}
} else {
//设置希望展示的地图缩放级别
if (mCarMarker != null && mAMap != null) {
val cameraPosition = CameraPosition.Builder()
.target(mCarMarker!!.position).tilt(mTilt).zoom(zoomLevel.toFloat()).build()
mAMap!!.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
}
}
}
private fun realDrawSitePolyline(options: PolylineOptions) {
mSitePolyline = mAMap?.addPolyline(options)
}
private fun realClearPolyline() {
mBottomPolyline?.remove()
mCoveredPolyline?.remove()
}
private fun realClearSitePolyline() {
mSitePolyline?.remove()
}
fun realClearV2XMarkers() {
if (currMarkerList != null) {
for (marker in currMarkerList!!) {
marker.destroy()
}
currMarkerList = null
}
}
private fun realClearSiteNameViews() {
if (siteNameList != null) {
for (marker in siteNameList!!) {
marker.destroy()
}
siteNameList = null
}
}
private fun realDrawSiteMarkers(markerOptionsList: ArrayList<MarkerOptions>) {
siteMarkerList = mAMap?.addMarkers(markerOptionsList, false)
}
private fun realClearSiteMarkers() {
if (siteMarkerList != null) {
for (marker in siteMarkerList!!) {
marker.destroy()
}
siteMarkerList = null
}
}
private fun getBitmap(count: Int): Bitmap {
val marker = MakerWithCount(context)
marker.setCount(count)
marker.measure(
MeasureSpec.makeMeasureSpec(AutoSizeUtils.dp2px(mContext, 116f), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(AutoSizeUtils.dp2px(mContext, 116f), MeasureSpec.EXACTLY)
)
marker.layout(0, 0, marker.measuredWidth, marker.measuredHeight)
val bitmap = Bitmap.createBitmap(marker.width, marker.height, Bitmap.Config.ARGB_8888)
marker.draw(Canvas(bitmap))
return bitmap
}
override fun onChassisLocationGCJ02(gnssInfo: MogoLocation?) {
gnssInfo?.let {
// 在中国境内
@@ -958,6 +1063,7 @@ class OverMapView @JvmOverloads constructor(
} else {
lastTime = System.currentTimeMillis()
}
MarkerDrawerManager.stopLoopCalCarLocation()
globalPathResp?.let {
ThreadUtils.getIoPool().execute {
handlePlanningData(it.wayPointsList)
@@ -1025,8 +1131,109 @@ class OverMapView @JvmOverloads constructor(
)
}
}
UiThreadHandler.post({
showV2XEventMarkers(list)
}, UiThreadHandler.MODE.QUEUE)
showV2XEventMarkers(list)
}
private inner class FrequentHandler(looper: Looper) : Handler(looper) {
@Suppress("UNCHECKED_CAST")
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
when (msg.what) {
DRAW_POLY_LINE -> {
removeMessages(CLEAR_POLY_LINE)
removeMessages(DRAW_POLY_LINE)
(msg.obj as Pair<List<LatLng>, Int>).apply {
realDrawPolyline(first, second)
}
}
DRAW_CAR_LOCATION -> {
removeMessages(DRAW_CAR_LOCATION)
(msg.obj as MogoLocation).apply {
realDrawCarMarker(this)
}
}
CLEAR_POLY_LINE -> {
removeMessages(DRAW_POLY_LINE)
removeMessages(CLEAR_POLY_LINE)
realClearPolyline()
}
}
}
}
private inner class NonFrequentHandler(looper: Looper) : Handler(looper) {
@Suppress("UNCHECKED_CAST")
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
when (msg.what) {
DRAW_SITE_LINE -> {
removeMessages(CLEAR_SITE_POLYLINE)
removeMessages(DRAW_SITE_LINE)
// 绘制站点轨迹线时停止绘制全局轨迹,降低性能损耗
MarkerDrawerManager.isStopCalculate = true
(msg.obj as PolylineOptions).apply {
realDrawSitePolyline(this)
}
}
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(DRAW_SITE_LINE)
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 {
realDrawInfStructures(it)
}
}
}
}
}
}