Merge branch 'dev_robotaxi-d-app-module_290_220715_2.9.0' into 'dev_robotaxi-d-app-module_282_220707_2.8.2'

# Conflicts:
#   core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt
#   core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/V2XEventManager.kt
This commit is contained in:
pangfan
2022-07-25 09:38:11 +00:00
330 changed files with 6283 additions and 1849 deletions

View File

@@ -246,10 +246,11 @@ class MoGoAdasListenerImpl : OnAdasListener {
//他车轨迹预测
}
override fun onPointCloud(header: MessagePad.Header?, pointCloud: MogoPointCloudOuterClass.MogoPointCloud?) {
//点云数据透传
//Logger.d("pointCloud","pointCloud"+pointCloud);
}
// override fun onPointCloud(header: MessagePad.Header?, pointCloud: MogoPointCloudOuterClass.MogoPointCloud?) {
// //点云数据透传
// //Logger.d("pointCloud","pointCloud"+pointCloud);
// CallerAutopilotPointCloudListenerManager.invokeAutopilotPointCloudDataUpdate(header, pointCloud)
// }
override fun onPointCloud(pointCloud: ByteArray?) {
//点云数据透传

View File

@@ -6,9 +6,11 @@ import com.mogo.commons.debug.DebugConfig
import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.cloud.IMoGoCloudListener
import com.mogo.eagle.core.function.autopilot.network.AdasServiceModel
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.cloud.CallerCloudListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_ADAS_IMPL
import com.mogo.eagle.core.utilcode.util.ToastUtils
@@ -26,7 +28,7 @@ import java.util.concurrent.TimeUnit
* ADAS-SDK与工控机连接状态回调
*/
class MoGoAdasMsgConnectStatusListenerImpl : OnAdasConnectStatusListener,
IMoGoAutopilotStatusListener {
IMoGoAutopilotStatusListener, IMoGoCloudListener {
private val TAG = "ConnectStatus"
//自动驾驶状态
@@ -37,8 +39,15 @@ class MoGoAdasMsgConnectStatusListenerImpl : OnAdasConnectStatusListener,
private var connectStatus = false
init {
CallerCloudListenerManager.registerCloudListener(TAG, this)
}
override fun onConnectionIPCStatus(ipcConnectionStatus: Int, reason: String?) {
CallerAutoPilotStatusListenerManager.invokeAutoPilotIPCStatusChanged(ipcConnectionStatus, reason)
CallerAutoPilotStatusListenerManager.invokeAutoPilotIPCStatusChanged(
ipcConnectionStatus,
reason
)
if (ipcConnectionStatus == Constants.IPC_CONNECTION_STATUS.CONNECTED) {
CallerLogger.d("$M_ADAS_IMPL$TAG", "webSocket 连接成功")
connectStatus = true
@@ -55,7 +64,7 @@ class MoGoAdasMsgConnectStatusListenerImpl : OnAdasConnectStatusListener,
//每次工控机连接成功后,需同步当前设置的美化模式状态
CallerAutoPilotManager.setDemoMode(FunctionBuildConfig.isDemoMode)
//当连接状态是关闭美化模式时,同步给工控机
if(!FunctionBuildConfig.isDemoMode){
if (!FunctionBuildConfig.isDemoMode) {
CallerAutoPilotManager.setIPCDemoMode(FunctionBuildConfig.isDemoMode)
}
//每次工控机连接成功后,需同步当前设置的雨天模式状态
@@ -85,8 +94,9 @@ class MoGoAdasMsgConnectStatusListenerImpl : OnAdasConnectStatusListener,
} else if (ipcConnectionStatus == Constants.IPC_CONNECTION_STATUS.NOT_FOUND_ADDRESS) {
CallerLogger.d("$M_ADAS_IMPL$TAG", "webSocket 找不到可用IP 传入的IP不可用或固定IP列表中所有IP不可用")
}
CallerAutoPilotStatusListenerManager.getAutoPilotStatusInfo().ipcConnStatus = ipcConnectionStatus
CallerAutoPilotStatusListenerManager.getAutoPilotStatusInfo().connectStatusDescribe=reason
CallerAutoPilotStatusListenerManager.getAutoPilotStatusInfo().ipcConnStatus =
ipcConnectionStatus
CallerAutoPilotStatusListenerManager.getAutoPilotStatusInfo().connectStatusDescribe = reason
CallerAutoPilotStatusListenerManager.invokeAutoPilotStatus()
}
@@ -119,7 +129,7 @@ class MoGoAdasMsgConnectStatusListenerImpl : OnAdasConnectStatusListener,
/**
* 同步SN信息给工控机
*/
private fun syncBasicInfoToAutopilot() {
private fun syncBasicInfoToAutopilot(sn: String? = null) {
CallerLogger.d("$M_ADAS_IMPL$TAG", "同步PAD的SN给工控机……")
// 设置PAD-SN给工控,网络环境
AdasManager.getInstance()
@@ -142,5 +152,8 @@ class MoGoAdasMsgConnectStatusListenerImpl : OnAdasConnectStatusListener,
}
}
override fun tokenGot(sn: String) {
syncBasicInfoToAutopilot(sn)
}
}

View File

@@ -105,7 +105,9 @@ public class MoGoHandAdasMsgManager implements
@Override
public void onAutopilotCarConfig(@NotNull MessagePad.CarConfigResp carConfigResp) {
Log.d("liyz", "onAutopilotCarConfig carConfigResp ");
if (carConfigResp != null && !TextUtils.isEmpty(carConfigResp.getMacAddress())) {
Log.d("liyz", "carConfigResp.getMacAddress() = " + carConfigResp.getMacAddress());
CallerBindingcarManager.getBindingcarProvider().getBindingcarInfo(carConfigResp.getMacAddress(), MoGoAiCloudClientConfig.getInstance().getSn());
}
}
@@ -149,4 +151,9 @@ public class MoGoHandAdasMsgManager implements
@Override
public void onAutopilotDataException(long timestamp) {
}
@Override
public void onAutopilotAcc(float carAcc) {
}
}

View File

@@ -95,6 +95,7 @@ public class BindingcarProvider implements IMoGoBindingcarProvider {
private void driverScreen(String macAddress, String widevineIDWithMd5) {
long currentHour = System.currentTimeMillis() / (1000 * 60);
long oldHour = SharedPrefsMgr.getInstance(mContext).getLong("typeDriver", 0);
Log.d("liyz", "driverScreen --------> ");
//如果2分钟内频繁调需要拦截业务导致的会多次请求工控机信息
if (HmiBuildConfig.isShowSnBindingView) {
if (currentHour - oldHour > 1) {
@@ -107,6 +108,7 @@ public class BindingcarProvider implements IMoGoBindingcarProvider {
private void passengerScreen(String macAddress, String widevineIDWithMd5) {
long currentHour = System.currentTimeMillis() / (1000 * 60);
long oldHour = SharedPrefsMgr.getInstance(mContext).getLong("typePassenger", 0);
Log.d("liyz", "passengerScreen --------> ");
//如果2分钟内频繁调需要拦截业务导致的会多次请求工控机信息
if (HmiBuildConfig.isShowSnBindingView) {
if (currentHour - oldHour > 1) {

View File

@@ -7,7 +7,9 @@ import com.mogo.commons.constants.SharedPrefsConstants;
import com.mogo.eagle.core.data.bindingcar.BindingcarInfo;
import com.mogo.eagle.core.data.bindingcar.ModifyBindingcarInfo;
import com.mogo.eagle.core.function.api.bindingcar.BindingcarCallBack;
import com.mogo.eagle.core.function.bindingcar.R;
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager;
import com.mogo.eagle.core.function.call.map.CallerHDMapManager;
import com.mogo.eagle.core.network.MoGoRetrofitFactory;
import com.mogo.eagle.core.network.utils.GsonUtil;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
@@ -60,7 +62,7 @@ public class BindingcarNetWorkManager {
public void getBindingcarInfo(Context context, String macAddress, String widevineIDWithMd5, int screenType) {
// String macAddress = "48:b0:2d:3a:bc:78";
// String sn = "X20202203105S688HZ";
Log.d("liyz", "macAddress = " + macAddress + "----widevineIDWithMd5 = " + widevineIDWithMd5);
BindingcarRequest request = new BindingcarRequest(macAddress, widevineIDWithMd5, screenType);
RequestBody requestBody = RequestBody.create(MediaType.get("application/json;charset=UTF-8"), GsonUtil.jsonFromObject(request));
mBindingcarApiService.getBindingcarInfo(token, requestBody)
@@ -75,6 +77,7 @@ public class BindingcarNetWorkManager {
public void onNext(@NonNull BindingcarInfo info) {
if (info != null && info.getData() != null) {
CallerLogger.INSTANCE.d(TAG, "getBindingcarInfo onNext info.getData() =" + info.getData().toString());
Log.d("liyz", "getBindingcarInfo onNext info.getData() =" + info.getData().toString());
if (info.getData().getCompare().equals("0")) {
CallerHmiManager.INSTANCE.showBindingcarDialog();
} else if (info.getData().getCompare().equals("3")) {
@@ -83,6 +86,17 @@ public class BindingcarNetWorkManager {
TipToast.shortTip("当前工控机没有入库");
}
//根据车辆类型切换不同的车辆模型
if (info.getData().getVendor().equals("一汽红旗")) { //TODO
CallerHDMapManager.INSTANCE.changeCurrentIcon(R.raw.xiaobache);
} else if (info.getData().getVendor().equals("东风")) {
CallerHDMapManager.INSTANCE.changeCurrentIcon(R.raw.chuzuche);
} else if (info.getData().getVendor().equals("金旅星辰")) {
CallerHDMapManager.INSTANCE.changeCurrentIcon(R.raw.xiaobache);
} else {
CallerHDMapManager.INSTANCE.changeCurrentIcon(R.raw.chuzuche);
}
SharedPrefsMgr.getInstance(context).putString(SharedPrefsConstants.CAR_INFO, GsonUtils.toJson(info.getData()));
}
}
@@ -90,7 +104,7 @@ public class BindingcarNetWorkManager {
@Override
public void onError(@NonNull Throwable e) {
CallerLogger.INSTANCE.e(TAG, "getBindingcarInfo onError e = " + e.toString() + "---e.getMessage = " + e.getMessage());
// Log.e("liyz", "getBindingcarInfo onError e = " + e.toString() + "---e.getMessage = " + e.getMessage());
Log.e("liyz", "getBindingcarInfo onError e = " + e.toString() + "---e.getMessage = " + e.getMessage());
}
@Override

View File

@@ -66,6 +66,11 @@ internal class CanImpl(ctx: Context): IFlow<CanStatus>(ctx), IMoGoAutopilotVehic
send(CanStatus(false))
}
override fun onAutopilotAcc(carAcc: Float) {
send(CanStatus(isCanEnabled()))
timeOutCheck()
}
override fun onAutopilotGuardian(guardianInfo: MogoReportMessage?) {
super.onAutopilotGuardian(guardianInfo)
send(CanStatus(isCanEnabled()))

View File

@@ -4,10 +4,10 @@ import android.content.Context
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.data.deva.chain.ChainConstant
import com.mogo.eagle.core.data.deva.chain.ChainLogParam
import com.mogo.eagle.core.function.api.cloud.IMoGoCloudListener
import com.mogo.eagle.core.function.call.cloud.CallerCloudListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.LogLevel
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
import com.mogo.eagle.core.utilcode.util.DeviceUtils
import com.mogo.eagle.core.utilcode.util.Utils
@@ -15,7 +15,7 @@ import com.zhidao.loglib.fw.FileWriteManager
import com.zhidao.loglib.fw.FwBuild
import com.zhjt.service.chain.core.ChainTraceStarter
class TraceManager {
class TraceManager : IMoGoCloudListener {
private val traceInfoCache = hashMapOf<Int, ChainLogParam>()
private val fwBuildMap: MutableMap<Int, FwBuild> = HashMap()
@@ -33,24 +33,25 @@ class TraceManager {
// 初始化Trace抓取服务
val pkgName = Utils.getApp().packageName
ChainTraceStarter.start(pkgName, DeviceUtils.getMacAddress(), false)
CallerCloudListenerManager.registerCloudListener(TAG, this)
// Trace过程中进行日志抓取对日志进行配置
fwBuildMap[ChainConstant.CHAIN_LINK_LOG_CONNECT_STATUS] =
FwBuild(true, -1,pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_INIT)
FwBuild(true, -1, pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_INIT)
fwBuildMap[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_GNSSINFO] =
FwBuild(true, -1,pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_GNSS)
FwBuild(true, -1, pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_GNSS)
fwBuildMap[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_AUTOPILOT] =
FwBuild(true, -1,pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_AUTO)
FwBuild(true, -1, pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_AUTO)
fwBuildMap[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_DATA_TRACKED] =
FwBuild(false, 30,pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_DATA_TRACK)
FwBuild(false, 30, pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_DATA_TRACK)
fwBuildMap[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_TRAJECTORY] =
FwBuild(false, 30,pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_TRAJECTORY)
FwBuild(false, 30, pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_TRAJECTORY)
fwBuildMap[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_VEHICLE] =
FwBuild(false, 30,pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_VEHICLE)
FwBuild(false, 30, pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_VEHICLE)
fwBuildMap[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_TRAFFIC_LIGHT] =
FwBuild(false, 30,pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_TRAFFIC_LIGHT)
FwBuild(false, 30, pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_TRAFFIC_LIGHT)
fwBuildMap[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_PLANNING_OBJECTS] =
FwBuild(false, 30,pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_PLANNING_OBJECTS)
FwBuild(false, 30, pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_PLANNING_OBJECTS)
traceInfoCache[ChainConstant.CHAIN_LINK_LOG_CONNECT_STATUS] =
ChainLogParam(true, "ADAS连接状态")
@@ -79,11 +80,15 @@ class TraceManager {
}
}
fun setTraceLogEnable(enable:Boolean){
override fun tokenGot(sn: String) {
FileWriteManager.getInstance().updateDeviceId(sn)
}
fun setTraceLogEnable(enable: Boolean) {
FileWriteManager.getInstance().logger = enable
}
fun getTraceLogStatus():Boolean{
fun getTraceLogStatus(): Boolean {
return FileWriteManager.getInstance().logger
}
@@ -93,7 +98,7 @@ class TraceManager {
fun refreshTraceInfo(map: HashMap<Int, ChainLogParam>) {
map.forEach { (type, param) ->
if(type != ChainConstant.CHAIN_LINK_LOG_CONNECT_STATUS){
if (type != ChainConstant.CHAIN_LINK_LOG_CONNECT_STATUS) {
val fwBuild = this.fwBuildMap[type]
fwBuild?.let {
CallerLogger.d("$M_DEVA$TAG", "param : ${param.des} , record : ${param.record}")
@@ -103,4 +108,5 @@ class TraceManager {
}
FileWriteManager.getInstance().operateChainMap(fwBuildMap)
}
}

View File

@@ -34,7 +34,7 @@
-->
<activity
android:name="com.mogo.eagle.core.function.main.MainLauncherActivity"
android:clearTaskOnLaunch="true"
android:clearTaskOnLaunch="${ACTIVITY_ROOT}"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize"
android:enabled="true"
android:launchMode="singleTop"
@@ -63,6 +63,10 @@
</intent-filter>
</activity>
<meta-data
android:name="MAP_SDK_VERSION111111"
android:value="${MAP_SDK_VERSION}" />
<service
android:name="com.mogo.eagle.core.function.main.service.MogoMainService"
android:enabled="true"

View File

@@ -19,6 +19,8 @@ import android.widget.*
import androidx.core.view.*
import androidx.lifecycle.lifecycleScope
import com.alibaba.android.arouter.facade.annotation.Route
import com.alibaba.android.arouter.launcher.ARouter
import com.mogo.commons.mvp.BaseFragment
import com.mogo.commons.mvp.MvpFragment
import com.mogo.commons.voice.*
import com.mogo.eagle.core.data.bindingcar.AdUpgradeStateHelper
@@ -48,6 +50,7 @@ import com.mogo.eagle.core.function.call.bindingcar.CallerBindingcarManager
import com.mogo.eagle.core.function.call.check.CallerCheckManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.call.map.CallerMapDataCollectorManager
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
import com.mogo.eagle.core.function.call.monitor.CallerMonitorManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.WaringConst
@@ -57,6 +60,7 @@ import com.mogo.eagle.core.function.hmi.ui.bindingcar.ModifyBindingCarDialog
import com.mogo.eagle.core.function.hmi.ui.bindingcar.ToBindingCarDialog
import com.mogo.eagle.core.function.hmi.ui.bindingcar.UpgradeAppDialog
import com.mogo.eagle.core.function.hmi.ui.camera.CameraListView
import com.mogo.eagle.core.function.hmi.ui.camera.RoadVideoDialog
import com.mogo.eagle.core.function.hmi.ui.notice.NoticeBannerView
import com.mogo.eagle.core.function.hmi.ui.notice.NoticeNormalBannerView
import com.mogo.eagle.core.function.hmi.ui.setting.DebugSettingView
@@ -87,7 +91,6 @@ import kotlinx.coroutines.*
import mogo_msg.MogoReportMsg
import record_cache.RecordPanelOuterClass
import java.util.*
import kotlin.collections.ArrayList
/**
@@ -143,6 +146,12 @@ import kotlin.collections.ArrayList
private var speakJob: Job? = null
private var showingV2XTip: IReminder? = null
private var roadVideoDialog: RoadVideoDialog? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun vipIdentification(visible: Boolean) {
ThreadUtils.runOnUiThread {
if (visible) {
@@ -161,10 +170,10 @@ import kotlin.collections.ArrayList
}
}
/*ivCameraIcon?.setOnLongClickListener {
activity?.let { it1 -> CarcorderPreviewView.show(it1) }
ivCameraIcon?.setOnLongClickListener {
showSmallFragment()
true
}*/
}
ivToolsIcon?.setOnClickListener {
if (toolsViewFloat == null) {
@@ -297,6 +306,15 @@ import kotlin.collections.ArrayList
mViewNotificationProvider = provider
}
override fun showVideoDialog(url: String, isFlvUrl: Boolean) {
context?.let {
if (roadVideoDialog == null) {
roadVideoDialog = RoadVideoDialog(it)
}
roadVideoDialog?.show(url, isFlvUrl)
}
}
/**
* 设置 红绿灯 代理View
*/
@@ -1004,28 +1022,72 @@ import kotlin.collections.ArrayList
}
}
private var isLeftLight :Boolean = false
private var isRightLight :Boolean = false
private var isDisappare :Boolean = false
/**
* 显示转向灯效果 if (HmiBuildConfig.isShowBadCaseView) {
*/
override fun showTurnLight(light: Int) {
if (HmiBuildConfig.isShowTurnLightView) {
Log.e("liyz", "showTurnLight light = $light")
ThreadUtils.runOnUiThread {
turnLightView?.let {
turnLightView.setTurnLight(light)
if (light == 1) {
if (!isLeftLight) {
isLeftLight = true
isRightLight = false
isDisappare = false
//TODO
CallerMapUIServiceManager.getMapUIController()?.setCarLightsType(4, 500)
}
} else if (light == 2) {
if (!isRightLight) {
isRightLight = true
isLeftLight = false
isDisappare = false
CallerMapUIServiceManager.getMapUIController()?.setCarLightsType(2, 500)
}
} else {
if (!isDisappare) {
isDisappare = true
isLeftLight = false
isRightLight = false
CallerMapUIServiceManager.getMapUIController()?.setCarLightsType(3, 500)
}
}
// turnLightView?.let {
// turnLightView.setTurnLight(light)
// }
}
}
}
private var isBrake: Boolean = false
/**
* 显示刹车效果
*/
override fun showBrakeLight(light: Int) {
if (HmiBuildConfig.isShowBrakeLightView) {
Log.e("liyz", "showBrakeLight isBrake = $isBrake")
ThreadUtils.runOnUiThread {
brakeView?.let {
brakeView.setBrakeLight(light)
if (light == 1) { //刹车灯亮
if (!isBrake) {
isBrake = true
CallerMapUIServiceManager.getMapUIController()?.setCarLightsType(0, 500)
}
} else {
if (isBrake) {
isBrake = false
CallerMapUIServiceManager.getMapUIController()?.setCarLightsType(3, 500)
}
}
// brakeView?.let {
// brakeView.setBrakeLight(light)
// }
}
}
}
@@ -1138,6 +1200,29 @@ import kotlin.collections.ArrayList
}
}
override fun showSmallFragment() {
// 加载全览模式图层
val fragmentOverview = ARouter.getInstance().build(MoGoFragmentPaths.PATH_FRAGMENT_OVERVIEW)
.navigation() as BaseFragment
activity?.supportFragmentManager?.beginTransaction()
?.setCustomAnimations(R.anim.slide_in, R.anim.fade_out)?.apply {
if (!fragmentOverview.isAdded) {
add(R.id.module_main_id_smp_fragment, fragmentOverview, fragmentOverview.tagName)
} else {
show(fragmentOverview)
}.commitAllowingStateLoss()
}
}
override fun hideSmallFragment() {
val fragmentOverview = ARouter.getInstance().build(MoGoFragmentPaths.PATH_FRAGMENT_OVERVIEW)
.navigation() as BaseFragment
activity?.supportFragmentManager?.beginTransaction()
?.setCustomAnimations(R.anim.slide_in, R.anim.fade_out)
?.hide(fragmentOverview)
?.commitAllowingStateLoss()
}
override fun onDestroy() {
super.onDestroy()
CallerLogger.d("$M_HMI$TAG", "onDestroy")

View File

@@ -0,0 +1,120 @@
package com.mogo.eagle.core.function.hmi.ui.camera
import android.content.Context
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.view.View
import androidx.core.content.ContextCompat
import androidx.lifecycle.LifecycleObserver
import com.mogo.eagle.core.function.call.monitor.CallerMonitorManager
import com.mogo.eagle.core.function.hmi.R
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.ToastUtils
import com.mogo.eagle.core.widget.media.video.SimpleVideoPlayer
import com.mogo.module.common.dialog.BaseFloatDialog
import com.shuyu.gsyvideoplayer.GSYVideoManager
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
import com.shuyu.gsyvideoplayer.model.VideoOptionModel
import com.shuyu.gsyvideoplayer.player.IjkPlayerManager
import com.shuyu.gsyvideoplayer.player.PlayerFactory
import com.shuyu.gsyvideoplayer.utils.GSYVideoType
import kotlinx.android.synthetic.main.road_video_dialog.*
import kotlinx.android.synthetic.main.view_camera_list.view.*
import tv.danmaku.ijk.media.player.IjkMediaPlayer
/**
* @brief 道路视频Dialog
* @author chenfufeng
*/
class RoadVideoDialog(context: Context) : BaseFloatDialog(context), LifecycleObserver {
private val TAG = "RoadVideoDialog"
private var mVideoUrl: String = ""
private val gsyVideoOptionBuilder by lazy {
GSYVideoOptionBuilder()
}
init {
setContentView(R.layout.road_video_dialog)
roadVideoPB.indeterminateDrawable.colorFilter = PorterDuffColorFilter(
ContextCompat.getColor(context, R.color.notice_blue),
PorterDuff.Mode.MULTIPLY
)
setCanceledOnTouchOutside(false)
roadVideoClose.setOnClickListener {
dismiss()
}
initVideoPlayer()
}
fun show(url: String, isFlvUrl: Boolean) {
show()
roadVideoPB.visibility = View.VISIBLE
if (!isFlvUrl) {
// 打开指定ip的摄像头直播流
CallerMonitorManager.openCameraStream(url, { flvUrl ->
gsyVideoPlay(flvUrl)
}) {
ToastUtils.showShort(it.message)
dismiss()
}
} else {
gsyVideoPlay(url)
}
}
override fun dismiss() {
super.dismiss()
stopLive()
}
private fun initVideoPlayer() {
val list: MutableList<VideoOptionModel> = ArrayList()
list.add(VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "reconnect", 3))
GSYVideoManager.instance().optionModelList = list
GSYVideoType.setShowType(GSYVideoType.SCREEN_MATCH_FULL)
PlayerFactory.setPlayManager(IjkPlayerManager::class.java)
roadVideoPlayer.setPlayListener(object : SimpleVideoPlayer.PlayListener {
override fun onPlayEvent(event: Int) {
CallerLogger.d("${SceneConstant.M_HMI}$TAG", "onPlayEvent: event is:$event")
when (event) {
SimpleVideoPlayer.PLAY_EVT_PLAY_LOADING -> {
// 会出现临时中断后又可以继续播放,需要停掉倒计时
}
SimpleVideoPlayer.PLAY_EVT_PLAY_BEGIN -> {
roadVideoPB.visibility = View.GONE
roadVideoPlayer.visibility = View.VISIBLE
}
else -> {
CallerLogger.w("${SceneConstant.M_HMI}$TAG", "播放视频异常,event is:$event")
}
}
}
})
}
private fun gsyVideoPlay(flvUrl: String) {
gsyVideoOptionBuilder.setUrl(flvUrl)
.setCacheWithPlay(false)
.setAutoFullWithSize(false)
.setIsTouchWigetFull(false)
.setIsTouchWiget(false)
.setPlayTag(TAG).build(roadVideoPlayer)
roadVideoPlayer.startButton.performClick()
}
private fun stopLive() {
try {
GSYVideoManager.releaseAllVideos()
} catch (e: Exception) {
e.printStackTrace()
}
}
}

View File

@@ -1956,6 +1956,13 @@ class DebugSettingView @JvmOverloads constructor(
}
}
/**
* 车辆加速度
*/
override fun onAutopilotAcc(carAcc: Float) {
TODO("Not yet implemented")
}
/**
* 吐司提示
*/

View File

@@ -176,6 +176,15 @@ public class SteeringWheelView extends ConstraintLayout {
Log.d(TAG, "刹车灯:" + String.valueOf(brakeLight));
}
/**
* 车辆加速度
* @param carAcc
*/
@Override
public void onAutopilotAcc(float carAcc) {
}
/**
* 方向盘转向角 左+右-
* @param steering
@@ -223,7 +232,7 @@ public class SteeringWheelView extends ConstraintLayout {
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
Log.d(TAG, "档位" + gear.toString());
Log.d(TAG, "乘客屏档位" + gear.toString());
if (tapPositionView != null) {
tapPositionView.updateWithGear(gear);
}

View File

@@ -1,6 +1,7 @@
package com.mogo.eagle.core.function.hmi.ui.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
@@ -30,6 +31,7 @@ public class TapPositionView extends ConstraintLayout {
private TextView tabR;
private TextView tabN;
private TextView tabD;
private TypedArray typedArray;
public TapPositionView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
@@ -39,90 +41,48 @@ public class TapPositionView extends ConstraintLayout {
tabR = findViewById(R.id.tap_r);
tabN = findViewById(R.id.tap_n);
tabD = findViewById(R.id.tap_d);
typedArray = context.obtainStyledAttributes(attrs, R.styleable.TapPositionView);
}
public void updateWithGear(@NotNull Chassis.GearPosition gear) {
if (tabP != null && tabR != null && tabN != null && tabD != null) {
if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) {
taxiGear(gear);
} else {
busGear(gear);
int defaultColor = typedArray.getColor(R.styleable.TapPositionView_defaultColor, -1);
int selectColor = typedArray.getColor(R.styleable.TapPositionView_selectColor, -1);
Log.d(TAG, "gear:" + gear);
switch (gear) {
case GEAR_NONE:
tabP.setTextColor(defaultColor);
tabR.setTextColor(defaultColor);
tabN.setTextColor(defaultColor);
tabD.setTextColor(defaultColor);
break;
case GEAR_P:
tabP.setTextColor(selectColor);
tabR.setTextColor(defaultColor);
tabN.setTextColor(defaultColor);
tabD.setTextColor(defaultColor);
break;
case GEAR_R:
tabR.setTextColor(selectColor);
tabP.setTextColor(defaultColor);
tabN.setTextColor(defaultColor);
tabD.setTextColor(defaultColor);
break;
case GEAR_N:
tabN.setTextColor(selectColor);
tabR.setTextColor(defaultColor);
tabP.setTextColor(defaultColor);
tabD.setTextColor(defaultColor);
break;
case GEAR_D:
tabD.setTextColor(selectColor);
tabN.setTextColor(defaultColor);
tabR.setTextColor(defaultColor);
tabP.setTextColor(defaultColor);
break;
default:
break;
}
}
}
private void busGear(@NotNull Chassis.GearPosition gear) {
switch (gear) {
case GEAR_NONE:
tabP.setTextColor(Color.parseColor("#6E8EC9"));
tabR.setTextColor(Color.parseColor("#6E8EC9"));
tabN.setTextColor(Color.parseColor("#6E8EC9"));
tabD.setTextColor(Color.parseColor("#6E8EC9"));
break;
case GEAR_P:
tabP.setTextColor(Color.parseColor("#0043FF"));
tabR.setTextColor(Color.parseColor("#6E8EC9"));
tabN.setTextColor(Color.parseColor("#6E8EC9"));
tabD.setTextColor(Color.parseColor("#6E8EC9"));
break;
case GEAR_R:
tabR.setTextColor(Color.parseColor("#0043FF"));
tabP.setTextColor(Color.parseColor("#6E8EC9"));
tabN.setTextColor(Color.parseColor("#6E8EC9"));
tabD.setTextColor(Color.parseColor("#6E8EC9"));
break;
case GEAR_N:
tabN.setTextColor(Color.parseColor("#0043FF"));
tabR.setTextColor(Color.parseColor("#6E8EC9"));
tabP.setTextColor(Color.parseColor("#6E8EC9"));
tabD.setTextColor(Color.parseColor("#6E8EC9"));
break;
case GEAR_D:
tabD.setTextColor(Color.parseColor("#0043FF"));
tabN.setTextColor(Color.parseColor("#6E8EC9"));
tabR.setTextColor(Color.parseColor("#6E8EC9"));
tabP.setTextColor(Color.parseColor("#6E8EC9"));
break;
default:
break;
}
}
private void taxiGear(@NotNull Chassis.GearPosition gear) {
switch (gear) {
case GEAR_NONE:
tabP.setTextColor(Color.parseColor("#FF6E8EC9"));
tabR.setTextColor(Color.parseColor("#FF6E8EC9"));
tabN.setTextColor(Color.parseColor("#FF6E8EC9"));
tabD.setTextColor(Color.parseColor("#FF6E8EC9"));
break;
case GEAR_P:
tabP.setTextColor(Color.parseColor("#FFFFFFFF"));
tabR.setTextColor(Color.parseColor("#FF6E8EC9"));
tabN.setTextColor(Color.parseColor("#FF6E8EC9"));
tabD.setTextColor(Color.parseColor("#FF6E8EC9"));
break;
case GEAR_R:
tabR.setTextColor(Color.parseColor("#FFFFFFFF"));
tabP.setTextColor(Color.parseColor("#FF6E8EC9"));
tabN.setTextColor(Color.parseColor("#FF6E8EC9"));
tabD.setTextColor(Color.parseColor("#FF6E8EC9"));
break;
case GEAR_N:
tabN.setTextColor(Color.parseColor("#FFFFFFFF"));
tabR.setTextColor(Color.parseColor("#FF6E8EC9"));
tabP.setTextColor(Color.parseColor("#FF6E8EC9"));
tabD.setTextColor(Color.parseColor("#FF6E8EC9"));
break;
case GEAR_D:
tabD.setTextColor(Color.parseColor("#FFFFFFFF"));
tabN.setTextColor(Color.parseColor("#FF6E8EC9"));
tabR.setTextColor(Color.parseColor("#FF6E8EC9"));
tabP.setTextColor(Color.parseColor("#FF6E8EC9"));
break;
default:
break;
}
}
}

View File

@@ -0,0 +1,173 @@
package com.mogo.eagle.core.function.hmi.ui.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.mogo.eagle.core.data.config.FunctionBuildConfig;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotVehicleStateListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotVehicleStateListenerManager;
import com.mogo.eagle.core.function.hmi.R;
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils;
import com.mogo.eagle.core.utilcode.util.ThreadUtils;
import org.jetbrains.annotations.NotNull;
import java.math.BigDecimal;
import chassis.Chassis;
/**
* @author Jing
* @description 速度 加速度 档位 刹车 油门状态值
* @since: 6/24/22
*/
public class TrafficDataView extends ConstraintLayout {
private static final String TAG = "TrafficDataView";
private TapPositionView tapPositionView;
private TextView speedTextView;
private TextView accTextView;
private ImageView speedImage;
//圆弧颜色
private int mArcColor;
public TrafficDataView(@NonNull Context context) {
super(context);
}
public TrafficDataView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initView(context);
CallerAutopilotVehicleStateListenerManager.INSTANCE.addListener(TAG, mIMoGoAutopilotVehicleStateListener);
}
public TrafficDataView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public TrafficDataView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
private void initView(@NonNull Context context) {
if (AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) {
// LayoutInflater.from(context).inflate(R.layout.hmi_traffic_data, this);
} else {
}
LayoutInflater.from(context).inflate(R.layout.hmi_traffic_data, this);
tapPositionView = findViewById(R.id.traffic_position);
speedImage = findViewById(R.id.speedImage);
speedTextView = findViewById(R.id.speedTextView);
accTextView = findViewById(R.id.speedAccTextView);
}
private final IMoGoAutopilotVehicleStateListener mIMoGoAutopilotVehicleStateListener = new IMoGoAutopilotVehicleStateListener() {
/**
* 车辆转向灯
* @param lightSwitch
*/
@Override
public void onAutopilotLightSwitchData(@org.jetbrains.annotations.Nullable Chassis.LightSwitch lightSwitch) {
Log.d(TAG, "车辆转向灯:" + lightSwitch.toString());
}
/**
* 刹车灯
* @param brakeLight
*/
@Override
public void onAutopilotBrakeLightData(boolean brakeLight) {
Log.d(TAG, "刹车灯:" + String.valueOf(brakeLight));
}
/**
* 方向盘转向角 左+右-
* @param steering
*/
@Override
public void onAutopilotSteeringData(float steering) {
Log.d(TAG, "steering原始值====" + String.valueOf(steering));
if (Math.abs(steering) < 1) {
steering = 0;
}
float steeringValue = steering;
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
Log.d(TAG, "steering忽略小数点后====" + String.valueOf((int) steeringValue));
}
});
}
/**
* 档位
* @param gear
*/
@Override
public void onAutopilotGearData(@NotNull Chassis.GearPosition gear) {
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
Log.d(TAG, "司机屏档位" + gear.toString());
if (tapPositionView != null) {
tapPositionView.updateWithGear(gear);
}
}
});
}
@Override
public void onAutopilotDataException(long timestamp) {
}
@Override
public void onAutopilotAcc(float carAcc) {
Log.d(TAG, "司机屏加速度:" + carAcc);
java.text.DecimalFormat myformat = new java.text.DecimalFormat("0.00");
String accStr = myformat.format(carAcc);
accTextView.setText("a: " + accStr);
}
};
/**
* 设置弧形颜色
*
* @param value 颜色值
*/
public void setArcColor(int value) {
mArcColor = value;
}
/**
* 设置数据
*
* @param value 当前绘制的值
*/
public void setValues(int value) {
}
/**
* value呈现
*/
public void updateSpeedWithValue(int newSpeed) {
if (speedTextView != null) {
speedTextView.setText(String.valueOf(newSpeed));
}
if (speedImage != null) {
speedImage.setBackgroundResource(newSpeed > 60 ? R.drawable.traffic_data_speed_warning : R.drawable.traffic_data_speed);
}
}
}

View File

@@ -33,7 +33,6 @@ import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager;
import com.mogo.eagle.core.function.hmi.R;
import com.mogo.eagle.core.function.main.cards.MogoModulesManager;
import com.mogo.eagle.core.function.main.service.MogoMainService;
import com.mogo.eagle.core.function.main.stagetwo.APMStartup;
import com.mogo.eagle.core.function.main.stagetwo.AutopilotStartup;
import com.mogo.eagle.core.function.main.utils.DisplayEffectsHelper;
import com.mogo.eagle.core.function.main.windowview.FloatingViewHandler;
@@ -229,7 +228,6 @@ public class MainActivity extends MvpActivity<MainView, MainPresenter> implement
final long start = System.currentTimeMillis();
MogoModulesManager.getInstance().init(this);
IMogoHosListenerRegister listenerRegister = CallerMapUIServiceManager.INSTANCE.getHostListenerRegister();
if (listenerRegister != null) {
listenerRegister.registerHostMapListener(EventDispatchCenter.getInstance());
@@ -304,7 +302,6 @@ public class MainActivity extends MvpActivity<MainView, MainPresenter> implement
// 加载 HMI 图层
BaseFragment fragmentHdMap = (BaseFragment) ARouter.getInstance().build(MoGoFragmentPaths.PATH_FRAGMENT_HMI).navigation();
addFragment(fragmentHdMap, fragmentHdMap.getTagName(), R.id.module_main_id_waring_fragment);
// 加载 小地图 图层
BaseFragment fragmentSmpMap = (BaseFragment) ARouter.getInstance().build(MoGoFragmentPaths.PATH_FRAGMENT_SMP).navigation();
addFragment(fragmentSmpMap, fragmentSmpMap.getTagName(), R.id.module_main_id_smp_fragment);

View File

@@ -17,6 +17,7 @@ import com.mogo.eagle.core.function.api.chat.biz.ChatConsts;
import com.mogo.eagle.core.function.call.bindingcar.CallerBindingcarManager;
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager;
import com.mogo.eagle.core.function.notice.PushUIConstants;
import com.mogo.eagle.core.function.overview.OverviewDb;
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils;
import com.mogo.eagle.core.utilcode.mogo.AppLaunchTimeUtils;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
@@ -48,6 +49,7 @@ public abstract class MainMoGoApplication extends AbsMogoApplication {
}
start = System.currentTimeMillis();
connectAmiIp();
initOverviewDb();
// Crash 日志收集
initCrashConfig();
initLogConfig();
@@ -95,6 +97,10 @@ public abstract class MainMoGoApplication extends AbsMogoApplication {
CallerDevaToolsManager.INSTANCE.init(this);
}
private void initOverviewDb() {
OverviewDb.Companion.getDb(this);
}
/**
* 连接ami
*/

View File

@@ -1,33 +0,0 @@
package com.mogo.eagle.core.function.main.stagetwo;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.alibaba.android.arouter.launcher.ARouter;
import com.mogo.test.crashreport.CrashReportConstants;
import com.mogo.test.crashreport.upgrade.UpgradeReportConstants;
import com.rousetime.android_startup.AndroidStartup;
public class APMStartup extends AndroidStartup<Boolean> {
@Nullable
@Override
public Boolean create(@NonNull Context context) {
// bugly
ARouter.getInstance().build(UpgradeReportConstants.PATH).navigation();
// apm
ARouter.getInstance().build(CrashReportConstants.PATH).navigation();
return true;
}
@Override
public boolean callCreateOnMainThread() {
return true;
}
@Override
public boolean waitOnMainThread() {
return false;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@@ -51,7 +51,7 @@
android:layout_marginTop="@dimen/dp_72"
android:layout_marginRight="-16px"
android:gravity="right"
android:text="180°"
android:text="0°"
android:textColor="#415479"
android:textSize="@dimen/dp_38"
android:visibility="invisible"
@@ -65,7 +65,7 @@
android:layout_marginLeft="-16px"
android:layout_marginTop="@dimen/dp_72"
android:gravity="left"
android:text="180°"
android:text="0°"
android:textColor="#415479"
android:textSize="@dimen/dp_38"
app:layout_constraintLeft_toRightOf="@+id/steering_circular"
@@ -87,6 +87,8 @@
android:layout_width="@dimen/dp_390"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dp_42"
app:defaultColor = "@color/p_default_txt_color"
app:selectColor="@color/bus_p_select_txt_color"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"

View File

@@ -88,6 +88,8 @@
android:layout_width="@dimen/dp_272"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_30"
app:defaultColor="@color/p_default_txt_color"
app:selectColor="@color/dark_mode_select_txt_color"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/steering_circular_alpha" />

View File

@@ -12,7 +12,7 @@
android:gravity="center"
android:text="P"
android:textAlignment="center"
android:textColor="#6E8EC9"
android:textColor="@color/p_default_txt_color"
android:textSize="@dimen/dp_46"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
@@ -27,7 +27,7 @@
android:gravity="center"
android:text="R"
android:textAlignment="center"
android:textColor="#6E8EC9"
android:textColor="@color/p_default_txt_color"
android:textSize="@dimen/dp_46"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
@@ -42,7 +42,7 @@
android:gravity="center"
android:text="N"
android:textAlignment="center"
android:textColor="#6E8EC9"
android:textColor="@color/p_default_txt_color"
android:textSize="@dimen/dp_46"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
@@ -57,7 +57,7 @@
android:gravity="center"
android:text="D"
android:textAlignment="center"
android:textColor="#0043FF"
android:textColor="@color/p_default_txt_color"
android:textSize="@dimen/dp_46"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"

View File

@@ -0,0 +1,85 @@
<?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"
android:layout_width="@dimen/dp_616"
android:layout_height="@dimen/dp_320"
android:background="@drawable/traffic_data_back">
<ImageView
android:id="@+id/speedImage"
android:layout_width="@dimen/dp_270"
android:layout_height="@dimen/dp_270"
android:layout_marginLeft="@dimen/dp_46"
android:background="@drawable/traffic_data_speed"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/speedTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="80px"
android:text="0"
android:textAlignment="center"
android:textColor="#fff"
android:textSize="@dimen/dp_70"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="@+id/speedImage"
app:layout_constraintRight_toRightOf="@+id/speedImage"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/kmTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_176"
android:text="KM/H"
android:textAlignment="center"
android:textColor="#fff"
android:textSize="@dimen/dp_30"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="@+id/speedImage"
app:layout_constraintRight_toRightOf="@+id/speedImage"
app:layout_constraintTop_toTopOf="parent" />
<com.mogo.eagle.core.function.hmi.ui.widget.TapPositionView
android:id="@+id/traffic_position"
android:layout_width="@dimen/dp_220"
app:defaultColor="@color/acc_default_txt_color"
app:selectColor="@color/dark_mode_select_txt_color"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_28"
android:layout_marginTop="@dimen/dp_80"
android:layout_marginRight="@dimen/dp_80"
app:layout_constraintLeft_toRightOf="@+id/speedImage"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/brakeStatus"
android:layout_width="@dimen/dp_66"
android:layout_height="@dimen/dp_68"
android:layout_marginLeft="@dimen/dp_20"
android:layout_marginTop="@dimen/dp_174"
android:layout_marginBottom="@dimen/dp_57"
android:src="@drawable/traffic_data_empty"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@id/speedImage"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/speedAccTextView"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_56"
android:layout_marginLeft="@dimen/dp_42"
android:layout_marginTop="@dimen/dp_190"
android:text="a: "
android:textAlignment="viewStart"
android:textColor="#fff"
android:textSize="@dimen/dp_40"
app:layout_constraintLeft_toLeftOf="@+id/brakeStatus"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<com.mogo.eagle.core.widget.RoundConstraintLayout 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="wrap_content"
android:layout_height="wrap_content"
android:minWidth="1736px"
android:minHeight="974px"
app:roundLayoutRadius="30px"
android:background="@drawable/road_video_bg"
tools:ignore="MissingDefaultResource">
<com.mogo.eagle.core.widget.media.video.SimpleVideoPlayer
android:id="@+id/roadVideoPlayer"
android:layout_width="1736px"
android:layout_height="974px"
android:visibility="visible"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/roadVideoPB"
style="?android:attr/progressBarStyleSmall"
android:layout_width="36dp"
android:layout_height="36dp"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/roadVideoClose"
android:layout_width="100px"
android:layout_height="100px"
android:layout_marginEnd="42px"
android:layout_marginTop="42px"
android:scaleType="fitXY"
android:src="@drawable/module_push_dialog_close"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
</com.mogo.eagle.core.widget.RoundConstraintLayout>

View File

@@ -6,4 +6,5 @@
<color name="notice_check_dialog_bg_color">#E63B4577</color>
<color name="notice_traffic_line">#555C7E</color>
<color name="notice_dialog_back">#3B4577</color>
<color name="acc_default_txt_color">#FF343C63</color>
</resources>

View File

@@ -49,4 +49,8 @@
<attr name="progress" format="integer" /> <!--圆环进度-->
</declare-styleable>
<declare-styleable name="TapPositionView">
<attr name="defaultColor" format="color"/> <!--档位默认色值-->
<attr name="selectColor" format="color"/> <!--当前档位色值-->
</declare-styleable>
</resources>

View File

@@ -60,4 +60,9 @@
<color name="hmi_light_blue_alpha_00">#D945D3FF</color>
<color name="hmi_light_blue_alpha_ff">#D93261B6</color>
<color name="hmi_clear_00">#00FFFFFF</color>
<color name="acc_default_txt_color">#FF343C63</color>
<color name="bus_p_select_txt_color">#0043FF</color>
<color name="p_default_txt_color">#FF6E8EC9</color>
<color name="dark_mode_select_txt_color">#FFFFFFFF</color>
</resources>

View File

@@ -23,7 +23,11 @@ android {
arg("AROUTER_MODULE_NAME", project.getName())
}
}
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
}
buildTypes {
@@ -37,7 +41,6 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
@@ -56,6 +59,12 @@ dependencies {
implementation rootProject.ext.dependencies.amapnavi3dmap
implementation rootProject.ext.dependencies.amaplocation
implementation rootProject.ext.dependencies.androidxroomruntime
kapt rootProject.ext.dependencies.androidxroomcompiler
implementation rootProject.ext.dependencies.androidxroomktx
implementation rootProject.ext.dependencies.view_model_scope
implementation rootProject.ext.dependencies.lifecycle_extension
if (Boolean.valueOf(USE_MAVEN_PACKAGE)) {
implementation rootProject.ext.dependencies.modulecommon
implementation rootProject.ext.dependencies.mogoserviceapi

View File

@@ -12,10 +12,16 @@ import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.commons.mvp.MvpFragment;
import com.mogo.eagle.core.data.constants.MoGoFragmentPaths;
import com.mogo.eagle.core.data.map.CenterLine;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotPlanningListener;
import com.mogo.eagle.core.function.api.map.hd.IMoGoMapFragmentProvider;
import com.mogo.eagle.core.function.api.setting.IMoGoSkinModeChangeListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotPlanningListenerManager;
import com.mogo.eagle.core.function.call.map.CallerHDMapManager;
import com.mogo.eagle.core.function.call.setting.CallerSkinModeListenerManager;
import com.mogo.eagle.core.function.overview.InfStructureManager;
import com.mogo.eagle.core.function.overview.Infrastructure;
import com.mogo.eagle.core.function.overview.ViewModelExtKt;
import com.mogo.eagle.core.function.overview.vm.OverViewModel;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.map.IMogoMap;
import com.mogo.map.IMogoUiSettings;
@@ -24,6 +30,13 @@ import com.mogo.map.uicontroller.IMogoMapUIController;
import com.zhidaoauto.map.sdk.open.MapAutoApi;
import com.zhidaoauto.map.sdk.open.business.PointCloudHelper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import ch.hsr.geohash.GeoHash;
import mogo.telematics.pad.MessagePad;
/**
* @author donghongyu
* @since 2021-11-09
@@ -33,7 +46,8 @@ import com.zhidaoauto.map.sdk.open.business.PointCloudHelper;
*/
@Route(path = MoGoFragmentPaths.PATH_FRAGMENT_MAP)
public class MapFragment extends MvpFragment<MapView, MapPresenter>
implements MapView, IMoGoMapFragmentProvider, IMoGoSkinModeChangeListener {
implements MapView, IMoGoMapFragmentProvider, IMoGoSkinModeChangeListener,
IMoGoAutopilotPlanningListener {
private static final String TAG = "MapFragment";
@@ -95,6 +109,7 @@ public class MapFragment extends MvpFragment<MapView, MapPresenter>
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initMapView();
queryInfStructure();
}
@Override
@@ -177,6 +192,27 @@ public class MapFragment extends MvpFragment<MapView, MapPresenter>
MapPointCloudSubscriber.Companion.getInstance();
}
private void queryInfStructure() {
OverViewModel viewModel = ViewModelExtKt.obtainViewModel(this, OverViewModel.class);
// viewModel.getInfStructures().observe(this.getViewLifecycleOwner(), infrastructures -> {
// if (isFirst) {
// for (Infrastructure entity : infrastructures) {
// Double lat = Double.parseDouble(entity.getLat());
// Double lon = Double.parseDouble(entity.getLon());
// if (lat < 0 || lat > 90 || lon < 0 || lon > 180) {
// continue;
// }
// String geoHash = GeoHash.withCharacterPrecision(lat, lon, 7).toBase32();
// viewModel.updateGeoHash(entity.getId(), geoHash);
// }
// isFirst = false;
// }
// });
viewModel.getInfStructuresMap().observe(this.getViewLifecycleOwner(), InfStructureManager.INSTANCE::saveData);
viewModel.fetchInfStructures();
}
@Override
public IMogoMapUIController getUIController() {
return mMogoMap.getUIController();
@@ -185,6 +221,7 @@ public class MapFragment extends MvpFragment<MapView, MapPresenter>
@Override
public void onDestroyView() {
CallerSkinModeListenerManager.INSTANCE.removeListener(TAG);
CallerAutopilotPlanningListenerManager.INSTANCE.removeListener(TAG);
if (mMogoMapView != null) {
mMogoMapView.onDestroy();
mMogoMapView = null;
@@ -303,4 +340,31 @@ public class MapFragment extends MvpFragment<MapView, MapPresenter>
public void setDebugMode(boolean debugMode) {
MapAutoApi.INSTANCE.setDebugMode(debugMode);
}
@Override
public void onAutopilotTrajectory(@NonNull List<MessagePad.TrajectoryPoint> trajectoryInfos) {
}
@Override
public void onAutopilotRotting(@Nullable MessagePad.GlobalPathResp globalPathResp) {
if (globalPathResp != null) {
HashMap<String, ArrayList<Infrastructure>> pathMap = new HashMap();
String geoHash;
ArrayList<Infrastructure> infList;
for (MessagePad.Location location : globalPathResp.getWayPointsList()) {
geoHash = GeoHash.withCharacterPrecision(location.getLatitude(), location.getLongitude(), 7).toBase32();
// 网格内的轨迹点只取一次
if (!pathMap.containsKey(geoHash)) {
// 从缓存的新基建数据中去取对应geoHash的新基建数据集合
infList = InfStructureManager.INSTANCE.getData().get(geoHash);
if (infList != null) {
pathMap.put(geoHash, infList);
}
}
}
// 全局路径规划只回调一次保存供全览模式所在Fragment使用
InfStructureManager.INSTANCE.savePathData(pathMap);
}
}
}

View File

@@ -3,9 +3,13 @@ package com.mogo.eagle.core.function.map
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotPointCloudListener
import com.mogo.eagle.core.function.api.base.IMoGoSubscriber
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotPointCloudListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.zhidaoauto.map.sdk.open.business.PointCloudHelper
import mogo.telematics.pad.MessagePad
import rule_segement.MogoPointCloudOuterClass
import java.math.BigDecimal
/**
* 订阅点云数据
@@ -56,9 +60,9 @@ class MapPointCloudSubscriber private constructor() : IMoGoSubscriber, IMoGoAuto
* @param isStrong 是否加粗显示
* @return 是否执行
*/
Logger.d(TAG, "====开始传入地图点云数据====")
//Logger.d(TAG, "====开始传入地图点云数据====")
val result = PointCloudHelper.updatePointCloudDataByPb(pointCloud, false, true, true)
Logger.d(TAG, "====结束传入地图点云数据=====$result")
//Logger.d(TAG, "====结束传入地图点云数据=====$result")
} else {
if (isDrawPointCloud) {
Logger.d(TAG, "====停止点云绘制====")
@@ -67,4 +71,16 @@ class MapPointCloudSubscriber private constructor() : IMoGoSubscriber, IMoGoAuto
}
}
}
override fun onAutopilotPointCloudDataUpdate(header: MessagePad.Header?, pointCloud: MogoPointCloudOuterClass.MogoPointCloud?) {
// Logger.d(TAG, "数据对比:"
// + "\n自车定位自车的 satelliteTime==${getPrettyNumber(CallerAutoPilotStatusListenerManager.getAutoPilotStatusInfo().satelliteTime.toString())} 经纬度:${CallerAutoPilotStatusListenerManager.getAutoPilotStatusInfo().locationLat},${CallerAutoPilotStatusListenerManager.getAutoPilotStatusInfo().locationLon}"
// + "\n点云数据点云的 header?.timestamp==${getPrettyNumber(header?.timestamp.toString())} 经纬度:${pointCloud?.selfLatitude},${pointCloud?.selfLongitude} 点云数量addDataCount==${pointCloud?.addDataCount} delDataCount===${pointCloud?.delDataCount} "
// )
}
fun getPrettyNumber(number: String): String {
return BigDecimal.valueOf(number.toDouble())
.stripTrailingZeros().toPlainString()
}
}

View File

@@ -0,0 +1,35 @@
package com.mogo.eagle.core.function.overview
/**
* 本地数据库查询出来的红绿灯、摄像头等数据
*/
object InfStructureManager {
// 每个GeoHash网格对应的新基建Bean
private val _infMap by lazy {
HashMap<String, ArrayList<Infrastructure>>()
}
// 全局路径规划中所有点的GeoHash网格对应的新基建数据集合
private val _pathMap by lazy {
HashMap<String, ArrayList<Infrastructure>>()
}
fun saveData(map: HashMap<String, java.util.ArrayList<Infrastructure>>) {
if (_infMap.isNotEmpty()) {
_infMap.clear()
}
_infMap.putAll(map)
}
fun getData(): Map<String, ArrayList<Infrastructure>> = _infMap
fun savePathData(map: HashMap<String, java.util.ArrayList<Infrastructure>>) {
if (_pathMap.isNotEmpty()) {
_pathMap.clear()
}
_pathMap.putAll(map)
}
fun getPathData(): Map<String, ArrayList<Infrastructure>> = _pathMap
}

View File

@@ -0,0 +1,30 @@
package com.mogo.eagle.core.function.overview
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "t_device")
data class Infrastructure(
@PrimaryKey
@ColumnInfo(name = "id")
var id: Int,
@ColumnInfo(name = "category")
var category: Int,
@ColumnInfo(name = "ip")
var ip: String?,
@ColumnInfo(name = "lon")
var lon: String?,
@ColumnInfo(name = "lat")
var lat: String?,
@ColumnInfo(name = "heading")
var heading: Int,
@ColumnInfo(name = "geohash")
var geoHash: String?
)

View File

@@ -0,0 +1,14 @@
package com.mogo.eagle.core.function.overview
class OverViewManager private constructor() {
private object Holder {
val INSTANCE = OverViewManager()
}
companion object {
val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
Holder.INSTANCE
}
}
}

View File

@@ -0,0 +1,17 @@
package com.mogo.eagle.core.function.overview
import androidx.room.Dao
import androidx.room.Query
@Dao
interface OverviewDao {
// 0表示摄像头8表示红绿灯
@Query("SELECT * FROM t_device WHERE category = :category")
suspend fun listInfStructures(category: Int): List<Infrastructure>
@Query("SELECT * FROM t_device")
suspend fun listAllInfStructures(): List<Infrastructure>
@Query("UPDATE t_device SET geohash = :geoHash WHERE id = :id")
suspend fun updateGeoHash(id: Int, geoHash: String)
}

View File

@@ -0,0 +1,28 @@
package com.mogo.eagle.core.function.overview
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(entities = [Infrastructure::class], version = 1, exportSchema = false)
abstract class OverviewDb: RoomDatabase() {
abstract fun overviewDao(): OverviewDao
companion object {
private const val DB_PATH = "database/t_device.db"
private const val INTERNAL_DB_NAME = "t_device.db"
private var db: OverviewDb? = null
fun getDb(context: Context): OverviewDb {
if (db == null) {
db = Room.databaseBuilder(context.applicationContext, OverviewDb::class.java, INTERNAL_DB_NAME)
.createFromAsset(DB_PATH)
.fallbackToDestructiveMigration()
.build()
}
return db!!
}
}
}

View File

@@ -0,0 +1,13 @@
package com.mogo.eagle.core.function.overview
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProviders
import com.mogo.commons.AbsMogoApplication
fun <T : ViewModel> AppCompatActivity.obtainViewModel(viewModelClass: Class<T>) =
ViewModelProviders.of(this, ViewModelFactory.getInstance(application)).get(viewModelClass)
fun <T : ViewModel> Fragment.obtainViewModel(viewModelClass: Class<T>) =
ViewModelProviders.of(this, ViewModelFactory.getInstance(AbsMogoApplication.getApp())).get(viewModelClass)

View File

@@ -0,0 +1,39 @@
package com.mogo.eagle.core.function.overview
import android.annotation.SuppressLint
import android.app.Application
import androidx.annotation.VisibleForTesting
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.mogo.eagle.core.function.overview.vm.OverViewModel
class ViewModelFactory private constructor(
private val overviewDao: OverviewDao
) : ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>) =
with(modelClass) {
when {
isAssignableFrom(OverViewModel::class.java) ->
OverViewModel(overviewDao)
else ->
throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}")
}
} as T
companion object {
@SuppressLint("StaticFieldLeak")
@Volatile private var INSTANCE: ViewModelFactory? = null
fun getInstance(application: Application) =
INSTANCE ?: synchronized(ViewModelFactory::class.java) {
INSTANCE ?: ViewModelFactory(
OverviewDb.getDb(application).overviewDao())
.also { INSTANCE = it }
}
@VisibleForTesting fun destroyInstance() {
INSTANCE = null
}
}
}

View File

@@ -0,0 +1,65 @@
package com.mogo.eagle.core.function.overview.vm
import androidx.lifecycle.*
import com.mogo.eagle.core.function.overview.Infrastructure
import com.mogo.eagle.core.function.overview.OverviewDao
import kotlinx.coroutines.launch
import java.lang.Exception
class OverViewModel(
private val overviewDao: OverviewDao
) : ViewModel() {
private val _infStructures = MutableLiveData<List<Infrastructure>>()
val infStructures
get() = _infStructures
private val _infStructuresMap = _infStructures
.switchMap { infStructures ->
liveData {
val map = HashMap<String, ArrayList<Infrastructure>>()
infStructures.forEach {
val geoHash = it.geoHash
if (geoHash == null) {
return@forEach
} else {
if (!map.containsKey(geoHash)) {
val list = ArrayList<Infrastructure>()
list.add(it)
map[geoHash] = list
} else {
map[geoHash]?.add(it)
}
}
}
emit(map)
}
}
val infStructuresMap
get() = _infStructuresMap
fun fetchInfStructures() {
viewModelScope.launch {
val data = try {
// 只查找摄像头
overviewDao.listInfStructures(0)
// overviewDao.listAllInfStructures()
} catch (e: Exception) {
e.printStackTrace()
null
}
data?.let {
_infStructures.value = it
}
}
}
fun updateGeoHash(id: Int, geoHash: String) {
viewModelScope.launch {
try {
overviewDao.updateGeoHash(id, geoHash)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}

View File

@@ -0,0 +1,794 @@
package com.mogo.eagle.core.function.smp;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.location.Location;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.CoordinateConverter;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CustomMapStyleOptions;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.Polyline;
import com.amap.api.navi.AMapNavi;
import com.amap.api.navi.AMapNaviListener;
import com.amap.api.navi.AMapNaviView;
import com.amap.api.navi.AMapNaviViewListener;
import com.amap.api.navi.AMapNaviViewOptions;
import com.amap.api.navi.enums.NaviType;
import com.amap.api.navi.model.AMapCalcRouteResult;
import com.amap.api.navi.model.AMapLaneInfo;
import com.amap.api.navi.model.AMapModelCross;
import com.amap.api.navi.model.AMapNaviCameraInfo;
import com.amap.api.navi.model.AMapNaviCross;
import com.amap.api.navi.model.AMapNaviInfo;
import com.amap.api.navi.model.AMapNaviLocation;
import com.amap.api.navi.model.AMapNaviRouteNotifyData;
import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo;
import com.amap.api.navi.model.AMapServiceAreaInfo;
import com.amap.api.navi.model.AimLessModeCongestionInfo;
import com.amap.api.navi.model.AimLessModeStat;
import com.amap.api.navi.model.NaviInfo;
import com.amap.api.navi.model.NaviLatLng;
import com.amap.api.navi.model.RouteOverlayOptions;
import com.autonavi.tbt.TrafficFacilityInfo;
import com.elegant.utils.UiThreadHandler;
import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo;
import com.mogo.eagle.core.data.config.FunctionBuildConfig;
import com.mogo.eagle.core.data.map.MogoLatLng;
import com.mogo.eagle.core.data.map.MogoLocation;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotPlanningListener;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
import com.mogo.eagle.core.function.api.map.listener.IMoGoMapLocationListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotPlanningListenerManager;
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager;
import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager;
import com.mogo.eagle.core.function.map.R;
import com.mogo.eagle.core.function.overview.InfStructureManager;
import com.mogo.eagle.core.function.overview.Infrastructure;
import com.mogo.eagle.core.function.smp.view.ISmallMapDirectionView;
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils;
import com.mogo.eagle.core.utilcode.mogo.MapAssetStyleUtils;
import com.mogo.eagle.core.utilcode.util.ThreadUtils;
import com.mogo.module.common.utils.DrivingDirectionUtils;
import com.zhidao.support.adas.high.AdasManager;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import ch.hsr.geohash.GeoHash;
import mogo.telematics.pad.MessagePad;
import mogo_msg.MogoReportMsg;
import system_master.SystemStatusInfo;
/**
* 小地图的方向View
* 监听自动驾驶路径结束,结束高德地图导航
*
* @author donghongyu
* @date 12/14/20 4:40 PM
*/
public class AMapCustomView
extends RelativeLayout
implements IMoGoMapLocationListener, ISmallMapDirectionView, AMapNaviListener, AMapNaviViewListener {
public static final String TAG = "AMapCustomView";
private AMapNaviView mAMapNaviView;
protected AMapNavi mAMapNavi;
private AMap mAMap;
protected NaviLatLng mStartLatlng = new NaviLatLng();
protected NaviLatLng mEndLatlng = new NaviLatLng();
protected final List<NaviLatLng> sList = new ArrayList<NaviLatLng>();
protected final List<NaviLatLng> eList = new ArrayList<NaviLatLng>();
private int zoomLevel = 15;
private final List<LatLng> mCoordinatesLatLng = new ArrayList<>();
private final List<MogoLatLng> mCoordinatesLatLngCurrent = new ArrayList<>();
protected List<NaviLatLng> mWayPointList = new ArrayList<NaviLatLng>();
private Polyline mPolyline;
private CameraUpdate mCameraUpdate;
private Context mContext;
private float tilt = 30f;
private TextView overLayerView;
private boolean calculate = false;
// 全局路径规划中的GeoHash网格
private Map<String, ArrayList<Infrastructure>> pathMap = new HashMap();
private Map<LatLng, Infrastructure> posInfMap = new HashMap();
public AMapCustomView(Context context) {
this(context, null);
}
public AMapCustomView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public AMapCustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
try {
initView(context);
} catch (Exception e) {
e.printStackTrace();
}
}
private void initView(Context context) {
mContext = context;
View smpView = LayoutInflater.from(context).inflate(R.layout.module_overview_map_view, this);
mAMapNaviView = smpView.findViewById(R.id.aMapNaviView);
overLayerView = findViewById(R.id.overLayer);
mAMapNavi = AMapNavi.getInstance(context);
mAMapNavi.addAMapNaviListener(this);
mAMapNaviView.setAMapNaviViewListener(this);
CallerAutoPilotStatusListenerManager.INSTANCE.addListener(TAG, mGoAutopilotStatusListener);
CallerAutopilotPlanningListenerManager.INSTANCE.addListener(TAG, moGoAutopilotPlanningListener);
initAMapView(context);
// 注册定位监听
CallerMapLocationListenerManager.INSTANCE.addListener(TAG, this);
//设置全览模式
overLayerView.setOnClickListener(v -> {
CallerHmiManager.INSTANCE.hideSmallFragment();
// mAMapNaviView.displayOverview();
});
// 注册定位监听
CallerMapLocationListenerManager.INSTANCE.addListener(TAG, this);
CallerAutoPilotStatusListenerManager.INSTANCE.addListener(TAG, mGoAutopilotStatusListener);
CallerAutopilotPlanningListenerManager.INSTANCE.addListener(TAG, moGoAutopilotPlanningListener);
}
private void initAMapView(Context context) {
Log.d(TAG, "initAMapView");
mCameraUpdate = CameraUpdateFactory.zoomTo(zoomLevel);
mAMap = mAMapNaviView.getMap();
setUpMap();
customOptions();
}
private void setUpMap() {
// 地图文字标注
mAMap.showMapText(true);
//设置希望展示的地图缩放级别
mAMap.moveCamera(mCameraUpdate);
//设置地图的样式
UiSettings uiSettings = mAMap.getUiSettings();
//地图缩放级别的交换按钮
uiSettings.setZoomControlsEnabled(false);
//所有手势
uiSettings.setAllGesturesEnabled(true);
//隐藏指南针
uiSettings.setCompassEnabled(false);
//设置倾斜手势是否可用。
uiSettings.setTiltGesturesEnabled(true);
//隐藏默认的定位按钮
uiSettings.setMyLocationButtonEnabled(false);
//设置Logo下边界距离屏幕底部的边距,设置为负值即可
uiSettings.setLogoBottomMargin(-150);
Log.d(TAG, "before onMapLoaded");
}
/**
* 自定义导航View和路况状态
*/
private void customOptions() {
AMapNaviViewOptions options = mAMapNaviView.getViewOptions();
//关闭自动绘制路线,自行绘制路线
// options.setAutoDrawRoute(false);
//不显示导航界面
options.setLayoutVisible(false);
options.setTilt(60);
//黑夜模式
options.setNaviNight(true);
//导航全程光柱
options.setTrafficBarEnabled(false);
//指南针
// options.setCompassEnabled(false);
// options.setTilt((int) tilt);
//自车车标
options.setCarBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.module_small_map_view_my_location_logo));
options.setFourCornersBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.amap_custom_corner));
options.setStartPointBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.module_small_map_view_dir_start));
options.setWayPointBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.icon_module_small_map_four_corners));
options.setEndPointBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.module_small_map_view_dir_end));
//与走过的路线
options.setAfterRouteAutoGray(true);
//路线纹理自定义
RouteOverlayOptions routeOverlayOptions = new RouteOverlayOptions();
routeOverlayOptions.setTurnArrowIs3D(false);
routeOverlayOptions.setUnknownTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.custtexture_no));//未知路段
routeOverlayOptions.setSmoothTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.amap_custom_smooth_route));
routeOverlayOptions.setJamTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.custtexture_bad));//拥堵路段
routeOverlayOptions.setVeryJamTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.custtexture_grayred));//超级拥堵路段
routeOverlayOptions.setPassRoute(BitmapFactory.decodeResource(getResources(), R.drawable.amap_custom_pass_route));//走过的路段
options.setRouteOverlayOptions(routeOverlayOptions);
mAMapNaviView.setViewOptions(options);
}
private final IMoGoAutopilotStatusListener mGoAutopilotStatusListener = new IMoGoAutopilotStatusListener() {
@Override
public void onAutopilotStatusRespByQuery(@NonNull SystemStatusInfo.StatusInfo status) {
}
@Override
public void onAutopilotIpcConnectStatusChanged(int status, @org.jetbrains.annotations.Nullable String reason) {
}
@Override
public void onAutopilotGuardian(@org.jetbrains.annotations.Nullable MogoReportMsg.MogoReportMessage guardianInfo) {
}
@Override
public void onAutopilotSNRequest() {
}
@Override
public void onAutopilotArriveAtStation(@org.jetbrains.annotations.Nullable MessagePad.ArrivalNotification arrivalNotification) {
}
@Override
public void onAutopilotStatusResponse(@NotNull AutopilotStatusInfo autoPilotStatusInfo) {
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
if (autoPilotStatusInfo == null) return;
int state = autoPilotStatusInfo.getState();
//0 不能自动驾驶 1 可以自动驾驶,但是在人工干预 2 自动驾驶中
if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {
Log.d(TAG, "自动驾驶中 state=" + String.valueOf(state));
if (sList.size() == 0 && eList.size() == 0 && mWayPointList.size() == 0) {
Log.d(TAG, "sendGlobalPathReq");
AdasManager.getInstance().sendGlobalPathReq();
}
} else {
int type = mAMapNavi.getNaviType();
Log.d(TAG, "非自动驾驶状态,导航类型==" + String.valueOf(type));
if (type == NaviType.GPS || type == NaviType.EMULATOR) {
mAMapNavi.stopNavi();
}
}
}
});
}
};
private final IMoGoAutopilotPlanningListener moGoAutopilotPlanningListener = new IMoGoAutopilotPlanningListener() {
@Override
public void onAutopilotTrajectory(@NotNull List<MessagePad.TrajectoryPoint> trajectoryInfos) {
Log.d(TAG, "onAutopilotTrajectory");
}
/**
* 根据全路径获取起始点和经停点进行导航路线绘制
* 自动驾驶启动后获得数据,获取全路径的具体时间要进行路测
* 室内某个bag包自动驾驶启动8s后返回
*/
@Override
public void onAutopilotRotting(@org.jetbrains.annotations.Nullable MessagePad.GlobalPathResp globalPathResp) {
if (calculate == true && sList.size() == 0 && eList.size() == 0 && mWayPointList.size() == 0) {
return;
}
calculate = true;
Log.d(TAG, "onAutopilotRotting");
List list = globalPathResp.getWayPointsList();
int minCount = 2;
if (list.size() >= minCount && sList.size() == 0 && eList.size() == 0 && mWayPointList.size() == 0) {
calculate = true;
MessagePad.Location sLocation = (MessagePad.Location) list.get(0);
MessagePad.Location eLocation = (MessagePad.Location) list.get(list.size() - 1);
mStartLatlng = new NaviLatLng(sLocation.getLatitude(), sLocation.getLongitude());
mEndLatlng = new NaviLatLng(eLocation.getLatitude(), eLocation.getLongitude());
sList.clear();
eList.clear();
sList.add(mStartLatlng);
eList.add(mEndLatlng);
mWayPointList.clear();
for (int i = 1; i < list.size() - minCount; i++) {
MessagePad.Location wayLoc = (MessagePad.Location) list.get(i);
NaviLatLng way = new NaviLatLng(wayLoc.getLatitude(), wayLoc.getLongitude());
mWayPointList.add(way);
}
}
int strategy = 0;
try {
//再次强调最后一个参数为true时代表多路径否则代表单路径
strategy = mAMapNavi.strategyConvert(true, false, false, false, false);
} catch (Exception e) {
e.printStackTrace();
}
Log.d(TAG, "全局路径" + list.size() + ",起点:" + sList.toString() + ",终点:" + eList.toString() + ",经点:" + mWayPointList.toString());
//指定路径绘制导航路线
mAMapNavi.calculateDriveRoute(sList, eList, mWayPointList, strategy);
drawInfrastructureMarkers(globalPathResp);
}
};
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
// 注册定位监听
CallerMapLocationListenerManager.INSTANCE.removeListener(TAG);
CallerAutoPilotStatusListenerManager.INSTANCE.removeListener(TAG);
CallerAutopilotPlanningListenerManager.INSTANCE.removeListener(TAG);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return false;
}
@Override
public void onLocationChanged(@org.jetbrains.annotations.Nullable MogoLocation location, int from) {
}
private void removeLocation(Location latLng) {
for (LatLng l : mCoordinatesLatLng) {
if (!isPointOnCarFront(latLng, l)) {
mCoordinatesLatLng.remove(l);
}
}
}
public static boolean isPointOnCarFront(Location carLocal, LatLng pointLocal) {
double carLon = carLocal.getLongitude();
double carLat = carLocal.getLatitude();
double poiLon = pointLocal.longitude;
double poiLat = pointLocal.latitude;
float carAngle = carLocal.getBearing();
// 计算车辆与点之间的夹角
int diffAngle = DrivingDirectionUtils.getDegreeOfCar2Poi(
carLon, carLat, poiLon, poiLat, (int) carAngle);
return diffAngle <= 90;
}
@Override
public void drawablePolyline() {
}
public LatLng CoordinateConverterFrom84(Context mContext, MogoLatLng mogoLatLng) {
CoordinateConverter mCoordinateConverter = new CoordinateConverter(mContext);
mCoordinateConverter.from(CoordinateConverter.CoordType.GPS);
mCoordinateConverter.coord(new LatLng(mogoLatLng.lat, mogoLatLng.lon));
return mCoordinateConverter.convert();
}
public List<LatLng> CoordinateConverterFrom84ForList(Context mContext, List<MogoLatLng> mogoLatLngList) {
List<LatLng> list = new ArrayList<>();
for (MogoLatLng m : mogoLatLngList) {
LatLng mogoLatLng = CoordinateConverterFrom84(mContext, m);
list.add(mogoLatLng);
}
return list;
}
@Override
public void clearPolyline() {
if (mPolyline != null) {
mPolyline.remove();
}
}
public void resetPolyLine() {
mCoordinatesLatLng.clear();
if (mPolyline != null) {
mPolyline.remove();
}
}
public void onCreateView(Bundle savedInstanceState) {
if (mAMapNaviView != null) {
mAMapNaviView.onCreate(savedInstanceState);
}
}
public void onResume() {
if (mAMapNaviView != null) {
mAMapNaviView.onResume();
}
}
public void onPause() {
if (mAMapNaviView != null) {
mAMapNaviView.onPause();
}
}
public void onDestroy() {
if (mAMapNaviView != null) {
mAMapNaviView.onDestroy();
}
//since 1.6.0 不再在naviview destroy的时候自动执行AMapNavi.stopNavi();请自行执行
if (mAMapNavi != null) {
mAMapNavi.stopNavi();
mAMapNavi.destroy();
}
if (mAMapNaviView != null) {
mAMapNaviView.onDestroy();
}
}
public void convert(List<MogoLatLng> coordinates) {
}
//多路径算路成功回调
@Override
public void onCalculateRouteSuccess(int[] ints) {
Log.d(TAG, "onCalculateRouteSuccess int");
}
@Override
public void onInitNaviFailure() {
calculate = false;
Log.d(TAG, "onInitNaviFailure");
}
@Override
public void onInitNaviSuccess() {
Log.d(TAG, "onInitNaviSuccess");
}
@Override
public void onStartNavi(int i) {
Log.d(TAG, "onStartNavi");
}
@Override
public void onTrafficStatusUpdate() {
}
@Override
public void onLocationChange(AMapNaviLocation aMapNaviLocation) {
// Log.d(TAG, "高德地图经纬度:" + aMapNaviLocation.getCoord().getLongitude() + "," + aMapNaviLocation.getCoord().getLatitude());
}
@Override
public void onGetNavigationText(int i, String s) {
Log.d(TAG, "onGetNavigationText int");
}
@Override
public void onGetNavigationText(String s) {
Log.d(TAG, "onGetNavigationText ss");
}
@Override
public void onEndEmulatorNavi() {
Log.d(TAG, "onEndEmulatorNavi");
}
@Override
public void onArriveDestination() {
Log.d(TAG, "onArriveDestination");
}
@Override
public void onCalculateRouteFailure(int i) {
Log.d(TAG, "onCalculateRouteFailure");
}
@Override
public void onReCalculateRouteForYaw() {
Log.d(TAG, "onReCalculateRouteForYaw");
}
@Override
public void onReCalculateRouteForTrafficJam() {
Log.d(TAG, "onReCalculateRouteForTrafficJam");
}
@Override
public void onArrivedWayPoint(int i) {
Log.d(TAG, "onArrivedWayPoint");
}
@Override
public void onGpsOpenStatus(boolean b) {
Log.d(TAG, "onGpsOpenStatus");
}
@Override
public void onNaviInfoUpdate(NaviInfo naviInfo) {
Log.d(TAG, "onNaviInfoUpdate");
}
@Override
public void onNaviInfoUpdated(AMapNaviInfo aMapNaviInfo) {
Log.d(TAG, "onNaviInfoUpdated");
}
@Override
public void updateCameraInfo(AMapNaviCameraInfo[] aMapNaviCameraInfos) {
Log.d(TAG, "updateCameraInfo");
}
@Override
public void updateIntervalCameraInfo(AMapNaviCameraInfo aMapNaviCameraInfo, AMapNaviCameraInfo aMapNaviCameraInfo1, int i) {
Log.d(TAG, "updateIntervalCameraInfo");
}
@Override
public void onServiceAreaUpdate(AMapServiceAreaInfo[] aMapServiceAreaInfos) {
Log.d(TAG, "onServiceAreaUpdate");
}
@Override
public void showCross(AMapNaviCross aMapNaviCross) {
Log.d(TAG, "showCross");
}
@Override
public void hideCross() {
Log.d(TAG, "hideCross");
}
@Override
public void showModeCross(AMapModelCross aMapModelCross) {
Log.d(TAG, "showModeCross");
}
@Override
public void hideModeCross() {
Log.d(TAG, "hideModeCross");
}
@Override
public void showLaneInfo(AMapLaneInfo[] aMapLaneInfos, byte[] bytes, byte[] bytes1) {
Log.d(TAG, "showLaneInfo");
}
@Override
public void showLaneInfo(AMapLaneInfo aMapLaneInfo) {
Log.d(TAG, "showLaneInfo");
}
@Override
public void hideLaneInfo() {
Log.d(TAG, "hideLaneInfo");
}
@Override
public void notifyParallelRoad(int i) {
}
@Override
public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos) {
}
@Override
public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) {
}
@Override
public void OnUpdateTrafficFacility(TrafficFacilityInfo trafficFacilityInfo) {
}
@Override
public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) {
}
@Override
public void updateAimlessModeCongestionInfo(AimLessModeCongestionInfo aimLessModeCongestionInfo) {
}
@Override
public void onPlayRing(int i) {
}
//算路详情
@Override
public void onCalculateRouteSuccess(AMapCalcRouteResult aMapCalcRouteResult) {
Log.d(TAG, "onCalculateRouteSuccess aMapCalcRouteResult" + aMapCalcRouteResult.toString());
//提测修改为EMULATOR
mAMapNavi.startNavi(NaviType.GPS);
UiThreadHandler.postDelayed(() -> {
mAMapNaviView.displayOverview();
}, 2000);
//停止导航测试代码
// UiThreadHandler.postDelayed(() -> {
// mAMapNavi.stopNavi();
// Log.d(TAG, "stop------------");
// }, 20000);
}
@Override
public void onCalculateRouteFailure(AMapCalcRouteResult aMapCalcRouteResult) {
Log.d(TAG, "onCalculateRouteFailure");
}
@Override
public void onNaviRouteNotify(AMapNaviRouteNotifyData aMapNaviRouteNotifyData) {
Log.d(TAG, "onNaviRouteNotify");
}
@Override
public void onNaviSetting() {
}
@Override
public void onNaviCancel() {
}
@Override
public boolean onNaviBackClick() {
return false;
}
@Override
public void onNaviMapMode(int i) {
}
@Override
public void onNaviTurnClick() {
}
@Override
public void onNextRoadClick() {
}
@Override
public void onScanViewButtonClick() {
}
@Override
public void onLockMap(boolean b) {
}
@Override
public void onNaviViewLoaded() {
Log.d(TAG, "---onNaviViewLoaded---");
CustomMapStyleOptions customMapStyleOptions = new CustomMapStyleOptions();
// 加载自定义样式
customMapStyleOptions.setEnable(true);
if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) {
customMapStyleOptions.setStyleData(MapAssetStyleUtils.getAssetsStyle(getContext(), "over_view_style.data"));
customMapStyleOptions.setStyleExtraData(MapAssetStyleUtils.getAssetsExtraStyle(getContext(), "over_view_style_extra.data"));
} else {
customMapStyleOptions.setStyleData(MapAssetStyleUtils.getAssetsStyle(getContext(), "over_view_style_bus.data"));
customMapStyleOptions.setStyleExtraData(MapAssetStyleUtils.getAssetsExtraStyle(getContext(), "over_view_style_extra_bus.data"));
}
// 设置自定义样式
mAMap.setCustomMapStyle(customMapStyleOptions);
// 实时路况图层关闭必须添加在loaded结束之后,其他位置不生效
mAMap.setTrafficEnabled(false);
}
@Override
public void onMapTypeChanged(int i) {
}
@Override
public void onNaviViewShowMode(int i) {
}
private void drawInfrastructureMarkers(MessagePad.GlobalPathResp globalPathResp) {
if (globalPathResp != null) {
if (!pathMap.isEmpty()) {
pathMap.clear();
}
String geoHash;
ArrayList<Infrastructure> infList;
for (MessagePad.Location location : globalPathResp.getWayPointsList()) {
geoHash = GeoHash.withCharacterPrecision(location.getLatitude(), location.getLongitude(), 7).toBase32();
// 网格内的轨迹点只取一次
if (!pathMap.containsKey(geoHash)) {
// 从缓存的新基建数据中去取对应geoHash的新基建数据集合
infList = InfStructureManager.INSTANCE.getData().get(geoHash);
if (infList != null) {
pathMap.put(geoHash, infList);
}
}
}
drawInfMarkers(pathMap);
}
}
public void drawInfMarkers(Map<String, ArrayList<Infrastructure>> infStruMap) {
// 绘制新基建数据
if (!posInfMap.isEmpty()) {
posInfMap.clear();
}
ArrayList<MarkerOptions> markerOptionsList = new ArrayList();
for (ArrayList<Infrastructure> structureList : infStruMap.values()) {
int firstQuadrantCt = 0, secondQuadrantCt = 0, thirdQuadrantCt = 0, forthQuadrantCt = 0;
// 每个GeoHash内根据坐标系象限分散开摄像头icon显示
for (Infrastructure structure : structureList) {
MarkerOptions markerOption = new MarkerOptions();
LatLng latLng = new LatLng(Double.valueOf(structure.getLat()),
Double.valueOf(structure.getLon()));
markerOption.position(latLng);
if (structure.getHeading() >= 0 && structure.getHeading() <= 90) {
markerOption.anchor(0.5f * firstQuadrantCt, 0.5f + 0.5f * firstQuadrantCt);
markerOption.icon(BitmapDescriptorFactory.fromBitmap(
BitmapFactory.decodeResource(getResources(),R.drawable.video_icon_right)
));
firstQuadrantCt++;
} else if (structure.getHeading() >= 90 && structure.getHeading() <= 180) {
markerOption.anchor(0.5f * secondQuadrantCt, 0.5f * secondQuadrantCt);
markerOption.icon(BitmapDescriptorFactory.fromBitmap(
BitmapFactory.decodeResource(getResources(),R.drawable.video_icon_right)
));
secondQuadrantCt++;
} else if (structure.getHeading() >= 180 && structure.getHeading() <= 270) {
markerOption.anchor(0.5f + 0.5f * thirdQuadrantCt, 0.5f * thirdQuadrantCt);
markerOption.icon(BitmapDescriptorFactory.fromBitmap(
BitmapFactory.decodeResource(getResources(),R.drawable.video_icon_left)
));
thirdQuadrantCt++;
} else {
markerOption.anchor(0.75f + 0.25f * forthQuadrantCt, 0.75f + 0.25f * forthQuadrantCt);
markerOption.icon(BitmapDescriptorFactory.fromBitmap(
BitmapFactory.decodeResource(getResources(),R.drawable.video_icon_left)
));
forthQuadrantCt++;
}
posInfMap.put(latLng, structure);
markerOptionsList.add(markerOption);
}
}
mAMap.addMarkers(markerOptionsList, false);
mAMap.setOnMarkerClickListener(marker -> {
Infrastructure infrastructure = posInfMap.get(marker.getPosition());
// 如果是摄像头
if (0 == infrastructure.getCategory() && infrastructure.getIp() != null) {
CallerHmiManager.INSTANCE.showVideoDialog(infrastructure.getIp());
return true;
}
return false;
});
}
}

