[fea]
[算路模块修改]
This commit is contained in:
yangyakun
2024-10-10 19:01:20 +08:00
parent 8299e138e8
commit 01553cbbef
48 changed files with 2054 additions and 2402 deletions

View File

@@ -131,28 +131,30 @@ class LoginFragment : MvpFragment<LoginFragment?, LoginPresenter?>(), ILoginView
showLoginInfoAnimator2?.interpolator = DecelerateInterpolator()
}
UiThreadHandler.postDelayed({
val animatorSet = AnimatorSet()
animatorSet.playTogether(showLoginInfoAnimator1, showLoginInfoAnimator2)
animatorSet.duration = 500
animatorSet.addListener(object :AnimatorListener{
override fun onAnimationStart(animation: Animator) {
cl_login_info.visibility = View.VISIBLE
}
cl_login_info?.let {
val animatorSet = AnimatorSet()
animatorSet.playTogether(showLoginInfoAnimator1, showLoginInfoAnimator2)
animatorSet.duration = 500
animatorSet.addListener(object :AnimatorListener{
override fun onAnimationStart(animation: Animator) {
cl_login_info?.visibility = View.VISIBLE
}
override fun onAnimationEnd(animation: Animator) {
override fun onAnimationEnd(animation: Animator) {
}
}
override fun onAnimationCancel(animation: Animator) {
override fun onAnimationCancel(animation: Animator) {
}
}
override fun onAnimationRepeat(animation: Animator) {
override fun onAnimationRepeat(animation: Animator) {
}
}
})
animatorSet.start()
})
animatorSet.start()
}
},2_000,UiThreadHandler.MODE.QUEUE)
}

View File

@@ -327,6 +327,69 @@ object LineManager : CallerBase<ILineCallback>() {
0L
)
}
val wayLatLons = mutableListOf<AutoPilotLonLat>()
// 途经点
if (!contrai.passPoints.isNullOrEmpty()) {
for (mogoLatLng in contrai.passPoints!!) {
wayLatLons.add(
AutoPilotLonLat(
mogoLatLng.lat,
mogoLatLng.lon,
when (mogoLatLng.pointType) {
1 -> {//途径点
false
}
2 -> {//禁行点
false
}
3 -> {//站点
true
}
else -> {
false
}
}
)
)
}
}
val blackLatLons = mutableListOf<AutoPilotLonLat>()
// 黑名单点
if (!contrai.blackPoints.isNullOrEmpty()) {
for (mogoLatLng in contrai.blackPoints!!) {
blackLatLons.add(
AutoPilotLonLat(
mogoLatLng.lat,
mogoLatLng.lat,
when (mogoLatLng.pointType) {
1 -> {//途径点
false
}
2 -> {//禁行点
false
}
3 -> {//站点
true
}
else -> {
false
}
}
)
)
}
}
parameters?.wayLatLons = wayLatLons
parameters?.blackLatLons = blackLatLons
}
if (parameters == null) {
ToastUtils.showShort("未设置起始或终点站点")

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:background="@color/common_f7151d41"
android:id="@+id/no_order_data_view">
<ImageView
android:id="@+id/no_order_data_iv"
android:layout_width="@dimen/dp_198"
android:layout_height="@dimen/dp_158"
android:src="@drawable/common_empty"
android:scaleType="fitXY"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<TextView
android:id="@+id/no_order_data_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/common_B3FFFFFF"
android:textSize="@dimen/dp_40"
android:gravity="center"
android:layout_marginTop="@dimen/dp_31"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/no_order_data_iv"
android:text="@string/common_empty_data"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:background="@color/common_f7151d41"
android:id="@+id/no_order_data_view">
<ImageView
android:id="@+id/no_order_data_iv"
android:layout_width="@dimen/dp_198"
android:layout_height="@dimen/dp_158"
android:src="@drawable/common_empty"
android:scaleType="fitXY"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<TextView
android:id="@+id/tv_error_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/common_B3FFFFFF"
android:textSize="@dimen/dp_40"
android:gravity="center"
android:layout_marginTop="@dimen/dp_31"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/no_order_data_iv"
android:text="@string/common_empty_data"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -31,4 +31,5 @@
<string name="common_change2_pxjs_manual">平行驾驶已退出,请立即接管,注意周边环境 小心驾驶</string>
<string name="common_biz_loading">加载中……</string>
<string name="common_empty_data">暂无数据</string>
</resources>

View File

@@ -20,6 +20,7 @@ public class BusStationBean {
private boolean leaving;
private String introduction;// 站点简介
private boolean isPlayTts;
private int pointType; // 1:途径点 2:禁行点 3:站点
public String getNameKr() {
return nameKr;
@@ -117,6 +118,14 @@ public class BusStationBean {
isPlayTts = playTts;
}
public int getPointType() {
return pointType;
}
public void setPointType(int pointType) {
this.pointType = pointType;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -130,13 +139,14 @@ public class BusStationBean {
&& Double.compare(that.lat, lat) == 0
&& drivingStatus == that.drivingStatus
&& leaving == that.leaving
&& pointType == that.pointType
&& name.equals(that.name)
&& (nameKr == null || nameKr.equals(that.nameKr));
}
@Override
public int hashCode() {
return Objects.hash(siteId, name, nameKr, seq, gcjLon, gcjLat, lon, lat, drivingStatus, leaving);
return Objects.hash(siteId, name, nameKr, seq, gcjLon, gcjLat, lon, lat, drivingStatus, leaving,pointType);
}
@Override
@@ -154,6 +164,7 @@ public class BusStationBean {
", leaving=" + leaving +
", introduction='" + introduction + '\'' +
", isPlayTts=" + isPlayTts +
", pointType=" + pointType +
'}';
}
}

View File

@@ -30,4 +30,7 @@ data class ContraiInfo(
* 文件的保存时间
*/
val contrailSaveTime: Long,
var passPoints: MutableList<BusStationBean>?, // 用于算路的经停点
var blackPoints: MutableList<BusStationBean>?, // 用于算路的黑名單點
)

View File

@@ -23,6 +23,7 @@ import com.mogo.och.weaknet.ui.bizswitch.SwtichBizeModel
import kotlinx.android.synthetic.main.shuttle_wadk_task_running.view.no_order_data_view
import kotlinx.android.synthetic.main.shuttle_weak_switch_line.view.aciv_refresh_task
import kotlinx.android.synthetic.main.shuttle_weak_switch_line.view.actv_last_refresh_date
import kotlinx.android.synthetic.main.shuttle_weak_switch_line.view.include_empty
import kotlinx.android.synthetic.main.shuttle_weak_switch_line.view.switch_line_rv
import me.jessyan.autosize.utils.AutoSizeUtils
@@ -135,10 +136,10 @@ class SwitchLineView: WindowRelativeLayout, SwtichLineModel.SwtichLineViewCallba
BizLoopManager.runInMainThread{
if (b) {
switch_line_rv.visibility = View.GONE
no_order_data_view.visibility = View.VISIBLE
include_empty.visibility = View.VISIBLE
} else {
switch_line_rv.visibility = View.VISIBLE
no_order_data_view.visibility = View.GONE
include_empty.visibility = View.GONE
}
}
}

View File

@@ -37,9 +37,6 @@ class TaskBottomDecoration(val distance: Int) : RecyclerView.ItemDecoration() {
}else{
outRect.bottom = distance
}
// if(pos==itemCount-1){
// outRect.bottom = distance
// }
}
//super.getItemOffsets(outRect, view, parent, state)
}

View File

@@ -47,12 +47,16 @@
app:layout_constraintTop_toBottomOf="@+id/actv_last_refresh_date"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginTop="@dimen/dp_22" />
<include
android:layout_width="match_parent"
android:id="@+id/include_empty"
layout="@layout/shuttle_weak_empty_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
layout="@layout/shuttle_weak_no_data_common_view"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,9 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mogo.och.unmanned.taxi">
<application>
<activity android:name=".ui.routing.TaxiRoutingChooseLineActivity"
android:theme="@style/RoutingChooseLineDialogStyle"
android:launchMode="singleTask"
android:screenOrientation="landscape" />
</application>
</manifest>

View File

