diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/AMapCustomView.java b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/AMapCustomView.java new file mode 100644 index 0000000000..793381471e --- /dev/null +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/smp/AMapCustomView.java @@ -0,0 +1,698 @@ +package com.mogo.eagle.core.function.smp; + +import android.content.Context; +import android.graphics.BitmapFactory; +import android.location.Location; +import android.os.Bundle; +import android.util.AttributeSet; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import androidx.annotation.Nullable; + +import com.amap.api.maps.AMap; +import com.amap.api.maps.CameraUpdate; +import com.amap.api.maps.CameraUpdateFactory; +import com.amap.api.maps.CoordinateConverter; +import com.amap.api.maps.UiSettings; +import com.amap.api.maps.model.LatLng; +import com.amap.api.maps.model.Polyline; +import com.amap.api.navi.AMapNavi; +import com.amap.api.navi.AMapNaviListener; +import com.amap.api.navi.AMapNaviView; +import com.amap.api.navi.AMapNaviViewListener; +import com.amap.api.navi.AMapNaviViewOptions; +import com.amap.api.navi.enums.NaviType; +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.amap.api.navi.model.NaviLatLng; +import com.amap.api.navi.model.RouteOverlayOptions; +import com.autonavi.tbt.TrafficFacilityInfo; +import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo; +import com.mogo.eagle.core.data.map.MogoLatLng; +import com.mogo.eagle.core.data.map.MogoLocation; +import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotPlanningListener; +import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener; +import com.mogo.eagle.core.function.api.map.listener.IMoGoMapLocationListener; +import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager; +import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotPlanningListenerManager; +import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager; +import com.mogo.eagle.core.function.map.R; +import com.mogo.eagle.core.function.smp.view.ISmallMapDirectionView; +import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; +import com.mogo.eagle.core.utilcode.util.ThreadUtils; +import com.mogo.module.common.utils.DrivingDirectionUtils; +import com.zhidao.support.adas.high.AdasManager; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import mogo.telematics.pad.MessagePad; +import mogo_msg.MogoReportMsg; + +/** + * 小地图的方向View + * 监听自动驾驶路径结束,结束高德地图导航 + * + * @author donghongyu + * @date 12/14/20 4:40 PM + */ +public class AMapCustomView + extends RelativeLayout + implements IMoGoMapLocationListener, ISmallMapDirectionView, AMapNaviListener, AMapNaviViewListener { + public static final String TAG = "AMapCustomView"; + private AMapNaviView mAMapNaviView; + protected AMapNavi mAMapNavi; + private AMap mAMap; + protected NaviLatLng mStartLatlng = new NaviLatLng(); + protected NaviLatLng mEndLatlng = new NaviLatLng(); + //328路线测试数据 +// protected NaviLatLng mStartLatlng = new NaviLatLng(39.969111, 116.411903); +// protected NaviLatLng mEndLatlng = new NaviLatLng(40.037209, 116.314358); + //顺义国展测试数据 +// mStartLatlng = new NaviLatLng(40.09383,116.51899); +// mEndLatlng = new NaviLatLng(40.09964,116.54570); + protected final List sList = new ArrayList(); + protected final List eList = new ArrayList(); + private int zoomLevel = 15; + private final List mCoordinatesLatLng = new ArrayList<>(); + private final List mCoordinatesLatLngCurrent = new ArrayList<>(); + protected List mWayPointList = new ArrayList(); + private Polyline mPolyline; + private CameraUpdate mCameraUpdate; + private Context mContext; + private float tilt = 30f; + private TextView overLayerView; + private boolean calculate = false; + + public AMapCustomView(Context context) { + this(context, null); + } + + public AMapCustomView(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public AMapCustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + try { + initView(context); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void initView(Context context) { + mContext = context; + //测试代码:路线指定路径328线路 +// mWayPointList.add(new NaviLatLng(39.968847, 116.406952)); +// mWayPointList.add(new NaviLatLng(39.969058, 116.407346)); +// mWayPointList.add(new NaviLatLng(39.968955, 116.401767)); +// mWayPointList.add(new NaviLatLng(39.968626, 116.394938)); +// mWayPointList.add(new NaviLatLng(39.968433, 116.388725)); +// mWayPointList.add(new NaviLatLng(39.968542, 116.383775)); +// mWayPointList.add(new NaviLatLng(40.037808, 116.342539)); +// mWayPointList.add(new NaviLatLng(40.037239, 116.337172)); +// mWayPointList.add(new NaviLatLng(40.035897, 116.329582)); +// mWayPointList.add(new NaviLatLng(40.036396, 116.322166)); + Log.d(TAG, "initView:" + mWayPointList.toString()); + + //顺义国展路线 +// mWayPointList.add(new NaviLatLng(40.097621,116.526495)); +// mWayPointList.add(new NaviLatLng(40.097982,116.529135)); +// mWayPointList.add(new NaviLatLng(40.098434,116.531903)); +// mWayPointList.add(new NaviLatLng(40.098828,116.534563)); +// mWayPointList.add(new NaviLatLng(40.099377,116.538651)); +// mWayPointList.add(new NaviLatLng(40.099927,116.54173)); + + View smpView = LayoutInflater.from(context).inflate(R.layout.module_small_map_view, this); + mAMapNaviView = smpView.findViewById(R.id.aMapNaviView); + overLayerView = findViewById(R.id.overLayer); + mAMapNavi = AMapNavi.getInstance(context); + mAMapNavi.addAMapNaviListener(this); + mAMapNaviView.setAMapNaviViewListener(this); + CallerAutoPilotStatusListenerManager.INSTANCE.addListener(TAG, mGoAutopilotStatusListener); + CallerAutopilotPlanningListenerManager.INSTANCE.addListener(TAG, moGoAutopilotPlanningListener); + initAMapView(context); + // 注册定位监听 + CallerMapLocationListenerManager.INSTANCE.addListener(TAG, this); + //设置全览模式 + overLayerView.setOnClickListener(v -> { + mAMapNaviView.displayOverview(); + }); + } + + private final IMoGoAutopilotStatusListener mGoAutopilotStatusListener = new IMoGoAutopilotStatusListener() { + + @Override + public void onAutopilotIpcConnectStatusChanged(int status, @org.jetbrains.annotations.Nullable String reason) { + + } + + @Override + public void onAutopilotGuardian(@org.jetbrains.annotations.Nullable MogoReportMsg.MogoReportMessage guardianInfo) { + + } + + @Override + public void onAutopilotSNRequest() { + + } + + @Override + public void onAutopilotArriveAtStation(@org.jetbrains.annotations.Nullable MessagePad.ArrivalNotification arrivalNotification) { + + } + + @Override + public void onAutopilotStatusResponse(@NotNull AutopilotStatusInfo autoPilotStatusInfo) { + ThreadUtils.runOnUiThread(new Runnable() { + @Override + public void run() { + if (autoPilotStatusInfo == null) return; + int state = autoPilotStatusInfo.getState(); + //0 不能自动驾驶 1 可以自动驾驶,但是在人工干预 2 自动驾驶中 + if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) { + Log.d(TAG, "自动驾驶中= %s" + String.valueOf(state)); + if (sList.size() == 0 && eList.size() == 0 && mWayPointList.size() == 0) { + Log.d(TAG, "sendGlobalPathReq"); + AdasManager.getInstance().sendGlobalPathReq(); + } + } else { + int type = mAMapNavi.getNaviType(); + Log.d(TAG, "非自动驾驶状态,导航类型==" + String.valueOf(type)); + if (type == NaviType.GPS || type == NaviType.EMULATOR) { + mAMapNavi.stopNavi(); + } + } + } + }); + } + }; + + private final IMoGoAutopilotPlanningListener moGoAutopilotPlanningListener = new IMoGoAutopilotPlanningListener() { + + @Override + public void onAutopilotTrajectory(@NotNull List trajectoryInfos) { + Log.d(TAG, "onAutopilotTrajectory"); + } + + /** + * 根据全路径获取起始点和经停点进行导航路线绘制 + * 自动驾驶启动后获得数据,获取全路径的具体时间要进行路测 + * 室内某个bag包自动驾驶启动8s后返回 + */ + @Override + public void onAutopilotRotting(@org.jetbrains.annotations.Nullable MessagePad.GlobalPathResp globalPathResp) { + if (calculate == true) { + return; + } + calculate = true; + Log.d(TAG, "onAutopilotRotting"); + List list = globalPathResp.getWayPointsList(); + int minCount = 2; + if (list.size() >= minCount && sList.size() == 0 && eList.size() == 0 && mWayPointList.size() == 0) { + calculate = true; + MessagePad.Location sLocation = (MessagePad.Location) list.get(0); + MessagePad.Location eLocation = (MessagePad.Location) list.get(list.size() - 1); + mStartLatlng = new NaviLatLng(sLocation.getLatitude(), sLocation.getLongitude()); + mEndLatlng = new NaviLatLng(eLocation.getLatitude(), eLocation.getLongitude()); + sList.clear(); + eList.clear(); + sList.add(mStartLatlng); + eList.add(mEndLatlng); + + mWayPointList.clear(); + for (int i = 1; i < list.size() - minCount; i++) { + MessagePad.Location wayLoc = (MessagePad.Location) list.get(i); + NaviLatLng way = new NaviLatLng(wayLoc.getLatitude(), wayLoc.getLongitude()); + mWayPointList.add(way); + } + } + int strategy = 0; + try { + //再次强调,最后一个参数为true时代表多路径,否则代表单路径 + strategy = mAMapNavi.strategyConvert(true, false, false, false, false); + } catch (Exception e) { + e.printStackTrace(); + } + Log.d(TAG, "全局路径" + list.size() + ",起点:" + sList.toString() + ",终点:" + eList.toString() + ",经点:" + mWayPointList.toString()); + //指定路径绘制导航路线 + mAMapNavi.calculateDriveRoute(sList, eList, mWayPointList, strategy); + } + }; + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + // 注册定位监听 + CallerMapLocationListenerManager.INSTANCE.removeListener(TAG); + CallerAutoPilotStatusListenerManager.INSTANCE.removeListener(TAG); + CallerAutopilotPlanningListenerManager.INSTANCE.removeListener(TAG); + } + + private void initAMapView(Context context) { + mCameraUpdate = CameraUpdateFactory.zoomTo(zoomLevel); + AMapNaviViewOptions options = mAMapNaviView.getViewOptions(); + //关闭自动绘制路线,自行绘制路线 +// options.setAutoDrawRoute(false); + //不显示导航界面 + options.setLayoutVisible(false); + //黑夜模式 + options.setNaviNight(true); + //导航全程光柱 + options.setTrafficBarEnabled(false); + //指南针 +// options.setCompassEnabled(false); + options.setTilt((int) tilt); + //自车车标 + options.setCarBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.module_small_map_view_my_location_logo)); + options.setFourCornersBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.amap_custom_corner)); + options.setStartPointBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.module_small_map_view_dir_start)); + options.setWayPointBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.icon_module_small_map_four_corners)); + options.setEndPointBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.module_small_map_view_dir_end)); + //与走过的路线 + options.setAfterRouteAutoGray(true); + //路线纹理自定义 + RouteOverlayOptions routeOverlayOptions = new RouteOverlayOptions(); + routeOverlayOptions.setTurnArrowIs3D(false); + routeOverlayOptions.setUnknownTraffic(BitmapFactory.decodeResource(getResources(),R.drawable.custtexture_no));//未知路段 + routeOverlayOptions.setSmoothTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.amap_custom_smooth_route)); + routeOverlayOptions.setJamTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.custtexture_bad));//拥堵路段 + routeOverlayOptions.setVeryJamTraffic(BitmapFactory.decodeResource(getResources(), R.drawable.custtexture_grayred));//超级拥堵路段 + routeOverlayOptions.setPassRoute(BitmapFactory.decodeResource(getResources(), R.drawable.custtexture_slow));//走过的路段 + options.setRouteOverlayOptions(routeOverlayOptions); + mAMapNaviView.setViewOptions(options); + + mAMap = mAMapNaviView.getMap(); + // 地图文字标注 + mAMap.showMapText(true); + // 显示实时路况图层,aMap是地图控制器对象。 + mAMap.setTrafficEnabled(true); + //设置希望展示的地图缩放级别 + mAMap.moveCamera(mCameraUpdate); + //设置地图的样式 + UiSettings uiSettings = mAMap.getUiSettings(); + //地图缩放级别的交换按钮 + uiSettings.setZoomControlsEnabled(false); + //所有手势 + uiSettings.setAllGesturesEnabled(true); + //隐藏指南针 + uiSettings.setCompassEnabled(false); + //设置倾斜手势是否可用。 + uiSettings.setTiltGesturesEnabled(true); + //隐藏默认的定位按钮 + uiSettings.setMyLocationButtonEnabled(false); + //设置Logo下边界距离屏幕底部的边距,设置为负值即可 + uiSettings.setLogoBottomMargin(-150); + int strategy = 0; + try { + //再次强调,最后一个参数为true时代表多路径,否则代表单路径 + strategy = mAMapNavi.strategyConvert(true, false, false, false, false); + } catch (Exception e) { + e.printStackTrace(); + } + //指定路径绘制导航路线 + mAMapNavi.calculateDriveRoute(sList, eList, mWayPointList, strategy); + } + + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + return false; + } + + + @Override + public void onLocationChanged(@org.jetbrains.annotations.Nullable MogoLocation location, int from) { + + } + + private void removeLocation(Location latLng) { + for (LatLng l : mCoordinatesLatLng) { + if (!isPointOnCarFront(latLng, l)) { + mCoordinatesLatLng.remove(l); + } + } + } + + public static boolean isPointOnCarFront(Location carLocal, LatLng pointLocal) { + double carLon = carLocal.getLongitude(); + double carLat = carLocal.getLatitude(); + double poiLon = pointLocal.longitude; + double poiLat = pointLocal.latitude; + float carAngle = carLocal.getBearing(); + + // 计算车辆与点之间的夹角 + int diffAngle = DrivingDirectionUtils.getDegreeOfCar2Poi( + carLon, carLat, poiLon, poiLat, (int) carAngle); + + return diffAngle <= 90; + } + + + @Override + public void drawablePolyline() { + } + + + public LatLng CoordinateConverterFrom84(Context mContext, MogoLatLng mogoLatLng) { + CoordinateConverter mCoordinateConverter = new CoordinateConverter(mContext); + mCoordinateConverter.from(CoordinateConverter.CoordType.GPS); + mCoordinateConverter.coord(new LatLng(mogoLatLng.lat, mogoLatLng.lon)); + return mCoordinateConverter.convert(); + } + + public List CoordinateConverterFrom84ForList(Context mContext, List mogoLatLngList) { + List list = new ArrayList<>(); + for (MogoLatLng m : mogoLatLngList) { + LatLng mogoLatLng = CoordinateConverterFrom84(mContext, m); + list.add(mogoLatLng); + } + return list; + } + + @Override + public void clearPolyline() { + if (mPolyline != null) { + mPolyline.remove(); + } + } + + public void resetPolyLine() { + mCoordinatesLatLng.clear(); + if (mPolyline != null) { + mPolyline.remove(); + } + } + + public void onCreateView(Bundle savedInstanceState) { + if (mAMapNaviView != null) { + mAMapNaviView.onCreate(savedInstanceState); + } + } + + public void onResume() { + if (mAMapNaviView != null) { + mAMapNaviView.onResume(); + } + } + + public void onPause() { + if (mAMapNaviView != null) { + mAMapNaviView.onPause(); + } + } + + public void onDestroy() { + if (mAMapNaviView != null) { + mAMapNaviView.onDestroy(); + } + //since 1.6.0 不再在naviview destroy的时候自动执行AMapNavi.stopNavi();请自行执行 + if (mAMapNavi != null) { + mAMapNavi.stopNavi(); + mAMapNavi.destroy(); + } + if (mAMapNaviView != null) { + mAMapNaviView.onDestroy(); + } + } + + public void convert(List coordinates) { + + } + + //多路径算路成功回调 + @Override + public void onCalculateRouteSuccess(int[] ints) { + Log.d(TAG, "onCalculateRouteSuccess int"); + } + + + @Override + public void onInitNaviFailure() { + calculate = false; + Log.d(TAG, "onInitNaviFailure"); + } + + @Override + public void onInitNaviSuccess() { + Log.d(TAG, "onInitNaviSuccess"); + + } + + @Override + public void onStartNavi(int i) { + Log.d(TAG, "onStartNavi"); + + } + + @Override + public void onTrafficStatusUpdate() { + + } + + @Override + public void onLocationChange(AMapNaviLocation aMapNaviLocation) { +// Log.d(TAG, "高德地图经纬度:" + aMapNaviLocation.getCoord().getLongitude() + "," + aMapNaviLocation.getCoord().getLatitude()); + + } + + @Override + public void onGetNavigationText(int i, String s) { + Log.d(TAG, "onGetNavigationText int"); + } + + @Override + public void onGetNavigationText(String s) { + Log.d(TAG, "onGetNavigationText ss"); + + } + + @Override + public void onEndEmulatorNavi() { + Log.d(TAG, "onEndEmulatorNavi"); + } + + @Override + public void onArriveDestination() { + Log.d(TAG, "onArriveDestination"); + } + + @Override + public void onCalculateRouteFailure(int i) { + Log.d(TAG, "onCalculateRouteFailure"); + } + + @Override + public void onReCalculateRouteForYaw() { + Log.d(TAG, "onReCalculateRouteForYaw"); + } + + @Override + public void onReCalculateRouteForTrafficJam() { + Log.d(TAG, "onReCalculateRouteForTrafficJam"); + } + + @Override + public void onArrivedWayPoint(int i) { + Log.d(TAG, "onArrivedWayPoint"); + } + + @Override + public void onGpsOpenStatus(boolean b) { + Log.d(TAG, "onGpsOpenStatus"); + } + + @Override + public void onNaviInfoUpdate(NaviInfo naviInfo) { + Log.d(TAG, "onNaviInfoUpdate"); + } + + @Override + public void onNaviInfoUpdated(AMapNaviInfo aMapNaviInfo) { + Log.d(TAG, "onNaviInfoUpdated"); + } + + @Override + public void updateCameraInfo(AMapNaviCameraInfo[] aMapNaviCameraInfos) { + Log.d(TAG, "updateCameraInfo"); + } + + @Override + public void updateIntervalCameraInfo(AMapNaviCameraInfo aMapNaviCameraInfo, AMapNaviCameraInfo aMapNaviCameraInfo1, int i) { + Log.d(TAG, "updateIntervalCameraInfo"); + } + + @Override + public void onServiceAreaUpdate(AMapServiceAreaInfo[] aMapServiceAreaInfos) { + Log.d(TAG, "onServiceAreaUpdate"); + } + + @Override + public void showCross(AMapNaviCross aMapNaviCross) { + Log.d(TAG, "showCross"); + } + + @Override + public void hideCross() { + Log.d(TAG, "hideCross"); + } + + @Override + public void showModeCross(AMapModelCross aMapModelCross) { + Log.d(TAG, "showModeCross"); + } + + @Override + public void hideModeCross() { + Log.d(TAG, "hideModeCross"); + } + + @Override + public void showLaneInfo(AMapLaneInfo[] aMapLaneInfos, byte[] bytes, byte[] bytes1) { + Log.d(TAG, "showLaneInfo"); + } + + @Override + public void showLaneInfo(AMapLaneInfo aMapLaneInfo) { + Log.d(TAG, "showLaneInfo"); + } + + @Override + public void hideLaneInfo() { + Log.d(TAG, "hideLaneInfo"); + } + + @Override + public void notifyParallelRoad(int i) { + + } + + @Override + public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos) { + + } + + @Override + public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) { + + } + + @Override + public void OnUpdateTrafficFacility(TrafficFacilityInfo trafficFacilityInfo) { + + } + + @Override + public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) { + + } + + @Override + public void updateAimlessModeCongestionInfo(AimLessModeCongestionInfo aimLessModeCongestionInfo) { + + } + + @Override + public void onPlayRing(int i) { + + } + + //算路详情 + @Override + public void onCalculateRouteSuccess(AMapCalcRouteResult aMapCalcRouteResult) { + Log.d(TAG, "onCalculateRouteSuccess aMapCalcRouteResult" + aMapCalcRouteResult.toString()); + mAMapNavi.startNavi(NaviType.EMULATOR); + mAMapNaviView.displayOverview(); + + //停止导航测试代码 +// UiThreadHandler.postDelayed(() -> { +// mAMapNavi.stopNavi(); +// Log.d(TAG, "stop------------"); +// }, 20000); + } + + @Override + public void onCalculateRouteFailure(AMapCalcRouteResult aMapCalcRouteResult) { + Log.d(TAG, "onCalculateRouteFailure"); + } + + @Override + public void onNaviRouteNotify(AMapNaviRouteNotifyData aMapNaviRouteNotifyData) { + Log.d(TAG, "onNaviRouteNotify"); + } + + @Override + public void onNaviSetting() { + + } + + @Override + public void onNaviCancel() { + + } + + @Override + public boolean onNaviBackClick() { + return false; + } + + @Override + public void onNaviMapMode(int i) { + + } + + @Override + public void onNaviTurnClick() { + + } + + @Override + public void onNextRoadClick() { + + } + + @Override + public void onScanViewButtonClick() { + + } + + @Override + public void onLockMap(boolean b) { + + } + + @Override + public void onNaviViewLoaded() { + + } + + @Override + public void onMapTypeChanged(int i) { + + } + + @Override + public void onNaviViewShowMode(int i) { + + } + +}