View File

@@ -0,0 +1,291 @@
package com.mogo.eagle.core.function.smp;
import android.content.Context;
import android.graphics.BitmapFactory;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.TextureMapView;
import com.amap.api.maps.model.BitmapDescriptor;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.Polyline;
import com.amap.api.navi.AMapNaviView;
import com.autonavi.amap.mapcore.IPoint;
import com.mogo.eagle.core.function.map.R;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 包名: com.amap.api.navi.core
* <p>
* 创建时间2018/3/1
* 项目名称AndroidNavigationSDK
*
* @author guibao.ggb
* @email guibao.ggb@alibaba-inc.com
* <p>
* 类说明自车位置管理Overlay类
*/
public class CarOverlay {
protected static final int CAR_MOVE_ANIMATION_PERIOD = 50;
protected int carMoveAnimationFrameNum = 2;
protected boolean mIsLock = true;
protected IPoint mapAnchorBackup = null;
protected double dXOffStep;
protected double dYOffStep;
protected float dAngleOffStep;
protected int currentFrameIndex;
protected float angleStart = 0;
protected boolean isMoveStarted = false;
protected float newAngle = 0;
protected BitmapDescriptor carDescriptor = null;
protected BitmapDescriptor fourCornersDescriptor = null;
protected Marker carMarker;
protected Marker directionMarker;
protected AMap mAmap = null;
protected TextureMapView mapView;
protected boolean isDirectionVisible = true;
protected LatLng endLatLng = null;
protected Polyline leaderLine = null;
protected final int DISTANCE_OFFSET = 150;// 默认 500 偏差
// API 默认 1800 UI 默认 360
protected int angleModValue = 1800;
private ScheduledExecutorService executorService;
public CarOverlay(Context context, TextureMapView mapView) {
this.mapView = mapView;
// fourCornersDescriptor = BitmapDescriptorFactory.fromBitmap(BitmapFactory
// .decodeResource(context.getResources(),
// R.drawable.module_small_map_navi_direction));
carDescriptor = BitmapDescriptorFactory.fromBitmap(BitmapFactory
.decodeResource(context.getResources(),
R.drawable.module_small_map_view_my_location_logo));
angleModValue = 1800;
}
/**
* 设置自车状态
*
* @param lock true 锁车 false 非锁车
*/
public void setLock(boolean lock) {
mIsLock = lock;
if (carMarker == null) {
return;
}
if (mAmap == null) {
return;
}
if (directionMarker == null) {
return;
}
carMarker.setFlat(true);
directionMarker.setGeoPoint(carMarker.getGeoPoint());
carMarker.setGeoPoint(carMarker.getGeoPoint());
carMarker.setRotateAngle(carMarker.getRotateAngle());
if (mIsLock) {
CameraPosition cameraPosition = new CameraPosition.Builder().target(carMarker.getPosition()).bearing(newAngle).tilt(0).zoom(16).build();
mAmap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
}
public void reset() {
if (carMarker != null) {
carMarker.remove();
}
if (directionMarker != null) {
directionMarker.remove();
}
if (leaderLine != null) {
leaderLine.remove();
}
leaderLine = null;
carMarker = null;
directionMarker = null;
if (executorService != null) {
if (!executorService.isShutdown()) {
executorService.shutdown();
}
isMoveStarted = false;
executorService = null;
}
}
/**
* 绘制自车
*
* @param aMap
* @param mLatLng
* @param bearing
*/
public void draw(AMap aMap, LatLng mLatLng, float bearing) {
if (aMap == null || mLatLng == null || carDescriptor == null) {
return;
}
mAmap = aMap;
try {
if (carMarker == null) {
carMarker = aMap.addMarker(new MarkerOptions().anchor(0.5f, 0.5f).setFlat(true).icon(carDescriptor).position(mLatLng));
}
if (directionMarker == null) {
directionMarker = aMap.addMarker(new MarkerOptions().anchor(0.5f, 0.5f).setFlat(true).icon(fourCornersDescriptor).position(mLatLng));
if (isDirectionVisible) {
directionMarker.setVisible(true);
} else {
directionMarker.setVisible(false);
}
}
carMarker.setVisible(true);
newAngle = bearing;
IPoint resultGeoPnt = IPoint.obtain();
// resultGeoPnt = NaviUtil.lonlat2Geo(mLatLng.latitude, mLatLng.longitude, 20);
updateCarPosition(resultGeoPnt);
resultGeoPnt.recycle();
} catch (Throwable e) {
e.printStackTrace();
}
}
private void updateCarPosition(IPoint p) {
carMarker.setGeoPoint(p);
carMarker.setFlat(true);
carMarker.setRotateAngle(360 - newAngle);
if (directionMarker != null) {
directionMarker.setGeoPoint(p);
}
if (mIsLock) {
CameraPosition cameraPosition = new CameraPosition.Builder().target(carMarker.getPosition()).bearing(newAngle).tilt(0).zoom(16).build();
mAmap.moveCamera(CameraUpdateFactory.changeBearingGeoCenter(newAngle, p));
}
}
public void setEndPoi(LatLng latlng) {
endLatLng = latlng;
}
/**
* 释放自车资源
*/
public void destroy() {
if (carMarker != null) {
carMarker.remove();
carMarker = null;
}
if (directionMarker != null) {
directionMarker.remove();
directionMarker = null;
}
carDescriptor = null;
if (executorService != null && !executorService.isShutdown()) {
executorService.shutdown();
isMoveStarted = false;
executorService = null;
}
}
private void calculateCarSmoothMoveOffset(IPoint newCenter, float newAngle) {
if (carMarker == null) {
return;
}
IPoint currentAnchorGeoPoint = carMarker.getGeoPoint();
if (currentAnchorGeoPoint == null || currentAnchorGeoPoint.x == 0 || currentAnchorGeoPoint.y == 0) {
currentAnchorGeoPoint = newCenter;
}
currentFrameIndex = 0;
mapAnchorBackup = currentAnchorGeoPoint;
dXOffStep = (newCenter.x - currentAnchorGeoPoint.x) / carMoveAnimationFrameNum;
dYOffStep = (newCenter.y - currentAnchorGeoPoint.y) / carMoveAnimationFrameNum;
// 获取当前的旋转角度
angleStart = carMarker.getRotateAngle();
boolean isFirst = false;
if (Float.compare(angleStart, newAngle) == 0) {
isFirst = true;
} else {
angleStart = 360 - angleStart;
}
// 校正旋转角度问题
float dAngleDelta = newAngle - angleStart;
if (isFirst) {
dAngleDelta = 0;
}
if (dAngleDelta > 180) {
dAngleDelta = dAngleDelta - 360;
}
else if (dAngleDelta < -180) {
dAngleDelta = dAngleDelta + 360;
}
dAngleOffStep = dAngleDelta / carMoveAnimationFrameNum;
isMoveStarted = true;
}
// protected void startSmoothMoveTimer() {
// if (executorService == null) {
// executorService = new ScheduledThreadPoolExecutor(1, new BasicThreadFactory.Builder().namingPattern("caroverlay-schedule-pool-%d").daemon(true).build());
//
// executorService.scheduleAtFixedRate(new Runnable() {
// long currentSeconds;
// @Override
// public void run() {
// try{
// currentSeconds = System.currentTimeMillis();
// mapSmoothMoveTimerTick();
// } catch(Throwable e){
// e.printStackTrace();
// }
// }
// }, 0, CAR_MOVE_ANIMATION_PERIOD, TimeUnit.MILLISECONDS);
// }
// }
private void mapSmoothMoveTimerTick() {
if (!isMoveStarted) {
return;
}
if (carMarker == null) {
return;
}
if (mAmap == null) {
return;
}
try {
IPoint p = carMarker.getGeoPoint();
double newX = 0, newY = 0;
if (currentFrameIndex++ < carMoveAnimationFrameNum) {
newX = mapAnchorBackup.x + dXOffStep * currentFrameIndex;
newY = mapAnchorBackup.y + dYOffStep * currentFrameIndex;
newAngle = angleStart + dAngleOffStep * currentFrameIndex;
newAngle %= angleModValue;
if (newX != 0 || newY != 0) {
p = new IPoint((int)newX, (int)newY);
}
updateCarPosition(p);
}
} catch (Throwable e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,121 @@
package com.mogo.eagle.core.function.smp;
import com.amap.api.maps.AMapUtils;
import com.amap.api.maps.model.LatLng;
import com.amap.api.navi.model.NaviLatLng;
import com.autonavi.amap.mapcore.IPoint;
import com.autonavi.amap.mapcore.MapProjection;
/**
* 包名: com.amap.navi.demo.util
* <p>
* 创建时间2018/4/19
* 项目名称NaviDemo
*
* @author guibao.ggb
* @email guibao.ggb@alibaba-inc.com
* <p>
* 类说明:
*/
public class NaviUtil {
public static float calculateDistance(NaviLatLng start, NaviLatLng end) {
double x1 = start.getLongitude();
double y1 = start.getLatitude();
double x2 = end.getLongitude();
double y2 = end.getLatitude();
return AMapUtils.calculateLineDistance(new LatLng(y1, x1), new LatLng(y2, x2));
}
public static NaviLatLng getPointForDis(NaviLatLng sPt, NaviLatLng ePt, double dis) {
double lSegLength = calculateDistance(sPt, ePt);
NaviLatLng pt = new NaviLatLng();
double preResult = dis / lSegLength;
pt.setLatitude(((ePt.getLatitude() - sPt.getLatitude()) * preResult + sPt.getLatitude()));
pt.setLongitude(((ePt.getLongitude() - sPt.getLongitude()) * preResult + sPt.getLongitude()));
return pt;
}
/**
* 根据经纬度计算需要偏转的角度
*
* @param startPoi
* @param secondPoi
* @return
*/
public static float getRotate(NaviLatLng startPoi, NaviLatLng secondPoi) {
float rotate = 0;
try {
IPoint point1 = new IPoint();
IPoint point2 = new IPoint();
MapProjection.lonlat2Geo(startPoi.getLongitude(), startPoi.getLatitude(), point1);
MapProjection.lonlat2Geo(secondPoi.getLongitude(), secondPoi.getLatitude(), point2);
double x1 = point1.x;
double x2 = point2.x;
double y1 = point1.y;
double y2 = point2.y;
rotate = (float) (Math.atan2(y2 - y1, x2 - x1) / Math.PI * 180);
rotate = rotate + 90;
return rotate;
} catch (Exception e) {
e.printStackTrace();
}
return rotate;
}
public static final int MAXZOOMLEVEL = 20;
public static final int PIXELSPERTILE = 256;
public static final double MINLATITUDE = -85.0511287798;
public static final double MAXLATITUDE = 85.0511287798;
public static final double MINLONGITUDE = -180;
public static final double MAXLONGITUDE = 180;
public static final int EARTHRADIUSINMETERS = 6378137;
public static final int TILESPLITLEVEL = 0;
public static final double EarthCircumferenceInMeters = 2 * Math.PI
* EARTHRADIUSINMETERS;
public static double clip(double n, double minValue, double maxValue) {
return Math.min(Math.max(n, minValue), maxValue);
}
public static IPoint lonlat2Geo(double latitude, double longitude,
int levelOfDetail) {
IPoint rPnt = new IPoint();
latitude = clip(latitude, MINLATITUDE, MAXLATITUDE) * Math.PI / 180;
longitude = clip(longitude, MINLONGITUDE, MAXLONGITUDE) * Math.PI / 180;
double sinLatitude = Math.sin(latitude);
double xMeters = EARTHRADIUSINMETERS * longitude;
double lLog = Math.log((1 + sinLatitude) / (1 - sinLatitude));
double yMeters = EARTHRADIUSINMETERS / 2 * lLog;
long numPixels = (long) PIXELSPERTILE << levelOfDetail;
double metersPerPixel = EarthCircumferenceInMeters / numPixels;
rPnt.x = (int) clip((EarthCircumferenceInMeters / 2 + xMeters)
/ metersPerPixel + 0.5, 0, numPixels - 1);
long tmp = (long) (EarthCircumferenceInMeters / 2 - yMeters);
rPnt.y = (int) clip((double) tmp / metersPerPixel + 0.5, 0,
numPixels - 1);
return rPnt;
}
public static String formatKM(int d) {
if (d == 0) {
return "0米";
} else if (d < 100) {
return d + "";
} else if ((100 <= d) && (d < 1000)) {
return d + "";
} else if ((1000 <= d) && (d < 10000)) {
return (d / 10) * 10 / 1000.0D + "公里";
} else if ((10000 <= d) && (d < 100000)) {
return (d / 100) * 100 / 1000.0D + "公里";
}
return (d / 1000) + "公里";
}
}

View File

@@ -0,0 +1,199 @@
package com.mogo.eagle.core.function.smp;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.commons.mvp.BaseFragment;
import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo;
import com.mogo.eagle.core.data.constants.MoGoFragmentPaths;
import com.mogo.eagle.core.data.map.MogoLatLng;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotPlanningListener;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
import com.mogo.eagle.core.function.api.map.smp.IMogoSmallMapProvider;
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotPlanningListenerManager;
import com.mogo.eagle.core.function.map.R;
import com.mogo.eagle.core.function.overview.InfStructureManager;
import com.mogo.eagle.core.function.overview.Infrastructure;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import mogo.telematics.pad.MessagePad;
import mogo_msg.MogoReportMsg;
import system_master.SystemStatusInfo;
/**
* @author donghongyu
* @date 2021/5/19 10:50 上午
* 全览模式Fragment
*/
@Route(path = MoGoFragmentPaths.PATH_FRAGMENT_OVERVIEW)
public class OverviewMapFragment extends BaseFragment
implements IMogoSmallMapProvider, IMoGoAutopilotPlanningListener,
IMoGoAutopilotStatusListener {
private final String TAG = "SmallMapFragment";
protected AMapCustomView mAMapCustomView;
@Override
public void onAttach(Context context) {
super.onAttach(context);
}
@Override
protected int getLayoutId() {
return R.layout.module_overview_map_fragment;
}
@Override
public String getTagName() {
return TAG;
}
@Override
protected void initViews() {
}
@Override
protected void initViews(Bundle savedInstanceState) {
super.initViews(savedInstanceState);
mAMapCustomView = mRootView.findViewById(R.id.smallMapDirectionView);
mAMapCustomView.onCreateView(savedInstanceState);
CallerAutopilotPlanningListenerManager.INSTANCE.addListener(TAG, this);
}
@Override
public void showPanel() {
if (mAMapCustomView != null) {
mAMapCustomView.setVisibility(View.VISIBLE);
}
}
@Override
public void hidePanel() {
if (mAMapCustomView != null) {
mAMapCustomView.setVisibility(View.GONE);
}
}
@Override
public void drawablePolyline(List<MogoLatLng> coordinates) {
if (mAMapCustomView != null) {
mAMapCustomView.convert(coordinates);
UiThreadHandler.post(() -> mAMapCustomView.drawablePolyline());
}
}
@Override
public void clearPolyline() {
if (mAMapCustomView != null) {
UiThreadHandler.post(() -> mAMapCustomView.clearPolyline());
}
}
@Override
public void onResume() {
super.onResume();
if (mAMapCustomView != null) {
mAMapCustomView.onResume();
}
Map<String, ArrayList<Infrastructure>> map = InfStructureManager.INSTANCE.getPathData();
if (!map.isEmpty()) {
mAMapCustomView.drawInfMarkers(map);
}
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// queryInfStructure();
}
// private void queryInfStructure() {
// mViewModel = ViewModelExtKt.obtainViewModel(this, OverViewModel.class);
// mViewModel.getInfStructuresMap().observe(this.getViewLifecycleOwner(), map -> {
// mAMapCustomView.updateInfStructures(map);
// });
// // 本地数据库查询
// mViewModel.fetchInfStructures();
// }
@Override
public void onPause() {
super.onPause();
if (mAMapCustomView != null) {
mAMapCustomView.onPause();
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mAMapCustomView != null) {
mAMapCustomView.onDestroy();
}
CallerAutopilotPlanningListenerManager.INSTANCE.removeListener(TAG);
}
@Override
public void onAutopilotTrajectory(List<MessagePad.TrajectoryPoint> trajectoryInfos) {
}
@Override
public void onAutopilotStatusResponse(@NotNull AutopilotStatusInfo autoPilotStatusInfo) {
if (autoPilotStatusInfo.getPilotmode() != 1) {
clearPolyline();
}
}
@Override
public void onAutopilotArriveAtStation(MessagePad.ArrivalNotification arrivalNotification) {
}
@Override
public void onAutopilotSNRequest() {
}
@Override
public void onAutopilotGuardian(MogoReportMsg.MogoReportMessage guardianInfo) {
}
@Override
public void onAutopilotIpcConnectStatusChanged(int status, @Nullable String reason) {
}
@Override
public void onAutopilotRotting(MessagePad.GlobalPathResp globalPathResp) {
if (globalPathResp == null || globalPathResp.getWayPointsList().size() == 0) {
return;
}
List<MogoLatLng> latLngList = new ArrayList<>();
for (MessagePad.Location routeModel : globalPathResp.getWayPointsList()) {
latLngList.add(new MogoLatLng(routeModel.getLatitude(), routeModel.getLongitude()));
}
if (latLngList.size() > 0) {
drawablePolyline(latLngList);
} else {
clearPolyline();
}
}
@Override
public void onAutopilotStatusRespByQuery(@NonNull SystemStatusInfo.StatusInfo status) {
}
}

View File

@@ -33,11 +33,11 @@ import com.mogo.cloud.commons.utils.CoordinateUtils;
import com.mogo.eagle.core.data.map.MogoLatLng;
import com.mogo.eagle.core.data.map.MogoLocation;
import com.mogo.eagle.core.function.api.map.listener.IMoGoMapLocationListener;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager;
import com.mogo.eagle.core.function.map.R;
import com.mogo.eagle.core.utilcode.mogo.MapAssetStyleUtils;
import com.mogo.eagle.core.function.smp.view.ISmallMapDirectionView;
import com.mogo.eagle.core.utilcode.mogo.MapAssetStyleUtils;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.widget.RoundLayout;
import com.mogo.module.common.utils.DrivingDirectionUtils;
@@ -129,8 +129,8 @@ public class SmallMapDirectionView
// 加载自定义样式
CustomMapStyleOptions customMapStyleOptions = new CustomMapStyleOptions()
.setEnable(true)
.setStyleData(MapAssetStyleUtils.getAssetsStyle(getContext()))
.setStyleExtraData(MapAssetStyleUtils.getAssetsExtraStyle(getContext()));
.setStyleData(MapAssetStyleUtils.getAssetsStyle(getContext(), "small_map_style.data"))
.setStyleExtraData(MapAssetStyleUtils.getAssetsExtraStyle(getContext(), "small_map_style_extra.data"));
// 设置自定义样式
mAMap.setCustomMapStyle(customMapStyleOptions);
//设置希望展示的地图缩放级别
@@ -146,8 +146,8 @@ public class SmallMapDirectionView
// 加载自定义样式
CustomMapStyleOptions customMapStyleOptions1 = new CustomMapStyleOptions()
.setEnable(true)
.setStyleData(MapAssetStyleUtils.getAssetsStyle(getContext()))
.setStyleExtraData(MapAssetStyleUtils.getAssetsExtraStyle(getContext()));
.setStyleData(MapAssetStyleUtils.getAssetsStyle(getContext(), "small_map_style.data"))
.setStyleExtraData(MapAssetStyleUtils.getAssetsExtraStyle(getContext(), "small_map_style_extra.data"));
// 设置自定义样式
mAMap.setCustomMapStyle(customMapStyleOptions1);
mAMapNaviView.getMap().setPointToCenter(mAMapNaviView.getWidth() / 2, mAMapNaviView.getHeight() / 2);

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
>
<alpha
android:duration="1000"
android:fromAlpha="1.0"
android:toAlpha="0"
/>
</set>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
>
<alpha
android:duration="1000"
android:fromAlpha="0"
android:toAlpha="1.0"
/>
</set>

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -1,12 +1,13 @@
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
>
<com.mogo.map.MogoMapView
android:id="@+id/module_map_id_map"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent"
android:visibility="visible"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,14 @@
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mogo.eagle.core.function.smp.AMapCustomView
android:id="@+id/smallMapDirectionView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,46 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:parentTag="RelativeLayout">
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true" />
<RelativeLayout
android:id="@+id/rlSmallMapBorder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true">
<com.amap.api.navi.AMapNaviView
android:id="@+id/aMapNaviView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/overLayer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:background="@color/blue"
android:text="全览模式"
android:textColor="@drawable/white"
android:textSize="@dimen/dp_34" />
</RelativeLayout>
<ImageView
android:id="@+id/ivMapBorder"
android:layout_width="@dimen/module_small_map_border_view_width"
android:layout_height="@dimen/module_small_map_border_view_width"
android:layout_centerInParent="true"
android:src="@drawable/module_small_map_view_border_north"
android:visibility="gone" />
</merge>

View File

@@ -13,6 +13,7 @@ import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_MONITOR
import com.mogo.map.MogoLocationClient
import com.mogo.module.common.constants.HostConst
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
@@ -32,6 +33,7 @@ class CronTaskManager(private var context: Context?) {
// 开启路侧摄像头推流
private var streamDisposable: Disposable? = null
private var streamDisposable2: Disposable? = null
private var cameraList: List<CameraEntity>? = null
private var carCameraList: List<CameraEntity>? = null
@@ -209,6 +211,48 @@ class CronTaskManager(private var context: Context?) {
})
}
/**
* 供全览模式摄像头业务使用
*/
fun reqOpenCameraStream(cameraIp: String, success: (String) -> Unit, error: (Throwable) -> Unit) {
streamDisposable2?.let {
if (!it.isDisposed) it.dispose()
}
streamDisposable2 = MoGoRetrofitFactory.getInstance(HostConst.CITY_HOST)
.create(CameraListServices::class.java)
.reqOpenCameraStreamWithRetry(cameraIp)
.flatMap {
if (it.code != 200 && it.code != 0) {
Observable.error(Throwable(it.msg))
} else {
Observable.just(it)
}
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.retryWhen(RetryWithDelay())
.subscribe({
CallerLogger.d("$M_MONITOR$TAG", "reqOpenCameraStream返回结果为$it")
if (it.code == 200 || it.code == 0) {
val flvString = it.flvUrl
if (!flvString.isNullOrEmpty()) {
success(flvString)
} else {
error(Throwable("flvUrl为空"))
}
} else {
error(Throwable(it.msg))
}
}, {
CallerLogger.e(
"$M_MONITOR$TAG",
"reqOpenCameraStream&message is:${it.message}, cause is:${it.cause}"
)
error(it)
it.printStackTrace()
})
}
fun startCronTask() {
cronHandler.sendEmptyMessageDelayed(CRON_TASK_TYPE, 0)
}
@@ -231,6 +275,9 @@ class CronTaskManager(private var context: Context?) {
streamDisposable?.let {
if (!it.isDisposed) it.dispose()
}
streamDisposable2?.let {
if (!it.isDisposed) it.dispose()
}
cronHandler.removeMessages(CRON_TASK_TYPE)
}
}

View File

@@ -1,58 +0,0 @@
package com.mogo.eagle.core.function.monitoring;
import android.content.Context;
import androidx.annotation.NonNull;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.eagle.core.data.camera.CameraEntity;
import com.mogo.eagle.core.data.constants.MogoServicePaths;
import com.mogo.eagle.core.function.api.monitoring.IMoGoMonitoringProvider;
import java.util.List;
/**
* @author xiaoyuzhou
* @date 2021/10/29 11:09 上午
*/
@Route(path = MogoServicePaths.PATH_AI_MONITORING)
public class MoGoMonitoringProvider implements IMoGoMonitoringProvider {
public String TAG = "MoGoMonitoringProvider";
private CronTaskManager mCronTaskManager;
@NonNull
@Override
public String getFunctionName() {
return TAG;
}
@Override
public void init(Context context) {
mCronTaskManager = new CronTaskManager(context);
mCronTaskManager.startCronTask();
}
@Override
public List<CameraEntity> getCameraList() {
return mCronTaskManager.getCameraList();
}
@Override
public void openCameraStream(String cameraIp) {
// 现在不用华哥接口,改用卫明的打开视频推流接口
// mCronTaskManager.requestOpenCamera(cameraIp);
mCronTaskManager.reqOpenCameraStream(cameraIp);
}
@Override
public void disposeCameraStream() {
mCronTaskManager.clear();
}
@Override
public void onDestroy() {
mCronTaskManager.onDestroy();
}
}

View File

@@ -0,0 +1,42 @@
package com.mogo.eagle.core.function.monitoring
import android.content.Context
import com.alibaba.android.arouter.facade.annotation.Route
import com.mogo.eagle.core.data.constants.MogoServicePaths
import com.mogo.eagle.core.function.api.monitoring.IMoGoMonitoringProvider
import com.mogo.eagle.core.data.camera.CameraEntity
/**
* @author xiaoyuzhou
* @date 2021/10/29 11:09 上午
*/
@Route(path = MogoServicePaths.PATH_AI_MONITORING)
class MoGoMonitoringProvider : IMoGoMonitoringProvider {
override var functionName = "MoGoMonitoringProvider"
private var mCronTaskManager: CronTaskManager? = null
override fun init(context: Context) {
mCronTaskManager = CronTaskManager(context)
mCronTaskManager!!.startCronTask()
}
override val cameraList: List<CameraEntity>
get() = mCronTaskManager!!.getCameraList()
override fun openCameraStream(cameraIp: String) {
// 现在不用华哥接口,改用卫明的打开视频推流接口
// mCronTaskManager.requestOpenCamera(cameraIp);
mCronTaskManager!!.reqOpenCameraStream(cameraIp)
}
override fun openCameraStream(cameraIp: String, success: (String) -> Unit, error: (Throwable) -> Unit) {
mCronTaskManager!!.reqOpenCameraStream(cameraIp, success, error)
}
override fun disposeCameraStream() {
mCronTaskManager!!.clear()
}
override fun onDestroy() {
mCronTaskManager!!.onDestroy()
}
}

View File

@@ -0,0 +1,25 @@
package com.mogo.eagle.core.function.monitoring;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.functions.Function;
public class RetryWithDelay implements Function<Observable<? extends Throwable>, Observable<?>> {
private final int maxRetries = 3;
private final int retryDelayMillis = 5000;
// 计数器
private int retryCount = 0;
@Override
public Observable<?> apply(Observable<? extends Throwable> observable) throws Exception {
return observable.flatMap((Function<Throwable, ObservableSource<?>>) throwable -> {
if (++retryCount <= maxRetries) {
return Observable.timer(retryDelayMillis, TimeUnit.MILLISECONDS);
}
return Observable.error(throwable);
});
}
}

View File

@@ -1,6 +1,7 @@
package com.mogo.eagle.core.function.monitoring.net
import com.mogo.eagle.core.data.camera.*
import io.reactivex.Observable
import io.reactivex.Single
import retrofit2.http.*
@@ -22,4 +23,7 @@ interface CameraListServices {
@Query("lon") lon: Double, @Query("lat") lat: Double,
@Query("radiusMeter") radiusMeter: Int
): Single<CameraListInfo?>
@GET("/camera-stream/stream/camera/openStream")
fun reqOpenCameraStreamWithRetry(@Query("ip") cameraIp: String): Observable<OpenCameraStreamEntity>
}

View File

@@ -104,6 +104,7 @@ object V2XEventManager : IMoGoMapLocationListener, IMoGoTokenCallback, IV2XCallb
V2XManager.init(V2XConfig.Builder().also {
it.aiCloudConfig(MoGoAiCloudClientConfig.getInstance())
it.context(context)
it.loggable(false)
it.distanceForTriggerRefresh(200f) //行驶超过200包含刷新道路周边信息短链请求
it.durationForTriggerRefresh(
60,