[3.2.0][Opt]区分高低频数据,每次移除已堆积的同类或互斥的数据
This commit is contained in:
@@ -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)) {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user