diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/MarkerDrawerManager.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/MarkerDrawerManager.kt index 9cdb5411da..00cf6f6f66 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/MarkerDrawerManager.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/MarkerDrawerManager.kt @@ -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, locIndex: Int) } + @Volatile private var routeWipeDisposable: CompositeDisposable? = null // 自主画线的所有高德坐标系的轨迹点 val planningPoints by lazy { - ArrayList() + Collections.synchronizedList(ArrayList()) } @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() val locationIndex: Int = getCarLocationIndex(routePoints, newPointList, lon, lat, heading) @@ -91,16 +96,12 @@ object MarkerDrawerManager { */ fun updateGDRoutePoints(routePoints: List?) { 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, newPoints: MutableList, @@ -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)) { diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/OverMapView.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/OverMapView.kt index 3066feb460..340025c842 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/OverMapView.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/OverMapView.kt @@ -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? = null var siteNameList: ArrayList? = 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? = 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, 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?) { 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, 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, 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?) { - 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? = 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) { - 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) { + Message.obtain().apply { + what = DRAW_START_AND_END + obj = coordinates + nonFrequentHandler?.sendMessage(this) + } + } + + /** + * 绘制站点轨迹线 + */ + fun drawSitePolyline(coordinates: List?, bitmap: Bitmap) { + if (coordinates.isNullOrEmpty()) return + clearSitePolyline() + val textureList = arrayListOf() + val texIndexList = arrayListOf() + 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?) { + 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, locIndex: Int) { + private fun realDrawPolyline(coordinates: List, 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?, bitmap: Bitmap) { - if (coordinates.isNullOrEmpty()) return - singlePool.execute { - if (mSitePolyline != null) { - mSitePolyline!!.remove() - } - val textureList = arrayListOf() - val texIndexList = arrayListOf() - 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) { + siteNameList = mAMap?.addMarkers(markerOptionsList, false) } - /** - * 清除已选站点的轨迹线 - */ - fun clearSitePolyline() { - singlePool.execute { - if (mSitePolyline != null) { - mSitePolyline!!.remove() - } - } - } - - /** - * 站点轨迹集合被包含在地图显示范围内 - */ - fun includeSitePointsAndUpdateCamera(coordinates: List?) { - 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) { + 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?) { + currMarkerList = mAMap?.addMarkers(markerOptionsList, false) + } + + fun realDrawInfStructures(markerOptionsList: ArrayList) { + mAMap?.addMarkers(markerOptionsList, false) + mAMap?.setOnMarkerClickListener { marker: Marker -> + val infList: List? = posInfMap[marker.position] + // 如果是摄像头 + if (infList != null) { + showVideoDialog(infList) + return@setOnMarkerClickListener true + } + false + } + } + + private fun realIncludeSitePointsAndRefresh(coordinates: List?) { + 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) { + 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, 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).apply { + realDrawV2XMarkers(this) + } + } + DISPLAY_OVER_VIEW -> { + removeMessages(DISPLAY_OVER_VIEW) + realDisplayOverView() + } + INCLUDE_SITES_OVER_VIEW -> { + removeMessages(INCLUDE_SITES_OVER_VIEW) + (msg.obj as List).also { + realIncludeSitePointsAndRefresh(it) + } + } + DRAW_START_AND_END -> { + removeMessages(DRAW_START_AND_END) + (msg.obj as List).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).also { + realDrawSiteNames(it) + } + } + CLEAR_SITE_NAME -> { + removeMessages(CLEAR_SITE_NAME) + realClearSiteNameViews() + } + DRAW_SITE_MARKER -> { + (msg.obj as ArrayList).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).also { + realDrawInfStructures(it) + } + } + } + } } } \ No newline at end of file