新增snapshot多线程执行

This commit is contained in:
tongchenfei
2021-03-04 15:25:38 +08:00
parent f470b575d0
commit def4004885
5 changed files with 280 additions and 41 deletions

View File

@@ -57,6 +57,7 @@ import com.zhidaoauto.map.sdk.open.marker.MarkerOptions;
import com.zhidaoauto.map.sdk.open.marker.MultiPointOverlayOptions;
import com.zhidaoauto.map.sdk.open.marker.OnInfoWindowClickListener;
import com.zhidaoauto.map.sdk.open.marker.OnMarkClickListener;
import com.zhidaoauto.map.sdk.open.poyline.PolylineOptions;
import com.zhidaoauto.map.sdk.open.query.LonLatPoint;
import com.zhidaoauto.map.sdk.open.tools.MapTools;
import com.zhidaoauto.map.sdk.open.view.MapAutoView;
@@ -1020,7 +1021,7 @@ public class AMapViewWrapper implements IMogoMapView,
e.printStackTrace();
}
}
private float lastRoadId;
@Override
public double[] matchRoad( double lon, double lat, double angle, boolean isGpsLocation, boolean isRTK ) {
double wgs[] = CoordinateUtils.transformGcj02toWgs84( lat, lon );
@@ -1032,19 +1033,29 @@ public class AMapViewWrapper implements IMogoMapView,
// return CoordinateUtils.transformWgsToGcj( matchedPoint[1], matchedPoint[0] );
matchedPoint = CoordinateUtils.transformWgsToGcj( matchedPoint[1], matchedPoint[0] );
MarkerOptions options
= new MarkerOptions();
options.markerIcon( R.drawable.red )
.position( new LonLatPoint( matchedPoint[0], matchedPoint[1] ) )
.setGps( false );
mMapView.getMapAutoViewHelper().addMarker( options );
MarkerOptions options2 = new MarkerOptions();
options2.markerIcon( R.drawable.blue )
.position( new LonLatPoint( lon, lat ) )
.setGps( true );
mMapView.getMapAutoViewHelper().addMarker( options2 );
// MarkerOptions options
// = new MarkerOptions();
// options.markerIcon( R.drawable.red )
// .position( new LonLatPoint( matchedPoint[0], matchedPoint[1] ) )
// .setGps( false );
// mMapView.getMapAutoViewHelper().addMarker( options );
//
// MarkerOptions options2 = new MarkerOptions();
// options2.markerIcon( R.drawable.blue )
// .position( new LonLatPoint( lon, lat ) )
// .setGps( true );
// mMapView.getMapAutoViewHelper().addMarker( options2 );
// if(lastRoadId != singlePointRoadInfo.getRoadId()) {
// lastRoadId = singlePointRoadInfo.getRoadId();
// PolylineOptions lineOptions = new PolylineOptions();
// lineOptions.setGps(true)
// .lonLatPoints(singlePointRoadInfo.getCoords())
// .color(Color.RED)
// .lineWidth(10);
// mMapView.getMapAutoViewHelper().drawLine(lineOptions);
// }
return matchedPoint;
}
return null;

View File

