Files
MoGoEagleEye/libraries/mogo-map/src/main/java/com/mogo/map/AMapViewWrapper.java

1145 lines
44 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.mogo.map;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_DEVA;
import static com.mogo.map.uicontroller.VisualAngleMode.MAP_STYLE_VR_ANGLE_300;
import static com.mogo.map.uicontroller.VisualAngleMode.MAP_STYLE_VR_ANGLE_CROSS;
import static com.mogo.map.uicontroller.VisualAngleMode.MAP_STYLE_VR_ANGLE_TOP;
import static com.mogo.map.uicontroller.VisualAngleMode.MODE_CLOSE_SIGHT;
import static com.mogo.map.uicontroller.VisualAngleMode.MODE_LONG_SIGHT;
import static com.mogo.map.uicontroller.VisualAngleMode.MODE_MEDIUM_SIGHT;
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
import android.location.Location;
import android.os.Bundle;
import android.os.Trace;
import android.text.TextUtils;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import com.mogo.commons.constants.SharedPrefsConstants;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.eagle.core.data.config.HdMapBuildConfig;
import com.mogo.eagle.core.data.map.MapRoadInfo;
import com.mogo.eagle.core.data.map.MogoLatLng;
import com.mogo.eagle.core.data.map.MogoLocation;
import com.mogo.eagle.core.function.call.map.CallerMapDataCollectorManager;
import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager;
import com.mogo.eagle.core.function.call.map.CallerMapRoadListenerManager;
import com.mogo.eagle.core.function.call.map.CallerMapStyleListenerManager;
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr;
import com.mogo.eagle.core.utilcode.mogo.toast.TipToast;
import com.mogo.eagle.core.utilcode.util.GsonUtils;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.map.listener.MogoMapListenerHandler;
import com.mogo.map.navi.MogoCarLocationChangedListenerRegister;
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.map.uicontroller.VisualAngleMode;
import com.mogo.map.utils.MogoMapUtils;
import com.mogo.map.utils.ObjectUtils;
import com.mogo.map.utils.PointInterpolatorUtil;
import com.mogo.map.utils.ResIdCache;
import com.zhidaoauto.map.sdk.open.MapAutoApi;
import com.zhidaoauto.map.sdk.open.abs.MapStatusListener;
import com.zhidaoauto.map.sdk.open.abs.OnCameraChangeListener;
import com.zhidaoauto.map.sdk.open.abs.OnMapClickListener;
import com.zhidaoauto.map.sdk.open.abs.OnMapLoadedListener;
import com.zhidaoauto.map.sdk.open.abs.OnMapStyleListener;
import com.zhidaoauto.map.sdk.open.abs.OnMapTouchListener;
import com.zhidaoauto.map.sdk.open.abs.OnMapViewVisualAngleChangeListener;
import com.zhidaoauto.map.sdk.open.abs.OnRoadInfoListener;
import com.zhidaoauto.map.sdk.open.camera.CameraPosition;
import com.zhidaoauto.map.sdk.open.camera.CameraUpdateFactory;
import com.zhidaoauto.map.sdk.open.camera.LatLngBounds;
import com.zhidaoauto.map.sdk.open.data.MapDataApi;
import com.zhidaoauto.map.sdk.open.data.SinglePointRoadInfo;
import com.zhidaoauto.map.sdk.open.location.LocationListener;
import com.zhidaoauto.map.sdk.open.location.MyLocationStyle;
import com.zhidaoauto.map.sdk.open.location.RTKAutopilotLocationBean;
import com.zhidaoauto.map.sdk.open.marker.BitmapDescriptorFactory;
import com.zhidaoauto.map.sdk.open.marker.Marker;
import com.zhidaoauto.map.sdk.open.marker.OnMarkClickListener;
import com.zhidaoauto.map.sdk.open.query.LonLatPoint;
import com.zhidaoauto.map.sdk.open.road.StopLine;
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 org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import mogo.telematics.pad.MessagePad;
public class AMapViewWrapper implements IMogoMapView,
IMogoMapUIController,
LocationListener,
OnMapLoadedListener,
MapStatusListener,
OnCameraChangeListener,
OnMapClickListener,
OnMapTouchListener,
OnMarkClickListener,
OnMapStyleListener,
MapStyleController.IMapStyleAutoChangedListener,
OnMapViewVisualAngleChangeListener,
OnRoadInfoListener {
private static final String TAG = "AMapViewWrapper";
private final MapAutoView mMapView;
private final IMogoMap mIMap;
private AMapMarkerClickHandler mMarkerClickHandler;
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;
private EnumMapUI mCurrentCarUIMode;
private EnumMapUI mCurrentUI;
private VisualAngleMode mVisualAngleMode = MODE_MEDIUM_SIGHT;
private int mLockZoom = 16;
private long startTime;
private float mDefaultZoomLevel = 16.0f;
private boolean mIsCarLocked = false;
private boolean mIsLightStyle = false;
private boolean mMapLoaded = false;
private boolean mIsFirstLocated = true;
private boolean mIsDelayed = false;
private volatile String mRoadId = null;
public AMapViewWrapper(MapAutoView mMapView) {
startTime = System.currentTimeMillis();
CallerLogger.INSTANCE.i(TAG, "autoop--AMapViewWrapper: init");
this.mMapView = mMapView;
initViews();
initListeners();
this.mIMap = new AMapWrapper(this.mMapView.getMapAutoViewHelper(), this.mMapView, this);
}
private void initViews() {
}
private void initMapView() {
if (mMapView == null) {
return;
}
MapAutoViewHelper options = mMapView.getMapAutoViewHelper();
if (options != null) {
//设置手势是否可以缩放 isCanZoom true 可缩放 false 不可缩放
options.setZoomGesturesEnabled(true);
options.setScaleVRMode(true);
if (options.getMyLocationStyle() != null) {
options.getMyLocationStyle().setDisplayAnimEnable(true);
}
//修改自车模型,未来需区分车的类型
options.setMyLocationStyle(options.getMyLocationStyle().myLocationIcon(HdMapBuildConfig.currentCarVrIconRes, true));
// MapAutoApi.INSTANCE.getMyLocationStyle().myLocationIcon(HdMapBuildConfig.currentCarVrIconRes, true);
}
}
private void initListeners() {
mMapView.setOnMarkClickListener(this);
mMarkerClickHandler = AMapMarkerClickHandler.getInstance();
mMapView.setOnMapLoadedListener(this);
mMapView.setOnMapTouchListener(this);
mMapView.setOnMapClickListener(this);
mMapView.getLocationClient().registerListener(this);
mMapView.registerListener(this, MapAutoApi.LISTENER_TYPE_ZOOM);
mMapView.registerListener(this, MapAutoApi.LISTENER_TYPE_ROTATE);
mMapView.registerListener(this, MapAutoApi.LISTENER_TYPE_3D);
mMapView.setOnCameraChangeListener(this);
mMapView.setOnMapStyleListener(this);
mMapView.setOnMapViewVisualAngleChangeListener(this);
mMapView.setOnRoadInfoListener(this, 1);
CallerLogger.INSTANCE.d(TAG, "styleop - initListeners - setOnMapStyleListener - view " + mMapView);
}
@Override
public void onRoadIdInfo(@androidx.annotation.Nullable String roadId) {
if (roadId != null && !TextUtils.isEmpty(roadId)) {
CallerLogger.INSTANCE.d(M_DEVA + TAG, "onRoadIdInfo::" + roadId);
CallerMapRoadListenerManager.INSTANCE.invokeListenersOnRoadIdGet(roadId);
} else {
CallerLogger.INSTANCE.d("${M_DEVA}${TAG}", "onRoadIdInfo::null");
}
}
@Override
public void onStopLineInfo(@androidx.annotation.Nullable StopLine stopLine) {
MogoLocation carLoc = CallerMapLocationListenerManager.INSTANCE.getCurrentLocation();
if (stopLine != null && !TextUtils.isEmpty(stopLine.road_id) && stopLine.points != null && stopLine.points.size() > 0) {
ArrayList<LonLatPoint> points = stopLine.points;
if (carLoc != null) {
/**
* //地图组提供的高德坐标切到WGS84坐标系
* var cal = LonLatPoint(point!!.lon, point!!.lat)
* if(!point!!.provider.equals(MapAutoApi.GPS_FLAG)){
* cal = MapTools.switchLonLatWGS84(cal)
* }
*/
String provider = carLoc.getProvider();
CallerLogger.INSTANCE.d(M_DEVA + TAG, "car_loc: " + carLoc + "");
if (!MapAutoApi.GPS_FLAG.equals(provider)) {
CallerLogger.INSTANCE.d(M_DEVA + TAG, "convert before: car_loc: {lon: " + carLoc.getLongitude() + ", lat: " + carLoc.getLatitude() + "}");
LonLatPoint p = new LonLatPoint(carLoc.getLongitude(), carLoc.getLatitude());
p = MapTools.INSTANCE.switchLonLatWGS84(p);
carLoc.setLongitude(p.longitude);
carLoc.setLatitude(p.latitude);
CallerLogger.INSTANCE.d(M_DEVA + TAG, "convert after: car_loc: {lon: " + carLoc.getLongitude() + ", lat: " + carLoc.getLatitude() + "}");
}
CallerLogger.INSTANCE.d(M_DEVA + TAG, "onStopLineInfo:stop_line" + stopLine + ", car_loc:{lon: " + carLoc.getLatitude() + ", lat: " + carLoc.getLongitude() + "}");
MapRoadInfo.StopLine stopInfo = convert(stopLine);
LonLatPoint p1 = points.get(0);
LonLatPoint p2 = points.get(points.size() - 1);
double distanceOfCarToStopLine = MapDataApi.INSTANCE.getNearstFromPointToSegment(carLoc.getLongitude(), carLoc.getLatitude(), p1.longitude, p1.latitude, p2.longitude, p2.latitude) * 10_0000;
stopInfo.setDistanceOfCarToStopLine(distanceOfCarToStopLine);
CallerLogger.INSTANCE.d(M_DEVA + TAG, "onStopLineInfo: --- distance: "+ distanceOfCarToStopLine);
CallerMapRoadListenerManager.INSTANCE.invokeListenersOnStopLineGet(stopInfo);
}
} else {
if (carLoc != null) {
CallerLogger.INSTANCE.d(M_DEVA + TAG, "onStopLineInfo::null, car_loc:{lon: " + carLoc.getLatitude() + ", lat: " + carLoc.getLongitude() + "}");
}
}
}
private MapRoadInfo.StopLine convert(StopLine line) {
MapRoadInfo.StopLine ret = new MapRoadInfo.StopLine();
ret.setDistance(line.distance);
ret.setLaneId(line.lane_id);
ret.setRoadId(line.road_id);
ret.setTieId(line.tile_id);
ArrayList<LonLatPoint> points = line.points;
if (points != null && points.size() > 0) {
List<MogoLatLng> newPoints = new ArrayList<>();
for (int i = 0; i < points.size(); i++) {
LonLatPoint lonLatPoint = points.get(i);
MogoLatLng latLng = new MogoLatLng(lonLatPoint.latitude, lonLatPoint.longitude);
latLng.duration = lonLatPoint.duration;
latLng.angle = lonLatPoint.angle;
latLng.speed = lonLatPoint.speed;
latLng.altitude = lonLatPoint.altitude;
latLng.provider = lonLatPoint.provider;
newPoints.add(latLng);
}
ret.setPoints(newPoints);
}
return ret;
}
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);
CallerLogger.INSTANCE.d(TAG, "map onCreate");
}
}
@Override
public void onResume() {
if (mMapView != null) {
mMapView.onResume();
CallerLogger.INSTANCE.d(TAG, "map onResume");
}
}
@Override
public void onPause() {
if (mMapView != null) {
mMapView.onPause();
CallerLogger.INSTANCE.d(TAG, "map onPause");
}
}
@Override
public void onDestroy() {
if (mMapView != null) {
mMapView.onDestroy();
mMapView.setOnMarkClickListener(null);
mMapView.setOnMapLoadedListener(null);
mMapView.setOnMapTouchListener(null);
mMapView.setOnMapClickListener(null);
mMapView.getLocationClient().unRegisterListener(this);
mMapView.setOnCameraChangeListener(null);
CallerLogger.INSTANCE.d(TAG, "map onDestroy");
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
if (mMapView != null) {
mMapView.onSaveInstanceState(outState);
CallerLogger.INSTANCE.d(TAG, "map onSaveInstanceState");
}
}
@Override
public void onLowMemory() {
}
@Override
public void setTrafficEnabled(boolean visible) {
if (checkAMapView()) {
// mMapView.getMapAutoViewHelper().setTraffic( visible );
}
}
@Override
public MapControlResult changeZoom(boolean zoom) {
if (checkAMapView()) {
mDefaultZoomLevel = (getMap().getZoomLevel() + 0.5f);
if (zoom) {
if (mDefaultZoomLevel >= 20f) {
return MapControlResult.TARGET;
}
} else {
if (mDefaultZoomLevel <= 7f) {
return MapControlResult.TARGET;
}
}
if (zoom) {
mDefaultZoomLevel += 1f;
if (mDefaultZoomLevel > 19f) {
mDefaultZoomLevel = 19f;
}
} else {
mDefaultZoomLevel -= 1f;
if (mDefaultZoomLevel < 8f) {
mDefaultZoomLevel = 8f;
}
}
changeZoom(mDefaultZoomLevel);
}
return MapControlResult.SUCCESS;
}
@Override
public MapControlResult changeZoom(float zoom) {
if (mCurrentUI == EnumMapUI.Type_VR) {
return MapControlResult.ERROR;
}
CallerLogger.INSTANCE.d(TAG, "changeZoom : " + zoom);
if (DebugConfig.isDebug()) {
CallerLogger.INSTANCE.d(TAG, Log.getStackTraceString(new Throwable()));
}
getMap().changeZoom(zoom);
return MapControlResult.SUCCESS;
}
@Override
public void changeMapMode(EnumMapUI ui) {
if (ui == null) {
return;
}
CallerLogger.INSTANCE.d(TAG, "设置的样式 :" + ui);
if (checkAMapView()) {
mMapView.getMapAutoViewHelper().setScaleVRMode(true);
mMapView.getMapAutoViewHelper().setMapStyle(MapAutoApi.MAP_STYLE_VR);
// TODO 这里临时修改关闭2D
// switch (ui) {
// case CarUp_2D:
// case CarUp_3D:
// case NorthUP_2D:
// setUIMode(ui);
// break;
// case Type_VR:
// mMapView.getMapAutoViewHelper().setScaleVRMode(true);
// mMapView.getMapAutoViewHelper().setMapStyle(MapAutoApi.MAP_STYLE_VR);
// return;
// case Type_Light:
// mMapView.getMapAutoViewHelper().setAutoSwitchStyle(false);
// mMapView.getMapAutoViewHelper().setMapStyle(MapAutoApi.MAP_STYLE_DAY);
// mIsLightStyle = true;
// break;
// case Type_Night:
// mMapView.getMapAutoViewHelper().setAutoSwitchStyle(false);
// mMapView.getMapAutoViewHelper().setMapStyle(MapAutoApi.MAP_STYLE_NIGHT);
// mIsLightStyle = false;
// break;
// case Type_AUTO_LIGHT_Night:
// mMapView.getMapAutoViewHelper().setAutoSwitchStyle(true);
// break;
// }
}
}
@Override
public void changeMapVisualAngle(VisualAngleMode angelMode, MogoLatLng mogoLatLng) {
MapAutoViewHelper mapAutoViewHelper = mMapView.getMapAutoViewHelper();
if (mapAutoViewHelper != null) {
mVisualAngleMode = angelMode;
if (angelMode == MODE_CLOSE_SIGHT) {
if (mogoLatLng == null) {
CallerLogger.INSTANCE.e(TAG, "切换地图近景需要传入要移动的经纬度数据");
return;
}
// 近景传入经纬度为点击地图上静态marker经纬度数据为GPS坐标点。
mapAutoViewHelper.setNearViewAnglePosition(new LonLatPoint(mogoLatLng.lon, mogoLatLng.lat), true);
} else {
mapAutoViewHelper.setMapViewVisualAngle(angelMode.getCode());
}
}
}
@Override
public VisualAngleMode getCurrentMapVisualAngle() {
return mVisualAngleMode;
}
@Override
public void moveToCenter(MogoLatLng latLng) {
moveToCenter(latLng, true);
}
private boolean checkAMapView() {
if (mMapView == null || mMapView.getMapAutoViewHelper() == null) {
CallerLogger.INSTANCE.e(TAG, "自研mapView实例为空请检查");
return false;
}
return true;
}
@Override
public void moveToCenter(MogoLatLng latLng, boolean animate) {
CallerLogger.INSTANCE.d(TAG, "move to center " + latLng);
if (latLng == null || latLng.lat == 0.0d || latLng.lon == 0.0d) {
CallerLogger.INSTANCE.e(TAG, "latlng = null or is illegal");
return;
}
if (DebugConfig.isDebug()) {
CallerLogger.INSTANCE.d(TAG, Log.getStackTraceString(new Throwable()));
}
loseLockMode();
mMapView.getMapAutoViewHelper().animateCamera(new LonLatPoint(latLng.lon, latLng.lat));
}
@Override
public void showMyLocation(boolean visible) {
CallerLogger.INSTANCE.d(TAG, "showMyLocation1 " + visible);
// 如果是VR模式
if (mCurrentUI == EnumMapUI.Type_VR) {
return;
}
// 不是VR模式情况强制刷新下
if (checkAMapView()) {
MyLocationStyle style = mMapView.getMapAutoViewHelper().getMyLocationStyle();
if (visible) {
// 强制刷新一遍车标
style.myLocationIcon(mCarCursorOption.getCarCursorRes());
}
mMapView.getMapAutoViewHelper().setMyLocationStyle(style);
}
}
@Override
public void showMyLocation(View view) {
if (DebugConfig.isDebug()) {
CallerLogger.INSTANCE.d(TAG, Log.getStackTraceString(new Throwable()));
}
if (checkAMapView()) {
MyLocationStyle style = mMapView.getMapAutoViewHelper().getMyLocationStyle();
style.myLocationIcon(BitmapDescriptorFactory.INSTANCE.convertViewToBitmap(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 (mCurrentUI == EnumMapUI.Type_VR) {
return;
}
CallerLogger.INSTANCE.d(TAG, "锁车");
mMapView.getMapAutoViewHelper().setLockMode(true);
mIsCarLocked = true;
}
}
@Override
public void loseLockMode() {
if (mCurrentUI == EnumMapUI.Type_VR) {
return;
}
CallerLogger.INSTANCE.d(TAG, "解锁锁车");
mMapView.getMapAutoViewHelper().setLockMode(false);
mIsCarLocked = false;
}
@Override
public void setLockZoom(int var1) {
mLockZoom = var1;
}
@Override
public void displayOverview(Rect bounds) {
}
@Override
public float getScalePerPixel() {
return getMap().getScalePerPixel();
}
@Override
public float getZoomLevel() {
return getMap().getZoomLevel();
}
@Override
public float getRoadWidth(double lon, double lat, float angle, boolean isGpsLocation, boolean isRTK) {
return getMap().getRoadWidth(lon, lat, angle, isGpsLocation, isRTK);
}
@Override
public MogoLatLng getCameraNorthEastPosition() {
return ObjectUtils.fromAMap(MapTools.INSTANCE.getVisibleRegion().getRightTopPoint());
}
@Override
public MogoLatLng getCameraSouthWestPosition() {
try {
return ObjectUtils.fromAMap(MapTools.INSTANCE.getVisibleRegion().getLeftBottomPoint());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public MogoLatLng getWindowCenterLocation() {
try {
return ObjectUtils.fromAMap(mMapView.getMapAutoViewHelper().getCenter());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public void setPointToCenter(double mapCenterX, double mapCenterY) {
if (checkAMapView()) {
if (mCurrentUI == EnumMapUI.Type_VR) {
return;
}
CallerLogger.INSTANCE.d(TAG, "setPointToCenter x : " + mapCenterX + " y : " + 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) {
e.printStackTrace();
return null;
}
}
return null;
}
@Override
public MogoLatLng getLocationMogoLatLngInScreen(Point point) {
if (checkAMapView()) {
try {
return ObjectUtils.fromAMap(
MapTools.INSTANCE.fromScreenLocation(point));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
return null;
}
@Override
public void setRenderFps(int fps) {
if (checkAMapView()) {
if (mMapView.getMapAutoViewHelper() != null) {
mMapView.getMapAutoViewHelper().setRenderFps(fps);
CallerLogger.INSTANCE.d(TAG, "设置刷新帧率 fps = " + fps);
}
}
}
@Override
public void showBounds(String tag, MogoLatLng carPosition, List<MogoLatLng> lonLats, Rect bound, boolean lockCarPosition) {
if (!checkAMapView()) {
return;
}
if (mCurrentUI == EnumMapUI.Type_VR) {
CallerLogger.INSTANCE.w(TAG, "vr 模式下忽略该设置");
return;
}
CallerLogger.INSTANCE.i(TAG, "showBounds : " + tag + " , " + carPosition.toString() + " , " + bound.toShortString() + " , " + lockCarPosition);
try {
LatLngBounds latLngBounds = MogoMapUtils.getLatLngBounds(carPosition, lonLats, lockCarPosition);
if (!lockCarPosition) {
loseLockMode();
}
mMapView.getMapAutoViewHelper().setCenter(ObjectUtils.fromMogo(carPosition));
mMapView.getMapAutoViewHelper().moveCamera(CameraUpdateFactory.INSTANCE.newLatLngBounds(latLngBounds, bound.left, bound.right, bound.top, bound.bottom));
} catch (Exception e) {
CallerLogger.INSTANCE.e(TAG, "tag : " + tag + " error : " + e);
}
}
@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 MogoMapUtils.calculateLineDistance(ObjectUtils.fromMogo(p1), ObjectUtils.fromMogo(p2));
}
@Override
public EnumMapUI getCurrentUiMode() {
return mCurrentCarUIMode;
}
@Override
public void changeMyLocation(Location location) {
}
@Override
public synchronized boolean isCarLocked() {
return mMapView.getMapAutoViewHelper().getLockMode();
}
@Override
public void setCarCursorOption(CarCursorOption option) {
if (mCurrentUI == EnumMapUI.Type_VR) {
return;
}
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;
}
if (mMapView.getMapAutoViewHelper() == null) {
return;
}
MyLocationStyle style = mMapView.getMapAutoViewHelper().getMyLocationStyle();
if (mCarCursorOption.getCarCursorBmp() != null && !mCarCursorOption.getCarCursorBmp().isRecycled()) {
style.myLocationIcon(mCarCursorOption.getCarCursorBmp());
} else {
if (mCarCursorOption.getCarCursorRes() != 0) {
style.myLocationIcon(mCarCursorOption.getCarCursorRes());
}
}
mMapView.getMapAutoViewHelper().setMyLocationStyle(style);
}
@Override
public MapCameraPosition getMapCameraPosition() {
if (checkAMapView()) {
CameraPosition cameraPosition = mMapView.getMapAutoViewHelper().getCameraPosition();
return ObjectUtils.fromAMap(cameraPosition);
}
return null;
}
@Override
public void changeBearing(float bearing) {
if (checkAMapView()) {
mMapView.getMapAutoViewHelper().setMapViewRotation(bearing);
}
}
@Override
public void changeMapViewAngle(int type) {
if (checkAMapView()) {
//mMapView.getMapAutoViewHelper().testMapViewAngle(type);
}
}
@Override
public void changeCurrentIcon(int iconId) {
if (checkAMapView()) {
mMapView.getMapAutoViewHelper().getMyLocationStyle().myLocationIcon(iconId, true);
}
}
@Override
public long getTileId(double lon, double lat) {
return getMap().getUIController().getTileId(lon, lat);
}
@Override
public int getSpeedLimmit(double lon, double lat, float angle) {
return MapDataApi.INSTANCE.getLimitSpeed(lon, lat, angle);
}
@Override
public void onLocationChanged(@NotNull com.zhidaoauto.map.sdk.open.location.MogoLocation location) {
MogoLocation mLastLocation = ObjectUtils.fromLocation(location);
UiThreadHandler.post(() -> CallerMapLocationListenerManager.INSTANCE.invokeMapLocationChangeListener(mLastLocation));
Location sysLocation = new Location(location.getProvider());
sysLocation.setAltitude(location.getAltitude());
sysLocation.setLatitude(location.getLat());
sysLocation.setLongitude(location.getLon());
sysLocation.setProvider(location.getProvider());
sysLocation.setAccuracy(location.getAcceleration());
sysLocation.setTime(location.getDuration());
sysLocation.setBearing((float) location.getHeading());
sysLocation.setSpeed(location.getSpeed());
// 将有效经纬度暂存本地提供给下一次的Http-DNS使用防止首次请求位置获取不到
if (location.getLat() > 0) {
SharedPrefsMgr.getInstance(mMapView.getContext())
.putString(SharedPrefsConstants.LOCATION_CITY_CODE, location.getCityCode());
SharedPrefsMgr.getInstance(mMapView.getContext())
.putString(SharedPrefsConstants.LOCATION_LATITUDE, String.valueOf(location.getLat()));
SharedPrefsMgr.getInstance(mMapView.getContext())
.putString(SharedPrefsConstants.LOCATION_LONGITUDE, String.valueOf(location.getLon()));
}
if (MogoCarLocationChangedListenerRegister.getInstance().getListener() != null) {
MogoCarLocationChangedListenerRegister.getInstance().getListener().onCarLocationChanged2(sysLocation);
}
if (checkAMapView() && mMapLoaded) {
// 地图初始化完成后每隔5s自动判断当前地图的模式
if (mIsFirstLocated) {
if (!mIsDelayed) {
mIsDelayed = true;
UiThreadHandler.postDelayed(() -> {
//CallerLogger.INSTANCE.d(TAG, "倒计时结束");
mIsFirstLocated = false;
}, 5_000L);
}
} else {
mIsFirstLocated = true;
mIsDelayed = false;
CallerLogger.INSTANCE.d(TAG, "同步定位:" + GsonUtils.toJson(location));
MapStyleController.getInstance().onLocationChanged(location, this);
}
}
}
@Override
public void onMapClick(@Nullable LonLatPoint lonLatPoint) {
MogoMapListenerHandler.getInstance().onMapClick(ObjectUtils.fromAMap(lonLatPoint));
}
@Override
public void onMapInit() {
CallerLogger.INSTANCE.i(TAG, "autoop--onMapInit: ");
MogoMapListenerHandler.getInstance().onMapLoaded();
}
@Override
public void onMapLoaded() {
CallerLogger.INSTANCE.i(TAG, "autoop--onMapLoaded: ");
mMapLoaded = true;
CameraPosition cameraPosition = mMapView.getMapAutoViewHelper().getCameraPosition();
Trace.beginSection("timer.onCameraChangeFinish");
MogoMapListenerHandler.getInstance().onMapChanged(ObjectUtils.fromAMap(cameraPosition.getTarget()),
cameraPosition.getZoom(),
cameraPosition.getTilt(),
cameraPosition.getBearing());
Trace.endSection();
initMapView();
initMyLocation();
}
@Override
public boolean onTouch(@Nullable MotionEvent motionEvent) {
MogoMapListenerHandler.getInstance().onTouch(motionEvent);
return false;
}
@Override
public void onMarkClick(@NotNull Marker markerInfo) {
mMarkerClickHandler.handleMarkerClicked(markerInfo);
}
@Override
public void onRoadLoaded(@Nullable String s) {
CallerLogger.INSTANCE.i(TAG, "autoop--onMapLoaded: ");
}
@Override
public void onMapStatusChanged(int type, int value) {
//CallerLogger.INSTANCE.i(TAG, "mapop--onMapStatusChanged-: " + type + "," + value);
}
@Override
public void onMapViewVisualAngleChange(int i) {
CallerLogger.INSTANCE.d(TAG, " 地图自动更改视距 currentThread : " + Thread.currentThread().getName());
mVisualAngleMode = getVisualAngleMode(i);
MogoMapListenerHandler.getInstance().onMapVisualAngleChanged(mVisualAngleMode);
}
private VisualAngleMode getVisualAngleMode(int mode) {
switch (mode) {
case 0:
return MODE_CLOSE_SIGHT;
case 1:
return MODE_MEDIUM_SIGHT;
case 2:
return MODE_LONG_SIGHT;
case 3:
return MAP_STYLE_VR_ANGLE_300;
case 4:
return MAP_STYLE_VR_ANGLE_TOP;
case 5:
return MAP_STYLE_VR_ANGLE_CROSS;
default:
throw new IllegalStateException("mode is unCorrect");
}
}
@Override
public void onCameraChange(int type, int value) {
//CallerLogger.INSTANCE.i(TAG, "mapop--onCameraChange-: " + type + "," + value);
}
@Override
public void onCameraChangeFinish(@Nullable CameraPosition cameraPosition) {
// CallerLogger.INSTANCE.i( TAG, "mapop--onCameraChangeFinish-: " + cameraPosition + "cost:" + ( System.currentTimeMillis() - startTime ) );
if (cameraPosition != null) {
Trace.beginSection("timer.onCameraChangeFinish");
MogoMapListenerHandler.getInstance().onMapChanged(ObjectUtils.fromAMap(cameraPosition.getTarget()),
cameraPosition.getZoom(),
cameraPosition.getTilt(),
cameraPosition.getBearing());
Trace.endSection();
}
}
@Override
public void emphasizeMyLocation() {
}
@Override
public void onChangeMapStyle(int styleId) {
EnumMapUI last = mCurrentUI;
CallerLogger.INSTANCE.d(TAG, "currentMapStyle = " + styleId);
if (styleId == MapAutoApi.MAP_STYLE_DAY
|| styleId == MapAutoApi.MAP_STYLE_DAY_NAV) {
mCurrentUI = EnumMapUI.Type_Light;
} else if (styleId == MapAutoApi.MAP_STYLE_NIGHT
|| styleId == MapAutoApi.MAP_STYLE_NIGHT_NAV) {
mCurrentUI = EnumMapUI.Type_Night;
} else if (styleId == MapAutoApi.MAP_STYLE_VR) {
mCurrentUI = EnumMapUI.Type_VR;
// 进入vr模式的时候自动切换到车头朝上
change2CarUp();
}
if (last == mCurrentUI) {
CallerLogger.INSTANCE.d(TAG, "currentUI is same as last = " + mCurrentUI);
return;
}
// vr 模式切换到普通模式下,保持之前的白天模式 wtf.
if (last == EnumMapUI.Type_VR && mCurrentUI != EnumMapUI.Type_Light) {
if (mIsLightStyle) {
changeMapMode(EnumMapUI.Type_Light);
return;
}
}
CallerLogger.INSTANCE.d(TAG, Log.getStackTraceString(new Throwable()));
if (mCurrentUI != null) {
UiThreadHandler.post(() -> {
try {
CallerLogger.INSTANCE.d(TAG, "currentUI = " + mCurrentUI);
MogoMapListenerHandler.getInstance().onMapModeChanged(mCurrentUI);
CallerMapStyleListenerManager.INSTANCE.invokeMapStyleChange(styleId);
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
/**
* 切换到车头朝上
*/
private void change2CarUp() {
mMapView.getMapAutoViewHelper().setMapViewPerspective(MapAutoApi.MAP_PERSPECTIVE_UP_CAR);
}
@Override
public void onStyleAutoChanged(boolean isVrMode) {
if (isVrMode) {
if (mCurrentUI != EnumMapUI.Type_VR) {
CallerLogger.INSTANCE.d(TAG, "自动切换为vr模式");
changeMapMode(EnumMapUI.Type_VR);
}
} else {
if (mCurrentUI == EnumMapUI.Type_VR) {
CallerLogger.INSTANCE.d(TAG, "自动切换为2D模式");
if (mIsLightStyle) {
changeMapMode(EnumMapUI.Type_Light);
} else {
changeMapMode(EnumMapUI.Type_Night);
}
}
}
}
private boolean mRtkEnable = false;
@Override
public void rtkEnable(boolean enable) {
try {
mRtkEnable = !mRtkEnable;
TipToast.shortTip(mRtkEnable ? "已开启rtk道路匹配" : "已开启gps道路匹配");
mMapView.getLocationClient().rtkEnable(mRtkEnable);
} catch (Exception e) {
CallerLogger.INSTANCE.e(TAG, "rtkEnable has exception : " + e);
}
}
@Override
public void syncLocation2Map(JSONObject data) {
if (!checkAMapView()) {
return;
}
if (data == null) {
CallerLogger.INSTANCE.d(TAG, "停止使用rtk定位数据");
return;
}
double lon = data.optDouble("lon", -1);
double lat = data.optDouble("lat", -1);
double alt = data.optDouble("alt", -1);
double heading = data.optDouble("heading", -1);
double acceleration = data.optDouble("acceleration", -1);
double yawRate = data.optDouble("yawRate", -1);
double speed = data.optDouble("speed", -1);
long systemTime = data.optLong("systemTime");
long satelliteTime = data.optLong("satelliteTime");
if (lon == -1) {
return;
}
RTKAutopilotLocationBean bean = new RTKAutopilotLocationBean();
bean.setYaw_rate(yawRate);
bean.setHeading(heading);
bean.setAcceleration(acceleration);
bean.setAlt(alt);
bean.setSystemTime(systemTime);
bean.setSatelliteTime(satelliteTime);
bean.setLon(lon);
bean.setGnss_speed(((float) speed));
bean.setLat(lat);
// 使用外部定位数据修改自车位置
mMapView.getLocationClient().updateRTKAutoPilotLocation(bean);
CallerMapUIServiceManager.INSTANCE.getSingletonLocationClient(getContext()).updateLocation(bean);
CallerMapDataCollectorManager.INSTANCE.setIsInit();
}
@Override
public void syncLocation2Map(MessagePad.GnssInfo gnssInfo) {
if (!checkAMapView()) {
return;
}
if (gnssInfo.getLongitude() == -1) {
return;
}
RTKAutopilotLocationBean bean = new RTKAutopilotLocationBean();
bean.setYaw_rate(gnssInfo.getYawRate());
bean.setHeading(gnssInfo.getHeading());
bean.setAcceleration(gnssInfo.getAcceleration());
bean.setAlt(gnssInfo.getAltitude());
bean.setSystemTime(Double.valueOf(gnssInfo.getSystemTime()).longValue());
bean.setSatelliteTime(Double.valueOf(gnssInfo.getSatelliteTime()).longValue());
bean.setLon(gnssInfo.getLongitude());
bean.setLat(gnssInfo.getLatitude());
bean.setGnss_speed(((float) gnssInfo.getGnssSpeed()));
// 使用外部定位数据修改自车位置
mMapView.getLocationClient().updateRTKAutoPilotLocation(bean);
CallerMapUIServiceManager.INSTANCE.getSingletonLocationClient(getContext()).updateLocation(bean);
CallerMapDataCollectorManager.INSTANCE.setIsInit();
}
@Override
public void openVrMode(boolean zoomGestureEnable) {
try {
mMapView.getMapAutoViewHelper().setZoomGesturesEnabled(zoomGestureEnable);
mMapView.getMapAutoViewHelper().setMapStyle(MapAutoApi.MAP_STYLE_VR);
} catch (Exception e) {
e.printStackTrace();
}
}
Map<String, RoadCacheWrapper> roadCacheMap = new ConcurrentHashMap<>();
private final RoadCacheWrapper noCache = new RoadCacheWrapper(null);
@Override
public void clearRoadCacheById(String id) {
roadCacheMap.remove(id);
}
@Override
public double[] matchRoad(String id, double lon, double lat, double angle, boolean isGpsLocation, boolean isRTK) {
return matchRoad(id, lon, lat, angle, isGpsLocation, isRTK, true);
}
/**
* 带缓存的道路匹配算法
* <p>
* 使用{@link MapDataApi#INSTANCE#getSinglePointMatchRoad()}这个方法获取道路数据会存在一定耗时目前是4-10ms因为请求频繁为了
* 减小这部分耗时使用一个ConcurrentHashMap{@link #roadCacheMap}缓存道路数据此缓存是以目标车id为key道路数据为value以此减少
* 道路数据获取次数。
* <p>
* 当出现道路改变的情况需要重新获取道路数据采用递归的方式重获道路数据以及添加缓存为了避免一直获取不到道路数据一直递归增加useCache参数跳出递归。
* <p>
* 道路改变的情况主要分为:
* 1. 目标车距离道路中心线距离超过阈值 matchThreshold取路宽的1/4为阈值
* 2. 目标车到道路中心线的映射点不在道路上(此判断在{@link PointInterpolatorUtil#mergeToRoad(double, double, List)}),也就是说已经驶出了这条道路
*
* @param id 目标车唯一标识
* @param lon 目标车经度
* @param lat 目标车纬度
* @param angle 目标车角度
* @param isGpsLocation true-使用gps定位数据
* @param isRTK true-使用rtk数据
* @param usdCache true-使用道路缓存 false-不使用道路缓存
* @return double[]{匹配后经度,匹配后纬度,目标车距离车道中心线距离},若匹配后经纬度值为-1则没有匹配成功
*/
private double[] matchRoad(String id, double lon, double lat, double angle, boolean isGpsLocation, boolean isRTK, boolean usdCache) {
double[] wgs = new double[]{lon, lat};
long start = System.currentTimeMillis();
RoadCacheWrapper roadCache = roadCacheMap.get(id);
double matchThreshold = -1;
if (roadCache == null || roadCache == noCache) {
SinglePointRoadInfo singlePointRoadInfo = MapDataApi.INSTANCE.getSinglePointMatchRoad(((float) wgs[0]), ((float) wgs[1]), ((float) angle), isGpsLocation, isRTK);
if (singlePointRoadInfo != null && singlePointRoadInfo.getCoords() != null && !singlePointRoadInfo.getCoords().isEmpty()) {
roadCache = new RoadCacheWrapper(singlePointRoadInfo.getCoords());
roadCache.setLaneWidth(singlePointRoadInfo.getLaneWidth());
}
}
if (roadCache != null
&& roadCache.getRoad() != null
&& !roadCache.getRoad().isEmpty()) {
// 未获取到道路中心线数据
start = System.currentTimeMillis();
matchThreshold = roadCache.getLaneWidth() / 4;
double[] matchedPoint = PointInterpolatorUtil.mergeToRoad(wgs[0], wgs[1], roadCache.getRoad());
if (matchThreshold > 0 && matchedPoint[2] > 0 && matchedPoint[2] <= matchThreshold) {
// 目标车在阈值范围内
roadCacheMap.put(id, roadCache);
// CallerLogger.INSTANCE.i("timer-matchRoad-3", "cost " + (System.currentTimeMillis() - start) + "ms");
return matchedPoint;
// CallerLogger.INSTANCE.i("timer-matchRoad-2", "cost " + (System.currentTimeMillis() - start) + "ms roadId: "+roadCache.getLastLat());
} else if (matchedPoint[2] > matchThreshold && matchedPoint[2] < 1.5) {
// 目标车在阈值范围外,也就是说距离道路中心线太远了,就不吸附了
return null;
} else {
// 目标车到道路中心线的映射点不在道路上也就是已经使出了缓存的那条道路需要重新获取一条道路用useCache这个参数来避免重复递归
roadCacheMap.put(id, noCache);
// CallerLogger.INSTANCE.i("timer-matchRoad-2", "cost " + (System.currentTimeMillis() - start) + "ms roadId: " + roadCache.getLastLat());
if (usdCache) {
return matchRoad(id, lon, lat, angle, isGpsLocation, isRTK, false);
} else {
return null;
}
}
}
roadCacheMap.put(id, noCache);
return null;
}
@Override
public String getMarkerInfoResName(String speedVal) {
return ResIdCache.getVal(speedVal);
}
@Override
public void setMarkerInfoResName(String speedVal, String val) {
ResIdCache.putVal(speedVal, val);
}
@Override
public void setMapDAngle(float angle) {
mMapView.getMapAutoViewHelper().setMapDAngle(angle);
}
}