[merge2master]
This commit is contained in:
@@ -0,0 +1 @@
|
||||
全局路径规划的GSON格式的轨迹点数据放这里,然后使用PlanningDataUtils工具类解析一下
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.mogo.eagle.core.function
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.mogo.commons.AbsMogoApplication
|
||||
import com.mogo.eagle.core.data.constants.MogoServicePaths
|
||||
import com.mogo.eagle.core.function.api.base.IMoGoFunctionServerProvider
|
||||
import com.mogo.eagle.core.function.business.MapPointCloudSubscriber
|
||||
import com.mogo.eagle.core.function.business.SpeedLimitDataManager
|
||||
import com.mogo.eagle.core.function.business.ai.AiCloudIdentifyDataManager.Companion.aiCloudIdentifyDataManager
|
||||
import com.mogo.eagle.core.function.business.identify.MapIdentifySubscriber
|
||||
import com.mogo.eagle.core.function.business.routeoverlay.MogoRouteOverlayManager
|
||||
|
||||
@Route(path = MogoServicePaths.PATH_MAP_BIZ)
|
||||
class MapBizProvider :IMoGoFunctionServerProvider{
|
||||
|
||||
override val functionName: String
|
||||
get() = "MapBizProvider"
|
||||
|
||||
override fun init(context: Context?) {
|
||||
MapIdentifySubscriber.instance
|
||||
MogoRouteOverlayManager.getInstance().init()
|
||||
MapPointCloudSubscriber.instance
|
||||
SpeedLimitDataManager.getInstance().start()
|
||||
aiCloudIdentifyDataManager.init(AbsMogoApplication.getApp())
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
package com.mogo.eagle.core.function.angle
|
||||
|
||||
import android.content.*
|
||||
import android.os.*
|
||||
import android.util.*
|
||||
import androidx.lifecycle.*
|
||||
import androidx.lifecycle.Lifecycle.Event
|
||||
import androidx.lifecycle.Lifecycle.Event.ON_DESTROY
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.mogo.eagle.core.data.config.*
|
||||
import com.mogo.eagle.core.data.constants.MogoServicePaths
|
||||
import com.mogo.eagle.core.data.map.*
|
||||
import com.mogo.eagle.core.data.map.MapRoadInfo.StopLine
|
||||
import com.mogo.eagle.core.function.api.map.angle.*
|
||||
import com.mogo.eagle.core.function.api.map.angle.Scene
|
||||
import com.mogo.eagle.core.function.call.autopilot.*
|
||||
import com.mogo.eagle.core.function.call.map.*
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapRoadListenerManager.OnRoadListener
|
||||
import com.mogo.eagle.core.utilcode.kotlin.*
|
||||
import com.mogo.eagle.core.utilcode.mogo.*
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.*
|
||||
import com.zhidaoauto.map.sdk.open.tools.*
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.android.*
|
||||
import java.util.*
|
||||
import java.util.concurrent.atomic.*
|
||||
|
||||
@Route(path = MogoServicePaths.PATH_VISUAL_ANGLE)
|
||||
class MoGoVisualAngleChangeProvider: IMoGoVisualAngleChangeProvider {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "VisualAngleChange"
|
||||
}
|
||||
|
||||
private val triggerLocation = AtomicReference<MogoLocation>()
|
||||
|
||||
private val distanceOfCarToStopLine = AtomicReference(0.0)
|
||||
|
||||
private val travelled by lazy { AtomicReference(0.0) }
|
||||
|
||||
/**
|
||||
* 业务实体,不对外暴露
|
||||
* @param target: 目标场景
|
||||
* @param isDisplay: 是否正在展示
|
||||
* @param triggerTime: 触发时间
|
||||
*/
|
||||
private data class Record(val target: Scene, var isDisplay: Boolean = false, var triggerTime: Long): Comparable<Record> {
|
||||
override fun compareTo(other: Record): Int {
|
||||
//如果时间一样,优先级越高,越靠近堆顶
|
||||
return other.target.priority - target.priority
|
||||
}
|
||||
}
|
||||
|
||||
private val queue by lazy {
|
||||
PriorityQueue<Record>()
|
||||
}
|
||||
|
||||
private val listener = object : OnRoadListener {
|
||||
private val roadId = AtomicReference<String>()
|
||||
private val triggerRoadId = AtomicReference<String>()
|
||||
|
||||
override fun onRoadIdInfo(roadId: String) {
|
||||
this.roadId.set(roadId)
|
||||
Log.d(TAG, "-- onRoadIdInfo --: prev: ${this.triggerRoadId.get()} -> curr: $roadId")
|
||||
val loc = CallerChassisLocationGCJ02ListenerManager.getChassisLocationGCJ02()
|
||||
var triggerClose = false
|
||||
val distance = distanceOfCarToStopLine.get() + 5
|
||||
if (hasCrossRoad && distance > 0) {
|
||||
val prev = triggerLocation.get()
|
||||
if (prev != null && loc != null) {
|
||||
travelled.set(MapTools.distance(loc.longitude, loc.latitude, prev.longitude, prev.latitude) + travelled.get())
|
||||
triggerLocation.set(loc)
|
||||
}
|
||||
val oldRoadId = triggerRoadId.get()
|
||||
Log.d(TAG, "-- onRoadIdInfo --: travelled --: ${travelled.get()}")
|
||||
if ((travelled.get() > distance) && oldRoadId != null && oldRoadId != roadId) {
|
||||
distanceOfCarToStopLine.set(0.0)
|
||||
hasCrossRoad = false
|
||||
triggerRoadId.set(null)
|
||||
travelled.set(0.0)
|
||||
triggerLocation.set(null)
|
||||
Log.d(TAG, "-- onRoadIdInfo --: trigger close --")
|
||||
triggerClose = true
|
||||
}
|
||||
}
|
||||
if (triggerClose) {
|
||||
changeAngle(CrossRoad(false))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onStopLineInfo(info: StopLine) {
|
||||
Log.d(TAG, "-- onStopLineInfo --: ${info.distanceOfCarToStopLine}")
|
||||
if (!hasCrossRoad && info.distanceOfCarToStopLine <= 30.0) {
|
||||
hasCrossRoad = true
|
||||
triggerRoadId.set(this.roadId.get())
|
||||
distanceOfCarToStopLine.set(info.distanceOfCarToStopLine)
|
||||
triggerLocation.set(CallerChassisLocationGCJ02ListenerManager.getChassisLocationGCJ02())
|
||||
changeAngle(CrossRoad(true))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
if (Thread.currentThread() != Looper.getMainLooper().thread) {
|
||||
scope.launch {
|
||||
initListen(context)
|
||||
}
|
||||
} else {
|
||||
initListen(context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun initListen(ctx: Context?) {
|
||||
ctx ?: return
|
||||
ctx.lifeCycleOwner.lifecycle.addObserver(object : LifecycleEventObserver {
|
||||
override fun onStateChanged(source: LifecycleOwner, event: Event) {
|
||||
if (event == ON_DESTROY) {
|
||||
CallerMapRoadListenerManager.unRegisterRoadListener("VisualAngleChange")
|
||||
}
|
||||
}
|
||||
})
|
||||
CallerMapRoadListenerManager.registerRoadListener("VisualAngleChange", listener)
|
||||
}
|
||||
|
||||
@Volatile
|
||||
private var hasCrossRoad = false
|
||||
|
||||
|
||||
private var scope: CoroutineScope = acquireScope()
|
||||
@Synchronized
|
||||
get() {
|
||||
if (field.isActive) {
|
||||
return field
|
||||
}
|
||||
val scope = acquireScope()
|
||||
field = scope
|
||||
return field
|
||||
}
|
||||
|
||||
private var defaultDelayJob: Job? = null
|
||||
|
||||
private fun acquireScope(): CoroutineScope {
|
||||
return CoroutineScope(Handler(Looper.getMainLooper()).asCoroutineDispatcher("change-visual-angle") + SupervisorJob())
|
||||
}
|
||||
|
||||
@Volatile
|
||||
private var mLevel:Boolean = false
|
||||
|
||||
override fun updateLongSightLevel(level:Boolean){
|
||||
mLevel = level
|
||||
}
|
||||
|
||||
override fun changeAngle(scene: Scene) {
|
||||
val appIdentityMode = FunctionBuildConfig.appIdentityMode
|
||||
if (AppIdentityModeUtils.isBus(appIdentityMode) && AppIdentityModeUtils.isPassenger(appIdentityMode)) {
|
||||
return
|
||||
}
|
||||
if(mLevel){
|
||||
return
|
||||
}
|
||||
val triggerTime = SystemClock.elapsedRealtime()
|
||||
scope.launch {
|
||||
Log.d(TAG, "--- 1 ---")
|
||||
val displayed = getDisplayed()
|
||||
if (displayed == null) {
|
||||
Log.d(TAG, "--- 2 ---")
|
||||
if (scene is Turning) {
|
||||
if (!scene.open) {
|
||||
changeAngle(Default())
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
if (scene is CrossRoad) {
|
||||
if (!scene.open) {
|
||||
changeAngle(Default())
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
doRealVisualAngleChange(triggerTime, scene, null)
|
||||
} else {
|
||||
val prev = displayed.target
|
||||
Log.d(TAG, "--- 3 --- old: $prev -> cur: $scene")
|
||||
val prevTriggerTime = displayed.triggerTime
|
||||
if (scene !is Default && prev.priority > scene.priority && (prev is RoadEvent || prev is TooClose)) {
|
||||
val displayDuration = triggerTime - prevTriggerTime
|
||||
Log.d(TAG, "--- 4 ---:场景[$prev], 已展示时长: duration: $displayDuration")
|
||||
if (displayDuration < prev.displayThreshold) {
|
||||
Log.d(TAG, "--- 5 --- 场景[$prev]:仍在保护展示时长内,直接return")
|
||||
return@launch
|
||||
} else {
|
||||
Log.d(TAG, "--- 6 --- 场景[$prev]:已过保护展示时长,从展示的队列中移除,显示默认视角")
|
||||
queue -= displayed
|
||||
changeAngle(Default())
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
if (prev is Turning && scene is Turning) {
|
||||
val isOpen = scene.open
|
||||
if (!isOpen) {
|
||||
Log.d(TAG, "--- 7 --- 场景[$scene], 收到关闭通知")
|
||||
queue -= displayed
|
||||
changeAngle(Default())
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
if (prev is CrossRoad && scene is CrossRoad) {
|
||||
val isOpen = scene.open
|
||||
if (!isOpen) {
|
||||
Log.d(TAG, "--- 8 --- old: $prev -> cur: $scene")
|
||||
queue -= displayed
|
||||
changeAngle(Default())
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
if (prev.priority == scene.priority) {
|
||||
Log.d(TAG, "--- 9 --- 场景[$prev]正在展示,尚未收到关闭,优先级一致,直接return")
|
||||
return@launch
|
||||
}
|
||||
if (prev.priority > scene.priority && prev.displayThreshold < 0) {
|
||||
Log.d(TAG, "--- 10 --- 场景[$prev]正在展示,尚未收到关闭,场景,依然展示当前场景,直接return")
|
||||
return@launch
|
||||
}
|
||||
doRealVisualAngleChange(triggerTime, scene, displayed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun CoroutineScope.doRealVisualAngleChange(triggerTime: Long, target: Scene, displayed: Record? = null) {
|
||||
if (target is Default) {
|
||||
Log.d(TAG, "--- doRealVisualAngleChange --- 1 ---")
|
||||
displayed?.also {
|
||||
queue -= it
|
||||
}
|
||||
defaultDelayJob?.safeCancel()
|
||||
launch {
|
||||
val delay = target.unit.toMillis(target.delay)
|
||||
Log.d(TAG, "--- doRealVisualAngleChange --- 2 ---")
|
||||
delay(delay)
|
||||
Log.d(TAG, "--- doRealVisualAngleChange --- 3 ---")
|
||||
doChangeAngle(Record(target, triggerTime = triggerTime))
|
||||
}.also { itx ->
|
||||
itx.invokeOnCompletion {
|
||||
if (it is CancellationException) {
|
||||
Log.d(TAG, "--- doRealVisualAngleChange --- 4 ---")
|
||||
}
|
||||
}
|
||||
defaultDelayJob = itx
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "--- doRealVisualAngleChange --- 5 ---")
|
||||
defaultDelayJob?.safeCancel()
|
||||
if (displayed == null || displayed.target.priority <= target.priority) {
|
||||
Log.d(TAG, "--- doRealVisualAngleChange --- 6 ---")
|
||||
displayed?.also {
|
||||
queue -= it
|
||||
}
|
||||
if (target is Turning) {
|
||||
if (!target.open) {
|
||||
Log.d(TAG, "--- doRealVisualAngleChange --- 7 ---")
|
||||
changeAngle(Default())
|
||||
return
|
||||
}
|
||||
}
|
||||
if (target is CrossRoad) {
|
||||
if (!target.open) {
|
||||
Log.d(TAG, "--- doRealVisualAngleChange --- 8 ---")
|
||||
changeAngle(Default())
|
||||
return
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "--- doRealVisualAngleChange --- 10 ---")
|
||||
doChangeAngle(Record(target, triggerTime = triggerTime))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(InternalCoroutinesApi::class)
|
||||
private fun doChangeAngle(record: Record) {
|
||||
val angle = record.target.angle
|
||||
CallerMapUIServiceManager.getMapUIController()?.also {
|
||||
Log.d(TAG, "--- doChangeAngle ---: ${record.target}")
|
||||
if (record.target !is Default) {
|
||||
record.isDisplay = true
|
||||
kotlinx.coroutines.internal.synchronized(queue) {
|
||||
queue += record
|
||||
}
|
||||
}
|
||||
it.changeMapVisualAngle(angle, null)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否有正在展示的
|
||||
*/
|
||||
@Synchronized
|
||||
private fun getDisplayed() = queue.firstOrNull()
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.mogo.eagle.core.function.business;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.mogo.eagle.core.data.enums.DataSourceType;
|
||||
import com.mogo.eagle.core.data.map.MogoLocation;
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener;
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationWGS84Listener;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager;
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager;
|
||||
import com.mogo.eagle.core.function.call.v2x.CallerLimitingVelocityListenerManager;
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
/**
|
||||
* 限速
|
||||
*
|
||||
* @author mogoauto
|
||||
*/
|
||||
public class SpeedLimitDataManager implements IMoGoChassisLocationWGS84Listener {
|
||||
|
||||
private final static String TAG = "SpeedLimitDataManager";
|
||||
private static volatile SpeedLimitDataManager instance;
|
||||
private volatile MogoLocation mLocation;
|
||||
|
||||
private SpeedLimitDataManager() {
|
||||
}
|
||||
|
||||
public static SpeedLimitDataManager getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (SpeedLimitDataManager.class) {
|
||||
if (instance == null) {
|
||||
instance = new SpeedLimitDataManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChassisLocationWGS84(@Nullable MogoLocation gnssInfo) {
|
||||
mLocation = gnssInfo;
|
||||
}
|
||||
|
||||
private class SpeedTimerTask extends TimerTask {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mLocation != null) {
|
||||
if (CallerMapUIServiceManager.INSTANCE.getMapUIController() != null) {
|
||||
getSpeedLimit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void getSpeedLimit() {
|
||||
int speedLimit = Objects.requireNonNull(CallerMapUIServiceManager.INSTANCE.getMapUIController()).getLimitSpeed(mLocation.getLongitude(), mLocation.getLatitude(), (float) mLocation.getHeading());
|
||||
UiThreadHandler.post(() -> {
|
||||
if (speedLimit > 0) {
|
||||
CallerLimitingVelocityListenerManager.INSTANCE.invokeUnion(speedLimit, DataSourceType.MAP);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void start() {
|
||||
CallerChassisLocationWGS84ListenerManager.INSTANCE.addListener(TAG, this);
|
||||
Timer mTimer = new Timer();
|
||||
mTimer.schedule(new SpeedTimerTask(), 3000, 1000);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,18 +4,12 @@ import android.content.Context
|
||||
import com.mogo.aicloud.services.socket.IMogoOnMessageListener
|
||||
import com.mogo.aicloud.services.socket.MogoAiCloudSocketManager
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig
|
||||
import com.mogo.eagle.core.data.deva.chain.ChainConstant
|
||||
import com.mogo.eagle.core.function.business.ai.net.AiCloudIdentifyNetWorkModel
|
||||
import com.mogo.eagle.core.function.business.identify.MapIdentifySubscriber
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapIdentifyManager
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_MAP
|
||||
import com.mogo.map.listener.IMogoMapListener
|
||||
import com.mogo.map.uicontroller.VisualAngleMode
|
||||
import com.mogo.module.common.MogoApisHandler
|
||||
import com.zhjt.service.chain.ChainLog
|
||||
import com.zhjt.service.chain.TracingConstants
|
||||
import mogo.yycp.api.proto.SocketDownData
|
||||
|
||||
class AiCloudIdentifyDataManager : IMogoMapListener {
|
||||
@@ -36,7 +30,6 @@ class AiCloudIdentifyDataManager : IMogoMapListener {
|
||||
private var showAiCloud = false
|
||||
|
||||
fun init(mContext: Context) {
|
||||
MogoApisHandler.getInstance().apis.registerCenterApi.registerMogoMapListener(TAG, this)
|
||||
MogoAiCloudSocketManager.getInstance(mContext)
|
||||
.registerOnMessageListener(
|
||||
0x040003, //低频数据
|
||||
@@ -45,16 +38,8 @@ class AiCloudIdentifyDataManager : IMogoMapListener {
|
||||
return SocketDownData.SocketDownDataProto::class.java
|
||||
}
|
||||
|
||||
@ChainLog(
|
||||
linkChainLog = ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_DATA_TRACKED,
|
||||
linkCode = ChainConstant.CHAIN_LINK_ADAS,
|
||||
endpoint = TracingConstants.Endpoint.PAD,
|
||||
nodeAliasCode = ChainConstant.CHAIN_ALIAS_CODE_ADAS_MESSAGE_RECT_DATA,
|
||||
paramIndexes = [0],
|
||||
clientPkFileName = "sn"
|
||||
)
|
||||
override fun onMsgReceived(obj: SocketDownData.SocketDownDataProto?) {
|
||||
if(!FunctionBuildConfig.isDrawAiCloudFusion){
|
||||
if (!FunctionBuildConfig.isDrawAiCloudFusion) {
|
||||
MapIdentifySubscriber.instance.clearAiCloudRoma()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.mogo.eagle.core.function.business.ai.net
|
||||
|
||||
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
|
||||
import com.mogo.commons.constants.HostConst
|
||||
import com.mogo.commons.debug.DebugConfig
|
||||
import com.mogo.eagle.core.data.BaseResponse
|
||||
import com.mogo.eagle.core.function.business.ai.AiCloudIdentifyDataManager.Companion.END_METRE
|
||||
@@ -27,7 +28,7 @@ class AiCloudIdentifyNetWorkModel {
|
||||
return host
|
||||
}
|
||||
|
||||
private fun getNetWorkApi(baseUrl: String = getHost()): IAiCloudIdentifyApiService {
|
||||
private fun getNetWorkApi(baseUrl: String = HostConst.getEagleHost()): IAiCloudIdentifyApiService {
|
||||
return MoGoRetrofitFactory.getInstanceNoCallAdapter(baseUrl)
|
||||
.create(IAiCloudIdentifyApiService::class.java)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,6 @@ import retrofit2.http.POST
|
||||
interface IAiCloudIdentifyApiService {
|
||||
|
||||
@Headers("Content-type:application/json;charset=UTF-8")
|
||||
@POST("yycp-c-v2x-service/dataFusion/remoteDrivingSet")
|
||||
@POST("eagle-eye-dns/yycp-c-v2x-service/dataFusion/remoteDrivingSet")
|
||||
suspend fun identifyRange(@Body map: MutableMap<String, Any>): BaseResponse<Any>
|
||||
}
|
||||
@@ -6,22 +6,28 @@ import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.mogo.cloud.passport.IMoGoTokenCallback
|
||||
import com.mogo.cloud.passport.MoGoAiCloudClient
|
||||
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig
|
||||
import com.mogo.eagle.core.data.constants.MogoServicePaths
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_MAP
|
||||
import com.mogo.eagle.core.data.map.MogoLocation
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
|
||||
import com.mogo.eagle.core.function.api.map.collect.IMoGoMapDataCollectProvider
|
||||
import com.mogo.eagle.core.function.api.map.listener.IMoGoMapLocationListener
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_MAP
|
||||
import com.zhidaoauto.map.operational.open.GatherApi
|
||||
import com.zhidaoauto.map.operational.open.GatherParams
|
||||
import com.zhidaoauto.map.operational.open.abs.OnTaskListener
|
||||
import record_cache.RecordPanelOuterClass
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
@Route(path = MogoServicePaths.PATH_MAP_DATA_COLLECT_PROVIDER)
|
||||
class MoGoMapDataCollectProvider : IMoGoMapDataCollectProvider, OnTaskListener, IMoGoMapLocationListener, IMoGoTokenCallback {
|
||||
class MoGoMapDataCollectProvider : IMoGoMapDataCollectProvider, OnTaskListener,
|
||||
IMoGoChassisLocationGCJ02Listener, IMoGoTokenCallback,
|
||||
IMoGoAutopilotRecordListener {
|
||||
|
||||
companion object {
|
||||
const val TAG = "MoGoMapDataCollect"
|
||||
@@ -39,20 +45,26 @@ class MoGoMapDataCollectProvider : IMoGoMapDataCollectProvider, OnTaskListener,
|
||||
ConcurrentHashMap()
|
||||
}
|
||||
|
||||
override val functionName: String = "$M_MAP$TAG"
|
||||
override val functionName: String = TAG
|
||||
|
||||
@Volatile
|
||||
private var hasInit = false
|
||||
|
||||
override fun init(context: Context?) {
|
||||
CallerMapLocationListenerManager.addListener(functionName, this, false)
|
||||
|
||||
CallerChassisLocationGCJ02ListenerManager.addListener(TAG, this)
|
||||
CallerAutopilotRecordListenerManager.addListener(TAG, this)
|
||||
|
||||
executor.set(context?.let {
|
||||
GatherApi.also { itx ->
|
||||
itx.init(it,
|
||||
GatherParams.init()
|
||||
.setDebugMode(false)
|
||||
.setCoordinateType(GatherParams.COORDINATETYPE_GCJ02))
|
||||
} })
|
||||
itx.init(
|
||||
it,
|
||||
GatherParams.init()
|
||||
.setDebugMode(false)
|
||||
.setCoordinateType(GatherParams.COORDINATETYPE_GCJ02)
|
||||
)
|
||||
}
|
||||
})
|
||||
executor.get()?.setOnTaskListener(this)
|
||||
val carSn = MoGoAiCloudClientConfig.getInstance().sn
|
||||
if (!TextUtils.isEmpty(carSn)) {
|
||||
@@ -60,17 +72,37 @@ class MoGoMapDataCollectProvider : IMoGoMapDataCollectProvider, OnTaskListener,
|
||||
}
|
||||
MoGoAiCloudClient.getInstance().addTokenCallbacks(this)
|
||||
CallerLogger.d("$M_MAP$TAG", "--------- init --------")
|
||||
CallerLogger.d("$M_MAP$TAG", "executor: ${ executor.get()?.hashCode() ?: 0 }")
|
||||
CallerLogger.d("$M_MAP$TAG", "executor: ${executor.get()?.hashCode() ?: 0}")
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
CallerMapLocationListenerManager.removeListener("$M_MAP$TAG", false)
|
||||
CallerLogger.d("$M_MAP$TAG", "--------- onDestroy --------")
|
||||
CallerChassisLocationGCJ02ListenerManager.removeListener(TAG)
|
||||
CallerAutopilotRecordListenerManager.removeListener(TAG)
|
||||
executor.get()?.setOnTaskListener(null)
|
||||
listeners.clear()
|
||||
map.clear()
|
||||
}
|
||||
|
||||
override fun onAutopilotRecordResult(recordPanel: RecordPanelOuterClass.RecordPanel) {
|
||||
super.onAutopilotRecordResult(recordPanel)
|
||||
CallerLogger.d("$M_MAP$TAG", "recordKey=${recordPanel.key},stat=${recordPanel.stat}")
|
||||
if (!FunctionBuildConfig.isDemoMode && recordPanel.type == 2 && (
|
||||
recordPanel.stat == 101 || //工控机采集完成-被动完成
|
||||
recordPanel.stat == 100 || //工控机采集完成-主动完成
|
||||
recordPanel.stat == 102 || //工控机达到最大采集时长
|
||||
recordPanel.stat == 103) //工控机磁盘满了
|
||||
) {
|
||||
finish(
|
||||
recordPanel.id,
|
||||
recordPanel.stat,
|
||||
"",
|
||||
recordPanel.filename ?: "",
|
||||
recordPanel.note ?: ""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun registerOnMapCollectTaskListener(listener: IMoGoMapDataCollectProvider.OnMapCollectCmdListener?) {
|
||||
CallerLogger.d("$M_MAP$TAG", "--------- registerOnMapCollectTaskListener --------")
|
||||
listener ?: return
|
||||
@@ -108,7 +140,7 @@ class MoGoMapDataCollectProvider : IMoGoMapDataCollectProvider, OnTaskListener,
|
||||
}
|
||||
CallerLogger.d("$M_MAP$TAG", "-- finish: 结束任务[$id]")
|
||||
executor.get()?.finishTask(id, state, gpsPath, videoPath, reason)
|
||||
} catch (e : Throwable) {
|
||||
} catch (e: Throwable) {
|
||||
e.printStackTrace()
|
||||
CallerLogger.e("$M_MAP$TAG", "-- finish:\n$e")
|
||||
} finally {
|
||||
@@ -147,18 +179,19 @@ class MoGoMapDataCollectProvider : IMoGoMapDataCollectProvider, OnTaskListener,
|
||||
}
|
||||
}
|
||||
|
||||
override fun onLocationChanged(location: MogoLocation?, from: Int, isGps: Boolean) {
|
||||
location ?: return
|
||||
executor.get()?.updateLocation(
|
||||
location.longitude,
|
||||
location.latitude,
|
||||
location.altitude,
|
||||
location.bearing,
|
||||
location.speed,
|
||||
isGps)
|
||||
override fun onChassisLocationGCJ02(gnssInfo: MogoLocation?) {
|
||||
if (gnssInfo != null) {
|
||||
executor.get()?.updateLocation(
|
||||
gnssInfo.longitude,
|
||||
gnssInfo.latitude,
|
||||
gnssInfo.altitude,
|
||||
gnssInfo.heading.toFloat(),
|
||||
gnssInfo.gnssSpeed,
|
||||
false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun isInValidStatus(): Boolean {
|
||||
if (map.isEmpty()) {
|
||||
return true
|
||||
|
||||
@@ -24,18 +24,10 @@ public class CircleQueue {
|
||||
objQueue.add(obj);
|
||||
}
|
||||
|
||||
public void deleteObj(ObjQueue obj) {
|
||||
objQueue.remove(obj);
|
||||
}
|
||||
|
||||
public List<ObjQueue> getLastThreeFrame() {
|
||||
return objQueue.subList(objQueue.size() - 3, objQueue.size());
|
||||
}
|
||||
|
||||
public List<ObjQueue> getLastFiveFrame() {
|
||||
return objQueue.subList(objQueue.size() - 5, objQueue.size());
|
||||
}
|
||||
|
||||
public List<ObjQueue> getPreFrame() {
|
||||
return objQueue.subList(0, objQueue.size());
|
||||
}
|
||||
@@ -44,6 +36,10 @@ public class CircleQueue {
|
||||
return objQueue.lastElement();
|
||||
}
|
||||
|
||||
public void clear(){
|
||||
objQueue.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CircleQueue{" +
|
||||
|
||||
@@ -7,15 +7,15 @@ import mogo.yycp.api.proto.SocketDownData
|
||||
|
||||
interface Identify {
|
||||
|
||||
fun renderAdasRecognizedResult(resultList: List<TrackedObject>?){
|
||||
fun renderAdasRecognizedResult(resultList: List<TrackedObject>?) {
|
||||
|
||||
}
|
||||
|
||||
fun renderAiCloudResult(resultList: List<SocketDownData.CloudRoadDataProto>){
|
||||
fun renderAiCloudResult(resultList: List<SocketDownData.CloudRoadDataProto>) {
|
||||
|
||||
}
|
||||
|
||||
fun renderPlanningWarningObj(planningObjects: List<MessagePad.PlanningObject>?){
|
||||
fun renderPlanningWarningObj(planningObjects: List<MessagePad.PlanningObject>?) {
|
||||
|
||||
}
|
||||
|
||||
@@ -23,15 +23,15 @@ interface Identify {
|
||||
|
||||
}
|
||||
|
||||
fun clearOldMarker(){
|
||||
fun clearOldMarker() {
|
||||
|
||||
}
|
||||
|
||||
fun clearAiMarker(){
|
||||
fun clearAiMarker() {
|
||||
|
||||
}
|
||||
|
||||
fun getIdentifyObj(uuid: String):TrackedObject?{
|
||||
fun getIdentifyObj(uuid: String): TrackedObject? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,8 @@ import com.mogo.commons.AbsMogoApplication
|
||||
import com.mogo.commons.module.status.MogoStatusManager
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.w
|
||||
import com.mogo.map.MogoMarkerManager
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import mogo.yycp.api.proto.SocketDownData
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class IdentifyAiCloudDataDrawer : Identify {
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ import android.os.Handler
|
||||
import android.os.Message
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig
|
||||
import com.mogo.eagle.core.data.traffic.TrafficData
|
||||
import com.mogo.eagle.core.function.api.obu.IMoGoObuStatusListener
|
||||
import com.mogo.eagle.core.function.call.obu.CallerObuListenerManager
|
||||
import com.mogo.eagle.core.function.api.datacenter.obu.IMoGoObuStatusListener
|
||||
import com.mogo.eagle.core.function.call.obu.CallerObuWarningListenerManager
|
||||
import com.mogo.eagle.core.utilcode.mogo.thread.WorkThreadHandler
|
||||
import mogo.telematics.pad.MessagePad
|
||||
import mogo.telematics.pad.MessagePad.TrackedObject
|
||||
@@ -37,7 +37,7 @@ object IdentifyFactory : Identify, IMoGoObuStatusListener {
|
||||
DriverIdentify.originDataDrawer
|
||||
}
|
||||
aiCloudIdentify = AiIdentify.aiCloudDataDrawer
|
||||
CallerObuListenerManager.addListener(TAG, this)
|
||||
CallerObuWarningListenerManager.addListener(TAG, this)
|
||||
}
|
||||
|
||||
private const val MSG_DATA_TRACK = 0
|
||||
|
||||
@@ -102,7 +102,6 @@ class IdentifyOriginDataDrawer : Identify {
|
||||
@SuppressLint("NewApi")
|
||||
private fun filterTrafficData(trafficData: List<TrackedObject>): HashMap<String, TrackedObject> {
|
||||
mFilterTrafficData.clear()
|
||||
trafficDataUuidList.clear()
|
||||
for (data in trafficData) {
|
||||
// 过滤掉未知感知数据
|
||||
if (TrackerSourceColorHelper.filterData(data)) {
|
||||
@@ -110,13 +109,12 @@ class IdentifyOriginDataDrawer : Identify {
|
||||
}
|
||||
var temp: TrackedObject = data
|
||||
val uuid = "" + data.uuid
|
||||
//首次过来的数据不添加,首次未添加的感知物在调用完绘制方法后再塞入cache map
|
||||
val cacheData = mMarkersCaches[uuid]
|
||||
if (cacheData != null) {
|
||||
val color = TrackerSourceColorHelper.getDefaultColor(data)
|
||||
temp = data.toBuilder().setColor(color).build()
|
||||
mFilterTrafficData[uuid] = temp
|
||||
}
|
||||
mFilterTrafficData[uuid] = temp
|
||||
mMarkersCaches[uuid] = temp
|
||||
trafficDataUuidList.add(uuid)
|
||||
}
|
||||
|
||||
@@ -4,11 +4,13 @@ import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig
|
||||
import com.mogo.eagle.core.data.constants.MogoServicePaths.PATH_IDENTIFY
|
||||
import com.mogo.eagle.core.data.traffic.TrafficData
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotIdentifyListener
|
||||
import com.mogo.eagle.core.function.api.base.IMoGoSubscriber
|
||||
import com.mogo.eagle.core.function.api.map.marker.IMoGoIdentifyListener
|
||||
import com.mogo.eagle.core.function.business.identify.IdentifyFactory.AiIdentify.aiCloudDataDrawer
|
||||
import com.mogo.eagle.core.function.api.datacenter.obu.IMoGoObuStatusListener
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager
|
||||
import com.mogo.eagle.core.function.call.obu.CallerObuWarningListenerManager
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils
|
||||
import mogo.telematics.pad.MessagePad
|
||||
import mogo.telematics.pad.MessagePad.TrackedObject
|
||||
@@ -22,7 +24,7 @@ import mogo.yycp.api.proto.SocketDownData
|
||||
*/
|
||||
@Route(path = PATH_IDENTIFY)
|
||||
class MapIdentifySubscriber private constructor() : IMoGoIdentifyListener, IMoGoSubscriber,
|
||||
IMoGoAutopilotIdentifyListener {
|
||||
IMoGoAutopilotIdentifyListener, IMoGoObuStatusListener {
|
||||
|
||||
private val TAG = "MapIdentifySubscriber"
|
||||
|
||||
@@ -38,11 +40,12 @@ class MapIdentifySubscriber private constructor() : IMoGoIdentifyListener, IMoGo
|
||||
|
||||
override fun onCrate() {
|
||||
CallerAutopilotIdentifyListenerManager.addListener(TAG, this)
|
||||
|
||||
CallerObuWarningListenerManager.addListener(TAG, this)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
CallerAutopilotIdentifyListenerManager.removeListener(TAG)
|
||||
CallerObuWarningListenerManager.removeListener(TAG)
|
||||
}
|
||||
|
||||
override fun onAutopilotIdentifyDataUpdate(trafficData: List<TrackedObject>?) {
|
||||
@@ -63,7 +66,6 @@ class MapIdentifySubscriber private constructor() : IMoGoIdentifyListener, IMoGo
|
||||
try {
|
||||
if (FunctionBuildConfig.isDrawAiCloudFusion) {
|
||||
ThreadUtils.getSinglePool().execute {
|
||||
// aiCloudDataDrawer.renderAiCloudResult(cloudData)
|
||||
IdentifyFactory.renderAiCloudResult(cloudData)
|
||||
}
|
||||
} else {
|
||||
@@ -75,7 +77,6 @@ class MapIdentifySubscriber private constructor() : IMoGoIdentifyListener, IMoGo
|
||||
}
|
||||
|
||||
fun clearAiCloudRoma() {
|
||||
// aiCloudDataDrawer.clearAiMarker()
|
||||
IdentifyFactory.clearAiMarker()
|
||||
}
|
||||
|
||||
@@ -93,6 +94,32 @@ class MapIdentifySubscriber private constructor() : IMoGoIdentifyListener, IMoGo
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateTrackerWarningInfo(trafficData: TrafficData) {
|
||||
super.updateTrackerWarningInfo(trafficData)
|
||||
try {
|
||||
if (FunctionBuildConfig.isObuWarningFusionUnion) {
|
||||
ThreadUtils.getSinglePool().execute {
|
||||
IdentifyFactory.renderOBUWarningObj(true, trafficData)
|
||||
}
|
||||
} else {
|
||||
IdentifyFactory.renderOBUWarningObj(false, trafficData)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
override fun removeTrackerWarningInfo(trafficData: TrafficData) {
|
||||
super.removeTrackerWarningInfo(trafficData)
|
||||
try {
|
||||
ThreadUtils.getSinglePool().execute {
|
||||
IdentifyFactory.renderOBUWarningObj(false, trafficData)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getIdentifyObj(uuid: String): TrackedObject? {
|
||||
return IdentifyFactory.getIdentifyObj(uuid)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.mogo.eagle.core.function.business.identify;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Build;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
@@ -50,7 +52,7 @@ public class TrackManager {
|
||||
* 记录每次实际绘制的交通元素UUID
|
||||
*/
|
||||
@SuppressLint("NewApi")
|
||||
private final HashMap<String, Long> trafficDataUuid = new HashMap<>();
|
||||
private final ArraySet<String> trafficDataUuid = new ArraySet<>();
|
||||
|
||||
/**
|
||||
* 过滤后的数据集合
|
||||
@@ -71,9 +73,10 @@ public class TrackManager {
|
||||
* 过滤后的数据集合
|
||||
*/
|
||||
@SuppressLint("NewApi")
|
||||
public synchronized HashMap<String, MessagePad.TrackedObject> filterTrafficData(List<MessagePad.TrackedObject> trafficData) {
|
||||
public HashMap<String, MessagePad.TrackedObject> filterTrafficData(List<MessagePad.TrackedObject> trafficData) {
|
||||
//清空上次返回数据,做到缓存复用
|
||||
mFilterTrafficData.clear();
|
||||
long cost = System.currentTimeMillis();
|
||||
//进入过滤机制的感知物体,首先从缓存队列中进行查找 uuid
|
||||
for (MessagePad.TrackedObject data : trafficData) {
|
||||
if (TrackerSourceColorHelper.INSTANCE.filterData(data)) {
|
||||
@@ -101,7 +104,7 @@ public class TrackManager {
|
||||
trackObj = cacheTrack;
|
||||
MessagePad.TrackedObject cache = cacheTrack.getCache();
|
||||
if (cache != null) {
|
||||
//相对静止物体并且非obu数据,则不改变,为感知融合同位置物体,使用缓存数据做覆盖
|
||||
//相对静止物体 感知融合同位置物体,使用缓存数据做覆盖
|
||||
if (cacheTrack.relativeStatic()) {
|
||||
if (data.getColor() != null && !data.getColor().isEmpty()) {
|
||||
cache = cache.toBuilder().setColor(data.getColor()).build();
|
||||
@@ -112,55 +115,60 @@ public class TrackManager {
|
||||
uuid = findSameValue;
|
||||
trackObj.updateObj(data);
|
||||
} else {
|
||||
trackObj = new TrackObj(data);
|
||||
trackObj = new TrackObj(data,s2CellId,s2LatLng);
|
||||
}
|
||||
} else {
|
||||
trackObj = new TrackObj(data);
|
||||
trackObj = new TrackObj(data,s2CellId,s2LatLng);
|
||||
}
|
||||
}
|
||||
mFilterTrafficData.put(uuid, trackObj.getCache());
|
||||
cellIdCaches.forcePut(uuid, trackObj.getCellIdPos());
|
||||
mMarkersCaches.put(uuid, trackObj);
|
||||
trafficDataUuid.put(uuid, System.currentTimeMillis());
|
||||
trafficDataUuid.add(uuid);
|
||||
//Log.i("costTime","" + (System.currentTimeMillis() - cost));
|
||||
}
|
||||
return mFilterTrafficData;
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
public void clearCache(List<MessagePad.TrackedObject> resultList) {
|
||||
//过滤现有元素
|
||||
for (MessagePad.TrackedObject data : resultList) {
|
||||
String uuid = "" + data.getUuid();
|
||||
if (TrackerSourceColorHelper.INSTANCE.filterData(data)) {
|
||||
continue;
|
||||
}
|
||||
if (trafficDataUuid.size() > 0) {
|
||||
if (trafficDataUuid.size() > 0 && trafficDataUuid.contains(uuid)) {
|
||||
if (TrackerSourceColorHelper.INSTANCE.filterData(data)) {
|
||||
continue;
|
||||
}
|
||||
trafficDataUuid.remove(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
//清除缓存,删除marker
|
||||
Iterator<Map.Entry<String, Long>> it = trafficDataUuid.entrySet().iterator();
|
||||
Iterator<String> it = trafficDataUuid.iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<String, Long> next = it.next();
|
||||
String key = next.getKey();
|
||||
String key = it.next();
|
||||
it.remove();
|
||||
removeKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void removeKey(String key) {
|
||||
mMarkersCaches.remove(key);
|
||||
public void removeKey(String key) {
|
||||
cellIdCaches.remove(key);
|
||||
mMarkersCaches.remove(key);
|
||||
WarningHelper.INSTANCE.remove(key);
|
||||
MogoMarkerManager.getInstance(AbsMogoApplication.getApp())
|
||||
.removeMarker(key);
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public void clearAll() {
|
||||
cellIdCaches.clear();
|
||||
trafficDataUuid.clear();
|
||||
WarningHelper.INSTANCE.clear();
|
||||
mMarkersCaches.forEach((uuid, trackObj) -> removeKey(uuid));
|
||||
mMarkersCaches.forEach((uuid, trackObj) -> {
|
||||
trackObj.clear();
|
||||
MogoMarkerManager.getInstance(AbsMogoApplication.getApp())
|
||||
.removeMarker(uuid);
|
||||
});
|
||||
mMarkersCaches.clear();
|
||||
}
|
||||
|
||||
public MessagePad.TrackedObject getIdentifyObj(String uuid) {
|
||||
|
||||
@@ -4,12 +4,10 @@ import static com.mogo.eagle.core.function.business.identify.TrackManager.LIMIT_
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
|
||||
import com.mogo.cloud.commons.utils.CoordinateUtils;
|
||||
import com.mogo.eagle.core.data.enums.TrafficTypeEnum;
|
||||
import com.mogo.eagle.core.data.map.CenterLine;
|
||||
import com.mogo.eagle.core.function.call.map.CallerHDMapManager;
|
||||
import com.mogo.eagle.core.utilcode.geometry.S2CellId;
|
||||
import com.mogo.eagle.core.utilcode.geometry.S2LatLng;
|
||||
import com.mogo.eagle.core.utilcode.util.CoordinateUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
@@ -22,20 +20,18 @@ public class TrackObj {
|
||||
private final CircleQueue circleQueue = new CircleQueue(6);
|
||||
private S2CellId s2CellId; //s2 id权重
|
||||
private S2LatLng s2LatLng; //s2 经纬度
|
||||
private double recentlyTime; //用于缓存帧数判断,暂定缓存1秒数据,中间如果有物体未出现,1秒后删除
|
||||
// private int[] typeArray = new int[3];
|
||||
// private int typeWeight; //类型权重
|
||||
private int[] typeArray = new int[3];
|
||||
private int typeWeight; //类型权重
|
||||
private double lat;
|
||||
private double lon;
|
||||
private double speedAverage;
|
||||
|
||||
public TrackObj(MessagePad.TrackedObject data) {
|
||||
public TrackObj(MessagePad.TrackedObject data, S2CellId cellId, S2LatLng latLng) {
|
||||
circleQueue.addQueue(new ObjQueue(data.getHeading(), data.getSpeed(), data.getLatitude(), data.getLongitude(), data.getType()));
|
||||
recentlyTime = data.getSatelliteTime();
|
||||
lat = data.getLatitude();
|
||||
lon = data.getLongitude();
|
||||
s2LatLng = S2LatLng.fromDegrees(data.getLatitude(), data.getLongitude());
|
||||
s2CellId = S2CellId.fromLatLng(s2LatLng).parent(22); //需要验证22前后
|
||||
s2LatLng = latLng;
|
||||
s2CellId = cellId; //需要验证22前后
|
||||
}
|
||||
|
||||
private MessagePad.TrackedObject cacheData;
|
||||
@@ -44,14 +40,12 @@ public class TrackObj {
|
||||
public void updateObj(MessagePad.TrackedObject data) {
|
||||
cacheData = data;
|
||||
correct();
|
||||
recentlyTime = data.getSatelliteTime();
|
||||
circleQueue.addQueue(new ObjQueue(cacheData.getHeading(), cacheData.getSpeed(), data.getLatitude(), data.getLongitude(), data.getType()));
|
||||
}
|
||||
|
||||
private void correct() {
|
||||
calAverageSpeedAndType();
|
||||
calLoc();
|
||||
// calHeading();
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@@ -62,20 +56,22 @@ public class TrackObj {
|
||||
objQueueList.sort(Comparator.comparing(ObjQueue::getSpeed));
|
||||
speedAverage = objQueueList.get(1).getSpeed();
|
||||
//计算类型
|
||||
// typeArray[0] = objQueueList.get(0).getType();
|
||||
// typeArray[1] = objQueueList.get(1).getType();
|
||||
// typeArray[2] = objQueueList.get(2).getType();
|
||||
typeArray[0] = objQueueList.get(0).getType();
|
||||
typeArray[1] = objQueueList.get(1).getType();
|
||||
typeArray[2] = objQueueList.get(2).getType();
|
||||
} else {
|
||||
double cal = 0;
|
||||
List<ObjQueue> objQueueList = circleQueue.getPreFrame();
|
||||
for (int i = 0; i < objQueueList.size() - 1; i++) {
|
||||
cal += objQueueList.get(i).getSpeed();
|
||||
// typeArray[i] = objQueueList.get(i).getType();
|
||||
typeArray[i] = objQueueList.get(i).getType();
|
||||
}
|
||||
speedAverage = cal / objQueueList.size();
|
||||
}
|
||||
// typeArray = Arrays.stream(typeArray).sorted().toArray();
|
||||
// typeWeight = typeArray[typeArray.length / 2] == 0 ? cacheData.getType() : typeArray[typeArray.length / 2];
|
||||
if(typeArray.length > 0){
|
||||
typeArray = Arrays.stream(typeArray).sorted().toArray();
|
||||
typeWeight = typeArray[typeArray.length / 2] == 0 ? cacheData.getType() : typeArray[typeArray.length / 2];
|
||||
}
|
||||
|
||||
// 重新给静止物体赋值速度
|
||||
if (relativeStatic()) {
|
||||
@@ -99,26 +95,6 @@ public class TrackObj {
|
||||
}
|
||||
}
|
||||
|
||||
private void calHeading() {
|
||||
//更正数据,速度小于LIMIT_SPEED使用上一帧数据
|
||||
// if (relativeStatic()) {
|
||||
// if (roadAngle != 0.0) {
|
||||
// CenterLine centerLine = CallerHDMapManager.INSTANCE.getCenterLineInfo(lon, lat, -1);
|
||||
// if (centerLine != null && centerLine.getAngle() != 0) {
|
||||
// cacheData = cacheData.toBuilder().setHeading(centerLine.getAngle()).build();
|
||||
// } else {
|
||||
// cacheData = cacheData.toBuilder().setHeading(circleQueue.getLastFrame().getHeading()).build();
|
||||
// }
|
||||
// } else {
|
||||
// cacheData = cacheData.toBuilder().setHeading(circleQueue.getLastFrame().getHeading()).build();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
public double getRecentlyTime() {
|
||||
return recentlyTime;
|
||||
}
|
||||
|
||||
public long getCellIdPos() {
|
||||
return s2CellId.pos();
|
||||
}
|
||||
@@ -161,12 +137,6 @@ public class TrackObj {
|
||||
}
|
||||
}
|
||||
|
||||
// public boolean isFourWheelType() {
|
||||
// return typeWeight != TrafficTypeEnum.TYPE_TRAFFIC_ID_PEOPLE.getType()
|
||||
// && typeWeight != TrafficTypeEnum.TYPE_TRAFFIC_ID_BICYCLE.getType()
|
||||
// && typeWeight != TrafficTypeEnum.TYPE_TRAFFIC_ID_MOTO.getType();
|
||||
// }
|
||||
|
||||
private double[] getCenterPoint(List<ObjQueue> objQueueList) {
|
||||
int total = objQueueList.size();
|
||||
double X = 0, Y = 0, Z = 0;
|
||||
@@ -196,12 +166,18 @@ public class TrackObj {
|
||||
return d;
|
||||
}
|
||||
|
||||
public void clear(){
|
||||
circleQueue.clear();
|
||||
s2CellId = null;
|
||||
s2LatLng = null;
|
||||
typeArray = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TrackObj{" +
|
||||
"circleQueue=" + circleQueue +
|
||||
", s2CellId=" + s2CellId +
|
||||
", recentlyTime=" + recentlyTime +
|
||||
", cacheData=" + cacheData +
|
||||
'}';
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.mogo.eagle.core.function.business.identify
|
||||
import android.annotation.SuppressLint
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig
|
||||
import com.mogo.eagle.core.data.enums.TrafficTypeEnum
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
|
||||
import mogo.telematics.pad.MessagePad.*
|
||||
|
||||
object TrackerSourceColorHelper {
|
||||
@@ -46,9 +47,9 @@ object TrackerSourceColorHelper {
|
||||
return ""
|
||||
}
|
||||
|
||||
if (isV2I(data).second) {
|
||||
color = "#00AEFFFF"
|
||||
}
|
||||
// if (isV2I(data).second) {
|
||||
// color = "#00AEFFFF"
|
||||
// }
|
||||
|
||||
//level : 2
|
||||
if (isObu(data).second) {
|
||||
@@ -62,9 +63,14 @@ object TrackerSourceColorHelper {
|
||||
}
|
||||
}
|
||||
|
||||
//融合结果 level : 1
|
||||
if (isFusion(data)) {
|
||||
color = "#9900ffFF"
|
||||
//僵尸车
|
||||
if(data.addAttribute == AdditionalAttribute.ATTR_ZOMBIE){
|
||||
color = "#AD7488FF"
|
||||
CallerMapUIServiceManager.getMapUIController()?.let {
|
||||
if(it.isDayMode){
|
||||
color = "#AE7887FF"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// pnc预警
|
||||
|
||||
@@ -139,6 +139,12 @@ object WarningHelper {
|
||||
}
|
||||
}
|
||||
|
||||
fun remove(key:String){
|
||||
pncWarningBeautyTrafficData.remove(key)
|
||||
pncWarningOriginTrafficData.remove(key)
|
||||
obuWarningTrafficData.remove(key)
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
pncWarningBeautyTrafficData.clear()
|
||||
pncWarningOriginTrafficData.clear()
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
package com.mogo.eagle.core.function.business.routeoverlay;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo;
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig;
|
||||
import com.mogo.eagle.core.data.config.HdMapBuildConfig;
|
||||
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.api.autopilot.IMoGoChassisLocationGCJ02Listener;
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoPlanningTrajectoryListener;
|
||||
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.map.CallerMapLocationListenerManager;
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningTrajectoryListenerManager;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@@ -23,7 +26,9 @@ import mogo_msg.MogoReportMsg;
|
||||
import system_master.SystemStatusInfo;
|
||||
|
||||
public class MogoRouteOverlayManager implements
|
||||
IMoGoAutopilotPlanningListener, IMoGoAutopilotStatusListener, IMoGoMapLocationListener {
|
||||
IMoGoPlanningTrajectoryListener,
|
||||
IMoGoAutopilotStatusListener,
|
||||
IMoGoChassisLocationGCJ02Listener {
|
||||
private static volatile MogoRouteOverlayManager sInstance;
|
||||
private static final String TAG = "Route";
|
||||
|
||||
@@ -32,13 +37,14 @@ public class MogoRouteOverlayManager implements
|
||||
|
||||
private final LinkedList<List<MessagePad.TrajectoryPoint>> queue = new LinkedList<>();
|
||||
|
||||
private MogoRouteOverlayManager() {}
|
||||
private MogoRouteOverlayManager() {
|
||||
}
|
||||
|
||||
|
||||
public void init() {
|
||||
CallerAutopilotPlanningListenerManager.INSTANCE.addListener(TAG, this);
|
||||
CallerPlanningTrajectoryListenerManager.INSTANCE.addListener(TAG, this);
|
||||
CallerAutoPilotStatusListenerManager.INSTANCE.addListener(TAG, this);
|
||||
CallerMapLocationListenerManager.INSTANCE.addListener(TAG, this, false);
|
||||
CallerChassisLocationGCJ02ListenerManager.INSTANCE.addListener(TAG, 20,this);
|
||||
}
|
||||
|
||||
public static MogoRouteOverlayManager getInstance() {
|
||||
@@ -61,8 +67,8 @@ public class MogoRouteOverlayManager implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(@org.jetbrains.annotations.Nullable MogoLocation location, int from, boolean isGps) {
|
||||
if (from != 1 || location == null) {
|
||||
public void onChassisLocationGCJ02(@Nullable MogoLocation gnssInfo) {
|
||||
if (gnssInfo == null) {
|
||||
return;
|
||||
}
|
||||
if (isArriveAtStation.get() && autopilotMode.get() != 1) {
|
||||
@@ -78,16 +84,12 @@ public class MogoRouteOverlayManager implements
|
||||
if (!queue.isEmpty()) {
|
||||
List<MessagePad.TrajectoryPoint> items = queue.pollLast();
|
||||
if (items != null && !items.isEmpty()) {
|
||||
RouteOverlayDrawer.getInstance().drawTrajectoryList(items, location.getBearing());
|
||||
RouteOverlayDrawer.getInstance().drawTrajectoryList(items, gnssInfo.getHeading());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutopilotRotting(MessagePad.GlobalPathResp globalPathResp) {}
|
||||
|
||||
|
||||
@Override
|
||||
public void onAutopilotStatusResponse(@NotNull AutopilotStatusInfo autoPilotStatusInfo) {
|
||||
int mode = autoPilotStatusInfo.getPilotmode();
|
||||
@@ -102,6 +104,9 @@ public class MogoRouteOverlayManager implements
|
||||
if (arrivalNotification == null) {
|
||||
return;
|
||||
}
|
||||
if(!HdMapBuildConfig.isMapLoaded){
|
||||
return;
|
||||
}
|
||||
if (!isArriveAtStation.get()) {
|
||||
isArriveAtStation.set(true);
|
||||
}
|
||||
@@ -123,7 +128,8 @@ public class MogoRouteOverlayManager implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutopilotStatusRespByQuery(@NonNull SystemStatusInfo.StatusInfo status) {}
|
||||
public void onAutopilotStatusRespByQuery(@NonNull SystemStatusInfo.StatusInfo status) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutopilotRouteLineId(long lineId) {
|
||||
|
||||
@@ -5,16 +5,20 @@ import android.graphics.Color;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.core.util.Pools;
|
||||
|
||||
import com.mogo.eagle.core.data.map.MogoLatLng;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager;
|
||||
import com.mogo.eagle.core.utilcode.util.DrivingDirectionUtils;
|
||||
import com.mogo.map.MogoOverlayManager;
|
||||
import com.mogo.map.overlay.IMogoOverlayManager;
|
||||
import com.mogo.map.overlay.IMogoPolyline;
|
||||
import com.mogo.map.overlay.MogoPolylineOptions;
|
||||
import com.mogo.commons.utils.DrivingDirectionUtils;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import mogo.telematics.pad.MessagePad;
|
||||
|
||||
public class RouteOverlayDrawer {
|
||||
@@ -128,8 +132,8 @@ public class RouteOverlayDrawer {
|
||||
pps.add(acquire);
|
||||
RouteStrategy.INSTANCE.check(route.getVelocity(), route.getAcceleration(), routeList.size());
|
||||
}
|
||||
double lon = CallerAutoPilotStatusListenerManager.INSTANCE.getCurWgs84Lon();
|
||||
double lat = CallerAutoPilotStatusListenerManager.INSTANCE.getCurWgs84Lat();
|
||||
double lon = CallerChassisLocationWGS84ListenerManager.INSTANCE.getChassisLocationWGS84().getLongitude();
|
||||
double lat = CallerChassisLocationWGS84ListenerManager.INSTANCE.getChassisLocationWGS84().getLatitude();
|
||||
if (points.size() > 0) {
|
||||
MogoLatLng top = null;
|
||||
while (points.size() != 0) {
|
||||
@@ -140,8 +144,8 @@ public class RouteOverlayDrawer {
|
||||
if (first == top) {
|
||||
break;
|
||||
}
|
||||
lon = CallerAutoPilotStatusListenerManager.INSTANCE.getCurWgs84Lon();
|
||||
lat = CallerAutoPilotStatusListenerManager.INSTANCE.getCurWgs84Lat();
|
||||
lon = CallerChassisLocationWGS84ListenerManager.INSTANCE.getChassisLocationWGS84().getLongitude();
|
||||
lat = CallerChassisLocationWGS84ListenerManager.INSTANCE.getChassisLocationWGS84().getLatitude();
|
||||
long angle = isPointOnCarFront(lon, lat, bearing, first.lon, first.lat);
|
||||
if (angle >= 90) {
|
||||
RouteStrategy.INSTANCE.remove(first.acc);
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
package com.mogo.eagle.core.function.business.routeoverlay
|
||||
|
||||
import android.animation.*
|
||||
import android.graphics.*
|
||||
import android.view.animation.*
|
||||
import com.mogo.eagle.core.data.config.*
|
||||
import com.mogo.eagle.core.utilcode.mogo.*
|
||||
import android.animation.ArgbEvaluator
|
||||
import android.graphics.Color
|
||||
import android.view.animation.AccelerateInterpolator
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig
|
||||
import com.mogo.eagle.core.data.config.HmiBuildConfig
|
||||
import com.mogo.eagle.core.function.business.routeoverlay.Colors.Companion.COLOR_BLUE
|
||||
import com.mogo.eagle.core.function.business.routeoverlay.Colors.Companion.COLOR_BLUE_DARK
|
||||
import com.mogo.eagle.core.function.business.routeoverlay.Colors.Companion.COLOR_RED_DARK
|
||||
import com.mogo.eagle.core.function.business.routeoverlay.Colors.Companion.COLOR_TRANSPARENT
|
||||
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
|
||||
interface IStrategy {
|
||||
@@ -22,26 +23,31 @@ class Colors {
|
||||
companion object {
|
||||
val COLOR_BLUE = Color.parseColor("#FF2ABAD9")
|
||||
val COLOR_BLUE_DARK = Color.parseColor("#FF074EFF")
|
||||
val COLOR_RED_DARK = Color.parseColor("#FFFF5F00")
|
||||
val COLOR_TRANSPARENT = Color.parseColor("#002ABAD9")
|
||||
val COLOR_RED_DARK = Color.parseColor("#FFFF5F00")
|
||||
val COLOR_TRANSPARENT = Color.parseColor("#002ABAD9")
|
||||
}
|
||||
}
|
||||
|
||||
sealed class Strategy: IStrategy
|
||||
sealed class Strategy : IStrategy
|
||||
|
||||
class DefaultStrategy(private val colors: List<Int>? = null): Strategy() {
|
||||
class DefaultStrategy(private val colors: List<Int>? = null) : Strategy() {
|
||||
|
||||
override fun getColors(): List<Int> = colors ?: listOf(COLOR_BLUE, COLOR_TRANSPARENT)
|
||||
}
|
||||
|
||||
class ColorfulStrategy(private val colors: List<Int> = emptyList(), var isLightOn: Boolean): Strategy() {
|
||||
class ColorfulStrategy(private val colors: List<Int> = emptyList(), var isLightOn: Boolean) :
|
||||
Strategy() {
|
||||
override fun getColors(): List<Int> = colors
|
||||
}
|
||||
|
||||
object RouteStrategy {
|
||||
|
||||
@Volatile
|
||||
private var isEnable = !AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)
|
||||
private var isEnable by Delegates.observable(HmiBuildConfig.isShowRouteStrategy) { _, _, newValue ->
|
||||
if (!newValue) {
|
||||
strategy = null
|
||||
colors.clear()
|
||||
}
|
||||
}
|
||||
|
||||
private var strategy: Strategy? = null
|
||||
|
||||
@@ -57,14 +63,6 @@ object RouteStrategy {
|
||||
|
||||
private var hasLessThan0 = false
|
||||
|
||||
fun enable(enable: Boolean) {
|
||||
isEnable = enable
|
||||
if (!enable) {
|
||||
strategy = null
|
||||
colors.clear()
|
||||
}
|
||||
}
|
||||
|
||||
fun start() {
|
||||
if (sorted.isEmpty()) {
|
||||
fill()
|
||||
@@ -89,7 +87,7 @@ object RouteStrategy {
|
||||
}
|
||||
|
||||
fun check(speed: Double, acc: Double, total: Int) {
|
||||
if (!isEnable){
|
||||
if (!isEnable) {
|
||||
return
|
||||
}
|
||||
if (sorted.isEmpty()) {
|
||||
@@ -112,7 +110,11 @@ object RouteStrategy {
|
||||
} else {
|
||||
if (endEvaluator != null) {
|
||||
val fraction = (index - last) * 1.0f / delta
|
||||
colors += endEvaluator!!.evaluate(fraction, startColor, COLOR_TRANSPARENT) as Int
|
||||
colors += endEvaluator!!.evaluate(
|
||||
fraction,
|
||||
startColor,
|
||||
COLOR_TRANSPARENT
|
||||
) as Int
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -156,11 +158,14 @@ object RouteStrategy {
|
||||
total = endValue - startValue
|
||||
while (current <= endValue) {
|
||||
val fraction = (current - startValue) / total
|
||||
val colorValue = evaluator.evaluate(fraction.toFloat(), COLOR_BLUE, COLOR_BLUE_DARK) as Int
|
||||
val colorValue =
|
||||
evaluator.evaluate(fraction.toFloat(), COLOR_BLUE, COLOR_BLUE_DARK) as Int
|
||||
sorted[current] = colorValue
|
||||
current += step
|
||||
}
|
||||
}
|
||||
|
||||
fun getStrategy(): Strategy = if (isEnable) { (strategy ?: DefaultStrategy()) } else DefaultStrategy()
|
||||
fun getStrategy(): Strategy = if (isEnable) {
|
||||
(strategy ?: DefaultStrategy())
|
||||
} else DefaultStrategy()
|
||||
}
|
||||
@@ -1,27 +1,19 @@
|
||||
package com.mogo.eagle.core.function.impl;
|
||||
|
||||
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.map.IMogoMapService;
|
||||
import com.mogo.eagle.core.function.api.map.marker.IMogoMarkerService;
|
||||
import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager;
|
||||
import com.mogo.map.MogoGeoSearch;
|
||||
import com.mogo.map.MogoLocationClient;
|
||||
import com.mogo.map.MogoMapUIController;
|
||||
import com.mogo.map.MogoMarkerManager;
|
||||
import com.mogo.map.MogoOverlayManager;
|
||||
import com.mogo.map.MogoPoiSearch;
|
||||
import com.mogo.map.MogoTrafficSearch;
|
||||
import com.mogo.map.listener.IMogoHosListenerRegister;
|
||||
import com.mogo.map.listener.MogoHosListenerRegister;
|
||||
import com.mogo.map.location.IMogoLocationClient;
|
||||
import com.mogo.map.location.GDLocationClient;
|
||||
import com.mogo.map.location.IMogoGDLocationClient;
|
||||
import com.mogo.map.marker.IMogoMarkerManager;
|
||||
import com.mogo.map.overlay.IMogoOverlayManager;
|
||||
import com.mogo.map.search.geo.IMogoGeoSearch;
|
||||
import com.mogo.map.search.poisearch.IMogoPoiSearch;
|
||||
import com.mogo.map.search.poisearch.query.MogoPoiSearchQuery;
|
||||
import com.mogo.map.search.traffic.IMogoTrafficSearch;
|
||||
import com.mogo.map.uicontroller.IMogoMapUIController;
|
||||
|
||||
/**
|
||||
@@ -33,21 +25,6 @@ import com.mogo.map.uicontroller.IMogoMapUIController;
|
||||
@Route(path = MogoServicePaths.PATH_SERVICES_MAP)
|
||||
public class MogoMapService implements IMogoMapService {
|
||||
|
||||
@Override
|
||||
public IMogoLocationClient getSingletonLocationClient(Context context) {
|
||||
return MogoLocationClient.getInstance(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMogoGeoSearch getGeoSearch(Context context) {
|
||||
return new MogoGeoSearch(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMogoPoiSearch getPoiSearch(Context context, MogoPoiSearchQuery query) {
|
||||
return new MogoPoiSearch(context, query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMogoMarkerManager getMarkerManager(Context context) {
|
||||
return MogoMarkerManager.getInstance(context);
|
||||
@@ -64,22 +41,16 @@ public class MogoMapService implements IMogoMapService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMogoHosListenerRegister getHostListenerRegister() {
|
||||
return MogoHosListenerRegister.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMogoOverlayManager getOverlayManager(Context context) {
|
||||
public IMogoOverlayManager getOverlayManager() {
|
||||
return MogoOverlayManager.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMogoTrafficSearch getTrafficSearchApi() {
|
||||
return new MogoTrafficSearch();
|
||||
public IMogoGDLocationClient getGDLocationServer(Context context) {
|
||||
return GDLocationClient.getInstance(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
CallerVisualAngleManager.INSTANCE.init(context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.mogo.eagle.core.function.impl;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.mogo.eagle.core.data.map.MogoLatLng;
|
||||
@@ -11,10 +9,8 @@ import com.mogo.eagle.core.function.api.map.marker.IMogoMarkerService;
|
||||
import com.mogo.eagle.core.function.impl.marker.drawer.MarkerDrawer;
|
||||
import com.mogo.eagle.core.function.impl.marker.drawer.TrafficMarkerDrawer;
|
||||
import com.mogo.eagle.core.function.impl.marker.drawer.V2XWarnDataDrawer;
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
|
||||
import com.mogo.map.marker.IMogoMarker;
|
||||
|
||||
|
||||
public class MogoMarkerServiceImpl implements IMogoMarkerService {
|
||||
|
||||
private static volatile MogoMarkerServiceImpl sInstance;
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.mogo.eagle.core.function.impl.marker.drawer;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.mogo.cloud.commons.utils.CoordinateUtils;
|
||||
import com.mogo.commons.AbsMogoApplication;
|
||||
import com.mogo.commons.module.status.MogoStatusManager;
|
||||
import com.mogo.eagle.core.data.enums.EventTypeEnumNew;
|
||||
@@ -16,6 +15,7 @@ import com.mogo.eagle.core.function.impl.marker.view.EmptyMarkerView;
|
||||
import com.mogo.eagle.core.function.impl.marker.view.IMarkerView;
|
||||
import com.mogo.eagle.core.function.impl.marker.view.MapMarkerAdapter;
|
||||
import com.mogo.eagle.core.function.impl.marker.view.OnlineCarMarkerView;
|
||||
import com.mogo.eagle.core.utilcode.util.CoordinateUtils;
|
||||
import com.mogo.map.MogoMarkerManager;
|
||||
import com.mogo.map.marker.IMogoMarker;
|
||||
import com.mogo.map.marker.IMogoMarkerClickListener;
|
||||
|
||||
@@ -55,10 +55,14 @@ public class V2XWarnDataDrawer extends BaseDrawer {
|
||||
IMogoMarker marker = drawMarker(markerShowEntity, modeResType(type));
|
||||
// marker.addDynamicAnchorPosition(new MogoLatLng(collisionlat, collisionLon), (float) heading, showTime * 1000);
|
||||
UiThreadHandler.postDelayed(marker::remove, showTime * 1000);
|
||||
|
||||
}
|
||||
|
||||
//根据识别物类型 (行人1/自行车2/摩托车4/骑行车辆11)获取3D模型(对应查看getModelRes)
|
||||
/**
|
||||
* 根据识别物类型 (行人1/自行车2/摩托车4/骑行车辆11)获取3D模型(对应查看getModelRes)
|
||||
*
|
||||
* @param dataType 数据类型
|
||||
* @return 做完映射后的数据类型
|
||||
*/
|
||||
private int modeResType(int dataType) {
|
||||
switch (dataType) {
|
||||
case 1:
|
||||
@@ -72,6 +76,13 @@ public class V2XWarnDataDrawer extends BaseDrawer {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制3D元素
|
||||
*
|
||||
* @param markerShowEntity 要展示的3d数据类型
|
||||
* @param modeResType
|
||||
* @return
|
||||
*/
|
||||
public IMogoMarker drawMarker(MarkerShowEntity markerShowEntity, int modeResType) {
|
||||
MogoMarkerOptions options = new MogoMarkerOptions()
|
||||
.data(markerShowEntity)
|
||||
@@ -90,6 +101,13 @@ public class V2XWarnDataDrawer extends BaseDrawer {
|
||||
return marker;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制箭头
|
||||
* @param location
|
||||
* @param markerType
|
||||
* @param type
|
||||
* @param rotate
|
||||
*/
|
||||
public void drawerArrowsMarkerWithLocation(MogoLatLng location, String markerType, int type, int rotate) {
|
||||
MogoMarkerOptions options = new MogoMarkerOptions()
|
||||
.latitude(location.getLat())
|
||||
|
||||
@@ -1,364 +0,0 @@
|
||||
package com.mogo.eagle.core.function.map;
|
||||
|
||||
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_MAP;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.alibaba.android.arouter.facade.annotation.Route;
|
||||
import com.mogo.commons.AbsMogoApplication;
|
||||
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.business.ai.AiCloudIdentifyDataManager;
|
||||
import com.mogo.eagle.core.function.business.identify.MapIdentifySubscriber;
|
||||
import com.mogo.eagle.core.function.business.MapPointCloudSubscriber;
|
||||
import com.mogo.eagle.core.function.business.routeoverlay.MogoRouteOverlayManager;
|
||||
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.ViewModelExtKt;
|
||||
import com.mogo.eagle.core.function.overview.vm.OverViewModel;
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
|
||||
import com.mogo.map.IMogoMap;
|
||||
import com.mogo.map.IMogoUiSettings;
|
||||
import com.mogo.map.MogoMapView;
|
||||
import com.mogo.map.uicontroller.IMogoMapUIController;
|
||||
import com.zhidaoauto.map.sdk.open.MapAutoApi;
|
||||
import com.zhidaoauto.map.sdk.open.business.PointCloudHelper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import mogo.telematics.pad.MessagePad;
|
||||
|
||||
/**
|
||||
* @author donghongyu
|
||||
* @since 2021-11-09
|
||||
* 高精度地图层UI
|
||||
* <p>
|
||||
* 地图图层,地图操作都在这个图层完成
|
||||
*/
|
||||
@Route(path = MoGoFragmentPaths.PATH_FRAGMENT_MAP)
|
||||
public class MapFragment extends MvpFragment<MapView, MapPresenter>
|
||||
implements MapView, IMoGoMapFragmentProvider, IMoGoSkinModeChangeListener {
|
||||
|
||||
private static final String TAG = "MapFragment";
|
||||
|
||||
private MogoMapView mMogoMapView;
|
||||
private IMogoMap mMogoMap;
|
||||
|
||||
private final boolean mIsControllerByOthersStatus = false;
|
||||
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
return R.layout.module_map_fragment_map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTagName() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initViews() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stepInVrMode(boolean isDayMode) {
|
||||
try {
|
||||
if (mMogoMapView != null && mMogoMapView.getMap() != null && mMogoMapView.getMap().getUIController() != null) {
|
||||
mMogoMapView.getMap().getUIController().stepInVrMode(isDayMode);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
// do not implement
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initViews(Bundle savedInstanceState) {
|
||||
super.initViews(savedInstanceState);
|
||||
mMogoMapView = findViewById(R.id.module_map_id_map);
|
||||
mMogoMapView.onCreate(savedInstanceState);
|
||||
mMogoMap = mMogoMapView.getMap();
|
||||
if (mMogoMap != null) {
|
||||
mMogoMap.getUIController().showMyLocation(true);
|
||||
}
|
||||
// 添加换肤监听
|
||||
CallerSkinModeListenerManager.INSTANCE.addListener(TAG, this);
|
||||
CallerAutopilotPlanningListenerManager.INSTANCE.addListener(TAG, moGoAutopilotPlanningListener);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected MapPresenter createPresenter() {
|
||||
return new MapPresenter(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
initMapView();
|
||||
queryInfStructure();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
if (mMogoMapView != null) {
|
||||
mMogoMapView.onSaveInstanceState(outState);
|
||||
} else {
|
||||
CallerLogger.INSTANCE.e(M_MAP + TAG, "mMogoMapView is null");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
if (mIsControllerByOthersStatus) {
|
||||
return;
|
||||
}
|
||||
if (mMogoMapView != null) {
|
||||
mMogoMapView.onPause();
|
||||
} else {
|
||||
CallerLogger.INSTANCE.e(M_MAP + TAG, "mMogoMapView is null");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (mIsControllerByOthersStatus) {
|
||||
return;
|
||||
}
|
||||
if (mMogoMapView != null) {
|
||||
mMogoMapView.onResume();
|
||||
} else {
|
||||
CallerLogger.INSTANCE.e(M_MAP + TAG, "mMogoMapView is null");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
if (mMogoMapView != null) {
|
||||
mMogoMapView.onLowMemory();
|
||||
} else {
|
||||
CallerLogger.INSTANCE.e(M_MAP + TAG, "mMogoMapView is null");
|
||||
}
|
||||
}
|
||||
|
||||
private void initMapView() {
|
||||
mMogoMap = mMogoMapView.getMap();
|
||||
if (mMogoMap == null) {
|
||||
return;
|
||||
}
|
||||
IMogoUiSettings uiSettings = mMogoMap.getUiSettings();
|
||||
if (uiSettings != null) {
|
||||
//设置所有手势是否可用
|
||||
uiSettings.setAllGesturesEnabled(true);
|
||||
//设置指南针是否可见。
|
||||
uiSettings.setCompassEnabled(false);
|
||||
//设置室内地图楼层切换控件是否可见。
|
||||
uiSettings.setIndoorSwitchEnabled(true);
|
||||
//设置定位按钮是否可见。
|
||||
uiSettings.setMyLocationButtonEnabled(false);
|
||||
//设置旋转手势是否可用。
|
||||
uiSettings.setRotateGesturesEnabled(false);
|
||||
//设置比例尺控件是否可见
|
||||
uiSettings.setScaleControlsEnabled(true);
|
||||
//设置拖拽手势是否可用。
|
||||
uiSettings.setScrollGesturesEnabled(true);
|
||||
//设置倾斜手势是否可用。
|
||||
uiSettings.setTiltGesturesEnabled(true);
|
||||
//设置缩放按钮是否可见。
|
||||
uiSettings.setZoomControlsEnabled(false);
|
||||
//设置双指缩放手势是否可用。
|
||||
uiSettings.setZoomGesturesEnabled(true);
|
||||
}
|
||||
|
||||
// TODO 临时初始化地图监听工控机、OBU等数据监听器,用于感知元素绘制
|
||||
MapIdentifySubscriber.Companion.getInstance();
|
||||
MogoRouteOverlayManager.getInstance().init();
|
||||
MapPointCloudSubscriber.Companion.getInstance();
|
||||
AiCloudIdentifyDataManager.Companion.getAiCloudIdentifyDataManager().init(AbsMogoApplication.getApp());
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
private final IMoGoAutopilotPlanningListener moGoAutopilotPlanningListener = new IMoGoAutopilotPlanningListener() {
|
||||
|
||||
@Override
|
||||
public void onAutopilotRotting(@Nullable MessagePad.GlobalPathResp globalPathResp) {
|
||||
UiThreadHandler.post(() -> {
|
||||
InfStructureManager.INSTANCE.savePlanningData(globalPathResp.getWayPointsList());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutopilotTrajectory(@NonNull List<MessagePad.TrajectoryPoint> trajectoryInfos) {}
|
||||
};
|
||||
|
||||
@Override
|
||||
public IMogoMapUIController getUIController() {
|
||||
return mMogoMap.getUIController();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
CallerSkinModeListenerManager.INSTANCE.removeListener(TAG);
|
||||
CallerAutopilotPlanningListenerManager.INSTANCE.removeListener(TAG);
|
||||
if (mMogoMapView != null) {
|
||||
mMogoMapView.onDestroy();
|
||||
mMogoMapView = null;
|
||||
mMogoMap = null;
|
||||
} else {
|
||||
CallerLogger.INSTANCE.e(M_MAP + TAG, "mMogoMapView is null");
|
||||
}
|
||||
super.onDestroyView();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getFunctionName() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeMaoViewAngle(int type) {
|
||||
if (mMogoMapView != null && mMogoMapView.getMap() != null && mMogoMapView.getMap().getUIController() != null) {
|
||||
mMogoMapView.getMap().getUIController().changeMapViewAngle(type);
|
||||
} else {
|
||||
CallerLogger.INSTANCE.e(M_MAP + TAG, "mMogoMapView is null");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeCurrentIcon(int iconId) {
|
||||
if (mMogoMapView != null && mMogoMapView.getMap() != null && mMogoMapView.getMap().getUIController() != null) {
|
||||
mMogoMapView.getMap().getUIController().changeCurrentIcon(iconId);
|
||||
} else {
|
||||
CallerLogger.INSTANCE.e(M_MAP + TAG, "mMogoMapView is null");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sight mode
|
||||
*
|
||||
* @param mode
|
||||
*/
|
||||
public static final int SIGHT_MODE_NORMAL = 0;
|
||||
public static final int SIGHT_MODE_TOP = 1;
|
||||
public static final int SIGHT_MODE_BACK = 2;
|
||||
public static final int SIGHT_MODE_CROSS = 3;
|
||||
public static final int SIGHT_MODE_FAR = 4;
|
||||
|
||||
@Override
|
||||
public void setMapDAngle(int mode) {
|
||||
float angle = getSightModeAngle(mode);
|
||||
if (mMogoMapView != null && mMogoMapView.getMap() != null && mMogoMapView.getMap().getUIController() != null) {
|
||||
mMogoMapView.getMap().getUIController().setMapDAngle(angle);
|
||||
} else {
|
||||
CallerLogger.INSTANCE.e(M_MAP + TAG, "mMogoMapView is null");
|
||||
}
|
||||
}
|
||||
|
||||
private float getSightModeAngle(int mode) {
|
||||
float angle = 0.0f;
|
||||
switch (mode) {
|
||||
case SIGHT_MODE_NORMAL:
|
||||
angle = 16.5f;
|
||||
case SIGHT_MODE_TOP:
|
||||
angle = 16.5f;
|
||||
case SIGHT_MODE_BACK:
|
||||
angle = 16.5f;
|
||||
case SIGHT_MODE_CROSS:
|
||||
angle = 16.5f;
|
||||
case SIGHT_MODE_FAR:
|
||||
angle = 16.5f;
|
||||
}
|
||||
return angle;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public CenterLine getCenterLineInfo(double lon, double lat, float angle) {
|
||||
if (mMogoMapView != null && mMogoMapView.getMap() != null && mMogoMapView.getMap().getUIController() != null) {
|
||||
return mMogoMapView.getMap().getUIController().getCenterLineInfo(lon, lat, angle);
|
||||
} else {
|
||||
CallerLogger.INSTANCE.e(M_MAP + TAG, "mMogoMapView is null");
|
||||
return null; //上层使用应该判空
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSkinModeChange(int skinMode) {
|
||||
if (skinMode == 0) {
|
||||
CallerHDMapManager.INSTANCE.stepInVrMode(false);
|
||||
} else if (skinMode == 1) {
|
||||
CallerHDMapManager.INSTANCE.stepInVrMode(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPointCloudSize(float pointCloudSize) {
|
||||
//设置点云大小
|
||||
PointCloudHelper.INSTANCE.setPointCloudSize(pointCloudSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPointCloudColor(@NonNull String color) {
|
||||
// 设置点云颜色
|
||||
PointCloudHelper.INSTANCE.setPointCloudColor(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsDrawPointCloud(boolean isDrawPointCloud) {
|
||||
try {
|
||||
// 是否绘制点云
|
||||
PointCloudHelper.INSTANCE.setIsDrawPointCloud(isDrawPointCloud);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置地图是否是Debug模式
|
||||
* @param debugMode 是否开启Debug模式
|
||||
*/
|
||||
@Override
|
||||
public void setDebugMode(boolean debugMode) {
|
||||
MapAutoApi.INSTANCE.setDebugMode(debugMode);
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package com.mogo.eagle.core.function.map;
|
||||
|
||||
import com.mogo.commons.mvp.Presenter;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-12-23
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public class MapPresenter extends Presenter<MapView> {
|
||||
|
||||
private static final String TAG = "MapPresenter";
|
||||
|
||||
public MapPresenter(MapView view) {
|
||||
super(view);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package com.mogo.eagle.core.function.map;
|
||||
|
||||
import com.mogo.commons.mvp.IView;
|
||||
import com.mogo.map.uicontroller.IMogoMapUIController;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-12-23
|
||||
* <p>
|
||||
* 地图view
|
||||
*/
|
||||
public interface MapView extends IView {
|
||||
|
||||
/**
|
||||
* 地图控制接口
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
IMogoMapUIController getUIController();
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
package com.mogo.eagle.core.function.overview
|
||||
|
||||
import com.mogo.eagle.core.data.map.Infrastructure
|
||||
import mogo.telematics.pad.MessagePad
|
||||
|
||||
/**
|
||||
* 本地数据库查询出来的红绿灯、摄像头等数据
|
||||
*/
|
||||
object InfStructureManager {
|
||||
|
||||
// 每个GeoHash网格对应的新基建Bean
|
||||
private val _infMap by lazy {
|
||||
HashMap<String, ArrayList<Infrastructure>>()
|
||||
}
|
||||
|
||||
// 全局路径规划中所有点的GeoHash网格对应的新基建数据集合
|
||||
private val _pathMap by lazy {
|
||||
HashMap<String, ArrayList<Infrastructure>>()
|
||||
}
|
||||
|
||||
private val _planningList by lazy {
|
||||
ArrayList<MessagePad.Location>()
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
fun savePlanningData(planningList: List<MessagePad.Location>) {
|
||||
if (_planningList.isNotEmpty()) {
|
||||
_planningList.clear()
|
||||
}
|
||||
_planningList.addAll(planningList)
|
||||
}
|
||||
|
||||
fun getPlanningData() = _planningList
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package com.mogo.eagle.core.function.overview
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import com.mogo.eagle.core.data.map.Infrastructure
|
||||
|
||||
@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)
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package com.mogo.eagle.core.function.overview
|
||||
|
||||
import android.content.Context
|
||||
import androidx.room.Database
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import com.mogo.eagle.core.data.map.Infrastructure
|
||||
|
||||
@Database(entities = [Infrastructure::class], version = 2, 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 val MIGRATION_1_2 = object : Migration(1, 2) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
.addMigrations(MIGRATION_1_2)
|
||||
.fallbackToDestructiveMigration()
|
||||
.build()
|
||||
}
|
||||
return db!!
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
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)
|
||||
@@ -1,39 +0,0 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.mogo.eagle.core.function.overview.remote
|
||||
|
||||
import io.reactivex.Observable
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Query
|
||||
|
||||
interface OverViewServiceApi {
|
||||
|
||||
@GET("/eagleEye-mis/config/queryV2NInformation")
|
||||
fun queryAllV2XEventsByLineId(@Query("lineId") lineId: String, @Query("sn") sn: String): Observable<V2XEventResult>
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
package com.mogo.eagle.core.function.overview.remote
|
||||
|
||||
import androidx.annotation.Keep
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.mogo.eagle.core.data.BaseData
|
||||
|
||||
|
||||
@Keep
|
||||
data class V2XEventResult (
|
||||
@SerializedName("result")
|
||||
var result: Result?
|
||||
): BaseData()
|
||||
|
||||
@Keep
|
||||
data class Result(
|
||||
@SerializedName("eventList")
|
||||
var v2XEventList: List<V2XEvent>?
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class V2XEvent(
|
||||
@SerializedName("receiveTime")
|
||||
var receiveTime: Long,
|
||||
|
||||
@SerializedName("detectTime")
|
||||
var detectTime: Long,
|
||||
|
||||
@SerializedName("id")
|
||||
var id: String?,
|
||||
|
||||
@SerializedName("center")
|
||||
var center: Center?,
|
||||
|
||||
@SerializedName("centerRoad")
|
||||
var centerRoad: CenterRoad?,
|
||||
|
||||
@SerializedName("radius")
|
||||
var radius: Double,
|
||||
|
||||
@SerializedName("poiType")
|
||||
var poiType: String?,
|
||||
|
||||
@SerializedName("coordinateType")
|
||||
var coordinateType:Int? = null
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class Center(
|
||||
@SerializedName("lat")
|
||||
var lat: Double,
|
||||
|
||||
@SerializedName("lon")
|
||||
var lon: Double
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class CenterRoad(
|
||||
@SerializedName("bearing")
|
||||
var bearing: Double,
|
||||
|
||||
@SerializedName("laneNo")
|
||||
var laneNo: Long,
|
||||
|
||||
@SerializedName("roadId")
|
||||
var roadId: String?,
|
||||
|
||||
@SerializedName("roadName")
|
||||
var roadName: String?,
|
||||
|
||||
@SerializedName("tileId")
|
||||
var tileId: Long
|
||||
)
|
||||
@@ -1,141 +0,0 @@
|
||||
package com.mogo.eagle.core.function.overview.vm
|
||||
|
||||
import androidx.lifecycle.*
|
||||
import com.mogo.commons.constants.HostConst
|
||||
import com.mogo.eagle.core.data.map.Infrastructure
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.getAutoPilotStatusInfo
|
||||
import com.mogo.eagle.core.function.overview.OverviewDao
|
||||
import com.mogo.eagle.core.function.overview.remote.OverViewServiceApi
|
||||
import com.mogo.eagle.core.function.overview.remote.V2XEvent
|
||||
import com.mogo.eagle.core.network.MoGoRetrofitFactory
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class OverViewModel(
|
||||
private val overviewDao: OverviewDao
|
||||
) : ViewModel() {
|
||||
private val _infStructures = MutableLiveData<List<Infrastructure>>()
|
||||
private val _V2XEvents = MutableLiveData<List<V2XEvent>>()
|
||||
private var disposable: Disposable? = null
|
||||
|
||||
companion object {
|
||||
const val TAG = "OverViewModel"
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getAllV2XEventsByLineId(sn: String) {
|
||||
if (disposable != null && !disposable!!.isDisposed) {
|
||||
disposable!!.dispose()
|
||||
}
|
||||
|
||||
// 1分钟查询一次
|
||||
disposable = Observable.interval(2000, 60000, TimeUnit.MILLISECONDS)
|
||||
.flatMap {
|
||||
val lineId = getLineId()
|
||||
if (lineId > 0) {
|
||||
MoGoRetrofitFactory.getInstance(HostConst.getHost())
|
||||
.create(OverViewServiceApi::class.java)
|
||||
.queryAllV2XEventsByLineId(lineId.toString(), sn)
|
||||
.map {
|
||||
if (it.code == 200 || it.code == 0) {
|
||||
CallerLogger.d(SceneConstant.M_MAP + TAG, "请求成功,size为:${it.result?.v2XEventList?.size}")
|
||||
return@map it.result?.v2XEventList
|
||||
} else {
|
||||
CallerLogger.d(SceneConstant.M_MAP + TAG, "请求失败,code为:${it.code}")
|
||||
return@map ArrayList()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Observable.just(ArrayList())
|
||||
}
|
||||
}
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe {
|
||||
it?.apply {
|
||||
_V2XEvents.value = this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getV2XEventLiveData() = _V2XEvents
|
||||
|
||||
fun stopQueryV2XEvents() {
|
||||
disposable?.dispose()
|
||||
}
|
||||
|
||||
private fun getLineId(): Long {
|
||||
var lineId: Long = -1
|
||||
val parameter = getAutoPilotStatusInfo()
|
||||
.autopilotControlParameters
|
||||
if (parameter != null) {
|
||||
if (parameter.autoPilotLine != null) {
|
||||
lineId = parameter.autoPilotLine!!.lineId
|
||||
CallerLogger.d(SceneConstant.M_MAP + TAG, "lineId为:$lineId")
|
||||
} else {
|
||||
CallerLogger.d(SceneConstant.M_MAP + TAG, "parameter.autoPilotLine为null")
|
||||
}
|
||||
} else {
|
||||
CallerLogger.d(SceneConstant.M_MAP + TAG, "parameter为null")
|
||||
}
|
||||
return lineId
|
||||
}
|
||||
}
|
||||
@@ -1,555 +0,0 @@
|
||||
package com.mogo.eagle.core.function.smp;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
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.Nullable;
|
||||
|
||||
import com.amap.api.maps.AMap;
|
||||
import com.amap.api.maps.CameraUpdate;
|
||||
import com.amap.api.maps.CameraUpdateFactory;
|
||||
import com.amap.api.maps.TextureMapView;
|
||||
import com.amap.api.maps.UiSettings;
|
||||
import com.amap.api.maps.model.BitmapDescriptor;
|
||||
import com.amap.api.maps.model.BitmapDescriptorFactory;
|
||||
import com.amap.api.maps.model.CameraPosition;
|
||||
import com.amap.api.maps.model.CustomMapStyleOptions;
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.amap.api.maps.model.LatLngBounds;
|
||||
import com.amap.api.maps.model.Marker;
|
||||
import com.amap.api.maps.model.MarkerOptions;
|
||||
import com.amap.api.maps.model.Polyline;
|
||||
import com.amap.api.maps.model.PolylineOptions;
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig;
|
||||
import com.mogo.eagle.core.data.map.Infrastructure;
|
||||
import com.mogo.eagle.core.data.map.MogoLocation;
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotPlanningListener;
|
||||
import com.mogo.eagle.core.function.api.map.listener.IMoGoMapLocationListener;
|
||||
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.remote.Center;
|
||||
import com.mogo.eagle.core.function.overview.remote.V2XEvent;
|
||||
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils;
|
||||
import com.mogo.eagle.core.utilcode.mogo.MapAssetStyleUtils;
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
|
||||
|
||||
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 kotlin.Pair;
|
||||
import me.jessyan.autosize.utils.AutoSizeUtils;
|
||||
import mogo.telematics.pad.MessagePad;
|
||||
|
||||
/**
|
||||
* 小地图的方向View
|
||||
* 监听自动驾驶路径结束,结束高德地图导航
|
||||
*
|
||||
* @author donghongyu
|
||||
* @date 12/14/20 4:40 PM
|
||||
*/
|
||||
public class AMapCustomView
|
||||
extends RelativeLayout
|
||||
implements IMoGoMapLocationListener {
|
||||
public static final String TAG = "AMapCustomView";
|
||||
private TextureMapView mAMapView;
|
||||
private AMap mAMap;
|
||||
private int zoomLevel = 15;
|
||||
private CameraUpdate mCameraUpdate;
|
||||
private Context mContext;
|
||||
private float mTilt = 60f;
|
||||
private TextView overLayerView;
|
||||
private boolean calculate = false;
|
||||
|
||||
// 全局路径规划中的GeoHash网格
|
||||
private Map<String, ArrayList<Infrastructure>> pathMap = new HashMap();
|
||||
private Map<LatLng, ArrayList<Infrastructure>> posInfMap = new HashMap();
|
||||
|
||||
// =============绘制轨迹线相关=============
|
||||
private Marker mCarMarker;
|
||||
private Marker mCompassMarker;
|
||||
private Marker mStartMarker;
|
||||
private Marker mEndMarker;
|
||||
private Polyline mBottomPolyline;
|
||||
private Polyline mCoveredPolyline;
|
||||
// 计算索引并设置对应的Bitmap
|
||||
BitmapDescriptor arrivedBitmap;
|
||||
BitmapDescriptor unArrivedBitmap;
|
||||
// 绘制轨迹线的集合
|
||||
private List<BitmapDescriptor> textureList = new ArrayList<>();
|
||||
private List<Integer> texIndexList = new ArrayList<>();
|
||||
|
||||
private MogoLocation mLocation;
|
||||
private boolean isFirstLocation = true;
|
||||
CustomMapStyleOptions mCustomMapStyleOptions;
|
||||
|
||||
ArrayList<Marker> currMarkerList;
|
||||
|
||||
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);
|
||||
mAMapView = smpView.findViewById(R.id.aMapView);
|
||||
overLayerView = findViewById(R.id.overLayer);
|
||||
if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) {
|
||||
overLayerView.setBackground(getResources().getDrawable(R.drawable.amap_reset));
|
||||
arrivedBitmap = BitmapDescriptorFactory.fromResource(R.drawable.taxi_map_arrow_arrived);
|
||||
unArrivedBitmap = BitmapDescriptorFactory.fromResource(R.drawable.taxi_map_arrow_un_arrive);
|
||||
} else {
|
||||
overLayerView.setBackground(getResources().getDrawable(R.drawable.amap_reset_bus));
|
||||
arrivedBitmap = BitmapDescriptorFactory.fromResource(R.drawable.arrow_arrived_img);
|
||||
unArrivedBitmap = BitmapDescriptorFactory.fromResource(R.drawable.amap_bus_smooth_route);
|
||||
}
|
||||
CallerAutopilotPlanningListenerManager.INSTANCE.addListener(TAG, moGoAutopilotPlanningListener);
|
||||
initAMapView(context);
|
||||
// 注册定位监听
|
||||
CallerMapLocationListenerManager.INSTANCE.addListener(TAG, this, false);
|
||||
//设置全览模式
|
||||
overLayerView.setOnClickListener(v -> {
|
||||
displayCustomOverView();
|
||||
});
|
||||
}
|
||||
|
||||
private void initAMapView(Context context) {
|
||||
Log.d(TAG, "initAMapView");
|
||||
mCameraUpdate = CameraUpdateFactory.zoomTo(zoomLevel);
|
||||
mAMap = mAMapView.getMap();
|
||||
mCustomMapStyleOptions = new CustomMapStyleOptions();
|
||||
if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) {
|
||||
mCustomMapStyleOptions.setStyleData(MapAssetStyleUtils.getAssetsStyle(getContext(), "over_view_style.data"));
|
||||
mCustomMapStyleOptions.setStyleExtraData(MapAssetStyleUtils.getAssetsExtraStyle(getContext(), "over_view_style_extra.data"));
|
||||
} else {
|
||||
mCustomMapStyleOptions.setStyleData(MapAssetStyleUtils.getAssetsStyle(getContext(), "over_view_style_bus.data"));
|
||||
mCustomMapStyleOptions.setStyleExtraData(MapAssetStyleUtils.getAssetsExtraStyle(getContext(), "over_view_style_extra_bus.data"));
|
||||
}
|
||||
mAMap.setOnMapLoadedListener(() -> {
|
||||
Log.d(TAG, "---onMapLoaded---");
|
||||
if (mCustomMapStyleOptions != null) {
|
||||
// 加载自定义样式
|
||||
mCustomMapStyleOptions.setEnable(true);
|
||||
// 设置自定义样式
|
||||
mAMap.setCustomMapStyle(mCustomMapStyleOptions);
|
||||
}
|
||||
// 实时路况图层关闭,必须添加在loaded结束之后,其他位置不生效
|
||||
mAMap.setTrafficEnabled(false);
|
||||
});
|
||||
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() {
|
||||
if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) {
|
||||
mCarMarker = mAMap.addMarker(new MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.map_car_icon))
|
||||
.anchor(0.5f, 0.5f));
|
||||
mCompassMarker = mAMap.addMarker(new MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.amap_custom_corner))
|
||||
.anchor(0.5f, 0.5f));
|
||||
} else {
|
||||
mCarMarker = mAMap.addMarker(new MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.map_bus_icon))
|
||||
.anchor(0.5f, 0.5f));
|
||||
mCompassMarker = mAMap.addMarker(new MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.amap_bus_corner))
|
||||
.anchor(0.5f, 0.5f));
|
||||
}
|
||||
|
||||
mStartMarker = mAMap.addMarker(new MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.module_small_map_view_dir_start)));
|
||||
mEndMarker = mAMap.addMarker(new MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.module_small_map_view_dir_end)));
|
||||
}
|
||||
|
||||
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) {
|
||||
Log.d(TAG, "onAutopilotRotting");
|
||||
handlePlanningData(globalPathResp.getWayPointsList());
|
||||
}
|
||||
};
|
||||
|
||||
public void handlePlanningData(List<MessagePad.Location> locationList) {
|
||||
List list = locationList;
|
||||
// 转成高德坐标系并存储
|
||||
MarkerDrawerManager.INSTANCE.updateRoutePoints(list, mContext);
|
||||
List<LatLng> planningPointList = MarkerDrawerManager.INSTANCE.getPlanningPoints();
|
||||
UiThreadHandler.post(() -> {
|
||||
displayCustomOverView();
|
||||
drawStartAndEndMarker(planningPointList);
|
||||
});
|
||||
MarkerDrawerManager.INSTANCE.setCallback((points, locIndex) -> {
|
||||
// 每1s刷新一下轨迹线
|
||||
UiThreadHandler.post(() -> {
|
||||
if (points.size() > 0) {
|
||||
drawPolyline(points, locIndex);
|
||||
}
|
||||
});
|
||||
});
|
||||
MarkerDrawerManager.INSTANCE.startLoopCalCarLocation();
|
||||
UiThreadHandler.post(() -> {
|
||||
drawInfrastructureMarkers(locationList);
|
||||
});
|
||||
}
|
||||
|
||||
public void showV2XEventMarkers(List<V2XEvent> v2XEvents) {
|
||||
if (v2XEvents == null || v2XEvents.size() <= 0) return;
|
||||
clearV2XMarkers();
|
||||
ArrayList<MarkerOptions> markerOptionsList = new ArrayList<>();
|
||||
for (V2XEvent event : v2XEvents) {
|
||||
Center center = event.getCenter();
|
||||
if (center != null) {
|
||||
center.getLon();
|
||||
MarkerOptions markerOption = new MarkerOptions();
|
||||
LatLng latLng;
|
||||
if (event.getCoordinateType() == null || event.getCoordinateType() == 0) {
|
||||
latLng = new LatLng(center.getLat(), center.getLon());
|
||||
} else {
|
||||
// wgs84坐标系需转成高德坐标系
|
||||
latLng = MarkerDrawerManager.INSTANCE.coordinateConverterWgsToGcj(mContext, center.getLat(), center.getLon());
|
||||
}
|
||||
markerOption.position(latLng);
|
||||
markerOption.anchor(0.13f, 1f);
|
||||
markerOption.icon(BitmapDescriptorFactory.fromBitmap(getV2XBitmap(event.getPoiType())));
|
||||
markerOptionsList.add(markerOption);
|
||||
}
|
||||
}
|
||||
if (markerOptionsList.size() > 0) {
|
||||
drawV2XMarkers(markerOptionsList);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawV2XMarkers(ArrayList<MarkerOptions> markerOptionsList) {
|
||||
currMarkerList = mAMap.addMarkers(markerOptionsList, false);
|
||||
}
|
||||
|
||||
private Bitmap getV2XBitmap(String poiType) {
|
||||
V2XMarkerView marker = new V2XMarkerView(getContext(), null, 0, poiType);
|
||||
marker.measure(View.MeasureSpec.makeMeasureSpec(AutoSizeUtils.dp2px(mContext, 229), View.MeasureSpec.EXACTLY),
|
||||
View.MeasureSpec.makeMeasureSpec(AutoSizeUtils.dp2px(mContext, 96), View.MeasureSpec.EXACTLY));
|
||||
marker.layout(0, 0, marker.getMeasuredWidth(), marker.getMeasuredHeight());
|
||||
Bitmap bitmap = Bitmap.createBitmap(marker.getWidth(), marker.getHeight(), Bitmap.Config.ARGB_8888);
|
||||
marker.draw(new Canvas(bitmap));
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public void clearV2XMarkers() {
|
||||
if (currMarkerList != null) {
|
||||
for (Marker marker : currMarkerList) {
|
||||
marker.destroy();
|
||||
}
|
||||
currMarkerList = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
// 注册定位监听
|
||||
CallerMapLocationListenerManager.INSTANCE.removeListener(TAG, false);
|
||||
CallerAutopilotPlanningListenerManager.INSTANCE.removeListener(TAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(@org.jetbrains.annotations.Nullable MogoLocation location, int from, boolean isGps) {
|
||||
mLocation = location;
|
||||
MarkerDrawerManager.INSTANCE.setLonLat(new Pair(location.getLongitude(), location.getLatitude()));
|
||||
drawCarMarker(location);
|
||||
if (isFirstLocation) {
|
||||
displayCustomOverView();
|
||||
isFirstLocation = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void onCreateView(Bundle savedInstanceState) {
|
||||
if (mAMapView != null) {
|
||||
mAMapView.onCreate(savedInstanceState);
|
||||
}
|
||||
}
|
||||
|
||||
public void onResume() {
|
||||
if (mAMapView != null) {
|
||||
mAMapView.onResume();
|
||||
}
|
||||
}
|
||||
|
||||
public void onPause() {
|
||||
if (mAMapView != null) {
|
||||
mAMapView.onPause();
|
||||
}
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
if (mAMapView != null) {
|
||||
mAMapView.onDestroy();
|
||||
}
|
||||
|
||||
if (mAMapView != null) {
|
||||
mAMapView.onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
public void clearCustomPolyline() {
|
||||
if (mBottomPolyline != null) {
|
||||
mBottomPolyline.remove();
|
||||
}
|
||||
if (mCoveredPolyline != null) {
|
||||
mCoveredPolyline.remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制新基建Markers(比如:摄像头)
|
||||
*
|
||||
* @param locationList
|
||||
*/
|
||||
private void drawInfrastructureMarkers(List<MessagePad.Location> locationList) {
|
||||
if (locationList == null) return;
|
||||
if (!pathMap.isEmpty()) {
|
||||
pathMap.clear();
|
||||
}
|
||||
String geoHash;
|
||||
ArrayList<Infrastructure> infList;
|
||||
for (int i = 0; i < locationList.size(); i++) {
|
||||
LatLng latLng = MarkerDrawerManager.INSTANCE.coordinateConverterWgsToGcj(mContext, locationList.get(i));
|
||||
geoHash = GeoHash.withCharacterPrecision(latLng.latitude, latLng.longitude, 7).toBase32();
|
||||
// 网格内的轨迹点只取一次s
|
||||
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()) {
|
||||
// 每个GeoHash内根据坐标系象限分散开摄像头icon显示
|
||||
|
||||
MarkerOptions markerOption = new MarkerOptions();
|
||||
LatLng latLng = new LatLng(Double.valueOf(structureList.get(0).getLat()),
|
||||
Double.valueOf(structureList.get(0).getLon()));
|
||||
markerOption.position(latLng);
|
||||
Bitmap bitmap = getBitmap(structureList.size());
|
||||
markerOption.icon(BitmapDescriptorFactory.fromBitmap(
|
||||
bitmap
|
||||
));
|
||||
markerOption.zIndex(2f);
|
||||
posInfMap.put(latLng, structureList);
|
||||
markerOptionsList.add(markerOption);
|
||||
}
|
||||
mAMap.addMarkers(markerOptionsList, false);
|
||||
mAMap.setOnMarkerClickListener(marker -> {
|
||||
List<Infrastructure> infList = posInfMap.get(marker.getPosition());
|
||||
// 如果是摄像头
|
||||
if (infList != null) {
|
||||
CallerHmiManager.INSTANCE.showVideoDialog(infList);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
private Bitmap getBitmap(int count) {
|
||||
MakerWithCount marker = new MakerWithCount(getContext());
|
||||
marker.setCount(count);
|
||||
|
||||
marker.measure(View.MeasureSpec.makeMeasureSpec(116, View.MeasureSpec.EXACTLY),
|
||||
View.MeasureSpec.makeMeasureSpec(116, View.MeasureSpec.EXACTLY));
|
||||
marker.layout(0, 0, marker.getMeasuredWidth(), marker.getMeasuredHeight());
|
||||
Bitmap bitmap = Bitmap.createBitmap(marker.getWidth(), marker.getHeight(), Bitmap.Config.ARGB_8888);
|
||||
marker.draw(new Canvas(bitmap));
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 进入自定义全览模式
|
||||
*/
|
||||
private void displayCustomOverView() {
|
||||
ArrayList<LatLng> linePointsLatLng = MarkerDrawerManager.INSTANCE.getPlanningPoints();
|
||||
MogoLocation location = mLocation;
|
||||
if (linePointsLatLng.size() > 1) {
|
||||
//圈定地图显示范围
|
||||
//存放经纬度
|
||||
LatLngBounds.Builder boundsBuilder = new LatLngBounds.Builder();
|
||||
for (int i = 0; i < linePointsLatLng.size(); i++) {
|
||||
boundsBuilder.include(linePointsLatLng.get(i));
|
||||
}
|
||||
LatLng currentLatLng = new LatLng(location.getLatitude(), location.getLongitude());
|
||||
boundsBuilder.include(currentLatLng);
|
||||
|
||||
CameraPosition cameraPosition = new CameraPosition.Builder().tilt(mTilt).build();
|
||||
//第二个参数为四周留空宽度
|
||||
mAMap.moveCamera(CameraUpdateFactory.newLatLngBoundsRect(boundsBuilder.build(), 100, 100, 100, 100));
|
||||
mAMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
|
||||
} else {
|
||||
//设置希望展示的地图缩放级别
|
||||
CameraPosition cameraPosition = new CameraPosition.Builder()
|
||||
.target(mCarMarker.getPosition()).tilt(0).zoom(zoomLevel).build();
|
||||
mAMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制自车
|
||||
*
|
||||
* @param location
|
||||
*/
|
||||
private void drawCarMarker(MogoLocation location) {
|
||||
if (location == null) return;
|
||||
if (mCarMarker != null) {
|
||||
LatLng currentLatLng = new LatLng(location.getLatitude(), location.getLongitude());
|
||||
mCarMarker.setRotateAngle(360 - location.getBearing());
|
||||
mCarMarker.setPosition(currentLatLng);
|
||||
mCarMarker.setToTop();
|
||||
if (mCompassMarker != null) {
|
||||
mCompassMarker.setRotateAngle(360 - location.getBearing());
|
||||
mCompassMarker.setPosition(currentLatLng);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制起始点、终点
|
||||
*/
|
||||
private void drawStartAndEndMarker(List<LatLng> coordinates) {
|
||||
if (mStartMarker != null) {
|
||||
mStartMarker.setVisible(false);
|
||||
}
|
||||
if (mEndMarker != null) {
|
||||
mEndMarker.setVisible(false);
|
||||
}
|
||||
if (coordinates.size() > 2) {
|
||||
// 设置开始结束Marker位置
|
||||
|
||||
LatLng startLatLng = coordinates.get(0);
|
||||
LatLng endLatLng = coordinates.get(coordinates.size() - 1);
|
||||
|
||||
mStartMarker.setPosition(startLatLng);
|
||||
mEndMarker.setPosition(endLatLng);
|
||||
mStartMarker.setVisible(true);
|
||||
mEndMarker.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制轨迹线
|
||||
*
|
||||
* @param coordinates
|
||||
* @param locIndex
|
||||
*/
|
||||
private void drawPolyline(List<LatLng> coordinates, int locIndex) {
|
||||
if (textureList.size() > 0) {
|
||||
textureList.clear();
|
||||
}
|
||||
if (texIndexList.size() > 0) {
|
||||
texIndexList.clear();
|
||||
}
|
||||
for (int i = 0; i < coordinates.size(); i++) {
|
||||
if (i <= locIndex) {
|
||||
// 已走过的置灰
|
||||
textureList.add(arrivedBitmap);
|
||||
} else {
|
||||
// 未走过的纹理
|
||||
textureList.add(unArrivedBitmap);
|
||||
}
|
||||
texIndexList.add(i);
|
||||
}
|
||||
if (mAMap != null && coordinates.size() > 2) {
|
||||
//设置线段纹理
|
||||
PolylineOptions polylineOptions = new PolylineOptions();
|
||||
polylineOptions.addAll(coordinates);
|
||||
polylineOptions.width(14); //线段宽度
|
||||
polylineOptions.lineCapType(PolylineOptions.LineCapType.LineCapRound);
|
||||
polylineOptions.setCustomTextureList(textureList);
|
||||
polylineOptions.setCustomTextureIndex(texIndexList);
|
||||
// 绘制线
|
||||
mBottomPolyline = mCoveredPolyline;
|
||||
mCoveredPolyline = mAMap.addPolyline(polylineOptions);
|
||||
if (mBottomPolyline != null) {
|
||||
mBottomPolyline.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,13 +13,10 @@ 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
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.mogo.eagle.core.function.smp
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import com.amap.api.maps.CoordinateConverter
|
||||
import com.amap.api.maps.model.LatLng
|
||||
import com.mogo.cloud.commons.utils.CoordinateUtils
|
||||
import com.mogo.eagle.core.utilcode.util.CoordinateUtils
|
||||
import com.mogo.eagle.core.utilcode.util.DrivingDirectionUtils
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.ObservableOnSubscribe
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
@@ -22,9 +22,7 @@ object MarkerDrawerManager {
|
||||
fun onLocationChanged(planningPoints: List<LatLng>, locIndex: Int)
|
||||
}
|
||||
|
||||
private val routeWipeDisposable by lazy {
|
||||
CompositeDisposable()
|
||||
}
|
||||
private var routeWipeDisposable: CompositeDisposable? = null
|
||||
|
||||
// 自主画线的所有高德坐标系的轨迹点
|
||||
val planningPoints by lazy {
|
||||
@@ -35,40 +33,44 @@ object MarkerDrawerManager {
|
||||
var lastArrivedIndex: Int = -1
|
||||
|
||||
@Volatile
|
||||
var lonLat = Pair(0.0, 0.0)
|
||||
var lonLatHeading = Triple(0.0, 0.0, 0.0)
|
||||
|
||||
var callback: Callback? = null
|
||||
|
||||
fun startLoopCalCarLocation() {
|
||||
getLoopCalCarObservable().delay(1000L, TimeUnit.MILLISECONDS, true)
|
||||
routeWipeDisposable = CompositeDisposable()
|
||||
getLoopCalCarObservable().delay(500L, TimeUnit.MILLISECONDS, true)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.repeat()
|
||||
.retry()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe().let {
|
||||
routeWipeDisposable.add(it)
|
||||
routeWipeDisposable?.add(it)
|
||||
}
|
||||
}
|
||||
|
||||
fun stopLoopCalCarLocation() {
|
||||
if (!routeWipeDisposable.isDisposed) {
|
||||
routeWipeDisposable.dispose()
|
||||
routeWipeDisposable?.let {
|
||||
if (!it.isDisposed) {
|
||||
it.dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getLoopCalCarObservable(): Observable<Int> {
|
||||
return Observable.create(ObservableOnSubscribe { emitter ->
|
||||
if (emitter.isDisposed) return@ObservableOnSubscribe
|
||||
loopRouteAndWipe(planningPoints, lonLat.first, lonLat.second)
|
||||
loopRouteAndWipe(planningPoints, lonLatHeading.first, lonLatHeading.second, lonLatHeading.third)
|
||||
emitter.onComplete()
|
||||
})
|
||||
}
|
||||
|
||||
private fun loopRouteAndWipe(routePoints: List<LatLng>?, lon: Double, lat: Double) {
|
||||
private fun loopRouteAndWipe(routePoints: List<LatLng>?, lon: Double, lat: Double, heading: Double) {
|
||||
if (routePoints != null && routePoints.isNotEmpty()) {
|
||||
val arrivedIndex: Int = getArrivedPointIndex(routePoints, lon, lat)
|
||||
val newPointList = ArrayList<LatLng>()
|
||||
val arrivedIndex: Int = getArrivedPointIndex(routePoints, newPointList, lon, lat, heading)
|
||||
if (arrivedIndex != -1 && lastArrivedIndex != arrivedIndex) {
|
||||
callback?.onLocationChanged(routePoints, arrivedIndex)
|
||||
callback?.onLocationChanged(newPointList, arrivedIndex)
|
||||
lastArrivedIndex = arrivedIndex
|
||||
}
|
||||
}
|
||||
@@ -90,8 +92,10 @@ object MarkerDrawerManager {
|
||||
*/
|
||||
private fun getArrivedPointIndex(
|
||||
routePoints: List<LatLng>,
|
||||
newPoints: MutableList<LatLng>,
|
||||
realLon: Double,
|
||||
realLat: Double
|
||||
realLat: Double,
|
||||
heading: Double
|
||||
): Int {
|
||||
var currentIndex = 0 //记录疑似点
|
||||
if (routePoints.isNotEmpty()) {
|
||||
@@ -107,12 +111,17 @@ object MarkerDrawerManager {
|
||||
)
|
||||
if (baseDiffDis > diff) {
|
||||
baseDiffDis = diff
|
||||
currentIndex = i
|
||||
// 距离最近的时候判断是否走过
|
||||
if (DrivingDirectionUtils.getDegreeOfCar2Poi2(realLon, realLat, latLng.longitude, latLng.latitude, heading) >= 90) {
|
||||
currentIndex = i
|
||||
}
|
||||
}
|
||||
}
|
||||
return currentIndex
|
||||
newPoints.addAll(routePoints)
|
||||
newPoints.add(currentIndex + 1, LatLng(realLat, realLon))
|
||||
return currentIndex + 1
|
||||
}
|
||||
return currentIndex
|
||||
return 0
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
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) + "公里";
|
||||
}
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
package com.mogo.eagle.core.function.smp;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.alibaba.android.arouter.facade.annotation.Route;
|
||||
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
|
||||
import com.mogo.commons.mvp.BaseFragment;
|
||||
import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters;
|
||||
import com.mogo.eagle.core.data.constants.MoGoFragmentPaths;
|
||||
import com.mogo.eagle.core.data.map.MogoLatLng;
|
||||
import com.mogo.eagle.core.function.api.map.smp.IMogoSmallMapProvider;
|
||||
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.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.ViewModelExtKt;
|
||||
import com.mogo.eagle.core.function.overview.vm.OverViewModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author donghongyu
|
||||
* @date 2021/5/19 10:50 上午
|
||||
* 全览模式Fragment
|
||||
*/
|
||||
@Route(path = MoGoFragmentPaths.PATH_FRAGMENT_OVERVIEW)
|
||||
public class OverviewMapFragment extends BaseFragment
|
||||
implements IMogoSmallMapProvider {
|
||||
private final String TAG = "OverviewMapFragment";
|
||||
protected AMapCustomView mAMapCustomView;
|
||||
private OverViewModel mViewModel;
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@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 startQueryV2XEvents() {
|
||||
if (isAdded()) {
|
||||
if (mViewModel != null) {
|
||||
mViewModel.getAllV2XEventsByLineId(MoGoAiCloudClientConfig.getInstance().getSn());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearV2XMarkers() {
|
||||
if (isAdded()) {
|
||||
if (mAMapCustomView != null) {
|
||||
mAMapCustomView.clearV2XMarkers();
|
||||
}
|
||||
if (mViewModel != null) {
|
||||
mViewModel.stopQueryV2XEvents();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawablePolyline(List<MogoLatLng> coordinates) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearPolyline() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (mAMapCustomView != null) {
|
||||
mAMapCustomView.onResume();
|
||||
}
|
||||
mAMapCustomView.handlePlanningData(InfStructureManager.INSTANCE.getPlanningData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
// 主动查一次全局路径规划的数据
|
||||
CallerAutoPilotManager.INSTANCE.getGlobalPath();
|
||||
queryV2XEvents();
|
||||
}
|
||||
|
||||
private void queryV2XEvents() {
|
||||
mViewModel = ViewModelExtKt.obtainViewModel(this, OverViewModel.class);
|
||||
mViewModel.getV2XEventLiveData().observe(this.getViewLifecycleOwner(), v2XEvents -> {
|
||||
mAMapCustomView.showV2XEventMarkers(v2XEvents);
|
||||
});
|
||||
mViewModel.getAllV2XEventsByLineId(MoGoAiCloudClientConfig.getInstance().getSn());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Taxi的下发的轨迹id
|
||||
*/
|
||||
private long getLineId() {
|
||||
long lineId = -1;
|
||||
AutopilotControlParameters parameter = CallerAutoPilotStatusListenerManager.INSTANCE.getAutoPilotStatusInfo()
|
||||
.getAutopilotControlParameters();
|
||||
if (parameter != null) {
|
||||
if (parameter.autoPilotLine != null) {
|
||||
lineId = parameter.autoPilotLine.getLineId();
|
||||
}
|
||||
}
|
||||
return lineId;
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
@@ -1,362 +0,0 @@
|
||||
package com.mogo.eagle.core.function.smp;
|
||||
|
||||
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_MAP;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
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.TextureMapView;
|
||||
import com.amap.api.maps.UiSettings;
|
||||
import com.amap.api.maps.model.BitmapDescriptorFactory;
|
||||
import com.amap.api.maps.model.CameraPosition;
|
||||
import com.amap.api.maps.model.CustomMapStyleOptions;
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.amap.api.maps.model.LatLngBounds;
|
||||
import com.amap.api.maps.model.Marker;
|
||||
import com.amap.api.maps.model.MarkerOptions;
|
||||
import com.amap.api.maps.model.Polyline;
|
||||
import com.amap.api.maps.model.PolylineOptions;
|
||||
import com.mogo.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.function.call.map.CallerMapLocationListenerManager;
|
||||
import com.mogo.eagle.core.function.map.R;
|
||||
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.commons.utils.DrivingDirectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
/**
|
||||
* 小地图的方向View
|
||||
*
|
||||
* @author donghongyu
|
||||
* @date 12/14/20 4:40 PM
|
||||
*/
|
||||
public class SmallMapDirectionView
|
||||
extends RelativeLayout
|
||||
implements IMoGoMapLocationListener, ISmallMapDirectionView {
|
||||
|
||||
//小地图名称
|
||||
public static final String TAG = "SmallMapDirectionView";
|
||||
|
||||
private RoundLayout rlSmallMapBorder;
|
||||
private TextureMapView mAMapNaviView;
|
||||
private AMap mAMap;
|
||||
private Marker mCarMarker;
|
||||
private Marker mStartMarker;
|
||||
private Marker mEndMarker;
|
||||
|
||||
private int zoomLevel = 15;
|
||||
private final List<LatLng> mCoordinatesLatLng = new ArrayList<>();
|
||||
private final List<MogoLatLng> mCoordinatesLatLngCurrent = new ArrayList<>();
|
||||
private Polyline mPolyline;
|
||||
private CameraUpdate mCameraUpdate;
|
||||
private Context mContext;
|
||||
private MogoLocation mLocation;
|
||||
|
||||
public SmallMapDirectionView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public SmallMapDirectionView(Context context, @Nullable AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public SmallMapDirectionView(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_small_map_view, this);
|
||||
|
||||
mAMapNaviView = smpView.findViewById(R.id.aMapNaviView);
|
||||
// rlSmallMapBorder = findViewById(R.id.rlSmallMapBorder);
|
||||
// rlSmallMapBorder.addView(mAMapNaviView);
|
||||
|
||||
initAMapView();
|
||||
|
||||
// 注册定位监听
|
||||
CallerMapLocationListenerManager.INSTANCE.addListener(TAG, this, false);
|
||||
startTask();
|
||||
}
|
||||
|
||||
private void startTask() {
|
||||
Timer mTimer = new Timer();
|
||||
mTimer.schedule(new UpdateLocationTask(), 1000, 200);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
// 注册定位监听
|
||||
CallerMapLocationListenerManager.INSTANCE.removeListener(TAG, false);
|
||||
}
|
||||
|
||||
private void initAMapView() {
|
||||
mCameraUpdate = CameraUpdateFactory.zoomTo(zoomLevel);
|
||||
mAMap = mAMapNaviView.getMap();
|
||||
// 关闭地图文字标注
|
||||
mAMap.showMapText(false);
|
||||
// 设置导航地图模式,aMap是地图控制器对象。
|
||||
mAMap.setMapType(AMap.MAP_TYPE_NIGHT);
|
||||
// 关闭显示实时路况图层,aMap是地图控制器对象。
|
||||
mAMap.setTrafficEnabled(false);
|
||||
// 设置 锚点 图标
|
||||
mCarMarker = mAMap.addMarker(new MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.module_small_map_view_my_location_logo))
|
||||
.anchor(0.5f, 0.5f));
|
||||
mStartMarker = mAMap.addMarker(new MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.module_small_map_view_dir_start)));
|
||||
mEndMarker = mAMap.addMarker(new MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.module_small_map_view_dir_end)));
|
||||
// 加载自定义样式
|
||||
CustomMapStyleOptions customMapStyleOptions = new CustomMapStyleOptions()
|
||||
.setEnable(true)
|
||||
.setStyleData(MapAssetStyleUtils.getAssetsStyle(getContext(), "over_view_style.data"))
|
||||
.setStyleExtraData(MapAssetStyleUtils.getAssetsExtraStyle(getContext(), "over_view_style_extra.data"));
|
||||
// 设置自定义样式
|
||||
mAMap.setCustomMapStyle(customMapStyleOptions);
|
||||
//设置希望展示的地图缩放级别
|
||||
mAMap.moveCamera(mCameraUpdate);
|
||||
// 设置地图的样式
|
||||
UiSettings uiSettings = mAMap.getUiSettings();
|
||||
uiSettings.setZoomControlsEnabled(false);// 地图缩放级别的交换按钮
|
||||
uiSettings.setAllGesturesEnabled(false);// 所有手势
|
||||
uiSettings.setMyLocationButtonEnabled(false); // 显示默认的定位按钮
|
||||
uiSettings.setLogoBottomMargin(-150); //设置Logo下边界距离屏幕底部的边距,设置为负值即可
|
||||
mAMap.setOnMapLoadedListener(() -> {
|
||||
CallerLogger.INSTANCE.d(M_MAP + TAG, "smp---onMapLoaded");
|
||||
// 加载自定义样式
|
||||
CustomMapStyleOptions customMapStyleOptions1 = new CustomMapStyleOptions()
|
||||
.setEnable(true)
|
||||
.setStyleData(MapAssetStyleUtils.getAssetsStyle(getContext(), "over_view_style.data"))
|
||||
.setStyleExtraData(MapAssetStyleUtils.getAssetsExtraStyle(getContext(), "over_view_style_extra.data"));
|
||||
// 设置自定义样式
|
||||
mAMap.setCustomMapStyle(customMapStyleOptions1);
|
||||
mAMapNaviView.getMap().setPointToCenter(mAMapNaviView.getWidth() / 2, mAMapNaviView.getHeight() / 2);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(@org.jetbrains.annotations.Nullable MogoLocation location, int from, boolean isGps) {
|
||||
if (location == null) {
|
||||
return;
|
||||
}
|
||||
mLocation = location;
|
||||
}
|
||||
|
||||
private class UpdateLocationTask extends TimerTask {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mLocation != null) {
|
||||
MogoLocation location = mLocation;
|
||||
if (mCarMarker == null){
|
||||
mCarMarker = mAMap.addMarker(new MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.module_small_map_view_my_location_logo))
|
||||
.anchor(0.5f, 0.5f));
|
||||
}
|
||||
if(mCarMarker == null){
|
||||
return;
|
||||
}
|
||||
LatLng currentLatLng = new LatLng(location.getLatitude(), location.getLongitude());
|
||||
float bearing = (float) Math.floor(location.getBearing());
|
||||
//更新车辆位置
|
||||
mCarMarker.setPosition(currentLatLng);
|
||||
|
||||
CameraPosition cameraPosition;
|
||||
if (mCoordinatesLatLng.size() > 1) {
|
||||
// 结束位置
|
||||
LatLng endLatLng = mCoordinatesLatLng.get(mCoordinatesLatLng.size() - 1);
|
||||
|
||||
float calculateDistance = CoordinateUtils.calculateLineDistance(
|
||||
endLatLng.latitude, endLatLng.longitude,
|
||||
currentLatLng.latitude, currentLatLng.longitude
|
||||
);
|
||||
|
||||
CallerLogger.INSTANCE.d(M_MAP + TAG, "calculateDistance=" + calculateDistance);
|
||||
if (calculateDistance <= 5) {
|
||||
clearPolyline();
|
||||
mCoordinatesLatLng.clear();
|
||||
}
|
||||
}
|
||||
cameraPosition = new CameraPosition.Builder().target(mCarMarker.getPosition()).tilt(0).bearing(bearing).zoom(zoomLevel).build();
|
||||
mAMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
clearPolyline();
|
||||
// mCoordinatesLatLng.clear();
|
||||
// List<LatLng> latLngs = CoordinateConverterFrom84ForList(mContext,coordinates);
|
||||
// mCoordinatesLatLng.addAll(latLngs);
|
||||
// for (LatLng coordinate : mCoordinatesLatLng) {
|
||||
// mCoordinatesLatLng.add(new LatLng(coordinate.getLat(), coordinate.getLon()));
|
||||
// }
|
||||
if (mAMap != null) {
|
||||
if (mCoordinatesLatLng.size() > 2) {
|
||||
// 设置开始结束Marker位置
|
||||
mStartMarker.setPosition(mCoordinatesLatLng.get(0));
|
||||
mEndMarker.setPosition(mCoordinatesLatLng.get(mCoordinatesLatLng.size() - 1));
|
||||
mStartMarker.setToTop();
|
||||
mStartMarker.setVisible(true);
|
||||
mEndMarker.setVisible(true);
|
||||
mEndMarker.setToTop();
|
||||
|
||||
|
||||
//存放所有点的经纬度
|
||||
LatLngBounds.Builder boundsBuilder = new LatLngBounds.Builder();
|
||||
|
||||
for (int i = 0; i < mCoordinatesLatLng.size(); i++) {
|
||||
//把所有点都include进去(LatLng类型)
|
||||
boundsBuilder.include(mCoordinatesLatLng.get(i));
|
||||
}
|
||||
//第二个参数为四周留空宽度
|
||||
mAMap.animateCamera(CameraUpdateFactory.newLatLngBounds(boundsBuilder.build(), 30));
|
||||
// 绘制线
|
||||
mPolyline = mAMap.addPolyline(
|
||||
new PolylineOptions()
|
||||
.addAll(mCoordinatesLatLng)
|
||||
.color(Color.argb(255, 31, 127, 255))
|
||||
.width(12));
|
||||
|
||||
}
|
||||
// else {
|
||||
// //设置希望展示的地图缩放级别
|
||||
// mAMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mCoordinatesLatLng.get(0), zoomLevel));
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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() {
|
||||
// mCoordinatesLatLng.clear();
|
||||
if (mPolyline != null) {
|
||||
mPolyline.remove();
|
||||
}
|
||||
if (mStartMarker != null) {
|
||||
mStartMarker.setVisible(false);
|
||||
}
|
||||
if (mEndMarker != null) {
|
||||
mEndMarker.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void resetPolyLine() {
|
||||
mCoordinatesLatLng.clear();
|
||||
if (mPolyline != null) {
|
||||
mPolyline.remove();
|
||||
}
|
||||
if (mStartMarker != null) {
|
||||
mStartMarker.setVisible(false);
|
||||
}
|
||||
if (mEndMarker != null) {
|
||||
mEndMarker.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
public void convert(List<MogoLatLng> coordinates) {
|
||||
mCoordinatesLatLng.clear();
|
||||
List<LatLng> latLngs = CoordinateConverterFrom84ForList(mContext, coordinates);
|
||||
mCoordinatesLatLng.addAll(latLngs);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,204 +0,0 @@
|
||||
package com.mogo.eagle.core.function.smp;
|
||||
|
||||
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_MAP;
|
||||
|
||||
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.CallerAutoPilotManager;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotPlanningListenerManager;
|
||||
import com.mogo.eagle.core.function.map.R;
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import mogo.telematics.pad.MessagePad;
|
||||
import mogo_msg.MogoReportMsg;
|
||||
import system_master.SystemStatusInfo;
|
||||
|
||||
/**
|
||||
* @author donghongyu
|
||||
* @date 2021/5/19 10:50 上午
|
||||
*/
|
||||
@Route(path = MoGoFragmentPaths.PATH_FRAGMENT_SMP)
|
||||
public class SmallMapFragment extends BaseFragment
|
||||
implements IMogoSmallMapProvider, IMoGoAutopilotPlanningListener,
|
||||
IMoGoAutopilotStatusListener {
|
||||
private final String TAG = "SmallMapFragment";
|
||||
protected SmallMapDirectionView mSmallMapDirectionView;
|
||||
private int autoPilotStatus = 0;
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
return R.layout.module_small_map_fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTagName() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initViews() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initViews(Bundle savedInstanceState) {
|
||||
super.initViews(savedInstanceState);
|
||||
mSmallMapDirectionView = mRootView.findViewById(R.id.smallMapDirectionView);
|
||||
mSmallMapDirectionView.onCreateView(savedInstanceState);
|
||||
CallerAutopilotPlanningListenerManager.INSTANCE.addListener(TAG, this);
|
||||
CallerAutoPilotStatusListenerManager.INSTANCE.addListener(TAG,this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showPanel() {
|
||||
if (mSmallMapDirectionView != null) {
|
||||
mSmallMapDirectionView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hidePanel() {
|
||||
if (mSmallMapDirectionView != null) {
|
||||
mSmallMapDirectionView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawablePolyline(List<MogoLatLng> coordinates) {
|
||||
if (mSmallMapDirectionView != null) {
|
||||
UiThreadHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mSmallMapDirectionView.convert(coordinates);
|
||||
mSmallMapDirectionView.drawablePolyline();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearPolyline() {
|
||||
if (mSmallMapDirectionView != null) {
|
||||
UiThreadHandler.post(() -> mSmallMapDirectionView.clearPolyline());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (mSmallMapDirectionView != null) {
|
||||
mSmallMapDirectionView.onResume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
if (mSmallMapDirectionView != null) {
|
||||
mSmallMapDirectionView.onPause();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mSmallMapDirectionView != null) {
|
||||
mSmallMapDirectionView.onDestroy();
|
||||
}
|
||||
CallerAutopilotPlanningListenerManager.INSTANCE.removeListener(TAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutopilotTrajectory(List<MessagePad.TrajectoryPoint> trajectoryInfos) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutopilotStatusResponse(@NotNull AutopilotStatusInfo autoPilotStatusInfo) {
|
||||
int tempStatus = autoPilotStatusInfo.getPilotmode();
|
||||
// CallerLogger.INSTANCE.i(M_MAP + TAG, "onAutopilotStatusResponse:"+tempStatus+" autoPilotStatus:"+autoPilotStatus);
|
||||
if (tempStatus != 1) {
|
||||
// CallerLogger.INSTANCE.i(M_MAP + TAG, "onAutopilotStatusResponse:"+tempStatus+" clearPolyline");
|
||||
clearPolyline();
|
||||
}else if (tempStatus == 1 && autoPilotStatus == 0){
|
||||
// CallerLogger.INSTANCE.i(M_MAP + TAG, "onAutopilotStatusResponse:getGlobalPath");
|
||||
CallerAutoPilotManager.INSTANCE.getGlobalPath();
|
||||
}
|
||||
autoPilotStatus = tempStatus;
|
||||
}
|
||||
|
||||
@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) {
|
||||
CallerLogger.INSTANCE.i(M_MAP + TAG, "onAutopilotRotting");
|
||||
if (globalPathResp == null || globalPathResp.getWayPointsList().size() == 0) {
|
||||
return;
|
||||
}
|
||||
CallerLogger.INSTANCE.i(M_MAP + TAG, "onAutopilotRotting:"+globalPathResp.getWayPointsList().size());
|
||||
|
||||
List<MogoLatLng> latLngList = new ArrayList<>();
|
||||
for (MessagePad.Location routeModel : globalPathResp.getWayPointsList()) {
|
||||
latLngList.add(new MogoLatLng(routeModel.getLatitude(), routeModel.getLongitude()));
|
||||
}
|
||||
if (latLngList.size() > 0) {
|
||||
CallerLogger.INSTANCE.i(M_MAP + TAG, "onAutopilotRotting:"+"drawablePolyline");
|
||||
drawablePolyline(latLngList);
|
||||
} else {
|
||||
CallerLogger.INSTANCE.i(M_MAP + TAG, "onAutopilotRotting:"+"clearPolyline");
|
||||
clearPolyline();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutopilotStatusRespByQuery(@NonNull SystemStatusInfo.StatusInfo status) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutopilotRouteLineId(long lineId) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package com.mogo.eagle.core.function.smp.view;
|
||||
|
||||
/**
|
||||
* @author xiaoyuzhou
|
||||
* @date 2021/6/24 11:33 上午
|
||||
*/
|
||||
public interface ISmallMapDirectionView {
|
||||
|
||||
/**
|
||||
* 绘制路径线
|
||||
*/
|
||||
void drawablePolyline();
|
||||
|
||||
/**
|
||||
* 清除路径线
|
||||
*/
|
||||
void clearPolyline();
|
||||
}
|
||||
@@ -0,0 +1,374 @@
|
||||
package com.mogo.eagle.core.function.smp.view
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.annotation.UiThread
|
||||
import com.amap.api.maps.*
|
||||
import com.amap.api.maps.model.*
|
||||
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.IMoGoAutopilotStatusListener
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoPlanningRottingListener
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager.getGlobalPath
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListenerManager
|
||||
import com.mogo.eagle.core.function.map.R
|
||||
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
|
||||
import com.mogo.eagle.core.utilcode.mogo.MapAssetStyleUtils
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
|
||||
import com.mogo.eagle.core.utilcode.util.CoordinateUtils
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
|
||||
import mogo.telematics.pad.MessagePad
|
||||
import kotlin.math.floor
|
||||
|
||||
class SmallMapView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : RelativeLayout(context, attrs, defStyleAttr), IMoGoChassisLocationGCJ02Listener,
|
||||
IMoGoPlanningRottingListener,
|
||||
IMoGoAutopilotStatusListener {
|
||||
|
||||
private var mAMapNaviView: TextureMapView? = null
|
||||
private var mAMap: AMap? = null
|
||||
private var mCarMarker: Marker? = null
|
||||
private var mStartMarker: Marker? = null
|
||||
private var mEndMarker: Marker? = null
|
||||
private val zoomLevel = 17
|
||||
private val mCoordinatesLatLng: MutableList<LatLng> = ArrayList()
|
||||
private var mPolyline: Polyline? = null
|
||||
private var mCameraUpdate: CameraUpdate? = null
|
||||
private var mContext: Context? = null
|
||||
private var mLocation: MogoLocation? = null
|
||||
|
||||
@Volatile
|
||||
private var autoPilotStatus = 0
|
||||
|
||||
companion object {
|
||||
const val TAG = "SmallMapView"
|
||||
}
|
||||
|
||||
init {
|
||||
try {
|
||||
initView(context)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
// =================必须通知高德地图生命周期的变化=================
|
||||
fun onCreateView(savedInstanceState: Bundle?) {
|
||||
if (mAMapNaviView != null) {
|
||||
mAMapNaviView!!.onCreate(savedInstanceState)
|
||||
}
|
||||
}
|
||||
|
||||
fun onResume() {
|
||||
if (mAMapNaviView != null) {
|
||||
mAMapNaviView!!.onResume()
|
||||
}
|
||||
}
|
||||
|
||||
fun onPause() {
|
||||
if (mAMapNaviView != null) {
|
||||
mAMapNaviView!!.onPause()
|
||||
}
|
||||
}
|
||||
|
||||
fun onDestroy() {
|
||||
if (mAMapNaviView != null) {
|
||||
mAMapNaviView!!.onDestroy()
|
||||
}
|
||||
}
|
||||
// =================必须通知高德地图生命周期的变化=================
|
||||
|
||||
fun convert(coordinates: List<MogoLatLng>) {
|
||||
mCoordinatesLatLng.clear()
|
||||
val latLngs = coordinateConverterFrom84ForList(mContext, coordinates)
|
||||
mCoordinatesLatLng.addAll(latLngs)
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun drawablePolyline() {
|
||||
clearPolyline()
|
||||
if (mAMap != null) {
|
||||
if (mCoordinatesLatLng.size >= 2) {
|
||||
// 设置开始结束Marker位置
|
||||
mStartMarker!!.position = mCoordinatesLatLng[0]
|
||||
mEndMarker!!.position = mCoordinatesLatLng[mCoordinatesLatLng.size - 1]
|
||||
mStartMarker!!.setToTop()
|
||||
mStartMarker!!.isVisible = true
|
||||
mEndMarker!!.isVisible = true
|
||||
mEndMarker!!.setToTop()
|
||||
|
||||
|
||||
//存放所有点的经纬度
|
||||
val boundsBuilder = LatLngBounds.Builder()
|
||||
for (i in mCoordinatesLatLng.indices) {
|
||||
//把所有点都include进去(LatLng类型)
|
||||
boundsBuilder.include(mCoordinatesLatLng[i])
|
||||
}
|
||||
//第二个参数为四周留空宽度
|
||||
mAMap!!.animateCamera(
|
||||
CameraUpdateFactory.newLatLngBounds(
|
||||
boundsBuilder.build(),
|
||||
30
|
||||
)
|
||||
)
|
||||
// 绘制线
|
||||
mPolyline = mAMap!!.addPolyline(
|
||||
PolylineOptions()
|
||||
.addAll(mCoordinatesLatLng)
|
||||
.color(Color.argb(255, 31, 127, 255))
|
||||
.width(12f)
|
||||
)
|
||||
CallerLogger.d(
|
||||
SceneConstant.M_MAP + TAG, "SmallMapView drawPolyline size is = ${mCoordinatesLatLng.size} ")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun clearPolyline() {
|
||||
CallerLogger.d(
|
||||
SceneConstant.M_MAP + TAG, "SmallMapView clearPolyline mPolyline -----> ")
|
||||
if (mPolyline != null) {
|
||||
mPolyline!!.remove()
|
||||
}
|
||||
if (mStartMarker != null) {
|
||||
mStartMarker!!.isVisible = false
|
||||
}
|
||||
if (mEndMarker != null) {
|
||||
mEndMarker!!.isVisible = false
|
||||
}
|
||||
}
|
||||
|
||||
private fun initView(context: Context) {
|
||||
mContext = context
|
||||
val smpView = LayoutInflater.from(context).inflate(R.layout.module_small_map_view, this)
|
||||
mAMapNaviView = smpView.findViewById(R.id.aMapNaviView)
|
||||
initAMapView()
|
||||
|
||||
// 注册定位监听
|
||||
CallerChassisLocationGCJ02ListenerManager.addListener(TAG, 10, this)
|
||||
CallerPlanningRottingListenerManager.addListener(TAG, this)
|
||||
CallerAutoPilotStatusListenerManager.addListener(TAG, this)
|
||||
}
|
||||
|
||||
private fun initAMapView() {
|
||||
mCameraUpdate = CameraUpdateFactory.zoomTo(zoomLevel.toFloat())
|
||||
mAMap = mAMapNaviView!!.map
|
||||
// 关闭地图文字标注
|
||||
mAMap?.showMapText(false)
|
||||
// 设置导航地图模式,aMap是地图控制器对象。
|
||||
mAMap?.mapType = AMap.MAP_TYPE_NIGHT
|
||||
// 关闭显示实时路况图层,aMap是地图控制器对象。
|
||||
mAMap?.isTrafficEnabled = false
|
||||
// 设置 锚点 图标
|
||||
mCarMarker = if (AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)
|
||||
|| AppIdentityModeUtils.isShuttle(FunctionBuildConfig.appIdentityMode)
|
||||
|| AppIdentityModeUtils.isCharter(FunctionBuildConfig.appIdentityMode)) {
|
||||
mAMap?.addMarker(
|
||||
MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.map_bus_icon))
|
||||
.anchor(0.5f, 0.5f)
|
||||
)
|
||||
} else {
|
||||
mAMap?.addMarker(
|
||||
MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.map_car_icon))
|
||||
.anchor(0.5f, 0.5f)
|
||||
)
|
||||
}
|
||||
mStartMarker = mAMap?.addMarker(
|
||||
MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.module_small_map_view_dir_start))
|
||||
)
|
||||
mEndMarker = mAMap?.addMarker(
|
||||
MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.module_small_map_view_dir_end))
|
||||
)
|
||||
// 加载自定义样式
|
||||
val customMapStyleOptions = CustomMapStyleOptions()
|
||||
.setEnable(true)
|
||||
.setStyleData(MapAssetStyleUtils.getAssetsStyle(context, "over_view_style.data"))
|
||||
.setStyleExtraData(
|
||||
MapAssetStyleUtils.getAssetsExtraStyle(
|
||||
context,
|
||||
"over_view_style_extra.data"
|
||||
)
|
||||
)
|
||||
// 设置自定义样式
|
||||
mAMap?.setCustomMapStyle(customMapStyleOptions)
|
||||
//设置希望展示的地图缩放级别
|
||||
mAMap?.moveCamera(mCameraUpdate)
|
||||
// 设置地图的样式
|
||||
val uiSettings = mAMap?.uiSettings
|
||||
uiSettings?.isZoomControlsEnabled = false // 地图缩放级别的交换按钮
|
||||
uiSettings?.setAllGesturesEnabled(false) // 所有手势
|
||||
uiSettings?.isMyLocationButtonEnabled = false // 显示默认的定位按钮
|
||||
uiSettings?.setLogoBottomMargin(-150) //设置Logo下边界距离屏幕底部的边距,设置为负值即可
|
||||
mAMap?.setOnMapLoadedListener {
|
||||
CallerLogger.d(
|
||||
SceneConstant.M_MAP + TAG,
|
||||
"smp---onMapLoaded"
|
||||
)
|
||||
// 加载自定义样式
|
||||
val customMapStyleOptions1 = CustomMapStyleOptions()
|
||||
.setEnable(true)
|
||||
.setStyleData(MapAssetStyleUtils.getAssetsStyle(context, "over_view_style.data"))
|
||||
.setStyleExtraData(
|
||||
MapAssetStyleUtils.getAssetsExtraStyle(
|
||||
context,
|
||||
"over_view_style_extra.data"
|
||||
)
|
||||
)
|
||||
// 设置自定义样式
|
||||
mAMap?.setCustomMapStyle(customMapStyleOptions1)
|
||||
mAMapNaviView!!.map.setPointToCenter(
|
||||
mAMapNaviView!!.width / 2,
|
||||
mAMapNaviView!!.height / 2
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun coordinateConverterFrom84(mContext: Context?, mogoLatLng: MogoLatLng): LatLng {
|
||||
val mCoordinateConverter = CoordinateConverter(mContext)
|
||||
mCoordinateConverter.from(CoordinateConverter.CoordType.GPS)
|
||||
mCoordinateConverter.coord(LatLng(mogoLatLng.lat, mogoLatLng.lon))
|
||||
return mCoordinateConverter.convert()
|
||||
}
|
||||
|
||||
private fun coordinateConverterFrom84ForList(
|
||||
mContext: Context?,
|
||||
mogoLatLngList: List<MogoLatLng>
|
||||
): List<LatLng> {
|
||||
val list: MutableList<LatLng> = ArrayList()
|
||||
for (m in mogoLatLngList) {
|
||||
val mogoLatLng = coordinateConverterFrom84(mContext, m)
|
||||
list.add(mogoLatLng)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
override fun onChassisLocationGCJ02(mogoLocation: MogoLocation?) {
|
||||
if (mogoLocation == null) {
|
||||
return
|
||||
}
|
||||
mLocation = mogoLocation
|
||||
if (mCarMarker == null) {
|
||||
mCarMarker =
|
||||
if (AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) {
|
||||
mAMap?.addMarker(
|
||||
MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.map_bus_icon))
|
||||
.anchor(0.5f, 0.5f)
|
||||
)
|
||||
} else {
|
||||
mAMap?.addMarker(
|
||||
MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.map_car_icon))
|
||||
.anchor(0.5f, 0.5f)
|
||||
)
|
||||
}
|
||||
}
|
||||
if (mCarMarker == null) {
|
||||
return
|
||||
}
|
||||
UiThreadHandler.post {
|
||||
val currentLatLng = LatLng(mLocation!!.latitude, mLocation!!.longitude)
|
||||
val bearing = floor(mLocation!!.heading).toFloat()
|
||||
//更新车辆位置
|
||||
mCarMarker!!.position = currentLatLng
|
||||
if (mCoordinatesLatLng.size > 1) {
|
||||
// 结束位置
|
||||
val endLatLng = mCoordinatesLatLng[mCoordinatesLatLng.size - 1]
|
||||
val calculateDistance = CoordinateUtils.calculateLineDistance(
|
||||
endLatLng.latitude, endLatLng.longitude,
|
||||
currentLatLng.latitude, currentLatLng.longitude
|
||||
)
|
||||
CallerLogger.d(
|
||||
SceneConstant.M_MAP + TAG,
|
||||
"calculateDistance=$calculateDistance"
|
||||
)
|
||||
if (calculateDistance <= 5) {
|
||||
CallerLogger.d(
|
||||
SceneConstant.M_MAP + TAG, "onChassisLocationGCJ02 -----> calculateDistance <= 5 ")
|
||||
clearPolyline()
|
||||
mCoordinatesLatLng.clear()
|
||||
}
|
||||
}
|
||||
val cameraPosition: CameraPosition =
|
||||
CameraPosition.Builder()
|
||||
.target(mCarMarker!!.position)
|
||||
.tilt(0f)
|
||||
.bearing(bearing)
|
||||
.zoom(zoomLevel.toFloat())
|
||||
.build()
|
||||
mAMap?.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onAutopilotStatusResponse(autoPilotStatusInfo: AutopilotStatusInfo) {
|
||||
val tempStatus = autoPilotStatusInfo.pilotmode
|
||||
if (tempStatus != 1) {
|
||||
UiThreadHandler.post {
|
||||
CallerLogger.d(
|
||||
SceneConstant.M_MAP + TAG, "onAutopilotStatusResponse tempStatus = $tempStatus ---clearPolyline() ")
|
||||
clearPolyline()
|
||||
}
|
||||
} else if (tempStatus == 1 && autoPilotStatus == 0) {
|
||||
getGlobalPath()
|
||||
}
|
||||
autoPilotStatus = tempStatus
|
||||
}
|
||||
|
||||
override fun onAutopilotRotting(globalPathResp: MessagePad.GlobalPathResp?) {
|
||||
CallerLogger.d(
|
||||
SceneConstant.M_MAP + TAG, "SmallMapView globalPathResp = $globalPathResp")
|
||||
if (globalPathResp == null || globalPathResp.wayPointsList.size == 0) {
|
||||
return
|
||||
}
|
||||
val latLngList: MutableList<MogoLatLng> = ArrayList()
|
||||
for (routeModel in globalPathResp.wayPointsList) {
|
||||
latLngList.add(MogoLatLng(routeModel.latitude, routeModel.longitude))
|
||||
}
|
||||
CallerLogger.d(
|
||||
SceneConstant.M_MAP + TAG, "SmallMapView latLngList.size = ${latLngList.size}")
|
||||
if (latLngList.size > 0) {
|
||||
UiThreadHandler.post {
|
||||
convert(latLngList)
|
||||
drawablePolyline()
|
||||
}
|
||||
} else {
|
||||
UiThreadHandler.post {
|
||||
CallerLogger.d(
|
||||
SceneConstant.M_MAP + TAG, "SmallMapView latLngList.size = ${latLngList.size} clearPolyline ---->")
|
||||
clearPolyline()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
// 注册定位监听
|
||||
CallerChassisLocationGCJ02ListenerManager.removeListener(TAG)
|
||||
CallerPlanningRottingListenerManager.removeListener(TAG)
|
||||
CallerAutoPilotStatusListenerManager.removeListener(TAG)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.mogo.eagle.core.function.utils
|
||||
|
||||
import android.content.Context
|
||||
import mogo.telematics.pad.MessagePad
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
|
||||
object PlanningDataUtils {
|
||||
|
||||
@JvmStatic
|
||||
fun test(context: Context?): List<MessagePad.Location> {
|
||||
if (context == null) return emptyList()
|
||||
val list: MutableList<MessagePad.Location> = ArrayList()
|
||||
val jsonStr = getAssetsString(context, "planningDataTest.txt")
|
||||
try {
|
||||
val jsonElements = JSONArray(jsonStr)
|
||||
for (i in 0 until jsonElements.length()) {
|
||||
val s = jsonElements.getJSONObject(i)
|
||||
val builder = MessagePad.Location.newBuilder()
|
||||
builder.latitude = s.getDouble("latitude")
|
||||
builder.longitude = s.getDouble("longitude")
|
||||
list.add(builder.build())
|
||||
}
|
||||
} catch (e: JSONException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
private fun getAssetsString(context: Context, fileName: String): String {
|
||||
var buffer: ByteArray? = null
|
||||
var istream: InputStream? = null
|
||||
try {
|
||||
istream = context.resources.assets.open(fileName)
|
||||
buffer = ByteArray(istream.available())
|
||||
istream.read(buffer)
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
} finally {
|
||||
try {
|
||||
istream?.close()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
return String(buffer!!)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package com.mogo.eagle.core.function.view
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.LifecycleObserver
|
||||
import chassis.Chassis
|
||||
import com.mogo.eagle.core.data.map.MogoLocation
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLamplightListener
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationWGS84Listener
|
||||
import com.mogo.eagle.core.function.api.setting.IMoGoSkinModeChangeListener
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLamplightListenerManager
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
|
||||
import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager
|
||||
import com.mogo.eagle.core.function.call.setting.CallerSkinModeListenerManager
|
||||
import com.mogo.map.MogoMapView
|
||||
|
||||
|
||||
class MapBizView(context: Context?, attrs: AttributeSet?) : MogoMapView(context, attrs),
|
||||
IMoGoSkinModeChangeListener,
|
||||
IMoGoChassisLocationWGS84Listener, IMoGoChassisLamplightListener, LifecycleObserver {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "MapBizView"
|
||||
}
|
||||
|
||||
override fun onCreate(bundle: Bundle?) {
|
||||
super.onCreate(bundle)
|
||||
map?.uiController?.showMyLocation(true)
|
||||
initMapView()
|
||||
|
||||
CallerSkinModeListenerManager.addListener(TAG, this)
|
||||
CallerChassisLocationWGS84ListenerManager.addListener(TAG, 20,this)
|
||||
CallerChassisLamplightListenerManager.addListener(TAG, this)
|
||||
|
||||
}
|
||||
|
||||
private fun initMapView() {
|
||||
map?.uiSettings?.let {
|
||||
//设置所有手势是否可用
|
||||
it.setAllGesturesEnabled(true)
|
||||
//设置指南针是否可见。
|
||||
it.setCompassEnabled(false)
|
||||
//设置室内地图楼层切换控件是否可见。
|
||||
it.setIndoorSwitchEnabled(true)
|
||||
//设置定位按钮是否可见。
|
||||
it.setMyLocationButtonEnabled(false)
|
||||
//设置旋转手势是否可用。
|
||||
it.setRotateGesturesEnabled(false)
|
||||
//设置比例尺控件是否可见
|
||||
it.setScaleControlsEnabled(true)
|
||||
//设置拖拽手势是否可用。
|
||||
it.setScrollGesturesEnabled(true)
|
||||
//设置倾斜手势是否可用。
|
||||
it.setTiltGesturesEnabled(true)
|
||||
//设置缩放按钮是否可见。
|
||||
it.setZoomControlsEnabled(false)
|
||||
//设置双指缩放手势是否可用。
|
||||
it.setZoomGesturesEnabled(true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle?) {
|
||||
super.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
override fun onSkinModeChange(skinMode: Int) {
|
||||
if (skinMode == 0) {
|
||||
CallerMapUIServiceManager.getMapUIController()?.stepInVrMode(false)
|
||||
} else if (skinMode == 1) {
|
||||
CallerMapUIServiceManager.getMapUIController()?.stepInVrMode(true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onChassisLocationWGS84(gnssInfo: MogoLocation) {
|
||||
// 跟新地图控件
|
||||
setExtraGPSData(gnssInfo)
|
||||
}
|
||||
|
||||
private var currentLevel:Int = 0
|
||||
|
||||
override fun onAutopilotLightSwitchData(lightSwitch: Chassis.LightSwitch?) {
|
||||
super.onAutopilotLightSwitchData(lightSwitch)
|
||||
lightSwitch?.let {
|
||||
when (it.number) {
|
||||
Chassis.LightSwitch.LIGHT_LEFT_VALUE -> { //左转灯
|
||||
CallerVisualAngleManager.showTurning(true)
|
||||
turn(1)
|
||||
}
|
||||
Chassis.LightSwitch.LIGHT_RIGHT_VALUE -> { //右转灯
|
||||
CallerVisualAngleManager.showTurning(true)
|
||||
turn(2)
|
||||
}
|
||||
Chassis.LightSwitch.LIGHT_NONE_VALUE -> {
|
||||
CallerVisualAngleManager.showTurning(false)
|
||||
turn(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun turn(lightNum: Int) {
|
||||
if (currentLevel != lightNum) {
|
||||
when (lightNum) {
|
||||
0 -> CallerMapUIServiceManager.getMapUIController()?.setCarLightsType(3, 500)
|
||||
1 -> CallerMapUIServiceManager.getMapUIController()?.setCarLightsType(4, 500)
|
||||
2 -> CallerMapUIServiceManager.getMapUIController()?.setCarLightsType(2, 500)
|
||||
}
|
||||
currentLevel = lightNum
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
// 先取消注册数据,再onDestroy
|
||||
CallerSkinModeListenerManager.removeListener(TAG)
|
||||
CallerChassisLocationWGS84ListenerManager.removeListener(TAG)
|
||||
CallerChassisLamplightListenerManager.removeListener(TAG)
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,699 @@
|
||||
package com.mogo.eagle.core.function.view
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
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.MainThread
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import ch.hsr.geohash.GeoHash
|
||||
import com.amap.api.maps.AMap
|
||||
import com.amap.api.maps.CameraUpdate
|
||||
import com.amap.api.maps.CameraUpdateFactory
|
||||
import com.amap.api.maps.TextureMapView
|
||||
import com.amap.api.maps.model.*
|
||||
import com.mogo.eagle.core.data.map.Infrastructure
|
||||
import com.mogo.eagle.core.data.map.MogoLocation
|
||||
import com.mogo.eagle.core.data.v2x.V2XEventData
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoPlanningRottingListener
|
||||
import com.mogo.eagle.core.function.api.biz.IFuncBizProvider
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager.getGlobalPath
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListenerManager
|
||||
import com.mogo.eagle.core.function.call.biz.CallerFuncBizListenerManager
|
||||
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager.showVideoDialog
|
||||
import com.mogo.eagle.core.function.map.R
|
||||
import com.mogo.eagle.core.function.smp.MakerWithCount
|
||||
import com.mogo.eagle.core.function.smp.MarkerDrawerManager
|
||||
import com.mogo.eagle.core.function.smp.MarkerDrawerManager.callback
|
||||
import com.mogo.eagle.core.function.smp.MarkerDrawerManager.coordinateConverterWgsToGcj
|
||||
import com.mogo.eagle.core.function.smp.MarkerDrawerManager.lastArrivedIndex
|
||||
import com.mogo.eagle.core.function.smp.MarkerDrawerManager.lonLatHeading
|
||||
import com.mogo.eagle.core.function.smp.MarkerDrawerManager.planningPoints
|
||||
import com.mogo.eagle.core.function.smp.MarkerDrawerManager.startLoopCalCarLocation
|
||||
import com.mogo.eagle.core.function.smp.MarkerDrawerManager.updateRoutePoints
|
||||
import com.mogo.eagle.core.function.smp.V2XMarkerView
|
||||
import com.mogo.eagle.core.utilcode.mogo.MapAssetStyleUtils
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
|
||||
import me.jessyan.autosize.utils.AutoSizeUtils
|
||||
import mogo.telematics.pad.MessagePad
|
||||
|
||||
/**
|
||||
* 全览地图View
|
||||
*
|
||||
* @author chenfufeng
|
||||
*/
|
||||
class OverMapView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : RelativeLayout(context, attrs, defStyleAttr), IMoGoChassisLocationGCJ02Listener,
|
||||
IMoGoPlanningRottingListener {
|
||||
|
||||
// =============自定义属性相关=============
|
||||
private var mapStylePath: String? = null
|
||||
private var mapStyleExtraPath: String? = null
|
||||
private var carDrawable: Int = -1
|
||||
private var compassDrawable: Int = -1
|
||||
private var startPointDrawable: Int = -1
|
||||
private var endPointDrawable: Int = -1
|
||||
private var arrivedDrawable: Int = -1
|
||||
private var unArrivedDrawable: Int = -1
|
||||
private var resetDrawable: Int = -1
|
||||
private var resetDrawableMarginRight: Int = -1
|
||||
private var resetDrawableMarginBottom: Int = -1
|
||||
private var isClearArrived: Boolean = false
|
||||
private var leftPadding: Int = 100
|
||||
private var topPadding: Int = 100
|
||||
private var rightPadding: Int = 100
|
||||
private var bottomPadding: Int = 100
|
||||
|
||||
private var mMapView: TextureMapView? = null
|
||||
private var mAMap: AMap? = null
|
||||
private val zoomLevel = 15
|
||||
private var mCameraUpdate: CameraUpdate? = null
|
||||
private var mContext: Context? = null
|
||||
private var mTilt = 0f
|
||||
private var overLayerView: TextView? = null
|
||||
|
||||
// 全局路径规划中的GeoHash网格
|
||||
private val pathMap: MutableMap<String?, ArrayList<Infrastructure>?> = HashMap()
|
||||
private val posInfMap: MutableMap<LatLng?, ArrayList<Infrastructure>?> = HashMap()
|
||||
|
||||
private var geoHashInfMap: HashMap<String, java.util.ArrayList<Infrastructure>>? = null
|
||||
|
||||
// =============绘制轨迹线相关=============
|
||||
private var mCarMarker: Marker? = null
|
||||
private var mCompassMarker: Marker? = null
|
||||
private var mStartMarker: Marker? = null
|
||||
private var mEndMarker: Marker? = null
|
||||
private var mBottomPolyline: Polyline? = null
|
||||
private var mCoveredPolyline: Polyline? = null
|
||||
|
||||
// 计算索引并设置对应的Bitmap
|
||||
var arrivedBitmap: BitmapDescriptor? = null
|
||||
var unArrivedBitmap: BitmapDescriptor? = null
|
||||
var transparentBitmap: BitmapDescriptor? = null
|
||||
|
||||
// 绘制轨迹线的集合
|
||||
private val textureList: MutableList<BitmapDescriptor?> = ArrayList()
|
||||
private val texIndexList: MutableList<Int> = ArrayList()
|
||||
private var mLocation: MogoLocation? = null
|
||||
private var isFirstLocation = true
|
||||
var mCustomMapStyleOptions: CustomMapStyleOptions? = null
|
||||
var currMarkerList: ArrayList<Marker>? = null
|
||||
var siteMarkerList: ArrayList<Marker>? = null
|
||||
|
||||
companion object {
|
||||
const val TAG = "OverMapView"
|
||||
}
|
||||
|
||||
init {
|
||||
try {
|
||||
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.OverMapView)
|
||||
mapStylePath = typedArray.getString(R.styleable.OverMapView_mapStylePath)
|
||||
mapStyleExtraPath = typedArray.getString(R.styleable.OverMapView_mapStyleExtraPath)
|
||||
carDrawable = typedArray.getResourceId(R.styleable.OverMapView_carDrawable, -1)
|
||||
compassDrawable = typedArray.getResourceId(R.styleable.OverMapView_compassDrawable, -1)
|
||||
startPointDrawable =
|
||||
typedArray.getResourceId(R.styleable.OverMapView_startPointDrawable, -1)
|
||||
endPointDrawable =
|
||||
typedArray.getResourceId(R.styleable.OverMapView_endPointDrawable, -1)
|
||||
arrivedDrawable = typedArray.getResourceId(R.styleable.OverMapView_arrivedDrawable, -1)
|
||||
unArrivedDrawable =
|
||||
typedArray.getResourceId(R.styleable.OverMapView_unArrivedDrawable, -1)
|
||||
resetDrawable = typedArray.getResourceId(R.styleable.OverMapView_resetDrawable, -1)
|
||||
resetDrawableMarginRight = typedArray.getResourceId(
|
||||
R.styleable.OverMapView_resetDrawableMarginRight,
|
||||
AutoSizeUtils.dp2px(context, 40f)
|
||||
)
|
||||
resetDrawableMarginBottom = typedArray.getResourceId(
|
||||
R.styleable.OverMapView_resetDrawableMarginBottom,
|
||||
AutoSizeUtils.dp2px(context, 40f)
|
||||
)
|
||||
isClearArrived = typedArray.getBoolean(R.styleable.OverMapView_isClearArrived, false)
|
||||
leftPadding = typedArray.getInt(R.styleable.OverMapView_leftPadding, 100)
|
||||
topPadding = typedArray.getInt(R.styleable.OverMapView_topPadding, 100)
|
||||
rightPadding = typedArray.getInt(R.styleable.OverMapView_rightPadding, 100)
|
||||
bottomPadding = typedArray.getInt(R.styleable.OverMapView_bottomPadding, 100)
|
||||
typedArray.recycle()
|
||||
initView(context)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
// =================必须通知高德地图生命周期的变化=================
|
||||
fun onCreateView(savedInstanceState: Bundle?) {
|
||||
if (mMapView != null) {
|
||||
mMapView!!.onCreate(savedInstanceState)
|
||||
}
|
||||
}
|
||||
|
||||
fun onResume() {
|
||||
if (mMapView != null) {
|
||||
mMapView!!.onResume()
|
||||
}
|
||||
}
|
||||
|
||||
fun onPause() {
|
||||
if (mMapView != null) {
|
||||
mMapView!!.onPause()
|
||||
}
|
||||
}
|
||||
|
||||
fun onDestroy() {
|
||||
if (mMapView != null) {
|
||||
mMapView!!.onDestroy()
|
||||
}
|
||||
if (mMapView != null) {
|
||||
mMapView!!.onDestroy()
|
||||
}
|
||||
}
|
||||
// =================必须通知高德地图生命周期的变化=================
|
||||
|
||||
/**
|
||||
* 隐藏右下角的重置View
|
||||
*/
|
||||
fun hideResetView() {
|
||||
overLayerView?.visibility = View.GONE
|
||||
}
|
||||
|
||||
/**
|
||||
* siteLatLngs: 高德坐标集合
|
||||
* bitmap: Marker对应的图片
|
||||
* (anchorX,anchorY)为锚点坐标,各自取值范围为[0,1],默认值为(0.5,1)
|
||||
*/
|
||||
@MainThread
|
||||
fun drawSiteMarkers(
|
||||
siteLatLngs: List<LatLng>?,
|
||||
bitmap: Bitmap,
|
||||
anchorX: Float,
|
||||
anchorY: Float
|
||||
) {
|
||||
if (siteLatLngs.isNullOrEmpty()) return
|
||||
clearSiteMarkers()
|
||||
val markerOptionsList = ArrayList<MarkerOptions>()
|
||||
for (latLng in siteLatLngs) {
|
||||
val markerOption = MarkerOptions()
|
||||
markerOption.position(latLng)
|
||||
markerOption.anchor(anchorX, anchorY)
|
||||
markerOption.icon(
|
||||
BitmapDescriptorFactory.fromBitmap(bitmap)
|
||||
)
|
||||
markerOptionsList.add(markerOption)
|
||||
}
|
||||
siteMarkerList = mAMap!!.addMarkers(markerOptionsList, false)
|
||||
}
|
||||
|
||||
@MainThread
|
||||
fun clearSiteMarkers() {
|
||||
if (siteMarkerList != null) {
|
||||
for (marker in siteMarkerList!!) {
|
||||
marker.destroy()
|
||||
}
|
||||
siteMarkerList = null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空线路并隐藏起、终点
|
||||
*/
|
||||
fun clearCustomPolyline() {
|
||||
if (mBottomPolyline != null) {
|
||||
mBottomPolyline!!.remove()
|
||||
}
|
||||
if (mCoveredPolyline != null) {
|
||||
mCoveredPolyline!!.remove()
|
||||
}
|
||||
mStartMarker?.isVisible = false
|
||||
mEndMarker?.isVisible = false
|
||||
MarkerDrawerManager.stopLoopCalCarLocation()
|
||||
planningPoints.clear()
|
||||
lastArrivedIndex = -1
|
||||
}
|
||||
|
||||
@SuppressLint("UseCompatLoadingForDrawables")
|
||||
private fun initView(context: Context) {
|
||||
mContext = context
|
||||
val smpView = LayoutInflater.from(context).inflate(R.layout.module_overview_map_view, this)
|
||||
mMapView = smpView.findViewById(R.id.aMapView)
|
||||
overLayerView = findViewById(R.id.overLayer)
|
||||
overLayerView?.background =
|
||||
resources.getDrawable(if (resetDrawable != -1) resetDrawable else R.drawable.amap_reset)
|
||||
arrivedBitmap =
|
||||
BitmapDescriptorFactory.fromResource(if (arrivedDrawable != -1) arrivedDrawable else R.drawable.taxi_map_arrow_arrived)
|
||||
unArrivedBitmap =
|
||||
BitmapDescriptorFactory.fromResource(if (unArrivedDrawable != -1) unArrivedDrawable else R.drawable.taxi_map_arrow_un_arrive)
|
||||
transparentBitmap = BitmapDescriptorFactory.fromBitmap(
|
||||
resources.getDrawable(R.drawable.transparent_background, null)
|
||||
.toBitmap(AutoSizeUtils.dp2px(context, 32f), AutoSizeUtils.dp2px(context, 230f))
|
||||
)
|
||||
CallerPlanningRottingListenerManager.addListener(TAG, this)
|
||||
initAMapView(context)
|
||||
// 注册定位监听
|
||||
CallerChassisLocationGCJ02ListenerManager.addListener(TAG, this)
|
||||
//设置全览模式
|
||||
overLayerView?.setOnClickListener { displayCustomOverView() }
|
||||
overLayerView?.let {
|
||||
it.background =
|
||||
resources.getDrawable(if (resetDrawable != -1) resetDrawable else R.drawable.amap_reset)
|
||||
val layoutParams = it.layoutParams
|
||||
layoutParams as RelativeLayout.LayoutParams
|
||||
layoutParams.rightMargin = resetDrawableMarginRight
|
||||
layoutParams.bottomMargin = resetDrawableMarginBottom
|
||||
it.layoutParams = layoutParams
|
||||
}
|
||||
}
|
||||
|
||||
private fun initAMapView(context: Context) {
|
||||
Log.d(TAG, "initAMapView")
|
||||
mTilt = 30f
|
||||
mCameraUpdate = CameraUpdateFactory.zoomTo(zoomLevel.toFloat())
|
||||
mAMap = mMapView!!.map
|
||||
mCustomMapStyleOptions = CustomMapStyleOptions()
|
||||
|
||||
if (!mapStylePath.isNullOrEmpty() && !mapStyleExtraPath.isNullOrEmpty()) {
|
||||
mCustomMapStyleOptions!!.styleData =
|
||||
MapAssetStyleUtils.getAssetsStyle(getContext(), mapStylePath)
|
||||
mCustomMapStyleOptions!!.styleExtraData =
|
||||
MapAssetStyleUtils.getAssetsExtraStyle(getContext(), mapStyleExtraPath)
|
||||
}
|
||||
mAMap?.setOnMapLoadedListener {
|
||||
Log.d(TAG, "---onMapLoaded---")
|
||||
if (mCustomMapStyleOptions != null) {
|
||||
// 加载自定义样式
|
||||
mCustomMapStyleOptions!!.isEnable = true
|
||||
// 设置自定义样式
|
||||
mAMap?.setCustomMapStyle(mCustomMapStyleOptions)
|
||||
}
|
||||
// 实时路况图层关闭,必须添加在loaded结束之后,其他位置不生效
|
||||
mAMap?.isTrafficEnabled = false
|
||||
mAMap?.showBuildings(true)
|
||||
mAMap?.animateCamera(CameraUpdateFactory.changeTilt(mTilt))
|
||||
}
|
||||
setUpMap()
|
||||
customOptions()
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
CallerFuncBizListenerManager.addListener(TAG, object : IFuncBizProvider {
|
||||
override fun onInfStructures(map: HashMap<String, ArrayList<Infrastructure>>?) {
|
||||
geoHashInfMap = map
|
||||
}
|
||||
|
||||
override fun onV2XEvents(v2XEventData: List<V2XEventData>?) {
|
||||
showV2XEventMarkers(v2XEventData)
|
||||
}
|
||||
})
|
||||
// 主动查一次全局路径规划的数据
|
||||
getGlobalPath()
|
||||
}
|
||||
|
||||
private fun setUpMap() {
|
||||
// 地图文字标注
|
||||
mAMap!!.showMapText(true)
|
||||
//设置希望展示的地图缩放级别
|
||||
mAMap!!.moveCamera(mCameraUpdate)
|
||||
//设置地图的样式
|
||||
val uiSettings = mAMap!!.uiSettings
|
||||
//地图缩放级别的交换按钮
|
||||
uiSettings.isZoomControlsEnabled = false
|
||||
//所有手势
|
||||
uiSettings.setAllGesturesEnabled(true)
|
||||
//隐藏指南针
|
||||
uiSettings.isCompassEnabled = false
|
||||
//设置倾斜手势是否可用。
|
||||
uiSettings.isTiltGesturesEnabled = true
|
||||
//隐藏默认的定位按钮
|
||||
uiSettings.isMyLocationButtonEnabled = false
|
||||
//设置Logo下边界距离屏幕底部的边距,设置为负值即可
|
||||
uiSettings.setLogoBottomMargin(-150)
|
||||
Log.d(TAG, "before onMapLoaded")
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义导航View和路况状态
|
||||
*/
|
||||
private fun customOptions() {
|
||||
mCarMarker = mAMap!!.addMarker(
|
||||
MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(if (carDrawable != -1) carDrawable else R.drawable.map_car_icon))
|
||||
.anchor(0.5f, 0.5f)
|
||||
)
|
||||
mCompassMarker = mAMap!!.addMarker(
|
||||
MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(if (compassDrawable != -1) compassDrawable else R.drawable.amap_custom_corner))
|
||||
.anchor(0.5f, 0.5f)
|
||||
)
|
||||
if (startPointDrawable != -1) {
|
||||
mStartMarker = mAMap!!.addMarker(
|
||||
MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(startPointDrawable))
|
||||
)
|
||||
}
|
||||
if (endPointDrawable != -1) {
|
||||
mEndMarker = mAMap!!.addMarker(
|
||||
MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(endPointDrawable))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun handlePlanningData(locationList: List<MessagePad.Location>?) {
|
||||
if (locationList.isNullOrEmpty()) return
|
||||
val list: List<MessagePad.Location> = locationList
|
||||
// 转成高德坐标系并存储
|
||||
updateRoutePoints(list, mContext!!)
|
||||
val planningPointList: List<LatLng> = planningPoints
|
||||
UiThreadHandler.post {
|
||||
displayCustomOverView()
|
||||
drawStartAndEndMarker(planningPointList)
|
||||
}
|
||||
callback = object : MarkerDrawerManager.Callback {
|
||||
override fun onLocationChanged(planningPoints: List<LatLng>, locIndex: Int) {
|
||||
// 每1s刷新一下轨迹线
|
||||
UiThreadHandler.post {
|
||||
if (planningPoints.isNotEmpty()) {
|
||||
drawPolyline(planningPoints, locIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
startLoopCalCarLocation()
|
||||
UiThreadHandler.post {
|
||||
if (geoHashInfMap.isNullOrEmpty()) {
|
||||
UiThreadHandler.postDelayed({
|
||||
drawInfrastructureMarkers(locationList)
|
||||
}, 1000)
|
||||
} else {
|
||||
drawInfrastructureMarkers(locationList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示V2X事件的Marker
|
||||
*/
|
||||
private fun showV2XEventMarkers(v2XEventData: List<V2XEventData>?) {
|
||||
if (v2XEventData == null || v2XEventData.isEmpty()) return
|
||||
clearV2XMarkers()
|
||||
val markerOptionsList = ArrayList<MarkerOptions>()
|
||||
for (v2xEvent in v2XEventData) {
|
||||
val center = v2xEvent.center
|
||||
if (center != null) {
|
||||
val markerOption = MarkerOptions()
|
||||
val latLng: LatLng =
|
||||
if (v2xEvent.coordinateType == null || v2xEvent.coordinateType == 0) {
|
||||
LatLng(center.lat, center.lon)
|
||||
} else {
|
||||
// wgs84坐标系需转成高德坐标系
|
||||
coordinateConverterWgsToGcj(
|
||||
mContext!!,
|
||||
center.lat,
|
||||
center.lon
|
||||
)
|
||||
}
|
||||
markerOption.position(latLng)
|
||||
markerOption.anchor(0.13f, 1f)
|
||||
markerOption.icon(
|
||||
BitmapDescriptorFactory.fromBitmap(
|
||||
getV2XBitmap(
|
||||
v2xEvent.poiType
|
||||
)
|
||||
)
|
||||
)
|
||||
markerOptionsList.add(markerOption)
|
||||
}
|
||||
}
|
||||
if (markerOptionsList.size > 0) {
|
||||
drawV2XMarkers(markerOptionsList)
|
||||
}
|
||||
}
|
||||
|
||||
fun drawV2XMarkers(markerOptionsList: ArrayList<MarkerOptions>?) {
|
||||
currMarkerList = mAMap!!.addMarkers(markerOptionsList, false)
|
||||
}
|
||||
|
||||
private fun getV2XBitmap(poiType: String?): Bitmap {
|
||||
val marker = V2XMarkerView(context, null, 0, poiType)
|
||||
marker.measure(
|
||||
MeasureSpec.makeMeasureSpec(AutoSizeUtils.dp2px(mContext, 229f), MeasureSpec.EXACTLY),
|
||||
MeasureSpec.makeMeasureSpec(AutoSizeUtils.dp2px(mContext, 96f), MeasureSpec.EXACTLY)
|
||||
)
|
||||
marker.layout(0, 0, marker.measuredWidth, marker.measuredHeight)
|
||||
val bitmap = Bitmap.createBitmap(marker.width, marker.height, Bitmap.Config.ARGB_8888)
|
||||
marker.draw(Canvas(bitmap))
|
||||
return bitmap
|
||||
}
|
||||
|
||||
private fun clearV2XMarkers() {
|
||||
if (currMarkerList != null) {
|
||||
for (marker in currMarkerList!!) {
|
||||
marker.destroy()
|
||||
}
|
||||
currMarkerList = null
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
// 注册定位监听
|
||||
CallerChassisLocationGCJ02ListenerManager.removeListener(TAG)
|
||||
CallerPlanningRottingListenerManager.removeListener(TAG)
|
||||
}
|
||||
|
||||
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制新基建Markers(比如:摄像头)
|
||||
*
|
||||
* @param locationList
|
||||
*/
|
||||
private fun drawInfrastructureMarkers(locationList: List<MessagePad.Location>?) {
|
||||
val infMap = geoHashInfMap
|
||||
if (locationList == null || infMap.isNullOrEmpty()) return
|
||||
if (pathMap.isNotEmpty()) {
|
||||
pathMap.clear()
|
||||
}
|
||||
var geoHash: String?
|
||||
var infList: ArrayList<Infrastructure>?
|
||||
for (i in locationList.indices) {
|
||||
val latLng = coordinateConverterWgsToGcj(mContext!!, locationList[i])
|
||||
geoHash =
|
||||
GeoHash.withCharacterPrecision(latLng.latitude, latLng.longitude, 7).toBase32()
|
||||
// 网格内的轨迹点只取一次s
|
||||
if (!pathMap.containsKey(geoHash)) {
|
||||
// 从缓存的新基建数据中去取对应geoHash的新基建数据集合
|
||||
infList = infMap[geoHash]
|
||||
if (infList != null) {
|
||||
pathMap[geoHash] = infList
|
||||
}
|
||||
}
|
||||
}
|
||||
drawInfMarkers(pathMap)
|
||||
}
|
||||
|
||||
private fun drawInfMarkers(infStruMap: Map<String?, ArrayList<Infrastructure>?>) {
|
||||
// 绘制新基建数据
|
||||
if (posInfMap.isNotEmpty()) {
|
||||
posInfMap.clear()
|
||||
}
|
||||
val markerOptionsList: ArrayList<MarkerOptions?> = ArrayList()
|
||||
for (structureList in infStruMap.values) {
|
||||
// 每个GeoHash内根据坐标系象限分散开摄像头icon显示
|
||||
val markerOption = MarkerOptions()
|
||||
val latLng = LatLng(
|
||||
java.lang.Double.valueOf(structureList!![0].lat!!),
|
||||
java.lang.Double.valueOf(structureList[0].lon!!)
|
||||
)
|
||||
markerOption.position(latLng)
|
||||
val bitmap = getBitmap(structureList.size)
|
||||
markerOption.icon(
|
||||
BitmapDescriptorFactory.fromBitmap(
|
||||
bitmap
|
||||
)
|
||||
)
|
||||
markerOption.anchor(0.18f, 0.98f)
|
||||
markerOption.zIndex(2f)
|
||||
posInfMap[latLng] = structureList
|
||||
markerOptionsList.add(markerOption)
|
||||
}
|
||||
mAMap!!.addMarkers(markerOptionsList, false)
|
||||
mAMap!!.setOnMarkerClickListener { marker: Marker ->
|
||||
val infList: List<Infrastructure>? = posInfMap[marker.position]
|
||||
// 如果是摄像头
|
||||
if (infList != null) {
|
||||
showVideoDialog(infList)
|
||||
return@setOnMarkerClickListener true
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
private fun getBitmap(count: Int): Bitmap {
|
||||
val marker = MakerWithCount(context)
|
||||
marker.setCount(count)
|
||||
marker.measure(
|
||||
MeasureSpec.makeMeasureSpec(AutoSizeUtils.dp2px(mContext, 116f), MeasureSpec.EXACTLY),
|
||||
MeasureSpec.makeMeasureSpec(AutoSizeUtils.dp2px(mContext, 116f), MeasureSpec.EXACTLY)
|
||||
)
|
||||
marker.layout(0, 0, marker.measuredWidth, marker.measuredHeight)
|
||||
val bitmap = Bitmap.createBitmap(marker.width, marker.height, Bitmap.Config.ARGB_8888)
|
||||
marker.draw(Canvas(bitmap))
|
||||
return bitmap
|
||||
}
|
||||
|
||||
/**
|
||||
* 进入自定义全览模式
|
||||
*/
|
||||
private fun displayCustomOverView() {
|
||||
val linePointsLatLng = planningPoints
|
||||
if (linePointsLatLng.size > 1 && mLocation != null) {
|
||||
//圈定地图显示范围
|
||||
//存放经纬度
|
||||
val boundsBuilder = LatLngBounds.Builder()
|
||||
for (i in linePointsLatLng.indices) {
|
||||
boundsBuilder.include(linePointsLatLng[i])
|
||||
}
|
||||
val currentLatLng = LatLng(mLocation!!.latitude, mLocation!!.longitude)
|
||||
boundsBuilder.include(currentLatLng)
|
||||
val cameraPosition = CameraPosition.Builder().tilt(mTilt).build()
|
||||
//第二个参数为四周留空宽度
|
||||
mAMap!!.moveCamera(
|
||||
CameraUpdateFactory.newLatLngBoundsRect(
|
||||
boundsBuilder.build(),
|
||||
AutoSizeUtils.dp2px(context, leftPadding.toFloat()),
|
||||
AutoSizeUtils.dp2px(context, rightPadding.toFloat()),
|
||||
AutoSizeUtils.dp2px(context, topPadding.toFloat()),
|
||||
AutoSizeUtils.dp2px(context, bottomPadding.toFloat())
|
||||
)
|
||||
)
|
||||
mAMap!!.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
|
||||
} else {
|
||||
//设置希望展示的地图缩放级别
|
||||
val cameraPosition = CameraPosition.Builder()
|
||||
.target(mCarMarker!!.position).tilt(mTilt).zoom(zoomLevel.toFloat()).build()
|
||||
mAMap!!.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制自车
|
||||
*
|
||||
* @param location
|
||||
*/
|
||||
private fun drawCarMarker(location: MogoLocation?) {
|
||||
if (location == null) return
|
||||
if (mCarMarker != null) {
|
||||
val currentLatLng = LatLng(location.latitude, location.longitude)
|
||||
mCarMarker!!.rotateAngle = (360 - location.heading).toFloat()
|
||||
mCarMarker!!.position = currentLatLng
|
||||
mCarMarker!!.setToTop()
|
||||
if (mCompassMarker != null) {
|
||||
mCompassMarker!!.rotateAngle = (360 - location.heading).toFloat()
|
||||
mCompassMarker!!.position = currentLatLng
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制起始点、终点
|
||||
*/
|
||||
private fun drawStartAndEndMarker(coordinates: List<LatLng>) {
|
||||
mStartMarker?.isVisible = false
|
||||
mEndMarker?.isVisible = false
|
||||
if (coordinates.size > 2) {
|
||||
// 设置开始结束Marker位置
|
||||
val startLatLng = coordinates[0]
|
||||
val endLatLng = coordinates[coordinates.size - 1]
|
||||
mStartMarker?.position = startLatLng
|
||||
mEndMarker?.position = endLatLng
|
||||
mStartMarker?.isVisible = true
|
||||
mEndMarker?.isVisible = true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制轨迹线
|
||||
*
|
||||
* @param coordinates
|
||||
* @param locIndex
|
||||
*/
|
||||
private fun drawPolyline(coordinates: List<LatLng>, locIndex: Int) {
|
||||
if (textureList.size > 0) {
|
||||
textureList.clear()
|
||||
}
|
||||
if (texIndexList.size > 0) {
|
||||
texIndexList.clear()
|
||||
}
|
||||
for (i in coordinates.indices) {
|
||||
// 线段数比点数少一个
|
||||
if (i == 0) continue
|
||||
if (i <= locIndex) {
|
||||
if (isClearArrived) {
|
||||
textureList.add(transparentBitmap)
|
||||
} else {
|
||||
// 已走过的置灰
|
||||
textureList.add(arrivedBitmap)
|
||||
}
|
||||
} else {
|
||||
// 未走过的纹理
|
||||
textureList.add(unArrivedBitmap)
|
||||
}
|
||||
texIndexList.add(i - 1)
|
||||
}
|
||||
if (mAMap != null && coordinates.size > 2) {
|
||||
//设置线段纹理
|
||||
val polylineOptions = PolylineOptions()
|
||||
polylineOptions.addAll(coordinates)
|
||||
polylineOptions.width(14f) //线段宽度
|
||||
polylineOptions.lineCapType(PolylineOptions.LineCapType.LineCapRound)
|
||||
polylineOptions.customTextureList = textureList
|
||||
polylineOptions.customTextureIndex = texIndexList
|
||||
// 绘制线
|
||||
mBottomPolyline = mCoveredPolyline
|
||||
mCoveredPolyline = mAMap!!.addPolyline(polylineOptions)
|
||||
if (mBottomPolyline != null) {
|
||||
mBottomPolyline!!.remove()
|
||||
mBottomPolyline = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onChassisLocationGCJ02(gnssInfo: MogoLocation?) {
|
||||
gnssInfo?.let {
|
||||
mLocation = it
|
||||
lonLatHeading = Triple(it.longitude, it.latitude, it.heading)
|
||||
drawCarMarker(it)
|
||||
if (isFirstLocation) {
|
||||
displayCustomOverView()
|
||||
isFirstLocation = false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据全路径获取起始点和经停点进行导航路线绘制
|
||||
* 自动驾驶启动后获得数据,获取全路径的具体时间要进行路测
|
||||
* 室内某个bag包自动驾驶启动8s后返回
|
||||
*/
|
||||
override fun onAutopilotRotting(globalPathResp: MessagePad.GlobalPathResp?) {
|
||||
globalPathResp?.let {
|
||||
handlePlanningData(it.wayPointsList)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="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:visibility="visible"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
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>
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
<TextView
|
||||
android:id="@+id/overLayer"
|
||||
android:layout_width="@dimen/dp_116"
|
||||
android:layout_height="@dimen/dp_116"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:scaleType="centerInside"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.mogo.eagle.core.function.smp.SmallMapDirectionView
|
||||
android:id="@+id/smallMapDirectionView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="30dp"
|
||||
android:layout_marginBottom="30dp"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<declare-styleable name="OverMapView">
|
||||
<!-- 地图样式asset目录下的路径 -->
|
||||
<attr name="mapStylePath" format="string" />
|
||||
<attr name="mapStyleExtraPath" format="string" />
|
||||
<!-- 自车模型图片 -->
|
||||
<attr name="carDrawable" format="reference" />
|
||||
<!-- 罗盘图片 -->
|
||||
<attr name="compassDrawable" format="reference" />
|
||||
<!-- 起点图片 -->
|
||||
<attr name="startPointDrawable" format="reference" />
|
||||
<!-- 终点图片 -->
|
||||
<attr name="endPointDrawable" format="reference" />
|
||||
<!-- 已走过路线的图片 -->
|
||||
<attr name="arrivedDrawable" format="reference" />
|
||||
<!-- 未走过路线的图片 -->
|
||||
<attr name="unArrivedDrawable" format="reference" />
|
||||
<!-- 重置位置图片 -->
|
||||
<attr name="resetDrawable" format="reference" />
|
||||
<!-- 重置位置图片右面margin -->
|
||||
<attr name="resetDrawableMarginRight" format="dimension" />
|
||||
<!-- 重置位置图片下面margin -->
|
||||
<attr name="resetDrawableMarginBottom" format="dimension" />
|
||||
<!-- 是否擦除已走过的路线 -->
|
||||
<attr name="isClearArrived" format="boolean" />
|
||||
<!-- 规定屏幕范围的padding -->
|
||||
<attr name="leftPadding" format="integer" />
|
||||
<attr name="topPadding" format="integer" />
|
||||
<attr name="rightPadding" format="integer" />
|
||||
<attr name="bottomPadding" format="integer" />
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user