Merge branch 'dev_robotaxi-d_240227_6.3.0' of gitlab.zhidaoauto.com:SCA/L4HA/AndroidApp/MoGoEagleEye into dev_robotaxi-d_240227_6.3.0

This commit is contained in:
xinfengkun
2024-02-28 14:15:51 +08:00
87 changed files with 464 additions and 3030 deletions

View File

@@ -23,7 +23,7 @@ import com.mogo.och.shuttle.passenger.ui.adapter.BusPassengerLineStationsAdapter
import com.mogo.och.shuttle.passenger.constant.BusPassengerConst;
import com.mogo.och.shuttle.passenger.presenter.BaseBusPassengerPresenter;
import com.mogo.och.shuttle.passenger.ui.layoutmanager.CenterLayoutManager;
import com.mogo.och.shuttle.passenger.ui.mapdirectionview.BusPassengerMapDirectionView;
import com.mogo.och.common.module.wigets.mapdirectionview.MapDirectionView;
import com.mogo.och.common.module.utils.NumberFormatUtil;
import com.mogo.och.common.module.wigets.MarqueeTextView;
import com.mogo.och.common.module.wigets.OCHGradientTextView;
@@ -48,7 +48,7 @@ public class BusPassengerRouteFragment extends
private MarqueeTextView mLineName;
private Group mRouteInfoView;
private RecyclerView mStationsListRv;
private BusPassengerMapDirectionView mMapDirectionView;
private MapDirectionView mMapDirectionView;
private BusPassengerLineStationsAdapter mAdapter;
private TextView emptyTv;
private AppCompatImageView mAutopilotIv;
@@ -157,7 +157,6 @@ public class BusPassengerRouteFragment extends
@Override
public void run() {
mMapDirectionView.clearLineMarkers();
}
});
}

View File