@@ -1,6 +1,8 @@
package com.mogo.och.unmanned.taxi.bean
import com.mogo.eagle.core.data.BaseData
import com.mogo.och.data.bean.BusStationBean
import com.mogo.och.data.bean.ContraiInfo
/**
* 灰度路线信息
@@ -28,7 +30,19 @@ data class RoutingSite(
var wgs84Lon: Double,//高精坐标
var wgs84Lat: Double,//高精坐标
var pointType: Int // 1:途径点 2:禁行点 3:站点
)
) {
fun toBusStationBean(): BusStationBean {
val temp = BusStationBean()
temp.siteId = siteId.toInt()
temp.name = siteName
temp.lat = wgs84Lat
temp.lon = wgs84Lon
temp.gcjLat = gcjLat
temp.gcjLon = gcjLon
temp.pointType = pointType
return temp
}
}
/**
* 轨迹信息
@@ -50,7 +64,19 @@ data class ContrailBean(
var version: Long = -1L,
var passPoints: MutableList<RoutingSite>?, // 用于算路的经停点
var blackPoints: MutableList<RoutingSite>?, // 用于算路的黑名單點
)
) {
fun toContraiInfo(): ContraiInfo {
val tempPassPoints = mutableListOf<BusStationBean>()
passPoints?.forEach {
tempPassPoints.add(it.toBusStationBean())
}
val tempblackPoints = mutableListOf<BusStationBean>()
blackPoints?.forEach {
tempPassPoints.add(it.toBusStationBean())
}
return ContraiInfo(lineId,csvFileUrl,csvFileMd5,txtFileUrl,txtFileMd5,contrailSaveTime,tempPassPoints,tempblackPoints)
}
}
/**
* 查询灰度线路列表

View File

@@ -8,11 +8,6 @@ import com.mogo.eagle.core.data.map.MogoLocation;
* Model->Presenter回调状态控制器监听accOn、adas ui show、voice ui show、push ui show、v2x ui show等等
*/
public interface ITaxiControllerStatusCallback {
// 是否vr map模式
void onVRModeChanged(boolean isVRMode);
// 自车定位
void onCarLocationChanged(MogoLocation location);
//开始开启自动驾驶
void startOpenAutopilot();

View File

@@ -1,342 +0,0 @@
package com.mogo.och.unmanned.taxi.ui.base
import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.view.View
import androidx.fragment.app.FragmentTransaction
import com.mogo.commons.mvp.IView
import com.mogo.commons.mvp.MvpFragment
import com.mogo.commons.mvp.Presenter
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.och.toolkit.IToolKitItemClickListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.getState
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager
import com.mogo.eagle.core.function.call.och.CallerEagleBaseFunctionCall4OchManager
import com.mogo.eagle.core.function.view.MapRoamView
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.map.listener.IMogoMapListener
import com.mogo.map.uicontroller.VisualAngleMode
import com.mogo.och.common.module.wigets.map.drawline.LineView
import com.mogo.och.unmanned.taxi.R
import com.mogo.och.unmanned.taxi.constant.TaxiUnmannedConst
import com.mogo.och.unmanned.taxi.ui.navi.amap.TaxiAmapNaviFragment
import com.mogo.och.unmanned.taxi.ui.navi.auto.TaxiRoutingNaviFragment
import com.mogo.och.unmanned.taxi.ui.operational.TaxiOperationalDialogFragment
import kotlinx.android.synthetic.main.unmanned_taxi_base_fragment.unmannedMapCL
import kotlinx.android.synthetic.main.unmanned_taxi_base_fragment.module_mogo_och_navi_panel_container
import kotlinx.android.synthetic.main.unmanned_taxi_base_fragment.taxi_close_navi_icon
import java.lang.ref.WeakReference
/**
* @author: wangmingjun
* @date: 2023/7/24
*/
abstract class BaseTaxiTabFragment<V : IView, P : Presenter<V>> : MvpFragment<V, P>(),
IMogoMapListener, IMoGoAutopilotRecordListener {
companion object {
const val TAG = "BaseTaxiTabFragment"
}
// 高德导航fragment
private var ochAmapNaviFragment: TaxiAmapNaviFragment? = null
// 高德地图轨迹展示fragment
private var taxiRoutingNaviFragment: TaxiRoutingNaviFragment? = null
private val runningTaskGateWay = "RUNNINGTASKGATEWAY"
private val lineView = "LINEVIEW"
private var personalDialogFragment: WeakReference<TaxiOperationalDialogFragment>? = null
override fun getLayoutId(): Int {
return R.layout.unmanned_taxi_base_fragment
}
fun showDebugPanel() {
}
fun getDebugPanelView(): View? {
return null
}
@SuppressLint("UseCompatLoadingForDrawables")
override fun initViews() {
updateCtvAutopilotStatusTag(false)
onAutopilotStatusChanged(
getState(),
CallerAutoPilotControlManager.isCanStartAutopilot(false)
)
CallerHmiViewControlListenerManager.invokeMainPageViewVisible(View.VISIBLE)
taxi_close_navi_icon.setOnClickListener {
showAmapNaviToStationFragment(false)
showRoutingToStationFragment(false)
}
context?.let {
CallerEagleBaseFunctionCall4OchManager.addSingleToolKitDefaultItem(
runningTaskGateWay,
"运营看板",
R.drawable.common_biz_operation,
4
);
CallerEagleBaseFunctionCall4OchManager.addToolKitDefaultItemClickListener(
runningTaskGateWay,
object :
IToolKitItemClickListener {
override fun onItemClick(toolTag: String, ctx: Context?) {
when (toolTag) {
runningTaskGateWay -> {
personalDialogFragment =
WeakReference(TaxiOperationalDialogFragment())
activity?.supportFragmentManager?.let {
personalDialogFragment!!.get()
?.show(it, "service_data")
}
}
}
}
});
CallerEagleBaseFunctionCall4OchManager.addSingleToolKitCustomItem(
lineView,
LineView(it),
10
);
}
}
abstract fun stopAutoStartAutopilot()
override fun initViews(savedInstanceState: Bundle?) {
super.initViews(savedInstanceState)
unmannedMapCL.onCreate(savedInstanceState)
}
override fun onResume() {
super.onResume()
unmannedMapCL.onResume()
}
override fun onPause() {
super.onPause()
unmannedMapCL.onPause()
}
protected open fun onChangeOperationStatus() {}
override fun onLowMemory() {
super.onLowMemory()
unmannedMapCL.onLowMemory()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
unmannedMapCL.onSaveInstanceState(outState)
}
override fun onDestroyView() {
unmannedMapCL.onDestroy()
CallerAutopilotRecordListenerManager.removeListener(TAG)
super.onDestroyView()
}
/**
* 改变自动驾驶状态
*
* @param status 2 - running 1 - enable 2 - disable
*/
fun onAutopilotStatusChanged(status: Int, canStartAuto: Boolean) {
activity?.runOnUiThread(Runnable runOnUiThread@{
if (isStarting && IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING != status) {
// 1. 主动开启自动驾驶中不为2为0、1则继续loading
return@runOnUiThread
}
if (isStarting && IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING == status
) {
// 2. 主动开启自动驾驶中为2则停止loading并isStarting = false
startAutopilotDone(true)
return@runOnUiThread
}
// 3. 其他过程直接更新
startOrStopLoadingAnim(false)
updateAutopilotBtnByStatus(status, canStartAuto)
})
}
/**
* 停止【开启自动驾驶按钮】动画,并更新按钮状态
*/
fun stopAnimAndUpdateBtnStatus() {
startOrStopLoadingAnim(false)
startAutopilotDone(false)
}
/**
* 平行驾驶 【开启自动驾驶按钮】 更新
*/
fun onParallelDrivingStatus(parallelDrivingValue: Int, canStartAuto: Boolean) {
updateAutopilotBtnByStatus(parallelDrivingValue, canStartAuto)
}
private fun updateCtvAutopilotStatusTag(tag: Boolean) {
}
private fun updateAutopilotBtnByStatus(status: Int, canStartAuto: Boolean) {
}
var isStarting = false
@SuppressLint("ObjectAnimatorBinding")
fun startOrStopLoadingAnim(start: Boolean) {
if (start) {
isStarting = true
startingAutopilotCountDown()
} else {
isStarting = false
}
}
private fun startAutopilotDone(success: Boolean) {
UiThreadHandler.postDelayed({
startOrStopLoadingAnim(false)
onAutopilotStatusChanged(
getState(),
CallerAutoPilotControlManager.isCanStartAutopilot(false)
)
}, 1000L)
}
private fun startingAutopilotCountDown() {
UiThreadHandler.postDelayed({
//未启动成功10s后做处理
if (isStarting) { //判断动画是否在进行
//并且根据状态来设置自动驾驶启动成功还是失败
if (getState()
== IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING
) {
startAutopilotDone(true)
} else {
startAutopilotDone(false)
}
}
}, TaxiUnmannedConst.TIMER_START_AUTOPILOT_INTERVAL)
}
/**
* 获取站点面板view在[.initViews]时候添加到container中
*
* @return 站点面板view
*/
abstract fun getStationPanelViewId(): Int
/**
* 重新开启自动驾驶
*/
abstract fun startAutopilot()
fun changeOperationViewVisible(visible: Int) {
}
override fun onMapVisualAngleChanged(visualAngleMode: VisualAngleMode?) {
}
fun showAmapNaviToStationFragment(isShow: Boolean) {
val transaction: FragmentTransaction = childFragmentManager.beginTransaction()
closeAmapViewIFHadeAdd()
if (isShow) {
closeRoutingViewIfHadAdd()
ochAmapNaviFragment = TaxiAmapNaviFragment.newInstance()
if (ochAmapNaviFragment!!.isAdded) {
return
}
transaction.add(R.id.module_mogo_och_navi_panel_container, ochAmapNaviFragment!!)
.show(ochAmapNaviFragment!!)
transaction.commitAllowingStateLoss()
taxi_close_navi_icon.visibility = View.VISIBLE
module_mogo_och_navi_panel_container.visibility = View.VISIBLE
} else {
taxi_close_navi_icon.visibility = View.GONE
module_mogo_och_navi_panel_container.visibility = View.INVISIBLE
}
}
private fun closeAmapViewIFHadeAdd() {
if (ochAmapNaviFragment != null) {
val transaction: FragmentTransaction = childFragmentManager.beginTransaction()
ochAmapNaviFragment!!.onDestroy()
transaction.remove(ochAmapNaviFragment!!)
transaction.commitAllowingStateLoss()
ochAmapNaviFragment = null
}
}
private fun closeRoutingViewIfHadAdd() {
if (taxiRoutingNaviFragment != null) {
val transaction: FragmentTransaction = childFragmentManager.beginTransaction()
taxiRoutingNaviFragment!!.onDestroy()
transaction.remove(taxiRoutingNaviFragment!!)
transaction.commitAllowingStateLoss()
taxiRoutingNaviFragment = null
}
}
fun showRoutingToStationFragment(isShow: Boolean) {
val transaction: FragmentTransaction = childFragmentManager.beginTransaction()
closeRoutingViewIfHadAdd()
if (isShow) {
closeAmapViewIFHadeAdd()
taxiRoutingNaviFragment = TaxiRoutingNaviFragment.newInstance()
if (taxiRoutingNaviFragment!!.isAdded) {
return
}
transaction.add(R.id.module_mogo_och_navi_panel_container, taxiRoutingNaviFragment!!)
.show(taxiRoutingNaviFragment!!)
transaction.commitAllowingStateLoss()
taxi_close_navi_icon.visibility = View.VISIBLE
module_mogo_och_navi_panel_container.visibility = View.VISIBLE
} else {
taxi_close_navi_icon.visibility = View.GONE
module_mogo_och_navi_panel_container.visibility =
View.INVISIBLE //2023.9.4高德导航由gone设置成INVISIBLE,保留导航实例,避免导航被挂起
}
}
abstract fun startNaviToEndStation(isShow: Boolean)
fun showStartAutopilotBlinkAnimation() {
}
abstract fun pauseStartAutopilot()
abstract fun resumeStartAutopilot(remainingTime: Long)
fun stopAutopilotBlinkAnimation() {
stopStartAutopilotBlinkAnimation()
}
private fun stopStartAutopilotBlinkAnimation() {
}
fun pauseAutopilotBlinkAnimation() {
}
fun resumeAutopilotBlinkAnimation() {
}
fun setGuidShow() {
}
fun setGuidHide() {
}
}

View File

@@ -1,137 +1,135 @@
package com.mogo.och.unmanned.taxi.ui.base
import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.FragmentTransaction
import com.mogo.commons.module.status.IMogoStatusChangedListener
import com.mogo.commons.module.status.MogoStatusManager
import com.mogo.commons.module.status.StatusDescriptor
import com.mogo.eagle.core.data.temp.EventLogout
import com.mogo.commons.mvp.MvpFragment
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.och.toolkit.IToolKitItemClickListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.getState
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
import com.mogo.eagle.core.function.call.och.CallerEagleBaseFunctionCall4OchManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.e
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.map.listener.IMogoMapListener
import com.mogo.map.uicontroller.VisualAngleMode
import com.mogo.och.common.module.biz.login.OpenOrderStatusEnum
import com.mogo.och.common.module.biz.order.TaxiOrderStatusEnum
import com.mogo.och.common.module.utils.FlowBus
import com.mogo.och.common.module.wigets.map.drawline.LineView
import com.mogo.och.unmanned.taxi.R
import com.mogo.och.unmanned.taxi.constant.TaxiDriverEventConst
import com.mogo.och.unmanned.taxi.ui.routing.TaxiRoutingFragment
import com.mogo.och.unmanned.taxi.constant.TaxiUnmannedConst
import com.mogo.och.unmanned.taxi.ui.navi.amap.TaxiAmapNaviFragment
import com.mogo.och.unmanned.taxi.ui.navi.auto.TaxiRoutingNaviFragment
import com.mogo.och.unmanned.taxi.ui.operational.TaxiOperationalDialogFragment
import com.mogo.och.unmanned.taxi.ui.task.TaxiTaskModel
import com.mogo.och.unmanned.taxi.ui.task.TaxiTaskTabFragment
import com.mogo.och.unmanned.taxi.utils.TPRouteDataTestUtils
import kotlinx.android.synthetic.main.unmanned_taxi_base_fragment.unmannedMapCL
import kotlinx.android.synthetic.main.unmanned_taxi_base_fragment.module_mogo_och_navi_panel_container
import kotlinx.android.synthetic.main.unmanned_taxi_base_fragment.taxi_close_navi_icon
import kotlinx.android.synthetic.main.unmanned_taxi_panel.orderDebugView
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.lang.ref.WeakReference
/**
* @author: wangmingjun
* @date: 2023/7/24
*/
class TaxiFragment : BaseTaxiTabFragment<TaxiFragment, TaxiPresenter>(),
ITaxiView {
class TaxiFragment :MvpFragment<TaxiFragment?, TaxiPresenter?>(),
IMogoMapListener, IMoGoAutopilotRecordListener {
companion object {
const val TAG = "TaxiFragment"
const val TAG = "BaseTaxiTabFragment"
}
// 高德导航fragment
private var ochAmapNaviFragment: TaxiAmapNaviFragment? = null
// 高德地图轨迹展示fragment
private var taxiRoutingNaviFragment: TaxiRoutingNaviFragment? = null
private val runningTaskGateWay = "RUNNINGTASKGATEWAY"
private val lineView = "LINEVIEW"
private var personalDialogFragment: WeakReference<TaxiOperationalDialogFragment>? = null
private var taskTabFragment: WeakReference<TaxiTaskTabFragment>? = null
private var routingVerifyFragment: WeakReference<TaxiRoutingFragment>? = null
private var moFanglistener: IMogoStatusChangedListener? = object : IMogoStatusChangedListener {
override fun onStatusChanged(descriptor: StatusDescriptor?, isTrue: Boolean) {
if (StatusDescriptor.TAXI_UNMANED_DRIVER_LINE_ROUTING_VERIFY_MODE == descriptor) {
UiThreadHandler.post {
if (isTrue) {
showRoutingFragment()
} else {
showTaskFragment()
}
updateOperationBtnStatusOnModeChange(isTrue)
}
}
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun changeOverview(eventLogout: EventLogout) {
if (eventLogout.messgae == EventLogout.LOGOUT_TYPE) {
d(SceneConstant.M_TAXI + TAG, "changeOverview Event消息去登出")
mPresenter?.logout()
private fun updateOperationBtnStatusOnModeChange(isRoutingVerifyMode: Boolean) {
if (MogoStatusManager.getInstance().isTaxiUnmanedDriverTakingOrders) {
return
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun openOperationalInfoView(eventLogout: EventLogout) {
// V6.2.0 增加订单统计功能
// if (eventLogout.messgae == EventLogout.PERSONAL_TYPE) {
//// 个人信息, 运营数据在无人化阶段暂时不展示
// d(SceneConstant.M_TAXI + TAG, "openOperationalInfoView Event个人中心")
// openOperationalInfoView()
// }
override fun getLayoutId(): Int {
return R.layout.unmanned_taxi_base_fragment
}
override fun getTagName(): String {
return "TaxiFragment"
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
e(SceneConstant.M_TAXI + TAG, "onActivityCreated")
super.onActivityCreated(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
e(SceneConstant.M_TAXI + TAG, "onCreateView")
EventBus.getDefault().register(this)
return super.onCreateView(inflater, container, savedInstanceState)
}
override fun getStationPanelViewId(): Int {
return R.layout.unmanned_taxi_panel
}
override fun startAutopilot() {
// 在自动驾驶中,或者自己确认车辆环境可开启自动驾驶 则可点击
if (!isStarting) {
d(SceneConstant.M_TAXI + TAG, "startAutopilot")
mPresenter?.startAutoPilot()
}
}
override fun pauseStartAutopilot() {
mPresenter?.pauseStartAutopilot()
}
override fun resumeStartAutopilot(remainingTime: Long) {
mPresenter.resumeStartAutopilot(remainingTime)
}
override fun startNaviToEndStation(isShow: Boolean) {
mPresenter?.startNaviToEndStation(isShow)
return "BaseTaxiTabFragment"
}
@SuppressLint("UseCompatLoadingForDrawables")
override fun initViews() {
super.initViews()
initFlowEvent()
initFragment()
switchVRFlatMode(MogoStatusManager.getInstance().isVrMode)
initOrderDebugView()
}
override fun stopAutoStartAutopilot() {
mPresenter?.stopAutoStartAutopilot()
onAutopilotStatusChanged(
getState(),
CallerAutoPilotControlManager.isCanStartAutopilot(false)
)
CallerHmiViewControlListenerManager.invokeMainPageViewVisible(View.VISIBLE)
taxi_close_navi_icon.setOnClickListener {
showAmapNaviToStationFragment(false)
showRoutingToStationFragment(false)
}
context?.let {
CallerEagleBaseFunctionCall4OchManager.addSingleToolKitDefaultItem(
runningTaskGateWay,
"运营看板",
R.drawable.common_biz_operation,
4
);
CallerEagleBaseFunctionCall4OchManager.addToolKitDefaultItemClickListener(
runningTaskGateWay,
object :
IToolKitItemClickListener {
override fun onItemClick(toolTag: String, ctx: Context?) {
when (toolTag) {
runningTaskGateWay -> {
personalDialogFragment =
WeakReference(TaxiOperationalDialogFragment())
activity?.supportFragmentManager?.let {
personalDialogFragment!!.get()
?.show(it, "service_data")
}
}
}
}
});
CallerEagleBaseFunctionCall4OchManager.addSingleToolKitCustomItem(
lineView,
LineView(it),
10
);
}
initFlowEvent()
initOrderDebugView()
}
private fun initFlowEvent() {
@@ -153,70 +151,48 @@ class TaxiFragment : BaseTaxiTabFragment<TaxiFragment, TaxiPresenter>(),
}
}
private fun initFragment() {
showTaskFragment()
MogoStatusManager.getInstance()
.registerStatusChangedListener(
TAG, StatusDescriptor.TAXI_UNMANED_DRIVER_LINE_ROUTING_VERIFY_MODE, moFanglistener
)
fun stopAutoStartAutopilot() {
mPresenter?.stopAutoStartAutopilot()
}
private fun showTaskFragment() {
val transaction: FragmentTransaction = childFragmentManager.beginTransaction()
if (routingVerifyFragment?.get()?.isVisible == true) {
routingVerifyFragment?.get()?.also {
transaction.remove(it)
routingVerifyFragment = null
}
}
// if (taskTabFragment?.get() == null) {
// taskTabFragment = WeakReference(TaxiTaskTabFragment.newInstance())
// }
// taskTabFragment?.get()?.also {
// transaction.replace(R.id.fragment_container, it).show(it)
// transaction.commitAllowingStateLoss()
// }
}
private fun showRoutingFragment() {
val transaction: FragmentTransaction = childFragmentManager.beginTransaction()
if (taskTabFragment?.get()?.isVisible == true) {
taskTabFragment?.get()?.also {
transaction.remove(it)
taskTabFragment = null
}
}
if (routingVerifyFragment?.get() == null) {
routingVerifyFragment = WeakReference(TaxiRoutingFragment.newInstance())
}
routingVerifyFragment?.get()?.also {
transaction.replace(R.id.fragment_container, it).show(it)
transaction.commitAllowingStateLoss()
}
override fun initViews(savedInstanceState: Bundle?) {
super.initViews(savedInstanceState)
unmannedMapCL.onCreate(savedInstanceState)
}
override fun createPresenter(): TaxiPresenter {
return TaxiPresenter(this)
}
override fun onChangeOperationStatus() {
super.onChangeOperationStatus()
override fun onResume() {
super.onResume()
unmannedMapCL.onResume()
}
override fun onPause() {
super.onPause()
unmannedMapCL.onPause()
}
fun onChangeOperationStatus() {
if (null == taskTabFragment || taskTabFragment!!.get() == null) return
taskTabFragment!!.get()!!.onCarTakeOrderStatusChanged()
}
fun switchVRFlatMode(isVRMode: Boolean) {
if (mRootView != null) {
mRootView.visibility = if (isVRMode) View.VISIBLE else View.GONE
}
override fun onLowMemory() {
super.onLowMemory()
unmannedMapCL.onLowMemory()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
unmannedMapCL.onSaveInstanceState(outState)
}
override fun onDestroyView() {
e(SceneConstant.M_TAXI + TAG, "onDestroyView")
MogoStatusManager.getInstance().unregisterStatusChangedListener(
TAG,
StatusDescriptor.TAXI_UNMANED_DRIVER_LINE_ROUTING_VERIFY_MODE, moFanglistener
)
unmannedMapCL.onDestroy()
CallerAutopilotRecordListenerManager.removeListener(TAG)
if (mPresenter != null) {
mPresenter?.onDestroy(this)
}
@@ -225,24 +201,205 @@ class TaxiFragment : BaseTaxiTabFragment<TaxiFragment, TaxiPresenter>(),
it.removeAllPoints()
}
super.onDestroyView()
EventBus.getDefault().unregister(this)
}
override fun onDestroy() {
moFanglistener = null
super.onDestroy()
e(SceneConstant.M_TAXI + TAG, "onDestroy")
/**
* 改变自动驾驶状态
*
* @param status 2 - running 1 - enable 2 - disable
*/
fun onAutopilotStatusChanged(status: Int, canStartAuto: Boolean) {
activity?.runOnUiThread(Runnable runOnUiThread@{
if (isStarting && IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING != status) {
// 1. 主动开启自动驾驶中不为2为0、1则继续loading
return@runOnUiThread
}
if (isStarting && IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING == status
) {
// 2. 主动开启自动驾驶中为2则停止loading并isStarting = false
startAutopilotDone(true)
return@runOnUiThread
}
// 3. 其他过程直接更新
startOrStopLoadingAnim(false)
})
}
override fun onDetach() {
super.onDetach()
e(SceneConstant.M_TAXI + TAG, "onDetach")
/**
* 停止【开启自动驾驶按钮】动画,并更新按钮状态
*/
fun stopAnimAndUpdateBtnStatus() {
startOrStopLoadingAnim(false)
startAutopilotDone(false)
}
fun setRole(finalRole: String) {
var isStarting = false
@SuppressLint("ObjectAnimatorBinding")
fun startOrStopLoadingAnim(start: Boolean) {
if (start) {
isStarting = true
startingAutopilotCountDown()
} else {
isStarting = false
}
}
private fun startAutopilotDone(success: Boolean) {
UiThreadHandler.postDelayed({
startOrStopLoadingAnim(false)
onAutopilotStatusChanged(
getState(),
CallerAutoPilotControlManager.isCanStartAutopilot(false)
)
}, 1000L)
}
private fun startingAutopilotCountDown() {
UiThreadHandler.postDelayed({
//未启动成功10s后做处理
if (isStarting) { //判断动画是否在进行
//并且根据状态来设置自动驾驶启动成功还是失败
if (getState()
== IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING
) {
startAutopilotDone(true)
} else {
startAutopilotDone(false)
}
}
}, TaxiUnmannedConst.TIMER_START_AUTOPILOT_INTERVAL)
}
/**
* 获取站点面板view在[.initViews]时候添加到container中
*
* @return 站点面板view
*/
fun getStationPanelViewId(): Int {
return R.layout.unmanned_taxi_panel
}
/**
* 重新开启自动驾驶
*/
fun startAutopilot() {
// 在自动驾驶中,或者自己确认车辆环境可开启自动驾驶 则可点击
if (!isStarting) {
d(SceneConstant.M_TAXI + TAG, "startAutopilot")
mPresenter?.startAutoPilot()
}
}
fun changeOperationViewVisible(visible: Int) {
}
override fun onMapVisualAngleChanged(visualAngleMode: VisualAngleMode?) {
}
fun showAmapNaviToStationFragment(isShow: Boolean) {
val transaction: FragmentTransaction = childFragmentManager.beginTransaction()
closeAmapViewIFHadeAdd()
if (isShow) {
closeRoutingViewIfHadAdd()
ochAmapNaviFragment = TaxiAmapNaviFragment.newInstance()
if (ochAmapNaviFragment!!.isAdded) {
return
}
transaction.add(R.id.module_mogo_och_navi_panel_container, ochAmapNaviFragment!!)
.show(ochAmapNaviFragment!!)
transaction.commitAllowingStateLoss()
taxi_close_navi_icon.visibility = View.VISIBLE
module_mogo_och_navi_panel_container.visibility = View.VISIBLE
} else {
taxi_close_navi_icon.visibility = View.GONE
module_mogo_och_navi_panel_container.visibility = View.INVISIBLE
}
}
private fun closeAmapViewIFHadeAdd() {
if (ochAmapNaviFragment != null) {
val transaction: FragmentTransaction = childFragmentManager.beginTransaction()
ochAmapNaviFragment!!.onDestroy()
transaction.remove(ochAmapNaviFragment!!)
transaction.commitAllowingStateLoss()
ochAmapNaviFragment = null
}
}
private fun closeRoutingViewIfHadAdd() {
if (taxiRoutingNaviFragment != null) {
val transaction: FragmentTransaction = childFragmentManager.beginTransaction()
taxiRoutingNaviFragment!!.onDestroy()
transaction.remove(taxiRoutingNaviFragment!!)
transaction.commitAllowingStateLoss()
taxiRoutingNaviFragment = null
}
}
fun showRoutingToStationFragment(isShow: Boolean) {
val transaction: FragmentTransaction = childFragmentManager.beginTransaction()
closeRoutingViewIfHadAdd()
if (isShow) {
closeAmapViewIFHadeAdd()
taxiRoutingNaviFragment = TaxiRoutingNaviFragment.newInstance()
if (taxiRoutingNaviFragment!!.isAdded) {
return
}
transaction.add(R.id.module_mogo_och_navi_panel_container, taxiRoutingNaviFragment!!)
.show(taxiRoutingNaviFragment!!)
transaction.commitAllowingStateLoss()
taxi_close_navi_icon.visibility = View.VISIBLE
module_mogo_och_navi_panel_container.visibility = View.VISIBLE
} else {
taxi_close_navi_icon.visibility = View.GONE
module_mogo_och_navi_panel_container.visibility =
View.INVISIBLE //2023.9.4高德导航由gone设置成INVISIBLE,保留导航实例,避免导航被挂起
}
}
fun startNaviToEndStation(isShow: Boolean) {
mPresenter?.startNaviToEndStation(isShow)
}
fun showStartAutopilotBlinkAnimation() {
}
fun pauseStartAutopilot() {
mPresenter?.pauseStartAutopilot()
}
fun resumeStartAutopilot(remainingTime: Long) {
mPresenter?.resumeStartAutopilot(remainingTime)
}
fun stopAutopilotBlinkAnimation() {
stopStartAutopilotBlinkAnimation()
}
private fun stopStartAutopilotBlinkAnimation() {
}
fun pauseAutopilotBlinkAnimation() {
}
fun resumeAutopilotBlinkAnimation() {
}
fun setGuidShow() {
}
fun setGuidHide() {
}
fun updateAutopilotStatus(status: Int, canStartAuto: Boolean) {
onAutopilotStatusChanged(status, canStartAuto)
}
/**
* 状态变更
* @param inOperation true 可以接单 false 暂停接单
@@ -253,26 +410,10 @@ class TaxiFragment : BaseTaxiTabFragment<TaxiFragment, TaxiPresenter>(),
SceneConstant.M_TAXI + TAG,
"onOperationChanged:$inOperation"
)
if (inOperation == OpenOrderStatusEnum.Ordering) {
showDebugPanel()
}
updateOperationBtnStatusOnModeChange(MogoStatusManager.getInstance().isTaxiUnmanedDriverLineRoutingVerifyMode)
MogoStatusManager.getInstance()
.setTaxiUnmanedDriverTakingOrders(TAG, inOperation == OpenOrderStatusEnum.Ordering)
}
private fun updateOperationBtnStatusOnModeChange(isRoutingVerifyMode: Boolean) {
if (MogoStatusManager.getInstance().isTaxiUnmanedDriverTakingOrders) {
return
}
}
override fun onMapLoaded() {}
fun updateAutopilotStatus(status: Int, canStartAuto: Boolean) {
onAutopilotStatusChanged(status, canStartAuto)
}
fun onNaviToEnd(isAmap: Boolean, isShow: Boolean) {
if (isAmap) {
if (MogoStatusManager.getInstance().isTaxiUnmanedDriverLineRoutingVerifyMode) {
@@ -332,11 +473,10 @@ class TaxiFragment : BaseTaxiTabFragment<TaxiFragment, TaxiPresenter>(),
}
}
private fun testRouteInfoUpload() {
TPRouteDataTestUtils.converToRouteData()
}
fun clickOrderDebugView() {
orderDebugView.toggleOrderDebugView()
}
private fun testRouteInfoUpload() {
TPRouteDataTestUtils.converToRouteData()
}
}

View File

@@ -7,7 +7,6 @@ import androidx.lifecycle.LifecycleOwner;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.commons.module.status.MogoStatusManager;
import com.mogo.commons.mvp.Presenter;
import com.mogo.eagle.core.data.map.MogoLocation;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
@@ -25,13 +24,8 @@ import com.mogo.och.data.taxi.BaseOrderBean;
import com.mogo.och.unmanned.taxi.callback.ITaxiADASStatusCallback;
import com.mogo.och.unmanned.taxi.callback.ITaxiControllerStatusCallback;
import com.mogo.och.unmanned.taxi.callback.ITaxiOrderStatusCallback;
import com.mogo.och.common.module.biz.login.RoleEnum;
import com.mogo.och.unmanned.taxi.constant.TaxiUnmannedConst;
import com.mogo.och.unmanned.taxi.ui.routing.TaxiRoutingModel;
import com.mogo.och.unmanned.taxi.ui.task.TaxiTaskModel;
import com.mogo.och.unmanned.taxi.callback.ITaxiADASStatusCallback;
import com.mogo.och.unmanned.taxi.callback.ITaxiControllerStatusCallback;
import com.mogo.och.unmanned.taxi.callback.ITaxiOrderStatusCallback;
/**
* @author congtaowang
@@ -48,7 +42,6 @@ public class TaxiPresenter extends Presenter<TaxiFragment> implements ITaxiADASS
super(view);
TaxiTaskModel.INSTANCE.init();
OCHAdasAbilityManager.getInstance().init(AbsMogoApplication.getApp());
onStatusChange(LoginStatusManager.getLoginStatus());
initListeners();
}
@@ -63,7 +56,6 @@ public class TaxiPresenter extends Presenter<TaxiFragment> implements ITaxiADASS
TaxiTaskModel.INSTANCE.setADASStatusCallback(this);
TaxiTaskModel.INSTANCE.setControllerStatusCallback(this);
TaxiTaskModel.INSTANCE.setOrderStatusCallback(this);
TaxiRoutingModel.INSTANCE.setControllerStatusCallback(this);
TaxiRoutingModel.INSTANCE.setOrderStatusCallback(this);
LoginStatusManager.INSTANCE.addListener(TAG,this);
OrderModel.INSTANCE.setOrderStatusCallback(TAG,this);
@@ -84,14 +76,7 @@ public class TaxiPresenter extends Presenter<TaxiFragment> implements ITaxiADASS
* 开启自动驾驶 自驾模式
*/
public void startAutoPilot() {
// 这里区分是订单还是灰度测试
if (MogoStatusManager.getInstance().isTaxiUnmanedDriverLineRoutingVerifyMode()) {
// 灰度测试
TaxiRoutingModel.INSTANCE.startAutoPilotByClick();
} else {
// 订单
TaxiTaskModel.INSTANCE.startAutopilotByClick();
}
TaxiTaskModel.INSTANCE.startAutopilotByClick();
}
private OchTransformDispatch ochTransform = new OchTransformDispatch(){
@@ -101,11 +86,6 @@ public class TaxiPresenter extends Presenter<TaxiFragment> implements ITaxiADASS
}
};
// 登出
public void logout() {
TaxiTaskModel.INSTANCE.logout();
}
//导航去订单目的地
public void startNaviToEndStation(boolean isShow) {
TaxiTaskModel.INSTANCE.startNaviToEndStation(isShow);
@@ -163,9 +143,7 @@ public class TaxiPresenter extends Presenter<TaxiFragment> implements ITaxiADASS
UiThreadHandler.post(new Runnable() {
@Override
public void run() {
if(mView!=null) {
mView.onParallelDrivingStatus(IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING,canStartAuto);
}
}
}, UiThreadHandler.MODE.QUEUE);
@@ -204,24 +182,6 @@ public class TaxiPresenter extends Presenter<TaxiFragment> implements ITaxiADASS
}
@Override
public void onVRModeChanged(boolean isVRMode) {
UiThreadHandler.post(new Runnable() {
@Override
public void run() {
if(mView!=null) {
mView.switchVRFlatMode(isVRMode);
}
}
}, UiThreadHandler.MODE.QUEUE);
}
@Override
public void onCarLocationChanged(MogoLocation location) {
}
@Override
public void startOpenAutopilot() {
UiThreadHandler.post(new Runnable() {
@@ -295,29 +255,16 @@ public class TaxiPresenter extends Presenter<TaxiFragment> implements ITaxiADASS
@Override
public void onStatusChange(LoginStatusEnum currentStatus) {
// 设置当前用户角色
String role = "";
if (RoleEnum.DEMO == LoginStatusManager.getPurpose()) {
role = TaxiUnmannedConst.DEMO_USER;
} else if (RoleEnum.TEST == LoginStatusManager.getPurpose()) {
role = TaxiUnmannedConst.TEST_USER;
}
String finalRole = role;
UiThreadHandler.post(new Runnable() {
@Override
public void run() {
if(mView!=null) {
mView.updateOperationStatus(LoginStatusManager.getOpenOrderType());
mView.setRole(finalRole);
}
}
}, UiThreadHandler.MODE.QUEUE);
if (!TaxiTaskModel.INSTANCE.checkCurrentTaskCondition()&&mView!=null) {
mView.showDebugPanel();
}
TaxiTaskModel.INSTANCE.updatePrepareTaskDelayUI();
}

View File

@@ -3,22 +3,12 @@ package com.mogo.och.unmanned.taxi.ui.bizswitch
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.findViewTreeViewModelStoreOwner
import com.mogo.commons.module.status.MogoStatusManager
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.common.module.utils.FlowBus
import com.mogo.och.common.module.utils.ResourcesUtils
import com.mogo.och.common.module.wigets.WindowRelativeLayout
import com.mogo.och.unmanned.taxi.R
import com.mogo.och.unmanned.taxi.TaxiUnmannedDriverProvider
import com.mogo.och.unmanned.taxi.constant.TaxiDriverEventConst
import kotlinx.android.synthetic.main.unmanned_switch_biz.view.loading_biz
import kotlinx.android.synthetic.main.unmanned_switch_biz.view.itinerarySwitchView
import kotlinx.android.synthetic.main.unmanned_switch_biz.view.routingSwitchView
class SwitchBizView: WindowRelativeLayout, SwtichBizeModel.SwtichLineViewCallback {
@@ -38,25 +28,12 @@ class SwitchBizView: WindowRelativeLayout, SwtichBizeModel.SwtichLineViewCallbac
private var viewModel: SwtichBizeModel?=null
private var fragment: LifecycleOwner?=null
init {
LayoutInflater.from(context).inflate(R.layout.unmanned_switch_biz, this, true)
initView()
initEventBus()
}
private fun initView(){
fragment = TaxiUnmannedDriverProvider.getFragmentInfo()
loading_biz.setEmptyText(ResourcesUtils.getString(R.string.common_biz_loading))
}
private fun initEventBus() {
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
viewModel = findViewTreeViewModelStoreOwner()?.let {
@@ -65,12 +42,14 @@ class SwitchBizView: WindowRelativeLayout, SwtichBizeModel.SwtichLineViewCallbac
viewModel?.setDistanceCallback(this)
}
var startLoading = System.currentTimeMillis()
override fun showTaskView() {
itinerarySwitchView.visibility = VISIBLE
routingSwitchView.visibility = GONE
}
// 展示loading页面
override fun showLoadingView(){
startLoading = System.currentTimeMillis()
loading_biz.visibility = GONE
override fun showRoutingView() {
itinerarySwitchView.visibility = GONE
routingSwitchView.visibility = VISIBLE
}
}

View File

@@ -1,6 +1,12 @@
package com.mogo.och.unmanned.taxi.ui.bizswitch
import androidx.lifecycle.ViewModel
import com.mogo.commons.module.status.IMogoStatusChangedListener
import com.mogo.commons.module.status.MogoStatusManager
import com.mogo.commons.module.status.StatusDescriptor
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.unmanned.taxi.ui.base.TaxiFragment
import com.mogo.och.unmanned.taxi.ui.base.TaxiFragment.Companion
import com.mogo.och.unmanned.taxi.ui.task.TaxiTaskModel
/**
@@ -19,17 +25,33 @@ class SwtichBizeModel : ViewModel() {
}
fun changeOperationStatus(){
TaxiTaskModel.updateCarServingStatus()
}
fun setDistanceCallback(viewCallback: SwtichLineViewCallback) {
this.viewCallback = viewCallback
this.viewCallback?.showLoadingView()
this.viewCallback?.showTaskView()
MogoStatusManager.getInstance()
.registerStatusChangedListener(
TaxiFragment.TAG, StatusDescriptor.TAXI_UNMANED_DRIVER_LINE_ROUTING_VERIFY_MODE, moFanglistener
)
}
private var moFanglistener: IMogoStatusChangedListener? = object : IMogoStatusChangedListener {
override fun onStatusChanged(descriptor: StatusDescriptor?, isTrue: Boolean) {
if (StatusDescriptor.TAXI_UNMANED_DRIVER_LINE_ROUTING_VERIFY_MODE == descriptor) {
UiThreadHandler.post {
if (isTrue) {// 展示算路
viewCallback?.showRoutingView()
} else {// 展示任务
viewCallback?.showTaskView()
}
}
}
}
}
interface SwtichLineViewCallback {
fun showLoadingView()
fun showTaskView()
fun showRoutingView()
}
}

View File

@@ -0,0 +1,45 @@
package com.mogo.och.unmanned.taxi.ui.routing
import androidx.lifecycle.ViewModel
import com.mogo.och.unmanned.taxi.bean.StartGrayAndQueryContrailRsp
/**
* @author XuXinChao
* @description BadCase录包管理页面
* @since: 2022/12/15
*/
class RoutingSwitchModel : ViewModel() {
private val TAG = RoutingSwitchModel::class.java.simpleName
private var viewCallback: SwtichLineViewCallback? = null
override fun onCleared() {
}
fun setDistanceCallback(viewCallback: SwtichLineViewCallback) {
this.viewCallback = viewCallback
}
fun showLoading() {
this.viewCallback?.showLoadingView()
}
fun showRoutingSelectView(){
this.viewCallback?.showRoutingSelectView()
}
fun showRoutingRunning(data: StartGrayAndQueryContrailRsp) {
this.viewCallback?.showRoutingRunning(data)
}
interface SwtichLineViewCallback {
fun showLoadingView()
fun showRoutingSelectView()
fun showRoutingRunning(data: StartGrayAndQueryContrailRsp)
}
}

View File

@@ -0,0 +1,105 @@
package com.mogo.och.unmanned.taxi.ui.routing
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.findViewTreeViewModelStoreOwner
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.och.common.module.utils.ResourcesUtils
import com.mogo.och.unmanned.taxi.R
import com.mogo.och.unmanned.taxi.TaxiUnmannedDriverProvider
import com.mogo.och.unmanned.taxi.bean.StartGrayAndQueryContrailRsp
import kotlinx.android.synthetic.main.unmanned_routing_switch.view.routingRunningView
import kotlinx.android.synthetic.main.unmanned_routing_switch.view.routingSelectView
import kotlinx.android.synthetic.main.unmanned_routing_switch.view.switch_routing_loading
class RoutingSwitchView: ConstraintLayout, RoutingSwitchModel.SwtichLineViewCallback {
constructor(context: Context) : super(context)
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
companion object {
const val TAG = "SwitchBizView"
}
private var viewModel: RoutingSwitchModel?=null
private var fragment: LifecycleOwner?=null
init {
LayoutInflater.from(context).inflate(R.layout.unmanned_routing_switch, this, true)
initView()
initEventBus()
}
private fun initView(){
fragment = TaxiUnmannedDriverProvider.getFragmentInfo()
switch_routing_loading.setEmptyText(ResourcesUtils.getString(R.string.common_biz_loading))
}
private fun initEventBus() {
}
override fun onVisibilityAggregated(isVisible: Boolean) {
super.onVisibilityAggregated(isVisible)
if(isVisible){
showLoadingView()
showRoutingSelectView()
}
}
var startLoading = System.currentTimeMillis()
// 展示loading页面
override fun showLoadingView(){
startLoading = System.currentTimeMillis()
routingSelectView.visibility = GONE
routingRunningView.visibility = GONE
switch_routing_loading.visibility = VISIBLE
}
override fun showRoutingSelectView() {
val endLoading = System.currentTimeMillis()
val dex = (100-(endLoading - startLoading)).takeIf { it>=0 }?:0
CallerLogger.d(TAG,"展示选择线路 lading 展示了 ${dex}毫秒")
ThreadUtils.runOnUiThreadDelayed({
routingSelectView.visibility = VISIBLE
routingRunningView.visibility = GONE
switch_routing_loading.visibility = GONE
},dex, ThreadUtils.MODE.QUEUE)
}
override fun showRoutingRunning(data: StartGrayAndQueryContrailRsp) {
val endLoading = System.currentTimeMillis()
val dex = (100-(endLoading - startLoading)).takeIf { it>=0 }?:0
CallerLogger.d(TAG,"展示线路 lading 展示了 ${dex}毫秒")
ThreadUtils.runOnUiThreadDelayed({
routingSelectView.visibility = GONE
routingRunningView.visibility = VISIBLE
switch_routing_loading.visibility = GONE
routingRunningView.setData(data)
},dex, ThreadUtils.MODE.QUEUE)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
viewModel = findViewTreeViewModelStoreOwner()?.let {
ViewModelProvider(it).get(RoutingSwitchModel::class.java)
}
viewModel?.setDistanceCallback(this)
}
}

View File

@@ -1,178 +0,0 @@
package com.mogo.och.unmanned.taxi.ui.routing
import android.graphics.Point
import android.os.Bundle
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.view.SpacesItemDecoration
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.common.module.utils.FlowBus
import com.mogo.och.unmanned.taxi.R
import com.mogo.och.unmanned.taxi.bean.GrayLineBean
import com.mogo.och.unmanned.taxi.constant.TaxiDriverEventConst
import com.mogo.och.unmanned.taxi.ui.debug.DebugView
import kotlinx.android.synthetic.main.unmanned_routing_choose_task_activity.btnChooseLineSubmit
import kotlinx.android.synthetic.main.unmanned_routing_choose_task_activity.btnClose
import kotlinx.android.synthetic.main.unmanned_routing_choose_task_activity.chooseLineListView
import kotlinx.android.synthetic.main.unmanned_routing_no_data_common_view.noDataContainer
import kotlinx.coroutines.flow.map
class TaxiRoutingChooseLineActivity : AppCompatActivity() {
companion object {
const val TAG = "TaxiRoutingChooseLineActivity"
}
private val mViewModel: TaxiRoutingChooseLineViewModel by lazy {
ViewModelProvider(
this,
ViewModelProvider.NewInstanceFactory()
)[TaxiRoutingChooseLineViewModel::class.java]
}
private val mLoadingDialog: TaxiRoutingLoadingDialog by lazy {
TaxiRoutingLoadingDialog(
this
)
}
private lateinit var mChooseLineListAdapter: TaxiRoutingChooseLineAdapter
private lateinit var mLinearLayoutManager: LinearLayoutManager
private val mRoutingLineList: MutableList<GrayLineBean> = ArrayList()
private var mCurrentChosenPosition: Int = -1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.unmanned_routing_choose_task_activity)
initWindowParams()
initView()
initViewListener()
initViewModelObserver()
loadData()
}
private fun initWindowParams() {
val window = window
val params = window.attributes
val windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
val point = Point()
windowManager.defaultDisplay.getSize(point) //用于获取屏幕高度
params.width = (point.x * 0.375).toInt()
params.height = ViewGroup.LayoutParams.MATCH_PARENT
window.attributes = params
window.setGravity(Gravity.START or Gravity.BOTTOM)
}
private fun initView() {
mLinearLayoutManager = LinearLayoutManager(this)
chooseLineListView.layoutManager = mLinearLayoutManager
chooseLineListView.itemAnimator =
TaxiRoutingChooseLineItemOpenAnimator()
mChooseLineListAdapter = TaxiRoutingChooseLineAdapter(applicationContext, mRoutingLineList)
chooseLineListView.addItemDecoration(SpacesItemDecoration(4))
chooseLineListView.adapter = mChooseLineListAdapter
//设置item 点击事件
mChooseLineListAdapter.setOnLineItemClickListener(object :
TaxiRoutingChooseLineAdapter.OnChooseLineItemClickListener {
override fun onItemClick(position: Int, close: Boolean) {
mCurrentChosenPosition = position
}
})
}
private fun initViewListener() {
btnClose.setOnClickListener {
finish()
}
// 选择路线后,「确认」按钮
btnChooseLineSubmit.setOnClickListener {
if (mCurrentChosenPosition == -1) {
ToastUtils.showLong("请先选择任务")
return@setOnClickListener
}
DebugView.printInfoMsg("[选择灰度任务] 当前选择 mCurrentChosenPosition=$mCurrentChosenPosition, ")
mLoadingDialog.showLoading()
val chosenItem = mRoutingLineList[mCurrentChosenPosition]
mViewModel.sendUiIntent(
// 调用查询接口获取路线详情
TaxiRoutingUiIntent.StartTaskAndQueryContrail(chosenItem)
)
}
}
/**
* 初始化UI观察者
*/
private fun initViewModelObserver() {
lifecycleScope.launchWhenStarted {
mViewModel.uiStateFlow.map { it.routingUiState }.collect { routingUiState ->
CallerLogger.d(
TAG,
"uiStateFlow-initViewModelObserver: $routingUiState"
)
// 分发处理具体UI更新
when (routingUiState) {
is RoutingUIState.Init -> {
showEmptyView()
}
is RoutingUIState.ShowGrayLineList -> {
onRoutingGrayLineListChanged(routingUiState.data)
}
is RoutingUIState.HideChooseLineLoading -> {
mLoadingDialog.hideLoading()
if (routingUiState.isCosePage) {
mChooseLineListAdapter.setOnLineItemClickListener(null)
finish()
}
}
// 将结果同步更新到UI
is RoutingUIState.PostRoutingTaskResult -> {
FlowBus.with<RoutingUIState.RoutingTask>(TaxiDriverEventConst.RoutingActivityEvent.EVENT_TYPE_GET_CHOSEN_LINE_TASK)
.post(this, RoutingUIState.RoutingTask(
grayLineBean = routingUiState.grayLineBean,
contrailBean = routingUiState.contrailBean,
grayId = routingUiState.grayId
))
}
}
}
}
}
private fun showEmptyView() {
chooseLineListView.visibility = View.GONE
btnChooseLineSubmit.visibility = View.GONE
noDataContainer.visibility = View.VISIBLE
}
private fun showRecyclerView() {
chooseLineListView.visibility = View.VISIBLE
btnChooseLineSubmit.visibility = View.VISIBLE
noDataContainer.visibility = View.GONE
}
private fun loadData() {
mViewModel.sendUiIntent(TaxiRoutingUiIntent.QueryRoutingGrayLineList(System.currentTimeMillis()))
}
private fun onRoutingGrayLineListChanged(data: MutableList<GrayLineBean>) {
if (data.isNotEmpty()) {
showRecyclerView()
mRoutingLineList.clear()
mRoutingLineList.addAll(data)
mChooseLineListAdapter.notifyDataSetChanged()
} else {
showEmptyView()
}
}
}

View File

@@ -1,88 +0,0 @@
package com.mogo.och.unmanned.taxi.ui.routing
import android.content.Context
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.AppCompatTextView
import androidx.recyclerview.widget.RecyclerView
import com.mogo.och.unmanned.taxi.R
import com.mogo.och.unmanned.taxi.bean.GrayLineBean
class TaxiRoutingChooseLineAdapter(
private val mContext: Context,
private val mData: List<GrayLineBean>
) : RecyclerView.Adapter<TaxiRoutingChooseLineAdapter.SwitchLineViewHolder>() {
companion object {
const val TAG = "TaxiRoutingChooseLineAdapter"
}
private var mItemClickListener: OnChooseLineItemClickListener? = null
private var mLastChoosedLineIndex = -1
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SwitchLineViewHolder {
val view = LayoutInflater.from(mContext).inflate(
R.layout.unmanned_routing_choose_line_list_item, parent, false
)
return SwitchLineViewHolder(view)
}
override fun onBindViewHolder(holder: SwitchLineViewHolder, position: Int) {
val currentPosition = holder.bindingAdapterPosition
val data = mData[currentPosition]
holder.lineNameTextView.text = data.lineName
holder.todayVerifyNumTextView.text = "本车今日已验证:${data.carVerificationCount}"
holder.historyVerifyNumTextView.text =
"路线累计反馈${data.lineSuccessCount}可用,${data.lineFailCount}不可用"
if (data.isChoosed) {
holder.itemView.setBackgroundResource(R.drawable.routing_choose_line_shape_select_line_item_bg_selected)
} else {
holder.itemView.setBackgroundColor(Color.parseColor("#162761"))
}
//设置item点击事件
holder.itemView.setOnClickListener {
mData.forEachIndexed { index, result ->
if (result.isChoosed && index != currentPosition) {
result.isChoosed = false
notifyItemChanged(index)
}
}
val isCurrentItemSelected = !mData[currentPosition].isChoosed
mData[currentPosition].isChoosed = isCurrentItemSelected
notifyItemChanged(currentPosition)
mItemClickListener?.onItemClick(
currentPosition,
isCurrentItemSelected
)
mLastChoosedLineIndex = currentPosition
}
}
override fun getItemCount(): Int {
return mData.size
}
fun setOnLineItemClickListener(itemClickListener: OnChooseLineItemClickListener?) {
mItemClickListener = itemClickListener
}
interface OnChooseLineItemClickListener {
fun onItemClick(position: Int, isChoosed: Boolean)
}
class SwitchLineViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val lineNameTextView: AppCompatTextView//线路名称
val todayVerifyNumTextView: AppCompatTextView //本车今天验证次数
val historyVerifyNumTextView: AppCompatTextView //路线累计验证次数
init {
lineNameTextView = itemView.findViewById(R.id.switchLineNameTextView)
todayVerifyNumTextView = itemView.findViewById(R.id.todayVerifyNumTextView)
historyVerifyNumTextView = itemView.findViewById(R.id.historyVerifyNumTextView)
}
}
}

View File

@@ -1,120 +0,0 @@
package com.mogo.och.unmanned.taxi.ui.routing
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.unmanned.taxi.base.BaseViewModel
import com.mogo.och.unmanned.taxi.base.IUiIntent
import com.mogo.och.unmanned.taxi.bean.GrayLineBean
import com.mogo.och.unmanned.taxi.bean.StartGrayAndQueryContrailRsp
import com.mogo.och.unmanned.taxi.callback.ITaxiRoutingCallback
import com.mogo.och.unmanned.taxi.ui.debug.DebugView
class TaxiRoutingChooseLineViewModel : BaseViewModel<TaxiRoutingUiState, TaxiRoutingUiIntent>(),
ITaxiRoutingCallback {
private val TAG = SceneConstant.M_TAXI + "TaxiRoutingChooseLineViewModel"
init {
TaxiRoutingModel.addTaxiRoutingListener(TAG, this)
}
override fun initUiState(): TaxiRoutingUiState {
return TaxiRoutingUiState(RoutingUIState.Init)
}
override fun handleIntent(intent: IUiIntent) {
when (intent) {
is TaxiRoutingUiIntent.QueryRoutingGrayLineList -> {
TaxiRoutingModel.queryRoutingGrayLineList()
}
is TaxiRoutingUiIntent.StartTaskAndQueryContrail -> {
val contrailId = intent.grayLineBean.contrailId
TaxiRoutingModel.startGrayTaskAndQueryRoutingContrail(
contrailId ?: -1L,
intent.grayLineBean
)
}
}
}
override fun onQueryRoutingGrayLineListSuccess(data: MutableList<GrayLineBean>) {
sendUiState {
copy(
routingUiState = RoutingUIState.ShowGrayLineList(data)
)
}
}
override fun onQueryRoutingGrayLineListFailed(errorStr: String) {
ToastUtils.showShort(errorStr)
DebugView.printErrorMsg("[查询灰度任务] 失败, error=$errorStr")
sendUiState {
copy(
routingUiState = RoutingUIState.Init
)
}
}
/**
* 查询轨迹详情成功的回调
*/
override fun onStartGrayTaskAndQueryContrailSuccess(data: StartGrayAndQueryContrailRsp) {
if (data.taskId == -1L) {
onStartGrayTaskAndQueryContrailFailed("开始任务失败, 请稍后重试")
DebugView.printErrorMsg("[开始灰度任务] 开始任务失败, 请稍后重试")
return
}
sendUiState {
copy(
routingUiState = RoutingUIState.PostRoutingTaskResult(
grayLineBean = data.grayLineBean,
contrailBean = data.contrail,
grayId = data.taskId
)
)
}
sendUiState {
copy(
routingUiState = RoutingUIState.HideChooseLineLoading(
isCosePage = true
)
)
}
}
override fun onStartGrayTaskAndQueryContrailFailed(errorStr: String) {
ToastUtils.showShort(errorStr)
DebugView.printErrorMsg("[开始灰度任务&查询轨迹详情] 操作失败, 请稍后重试")
sendUiState {
copy(
routingUiState = RoutingUIState.HideChooseLineLoading(
isCosePage = false
)
)
}
}
override fun onSubmitGrayLineIssueLocationSuccess() {
}
override fun onSubmitGrayLineIssueLocationFailed(errorStr: String) {
}
override fun onSubmitEndTaskSuccess() {
}
override fun onSubmitEndTaskFailed(errorStr: String) {
}
override fun onAutoPilotArriveAtEndStation(grayId: Long?) {
}
override fun onGDMapArriveAtEndStation(grayId: Long?) {
}
override fun onCleared() {
super.onCleared()
TaxiRoutingModel.removeTaxiRoutingListener(TAG)
}
}

View File

@@ -1,399 +0,0 @@
package com.mogo.och.unmanned.taxi.ui.routing
import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.amap.api.navi.model.NaviLatLng
import com.mogo.commons.mvp.BaseFragment
import com.mogo.eagle.core.function.main.MainMoGoApplication
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.ThreadUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.common.module.manager.autopilot.location.OchLocationManager
import com.mogo.och.common.module.map.AmapNaviToDestinationModel
import com.mogo.och.common.module.map.ICommonNaviChangedCallback
import com.mogo.och.common.module.utils.FlowBus
import com.mogo.och.unmanned.taxi.R
import com.mogo.och.unmanned.taxi.bean.EndGrayTaskFeedbackType
import com.mogo.och.unmanned.taxi.constant.TaxiDriverEventConst
import com.mogo.och.unmanned.taxi.constant.TaxiUnmannedConst
import com.mogo.och.unmanned.taxi.ui.errorpoint.ReportErrorPointDialog
import com.mogo.och.unmanned.taxi.utils.MapMakerManager
import com.mogo.och.unmanned.taxi.utils.TaskUtils
import kotlinx.android.synthetic.main.unmanned_routing_fragment.btnChooseTask
import kotlinx.android.synthetic.main.unmanned_routing_fragment.btnFinishTask
import kotlinx.android.synthetic.main.unmanned_routing_fragment.btnStartTask
import kotlinx.android.synthetic.main.unmanned_routing_fragment.btnSummitIssue
import kotlinx.android.synthetic.main.unmanned_routing_fragment.endPoint
import kotlinx.android.synthetic.main.unmanned_routing_fragment.endStationName
import kotlinx.android.synthetic.main.unmanned_routing_fragment.finishSubmitIssueGroup
import kotlinx.android.synthetic.main.unmanned_routing_fragment.headerTitleContainer
import kotlinx.android.synthetic.main.unmanned_routing_fragment.mCurrentTaskLayout
import kotlinx.android.synthetic.main.unmanned_routing_fragment.naviToEnd
import kotlinx.android.synthetic.main.unmanned_routing_fragment.naviToStart
import kotlinx.android.synthetic.main.unmanned_routing_fragment.noDataContainer
import kotlinx.android.synthetic.main.unmanned_routing_fragment.startPoint
import kotlinx.android.synthetic.main.unmanned_routing_fragment.startStationName
import kotlinx.android.synthetic.main.unmanned_routing_fragment.taskTitleTv
import kotlinx.android.synthetic.main.unmanned_routing_fragment.taskTripInfo
import kotlinx.coroutines.flow.map
class TaxiRoutingFragment : BaseFragment(), ICommonNaviChangedCallback {
companion object {
const val TAG = SceneConstant.M_TAXI + "TaxiRoutingFragment"
fun newInstance(): TaxiRoutingFragment {
val args = Bundle()
val fragment = TaxiRoutingFragment()
fragment.arguments = args
return fragment
}
}
private var mFeedbackDialog: TaxiRoutingFeedbackDialog? = null
private val mViewModel: TaxiRoutingFragmentViewModel by lazy {
ViewModelProvider(
this,
ViewModelProvider.NewInstanceFactory()
)[TaxiRoutingFragmentViewModel::class.java]
}
override fun getLayoutId(): Int {
return R.layout.unmanned_routing_fragment
}
override fun getTagName(): String {
return "TaxiRoutingFragment"
}
override fun initViews() {
initEventBus()
initViewListener()
initViewModelObserver()
}
private fun initEventBus() {
FlowBus.with<RoutingUIState.RoutingTask>(TaxiDriverEventConst.RoutingActivityEvent.EVENT_TYPE_GET_CHOSEN_LINE_TASK)
.register(this) { task ->
mViewModel.sendUiIntent(TaxiRoutingUiIntent.ShowRoutingTask(task))
}
}
private fun initViewListener() {
btnChooseTask.setOnClickListener {
mViewModel.sendUiIntent(TaxiRoutingUiIntent.StartChooseLineAction(System.currentTimeMillis()))
}
}
private fun initViewModelObserver() {
lifecycleScope.launchWhenStarted {
mViewModel.uiStateFlow.map { it.routingUiState }.collect { routingUiState ->
CallerLogger.d(
TAG,
"uiStateFlow-initViewModelObserver: $routingUiState"
)
when (routingUiState) {
is RoutingUIState.Init -> {
showChooseTaskView()
}
is RoutingUIState.RoutingTask -> {
showCurrentLineTaskContentView(routingUiState)
}
is RoutingUIState.ShowFinishTaskButton -> {
showFinishTaskView(routingUiState.routingTask)
}
is RoutingUIState.ShowFeedbackDialog -> {
showFeedbackDialog(routingUiState.grayId)
}
is RoutingUIState.DismissFeedbackDialog -> {
hideFeedbackDialog()
}
}
}
}
}
/**
* 展示选择任务视图
*/
private fun showChooseTaskView() {
noDataContainer.visibility = View.VISIBLE
mCurrentTaskLayout.visibility = View.GONE
headerTitleContainer.visibility = View.GONE
btnChooseTask.visibility = View.VISIBLE
btnStartTask.visibility = View.GONE
finishSubmitIssueGroup.visibility = View.GONE
removeAllMapMarker()
}
/**
* 展示当前路线任务信息
*/
private fun showCurrentLineTaskContentView(data: RoutingUIState.RoutingTask) {
noDataContainer.visibility = View.GONE
mCurrentTaskLayout.visibility = View.VISIBLE
headerTitleContainer.visibility = View.VISIBLE
taskTitleTv.text = data.grayLineBean?.lineName
btnChooseTask.visibility = View.GONE
btnStartTask.visibility = View.VISIBLE
// 开始任务,按钮
btnStartTask.setOnClickListener {
mViewModel.sendUiIntent(TaxiRoutingUiIntent.StartTaskAction(data))
}
finishSubmitIssueGroup.visibility = View.GONE
naviToStart.visibility = View.VISIBLE
naviToEnd.visibility = View.INVISIBLE
updateStartAndEndStationPointByStatus(false)
updateCurrentTaskTripInfo(0, 0)
data.grayLineBean?.startSite?.also {
initStartNaviToStationParam(
false,
it.gcjLat,
it.gcjLon
)
naviToStart.setOnClickListener {
showNaviToEndStationFragment(true)
}
setOrRemoveMapMaker(
true,
TaxiUnmannedConst.TAXI_ROUTING_VERIFY_START_SITE,
it.wgs84Lat,
it.wgs84Lon,
R.raw.star_marker
)
}
data.grayLineBean?.endSite?.also {
setOrRemoveMapMaker(
false,
TaxiUnmannedConst.TAXI_ROUTING_VERIFY_END_SITE,
it.wgs84Lat,
it.wgs84Lon,
R.raw.end_marker
)
}
startStationName.text = data.grayLineBean?.startSite?.siteName
endStationName.text = data.grayLineBean?.endSite?.siteName
}
private fun showFinishTaskView(routingTask: RoutingUIState.RoutingTask) {
btnChooseTask.visibility = View.GONE
btnStartTask.visibility = View.GONE
finishSubmitIssueGroup.visibility = View.VISIBLE
btnFinishTask.setOnClickListener {
mViewModel.sendUiIntent(
TaxiRoutingUiIntent.ShowFeedbackDialog(
routingTask.grayId ?: -1
)
)
}
btnSummitIssue.setOnClickListener {
// mViewModel.sendUiIntent(
// TaxiRoutingUiIntent.SubmitGrayLineIssueLocation(
// routingTask.grayId ?: -1L
// )
// )
//ErrorPointFloatWindow(ActivityUtils.getTopActivity()).showFloatWindow()
context?.let {
ReportErrorPointDialog(it,routingTask.grayId ?: -1L).showDialog()
}
}
naviToStart.visibility = View.INVISIBLE
naviToEnd.visibility = View.VISIBLE
updateStartAndEndStationPointByStatus(true)
updateCurrentTaskTripInfo(0, 0)
routingTask.grayLineBean?.endSite?.also {
initStartNaviToStationParam(
false,
it.gcjLat,
it.gcjLon
)
naviToEnd.setOnClickListener {
showNaviToEndStationFragment(true)
}
setOrRemoveMapMaker(
true,
TaxiUnmannedConst.TAXI_ROUTING_VERIFY_END_SITE,
it.wgs84Lat,
it.wgs84Lon,
R.raw.end_marker
)
}
routingTask.grayLineBean?.startSite?.also {
setOrRemoveMapMaker(
false,
TaxiUnmannedConst.TAXI_ROUTING_VERIFY_START_SITE,
it.wgs84Lat,
it.wgs84Lon,
R.raw.star_marker
)
}
}
private fun updateStartAndEndStationPointByStatus(isGoingToStation: Boolean) {
if (isGoingToStation) {// 即将到达的站点
startPoint.setImageResource(R.drawable.taxi_driver_circle_blue_big)
endPoint.setImageResource(R.drawable.taxi_driver_circle_green_big)
} else {// 到达站点 或 已经经过的站点
startPoint.setImageResource(R.drawable.taxi_driver_circle_green_big)
endPoint.setImageResource(R.drawable.taxi_driver_circle_blue_big)
}
}
private fun showFeedbackDialog(grayId: Long) {
val occurrenceTime = System.currentTimeMillis()
val builder: TaxiRoutingFeedbackDialog.Builder = TaxiRoutingFeedbackDialog.Builder()
builder.cancelStr(
MainMoGoApplication.getApp()
.getString(R.string.routing_feedback_result_btn_not_sure)
).confirmStr(
MainMoGoApplication.getApp()
.getString(R.string.routing_feedback_result_btn_sure)
).tips(MainMoGoApplication.getApp().getString(R.string.routing_feedback_result_hint))
.clickListener(object :
TaxiRoutingFeedbackDialog.TaxiRoutingFeedBackDialogClickListener {
override fun confirm() {
mViewModel.sendUiIntent(
TaxiRoutingUiIntent.SubmitEndTask(
grayId,
EndGrayTaskFeedbackType.USABLE_YES,
occurrenceTime
)
)
}
override fun cancel() {
mViewModel.sendUiIntent(
TaxiRoutingUiIntent.SubmitEndTask(
grayId,
EndGrayTaskFeedbackType.USABLE_NO,
occurrenceTime
)
)
}
})
activity?.also {
mFeedbackDialog = builder.build(it)
mFeedbackDialog?.showDialog()
}
}
private fun hideFeedbackDialog() {
mFeedbackDialog?.hideDialog()
}
/**
* 显示/隐藏 前往任务目的地的导航
*
* @param isShow
*/
private fun showNaviToEndStationFragment(isShow: Boolean) {
// FlowBus.with<Boolean>(TaxiDriverEventConst.TaxiFragmentEvent.EVENT_TYPE_START_NAVI_TO_END_STATION)
// .post(this.lifecycleScope, isShow)
TaxiRoutingModel.startNaviToEndStationByAMap(isShow)
}
private fun initStartNaviToStationParam(
isVoicePlay: Boolean,
stationLat: Double,
stationLng: Double
) {
AmapNaviToDestinationModel.getInstance(context).destroyAmaNavi()
val gcJ02Location = OchLocationManager.getGCJ02Location()
val mCurLatitude = gcJ02Location.latitude
val mCurLongitude = gcJ02Location.longitude
CallerLogger.d(
TAG,
"currentLocation, lat=$mCurLatitude, lon=$mCurLongitude"
)
val startNaviLatLng = NaviLatLng(mCurLatitude, mCurLongitude)
val endNaviLatLng = NaviLatLng(stationLat, stationLng)
AmapNaviToDestinationModel.getInstance(context).initAMapNavi(startNaviLatLng, endNaviLatLng)
AmapNaviToDestinationModel.getInstance(context).setVoiceIsMute(isVoicePlay)
// 怀疑在线程池执行的destroyAmaNavi会比 主线程执行的setTaxiNaviChangedCallback慢导致setTaxiNaviChangedCallback(this)会被冲掉
ThreadUtils.getSinglePool().execute {
AmapNaviToDestinationModel.getInstance(context).setTaxiNaviChangedCallback(this)
}
}
override fun onCurrentNaviDistAndTimeChanged(meters: Int, timeInSecond: Long) {
updateCurrentTaskTripInfo(meters.toLong(), timeInSecond)
}
override fun reInitNaviAmap(isPlay: Boolean, isRestart: Boolean) {
CallerLogger.d(TAG, "isPlay = $isPlay, isRestart=$isRestart")
if (!isRestart) {
// FlowBus.with<Boolean>(TaxiDriverEventConst.TaxiFragmentEvent.EVENT_TYPE_SHOW_AMAP_NAVI_TO_STATION_FRAGMENT)
// .post(this.lifecycleScope, false)
TaxiRoutingModel.startNaviToEndStationByAMap(false)
return
}
}
/**
* 剩余里程和剩余时间
* @param meters 米
* @param timeInSecond 秒
*/
private fun updateCurrentTaskTripInfo(meters: Long, timeInSecond: Long) {
UiThreadHandler.post {
CallerLogger.d(
TAG,
"updateCurrentTaskTripInfo, taskUtil, ${
TaskUtils.getCurrentTaskTripHtml(
meters,
timeInSecond
)
}"
)
taskTripInfo.text = TaskUtils.getCurrentTaskTripHtml(meters, timeInSecond)
}
}
/**
* 绘制地图起点终点
* @param isAdd
* @param uuid
*/
private fun setOrRemoveMapMaker(
isAdd: Boolean,
uuid: String,
lat: Double,
lon: Double,
resourceId: Int
) {
if (isAdd) {
MapMakerManager.addMapMaker(TaxiUnmannedConst.TYPE_MARKER_ROUTING_VERIFY, uuid, lat, lon, resourceId)
} else {
MapMakerManager.removeMapMaker(uuid, lat, lon)
}
}
private fun removeAllMapMarker() {
MapMakerManager.removeAllMapMarkerByOwner(TaxiUnmannedConst.TYPE_MARKER_ROUTING_VERIFY)
}
override fun onDestroyView() {
AmapNaviToDestinationModel.getInstance(context).destroyAmaNavi()
super.onDestroyView()
}
}

View File

@@ -1,211 +0,0 @@
package com.mogo.och.unmanned.taxi.ui.routing
import android.content.Context
import android.content.Intent
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.module.status.MogoStatusManager
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.ActivityUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.common.module.manager.autopilot.location.OchLocationManager
import com.mogo.och.common.module.manager.autopilot.line.LineManager
import com.mogo.och.common.module.map.AmapNaviToDestinationModel
import com.mogo.och.data.bean.LineInfo
import com.mogo.och.unmanned.taxi.base.BaseViewModel
import com.mogo.och.unmanned.taxi.base.IUiIntent
import com.mogo.och.unmanned.taxi.bean.GrayLineBean
import com.mogo.och.unmanned.taxi.bean.StartGrayAndQueryContrailRsp
import com.mogo.och.unmanned.taxi.callback.ITaxiRoutingCallback
import com.mogo.och.unmanned.taxi.ui.debug.DebugView
class TaxiRoutingFragmentViewModel : BaseViewModel<TaxiRoutingUiState, TaxiRoutingUiIntent>(),
ITaxiRoutingCallback {
companion object {
const val TAG = SceneConstant.M_TAXI + "TaxiRoutingFragmentViewModel"
}
init {
TaxiRoutingModel.addTaxiRoutingListener(TAG, this)
}
private val mContext: Context
get() = AbsMogoApplication.getApp().applicationContext
override fun initUiState(): TaxiRoutingUiState {
return TaxiRoutingUiState(RoutingUIState.Init)
}
override fun handleIntent(intent: IUiIntent) {
when (intent) {
is TaxiRoutingUiIntent.StartChooseLineAction -> {
DebugView.printInfoMsg("[选择任务] 跳转到选择任务列表")
val intent = Intent(mContext, TaxiRoutingChooseLineActivity::class.java)
ActivityUtils.startActivity(intent)
}
is TaxiRoutingUiIntent.ShowRoutingTask -> {
DebugView.printInfoMsg("[选择任务] 展示当前选择任务刷新UI")
val task = intent.routingTask
sendUiState {
copy(
routingUiState = RoutingUIState.RoutingTask(
task.grayLineBean,
task.contrailBean,
task.grayId
)
)
}
if(task.contrailBean?.lineId != null &&task.contrailBean.lineName!=null){
LineManager.setLineInfo(LineInfo(task.contrailBean.lineId,task.contrailBean.lineName))
}
// 设置灰度路线任务执行状态,切换模式时判断使用
MogoStatusManager.getInstance()
.setTaxiUnmanedDriverLineRoutingPerformTask(TAG, true)
}
// 启动自动驾驶
is TaxiRoutingUiIntent.StartTaskAction -> {
DebugView.printInfoMsg("[开始任务] 准备开始任务")
val grayLineBean = intent.routingTask.grayLineBean
val contrailBean = intent.routingTask.contrailBean
val grayId = intent.routingTask.grayId
if (grayLineBean == null || contrailBean == null) {
ToastUtils.showShort("灰度线路或轨迹信息异常,请稍后再试")
DebugView.printErrorMsg("[开始任务] 灰度线路或轨迹信息异常,请稍后再试")
return
}
DebugView.printInfoMsg("[启自驾] 准备启动自驾")
TaxiRoutingModel.updateCurrentGrayLineAndContrail(
grayLineBean,
contrailBean,
grayId
)
TaxiRoutingModel.startAutoPilot(grayLineBean!!, contrailBean!!)
//添加到站监听
TaxiRoutingModel.addAutoPilotStatusListener()
TaxiRoutingModel.addGDMapCurrentLocationListener()
sendUiState {
copy(
routingUiState = RoutingUIState.ShowFinishTaskButton(intent.routingTask)
)
}
}
is TaxiRoutingUiIntent.SubmitGrayLineIssueLocation -> {
DebugView.printInfoMsg("[上报打点] 准备上报打点")
val grayId = intent.grayId
val currentLocation = OchLocationManager.getGCJ02Location()
TaxiRoutingModel.submitGrayLineIssueLocation(
grayId,
currentLocation.longitude,
currentLocation.latitude
)
}
is TaxiRoutingUiIntent.ShowFeedbackDialog -> {
DebugView.printInfoMsg("[结束任务] 展示结束任务弹框")
sendUiState {
copy(
routingUiState = RoutingUIState.ShowFeedbackDialog(
intent.grayId,
System.currentTimeMillis()
)
)
}
}
is TaxiRoutingUiIntent.SubmitEndTask -> {
DebugView.printInfoMsg("[结束任务] 准备结束任务grayId=${intent.grayId}, type=${intent.type.name}")
TaxiRoutingModel.endGrayTask(intent.grayId, intent.type,intent.occurrenceTime)
}
}
}
override fun onQueryRoutingGrayLineListSuccess(data: MutableList<GrayLineBean>) {
}
override fun onQueryRoutingGrayLineListFailed(errorStr: String) {
}
override fun onStartGrayTaskAndQueryContrailSuccess(data: StartGrayAndQueryContrailRsp) {
}
override fun onStartGrayTaskAndQueryContrailFailed(errorStr: String) {
}
override fun onSubmitGrayLineIssueLocationSuccess() {
ToastUtils.showShort("问题记录成功")
}
override fun onSubmitGrayLineIssueLocationFailed(errorStr: String) {
ToastUtils.showShort("问题记录失败:$errorStr")
}
override fun onSubmitEndTaskSuccess() {
ToastUtils.showLong("结束任务成功")
sendUiState {
copy(
routingUiState = RoutingUIState.Init
)
}
TaxiRoutingModel.updateCurrentGrayLineAndContrail(null, null, -1L)
// 设置灰度路线任务执行状态,切换模式时判断使用
MogoStatusManager.getInstance().setTaxiUnmanedDriverLineRoutingPerformTask(TAG, false)
LineManager.setLineInfo(null);
TaxiRoutingModel.startNaviToEndStationByAMap(false)
// 移除到站监听
TaxiRoutingModel.removeAutoPilotStatusListener()
TaxiRoutingModel.removeGDMapCurrentLocationListener()
// 移除高德导航计算距离
AmapNaviToDestinationModel.getInstance(mContext).destroyAmaNavi()
}
override fun onSubmitEndTaskFailed(errorStr: String) {
ToastUtils.showLong("结束任务失败")
sendUiState {
copy(
routingUiState = RoutingUIState.DismissFeedbackDialog
)
}
}
override fun onAutoPilotArriveAtEndStation(grayId: Long?) {
TaxiRoutingModel.removeAutoPilotStatusListener()
TaxiRoutingModel.removeGDMapCurrentLocationListener()
TaxiRoutingModel.cancelAutopilot()
DebugView.printInfoMsg("[结束任务] 到终点站,自动展示结束任务弹框")
sendUiState {
copy(
routingUiState = RoutingUIState.ShowFeedbackDialog(
grayId ?: -1L,
System.currentTimeMillis()
)
)
}
}
override fun onGDMapArriveAtEndStation(grayId: Long?) {
TaxiRoutingModel.removeAutoPilotStatusListener()
TaxiRoutingModel.removeGDMapCurrentLocationListener()
TaxiRoutingModel.cancelAutopilot()
DebugView.printInfoMsg("[结束任务] 到终点站,自动展示结束任务弹框")
sendUiState {
copy(
routingUiState = RoutingUIState.ShowFeedbackDialog(
grayId ?: -1L,
System.currentTimeMillis()
)
)
}
}
override fun onCleared() {
TaxiRoutingModel.removeTaxiRoutingListener(TAG)
super.onCleared()
}
}

View File

@@ -1,684 +1,19 @@
package com.mogo.och.unmanned.taxi.ui.routing
import android.content.Context
import android.text.TextUtils
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.data.BaseData
import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters
import com.mogo.eagle.core.data.config.FunctionBuildConfig
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.CallerAutoPilotControlManager
import com.mogo.eagle.core.network.utils.GsonUtil
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.DrivingDirectionUtils
import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.eagle.core.utilcode.util.NetworkUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.common.module.manager.autopilot.OCHAdasAbilityManager
import com.mogo.och.common.module.manager.autopilot.autopilot.IOchAutopilotStatusListener
import com.mogo.och.common.module.manager.autopilot.autopilot.OchAutoPilotManager
import com.mogo.och.common.module.manager.autopilot.autopilot.OchAutoPilotStatusListenerManager
import com.mogo.och.common.module.manager.autopilot.autopilot.bean.ArrivedStation
import com.mogo.och.common.module.manager.autopilot.location.OchLocationManager
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager.writeChainLog
import com.mogo.och.common.module.network.OchCommonServiceCallback
import com.mogo.och.common.module.utils.OCHThreadPoolManager
import com.mogo.och.unmanned.taxi.bean.ContrailBean
import com.mogo.och.unmanned.taxi.bean.EndGrayContrailTaskReq
import com.mogo.och.unmanned.taxi.bean.EndGrayTaskFeedbackType
import com.mogo.och.unmanned.taxi.bean.GrayLineBean
import com.mogo.och.unmanned.taxi.bean.QueryGrayContrailListRsp
import com.mogo.och.unmanned.taxi.bean.StartGrayAndQueryContrailRsp
import com.mogo.och.unmanned.taxi.bean.SubmitGrayLineIssueLocationReq
import com.mogo.och.unmanned.taxi.callback.ITaxiControllerStatusCallback
import com.mogo.och.unmanned.taxi.callback.ITaxiOrderStatusCallback
import com.mogo.och.unmanned.taxi.callback.ITaxiRoutingCallback
import com.mogo.och.unmanned.taxi.constant.TaxiUnmannedConst
import com.mogo.och.unmanned.taxi.network.TaxiRoutingServiceManager
import com.mogo.och.unmanned.taxi.ui.debug.DebugView
import java.util.concurrent.ConcurrentHashMap
object TaxiRoutingModel {
private val TAG = SceneConstant.M_TAXI + TaxiRoutingModel::class.java.simpleName
private val mContext: Context
get() = AbsMogoApplication.getApp().applicationContext
private var currentGrayLineBean: GrayLineBean? = null
private var currentContrailBean: ContrailBean? = null
private var currentGrayId: Long? = null
private val mTaxiRoutingCallbackMap: ConcurrentHashMap<String, ITaxiRoutingCallback> =
ConcurrentHashMap()
fun addTaxiRoutingListener(tag: String, listener: ITaxiRoutingCallback) {
if (mTaxiRoutingCallbackMap.containsKey(tag)) {
return
}
mTaxiRoutingCallbackMap[tag] = listener
}
fun removeTaxiRoutingListener(tag: String) {
if (!mTaxiRoutingCallbackMap.containsKey(tag)) {
return
}
mTaxiRoutingCallbackMap.remove(tag)
}
private var mControllerStatusCallback: ITaxiControllerStatusCallback? = null
fun setControllerStatusCallback(callback: ITaxiControllerStatusCallback?) {
mControllerStatusCallback = callback
}
private var mOrderStatusCallback: ITaxiOrderStatusCallback? = null
fun setOrderStatusCallback(callback: ITaxiOrderStatusCallback?) {
mOrderStatusCallback = callback
}
fun addAutoPilotStatusListener() {
OchAutoPilotStatusListenerManager.addListener(TAG, mMogoAutopilotStatusListener)
}
fun removeAutoPilotStatusListener() {
OchAutoPilotStatusListenerManager.removeListener(TAG)
}
//MAP到站监听
private val mMogoAutopilotStatusListener: IOchAutopilotStatusListener =
object : IOchAutopilotStatusListener {
override fun onAutopilotArriveAtStation(arrivalNotification: ArrivedStation?) {
CallerLogger.i(
TAG,
"onAutopilotArriveAtStation = ${arrivalNotification.toString()}"
)
DebugView.printInfoMsg("[MAP到站通知] 上报到站location=${arrivalNotification?.endLocation}")
val endSiteLat: Double? = currentGrayLineBean?.endSite?.gcjLat
val endSiteLon: Double? = currentGrayLineBean?.endSite?.gcjLon
val mapEndSiteLatWgs: Double? = arrivalNotification?.endLocation?.latitude
val mapEndSiteLonWgs: Double? = arrivalNotification?.endLocation?.longitude
if (endSiteLon != null && endSiteLat != null && mapEndSiteLonWgs != null && mapEndSiteLatWgs != null) {
val latLngs =
CoordinateUtils.transformWgsToGcj(mapEndSiteLatWgs, mapEndSiteLonWgs)
val distance = CoordinateUtils.calculateLineDistance(
endSiteLon, endSiteLat,
latLngs[0], latLngs[1]
).toDouble()
if (distance <= TaxiUnmannedConst.ARRIVE_AT_START_STATION_DISTANCE) {// 两坐标小于15米
DebugView.printInfoMsg("[MAP到站通知] 到站坐标和任务终点15米内, 请求到站")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onAutoPilotArriveAtEndStation(currentGrayId)
}
} else {
DebugView.printInfoMsg("[MAP到站通知] 到站坐标和任务终点不一致, 不请求到站")
}
} else {
DebugView.printErrorMsg(
"[MAP到站通知] 上报到站数据异常endSiteLat = $endSiteLat, endSiteLon = $endSiteLon, " +
"mapEndSiteLat = $mapEndSiteLatWgs, mapEndSiteLon = $mapEndSiteLonWgs"
)
}
}
}
// 自车定位监听
private val mMapLocationListener: IMoGoChassisLocationGCJ02Listener =
object : IMoGoChassisLocationGCJ02Listener {
override fun onChassisLocationGCJ02(currentLocation: MogoLocation?) {
//位置变化时通过围栏判断是否到达x点
if (null == currentLocation) return
val endSite = currentGrayLineBean?.endSite ?: return
OCHThreadPoolManager.getsInstance().locationExecute {
val endLon = endSite.gcjLon
val endLat = endSite.gcjLat
val distance = CoordinateUtils.calculateLineDistance(
endLon,
endLat,
currentLocation.longitude,
currentLocation.latitude
).toDouble()
CallerLogger.i(TAG, "judgeEndStation() distance = $distance")
//1、当前位置和站点围栏15m内
if (distance <= TaxiUnmannedConst.ARRIVE_AT_START_STATION_DISTANCE) {
//2、开始计算当前位置和站点的向量角度 < 90度 未经过 >90度 经过
val stationAngle = DrivingDirectionUtils.getDegreeOfCar2Poi(
currentLocation.longitude,
currentLocation.latitude,
endLon,
endLat,
currentLocation.heading.toInt()
).toDouble()
CallerLogger.i(TAG, "judgeEndStation() stationAngle = $stationAngle")
//3、刚过站且过站距离在15m内 提交到站
if (stationAngle > 90) {
CallerLogger.i(TAG, "judgeEndStation() = 刚过站且在15m内")
DebugView.printInfoMsg(
"[自车定位围栏] 触发围栏, endSiteId=${currentGrayLineBean?.endSite?.siteId}, endSiteName=${currentGrayLineBean?.endSite?.siteName}, lineId=${currentGrayLineBean?.lineId},围栏范围:${TaxiUnmannedConst.ARRIVE_AT_START_STATION_DISTANCE}米 刚过站且在15m内"
)
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onGDMapArriveAtEndStation(currentGrayId)
}
} else {
// 4、 没有过站距离小于15m 速度小于0.3(根据M1来的模数 可能要调)
if (currentLocation.gnssSpeed < 0.3) {
CallerLogger.i(
TAG,
"judgeEndStation() = 没有过站、速度基本为零且在15m内"
)
DebugView.printInfoMsg(
"[自车定位围栏] 触发围栏, endSiteId=${currentGrayLineBean?.endSite?.siteId}, endSiteName=${currentGrayLineBean?.endSite?.siteName}, lineId=${currentGrayLineBean?.lineId},围栏范围:${TaxiUnmannedConst.ARRIVE_AT_START_STATION_DISTANCE}米 没有过站、速度基本为零且在15m内"
)
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onGDMapArriveAtEndStation(currentGrayId)
}
}
}
}
}
}
}
fun addGDMapCurrentLocationListener() {
//定位监听, 传false是高德坐标系 10 -> 100ms一次
OchLocationManager.addGCJ02Listener(TAG, 5, mMapLocationListener)
}
fun removeGDMapCurrentLocationListener() {
OchLocationManager.removeGCJ02Listener(TAG)
}
/**
* 查询灰度路线
*/
fun queryRoutingGrayLineList() {
DebugView.printInfoMsg("[查询灰度路线] 准备发送请求sn=${SharedPrefsMgr.getInstance().sn}")
TaxiRoutingServiceManager.queryRoutingGrayLineList(mContext,
object : OchCommonServiceCallback<QueryGrayContrailListRsp> {
override fun onSuccess(data: QueryGrayContrailListRsp) {
CallerLogger.d(
TAG,
"queryRoutingGrayLineList onSuccess: data=${GsonUtils.toJson(data)}"
)
DebugView.printInfoMsg("[查询灰度路线] 请求successdataSize=${data?.data?.size}")
val result = mutableListOf<GrayLineBean>()
data.data?.also {
result.addAll(it)
}
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onQueryRoutingGrayLineListSuccess(result)
}
}
override fun onFail(code: Int, msg: String?) {
CallerLogger.d(
TAG,
"queryRoutingGrayLineList onFail: code=$code, msg=$msg"
)
DebugView.printErrorMsg("[查询灰度路线] 请求fail, code=$code, msg=$msg, sn=${SharedPrefsMgr.getInstance().sn}")
ToastUtils.showShort("查询灰度线路列表异常, 请稍后重试, code=$code")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onQueryRoutingGrayLineListFailed(
msg ?: "查询灰度线路列表异常, 请稍后重试"
)
}
}
override fun onError() {
super.onError()
var hintStr = ""
if (!NetworkUtils.isConnected(mContext)) {
hintStr = "网络出现异常,请稍后重试"
} else {
hintStr = "查询灰度线路列表异常, 请稍后重试"
}
CallerLogger.d(
TAG,
"queryRoutingGrayLineList onError, msg=$hintStr, sn=${SharedPrefsMgr.getInstance().sn}"
)
DebugView.printErrorMsg("[查询灰度路线] 请求error, msg=$hintStr")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onQueryRoutingGrayLineListFailed(hintStr)
}
}
})
}
/**
* 开始灰度任务&查询轨迹详情
*/
fun startGrayTaskAndQueryRoutingContrail(contrailId: Long, grayLineBean: GrayLineBean) {
DebugView.printInfoMsg("[开始灰度任务&查询轨迹详情] 准备发送请求contrailId=${contrailId}, lineId=${grayLineBean.lineId}")
TaxiRoutingServiceManager.startGrayTaskAndQueryRoutingContrail(
mContext,
sn = SharedPrefsMgr.getInstance().sn,
contrailId = contrailId,
grayLineBean = grayLineBean,
object : OchCommonServiceCallback<StartGrayAndQueryContrailRsp> {
override fun onSuccess(data: StartGrayAndQueryContrailRsp) {
CallerLogger.d(
TAG,
"startGrayTaskAndQueryRoutingContrail onSuccess: data=${
GsonUtils.toJson(
data
)
}"
)
DebugView.printInfoMsg("[开始灰度任务&查询轨迹详情] 请求successtaskId=${data.taskId}, contrailId=${contrailId}, lineId=${grayLineBean.lineId}")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onStartGrayTaskAndQueryContrailSuccess(data)
// Routing 从这里解析出经停信息,轨迹信息,并调用下载轨迹接口
sendTrajectoryReq(data)
}
}
override fun onFail(code: Int, msg: String?) {
CallerLogger.d(
TAG,
"startGrayTaskAndQueryRoutingContrail onFail: code=$code, msg=$msg"
)
DebugView.printErrorMsg("[开始灰度任务&查询轨迹详情] 请求fail, code=$code, msg=$msg, contrailId=${contrailId}, lineId=${grayLineBean.lineId}")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onStartGrayTaskAndQueryContrailFailed(
msg ?: "startGrayTaskAndQueryRoutingContrail onFail"
)
}
}
override fun onError() {
super.onError()
var hintStr = ""
if (!NetworkUtils.isConnected(mContext)) {
hintStr = "网络出现异常,请稍后重试"
} else {
hintStr = "开始任务并查询轨迹详情异常, 请稍后重试"
}
CallerLogger.d(
TAG,
"startGrayTaskAndQueryRoutingContrail onError, msg=$hintStr, contrailId=${contrailId}, lineId=${grayLineBean.lineId}"
)
DebugView.printErrorMsg("[开始灰度任务&查询轨迹详情] 请求error, msg=$hintStr")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onStartGrayTaskAndQueryContrailFailed(hintStr)
}
}
}
)
}
/**
* 灰度任务过程中,上报问题打点
*/
fun submitGrayLineIssueLocation(grayId: Long, gcjLon: Double, gcjLat: Double) {
DebugView.printInfoMsg("[上报打点] 准备发送请求grayId=$grayId, gcjLon=$gcjLon, gcjLat=$gcjLat")
val submit = SubmitGrayLineIssueLocationReq(grayId, gcjLon, gcjLat)
TaxiRoutingServiceManager.submitGrayLineIssueLocation(
mContext,
submit,
object : OchCommonServiceCallback<BaseData> {
override fun onSuccess(data: BaseData?) {
CallerLogger.d(
TAG,
"submitGrayLineIssueLocation onSuccess: data=${
GsonUtils.toJson(
data
)
}"
)
DebugView.printInfoMsg("[上报打点] 准备successgrayId=$grayId, gcjLon=$gcjLon, gcjLat=$gcjLat")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onSubmitGrayLineIssueLocationSuccess()
}
}
override fun onFail(code: Int, msg: String?) {
CallerLogger.d(
TAG,
"submitGrayLineIssueLocation onFail: code=$code, msg=$msg"
)
DebugView.printErrorMsg("[上报打点] 请求fail, code=$code, msg=$msg, grayId=$grayId")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onSubmitGrayLineIssueLocationFailed(
msg ?: "submitGrayLineIssueLocation onFail"
)
}
}
override fun onError() {
super.onError()
var hintStr = ""
if (!NetworkUtils.isConnected(mContext)) {
hintStr = "网络出现异常,请稍后重试"
} else {
hintStr = "上报问题打点异常, 请稍后重试"
}
CallerLogger.d(
TAG,
"submitGrayLineIssueLocation onError, msg=$hintStr"
)
DebugView.printErrorMsg("[上报打点] 请求error, msg=$hintStr, grayId=$grayId")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onSubmitGrayLineIssueLocationFailed(hintStr)
}
}
}
)
}
/**
* 结束灰度任务
*/
fun endGrayTask(grayId: Long, type: EndGrayTaskFeedbackType, occurrenceTime: Long) {
DebugView.printInfoMsg("[结束灰度任务] 准备发送请求grayId=$grayId type=${type.type}, typeName=${type.name}")
val submit = EndGrayContrailTaskReq(grayId, type.type, occurrenceTime)
TaxiRoutingServiceManager.endGrayTask(
mContext,
submit,
object : OchCommonServiceCallback<BaseData> {
override fun onSuccess(data: BaseData?) {
CallerLogger.d(
TAG,
"endGrayTask onSuccess: data=${
GsonUtils.toJson(
data
)
}"
)
DebugView.printInfoMsg("[结束灰度任务] 请求successgrayId=$grayId type=${type.type}, typeName=${type.name}")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onSubmitEndTaskSuccess()
}
}
override fun onFail(code: Int, msg: String?) {
CallerLogger.d(
TAG,
"endGrayTask onFail: code=$code, msg=$msg"
)
DebugView.printErrorMsg("[结束灰度任务] 请求fail, code=$code, msg=$msg, grayId=$grayId type=${type.type}, typeName=${type.name}")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onSubmitEndTaskFailed(
msg ?: "endGrayTask onFail"
)
}
}
override fun onError() {
super.onError()
var hintStr = ""
if (!NetworkUtils.isConnected(mContext)) {
hintStr = "网络出现异常,请稍后重试"
} else {
hintStr = "上报结束任务异常, 请稍后重试"
}
CallerLogger.d(
TAG,
"endGrayTask onError, msg=$hintStr"
)
DebugView.printErrorMsg("[结束灰度任务] 请求error, msg=$hintStr, grayId=$grayId type=${type.type}, typeName=${type.name}")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onSubmitEndTaskFailed(hintStr)
}
}
})
}
/**
* 下载路线请求
*/
fun sendTrajectoryReq(startGrayAndQueryContrailRsp: StartGrayAndQueryContrailRsp) {
startGrayAndQueryContrailRsp.contrail?.let { contrail ->
// 初始化自动驾驶需要的参数
val parameters = initAutopilotControlParameters(
startGrayAndQueryContrailRsp.grayLineBean,
contrail
)
if (parameters!!.autoPilotLine == null) {
CallerLogger.e(
SceneConstant.M_BUS + TAG,
"sendTrajectoryReq(): mAutoPilotLine is null!!!"
)
return
}
writeChainLog(
"轨迹监控",
"sendTrajectoryReq() 下发轨迹 轨迹id" + parameters.autoPilotLine!!.lineId,
true,
OchChainLogManager.EVENT_KEY_INFE_WITH_TRAJECTORY
)
CallerAutoPilotControlManager.sendTrajectoryDownloadReq(parameters)
CallerLogger.d(
SceneConstant.M_BUS + TAG,
"sendTrajectoryReq(): "
+ GsonUtils.toJson(parameters)
)
}
}
/**
* 更新灰度路线信息
*/
fun updateCurrentGrayLineAndContrail(
grayLineBean: GrayLineBean?,
contrailBean: ContrailBean?,
grayId: Long?
) {
currentGrayLineBean = grayLineBean
currentContrailBean = contrailBean
currentGrayId = grayId
}
/**
* 灰度测试路线,启动自动驾驶
*/
fun startAutoPilotByClick() {
if (currentGrayLineBean == null || currentContrailBean == null) {
CallerLogger.e(
TAG,
"startAutoPilotByClick 异常currentGrayLineBean == null || currentContrailBean == null"
)
DebugView.printErrorMsg("[启自驾] startAutoPilotByClick 异常currentGrayLineBean == null || currentContrailBean == null")
return
}
startAutoPilot(currentGrayLineBean!!, currentContrailBean!!)
}
/**
* 启动自动驾驶
*/
fun startAutoPilot(grayLineBean: GrayLineBean, contrailBean: ContrailBean) {
if (grayLineBean.startSite == null || grayLineBean.endSite == null) {
CallerLogger.e(TAG, "start site or end site is null")
DebugView.printErrorMsg("[启自驾] 当前订单不存在或异常!")
ToastUtils.showShort("当前订单不存在或异常!")
return
}
//根据开关和后台是否发布轨迹启动自驾
if (FunctionBuildConfig.isPassStartAutopilotCommand
&& TextUtils.isEmpty(contrailBean.csvFileUrl)
&& TextUtils.isEmpty(contrailBean.csvFileUrlDPQP)
) {
ToastUtils.showLong("无发布轨迹, 请发布后重试")
DebugView.printErrorMsg("[启自驾] 无发布轨迹, 请发布后重试")
CallerLogger.e(
TAG, "isPassStartAutopilotCommand = " +
FunctionBuildConfig.isPassStartAutopilotCommand
+ "busRoutesResult.csvFileUrl = " + contrailBean.csvFileUrl
)
return
}
if (!CallerAutoPilotControlManager.isCanStartAutopilot(true)) {
return
}
//4、ssm 给出数据
if (!OchAutoPilotManager.canStartAutoPilotSSM()) {
DebugView.printErrorMsg("[启自驾] ${OCHAdasAbilityManager.getInstance().autopilotUnAbilityReason}")
return
}
// 初始化自动驾驶需要的参数
val parameters = initAutopilotControlParameters(grayLineBean, contrailBean)
if (null == parameters) {
CallerLogger.e(TAG, "AutopilotControlParameters is empty.")
return
}
// 开启自动驾驶
OchAutoPilotManager.startAutoPilot(parameters)
DebugView.printInfoMsg("[启自驾] 调用成功")
CallerLogger.d(
TAG, "start autopilot with parameter: %s",
GsonUtil.jsonFromObject(parameters)
)
mControllerStatusCallback?.startOpenAutopilot()
}
/**
* 初始化自动驾驶控制参数
*/
private fun initAutopilotControlParameters(
grayLineBean: GrayLineBean,
contrailBean: ContrailBean
): AutopilotControlParameters? {
val parameters = AutopilotControlParameters()
val startWgsLon = grayLineBean.startSite!!.wgs84Lon
val startWgsLat = grayLineBean.startSite!!.wgs84Lat
val endWgsLon = grayLineBean.endSite!!.wgs84Lon
val endWgsLat = grayLineBean.endSite!!.wgs84Lat
parameters.vehicleType = TaxiUnmannedConst.BUSINESSTYPE
parameters.startName =
grayLineBean.startSite!!.siteName // 8.10 拼音首字母大写 改为直接传中文
parameters.endName =
grayLineBean.endSite!!.siteName // 8.10 拼音首字母大写 改为直接传中文
parameters.startLatLon =
AutopilotControlParameters.AutoPilotLonLat(startWgsLat, startWgsLon)
parameters.endLatLon = AutopilotControlParameters.AutoPilotLonLat(endWgsLat, endWgsLon)
// Routing 给算路引擎使用的:经停点列表、黑名单
val wayLatLons: MutableList<AutopilotControlParameters.AutoPilotLonLat> = ArrayList()
val blackLatLons: MutableList<AutopilotControlParameters.AutoPilotLonLat> = ArrayList()
// 途经点
if (!contrailBean.passPoints.isNullOrEmpty()) {
for (mogoLatLng in contrailBean.passPoints!!) {
wayLatLons.add(
AutopilotControlParameters.AutoPilotLonLat(
mogoLatLng.wgs84Lat,
mogoLatLng.wgs84Lon,
when (mogoLatLng.pointType) {
1 -> {//途径点
false
}
2 -> {//禁行点
false
}
3 -> {//站点
true
}
else -> {
false
}
}
)
)
}
}
// 黑名单点
if (!contrailBean.blackPoints.isNullOrEmpty()) {
for (mogoLatLng in contrailBean.blackPoints!!) {
blackLatLons.add(
AutopilotControlParameters.AutoPilotLonLat(
mogoLatLng.wgs84Lat,
mogoLatLng.wgs84Lon,
when (mogoLatLng.pointType) {
1 -> {//途径点
false
}
2 -> {//禁行点
false
}
3 -> {//站点
true
}
else -> {
false
}
}
)
)
}
}
parameters.wayLatLons = wayLatLons
parameters.blackLatLons = blackLatLons
if (parameters.autoPilotLine == null) {
parameters.autoPilotLine = AutopilotControlParameters.AutoPilotLine(
contrailBean.lineId,
contrailBean.lineName,
contrailBean.csvFileUrl,
contrailBean.csvFileMd5,
contrailBean.txtFileUrl,
contrailBean.txtFileMd5,
contrailBean.contrailSaveTime,
TaxiUnmannedConst.BUSINESSTYPE.toString(),
"",
"",
"",
"",
-1L
)
}
return parameters
}
/**
* 结束自动驾驶
* */
fun cancelAutopilot() {
try {
CallerAutoPilotControlManager.cancelAutoPilot()
DebugView.printInfoMsg("[取消自驾] 调用成功")
CallerLogger.d(TAG, "结束自动驾驶")
} catch (e: Exception) {
e.printStackTrace()
}
}
/**
* 显示/隐藏 前往任务目的地的导航

View File

@@ -0,0 +1,189 @@
package com.mogo.och.unmanned.taxi.ui.routing.routingrunning
import androidx.lifecycle.ViewModel
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.module.status.MogoStatusManager
import com.mogo.eagle.core.data.BaseData
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.eagle.core.utilcode.util.NetworkUtils
import com.mogo.och.common.module.manager.autopilot.autopilot.IOchAutopilotStatusListener
import com.mogo.och.common.module.manager.autopilot.autopilot.OchAutoPilotStatusListenerManager
import com.mogo.och.common.module.manager.autopilot.autopilot.bean.ArrivedStation
import com.mogo.och.common.module.manager.autopilot.line.ILineCallback
import com.mogo.och.common.module.manager.autopilot.line.LineManager
import com.mogo.och.common.module.network.OchCommonServiceCallback
import com.mogo.och.unmanned.taxi.bean.ContrailBean
import com.mogo.och.unmanned.taxi.bean.EndGrayContrailTaskReq
import com.mogo.och.unmanned.taxi.bean.EndGrayTaskFeedbackType
import com.mogo.och.unmanned.taxi.bean.GrayLineBean
import com.mogo.och.unmanned.taxi.bean.StartGrayAndQueryContrailRsp
import com.mogo.och.unmanned.taxi.constant.TaxiUnmannedConst
import com.mogo.och.unmanned.taxi.network.TaxiRoutingServiceManager
import com.mogo.och.unmanned.taxi.ui.debug.DebugView
import com.mogo.och.unmanned.taxi.ui.routing.TaxiRoutingModel
/**
* @author XuXinChao
* @description BadCase录包管理页面
* @since: 2022/12/15
*/
class RoutingRunningModel : ViewModel() {
private val TAG = RoutingRunningModel::class.java.simpleName
private var viewCallback: RoutingRuningCallback? = null
private val content = AbsMogoApplication.getApp()
private var _data: StartGrayAndQueryContrailRsp?=null
val data: StartGrayAndQueryContrailRsp?
get() = _data
private var currentGrayLineBean: GrayLineBean? = null
private var currentContrailBean: ContrailBean? = null
private var currentGrayId: Long? = null
//MAP到站监听
private val mMogoAutopilotStatusListener: IOchAutopilotStatusListener =
object : IOchAutopilotStatusListener {
override fun onAutopilotArriveAtStation(arrivalNotification: ArrivedStation?) {
CallerLogger.i(
TAG,
"onAutopilotArriveAtStation = ${arrivalNotification.toString()}"
)
DebugView.printInfoMsg("[MAP到站通知] 上报到站location=${arrivalNotification?.endLocation}")
viewCallback?.onArrivedStation(currentGrayId)
}
}
private val lineCallback: ILineCallback = object : ILineCallback {
override fun arrivedStationSuccessBySearch() {
DebugView.printInfoMsg(
"[自车定位围栏] 并查询底盘触发到站, endSiteId=${currentGrayLineBean?.endSite?.siteId}, endSiteName=${currentGrayLineBean?.endSite?.siteName}, lineId=${currentGrayLineBean?.lineId},围栏范围:${TaxiUnmannedConst.ARRIVE_AT_START_STATION_DISTANCE}米 没有过站、速度基本为零且在15m内"
)
viewCallback?.onArrivedStation(currentGrayId)
}
}
override fun onCleared() {
}
fun setDistanceCallback(viewCallback: RoutingRuningCallback) {
this.viewCallback = viewCallback
}
fun setNewData(data: StartGrayAndQueryContrailRsp) {
this._data = data
this.currentGrayLineBean = data.grayLineBean
this.currentContrailBean = data.contrail
this.currentGrayId = data.taskId
//添加到站监听
OchAutoPilotStatusListenerManager.addListener(TAG, mMogoAutopilotStatusListener)
LineManager.addListener(TAG, lineCallback)
}
/**
* 结束灰度任务
*/
fun endGrayTask(grayId: Long, type: EndGrayTaskFeedbackType, occurrenceTime: Long) {
DebugView.printInfoMsg("[结束灰度任务] 准备发送请求grayId=$grayId type=${type.type}, typeName=${type.name}")
val submit = EndGrayContrailTaskReq(grayId, type.type, occurrenceTime)
TaxiRoutingServiceManager.endGrayTask(
content,
submit,
object : OchCommonServiceCallback<BaseData> {
override fun onSuccess(data: BaseData?) {
CallerLogger.d(
TAG,
"endGrayTask onSuccess: data=${
GsonUtils.toJson(
data
)
}"
)
DebugView.printInfoMsg("[结束灰度任务] 请求successgrayId=$grayId type=${type.type}, typeName=${type.name}")
clearData()
viewCallback?.onSubmitEndTaskSuccess()
}
override fun onFail(code: Int, msg: String?) {
CallerLogger.d(
TAG,
"endGrayTask onFail: code=$code, msg=$msg"
)
DebugView.printErrorMsg("[结束灰度任务] 请求fail, code=$code, msg=$msg, grayId=$grayId type=${type.type}, typeName=${type.name}")
viewCallback?.onSubmitEndTaskFailed(msg ?: "endGrayTask onFail")
}
override fun onError() {
super.onError()
var hintStr = ""
if (!NetworkUtils.isConnected(content)) {
hintStr = "网络出现异常,请稍后重试"
} else {
hintStr = "上报结束任务异常, 请稍后重试"
}
CallerLogger.d(
TAG,
"endGrayTask onError, msg=$hintStr"
)
DebugView.printErrorMsg("[结束灰度任务] 请求error, msg=$hintStr, grayId=$grayId type=${type.type}, typeName=${type.name}")
viewCallback?.onSubmitEndTaskFailed(hintStr)
}
})
}
private fun clearData() {
_data = null
this.currentGrayLineBean = null
this.currentContrailBean = null
this.currentGrayId = null
LineManager.setLineInfo(null)
LineManager.setContraiInfo(null)
LineManager.setStartAndEndStation(null,null)
// 设置灰度路线任务执行状态,切换模式时判断使用
MogoStatusManager.getInstance().setTaxiUnmanedDriverLineRoutingPerformTask(TAG, false)
// 移除到站监听
OchAutoPilotStatusListenerManager.removeListener(TAG)
LineManager.removeListener(TAG)
cancelAutopilot()
}
/**
* 结束自动驾驶
* */
private fun cancelAutopilot() {
try {
CallerAutoPilotControlManager.cancelAutoPilot()
DebugView.printInfoMsg("[取消自驾] 调用成功")
CallerLogger.d(TAG, "结束自动驾驶")
} catch (e: Exception) {
e.printStackTrace()
}
}
interface RoutingRuningCallback {
/**
* 结束灰度任务--成功✅
*/
fun onSubmitEndTaskSuccess()
/**
* 结束灰度任务--成功❌
* @param errorStr 错误信息
*/
fun onSubmitEndTaskFailed(errorStr: String)
fun onArrivedStation(currentGrayId: Long?)
}
}