@@ -78,7 +78,7 @@ class BaseDrawer {
* @param msg
* @param data
*/
protected void sendMessage( int msg, Object data ) {
public void sendMessage( int msg, Object data ) {
if ( mWorkThreadHandler == null ) {
initWorkThreadHandler();
}
@@ -94,7 +94,7 @@ class BaseDrawer {
* @param type
* @return
*/
protected boolean isCarType( int type ) {
public boolean isCarType( int type ) {
AdasRecognizedType recognizedType = AdasRecognizedType.valueFrom( type );
if ( recognizedType == AdasRecognizedType.classIdCar
|| recognizedType == AdasRecognizedType.classIdTrafficBus
@@ -115,7 +115,7 @@ class BaseDrawer {
* @param speed
* @param isVrMode
*/
protected void showSelfSpeed( Context context, IMogoMarker mogoMarker, double speed, boolean isVrMode ) {
public void showSelfSpeed( Context context, IMogoMarker mogoMarker, double speed, boolean isVrMode ) {
if ( mogoMarker == null || mogoMarker.isDestroyed() ) {
return;
}
@@ -189,7 +189,7 @@ class BaseDrawer {
* @param isRtk
* @return
*/
protected double[] matchRoad( double lon, double lat, double angle, boolean isRtk ) {
public double[] matchRoad( double lon, double lat, double angle, boolean isRtk ) {
return MogoApisHandler.getInstance()
.getApis()
.getMapServiceApi()
@@ -206,7 +206,7 @@ class BaseDrawer {
* @param curSatelliteTime
* @return
*/
protected long computeAnimDuration( long lastSystemTime, long curSystemTime, long lastSatelliteTime, long curSatelliteTime ) {
public long computeAnimDuration( long lastSystemTime, long curSystemTime, long lastSatelliteTime, long curSatelliteTime ) {
long systemTimeInterval = curSystemTime - lastSystemTime - 25;
long satelliteTimeInterval = curSatelliteTime - lastSatelliteTime - 25;
long interval = systemTimeInterval < satelliteTimeInterval || satelliteTimeInterval == 0 ? systemTimeInterval : satelliteTimeInterval;

View File

@@ -2,6 +2,7 @@ package com.mogo.module.common.drawer;
import android.content.Context;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
@@ -16,6 +17,7 @@ import com.mogo.module.common.R;
import com.mogo.module.common.api.CallChatApi;
import com.mogo.module.common.constants.DataTypes;
import com.mogo.module.common.kt.ScopeManager;
import com.mogo.module.common.utils.SimpleHandlerThreadPool;
import com.mogo.realtime.entity.CloudRoadData;
import com.mogo.realtime.entity.MogoSnapshotSetData;
import com.mogo.service.statusmanager.IMogoStatusChangedListener;
@@ -129,6 +131,8 @@ public class SnapshotSetDataDrawer extends BaseDrawer implements IMogoMarkerClic
return false;
}
Map<String,String> cloudKeyCache = new ArrayMap<>();
/**
* mogo 他车、mogo 他车识别的社会车辆、路边单元识别的车辆
*
@@ -142,29 +146,24 @@ public class SnapshotSetDataDrawer extends BaseDrawer implements IMogoMarkerClic
List< CloudRoadData > allDatumsList = new ArrayList<>();
prepareData( data.getAllList(), allDatumsList );
Map< String, IMogoMarker > newAdasRecognizedMarkersCaches = new ConcurrentHashMap<>();
Map< String, String > newAdasRecognizedMarkersCaches = new ArrayMap<>(allDatumsList.size());
for ( CloudRoadData cloudRoadData : allDatumsList ) {
// double[] matchedPoint = matchRoad( cloudRoadData.getLon(),
// cloudRoadData.getLat(),
// cloudRoadData.getHeading(),
// true
// );
// if ( matchedPoint != null ) {
// cloudRoadData.setLon( matchedPoint[0] );
// cloudRoadData.setLat( matchedPoint[1] );
// }
ScopeManager.INSTANCE.mainScope( () -> {
rendCarOneFrame( cloudRoadData, newAdasRecognizedMarkersCaches );
} );
cloudKeyCache.remove(cloudRoadData.getUniqueKey());
// newAdasRecognizedMarkersCaches.put(cloudRoadData.getUniqueKey(), cloudRoadData.getUniqueKey());
SimpleHandlerThreadPool.getInstance().post(cloudRoadData);
// ScopeManager.INSTANCE.mainScope( () -> {
// rendCarOneFrame( cloudRoadData, newAdasRecognizedMarkersCaches );
// } );
}
ScopeManager.INSTANCE.mainScope( () -> {
sendMessage( MSG_REMOVE_DIRTY_MARKERS, mCloudSnapshotMarkersCaches );
mCloudSnapshotMarkersCaches = newAdasRecognizedMarkersCaches;
} );
SimpleHandlerThreadPool.getInstance().removeDirtyMarker(cloudKeyCache.values());
cloudKeyCache = newAdasRecognizedMarkersCaches;
// ScopeManager.INSTANCE.mainScope( () -> {
// sendMessage( MSG_REMOVE_DIRTY_MARKERS, mCloudSnapshotMarkersCaches );
// mCloudSnapshotMarkersCaches = newAdasRecognizedMarkersCaches;
// } );
}
private void rendCarOneFrame( CloudRoadData cloudRoadData, Map< String, IMogoMarker > newAdasRecognizedMarkersCaches ) {
public void rendCarOneFrame( CloudRoadData cloudRoadData, Map< String, IMogoMarker > newAdasRecognizedMarkersCaches ) {
if ( cloudRoadData == null ) {
return;
@@ -196,8 +195,9 @@ public class SnapshotSetDataDrawer extends BaseDrawer implements IMogoMarkerClic
bindClickListener( marker );
}
}
newAdasRecognizedMarkersCaches.put( uniqueKey, marker );
if(newAdasRecognizedMarkersCaches != null) {
newAdasRecognizedMarkersCaches.put(uniqueKey, marker);
}
//
// if ( mChangeCarModeStatus ) {
// mIsVrMode = MogoApisHandler.getInstance().getApis().getStatusManagerApi().isVrMode();
@@ -263,7 +263,7 @@ public class SnapshotSetDataDrawer extends BaseDrawer implements IMogoMarkerClic
/**
* 绑定点击事件
*/
private void bindClickListener( IMogoMarker marker ) {
public void bindClickListener( IMogoMarker marker ) {
if ( marker == null || marker.isDestroyed() ) {
return;
}
@@ -276,7 +276,7 @@ public class SnapshotSetDataDrawer extends BaseDrawer implements IMogoMarkerClic
* @param data
* @return
*/
private IMogoMarker drawSnapshotDataMarker( CloudRoadData data ) {
public IMogoMarker drawSnapshotDataMarker( CloudRoadData data ) {
if ( data == null ) {
return null;
}

View File

@@ -0,0 +1,186 @@
package com.mogo.module.common.utils;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.ArrayMap;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.map.MogoLatLng;
import com.mogo.map.marker.IMogoMarker;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.module.common.drawer.AdasRecognizedResultDrawer;
import com.mogo.module.common.drawer.SnapshotSetDataDrawer;
import com.mogo.realtime.entity.CloudRoadData;
import com.mogo.utils.logger.Logger;
import java.util.Collection;
import java.util.Map;
import static com.mogo.module.common.drawer.BaseDrawer.MSG_REMOVE_DIRTY_MARKERS;
/**
* 简单HandlerThread线程池实现
*
* @author tongchenfei
*/
public class SimpleHandlerThreadPool {
private static final String TAG = "SimpleHandlerThreadPool";
private HandlerThread renderThread = new HandlerThread("one-frame-render-thread");
private Handler renderHandler;
private SimpleHandlerThreadPool() {
renderThread.start();
renderHandler = new Handler(renderThread.getLooper());
}
private static final SimpleHandlerThreadPool INSTANCE = new SimpleHandlerThreadPool();
public static SimpleHandlerThreadPool getInstance() {
return INSTANCE;
}
/**
* 默认线程数量
*/
private static final int DEFAULT_THREAD_COUNT = 3;
private int threadCount = DEFAULT_THREAD_COUNT;
public void setThreadCount(int threadCount) {
this.threadCount = threadCount;
}
Map<String, WorkHandler> dataHandlerMap = new ArrayMap<>();
Map<Integer, WorkHandler> handlerPool = new ArrayMap<>();
private int lastUseThreadId = -1;
public void post(CloudRoadData cloudRoadData) {
String uuid = cloudRoadData.getUniqueKey();
Message msg;
if (dataHandlerMap.containsKey(uuid)) {
msg = dataHandlerMap.get(uuid).obtainMessage();
} else {
if (handlerPool.size() < threadCount) {
// 新开线程
lastUseThreadId = handlerPool.size();
HandlerThread thread = new HandlerThread("one-frame-work-thread-" + handlerPool.size());
thread.start();
WorkHandler handler = new WorkHandler(thread.getLooper());
handlerPool.put(handlerPool.size(), handler);
dataHandlerMap.put(uuid, handler);
msg = handler.obtainMessage();
} else {
// 复用线程
if (lastUseThreadId == threadCount - 1) {
lastUseThreadId = 0;
} else {
lastUseThreadId++;
}
WorkHandler handler = handlerPool.get(lastUseThreadId);
dataHandlerMap.put(uuid, handler);
msg = handler.obtainMessage();
}
}
msg.obj = cloudRoadData;
msg.sendToTarget();
}
public void removeDirtyMarker(Collection<String> keys) {
for (WorkHandler handler : handlerPool.values()) {
handler.removeDirtyMarker(keys);
}
}
class WorkHandler extends Handler {
public WorkHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
CloudRoadData cloudRoadData = (CloudRoadData) msg.obj;
rendCarOneFrame(cloudRoadData);
}
private final Map<String, IMogoMarker> markerCache = new ArrayMap<>();
private final Map<String, CloudRoadData> roadDataCache = new ArrayMap<>();
private final Map<String, Long> lastExecutionTimeCache = new ArrayMap<>();
private void rendCarOneFrame(CloudRoadData cloudRoadData) {
if (cloudRoadData == null) {
return;
}
// 暂时只显示车辆
if (TextUtils.isEmpty(cloudRoadData.getSn())) {
if (!SnapshotSetDataDrawer.getInstance().isCarType(cloudRoadData.getType())) {
return;
}
}
String uniqueKey = cloudRoadData.getUniqueKey();
if (TextUtils.isEmpty(uniqueKey)
// 本地过滤重复下发的adas识别车辆
|| AdasRecognizedResultDrawer.getInstance().hasCached(uniqueKey)) {
return;
}
IMogoMarker marker = markerCache.get(uniqueKey);
CloudRoadData lastPosition = roadDataCache.put(uniqueKey, cloudRoadData);
if (marker == null || marker.isDestroyed()) {
marker = SnapshotSetDataDrawer.getInstance().drawSnapshotDataMarker(cloudRoadData);
if (marker == null) {
return;
}
markerCache.put(uniqueKey, marker);
if (!TextUtils.isEmpty(cloudRoadData.getSn())) {
SnapshotSetDataDrawer.getInstance().bindClickListener(marker);
}
}
if(cloudRoadData.getFromType() == CloudRoadData.FROM_MY_LOCATION) {
double[] matchedPoint = SnapshotSetDataDrawer.getInstance().matchRoad(cloudRoadData.getLon(),
cloudRoadData.getLat(),
cloudRoadData.getHeading(),
true
);
if (matchedPoint != null) {
cloudRoadData.setLon(matchedPoint[0]);
cloudRoadData.setLat(matchedPoint[1]);
}
}
final IMogoMarker finalMarker = marker;
Logger.d(TAG, "work in " + Thread.currentThread().getName());
renderHandler.post(()->{
// 由于地图现在不支持addDynamicAnchorPosition并发所以工作线程仅做相关计算真正绘制发送到另外一条绘制线程中做
if (lastPosition != null && !lastPosition.equals(cloudRoadData)) {
long interval = SnapshotSetDataDrawer.getInstance().computeAnimDuration(lastPosition.getSystemTime(), cloudRoadData.getSystemTime(), lastPosition.getSatelliteTime(), cloudRoadData.getSatelliteTime());
interval = SystemClock.uptimeMillis() - lastExecutionTimeCache.get(uniqueKey);
finalMarker.addDynamicAnchorPosition(new MogoLatLng(cloudRoadData.getLat(), cloudRoadData.getLon()), interval);
Logger.d(TAG, "anim duration: %s in thread: %s", interval, Thread.currentThread().getName());
} else {
finalMarker.setRotateAngle((float) cloudRoadData.getHeading());
finalMarker.setPosition(cloudRoadData.getLat(), cloudRoadData.getLon());
Logger.d(TAG, "设置点位置 in thread: %s", Thread.currentThread().getName());
}
lastExecutionTimeCache.put(uniqueKey, SystemClock.uptimeMillis());
SnapshotSetDataDrawer.getInstance().showSelfSpeed(AbsMogoApplication.getApp(), finalMarker, cloudRoadData.getSpeed(), MogoApisHandler.getInstance().getApis().getStatusManagerApi().isVrMode());
});
}
public void removeDirtyMarker(Collection<String> keys) {
Map<String, IMogoMarker> result = new ArrayMap<>(keys.size());
for (String key : keys) {
if(markerCache.containsKey(key)) {
result.put(key, markerCache.remove(key));
}
}
SnapshotSetDataDrawer.getInstance().sendMessage( MSG_REMOVE_DIRTY_MARKERS, result );
}
}
}

View File

@@ -556,8 +556,9 @@ public class MockIntentHandler implements IntentHandler {
SnapshotSetDataDrawer.getInstance().renderSnapshotData( GsonUtil.objectFromJson( json, MogoSnapshotSetData.class ) );
break;
case 47:
mLocationMockHandler.sendEmptyMessageDelayed( 1, 200L );
mLocationMockHandler.sendEmptyMessageDelayed( 1, 400L );
mLocationMockHandler.sendEmptyMessageDelayed( 2, 0 );
mLocationMockHandler.sendEmptyMessageDelayed( 21, 200 );
// mLocationMockHandler.sendEmptyMessageDelayed( 3, 300L );
break;
}
@@ -612,6 +613,17 @@ public class MockIntentHandler implements IntentHandler {
}
br2 = null;
}
} else if( msg.what == 21 ) {
try {
handleMockSnapshotIntent2();
} catch (Exception e) {
try {
br4.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
};
@@ -693,6 +705,36 @@ public class MockIntentHandler implements IntentHandler {
return true;
}
private BufferedReader br4;
private boolean handleMockSnapshotIntent2() throws Exception {
if ( br4 == null ) {
br4 = new BufferedReader( new InputStreamReader( AbsMogoApplication.getApp().getAssets().open( "snapshot.txt" ) ) );
}
String line = br4.readLine();
if ( line == null ) {
throw new Exception( "end of file 2." );
}
MogoSnapshotSetData data = new MogoSnapshotSetData();
List< CloudRoadData > allList = new ArrayList<>();
CloudRoadData cloudRoadData = GsonUtil.objectFromJson( line, CloudRoadData.class );
if ( cloudRoadData == null ) {
return false;
}
double[] coor = CoordinateUtils.transformWgsToGcj( cloudRoadData.getLat(), cloudRoadData.getLon() );
cloudRoadData.setUuid("1_21");
cloudRoadData.setLon( coor[0] );
cloudRoadData.setLat( coor[1] );
allList.add( cloudRoadData );
data.setAllList( allList );
final long start = System.currentTimeMillis();
SnapshotSetDataDrawer.getInstance().renderSnapshotData( data );
Log.i( "mock-timer-snapshot", "cost " + ( System.currentTimeMillis() - start ) + "ms" );
mLocationMockHandler.sendEmptyMessageDelayed( 21, 100L );
return true;
}
private BufferedReader br3;
private boolean handleMockAdasIntent() throws Exception {