@@ -1,354 +0,0 @@
package com.mogo.och.shuttle.passenger.ui.mapdirectionview
import android.content.Context
import android.os.Bundle
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.RelativeLayout
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.findViewTreeViewModelStoreOwner
import com.amap.api.maps.AMap
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.TextureMapView
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
import com.amap.api.maps.model.Marker
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.map.MogoLocation
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.shuttle.passenger.R
import com.mogo.och.shuttle.passenger.ui.IBusPassengerMapDirectionView
import com.mogo.och.shuttle.passenger.utils.BusPassengerMapAssetStyleUtil
/**
* 乘客屏小地图
*/
class BusPassengerMapDirectionView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : RelativeLayout(context, attrs, defStyleAttr), IMoGoChassisLocationGCJ02Listener,
IBusPassengerMapDirectionView, AMap.OnCameraChangeListener,
MapDirectionViewModel.ItineraryViewCallback {
companion object {
//小地图名称
const val TAG = "BusPassengerMapDirectionView"
}
private lateinit var mAMapNaviView: TextureMapView
private lateinit var mAMap: AMap
private var mPolyline: Polyline? = null
private val mLineMarkers: MutableList<Marker> = ArrayList()
private lateinit var mCarMarker: Marker
private val mLineStationLatLng: MutableList<LatLng> = ArrayList() //站点坐标数据
var textureList: MutableList<BitmapDescriptor?> = ArrayList()
var texIndexList: MutableList<Int> = ArrayList()
private var mArrivedRes: BitmapDescriptor? = null
private var mUnArrivedRes: BitmapDescriptor? = null
private val routeArrived: MutableList<LatLng> = ArrayList()
private val routeArriving: MutableList<LatLng> = ArrayList()
private var location: MogoLocation? = null
init {
try {
initView(context)
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun initView(context: Context) {
d(SceneConstant.M_BUS_P + TAG, "initView")
val smpView = LayoutInflater.from(context).inflate(R.layout.shuttle_p_jl_map_view, this)
mAMapNaviView = smpView.findViewById<View>(R.id.bus_p_line_amap_view) as TextureMapView
initAMapView()
// 注册定位监听
CallerChassisLocationGCJ02ListenerManager.addListener(TAG, 10, this)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
// 注册定位监听
CallerChassisLocationGCJ02ListenerManager.removeListener(TAG)
}
private fun initAMapView() {
mAMap = mAMapNaviView.map
// 设置导航地图模式aMap是地图控制器对象。
mAMap.mapType = AMap.MAP_TYPE_NIGHT
// 关闭显示实时路况图层aMap是地图控制器对象。
mAMap.isTrafficEnabled = false
// 设置 锚点 图标
mCarMarker = mAMap.addMarker(
MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.drawable.shuttle_p_jl_map_car))
.anchor(0.5f, 0.5f)
)
mArrivedRes = BitmapDescriptorFactory.fromResource(R.drawable.shuttle_p_jl_map_arrow_arrived)
mUnArrivedRes = BitmapDescriptorFactory.fromResource(R.drawable.shuttle_p_jl_map_arrow_un_arrive)
// 加载自定义样式
val customMapStyleOptions = CustomMapStyleOptions()
.setEnable(true)
.setStyleData(
BusPassengerMapAssetStyleUtil.getAssetsStyle(
context, "map_style.data"
)
)
.setStyleExtraData(
BusPassengerMapAssetStyleUtil.getAssetsExtraStyle(
context, "map_style_extra.data"
)
)
// 设置自定义样式
mAMap.setCustomMapStyle(customMapStyleOptions)
// 设置地图的样式
mAMap.uiSettings.apply {
isZoomControlsEnabled = false // 地图缩放级别的交换按钮
setAllGesturesEnabled(true) // 所有手势
isMyLocationButtonEnabled = false // 显示默认的定位按钮
setLogoBottomMargin(-150) //设置Logo下边界距离屏幕底部的边距,设置为负值即可
}
mAMap.setOnMapLoadedListener {
d(SceneConstant.M_BUS_P + TAG, "smp---onMapLoaded")
// 加载自定义样式
val options = CustomMapStyleOptions()
.setEnable(true)
.setStyleData(
BusPassengerMapAssetStyleUtil.getAssetsStyle(
context, "map_style.data"
)
)
.setStyleExtraData(
BusPassengerMapAssetStyleUtil.getAssetsExtraStyle(
context, "map_style_extra.data"
)
)
// 设置自定义样式
mAMap.setCustomMapStyle(options)
mAMapNaviView.map.setPointToCenter(
mAMapNaviView.width / 2,
mAMapNaviView.height / 2
)
}
//设置地图状态的监听接口
mAMap.setOnCameraChangeListener(this)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
val viewModel = findViewTreeViewModelStoreOwner()?.let {
ViewModelProvider(it).get(MapDirectionViewModel::class.java)
}
viewModel?.setDistanceCallback(this)
}
fun clearMapView() {
UiThreadHandler.post( {
clearPolyline()
clearCoordinatesLatLng()
}, UiThreadHandler.MODE.QUEUE)
}
override fun onChassisLocationGCJ02(mogoLocation: MogoLocation?) {
if (mogoLocation == null) {
return
}
val currentLatLng = LatLng(mogoLocation.latitude, mogoLocation.longitude)
//更新车辆位置
mCarMarker.rotateAngle = (360 - mogoLocation.heading).toFloat()
mCarMarker.position = currentLatLng
mCarMarker.setToTop()
try {
//圈定地图显示范围
val boundsBuilder = LatLngBounds.Builder()
routeArrived.forEach {
boundsBuilder.include(it)
}
routeArriving.forEach {
boundsBuilder.include(it)
}
mLineStationLatLng.forEach {
boundsBuilder.include(it)
}
boundsBuilder.include(currentLatLng)
mAMap.moveCamera(
CameraUpdateFactory.newLatLngBoundsRect(
boundsBuilder.build(),
100,
100,
100,
100
)
)
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun drawablePolyline() {
if (routeArrived.isEmpty() && routeArriving.isEmpty()) {
d(SceneConstant.M_TAXI + TAG, "没有点")
return
}
try {
texIndexList.clear()
val allPoints = ArrayList(routeArrived)
for (i in routeArrived.indices) {
if (routeArrived.size > 1 && i < routeArrived.size - 1) {
texIndexList.add(0)
}
}
texIndexList.add(0)
location?.let {
allPoints.add(LatLng(it.latitude, it.longitude))
}
allPoints.addAll(routeArriving)
for (ignored in routeArrived) {
texIndexList.add(1)
}
mPolyline?.let {
it.points = allPoints
it.options.customTextureIndex = texIndexList
return
}
if (textureList.isEmpty()) {
textureList.add(mArrivedRes)
textureList.add(mUnArrivedRes)
}
//设置线段纹理
val polylineOptions = PolylineOptions().apply {
addAll(allPoints)
isUseTexture = true
width(15f)
lineCapType(PolylineOptions.LineCapType.LineCapRound)
customTextureList = textureList
customTextureIndex = texIndexList
}
// 绘制线
mPolyline = mAMap.addPolyline(polylineOptions)
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun clearPolyline() {
mPolyline?.remove()
mPolyline = null
}
override fun setLineMarker() {}
fun clearCoordinatesLatLng() {
textureList.clear()
texIndexList.clear()
routeArrived.clear()
routeArriving.clear()
mLineStationLatLng.clear()
d(SceneConstant.M_BUS_P + TAG, " mCoordinatesLatLng.clear ")
}
fun onCreateView(savedInstanceState: Bundle?) {
mAMapNaviView.onCreate(savedInstanceState)
}
fun onResume() {
mAMapNaviView.onResume()
}
fun onPause() {
mAMapNaviView.onPause()
}
fun onDestroy() {
mAMapNaviView.onDestroy()
}
override fun setCoordinatesLatLng(
routeArrived: List<LatLng>,
routeArriving: List<LatLng>,
location: MogoLocation?
) {
this.routeArrived.clear()
this.routeArrived.addAll(routeArrived)
this.routeArriving.clear()
this.routeArriving.addAll(routeArriving)
this.location = location
UiThreadHandler.post({
drawablePolyline()
}, UiThreadHandler.MODE.QUEUE)
}
fun clearLineMarkers() {
for (i in mLineMarkers.indices) {
mLineMarkers[i].isVisible = false
mLineMarkers[i].remove()
}
mLineMarkers.clear()
}
fun setLinePointMarkerAndDraw(mLineStationsList: List<LatLng>, currentIndex: Int) {
clearLineMarkers()
mLineStationLatLng.clear()
mLineStationLatLng.addAll(mLineStationsList)
if (mLineStationsList.isNotEmpty()) {
// 起点marker, 终点marker, 过站marker, 未过站marker
val size = mLineStationsList.size
val mStartMarker = mAMap.addMarker(
MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.shuttle_p_jl_map_start_point))
)
val mEndMarker = mAMap.addMarker(
MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.shuttle_p_jl_map_end_point))
)
mStartMarker.position = mLineStationsList[0]
mLineMarkers.add(0, mStartMarker)
for (i in mLineStationsList.indices) {
if (currentIndex <= i && i < size - 1 && i > 0) { //未到达
val unArrivedMarker = mAMap.addMarker(
MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.shuttle_p_jl_map_unarrived_point))
)
unArrivedMarker.position = mLineStationsList[i]
mLineMarkers.add(i, unArrivedMarker)
} else if (i in 1 until currentIndex) {
val arrivedMarker = mAMap.addMarker(
MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.shuttle_p_jl_map_arrived_point))
)
arrivedMarker.position = mLineStationsList[i]
mLineMarkers.add(i, arrivedMarker)
}
}
mEndMarker.position = mLineStationsList[size - 1]
mLineMarkers.add(size - 1, mEndMarker)
}
}
override fun onCameraChange(cameraPosition: CameraPosition) {
}
override fun onCameraChangeFinish(cameraPosition: CameraPosition) {}
}

