diff --git a/OCH/mogo-och-bus-passenger/src/main/assets/map_style.data b/OCH/mogo-och-bus-passenger/src/main/assets/map_style.data index 8e06219090..efcf9bf6c4 100644 Binary files a/OCH/mogo-och-bus-passenger/src/main/assets/map_style.data and b/OCH/mogo-och-bus-passenger/src/main/assets/map_style.data differ diff --git a/OCH/mogo-och-bus-passenger/src/main/assets/map_style_extra.data b/OCH/mogo-och-bus-passenger/src/main/assets/map_style_extra.data index e5a16d46be..ff5d9fb51b 100644 Binary files a/OCH/mogo-och-bus-passenger/src/main/assets/map_style_extra.data and b/OCH/mogo-och-bus-passenger/src/main/assets/map_style_extra.data differ diff --git a/OCH/mogo-och-charter-passenger/src/main/java/com/mogo/och/bus/passenger/presenter/BusPassengerFunctionOrderPresenter.kt b/OCH/mogo-och-charter-passenger/src/main/java/com/mogo/och/bus/passenger/presenter/BusPassengerFunctionOrderPresenter.kt index cd85036600..ccc8f03fca 100644 --- a/OCH/mogo-och-charter-passenger/src/main/java/com/mogo/och/bus/passenger/presenter/BusPassengerFunctionOrderPresenter.kt +++ b/OCH/mogo-och-charter-passenger/src/main/java/com/mogo/och/bus/passenger/presenter/BusPassengerFunctionOrderPresenter.kt @@ -66,7 +66,7 @@ class BusPassengerFunctionOrderPresenter(view: M1OrderLineFragment?) : CharterPassengerModel.setStatusChangeListener(TAG,this) CallerTelematicListenerManager.addListener(TAG, msgReceived) val currentOrderStatus = CharterPassengerModel.getCurrentOrderStatus() - onStatusChange(currentOrderStatus) + needRunUI(currentOrderStatus) extracted() } @@ -292,17 +292,21 @@ class BusPassengerFunctionOrderPresenter(view: M1OrderLineFragment?) : override fun onStatusChange(currentStatus: OrderStatusEnum) { UiThreadHandler.post { - when (currentStatus) { - OrderStatusEnum.OrderNoLine -> { - mView?.setVisableByTrun(showBiz = true) - extracted() - } - OrderStatusEnum.OrdersWithLine ->{ - mView?.setVisableByTrun(showBiz = true) - } - else ->{ - mView?.setVisableByTrun(showNorOrder = true) - } + needRunUI(currentStatus) + } + } + + private fun needRunUI(currentStatus: OrderStatusEnum){ + when (currentStatus) { + OrderStatusEnum.OrderNoLine -> { + mView?.setVisableByTrun(showBiz = true) + extracted() + } + OrderStatusEnum.OrdersWithLine ->{ + mView?.setVisableByTrun(showBiz = true) + } + else ->{ + mView?.setVisableByTrun(showNorOrder = true) } } } diff --git a/OCH/mogo-och-shuttle-passenger/src/main/assets/map_style.data b/OCH/mogo-och-shuttle-passenger/src/main/assets/map_style.data index 8e06219090..efcf9bf6c4 100644 Binary files a/OCH/mogo-och-shuttle-passenger/src/main/assets/map_style.data and b/OCH/mogo-och-shuttle-passenger/src/main/assets/map_style.data differ diff --git a/OCH/mogo-och-shuttle-passenger/src/main/assets/map_style_extra.data b/OCH/mogo-och-shuttle-passenger/src/main/assets/map_style_extra.data index e5a16d46be..ff5d9fb51b 100644 Binary files a/OCH/mogo-och-shuttle-passenger/src/main/assets/map_style_extra.data and b/OCH/mogo-och-shuttle-passenger/src/main/assets/map_style_extra.data differ diff --git a/core/function-impl/mogo-core-function-chat/src/main/java/com/mogo/eagle/core/function/chat/facade/ui/CallChatWindowManager.kt b/core/function-impl/mogo-core-function-chat/src/main/java/com/mogo/eagle/core/function/chat/facade/ui/CallChatWindowManager.kt index a750dbdf93..3d9ea56a48 100644 --- a/core/function-impl/mogo-core-function-chat/src/main/java/com/mogo/eagle/core/function/chat/facade/ui/CallChatWindowManager.kt +++ b/core/function-impl/mogo-core-function-chat/src/main/java/com/mogo/eagle/core/function/chat/facade/ui/CallChatWindowManager.kt @@ -405,6 +405,9 @@ internal class CallChatWindowManager { } private fun hide(view: View) { + if (view != null && view.visibility == View.VISIBLE) { + view.visibility = View.INVISIBLE + } if (!ViewCompat.isAttachedToWindow(view)) { return } 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..f69b8bfeb1 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, 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..2887793cc9 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 /** @@ -86,6 +88,8 @@ class OverMapView @JvmOverloads constructor( private var mContext: Context? = null private var mTilt = 0f private var overLayerView: TextView? = null + @Volatile + private var isMapLoaded = false // 全局路径规划中的GeoHash网格 private val pathMap: MutableMap?> = HashMap() @@ -98,7 +102,8 @@ class OverMapView @JvmOverloads constructor( private var mCompassMarker: Marker? = null private var mStartMarker: Marker? = null private var mEndMarker: Marker? = null - private var mBottomPolyline: Polyline? = null + + // private var mBottomPolyline: Polyline? = null private var mCoveredPolyline: Polyline? = null private var mSitePolyline: Polyline? = null @@ -111,6 +116,7 @@ class OverMapView @JvmOverloads constructor( // 绘制轨迹线的集合 private val textureList: MutableList = ArrayList() private val texIndexList: MutableList = ArrayList() + @Volatile private var mLocation: MogoLocation? = null private var isFirstLocation = true var mCustomMapStyleOptions: CustomMapStyleOptions? = null @@ -118,24 +124,46 @@ 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() - } + @Volatile + private var isPointsChanged = false + /** + * 高频的 + */ + 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 +261,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 +283,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 +313,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 +324,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 +351,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 +361,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 +407,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()) { @@ -399,6 +418,7 @@ class OverMapView @JvmOverloads constructor( } mAMap?.setOnMapLoadedListener { Log.d(TAG, "---onMapLoaded---") + isMapLoaded = true if (mCustomMapStyleOptions != null) { // 加载自定义样式 mCustomMapStyleOptions!!.isEnable = true @@ -429,6 +449,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 +517,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 +542,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 +606,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 +626,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 +696,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,26 +718,178 @@ 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) { + 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() + if (mAMap != null) { + Message.obtain().apply { + what = DRAW_SITE_LINE + obj = Pair(coordinates, bitmap) + 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) + } + } + + /** + * 绘制轨迹线 + * + * @param coordinates + * @param locIndex + */ + private fun realDrawPolyline(coordinates: List, locIndex: Int) { + val time = System.currentTimeMillis() + if (textureList.size > 0) { + textureList.clear() + } + if (texIndexList.size > 0) { + texIndexList.clear() + } + if (isClearArrived) { + textureList.add(transparentBitmap)// index:0 + } else { + // 已走过的置灰 + textureList.add(arrivedBitmap)// index:0 + } + // 未走过的纹理 + textureList.add(unArrivedBitmap)// index:1 + for (i in coordinates.indices) { + // 线段数比点数少一个 + if (i == 0) continue + if (i <= locIndex) { + texIndexList.add(0) + } else { + texIndexList.add(1) + } + } + if (mCoveredPolyline != null) { + mCoveredPolyline!!.options.customTextureList = textureList + mCoveredPolyline!!.options.customTextureIndex = texIndexList + if (isPointsChanged) { + mCoveredPolyline!!.points = coordinates + isPointsChanged = false + } + return + } + + if (mAMap != null && coordinates.size > 2) { + Log.d( + TAG, + "绘制时轨迹点数为:${coordinates.size},车辆index为:$locIndex,起点为:(${coordinates[0].longitude},${coordinates[0].latitude}),终点为:(${coordinates.last().longitude},${coordinates.last().latitude})" + ) + //设置线段纹理 + val polylineOptions = PolylineOptions() + polylineOptions.addAll(coordinates) + polylineOptions.width(14f) //线段宽度 + polylineOptions.lineCapType(PolylineOptions.LineCapType.LineCapRound) + polylineOptions.customTextureList = textureList + polylineOptions.customTextureIndex = texIndexList + // 绘制线 + mCoveredPolyline = mAMap?.addPolyline(polylineOptions) + } + Log.d(TAG, "绘制全局轨迹线耗时为:${System.currentTimeMillis() - time}ms") + } + + private fun realDrawSiteNames(markerOptionsList: ArrayList) { + siteNameList = mAMap?.addMarkers(markerOptionsList, false) + } + + private fun realDisplayOverView() { + Log.d(TAG, "realDisplayOverView被调用") + 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)) + Log.d(TAG, "切换视角展示轨迹点和车!") + } + } else { + if (mLocation != null && mAMap != null) { + //设置希望展示的地图缩放级别 + Log.d(TAG, "切换视角展示车,定位为:${mLocation!!.longitude},${mLocation!!.latitude}") + val cameraPosition = CameraPosition.Builder() + .target(LatLng(mLocation!!.latitude, mLocation!!.longitude)).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) { @@ -781,40 +912,90 @@ class OverMapView @JvmOverloads constructor( } } - /** - * 绘制轨迹线 - * - * @param coordinates - * @param locIndex - */ - private fun drawPolyline(coordinates: List, locIndex: Int) { - if (textureList.size > 0) { - textureList.clear() + 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 } - if (texIndexList.size > 0) { - texIndexList.clear() + } + + 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(coordinates: List, bitmap: Bitmap) { + val textureList = arrayListOf() + textureList.add(BitmapDescriptorFactory.fromBitmap(bitmap)) + val texIndexList = arrayListOf() for (i in coordinates.indices) { // 线段数比点数少一个 if (i == 0) continue - if (i <= locIndex) { - if (isClearArrived) { - textureList.add(transparentBitmap) - } else { - // 已走过的置灰 - textureList.add(arrivedBitmap) - } - } else { - // 未走过的纹理 - textureList.add(unArrivedBitmap) - } - texIndexList.add(i - 1) + texIndexList.add(0) } - if (mAMap != null && coordinates.size > 2) { - Log.d( - TAG, - "绘制时轨迹点数为:${coordinates.size},车辆index为:$locIndex,起点为:(${coordinates[0].longitude},${coordinates[0].latitude}),终点为:(${coordinates.last().longitude},${coordinates.last().latitude})" - ) + if (mAMap != null) { + if (mSitePolyline != null) { + mSitePolyline!!.options.customTextureList = textureList + mSitePolyline!!.options.customTextureIndex = texIndexList + mSitePolyline!!.points = coordinates + return + } //设置线段纹理 val polylineOptions = PolylineOptions() polylineOptions.addAll(coordinates) @@ -823,113 +1004,62 @@ class OverMapView @JvmOverloads constructor( polylineOptions.customTextureList = textureList polylineOptions.customTextureIndex = texIndexList // 绘制线 - mBottomPolyline = mCoveredPolyline - mCoveredPolyline = mAMap!!.addPolyline(polylineOptions) - if (mBottomPolyline != null) { - mBottomPolyline!!.remove() - mBottomPolyline = null - } + mSitePolyline = mAMap?.addPolyline(polylineOptions) } } - /** - * 绘制站点轨迹线 - */ - 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 realClearPolyline() { + mCoveredPolyline?.points = emptyList() + } + + private fun realClearSitePolyline() { + mSitePolyline?.points = emptyList() + } + + fun realClearV2XMarkers() { + if (currMarkerList != null) { + for (marker in currMarkerList!!) { + marker.destroy() } + currMarkerList = null } } - /** - * 清除已选站点的轨迹线 - */ - fun clearSitePolyline() { - singlePool.execute { - if (mSitePolyline != null) { - mSitePolyline!!.remove() + private fun realClearSiteNameViews() { + if (siteNameList != null) { + for (marker in siteNameList!!) { + marker.destroy() } + siteNameList = null } } - /** - * 站点轨迹集合被包含在地图显示范围内 - */ - fun includeSitePointsAndUpdateCamera(coordinates: List?) { - singlePool.execute { - val linePointsLatLng = allPoints - val boundsBuilder = LatLngBounds.Builder() - var isOnlyCarLocation = true + private fun realDrawSiteMarkers(markerOptionsList: ArrayList) { + siteMarkerList = mAMap?.addMarkers(markerOptionsList, false) + } - 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 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 { // 在中国境内 @@ -937,7 +1067,8 @@ class OverMapView @JvmOverloads constructor( mLocation = it lonLatHeading = Triple(it.longitude, it.latitude, it.heading) drawCarMarker(it) - if (isFirstLocation) { + if (isFirstLocation && isMapLoaded) { + Log.d(TAG, "车辆首次获取定位") displayCustomOverView() isFirstLocation = false } @@ -958,6 +1089,8 @@ class OverMapView @JvmOverloads constructor( } else { lastTime = System.currentTimeMillis() } + MarkerDrawerManager.stopLoopCalCarLocation() + isPointsChanged = true globalPathResp?.let { ThreadUtils.getIoPool().execute { handlePlanningData(it.wayPointsList) @@ -1025,8 +1158,105 @@ 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(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(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(DRAW_SITE_LINE) + // 绘制站点轨迹线时停止绘制全局轨迹,降低性能损耗 + MarkerDrawerManager.isStopCalculate = true + (msg.obj as Pair, Bitmap>).apply { + realDrawSitePolyline(first, second) + } + } + 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(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