[6.7.0][Feat]小地图和全览地图动态切换

This commit is contained in:
chenfufeng
2024-09-24 18:02:39 +08:00
parent d08f1fcd60
commit 465a309704
5 changed files with 510 additions and 254 deletions

View File

@@ -7,13 +7,8 @@ import android.animation.ObjectAnimator
import android.animation.PropertyValuesHolder
import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.util.ConstraintUtil
import kotlinx.android.synthetic.main.view_map_container.view.exchangeLayout
import me.jessyan.autosize.utils.AutoSizeUtils
/**
* 可自定义绘制顺序的ConstraintLayout
@@ -184,7 +179,7 @@ class ExchangeChildLayout @JvmOverloads constructor(
override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
// updateLayoutParams()
swapLayoutParamsWithoutAnim()
// swapLayoutParamsWithoutAnim()
invalidate()
isPlayingAnim = false
}
@@ -192,7 +187,7 @@ class ExchangeChildLayout @JvmOverloads constructor(
override fun onAnimationCancel(animation: Animator) {
super.onAnimationCancel(animation)
// updateLayoutParams()
swapLayoutParamsWithoutAnim()
// swapLayoutParamsWithoutAnim()
invalidate()
isPlayingAnim = false
}
@@ -220,112 +215,61 @@ class ExchangeChildLayout @JvmOverloads constructor(
}
}
private fun updateLayoutParams() {
// if (childCount > 2) return
// children.forEachIndexed { index, view ->
// if (index == 0) {
// changeRule(view, true)
// } else {
// changeRule(view, false)
// }
private fun swapLayoutParamsWithoutAnim() {
// if (constraintUtil == null) {
// constraintUtil = ConstraintUtil(exchangeLayout)
// }
// if (isSwapped) {
// val begin = constraintUtil!!.begin()
// // 清除约束关系
// begin.clear(R.id.mapBizView, R.id.overMapView)
// // 设置新的约束关系
// begin.Left_toLeftOf(R.id.overMapView, ConstraintSet.PARENT_ID)
// begin.Top_toTopOf(R.id.overMapView, ConstraintSet.PARENT_ID)
// begin.Right_toRightOf(R.id.overMapView, ConstraintSet.PARENT_ID)
// begin.Bottom_toBottomOf(R.id.overMapView, ConstraintSet.PARENT_ID)
//
// begin.Left_toLeftOf(R.id.mapBizView, ConstraintSet.UNSET)
// begin.Top_toTopOf(R.id.mapBizView, ConstraintSet.UNSET)
// begin.Right_toRightOf(R.id.mapBizView, ConstraintSet.PARENT_ID)
// begin.Bottom_toBottomOf(R.id.mapBizView, ConstraintSet.PARENT_ID)
// begin.setWidth(R.id.mapBizView, AutoSizeUtils.dp2px(context, 270f))
// begin.setHeight(R.id.mapBizView, AutoSizeUtils.dp2px(context, 270f))
// begin.setMargin(
// R.id.mapBizView,
// 0,
// 0,
// AutoSizeUtils.dp2px(context, 60f),
// AutoSizeUtils.dp2px(context, 60f)
// )
// // 应用新的属性集
// begin.commit()
// } else {
//// constraintUtil?.reSet()
// val begin = constraintUtil!!.begin()
// // 清除约束关系
// begin.clear(R.id.mapBizView, R.id.overMapView)
// // 设置新的约束关系
// begin.Left_toLeftOf(R.id.mapBizView, ConstraintSet.PARENT_ID)
// begin.Top_toTopOf(R.id.mapBizView, ConstraintSet.PARENT_ID)
// begin.Right_toRightOf(R.id.mapBizView, ConstraintSet.PARENT_ID)
// begin.Bottom_toBottomOf(R.id.mapBizView, ConstraintSet.PARENT_ID)
//
// begin.Left_toLeftOf(R.id.overMapView, ConstraintSet.UNSET)
// begin.Top_toTopOf(R.id.overMapView, ConstraintSet.UNSET)
// begin.Right_toRightOf(R.id.overMapView, ConstraintSet.PARENT_ID)
// begin.Bottom_toBottomOf(R.id.overMapView, ConstraintSet.PARENT_ID)
// begin.setWidth(R.id.overMapView, AutoSizeUtils.dp2px(context, 270f))
// begin.setHeight(R.id.overMapView, AutoSizeUtils.dp2px(context, 270f))
// begin.setMargin(
// R.id.overMapView,
// 0,
// 0,
// AutoSizeUtils.dp2px(context, 60f),
// AutoSizeUtils.dp2px(context, 60f)
// )
// // 应用新的属性集
// begin.commit()
// }
}
private fun changeRule(
view: View, isBottom: Boolean,
) {
val layoutParams = view.layoutParams as LayoutParams
if (isBottom) {
if (isSwapped) {
layoutParams.startToStart = LayoutParams.UNSET
layoutParams.topToTop = LayoutParams.UNSET
layoutParams.endToEnd = LayoutParams.PARENT_ID
layoutParams.bottomToBottom = LayoutParams.PARENT_ID
layoutParams.width = minWidth
layoutParams.height = minHeight
} else {
layoutParams.startToStart = LayoutParams.PARENT_ID
layoutParams.topToTop = LayoutParams.PARENT_ID
layoutParams.endToEnd = LayoutParams.UNSET
layoutParams.bottomToBottom = LayoutParams.UNSET
layoutParams.width = maxWidth
layoutParams.height = maxHeight
}
} else {
if (isSwapped) {
layoutParams.startToStart = LayoutParams.PARENT_ID
layoutParams.topToTop = LayoutParams.PARENT_ID
layoutParams.endToEnd = LayoutParams.UNSET
layoutParams.bottomToBottom = LayoutParams.UNSET
layoutParams.width = maxWidth
layoutParams.height = maxHeight
} else {
layoutParams.startToStart = LayoutParams.UNSET
layoutParams.topToTop = LayoutParams.UNSET
layoutParams.endToEnd = LayoutParams.PARENT_ID
layoutParams.bottomToBottom = LayoutParams.PARENT_ID
layoutParams.width = minWidth
layoutParams.height = minHeight
}
}
view.layoutParams = layoutParams
}
private fun swapLayoutParamsWithoutAnim() {
if (constraintUtil == null) {
constraintUtil = ConstraintUtil(exchangeLayout)
}
if (isSwapped) {
val begin = constraintUtil!!.begin()
// 清除约束关系
begin.clear(R.id.mapBizView, R.id.overMapView)
// 设置新的约束关系
begin.Left_toLeftOf(R.id.overMapView, ConstraintSet.PARENT_ID)
begin.Top_toTopOf(R.id.overMapView, ConstraintSet.PARENT_ID)
begin.Right_toRightOf(R.id.overMapView, ConstraintSet.PARENT_ID)
begin.Bottom_toBottomOf(R.id.overMapView, ConstraintSet.PARENT_ID)
begin.Left_toLeftOf(R.id.mapBizView, ConstraintSet.UNSET)
begin.Top_toTopOf(R.id.mapBizView, ConstraintSet.UNSET)
begin.Right_toRightOf(R.id.mapBizView, ConstraintSet.PARENT_ID)
begin.Bottom_toBottomOf(R.id.mapBizView, ConstraintSet.PARENT_ID)
begin.setWidth(R.id.mapBizView, AutoSizeUtils.dp2px(context, 270f))
begin.setHeight(R.id.mapBizView, AutoSizeUtils.dp2px(context, 270f))
begin.setMargin(
R.id.mapBizView,
0,
0,
AutoSizeUtils.dp2px(context, 60f),
AutoSizeUtils.dp2px(context, 60f)
)
// 应用新的属性集
begin.commit()
} else {
// constraintUtil?.reSet()
val begin = constraintUtil!!.begin()
// 清除约束关系
begin.clear(R.id.mapBizView, R.id.overMapView)
// 设置新的约束关系
begin.Left_toLeftOf(R.id.mapBizView, ConstraintSet.PARENT_ID)
begin.Top_toTopOf(R.id.mapBizView, ConstraintSet.PARENT_ID)
begin.Right_toRightOf(R.id.mapBizView, ConstraintSet.PARENT_ID)
begin.Bottom_toBottomOf(R.id.mapBizView, ConstraintSet.PARENT_ID)
begin.Left_toLeftOf(R.id.overMapView, ConstraintSet.UNSET)
begin.Top_toTopOf(R.id.overMapView, ConstraintSet.UNSET)
begin.Right_toRightOf(R.id.overMapView, ConstraintSet.PARENT_ID)
begin.Bottom_toBottomOf(R.id.overMapView, ConstraintSet.PARENT_ID)
begin.setWidth(R.id.overMapView, AutoSizeUtils.dp2px(context, 270f))
begin.setHeight(R.id.overMapView, AutoSizeUtils.dp2px(context, 270f))
begin.setMargin(
R.id.overMapView,
0,
0,
AutoSizeUtils.dp2px(context, 60f),
AutoSizeUtils.dp2px(context, 60f)
)
// 应用新的属性集
begin.commit()
}
}
}

View File

@@ -6,19 +6,20 @@ import android.transition.Transition
import android.transition.Transition.TransitionListener
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.animation.DecelerateInterpolator
import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import com.mogo.eagle.core.data.map.MogoLatLng
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.util.ConstraintUtil
import com.mogo.eagle.core.function.view.TravelRealityView
import com.mogo.eagle.core.utilcode.mogo.view.OnPreventFastClickListener
import com.mogo.map.listener.IMogoMapListener
import com.mogo.map.listener.MogoMapListenerHandler
import kotlinx.android.synthetic.main.view_map_container.view.exchangeLayout
import kotlinx.android.synthetic.main.view_map_container.view.mapBizView
import kotlinx.android.synthetic.main.view_map_container.view.overMapView
import me.jessyan.autosize.utils.AutoSizeUtils
import kotlinx.android.synthetic.main.view_map_container.view.parentLayout
import kotlinx.android.synthetic.main.view_map_container.view.shadowView
class MapContainerLayout @JvmOverloads constructor(
context: Context,
@@ -26,7 +27,7 @@ class MapContainerLayout @JvmOverloads constructor(
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMogoMapListener {
private var isSwapped = false
private var isScaled = false
private var isPlayingAnim = false
private var constraintUtil: ConstraintUtil? = null
@@ -78,77 +79,58 @@ class MapContainerLayout @JvmOverloads constructor(
}
private fun initView() {
overMapView.setOnGestureListener(object : TravelRealityView.OnGestureListener {
override fun onSingleTap(lng: Float, lat: Float) {
if (!exchangeLayout.getSwapFlag()) {
overMapView.setMapFlag(false)
exchangeLayout.swapViews()
}
shadowView.setOnClickListener(object : OnPreventFastClickListener() {
override fun onClickImpl(v: View?) {
swapViewsWithAnim()
}
})
}
override fun onMapClick(latLng: MogoLatLng?) {
super.onMapClick(latLng)
if (exchangeLayout.getSwapFlag()) {
overMapView.setMapFlag(true)
exchangeLayout.swapViews()
}
}
@Deprecated(message = "会多次requestLayout导致高精地图卡顿")
private fun swapViewsWithAnim() {
if (isPlayingAnim) return
if (constraintUtil == null) {
constraintUtil = ConstraintUtil(exchangeLayout, 300, DecelerateInterpolator())
constraintUtil = ConstraintUtil(parentLayout, 300, AccelerateDecelerateInterpolator())
constraintUtil?.addTransitionListener(transitionListener)
}
if (!isSwapped) {
if (!isScaled) {
// 获取属性集并设置动画
val begin = constraintUtil!!.beginWithAnim()
// 清除约束关系
begin.clear(R.id.mapBizView, R.id.overMapView)
begin.clear(R.id.overMapView)
// 设置新的约束关系
begin.Left_toLeftOf(R.id.overMapView, ConstraintSet.PARENT_ID)
begin.Top_toTopOf(R.id.overMapView, ConstraintSet.PARENT_ID)
begin.Right_toRightOf(R.id.overMapView, ConstraintSet.PARENT_ID)
begin.Bottom_toBottomOf(R.id.overMapView, ConstraintSet.PARENT_ID)
begin.Left_toLeftOf(R.id.mapBizView, ConstraintSet.UNSET)
begin.Top_toTopOf(R.id.mapBizView, ConstraintSet.UNSET)
begin.Right_toRightOf(R.id.mapBizView, ConstraintSet.PARENT_ID)
begin.Bottom_toBottomOf(R.id.mapBizView, ConstraintSet.PARENT_ID)
begin.setWidth(R.id.mapBizView, AutoSizeUtils.dp2px(context, 270f))
begin.setHeight(R.id.mapBizView, AutoSizeUtils.dp2px(context, 270f))
begin.setMargin(
R.id.mapBizView,
0,
0,
AutoSizeUtils.dp2px(context, 60f),
AutoSizeUtils.dp2px(context, 60f)
)
// 应用新的属性集
begin.commit()
exchangeLayout.setSwapped(true)
isSwapped = true
} else {
constraintUtil?.reSetWidthAnim()
exchangeLayout.setSwapped(false)
isSwapped = false
}
}
private val transitionListener = object : TransitionListener {
override fun onTransitionStart(transition: Transition?) {
isPlayingAnim = true
overMapView.setMapFlag(isScaled)
}
override fun onTransitionEnd(transition: Transition?) {
isPlayingAnim = false
overMapView.swapSettings()
updateShadowBg(isScaled)
isScaled = !isScaled
}
override fun onTransitionCancel(transition: Transition?) {
isPlayingAnim = false
overMapView.swapSettings()
updateShadowBg(isScaled)
isScaled = !isScaled
}
override fun onTransitionPause(transition: Transition?) {
@@ -159,4 +141,12 @@ class MapContainerLayout @JvmOverloads constructor(
isPlayingAnim = true
}
}
private fun updateShadowBg(isSmallMap: Boolean) {
if (!isSmallMap) {
shadowView.setBackgroundResource(R.drawable.gaojing_bg)
} else {
shadowView.background = null
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

View File

@@ -2,47 +2,49 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/parentLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="MissingDefaultResource">
<com.mogo.eagle.core.function.hmi.map.ExchangeChildLayout
android:id="@+id/exchangeLayout"
<!--高精地图-->
<com.mogo.eagle.core.function.view.MapBizView
android:id="@+id/mapBizView"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<!--高精地图-->
<com.mogo.eagle.core.function.view.MapBizView
android:id="@+id/mapBizView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:isWeatherEnable="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
app:isWeatherEnable="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!--高德地图-->
<com.mogo.eagle.core.function.view.TravelRealityView
android:id="@+id/overMapView"
android:layout_width="270dp"
android:layout_height="270dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginEnd="60dp"
android:layout_marginBottom="60dp"
app:roadRangeDrawable="@drawable/taxi_overmap_road_range"
app:roadTrajectoryDrawable="@drawable/taxi_orvermap_road_trajectory"
app:globalPathColor="#39BA90"
app:carDrawable="@drawable/taxt_u_p_map_car"
app:compassDrawable="@drawable/taxt_u_p_map_car_light"
app:endPointDrawable="@drawable/taxi_overmap_endpoint"
app:mapStyleExtraPath="over_view_style_extra.data"
app:mapStylePath="over_view_style.data"
app:resetDrawable="@null"
app:leftPadding="70"
app:topPadding="70"
app:rightPadding="70"
app:bottomPadding="160"
/>
</com.mogo.eagle.core.function.hmi.map.ExchangeChildLayout>
<!--高德地图-->
<com.mogo.eagle.core.function.view.TravelRealityView
android:id="@+id/overMapView"
android:layout_width="270dp"
android:layout_height="270dp"
android:layout_marginEnd="60dp"
android:layout_marginBottom="60dp"
app:bottomPadding="160"
app:carDrawable="@drawable/taxt_u_p_map_car"
app:compassDrawable="@drawable/taxt_u_p_map_car_light"
app:endPointDrawable="@drawable/taxi_overmap_endpoint"
app:globalPathColor="#39BA90"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:leftPadding="70"
app:mapStyleExtraPath="over_view_style_extra.data"
app:mapStylePath="over_view_style.data"
app:resetDrawable="@null"
app:rightPadding="70"
app:roadRangeDrawable="@drawable/taxi_overmap_road_range"
app:roadTrajectoryDrawable="@drawable/taxi_orvermap_road_trajectory"
app:topPadding="70" />
<View
android:id="@+id/shadowView"
android:layout_width="270dp"
android:layout_height="270dp"
android:layout_marginEnd="60dp"
android:layout_marginBottom="60dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -22,6 +22,7 @@ import com.amap.api.maps.TextureMapView
import com.amap.api.maps.model.AMapGestureListener
import com.amap.api.maps.model.BitmapDescriptor
import com.amap.api.maps.model.BitmapDescriptorFactory
import com.amap.api.maps.model.CameraPosition
import com.amap.api.maps.model.CustomMapStyleOptions
import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.LatLngBounds
@@ -30,7 +31,9 @@ import com.amap.api.maps.model.MarkerOptions
import com.amap.api.maps.model.Polyline
import com.amap.api.maps.model.PolylineOptions
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.map.MogoLatLng
import com.mogo.eagle.core.data.map.MogoLocation
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
import com.mogo.eagle.core.function.api.autopilot.IMoGoPlanningRottingListener
import com.mogo.eagle.core.function.business.travelreality.CrossDeviceBean
@@ -42,16 +45,23 @@ import com.mogo.eagle.core.function.business.travelreality.Point
import com.mogo.eagle.core.function.business.travelreality.TravelRealityModel.Companion.travelNetWorkModel
import com.mogo.eagle.core.function.business.travelreality.view.EventVideoView
import com.mogo.eagle.core.function.business.travelreality.view.VideoMarkerEntity
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListenerManager
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
import com.mogo.eagle.core.function.map.R
import com.mogo.eagle.core.function.smp.view.SmallMapView
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.mogo.MapAssetStyleUtils
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.CoordinateUtils
import com.mogo.eagle.core.utilcode.util.LocationUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.eagle.core.widget.media.video.TextureVideoViewOutlineProvider
import me.jessyan.autosize.utils.AutoSizeUtils
import mogo.telematics.pad.MessagePad
import kotlin.math.floor
/**
* 行程实况View
@@ -63,7 +73,7 @@ class TravelRealityView @JvmOverloads constructor(
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoChassisLocationGCJ02Listener,
IMoGoPlanningRottingListener {
IMoGoPlanningRottingListener, IMoGoAutopilotStatusListener {
companion object {
private const val TAG = "TravelRealityView"
@@ -79,6 +89,7 @@ class TravelRealityView @JvmOverloads constructor(
private const val DRAW_LIVE_DETAIL = 9
private const val DRAW_END_MARKER = 10
private const val UPDATE_VIDEO_MARKER = 11
private const val HIDE_CAR_MARKER = 12
// private const val CLEAR_POLY_LINE = 12
// private const val CLEAR_ROAD_EVENT = 13
@@ -112,11 +123,11 @@ class TravelRealityView @JvmOverloads constructor(
private val globalPolylineList by lazy {
ArrayList<Polyline>()
}
private var mStartMarker: Marker? = null
private var mEndMarker: Marker? = null
@Volatile
private var mLocation: MogoLocation? = null
private var mStartMarker: Marker? = null
private var mEndMarker: Marker? = null
@Volatile
private var isMapLoaded = false
@@ -209,7 +220,19 @@ class TravelRealityView @JvmOverloads constructor(
private var listener: OnDrawListener? = null
private var gestureListener: OnGestureListener? = null
/**
* ====================小地图使用的====================
*/
@Volatile
private var isSmallMap: Boolean = true
private var iconRes = R.drawable.map_car_icon
private var globalPathResp: MessagePad.GlobalPathResp? = null
private val mCoordinatesLatLng: MutableList<LatLng> = ArrayList()
private var mSmallCarMarker: Marker? = null
private var mPolyline: Polyline? = null
private var mSmallStartMarker: Marker? = null
private var mSmallEndMarker: Marker? = null
init {
try {
@@ -285,6 +308,26 @@ class TravelRealityView @JvmOverloads constructor(
this.isSmallMap = isSmallMap
}
fun swapSettings() {
if (isSmallMap) {
Message.obtain().apply {
what = CLEAR_ALL_DATA
nonFrequentHandler?.sendMessage(this)
}
Message.obtain().apply {
what = HIDE_CAR_MARKER
nonFrequentHandler?.sendMessage(this)
}
// 显示小地图样式
changeMapSettings(true)
} else {
clearPolyline()
hideSmallCarMarker()
// 显示行程总览地图样式
changeMapSettings(false)
}
}
/**
* 清除所有Marker和Polyline
*/
@@ -310,7 +353,16 @@ class TravelRealityView @JvmOverloads constructor(
BitmapDescriptorFactory.fromResource(if (roadRangeDrawable != -1) roadRangeDrawable else R.drawable.mogo_road_over)
roadTrajectoryBitmap =
BitmapDescriptorFactory.fromResource(if (roadTrajectoryDrawable != -1) roadTrajectoryDrawable else R.drawable.road_trajectory_arrow_nor)
initAMapView()
// initTravelRealityMapView()
initSmallMapView(true)
}
private fun changeMapSettings(isSmallMap: Boolean) {
if (isSmallMap) {
initSmallMapView(false)
} else {
initTravelRealityMapView(false)
}
}
private fun getBitmap1(): Bitmap {
@@ -327,7 +379,83 @@ class TravelRealityView @JvmOverloads constructor(
return BitmapFactory.decodeResource(resources, R.drawable.count_bg, options)
}
private fun initAMapView() {
private fun initSmallMapView(isInit: Boolean) {
val cameraUpdate = CameraUpdateFactory.zoomTo(17f)
mAMap = mMapView?.map
// 关闭地图文字标注
mAMap?.showMapText(false)
// 设置导航地图模式aMap是地图控制器对象。
mAMap?.mapType = AMap.MAP_TYPE_NIGHT
// 关闭显示实时路况图层aMap是地图控制器对象。
mAMap?.isTrafficEnabled = false
// 设置 锚点 图标
if (isInit) {
iconRes = if (AppIdentityModeUtils.isB1(FunctionBuildConfig.appIdentityMode)) {
R.drawable.map_bus_icon
} else if (AppIdentityModeUtils.isB2(FunctionBuildConfig.appIdentityMode) || AppIdentityModeUtils.isM1(FunctionBuildConfig.appIdentityMode)) {
R.drawable.map_m2_icon
} else {
R.drawable.map_car_icon
}
mSmallCarMarker = mAMap?.addMarker(
MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(iconRes))
.anchor(0.5f, 0.5f)
)
mSmallStartMarker = mAMap?.addMarker(
MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.module_small_map_view_dir_start))
)
mSmallEndMarker = mAMap?.addMarker(
MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.module_small_map_view_dir_end))
)
// 加载自定义样式
val customMapStyleOptions = CustomMapStyleOptions()
.setEnable(true)
.setStyleData(MapAssetStyleUtils.getAssetsStyle(context, "over_view_style.data"))
.setStyleExtraData(
MapAssetStyleUtils.getAssetsExtraStyle(
context,
"over_view_style_extra.data"
)
)
// 设置自定义样式
mAMap?.setCustomMapStyle(customMapStyleOptions)
}
//设置希望展示的地图缩放级别
mAMap?.moveCamera(cameraUpdate)
// 设置地图的样式
val uiSettings = mAMap?.uiSettings
uiSettings?.isZoomControlsEnabled = false // 地图缩放级别的交换按钮
uiSettings?.setAllGesturesEnabled(false) // 所有手势
uiSettings?.isMyLocationButtonEnabled = false // 显示默认的定位按钮
uiSettings?.setLogoBottomMargin(-150) //设置Logo下边界距离屏幕底部的边距,设置为负值即可
if (isInit) {
mAMap?.setOnMapLoadedListener {
CallerLogger.d(
SceneConstant.M_MAP + SmallMapView.TAG,
"smp---onMapLoaded"
)
isMapLoaded = true
// 加载自定义样式
val customMapStyleOptions1 = CustomMapStyleOptions()
.setEnable(true)
.setStyleData(MapAssetStyleUtils.getAssetsStyle(context, "over_view_style.data"))
.setStyleExtraData(
MapAssetStyleUtils.getAssetsExtraStyle(
context,
"over_view_style_extra.data"
)
)
// 设置自定义样式
mAMap?.setCustomMapStyle(customMapStyleOptions1)
}
mAMap?.setAMapGestureListener(gestListener)
}
}
private fun initTravelRealityMapView(isInit: Boolean = false) {
Log.d(TAG, "initAMapView")
mAMap = mMapView?.map
val mapStyleOptions = CustomMapStyleOptions()
@@ -343,23 +471,21 @@ class TravelRealityView @JvmOverloads constructor(
//设置希望展示的地图缩放级别
val loc = CallerChassisLocationGCJ02ListenerManager.getChassisLocationGCJ02()
if (loc.latitude.toInt() == 0 || loc.longitude.toInt() == 0) {
mAMap?.moveCamera(CameraUpdateFactory.zoomTo(14f))
moveMapCamera(CameraUpdateFactory.zoomTo(14f))
} else {
mAMap?.moveCamera(
CameraUpdateFactory.newLatLngZoom(
coordinateConverterWgsToGcj(
loc.latitude,
loc.longitude
), 14f
)
)
moveMapCamera(CameraUpdateFactory.newLatLngZoom(
coordinateConverterWgsToGcj(
loc.latitude,
loc.longitude
), 14f
))
}
//设置地图的样式
mAMap?.uiSettings?.let {
//所有手势
it.setAllGesturesEnabled(true)
//地图缩放级别的交换按钮
it.isZoomControlsEnabled = true
it.isZoomControlsEnabled = false
it.isZoomGesturesEnabled = true
//指南针
it.isCompassEnabled = false
@@ -368,53 +494,58 @@ class TravelRealityView @JvmOverloads constructor(
//定位按钮
it.isMyLocationButtonEnabled = false
//去掉高德Logo
it.setLogoBottomMargin(-100)
it.setLogoBottomMargin(-150)
}
mAMap?.setOnMapLoadedListener {
Log.d(TAG, "地图加载完成!")
isMapLoaded = true
mAMap?.setCustomMapStyle(mapStyleOptions)
// 实时路况图层关闭必须添加在loaded结束之后,其他位置不生效
mAMap?.isTrafficEnabled = false
mAMap?.showBuildings(false)
mAMap?.uiSettings?.isZoomControlsEnabled = false
if (isInit) {
mAMap?.setOnMapLoadedListener {
Log.d(TAG, "地图加载完成!")
isMapLoaded = true
mAMap?.setCustomMapStyle(mapStyleOptions)
// 实时路况图层关闭必须添加在loaded结束之后,其他位置不生效
mAMap?.isTrafficEnabled = false
mAMap?.showBuildings(false)
mAMap?.uiSettings?.isZoomControlsEnabled = false
// mAMap?.animateCamera(CameraUpdateFactory.changeTilt(30f))
}
mAMap?.setAMapGestureListener(gestListener)
}
mAMap?.setAMapGestureListener(object : AMapGestureListener {
override fun onDoubleTap(p0: Float, p1: Float) {
}
}
override fun onSingleTap(p0: Float, p1: Float) {
gestureListener?.onSingleTap(p0, p1)
}
private val gestListener = object : AMapGestureListener {
override fun onDoubleTap(p0: Float, p1: Float) {
}
override fun onFling(p0: Float, p1: Float) {
}
override fun onSingleTap(p0: Float, p1: Float) {
gestureListener?.onSingleTap(p0, p1)
}
override fun onScroll(p0: Float, p1: Float) {
}
override fun onFling(p0: Float, p1: Float) {
}
override fun onLongPress(p0: Float, p1: Float) {
}
override fun onScroll(p0: Float, p1: Float) {
}
override fun onDown(p0: Float, p1: Float) {
}
override fun onLongPress(p0: Float, p1: Float) {
}
override fun onUp(p0: Float, p1: Float) {
}
override fun onDown(p0: Float, p1: Float) {
}
override fun onMapStable() {
}
})
override fun onUp(p0: Float, p1: Float) {
}
override fun onMapStable() {
}
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) {
if (isSmallMap) {
this.outlineProvider = TextureVideoViewOutlineProvider(AutoSizeUtils.dp2px(context, 32f)
.toFloat())
this.outlineProvider = TextureVideoViewOutlineProvider(
AutoSizeUtils.dp2px(context, 32f)
.toFloat()
)
this.clipToOutline = true
} else {
this.clipToOutline = false
@@ -441,6 +572,7 @@ class TravelRealityView @JvmOverloads constructor(
CallerPlanningRottingListenerManager.addListener("${TAG}${this.hashCode()}", this)
// 注册定位监听
CallerChassisLocationGCJ02ListenerManager.addListener("${TAG}${this.hashCode()}", this)
CallerAutoPilotStatusListenerManager.addListener("${TAG}${this.hashCode()}", this)
}
override fun onDetachedFromWindow() {
@@ -944,9 +1076,14 @@ class TravelRealityView @JvmOverloads constructor(
globalList[index + 1].lat
)
// 深拷贝一下数据
deviceInPaths.add(DeviceInfoBean(deviceBean.deviceIp, deviceBean.lon, deviceBean.lat).also { deviceInfo ->
deviceInfo.orientation = deviceBean.orientation
})
deviceInPaths.add(
DeviceInfoBean(
deviceBean.deviceIp,
deviceBean.lon,
deviceBean.lat
).also { deviceInfo ->
deviceInfo.orientation = deviceBean.orientation
})
crossOptionsList.add(MarkerOptions().apply {
position(
coordinateConverterWgsToGcj(
@@ -1235,10 +1372,14 @@ class TravelRealityView @JvmOverloads constructor(
override fun onChassisLocationGCJ02(gnssInfo: MogoLocation?) {
gnssInfo?.let {
mLocation = it
if (isMapLoaded) {
// 绘制自车
drawCarMarker(it)
if (!isSmallMap) {
mLocation = it
if (isMapLoaded) {
// 绘制自车
drawCarMarker(it)
}
} else {
drawSmallMapMarker(it)
}
}
}
@@ -1252,26 +1393,193 @@ class TravelRealityView @JvmOverloads constructor(
}
Log.d(TAG, "下发全局轨迹!")
globalPathResp?.let { globalPath ->
// nonFrequentHandler?.removeCallbacksAndMessages(null)
if (isSmallMap) {
if (globalPath.wayPointsList.size > 0) {
this.globalPathResp = globalPath
drawRotting()
}
} else {
val pointList = ArrayList<Point>()
val pointCloneList = ArrayList<Point>()
globalPath.wayPointsList.forEach { loc ->
pointList.add(Point(loc.longitude, loc.latitude))
pointCloneList.add(Point(loc.longitude, loc.latitude))
}
Log.d(TAG, "轨迹点个数为:${pointList.size}")
reqData = pointCloneList
handleGlobalPath(pointList)
val pointList = ArrayList<Point>()
val pointCloneList = ArrayList<Point>()
globalPath.wayPointsList.forEach { loc ->
pointList.add(Point(loc.longitude, loc.latitude))
pointCloneList.add(Point(loc.longitude, loc.latitude))
}
Log.d(TAG, "轨迹点个数为:${pointList.size}")
reqData = pointCloneList
handleGlobalPath(pointList)
requestData(pointList)
if (!isRoadTrackReq) {
Log.d(TAG, "处理智慧道路轨迹!")
handleRoadTrajectories(roadTrackList, pointList)
requestData(pointList)
if (!isRoadTrackReq) {
Log.d(TAG, "处理智慧道路轨迹!")
handleRoadTrajectories(roadTrackList, pointList)
}
}
}
}
//===================================小地图绘制起始!===================================
override fun onAutopilotStatusResponse(state: Int) {
if (isSmallMap) {
if (state == 2) {
drawRotting()
} else {
UiThreadHandler.post {
clearPolyline()
}
}
}
}
private fun drawRotting() {
globalPathResp?.let {
val latLngList: MutableList<MogoLatLng> = ArrayList()
for (routeModel in globalPathResp!!.wayPointsList) {
latLngList.add(MogoLatLng(routeModel.latitude, routeModel.longitude))
}
CallerLogger.d(
SceneConstant.M_MAP + SmallMapView.TAG,
"SmallMapView latLngList.size = ${latLngList.size}"
)
if (latLngList.size > 0) {
UiThreadHandler.post {
convert(latLngList)
drawablePolyline()
}
} else {
UiThreadHandler.post {
CallerLogger.d(
SceneConstant.M_MAP + SmallMapView.TAG,
"SmallMapView latLngList.size = ${latLngList.size} clearPolyline ---->"
)
clearPolyline()
}
}
}
}
private fun convert(coordinates: List<MogoLatLng>) {
mCoordinatesLatLng.clear()
val latLngs = coordinateConverterFrom84ForList(mContext, coordinates)
mCoordinatesLatLng.addAll(latLngs)
}
private fun drawablePolyline() {
clearPolyline()
if (mAMap != null) {
if (mCoordinatesLatLng.size >= 2) {
// 设置开始结束Marker位置
mSmallStartMarker!!.position = mCoordinatesLatLng[0]
mSmallEndMarker!!.position = mCoordinatesLatLng[mCoordinatesLatLng.size - 1]
mSmallStartMarker!!.setToTop()
mSmallStartMarker!!.isVisible = true
mSmallEndMarker!!.isVisible = true
mSmallEndMarker!!.setToTop()
//存放所有点的经纬度
val boundsBuilder = LatLngBounds.Builder()
for (i in mCoordinatesLatLng.indices) {
//把所有点都include进去LatLng类型
boundsBuilder.include(mCoordinatesLatLng[i])
}
//第二个参数为四周留空宽度
mAMap!!.animateCamera(
CameraUpdateFactory.newLatLngBounds(
boundsBuilder.build(),
30
)
)
// 绘制线
mPolyline?.points = mCoordinatesLatLng
CallerLogger.d(
SceneConstant.M_MAP + SmallMapView.TAG,
"SmallMapView drawPolyline size is = ${mCoordinatesLatLng.size} "
)
}
}
}
private fun clearPolyline() {
if (mPolyline != null) {
mPolyline!!.points = emptyList()
}
if (mSmallStartMarker != null) {
mSmallStartMarker!!.isVisible = false
}
if (mSmallEndMarker != null) {
mSmallEndMarker!!.isVisible = false
}
}
private fun hideSmallCarMarker() {
mSmallCarMarker?.isVisible = false
}
private fun drawSmallMapMarker(mogoLocation: MogoLocation) {
mLocation = mogoLocation
if (mSmallCarMarker == null) {
mSmallCarMarker = mAMap?.addMarker(
MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(iconRes))
.anchor(0.5f, 0.5f)
)
}
if (mSmallCarMarker == null) {
return
}
UiThreadHandler.post {
val currentLatLng = LatLng(mLocation!!.latitude, mLocation!!.longitude)
val bearing = floor(mLocation!!.heading).toFloat()
//更新车辆位置
mSmallCarMarker!!.position = currentLatLng
mSmallCarMarker!!.isVisible = true
if (mCoordinatesLatLng.size > 1) {
// 结束位置
val endLatLng = mCoordinatesLatLng[mCoordinatesLatLng.size - 1]
val calculateDistance = CoordinateUtils.calculateLineDistance(
endLatLng.latitude, endLatLng.longitude,
currentLatLng.latitude, currentLatLng.longitude
)
if (calculateDistance <= 5) {
CallerLogger.d(
SceneConstant.M_MAP + SmallMapView.TAG,
"onChassisLocationGCJ02 -----> calculateDistance <= 5 "
)
clearPolyline()
mCoordinatesLatLng.clear()
}
}
val cameraPosition: CameraPosition =
CameraPosition.Builder()
.target(mSmallCarMarker!!.position)
.tilt(0f)
.bearing(bearing)
.zoom(17f)
.build()
mAMap?.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
}
}
private fun coordinateConverterFrom84ForList(
mContext: Context?,
mogoLatLngList: List<MogoLatLng>
): List<LatLng> {
val list: MutableList<LatLng> = ArrayList()
for (m in mogoLatLngList) {
val mogoLatLng = coordinateConverterFrom84(mContext, m)
list.add(mogoLatLng)
}
return list
}
private fun coordinateConverterFrom84(mContext: Context?, mogoLatLng: MogoLatLng): LatLng {
val mCoordinateConverter = CoordinateConverter(mContext)
mCoordinateConverter.from(CoordinateConverter.CoordType.GPS)
mCoordinateConverter.coord(LatLng(mogoLatLng.lat, mogoLatLng.lon))
return mCoordinateConverter.convert()
}
//===================================小地图绘制结束!===================================
private fun requestData(pointList: ArrayList<Point>) {
if (!isCrossDeviceReq) {
Log.d(TAG, "请求获取路口设备!")
@@ -1356,6 +1664,11 @@ class TravelRealityView @JvmOverloads constructor(
realDrawCar(this)
}
}
HIDE_CAR_MARKER -> {
removeMessages(HIDE_CAR_MARKER)
if (isMapDestroyed) return
hideCarMarker()
}
DRAW_POLY_LINE -> {
removeMessages(DRAW_POLY_LINE)
@@ -1475,6 +1788,7 @@ class TravelRealityView @JvmOverloads constructor(
val latLng = LatLng(location.latitude, location.longitude)
val angle = (360 - location.heading).toFloat()
if (mCarMarker != null) {
mCarMarker!!.isVisible = true
mCarMarker!!.rotateAngle = angle
mCarMarker!!.position = latLng
} else {
@@ -1488,6 +1802,7 @@ class TravelRealityView @JvmOverloads constructor(
// mCarMarker?.setToTop()
}
if (mCompassMarker != null) {
mCompassMarker!!.isVisible = true
mCompassMarker!!.rotateAngle = angle
mCompassMarker!!.position = latLng
} else {
@@ -1500,6 +1815,11 @@ class TravelRealityView @JvmOverloads constructor(
}
}
private fun hideCarMarker() {
mCarMarker?.isVisible = false
mCompassMarker?.isVisible = false
}
private fun realDrawGlobalPath(polylineOptions: PolylineOptions) {
Log.d(TAG, "realDrawGlobalPath")
if (globalPolyline == null) {