View File

@@ -0,0 +1,284 @@
package com.mogo.och.unmanned.taxi.ui.routing.routingrunning
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.findViewTreeViewModelStoreOwner
import com.amap.api.navi.model.NaviLatLng
import com.mogo.eagle.core.function.main.MainMoGoApplication
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.common.module.manager.autopilot.location.OchLocationManager
import com.mogo.och.common.module.map.AmapNaviToDestinationModel
import com.mogo.och.common.module.map.ICommonNaviChangedCallback
import com.mogo.och.unmanned.taxi.R
import com.mogo.och.unmanned.taxi.bean.EndGrayTaskFeedbackType
import com.mogo.och.unmanned.taxi.bean.StartGrayAndQueryContrailRsp
import com.mogo.och.unmanned.taxi.constant.TaxiUnmannedConst
import com.mogo.och.unmanned.taxi.ui.errorpoint.ReportErrorPointDialog
import com.mogo.och.unmanned.taxi.ui.routing.RoutingSwitchModel
import com.mogo.och.unmanned.taxi.ui.routing.TaxiRoutingFeedbackDialog
import com.mogo.och.unmanned.taxi.ui.routing.TaxiRoutingModel
import com.mogo.och.unmanned.taxi.utils.MapMakerManager
import com.mogo.och.unmanned.taxi.utils.TaskUtils
import kotlinx.android.synthetic.main.unmanned_routing_running.view.actv_current_itinerary_end_name
import kotlinx.android.synthetic.main.unmanned_routing_running.view.actv_current_itinerary_start_name
import kotlinx.android.synthetic.main.unmanned_routing_running.view.actv_distance_end
import kotlinx.android.synthetic.main.unmanned_routing_running.view.actv_end_routing
import kotlinx.android.synthetic.main.unmanned_routing_running.view.actv_routing_name
import kotlinx.android.synthetic.main.unmanned_routing_running.view.actv_submit_task
import kotlinx.android.synthetic.main.unmanned_routing_running.view.actv_time_end
import kotlinx.android.synthetic.main.unmanned_routing_running.view.goutp_show_routing_info
import kotlinx.android.synthetic.main.unmanned_routing_running.view.include_empty
import kotlinx.android.synthetic.main.unmanned_routing_running.view.naviToStart
import kotlinx.coroutines.flow.map
class RoutingRunningView: ConstraintLayout, RoutingRunningModel.RoutingRuningCallback,
ICommonNaviChangedCallback {
constructor(context: Context) : super(context)
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
companion object {
const val TAG = "RoutingRunningView"
}
private var viewModel: RoutingRunningModel?=null
private var swtichViewModel: RoutingSwitchModel?=null
private var mFeedbackDialog: TaxiRoutingFeedbackDialog? = null
init {
LayoutInflater.from(context).inflate(R.layout.unmanned_routing_running, this, true)
initView()
initListener()
}
private fun initListener() {
actv_end_routing.onClick {
viewModel?.data?.taskId?.let {
showFeedbackDialog(it)
}
}
actv_submit_task.onClick {
viewModel?.data?.taskId?.let {
ReportErrorPointDialog(context,it).showDialog()
}
}
}
private fun initView(){
}
private fun hideFeedbackDialog() {
mFeedbackDialog?.hideDialog()
}
private fun showFeedbackDialog(grayId: Long) {
val occurrenceTime = System.currentTimeMillis()
val builder: TaxiRoutingFeedbackDialog.Builder = TaxiRoutingFeedbackDialog.Builder()
builder.cancelStr(
MainMoGoApplication.getApp()
.getString(R.string.routing_feedback_result_btn_not_sure)
).confirmStr(
MainMoGoApplication.getApp()
.getString(R.string.routing_feedback_result_btn_sure)
).tips(MainMoGoApplication.getApp().getString(R.string.routing_feedback_result_hint))
.clickListener(object :
TaxiRoutingFeedbackDialog.TaxiRoutingFeedBackDialogClickListener {
override fun confirm() {
swtichViewModel?.showLoading()
viewModel?.endGrayTask( grayId,
EndGrayTaskFeedbackType.USABLE_YES,
occurrenceTime)
}
override fun cancel() {
swtichViewModel?.showLoading()
viewModel?.endGrayTask( grayId,
EndGrayTaskFeedbackType.USABLE_NO,
occurrenceTime)
}
})
mFeedbackDialog = builder.build(context)
mFeedbackDialog?.showDialog()
}
/**
* 展示选择任务视图
*/
private fun showChooseTaskView() {
swtichViewModel?.showRoutingSelectView()
removeAllMapMarker()
}
private fun removeAllMapMarker() {
MapMakerManager.removeAllMapMarkerByOwner(TaxiUnmannedConst.TYPE_MARKER_ROUTING_VERIFY)
}
private fun initStartNaviToStationParam(
isVoicePlay: Boolean,
stationLat: Double,
stationLng: Double
) {
AmapNaviToDestinationModel.getInstance(context).destroyAmaNavi()
val gcJ02Location = OchLocationManager.getGCJ02Location()
val mCurLatitude = gcJ02Location.latitude
val mCurLongitude = gcJ02Location.longitude
CallerLogger.d(TAG, "currentLocation, lat=$mCurLatitude, lon=$mCurLongitude")
val startNaviLatLng = NaviLatLng(mCurLatitude, mCurLongitude)
val endNaviLatLng = NaviLatLng(stationLat, stationLng)
AmapNaviToDestinationModel.getInstance(context).initAMapNavi(startNaviLatLng, endNaviLatLng)
AmapNaviToDestinationModel.getInstance(context).setVoiceIsMute(isVoicePlay)
// 怀疑在线程池执行的destroyAmaNavi会比 主线程执行的setTaxiNaviChangedCallback慢导致setTaxiNaviChangedCallback(this)会被冲掉
ThreadUtils.getSinglePool().execute {
AmapNaviToDestinationModel.getInstance(context).setTaxiNaviChangedCallback(this)
}
}
/**
* 剩余里程和剩余时间
* @param meters 米
* @param timeInSecond 秒
*/
private fun updateCurrentTaskTripInfo(meters: Long, timeInSecond: Long) {
UiThreadHandler.post {
CallerLogger.d(
TAG,
"updateCurrentTaskTripInfo, taskUtil, ${
TaskUtils.getCurrentTaskTripHtml(
meters,
timeInSecond
)
}"
)
actv_distance_end.text =TaskUtils.getCurrentTaskDistance(meters)
actv_time_end.text =TaskUtils.getCurrentTaskTime(timeInSecond)
}
}
/**
* 绘制地图起点终点
* @param isAdd
* @param uuid
*/
private fun setOrRemoveMapMaker(
isAdd: Boolean,
uuid: String,
lat: Double,
lon: Double,
resourceId: Int
) {
if (isAdd) {
MapMakerManager.addMapMaker(TaxiUnmannedConst.TYPE_MARKER_ROUTING_VERIFY, uuid, lat, lon, resourceId)
} else {
MapMakerManager.removeMapMaker(uuid, lat, lon)
}
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
viewModel = findViewTreeViewModelStoreOwner()?.let {
ViewModelProvider(it).get(RoutingRunningModel::class.java)
}
swtichViewModel = findViewTreeViewModelStoreOwner()?.let {
ViewModelProvider(it).get(RoutingSwitchModel::class.java)
}
viewModel?.setDistanceCallback(this)
}
override fun onCurrentNaviDistAndTimeChanged(meters: Int, timeInSecond: Long) {
updateCurrentTaskTripInfo(meters.toLong(), timeInSecond)
}
override fun reInitNaviAmap(isPlay: Boolean, isRestart: Boolean) {
CallerLogger.d(TAG, "isPlay = $isPlay, isRestart=$isRestart")
if (!isRestart) {
TaxiRoutingModel.startNaviToEndStationByAMap(false)
return
}
}
fun setData(data: StartGrayAndQueryContrailRsp) {
viewModel?.setNewData(data)
include_empty.visibility = View.GONE
goutp_show_routing_info.visibility = View.VISIBLE
actv_routing_name.text = data.grayLineBean.lineName
updateCurrentTaskTripInfo(0, 0)
data.grayLineBean.startSite?.also {
initStartNaviToStationParam(
false,
it.gcjLat,
it.gcjLon
)
naviToStart.setOnClickListener {
TaxiRoutingModel.startNaviToEndStationByAMap(true)
}
setOrRemoveMapMaker(
true,
TaxiUnmannedConst.TAXI_ROUTING_VERIFY_START_SITE,
it.wgs84Lat,
it.wgs84Lon,
R.raw.star_marker
)
}
data.grayLineBean.endSite?.also {
setOrRemoveMapMaker(
false,
TaxiUnmannedConst.TAXI_ROUTING_VERIFY_END_SITE,
it.wgs84Lat,
it.wgs84Lon,
R.raw.end_marker
)
}
actv_current_itinerary_start_name.text = data.grayLineBean.startSite?.siteName
actv_current_itinerary_end_name.text = data.grayLineBean.endSite?.siteName
}
override fun onSubmitEndTaskSuccess() {
ToastUtils.showLong("结束任务成功")
TaxiRoutingModel.startNaviToEndStationByAMap(false)
// 移除高德导航计算距离
AmapNaviToDestinationModel.getInstance(context).destroyAmaNavi()
swtichViewModel?.showRoutingSelectView()
}
override fun onSubmitEndTaskFailed(errorStr: String) {
ToastUtils.showShort(errorStr)
hideFeedbackDialog()
viewModel?.data?.let {
swtichViewModel?.showRoutingRunning(it)
}
}
override fun onArrivedStation(currentGrayId: Long?) {
currentGrayId?.let {
showFeedbackDialog(it)
}
}
}

