This commit is contained in:
wangcongtao
2020-12-08 14:08:53 +08:00
840 changed files with 31903 additions and 11168 deletions

View File

@@ -9,6 +9,7 @@ import com.mogo.map.marker.IMogoMarkerManager;
import com.mogo.map.navi.IMogoNavi;
import com.mogo.map.uicontroller.IMogoMapUIController;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.module.common.drawer.MarkerDrawer;
import com.mogo.module.common.entity.MarkerResponse;
import com.mogo.module.common.entity.MarkerShowEntity;
import com.mogo.module.service.marker.MapMarkerManager;
@@ -192,7 +193,7 @@ public class MarkerServiceHandler {
*/
@Deprecated
public static IMogoMarker drawMapMarker( MarkerShowEntity markerShowEntity ) {
return getMapMarkerManager().drawMapMarker( markerShowEntity, ServiceConst.MARKER_Z_INDEX_HIGH );
return getMapMarkerManager().drawMapMarker( markerShowEntity, MarkerDrawer.MARKER_Z_INDEX_HIGH );
}
/**

View File

@@ -14,6 +14,7 @@ import com.mogo.map.listener.IMogoMapListener;
import com.mogo.map.location.IMogoLocationListener;
import com.mogo.map.marker.IMogoMarkerClickListener;
import com.mogo.map.navi.IMogoNaviListener;
import com.mogo.module.service.location.MogoRTKLocation;
import com.mogo.service.module.IMogoModuleLifecycle;
import com.mogo.service.module.IMogoModuleProvider;
import com.mogo.service.module.ModuleType;
@@ -96,6 +97,8 @@ public class MogoServiceProvider implements IMogoModuleProvider {
public void init( Context context ) {
Logger.d( TAG, "init" );
MarkerServiceHandler.init( context );
MogoRTKLocation.getInstance().init();
MogoServices.getInstance().preInit( context );
UiThreadHandler.postDelayed( () -> {
MogoServices.getInstance().init( AbsMogoApplication.getApp() );
}, 5_000L );

View File

@@ -117,10 +117,6 @@ public class ServiceConst {
*/
public static final int MSG_LOCK_CAR = 0x202;
public static final int MARKER_Z_INDEX_HIGH = 100;
public static final int MARKER_Z_INDEX_LOW = 2;
/**
* 切换卡片内容-上一个
*/
@@ -223,4 +219,24 @@ public class ServiceConst {
*/
public static final long INTERVAL_SCHEDULE_CALCULATE_NOT_HOME_COMPANY_DISTANCE_FOR_PUSH = 60 * 1_000L;
/**
* 发送自车位置和adas识别结果给服务端
*/
public static final int MSG_SEND_CAR_LOCATION_AND_ADAS_RECOGNIZED_RESULT_2_SERVER = 0x401;
/**
* 间隔 1s 发送一次
*/
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";
}

View File

@@ -13,7 +13,7 @@ public
abstract class StatusChangedAdapter implements IMogoStatusChangedListener {
@Override
public void onStatusChanged( StatusDescriptor descriptor, boolean isTrue ) {
public final void onStatusChanged( StatusDescriptor descriptor, boolean isTrue ) {
switch ( descriptor ) {
case USER_INTERACTED:
onUserInteracted( isTrue );
@@ -33,6 +33,9 @@ abstract class StatusChangedAdapter implements IMogoStatusChangedListener {
case ACC_STATUS:
onAccStatusChanged( isTrue );
break;
case VR_MODE:
onVrModeChanged( isTrue );
break;
case TOP_VIEW:
onTopViewStatusChanged( isTrue );
break;
@@ -51,5 +54,7 @@ abstract class StatusChangedAdapter implements IMogoStatusChangedListener {
public abstract void onAccStatusChanged( boolean accOn );
public abstract void onVrModeChanged( boolean isVrMode );
public abstract void onTopViewStatusChanged( boolean visible );
}

View File

@@ -1,23 +0,0 @@
package com.mogo.module.service.autopilot;
import java.util.List;
public
/**
* @author congtaowang
* @since 2020/10/16
*
* 自动驾驶参数
*/
class AutoPilotParameters {
public AutoPilotLonLat startLatLon;
public List< AutoPilotLonLat > wayLatLons;
public AutoPilotLonLat endLatLon;
public float speedLimit;
public static class AutoPilotLonLat {
public double lat;
public double lon;
}
}

View File

@@ -2,6 +2,7 @@ package com.mogo.module.service.autopilot;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.service.adas.RemoteControlAutoPilotParameters;
import com.mogo.service.connection.IMogoOnMessageListener;
import com.mogo.service.connection.IMogoSocketManager;
import com.mogo.utils.logger.Logger;
@@ -22,21 +23,21 @@ class AutoPilotRemoteController {
private IMogoSocketManager mMogoSocketManager;
private IMogoOnMessageListener< AutoPilotParameters > mParametersListener = new IMogoOnMessageListener< AutoPilotParameters >() {
private IMogoOnMessageListener< RemoteControlAutoPilotParameters > mParametersListener = new IMogoOnMessageListener< RemoteControlAutoPilotParameters >() {
@Override
public Class< AutoPilotParameters > target() {
return AutoPilotParameters.class;
public Class< RemoteControlAutoPilotParameters > target() {
return RemoteControlAutoPilotParameters.class;
}
@Override
public void onMsgReceived( AutoPilotParameters obj ) {
public void onMsgReceived( RemoteControlAutoPilotParameters obj ) {
if ( obj == null ) {
Logger.e( TAG, "远端控制参数为null", new NullPointerException() );
return;
}
String json = GsonUtil.jsonFromObject( obj );
Logger.d( TAG, json );
MogoApisHandler.getInstance().getApis().getAdasControllerApi().notifyAdas( json );
MogoApisHandler.getInstance().getApis().getAdasControllerApi().aiCloudToAdasData( obj );
}
};

View File

@@ -4,6 +4,9 @@ import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.module.service.MarkerServiceHandler;
import com.mogo.module.service.ServiceConst;
import com.mogo.utils.LaunchUtils;
import com.mogo.utils.TipToast;
@@ -24,6 +27,7 @@ public class AppOperationIntentHandler implements IntentHandler {
public AppOperationIntentHandler() {
// sAppPackages.put( "车聊聊", "com.zhidao.imdemo" );
// sAppPackages.put( "VR模式", "" );
}
@Override
@@ -33,6 +37,12 @@ public class AppOperationIntentHandler implements IntentHandler {
String app = object.optString( "object" );
String operation = object.optString( "operation" );
if ( TextUtils.equals( "打开", operation ) ) {
if ( TextUtils.equals( "VR模式", app ) ) {
if ( MarkerServiceHandler.getApis().getStatusManagerApi().isMainPageOnResume() ) {
MarkerServiceHandler.getApis().getMapFrameControllerApi().changeToVRMode();
}
return;
}
if ( TextUtils.isEmpty( sAppPackages.get( app ) ) ) {
return;
}
@@ -41,6 +51,13 @@ public class AppOperationIntentHandler implements IntentHandler {
} catch ( Exception e ) {
TipToast.shortTip( "应用程序未安装" );
}
} else if ( TextUtils.equals( "关闭", operation ) ) {
if ( TextUtils.equals( "VR模式", app ) ) {
if ( MarkerServiceHandler.getApis().getStatusManagerApi().isMainPageOnResume() ) {
MarkerServiceHandler.getApis().getMapFrameControllerApi().changeTo2dMode();
}
return;
}
}
} catch ( Exception e ) {
e.printStackTrace();

View File

@@ -23,6 +23,7 @@ import com.mogo.map.search.geo.IMogoGeoSearchListener;
import com.mogo.map.search.geo.MogoGeocodeResult;
import com.mogo.map.search.geo.MogoRegeocodeResult;
import com.mogo.map.search.geo.query.MogoRegeocodeQuery;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.module.common.dialog.WMDialog;
import com.mogo.module.service.MarkerServiceHandler;
import com.mogo.module.service.R;
@@ -31,6 +32,7 @@ import com.mogo.utils.TipToast;
import com.mogo.utils.WorkThreadHandler;
import com.mogo.utils.logger.Logger;
import com.mogo.utils.network.utils.GsonUtil;
import com.mogo.utils.storage.SharedPrefsMgr;
import java.util.ArrayList;
import java.util.List;
@@ -334,6 +336,10 @@ public class MockIntentHandler implements IntentHandler {
case 17:
DebugConfig.setRequestOnlineCarData( intent.getBooleanExtra( "status", true ) );
break;
case 18:
TipToast.shortTip( "设置完成,下次启动生效" );
SharedPrefsMgr.getInstance( context ).putBoolean( "useCustomMap", intent.getBooleanExtra( "useCustomMap", false ) );
break;
case 30:
MarkerServiceHandler.getMapService().getMapUIController().forceRender();
break;
@@ -350,6 +356,14 @@ public class MockIntentHandler implements IntentHandler {
case 33:
AIAssist.getInstance( context ).speakTTSVoice( "庞帆说这个是一个 hard coding." );
break;
case 34:
int type = intent.getIntExtra( "type", 0 );
if ( type != 0 ) {
MogoApisHandler.getInstance().getApis().getMapFrameControllerApi().changeToVRMode();
} else {
MogoApisHandler.getInstance().getApis().getMapFrameControllerApi().changeTo2dMode();
}
break;
}
}

View File

@@ -0,0 +1,170 @@
package com.mogo.module.service.location;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.module.common.entity.CloudLocationInfo;
import com.mogo.utils.WorkThreadHandler;
import com.mogo.utils.logger.Logger;
import java.util.ArrayList;
import java.util.List;
public class MogoRTKLocation {
private static final String TAG = "MogoRTKLocation";
private static final int MSG_DATA_CHANGED = 0x100;
private static final long MSG_DATA_INTERNAL = 500L;
private Handler mHandler;
private LocationManager locationManager;
private RTKLocationListener rtkLocationListener;
private List<CloudLocationInfo> cacheList = new ArrayList<>();
public static MogoRTKLocation getInstance() {
return RTKHolder.rtkLoc;
}
private static class RTKHolder {
private static final MogoRTKLocation rtkLoc = new MogoRTKLocation();
}
private MogoRTKLocation() {
mHandler = new Handler(WorkThreadHandler.newInstance( TAG ).getLooper() ) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == MSG_DATA_CHANGED) {
mHandler.sendEmptyMessageDelayed(MSG_DATA_CHANGED, uploadDelay);
sendLocationData();
}
}
};
mHandler.sendEmptyMessage(MSG_DATA_CHANGED);
}
public interface RTKLocationListener {
void onLocationChanged(List<CloudLocationInfo> cloudLocationInfos);
}
private void sendLocationData() {
if (rtkLocationListener != null) {
List<CloudLocationInfo> list = new ArrayList<>(cacheList);
rtkLocationListener.onLocationChanged(list);
}
if (cacheList != null && cacheList.size() > 0) {
cacheList.clear();
}
}
public void registerRTKLocationListener(RTKLocationListener locationListener) {
rtkLocationListener = locationListener;
}
public void init() {
locationManager = (LocationManager) AbsMogoApplication.getApp().getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
String provider = locationManager.getBestProvider(getCriteria(), true);
Logger.d(TAG, "init provider : " + provider);
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
try {
locationManager.requestLocationUpdates(provider, 0, 0, locationListener);
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
Logger.i(TAG, "location : " + location.toString());
}
} catch (Exception e) {
e.printStackTrace();
Logger.d(TAG, "RTK LocationManager requestLocationUpdates has Exception : " + e.getMessage());
}
} else {
Logger.d(TAG, "RTK LocationManager Provider GPS_PROVIDER unable");
}
// 注册修改上报间隔的广播, 临时使用后面可直接干掉发送广播的地方在EntranceFragment
IntentFilter filter = new IntentFilter("com.mogo.launcher.action.FIX_UPLOAT_DELAY");
AbsMogoApplication.getApp().registerReceiver(fixUploadDelayReceiver, filter);
}
private Criteria getCriteria() {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE); //高精
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(true);
criteria.setSpeedRequired(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
return criteria;
}
private LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
if (location != null) {
CloudLocationInfo cloudLocationInfo = new CloudLocationInfo();
cloudLocationInfo.setAlt(location.getAltitude());
cloudLocationInfo.setHeading(location.getBearing());
cloudLocationInfo.setLat(location.getLatitude());
cloudLocationInfo.setLon(location.getLongitude());
cloudLocationInfo.setSpeed(location.getSpeed());
cloudLocationInfo.setSatelliteTime(location.getTime());
cloudLocationInfo.setSystemTime(System.currentTimeMillis());
cacheList.add(cloudLocationInfo);
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Logger.d(TAG, "onStatusChanged status: " + status);
}
@Override
public void onProviderEnabled(String provider) {
Logger.d(TAG, "onProviderEnabled");
}
@Override
public void onProviderDisabled(String provider) {
Logger.d(TAG, "onProviderEnabled");
}
};
public void stop() {
Logger.d(TAG, "stop RTK Location");
if (locationManager != null && locationListener != null) {
locationManager.removeUpdates(locationListener);
} else {
Logger.d(TAG, "stop failed , reason : loc" + locationManager + " , or loc listener: " + locationListener + " is null");
}
}
private long uploadDelay = MSG_DATA_INTERNAL;
private FixUploadDelayReceiver fixUploadDelayReceiver = new FixUploadDelayReceiver();
private class FixUploadDelayReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
uploadDelay = intent.getIntExtra("fixTime", 0);
}
}
/**
* 默认保持{@link #uploadDelay}间隔进行位置上报,如遇服务端控制,进行上报间隔修改
* @param delay 上报间隔
*/
public void resetUploadDelay(long delay) {
if (mHandler != null && mHandler.hasMessages(MSG_DATA_CHANGED)) {
mHandler.removeMessages(MSG_DATA_CHANGED);
mHandler.sendEmptyMessageDelayed(MSG_DATA_CHANGED, delay);
}
}
}

View File

@@ -0,0 +1,27 @@
package com.mogo.module.service.marker;
public
/**
* @author congtaowang
* @since 2020/10/27
* <p>
* 描述
*/
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;
}

View File

@@ -1,23 +0,0 @@
package com.mogo.module.service.marker;
import android.graphics.Bitmap;
import android.view.View;
import com.mogo.map.marker.IMogoMarker;
/**
* @author congtaowang
* @since 2020-02-15
* <p>
* 描述
*/
public interface IMarkerView {
View getView();
default Bitmap getBitmap(int type){
return null;
}
void setMarker( IMogoMarker marker );
}

View File

@@ -1,45 +0,0 @@
package com.mogo.module.service.marker;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.TextUtils;
import android.view.View;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.map.marker.IMogoMarker;
import com.mogo.map.marker.MogoMarkerOptions;
import com.mogo.module.common.ModuleNames;
import com.mogo.module.common.entity.MarkerShowEntity;
import com.mogo.module.service.R;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020-01-1015:55
* desc : 地图Marker的适配器
* version: 1.0
*/
public class MapMarkerAdapter {
/**
* 获取 MarkerShowEntity 填充好的 MarkerView
*
* @param context 上下文
* @param markerShowEntity 要填充的数据
* @return MarkerView
*/
public static IMarkerView getMarkerView(Context context, MarkerShowEntity markerShowEntity, MogoMarkerOptions options) {
if ( TextUtils.equals( markerShowEntity.getMarkerType(), ModuleNames.CARD_TYPE_USER_DATA ) ) {
return OnlineCarMarkerView.getInstance();
} else {
if (markerShowEntity.isChecked()) {
return new MapMarkerInfoView(context, markerShowEntity, options);
} else {
return new MapMarkerView(context, markerShowEntity, options);
}
}
}
}

View File

@@ -1,178 +0,0 @@
package com.mogo.module.service.marker;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Looper;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import com.mogo.map.marker.IMogoMarker;
import com.mogo.map.marker.MogoMarkerOptions;
import com.mogo.module.common.entity.MarkerShowEntity;
import com.mogo.module.service.MarkerServiceHandler;
import com.mogo.module.service.R;
import com.mogo.service.imageloader.IMogoImageLoaderListener;
import com.mogo.service.imageloader.MogoImageView;
import com.mogo.utils.UiThreadHandler;
import com.mogo.utils.WindowUtils;
import com.mogo.utils.logger.Logger;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020-01-1310:55
* desc : 地图上抽离的Marker的共性
* version: 1.0
*/
public abstract class MapMarkerBaseView extends LinearLayout implements IMarkerView {
private String TAG = "MapMarkerBaseView";
protected Context mContext;
protected MogoMarkerOptions mOptions;
protected MogoImageView ivUserHead;
protected MogoImageView ivIcon;
protected ImageView ivCar;
protected IMogoMarker mMarker;
public MapMarkerBaseView(Context context) {
super(context);
mContext = context;
initView(context);
}
public MapMarkerBaseView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mContext = context;
initView(context);
}
public MapMarkerBaseView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
initView(context);
}
@Override
public void setMarker( IMogoMarker marker ) {
this.mMarker = marker;
}
protected abstract void initView( Context context);
public abstract void updateView(MarkerShowEntity markerShowEntity);
protected void loadImageWithMarker(final MarkerShowEntity markerShowEntity) {
if ( Looper.myLooper() != Looper.getMainLooper() ) {
UiThreadHandler.post( ()-> {
runOnUiThread( markerShowEntity );
});
} else {
runOnUiThread( markerShowEntity );
}
}
protected void loadPoiTypeIcon(String url,int res) {
ivIcon.setImageResource(res);
if ( Looper.myLooper() != Looper.getMainLooper() ) {
UiThreadHandler.post( ()-> loadPoiTypeIconInUiThread(url, res));
} else {
loadPoiTypeIconInUiThread(url, res);
}
}
private void loadPoiTypeIconInUiThread(String url,int res) {
if (!url.isEmpty()) {
ivIcon.setPlaceHolder(res);
ivIcon.setFailureHolder(res);
MarkerServiceHandler.getImageloader().displayImage(url,
ivIcon, WindowUtils.dip2px(mContext, 50), WindowUtils.dip2px(mContext, 50),
new IMogoImageLoaderListener() {
@Override
public void onStart() {
}
@Override
public void onCompleted(Bitmap bitmap) {
// 使用view渲染地图marker刷新纹理的时候需要重新用view生成纹理然后在设置
if (mMarker != null) {
mMarker.setIcon(fromView(MapMarkerBaseView.this));
}
}
@Override
public void onFailure(Exception e) {
}
});
}
}
private void runOnUiThread(final MarkerShowEntity markerShowEntity){
if (!TextUtils.isEmpty(markerShowEntity.getIconUrl())) {
MarkerServiceHandler.getImageloader().displayImage(markerShowEntity.getIconUrl(),
ivUserHead,
WindowUtils.dip2px(mContext, 50), WindowUtils.dip2px(mContext, 50),
new IMogoImageLoaderListener() {
@Override
public void onStart() {
}
@Override
public void onCompleted(Bitmap bitmap) {
Logger.d(TAG, "loadImageWithMarker loaded.");
// 使用view渲染地图marker刷新纹理的时候需要重新用view生成纹理然后在设置
if ( mMarker != null ) {
mMarker.setIcon( fromView( MapMarkerBaseView.this ) );
}
}
@Override
public void onFailure(Exception e) {
Logger.e(TAG, "loadImageWithMarker onFailure.");
}
});
} else {
ivUserHead.setBackgroundResource(R.drawable.icon_default_user_head);
}
}
private Bitmap fromView( View view ) {
view.setDrawingCacheEnabled( true );
processChildView( view );
view.destroyDrawingCache();
view.measure( View.MeasureSpec.makeMeasureSpec( 0, View.MeasureSpec.UNSPECIFIED ), View.MeasureSpec.makeMeasureSpec( 0, View.MeasureSpec.UNSPECIFIED ) );
view.layout( 0, 0, view.getMeasuredWidth(), view.getMeasuredHeight() );
Bitmap bitmap = null;
return ( bitmap = view.getDrawingCache() ) != null ? bitmap.copy( Bitmap.Config.ARGB_8888, false ) : null;
}
private void processChildView( View view ) {
if ( !( view instanceof ViewGroup ) ) {
if ( view instanceof TextView ) {
( ( TextView ) view ).setHorizontallyScrolling( false );
}
} else {
for ( int var1 = 0; var1 < ( ( ViewGroup ) view ).getChildCount(); ++var1 ) {
processChildView( ( ( ViewGroup ) view ).getChildAt( var1 ) );
}
}
}
@Override
public View getView() {
return this;
}
}

View File

@@ -1,146 +0,0 @@
package com.mogo.module.service.marker;
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.mogo.map.marker.MogoMarkerOptions;
import com.mogo.module.common.entity.MarkerExploreWay;
import com.mogo.module.common.entity.MarkerShareMusic;
import com.mogo.module.common.entity.MarkerShowEntity;
import com.mogo.module.common.marker.PoiWrapper;
import com.mogo.module.common.utils.CloudPoiManager;
import com.mogo.module.service.R;
import com.mogo.module.service.ServiceConst;
import com.mogo.utils.logger.Logger;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020-01-0619:55
* desc : 地图Marker图标带文本信息
* version: 1.0
*/
public class MapMarkerInfoView extends MapMarkerBaseView {
private String TAG = "MapMarkerInfoView";
private TextView tvMarkerContent;
private ConstraintLayout clMarkerContent;
private ImageView ivReverseTriangle;
public MapMarkerInfoView( Context context ) {
super( context );
}
public MapMarkerInfoView( Context context, @Nullable AttributeSet attrs ) {
super( context, attrs );
}
public MapMarkerInfoView( Context context, @Nullable AttributeSet attrs, int defStyleAttr ) {
super( context, attrs, defStyleAttr );
}
public MapMarkerInfoView( Context context, MarkerShowEntity markerShowEntity, MogoMarkerOptions options ) {
super( context );
mOptions = options;
updateView( markerShowEntity );
}
@Override
protected void initView( Context context ) {
LayoutInflater.from( context ).inflate( R.layout.modudle_services_marker_layout_info, this );
ivUserHead = findViewById( R.id.ivUserHead );
// ivIcon = findViewById( R.id.ivIcon );
ivIcon = findViewById(R.id.ivIcon);
clMarkerContent = findViewById( R.id.clMarkerContent );
ivReverseTriangle = findViewById( R.id.ivReverseTriangle );
ivCar = findViewById( R.id.ivCar );
tvMarkerContent = findViewById( R.id.tvMarkerContent );
}
@Override
public void updateView( MarkerShowEntity markerShowEntity ) {
try {
Object bindObj = markerShowEntity.getBindObj();
ivCar.setImageResource( R.drawable.icon_map_marker_location_yellow );
clMarkerContent.setBackgroundResource( R.drawable.bg_map_marker_yellow_info );
ivReverseTriangle.setImageResource( R.drawable.bg_shape_reverse_yellow );
switch ( markerShowEntity.getMarkerType() ) {
case ServiceConst.CARD_TYPE_CARS_CHATTING:
case ServiceConst.CARD_TYPE_USER_DATA:
ivUserHead.setVisibility( View.VISIBLE );
ivIcon.setVisibility( View.INVISIBLE );
loadImageWithMarker( markerShowEntity );
ivCar.setImageResource( R.drawable.icon_map_marker_car_gray );
//ivCar.setRotation(new Random().nextInt(360));
ivCar.setRotation( ( float ) markerShowEntity.getMarkerLocation().getAngle() );
break;
case ServiceConst.CARD_TYPE_ROAD_CONDITION:
case ServiceConst.CARD_TYPE_NOVELTY:
ivUserHead.setVisibility( View.INVISIBLE );
ivIcon.setVisibility( View.VISIBLE );
if ( bindObj instanceof MarkerExploreWay && ( ( MarkerExploreWay ) bindObj ).getPoiType() != null ) {
// 根据poiType获取对应的图片
String poiType = ((MarkerExploreWay) bindObj).getPoiType();
PoiWrapper poiWrapper =
CloudPoiManager.getInstance().getWrapperByPoiType(poiType);
if (poiWrapper != null) {
// 加载图片
loadPoiTypeIcon(poiWrapper.getIconInfoUrl(),poiWrapper.getIconInfoRes());
}else{
Logger.e(TAG, "未能根据poiType获取对应poi信息无法渲染info marker====" + poiType);
}
}
break;
case ServiceConst.CARD_TYPE_SHARE_MUSIC:
ivUserHead.setVisibility( View.INVISIBLE );
ivIcon.setVisibility( View.VISIBLE );
if ( bindObj instanceof MarkerShareMusic ) {
// 2 为书籍听书3 为新闻,1 为qq音乐,int
switch ( ( ( MarkerShareMusic ) bindObj ).getShareType() ) {
case 1:
ivIcon.setImageResource( R.drawable.icon_map_marker_misic );
break;
case 2:
ivIcon.setImageResource( R.drawable.icon_map_marker_book );
break;
case 3:
ivIcon.setImageResource( R.drawable.icon_map_marker_news );
break;
default:
ivIcon.setImageResource( R.drawable.icon_map_marker_misic );
break;
}
}
break;
default:
break;
}
if ( !TextUtils.isEmpty( markerShowEntity.getTextContent() ) ) {
String content;
if ( markerShowEntity.getTextContent().length() > 8 ) {
content = markerShowEntity.getTextContent().substring( 0, 7 ) + "...";
} else {
content = markerShowEntity.getTextContent();
}
tvMarkerContent.setText( content );
}
} catch ( Exception e ) {
e.printStackTrace();
}
}
}

View File

@@ -3,7 +3,6 @@ package com.mogo.module.service.marker;
import android.content.Context;
import android.graphics.Rect;
import android.text.TextUtils;
import android.view.animation.LinearInterpolator;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.commons.debug.DebugConfig;
@@ -11,36 +10,44 @@ import com.mogo.map.MogoLatLng;
import com.mogo.map.marker.IMogoMarker;
import com.mogo.map.marker.IMogoMarkerClickListener;
import com.mogo.map.marker.IMogoMarkerManager;
import com.mogo.map.marker.MogoMarkerOptions;
import com.mogo.map.marker.anim.OnMarkerAnimationListener;
import com.mogo.map.uicontroller.EnumMapUI;
import com.mogo.module.common.ModuleNames;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.module.common.api.CallChatApi;
import com.mogo.module.common.entity.MarkerCarPois;
import com.mogo.module.common.drawer.AdasRecognizedResultDrawer;
import com.mogo.module.common.drawer.MarkerDrawer;
import com.mogo.module.common.drawer.OnlineCarDrawer;
import com.mogo.module.common.drawer.RoadConditionDrawer;
import com.mogo.module.common.drawer.SnapshotSetDataDrawer;
import com.mogo.module.common.drawer.marker.IMarkerView;
import com.mogo.module.common.drawer.marker.MapMarkerAdapter;
import com.mogo.module.common.drawer.marker.OnlineCarMarkerView;
import com.mogo.module.common.entity.MarkerCardResult;
import com.mogo.module.common.entity.MarkerExploreWay;
import com.mogo.module.common.entity.MarkerLocation;
import com.mogo.module.common.entity.MarkerNoveltyInfo;
import com.mogo.module.common.entity.MarkerOnlineCar;
import com.mogo.module.common.entity.MarkerResponse;
import com.mogo.module.common.entity.MarkerShareMusic;
import com.mogo.module.common.entity.MarkerShowEntity;
import com.mogo.module.common.utils.CloudPoiManager;
import com.mogo.module.common.entity.MogoSnapshotSetData;
import com.mogo.module.service.MarkerServiceHandler;
import com.mogo.module.service.MogoServices;
import com.mogo.module.service.R;
import com.mogo.module.service.ServiceConst;
import com.mogo.module.service.Utils;
import com.mogo.module.service.network.RefreshCallback;
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.connection.IMogoOnMessageListener;
import com.mogo.service.connection.IMogoOnWebSocketMessageListener;
import com.mogo.service.connection.WebSocketMsgType;
import com.mogo.service.module.IMogoBizActionDoneListener;
import com.mogo.utils.ResourcesHelper;
import com.mogo.utils.ThreadPoolService;
import com.mogo.utils.UiThreadHandler;
import com.mogo.utils.WorkThreadHandler;
import com.zhidao.carchattingprovider.ICallChatResponse;
import com.mogo.utils.logger.Logger;
import org.json.JSONArray;
import org.json.JSONException;
@@ -105,7 +112,7 @@ public class MapMarkerManager implements IMogoMarkerClickListener,
mContext = context.getApplicationContext();
mRefreshModel = new RefreshModel( mContext );
CloudPoiManager.getInstance().updateFromConfig(context);
CloudPoiManager.getInstance().updateFromConfig( context );
MarkerServiceHandler.getActionManager().registerBizActionDoneListener( this );
MarkerServiceHandler.getApis().getRegisterCenterApi().registerADASControlStatusChangedListener( TAG, this );
@@ -128,6 +135,59 @@ public class MapMarkerManager implements IMogoMarkerClickListener,
}
} );
// 每隔一秒下发的数据
MarkerServiceHandler.getApis().getWebSocketManagerApi( mContext )
.registerOnWebSocketMessageListener( new IMogoOnWebSocketMessageListener< MogoSnapshotSetData >() {
@Override
public WebSocketMsgType getUpLinkType() {
return null;
}
@Override
public WebSocketMsgType getDownLinkType() {
return WebSocketMsgType.MSG_TYPE_DOWNLINK_CAR_DATA;
}
@Override
public Class< MogoSnapshotSetData > target() {
return MogoSnapshotSetData.class;
}
@Override
public void onMsgReceived( MogoSnapshotSetData data ) {
if ( data == null ) {
return;
}
if ( !MogoApisHandler.getInstance().getApis().getMapFrameControllerApi().isVrMode() ) {
// return;
}
if ( MogoServices.getInstance().getLastCarLocation() != null ) {
data.curSpeed = MogoServices.getInstance().getLastCarLocation().getSpeed();
}
SnapshotSetDataDrawer.getInstance().renderSnapshotData( data, false );
// VrModeController.getInstance().renderMogoSnapshotSetData( data );
}
@Override
public void onError( String errorMsg ) {
}
} );
// adas 每隔一秒传递的数据
MarkerServiceHandler.getApis().getAdasControllerApi().addAdasRecognizedDataCallback( resultList -> {
if ( resultList == null || resultList.isEmpty() ) {
return;
}
double speed = 0.0;
if ( MogoServices.getInstance().getLastCarLocation() != null ) {
speed = MogoServices.getInstance().getLastCarLocation().getSpeed();
}
// 绘制近景识别到的车辆,每秒绘制一次
AdasRecognizedResultDrawer.getInstance().renderAdasRecognizedResult( resultList, false, speed );
} );
}
}
@@ -146,7 +206,7 @@ public class MapMarkerManager implements IMogoMarkerClickListener,
Map< String, Object > properties = new HashMap<>();
if ( marker.getObject() instanceof MarkerShowEntity ) {
final String sn = getCarSnFromMarker( marker );
final String sn = MarkerDrawer.getInstance().getCarSnFromMarker( marker );
if ( TextUtils.isEmpty( sn ) ) {
return false;
}
@@ -198,7 +258,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() );
@@ -215,8 +275,10 @@ public class MapMarkerManager implements IMogoMarkerClickListener,
mogoMarker.setToTop();
}
}
MarkerServiceHandler.getMogoStatusManager().setUserInteractionStatus( TAG, true, false );
MarkerServiceHandler.getMapUIController().moveToCenter( mogoMarker.getPosition(), DebugConfig.isRoadEventAnimated() );
if ( !MarkerServiceHandler.getApis().getMapFrameControllerApi().isVrMode() ) {
MarkerServiceHandler.getMogoStatusManager().setUserInteractionStatus( TAG, true, false );
MarkerServiceHandler.getMapUIController().moveToCenter( mogoMarker.getPosition(), DebugConfig.isRoadEventAnimated() );
}
}
private void updateCarUserInfoWindow( IMogoMarker marker ) {
@@ -323,237 +385,9 @@ public class MapMarkerManager implements IMogoMarkerClickListener,
*/
private void drawAllMarker( MarkerCardResult markerCardResult ) {
List< MarkerExploreWay > exploreWayList = markerCardResult.getExploreWay();
drawRoadConditionMarker( exploreWayList, ServiceConst.MAX_AMOUNT_ALL );
RoadConditionDrawer.getInstance().drawRoadConditionMarker( exploreWayList, ServiceConst.MAX_AMOUNT_ALL, this );
}
/**
* 绘制在线车辆marker
*
* @param onlineCarList
*/
private void drawOnlineCarMarkers( List< MarkerOnlineCar > onlineCarList,
int maxAmount,
boolean clearOld,
boolean showBounds,
Rect bound,
MogoLatLng centerPoint ) {
// 将数据同步给在线车辆,避免每次 perform 的时候去拉取,造成消耗
if ( onlineCarList == null || onlineCarList.isEmpty() ) {
MarkerServiceHandler.getMarkerManager().removeMarkers( ModuleNames.CARD_TYPE_USER_DATA );
return;
}
if ( clearOld ) {
MarkerServiceHandler.getMarkerManager().removeMarkers( ModuleNames.CARD_TYPE_USER_DATA );
}
int size = getAppropriateSize( maxAmount, onlineCarList );
Map< String, IMogoMarker > existCarMap = purgeMarkerData( onlineCarList, ModuleNames.CARD_TYPE_USER_DATA );
List< MogoLatLng > carPoints = new ArrayList<>();
for ( int i = 0; i < size; i++ ) {
MarkerOnlineCar markerOnlineCar = onlineCarList.get( i );
MarkerLocation markerLocation = markerOnlineCar.getLocation();
MarkerShowEntity markerShowEntity = new MarkerShowEntity();
markerShowEntity.setBindObj( markerOnlineCar );
markerShowEntity.setMarkerLocation( markerLocation );
markerShowEntity.setMarkerType( markerOnlineCar.getType() );
if ( markerOnlineCar.getCarInfo() != null ) {
markerShowEntity.setTextContent( markerOnlineCar.getUserInfo().getUserName() );
markerShowEntity.setIconUrl( markerOnlineCar.getUserInfo().getUserHead() );
}
if ( i <= 5 ) {
carPoints.add( new MogoLatLng( markerLocation.getLat(), markerLocation.getLon() ) );
}
String sn = getPrimaryKeyFromEntity( markerOnlineCar );
IMogoMarker mogoMarker = existCarMap.get( sn );
if ( mogoMarker == null || mogoMarker.isDestroyed() ) {
mogoMarker = drawMapMarker( markerShowEntity, ServiceConst.MARKER_Z_INDEX_LOW );
}
if ( mogoMarker != null ) {
mogoMarker.setVisible( true );
}
startSmooth( mogoMarker, markerOnlineCar, markerLocation );
}
if ( showBounds && bound != null ) {
// 将前6个点显示在固定范围内
MarkerServiceHandler.getMapUIController().showBounds( TAG, centerPoint, carPoints, bound, false );
}
}
/**
* 探路数据
*
* @param exploreWayList
*/
private void drawRoadConditionMarker( List< MarkerExploreWay > exploreWayList, int maxAmount ) {
// 将数据同步给探路,避免探路每次 perform 的时候去拉取,造成消耗
if ( exploreWayList == null || exploreWayList.isEmpty() ) {
MarkerServiceHandler.getMarkerManager().removeMarkers( ModuleNames.CARD_TYPE_ROAD_CONDITION );
return;
}
int size = getAppropriateSize( maxAmount, exploreWayList );
Map< String, IMogoMarker > existCarMap = purgeMarkerData( exploreWayList, ModuleNames.CARD_TYPE_ROAD_CONDITION );
for ( int i = 0; i < size; i++ ) {
MarkerExploreWay markerExploreWay = exploreWayList.get( i );
if ( !markerExploreWay.getCanLive() ) {
MarkerLocation markerLocation = markerExploreWay.getLocation();
MarkerShowEntity markerShowEntity = new MarkerShowEntity();
markerShowEntity.setBindObj( markerExploreWay );
markerShowEntity.setMarkerLocation( markerLocation );
markerShowEntity.setMarkerType( markerExploreWay.getType() );
markerShowEntity.setTextContent( markerExploreWay.getAddr() );
String sn = getPrimaryKeyFromEntity( markerExploreWay );
IMogoMarker mogoMarker = existCarMap.get( sn );
if ( mogoMarker == null || mogoMarker.isDestroyed() ) {
try {
if ( DebugConfig.isRoadEventAnimated() ) {
post2AddAndStartAnimation( markerShowEntity, i * 100L );
} else {
mogoMarker = drawMapMarker( markerShowEntity, ServiceConst.MARKER_Z_INDEX_HIGH );
}
} catch ( Exception e ) {
}
}
}
}
}
private void post2AddAndStartAnimation( MarkerShowEntity entity, long delay ) {
if ( entity == null ) {
return;
}
WorkThreadHandler.getInstance().postDelayed( () -> {
if ( entity == null ) {
return;
}
IMogoMarker marker = drawMapMarker( entity, ServiceConst.MARKER_Z_INDEX_HIGH );
if ( marker == null ) {
return;
}
marker.startScaleAnimationWithAlpha( 0, 1.2f, 0, 1.2f, 0f, 1f, 300, new LinearInterpolator(), new OnMarkerAnimationListener() {
@Override
public void onAnimStart() {
}
@Override
public void onAnimEnd() {
if ( marker == null || marker.isDestroyed() ) {
return;
}
marker.startScaleAnimation( 1.2f, 1, 1.2f, 1, 100, new LinearInterpolator(), null );
}
} );
}, delay );
}
/**
* S = (A ∩ B) B
* A ∩ B)作为旧列表需要保留的部分
*
* @param newList
* @return
*/
private Map< String, IMogoMarker > purgeMarkerData( List newList, String markerType ) {
Map< String, IMogoMarker > existMap = new HashMap<>();
List< IMogoMarker > allCarsList = MarkerServiceHandler.getMarkerManager().getMarkers( markerType );
if ( allCarsList == null || allCarsList.isEmpty() ) {
return existMap;
}
if ( newList == null || newList.isEmpty() ) {
return existMap;
}
Map< String, IMogoMarker > allMap = new HashMap<>();
for ( IMogoMarker marker : allCarsList ) {
String sn = getPrimaryKeyFromMarker( marker );
allMap.put( sn, marker );
}
for ( Object entity : newList ) {
String sn = getPrimaryKeyFromEntity( entity );
if ( allMap.containsKey( sn ) ) {
existMap.put( sn, allMap.get( sn ) );
}
}
for ( String sn : allMap.keySet() ) {
if ( !existMap.containsKey( sn ) ) {
IMogoMarker dirtyMarker = allMap.get( sn );
allCarsList.remove( dirtyMarker );
dirtyMarker.destroy();
}
}
allMap.clear();
return existMap;
}
private String getPrimaryKeyFromEntity( Object entity ) {
if ( entity instanceof MarkerExploreWay ) {
String id = ( ( MarkerExploreWay ) entity ).getInfoId();
if ( !TextUtils.isEmpty( id ) ) {
return id;
}
}
return getCarSnFromEntity( entity );
}
private String getPrimaryKeyFromMarker( IMogoMarker marker ) {
if ( marker == null || marker.getObject() == null || marker.isDestroyed() ) {
return null;
}
if ( !( marker.getObject() instanceof MarkerShowEntity ) ) {
return null;
}
return getPrimaryKeyFromEntity( ( ( MarkerShowEntity ) marker.getObject() ).getBindObj() );
}
private String getCarSnFromEntity( Object entity ) {
try {
if ( entity instanceof MarkerOnlineCar ) {
return ( ( MarkerOnlineCar ) entity ).getUserInfo().getSn();
} else if ( entity instanceof MarkerShareMusic ) {
return ( ( MarkerShareMusic ) entity ).getUserInfo().getSn();
} else if ( entity instanceof MarkerNoveltyInfo ) {
return ( ( MarkerNoveltyInfo ) entity ).getSn();
} else if ( entity instanceof MarkerExploreWay ) {
return ( ( MarkerExploreWay ) entity ).getUserInfo().getSn();
}
} catch ( Exception e ) {
}
return "";
}
private String getCarSnFromMarker( IMogoMarker marker ) {
if ( marker == null || marker.getObject() == null || marker.isDestroyed() ) {
return null;
}
if ( !( marker.getObject() instanceof MarkerShowEntity ) ) {
return null;
}
return getCarSnFromEntity( ( ( MarkerShowEntity ) marker.getObject() ).getBindObj() );
}
/**
* @param maxAmount 展示的最大数量
* @param list
* @return
*/
private int getAppropriateSize( int maxAmount, List list ) {
if ( list == null ) {
return 0;
}
return Math.min( maxAmount, list.size() );
}
/**
* 统计地图内数据获取
*
@@ -638,37 +472,6 @@ public class MapMarkerManager implements IMogoMarkerClickListener,
}
}
/**
* 大而全数据计数埋点
*/
private synchronized static JSONObject fillPoiTypeTrackBody( JSONArray arr, String poiType, int poiTypeNum ) {
JSONObject object = new JSONObject();
try {
object.put( "poitype", poiType );
object.put( "num", poiTypeNum );
if ( arr != null ) {
arr.put( object );
}
return object;
} catch ( JSONException e ) {
e.printStackTrace();
}
return null;
}
private synchronized static void fillPoiChildTypeTrackBody( JSONArray arr, String childType, int childTypeNum ) {
JSONObject object = new JSONObject();
try {
object.put( "contenttype", childType );
object.put( "num", childTypeNum );
if ( arr != null ) {
arr.put( object );
}
} catch ( JSONException e ) {
e.printStackTrace();
}
}
/**
* 绘制Marker这里绘制的会使用markerShowEntities队列进行维护
*
@@ -677,38 +480,12 @@ public class MapMarkerManager implements IMogoMarkerClickListener,
*/
public synchronized IMogoMarker drawMapMarker( MarkerShowEntity markerShowEntity, int zIndex ) {
try {
return drawMapMarkerImpl( markerShowEntity, zIndex );
return MarkerDrawer.getInstance().drawMapMarkerImpl( markerShowEntity, zIndex, this );
} catch ( Exception e ) {
return null;
}
}
private IMogoMarker drawMapMarkerImpl( MarkerShowEntity markerShowEntity, int zIndex ) {
if ( markerShowEntity == null || markerShowEntity.getMarkerLocation() == null ) {
return null;
}
MogoMarkerOptions options = new MogoMarkerOptions().owner( markerShowEntity.getMarkerType() ).zIndex( zIndex ).object( markerShowEntity ).latitude( markerShowEntity.getMarkerLocation().getLat() ).longitude( markerShowEntity.getMarkerLocation().getLon() );
IMarkerView markerView = MapMarkerAdapter.getMarkerView( mContext, markerShowEntity, options );
if ( markerView instanceof OnlineCarMarkerView ) {
try {
options.icon( markerView.getBitmap( ( ( MarkerOnlineCar ) markerShowEntity.getBindObj() ).getCarInfo().getVehicleType() ) );
} catch ( Exception e ) {
options.icon( markerView.getBitmap( 0 ) );
}
options.anchor( 0.5f, 0.5f );
} else {
options.icon( markerView.getView() );
}
IMogoMarker marker = MarkerServiceHandler.getMarkerManager().addMarker( markerShowEntity.getMarkerType(), options );
marker.setOwner( markerShowEntity.getMarkerType() );
markerView.setMarker( marker );
marker.setOnMarkerClickListener( this );
markerShowEntity.setMarker( marker );
return marker;
}
@Override
public Class< MarkerResponse > target() {
return MarkerResponse.class;
@@ -832,7 +609,7 @@ public class MapMarkerManager implements IMogoMarkerClickListener,
runOnTargetThread( () -> {
trackData( size );
drawOnlineCarMarkers( onlineCarList, Integer.MAX_VALUE, fitBounds, fitBounds, mMarkerDisplayBounds, latLng );
OnlineCarDrawer.getInstance().drawOnlineCarMarkers( onlineCarList, Integer.MAX_VALUE, fitBounds, fitBounds, mMarkerDisplayBounds, latLng, MapMarkerManager.this );
UiThreadHandler.postDelayed( runnable, SMOOTH_DURATION * 1000 );
} );
}
@@ -871,81 +648,13 @@ public class MapMarkerManager implements IMogoMarkerClickListener,
MarkerServiceHandler.getMarkerManager().removeMarkers( ModuleNames.CARD_TYPE_USER_DATA );
}
// 平滑移动
private void startSmooth( IMogoMarker iMogoMarker, MarkerOnlineCar markerOnlineCar,
MarkerLocation markerLocation ) {
if ( iMogoMarker == null ) {
return;
}
List< MarkerCarPois > poiList = markerOnlineCar.getPois();
if ( filterErrorPoint( poiList ) ) {
return;
}
if ( poiList == null || poiList.size() < 2 ) {
return;
}
List< MogoLatLng > points = new ArrayList<>();
double lastLat = 0.0d;
double lastLon = 0.0d;
for ( int j = 0; j < poiList.size(); j++ ) {
MarkerCarPois poi = poiList.get( j );
if ( poi == null || poi.getCoordinates() == null && poi.getCoordinates().size() != 2 ) {
continue;
}
try {
double lat = Double.valueOf( poi.getCoordinates().get( 1 ) + "" );
double lng = Double.valueOf( poi.getCoordinates().get( 0 ) + "" );
float distance = Utils.calculateLineDistance( lastLon, lastLat, lng, lat );
lastLon = lng;
lastLat = lat;
if ( distance < 0.2f ) {// 距离过短,认为静止不动
continue;
}
points.add( new MogoLatLng( lat, lng ) );
} catch ( Exception e ) {
}
}
if ( points.size() >= 1 ) {
iMogoMarker.startSmooth( points, SMOOTH_DURATION );
} else {
}
}
/**
* 有可能出现终点到起点跳跃的情况,需要用"500M"约束起点和终点
*
* @param poiList
*/
private boolean filterErrorPoint( List< MarkerCarPois > poiList ) {
if ( poiList == null || poiList.size() < 2 ) {
return false;
}
MarkerCarPois start = poiList.get( 0 );
MarkerCarPois end = poiList.get( poiList.size() - 1 );
try {
double lat1 = Double.valueOf( start.getCoordinates().get( 1 ) + "" );
double lng1 = Double.valueOf( start.getCoordinates().get( 0 ) + "" );
double lat2 = Double.valueOf( end.getCoordinates().get( 1 ) + "" );
double lng2 = Double.valueOf( end.getCoordinates().get( 0 ) + "" );
if ( Utils.calculateLineDistance( new MogoLatLng( lat1, lng1 ), new MogoLatLng( lat2, lng2 ) ) >= 500 ) {
return true;
}
} catch ( Exception e ) {
}
return false;
}
private boolean ignoreDrawRequest() {
return MarkerServiceHandler.getMogoStatusManager().isSearchUIShow()
|| MarkerServiceHandler.getMogoStatusManager().isV2XShow()
|| !MarkerServiceHandler.getMogoStatusManager().isMainPageLaunched()
|| !MarkerServiceHandler.getMogoStatusManager().isMainPageOnResume();
|| !MarkerServiceHandler.getMogoStatusManager().isMainPageOnResume()
|| MarkerServiceHandler.getApis().getMapFrameControllerApi().isVrMode();
}
private void runOnTargetThread( Runnable runnable ) {

View File

@@ -1,83 +0,0 @@
package com.mogo.module.service.marker;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import androidx.annotation.Nullable;
import com.mogo.map.marker.MogoMarkerOptions;
import com.mogo.module.common.entity.MarkerExploreWay;
import com.mogo.module.common.entity.MarkerShowEntity;
import com.mogo.module.common.marker.PoiWrapper;
import com.mogo.module.common.utils.CloudPoiManager;
import com.mogo.module.service.R;
import com.mogo.module.service.ServiceConst;
import com.mogo.utils.logger.Logger;
/**
* author : donghongyu
* e-mail : 1358506549@qq.com
* date : 2020-01-0619:55
* desc : 地图Marker图标
* version: 1.0
*/
public class MapMarkerView extends MapMarkerBaseView {
private String TAG = "MapMarkerView";
public MapMarkerView( Context context ) {
super( context );
}
public MapMarkerView( Context context, @Nullable AttributeSet attrs ) {
super( context, attrs );
}
public MapMarkerView( Context context, @Nullable AttributeSet attrs, int defStyleAttr ) {
super( context, attrs, defStyleAttr );
}
public MapMarkerView( Context context, MarkerShowEntity markerShowEntity, MogoMarkerOptions options ) {
super( context );
mOptions = options;
updateView( markerShowEntity );
}
@Override
protected void initView( Context context ) {
LayoutInflater.from( context ).inflate( R.layout.modudle_services_marker_layout, this );
ivIcon = findViewById( R.id.ivIcon );
ivCar = findViewById( R.id.ivCar );
}
@Override
public void updateView( MarkerShowEntity markerShowEntity ) {
try {
Object bindObj = markerShowEntity.getBindObj();
switch ( markerShowEntity.getMarkerType() ) {
case ServiceConst.CARD_TYPE_ROAD_CONDITION:
case ServiceConst.CARD_TYPE_NOVELTY:
if ( bindObj instanceof MarkerExploreWay && ( ( MarkerExploreWay ) bindObj ).getPoiType() != null ) {
// 根据poiType获取对应的图片
String poiType = ((MarkerExploreWay) bindObj).getPoiType();
PoiWrapper poiWrapper =
CloudPoiManager.getInstance().getWrapperByPoiType(poiType);
if (poiWrapper != null) {
// 加载图片
loadPoiTypeIcon(poiWrapper.getIconUrl(),poiWrapper.getIconRes());
}else{
Logger.e(TAG, "未能根据poiType获取对应poi信息无法渲染marker====" + poiType);
}
}
break;
default:
break;
}
} catch ( Exception e ) {
e.printStackTrace();
}
}
}

View File

@@ -6,6 +6,7 @@ import androidx.annotation.Nullable;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.map.marker.IMogoMarker;
import com.mogo.module.common.drawer.MarkerDrawer;
import com.mogo.module.common.entity.MarkerShowEntity;
import com.mogo.module.service.MarkerServiceHandler;
import com.mogo.module.service.ServiceConst;
@@ -28,7 +29,7 @@ public class MogoMarkerServiceImpl implements IMogoMarkerService {
@Override
public IMogoMarker drawMarker( Object object ) {
if ( object instanceof MarkerShowEntity ) {
return MarkerServiceHandler.getMapMarkerManager().drawMapMarker( ( ( MarkerShowEntity ) object ), ServiceConst.MARKER_Z_INDEX_HIGH );
return MarkerServiceHandler.getMapMarkerManager().drawMapMarker( ( ( MarkerShowEntity ) object ), MarkerDrawer.MARKER_Z_INDEX_HIGH );
}
Logger.w( TAG, "object must instance of [com.mogo.module.common.entity.MarkerShowEntity]" );
return null;

View File

@@ -1,82 +0,0 @@
package com.mogo.module.service.marker;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.View;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.map.marker.IMogoMarker;
import com.mogo.module.common.ModuleNames;
import com.mogo.module.service.R;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;
/**
* @author congtaowang
* @since 2020-04-30
* <p>
* 描述
*/
public class OnlineCarMarkerView implements IMarkerView {
private static Map< Integer, SoftReference< Bitmap > > sRef = new HashMap<>();
private static Map< Integer, SoftReference< Bitmap > > sTypedRef = new HashMap<>();
private OnlineCarMarkerView() {
// private constructor
}
private static final class InstanceHolder {
private static final OnlineCarMarkerView INSTANCE = new OnlineCarMarkerView();
}
public static OnlineCarMarkerView getInstance() {
return InstanceHolder.INSTANCE;
}
private Object readResolve() {
// 阻止反序列化,必须实现 Serializable 接口
return InstanceHolder.INSTANCE;
}
@Override
public View getView() {
return null;
}
@Override
public Bitmap getBitmap( int vehicleType ) {
if ( sRef.get( vehicleType ) == null || sRef.get( vehicleType ).get() == null
|| sRef.get( vehicleType ).get().isRecycled() ) {
switch ( vehicleType ) {
case 2:
sRef.put( vehicleType, new SoftReference<>( BitmapFactory.decodeResource( AbsMogoApplication.getApp().getResources(), R.drawable.icon_map_marker_car_type2 ) ) );
break;
default:
sRef.put( vehicleType, new SoftReference<>( BitmapFactory.decodeResource( AbsMogoApplication.getApp().getResources(), R.drawable.icon_map_marker_car_gray ) ) );
}
}
return sRef.get( vehicleType ).get();
}
public Bitmap getSelectedBitmap( int vehicleType ) {
if ( sTypedRef.get( vehicleType ) == null || sTypedRef.get( vehicleType ).get() == null
|| sTypedRef.get( vehicleType ).get().isRecycled() ) {
switch ( vehicleType ) {
case 2:
sTypedRef.put( vehicleType, new SoftReference<>( BitmapFactory.decodeResource( AbsMogoApplication.getApp().getResources(), R.drawable.icon_map_marker_car_type2 ) ) );
break;
default:
sTypedRef.put( vehicleType, new SoftReference<>( BitmapFactory.decodeResource( AbsMogoApplication.getApp().getResources(), R.drawable.icon_map_marker_car_gray_selected ) ) );
}
}
return sTypedRef.get( vehicleType ).get();
}
@Override
public void setMarker( IMogoMarker marker ) {
}
}

View File

@@ -1,221 +0,0 @@
package com.mogo.module.service.marker;
import android.content.Context;
import android.os.Looper;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.commons.network.SubscribeImpl;
import com.mogo.map.marker.IMogoInfoWindowAdapter;
import com.mogo.map.marker.IMogoMarker;
import com.mogo.module.common.entity.MarkerLocation;
import com.mogo.module.common.entity.MarkerOnlineCar;
import com.mogo.module.common.entity.MarkerShowEntity;
import com.mogo.module.common.entity.MarkerUserInfo;
import com.mogo.module.service.MarkerServiceHandler;
import com.mogo.module.service.R;
import com.mogo.module.service.network.RefreshApiService;
import com.mogo.module.service.network.RefreshModel;
import com.mogo.module.service.network.bean.DemoUserInfoEntity;
import com.mogo.service.imageloader.MogoImageView;
import com.mogo.service.network.IMogoNetwork;
import com.mogo.utils.UiThreadHandler;
import com.mogo.utils.WindowUtils;
import com.mogo.utils.logger.Logger;
import com.mogo.utils.network.RequestOptions;
import com.zhidao.carchattingprovider.CallChattingProviderConstant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
/**
* @author congtaowang
* @since 2020-04-27
* <p>
* 在线车辆点击后弹出的info window 样式
*/
public class UserDataMarkerInfoWindowAdapter implements IMogoInfoWindowAdapter {
private static final String TAG = "UserDataMarkerInfoWindowAdapter";
private static volatile UserDataMarkerInfoWindowAdapter sInstance;
private final Context mContext;
private static RefreshApiService sRefreshApiService;
private View mInfoWindowView = null;
private View mContentContainer;
private MogoImageView mUserHeader;
private TextView mContent;
private TextView mTag;
private ImageView mCall;
private UserDataMarkerInfoWindowAdapter( Context context ) {
this.mContext = context;
IMogoNetwork network = MarkerServiceHandler.getApis().getNetworkApi();
sRefreshApiService = network.create( RefreshApiService.class, RefreshModel.getNetHost() );
}
public static UserDataMarkerInfoWindowAdapter getInstance( Context context ) {
if ( sInstance == null ) {
synchronized ( UserDataMarkerInfoWindowAdapter.class ) {
if ( sInstance == null ) {
sInstance = new UserDataMarkerInfoWindowAdapter( context );
}
}
}
return sInstance;
}
public synchronized void release() {
sInstance = null;
}
@Override
public View getInfoWindow( IMogoMarker marker ) {
return inflateView( marker );
}
private View inflateView( IMogoMarker marker ) {
if ( marker == null ) {
return null;
}
if ( mInfoWindowView == null ) {
mInfoWindowView = LayoutInflater.from( mContext ).inflate( R.layout.modudle_services_marker_info_window_layout, null );
mContentContainer = mInfoWindowView.findViewById( R.id.module_service_id_marker_content );
mUserHeader = mInfoWindowView.findViewById( R.id.module_service_id_user_header );
mContent = mInfoWindowView.findViewById( R.id.module_service_id_content );
mTag = mInfoWindowView.findViewById( R.id.module_service_id_tag );
mCall = mInfoWindowView.findViewById( R.id.module_service_id_call );
}
if ( DebugConfig.getCarMachineType() == DebugConfig.CAR_MACHINE_TYPE_BYD ) {
mContentContainer.setPadding(
mContentContainer.getPaddingLeft(),
mContentContainer.getPaddingTop(),
mContentContainer.getResources().getDimensionPixelSize( R.dimen.module_service_id_marker_content_paddingRight_widthoutCall ),
mContentContainer.getPaddingBottom()
);
mCall.setVisibility( View.GONE );
}
try {
MarkerShowEntity markerShowEntity = ( MarkerShowEntity ) marker.getObject();
mContent.setText( markerShowEntity.getTextContent() );
loadImageHeader( markerShowEntity );
if ( markerShowEntity.getBindObj() instanceof MarkerOnlineCar ) {
try {
mTag.setText( ( ( MarkerOnlineCar ) markerShowEntity.getBindObj() ).getUserInfo().getSafeLabel() );
} catch ( Exception e ) {
e.printStackTrace();
}
}
mCall.setOnClickListener( view -> {
if ( markerShowEntity.getBindObj() instanceof MarkerOnlineCar ) {
if ( DebugConfig.getNetMode() != DebugConfig.NET_MODE_DEMO ) {
callToFactUser( markerShowEntity );
return;
}
sRefreshApiService.getMockUsers().subscribeOn( Schedulers.io() )
.observeOn( AndroidSchedulers.mainThread() )
.subscribe( new SubscribeImpl< DemoUserInfoEntity >( RequestOptions.create( mContext ) ) {
@Override
public void onSuccess( DemoUserInfoEntity o ) {
super.onSuccess( o );
callToDemoUser( markerShowEntity, o );
}
@Override
public void onError( String message, int code ) {
super.onError( message, code );
callToFactUser( markerShowEntity );
}
} );
}
} );
} catch ( Exception e ) {
Logger.e( TAG, e, "error." );
}
return mInfoWindowView;
}
private void callToDemoUser( MarkerShowEntity factUser, DemoUserInfoEntity demoUser ) {
if ( demoUser == null
|| demoUser.getResult() == null
|| demoUser.getResult().getUserList() == null
|| demoUser.getResult().getUserList().isEmpty() ) {
callToFactUser( factUser );
return;
}
List< DemoUserInfoEntity.ResultBean.UserListBean > users = demoUser.getResult().getUserList();
for ( DemoUserInfoEntity.ResultBean.UserListBean user : users ) {
if ( user == null ) {
continue;
}
if ( TextUtils.equals( "1", user.getSceneType() ) ) {
try {
( ( MarkerOnlineCar ) factUser.getBindObj() ).getUserInfo().setSn( user.getUserInfo().getSn() );
callToFactUser( factUser );
return;
} catch ( Exception e ) {
}
}
}
callToFactUser( factUser );
}
private void callToFactUser( MarkerShowEntity factUser ) {
if ( factUser == null ) {
return;
}
Map< String, String > params = new HashMap<>();
MarkerUserInfo userInfo = ( ( MarkerOnlineCar ) factUser.getBindObj() ).getUserInfo();
if ( userInfo != null ) {
params.put( CallChattingProviderConstant.CCPROVIDER_SN, userInfo.getSn() );
params.put( CallChattingProviderConstant.CCPROVIDER_USER_IMG, userInfo.getUserHead() );
params.put( CallChattingProviderConstant.CCPROVIDER_USER_AGE, userInfo.getAgeNumber() + "" );
params.put( CallChattingProviderConstant.CCPROVIDER_NICK_NAME, userInfo.getUserName() );
params.put( CallChattingProviderConstant.CCPROVIDER_USER_SEX, userInfo.getGender() + "" );
}
MarkerLocation location = ( ( MarkerOnlineCar ) factUser.getBindObj() ).getLocation();
if ( location != null ) {
params.put( CallChattingProviderConstant.CCPROVIDER_ADDRESS, location.getAddress() );
params.put( CallChattingProviderConstant.CCPROVIDER_LAT, location.getLat() + "" );
params.put( CallChattingProviderConstant.CCPROVIDER_LON, location.getLon() + "" );
}
Logger.d( TAG, "call parameters: %s", params );
if ( MarkerServiceHandler.getCarChatting() != null ) {
MarkerServiceHandler.getCarChatting().call( params );
}
}
protected void loadImageHeader( final MarkerShowEntity markerShowEntity ) {
if ( Looper.myLooper() != Looper.getMainLooper() ) {
UiThreadHandler.post( () -> runOnUiThread( markerShowEntity ));
} else {
runOnUiThread( markerShowEntity );
}
}
private void runOnUiThread( final MarkerShowEntity markerShowEntity ) {
if ( !TextUtils.isEmpty( markerShowEntity.getIconUrl() ) ) {
MarkerServiceHandler.getImageloader().displayImage( markerShowEntity.getIconUrl(),
mUserHeader,
WindowUtils.dip2px( mContext, 50 ), WindowUtils.dip2px( mContext, 50 ), null );
} else {
mUserHeader.setBackgroundResource( R.drawable.icon_default_user_head );
}
}
}

View File

@@ -4,6 +4,7 @@ import android.content.Context;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.module.service.MogoServices;
import com.mogo.module.service.location.MogoRTKLocation;
import com.mogo.service.MogoServicePaths;
import com.mogo.service.strategy.IMogoRefreshStrategyController;
import com.mogo.utils.logger.Logger;
@@ -35,6 +36,11 @@ public class MogoRefreshStrategyController implements IMogoRefreshStrategyContro
MogoServices.getInstance().clearAllData();
}
@Override
public void resetLocationUpDelay(long delay) {
MogoRTKLocation.getInstance().resetUploadDelay(delay);
}
@Override
public void init( Context context ) {

View File

@@ -0,0 +1,40 @@
package com.mogo.module.service.utils;
import android.location.Location;
import com.mogo.map.MogoLatLng;
import com.mogo.module.common.entity.CloudLocationInfo;
/**
* 定位数据类型转换工具
*
* @author tongchenfei
*/
public class LocationParseUtil {
/**
* 从Location 转 CloudLocationInfo
* @param info 待转数据
* @return 转后数据
*/
public static CloudLocationInfo locationToCloudLocation(Location info) {
if (info == null) {
return null;
}
CloudLocationInfo cloud = new CloudLocationInfo();
cloud.setLat(info.getLatitude());
cloud.setLon(info.getLongitude());
cloud.setAlt(info.getAltitude());
cloud.setHeading(info.getBearing());
cloud.setSpeed(info.getSpeed());
cloud.setSatelliteTime(info.getTime());
cloud.setSystemTime(System.currentTimeMillis());
return cloud;
}
public static MogoLatLng cloudLocationToMogoLatLng(CloudLocationInfo info) {
if (info == null) {
return null;
}
return new MogoLatLng(info.getLat(), info.getLon());
}
}

View File

@@ -0,0 +1,139 @@
package com.mogo.module.service.utils;
import java.util.Arrays;
/**
* 莫顿编码
*
* @author linyang
* @since 2020.07.09
*/
public class MortonCode {
/**
* morton 转 经纬度 时的中间常量
*/
private static final long NDS_180_DEGREES = 0x7fffffff;
/**
* morton 转 经纬度 时的中间常量
*/
private static final long NDS_360_DEGREES = 4294967295L;
/**
* morton 转 经纬度 时的中间常量
*/
private static final long NDS_90_DEGREES = 0x3fffffff;
/**
* 经纬度转 morton 时的中间常量
*/
private static final double RULE_MORTON = Math.pow( 2, 32 ) / 360;
/**
* morton 转 经纬度 时的中间常量
*/
private static final double RULE_MORTON_TO_LONLAT = 360.0 / Math.pow( 2, 32 );
/**
* 编码 morton code
*
* @param lon
* @param lat
* @return
*/
public static long encodeMorton( Double lon, Double lat ) {
Long bit = 1L;
long mortonCode = 0L;
long x = ( long ) ( lon * RULE_MORTON );
long y = ( long ) ( lat * RULE_MORTON );
if ( y < 0 ) {
y += 0x7FFFFFFF;
}
y = y << 1;
for ( int i = 0; i < 32; i++ ) {
// x-part
mortonCode = mortonCode | ( x & bit );
x = x << 1;
bit = bit << 1;
// y-part
mortonCode = mortonCode | ( y & bit );
y = y << 1;
bit = bit << 1;
}
return mortonCode;
}
/**
* 将莫顿码解码为坐标
*
* @param mortonCode
* @return
*/
public static double[] decodeMorton( long mortonCode ) {
long[] midPoint = mortonCodeToCoord( mortonCode );
normalizeCoord( midPoint );
double[] point = new double[2];
// 将经纬度长整数转化为 浮点类型
point[0] = midPoint[0] * RULE_MORTON_TO_LONLAT;
point[1] = midPoint[1] * RULE_MORTON_TO_LONLAT;
return point;
}
/**
* 莫顿码分别拆解为 编码后的经纬度长整数
*
* @param mortonCode
* @return
*/
private static long[] mortonCodeToCoord( long mortonCode ) {
long bit = 1L;
long[] longPoint = new long[2];
for ( int i = 0; i < 32; i++ ) {
longPoint[0] |= mortonCode & bit;
mortonCode >>= 1;
longPoint[1] |= mortonCode & bit;
bit <<= 1;
}
return longPoint;
}
/**
* 对编码后的经纬度长整数进行解码
*
* @param midPoint
*/
private static void normalizeCoord( long[] midPoint ) {
// if x > 180 degrees, then subtract 360 degrees
if ( midPoint[0] > NDS_180_DEGREES ) {
midPoint[0] -=
NDS_360_DEGREES + 1; // add 1 because 0 must be counted as well
} else if ( midPoint[0] < -NDS_180_DEGREES ) // if x < 180 , x += 360
{
midPoint[0] +=
NDS_360_DEGREES + 1; // add 1 because 0 must be counted as well
}
// if y > 90 degrees, then subtract 180 degrees
if ( midPoint[1] > NDS_90_DEGREES ) {
midPoint[1] -=
NDS_180_DEGREES + 1; // add 1 because 0 must be counted as well
} else if ( midPoint[1] < -NDS_90_DEGREES ) // if y < 90, y += 180
{
midPoint[1] +=
NDS_180_DEGREES + 1; // add 1 because 0 must be counted as well
}
return;
}
public static void main( String[] args ) {
System.out.println( encodeMorton( 116.39584, 39.98152 ) );
System.out.println( Arrays.toString( decodeMorton( 1415388919630379091L ) ) );
}
}

View File

@@ -0,0 +1,257 @@
package com.mogo.module.service.utils;
import android.location.Location;
import android.os.SystemClock;
import com.mogo.map.MogoLatLng;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.module.common.entity.CloudLocationInfo;
import com.mogo.utils.logger.Logger;
import java.util.ArrayList;
import java.util.List;
/**
* 定位预测纠错策略
*
* @author tongchenfei
*/
public class SimpleLocationCorrectStrategy {
private static final String TAG = "SimpleLocationCorrectStrategy";
private static final int ERR_COUNT_THRESHOLD = 3;
/**
* 目标距离误差是10米就是在原目标距离基础上增加10米
*/
private static final float TARGET_DISTANCE_DEVIATION = 10;
private CloudLocationInfo lastLocation = null;
private long anchorTime;
private int errCount;
private static SimpleLocationCorrectStrategy instance = new SimpleLocationCorrectStrategy();
public static SimpleLocationCorrectStrategy getInstance(){
return instance;
}
private List<CloudLocationInfo> historyList = new ArrayList<>();
private List<CloudLocationInfo> validList = new ArrayList<>();
private List<CloudLocationInfo> correctList = new ArrayList<>();
private List<CloudLocationInfo> errList = new ArrayList<>();
public CloudLocationInfo correct(CloudLocationInfo info) {
Logger.d(TAG, "info: " + info.print());
if(isLocationValid(info)) {
if(recordLocation()) {
historyList.add(info);
}
if (lastLocation == null) {
lastLocation = info;
anchorTime = SystemClock.elapsedRealtime();
Logger.d(TAG, "第一条数据");
if(recordLocation()) {
validList.add(lastLocation);
}
return info;
}
if (lastLocation.equals(info)) {
Logger.d(TAG, "相同坐标点==");
return info;
}
try {
float targetDistance =
(float) (lastLocation.getSpeed() * (SystemClock.elapsedRealtime() - anchorTime) / 1000) + TARGET_DISTANCE_DEVIATION;
float distance = MogoApisHandler.getInstance().getApis().getMapServiceApi().getMapUIController().calculateLineDistance(LocationParseUtil.cloudLocationToMogoLatLng(lastLocation), LocationParseUtil.cloudLocationToMogoLatLng(info));
Logger.d(TAG,
"准备计算{ lastInfo: " + lastLocation.print() + " info: " + info.print() + " targetDistance: " + targetDistance + " distance : " + distance + "}");
if (distance <= targetDistance) {
// 新的定位点在目标距离范围内,认为此数据有效
lastLocation = info;
anchorTime = SystemClock.elapsedRealtime();
errCount = 0;
Logger.d(TAG, "在范围内,为有效点");
if(recordLocation()) {
validList.add(lastLocation);
}
return info;
} else {
// 出现异常点
if (errCount >= ERR_COUNT_THRESHOLD) {
// 出错次数超过阈值,认为本次出错点为正确点
if(recordLocation()) {
errList.add(new CloudLocationInfo(lastLocation));
correctList.add(info);
}
lastLocation = info;
anchorTime = SystemClock.elapsedRealtime();
errCount = 0;
Logger.d(TAG, "出错次数超限,异常点变有效点");
return info;
} else {
// 按照上一个点的方向和速度,计算下一个点的位置,下一个点除坐标点外,其余数据与上一个点相同
CloudLocationInfo nextInfo = new CloudLocationInfo(lastLocation);
MogoLatLng nextLatLon = computerThatLonLat(lastLocation.getLon(),
lastLocation.getLat(), lastLocation.getHeading(), targetDistance);
nextInfo.setLon(nextLatLon.lon);
nextInfo.setLat(nextLatLon.lat);
if(recordLocation()) {
errList.add(info);
correctList.add(nextInfo);
}
lastLocation = nextInfo;
anchorTime = SystemClock.elapsedRealtime();
errCount++;
Logger.d(TAG, "异常点纠偏 info: " + lastLocation);
// return lastLocation;
if(recordLocation()) {
correctList.add(nextInfo);
}
return nextInfo;
}
}
} catch (Exception e) {
Logger.e(TAG, e, "纠偏异常");
e.printStackTrace();
}
}else{
Logger.d(TAG, "定位点异常");
if (lastLocation == null) {
return null;
}else{
try {
float targetDistance =
(float) (lastLocation.getSpeed() * (SystemClock.elapsedRealtime() - anchorTime) / 1000) + TARGET_DISTANCE_DEVIATION;
float distance = MogoApisHandler.getInstance().getApis().getMapServiceApi().getMapUIController().calculateLineDistance(LocationParseUtil.cloudLocationToMogoLatLng(lastLocation), LocationParseUtil.cloudLocationToMogoLatLng(info));
Logger.d(TAG,
"异常定位点\n准备计算{ lastInfo: " + lastLocation.print() + " info: " + info.print() + " targetDistance: " + targetDistance + " distance : " + distance + "}");
// 按照上一个点的方向和速度,计算下一个点的位置,下一个点除坐标点外,其余数据与上一个点相同
CloudLocationInfo nextInfo = new CloudLocationInfo(lastLocation);
MogoLatLng nextLatLon = computerThatLonLat(lastLocation.getLon(),
lastLocation.getLat(), lastLocation.getHeading(), targetDistance);
nextInfo.setLon(nextLatLon.lon);
nextInfo.setLat(nextLatLon.lat);
if(recordLocation()) {
errList.add(info);
correctList.add(nextInfo);
}
lastLocation = nextInfo;
anchorTime = SystemClock.elapsedRealtime();
errCount++;
Logger.d(TAG, "异常点纠偏 info: " + lastLocation);
if(recordLocation()) {
correctList.add(nextInfo);
}
// return lastLocation;
return nextInfo;
}catch (Exception e){
Logger.e(TAG, e, "纠偏异常");
e.printStackTrace();
}
}
}
return null;
}
private boolean isLocationValid(CloudLocationInfo info) {
return info.getLat() != 0 && info.getLon() != 0;
}
private RecordLocationListener recordLocationListener = null;
private boolean hasCallbackReocrd = false;
public void setRecordLocationListener(RecordLocationListener recordLocationListener) {
this.recordLocationListener = recordLocationListener;
}
private boolean recordLocation(){
if (historyList.size() >= 100 && !hasCallbackReocrd && recordLocationListener != null) {
hasCallbackReocrd = true;
recordLocationListener.onRecordFinish(historyList, correctList,validList,correctList);
}
return historyList.size() < 100;
}
/**
* 根据距离和角度计算下一个经纬度
* 大地坐标系资料WGS-84 长半径a=6378137 短半径b=6356752.3142 扁率f=1/298.2572236
*/
public MogoLatLng computerThatLonLat(double lon, double lat, double brng, double dist) {
double alpha1 = rad(brng);
double sinAlpha1 = Math.sin(alpha1);
double cosAlpha1 = Math.cos(alpha1);
// 扁率f=1/298.2572236
double f = 1 / 298.2572236;
double tanU1 = (1 - f) * Math.tan(rad(lat));
double cosU1 = 1 / Math.sqrt((1 + tanU1 * tanU1));
double sinU1 = tanU1 * cosU1;
double sigma1 = Math.atan2(tanU1, cosAlpha1);
double sinAlpha = cosU1 * sinAlpha1;
double cosSqAlpha = 1 - sinAlpha * sinAlpha;
// 长半径a=6378137
double a = 6378137;
// 短半径b=6356752.3142
double b = 6356752.3142;
double uSq = cosSqAlpha * (a * a - b * b) / (b * b);
double A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
double B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
double cos2SigmaM=0;
double sinSigma=0;
double cosSigma=0;
double sigma = dist / (b * A), sigmaP = 2 * Math.PI;
while (Math.abs(sigma - sigmaP) > 1e-12) {
cos2SigmaM = Math.cos(2 * sigma1 + sigma);
sinSigma = Math.sin(sigma);
cosSigma = Math.cos(sigma);
double deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)
- B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM)));
sigmaP = sigma;
sigma = dist / (b * A) + deltaSigma;
}
double tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1;
double lat2 = Math.atan2(sinU1 * cosSigma + cosU1 * sinSigma * cosAlpha1,
(1 - f) * Math.sqrt(sinAlpha * sinAlpha + tmp * tmp));
double lambda = Math.atan2(sinSigma * sinAlpha1, cosU1 * cosSigma - sinU1 * sinSigma * cosAlpha1);
double C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
double L = lambda - (1 - C) * f * sinAlpha
* (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));
// final bearing
double revAz = Math.atan2(sinAlpha, -tmp);
System.out.println(revAz);
System.out.println(lon+deg(L)+","+deg(lat2));
return new MogoLatLng(deg(lat2), lon + deg(L));
}
/**
* 度换成弧度
*
* @param d
* 度
* @return 弧度
*/
private double rad(double d) {
return d * Math.PI / 180.0;
}
/**
* 弧度换成度
*
* @param x
* 弧度
* @return 度
*/
private double deg(double x) {
return x * 180 / Math.PI;
}
public interface RecordLocationListener{
void onRecordFinish(List<CloudLocationInfo> history, List<CloudLocationInfo> correct,List<CloudLocationInfo> valid,List<CloudLocationInfo> err);
}
}