View File

@@ -1,60 +0,0 @@
package com.mogo.och.shuttle.passenger.ui.mapdirectionview
import androidx.lifecycle.ViewModel
import com.amap.api.maps.model.LatLng
import com.mogo.eagle.core.data.map.MogoLocation
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.och.common.module.manager.distancemamager.ITrajectoryListener
import com.mogo.och.common.module.manager.distancemamager.TrajectoryAndDistanceManager
class MapDirectionViewModel: ViewModel(), ITrajectoryListener {
private val TAG = MapDirectionViewModel::class.java.simpleName
private var viewCallback: ItineraryViewCallback?=null
init {
TrajectoryAndDistanceManager.addTrajectoryListener(TAG,this)
}
fun setDistanceCallback(viewCallback: ItineraryViewCallback){
this.viewCallback = viewCallback
}
override fun onCleared() {
super.onCleared()
this.viewCallback = null
TrajectoryAndDistanceManager.removeListener(TAG)
}
interface ItineraryViewCallback{
fun setCoordinatesLatLng(routeArrived: List<LatLng>, routeArriving: List<LatLng>, location: MogoLocation?)
}
override fun trajectoryCallback(
routeArrivied: MutableList<MogoLocation>,
routeArriving: MutableList<MogoLocation>,
location: MogoLocation
) {
val routeArrivedTemp: MutableList<LatLng> = ArrayList()
val routeArrivingTemp: MutableList<LatLng> = ArrayList()
var temp: LatLng
for (mogoLocation in routeArrivied) {
temp = LatLng(mogoLocation.latitude, mogoLocation.longitude)
routeArrivedTemp.add(temp)
}
for (mogoLocation in routeArriving) {
temp = LatLng(mogoLocation.latitude, mogoLocation.longitude)
routeArrivingTemp.add(temp)
}
this.viewCallback?.setCoordinatesLatLng(
routeArrivedTemp,
routeArrivingTemp,
location
)
CallerLogger.d(TAG,"已经走过的点routeArrivied:${routeArrivied.size} 未走过的点routeArriving${routeArriving.size}")
}
}

View File