View File

@@ -0,0 +1,108 @@
package com.mogo.och.unmanned.taxi.ui.routing.routingselect
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.AppCompatTextView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.DiffUtil.Callback
import androidx.recyclerview.widget.RecyclerView
import com.mogo.och.unmanned.taxi.R
import com.mogo.och.unmanned.taxi.bean.GrayLineBean
/**
* 路线列表adapter
*/
class RoutingItemAdapter(
private val mContext: Context,
val mData: MutableList<GrayLineBean>
) : RecyclerView.Adapter<RoutingItemAdapter.RoutingItemViewHolder>() {
companion object{
const val TAG = "SwitchLineAdapter"
}
// RecyclerView设置点击事件
private var mItemClickListener: LineItemClickListener? = null
fun setDataList(dataList: List<GrayLineBean>) {
if (this.mData == dataList) {
// 如果新旧列表一致,则直接返回
return
}
val diffResult = DiffUtil.calculateDiff(MyDiffCallback(this.mData, dataList))
this.mData.clear()
this.mData.addAll(dataList)
diffResult.dispatchUpdatesTo(this)
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): RoutingItemViewHolder {
val view = LayoutInflater.from(mContext).inflate(
R.layout.unmanned_routing_select_item, parent, false
)
return RoutingItemViewHolder(view)
}
override fun onBindViewHolder(holder: RoutingItemViewHolder, position: Int) {
val currentPosition = holder.bindingAdapterPosition
val routing = mData[currentPosition]
holder.routingName.text = routing.lineName
holder.todayVerifyNum.text = "今日验证:${routing.carVerificationCount}"
holder.routingEndName.text = "${routing.endSite?.siteName?:""}方向"
holder.historyVerifyNumEnableNum.text = "${routing.lineSuccessCount}可用"
holder.historyVerifyNumDisenableNum.text = "${routing.lineFailCount}不可用"
//设置item点击事件
holder.routingStart.setOnClickListener {
mItemClickListener?.onItemClick(routing)
}
}
override fun getItemCount(): Int {
return mData.size
}
fun setOnLineItemClickListener(itemClickListener: LineItemClickListener?) {
mItemClickListener = itemClickListener
}
class RoutingItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val routingName: AppCompatTextView = itemView.findViewById(R.id.actv_routing_name)//线路名称
val todayVerifyNum: AppCompatTextView = itemView.findViewById(R.id.actv_today_verify_num) //终点
val routingEndName: AppCompatTextView = itemView.findViewById(R.id.actv_routing_end_name) //终点站点名称
val historyVerifyNumEnableNum: AppCompatTextView = itemView.findViewById(R.id.actv_history_verify_num_enable_num) //终点站点名称
val historyVerifyNumDisenableNum: AppCompatTextView = itemView.findViewById(R.id.actv_history_verify_num_disenable_num) //终点站点名称
val routingStart: AppCompatTextView = itemView.findViewById(R.id.actv_routing_start) //终点站点名称
}
interface LineItemClickListener {
fun onItemClick(data: GrayLineBean)
}
inner class MyDiffCallback(private val oldData:List<GrayLineBean>, private val newData:List<GrayLineBean>):
Callback(){
override fun getOldListSize(): Int {
return oldData.size
}
override fun getNewListSize(): Int {
return newData.size
}
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val oldItem = oldData[oldItemPosition]
val newItem = newData[newItemPosition]
return oldItem == newItem
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val oldItem = oldData[oldItemPosition]
val newItem = newData[newItemPosition]
return oldItem == newItem
}
}
}

