[Feat]全览模式展示新基建图标

This commit is contained in:
chenfufeng
2022-07-11 17:13:44 +08:00
parent 65320311de
commit 545ba19033
19 changed files with 447 additions and 83 deletions

View File

@@ -3,6 +3,7 @@ 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.graphics.BitmapFactory;
import android.os.Bundle;
import androidx.annotation.NonNull;
@@ -11,14 +12,23 @@ import androidx.annotation.Nullable;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.amap.api.maps.AMap;
import com.amap.api.maps.TextureMapView;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.UiSettings;
import com.mogo.commons.mvp.MvpFragment;
import com.mogo.eagle.core.data.constants.MoGoFragmentPaths;
import com.mogo.eagle.core.data.map.CenterLine;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotPlanningListener;
import com.mogo.eagle.core.function.api.map.hd.IMoGoMapFragmentProvider;
import com.mogo.eagle.core.function.api.setting.IMoGoSkinModeChangeListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotPlanningListenerManager;
import com.mogo.eagle.core.function.call.map.CallerHDMapManager;
import com.mogo.eagle.core.function.call.monitor.CallerMonitorManager;
import com.mogo.eagle.core.function.call.setting.CallerSkinModeListenerManager;
import com.mogo.eagle.core.function.overview.Infrastructure;
import com.mogo.eagle.core.function.overview.ViewModelExtKt;
import com.mogo.eagle.core.function.overview.vm.OverViewModel;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.map.IMogoMap;
import com.mogo.map.IMogoUiSettings;
@@ -27,6 +37,15 @@ import com.mogo.map.uicontroller.IMogoMapUIController;
import com.zhidaoauto.map.sdk.open.MapAutoApi;
import com.zhidaoauto.map.sdk.open.business.PointCloudHelper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import ch.hsr.geohash.GeoHash;
import mogo.telematics.pad.MessagePad;
/**
* @author donghongyu
* @since 2021-11-09
@@ -36,7 +55,8 @@ import com.zhidaoauto.map.sdk.open.business.PointCloudHelper;
*/
@Route(path = MoGoFragmentPaths.PATH_FRAGMENT_MAP)
public class MapFragment extends MvpFragment<MapView, MapPresenter>
implements MapView, IMoGoMapFragmentProvider, IMoGoSkinModeChangeListener {
implements MapView, IMoGoMapFragmentProvider, IMoGoSkinModeChangeListener
, IMoGoAutopilotPlanningListener {
private static final String TAG = "MapFragment";
@@ -44,6 +64,11 @@ public class MapFragment extends MvpFragment<MapView, MapPresenter>
private IMogoMap mMogoMap;
private TextureMapView mNaviMapView;
private AMap mAMap;
// 每个GeoHash网格对应的新基建Bean
private Map<String, ArrayList<Infrastructure>> infMap = new HashMap();
// 全局路径规划中的GeoHash网格
private Map<String, ArrayList<Infrastructure>> pathMap = new HashMap();
private Map<LatLng, Infrastructure> posInfMap = new HashMap();
private final boolean mIsControllerByOthersStatus = false;
@@ -90,6 +115,7 @@ public class MapFragment extends MvpFragment<MapView, MapPresenter>
mAMap = mNaviMapView.getMap();
// 添加换肤监听
CallerSkinModeListenerManager.INSTANCE.addListener(TAG, this);
CallerAutopilotPlanningListenerManager.INSTANCE.addListener(TAG, this);
}
@NonNull
@@ -102,6 +128,7 @@ public class MapFragment extends MvpFragment<MapView, MapPresenter>
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initMapView();
queryInfStructure();
}
@Override
@@ -184,6 +211,34 @@ public class MapFragment extends MvpFragment<MapView, MapPresenter>
MapPointCloudSubscriber.Companion.getInstance();
}
private boolean isFirst = true;
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(), map -> {
if (!infMap.isEmpty()) {
infMap.clear();
}
infMap.putAll(map);
});
viewModel.fetchInfStructures();
}
@Override
public IMogoMapUIController getUIController() {
return mMogoMap.getUIController();
@@ -192,6 +247,7 @@ public class MapFragment extends MvpFragment<MapView, MapPresenter>
@Override
public void onDestroyView() {
CallerSkinModeListenerManager.INSTANCE.removeListener(TAG);
CallerAutopilotPlanningListenerManager.INSTANCE.removeListener(TAG);
if (mMogoMapView != null) {
mMogoMapView.onDestroy();
mMogoMapView = null;
@@ -302,6 +358,67 @@ public class MapFragment extends MvpFragment<MapView, MapPresenter>
PointCloudHelper.INSTANCE.setIsDrawPointCloud(isDrawPointCloud);
}
@Override
public void onAutopilotTrajectory(@NonNull List<MessagePad.TrajectoryPoint> trajectoryInfos) {
}
@Override
public void onAutopilotRotting(MessagePad.GlobalPathResp globalPathResp) {
if (globalPathResp != null) {
if (!pathMap.isEmpty()) {
pathMap.clear();
}
String geoHash;
ArrayList<Infrastructure> infList;
for (MessagePad.Location location : globalPathResp.getWayPointsList()) {
geoHash = GeoHash.withCharacterPrecision(location.getLatitude(), location.getLongitude(), 7).toBase32();
// 网格内的轨迹点只取一次
if (!pathMap.containsKey(geoHash)) {
// 从缓存的新基建数据中去取对应geoHash的新基建数据集合
infList = infMap.get(geoHash);
if (infList != null) {
pathMap.put(geoHash, infList);
}
}
}
// 绘制新基建数据
if (!posInfMap.isEmpty()) {
posInfMap.clear();
}
ArrayList<MarkerOptions> markerOptionsList = new ArrayList();
for (ArrayList<Infrastructure> structureList : pathMap.values()) {
for (Infrastructure structure : structureList) {
MarkerOptions markerOption = new MarkerOptions();
LatLng latLng = new LatLng(Double.valueOf(structure.getLat()),
Double.valueOf(structure.getLon()));
markerOption.position(latLng);
markerOption.icon(BitmapDescriptorFactory.fromBitmap(
BitmapFactory.decodeResource(getResources(), R.drawable.icon_shexiangtou_nor)
));
posInfMap.put(latLng, structure);
markerOptionsList.add(markerOption);
}
}
mAMap.addMarkers(markerOptionsList, false);
mAMap.setOnMarkerClickListener(marker -> {
Infrastructure infrastructure = posInfMap.get(marker.getPosition());
// 如果是摄像头
if (0 == infrastructure.getCategory() && infrastructure.getIp() != null) {
CallerMonitorManager.INSTANCE.openCameraStream(infrastructure.getIp(),
flvUrl -> {
return null;
}, throwable -> {
return null;
});
return true;
}
return false;
});
}
}
/**
* 设置地图是否是Debug模式
* @param debugMode 是否开启Debug模式

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB