From 5385199493fc3735713c8ddd08b5ef52ae0e6bf8 Mon Sep 17 00:00:00 2001 From: wangcongtao Date: Wed, 28 Oct 2020 14:31:12 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=98=E5=88=B6=E6=AF=8F=E7=A7=92=E4=B8=80?= =?UTF-8?q?=E6=AC=A1=E7=9A=84=E8=BD=A6=E8=BE=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libraries/map-custom/build.gradle | 2 +- .../mogo/map/impl/custom/AMapViewWrapper.java | 2 +- .../mogo/map/impl/custom/CustomMapView.java | 14 +- .../map_custom_ic_current_location2.png | Bin 0 -> 47414 bytes .../main/java/com/mogo/map/MogoMapView.java | 10 ++ .../IMachineVisionInterface.aidl | 4 + .../module/common/entity/CloudRoadData.java | 118 ++++++++----- .../module/service/MogoServiceProvider.java | 1 + .../com/mogo/module/service/MogoServices.java | 27 +-- .../com/mogo/module/service/ServiceConst.java | 10 ++ .../marker/AdasRecognizedResultDrawer.java | 151 ++++++++++++++++ .../service/marker/AdasRecognizedType.java | 27 +++ .../service/marker/MapMarkerManager.java | 13 +- .../service/marker/SnapshotSetDataDrawer.java | 164 ++++++++++++++++++ .../MogoRefreshStrategyController.java | 9 +- .../service/vrmode/VrModeController.java | 19 ++ .../vision/MachineVisionMapService.java | 36 +++- .../machine/vision/MachineVisionMapView.java | 26 ++- .../vision/MachineVisionMapViewHandler.java | 1 + .../res/layout/module_mvision_layout_view.xml | 9 +- 20 files changed, 566 insertions(+), 77 deletions(-) create mode 100644 libraries/map-custom/src/main/res/drawable-xhdpi/map_custom_ic_current_location2.png create mode 100644 modules/mogo-module-service/src/main/java/com/mogo/module/service/marker/AdasRecognizedResultDrawer.java create mode 100644 modules/mogo-module-service/src/main/java/com/mogo/module/service/marker/AdasRecognizedType.java create mode 100644 modules/mogo-module-service/src/main/java/com/mogo/module/service/marker/SnapshotSetDataDrawer.java diff --git a/libraries/map-custom/build.gradle b/libraries/map-custom/build.gradle index 56e4020d79..b542142f9d 100644 --- a/libraries/map-custom/build.gradle +++ b/libraries/map-custom/build.gradle @@ -55,7 +55,7 @@ dependencies { implementation project(':foudations:mogo-commons') } - implementation 'com.zhidaoauto.machine:map:1.0.0-online-19' + implementation 'com.zhidaoauto.machine:map:1.0.0-online-21' } apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString() diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/AMapViewWrapper.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/AMapViewWrapper.java index ad1ed7b446..06418ba36e 100644 --- a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/AMapViewWrapper.java +++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/AMapViewWrapper.java @@ -68,7 +68,7 @@ public class AMapViewWrapper implements IMogoMapView, IMogoMapUIController, Loca private float mDefaultZoomLevel = 16.0f; private final CarCursorOption DEFAULT_OPTION = new CarCursorOption.Builder() - .carCursorRes( R.drawable.map_api_ic_current_location2 ) + .carCursorRes( R.drawable.map_custom_ic_current_location2 ) .naviCursorRes( R.drawable.ic_amap_navi_cursor ) .build(); private CarCursorOption mCarCursorOption = DEFAULT_OPTION; diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/CustomMapView.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/CustomMapView.java index 9e8c503db9..dd7ce735df 100644 --- a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/CustomMapView.java +++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/CustomMapView.java @@ -23,12 +23,14 @@ public class CustomMapView implements IMogoMapViewCreator { @Override public IMogoMapView create( Context context ) { - MapAutoApi.INSTANCE.init( context, MapParams.Companion.init().setDebugMode( true ) - .setCoordinateType( MapParams.COORDINATETYPE_GCJ02 ) - .setPerspectiveMode( MapParams.MAP_PERSPECTIVE_2D ) - .setZoom( 16 ) - .setPointToCenter( 0.5f, 0.5f ) - .setStyleMode( MapParams.MAP_STYLE_VR ) ); + if ( mapView == null ) { + MapAutoApi.INSTANCE.init( context, MapParams.Companion.init().setDebugMode( false ) + .setCoordinateType( MapParams.COORDINATETYPE_GCJ02 ) + .setPerspectiveMode( MapParams.MAP_PERSPECTIVE_2D ) + .setZoom( 16 ) + .setPointToCenter( 0.5f, 0.5f ) + .setStyleMode( MapParams.MAP_STYLE_VR ) ); + } MapAutoView mapAutoView = new MapAutoView( context ); mapView = new AMapViewWrapper( mapAutoView ); return mapView; diff --git a/libraries/map-custom/src/main/res/drawable-xhdpi/map_custom_ic_current_location2.png b/libraries/map-custom/src/main/res/drawable-xhdpi/map_custom_ic_current_location2.png new file mode 100644 index 0000000000000000000000000000000000000000..dc22ac57a1ef296633c60207ee1250edd590a3eb GIT binary patch literal 47414 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 coordinates; + private List coordinates; - protected CloudRoadData(Parcel in) { - type = in.readInt(); - lat = in.readDouble(); - lon = in.readDouble(); - speed = in.readDouble(); - systemTime = in.readLong(); - lightStatus = in.readInt(); - lightLeftTime = in.readInt(); - rtmpUrl = in.readString(); - distance = in.readDouble(); - coordinates = in.createTypedArrayList(CloudLocationInfo.CREATOR); - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(type); - dest.writeDouble(lat); - dest.writeDouble(lon); - dest.writeDouble(speed); - dest.writeLong(systemTime); - dest.writeInt(lightStatus); - dest.writeInt(lightLeftTime); - dest.writeString(rtmpUrl); - dest.writeDouble(distance); - dest.writeTypedList(coordinates); - } - - @Override - public int describeContents() { - return 0; - } - - public static final Creator CREATOR = new Creator() { - @Override - public CloudRoadData createFromParcel(Parcel in) { - return new CloudRoadData(in); - } - - @Override - public CloudRoadData[] newArray(int size) { - return new CloudRoadData[size]; - } - }; - public int getType() { return type; } @@ -155,4 +115,70 @@ public class CloudRoadData implements Parcelable { public void setCoordinates(List coordinates) { this.coordinates = coordinates; } + + public String getUuid() { + return uuid; + } + + public String getSn() { + return sn; + } + + public String getUniqueKey(){ + if (! TextUtils.isEmpty( uuid ) ) { + return uuid; + } + return sn; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel( Parcel dest, int flags ) { + dest.writeInt( this.type ); + dest.writeDouble( this.lat ); + dest.writeDouble( this.lon ); + dest.writeString( this.uuid ); + dest.writeString( this.sn ); + dest.writeDouble( this.speed ); + dest.writeLong( this.systemTime ); + dest.writeInt( this.lightStatus ); + dest.writeInt( this.lightLeftTime ); + dest.writeString( this.rtmpUrl ); + dest.writeDouble( this.distance ); + dest.writeTypedList( this.coordinates ); + } + + public CloudRoadData() { + } + + protected CloudRoadData( Parcel in ) { + this.type = in.readInt(); + this.lat = in.readDouble(); + this.lon = in.readDouble(); + this.uuid = in.readString(); + this.sn = in.readString(); + this.speed = in.readDouble(); + this.systemTime = in.readLong(); + this.lightStatus = in.readInt(); + this.lightLeftTime = in.readInt(); + this.rtmpUrl = in.readString(); + this.distance = in.readDouble(); + this.coordinates = in.createTypedArrayList( CloudLocationInfo.CREATOR ); + } + + public static final Creator< CloudRoadData > CREATOR = new Creator< CloudRoadData >() { + @Override + public CloudRoadData createFromParcel( Parcel source ) { + return new CloudRoadData( source ); + } + + @Override + public CloudRoadData[] newArray( int size ) { + return new CloudRoadData[size]; + } + }; } diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/MogoServiceProvider.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/MogoServiceProvider.java index ca00298278..7f87e6ac52 100644 --- a/modules/mogo-module-service/src/main/java/com/mogo/module/service/MogoServiceProvider.java +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/MogoServiceProvider.java @@ -96,6 +96,7 @@ public class MogoServiceProvider implements IMogoModuleProvider { public void init( Context context ) { Logger.d( TAG, "init" ); MarkerServiceHandler.init( context ); + MogoServices.getInstance().preInit( context ); UiThreadHandler.postDelayed( () -> { MogoServices.getInstance().init( AbsMogoApplication.getApp() ); }, 5_000L ); diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/MogoServices.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/MogoServices.java index 4bde03d82e..65f2869d04 100644 --- a/modules/mogo-module-service/src/main/java/com/mogo/module/service/MogoServices.java +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/MogoServices.java @@ -339,6 +339,7 @@ public class MogoServices implements IMogoMapListener, unregisterInternalUnWakeupWords(); stopAutoRefreshStrategy(); } + VrModeController.getInstance().onMainPageResumeStatusChanged( resume ); } @Override @@ -373,15 +374,14 @@ public class MogoServices implements IMogoMapListener, } }; - public void init( Context context ) { + public void preInit( Context context ) { mContext = context; - initWorkThread(); - mRefreshModel = new RefreshModel( context ); mMogoMapService = MarkerServiceHandler.getMapService(); mUiController = mMogoMapService.getMapUIController(); mNavi = mMogoMapService.getNavi( context ); + mStatusManager = MarkerServiceHandler.getMogoStatusManager(); mStatusManager.registerStatusChangedListener( ServiceConst.TYPE, StatusDescriptor.USER_INTERACTED, statusChangedListener ); mStatusManager.registerStatusChangedListener( ServiceConst.TYPE, StatusDescriptor.SEARCH_UI, statusChangedListener ); @@ -390,6 +390,12 @@ public class MogoServices implements IMogoMapListener, mStatusManager.registerStatusChangedListener( ServiceConst.TYPE, StatusDescriptor.ACC_STATUS, statusChangedListener ); mStatusManager.registerStatusChangedListener( ServiceConst.TYPE, StatusDescriptor.VR_MODE, statusChangedListener ); mStatusManager.setAIAssistReady( TAG, AIAssist.getInstance( mContext ).hasFlush() ); + } + + public void init( Context context ) { + + + initWorkThread(); registerMogoReceiver( context ); registerInternalUnWakeupWords(); @@ -461,16 +467,17 @@ public class MogoServices implements IMogoMapListener, if ( lastCarLocation != null ) { locationResult = new LocationResult(); locationResult.lastCoordinate = new CloudLocationInfo(); - locationResult.lastCoordinate.setAlt(lastCarLocation.getAltitude()); - locationResult.lastCoordinate.setHeading(lastCarLocation.getBearing()); - locationResult.lastCoordinate.setLat(lastCarLocation.getLatitude()); - locationResult.lastCoordinate.setLon(lastCarLocation.getLongitude()); - locationResult.lastCoordinate.setSatelliteTime(lastCarLocation.getTime()); - locationResult.lastCoordinate.setSystemTime(System.currentTimeMillis()); - locationResult.lastCoordinate.setSpeed(lastCarLocation.getSpeed()); + locationResult.lastCoordinate.setAlt( lastCarLocation.getAltitude() ); + locationResult.lastCoordinate.setHeading( lastCarLocation.getBearing() ); + locationResult.lastCoordinate.setLat( lastCarLocation.getLatitude() ); + locationResult.lastCoordinate.setLon( lastCarLocation.getLongitude() ); + locationResult.lastCoordinate.setSatelliteTime( lastCarLocation.getTime() ); + locationResult.lastCoordinate.setSystemTime( System.currentTimeMillis() ); + locationResult.lastCoordinate.setSpeed( lastCarLocation.getSpeed() ); locationResult.coordinates = new ArrayList<>(); locationResult.sn = com.mogo.commons.network.Utils.getSn(); locationResult.mortonCode = MortonCode.wrapEncodeMorton( locationResult.lastCoordinate.getLon(), locationResult.lastCoordinate.getLat() ); + locationResult.coordinates.add( locationResult.lastCoordinate ); } List< ADASRecognizedResult > recognizedResults = MarkerServiceHandler.getADASController().getLastADASRecognizedResult(); OnePerSecondSendContent content = new OnePerSecondSendContent(); diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/ServiceConst.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/ServiceConst.java index 94bb9c7357..c42b5dc99d 100644 --- a/modules/mogo-module-service/src/main/java/com/mogo/module/service/ServiceConst.java +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/ServiceConst.java @@ -228,4 +228,14 @@ public class ServiceConst { */ public static final long INTERVAL_SEND_CAR_LOCATION_AND_ADAS_RECOGNIZED_RESULT_2_SERVER = 1 * 1_000L; + /** + * adas识别数据 + */ + public static final String TYPE_MARKER_ADAS = "TYPE_MARKER_ADAS"; + + /** + * 云端下发数据 + */ + public static final String TYPE_MARKER_CLOUD_DATA = "TYPE_MARKER_CLOUD_DATA"; + } diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/marker/AdasRecognizedResultDrawer.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/marker/AdasRecognizedResultDrawer.java new file mode 100644 index 0000000000..89f8234fee --- /dev/null +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/marker/AdasRecognizedResultDrawer.java @@ -0,0 +1,151 @@ +package com.mogo.module.service.marker; + +import android.content.Context; +import android.graphics.BitmapFactory; + +import com.mogo.commons.AbsMogoApplication; +import com.mogo.map.MogoLatLng; +import com.mogo.map.marker.IMogoMarker; +import com.mogo.map.marker.MogoMarkerOptions; +import com.mogo.module.common.ModuleNames; +import com.mogo.module.service.MarkerServiceHandler; +import com.mogo.module.service.R; +import com.mogo.module.service.ServiceConst; +import com.mogo.service.adas.entity.ADASRecognizedListResult; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public +/** + * @author congtaowang + * @since 2020/10/28 + * + * 绘制adas近景识别到的车辆 + */ +class AdasRecognizedResultDrawer { + + private static volatile AdasRecognizedResultDrawer sInstance; + + private Context mContext; + + private AdasRecognizedResultDrawer() { + mContext = AbsMogoApplication.getApp(); + } + + public static AdasRecognizedResultDrawer getInstance() { + if ( sInstance == null ) { + synchronized ( AdasRecognizedResultDrawer.class ) { + if ( sInstance == null ) { + sInstance = new AdasRecognizedResultDrawer(); + } + } + } + return sInstance; + } + + public synchronized void release() { + sInstance = null; + } + + private Object readResolve() { + // 阻止反序列化,必须实现 Serializable 接口 + return sInstance; + } + + // adas marker 缓存 + private Map< String, IMogoMarker > mAdasRecognizedMarkersCaches = new ConcurrentHashMap<>(); + + public void renderAdasRecognizedResult( List< ADASRecognizedListResult > resultList ) { + if ( resultList == null || resultList.isEmpty() ) { + MarkerServiceHandler.getApis().getMapServiceApi().getMarkerManager( mContext ).removeMarkers( ServiceConst.TYPE_MARKER_ADAS ); + return; + } + purgeAdasRecognizedData( resultList ); + for ( ADASRecognizedListResult recognizedListResult : resultList ) { + if ( recognizedListResult == null ) { + continue; + } + IMogoMarker marker = null; + String uniqueKey = recognizedListResult.uuid; + if ( mAdasRecognizedMarkersCaches.containsKey( uniqueKey ) ) { + marker = mAdasRecognizedMarkersCaches.get( uniqueKey ); + } + if ( marker == null || marker.isDestroyed() ) { + marker = drawAdasRecognizedDataMarker( recognizedListResult ); + mAdasRecognizedMarkersCaches.put( uniqueKey, marker ); + } + + if ( recognizedListResult.latLonList != null + || recognizedListResult.latLonList.size() > 1 ) { + List< MogoLatLng > points = new ArrayList<>(); + for ( int j = 0; j < recognizedListResult.latLonList.size(); j++ ) { + ADASRecognizedListResult.LatLon latLon = recognizedListResult.latLonList.get( j ); + if ( latLon == null ) { + continue; + } + points.add( new MogoLatLng( latLon.lat, latLon.lon ) ); + } + if ( points.size() >= 1 ) { + marker.startSmooth( points, 1000 ); + } else { + + } + } + } + } + + /** + * 过滤adas数据中,不存在的 marker + * + * @param resultList + */ + private void purgeAdasRecognizedData( List< ADASRecognizedListResult > resultList ) { + if ( resultList == null || resultList.isEmpty() ) { + return; + } + if ( mAdasRecognizedMarkersCaches.isEmpty() ) { + return; + } + Map< String, IMogoMarker > existMarker = new HashMap<>(); + for ( ADASRecognizedListResult recognizedListResult : resultList ) { + if ( recognizedListResult == null ) { + continue; + } + String uniqueKey = recognizedListResult.uuid; + if ( mAdasRecognizedMarkersCaches.containsKey( uniqueKey ) ) { + existMarker.put( uniqueKey, mAdasRecognizedMarkersCaches.get( uniqueKey ) ); + } + } + if ( !existMarker.isEmpty() ) { + for ( String key : mAdasRecognizedMarkersCaches.keySet() ) { + if ( !existMarker.containsKey( key ) ) { + try { + IMogoMarker marker = mAdasRecognizedMarkersCaches.remove( key ); + marker.destroy(); + } catch ( Exception e ) { + e.printStackTrace(); + } + } + } + } + } + + private IMogoMarker drawAdasRecognizedDataMarker( ADASRecognizedListResult recognizedListResult ) { + if ( recognizedListResult == null ) { + return null; + } + + if ( recognizedListResult.type == AdasRecognizedType.classIdBackground ) { + + } + MogoMarkerOptions options = new MogoMarkerOptions() + .owner( ServiceConst.TYPE_MARKER_ADAS ) + .icon( BitmapFactory.decodeResource( mContext.getResources(), R.drawable.map_custom_ic_current_location2 ) ) + .position( new MogoLatLng( recognizedListResult.latLonList.get( 0 ).lat, recognizedListResult.latLonList.get( 0 ).lon ) ); + return MarkerServiceHandler.getMapService().getMarkerManager( mContext ).addMarker( ModuleNames.CARD_TYPE_ROAD_CONDITION, options ); + } +} diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/marker/AdasRecognizedType.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/marker/AdasRecognizedType.java new file mode 100644 index 0000000000..228a134ea9 --- /dev/null +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/marker/AdasRecognizedType.java @@ -0,0 +1,27 @@ +package com.mogo.module.service.marker; + +public +/** + * @author congtaowang + * @since 2020/10/27 + *

+ * 描述 + */ +class AdasRecognizedType { + //背景 + public static final int classIdBackground = 0; + //人 + public static final int classIdPerson = 1; + //自行车 + public static final int classIdBicycle = 2; + //小轿车 + public static final int classIdCar = 3; + //摩托车 + public static final int classIdMoto = 4; + //红绿灯 + public static final int classIdTrafficSign = 5; + //bus + public static final int classIdTrafficBus = 6; + //track + public static final int classIdTrafficTruck = 8; +} diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/marker/MapMarkerManager.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/marker/MapMarkerManager.java index 757e1044ab..cba98cd5f4 100644 --- a/modules/mogo-module-service/src/main/java/com/mogo/module/service/marker/MapMarkerManager.java +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/marker/MapMarkerManager.java @@ -1,6 +1,7 @@ package com.mogo.module.service.marker; import android.content.Context; +import android.graphics.BitmapFactory; import android.graphics.Rect; import android.text.TextUtils; import android.view.animation.LinearInterpolator; @@ -16,6 +17,8 @@ import com.mogo.map.marker.anim.OnMarkerAnimationListener; import com.mogo.map.uicontroller.EnumMapUI; import com.mogo.module.common.ModuleNames; import com.mogo.module.common.api.CallChatApi; +import com.mogo.module.common.entity.CloudLocationInfo; +import com.mogo.module.common.entity.CloudRoadData; import com.mogo.module.common.entity.MarkerCarPois; import com.mogo.module.common.entity.MarkerCardResult; import com.mogo.module.common.entity.MarkerExploreWay; @@ -35,6 +38,7 @@ import com.mogo.module.service.network.RefreshModel; import com.mogo.module.service.utils.ViewUtils; import com.mogo.module.service.vrmode.VrModeController; import com.mogo.service.adas.IMogoADASControlStatusChangedListener; +import com.mogo.service.adas.entity.ADASRecognizedListResult; import com.mogo.service.connection.IMogoOnMessageListener; import com.mogo.service.connection.IMogoOnWebSocketMessageListener; import com.mogo.service.connection.WebSocketMsgType; @@ -53,6 +57,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** * author : donghongyu @@ -133,6 +138,7 @@ public class MapMarkerManager implements IMogoMarkerClickListener, } ); + // 每隔一秒下发的数据 MarkerServiceHandler.getApis().getWebSocketManagerApi( mContext ) .registerOnWebSocketMessageListener( new IMogoOnWebSocketMessageListener< MogoSnapshotSetData >() { @@ -156,6 +162,7 @@ public class MapMarkerManager implements IMogoMarkerClickListener, if ( data == null ) { return; } + SnapshotSetDataDrawer.getInstance().renderSnapshotData( data ); VrModeController.getInstance().renderMogoSnapshotSetData( data ); } @@ -164,15 +171,17 @@ public class MapMarkerManager implements IMogoMarkerClickListener, } } ); + // adas 每隔一秒传递的数据 MarkerServiceHandler.getApis().getAdasControllerApi().addAdasRecognizedDataCallback( resultList -> { if ( resultList == null || resultList.isEmpty() ) { return; } // 绘制近景识别到的车辆,每秒绘制一次 + AdasRecognizedResultDrawer.getInstance().renderAdasRecognizedResult( resultList ); } ); - } + /** * 地图上的Marker点击回调 */ @@ -242,7 +251,7 @@ public class MapMarkerManager implements IMogoMarkerClickListener, updateCarUserInfoWindow( mogoMarker ); } else { Object object = mogoMarker.getObject(); - if ( object != null ) { + if ( object instanceof MarkerShowEntity ) { MarkerShowEntity markerShowEntity = ( MarkerShowEntity ) object; markerShowEntity.setChecked( true ); IMarkerView markerView = MapMarkerAdapter.getMarkerView( mContext, markerShowEntity, mogoMarker.getMogoMarkerOptions() ); diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/marker/SnapshotSetDataDrawer.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/marker/SnapshotSetDataDrawer.java new file mode 100644 index 0000000000..70b36b7fe2 --- /dev/null +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/marker/SnapshotSetDataDrawer.java @@ -0,0 +1,164 @@ +package com.mogo.module.service.marker; + +import android.content.Context; +import android.graphics.BitmapFactory; + +import com.mogo.commons.AbsMogoApplication; +import com.mogo.map.MogoLatLng; +import com.mogo.map.marker.IMogoMarker; +import com.mogo.map.marker.MogoMarkerOptions; +import com.mogo.module.common.ModuleNames; +import com.mogo.module.common.entity.CloudLocationInfo; +import com.mogo.module.common.entity.CloudRoadData; +import com.mogo.module.common.entity.MogoSnapshotSetData; +import com.mogo.module.service.MarkerServiceHandler; +import com.mogo.module.service.R; +import com.mogo.module.service.ServiceConst; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public +/** + * @author congtaowang + * @since 2020/10/28 + * + * 云端数据绘制 + */ +class SnapshotSetDataDrawer { + + private static volatile SnapshotSetDataDrawer sInstance; + + private Context mContext; + + private SnapshotSetDataDrawer() { + mContext = AbsMogoApplication.getApp(); + } + + public static SnapshotSetDataDrawer getInstance() { + if ( sInstance == null ) { + synchronized ( SnapshotSetDataDrawer.class ) { + if ( sInstance == null ) { + sInstance = new SnapshotSetDataDrawer(); + } + } + } + return sInstance; + } + + public synchronized void release() { + sInstance = null; + } + + private Object readResolve() { + // 阻止反序列化,必须实现 Serializable 接口 + return sInstance; + } + + // 云端 marker 缓存 + private Map< String, IMogoMarker > mCloudSnapshotMarkersCaches = new ConcurrentHashMap<>(); + + + /** + * 其他车辆、rsu 车辆数据 + * + * @param data + */ + public void renderSnapshotData( MogoSnapshotSetData data ) { + if ( data == null || data.getAllList() == null || data.getAllList().isEmpty() ) { + return; + } + purgeCloudSnapshotData( data ); + for ( CloudRoadData cloudRoadData : data.getAllList() ) { + if ( cloudRoadData == null ) { + continue; + } + if ( cloudRoadData.getDistance() < 50 ) { + // 过滤 adas 识别的车辆 + continue; + } + IMogoMarker marker = null; + String uniqueKey = cloudRoadData.getUniqueKey(); + if ( mCloudSnapshotMarkersCaches.containsKey( uniqueKey ) ) { + marker = mCloudSnapshotMarkersCaches.get( uniqueKey ); + } + if ( marker == null || marker.isDestroyed() ) { + marker = drawSnapshotDataMarker( cloudRoadData ); + mCloudSnapshotMarkersCaches.put( uniqueKey, marker ); + } + if ( cloudRoadData.getCoordinates() != null + || cloudRoadData.getCoordinates().size() > 1 ) { + List< MogoLatLng > points = new ArrayList<>(); + for ( int j = 0; j < cloudRoadData.getCoordinates().size(); j++ ) { + CloudLocationInfo poi = cloudRoadData.getCoordinates().get( j ); + if ( poi == null ) { + continue; + } + double lat = poi.getLat(); + double lng = poi.getLon(); + points.add( new MogoLatLng( lat, lng ) ); + } + if ( points.size() >= 1 ) { + marker.startSmooth( points, 1000 ); + } else { + + } + } + } + } + + /** + * 过滤本次数据中,不存在的 marker + * + * @param data + */ + private void purgeCloudSnapshotData( MogoSnapshotSetData data ) { + if ( data == null || data.getAllList() == null || data.getAllList().isEmpty() ) { + return; + } + if ( mCloudSnapshotMarkersCaches.isEmpty() ) { + return; + } + Map< String, IMogoMarker > existMarker = new HashMap<>(); + for ( CloudRoadData cloudRoadData : data.getAllList() ) { + if ( cloudRoadData == null ) { + continue; + } + String uniqueKey = cloudRoadData.getUniqueKey(); + if ( mCloudSnapshotMarkersCaches.containsKey( uniqueKey ) ) { + existMarker.put( uniqueKey, mCloudSnapshotMarkersCaches.get( uniqueKey ) ); + } + } + + if ( !existMarker.isEmpty() ) { + for ( String key : mCloudSnapshotMarkersCaches.keySet() ) { + if ( !existMarker.containsKey( key ) ) { + try { + IMogoMarker marker = mCloudSnapshotMarkersCaches.remove( key ); + marker.destroy(); + } catch ( Exception e ) { + e.printStackTrace(); + } + } + } + } + } + + private IMogoMarker drawSnapshotDataMarker( CloudRoadData data ) { + if ( data == null ) { + return null; + } + + if ( data.getType() == AdasRecognizedType.classIdBackground ) { + + } + MogoMarkerOptions options = new MogoMarkerOptions() + .owner( ServiceConst.TYPE_MARKER_CLOUD_DATA ) + .icon( BitmapFactory.decodeResource( mContext.getResources(), R.drawable.map_custom_ic_current_location2 ) ) + .position( new MogoLatLng( data.getLat(), data.getLon() ) ); + return MarkerServiceHandler.getMapService().getMarkerManager( mContext ).addMarker( ModuleNames.CARD_TYPE_ROAD_CONDITION, options ); + } +} diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/strategy/MogoRefreshStrategyController.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/strategy/MogoRefreshStrategyController.java index 9d09334d74..6669e87641 100644 --- a/modules/mogo-module-service/src/main/java/com/mogo/module/service/strategy/MogoRefreshStrategyController.java +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/strategy/MogoRefreshStrategyController.java @@ -6,6 +6,7 @@ import com.alibaba.android.arouter.facade.annotation.Route; import com.mogo.module.service.MogoServices; import com.mogo.service.MogoServicePaths; import com.mogo.service.strategy.IMogoRefreshStrategyController; +import com.mogo.utils.logger.Logger; /** * @author congtaowang @@ -16,9 +17,15 @@ import com.mogo.service.strategy.IMogoRefreshStrategyController; @Route( path = MogoServicePaths.PATH_REFRESH_STRATEGY_API ) public class MogoRefreshStrategyController implements IMogoRefreshStrategyController { + private static final String TAG = "MogoRefreshStrategyController"; + @Override public void restartAutoRefreshAtTime( int delay ) { - MogoServices.getInstance().restartAutoRefreshAtTime( delay ); + try { + MogoServices.getInstance().restartAutoRefreshAtTime( delay ); + } catch ( Exception e ) { + Logger.e(TAG, e, "restartAutoRefreshAtTime"); + } } @Override diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/vrmode/VrModeController.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/vrmode/VrModeController.java index 40c465e2b8..6f8521dab3 100644 --- a/modules/mogo-module-service/src/main/java/com/mogo/module/service/vrmode/VrModeController.java +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/vrmode/VrModeController.java @@ -5,6 +5,7 @@ import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; +import android.os.RemoteException; import com.mogo.commons.AbsMogoApplication; import com.mogo.module.common.entity.MogoSnapshotSetData; @@ -93,6 +94,24 @@ class VrModeController { } } + public void onMainPageResumeStatusChanged( boolean isResume ) { + if ( mMachineVisionInterface != null ) { + if ( isResume ) { + try { + mMachineVisionInterface.showViewIfExist(); + } catch ( RemoteException e ) { + Logger.e( TAG, e, "onMainPageResumeStatusChanged" ); + } + } else { + try { + mMachineVisionInterface.hideViewIfExist(); + } catch ( RemoteException e ) { + Logger.e( TAG, e, "onMainPageResumeStatusChanged" ); + } + } + } + } + public void renderMogoSnapshotSetData( MogoSnapshotSetData data ) { if ( data == null ) { return; diff --git a/modules/mogo-modules-mvision/src/main/java/com/mogo/module/machine/vision/MachineVisionMapService.java b/modules/mogo-modules-mvision/src/main/java/com/mogo/module/machine/vision/MachineVisionMapService.java index 670be37437..0db735eb50 100644 --- a/modules/mogo-modules-mvision/src/main/java/com/mogo/module/machine/vision/MachineVisionMapService.java +++ b/modules/mogo-modules-mvision/src/main/java/com/mogo/module/machine/vision/MachineVisionMapService.java @@ -6,6 +6,8 @@ import android.content.ServiceConnection; import android.os.IBinder; import android.os.RemoteException; import android.view.Gravity; +import android.view.View; +import android.view.WindowManager; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -13,6 +15,7 @@ import androidx.annotation.Nullable; import com.mogo.module.common.entity.MogoSnapshotSetData; import com.mogo.module.common.machinevision.IMachineVisionInterface; import com.mogo.module.common.wm.WindowManagerView; +import com.mogo.utils.UiThreadHandler; import com.mogo.utils.logger.Logger; public @@ -29,6 +32,7 @@ class MachineVisionMapService extends Service { private IBinder mBinder; private WindowManagerView mMachineVisionMapViewManager; + private View mRootView; @Nullable @Override @@ -80,14 +84,38 @@ class MachineVisionMapService extends Service { public boolean unlinkToDeath( @NonNull DeathRecipient recipient, int flags ) { return super.unlinkToDeath( recipient, flags ); } + + @Override + public void hideViewIfExist() throws RemoteException { + if ( mRootView != null ) { + Logger.d( TAG, "hideViewIfExist" ); + UiThreadHandler.post( () -> { + if ( mRootView != null ) { + mRootView.setVisibility( View.GONE ); + } + } ); + } + } + + @Override + public void showViewIfExist() throws RemoteException { + if ( mRootView != null ) { + Logger.d( TAG, "showViewIfExist" ); + UiThreadHandler.post( () -> { + if ( mRootView != null ) { + mRootView.setVisibility( View.VISIBLE ); + } + } ); + } + } } private void addMachineVisionMapView() { mMachineVisionMapViewManager = new WindowManagerView.Builder( getApplicationContext() ) .contentView( R.layout.module_mvision_layout_view ) .size( - getResources().getDimensionPixelOffset( R.dimen.module_mvision_view_width ), - getResources().getDimensionPixelOffset( R.dimen.module_mvision_view_height ) + WindowManager.LayoutParams.WRAP_CONTENT, + WindowManager.LayoutParams.WRAP_CONTENT ) .position( getResources().getDimensionPixelOffset( R.dimen.module_mvision_view_x ), @@ -95,7 +123,7 @@ class MachineVisionMapService extends Service { ) .gravity( Gravity.TOP | Gravity.LEFT ) .showInWindowManager(); - + mRootView = mMachineVisionMapViewManager.findViewById( R.id.module_mvision_map_root ); MachineVisionMapViewHandler.getInstance().setMachineVisionMapView( mMachineVisionMapViewManager.findViewById( R.id.module_mvision_map_view ) ); mMachineVisionMapViewManager.show(); } @@ -103,8 +131,10 @@ class MachineVisionMapService extends Service { @Override public void onDestroy() { super.onDestroy(); + MachineVisionMapViewHandler.getInstance().release(); if ( mMachineVisionMapViewManager != null ) { mMachineVisionMapViewManager.dismiss(); + mRootView = null; } } } diff --git a/modules/mogo-modules-mvision/src/main/java/com/mogo/module/machine/vision/MachineVisionMapView.java b/modules/mogo-modules-mvision/src/main/java/com/mogo/module/machine/vision/MachineVisionMapView.java index 3bad7b9d22..bb65a08e11 100644 --- a/modules/mogo-modules-mvision/src/main/java/com/mogo/module/machine/vision/MachineVisionMapView.java +++ b/modules/mogo-modules-mvision/src/main/java/com/mogo/module/machine/vision/MachineVisionMapView.java @@ -10,6 +10,7 @@ import android.widget.FrameLayout; import androidx.annotation.Nullable; import com.mogo.map.IMogoMapView; +import com.mogo.map.MogoBaseMapView; import com.mogo.map.impl.custom.CustomMapView; import com.mogo.utils.logger.Logger; @@ -20,7 +21,7 @@ public * * 描述 */ -class MachineVisionMapView extends FrameLayout { +class MachineVisionMapView extends MogoBaseMapView { private static final String TAG = "MachineVisionMapView"; @@ -34,10 +35,10 @@ class MachineVisionMapView extends FrameLayout { public MachineVisionMapView( Context context, @Nullable AttributeSet attrs, int defStyleAttr ) { super( context, attrs, defStyleAttr ); - addMapView(); } - private void addMapView() { + @Override + protected void addDleMaps() { IMogoMapView machineMapView = new CustomMapView().create( getContext() ); if ( machineMapView != null ) { final View mapView = machineMapView.getMapView(); @@ -49,5 +50,24 @@ class MachineVisionMapView extends FrameLayout { } else { Logger.e( TAG, "create IMogoMapView instance failed." ); } + mMapView = machineMapView; + onCreate( null ); + postDelayed( ()->{ + getMap().getUIController().showMyLocation( true ); + }, 5000 ); + } + + @Override + public void display2DMap( boolean invokeCreateAuto, boolean invokeResumeAuto ) { + + } + + @Override + public void displayVRMap( boolean invokeCreateAuto, boolean invokeResumeAuto ) { + + } + + private void addMapView() { + } } diff --git a/modules/mogo-modules-mvision/src/main/java/com/mogo/module/machine/vision/MachineVisionMapViewHandler.java b/modules/mogo-modules-mvision/src/main/java/com/mogo/module/machine/vision/MachineVisionMapViewHandler.java index 79b92faa31..53587802d0 100644 --- a/modules/mogo-modules-mvision/src/main/java/com/mogo/module/machine/vision/MachineVisionMapViewHandler.java +++ b/modules/mogo-modules-mvision/src/main/java/com/mogo/module/machine/vision/MachineVisionMapViewHandler.java @@ -50,5 +50,6 @@ class MachineVisionMapViewHandler { if ( mMachineVisionMapView == null ) { return; } + } } diff --git a/modules/mogo-modules-mvision/src/main/res/layout/module_mvision_layout_view.xml b/modules/mogo-modules-mvision/src/main/res/layout/module_mvision_layout_view.xml index b37adc5822..47f1317dde 100644 --- a/modules/mogo-modules-mvision/src/main/res/layout/module_mvision_layout_view.xml +++ b/modules/mogo-modules-mvision/src/main/res/layout/module_mvision_layout_view.xml @@ -1,10 +1,11 @@ + android:id="@+id/module_mvision_map_root" + android:layout_width="@dimen/module_mvision_view_width" + android:layout_height="@dimen/module_mvision_view_height"> + android:layout_width="@dimen/module_mvision_view_width" + android:layout_height="@dimen/module_mvision_view_height" /> \ No newline at end of file