View File

@@ -0,0 +1,187 @@
package com.mogo.och.unmanned.taxi.ui.routing.routingselect
import androidx.lifecycle.ViewModel
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.eagle.core.utilcode.util.NetworkUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.common.module.manager.autopilot.line.LineManager
import com.mogo.och.common.module.network.OchCommonServiceCallback
import com.mogo.och.data.bean.LineInfo
import com.mogo.och.unmanned.taxi.bean.GrayLineBean
import com.mogo.och.unmanned.taxi.bean.QueryGrayContrailListRsp
import com.mogo.och.unmanned.taxi.bean.StartGrayAndQueryContrailRsp
import com.mogo.och.unmanned.taxi.network.TaxiRoutingServiceManager
import com.mogo.och.unmanned.taxi.ui.debug.DebugView
import com.mogo.och.unmanned.taxi.ui.routing.TaxiRoutingModel
import com.mogo.och.unmanned.taxi.ui.routing.routingrunning.RoutingRunningModel
/**
* @author XuXinChao
* @description BadCase录包管理页面
* @since: 2022/12/15
*/
class RoutingSelectModel : ViewModel() {
private val TAG = RoutingRunningModel::class.java.simpleName
private var viewCallback: SwtichRoutingViewCallback? = null
private val content = AbsMogoApplication.getApp()
override fun onCleared() {
}
/**
* 查询灰度路线
*/
fun queryRoutingGrayLineList() {
DebugView.printInfoMsg("[查询灰度路线] 准备发送请求sn=${SharedPrefsMgr.getInstance().sn}")
TaxiRoutingServiceManager.queryRoutingGrayLineList(
content,
object : OchCommonServiceCallback<QueryGrayContrailListRsp> {
override fun onSuccess(data: QueryGrayContrailListRsp) {
CallerLogger.d(
TAG,
"queryRoutingGrayLineList onSuccess: data=${GsonUtils.toJson(data)}"
)
DebugView.printInfoMsg("[查询灰度路线] 请求successdataSize=${data?.data?.size}")
val result = mutableListOf<GrayLineBean>()
data.data?.also {
result.addAll(it)
}
viewCallback?.onQueryRoutingGrayLineListSuccess(result)
}
override fun onFail(code: Int, msg: String?) {
CallerLogger.d(
TAG,
"queryRoutingGrayLineList onFail: code=$code, msg=$msg"
)
DebugView.printErrorMsg("[查询灰度路线] 请求fail, code=$code, msg=$msg, sn=${SharedPrefsMgr.getInstance().sn}")
ToastUtils.showShort("查询灰度线路列表异常, 请稍后重试, code=$code")
viewCallback?.onQueryRoutingGrayLineListFailed(msg ?: "查询灰度线路列表异常, 请稍后重试")
}
override fun onError() {
super.onError()
var hintStr = ""
if (!NetworkUtils.isConnected(content)) {
hintStr = "网络出现异常,请稍后重试"
} else {
hintStr = "查询灰度线路列表异常, 请稍后重试"
}
CallerLogger.d(
TAG,
"queryRoutingGrayLineList onError, msg=$hintStr, sn=${SharedPrefsMgr.getInstance().sn}"
)
DebugView.printErrorMsg("[查询灰度路线] 请求error, msg=$hintStr")
viewCallback?.onQueryRoutingGrayLineListFailed(hintStr)
}
})
}
/**
* 开始灰度任务&查询轨迹详情
*/
fun startGrayTaskAndQueryRoutingContrail(contrailId: Long, grayLineBean: GrayLineBean) {
DebugView.printInfoMsg("[开始灰度任务&查询轨迹详情] 准备发送请求contrailId=${contrailId}, lineId=${grayLineBean.lineId}")
TaxiRoutingServiceManager.startGrayTaskAndQueryRoutingContrail(
content,
sn = SharedPrefsMgr.getInstance().sn,
contrailId = contrailId,
grayLineBean = grayLineBean,
object : OchCommonServiceCallback<StartGrayAndQueryContrailRsp> {
override fun onSuccess(data: StartGrayAndQueryContrailRsp) {
CallerLogger.d(
TAG,
"startGrayTaskAndQueryRoutingContrail onSuccess: data=${
GsonUtils.toJson(
data
)
}"
)
DebugView.printInfoMsg("[开始灰度任务&查询轨迹详情] 请求successtaskId=${data.taskId}, contrailId=${contrailId}, lineId=${grayLineBean.lineId}")
initAutopilot(data)
}
override fun onFail(code: Int, msg: String?) {
CallerLogger.d(
TAG,
"startGrayTaskAndQueryRoutingContrail onFail: code=$code, msg=$msg"
)
DebugView.printErrorMsg("[开始灰度任务&查询轨迹详情] 请求fail, code=$code, msg=$msg, contrailId=${contrailId}, lineId=${grayLineBean.lineId}")
viewCallback?.onStartGrayTaskAndQueryContrailFailed( msg ?: "startGrayTaskAndQueryRoutingContrail onFail")
}
override fun onError() {
super.onError()
var hintStr = ""
if (!NetworkUtils.isConnected(content)) {
hintStr = "网络出现异常,请稍后重试"
} else {
hintStr = "开始任务并查询轨迹详情异常, 请稍后重试"
}
CallerLogger.d(
TAG,
"startGrayTaskAndQueryRoutingContrail onError, msg=$hintStr, contrailId=${contrailId}, lineId=${grayLineBean.lineId}"
)
DebugView.printErrorMsg("[开始灰度任务&查询轨迹详情] 请求error, msg=$hintStr")
viewCallback?.onStartGrayTaskAndQueryContrailFailed(hintStr)
}
}
)
}
private fun initAutopilot(data: StartGrayAndQueryContrailRsp) {
DebugView.printInfoMsg("[开始任务] 准备开始任务")
val grayLineBean = data.grayLineBean
val contrailBean = data.contrail
val grayId = data.taskId
if (grayLineBean == null || contrailBean == null) {
ToastUtils.showShort("灰度线路或轨迹信息异常,请稍后再试")
DebugView.printErrorMsg("[开始任务] 灰度线路或轨迹信息异常,请稍后再试")
return
}
DebugView.printInfoMsg("[启自驾] 准备启动自驾")
LineManager.setLineInfo(LineInfo(grayLineBean.lineId?:0L,grayLineBean.lineName?:""))
LineManager.setContraiInfo(contrailBean.toContraiInfo())
LineManager.setStartAndEndStation(grayLineBean.startSite?.toBusStationBean(),grayLineBean.endSite?.toBusStationBean())
viewCallback?.onStartGrayTaskAndQueryContrailSuccess(data)
// Routing 从这里解析出经停信息,轨迹信息,并调用下载轨迹接口
LineManager.initAutopilotControlParameters()?.let {
CallerAutoPilotControlManager.sendTrajectoryDownloadReq(it)
}
}
fun setDistanceCallback(viewCallback: SwtichRoutingViewCallback) {
this.viewCallback = viewCallback
}
interface SwtichRoutingViewCallback {
fun onQueryRoutingGrayLineListSuccess(data: MutableList<GrayLineBean>)
fun onQueryRoutingGrayLineListFailed(errorStr: String)
/**
* 灰度任务&查询轨迹详情--成功✅
*/
fun onStartGrayTaskAndQueryContrailSuccess(data: StartGrayAndQueryContrailRsp)
/**
* 灰度任务&查询轨迹详情--失败❌
* @param errorStr 错误信息
*/
fun onStartGrayTaskAndQueryContrailFailed(errorStr: String)
}
}

