增加控制地图「白天」「夜间」模式

Signed-off-by: donghongyu <donghongyu@zhidaoauto.com>
This commit is contained in:
donghongyu
2022-04-11 16:38:39 +08:00
parent 0f66542bca
commit 63f3f8d8c8
22 changed files with 155 additions and 528 deletions

View File

@@ -45,7 +45,6 @@ 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;
@@ -60,7 +59,6 @@ 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;
@@ -79,8 +77,6 @@ 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;
@@ -149,7 +145,6 @@ public class AMapViewWrapper implements IMogoMapView,
}
private void initListeners() {
mMapView.setOnMarkClickListener(this);
mMarkerClickHandler = AMapMarkerClickHandler.getInstance();
mMapView.setOnMapLoadedListener(this);
@@ -306,46 +301,9 @@ public class AMapViewWrapper implements IMogoMapView,
}
@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) {
if (isVrMold()) {
return MapControlResult.ERROR;
}
CallerLogger.INSTANCE.d(TAG, "changeZoom : " + zoom);
@@ -365,7 +323,14 @@ public class AMapViewWrapper implements IMogoMapView,
CallerLogger.INSTANCE.d(TAG, "设置的样式 :" + ui);
if (checkAMapView()) {
mMapView.getMapAutoViewHelper().setScaleVRMode(true);
mMapView.getMapAutoViewHelper().setMapStyle(MapAutoApi.MAP_STYLE_VR);
if (ui == EnumMapUI.MAP_STYLE_DAY_VR) {
mMapView.getMapAutoViewHelper().setMapStyle(MapAutoApi.MAP_STYLE_DAY_VR);
} else if (ui == EnumMapUI.MAP_STYLE_NIGHT_VR) {
mMapView.getMapAutoViewHelper().setMapStyle(MapAutoApi.MAP_STYLE_NIGHT_VR);
} else {
mMapView.getMapAutoViewHelper().setMapStyle(MapAutoApi.MAP_STYLE_NIGHT_VR);
CallerLogger.INSTANCE.e(TAG, "暂时不支持此模式 :" + ui);
}
}
}
@@ -423,7 +388,7 @@ public class AMapViewWrapper implements IMogoMapView,
public void showMyLocation(boolean visible) {
CallerLogger.INSTANCE.d(TAG, "showMyLocation1 " + visible);
// 如果是VR模式
if (mCurrentUI == EnumMapUI.Type_VR) {
if (isVrMold()) {
return;
}
// 不是VR模式情况强制刷新下
@@ -437,6 +402,10 @@ public class AMapViewWrapper implements IMogoMapView,
}
}
private boolean isVrMold() {
return mCurrentUI == EnumMapUI.MAP_STYLE_NIGHT_VR || mCurrentUI == EnumMapUI.MAP_STYLE_DAY_VR;
}
@Override
public void showMyLocation(View view) {
if (DebugConfig.isDebug()) {
@@ -453,7 +422,6 @@ public class AMapViewWrapper implements IMogoMapView,
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 );
@@ -466,7 +434,7 @@ public class AMapViewWrapper implements IMogoMapView,
@Override
public void recoverLockMode() {
if (checkAMapView()) {
if (mCurrentUI == EnumMapUI.Type_VR) {
if (isVrMold()) {
return;
}
CallerLogger.INSTANCE.d(TAG, "锁车");
@@ -476,17 +444,13 @@ public class AMapViewWrapper implements IMogoMapView,
@Override
public void loseLockMode() {
if (mCurrentUI == EnumMapUI.Type_VR) {
if (isVrMold()) {
return;
}
CallerLogger.INSTANCE.d(TAG, "解锁锁车");
mMapView.getMapAutoViewHelper().setLockMode(false);
}
@Override
public void displayOverview(Rect bounds) {
}
@Override
public float getScalePerPixel() {
@@ -531,7 +495,7 @@ public class AMapViewWrapper implements IMogoMapView,
@Override
public void setPointToCenter(double mapCenterX, double mapCenterY) {
if (checkAMapView()) {
if (mCurrentUI == EnumMapUI.Type_VR) {
if (isVrMold()) {
return;
}
CallerLogger.INSTANCE.d(TAG, "setPointToCenter x : " + mapCenterX + " y : " + mapCenterY);
@@ -581,7 +545,7 @@ public class AMapViewWrapper implements IMogoMapView,
if (!checkAMapView()) {
return;
}
if (mCurrentUI == EnumMapUI.Type_VR) {
if (isVrMold()) {
CallerLogger.INSTANCE.w(TAG, "vr 模式下忽略该设置");
return;
}
@@ -624,7 +588,7 @@ public class AMapViewWrapper implements IMogoMapView,
@Override
public void setCarCursorOption(CarCursorOption option) {
if (mCurrentUI == EnumMapUI.Type_VR) {
if (isVrMold()) {
return;
}
if (mCarCursorOption != null && mCarCursorOption != DEFAULT_OPTION) {
@@ -805,6 +769,12 @@ public class AMapViewWrapper implements IMogoMapView,
MogoMapListenerHandler.getInstance().onMapVisualAngleChanged(mVisualAngleMode);
}
/**
* 获取当前视距类型
*
* @param mode 当前类型
* @return 当前类型
*/
private VisualAngleMode getVisualAngleMode(int mode) {
switch (mode) {
case 0:
@@ -849,35 +819,23 @@ public class AMapViewWrapper implements IMogoMapView,
@Override
public void onChangeMapStyle(int styleId) {
EnumMapUI last = mCurrentUI;
CallerLogger.INSTANCE.d(TAG, "currentMapStyle = " + styleId);
CallerLogger.INSTANCE.d(TAG, Log.getStackTraceString(new Throwable()));
// 映射地图样式ID到鹰眼样式ID
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();
mCurrentUI = EnumMapUI.MAP_STYLE_DAY_NAV;
} else if (styleId == MapAutoApi.MAP_STYLE_NIGHT) {
mCurrentUI = EnumMapUI.MAP_STYLE_NIGHT;
} else if (styleId == MapAutoApi.MAP_STYLE_NIGHT_NAV) {
mCurrentUI = EnumMapUI.MAP_STYLE_NIGHT_NAV;
} else if (styleId == MapAutoApi.MAP_STYLE_NIGHT_VR) {
mCurrentUI = EnumMapUI.MAP_STYLE_NIGHT_VR;
} else if (styleId == MapAutoApi.MAP_STYLE_DAY_VR) {
mCurrentUI = EnumMapUI.MAP_STYLE_DAY_VR;
}
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 {
@@ -891,13 +849,7 @@ public class AMapViewWrapper implements IMogoMapView,
}
}
/**
* 切换到车头朝上
*/
private void change2CarUp() {
mMapView.getMapAutoViewHelper().setMapViewPerspective(MapAutoApi.MAP_PERSPECTIVE_UP_CAR);
}
// 是否使用RTK数据
private boolean mRtkEnable = false;
@Override
@@ -977,91 +929,25 @@ public class AMapViewWrapper implements IMogoMapView,
public void openVrMode(boolean zoomGestureEnable) {
try {
mMapView.getMapAutoViewHelper().setZoomGesturesEnabled(zoomGestureEnable);
mMapView.getMapAutoViewHelper().setMapStyle(MapAutoApi.MAP_STYLE_VR);
mMapView.getMapAutoViewHelper().setMapStyle(MapAutoApi.MAP_STYLE_DAY_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;
public void stepInVrMode(boolean isDayMode) {
try {
int mapStyle;
if (isDayMode) {
mapStyle = MapAutoApi.MAP_STYLE_DAY_VR;
} 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;
}
mapStyle = MapAutoApi.MAP_STYLE_NIGHT_VR;
}
mMapView.getMapAutoViewHelper().setMapStyle(mapStyle);
} catch (Exception e) {
e.printStackTrace();
}
roadCacheMap.put(id, noCache);
return null;
}
@Override
@@ -1081,7 +967,7 @@ public class AMapViewWrapper implements IMogoMapView,
@Override
public float getAngle(double startLon, double startLat, double endLon, double endLat) {
return MapAutoApi.INSTANCE.getAngle(startLon,startLat,endLon,endLat);
return MapAutoApi.INSTANCE.getAngle(startLon, startLat, endLon, endLat);
}
}