@@ -16,18 +16,15 @@ import com.mogo.eagle.core.data.config.FunctionBuildConfig
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.api.telematic.IReceivedMsgListener
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.telematic.CallerTelematicListenerManager
import com.mogo.eagle.core.function.call.telematic.CallerTelematicManager.sendMsgToServer
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
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.GsonUtils
import com.mogo.eagle.core.utilcode.util.NetworkUtils
import com.mogo.eagle.core.utilcode.util.StringUtils
@@ -36,9 +33,11 @@ import com.mogo.och.common.module.bean.dpmsg.*
import com.mogo.och.common.module.biz.common.socketmessage.OCHSocketMessageManager.pushAppOperationalMsgBox
import com.mogo.och.common.module.biz.constant.OchCommonConst
import com.mogo.och.common.module.biz.network.OchCommonServiceCallback
import com.mogo.och.common.module.utils.CoordinateCalculateRouteUtil
import com.mogo.och.common.module.manager.distancemamager.IDistanceListener
import com.mogo.och.common.module.manager.distancemamager.TrajectoryAndDistanceManager
import com.mogo.och.common.module.manager.loopmanager.BizLoopManager
import com.mogo.och.common.module.manager.loopmanager.LoopInfo
import com.mogo.och.common.module.utils.DateTimeUtil
import com.mogo.och.common.module.utils.RxUtils
import com.mogo.och.common.module.voice.VoiceNotice.showNotice
import com.mogo.och.data.bean.BusRoutesResult
import com.mogo.och.data.bean.BusStationBean
@@ -49,10 +48,8 @@ import com.mogo.och.shuttle.passenger.bean.response.PassengerRoutesResponse
import com.mogo.och.shuttle.passenger.callback.AutoPilotStatusCallback
import com.mogo.och.shuttle.passenger.callback.DrivingInfoCallback
import com.mogo.och.shuttle.passenger.constant.BusPassengerConst
import com.mogo.och.shuttle.passenger.network.PM2ModelLoopManager
import com.mogo.och.shuttle.passenger.network.PassengerServiceManager
import io.reactivex.disposables.Disposable
import mogo.telematics.pad.MessagePad
import io.reactivex.schedulers.Schedulers
import kotlin.math.abs
/**
@@ -62,29 +59,19 @@ import kotlin.math.abs
class PM2DrivingModel private constructor() {
private var mContext: Context? = null
private var mLocation: MogoLocation? = null
private var mRoutePoints = mutableListOf<MogoLocation>()
private var routesResult: BusRoutesResult? = null
private var mCurrentAutoStatus = -1
var mStations = mutableListOf<BusStationBean>()
private var mNextStationIndex = 0 // A-B要到达站的index
private var isGoingToNextStation = false //是否前往下一站过程中
private var mTwoStationsRouts = mutableListOf<MogoLocation>()
private var mPreRouteIndex = 0
private var mWipePreIndex = 0
private var mDrivingInfoCallback: DrivingInfoCallback? = null //行程信息
private var mAutoStatusCallback: AutoPilotStatusCallback? = null //自动驾驶状态
private var operationStatus: PassengerOperationStatusResponse.Result? = null
@Volatile
private var globalPathTruncation: Disposable? = null
private val handler = Handler(Handler.Callback { msg ->
if (msg.what == MSG_QUERY_BUS_P_STATION) {
queryDriverOperationStatus()
@@ -101,12 +88,12 @@ class PM2DrivingModel private constructor() {
}
}
fun init(context : Context){
fun init(context: Context) {
mContext = context
initListener()
queryDriverByLocalDriver()
queryDriverOperationStatus()
startOrStopOrderLoop(true)
BizLoopManager.setLoopFunction(TAG, LoopInfo(2,::queryDriverSiteByCoordinate, scheduler = Schedulers.io()))
}
private fun queryDriverByLocalDriver() {
@@ -120,16 +107,16 @@ class PM2DrivingModel private constructor() {
CallerAutoPilotStatusListenerManager.addListener(TAG, mAutoPilotStatusListener)
// 定位监听
CallerChassisLocationGCJ02ListenerManager.addListener(TAG, 10,mMapLocationListener)
CallerChassisLocationGCJ02ListenerManager.addListener(TAG, 10, mMapLocationListener)
//司乘屏通信监听
CallerTelematicListenerManager.addListener(TAG,mReceivedMsgListener)
//自动驾驶轨迹监听
CallerPlanningRottingListenerManager.addListener(TAG, moGoAutopilotPlanningListener)
CallerTelematicListenerManager.addListener(TAG, mReceivedMsgListener)
//网络监听
IntentManager.getInstance().registerIntentListener(ConnectivityManager.CONNECTIVITY_ACTION, mNetWorkIntentListener)
IntentManager.getInstance()
.registerIntentListener(ConnectivityManager.CONNECTIVITY_ACTION, mNetWorkIntentListener)
TrajectoryAndDistanceManager.addDistanceListener(TAG, trajectoryListener)
}
@@ -140,7 +127,7 @@ class PM2DrivingModel private constructor() {
)
}
fun releaseListener(){
fun releaseListener() {
//自动驾驶状态监听
CallerAutoPilotStatusListenerManager.removeListener(TAG)
@@ -149,8 +136,10 @@ class PM2DrivingModel private constructor() {
CallerTelematicListenerManager.removeListener(TAG)
//自动驾驶轨迹监听
CallerPlanningRottingListenerManager.removeListener(TAG)
cleanStation("release")
TrajectoryAndDistanceManager.removeListener(TAG)
}
fun setDrivingInfoCallback(drivingInfoCallback : DrivingInfoCallback?){
@@ -216,15 +205,43 @@ class PM2DrivingModel private constructor() {
}
}
private val trajectoryListener: IDistanceListener = object : IDistanceListener {
override fun distanceCallback(distance: Float) {
val lastTime = distance / BusPassengerConst.BUS_AVERAGE_SPEED * 3.6 //秒
d(SceneConstant.M_BUS_P + TAG, "轨迹排查==lastSumLength = $distance")
if (routesResult != null) {
for (site in routesResult!!.sites) {
if (site.drivingStatus == BusPassengerConst.STATION_STATUS_STOPPED && !site.isLeaving) {
return
}
}
}
// 小于200m 播报站点介绍
if (distance < 200) {
val stationNext = mStations[mNextStationIndex]
if (!stationNext.isPlayTts) {
if (!StringUtils.isEmpty(stationNext.introduction)) {
showNotice(stationNext.introduction)
stationNext.isPlayTts = true
}
}
}
mDrivingInfoCallback?.updateRemainMT(
distance.toLong(),
lastTime.toLong()
)
}
}
@RequiresApi(Build.VERSION_CODES.O)
private fun speakTTS(msg: String) {
var mAudioManager = mContext?.getSystemService(Context.AUDIO_SERVICE) as AudioManager
var mAudioAttributes = AudioAttributes.Builder()
val mAudioManager = mContext?.getSystemService(Context.AUDIO_SERVICE) as AudioManager
val mAudioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA) //设置声音的用途
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) //设置声音的类型
.build()
var mAudioFocusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) //设置焦点类型
val mAudioFocusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) //设置焦点类型
.setAudioAttributes(mAudioAttributes) //设置声音属性
.setAcceptsDelayedFocusGain(false) //设置接受延迟获取焦点需要设置OnAudioFocusChangeListener来监听焦点的获取
.build()
@@ -249,50 +266,10 @@ class PM2DrivingModel private constructor() {
object : IMoGoChassisLocationGCJ02Listener{
override fun onChassisLocationGCJ02(mogoLocation: MogoLocation?) {
if (null == mogoLocation) return
mLocation = mogoLocation
updateSpeed(mogoLocation)
}
}
private val moGoAutopilotPlanningListener = object : IMoGoPlanningRottingListener{
@Synchronized
override fun onAutopilotRotting(globalPathResp: MessagePad.GlobalPathResp?) {
d(SceneConstant.M_BUS_P + TAG, "och-rotting==globalPathResp = " + GsonUtils.toJson(globalPathResp))
globalPathResp?.let {
d(SceneConstant.M_BUS_P + TAG, "och-rotting==wayPointsSize = " + it.wayPointsList.size)
if (globalPathTruncation != null && !globalPathTruncation!!.isDisposed) {
d(SceneConstant.M_BUS_P + TAG, "1s内不可以接受轨迹")
return@let
}
globalPathTruncation = RxUtils.createSubscribe(1_000) {
d(SceneConstant.M_BUS_P + TAG, "可以接受轨迹")
}
d(SceneConstant.M_BUS_P + TAG, "接受轨迹中")
it.wayPointsList?.let {list->
updateRoutePoints(list)
}
}
}
}
@Synchronized
fun updateRoutePoints(routePoints: List<MessagePad.Location>) {
mRoutePoints.clear()
val latLngModels = CoordinateCalculateRouteUtil
.coordinateConverterWgsToGcjLocations(mContext, routePoints)
d(SceneConstant.M_BUS_P + TAG, "och-rotting==latLngModels = " + latLngModels.size)
mRoutePoints.addAll(latLngModels)
if (isGoingToNextStation){
mTwoStationsRouts.clear()
startRemainRouteInfo()
}
}
private fun updateSpeed(mogoLocation: MogoLocation) {
// km/h
val speedKM = (abs(mogoLocation.gnssSpeed) * 3.6f).toInt()
@@ -407,6 +384,7 @@ class PM2DrivingModel private constructor() {
d(SceneConstant.M_BUS_P+TAG, "queryDriverSiteByCoordinate = %s", msg)
if (code == 1003){
queryDriverOperationDelay()
cleanStation("queryDriverSiteByCoordinate 1003")
}
if (PassengerServiceManager.driverAppSn.isEmpty()){
return
@@ -414,7 +392,6 @@ class PM2DrivingModel private constructor() {
if (code == 1003) {
routesResult = null
isGoingToNextStation = false
startOrStopCalculateRouteInfo(false)
return
}
}
@@ -424,11 +401,10 @@ class PM2DrivingModel private constructor() {
}
private fun updateLocalOrder(){
mRoutePoints.clear()
routesResult = null
mNextStationIndex = 0
cleanStation("queryDriverSiteByCoordinate")
isGoingToNextStation = false
startOrStopCalculateRouteInfo(false)
mDrivingInfoCallback?.showNoTaskView(true)
}
@@ -460,20 +436,20 @@ class PM2DrivingModel private constructor() {
&& station.isLeaving && i + 1 < stations.size) {
mDrivingInfoCallback?.updateStationsInfo(stations as MutableList<BusStationBean>, i + 1, false)
d(SceneConstant.M_BUS_P+TAG,"och-rotting--mNextStationIndex = $mNextStationIndex , i = $i")
// if (mNextStationIndex != i + 1) {
d(SceneConstant.M_BUS_P+TAG,"och-rotting--start ")
mTwoStationsRouts.clear()
startRemainRouteInfo()
// }
d(SceneConstant.M_BUS_P+TAG,"och-rotting--start ")
isGoingToNextStation = true
mNextStationIndex = i + 1
val startStation = mStations[i]
val endStation = mStations[i + 1]
setTrajectoryStation(startStation, endStation, result.lineId)
return
} else if (station.drivingStatus == BusPassengerConst.STATION_STATUS_STOPPED && !station.isLeaving) {
d(SceneConstant.M_BUS_P+TAG,"och-rotting--mNextStationIndex = $mNextStationIndex , i = $i")
d(SceneConstant.M_BUS_P+TAG,"och-rotting--arrived ")
mPreRouteIndex = 0
if (i == stations.size - 1) {
cleanStation("updatePassengerRouteInfo最后一个站点")
}
isGoingToNextStation = false
startOrStopCalculateRouteInfo(false)
mDrivingInfoCallback?.updateStationsInfo(stations as MutableList<BusStationBean>, i, true)
return
}else{
@@ -484,162 +460,22 @@ class PM2DrivingModel private constructor() {
}
fun loopRouteAndWipe(){
if (mRoutePoints != null && mRoutePoints.size > 0 && mLocation != null) {
val haveArrivedIndex = CoordinateCalculateRouteUtil
.getArrivedPointIndexNew(
mWipePreIndex,
mRoutePoints,
mLocation!!
)
mWipePreIndex = haveArrivedIndex
d(SceneConstant.M_BUS_P + TAG,
"thread = " + Thread.currentThread().name + " haveArrivedIndex== " + haveArrivedIndex
)
// if (mAutopilotPlanningCallback != null) {
// val routePoints = CoordinateCalculateRouteUtil
// .coordinateConverterLocationToLatLng(mContext, mRoutePoints)
// mAutopilotPlanningCallback.routeResult(routePoints, haveArrivedIndex)
// }
}
private fun setTrajectoryStation(
startStationInfo: BusStationBean,
endStationInfo: BusStationBean,
lineId: Int
) {
val startStation = MogoLocation()
startStation.longitude = startStationInfo.gcjLon
startStation.latitude = startStationInfo.gcjLat
val endStation = MogoLocation()
endStation.longitude = endStationInfo.gcjLon
endStation.latitude = endStationInfo.gcjLat
TrajectoryAndDistanceManager.setStationPoint(startStation, endStation, lineId.toLong())
}
private fun startRemainRouteInfo() {
//开启实时计算剩余距离,剩余时间,预计时间
startOrStopCalculateRouteInfo(true)
}
fun dynamicCalculateRouteInfo(){
//计算当前位置和下一站的剩余点集合
//计算剩余点总里程和时间
d(SceneConstant.M_BUS_P + TAG, "och-rotting==mTwoStationsRouts.size() = " + mTwoStationsRouts.size)
//计算当前位置和下一站的剩余点集合
//计算剩余点总里程和时间
if (mTwoStationsRouts.size == 0) {
calculateTwoStationsRoute()
}
if (mTwoStationsRouts.size > 0 && mLocation != null) {
val lastPointsMap = CoordinateCalculateRouteUtil
.getRemainPointListByCompareNew(mPreRouteIndex, mTwoStationsRouts, mLocation!!)
for (index in lastPointsMap.keys) {
mPreRouteIndex = index
break
}
for (lastPoints in lastPointsMap.values) {
d(SceneConstant.M_BUS_P + TAG, "och-rotting==lastPoints.size() = " + lastPoints.size)
var lastSumLength = 0f
lastSumLength = if (lastPoints.size == 1) { //只是最后一个点,计算当前位置和最后一个点的距离
if (mNextStationIndex <= mStations.size - 1 && mNextStationIndex >= 0) {
val stationNext: BusStationBean = mStations[mNextStationIndex]
CoordinateUtils.calculateLineDistance(
stationNext.gcjLon, stationNext.gcjLat,
mLocation!!.longitude, mLocation!!.latitude
)
} else {
CoordinateUtils.calculateLineDistance(
lastPoints[0].longitude, lastPoints[0].latitude,
mLocation!!.longitude, mLocation!!.latitude
)
}
} else {
CoordinateCalculateRouteUtil.calculateRouteSumLength(lastPoints)
}
val lastTime = lastSumLength / BusPassengerConst.SHUTTLE_AVERAGE_SPEED * 3.6 //秒
d(SceneConstant.M_BUS_P + TAG, "och-rotting==lastSumLength = $lastSumLength")
// 小于200m 播报站点介绍
// 小于200m 播报站点介绍
if (lastSumLength < 200) {
val stationNext = mStations[mNextStationIndex]
if (!stationNext.isPlayTts) {
if (!StringUtils.isEmpty(stationNext.introduction)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
speakTTS(stationNext.introduction)
}
stationNext.isPlayTts = true
}
}
}
mDrivingInfoCallback?.updateRemainMT(
lastSumLength.toLong(),
lastTime.toLong()
)
}
}
}
private fun calculateTwoStationsRoute() {
//找出前往站对应的轨迹点,拿出两站点的集合
d(SceneConstant.M_BUS_P + TAG, "mRoutePoints.size() = " + mRoutePoints.size)
if (mRoutePoints.size > 0) {
if (mStations.size > 1) { //两个站点及以上要计算两个站点间的轨迹路线
if (mNextStationIndex <= mStations.size - 1 && mNextStationIndex - 1 >= 0) {
mTwoStationsRouts.clear()
val stationNext: BusStationBean = mStations[mNextStationIndex]
val stationCur: BusStationBean = mStations[mNextStationIndex - 1]
//当前站在轨迹中对应的点
val currentRouteIndex = CoordinateCalculateRouteUtil.getArrivedPointIndexNew(
0, mRoutePoints, stationCur.gcjLon, stationCur.gcjLat
)
//要前往的站在轨迹中对应的点
val nextRouteIndex = CoordinateCalculateRouteUtil.getArrivedPointIndexNew(
currentRouteIndex,
mRoutePoints,
stationNext.gcjLon,
stationNext.gcjLat
)
d(SceneConstant.M_BUS_P + TAG, "och-rotting==currentRouteIndex = " + currentRouteIndex
+ " nextRouteIndex = " + nextRouteIndex)
if (currentRouteIndex < nextRouteIndex) { //如果找到的next在起点的轨迹前面直接舍弃这个轨迹不显示
mTwoStationsRouts.addAll(
mRoutePoints.subList(
currentRouteIndex,
nextRouteIndex + 1
)
)
}
}
}
}
}
/**
* 开始轮询计算剩余里程和时间
* @param isStart
*/
fun startOrStopCalculateRouteInfo(isStart: Boolean) {
d(SceneConstant.M_BUS_P+TAG, "startOrStopCalculateRouteInfo() $isStart")
if (isStart) {
PM2ModelLoopManager.startCalculateRouteInfoLoop()
} else {
mTwoStationsRouts.clear()
PM2ModelLoopManager.stopCalculateRouteInfLoop()
}
}
/**
* 实时轨迹擦除
* @param isStart
*/
private fun startOrStopRouteAndWipe(isStart: Boolean) {
if (isStart) {
PM2ModelLoopManager.startOrStopRouteAndWipe()
} else {
mWipePreIndex = 0
PM2ModelLoopManager.stopOrStopRouteAndWipe()
}
}
private fun startOrStopOrderLoop(start: Boolean) {
d(SceneConstant.M_BUS_P + TAG, "startOrStopOrderLoop() $start")
if (start) {
PM2ModelLoopManager.startQueryDriverLineLoop()
} else {
PM2ModelLoopManager.stopQueryDriverLineLoop()
}
private fun cleanStation(type: String) {
d(SceneConstant.M_BUS_P + TAG, "清理站点:$type")
TrajectoryAndDistanceManager.setStationPoint(null, null, -1L)
}
}