View File

@@ -0,0 +1,154 @@
package com.mogo.och.unmanned.taxi.ui.routing.routingselect
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStoreOwner
import androidx.lifecycle.findViewTreeViewModelStoreOwner
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.view.SpacesItemDecoration
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.common.module.utils.FlowBus
import com.mogo.och.unmanned.taxi.R
import com.mogo.och.unmanned.taxi.TaxiUnmannedDriverProvider
import com.mogo.och.unmanned.taxi.bean.GrayLineBean
import com.mogo.och.unmanned.taxi.bean.StartGrayAndQueryContrailRsp
import com.mogo.och.unmanned.taxi.constant.TaxiDriverEventConst
import com.mogo.och.unmanned.taxi.ui.debug.DebugView
import com.mogo.och.unmanned.taxi.ui.routing.RoutingSwitchModel
import com.mogo.och.unmanned.taxi.ui.routing.RoutingUIState
import com.mogo.och.unmanned.taxi.ui.routing.TaxiRoutingChooseLineItemOpenAnimator
import com.mogo.och.unmanned.taxi.ui.routing.TaxiRoutingUiIntent
import com.mogo.och.unmanned.taxi.ui.routing.routingselect.RoutingSelectModel.SwtichRoutingViewCallback
import kotlinx.android.synthetic.main.unmanned_routing_select.view.include_empty
import kotlinx.android.synthetic.main.unmanned_routing_select.view.include_error
import kotlinx.android.synthetic.main.unmanned_routing_select.view.switch_routing_rv
import kotlinx.coroutines.flow.map
import me.jessyan.autosize.utils.AutoSizeUtils
class RoutingSelectView: ConstraintLayout, SwtichRoutingViewCallback {
constructor(context: Context) : super(context)
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
companion object {
const val TAG = "SwitchBizView"
}
private var viewModel: RoutingSelectModel?=null
private var swtichViewModel: RoutingSwitchModel?=null
private lateinit var mChooseLineListAdapter: RoutingItemAdapter
private lateinit var mLinearLayoutManager: LinearLayoutManager
private val mRoutingLineList: MutableList<GrayLineBean> = ArrayList()
private var mCurrentChosenPosition: Int = -1
init {
LayoutInflater.from(context).inflate(R.layout.unmanned_routing_select, this, true)
initView()
}
private fun initView(){
mLinearLayoutManager = LinearLayoutManager(context)
switch_routing_rv.layoutManager = mLinearLayoutManager
switch_routing_rv.itemAnimator = TaxiRoutingChooseLineItemOpenAnimator()
mChooseLineListAdapter = RoutingItemAdapter(context, mRoutingLineList)
switch_routing_rv.addItemDecoration(SpacesItemDecoration(AutoSizeUtils.dp2px(context,20f)))
switch_routing_rv.adapter = mChooseLineListAdapter
//设置item 点击事件
mChooseLineListAdapter.setOnLineItemClickListener(object : RoutingItemAdapter.LineItemClickListener {
override fun onItemClick(data: GrayLineBean) {
if(data.contrailId==null||data.contrailId!!<=0L){
ToastUtils.showShort("请设置轨迹信息")
}
DebugView.printInfoMsg("[选择灰度任务] 当前选择 mCurrentChosenPosition=$mCurrentChosenPosition, ")
swtichViewModel?.showLoading()
viewModel?.startGrayTaskAndQueryRoutingContrail(data.contrailId!!,data)
}
})
}
private fun showEmptyView() {
switch_routing_rv.visibility = GONE
include_empty.visibility = View.VISIBLE
include_error.visibility = View.GONE
}
private fun showErrorView() {
switch_routing_rv.visibility = GONE
include_empty.visibility = View.GONE
include_error.visibility = View.VISIBLE
}
private fun showRecyclerView() {
switch_routing_rv.visibility = VISIBLE
include_empty.visibility = View.GONE
include_error.visibility = View.GONE
}
private fun onRoutingGrayLineListChanged(data: MutableList<GrayLineBean>) {
if (data.isNotEmpty()) {
showRecyclerView()
mRoutingLineList.clear()
mRoutingLineList.addAll(data)
mChooseLineListAdapter.notifyDataSetChanged()
} else {
showEmptyView()
}
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
viewModel = findViewTreeViewModelStoreOwner()?.let {
ViewModelProvider(it).get(RoutingSelectModel::class.java)
}
viewModel?.setDistanceCallback(this)
swtichViewModel = findViewTreeViewModelStoreOwner()?.let {
ViewModelProvider(it).get(RoutingSwitchModel::class.java)
}
}
override fun onVisibilityAggregated(isVisible: Boolean) {
super.onVisibilityAggregated(isVisible)
if(isVisible){
viewModel?.queryRoutingGrayLineList()
}
}
override fun onQueryRoutingGrayLineListSuccess(data: MutableList<GrayLineBean>) {
onRoutingGrayLineListChanged(data)
}
override fun onQueryRoutingGrayLineListFailed(errorStr: String) {
showErrorView()
}
override fun onStartGrayTaskAndQueryContrailSuccess(data: StartGrayAndQueryContrailRsp) {
swtichViewModel?.showRoutingRunning(data)
}
override fun onStartGrayTaskAndQueryContrailFailed(errorStr: String) {
swtichViewModel?.showRoutingSelectView()
}
}

