diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index b69c9bf04f..be10595669 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -18,6 +18,7 @@
+
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000000..6560a98983
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,36 @@
+
+
+ * 描述 + */ +public class AMapBaseMapView extends MogoBaseMapView { + + private static final String TAG = "AMapBaseMapView"; + + public AMapBaseMapView( Context context ) { + super( context ); + } + + public AMapBaseMapView( Context context, @Nullable AttributeSet attrs ) { + super( context, attrs ); + } + + public AMapBaseMapView( Context context, @Nullable AttributeSet attrs, int defStyleAttr ) { + super( context, attrs, defStyleAttr ); + } + + + private MapAutoView mapAutoView; + @Override + protected IMogoMapView createMapView( Context context ) { + Log.i(TAG, "autoop--createMapView: "); + if(mapAutoView == null){ + Log.i(TAG, "autoop--createMapView: mapAutoView is null create"); + MapAutoApi.INSTANCE.init(MapParams.Companion.init().setDebugMode(false) + .setCoordinateType(MapParams.COORDINATETYPE_GCJ02) + .setPerspectiveMode(MapParams.MAP_PERSPECTIVE_2D) + .setStyleMode(MapParams.MAP_STYLE_NIGHT)); + mapAutoView = new MapAutoView( context ); + } + return new AMapViewWrapper(mapAutoView); + } +} diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/AMapMarkerClickHandler.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/AMapMarkerClickHandler.java new file mode 100644 index 0000000000..15706187e5 --- /dev/null +++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/AMapMarkerClickHandler.java @@ -0,0 +1,32 @@ +package com.mogo.map.impl.custom; + +import com.mogo.map.marker.IMogoMarker; +import com.mogo.map.marker.IMogoMarkerClickListener; +import com.mogo.map.marker.MogoMarkersHandler; +import com.mogo.utils.logger.Logger; +import com.zhidaoauto.map.sdk.open.marker.Marker; + +/** + * @author congtaowang + * @since 2019-12-24 + *
+ * marker 点击事件处理 + */ +public class AMapMarkerClickHandler { + + public boolean handleMarkerClicked( Marker marker ) { + if ( marker == null ) { + return false; + } + if ( marker.getMObject() instanceof IMogoMarker ) { + IMogoMarker mogoMarker = ( ( IMogoMarker ) marker.getMObject() ); + final IMogoMarkerClickListener listener = mogoMarker.getOnMarkerClickListener(); + Logger.d( "AMapMarkerWrapper", "marker 点击回调:%s -> %s", mogoMarker, marker ); + if ( listener != null ) { + listener.onMarkerClicked( mogoMarker ); + } + return MogoMarkersHandler.getInstance().onMarkerClicked( mogoMarker ); + } + return false; + } +} diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/AMapNaviViewWrapper.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/AMapNaviViewWrapper.java new file mode 100644 index 0000000000..a5ce478282 --- /dev/null +++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/AMapNaviViewWrapper.java @@ -0,0 +1,886 @@ +//package com.mogo.map.impl.custom; +// +//import android.content.Context; +//import android.graphics.BitmapFactory; +//import android.graphics.Color; +//import android.graphics.Point; +//import android.graphics.Rect; +//import android.location.Location; +//import android.os.Bundle; +//import android.os.SystemClock; +//import android.os.Trace; +//import android.util.Log; +//import android.view.MotionEvent; +//import android.view.View; +//import android.view.animation.Interpolator; +// +//import com.mogo.commons.debug.DebugConfig; +//import com.mogo.map.IMogoMap; +//import com.mogo.map.IMogoMapView; +//import com.mogo.map.MogoLatLng; +//import com.mogo.map.impl.custom.hook.BnHooker; +//import com.mogo.map.impl.custom.marker.AMapMarkerWrapper; +//import com.mogo.map.impl.custom.message.AMapMessageListener; +//import com.mogo.map.impl.custom.message.AMapMessageManager; +//import com.mogo.map.impl.custom.navi.NaviClient; +//import com.mogo.map.impl.custom.utils.MogoMapUtils; +//import com.mogo.map.impl.custom.utils.ObjectUtils; +//import com.mogo.map.listener.MogoMapListenerHandler; +//import com.mogo.map.marker.IMogoMarker; +//import com.mogo.map.uicontroller.CarCursorOption; +//import com.mogo.map.uicontroller.EnumMapUI; +//import com.mogo.map.uicontroller.IMogoMapUIController; +//import com.mogo.map.uicontroller.MapCameraPosition; +//import com.mogo.map.uicontroller.MapControlResult; +//import com.mogo.utils.WindowUtils; +//import com.mogo.utils.logger.Logger; +//import com.zhidaoauto.map.sdk.open.MapParams; +//import com.zhidaoauto.map.sdk.open.camera.CameraUpdate; +//import com.zhidaoauto.map.sdk.open.location.LocationListener; +//import com.zhidaoauto.map.sdk.open.location.MyLocationStyle; +//import com.zhidaoauto.map.sdk.open.tools.MapTools; +//import com.zhidaoauto.map.sdk.open.view.MapAutoView; +//import com.zhidaoauto.map.sdk.open.view.MapAutoViewHelper; +// +//import org.jetbrains.annotations.NotNull; +// +//import java.util.List; +// +///** +// * @author congtaowang +// * @since 2019-12-18 +// *
+// * 代理高德导航地图 +// */ +//public class AMapNaviViewWrapper implements IMogoMapView, +// IMogoMapUIController, +// OnMarkClickListener, +//// AMap.OnMapLoadedListener, +//// AMap.OnMapTouchListener, +//// AMap.OnPOIClickListener, +//// AMap.OnMapClickListener, +//// AMap.OnPolylineClickListener, +//// AMapNaviViewListener, +//// AMapMessageListener, +//// AMap.OnCameraChangeListener, +// LocationListener { +// +// private static final String TAG = "AMapNaviViewWrapper"; +// +// private final MapAutoView mMapView; +// private IMogoMap mIMap; +// +// private AMapMarkerClickHandler mMarkerClickHandler; +// private EnumMapUI mCurrentUIMode; +// +// private boolean mIsCarLocked = false; +// +// private float mDefaultZoomLevel = 16.0f; +// private final CarCursorOption DEFAULT_OPTION = new CarCursorOption.Builder() +// .carCursorRes( R.drawable.map_api_ic_current_location2 ) +// .naviCursorRes( R.drawable.ic_amap_navi_cursor ) +// .build(); +// private CarCursorOption mCarCursorOption = DEFAULT_OPTION; +// +// public AMapNaviViewWrapper( MapAutoView mapView ) { +// this.mMapView = mapView; +// this.mIMap = new AMapWrapper( mMapView.getMapAutoViewHelper(), mMapView, this ); +// try { +// new BnHooker( mMapView.getMapAutoViewHelper(), mapView.getContext() ); +// } catch ( Exception e ) { +// e.printStackTrace(); +// } +// } +// +// private void initMapView() { +// if ( mMapView == null ) { +// return; +// } +// MapAutoViewHelper options = mMapView.getMapAutoViewHelper(); +// if ( options != null ) { +// // 设置是否开启自动黑夜模式切换,默认为false,不自动切换 +//// options.setAutoNaviViewNightMode( false ); +// // 设置6秒后是否自动锁车 +//// options.setAutoLockCar( false ); +// // 设置路线上的摄像头气泡是否显示 +//// options.setCameraBubbleShow( true ); +// // 设置路线相关的配置属性,如:路线的路况颜色,路线上是否显示摄像头气泡等。 +// // options.setRouteOverlayOptions( MapStyleUtils.getRouteOverlayOptions() ); +// // 设置自车的图片对象 +//// options.setCarBitmap( BitmapFactory.decodeResource( getContext().getResources(), DEFAULT_OPTION.getNaviCursorRes() ) ); +// // 设置指南针图标否在导航界面显示,默认显示。true,显示;false,隐藏。 +// options.hiddenDirection(); +// // 黑夜模式 +// options.setMapStyle(MapParams.MAP_STYLE_NIGHT); +// //设置路况光柱条是否显示(只适用于驾车导航,需要联网)。 +//// options.setTrafficBarEnabled( false ); +// // 设置[实时交通图层开关按钮]是否显示(只适用于驾车导航,需要联网)。 +//// options.setTrafficLayerEnabled( false ); +// // 设置导航界面是否显示路线全览按钮。 +//// options.setRouteListButtonShow( false ); +// // 设置导航状态下屏幕是否一直开启。 +//// options.setScreenAlwaysBright( true ); +// // 设置交通播报是否打开(只适用于驾车导航,需要联网)。 +//// options.setTrafficInfoUpdateEnabled( true ); +// // 设置摄像头播报是否打开(只适用于驾车导航)。 +//// options.setCameraInfoUpdateEnabled( true ); +// // 设置菜单按钮是否在导航界面显示。 +//// options.setSettingMenuEnabled( false ); +// // 设置是否绘制显示交通路况的线路(彩虹线),拥堵-红色,畅通-绿色,缓慢-黄色,未知-蓝色。默认不绘制彩虹线。 +//// options.setTrafficLine( true ); +// // 设置是否绘制牵引线(当前位置到目的地的指引线)。默认不绘制牵引线。 +//// options.setLeaderLineEnabled( -1 ); +// // 设置导航界面UI是否显示。 +//// options.setLayoutVisible( false ); +// // 设置是否自动画路 +//// options.setAutoDrawRoute( false ); +// // 设置是否显示路口放大图(实景图) +//// options.setRealCrossDisplayShow( false ); +// // 设置是否显示路口放大图(路口模型图) +//// options.setModeCrossDisplayShow( false ); +// // 设置是否显示道路信息view +//// options.setLaneInfoShow( false ); +// // 设置是否自动改变缩放等级 +//// options.setAutoChangeZoom( false ); +// // 设置是否自动全览模式,即在算路成功后自动进入全览模式 +//// options.setAutoDisplayOverview( false ); +// // 设置路线转向箭头隐藏和显示 +//// options.setNaviArrowVisible( false ); +// // 通过路线是否自动置灰,仅支持驾车导航 +//// options.setAfterRouteAutoGray( true ); +// options.setZoom( ( ( int ) mDefaultZoomLevel ) ); +// options.setPointToCenter( 0.5D, 0.5D ); +// // 2D模式 +// options.setTilt( 0 ); +// mMapView.setViewOptions( options ); +// } +// mMapView.setRouteOverlayVisible( false ); +// mMapView.setCarOverlayVisible( false ); +// setUIMode( EnumMapUI.CarUp_2D, null ); +// } +// +// private void initListeners() { +// +// mMapView.setOnMarkerClickListener( this ); +// mMarkerClickHandler = new AMapMarkerClickHandler(); +// mMapView.setOnMapLoadedListener( this ); +// mMapView.setOnMapTouchListener( this ); +// mMapView.setOnPolylineClickListener( this ); +// mMapView.setAMapNaviViewListener( this ); +// mMapView.setOnCameraChangeListener( this ); +// +// final AMap aMap = mMapView.getMap(); +// if ( aMap != null ) { +// aMap.setOnPOIClickListener( this ); +// aMap.setOnMapClickListener( this ); +// aMap.setOnCameraChangeListener( this ); +// aMap.setOnMyLocationChangeListener( this ); +// } +// AMapMessageManager.getInstance().registerAMapMessageListener( this ); +// } +// +// private Context getContext() { +// return mMapView.getContext(); +// } +// +// @Override +// public View getMapView() { +// return mMapView; +// } +// +// @Override +// public IMogoMap getMap() { +// return mIMap; +// } +// +// @Override +// public void onCreate( Bundle bundle ) { +// if ( mMapView != null ) { +// mMapView.onCreate( bundle ); +// Logger.d( TAG, "map onCreate" ); +// initMapView(); +// initListeners(); +// initMyLocation(); +// } +// } +// +// @Override +// public void onResume() { +// if ( mMapView != null ) { +// mMapView.onResume(); +// Logger.d( TAG, "map onResume" ); +// } +// } +// +// @Override +// public void onPause() { +// if ( mMapView != null ) { +// mMapView.onPause(); +// Logger.d( TAG, "map onPause" ); +// } +// } +// +// @Override +// public void onDestroy() { +// if ( mMapView != null ) { +// mMapView.onDestroy(); +// Logger.d( TAG, "map onDestroy" ); +// } +// } +// +// @Override +// public void onSaveInstanceState( Bundle outState ) { +// if ( mMapView != null ) { +// mMapView.onSaveInstanceState( outState ); +// Logger.d( TAG, "map onSaveInstanceState" ); +// } +// } +// +// @Override +// public void onLowMemory() { +// Logger.d( TAG, "map onLowMemory" ); +// } +// +// /** +// * 地图marker点击 +// */ +// @Override +// public boolean onMarkerClick( Marker marker ) { +// return mMarkerClickHandler.handleMarkerClicked( marker ); +// } +// +// /** +// * 地图加载完毕 +// */ +// @Override +// public void onMapLoaded() { +// MogoMapListenerHandler.getInstance().onMapLoaded(); +// } +// +// /** +// * 地图点击回调 +// */ +// @Override +// public void onTouch( MotionEvent motionEvent ) { +// MogoMapListenerHandler.getInstance().onTouch( motionEvent ); +// } +// +// /** +// * POI 点击 +// */ +// @Override +// public void onPOIClick( Poi poi ) { +// if ( InterceptorHandler.getInstance().ignorePoiClicked( getContext() ) ) { +// return; +// } +// MogoMapListenerHandler.getInstance().onPOIClick( ObjectUtils.fromAMap( poi ) ); +// } +// +// @Override +// public void onMapClick( LatLng latLng ) { +// if ( InterceptorHandler.getInstance().ignoreMapClicked( getContext() ) ) { +// return; +// } +// MogoMapListenerHandler.getInstance().onMapClick( ObjectUtils.fromAMap( latLng ) ); +// } +// +// @Override +// public void onPolylineClick( Polyline polyline ) { +// if ( !NaviClient.getInstance( getContext() ).isNaviing() ) { +// NaviClient.getInstance( getContext() ).handleClickedPolyline( polyline ); +// } +// } +// +// @Override +// public void onNaviSetting() { +// +// } +// +// @Override +// public void onNaviCancel() { +// +// } +// +// @Override +// public boolean onNaviBackClick() { +// return true; +// } +// +// /** +// * @param mode 0:车头朝上状态;1:正北朝上模式 +// */ +// @Override +// public void onNaviMapMode( int mode ) { +// Logger.i( TAG, "mode=" + mode ); +// } +// +// @Override +// public void onNaviTurnClick() { +// +// } +// +// @Override +// public void onNextRoadClick() { +// +// } +// +// @Override +// public void onScanViewButtonClick() { +// +// } +// +// @Override +// public void onLockMap( boolean isLock ) { +// Logger.d( TAG, "lock status = %s", isLock ); +// mIsCarLocked = isLock; +// Trace.beginSection( "timer.onCameraChangeFinish" ); +// MogoMapListenerHandler.getInstance().onLockMap( isLock ); +// Trace.endSection(); +// } +// +// @Override +// public void onNaviViewLoaded() { +// +// } +// +// @Override +// public void onMapTypeChanged( int type ) { +// if ( type == 4 ) { +// MogoMapListenerHandler.getInstance().onMapModeChanged( EnumMapUI.Type_Light ); +// } else if ( type == 3 ) { +// MogoMapListenerHandler.getInstance().onMapModeChanged( EnumMapUI.Type_Night ); +// } +// } +// +// @Override +// public void onNaviViewShowMode( int i ) { +// +// long delay = mMapView.getViewOptions().getLockMapDelayed(); +// switch ( i ) { +// case AMapNaviViewShowMode.SHOW_MODE_DEFAULT: +// Logger.d( TAG, "普通模式" ); +// break; +// case AMapNaviViewShowMode.SHOW_MODE_DISPLAY_OVERVIEW: +// Logger.d( TAG, "全览模式" ); +// break; +// case AMapNaviViewShowMode.SHOW_MODE_LOCK_CAR: +// Logger.d( TAG, "锁车模式: %s", delay ); +// break; +// } +// } +// +// @Override +// public void setTrafficEnabled( boolean visible ) { +// if ( checkAMapView() ) { +// mMapView.setTrafficLine( visible ); +// } +// } +// +// @Override +// public MapControlResult changeZoom( boolean zoom ) { +// if ( checkAMapView() ) { +// mDefaultZoomLevel = ( int ) ( getMap().getZoomLevel() + 0.5f ); +// +// if ( zoom ) { +// if ( mDefaultZoomLevel >= 20 ) { +// return MapControlResult.TARGET; +// } +// } else { +// if ( mDefaultZoomLevel <= 3 ) { +// return MapControlResult.TARGET; +// } +// } +// +// if ( zoom ) { +// mDefaultZoomLevel += 2f; +// if ( mDefaultZoomLevel > 20 ) { +// mDefaultZoomLevel = 20; +// } +// } else { +// mDefaultZoomLevel -= 2f; +// if ( mDefaultZoomLevel < 1 ) { +// mDefaultZoomLevel = 1; +// } +// } +// changeZoom( ( int ) mDefaultZoomLevel ); +// } +// return MapControlResult.SUCCESS; +// } +// +// @Override +// public MapControlResult changeZoom( float zoom ) { +// Logger.d( TAG, "changeZoom %s", zoom ); +// if ( DebugConfig.isDebug() ) { +// Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); +// } +// getMap().changeZoom( zoom ); +// return MapControlResult.SUCCESS; +// } +// +// @Override +// public void changeMapMode( EnumMapUI ui ) { +// if ( ui == null ) { +// return; +// } +// if ( checkAMapView() ) { +// AMapNaviViewOptions options = mMapView.getViewOptions(); +// if ( options == null ) { +// options = new AMapNaviViewOptions(); +// } +// switch ( ui ) { +// case CarUp_2D: +// case CarUp_3D: +// case NorthUP_2D: +// setUIMode( ui, options ); +// return; +// case Type_Light: +// options.setNaviNight( false ); +// break; +// case Type_Night: +// options.setNaviNight( true ); +// break; +// case Type_AUTO_LIGHT_Night: +// options.setNaviNight( false ); +// options.setAutoNaviViewNightMode( true ); +// break; +// } +// mMapView.setViewOptions( options ); +// } +// } +// +// private void setUIMode( EnumMapUI ui, AMapNaviViewOptions options ) { +// this.mCurrentUIMode = ui; +// switch ( ui ) { +// case CarUp_2D: +// case CarUp_3D: +// mMapView.setNaviMode( AMapNaviView.CAR_UP_MODE ); +// break; +// case NorthUP_2D: +// mMapView.setNaviMode( AMapNaviView.NORTH_UP_MODE ); +// break; +// } +// +// Logger.d( TAG, "mCurrentUIMode--->" + mCurrentUIMode.name() ); +// if ( options == null ) { +// return; +// } +// switch ( ui ) { +// case CarUp_2D: +// case NorthUP_2D: +// options.setTilt( 0 ); +// break; +// case CarUp_3D: +// options.setTilt( 60 ); +// break; +// } +// } +// +// private boolean checkAMapView() { +// if ( mMapView == null ) { +// Logger.e( TAG, "高德mapView实例为空,请检查" ); +// return false; +// } +// return true; +// } +// +// @Override +// public void moveToCenter( MogoLatLng latLng, boolean animate ) { +// Logger.d( TAG, "move to center %s", latLng ); +// if ( latLng == null || latLng.lat == 0.0d || latLng.lng == 0.0d ) { +// Logger.e( TAG, "latlng = null or is illegal" ); +// return; +// } +// if ( DebugConfig.isDebug() ) { +// Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); +// } +// loseLockMode(); +// if ( animate ) { +// mMapView.getMap().animateCamera( CameraUpdateFactory.newLatLng( new LatLng( latLng.lat, latLng.lng ) ) ); +// } else { +// mMapView.getMap().moveCamera( CameraUpdateFactory.newLatLng( new LatLng( latLng.lat, latLng.lng ) ) ); +// } +// } +// +// @Override +// public void showMyLocation( boolean visible ) { +// Logger.d( TAG, "showMyLocation1 %s", visible ); +// if ( visible && NaviClient.getInstance( getContext() ).isNaviing() ) { +// return; +// } +// if ( DebugConfig.isDebug() ) { +// Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); +// } +// if ( checkAMapView() ) { +// MyLocationStyle style = mMapView.getMap().getMyLocationStyle(); +// style.showMyLocation( visible ); +// if ( visible ) { +// // 强制刷新一遍车标 +// style.myLocationIcon( BitmapDescriptorFactory.fromResource( mCarCursorOption.getCarCursorRes() ) ); +// } +// mMapView.getMap().setMyLocationStyle( style ); +// } +// } +// +// @Override +// public void showMyLocation( View view ) { +// if ( NaviClient.getInstance( getContext() ).isNaviing() ) { +// return; +// } +// if ( DebugConfig.isDebug() ) { +// Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); +// } +// if ( checkAMapView() ) { +// MyLocationStyle style = mMapView.getMap().getMyLocationStyle(); +// style.showMyLocation( true ); +// style.myLocationIcon( BitmapDescriptorFactory.fromView( view ) ); +// mMapView.getMap().setMyLocationStyle( style ); +// } +// } +// +// public void initMyLocation() { +// if ( checkAMapView() ) { +// mMapView.getMap().setMyLocationEnabled( true ); +// MyLocationStyle style = mMapView.getMap().getMyLocationStyle(); +// style.myLocationType( MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER ); +// style.interval( 1000 ); +// style.anchor( 0.5F, 0.5F ); +// style.strokeColor( Color.TRANSPARENT ); +// style.strokeWidth( 0 ); +// style.radiusFillColor( Color.TRANSPARENT ); +// mMapView.getMap().setMyLocationStyle( style ); +// } +// } +// +// @Override +// public void recoverLockMode() { +// if ( checkAMapView() ) { +// if ( DebugConfig.isDebug() ) { +// Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); +// } +// Logger.d( TAG, "锁车" ); +// mMapView.recoverLockMode(); +// mIsCarLocked = true; +// } +// } +// +// @Override +// public void loseLockMode() { +// if ( DebugConfig.isDebug() ) { +// Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); +// } +// Logger.d( TAG, "解锁锁车" ); +// mockTouchEvent(); +// mIsCarLocked = false; +// } +// +// /** +// * 模拟点击事件,达到锁车->普通事件 +// */ +// private void mockTouchEvent() { +// long downTime = SystemClock.uptimeMillis(); +// long eventTime = downTime + 1; +// int metaState = 0; +// MotionEvent motionEvent = MotionEvent.obtain( downTime, eventTime, MotionEvent.ACTION_DOWN, 0, 0, metaState ); +// mMapView.dispatchTouchEvent( motionEvent ); +// MotionEvent upEvent = MotionEvent.obtain( downTime + 1, eventTime + 2, MotionEvent.ACTION_UP, 0, 0, metaState ); +// mMapView.dispatchTouchEvent( upEvent ); +// } +// +// @Override +// public void setLockZoom( int var1 ) { +// if ( checkAMapView() ) { +// if ( DebugConfig.isDebug() ) { +// Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); +// } +// Logger.d( TAG, "Zoom锁定锁车比例尺 %s", var1 ); +// mMapView.setLockZoom( var1 ); +// } +// } +// +// @Override +// public void displayOverview( Rect bounds ) { +// if ( checkAMapView() ) { +// if ( NaviClient.getInstance( getContext() ).isNaviing() ) { +// loseLockMode(); +// NaviClient.getInstance( getContext() ).displayOverview( bounds ); +// } +// } +// } +// +// @Override +// public float getScalePerPixel() { +// return getMap().getScalePerPixel(); +// } +// +// @Override +// public float getZoomLevel() { +// return getMap().getZoomLevel(); +// } +// +// @Override +// public void onNaviStarted() { +// if ( checkAMapView() ) { +// mMapView.setCarOverlayVisible( true ); +// showMyLocation( false ); +// } +// } +// +// @Override +// public void onNaviStopped() { +// if ( checkAMapView() ) { +// mMapView.setCarOverlayVisible( false ); +// showMyLocation( true ); +// NaviClient.getInstance( getContext() ).startAimlessMode(); +// } +// } +// +// @Override +// public void onNaviInfoUpdat( NaviInfo naviInfo ) { +// +// } +// +// @Override +// public void onCalculateSuccess() { +// loseLockMode(); +// } +// +// @Override +// public void onCameraChange( CameraPosition cameraPosition ) { +// } +// +// @Override +// public void onCameraChangeFinish( CameraPosition cameraPosition ) { +// if ( cameraPosition != null ) { +// Trace.beginSection( "timer.onCameraChangeFinish" ); +// MogoMapListenerHandler.getInstance().onMapChanged( ObjectUtils.fromAMap( cameraPosition.target ), +// cameraPosition.zoom, +// cameraPosition.tilt, +// cameraPosition.bearing ); +// Trace.endSection(); +// } +// } +// +// @Override +// public MogoLatLng getCameraNorthEastPosition() { +// try { +// return ObjectUtils.fromAMap( mMapView.getMap().getProjection().getVisibleRegion().latLngBounds.northeast ); +// } catch ( Exception e ) { +// +// } +// return null; +// } +// +// @Override +// public MogoLatLng getCameraSouthWestPosition() { +// try { +// return ObjectUtils.fromAMap( mMapView.getMap().getProjection().getVisibleRegion().latLngBounds.southwest ); +// } catch ( Exception e ) { +// +// } +// return null; +// } +// +// @Override +// public MogoLatLng getWindowCenterLocation() { +// try { +// return ObjectUtils.fromAMap( mMapView.getMap().getCameraPosition().target ); +// } catch ( Exception e ) { +// +// } +// return null; +// } +// +// @Override +// public void setPointToCenter( double mapCenterX, double mapCenterY ) { +// if ( checkAMapView() ) { +// if ( DebugConfig.isDebug() ) { +// Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); +// } +// Logger.d( TAG, "setPointToCenter(%s, %s)", mapCenterX, mapCenterY ); +//// AMapNaviViewOptions options = mMapView.getViewOptions(); +//// options.setPointToCenter( mapCenterX, mapCenterY ); +//// mMapView.setViewOptions( options ); +// } +// } +// +// @Override +// public Point getLocationPointInScreen( MogoLatLng latLng ) { +// if ( checkAMapView() ) { +// try { +// return MapTools.INSTANCE.toScreenLocation( ObjectUtils.fromMogo( latLng ) ); +// } catch ( Exception e ) { +// return null; +// } +// } +// return null; +// } +// +// @Override +// public MogoLatLng getLocationMogoLatLngInScreen( Point point ) { +// if ( checkAMapView() ) { +// try { +// return ObjectUtils.fromAMap( +// MapTools.INSTANCE.fromScreenLocation( point ) ); +// } catch ( Exception e ) { +// return null; +// } +// } +// return null; +// } +// +// @Override +// public void startJumpAnimation( IMogoMarker marker, float high, Interpolator interpolator, +// long duration ) { +// if ( marker == null || high <= 0.0f || interpolator == null || duration < 0 ) { +// return; +// } +// try { +//// final LatLng latLng = ObjectUtils.fromMogo2( marker.getPosition() ); +//// Point point = mMapView.getMap().getProjection().toScreenLocation( latLng ); +//// point.y -= WindowUtils.dip2px( getContext(), high ); +//// LatLng target = mMapView.getMap().getProjection().fromScreenLocation( point ); +//// //使用TranslateAnimation,填写一个需要移动的目标点 +//// Animation animation = new TranslateAnimation( target ); +//// animation.setInterpolator( interpolator ); +//// //整个移动所需要的时间 +//// animation.setDuration( duration ); +//// //设置动画 +//// if ( marker instanceof AMapMarkerWrapper ) { +//// ( ( AMapMarkerWrapper ) marker ).getMarker().setAnimation( animation ); +//// ( ( AMapMarkerWrapper ) marker ).getMarker().startAnimation(); +//// } +// } catch ( Exception e ) { +// Logger.e( TAG, e, "error." ); +// } +// } +// +// @Override +// public void setRenderFps( int fps ) { +// if ( checkAMapView() ) { +// if ( mMapView.getMapAutoViewHelper() != null ) { +//// mMapView.getMapAutoViewHelper().setRenderFps( fps ); +// Logger.d( TAG, "设置刷新帧率 fps = %s", fps ); +// } +// } +// } +// +// @Override +// public void showBounds( String tag, MogoLatLng carPosition, List< MogoLatLng > lonLats, Rect bound, boolean lockCarPosition ) { +// if ( !checkAMapView() ) { +// return; +// } +// try { +//// if ( DebugConfig.isDebug() ) { +//// Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); +//// } +//// LatLngBounds latLngBounds = MogoMapUtils.getLatLngBounds( carPosition, lonLats, lockCarPosition ); +//// if ( !lockCarPosition ) { +//// loseLockMode(); +//// } +//// mMapView.getMapAutoViewHelper().moveCamera( new CameraUpdate(new MapCameraMessage( latLngBounds, bound.left, bound.right, bound.top, bound.bottom ) )); +// } catch ( Exception e ) { +// Logger.e( TAG, e, "%s error.", tag ); +// } +// } +// +// @Override +// public void forceRender() { +// if ( checkAMapView() ) { +// mMapView.getMapAutoViewHelper().runOnDrawFrame(); +// } +// } +// +// @Override +// public float calculateLineDistance( MogoLatLng p1, MogoLatLng p2 ) throws Exception { +// if ( p1 == null || p2 == null ) { +// throw new Exception( "计算距离的点不能为 null" ); +// } +// return AMapUtils.calculateLineDistance( ObjectUtils.fromMogo2( p1 ), ObjectUtils.fromMogo2( p2 ) ); +// } +// +// @Override +// public void onMyLocationChange( Location location ) { +// NaviClient.getInstance( getContext() ).syncCarLocation( location ); +// } +// +// @Override +// public EnumMapUI getCurrentUiMode() { +// return mCurrentUIMode; +// } +// +// @Override +// public void changeMyLocation( Location location ) { +// } +// +// @Override +// public synchronized boolean isCarLocked() { +// return mIsCarLocked; +// } +// +// @Override +// public void setCarCursorOption( CarCursorOption option ) { +// if ( mCarCursorOption != null && mCarCursorOption != DEFAULT_OPTION ) { +// mCarCursorOption.destroy(); +// } +// if ( option != null ) { +// try { +// mCarCursorOption = option.clone(); +// } catch ( Exception e ) { +// mCarCursorOption = DEFAULT_OPTION; +// } +// } else { +// mCarCursorOption = DEFAULT_OPTION; +// } +// if ( !checkAMapView() ) { +// return; +// } +//// AMapNaviViewOptions options = mMapView.getViewOptions(); +//// if ( options != null && mCarCursorOption.getNaviCursorRes() != 0 ) { +//// options.setCarBitmap( BitmapFactory.decodeResource( getContext().getResources(), mCarCursorOption.getNaviCursorRes() ) ); +//// } else { +//// options.setCarBitmap( BitmapFactory.decodeResource( getContext().getResources(), DEFAULT_OPTION.getNaviCursorRes() ) ); +//// } +//// mMapView.setViewOptions( options ); +// +// if ( mMapView.getMapAutoViewHelper() == null ) { +// return; +// } +// MyLocationStyle style = mMapView.getMapAutoViewHelper().getMyLocationStyle(); +// if ( mCarCursorOption.getCarCursorBmp() != null && !mCarCursorOption.getCarCursorBmp().isRecycled() ) { +//// style.myLocationIcon( BitmapDescriptorFactory.fromBitmap( mCarCursorOption.getCarCursorBmp() ) ); +// } else { +// if ( mCarCursorOption.getCarCursorRes() != 0 ) { +// style.myLocationIcon( mCarCursorOption.getCarCursorRes()); +// } else { +// style.myLocationIcon( mCarCursorOption.getCarCursorRes()); +// } +// } +// mMapView.getMapAutoViewHelper().setMyLocationStyle( style ); +// } +// +// @Override +// public MapCameraPosition getMapCameraPosition() { +// if ( checkAMapView() ) { +//// CameraPosition cameraPosition = mMapView.getMap().getCameraPosition(); +//// return ObjectUtils.fromAMap( cameraPosition ); +// } +// return null; +// } +// +// @Override +// public void changeBearing( float bearing ) { +// if ( checkAMapView() ) { +//// mMapView.getMap().moveCamera( CameraUpdateFactory.changeBearing( bearing ) ); +// } +// } +// +// @Override +// public void onLocationChanged(@NotNull com.zhidaoauto.map.sdk.open.location.Location location) { +// Location sysLocation = new Location(location.getProvider()); +// sysLocation.setAltitude(location.getAltitude()); +// sysLocation.setLatitude(location.getLat()); +// sysLocation.setLongitude(location.getLon()); +// sysLocation.setSpeed(location.getSpeed()); +// NaviClient.getInstance( getContext() ).syncCarLocation(sysLocation); +// } +//} diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/AMapUiSettingsWrapper.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/AMapUiSettingsWrapper.java new file mode 100644 index 0000000000..6113f83131 --- /dev/null +++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/AMapUiSettingsWrapper.java @@ -0,0 +1,113 @@ +package com.mogo.map.impl.custom; + +import com.mogo.map.IMogoUiSettings; +import com.zhidaoauto.map.sdk.open.view.MapAutoViewHelper; + +import java.lang.reflect.Method; + +/** + * @author congtaowang + * @since 2019-12-18 + *
+ * 代理高德地图UiSettings
+ */
+public class AMapUiSettingsWrapper implements IMogoUiSettings {
+
+ private MapAutoViewHelper mUiSettings;
+
+ public AMapUiSettingsWrapper( MapAutoViewHelper mUiSettings ) {
+ this.mUiSettings = mUiSettings;
+ }
+
+ @Override
+ public void setScaleControlsEnabled( boolean enabled ) {
+ if ( mUiSettings != null ) {
+
+ }
+ }
+
+ @Override
+ public void setZoomControlsEnabled( boolean enabled ) {
+ if ( mUiSettings != null ) {
+ mUiSettings.setZoomGesturesEnabled( enabled );
+ }
+ }
+
+ @Override
+ public void setCompassEnabled( boolean enabled ) {
+ if ( mUiSettings != null ) {
+ if(enabled){
+ mUiSettings.showDirection();
+ }else{
+ mUiSettings.hiddenDirection();
+ }
+ }
+ }
+
+ @Override
+ public void setMyLocationButtonEnabled( boolean enabled ) {
+ if ( mUiSettings != null ) {
+ if(enabled){
+ mUiSettings.showLocation();
+ }else{
+ mUiSettings.hiddenLocation();
+ }
+ }
+ }
+
+ @Override
+ public void setScrollGesturesEnabled( boolean enabled ) {
+ if ( mUiSettings != null ) {
+ mUiSettings.setScrollGesturesEnabled( enabled );
+ }
+ }
+
+ @Override
+ public void setZoomGesturesEnabled( boolean enabled ) {
+ if ( mUiSettings != null ) {
+ mUiSettings.setZoomGesturesEnabled( enabled );
+ }
+ }
+
+ @Override
+ public void setTiltGesturesEnabled( boolean enabled ) {
+ if ( mUiSettings != null ) {
+ mUiSettings.setTiltGesturesEnabled( enabled );
+ }
+ }
+
+ @Override
+ public void setRotateGesturesEnabled( boolean enabled ) {
+ if ( mUiSettings != null ) {
+ mUiSettings.setRotateGesturesEnabled( enabled );
+ }
+ }
+
+ @Override
+ public void setAllGesturesEnabled( boolean enabled ) {
+ if ( mUiSettings != null ) {
+ mUiSettings.setAllGesturesEnabled( enabled );
+ }
+ }
+
+ @Override
+ public void setIndoorSwitchEnabled( boolean enabled ) {
+ if ( mUiSettings != null ) {
+
+// mUiSettings.setIndoorSwitchEnabled( enabled );
+ }
+ }
+
+ @Override
+ public void setLogoEnable( boolean enabled ) {
+ if ( mUiSettings != null ) {
+ try {
+ Method method = mUiSettings.getClass().getMethod( "setLogoEnable", boolean.class );
+ method.setAccessible( true );
+ method.invoke( mUiSettings, enabled );
+ } catch ( Exception e ) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
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
new file mode 100644
index 0000000000..6540634586
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/AMapViewWrapper.java
@@ -0,0 +1,734 @@
+package com.mogo.map.impl.custom;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.location.Location;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.animation.Interpolator;
+
+import com.mogo.commons.debug.DebugConfig;
+import com.mogo.map.IMogoMap;
+import com.mogo.map.IMogoMapView;
+import com.mogo.map.MogoLatLng;
+import com.mogo.map.impl.custom.navi.NaviClient;
+import com.mogo.map.impl.custom.utils.MogoMapUtils;
+import com.mogo.map.impl.custom.utils.ObjectUtils;
+import com.mogo.map.listener.MogoMapListenerHandler;
+import com.mogo.map.marker.IMogoMarker;
+import com.mogo.map.uicontroller.CarCursorOption;
+import com.mogo.map.uicontroller.EnumMapUI;
+import com.mogo.map.uicontroller.IMogoMapUIController;
+import com.mogo.map.uicontroller.MapCameraPosition;
+import com.mogo.map.uicontroller.MapControlResult;
+import com.mogo.utils.logger.Logger;
+import com.zhidaoauto.map.sdk.inner.common.MapHelper;
+import com.zhidaoauto.map.sdk.open.MapParams;
+import com.zhidaoauto.map.sdk.open.abs.OnMapClickListener;
+import com.zhidaoauto.map.sdk.open.abs.OnMapLoadedListener;
+import com.zhidaoauto.map.sdk.open.abs.OnMapTouchListener;
+import com.zhidaoauto.map.sdk.open.location.LocationListener;
+import com.zhidaoauto.map.sdk.open.location.MyLocationStyle;
+import com.zhidaoauto.map.sdk.open.marker.BitmapDescriptorFactory;
+import com.zhidaoauto.map.sdk.open.marker.Marker;
+import com.zhidaoauto.map.sdk.open.marker.MarkerInfo;
+import com.zhidaoauto.map.sdk.open.query.LonLatPoint;
+import com.zhidaoauto.map.sdk.open.tools.MapTools;
+import com.zhidaoauto.map.sdk.open.view.MapAutoView;
+import com.zhidaoauto.map.sdk.open.view.MapAutoViewHelper;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+public class AMapViewWrapper implements IMogoMapView, IMogoMapUIController, LocationListener, OnMapLoadedListener,
+ OnMapClickListener, OnMapTouchListener, Marker.OnMarkClickListener {
+
+ private static final String TAG = "AMapViewWrapper";
+ private final MapAutoView mMapView;
+ private IMogoMap mIMap;
+
+ private AMapMarkerClickHandler mMarkerClickHandler;
+ private EnumMapUI mCurrentUIMode;
+
+ private boolean mIsCarLocked = false;
+
+ private float mDefaultZoomLevel = 7.0f;
+ private final CarCursorOption DEFAULT_OPTION = new CarCursorOption.Builder()
+ .carCursorRes(R.drawable.map_api_ic_current_location2)
+ .naviCursorRes(R.drawable.ic_amap_navi_cursor)
+ .build();
+ private CarCursorOption mCarCursorOption = DEFAULT_OPTION;
+
+ public AMapViewWrapper(MapAutoView mMapView) {
+ Log.i(TAG, "autoop--AMapViewWrapper: init");
+ this.mMapView = mMapView;
+ this.mIMap = new AMapWrapper(this.mMapView.getMapAutoViewHelper(), this.mMapView, this);
+ }
+
+ private void initMapView() {
+ if (mMapView == null) {
+ return;
+ }
+ MapAutoViewHelper options = mMapView.getMapAutoViewHelper();
+ if (options != null) {
+ // 设置是否开启自动黑夜模式切换,默认为false,不自动切换
+ options.setAutoSwitchStyle(false);
+ // 设置6秒后是否自动锁车
+// options.setAutoLockCar( false );
+ // 设置路线上的摄像头气泡是否显示
+// options.setCameraBubbleShow( true );
+ // 设置路线相关的配置属性,如:路线的路况颜色,路线上是否显示摄像头气泡等。
+ // options.setRouteOverlayOptions( MapStyleUtils.getRouteOverlayOptions() );
+ // 设置自车的图片对象
+// options.setCarBitmap( BitmapFactory.decodeResource( getContext().getResources(), DEFAULT_OPTION.getNaviCursorRes() ) );
+ // 设置指南针图标否在导航界面显示,默认显示。true,显示;false,隐藏。
+ options.hiddenDirection();
+ // 黑夜模式
+ options.setMapStyle(MapParams.MAP_STYLE_NIGHT);
+ //设置路况光柱条是否显示(只适用于驾车导航,需要联网)。
+// options.setTrafficBarEnabled( false );
+ // 设置[实时交通图层开关按钮]是否显示(只适用于驾车导航,需要联网)。
+// options.setTrafficLayerEnabled( false );
+ // 设置导航界面是否显示路线全览按钮。
+// options.setRouteListButtonShow( false );
+ // 设置导航状态下屏幕是否一直开启。
+// options.setScreenAlwaysBright( true );
+ // 设置交通播报是否打开(只适用于驾车导航,需要联网)。
+// options.setTrafficInfoUpdateEnabled( true );
+ // 设置摄像头播报是否打开(只适用于驾车导航)。
+// options.setCameraInfoUpdateEnabled( true );
+ // 设置菜单按钮是否在导航界面显示。
+// options.setSettingMenuEnabled( false );
+ // 设置是否绘制显示交通路况的线路(彩虹线),拥堵-红色,畅通-绿色,缓慢-黄色,未知-蓝色。默认不绘制彩虹线。
+// options.setTrafficLine( true );
+ // 设置是否绘制牵引线(当前位置到目的地的指引线)。默认不绘制牵引线。
+// options.setLeaderLineEnabled( -1 );
+ // 设置导航界面UI是否显示。
+// options.setLayoutVisible( false );
+ // 设置是否自动画路
+// options.setAutoDrawRoute( false );
+ // 设置是否显示路口放大图(实景图)
+// options.setRealCrossDisplayShow( false );
+ // 设置是否显示路口放大图(路口模型图)
+// options.setModeCrossDisplayShow( false );
+ // 设置是否显示道路信息view
+// options.setLaneInfoShow( false );
+ // 设置是否自动改变缩放等级
+// options.setAutoChangeZoom( false );
+ // 设置是否自动全览模式,即在算路成功后自动进入全览模式
+// options.setAutoDisplayOverview( false );
+ // 设置路线转向箭头隐藏和显示
+// options.setNaviArrowVisible( false );
+ // 通过路线是否自动置灰,仅支持驾车导航
+// options.setAfterRouteAutoGray( true );
+ options.setZoom(((int) mDefaultZoomLevel));
+// options.setPointToCenter( 0.5D, 0.5D );
+ // 2D模式
+ options.setMapViewPerspective(MapParams.MAP_PERSPECTIVE_2D);
+// mMapView.setViewOptions( options );
+ }
+// mMapView.setRouteOverlayVisible( false );
+// mMapView.setCarOverlayVisible( false );
+ setUIMode(EnumMapUI.CarUp_2D);
+ }
+
+ private void initListeners() {
+
+ mMapView.setOnMarkClickListener(this);
+ mMarkerClickHandler = new AMapMarkerClickHandler();
+ mMapView.setOnMapLoadedListener(this);
+ mMapView.setOnMapTouchListener(this);
+ mMapView.setOnMapClickListener(this);
+ mMapView.getLocationClient().registerListener(this);
+
+// mMapView.setOnPolylineClickListener( this );
+// mMapView.setAMapNaviViewListener( this );
+// mMapView.setOnCameraChangeListener( this );
+//
+// final AMap aMap = mMapView.getMap();
+// if ( aMap != null ) {
+// aMap.setOnPOIClickListener( this );
+// aMap.setOnMapClickListener( this );
+// aMap.setOnCameraChangeListener( this );
+// aMap.setOnMyLocationChangeListener( this );
+// }
+// AMapMessageManager.getInstance().registerAMapMessageListener( this );
+ }
+
+ private Context getContext() {
+ return mMapView.getContext();
+ }
+
+ @Override
+ public View getMapView() {
+ return mMapView;
+ }
+
+ @Override
+ public IMogoMap getMap() {
+ return mIMap;
+ }
+
+ @Override
+ public void onCreate(Bundle bundle) {
+ if (mMapView != null) {
+ mMapView.onCreate(bundle);
+ Logger.d(TAG, "map onCreate");
+// initMapView();
+ initListeners();
+// initMyLocation();
+ }
+ }
+
+ @Override
+ public void onResume() {
+ if (mMapView != null) {
+ mMapView.onResume();
+ Logger.d(TAG, "map onResume");
+ }
+ }
+
+ @Override
+ public void onPause() {
+ if (mMapView != null) {
+ mMapView.onPause();
+ Logger.d(TAG, "map onPause");
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ if (mMapView != null) {
+ mMapView.onDestroy();
+ Logger.d(TAG, "map onDestroy");
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ if (mMapView != null) {
+ mMapView.onSaveInstanceState(outState);
+ Logger.d(TAG, "map onSaveInstanceState");
+ }
+ }
+
+ @Override
+ public void onLowMemory() {
+
+ }
+
+
+ /**
+ * 地图marker点击
+ */
+// @Override
+// public boolean onMarkerClick( Marker marker ) {
+// return mMarkerClickHandler.handleMarkerClicked( marker );
+// }
+//
+// /**
+// * POI 点击
+// */
+// @Override
+// public void onPOIClick( Poi poi ) {
+// if ( InterceptorHandler.getInstance().ignorePoiClicked( getContext() ) ) {
+// return;
+// }
+// MogoMapListenerHandler.getInstance().onPOIClick( ObjectUtils.fromAMap( poi ) );
+// }
+//
+// @Override
+// public void onMapClick( LatLng latLng ) {
+// if ( InterceptorHandler.getInstance().ignoreMapClicked( getContext() ) ) {
+// return;
+// }
+// MogoMapListenerHandler.getInstance().onMapClick( ObjectUtils.fromAMap( latLng ) );
+// }
+//
+// @Override
+// public void onPolylineClick( Polyline polyline ) {
+// if ( !NaviClient.getInstance( getContext() ).isNaviing() ) {
+// NaviClient.getInstance( getContext() ).handleClickedPolyline( polyline );
+// }
+// }
+//
+ @Override
+ public void setTrafficEnabled(boolean visible) {
+ if (checkAMapView()) {
+// mMapView.setTrafficLine( visible );
+ }
+ }
+
+ @Override
+ public MapControlResult changeZoom(boolean zoom) {
+ if (checkAMapView()) {
+ mDefaultZoomLevel = (int) (getMap().getZoomLevel() + 0.5f);
+
+ if (zoom) {
+ if (mDefaultZoomLevel >= 7) {
+ return MapControlResult.TARGET;
+ }
+ } else {
+ if (mDefaultZoomLevel <= 0) {
+ return MapControlResult.TARGET;
+ }
+ }
+
+ if (zoom) {
+ mDefaultZoomLevel += 1f;
+ if (mDefaultZoomLevel > 7) {
+ mDefaultZoomLevel = 7;
+ }
+ } else {
+ mDefaultZoomLevel -= 1f;
+ if (mDefaultZoomLevel < 0) {
+ mDefaultZoomLevel = 0;
+ }
+ }
+ changeZoom((int) mDefaultZoomLevel);
+ }
+ return MapControlResult.SUCCESS;
+ }
+
+ @Override
+ public MapControlResult changeZoom(float zoom) {
+ Logger.d(TAG, "changeZoom %s", zoom);
+ if (DebugConfig.isDebug()) {
+ Logger.d(TAG, Log.getStackTraceString(new Throwable()));
+ }
+
+ getMap().changeZoom(zoom);
+ return MapControlResult.SUCCESS;
+ }
+
+ @Override
+ public void changeMapMode(EnumMapUI ui) {
+ if (ui == null) {
+ return;
+ }
+ if ( checkAMapView() ) {
+ switch ( ui ) {
+ case CarUp_2D:
+ case CarUp_3D:
+ case NorthUP_2D:
+ //setUIMode( ui, options );
+ return;
+ case Type_Light:
+ mMapView.getMapAutoViewHelper().setAutoSwitchStyle( false );
+ mMapView.getMapAutoViewHelper().setMapStyle(MapHelper.INSTANCE.getMMapParams().MAP_STYLE_DAY);
+ break;
+ case Type_Night:
+ mMapView.getMapAutoViewHelper().setAutoSwitchStyle( false );
+ mMapView.getMapAutoViewHelper().setMapStyle(MapHelper.INSTANCE.getMMapParams().MAP_STYLE_NIGHT);
+ break;
+ case Type_AUTO_LIGHT_Night:
+ mMapView.getMapAutoViewHelper().setAutoSwitchStyle( true );
+ break;
+ }
+
+ }
+ }
+
+ @Override
+ public void moveToCenter(MogoLatLng latLng) {
+
+ }
+
+ private void setUIMode(EnumMapUI ui) {
+ this.mCurrentUIMode = ui;
+ switch (ui) {
+ case CarUp_2D:
+ mMapView.getMapAutoViewHelper().setMapViewPerspective(MapParams.MAP_PERSPECTIVE_2D);
+ break;
+ case CarUp_3D:
+ mMapView.getMapAutoViewHelper().setMapViewPerspective(MapParams.MAP_PERSPECTIVE_3D);
+ break;
+ case NorthUP_2D:
+ mMapView.getMapAutoViewHelper().setRotateGesturesEnabled(false);
+ break;
+ }
+ }
+
+ private boolean checkAMapView() {
+ if (mMapView == null || mMapView.getMapAutoViewHelper() == null) {
+ Logger.e(TAG, "高德mapView实例为空,请检查");
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void moveToCenter(MogoLatLng latLng, boolean animate) {
+ Logger.d(TAG, "move to center %s", latLng);
+ if (latLng == null || latLng.lat == 0.0d || latLng.lng == 0.0d) {
+ Logger.e(TAG, "latlng = null or is illegal");
+ return;
+ }
+ if (DebugConfig.isDebug()) {
+ Logger.d(TAG, Log.getStackTraceString(new Throwable()));
+ }
+ loseLockMode();
+ mMapView.getMapAutoViewHelper().animateCamera(new LonLatPoint(latLng.lon, latLng.lat));
+ }
+
+ @Override
+ public void showMyLocation(boolean visible) {
+ Logger.d(TAG, "showMyLocation1 %s", visible);
+ if (visible && NaviClient.getInstance(getContext()).isNaviing()) {
+ return;
+ }
+// if (DebugConfig.isDebug()) {
+// Logger.d(TAG, Log.getStackTraceString(new Throwable()));
+// }
+ if (checkAMapView()) {
+ MyLocationStyle style = mMapView.getMapAutoViewHelper().getMyLocationStyle();
+ if (visible) {
+ // 强制刷新一遍车标
+ style.myLocationIcon(mCarCursorOption.getCarCursorRes());
+ }
+ mMapView.getMapAutoViewHelper().setMyLocationStyle(style);
+ }
+ }
+
+ @Override
+ public void showMyLocation(View view) {
+ if ( NaviClient.getInstance( getContext() ).isNaviing() ) {
+ return;
+ }
+ if ( DebugConfig.isDebug() ) {
+ Logger.d( TAG, Log.getStackTraceString( new Throwable() ) );
+ }
+ if ( checkAMapView() ) {
+ MyLocationStyle style = mMapView.getMapAutoViewHelper().getMyLocationStyle();
+// style.myLocationIcon( BitmapDescriptorFactory.fromView( view ) );
+ mMapView.getMapAutoViewHelper().setMyLocationStyle( style );
+ }
+ }
+
+ public void initMyLocation() {
+ if (checkAMapView()) {
+ mMapView.getMapAutoViewHelper().setMyLocationEnabled(true);
+ MyLocationStyle style = mMapView.getMapAutoViewHelper().getMyLocationStyle();
+ style.setLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW_NO_CENTER);
+ style.interval(1000);
+// style.anchor( 0.5F, 0.5F );
+// style.strokeColor( Color.TRANSPARENT );
+// style.strokeWidth( 0 );
+// style.radiusFillColor( Color.TRANSPARENT );
+ mMapView.getMapAutoViewHelper().setMyLocationStyle(style);
+ }
+ }
+
+ @Override
+ public void recoverLockMode() {
+ if (checkAMapView()) {
+// if ( DebugConfig.isDebug() ) {
+// Logger.d( TAG, Log.getStackTraceString( new Throwable() ) );
+// }
+ Logger.d(TAG, "锁车");
+// mMapView.recoverLockMode();
+ mIsCarLocked = true;
+ }
+ }
+
+ @Override
+ public void loseLockMode() {
+ if (DebugConfig.isDebug()) {
+ Logger.d(TAG, Log.getStackTraceString(new Throwable()));
+ }
+ Logger.d(TAG, "解锁锁车");
+ mockTouchEvent();
+ mIsCarLocked = false;
+ }
+
+ @Override
+ public void setLockZoom(int var1) {
+
+ }
+
+ @Override
+ public void displayOverview(Rect bounds) {
+
+ }
+
+ /**
+ * 模拟点击事件,达到锁车->普通事件
+ */
+ private void mockTouchEvent() {
+ long downTime = SystemClock.uptimeMillis();
+ long eventTime = downTime + 1;
+ int metaState = 0;
+ MotionEvent motionEvent = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, 0, 0, metaState);
+ mMapView.dispatchTouchEvent(motionEvent);
+ MotionEvent upEvent = MotionEvent.obtain(downTime + 1, eventTime + 2, MotionEvent.ACTION_UP, 0, 0, metaState);
+ mMapView.dispatchTouchEvent(upEvent);
+ }
+
+
+ @Override
+ public float getScalePerPixel() {
+ return getMap().getScalePerPixel();
+ }
+
+ @Override
+ public float getZoomLevel() {
+ return getMap().getZoomLevel();
+ }
+
+ @Override
+ public MogoLatLng getCameraNorthEastPosition() {
+ return null;
+ }
+
+
+ @Override
+ public MogoLatLng getCameraSouthWestPosition() {
+// try {
+// return ObjectUtils.fromAMap( mMapView.getMapAutoViewHelper().getProjection().getVisibleRegion().latLngBounds.southwest );
+// } catch ( Exception e ) {
+//
+// }
+ return null;
+ }
+
+ @Override
+ public MogoLatLng getWindowCenterLocation() {
+ try {
+ return ObjectUtils.fromAMap(mMapView.getMapAutoViewHelper().getCenter());
+ } catch (Exception e) {
+
+ }
+ return null;
+ }
+
+ @Override
+ public void setPointToCenter(double mapCenterX, double mapCenterY) {
+ if (checkAMapView()) {
+// if (DebugConfig.isDebug()) {
+// Logger.d(TAG, Log.getStackTraceString(new Throwable()));
+// }
+ Logger.d(TAG, "setPointToCenter(%s, %s)", mapCenterX, mapCenterY);
+ mMapView.getMapAutoViewHelper().setPointToCenter((float) mapCenterX, (float) mapCenterY);
+ }
+ }
+
+ @Override
+ public Point getLocationPointInScreen(MogoLatLng latLng) {
+ if (checkAMapView()) {
+ try {
+ return MapTools.INSTANCE.toScreenLocation(ObjectUtils.fromMogo(latLng));
+ } catch (Exception e) {
+ return null;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public MogoLatLng getLocationMogoLatLngInScreen(Point point) {
+ if (checkAMapView()) {
+ try {
+ return ObjectUtils.fromAMap(
+ MapTools.INSTANCE.fromScreenLocation(point));
+ } catch (Exception e) {
+ return null;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void startJumpAnimation(IMogoMarker marker, float high, Interpolator interpolator,
+ long duration) {
+ if (marker == null || high <= 0.0f || interpolator == null || duration < 0) {
+ return;
+ }
+ try {
+// final LatLng latLng = ObjectUtils.fromMogo2( marker.getPosition() );
+// Point point = mMapView.getMap().getProjection().toScreenLocation( latLng );
+// point.y -= WindowUtils.dip2px( getContext(), high );
+// LatLng target = mMapView.getMap().getProjection().fromScreenLocation( point );
+// //使用TranslateAnimation,填写一个需要移动的目标点
+// Animation animation = new TranslateAnimation( target );
+// animation.setInterpolator( interpolator );
+// //整个移动所需要的时间
+// animation.setDuration( duration );
+// //设置动画
+// if ( marker instanceof AMapMarkerWrapper ) {
+// ( ( AMapMarkerWrapper ) marker ).getMarker().setAnimation( animation );
+// ( ( AMapMarkerWrapper ) marker ).getMarker().startAnimation();
+// }
+ } catch (Exception e) {
+ Logger.e(TAG, e, "error.");
+ }
+ }
+
+ @Override
+ public void setRenderFps(int fps) {
+ if (checkAMapView()) {
+ if (mMapView.getMapAutoViewHelper() != null) {
+// mMapView.getMapAutoViewHelper().setRenderFps( fps );
+ Logger.d(TAG, "设置刷新帧率 fps = %s", fps);
+ }
+ }
+ }
+
+ @Override
+ public void showBounds(String tag, MogoLatLng carPosition, List
+ * 代理高德AMap
+ */
+public class AMapWrapper implements IMogoMap {
+
+ private static final String TAG = "AMapWrapper";
+
+ private static MapAutoViewHelper sAMap;
+ private IMogoMapUIController mUIcontroller;
+ private MapAutoViewHelper mAMap;
+ private MapAutoView mMapView;
+ private IMogoUiSettings mUiSettings;
+
+ public AMapWrapper(MapAutoViewHelper map, MapAutoView mapView, IMogoMapUIController controller) {
+ Log.i(TAG, "autoop--AMapWrapper: init"+this);
+ this.mAMap = map;
+ sAMap = map;
+ this.mMapView = mapView;
+ mUIcontroller = controller;
+ // 设置实现自定义 info window
+ MapAutoApi.INSTANCE.setInfoWindowAdapter( new AMapInfoWindowAdapter() );
+ AMapUIController.getInstance().initClient(mUIcontroller);
+ }
+
+ public static MapAutoViewHelper getAMap() {
+ return sAMap;
+ }
+
+ @Override
+ public IMogoUiSettings getUiSettings() {
+ if (!checkAMap()) {
+ return null;
+ }
+ if (mUiSettings == null) {
+ mUiSettings = new AMapUiSettingsWrapper(mAMap);
+ }
+ return mUiSettings;
+ }
+
+ @Override
+ public IMogoMapUIController getUIController() {
+ return mUIcontroller;
+ }
+
+ @Override
+ public IMogoMarker addMarker(String tag, MogoMarkerOptions options) {
+ Log.i(TAG, "autoop-addMarker: " + tag + ",options:" + options + ",AMap:" + (mAMap != null)+",this:"+this);
+ if (!checkAMap()) {
+ return null;
+ }
+ Log.i(TAG, "autoop-addMarker: AMap is not null");
+ MarkerOptions markerOptions = ObjectUtils.fromMogo(options);
+ if (markerOptions == null) {
+ Logger.e(TAG, "marker参数为空");
+ return null;
+ }
+ final IMogoMarker mogoMarker = new AMapMarkerWrapper(mAMap.addMarker(markerOptions), options);
+ if (options.isAutoManager()) {
+ MogoMarkersHandler.getInstance().add(tag, mogoMarker);
+ }
+ return mogoMarker;
+ }
+
+ @Override
+ public ArrayList
+ * 操作拦截器
+ */
+public interface IInterceptor {
+
+ /**
+ * 是否忽略添加多个marker时聚拢参数
+ *
+ * 导航时:不需要聚拢
+ *
+ * @return true - 忽略 false - 不忽略
+ */
+ boolean ignoreAddMarkersMoveToCenterParameters( Context context );
+
+ /**
+ * 导航时,是否响应 poi 点击
+ *
+ * @param context
+ * @return
+ */
+ boolean ignorePoiClicked( Context context );
+
+ /**
+ * 导航时,是否响应地图点击
+ *
+ * @param context
+ * @return
+ */
+ boolean ignoreMapClicked( Context context );
+
+ /**
+ * 请求绘制路线
+ *
+ * @param context
+ * @return
+ */
+ boolean ignoreDrawRouteOverlay( Context context );
+}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/InterceptorHandler.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/InterceptorHandler.java
new file mode 100644
index 0000000000..91f18a2c69
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/InterceptorHandler.java
@@ -0,0 +1,59 @@
+package com.mogo.map.impl.custom;
+
+import android.content.Context;
+
+
+/**
+ * @author congtaowang
+ * @since 2019-12-27
+ *
+ * 操作拦截器
+ */
+public class InterceptorHandler implements IInterceptor {
+
+ private static volatile InterceptorHandler sInstance;
+
+ private Context mContext;
+
+ private InterceptorHandler() {
+ }
+
+ public static InterceptorHandler getInstance() {
+ if ( sInstance == null ) {
+ synchronized ( InterceptorHandler.class ) {
+ if ( sInstance == null ) {
+ sInstance = new InterceptorHandler();
+ }
+ }
+ }
+ return sInstance;
+ }
+
+ public synchronized void release() {
+ sInstance = null;
+ }
+
+ public void init( Context context ) {
+ mContext = context;
+ }
+
+ @Override
+ public boolean ignoreAddMarkersMoveToCenterParameters( Context context ) {
+ return false;//NaviClient.getInstance( context ).isNaviing();
+ }
+
+ @Override
+ public boolean ignorePoiClicked( Context context ) {
+ return false;//NaviClient.getInstance( context ).isNaviing();
+ }
+
+ @Override
+ public boolean ignoreMapClicked( Context context ) {
+ return false;//NaviClient.getInstance( context ).isNaviing();
+ }
+
+ @Override
+ public boolean ignoreDrawRouteOverlay( Context context ) {
+ return false;//NaviClient.getInstance( context ).isNaviing();
+ }
+}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/hook/BnHooker.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/hook/BnHooker.java
new file mode 100644
index 0000000000..ef1c5f49af
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/hook/BnHooker.java
@@ -0,0 +1,60 @@
+package com.mogo.map.impl.custom.hook;
+
+import android.content.Context;
+
+import com.zhidaoauto.map.sdk.open.view.MapAutoViewHelper;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+/**
+ * @author congtaowang
+ * @since 2020-03-12
+ *
+ * 描述
+ */
+public class BnHooker implements InvocationHandler {
+
+ private static final String TAG = "BnHooker";
+ private final Context mContext;
+
+ private Object host;
+
+ public BnHooker(MapAutoViewHelper map, Context context ) throws Exception {
+
+ mContext = context;
+
+ if ( map == null ) {
+ return;
+ }
+// Field field = AMap.class.getDeclaredField( "a" );
+// field.setAccessible( true );
+// host = field.get( map );
+// Object object = Proxy.newProxyInstance(
+// BnHooker.class.getClassLoader(),
+// new Class[]{
+// com.amap.api.col.n3.ft.a.class,
+// IAMapDelegate.class,
+// IAMapListener.class,
+// IAMap.class
+// },
+// this
+// );
+// field.set( map, object );
+ }
+
+ @Override
+ public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable {
+// if ( method.getName().equals( "setRenderFps" ) ) {
+// Logger.d( TAG, "setRenderFps" );
+// if ( !NaviClient.getInstance( mContext ).isNaviing() ) {
+// }
+// return method.invoke( host, 10 );
+// }
+// if ( method.getName().equals( "drawFrame" ) ) {
+// Logger.d( TAG, "drawFrame" );
+// }
+// return method.invoke( host, args );
+ return null;
+ }
+}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/location/ALocationClient.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/location/ALocationClient.java
new file mode 100644
index 0000000000..8629d4a5ba
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/location/ALocationClient.java
@@ -0,0 +1,159 @@
+package com.mogo.map.impl.custom.location;
+
+import android.content.Context;
+import android.os.Trace;
+
+import com.mogo.map.impl.custom.utils.ObjectUtils;
+import com.mogo.map.location.IMogoLocationClient;
+import com.mogo.map.location.IMogoLocationListener;
+import com.mogo.map.location.MogoLocation;
+import com.mogo.utils.logger.Logger;
+import com.zhidaoauto.map.sdk.open.location.Location;
+import com.zhidaoauto.map.sdk.open.location.LocationClient;
+import com.zhidaoauto.map.sdk.open.location.LocationListener;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * @author congtaowang
+ * @since 2019-12-19
+ *
+ * 高德定位
+ */
+public class ALocationClient implements IMogoLocationClient {
+
+ private static final String TAG = "LocationClient";
+
+ private Set< IMogoLocationListener > sListeners = new HashSet<>( 10 );
+ private MogoLocation mLastLocation;
+ private LocationListener mListener = new InternalLocationListener();
+
+ private boolean mIsDestroyed = false;
+
+ public ALocationClient( Context context ) {
+ mClient = new LocationClient( context );
+ mClient.registerListener( mListener );
+ mLastLocation = ObjectUtils.fromLocation( mClient.getLastKnownLocation() );
+ if ( mLastLocation == null ) {
+ mLastLocation = new MogoLocation();
+ }
+ }
+
+ private LocationClient mClient;
+
+ @Override
+ public void start() {
+ start( 2_000L );
+ }
+
+ @Override
+ public void start( long interval ) {
+ if ( mIsDestroyed ) {
+ destroyWarming();
+ return;
+ }
+ if ( mClient != null ) {
+// AMapLocationClientOption option = new AMapLocationClientOption();
+// option.setLocationMode( AMapLocationClientOption.AMapLocationMode.Hight_Accuracy );
+// option.setNeedAddress( true );
+// option.setGpsFirst( true );
+// option.setInterval( interval );
+// mClient.setLocationOption( option );
+ mClient.start();
+ }
+ }
+
+ @Override
+ public void stop() {
+ if ( mIsDestroyed ) {
+ destroyWarming();
+ return;
+ }
+ if ( mClient != null && mClient.isStarted() ) {
+ mClient.stop();
+ }
+ }
+
+ @Override
+ public void addLocationListener( IMogoLocationListener listener ) {
+ if ( mIsDestroyed ) {
+ destroyWarming();
+ return;
+ }
+ if ( listener != null ) {
+ synchronized ( sListeners ) {
+ sListeners.add( listener );
+ }
+ }
+ }
+
+ @Override
+ public void removeLocationListener( IMogoLocationListener listener ) {
+ if ( mIsDestroyed ) {
+ destroyWarming();
+ return;
+ }
+ if ( listener != null ) {
+ synchronized ( sListeners ) {
+ sListeners.remove( listener );
+ }
+ }
+ }
+
+ @Override
+ public MogoLocation getLastKnowLocation() {
+ if ( mIsDestroyed ) {
+ destroyWarming();
+ return null;
+ }
+ return mLastLocation;
+ }
+
+ @Override
+ public synchronized void destroy() {
+ mIsDestroyed = true;
+ if ( sListeners != null ) {
+ sListeners.clear();
+ }
+ sListeners = null;
+ if ( mClient != null ) {
+ mClient.unRegisterListener( mListener );
+ mClient.stop();
+ }
+ mClient = null;
+ mLastLocation = null;
+ }
+
+ private class InternalLocationListener implements LocationListener {
+
+ @Override
+ public void onLocationChanged(@NotNull Location location) {
+ if ( mIsDestroyed ) {
+ destroyWarming();
+ return;
+ }
+ if ( location == null ||
+ location.getLat() == 0.0D ||
+ location.getLon() == 0.0D ) {
+ return;
+ }
+ Trace.beginSection("timer.onLocationChanged");
+ mLastLocation = ObjectUtils.fromLocation( location );
+ synchronized ( sListeners ) {
+ Iterator< IMogoLocationListener > listenerIterator = sListeners.iterator();
+ while ( listenerIterator.hasNext() ) {
+ listenerIterator.next().onLocationChanged( mLastLocation.clone() );
+ }
+ }
+ Trace.endSection();
+ }
+ }
+
+ private void destroyWarming() {
+ Logger.w( TAG, "location client has destroyed." );
+ }
+}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/marker/AMapInfoWindowAdapter.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/marker/AMapInfoWindowAdapter.java
new file mode 100644
index 0000000000..1e06b9ddbb
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/marker/AMapInfoWindowAdapter.java
@@ -0,0 +1,36 @@
+package com.mogo.map.impl.custom.marker;
+
+import android.view.View;
+
+import com.mogo.map.marker.IMogoInfoWindowAdapter;
+import com.mogo.map.marker.IMogoMarker;
+import com.zhidaoauto.map.sdk.open.abs.marker.InfoWindowAdapter;
+import com.zhidaoauto.map.sdk.open.marker.Marker;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author congtaowang
+ * @since 2019-12-24
+ *
+ * 自定义infowindow
+ */
+public final class AMapInfoWindowAdapter implements InfoWindowAdapter {
+
+ public View getInfoWindow( Marker marker ) {
+ if ( marker.getMObject() instanceof IMogoMarker ) {
+ IMogoMarker mogoMarker = ( ( IMogoMarker ) marker.getMObject() );
+ IMogoInfoWindowAdapter delegate = mogoMarker.getInfoWindowAdapter();
+ if ( delegate != null ) {
+ return delegate.getInfoWindow( mogoMarker );
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public View getInfoContents(@Nullable Marker marker) {
+ return null;
+ }
+}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/marker/AMapMarkerWrapper.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/marker/AMapMarkerWrapper.java
new file mode 100644
index 0000000000..51447adeed
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/marker/AMapMarkerWrapper.java
@@ -0,0 +1,469 @@
+package com.mogo.map.impl.custom.marker;
+
+import android.graphics.Bitmap;
+import android.graphics.Point;
+import android.view.View;
+import android.view.animation.Interpolator;
+
+import com.mogo.map.MogoLatLng;
+import com.mogo.map.impl.custom.utils.ObjectUtils;
+import com.mogo.map.marker.IMogoInfoWindowAdapter;
+import com.mogo.map.marker.IMogoMarker;
+import com.mogo.map.marker.IMogoMarkerClickListener;
+import com.mogo.map.marker.IMogoMarkerIconViewCreator;
+import com.mogo.map.marker.MogoMarkerOptions;
+import com.mogo.map.marker.anim.OnMarkerAnimationListener;
+import com.mogo.utils.logger.Logger;
+import com.zhidaoauto.map.sdk.open.marker.Marker;
+import com.zhidaoauto.map.sdk.open.marker.MarkerInfo;
+import com.zhidaoauto.map.sdk.open.marker.MarkerOptions;
+import com.zhidaoauto.map.sdk.open.query.LonLatPoint;
+import com.zhidaoauto.map.sdk.open.tools.MapTools;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Observable;
+import java.util.Observer;
+
+/**
+ * @author congtaowang
+ * @since 2019-12-18
+ *
+ * 高德marker
+ */
+public class AMapMarkerWrapper implements IMogoMarker, Observer {
+
+ private final String TAG = AMapMarkerWrapper.class.getName();
+
+ private Marker mMarker;
+ private Object mObject;
+ private IMogoMarkerClickListener mMogoMarkerClickListener;
+ private IMogoInfoWindowAdapter mMogoInfoWindowAdapter;
+
+ private boolean mIsDestroy = false;
+
+ private MogoMarkerOptions mMogoMarkerOptions;
+ private String mOwner;
+
+
+ public AMapMarkerWrapper(Marker marker, MogoMarkerOptions mogoMarkerOptions) {
+ this.mMarker = marker;
+ if (marker != null) {
+ // 设置高德 marker 的object对象为 IMogoMarker 实例。!!!!
+ marker.setMObject(this);
+ }
+ setObject(mogoMarkerOptions.getObject());
+ this.mMogoMarkerOptions = mogoMarkerOptions;
+ mMogoMarkerOptions.addObserver(this);
+ }
+
+ @Override
+ public void update(Observable o, Object arg) {
+ if (isDestroyed()) {
+ return;
+ }
+ setMarkerOptions(mMogoMarkerOptions);
+ }
+
+ @Override
+ public void destroy() {
+ if (mMogoMarkerOptions != null) {
+ mMogoMarkerOptions.deleteObservers();
+ mMogoMarkerOptions = null;
+ }
+ if (mMarker != null) {
+ mMarker.remove();
+ mMarker.setMObject(null);
+ mMarker = null;
+ }
+ mMogoInfoWindowAdapter = null;
+ mMogoMarkerClickListener = null;
+ mObject = null;
+ mIsDestroy = true;
+ }
+
+ @Override
+ public void remove() {
+ destroy();
+ }
+
+ @Override
+ public void hideInfoWindow() {
+ if (mMarker != null) {
+ mMarker.hideInfoWindow();
+ }
+ }
+
+ @Override
+ public void setAlpha(float alpha) {
+ if (mMarker != null) {
+ mMarker.setAlpha(alpha);
+ }
+ }
+
+ @Override
+ public void setAnchor(float anchorU, float anchorV) {
+ if (mMarker != null) {
+ mMarker.setAnchor(anchorU, anchorV);
+ }
+ }
+
+ @Override
+ public void setDraggable(boolean paramBoolean) {
+ if ( mMarker != null ) {
+ mMarker.setDraggable( paramBoolean );
+ }
+ }
+
+ @Override
+ public void setIcon(Bitmap icon) {
+ if (icon == null || icon.isRecycled()) {
+ return;
+ }
+ if (mMarker != null) {
+ mMarker.setIcon(icon);
+ }
+ }
+
+ @Override
+ public void setIcons(ArrayList
+ * 描述
+ */
+public class AMapMessageConsts {
+
+ /**
+ * 导航开始
+ */
+ public static final int MSG_NAVI_START = 1000;
+ /**
+ * 取消导航
+ */
+ public static final int MSG_NAVI_STOP = 1001;
+ /**
+ * 规划路线成功
+ */
+ public static final int MSG_CALCULATE_SUCCESS = 1002;
+
+}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/message/AMapMessageListener.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/message/AMapMessageListener.java
new file mode 100644
index 0000000000..84b5b9138f
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/message/AMapMessageListener.java
@@ -0,0 +1,21 @@
+package com.mogo.map.impl.custom.message;
+
+
+import com.autonavi.nge.guidance.NaviInfo;
+
+/**
+ * @author congtaowang
+ * @since 2019-12-28
+ *
+ * 消息回调
+ */
+public interface AMapMessageListener {
+
+ void onNaviStarted();
+
+ void onNaviStopped();
+
+ void onNaviInfoUpdat( NaviInfo naviInfo );
+
+ void onCalculateSuccess();
+}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/message/AMapMessageManager.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/message/AMapMessageManager.java
new file mode 100644
index 0000000000..ca953605f3
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/message/AMapMessageManager.java
@@ -0,0 +1,133 @@
+package com.mogo.map.impl.custom.message;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+
+import androidx.annotation.NonNull;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author congtaowang
+ * @since 2019-12-28
+ *
+ * 描述
+ */
+public class AMapMessageManager {
+
+ private static volatile AMapMessageManager sInstance;
+
+ private List< AMapMessageListener > mListeners = new ArrayList<>();
+
+ private AMapMessageManager() {
+ }
+
+ public static AMapMessageManager getInstance() {
+ if ( sInstance == null ) {
+ synchronized ( AMapMessageManager.class ) {
+ if ( sInstance == null ) {
+ sInstance = new AMapMessageManager();
+ }
+ }
+ }
+ return sInstance;
+ }
+
+ public synchronized void release() {
+ sInstance = null;
+ }
+
+ public synchronized void registerAMapMessageListener( AMapMessageListener listener ) {
+ if ( !mListeners.contains( listener ) ) {
+ mListeners.add( listener );
+ }
+ }
+
+ public synchronized void unregisterAMapMessageListener( AMapMessageListener listener ) {
+ mListeners.remove( listener );
+ }
+
+ private Handler mHandler = new Handler( Looper.getMainLooper() ) {
+ @Override
+ public void handleMessage( @NonNull Message msg ) {
+ super.handleMessage( msg );
+ AMapMessageManager.this.handleMessage( msg );
+ }
+ };
+
+ public void sendMessage( Message msg ) {
+ if ( msg != null ) {
+ mHandler.sendMessage( msg );
+ }
+ }
+
+ public void sendMessage( int what ) {
+ sendMessage( what, null );
+ }
+
+ public void sendMessage( int what, Object obj ) {
+ Message msg = Message.obtain();
+ msg.what = what;
+ msg.obj = obj;
+ sendMessage( msg );
+ }
+
+ public void postNaviStarted() {
+ sendMessage( AMapMessageConsts.MSG_NAVI_START );
+ }
+
+ public void postNaviStopped() {
+ sendMessage( AMapMessageConsts.MSG_NAVI_STOP );
+ }
+
+ public void postCalculateSuccess() {
+ sendMessage( AMapMessageConsts.MSG_CALCULATE_SUCCESS );
+ }
+
+ private synchronized void handleMessage( Message msg ) {
+ if ( msg == null ) {
+ return;
+ }
+ switch ( msg.what ) {
+ case AMapMessageConsts.MSG_NAVI_START:
+ handleNaviStartedMsg();
+ break;
+ case AMapMessageConsts.MSG_NAVI_STOP:
+ handleNaviStoppedMsg();
+ break;
+ case AMapMessageConsts.MSG_CALCULATE_SUCCESS:
+ handleCalculateSuccessMsg();
+ break;
+ }
+ }
+
+ private void handleNaviStartedMsg() {
+ if ( mListeners == null ) {
+ return;
+ }
+ for ( AMapMessageListener listener : mListeners ) {
+ listener.onNaviStarted();
+ }
+ }
+
+ private void handleNaviStoppedMsg() {
+ if ( mListeners == null ) {
+ return;
+ }
+ for ( AMapMessageListener listener : mListeners ) {
+ listener.onNaviStopped();
+ }
+ }
+
+ private void handleCalculateSuccessMsg() {
+ if ( mListeners == null ) {
+ return;
+ }
+ for ( AMapMessageListener listener : mListeners ) {
+ listener.onCalculateSuccess();
+ }
+ }
+}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/AMapNaviListenerAdapter.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/AMapNaviListenerAdapter.java
new file mode 100644
index 0000000000..94abd014d0
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/AMapNaviListenerAdapter.java
@@ -0,0 +1,237 @@
+//package com.mogo.map.impl.custom.navi;
+//
+//import com.amap.api.navi.AMapNaviListener;
+//import com.amap.api.navi.model.AMapCalcRouteResult;
+//import com.amap.api.navi.model.AMapLaneInfo;
+//import com.amap.api.navi.model.AMapModelCross;
+//import com.amap.api.navi.model.AMapNaviCameraInfo;
+//import com.amap.api.navi.model.AMapNaviCross;
+//import com.amap.api.navi.model.AMapNaviInfo;
+//import com.amap.api.navi.model.AMapNaviLocation;
+//import com.amap.api.navi.model.AMapNaviRouteNotifyData;
+//import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo;
+//import com.amap.api.navi.model.AMapServiceAreaInfo;
+//import com.amap.api.navi.model.AimLessModeCongestionInfo;
+//import com.amap.api.navi.model.AimLessModeStat;
+//import com.amap.api.navi.model.NaviInfo;
+//import com.autonavi.tbt.TrafficFacilityInfo;
+//import com.mogo.utils.logger.Logger;
+//
+///**
+// * @author congtaowang
+// * @since 2019-12-25
+// *
+// * 高德导航事件:导航事件
+// */
+//public abstract class AMapNaviListenerAdapter implements AMapNaviListener {
+//
+// private static final String TAG = "AMapNaviListenerAdapter";
+// protected String mLastSpeakWord;
+//
+// @Override
+// public void onInitNaviFailure() {
+//
+// }
+//
+// @Override
+// public void onInitNaviSuccess() {
+//
+// }
+//
+// @Override
+// public void onStartNavi( int i ) {
+//
+// }
+//
+// @Override
+// public void onTrafficStatusUpdate() {
+//
+// }
+//
+// @Override
+// public void onLocationChange( AMapNaviLocation aMapNaviLocation ) {
+//
+// }
+//
+// @Override
+// public void onGetNavigationText( int i, String s ) {
+//
+// }
+//
+// @Override
+// public void onGetNavigationText( String s ) {
+// mLastSpeakWord = s;
+// Logger.d( TAG, s );
+// TTSSpeaker.getInstance().speakTTS( s );
+// }
+//
+// @Override
+// public void onEndEmulatorNavi() {
+//
+// }
+//
+// @Override
+// public void onArriveDestination() {
+//
+// }
+//
+// @Override
+// public void onCalculateRouteFailure( int i ) {
+//
+// }
+//
+// @Override
+// public void onReCalculateRouteForYaw() {
+//
+// }
+//
+// @Override
+// public void onReCalculateRouteForTrafficJam() {
+//
+// }
+//
+// @Override
+// public void onArrivedWayPoint( int i ) {
+//
+// }
+//
+// @Override
+// public void onGpsOpenStatus( boolean b ) {
+//
+// }
+//
+// @Override
+// public void onNaviInfoUpdate( NaviInfo naviInfo ) {
+//
+// }
+//
+// @Override
+// public void onNaviInfoUpdated( AMapNaviInfo aMapNaviInfo ) {
+//
+// }
+//
+// @Override
+// public void updateCameraInfo( AMapNaviCameraInfo[] aMapNaviCameraInfos ) {
+//
+// }
+//
+// @Override
+// public void updateIntervalCameraInfo( AMapNaviCameraInfo aMapNaviCameraInfo, AMapNaviCameraInfo aMapNaviCameraInfo1, int i ) {
+// if ( aMapNaviCameraInfo != null ) {
+// Logger.i( TAG, "current camera speed: %d, status = %d", aMapNaviCameraInfo.getCameraSpeed(), i );
+// }
+// if ( aMapNaviCameraInfo1 != null ) {
+// Logger.i( TAG, "current camera speed: %d, status = %d", aMapNaviCameraInfo1.getCameraSpeed(), i );
+// }
+// }
+//
+//
+// @Override
+// public void onServiceAreaUpdate( AMapServiceAreaInfo[] aMapServiceAreaInfos ) {
+//
+// }
+//
+// @Override
+// public void showCross( AMapNaviCross aMapNaviCross ) {
+//
+// }
+//
+// @Override
+// public void hideCross() {
+//
+// }
+//
+// @Override
+// public void showModeCross( AMapModelCross aMapModelCross ) {
+//
+// }
+//
+// @Override
+// public void hideModeCross() {
+//
+// }
+//
+// @Override
+// public void showLaneInfo( AMapLaneInfo[] aMapLaneInfos, byte[] bytes, byte[] bytes1 ) {
+//
+// }
+//
+// @Override
+// public void showLaneInfo( AMapLaneInfo aMapLaneInfo ) {
+//
+// }
+//
+// @Override
+// public void hideLaneInfo() {
+//
+// }
+//
+// @Override
+// public void onCalculateRouteSuccess( int[] ints ) {
+//
+// }
+//
+// @Override
+// public void notifyParallelRoad( int i ) {
+//
+// }
+//
+// @Override
+// public void OnUpdateTrafficFacility( AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos ) {
+//
+// }
+//
+// @Override
+// public void OnUpdateTrafficFacility( AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo ) {
+//
+// }
+//
+// @Override
+// public void OnUpdateTrafficFacility( TrafficFacilityInfo trafficFacilityInfo ) {
+//
+// }
+//
+// /**
+// * 巡航回调
+// * 连续5个点速度大于15km/h后触发 updateAimlessModeStatistics 回调,通过 AimLessModeStat 对象可获取巡航的连续行驶距离和连续启用时间
+// *
+// * @param aimLessModeStat
+// */
+// @Override
+// public void updateAimlessModeStatistics( AimLessModeStat aimLessModeStat ) {
+//
+// }
+//
+// /**
+// * 巡航回调
+// * 出现拥堵长度大于500米且拥堵时间大于5分钟时,会进到 updateAimlessModeCongestionInfo 回调中,通过 AimLessModeCongestionInfo 对象,可获取到道路拥堵信息(如:导致拥堵的事件类型、拥堵的状态等)
+// *
+// * @param aimLessModeCongestionInfo
+// */
+// @Override
+// public void updateAimlessModeCongestionInfo( AimLessModeCongestionInfo aimLessModeCongestionInfo ) {
+//
+// }
+//
+// @Override
+// public void onPlayRing( int i ) {
+//
+// }
+//
+// @Override
+// public void onCalculateRouteSuccess( AMapCalcRouteResult aMapCalcRouteResult ) {
+//
+// }
+//
+// @Override
+// public void onCalculateRouteFailure( AMapCalcRouteResult aMapCalcRouteResult ) {
+//
+// }
+//
+// @Override
+// public void onNaviRouteNotify( AMapNaviRouteNotifyData aMapNaviRouteNotifyData ) {
+//
+// }
+//
+//
+//}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/AimlessModeListenerAdapter.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/AimlessModeListenerAdapter.java
new file mode 100644
index 0000000000..beecd19d46
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/AimlessModeListenerAdapter.java
@@ -0,0 +1,48 @@
+//package com.mogo.map.impl.custom.navi;
+//
+//import com.amap.api.navi.AimlessModeListener;
+//import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo;
+//import com.amap.api.navi.model.AimLessModeCongestionInfo;
+//import com.amap.api.navi.model.AimLessModeStat;
+//import com.mogo.map.impl.custom.utils.ObjectUtils;
+//import com.mogo.map.navi.MogoCongestionInfo;
+//import com.mogo.map.navi.MogoNaviListenerHandler;
+//import com.mogo.map.navi.MogoTraffic;
+//
+///**
+// * @author congtaowang
+// * @since 2020-01-16
+// *
+// * 巡航监听
+// */
+//public class AimlessModeListenerAdapter implements AimlessModeListener {
+//
+// @Override
+// public void onUpdateTrafficFacility( AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos ) {
+// MogoTraffic traffic = ObjectUtils.fromAMap( aMapNaviTrafficFacilityInfos );
+// if ( traffic != null ) {
+// MogoNaviListenerHandler.getInstance().onUpdateTraffic2( traffic );
+// }
+// }
+//
+// @Override
+// public void onUpdateAimlessModeElecCameraInfo( AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos ) {
+// MogoTraffic traffic = ObjectUtils.fromAMap( aMapNaviTrafficFacilityInfos );
+// if ( traffic != null ) {
+// MogoNaviListenerHandler.getInstance().onUpdateTraffic2( traffic );
+// }
+// }
+//
+// @Override
+// public void updateAimlessModeStatistics( AimLessModeStat aimLessModeStat ) {
+//
+// }
+//
+// @Override
+// public void updateAimlessModeCongestionInfo( AimLessModeCongestionInfo aimLessModeCongestionInfo ) {
+// MogoCongestionInfo congestionInfo = ObjectUtils.fromAMap( aimLessModeCongestionInfo );
+// if ( congestionInfo != null ) {
+// MogoNaviListenerHandler.getInstance().onUpdateCongestion( congestionInfo );
+// }
+// }
+//}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/CalculatePathItem.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/CalculatePathItem.java
new file mode 100644
index 0000000000..40a62e5d48
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/CalculatePathItem.java
@@ -0,0 +1,181 @@
+//package com.mogo.map.impl.custom.navi;
+//
+//import android.content.Context;
+//import android.text.TextUtils;
+//
+//import com.amap.api.maps.AMap;
+//import com.amap.api.navi.model.AMapNaviPath;
+//import com.amap.api.navi.model.AMapNaviStep;
+//import com.amap.api.navi.model.NaviLatLng;
+//import com.mogo.map.MogoLatLng;
+//import com.mogo.map.impl.custom.overlay.RouteOverLayWrapper;
+//
+//import java.util.ArrayList;
+//import java.util.List;
+//
+///**
+// * @author congtaowang
+// * @since 2019-12-04
+// *
+// * 导航路径代理类
+// */
+//public class CalculatePathItem {
+//
+// private Context mContext;
+// private AMap mAMap;
+// private int mId;
+// private AMapNaviPath mPath;
+//
+// private RouteOverLayWrapper mOverLazWrapper;
+// private ArrayList< MogoLatLng > mPoints;
+//
+// public int getId() {
+// return mId;
+// }
+//
+// public AMapNaviPath getPath() {
+// return mPath;
+// }
+//
+// public RouteOverLayWrapper getOverLazWrapper( boolean createIfNull ) {
+// if ( mOverLazWrapper == null && createIfNull ) {
+// mOverLazWrapper = new RouteOverLayWrapper( mContext, mAMap, mPath );
+// }
+// return mOverLazWrapper;
+// }
+//
+// public CalculatePathItem(Context context, AMap amap, int id, AMapNaviPath path ) {
+// mContext = context;
+// mAMap = amap;
+// this.mId = id;
+// this.mPath = path;
+// }
+//
+// public String getStrategyName() {
+// return mPath.getLabels();
+// }
+//
+// public String getFormattedTime() {
+// if ( mTimeBuilder == null ) {
+// final int time = mPath.getAllTime();
+// mTimeBuilder = new StringBuilder();
+// fillFormatTime( time, mTimeBuilder );
+// }
+// return mTimeBuilder.toString();
+// }
+//
+// public int getTime(){
+// return mPath.getAllTime();
+// }
+//
+// public int getDistance(){
+// return mPath.getAllLength();
+// }
+//
+// private StringBuilder mTimeBuilder;
+//
+// private void fillFormatTime( int seconds, StringBuilder builder ) {
+// // int days = seconds / ( 24 * 60 * 60 );
+// // if ( days > 0 ) {
+// // builder.append( days ).append( "天" );
+// // }
+// // seconds -= days * 24 * 60 * 60;
+// int hours = seconds / ( 60 * 60 );
+// if ( hours > 0 ) {
+// builder.append( hours ).append( "小时" );
+// }
+// seconds -= hours * 60 * 60;
+// int min = seconds / 60;
+// builder.append( min > 1 ? min : 1 ).append( "分钟" );
+// }
+//
+// private String mDistanceCacheStr = "";
+//
+// public String getFormattedDistance() {
+// if ( TextUtils.isEmpty( mDistanceCacheStr ) ) {
+// int distance = mPath.getAllLength();
+// if ( distance == -1 ) {
+// mDistanceCacheStr = "路程总程未获取";
+// }
+// if ( distance >= 1000 ) {
+// mDistanceCacheStr = String.format( "%.1f公里", ( float ) distance / 1000 );
+// } else {
+// mDistanceCacheStr = distance + "米";
+// }
+// }
+// return mDistanceCacheStr;
+// }
+//
+// private StringBuilder mDescBuilder = null;
+//
+// public String getDesc() {
+// if ( mDescBuilder == null ) {
+// mDescBuilder = new StringBuilder();
+// int lightsSize = getTrafficNumber();
+// if ( lightsSize > 0 ) {
+// mDescBuilder.append( "红绿灯" ).append( lightsSize ).append( "个" );
+// }
+// mDescBuilder.append( " " );
+// mDescBuilder.append( "收费" ).append( mPath.getTollCost() ).append( "元" );
+// }
+//
+// return mDescBuilder.toString();
+// }
+//
+// public int getTrafficNumber() {
+// int trafficLightNumber = 0;
+// if ( mPath == null ) {
+// return trafficLightNumber;
+// }
+// List
+ * 高德导航
+ */
+public class NaviClient implements IMogoNavi {
+
+ /**
+ * 巡航状态控制
+ */
+ public static final String KEY_AIMLESS_STATUS = "KEY_AIMLESS_STATUS";
+
+ private static final String TAG = "NaviClient";
+ private final Context mContext;
+
+ private MapAutoViewHelper mAMapNavi;
+// private final NaviListenerAdapter mAMapNaviListener;
+
+
+// private final AimlessModeListenerAdapter mAimlessModeListener;
+
+ /**
+ * 导航策略配置
+ */
+
+ private MogoNaviConfig mMogoNaviConfig = new MogoNaviConfig();
+
+ private static volatile NaviClient sInstance;
+ private boolean mIsRealNavi;
+
+ private Location mCarLocation = new Location("GPS");
+ private IMogoCarLocationChangedListener2 mCarLocationChangedListener;
+ /**
+ * 巡航模式配置状态
+ */
+ private boolean mAimlessModeStatus;
+
+ /**
+ * 巡航状态
+ */
+ private boolean mAimlessStatus;
+
+ private NaviClient( Context context ) {
+ mCarLocation.setLongitude(116.97000);
+ mCarLocation.setLatitude(39.97000);
+ mContext = context;
+ mAMapNavi = AMapWrapper.getAMap();
+// mAMapNavi.setEmulatorNaviSpeed( 120 );
+// mAMapNavi.setUseInnerVoice( false, true );
+// mAMapNaviListener = new NaviListenerAdapter( context, mAMapNavi, this );
+// mAimlessModeListener = new AimlessModeListenerAdapter() {
+// };
+// mAMapNavi.addAMapNaviListener( mAMapNaviListener );
+// mAMapNavi.addAimlessModeListener( mAimlessModeListener );
+// mAimlessModeStatus = SharedPrefsMgr.getInstance( mContext ).getBoolean( KEY_AIMLESS_STATUS, false );
+ }
+
+ public static NaviClient getInstance( Context context ) {
+ if ( sInstance == null ) {
+ synchronized ( NaviClient.class ) {
+ if ( sInstance == null ) {
+ sInstance = new NaviClient( context );
+ }
+ }
+ }
+ return sInstance;
+ }
+
+ public synchronized void release() {
+ sInstance = null;
+ }
+
+ @Override
+ public void naviTo( MogoLatLng endPoint ) {
+ naviTo( endPoint, mMogoNaviConfig );
+ }
+
+ @Override
+ public void naviTo( MogoLatLng endPoint, MogoNaviConfig config ) {
+ naviTo( endPoint, null, config );
+ }
+
+ @Override
+ public void naviTo( MogoLatLng endPoint, List< MogoLatLng > wayPoints ) {
+ naviTo( endPoint, wayPoints, mMogoNaviConfig );
+ }
+
+ @Override
+ public void naviTo( MogoLatLng endPoint, List< MogoLatLng > wayPoints, MogoNaviConfig config ) {
+ if ( !checkAMapNavi() ) {
+ return;
+ }
+ Logger.i( TAG, "开始规划路径" );
+ mMogoNaviConfig = config;
+ if ( mMogoNaviConfig == null ) {
+ mMogoNaviConfig = new MogoNaviConfig();
+ }
+// int strategy = mAMapNavi.strategyConvert( mMogoNaviConfig.isCongestion(), mMogoNaviConfig.isAvoidSpeed(), mMogoNaviConfig.isCost(), mMogoNaviConfig.isHighSpeed(), config.isMultipleRoute() );
+// List< NaviLatLng > naviWayPoints = null;
+// if ( wayPoints != null && !wayPoints.isEmpty() ) {
+// naviWayPoints = new ArrayList<>( wayPoints.size() );
+// for ( MogoLatLng wayPoint : wayPoints ) {
+// naviWayPoints.add( ObjectUtils.fromMogoAsNavi( wayPoint ) );
+// }
+// } else {
+// naviWayPoints = new ArrayList<>();
+// }
+// mAMapNavi.calculateDriveRoute(
+// new ArrayList( Arrays.asList( ObjectUtils.fromMogoAsNavi( endPoint ) ) ),
+// naviWayPoints,
+// strategy
+// );
+ }
+
+ @Override
+ public void reCalculateRoute( MogoNaviConfig config ) {
+ if ( !checkAMapNavi() ) {
+ return;
+ }
+ mMogoNaviConfig = config;
+ if ( mMogoNaviConfig == null ) {
+ mMogoNaviConfig = new MogoNaviConfig();
+ }
+// int strategy = mAMapNavi.strategyConvert( mMogoNaviConfig.isCongestion(), mMogoNaviConfig.isAvoidSpeed(), mMogoNaviConfig.isCost(), mMogoNaviConfig.isHighSpeed(), config.isMultipleRoute() );
+// mAMapNavi.reCalculateRoute( strategy );
+ }
+
+ @Override
+ public void stopNavi() {
+// if ( mAMapNaviListener != null ) {
+// mAMapNaviListener.stopNavi();
+// }
+ }
+
+
+ @Override
+ public void startNavi( boolean isRealNavi ) {
+// if ( mAMapNaviListener.isStopped() ) {
+// return;
+// }
+// mIsRealNavi = isRealNavi;
+// stopAimlessMode();
+// boolean isNaving = isNaviing();
+// boolean result = mAMapNavi.startNavi( isRealNavi ? NaviType.GPS : NaviType.EMULATOR );
+// if ( isNaving && !result ) {
+// // 如果正在导航,又重新规划路线,startNavi 不会成功,不会重新回调 #onStartNavi
+// MogoNaviListenerHandler.getInstance().onStartNavi();
+// AMapMessageManager.getInstance().postNaviStarted();
+// }
+// Logger.d( TAG, "start navi status: %s", result );
+ }
+
+ @Override
+ public boolean isNaviing() {
+// if ( mAMapNaviListener != null ) {
+// return mAMapNaviListener.isNaviing();
+// }
+ return false;
+ }
+
+ @Override
+ public List< MogoCalculatePath > getCalculatedStrategies() {
+// if ( mAMapNaviListener != null ) {
+// return mAMapNaviListener.getCalculateStrategies();
+// }
+ return null;
+ }
+
+ @Override
+ public List< MogoLatLng > getCalculatedPathPos() {
+// if ( mAMapNaviListener != null ) {
+// return mAMapNaviListener.getCalculatedPathPos();
+// }
+ return null;
+ }
+
+ @Override
+ public OnCalculatePathItemClickInteraction getItemClickInteraction() {
+// if ( mAMapNaviListener != null ) {
+// return mAMapNaviListener.getItemClickInteraction();
+// }
+ return null;
+ }
+
+ @Override
+ public void setLineClickInteraction( OnCalculatePathItemClickInteraction lineClickInteraction ) {
+// if ( mAMapNaviListener != null ) {
+// mAMapNaviListener.setLineClickInteraction( lineClickInteraction );
+// }
+ }
+
+ @Override
+ public void clearCalculatePaths() {
+// if ( mAMapNaviListener != null ) {
+// mAMapNaviListener.clearCalculatePaths();
+// }
+ }
+
+ @Override
+ public void setCalculatePathDisplayBounds( Rect bounds ) {
+// if ( mAMapNaviListener != null ) {
+// mAMapNaviListener.setCalculatePathDisplayBounds( bounds );
+// }
+ }
+
+ @Override
+ public MogoNaviConfig getNaviConfig() {
+ return mMogoNaviConfig;
+ }
+
+ @Override
+ public boolean setBroadcastMode( int mode ) {
+ return false;//mAMapNavi.setBroadcastMode( mode );
+ }
+
+ @Override
+ public List< MogoLatLng > getNaviPathCoordinates() {
+ return null;
+ }
+
+ @Override
+ public MogoLatLng getCarLocation() {
+ if ( mCarLocation != null ) {
+ synchronized ( mCarLocation ) {
+ return new MogoLatLng( mCarLocation.getLatitude(), mCarLocation.getLongitude() );
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Location getCarLocation2() {
+ return mCarLocation;
+ }
+
+ @Override
+ public void registerCarLocationChangedListener( IMogoCarLocationChangedListener2 listener ) {
+ mCarLocationChangedListener = listener;
+ }
+
+ // -- end
+
+ public void syncCarLocation( Location location ) {
+ mCarLocation = location;
+ if ( mCarLocationChangedListener != null ) {
+ mCarLocationChangedListener.onCarLocationChanged2( mCarLocation );
+ }
+ }
+
+ private boolean checkAMapNavi() {
+ mAMapNavi = AMapWrapper.getAMap();
+ if ( mAMapNavi == null ) {
+ Logger.e( TAG, "高德导航实例为空!!!" );
+ return false;
+ }
+ return true;
+ }
+
+ public boolean isRealNavi() {
+ return mIsRealNavi;
+ }
+
+ public void handleClickedPolyline( Polyline polyline ) {
+// if ( mAMapNaviListener != null ) {
+// mAMapNaviListener.handleClickedPolyline( polyline );
+// }
+ }
+
+ @Override
+ public void startAimlessMode() {
+// if ( mAimlessModeStatus && !isNaviing() ) {
+// mAMapNavi.startAimlessMode( AimLessMode.CAMERA_AND_SPECIALROAD_DETECTED );
+// mAimlessStatus = true;
+// Logger.d( TAG, "开启巡航成功" );
+// } else {
+// mAimlessStatus = false;
+// Logger.d( TAG, "开启巡航失败" );
+// }
+ }
+
+ @Override
+ public void stopAimlessMode() {
+// mAMapNavi.stopAimlessMode();
+// mAimlessStatus = false;
+// Logger.d( TAG, "关闭巡航成功" );
+ }
+
+ @Override
+ public void setAimlessModeStatus( boolean open ) {
+ this.mAimlessModeStatus = open;
+ SharedPrefsMgr.getInstance( mContext ).putBoolean( KEY_AIMLESS_STATUS, open );
+ if ( open ) {
+ if ( !mAimlessStatus ) {
+ startAimlessMode();
+ }
+ } else {
+ if ( mAimlessStatus ) {
+ stopAimlessMode();
+ }
+ }
+ }
+
+ @Override
+ public void displayOverview( Rect bounds ) {
+// if ( mAMapNaviListener != null ) {
+// mAMapNaviListener.displayOverview( bounds );
+// }
+ }
+
+ @Override
+ public void setUseExtraGPSData( boolean use ) {
+ Logger.d( TAG, "设置外部gps源状态 %s", use );
+ mAMapNavi.setIsUseExtraGPSData( use );
+ AMapWrapper.getAMap().setMyLocationEnabled( true );
+ }
+
+ @Override
+ public void setExtraGPSData( double lon, double lat, float speed, float accuracy, float bearing, long timestamp ) {
+ if ( !mAMapNavi.getIsUseExtraGPSData() ) {
+ Logger.d( TAG, "拒绝外部GPS数据" );
+ return;
+ }
+ Location location = new Location( "外部GPS源" );
+ location.setLongitude( lon );
+ location.setLatitude( lat );
+ location.setSpeed( speed );
+ location.setAccuracy( accuracy );
+ location.setBearing( bearing );
+ location.setTime( timestamp );
+ //type字段传1时代表WGS84坐标
+ mAMapNavi.setExtraGPSData( 2, location );
+ }
+}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/NaviListenerAdapter.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/NaviListenerAdapter.java
new file mode 100644
index 0000000000..9d2b049ed3
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/NaviListenerAdapter.java
@@ -0,0 +1,296 @@
+//package com.mogo.map.impl.custom.navi;
+//
+//import android.content.Context;
+//import android.graphics.Rect;
+//import android.os.Trace;
+//import android.text.TextUtils;
+//
+//import com.amap.api.maps.model.Polyline;
+//import com.amap.api.navi.AMapNavi;
+//import com.amap.api.navi.enums.CameraType;
+//import com.amap.api.navi.enums.NaviType;
+//import com.amap.api.navi.model.AMapCalcRouteResult;
+//import com.amap.api.navi.model.AMapNaviCameraInfo;
+//import com.amap.api.navi.model.AMapNaviLocation;
+//import com.amap.api.navi.model.NaviInfo;
+//import com.mogo.commons.voice.AIAssist;
+//import com.mogo.map.MogoLatLng;
+//import com.mogo.map.impl.custom.message.AMapMessageManager;
+//import com.mogo.map.impl.custom.utils.ObjectUtils;
+//import com.mogo.map.navi.MogoCalculatePath;
+//import com.mogo.map.navi.MogoNaviListenerHandler;
+//import com.mogo.map.navi.MogoTraffic;
+//import com.mogo.map.navi.OnCalculatePathItemClickInteraction;
+//import com.mogo.utils.UiThreadHandler;
+//import com.mogo.utils.logger.Logger;
+//
+//import java.util.List;
+//
+///**
+// * @author congtaowang
+// * @since 2019-12-25
+// *
+// * 高德导航回调
+// */
+//public class NaviListenerAdapter extends AMapNaviListenerAdapter {
+//
+// private static final String TAG = "NaviListenerAdapter";
+//
+// private Context mContext;
+// private AMapNavi mAMapNavi;
+// private NaviClient mClient;
+// /**
+// * 导航状态:true - 导航 onStartNavi(int) 被调用, false - 到达目的地、手动挺固执
+// */
+// private boolean mIsNaviing = false;
+//
+// /**
+// * 导航是否被停止:true - 手动停止或到达目的地、false - 规划路径成功、开启导航
+// */
+// private boolean mIsStopped = true;
+//
+// /**
+// * 路线规划
+// */
+// private NaviOverlayHelper mNaviOverlayHelper;
+//
+// public NaviListenerAdapter( Context mContext, AMapNavi mAMapNavi, NaviClient client ) {
+// this.mContext = mContext;
+// this.mAMapNavi = mAMapNavi;
+// this.mClient = client;
+//// mNaviOverlayHelper = new NaviOverlayHelper( mAMapNavi, AMapWrapper.getAMap(), mContext );
+// }
+//
+// public void setNaviing( boolean mIsNaviing ) {
+// this.mIsNaviing = mIsNaviing;
+// }
+//
+// public boolean isNaviing() {
+// return mIsNaviing;
+// }
+//
+// public void setStopped( boolean isStopped ) {
+// this.mIsStopped = isStopped;
+// }
+//
+// public boolean isStopped() {
+// return mIsStopped;
+// }
+//
+// public Context getContext() {
+// return mContext;
+// }
+//
+// @Override
+// public void onInitNaviFailure() {
+// MogoNaviListenerHandler.getInstance().onInitNaviFailure();
+// }
+//
+// @Override
+// public void onInitNaviSuccess() {
+// MogoNaviListenerHandler.getInstance().onInitNaviSuccess();
+// NaviClient.getInstance( mContext ).startAimlessMode();
+// }
+//
+// @Override
+// public void updateCameraInfo( AMapNaviCameraInfo[] aMapNaviCameraInfos ) {
+// super.updateCameraInfo( aMapNaviCameraInfos );
+// if ( aMapNaviCameraInfos == null || aMapNaviCameraInfos.length == 0 ) {
+// return;
+// }
+// int limitSpeed = 0;
+// for ( AMapNaviCameraInfo aMapNaviCameraInfo : aMapNaviCameraInfos ) {
+// if ( aMapNaviCameraInfo == null ) {
+// continue;
+// }
+// limitSpeed = aMapNaviCameraInfo.getCameraSpeed();
+// if ( limitSpeed > 0 && aMapNaviCameraInfo.getCameraType() == CameraType.SPEED ) {
+// MogoTraffic traffic = new MogoTraffic( MogoTraffic.TYPE_NAVI );
+// traffic.setDistance( aMapNaviCameraInfo.getCameraDistance() );
+// traffic.setSpeedLimit( aMapNaviCameraInfo.getCameraSpeed() );
+// MogoNaviListenerHandler.getInstance().onUpdateTraffic2( traffic );
+// }
+//
+//// switch ( aMapNaviCameraInfo.getCameraType() ) {
+//// case CameraType.SPEED:
+////
+//// break;
+//// case CameraType.SURVEILLANCE:
+//// traffic.setDesc( "监控摄像" );
+//// break;
+//// case CameraType.TRAFFICLIGHT:
+//// traffic.setDesc( "闯红灯拍照" );
+//// break;
+//// case CameraType.BREAKRULE:
+//// traffic.setDesc( "违章拍照" );
+//// break;
+//// case CameraType.BUSWAY:
+//// traffic.setDesc( "公交专用道摄像头" );
+//// break;
+//// case CameraType.EMERGENCY:
+//// traffic.setDesc( "应急车道拍照" );
+//// break;
+//// case CameraType.BICYCLE:
+//// traffic.setDesc( "非机动车道" );
+//// break;
+//// case CameraType.INTERVALVELOCITYSTART:
+//// traffic.setDesc( "区间测速起始" );
+//// break;
+//// case CameraType.INTERVALVELOCITYEND:
+//// traffic.setDesc( "区间测速解除" );
+//// break;
+//// }
+// }
+// if ( limitSpeed <= 0 ) {
+// MogoTraffic traffic = new MogoTraffic( MogoTraffic.TYPE_NAVI );
+// traffic.setDistance( 0 );
+// traffic.setSpeedLimit( 0 );
+// MogoNaviListenerHandler.getInstance().onUpdateTraffic2( traffic );
+// }
+// }
+//
+// @Override
+// public void onStartNavi( int type ) {
+//
+// Logger.d( TAG, "onStartNavi type = %s", type );
+// // 巡航
+// if ( type != NaviType.CRUISE ) {
+// setStopped( false );
+// setNaviing( true );
+// MogoNaviListenerHandler.getInstance().onStartNavi();
+// AMapMessageManager.getInstance().postNaviStarted();
+// }
+// }
+//
+// @Override
+// public void onEndEmulatorNavi() {
+// stopNaviDelay( () -> {
+// MogoNaviListenerHandler.getInstance().onEndEmulatorNavi();
+// } );
+// }
+//
+// @Override
+// public void onArriveDestination() {
+// stopNaviDelay( () -> {
+// MogoNaviListenerHandler.getInstance().onArriveDestination();
+// } );
+// }
+//
+// /**
+// * 避免导航结束语音播报被立刻打断的情况
+// *
+// * @param after 停止后的行为
+// */
+// private void stopNaviDelay( Runnable after ) {
+// UiThreadHandler.postDelayed( () -> {
+// if ( TextUtils.isEmpty( mLastSpeakWord ) || !mLastSpeakWord.contains( "结束" ) ) {
+// AIAssist.getInstance( mContext ).speakTTSVoice( "到达目的地附近,本次导航结束" );
+// }
+// mLastSpeakWord = "";
+// stopNavi();
+// if ( after != null ) {
+// after.run();
+// }
+// }, 5_000L );
+// }
+//
+// @Override
+// public void onNaviInfoUpdate( NaviInfo naviInfo ) {
+// Trace.beginSection( "NaviListenerAdapter.onNaviInfoUpdate" );
+// MogoNaviListenerHandler.getInstance().onNaviInfoUpdate( ObjectUtils.fromAMap( mContext, naviInfo ) );
+// mNaviOverlayHelper.handleNaviInfoUpdate( naviInfo );
+// Trace.endSection();
+// }
+//
+// @Override
+// public void onCalculateRouteFailure( AMapCalcRouteResult aMapCalcRouteResult ) {
+// if ( aMapCalcRouteResult != null ) {
+// Logger.i( TAG, PathPlanningErrorCodeConstants.getErrorMsg( aMapCalcRouteResult.getErrorCode() ) );
+// }
+// MogoNaviListenerHandler.getInstance().onoCalculateFailed();
+// }
+//
+// @Override
+// public void onCalculateRouteSuccess( AMapCalcRouteResult aMapCalcRouteResult ) {
+// super.onCalculateRouteSuccess( aMapCalcRouteResult );
+// Logger.i( TAG, "导航规划成功" );
+// setStopped( false );
+// mNaviOverlayHelper.showCalculatedPaths( () -> {
+// AMapMessageManager.getInstance().postCalculateSuccess();
+// MogoNaviListenerHandler.getInstance().onCalculateSuccess();
+// } );
+// }
+//
+// @Override
+// public void onLocationChange( AMapNaviLocation aMapNaviLocation ) {
+// Trace.beginSection( "NaviListenerAdapter.onLocationChange" );
+// super.onLocationChange( aMapNaviLocation );
+//// mNaviOverlayHelper.handlePassedLocation( aMapNaviLocation );
+// Trace.endSection();
+// }
+//
+// public void stopNavi() {
+// TTSSpeaker.getInstance().shutUp();
+// mNaviOverlayHelper.clearCalculatedOverlay();
+// setStopped( true );
+// setNaviing( false );
+// mAMapNavi.stopNavi();
+// MogoNaviListenerHandler.getInstance().onStopNavi();
+// AMapMessageManager.getInstance().postNaviStopped();
+// }
+//
+// public void handleClickedPolyline( Polyline polyline ) {
+// if ( mNaviOverlayHelper != null ) {
+//
+// mNaviOverlayHelper.handleClickedPolyline( polyline, isNaviing() );
+// mAMapNavi.selectRouteId( mNaviOverlayHelper.getSelectedPathId() );
+// mNaviOverlayHelper.showBoundsWithSettingBounds();
+// }
+// }
+//
+// public List< MogoCalculatePath > getCalculateStrategies() {
+// if ( mNaviOverlayHelper != null ) {
+// return mNaviOverlayHelper.getCalculateStrategies();
+// }
+// return null;
+// }
+//
+// public List< MogoLatLng > getCalculatedPathPos() {
+// if ( mNaviOverlayHelper != null ) {
+// return mNaviOverlayHelper.getCalculatedPathPos();
+// }
+// return null;
+// }
+//
+//
+// public OnCalculatePathItemClickInteraction getItemClickInteraction() {
+// if ( mNaviOverlayHelper != null ) {
+// return mNaviOverlayHelper.getItemClickInteraction();
+// }
+// return null;
+// }
+//
+// public void setLineClickInteraction( OnCalculatePathItemClickInteraction lineClickInteraction ) {
+// if ( mNaviOverlayHelper != null ) {
+// mNaviOverlayHelper.setLineClickInteraction( lineClickInteraction );
+// }
+// }
+//
+// public void clearCalculatePaths() {
+// if ( mNaviOverlayHelper != null ) {
+// mNaviOverlayHelper.clearCalculatedOverlay();
+// }
+// }
+//
+// public void setCalculatePathDisplayBounds( Rect bounds ) {
+// if ( mNaviOverlayHelper != null ) {
+// mNaviOverlayHelper.setCalculatePathDisplayBounds( bounds );
+// }
+// }
+//
+// public void displayOverview( Rect bounds ) {
+// if ( mNaviOverlayHelper != null ) {
+// mNaviOverlayHelper.displayOverview( bounds );
+// }
+// }
+//}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/NaviOverlayHelper.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/NaviOverlayHelper.java
new file mode 100644
index 0000000000..4dbebe02b1
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/NaviOverlayHelper.java
@@ -0,0 +1,461 @@
+//package com.mogo.map.impl.custom.navi;
+//
+//import android.content.Context;
+//import android.graphics.Bitmap;
+//import android.graphics.BitmapFactory;
+//import android.graphics.Rect;
+//import android.text.TextUtils;
+//
+//import com.amap.api.maps.AMap;
+//import com.amap.api.maps.CameraUpdateFactory;
+//import com.amap.api.maps.model.BitmapDescriptorFactory;
+//import com.amap.api.maps.model.LatLng;
+//import com.amap.api.maps.model.LatLngBounds;
+//import com.amap.api.maps.model.Marker;
+//import com.amap.api.maps.model.MarkerOptions;
+//import com.amap.api.maps.model.Polyline;
+//import com.amap.api.navi.AMapNavi;
+//import com.amap.api.navi.model.AMapNaviLocation;
+//import com.amap.api.navi.model.AMapNaviPath;
+//import com.amap.api.navi.model.NaviInfo;
+//import com.amap.api.navi.model.NaviLatLng;
+//import com.mogo.map.MogoLatLng;
+//import com.mogo.map.impl.custom.R;
+//import com.mogo.map.impl.custom.overlay.RouteOverLayWrapper;
+//import com.mogo.map.marker.MogoMarkersHandler;
+//import com.mogo.map.navi.MogoCalculatePath;
+//import com.mogo.map.navi.OnCalculatePathItemClickInteraction;
+//import com.mogo.utils.WindowUtils;
+//import com.mogo.utils.logger.Logger;
+//
+//import java.util.ArrayList;
+//import java.util.Comparator;
+//import java.util.List;
+//import java.util.Map;
+//import java.util.TreeMap;
+//
+///**
+// * @author congtaowang
+// * @since 2019-12-27
+// *
+// * 导航路径管理
+// */
+//public class NaviOverlayHelper implements OnCalculatePathItemClickInteraction {
+//
+// private static final String TAG = "NaviOverlayHelper";
+//
+// /**
+// * 选中的路径透明度
+// */
+// public static final float AMAP_ROUTE_OVERLAY_TRANSPARENCY_SELECTED = 1f;
+//
+// /**
+// * 未选中的路径透明度
+// */
+// public static final float AMAP_ROUTE_OVERLAY_TRANSPARENCY_UNSELECTED = 0.3f;
+//
+// private AMapNavi mAMapNavi;
+// private AMap mAMap;
+// private Context mContext;
+// // 规划的路线显示边距
+// private Rect mBoundRect = null;
+//
+// private List< CalculatePathItem > mCalculatePathItems;
+// private List< MogoCalculatePath > mPaths = new ArrayList<>();
+//
+// private int mSelectedPathId;
+// private CalculatePathItem mSelectedCalculatePathItem;
+// private OnCalculatePathItemClickInteraction mLineClickInteraction;
+//
+// /**
+// * 起点终点marker
+// */
+// private List< Marker > mMarkers = new ArrayList<>();
+//
+// public NaviOverlayHelper( AMapNavi mAMapNavi, AMap mAMap, Context mContext ) {
+// this.mAMapNavi = mAMapNavi;
+// this.mAMap = mAMap;
+// this.mContext = mContext;
+// calculateBoundArea();
+// }
+//
+// /**
+// * 显示规划的路径
+// */
+// public void showCalculatedPaths( Runnable after ) {
+// clearCalculatedOverlay();
+// mCalculatePathItems = getSortedPaths();
+// if ( mCalculatePathItems == null || mCalculatePathItems.isEmpty() ) {
+// return;
+// }
+// showPathsBound( getBounds(), () -> {
+// addEndPoints();
+// renderPathOverlay( mCalculatePathItems );
+// if ( after != null ) {
+// after.run();
+// }
+// }, mBoundRect );
+// }
+//
+// private LatLngBounds getBounds() {
+// if ( mCalculatePathItems == null ) {
+// return null;
+// }
+// LatLngBounds.Builder builder = new LatLngBounds.Builder();
+// for ( CalculatePathItem calculatePathItem : mCalculatePathItems ) {
+// if ( calculatePathItem == null ) {
+// continue;
+// }
+// try {
+// LatLngBounds bounds = calculatePathItem.getPath().getBoundsForPath();
+// builder.include( bounds.northeast );
+// builder.include( bounds.southwest );
+// } catch ( Exception e ) {
+// e.printStackTrace();
+// }
+// }
+// return builder.build();
+// }
+//
+// /**
+// * 按pathId升序排序
+// *
+// * @return 排序好的路径规划列表
+// */
+// private List< CalculatePathItem > getSortedPaths() {
+// checkAMapInstance();
+// final Map< Integer, AMapNaviPath > pathMap = mAMapNavi.getNaviPaths();
+// if ( pathMap == null || pathMap.isEmpty() ) {
+// return null;
+// }
+// TreeMap< Integer, AMapNaviPath > sortedMap =
+// new TreeMap< Integer, AMapNaviPath >( new Comparator< Integer >() {
+// @Override
+// public int compare( Integer obj1, Integer obj2 ) {
+// if ( obj1 != null ) {
+// return obj1.compareTo( obj2 );
+// }
+// if ( obj2 != null ) {
+// return obj2.compareTo( obj1 );
+// }
+// return 0;
+// }
+// } );
+// sortedMap.putAll( pathMap );
+//
+// final List< CalculatePathItem > items = new ArrayList<>();
+// for ( Map.Entry< Integer, AMapNaviPath > entry : sortedMap.entrySet() ) {
+// if ( entry == null || entry.getKey() == null || entry.getValue() == null ) {
+// continue;
+// }
+// items.add( new CalculatePathItem( mContext, mAMap, entry.getKey(), entry.getValue() ) );
+// }
+// return items;
+// }
+//
+// private void calculateBoundArea() {
+// if ( mBoundRect == null ) {
+// mBoundRect = new Rect();
+// final int padding = WindowUtils.dip2px( mContext, 80 );
+// mBoundRect.left = padding;
+// mBoundRect.right = padding;
+// mBoundRect.top = padding;
+// mBoundRect.bottom = padding;
+// }
+// }
+//
+// public void showBoundsWithSettingBounds() {
+// showBounds( mBoundRect );
+// }
+//
+// public void showBounds( Rect bounds ) {
+// Logger.d( TAG, "showBounds" );
+// showPathsBound( getBounds(), null, bounds );
+// }
+//
+// /**
+// * 将规划好的路径显示在视野内
+// */
+// private void showPathsBound( LatLngBounds bounds, Runnable after, Rect rect ) {
+// if ( bounds == null ) {
+// return;
+// }
+// if ( rect == null ) {
+// rect = new Rect();
+// }
+// checkAMapInstance();
+// mAMap.moveCamera( CameraUpdateFactory.newLatLngBoundsRect(
+// bounds,
+// rect.left,
+// rect.right,
+// rect.top,
+// rect.bottom ) );
+// if ( after != null ) {
+// after.run();
+// }
+// }
+//
+// private void checkAMapInstance() {
+// if ( mAMap == null ) {
+//// mAMap = AMapWrapper.getAMap();
+// }
+// }
+//
+// public void renderPathOverlay( List< CalculatePathItem > paths ) {
+// if ( paths == null || paths.size() == 0 ) {
+// return;
+// }
+// for ( int i = 0; i < paths.size(); i++ ) {
+// final CalculatePathItem item = paths.get( i );
+// if ( item == null || item.getPath() == null ) {
+// continue;
+// }
+// RouteOverLayWrapper wrapper = item.getOverLazWrapper( true );
+// wrapper.setTrafficLightsVisible( false );
+// // 默认选中第一个
+// if ( i == 0 ) {
+// mSelectedPathId = item.getId();
+// mSelectedCalculatePathItem = item;
+// //wrapper.setStartBitmap( R.drawable.ic_navi_start )
+// // .setEndBitmap( R.drawable.ic_navi_target );
+// mAMapNavi.selectRouteId( item.getId() );
+// Logger.d( TAG, "renderPathOverlay set default path" );
+// }
+// wrapper.addToMap();
+// wrapper.setTransparency( i == 0 ? AMAP_ROUTE_OVERLAY_TRANSPARENCY_SELECTED : AMAP_ROUTE_OVERLAY_TRANSPARENCY_UNSELECTED );
+// }
+// }
+//
+// public void addEndPoints() {
+// if ( mCalculatePathItems == null || mCalculatePathItems.isEmpty() ) {
+// return;
+// }
+//
+// Bitmap bitmap = BitmapFactory.decodeResource( mContext.getResources(), R.drawable.ic_endpoint );
+// Bitmap startBitmap = BitmapFactory.decodeResource( mContext.getResources(), R.drawable.ic_navi_start );
+// Bitmap endBitmap = BitmapFactory.decodeResource( mContext.getResources(), R.drawable.ic_navi_target );
+// MarkerOptions options = new MarkerOptions().icon( BitmapDescriptorFactory.fromBitmap( bitmap ) ).zIndex( 0 ).anchor( 0.5f, 0.5f );
+// MarkerOptions startOptions = new MarkerOptions().icon( BitmapDescriptorFactory.fromBitmap( startBitmap ) ).zIndex( 0 ).anchor( 0.5f, 1 );
+// MarkerOptions endOptions = new MarkerOptions().icon( BitmapDescriptorFactory.fromBitmap( endBitmap ) ).zIndex( 0 ).anchor( 0.5f, 1 );
+// for ( CalculatePathItem path : mCalculatePathItems ) {
+// List< MogoLatLng > points = path.getCoordList();
+// if ( points == null || points.isEmpty() ) {
+// continue;
+// }
+// MogoLatLng startPoint = path.getDriveStartPoint();
+// MogoLatLng endPoint = path.getDriveEndPoint();
+// if ( startPoint == null || endPoint == null ) {
+// continue;
+// }
+// mMarkers.add( mAMap.addMarker( options.position( new LatLng( startPoint.lat, startPoint.lng ) ) ) );
+// mMarkers.add( mAMap.addMarker( options.position( new LatLng( endPoint.lat, endPoint.lng ) ) ) );
+// mMarkers.add( mAMap.addMarker( startOptions.position( new LatLng( startPoint.lat, startPoint.lng ) ) ) );
+// mMarkers.add( mAMap.addMarker( endOptions.position( new LatLng( endPoint.lat, endPoint.lng ) ) ) );
+//
+// break;
+// }
+// }
+//
+// public void clearCalculatedOverlay() {
+// if ( mCalculatePathItems != null && !mCalculatePathItems.isEmpty() ) {
+// for ( CalculatePathItem calculatePathItem : mCalculatePathItems ) {
+// if ( calculatePathItem == null ) {
+// continue;
+// }
+// RouteOverLayWrapper wrapper = calculatePathItem.getOverLazWrapper( false );
+// if ( wrapper != null ) {
+// wrapper.destroy();
+// }
+// calculatePathItem.release();
+// }
+// mCalculatePathItems.clear();
+// }
+// if ( mPaths != null ) {
+// mPaths.clear();
+// }
+// if ( !mMarkers.isEmpty() ) {
+// for ( Marker mMarker : mMarkers ) {
+// if ( mMarker == null ) {
+// continue;
+// }
+// try {
+// mMarker.remove();
+// mMarker.destroy();
+// } catch ( Exception e ) {
+//
+// }
+// }
+// }
+// MogoMarkersHandler.getInstance().remove( TAG );
+// }
+//
+// /**
+// * 是否切换成功
+// *
+// * @param polyline 选中的线
+// */
+// public boolean handleClickedPolyline( Polyline polyline, boolean isNaviing ) {
+// if ( polyline == null ) {
+// return false;
+// }
+// if ( mPaths != null && !mPaths.isEmpty() ) {
+// for ( MogoCalculatePath path : mPaths ) {
+// if ( TextUtils.equals( path.getTagId(), polyline.getId() ) ) {
+// if ( mLineClickInteraction != null ) {
+// mLineClickInteraction.onItemClicked( path.getTagId() );
+// break;
+// }
+// }
+// }
+// }
+// return handleClickedPolyline( polyline.getId() );
+// }
+//
+// private boolean handleClickedPolyline( String id ) {
+// if ( id == null ) {
+// return false;
+// }
+// Logger.i( TAG, "polyline id = " + id );
+// mSelectedCalculatePathItem = isCalculatePolyline( id );
+// if ( mSelectedCalculatePathItem == null ) {
+// return false;
+// }
+// mSelectedPathId = mSelectedCalculatePathItem.getId();
+// if ( mCalculatePathItems != null ) {
+// for ( CalculatePathItem item : mCalculatePathItems ) {
+// final RouteOverLayWrapper wrapper = item.getOverLazWrapper( false );
+// if ( wrapper == null ) {
+// continue;
+// }
+// wrapper.setTransparency(
+// item == mSelectedCalculatePathItem
+// ? AMAP_ROUTE_OVERLAY_TRANSPARENCY_SELECTED
+// : AMAP_ROUTE_OVERLAY_TRANSPARENCY_UNSELECTED
+// );
+// }
+// }
+// return true;
+// }
+//
+// private CalculatePathItem isCalculatePolyline( String id ) {
+// CalculatePathItem result = null;
+// if ( mCalculatePathItems == null || mCalculatePathItems.isEmpty() ) {
+// return result;
+// }
+// for ( CalculatePathItem calculatePathItem : mCalculatePathItems ) {
+// if ( calculatePathItem == null ) {
+// continue;
+// }
+// final RouteOverLayWrapper wrapper = calculatePathItem.getOverLazWrapper( false );
+// if ( wrapper == null ) {
+// continue;
+// }
+// if ( wrapper.getTrafficColorfulPolyline() == null ) {
+// continue;
+// }
+// if ( TextUtils.equals( wrapper.getTrafficColorfulPolyline().getId(), id ) ) {
+// result = calculatePathItem;
+// }
+// }
+// return result;
+// }
+//
+// public int getSelectedPathId() {
+// return mSelectedPathId;
+// }
+//
+// /**
+// * 车辆拐弯时绘制转向箭头
+// */
+// public void handleNaviInfoUpdate( NaviInfo naviInfo ) {
+// if ( mSelectedCalculatePathItem != null ) {
+// RouteOverLayWrapper wrapper = mSelectedCalculatePathItem.getOverLazWrapper( false );
+// if ( wrapper != null ) {
+// wrapper.drawArrow( naviInfo );
+// }
+// }
+// }
+//
+// public void handlePassedLocation( AMapNaviLocation location ) {
+// if ( mSelectedCalculatePathItem != null ) {
+// RouteOverLayWrapper wrapper = mSelectedCalculatePathItem.getOverLazWrapper( false );
+// if ( wrapper != null ) {
+// wrapper.updatePolyline( location );
+// }
+// }
+// }
+//
+// public List< MogoCalculatePath > getCalculateStrategies() {
+// if ( mCalculatePathItems != null && !mCalculatePathItems.isEmpty() ) {
+// for ( CalculatePathItem calculatePathItem : mCalculatePathItems ) {
+// MogoCalculatePath path = new MogoCalculatePath();
+// path.setFormattedDistance( calculatePathItem.getFormattedDistance() );
+// path.setPathId( calculatePathItem.getId() );
+// path.setStrategyName( calculatePathItem.getStrategyName() );
+// path.setFormattedTime( calculatePathItem.getFormattedTime() );
+// path.setTime( calculatePathItem.getTime() );
+// path.setDistance( calculatePathItem.getDistance() );
+// List< NaviLatLng > coordList = calculatePathItem.getPath().getCoordList();
+// ArrayList< MogoLatLng > mogoLatLngs = new ArrayList<>();
+// for ( NaviLatLng latlng : coordList
+// ) {
+// MogoLatLng mogoLatLng =
+// new MogoLatLng( latlng.getLatitude(), latlng.getLongitude() );
+// mogoLatLngs.add( mogoLatLng );
+// }
+// path.setCoordList( mogoLatLngs );
+// path.setTrafficLights( calculatePathItem.getTrafficNumber() );
+// mPaths.add( path );
+// final RouteOverLayWrapper wrapper = calculatePathItem.getOverLazWrapper( true );
+// if ( wrapper == null ) {
+// continue;
+// }
+// if ( wrapper.getTrafficColorfulPolyline() == null ) {
+// continue;
+// }
+// path.setTagId( wrapper.getTrafficColorfulPolyline().getId() );
+// }
+// }
+//
+// return mPaths;
+// }
+//
+// public List< MogoLatLng > getCalculatedPathPos() {
+//
+// if ( mSelectedCalculatePathItem != null ) {
+// return mSelectedCalculatePathItem.getCoordList();
+// }
+// //if (mPaths != null && !mPaths.isEmpty()) {
+// // return mPaths.get(0).getCoordList();
+// //}
+// return null;
+// }
+//
+// @Override
+// public void onItemClicked( String tagId ) {
+// handleClickedPolyline( tagId );
+// mAMapNavi.selectRouteId( getSelectedPathId() );
+// showBounds( mBoundRect );
+// }
+//
+// public OnCalculatePathItemClickInteraction getItemClickInteraction() {
+// return this;
+// }
+//
+// public void setLineClickInteraction( OnCalculatePathItemClickInteraction lineClickInteraction ) {
+// mLineClickInteraction = lineClickInteraction;
+// }
+//
+// public void setCalculatePathDisplayBounds( Rect bounds ) {
+// if ( bounds != null ) {
+// mBoundRect = bounds;
+// }
+// }
+//
+// /**
+// * 展示全程
+// */
+// public void displayOverview( Rect bounds ) {
+// showBounds( bounds );
+// }
+//}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/PathPlanningErrorCodeConstants.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/PathPlanningErrorCodeConstants.java
new file mode 100644
index 0000000000..12298a2737
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/PathPlanningErrorCodeConstants.java
@@ -0,0 +1,92 @@
+//package com.mogo.map.impl.custom.navi;
+//
+//import com.amap.api.navi.enums.PathPlanningErrCode;
+//
+///**
+// * @author congtaowang
+// * @since 2019-10-18
+// *
+// * 描述
+// */
+//public enum PathPlanningErrorCodeConstants {
+//
+// NONE( -1, "路线规划错误,请重试" ),
+//
+// ACCESS_TOO_FREQUENT( PathPlanningErrCode.ACCESS_TOO_FREQUENT, "访问过于频繁,请稍后再试" ),
+//
+// DISABLE_RESTRICT( PathPlanningErrCode.DISABLE_RESTRICT, "无法躲避限行区域,请重新规划" ),
+//
+// ERROR_BUF( PathPlanningErrCode.ERROR_BUF, "Buf数据格式错误" ),
+//
+// ERROR_CONNECTION( PathPlanningErrCode.ERROR_CONNECTION, "网络超时或网络失败。" ),
+//
+// ERROR_DISTANCE( PathPlanningErrCode.ERROR_DISTANCE, "起点/终点/途经点的距离太长(步行距离>100km,骑行距离>1200km)" ),
+//
+// ERROR_ENCODER( PathPlanningErrCode.ERROR_ENCODER, "算路服务端编码失败" ),
+//
+// ERROR_ENDPOINT( PathPlanningErrCode.ERROR_ENDPOINT, "终点错误" ),
+//
+// ERROR_NAVI_PARAMS( PathPlanningErrCode.ERROR_NAVI_PARAMS, "调用直接导航 没有算路 参数错误,缺失有效的导航路径,无法开始导航" ),
+//
+// ERROR_NOROADFORENDPOINT( PathPlanningErrCode.ERROR_NOROADFORENDPOINT, "终点没有找到道路" ),
+//
+// ERROR_NOROADFORSTARTPOINT( PathPlanningErrCode.ERROR_NOROADFORSTARTPOINT, "起点没有找到道路。" ),
+//
+// ERROR_NOROADFORWAYPOINT( PathPlanningErrCode.ERROR_NOROADFORWAYPOINT, "途径点没有找到道路" ),
+//
+// ERROR_PREVIEW( PathPlanningErrCode.ERROR_PREVIEW, "路径数据缺乏预览数据" ),
+//
+// ERROR_PROTOCOL( PathPlanningErrCode.ERROR_PROTOCOL, "请求协议非法。" ),
+//
+// ERROR_STARTPOINT( PathPlanningErrCode.ERROR_STARTPOINT, "起点错误" ),
+//
+// ERROR_WAYPOINT( PathPlanningErrCode.ERROR_WAYPOINT, "途经点错误" ),
+//
+// INSUFFICIENT_PRIVILEGES( PathPlanningErrCode.INSUFFICIENT_PRIVILEGES, "无权限访问此服务。" ),
+//
+// INVALID_PARAMS( PathPlanningErrCode.INVALID_PARAMS, "请求参数非法。" ),
+//
+// INVALID_USER_KEY( PathPlanningErrCode.INVALID_USER_KEY, "用户key非法或过期(请检查key是否正确)" ),
+//
+// INVALID_USER_SCODE( PathPlanningErrCode.INVALID_USER_SCODE, "MD5安全码未通过验证,需要开发者判定key绑定的SHA1,package是否与sdk包里的一致." ),
+//
+// OUT_OF_SERVICE( PathPlanningErrCode.OUT_OF_SERVICE, "使用路径规划服务接口时可能出现该问题,规划点(包括起点、终点、途经点)不在中国陆地范围内" ),
+//
+// OVER_DIRECTION_RANGE( PathPlanningErrCode.OVER_DIRECTION_RANGE, "使用路径规划服务接口时可能出现该问题,路线计算失败,通常是由于道路起点和终点距离过长导致" ),
+//
+// OVER_QUOTA( PathPlanningErrCode.OVER_QUOTA, "请求超出配额。" ),
+//
+// SERVICE_NOT_EXIST( PathPlanningErrCode.SERVICE_NOT_EXIST, "请求服务不存在。" ),
+//
+// SERVICE_RESPONSE_ERROR( PathPlanningErrCode.SERVICE_RESPONSE_ERROR, "请求服务响应错误。" ),
+//
+// UNKNOWN_ERROR( PathPlanningErrCode.UNKNOWN_ERROR, "未知错误(可能是由于连接的网络无法访问外网)" ),
+//
+// USERKEY_PLAT_NOMATCH( PathPlanningErrCode.USERKEY_PLAT_NOMATCH, "请求中使用的key与绑定平台不符,例如:开发者申请的是js api的key,却用来调web服务接口" );
+//
+// private int code;
+// private String errorMsg;
+//
+// PathPlanningErrorCodeConstants( int code, String errorMsg ) {
+// this.code = code;
+// this.errorMsg = errorMsg;
+// }
+//
+// public int getCode() {
+// return code;
+// }
+//
+// public String getErrorMsg() {
+// return errorMsg;
+// }
+//
+// public static String getErrorMsg( int code ) {
+// for ( PathPlanningErrorCodeConstants value : PathPlanningErrorCodeConstants.values() ) {
+// if ( value.getCode() == code ) {
+// return value.getErrorMsg();
+// }
+// }
+// return NONE.getErrorMsg();
+// }
+//
+//}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/TTSSpeaker.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/TTSSpeaker.java
new file mode 100644
index 0000000000..301b2d17f0
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/navi/TTSSpeaker.java
@@ -0,0 +1,120 @@
+//package com.mogo.map.impl.custom.navi;
+//
+//import android.text.TextUtils;
+//
+//import com.mogo.commons.AbsMogoApplication;
+//import com.mogo.commons.voice.AIAssist;
+//import com.mogo.commons.voice.IMogoVoiceCmdCallBack;
+//
+//import java.util.LinkedList;
+//
+///**
+// * @author congtaowang
+// * @since 2020-04-21
+// *
+// * 播报导航TTS
+// *
+// * 策略:队列缓存预播报的 tts,然后上一句播完后
+// */
+//public class TTSSpeaker implements IMogoVoiceCmdCallBack {
+//
+// private static volatile TTSSpeaker sInstance;
+//
+// private TTSSpeaker() {
+// }
+//
+// public static TTSSpeaker getInstance() {
+// if ( sInstance == null ) {
+// synchronized ( TTSSpeaker.class ) {
+// if ( sInstance == null ) {
+// sInstance = new TTSSpeaker();
+// }
+// }
+// }
+// return sInstance;
+// }
+//
+// public synchronized void release() {
+// sInstance = null;
+// }
+//
+// private LinkedList< String > mWaiting = new LinkedList<>();
+//
+// private String mLastTts = null;
+// private String mLastTtsId = null;
+//
+// public synchronized void speakTTS( String tts ) {
+// if ( TextUtils.isEmpty( tts ) ) {
+// return;
+// }
+// mWaiting.add( tts );
+// peekAndSpeak();
+// }
+//
+// public synchronized void shutUp() {
+// if ( mLastTtsId != null ) {
+// AIAssist.getInstance( AbsMogoApplication.getApp() ).shutUp( mLastTtsId, mLastTts );
+// mWaiting.clear();
+// mLastTtsId = null;
+// mLastTts = null;
+// }
+// }
+//
+// @Override
+// public void onCmdSelected( String cmd ) {
+//
+// }
+//
+// @Override
+// public void onCmdAction( String speakText ) {
+//
+// }
+//
+// @Override
+// public void onCmdCancel( String speakText ) {
+//
+// }
+//
+// @Override
+// public void onSpeakEnd( String speakText ) {
+//
+// }
+//
+// @Override
+// public void onSpeakSelectTimeOut( String speakText ) {
+//
+// }
+//
+// @Override
+// public void onTTSStart( String ttsId, String tts ) {
+// if ( TextUtils.equals( mLastTts, tts ) ) {
+// mLastTtsId = ttsId;
+// }
+// }
+//
+// @Override
+// public void onTTSEnd( String ttsId, String tts ) {
+// mLastTtsId = null;
+// peekAndSpeak();
+// }
+//
+// @Override
+// public void onTTSError( String ttsId, String tts ) {
+// mLastTtsId = null;
+// peekAndSpeak();
+// }
+//
+// private synchronized void peekAndSpeak() {
+// if ( mWaiting.isEmpty() ) {
+// mLastTts = null;
+// mLastTtsId = null;
+// return;
+// }
+// if ( mLastTtsId != null ) {
+// // 上一句还没有播完
+// return;
+// }
+// mLastTts = mWaiting.pop();
+// AIAssist.getInstance( AbsMogoApplication.getApp() ).speakTTSAndDuck( mLastTts, this );
+// }
+//}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/overlay/AMapPolylineWrapper.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/overlay/AMapPolylineWrapper.java
new file mode 100644
index 0000000000..a4c8e2e538
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/overlay/AMapPolylineWrapper.java
@@ -0,0 +1,197 @@
+package com.mogo.map.impl.custom.overlay;
+
+
+import com.mogo.map.MogoLatLng;
+import com.mogo.map.impl.custom.utils.ObjectUtils;
+import com.mogo.map.overlay.IMogoPolyline;
+import com.mogo.map.overlay.MogoPolylineOptions;
+import com.zhidaoauto.map.sdk.open.poyline.Polyline;
+import com.zhidaoauto.map.sdk.open.poyline.PolylineOptions;
+import com.zhidaoauto.map.sdk.open.query.LonLatPoint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author congtaowang
+ * @since 2020-03-10
+ *
+ * 描述
+ */
+public class AMapPolylineWrapper implements IMogoPolyline {
+
+ private Polyline mPolyline;
+ private MogoPolylineOptions mOptions;
+ private boolean mIsDestroyed = false;
+
+ public AMapPolylineWrapper( Polyline mPolyline,
+ MogoPolylineOptions mOptions ) {
+ this.mPolyline = mPolyline;
+ this.mOptions = mOptions;
+ }
+
+ @Override
+ public void destroy() {
+ remove();
+ }
+
+ @Override
+ public void remove() {
+ if ( mPolyline != null ) {
+ mPolyline.remove();
+ }
+ mIsDestroyed = true;
+ }
+
+ @Override
+ public String getId() {
+ if ( mPolyline != null ) {
+ return mPolyline.getId();
+ }
+ return null;
+ }
+
+ @Override
+ public void setPoints( List< MogoLatLng > lonLats ) {
+ if ( lonLats == null || lonLats.isEmpty() ) {
+ mPolyline.setPoints( new ArrayList
+// * 描述
+// */
+//public abstract class OnRouteSearchListenerAdapter implements RouteSearch.OnRouteSearchListener {
+//
+// @Override
+// public void onBusRouteSearched( BusRouteResult busRouteResult, int i ) {
+//
+// }
+//
+// @Override
+// public void onDriveRouteSearched( DriveRouteResult driveRouteResult, int i ) {
+//
+// }
+//
+// @Override
+// public void onWalkRouteSearched( WalkRouteResult walkRouteResult, int i ) {
+//
+// }
+//
+// @Override
+// public void onRideRouteSearched( RideRouteResult rideRouteResult, int i ) {
+//
+// }
+//}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/overlay/RouteOverLayWrapper.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/overlay/RouteOverLayWrapper.java
new file mode 100644
index 0000000000..02cca9c629
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/overlay/RouteOverLayWrapper.java
@@ -0,0 +1,210 @@
+//package com.mogo.map.impl.custom.overlay;
+//
+//import android.content.Context;
+//import android.graphics.BitmapFactory;
+//import android.util.Log;
+//
+//import com.amap.api.maps.AMap;
+//import com.amap.api.maps.model.NavigateArrowOptions;
+//import com.amap.api.maps.model.Polyline;
+//import com.amap.api.navi.model.AMapNaviLocation;
+//import com.amap.api.navi.model.AMapNaviPath;
+//import com.amap.api.navi.model.NaviInfo;
+//import com.amap.api.navi.model.RouteOverlayOptions;
+//import com.amap.api.navi.view.RouteOverLay;
+//import com.mogo.map.impl.custom.utils.MapStyleUtils;
+//import com.mogo.utils.logger.Logger;
+//
+//import java.lang.ref.WeakReference;
+//import java.lang.reflect.Field;
+//
+///**
+// * @author congtaowang
+// * @since 2019-10-04
+// *
+// * 路径覆盖物
+// */
+//public class RouteOverLayWrapper {
+//
+// private static final String TAG = "RouteOverLayWrapper";
+//
+// private final WeakReference< Context > mContextRef;
+// private final AMap mAMap;
+// private final AMapNaviPath mPath;
+//
+// private RouteOverLay mRouteOverLay;
+// private boolean mIsRemoved = true;
+//
+// private boolean mIsTrafficLightsVisible = true;
+// private int mStartBitmapResId = 0;
+// private int mEndBitmapResId = 0;
+// private int mZIndex = 0;
+//
+// private static RouteOverlayOptions sOptions;
+//
+// public RouteOverLayWrapper( Context context,
+// AMap mAMap,
+// AMapNaviPath mPath ) {
+// this.mContextRef = new WeakReference<>( context );
+// this.mAMap = mAMap;
+// this.mPath = mPath;
+// }
+//
+// public void addToMap() {
+// if ( mContextRef == null || mContextRef.get() == null ) {
+// return;
+// }
+// mRouteOverLay = new RouteOverLay( mAMap, mPath, mContextRef.get() );
+// if ( sOptions == null ) {
+// sOptions = MapStyleUtils.getRouteOverlayOptions();
+// }
+// mRouteOverLay.setRouteOverlayOptions( sOptions );
+// mRouteOverLay.setTrafficLine( true );
+// mRouteOverLay.setRouteOverlayVisible( true );
+// mRouteOverLay.setTrafficLightsVisible( true );
+// mRouteOverLay.setArrowOnRoute( true );
+// mRouteOverLay.setZindex( mZIndex );
+// mRouteOverLay.setNaviArrowVisible( true );
+// mRouteOverLay.setLightsVisible( true );
+// mRouteOverLay.setTrafficLightsVisible( mIsTrafficLightsVisible );
+// hookRouteArrow();
+//
+// if ( mStartBitmapResId != 0 ) {
+// try {
+// mRouteOverLay.setStartPointBitmap( BitmapFactory.decodeResource( mContextRef.get().getResources(), mStartBitmapResId ) );
+// } catch ( Exception e ) {
+// e.printStackTrace();
+// }
+// } else {
+// mRouteOverLay.setStartPointBitmap( null );
+// }
+//
+// if ( mEndBitmapResId != 0 ) {
+// try {
+// mRouteOverLay.setEndPointBitmap( BitmapFactory.decodeResource( mContextRef.get().getResources(), mEndBitmapResId ) );
+// } catch ( Exception e ) {
+// e.printStackTrace();
+// }
+// } else {
+// mRouteOverLay.setEndPointBitmap( null );
+// }
+//
+// mRouteOverLay.addToMap();
+// mIsRemoved = false;
+// }
+//
+// public void remove() {
+// Log.d( TAG, "remove" );
+// if ( mRouteOverLay != null ) {
+// try {
+// mRouteOverLay.removeFromMap();
+// mIsRemoved = true;
+// } catch ( Exception e ) {
+// e.printStackTrace();
+// }
+// }
+// }
+//
+// /**
+// * 设置透明度
+// *
+// * @param alpha
+// */
+// public void setTransparency( float alpha ) {
+// if ( mRouteOverLay != null ) {
+// mRouteOverLay.setTransparency( alpha );
+// }
+// }
+//
+// public RouteOverLayWrapper setTrafficLightsVisible( boolean visible ) {
+// mIsTrafficLightsVisible = visible;
+// return this;
+// }
+//
+// public RouteOverLayWrapper setStartBitmap( int startBitmapResId ) {
+// mStartBitmapResId = startBitmapResId;
+// return this;
+// }
+//
+// public RouteOverLayWrapper setEndBitmap( int endBitmapResId ) {
+// mEndBitmapResId = endBitmapResId;
+// return this;
+// }
+//
+// public RouteOverLayWrapper setZIndex( int zIndex ) {
+// mZIndex = zIndex;
+// return this;
+// }
+//
+// public int getZIndex() {
+// return mZIndex;
+// }
+//
+// @Override
+// protected void finalize() throws Throwable {
+// super.finalize();
+// mIsRemoved = true;
+// }
+//
+// public synchronized boolean isRemoved() {
+// return mIsRemoved;
+// }
+//
+// public void updatePolyline( AMapNaviLocation aMapNaviLocation ) {
+// if ( mIsRemoved ) {
+// return;
+// }
+// if ( mRouteOverLay != null ) {
+// mRouteOverLay.updatePolyline( aMapNaviLocation );
+// }
+// }
+//
+// public void drawArrow( NaviInfo naviInfo ) {
+// Log.d( TAG, "drawArrow" );
+// if ( mIsRemoved ) {
+// return;
+// }
+// if ( naviInfo == null ) {
+// return;
+// }
+// if ( mRouteOverLay != null ) {
+// try {
+// mRouteOverLay.drawArrow( mRouteOverLay.getArrowPoints( naviInfo.getCurStep() ) );
+// } catch ( Exception e ) {
+// e.printStackTrace();
+// }
+// }
+// }
+//
+// private void hookRouteArrow() {
+// if ( mRouteOverLay != null && sOptions != null ) {
+// try {
+// Field field = mRouteOverLay.getClass().getDeclaredField( "naviArrow" );
+// field.setAccessible( true );
+// field.set( mRouteOverLay, mAMap.addNavigateArrow( new NavigateArrowOptions().topColor( sOptions.getArrowColor() ).width( sOptions.getLineWidth() ).sideColor( sOptions.getArrowSideColor() ) ) );
+// Logger.d( TAG, "hook 成功。" );
+// } catch ( Exception e ) {
+// e.printStackTrace();
+// }
+// }
+// }
+//
+// public Polyline getTrafficColorfulPolyline() {
+// if ( mRouteOverLay != null ) {
+// return mRouteOverLay.mTrafficColorfulPolyline;
+// }
+// return null;
+// }
+//
+// public void destroy() {
+// Log.d( TAG, "destroy" );
+// if ( mRouteOverLay != null ) {
+// try {
+// mRouteOverLay.destroy();
+// mIsRemoved = true;
+// } catch ( Exception e ) {
+// e.printStackTrace();
+// }
+// }
+// }
+//}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/overlay/RouteOverlay.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/overlay/RouteOverlay.java
new file mode 100644
index 0000000000..880a5b7c6b
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/overlay/RouteOverlay.java
@@ -0,0 +1,236 @@
+//package com.mogo.map.impl.custom.overlay;
+//
+//import android.content.Context;
+//import android.graphics.Bitmap;
+//import android.graphics.Color;
+//
+//import com.amap.api.maps.AMap;
+//import com.amap.api.maps.CameraUpdateFactory;
+//import com.amap.api.maps.model.BitmapDescriptor;
+//import com.amap.api.maps.model.BitmapDescriptorFactory;
+//import com.amap.api.maps.model.LatLng;
+//import com.amap.api.maps.model.LatLngBounds;
+//import com.amap.api.maps.model.Marker;
+//import com.amap.api.maps.model.MarkerOptions;
+//import com.amap.api.maps.model.Polyline;
+//import com.amap.api.maps.model.PolylineOptions;
+//import com.mogo.map.impl.custom.R;
+//
+//import java.util.ArrayList;
+//import java.util.List;
+//
+//
+//public class RouteOverlay {
+// protected List
+// * 给定起点、途经点,规划路径
+// */
+//public class RouteOverlayHelper {
+//
+// private static final String TAG = "RouteOverlayHelper";
+//
+// private static volatile RouteOverlayHelper sInstance;
+//
+// private DrivingRouteOverlay mDrivingRouteOverlay;
+//
+// private RouteOverlayHelper() {
+// }
+//
+// public static RouteOverlayHelper getInstance() {
+// if ( sInstance == null ) {
+// synchronized ( RouteOverlayHelper.class ) {
+// if ( sInstance == null ) {
+// sInstance = new RouteOverlayHelper();
+// }
+// }
+// }
+// return sInstance;
+// }
+//
+// public synchronized void release() {
+// sInstance = null;
+// }
+//
+// public void addRouteWay( final Context context, MogoLatLng start, MogoLatLng end, List< MogoLatLng > wayPoints ) {
+// if ( wayPoints == null || wayPoints.isEmpty() ) {
+// return;
+// }
+// if ( InterceptorHandler.getInstance().ignoreDrawRouteOverlay( context ) ) {
+// Logger.w( TAG, "naviing." );
+// return;
+// }
+//
+// if ( mDrivingRouteOverlay != null ) {
+// mDrivingRouteOverlay.removeFromMap();
+// }
+//
+// RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo( new LatLonPoint( start.lat, start.lng ),
+// new LatLonPoint( end.lat, end.lng ) );
+// final List< LatLonPoint > ways = new ArrayList<>();
+// for ( MogoLatLng wayPoint : wayPoints ) {
+// ways.add( new LatLonPoint( wayPoint.lat, wayPoint.lng ) );
+// }
+// RouteSearch.DriveRouteQuery query = new RouteSearch.DriveRouteQuery( fromAndTo, 0, ways, null, "" );
+// RouteSearch routeSearch = new RouteSearch( context );
+// routeSearch.calculateDriveRouteAsyn( query );
+// routeSearch.setRouteSearchListener( new OnRouteSearchListenerAdapter() {
+// @Override
+// public void onDriveRouteSearched( DriveRouteResult driveRouteResult, int i ) {
+// super.onDriveRouteSearched( driveRouteResult, i );
+// if ( i != 1000 ) {
+// Logger.e( TAG, "算路失败. code = %d", i );
+// return;
+// }
+// mDrivingRouteOverlay = new DrivingRouteOverlay( context, AMapWrapper.getAMap(),
+// driveRouteResult.getPaths().get( 0 ),
+// driveRouteResult.getStartPos(),
+// driveRouteResult.getTargetPos(),
+// null );
+// mDrivingRouteOverlay.setNodeIconVisibility( false );
+// mDrivingRouteOverlay.setIsColorfulline( false );
+// mDrivingRouteOverlay.addToMap();
+// mDrivingRouteOverlay.zoomToSpan();
+// }
+// } );
+// }
+//
+// public void removeAll() {
+// if ( mDrivingRouteOverlay != null ) {
+// mDrivingRouteOverlay.removeFromMap();
+// }
+// mDrivingRouteOverlay = null;
+// }
+//}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/search/GeocodeSearchClient.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/search/GeocodeSearchClient.java
new file mode 100644
index 0000000000..6b098f89bf
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/search/GeocodeSearchClient.java
@@ -0,0 +1,110 @@
+package com.mogo.map.impl.custom.search;
+
+import android.content.Context;
+
+import com.mogo.map.exception.MogoMapException;
+import com.mogo.map.impl.custom.utils.ObjectUtils;
+import com.mogo.map.search.geo.IMogoGeoSearch;
+import com.mogo.map.search.geo.IMogoGeoSearchListener;
+import com.mogo.map.search.geo.MogoGeocodeAddress;
+import com.mogo.map.search.geo.MogoRegeocodeAddress;
+import com.mogo.map.search.geo.query.MogoGeocodeQuery;
+import com.mogo.map.search.geo.query.MogoRegeocodeQuery;
+import com.zhidaoauto.map.sdk.open.exception.MapException;
+import com.zhidaoauto.map.sdk.open.query.GeocodeAddress;
+import com.zhidaoauto.map.sdk.open.query.GeocodeResult;
+import com.zhidaoauto.map.sdk.open.query.GeocodeSearch;
+import com.zhidaoauto.map.sdk.open.query.OnGeocodeSearchListener;
+import com.zhidaoauto.map.sdk.open.query.RegeocodeAddress;
+import com.zhidaoauto.map.sdk.open.query.RegeocodeResult;
+import com.zhidaoauto.map.sdk.open.query.RegeocodeQuery;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author congtaowang
+ * @since 2019-12-19
+ *
+ * 地理编码/逆地理编码高德实现
+ */
+public class GeocodeSearchClient implements IMogoGeoSearch, OnGeocodeSearchListener {
+
+ private GeocodeSearch mClient;
+ private IMogoGeoSearchListener mListener;
+
+ public GeocodeSearchClient( Context context ) {
+ mClient = new GeocodeSearch( context );
+ mClient.setOnGeocodeSearchListener( this );
+ }
+
+ @Override
+ public void setGeoSearchListener( IMogoGeoSearchListener listener ) {
+ mListener = listener;
+ }
+
+ @Override
+ public MogoRegeocodeAddress getFromLocation( MogoRegeocodeQuery query ) throws MogoMapException {
+ try {
+ RegeocodeQuery regeocodeQuery = ObjectUtils.fromMogo(query);
+ RegeocodeAddress regeocodeAddress = mClient.getFromLocation(regeocodeQuery);
+ return ObjectUtils.fromAMap( regeocodeAddress );
+ } catch ( Exception e ) {
+ throw new MogoMapException( e );
+ }
+ }
+
+ @Override
+ public List< MogoGeocodeAddress > getFromLocationName( MogoGeocodeQuery query ) throws MogoMapException {
+ try {
+ List
+ * 高德地图 inputtips搜索实现
+ */
+public class InputtipsSearch implements IMogoInputtipsSearch, InputtipsListener {
+
+ private static final String TAG = "InputtipsSearch";
+
+ private Inputtips mClient;
+ private InputtipsQuery mQuery;
+ private IMogoInputtipsListener mListener;
+
+ public InputtipsSearch(Context context, MogoInputtipsQuery query) {
+ mQuery = ObjectUtils.fromMogo(query);
+ mClient = new Inputtips(context, mQuery);
+ mClient.setInputtipsListener(this);
+ }
+
+ @Override
+ public void setQuery(MogoInputtipsQuery query) {
+ this.mQuery = ObjectUtils.fromMogo(query);
+ }
+
+ @Override
+ public void setInputtipsListener(IMogoInputtipsListener listener) {
+ this.mListener = listener;
+ }
+
+ @Override
+ public void requestInputtipsAsyn() {
+ if (mClient != null) {
+ mClient.requestInputtipsAsyn();
+ }
+ }
+
+ @Override
+ public void onGetInputtips(List list, int i) {
+ if (i == 0) {
+ if (mListener != null) {
+ mListener.onGetInputtips(getResult(list));
+ }
+ } else {
+ Logger.e(TAG, "errorcode = " + i);
+ }
+ }
+
+ private List
+ * poi搜索高德实现
+ *
+ * 错误码对照表:https://lbs.amap.com/api/android-sdk/guide/map-tools/error-code
+ */
+public class PoiSearchClient implements IMogoPoiSearch, OnPoiSearchListener {
+
+ private static final String TAG = "PoiSearchClient";
+
+ private MogoPoiSearchQuery mQuery;
+ private PoiSearch mClient;
+ private IMogoPoiSearchListener mListener;
+ private MogoSearchBound mBound;
+
+ public PoiSearchClient( Context context, MogoPoiSearchQuery query ) {
+ mQuery = query;
+ mClient = new PoiSearch( context, ObjectUtils.fromMogo( mQuery ) );
+ mClient.setOnPoiSearchListener( this );
+ }
+
+ @Override
+ public void setPoiSearchListener( IMogoPoiSearchListener listener ) {
+ mListener = listener;
+ }
+
+ @Override
+ public void searchPOIAsyn() {
+ if ( mClient != null ) {
+ mClient.searchPOIAsyn();
+ }
+ }
+
+ @Override
+ public MogoPoiResult searchPOI() throws MogoMapException {
+ if ( mClient != null ) {
+ try {
+ PoiSearchResult search = mClient.searchPOI();
+ return ObjectUtils.fromAMap( search );
+ } catch ( Exception e ) {
+ throw new MogoMapException( e );
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void setQuery( MogoPoiSearchQuery query ) {
+ mQuery = query;
+ if ( mClient != null ) {
+ mClient.setQuery( ObjectUtils.fromMogo( mQuery ) );
+ }
+ }
+
+ @Override
+ public MogoPoiItem searchPOIId( String poiId ) throws MogoMapException {
+ if ( mClient != null ) {
+ try {
+ PoiItem poiItem = mClient.searchPOIId( poiId );
+ return ObjectUtils.fromAMap( poiItem );
+ } catch ( Exception e ) {
+ throw new MogoMapException( e );
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void searchPOIIdAsyn( String poiId ) {
+ if ( mClient != null ) {
+ mClient.searchPOIIdAsyn( poiId );
+ }
+ }
+
+ @Override
+ public void setBound( MogoSearchBound bound ) {
+ mBound = bound;
+ if ( mClient != null ) {
+ mClient.setBound( ObjectUtils.fromMogo( mBound ) );
+ }
+ }
+
+ @Override
+ public void onPoiSearched( PoiSearchResult poiResult, int errorCode ) {
+ if ( errorCode != 0 ) {
+ Logger.e( TAG, "errorcode is %d", errorCode );
+ }
+ if ( mListener != null ) {
+ mListener.onPoiSearched( ObjectUtils.fromAMap( poiResult ), errorCode );
+ }
+ }
+
+ @Override
+ public void onPoiItemSearched( PoiItem poiItem, int errorCode ) {
+ if ( errorCode != 0 ) {
+ Logger.e( TAG, "errorcode is %d", errorCode );
+ }
+ if ( mListener != null ) {
+ mListener.onPoiItemSearched( ObjectUtils.fromAMap( poiItem ), errorCode );
+ }
+ }
+
+ @Override
+ public void destroy() {
+ mQuery = null;
+ mClient = null;
+ mListener = null;
+ mBound = null;
+ }
+
+ @Override
+ public void onPoiCategorySearched(@Nullable List
+ * 描述
+ */
+public class AMapUIController implements IMogoMapUIController {
+
+ private static final String TAG = "AMapUIController";
+
+ private static volatile AMapUIController sInstance;
+
+ private IMogoMapUIController mClient;
+
+ private AMapUIController() {
+ }
+
+ public static AMapUIController getInstance() {
+ if (sInstance == null) {
+ synchronized (AMapUIController.class) {
+ if (sInstance == null) {
+ sInstance = new AMapUIController();
+ }
+ }
+ }
+ return sInstance;
+ }
+
+ public void initClient(IMogoMapUIController client) {
+ this.mClient = client;
+ }
+
+ public synchronized void release() {
+ sInstance = null;
+ }
+
+ @Override
+ public void setTrafficEnabled(boolean visible) {
+ if (mClient != null) {
+ mClient.setTrafficEnabled(visible);
+ }
+ }
+
+ @Override
+ public MapControlResult changeZoom( boolean zoom) {
+ if (mClient != null) {
+ return mClient.changeZoom(zoom);
+ }
+ return MapControlResult.ERROR;
+ }
+
+ @Override
+ public MapControlResult changeZoom(float zoom) {
+ if (mClient != null) {
+ return mClient.changeZoom(zoom);
+ }
+ return MapControlResult.ERROR;
+ }
+
+ @Override
+ public void changeMapMode(EnumMapUI mode) {
+ if (mClient != null) {
+ mClient.changeMapMode(mode);
+ }
+ }
+
+ @Override
+ public void moveToCenter(MogoLatLng latLng, boolean animate) {
+ if (mClient != null) {
+ mClient.moveToCenter(latLng, animate);
+ }
+ }
+
+ @Override
+ public void showMyLocation(boolean visible) {
+ if (mClient != null) {
+ mClient.showMyLocation(visible);
+ }
+ }
+
+ @Override
+ public void showMyLocation( View view ) {
+ if ( mClient != null ) {
+ mClient.showMyLocation( view );
+ }
+ }
+
+ @Override
+ public void recoverLockMode() {
+ if (mClient != null) {
+ mClient.recoverLockMode();
+ }
+ }
+
+ @Override
+ public void loseLockMode() {
+ if ( mClient != null ) {
+ mClient.loseLockMode();
+ }
+ }
+
+ @Override
+ public void setLockZoom(int var1) {
+ if (mClient != null) {
+ mClient.setLockZoom(var1);
+ }
+ }
+
+ @Override
+ public void displayOverview( Rect bounds ) {
+ if (mClient != null) {
+ mClient.displayOverview(bounds);
+ }
+ }
+
+ @Override
+ public float getScalePerPixel() {
+ if (mClient != null) {
+ return mClient.getScalePerPixel();
+ }
+ return 0;
+ }
+
+ @Override
+ public float getZoomLevel() {
+ if (mClient != null) {
+ return mClient.getZoomLevel();
+ }
+ return 0;
+ }
+
+ @Override
+ public MogoLatLng getCameraNorthEastPosition() {
+ if (mClient != null) {
+ return mClient.getCameraNorthEastPosition();
+ }
+ return null;
+ }
+
+ @Override
+ public MogoLatLng getCameraSouthWestPosition() {
+ if (mClient != null) {
+ return mClient.getCameraSouthWestPosition();
+ }
+ return null;
+ }
+
+ @Override public MogoLatLng getWindowCenterLocation() {
+ if (mClient != null) {
+ return mClient.getWindowCenterLocation();
+ }
+ return null;
+ }
+
+ @Override
+ public void setPointToCenter(double mapCenterX, double mapCenterY) {
+ if (mClient != null) {
+// mClient.setPointToCenter(mapCenterX, mapCenterY);
+ }
+ }
+
+ @Override
+ public Point getLocationPointInScreen(MogoLatLng latLng) {
+ if (mClient != null) {
+ return mClient.getLocationPointInScreen(latLng);
+ }
+ return null;
+ }
+
+ @Override
+ public MogoLatLng getLocationMogoLatLngInScreen(Point point) {
+ if (mClient != null) {
+ return mClient.getLocationMogoLatLngInScreen(point);
+ }
+ return null;
+ }
+
+ @Override
+ public void startJumpAnimation(IMogoMarker marker, float high, Interpolator interpolator,
+ long duration) {
+ if (mClient != null) {
+ mClient.startJumpAnimation(marker, high, interpolator, duration);
+ }
+ }
+
+ @Override
+ public void setRenderFps(int fps) {
+ if (mClient != null) {
+ mClient.setRenderFps(fps);
+ }
+ }
+
+ @Override
+ public void showBounds( String tag, MogoLatLng carPosition, List< MogoLatLng > lonLats, Rect bound, boolean lockCarPosition ) {
+ if ( mClient != null ) {
+ mClient.showBounds( tag, carPosition, lonLats, bound, lockCarPosition );
+ }
+ }
+
+ @Override
+ public void forceRender() {
+ if (mClient != null) {
+ mClient.forceRender();
+ }
+ }
+
+ @Override
+ public float calculateLineDistance( MogoLatLng p1, MogoLatLng p2 ) throws Exception {
+ if ( mClient != null ) {
+ return mClient.calculateLineDistance( p1, p2 );
+ }
+ return 0;
+ }
+
+ @Override
+ public EnumMapUI getCurrentUiMode() {
+ if ( mClient != null ) {
+ return mClient.getCurrentUiMode();
+ }
+ return null;
+ }
+
+ @Override
+ public void changeMyLocation( Location location ) {
+ if ( mClient != null ) {
+ mClient.changeMyLocation( location );
+ }
+ }
+
+ @Override
+ public boolean isCarLocked() {
+ if ( mClient != null ) {
+ return mClient.isCarLocked();
+ }
+ return false;
+ }
+
+ @Override
+ public void setCarCursorOption( CarCursorOption option ) {
+ if ( mClient != null ) {
+ mClient.setCarCursorOption( option );
+ }
+ }
+
+ @Override
+ public MapCameraPosition getMapCameraPosition() {
+ if ( mClient != null ) {
+ return mClient.getMapCameraPosition();
+ }
+ return null;
+ }
+
+ @Override
+ public void changeBearing( float bearing ) {
+ if ( mClient != null ) {
+ mClient.changeBearing( bearing );
+ }
+ }
+}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/utils/IconTypeUtils.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/utils/IconTypeUtils.java
new file mode 100644
index 0000000000..dc243f78e4
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/utils/IconTypeUtils.java
@@ -0,0 +1,95 @@
+package com.mogo.map.impl.custom.utils;
+
+import android.content.Context;
+import android.util.SparseArray;
+
+
+/**
+ * @author congtaowang
+ * @since 2019-09-29
+ *
+ * 描述
+ */
+public class IconTypeUtils {
+
+ private static SparseArray< String > sIconName = new SparseArray<>();
+
+ static {
+// sIconName.put( IconType.ARRIVED_DESTINATION, "到达目的地" );
+// sIconName.put( IconType.ARRIVED_SERVICE_AREA, "到达服务区" );
+// sIconName.put( IconType.ARRIVED_TOLLGATE, "到达收费站" );
+// sIconName.put( IconType.ARRIVED_TUNNEL, "到达隧道" );
+// sIconName.put( IconType.ARRIVED_WAYPOINT, "到达途经点" );
+// sIconName.put( IconType.BRIDGE, "通过桥" );
+// sIconName.put( IconType.BY_ELEVATOR, "电梯换层" );
+// sIconName.put( IconType.BY_ESCALATOR, "扶梯换层" );
+// sIconName.put( IconType.BY_STAIR, "楼梯换层" );
+// sIconName.put( IconType.CABLEWAY, "通过索道" );
+// sIconName.put( IconType.CHANNEL, "通过通道" );
+// sIconName.put( IconType.CROSSWALK, "通过人行横道" );
+// sIconName.put( IconType.CRUISE_ROUTE, "通过游船路线" );
+// sIconName.put( IconType.DEFAULT, "自车" );
+// sIconName.put( IconType.ENTER_BUILDING, "进入建筑物" );
+// sIconName.put( IconType.ENTER_ROUNDABOUT, "进入环岛" );
+// sIconName.put( IconType.ENTRY_LEFT_RING, "进入环岛" );
+// sIconName.put( IconType.ENTRY_LEFT_RING_CONTINUE, "绕环岛直行" );
+// sIconName.put( IconType.ENTRY_LEFT_RING_LEFT, "绕环岛左转" );
+// sIconName.put( IconType.ENTRY_LEFT_RING_RIGHT, "绕环岛右转" );
+// sIconName.put( IconType.ENTRY_LEFTRINGU_TURN, "绕环岛调头" );
+// sIconName.put( IconType.ENTRY_RING_CONTINUE, "绕环岛直行" );
+// sIconName.put( IconType.ENTRY_RING_LEFT, "绕环岛左转" );
+// sIconName.put( IconType.ENTRY_RING_RIGHT, "绕环岛右转" );
+// sIconName.put( IconType.ENTRY_RING_UTURN, "绕环岛调头" );
+// sIconName.put( IconType.FERRY, "通过轮渡" );
+// sIconName.put( IconType.LADDER, "通过阶梯" );
+// sIconName.put( IconType.LEAVE_BUILDING, "离开建筑物" );
+// sIconName.put( IconType.LEAVE_LEFT_RING, "驶出环岛" );
+// sIconName.put( IconType.LEFT, "左转" );
+// sIconName.put( IconType.LEFT_BACK, "左后" );
+// sIconName.put( IconType.LEFT_FRONT, "左前方" );
+// sIconName.put( IconType.LEFT_TURN_AROUND, "左转掉头" );
+// sIconName.put( IconType.LIFT, "通过直梯" );
+// sIconName.put( IconType.LOW_CROSS, "通过普通路口" );
+// sIconName.put( IconType.LOW_TRAFFIC_CROSS, "红绿灯路口" );
+// sIconName.put( IconType.NONE, "无定义" );
+// sIconName.put( IconType.OUT_ROUNDABOUT, "驶出环岛" );
+// sIconName.put( IconType.OVERPASS, "通过过街天桥" );
+// sIconName.put( IconType.PARK, "通过公园" );
+// sIconName.put( IconType.RIGHT, "右转" );
+// sIconName.put( IconType.RIGHT_BACK, "右后方" );
+// sIconName.put( IconType.RIGHT_FRONT, "右前方" );
+// sIconName.put( IconType.SIGHTSEEING_BUSLINE, "通过观光车路线" );
+// sIconName.put( IconType.SKY_CHANNEL, "通过空中通道" );
+// sIconName.put( IconType.SLIDEWAY, "通过滑道" );
+// sIconName.put( IconType.SLOPE, "通过斜坡" );
+// sIconName.put( IconType.SPECIAL_CONTINUE, "顺行" );
+// sIconName.put( IconType.SQUARE, "通过广场" );
+// sIconName.put( IconType.STAIRCASE, "通过扶梯" );
+// sIconName.put( IconType.STRAIGHT, "直行" );
+// sIconName.put( IconType.SUBWAY, "通过地铁通道" );
+// sIconName.put( IconType.U_TURN_RIGHT, "右转掉头" );
+// sIconName.put( IconType.UNDERPASS, "通过地下通道" );
+// sIconName.put( IconType.WALK_ROAD, "通过行人道路" );
+ }
+
+ private static int lastIconType = 0;
+ private static int lastIconResId = 0;
+
+ public static String getNameByIconType( int iconType ) {
+ return sIconName.get( iconType );
+ }
+
+ public static int getResIdByIconType( Context context, int iconType ) {
+ try {
+ if ( iconType == lastIconType ) {
+ return lastIconResId;
+ }
+ int target = context.getResources().getIdentifier( "ic_" + iconType, "drawable", context.getPackageName() );
+ lastIconType = iconType;
+ lastIconResId = target;
+ return target;
+ } catch ( Exception e ) {
+ return -1;
+ }
+ }
+}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/utils/MapStyleUtils.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/utils/MapStyleUtils.java
new file mode 100644
index 0000000000..ae90dd43d4
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/utils/MapStyleUtils.java
@@ -0,0 +1,71 @@
+//package com.mogo.map.impl.custom.utils;
+//
+//import android.graphics.Bitmap;
+//import android.graphics.Color;
+//
+//import com.amap.api.navi.model.RouteOverlayOptions;
+//import com.mogo.commons.AbsMogoApplication;
+//import com.mogo.map.impl.custom.R;
+//
+///**
+// * @author congtaowang
+// * @since 2019-10-04
+// *
+// * 描述
+// */
+//public class MapStyleUtils {
+//
+// enum ColorEnum {
+// route_overlay_line_normal( Color.parseColor( "#00C96D" ) ),
+// route_overlay_line_unknown( Color.parseColor( "#3CD26E" ) ),
+// route_overlay_line_slow( Color.parseColor( "#ECC71F" ) ),
+// route_overlay_line_very_traffic( Color.parseColor( "#E16262" ) ),
+// route_overlay_line_traffic( Color.parseColor( "#E88181" ) ),
+// transparent( Color.parseColor( "#00000000" ) ),
+// light_gray( Color.parseColor( "#334BD089" ) );
+//
+// private int color;
+//
+// ColorEnum( int color ) {
+// this.color = color;
+// }
+//
+// public int getColor() {
+// return color;
+// }
+// }
+//
+// public static RouteOverlayOptions getRouteOverlayOptions() {
+// RouteOverlayOptions options = new RouteOverlayOptions();
+// // 设置导航线路的宽度
+// options.setLineWidth( AbsMogoApplication.getApp().getResources().getDimension(R.dimen.path_width) );
+//// // 设置交通状况情况良好下的纹理位图
+//// options.setSmoothTraffic( colorToBitmap( ColorEnum.route_overlay_line_normal.getColor() ) );
+//// // 设置路线的图标
+//// options.setNormalRoute( colorToBitmap( ColorEnum.route_overlay_line_normal.getColor() ) );
+//// // 设置交通状况未知下的纹理位图
+//// options.setUnknownTraffic( colorToBitmap( ColorEnum.route_overlay_line_unknown.getColor() ) );
+//// // 设置交通状况迟缓下的纹理位图
+//// options.setSlowTraffic( colorToBitmap( ColorEnum.route_overlay_line_slow.getColor() ) );
+//// // 设置交通状况非常拥堵下的纹理位图
+//// options.setVeryJamTraffic( colorToBitmap( ColorEnum.route_overlay_line_very_traffic.getColor() ) );
+//// // 设置交通状况拥堵下的纹理位图
+//// options.setJamTraffic( colorToBitmap( ColorEnum.route_overlay_line_traffic.getColor() ) );
+//// // 设置浮于道路上的『小箭头』图标的纹理位图
+//// options.setArrowOnTrafficRoute( colorToBitmap( ColorEnum.transparent.getColor() ) );
+// // 自定义走过路线纹理,默认走过路线置灰功能为关,需要在AMapNaviViewOptions.setAfterRouteAutoGray(boolean)打开,该方法才生效
+// options.setPassRoute( colorToBitmap( ColorEnum.light_gray.getColor() ) );
+//// // 设置路线虚线纹理
+//// options.setFairWayRes( colorToBitmap( ColorEnum.route_overlay_line_normal.getColor() ) );
+// options.setArrowColor( Color.parseColor( "#92C9FF" ) ); // 高德地图内部配置颜色
+// options.setArrowSideColor( Color.parseColor( "#4F9BF2" ) ); // 高德地图内部配置颜色
+// return options;
+// }
+//
+// public static Bitmap colorToBitmap( int color ) {
+// Bitmap.Config config = Bitmap.Config.ARGB_8888;
+// Bitmap bitmap = Bitmap.createBitmap( 1, 1, config );
+// bitmap.eraseColor( color );
+// return bitmap;
+// }
+//}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/utils/MogoMapUtils.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/utils/MogoMapUtils.java
new file mode 100644
index 0000000000..a539cc63bc
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/utils/MogoMapUtils.java
@@ -0,0 +1,132 @@
+package com.mogo.map.impl.custom.utils;
+
+import com.zhidaoauto.map.sdk.open.query.LonLatPoint;
+
+/**
+ * @author congtaowang
+ * @since 2020-03-04
+ *
+ * 地图工具类
+ */
+public class MogoMapUtils {
+
+ private static final String TAG = "MogoMapUtils";
+
+// public static LatLngBounds getLatLngBounds( MogoLatLng carPosition, List< MogoLatLng > lonLats, boolean lockCarPosition ) throws Exception {
+//
+// if ( lonLats == null || lonLats.isEmpty() ) {
+// throw new MogoMapException( "经纬度不能为null或空集合" );
+// }
+// LatLngBounds.Builder builder = new LatLngBounds.Builder();
+// for ( MogoLatLng lonLat : lonLats ) {
+// builder.include( ObjectUtils.fromMogo2( lonLat ) );
+// }
+// if ( carPosition != null && !lockCarPosition ) {
+// builder.include( ObjectUtils.fromMogo2( carPosition ) );
+// }
+// LatLngBounds latLngBounds = builder.build();
+// if ( !lockCarPosition ) {
+// return latLngBounds;
+// }
+//
+// if ( carPosition == null ) {
+// throw new MogoMapException( "自车位置经纬度信息不能为空" );
+// }
+//
+// if ( latLngBounds.northeast == null && latLngBounds.southwest == null ) {
+// return null;
+// }
+//
+// double south = 0.0;
+// double west = 0.0;
+//
+// double east = 0.0;
+// double north = 0.0;
+//
+// double dLat = 0.0;
+// double dLon = 0.0;
+//
+// if ( latLngBounds.northeast == null ) {
+// dLat = Math.abs( carPosition.lat - latLngBounds.southwest.latitude );
+// dLon = Math.abs( carPosition.lng - latLngBounds.southwest.longitude );
+// } else if ( latLngBounds.southwest == null ) {
+// dLat = Math.abs( carPosition.lat - latLngBounds.northeast.latitude );
+// dLon = Math.abs( carPosition.lng - latLngBounds.northeast.longitude );
+// } else {
+// final double dLat1 = Math.abs( carPosition.lat - latLngBounds.southwest.latitude );
+// final double dLon1 = Math.abs( carPosition.lng - latLngBounds.southwest.longitude );
+// final double dLat2 = Math.abs( carPosition.lat - latLngBounds.northeast.latitude );
+// final double dLon2 = Math.abs( carPosition.lng - latLngBounds.northeast.longitude );
+// dLat = dLat1 > dLat2 ? dLat1 : dLat2;
+// dLon = dLon1 > dLon2 ? dLon1 : dLon2;
+// }
+//
+// west = carPosition.lat - dLat;
+// south = carPosition.lng + dLon;
+//
+// east = carPosition.lat + dLat;
+// north = carPosition.lng - dLon;
+//
+// if ( south == 0.0 || west == 0.0 || east == 0.0 || north == 0.0 ) {
+// return null;
+// }
+//
+// if ( east < west ) {
+// double tmp = east;
+// east = west;
+// west = tmp;
+// }
+//
+// if( north < south ){
+// double tmp = north;
+// north = south;
+// south = tmp;
+// }
+//
+// Logger.d( TAG, "west = %s, east = %s, north = %s, south = %s", west, east, north, south );
+//
+// return new LatLngBounds.Builder().include( new LatLng( east, north ) ).include( new LatLng( west, south ) ).build();
+// }
+
+ public static float calculateLineDistance(LonLatPoint var0, LonLatPoint var1) {
+ if (var0 != null && var1 != null) {
+ try {
+ double var2 = var0.getLongitude();
+ double var4 = var0.getLatitude();
+ double var6 = var1.getLongitude();
+ double var8 = var1.getLatitude();
+ var2 *= 0.01745329251994329D;
+ var4 *= 0.01745329251994329D;
+ var6 *= 0.01745329251994329D;
+ var8 *= 0.01745329251994329D;
+ double var10 = Math.sin(var2);
+ double var12 = Math.sin(var4);
+ double var14 = Math.cos(var2);
+ double var16 = Math.cos(var4);
+ double var18 = Math.sin(var6);
+ double var20 = Math.sin(var8);
+ double var22 = Math.cos(var6);
+ double var24 = Math.cos(var8);
+ double[] var28 = new double[3];
+ double[] var29 = new double[3];
+ var28[0] = var16 * var14;
+ var28[1] = var16 * var10;
+ var28[2] = var12;
+ var29[0] = var24 * var22;
+ var29[1] = var24 * var18;
+ var29[2] = var20;
+ return (float)(Math.asin(Math.sqrt((var28[0] - var29[0]) * (var28[0] - var29[0]) + (var28[1] - var29[1]) * (var28[1] - var29[1]) + (var28[2] - var29[2]) * (var28[2] - var29[2])) / 2.0D) * 1.27420015798544E7D);
+ } catch (Throwable var26) {
+ var26.printStackTrace();
+ return 0.0F;
+ }
+ } else {
+ try {
+ throw new Exception("非法坐标值");
+ } catch (Exception var27) {
+ var27.printStackTrace();
+ return 0.0F;
+ }
+ }
+ }
+}
diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/utils/ObjectUtils.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/utils/ObjectUtils.java
new file mode 100644
index 0000000000..9c30d2c9f7
--- /dev/null
+++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/utils/ObjectUtils.java
@@ -0,0 +1,749 @@
+package com.mogo.map.impl.custom.utils;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.view.View;
+
+import com.autonavi.nge.guidance.NaviInfo;
+import com.mogo.map.MogoLatLng;
+import com.mogo.map.location.MogoLocation;
+import com.mogo.map.marker.MogoMarkerOptions;
+import com.mogo.map.navi.MogoCongestionInfo;
+import com.mogo.map.navi.MogoCongestionLink;
+import com.mogo.map.navi.MogoNaviInfo;
+import com.mogo.map.navi.MogoTraffic;
+import com.mogo.map.overlay.MogoPolylineOptions;
+import com.mogo.map.search.geo.MogoGeocodeAddress;
+import com.mogo.map.search.geo.MogoGeocodeResult;
+import com.mogo.map.search.geo.MogoPoiItem;
+import com.mogo.map.search.geo.MogoRegeocodeAddress;
+import com.mogo.map.search.geo.MogoRegeocodeResult;
+import com.mogo.map.search.geo.query.MogoGeocodeQuery;
+import com.mogo.map.search.geo.query.MogoRegeocodeQuery;
+import com.mogo.map.search.inputtips.MogoTip;
+import com.mogo.map.search.inputtips.query.MogoInputtipsQuery;
+import com.mogo.map.search.poisearch.MogoPoiResult;
+import com.mogo.map.search.poisearch.MogoSearchBound;
+import com.mogo.map.search.poisearch.query.MogoPoiSearchQuery;
+import com.mogo.map.uicontroller.MapCameraPosition;
+import com.zhidaoauto.map.sdk.open.camera.CameraPosition;
+import com.zhidaoauto.map.sdk.open.location.Location;
+import com.zhidaoauto.map.sdk.open.marker.BitmapDescriptor;
+import com.zhidaoauto.map.sdk.open.marker.BitmapDescriptorFactory;
+import com.zhidaoauto.map.sdk.open.marker.MarkerOptions;
+import com.zhidaoauto.map.sdk.open.poyline.PolylineOptions;
+import com.zhidaoauto.map.sdk.open.query.GeocodeAddress;
+import com.zhidaoauto.map.sdk.open.query.GeocodeQuery;
+import com.zhidaoauto.map.sdk.open.query.GeocodeResult;
+import com.zhidaoauto.map.sdk.open.query.InputtipsQuery;
+import com.zhidaoauto.map.sdk.open.query.LonLatPoint;
+import com.zhidaoauto.map.sdk.open.query.PoiItem;
+import com.zhidaoauto.map.sdk.open.query.PoiSearchItem;
+import com.zhidaoauto.map.sdk.open.query.PoiSearchResult;
+import com.zhidaoauto.map.sdk.open.query.Query;
+import com.zhidaoauto.map.sdk.open.query.RegeocodeAddress;
+import com.zhidaoauto.map.sdk.open.query.RegeocodeQuery;
+import com.zhidaoauto.map.sdk.open.query.RegeocodeResult;
+import com.zhidaoauto.map.sdk.open.query.SearchBound;
+import com.zhidaoauto.map.sdk.open.query.Tip;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * @author congtaowang
+ * @since 2019-12-18
+ *
+ * 业务对象和实际对象转换
+ */
+public class ObjectUtils {
+
+ public static MarkerOptions fromMogo(MogoMarkerOptions opt ) {
+
+ if ( opt == null ) {
+ return null;
+ }
+ ArrayList
"));
+ }
+
+ public static String colorFont(String src, String color) {
+ StringBuffer strBuf = new StringBuffer();
+
+ strBuf.append("").append(src)
+ .append("");
+ return strBuf.toString();
+ }
+
+ public static String makeHtmlNewLine() {
+ return "
";
+ }
+
+ public static String makeHtmlSpace(int number) {
+ final String space = " ";
+ StringBuilder result = new StringBuilder();
+ for (int i = 0; i < number; i++) {
+ result.append(space);
+ }
+ return result.toString();
+ }
+
+ public static String getFriendlyLength(int lenMeter) {
+ if (lenMeter > 10000) // 10 km
+ {
+ int dis = lenMeter / 1000;
+ return dis + ChString.Kilometer;
+ }
+
+ if (lenMeter > 1000) {
+ float dis = (float) lenMeter / 1000;
+ DecimalFormat fnum = new DecimalFormat("##0.0");
+ String dstr = fnum.format(dis);
+ return dstr + ChString.Kilometer;
+ }
+
+ if (lenMeter > 100) {
+ int dis = lenMeter / 50 * 50;
+ return dis + ChString.Meter;
+ }
+
+ int dis = lenMeter / 10 * 10;
+ if (dis == 0) {
+ dis = 10;
+ }
+
+ return dis + ChString.Meter;
+ }
+
+ public static boolean IsEmptyOrNullString(String s) {
+ return (s == null) || (s.trim().length() == 0);
+ }
+
+ /**
+ * 把LatLng对象转化为LatLonPoint对象
+ */
+// public static LonLatPoint convertToLatLonPoint(LatLng latlon) {
+// return new LonLatPoint(latlon.latitude, latlon.longitude);
+// }
+
+ /**
+ * 把LatLonPoint对象转化为LatLon对象
+ */
+// public static LatLng convertToLatLng(LatLonPoint latLonPoint) {
+// return new LatLng(latLonPoint.getLatitude(), latLonPoint.getLongitude());
+// }
+
+ /**
+ * 把集合体的LatLonPoint转化为集合体的LatLng
+ */
+// public static ArrayList