View File

@@ -0,0 +1,135 @@
package com.mogo.module.service.vrmode;
import android.content.ComponentName;
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;
import com.mogo.module.common.machinevision.IMachineVisionInterface;
import com.mogo.utils.logger.Logger;
public
/**
* @author congtaowang
* @since 2020/10/27
*
* 描述
*/
class VrModeController {
private static final String TAG = "VrModeController";
private static volatile VrModeController sInstance;
private volatile IMachineVisionInterface mMachineVisionInterface;
private ServiceConnection mServiceConnection;
private VrModeController() {
}
public static VrModeController getInstance() {
if ( sInstance == null ) {
synchronized ( VrModeController.class ) {
if ( sInstance == null ) {
sInstance = new VrModeController();
}
}
}
return sInstance;
}
public synchronized void release() {
sInstance = null;
}
private Object readResolve() {
// 阻止反序列化,必须实现 Serializable 接口
return sInstance;
}
private boolean mIsBinding = false;
public void onVrModeChanged( boolean isVrMode ) {
if ( isVrMode ) {
bindVrModeService();
} else {
unbindVrModeService();
}
}
private void bindVrModeService() {
if ( mIsBinding ) {
return;
}
mIsBinding = true;
Intent intent = new Intent();
intent.setComponent( new ComponentName( "com.mogo.launcher.f", "com.mogo.module.machine.vision.MachineVisionMapService" ) );
AbsMogoApplication.getApp().bindService( intent, mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected( ComponentName name, IBinder service ) {
mMachineVisionInterface = IMachineVisionInterface.Stub.asInterface( service );
}
@Override
public void onServiceDisconnected( ComponentName name ) {
mMachineVisionInterface = null;
}
@Override
public void onBindingDied( ComponentName name ) {
mMachineVisionInterface = null;
}
@Override
public void onNullBinding( ComponentName name ) {
mMachineVisionInterface = null;
}
}, Context.BIND_AUTO_CREATE );
}
private void unbindVrModeService() {
mIsBinding = false;
if ( mServiceConnection != null ) {
try {
AbsMogoApplication.getApp().unbindService( mServiceConnection );
} catch ( Exception e ) {
Logger.e( TAG, e, "unbindVrModeService" );
}
}
}
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;
}
if ( mMachineVisionInterface == null ) {
return;
}
try {
mMachineVisionInterface.postData( data );
} catch ( Exception e ) {
Logger.e( TAG, e, "postData" );
}
}
}

View File

@@ -0,0 +1,35 @@
package com.mogo.module.service.websocket;
import com.mogo.module.common.entity.CloudLocationInfo;
import java.util.List;
public
/**
* @author congtaowang
* @since 2020/10/25
*
* 自车定位信息
*/
class LocationResult {
/**
* sn
*/
public String sn;
/**
* 最后一个定位点的莫顿码
*/
public long mortonCode;
/**
* 最后一个定位点
*/
public CloudLocationInfo lastCoordinate;
/**
* 1s 内的连续定位点
*/
public List< CloudLocationInfo > coordinates;
}

View File

@@ -0,0 +1,25 @@
package com.mogo.module.service.websocket;
import com.mogo.service.adas.entity.ADASRecognizedResult;
import java.util.List;
public
/**
* @author congtaowang
* @since 2020/10/25
*
* 一秒一次的上行数据
*/
class OnePerSecondSendContent {
/**
* 自车定位点
*/
public LocationResult self;
/**
* adas 识别物体1s 识别到的最后帧
*/
public List< ADASRecognizedResult > adas;
}