View File

@@ -223,11 +223,6 @@ object TaxiTaskModel {
OCHSocketMessageManager.msgMonitorType,
OperateAction2()
)
MogoStatusManager.getInstance().registerStatusChangedListener(
TAG,
StatusDescriptor.VR_MODE,
mMogoStatusChangedListener
)
IntentManager.getInstance()
.registerIntentListener(ConnectivityManager.CONNECTIVITY_ACTION, mNetWorkIntentListener)
AbnormalFactorsLoopManager.startLoopAbnormalFactors(mContext)
@@ -237,11 +232,6 @@ object TaxiTaskModel {
}
private fun releaseListeners() {
MogoStatusManager.getInstance().unregisterStatusChangedListener(
TAG,
StatusDescriptor.VR_MODE,
mMogoStatusChangedListener
)
// 注销地图监听
OchLocationManager.removeGCJ02Listener(TAG)
@@ -432,15 +422,6 @@ object TaxiTaskModel {
}
private val mMogoStatusChangedListener: IMogoStatusChangedListener =
IMogoStatusChangedListener { descriptor, isTrue ->
// VR mode变更回调
if (StatusDescriptor.VR_MODE == descriptor) {
mControllerStatusCallback?.onVRModeChanged(isTrue)
DebugView.printInfoMsg("[VRMode变化] isVRMode=$isTrue")
}
}
// 自车定位
private val mMapLocationListener: IMoGoChassisLocationGCJ02Listener =
object : IMoGoChassisLocationGCJ02Listener {
@@ -459,7 +440,6 @@ object TaxiTaskModel {
judgeTaskEndSiteStation(mogoLocation)
}
mControllerStatusCallback?.onCarLocationChanged(mogoLocation)
}
}
}