View File

@@ -1,127 +0,0 @@
package com.mogo.och.shuttle.passenger.network
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.i
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.och.shuttle.passenger.constant.BusPassengerConst
import com.mogo.och.shuttle.passenger.model.PM2DrivingModel
import io.reactivex.Observable
import io.reactivex.ObservableOnSubscribe
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import java.util.concurrent.TimeUnit
/**
* @author: wangmingjun
* @date: 2023/2/1
*/
object PM2ModelLoopManager {
private val TAG: String = PM2ModelLoopManager::class.java.getSimpleName()
private var mQueryLineDisposable: Disposable? = null //心跳轮询
private var mRouteWipeDisposable: CompositeDisposable? = null //估计擦除
private var mCalculateRouteDisposable: CompositeDisposable? = null //每隔2s计算一次剩余里程和时间
fun startOrStopRouteAndWipe() {
i(SceneConstant.M_BUS_P + TAG, "startOrStopRouteWipe()")
if (mRouteWipeDisposable != null) return
if (mRouteWipeDisposable == null) {
mRouteWipeDisposable = CompositeDisposable()
}
val disposable = startLoopRouteAndWipe()
.doOnSubscribe { }
.doOnError { }
.delay(
BusPassengerConst.LOOP_LINE_1S,
TimeUnit.MILLISECONDS,
true
) // 设置delayError为true表示出现错误的时候也需要延迟5s进行通知达到无论是请求正常还是请求失败都是5s后重新订阅即重新请求。
.subscribeOn(Schedulers.io())
.repeat() // repeat保证请求成功后能够重新订阅。
.retry() // retry保证请求失败后能重新订阅
.observeOn(AndroidSchedulers.mainThread())
.subscribe { }
mRouteWipeDisposable!!.add(disposable)
}
fun stopOrStopRouteAndWipe() {
if (mRouteWipeDisposable != null) {
mRouteWipeDisposable!!.dispose()
mRouteWipeDisposable = null
}
}
fun startQueryDriverLineLoop() {
if (mQueryLineDisposable != null && !mQueryLineDisposable!!.isDisposed) {
return
}
i(SceneConstant.M_BUS_P + TAG, "startQueryDriverLineLoop()")
mQueryLineDisposable = Observable.interval(
BusPassengerConst.LOOP_DELAY,
BusPassengerConst.LOOP_LINE_2S, TimeUnit.MILLISECONDS
)
.map { aLong: Long -> aLong + 1 }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { aLong: Long? ->
PM2DrivingModel.INSTANCE.queryDriverSiteByCoordinate()
}
}
fun stopQueryDriverLineLoop() {
if (mQueryLineDisposable != null) {
i(SceneConstant.M_BUS_P + TAG, "stopQueryDriverLineLoop()")
mQueryLineDisposable!!.dispose()
mQueryLineDisposable = null
}
}
fun startCalculateRouteInfoLoop() {
i(SceneConstant.M_BUS_P + TAG, "startCalculateRouteInfoLoop()")
if (mCalculateRouteDisposable != null) return
if (mCalculateRouteDisposable == null) {
mCalculateRouteDisposable = CompositeDisposable()
}
val disposable = startLoopCalculateRouteInfo()
.doOnSubscribe { }
.doOnError { }
.delay(
BusPassengerConst.LOOP_LINE_2S,
TimeUnit.MILLISECONDS,
true
) // 设置delayError为true表示出现错误的时候也需要延迟5s进行通知达到无论是请求正常还是请求失败都是5s后重新订阅即重新请求。
.subscribeOn(Schedulers.io())
.repeat() // repeat保证请求成功后能够重新订阅。
.retry() // retry保证请求失败后能重新订阅
.observeOn(AndroidSchedulers.mainThread())
.subscribe { }
mCalculateRouteDisposable!!.add(disposable)
}
fun stopCalculateRouteInfLoop() {
if (mCalculateRouteDisposable != null) {
i(SceneConstant.M_BUS_P + TAG, "stopCalculateRouteInfLoop()")
mCalculateRouteDisposable!!.dispose()
mCalculateRouteDisposable = null
}
}
private fun startLoopRouteAndWipe(): Observable<Int?> {
return Observable.create(ObservableOnSubscribe { emitter ->
if (emitter.isDisposed) return@ObservableOnSubscribe
PM2DrivingModel.INSTANCE.loopRouteAndWipe()
emitter.onComplete()
})
}
private fun startLoopCalculateRouteInfo(): Observable<Int?> {
return Observable.create(ObservableOnSubscribe { emitter ->
if (emitter.isDisposed) return@ObservableOnSubscribe
PM2DrivingModel.INSTANCE.dynamicCalculateRouteInfo()
emitter.onComplete()
})
}
}