View File

@@ -1,6 +1,7 @@
package com.mogo.och.unmanned.taxi.ui.itinerarycurrent
import androidx.lifecycle.ViewModel
import com.mogo.och.unmanned.taxi.bean.StartGrayAndQueryContrailRsp
/**
* @author XuXinChao
@@ -14,6 +15,7 @@ class ItineraryCurrentModel : ViewModel() {
private var viewCallback: SwtichLineViewCallback? = null
override fun onCleared() {
}
@@ -22,6 +24,8 @@ class ItineraryCurrentModel : ViewModel() {
this.viewCallback = viewCallback
}
interface SwtichLineViewCallback {
}

View File

@@ -11,6 +11,26 @@ import kotlin.math.roundToInt
object TaskUtils {
fun getCurrentTaskDistance(meters: Long):String{
var dis = "0"
var disUnit = "公里"
if (meters > 0) {
if (meters / 1000 < 1) {
disUnit = ""
dis = meters.toFloat().roundToInt().toString()
} else {
disUnit = "公里"
dis = NumberFormatUtil.formatLong(meters.toDouble() / 1000)
}
}
return "${dis}${disUnit}"
}
fun getCurrentTaskTime(timeInSecond: Long):String{
val min = ceil(timeInSecond.toDouble() / 60f).toInt()
return "${min}分钟"
}
/**
* 剩余里程和剩余时间 html
*/

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/taxi_color_FF4E41" android:state_pressed="true"/>
<item android:color="@color/taxi_color_FF4E41" android:state_pressed="false"/>
<item android:color="@color/taxi_color_FF4E41"/>
</selector>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/taxi_color_2EACFF" android:state_pressed="true"/>
<item android:color="@color/taxi_color_2EACFF" android:state_pressed="false"/>
<item android:color="@color/taxi_color_2EACFF"/>
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/taxi_color_4D000000"/>
<corners android:radius="@dimen/dp_30"/>
</shape>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/taxi_color_80000000"/>
<corners android:radius="@dimen/dp_30"/>
</shape>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/taxi_button_selected"/>
<item android:state_pressed="false" android:drawable="@drawable/taxi_button_normal"/>
<item android:state_checked="true" android:drawable="@drawable/taxi_button_selected"/>
<item android:state_checked="false" android:drawable="@drawable/taxi_button_normal"/>
<item android:drawable="@drawable/taxi_button_normal"/>
</selector>

View File

@@ -1,75 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/routing_verify_choose_line_bg"
tools:ignore="MissingDefaultResource">
<View
android:id="@+id/chooseLineHint"
android:layout_width="@dimen/dp_14"
android:layout_height="@dimen/dp_50"
android:layout_marginStart="@dimen/dp_80"
android:background="@color/routing_verify_choose_line"
app:layout_constraintBottom_toBottomOf="@+id/chooseLineHeaderTitle"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@+id/chooseLineHeaderTitle" />
<TextView
android:id="@+id/chooseLineHeaderTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_113"
android:layout_marginTop="@dimen/dp_97"
android:text="@string/routing_verify_choose_line_title"
android:textColor="@android:color/white"
android:textSize="@dimen/taxi_routing_choose_line_title"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/btnClose"
android:layout_width="@dimen/dp_107"
android:layout_height="@dimen/dp_107"
android:layout_marginTop="@dimen/dp_67"
android:layout_marginRight="@dimen/dp_40"
android:src="@drawable/routing_choose_line_close"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/chooseLineListView"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_0"
android:layout_marginTop="@dimen/dp_50"
android:layout_marginBottom="@dimen/dp_30"
app:layout_constraintBottom_toTopOf="@+id/btnChooseLineSubmit"
app:layout_constraintLeft_toLeftOf="@+id/chooseLineHint"
app:layout_constraintTop_toBottomOf="@+id/chooseLineHint" />
<TextView
android:id="@+id/btnChooseLineSubmit"
android:layout_width="match_parent"
android:layout_height="126dp"
android:layout_marginStart="@dimen/dp_80"
android:layout_marginEnd="@dimen/dp_80"
android:layout_marginBottom="@dimen/taxi_choose_line_btn_margin_b"
android:background="@drawable/routing_choose_line_btn_submit_bg"
android:gravity="center"
android:text="@string/routing_verify_choose_line_btn_txt"
android:textColor="@android:color/white"
android:textSize="@dimen/dp_42"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<include
layout="@layout/unmanned_routing_no_data_common_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,179 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout"
android:layout_width="@dimen/dp_880"
android:layout_height="@dimen/dp_966"
tools:background="@drawable/shape_itinerary_bg_default"
xmlns:tools="http://schemas.android.com/tools">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_routing_page_title"
android:textSize="@dimen/dp_44"
android:textColor="@color/white"
android:text="当前行程"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="@dimen/dp_38"
android:layout_marginStart="@dimen/dp_54"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_routing_name"
android:textSize="@dimen/dp_40"
android:textColor="@color/white"
android:text="灰度路线11111111"
app:layout_constraintTop_toBottomOf="@+id/actv_routing_page_title"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="@dimen/dp_40"
android:layout_marginStart="@dimen/dp_54"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<View
android:id="@+id/v_bg_itinerary_info"
app:layout_constraintTop_toBottomOf="@+id/actv_routing_name"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="@dimen/dp_28"
android:layout_marginStart="@dimen/dp_54"
android:layout_marginEnd="@dimen/dp_52"
android:layout_width="match_parent"
android:background="@drawable/shape_itinerary_bg_default"
android:layout_height="@dimen/dp_351"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/aciv_current_itinerary_start_point"
app:layout_constraintTop_toTopOf="@+id/v_bg_itinerary_info"
app:layout_constraintStart_toStartOf="@+id/v_bg_itinerary_info"
android:layout_marginStart="@dimen/dp_30"
android:layout_marginTop="@dimen/dp_34"
android:layout_width="@dimen/dp_45"
android:layout_height="@dimen/dp_45"
android:src="@drawable/taxi_task_current_start_station_point" />
<View
android:id="@+id/v_line_current_start_end"
app:layout_constraintTop_toBottomOf="@+id/aciv_current_itinerary_start_point"
app:layout_constraintStart_toStartOf="@+id/aciv_current_itinerary_start_point"
app:layout_constraintEnd_toEndOf="@+id/aciv_current_itinerary_start_point"
android:layout_marginTop="@dimen/dp_8"
android:background="@color/taxi_color_4D000000"
android:layout_width="@dimen/dp_6"
android:layout_height="@dimen/dp_171"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/aciv_current_itinerary_end_point"
app:layout_constraintTop_toBottomOf="@+id/v_line_current_start_end"
app:layout_constraintStart_toStartOf="@+id/v_line_current_start_end"
app:layout_constraintEnd_toEndOf="@+id/v_line_current_start_end"
android:layout_marginTop="@dimen/dp_8"
android:layout_width="@dimen/dp_45"
android:layout_height="@dimen/dp_45"
android:src="@drawable/taxi_task_current_end_station_point" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_current_itinerary_start_name"
app:layout_constraintTop_toTopOf="@+id/aciv_current_itinerary_start_point"
app:layout_constraintBottom_toBottomOf="@+id/aciv_current_itinerary_start_point"
app:layout_constraintStart_toEndOf="@+id/aciv_current_itinerary_start_point"
android:layout_marginStart="@dimen/dp_29"
android:text="天安门"
android:textColor="@color/white"
android:textSize="@dimen/dp_40"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/naviToStart"
app:layout_constraintTop_toTopOf="@+id/actv_current_itinerary_start_name"
app:layout_constraintBottom_toBottomOf="@+id/actv_current_itinerary_start_name"
app:layout_constraintEnd_toEndOf="@+id/v_bg_itinerary_info"
android:src="@drawable/taxi_task_nav"
android:layout_marginEnd="@dimen/dp_36"
android:layout_width="@dimen/dp_46"
android:layout_height="@dimen/dp_46"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_distance_end"
android:text="5.2公里"
android:textSize="@dimen/dp_32"
android:textColor="@color/taxi_color_CCCCCC"
app:layout_constraintTop_toBottomOf="@+id/actv_current_itinerary_start_name"
app:layout_constraintStart_toStartOf="@+id/actv_current_itinerary_start_name"
app:layout_constraintBottom_toTopOf="@+id/actv_time_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_time_end"
android:text="1小时36分钟"
android:textSize="@dimen/dp_32"
android:textColor="@color/taxi_color_CCCCCC"
app:layout_constraintTop_toBottomOf="@+id/actv_distance_end"
app:layout_constraintStart_toStartOf="@+id/actv_current_itinerary_start_name"
app:layout_constraintBottom_toTopOf="@+id/actv_current_itinerary_end_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_current_itinerary_end_name"
app:layout_constraintTop_toTopOf="@+id/aciv_current_itinerary_end_point"
app:layout_constraintBottom_toBottomOf="@+id/aciv_current_itinerary_end_point"
app:layout_constraintStart_toEndOf="@+id/aciv_current_itinerary_end_point"
android:layout_marginStart="@dimen/dp_29"
android:text="环球贸易中心"
android:textColor="@color/white"
android:textSize="@dimen/dp_40"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_submit_task"
android:layout_width="@dimen/dp_356"
android:layout_height="@dimen/dp_120"
app:pressed_enabled="false"
android:gravity="center"
android:text="问题打点"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="@dimen/dp_54"
android:layout_marginBottom="@dimen/dp_55"
android:background="@drawable/taxi_button_selector"
android:textColor="@color/taxi_submit_text_color_selector"
android:textSize="@dimen/dp_40" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_end_routing"
android:layout_width="@dimen/dp_356"
android:layout_height="@dimen/dp_120"
app:pressed_enabled="false"
android:gravity="center"
android:text="结束服务"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="@dimen/dp_54"
android:layout_marginBottom="@dimen/dp_55"
android:background="@drawable/taxi_button_selector"
android:textColor="@color/taxi_button_red_text_color"
android:textSize="@dimen/dp_40" />
<androidx.constraintlayout.widget.Group
android:id="@+id/goutp_show_routing_info"
app:constraint_referenced_ids="actv_end_routing,actv_submit_task,actv_current_itinerary_end_name,actv_time_end,actv_distance_end,actv_current_itinerary_start_name,aciv_current_itinerary_end_point,v_line_current_start_end,aciv_current_itinerary_start_point,v_bg_itinerary_info,actv_routing_name,naviToStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<include
android:id="@+id/include_empty"
layout="@layout/common_empty_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</merge>

View File

@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout"
android:layout_width="@dimen/dp_880"
android:layout_height="@dimen/dp_966"
tools:background="@drawable/shape_itinerary_bg_default"
xmlns:tools="http://schemas.android.com/tools">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_routing_title"
android:textSize="@dimen/dp_45"
android:textColor="@color/white"
android:text="算路验证路线"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="@dimen/dp_54"
android:layout_marginTop="@dimen/dp_36"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/switch_routing_rv"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_0"
android:layout_marginStart="@dimen/dp_54"
android:layout_marginEnd="@dimen/dp_52"
app:layout_constraintTop_toBottomOf="@+id/actv_routing_title"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginTop="@dimen/dp_40" />
<include
android:id="@+id/include_empty"
layout="@layout/common_empty_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<include
android:id="@+id/include_error"
layout="@layout/common_error_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</merge>

View File

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout"
android:layout_width="@dimen/dp_774"
android:layout_height="wrap_content"
android:background="@drawable/shape_itinerary_bg_default"
xmlns:tools="http://schemas.android.com/tools">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_routing_name"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="@dimen/dp_30"
android:layout_marginTop="@dimen/dp_26"
android:textColor="@color/white"
android:textSize="@dimen/dp_40"
tools:text="灰度路线11111111"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_today_verify_num"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="@dimen/dp_40"
android:layout_marginTop="@dimen/dp_31"
android:textColor="@color/taxi_color_CCFFFFFF"
android:textSize="@dimen/dp_32"
tools:text="今日验证2次"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_routing_end_name"
app:layout_constraintTop_toBottomOf="@+id/actv_routing_name"
app:layout_constraintStart_toStartOf="@+id/actv_routing_name"
android:layout_marginTop="@dimen/dp_12"
android:textColor="@color/white"
android:textSize="@dimen/dp_32"
tools:text="往AAAA方向"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_history_verify_num_title"
app:layout_constraintTop_toBottomOf="@+id/actv_routing_end_name"
app:layout_constraintStart_toStartOf="@+id/actv_routing_end_name"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="@dimen/dp_33"
android:layout_marginTop="@dimen/dp_20"
android:textColor="@color/white"
android:textSize="@dimen/dp_30"
android:text="累计:"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_history_verify_num_enable_num"
app:layout_constraintTop_toTopOf="@+id/actv_history_verify_num_title"
app:layout_constraintBottom_toBottomOf="@+id/actv_history_verify_num_title"
app:layout_constraintStart_toEndOf="@+id/actv_history_verify_num_title"
android:textColor="@color/taxi_color_26C14F"
android:layout_marginStart="@dimen/dp_17"
android:textSize="@dimen/dp_30"
tools:text="5可用"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_history_verify_num_disenable_num"
app:layout_constraintTop_toTopOf="@+id/actv_history_verify_num_title"
app:layout_constraintBottom_toBottomOf="@+id/actv_history_verify_num_title"
app:layout_constraintStart_toEndOf="@+id/actv_history_verify_num_enable_num"
android:textColor="@color/taxi_color_FF852E"
android:layout_marginStart="@dimen/dp_28"
android:textSize="@dimen/dp_30"
tools:text="2不可用"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_routing_start"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:textColor="@color/taxi_color_2eacff"
android:layout_marginEnd="@dimen/dp_40"
android:layout_marginBottom="@dimen/dp_32"
android:textSize="@dimen/dp_30"
android:text="开始"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/dp_880"
android:layout_height="@dimen/dp_966"
xmlns:tools="http://schemas.android.com/tools"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
<com.mogo.och.unmanned.taxi.ui.routing.routingselect.RoutingSelectView
android:id="@+id/routingSelectView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<com.mogo.och.unmanned.taxi.ui.routing.routingrunning.RoutingRunningView
android:id="@+id/routingRunningView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<com.mogo.och.common.module.wigets.loading.LoadingViewBig
android:id="@+id/switch_routing_loading"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</merge>

View File

@@ -37,20 +37,19 @@
android:layout_height="@dimen/dp_100"/>
<com.mogo.och.unmanned.taxi.ui.task.ItinerarySwitchView
android:id="@+id/itinerarySwitchView"
app:layout_constraintTop_toTopOf="@+id/guideline_h_top"
app:layout_constraintStart_toStartOf="@+id/guideline_v_left"
app:layout_constraintEnd_toEndOf="@+id/guideline_v_right"
android:layout_width="@dimen/dp_880"
android:layout_height="@dimen/dp_966"/>
<com.mogo.och.common.module.wigets.loading.LoadingViewBig
android:id="@+id/loading_biz"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<com.mogo.och.unmanned.taxi.ui.routing.RoutingSwitchView
android:id="@+id/routingSwitchView"
app:layout_constraintTop_toTopOf="@+id/guideline_h_top"
app:layout_constraintStart_toStartOf="@+id/guideline_v_left"
app:layout_constraintEnd_toEndOf="@+id/guideline_v_right"
android:layout_width="@dimen/dp_880"
android:layout_height="@dimen/dp_966"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -37,4 +37,10 @@
<color name="taxi_color_4dffffff">#4Dffffff</color>
<color name="taxi_color_4D000000">#4D000000</color>
<color name="taxi_color_CCCCCC">#CCCCCC</color>
<color name="taxi_color_26C14F">#26C14F</color>
<color name="taxi_color_FF852E">#FF852E</color>
<color name="taxi_color_CCFFFFFF">#CCFFFFFF</color>
<color name="taxi_color_80000000">#80000000</color>
<color name="taxi_color_2EACFF">#2EACFF</color>
<color name="taxi_color_FF4E41">#FF4E41</color>
</resources>