合并obu部分代码

This commit is contained in:
tongchenfei
2020-08-19 20:42:17 +08:00
parent 5af67fecf4
commit ac72a04995
24 changed files with 1055 additions and 7 deletions

2
.idea/misc.xml generated
View File

@@ -4,7 +4,7 @@
<asm skipDebug="false" skipFrames="false" skipCode="false" expandFrames="false" />
<groovy codeStyle="LEGACY" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="JDK" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
</project>

View File

@@ -250,9 +250,9 @@ dependencies {
implementation rootProject.ext.dependencies.mogologlib
implementation rootProject.ext.dependencies.modulepushbase
launcherImplementation rootProject.ext.dependencies.modulepush
independentImplementation rootProject.ext.dependencies.modulepushnoop
// implementation rootProject.ext.dependencies.modulepushbase
// launcherImplementation rootProject.ext.dependencies.modulepush
// independentImplementation rootProject.ext.dependencies.modulepushnoop
if (Boolean.valueOf(RELEASE)) {
implementation rootProject.ext.dependencies.mogocommons

View File

@@ -96,7 +96,7 @@ public class MogoApplication extends AbsMogoApplication {
DebugConfig.setUseCustomNavi( BuildConfig.USE_CUSTOM_NAVI );
DebugConfig.setLauncher( BuildConfig.IS_LAUNCHER );
DebugConfig.setActiveAIAssistFlag( BuildConfig.AI_ASSIST_ACTIVE_STAUTS );
DebugConfig.setUseMockObuData(false);
DebugConfig.setUseMockObuData(true);
ObuConfig.useObuLocation = false;
DebugConfig.setCarMachineType( BuildConfig.CAR_MACHINE_TYPE );
DebugConfig.setProductFlavor( BuildConfig.FLAVOR_product );

View File

@@ -102,6 +102,8 @@ public class V2XMessageEntity<T> implements Serializable {
int ALERT_ILLEGAL_PARK_WARNING = 1_008;
// 自车求助
int ALERT_CAR_FOR_HELP = 8_000;
// obu事件
int ALERT_OBU_EVENT = 9_000;
}
@IntDef(value = {
@@ -115,6 +117,7 @@ public class V2XMessageEntity<T> implements Serializable {
V2XTypeEnum.ALERT_ROAD_LIVE_CAR_WARNING,
V2XTypeEnum.ALERT_ILLEGAL_PARK_WARNING,
V2XTypeEnum.ALERT_CAR_FOR_HELP,
V2XTypeEnum.ALERT_OBU_EVENT,
})
@Target({
ElementType.PARAMETER,

View File

@@ -0,0 +1,35 @@
package com.mogo.module.common.entity;
/**
* obu事件封装
*
* @author tongchenfei
*/
public class V2XObuEventEntity {
private int type;
private String desc;
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
@Override
public String toString() {
return "V2XObuEventEntity{" +
"type=" + type +
", desc='" + desc + '\'' +
'}';
}
}

View File

@@ -55,7 +55,7 @@ object MockUtil {
carEventInfo.describe = "这个应该是随便写,反正也不用"
dataCallback.showCarEventInfo(carEventInfo)
}
api.windowManagerApi.addView(view, 960, 500, false)
api.windowManagerApi.addView(view, 500, 300, false)
intervalMockData()
}

View File

@@ -83,10 +83,11 @@ dependencies {
}
annotationProcessor rootProject.ext.dependencies.aroutercompiler
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
compileOnly project(':modules:mogo-module-obu')
}
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()

View File

@@ -121,4 +121,8 @@ public class V2XConst {
*/
public static final String V2X_MARKER_GOVERNMENT = "V2X_MARKER_GOVERNMENT";
/**
* 绿波车速marker
*/
public static final String V2X_OPTIMAL_SPEED_MARKER = "V2X_OPTIMAL_SPEED_MARKER";
}

View File

@@ -134,6 +134,8 @@ public class V2XModuleProvider implements
intentFilter.addAction(V2XConst.BROADCAST_SCENE_HANDLER_ACTION);
localBroadcastManager.registerReceiver(localReceiver, intentFilter);
// obu数据转发初始化
V2XObuManager.getInstance().init();
}
private void initData() {

View File

@@ -0,0 +1,283 @@
package com.mogo.module.v2x;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.ArrayMap;
import com.amap.api.maps.CoordinateConverter;
import com.amap.api.maps.model.LatLng;
import com.mogo.map.location.MogoLocation;
import com.mogo.module.common.entity.V2XMessageEntity;
import com.mogo.module.common.entity.V2XObuEventEntity;
import com.mogo.module.common.entity.V2XPushMessageEntity;
import com.mogo.module.v2x.listener.V2XLocationListener;
import com.mogo.module.v2x.scenario.scene.obu.V2XObuEventScenario;
import com.mogo.module.v2x.utils.ADASUtils;
import com.mogo.module.v2x.utils.DrivingDirectionUtils;
import com.mogo.module.v2x.utils.ObuConfig;
import com.mogo.service.obu.IMogoObuDataChangedListener;
import com.mogo.utils.logger.Logger;
import com.zhidao.mogo.module.obu.ObuConstant;
import com.zhidao.smartv2x.model.obu.CarEventInfo;
import com.zhidao.smartv2x.model.obu.CarLocationInfo;
import com.zhidao.smartv2x.model.obu.TrafficLightInfo;
import org.json.JSONObject;
import java.util.Map;
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
import static com.mogo.module.v2x.scenario.scene.obu.V2XObuEventScenario.ACTION_LAUNCHER_ADAS_APP_BIZ;
/**
* obu数据管理类封装
*
* @author tongchenfei
*/
public class V2XObuManager implements IMogoObuDataChangedListener, Handler.Callback {
private static final String TAG = V2XObuManager.class.getSimpleName();
private static final long DEFAULT_INTERVAL_TIME = 30_000L;
private V2XObuManager() {
}
private volatile static V2XObuManager instance = null;
public static V2XObuManager getInstance() {
if (instance == null) {
synchronized (V2XObuManager.class) {
if (instance == null) {
instance = new V2XObuManager();
}
}
}
return instance;
}
private static final int MSG_HIDE_TRAFFIC_LIGHT = 1001;
private static final long DEFAULT_HIDE_TRAFFIC_LIGHT_DELAY = 1500L;
private Handler handler = new Handler(this);
public void init() {
Logger.d(MODULE_NAME, "obuManager初始化--");
V2XServiceManager.getMogoRegisterCenter().registerObuDataListener(MODULE_NAME, this);
}
/**
* 用来处理30秒内不重复播报的情况
*/
private Map<String, Long> intervalMap = new ArrayMap<>();
/**
* 车辆位置信息回调接口
*
* @param info 位置信息
*/
@Override
public void showCarLocationInfo(CarLocationInfo info) {
if (ObuConfig.useObuLocation) {
MogoLocation currentLocation = new MogoLocation();
CoordinateConverter converter = new CoordinateConverter(V2XServiceManager.getContext());
converter.from(CoordinateConverter.CoordType.GPS);
LatLng latLng = new LatLng(info.lat, info.lng);
converter.coord(latLng);
LatLng convert = converter.convert();
currentLocation.setLatitude(convert.latitude);
currentLocation.setLongitude(convert.longitude);
currentLocation.setBearing(computeCarAngle(currentLocation));
V2XObuEventScenario.getInstance().updateLocation(currentLocation);
}
}
/**
* UDP 收发消息回调接口
*
* @param info 消息回调
*/
@Override
public void showOtherInfo(String info) {
}
/**
* 交通信号灯信息回调接口
*
* @param info 信号灯信息
*/
@Override
public void showTrafficLightInfo(TrafficLightInfo info) {
handler.removeMessages(MSG_HIDE_TRAFFIC_LIGHT);
if (info == null) {
Logger.d("V2X_OBU_EVENT", "红绿灯数据为空===");
sendTrafficLightStatusToAdas(CALL_ADAS_HIDE_TRAFFIC_LIGHT, null);
} else {
Logger.d("V2X_OBU_EVENT", "红绿灯数据==" + info);
handler.sendEmptyMessageDelayed(MSG_HIDE_TRAFFIC_LIGHT, DEFAULT_HIDE_TRAFFIC_LIGHT_DELAY);
sendTrafficLightStatusToAdas(CALL_ADAS_SHOW_TRAFFIC_LIGHT, info);
}
}
/**
* 场景触发事件信息回调接口
*
* @param info 场景触发事件信息
*/
@Override
public void showCarEventInfo(CarEventInfo info) {
Logger.d("V2X_OBU_EVENT", "carEventInfo==" + info);
Long last = intervalMap.get(info.typeCode);
if (last == null) {
last = 0L;
}
int eventType = parseObuEvent(info.typeCode);
if (eventType == ObuConstant.TYPE_OPTIMAL_SPEED_ADVISORY) {
// 加一个容错机制如果已经驶过绿波车速路口那么再收到绿波车速obu事件就不再上报
MogoLocation currentLocation = V2XLocationListener.getInstance().getLastCarLocation();
double eventAngle = DrivingDirectionUtils.getDegreeOfCar2Poi(
currentLocation.getLongitude(),
currentLocation.getLatitude(),
V2XObuEventScenario.getInstance().getOptimalCrossing().getLon(),
V2XObuEventScenario.getInstance().getOptimalCrossing().getLat(),
(int) currentLocation.getBearing()
);
if (0 > eventAngle || eventAngle > 20) {
Logger.e(MODULE_NAME, "超出绿波引导点范围,不处理此次事件===" + eventAngle);
return;
}
}
if (SystemClock.elapsedRealtime() - last > DEFAULT_INTERVAL_TIME) {
// 距离上次记录超过三十秒,继续相关逻辑,如果不超过三十秒,忽略此次事件
intervalMap.put(info.typeCode, SystemClock.elapsedRealtime());
V2XMessageEntity<V2XObuEventEntity> messageEntity = new V2XMessageEntity<>();
messageEntity.setType(V2XMessageEntity.V2XTypeEnum.ALERT_OBU_EVENT);
switch (eventType) {
case ObuConstant
.TYPE_OPTIMAL_SPEED_ADVISORY:
// 绿波车速引导
V2XObuEventEntity optimalEvent = new V2XObuEventEntity();
optimalEvent.setType(ObuConstant.TYPE_OPTIMAL_SPEED_ADVISORY);
optimalEvent.setDesc(info.describe);
messageEntity.setContent(optimalEvent);
V2XObuEventScenario.getInstance().init(messageEntity);
break;
case ObuConstant.TYPE_URGENCY_COLLISION_WARNING:
// 前车紧急制动预警
V2XObuEventEntity urgencyEvent = new V2XObuEventEntity();
urgencyEvent.setType(ObuConstant.TYPE_URGENCY_COLLISION_WARNING);
urgencyEvent.setDesc(V2XObuEventScenario.URGENCY_COLLISION_WARN_TEXT);
messageEntity.setContent(urgencyEvent);
V2XObuEventScenario.getInstance().init(messageEntity);
break;
case ObuConstant.TYPE_ROAD_USER_COLLISION_WARNING:
// 行人预警给adas发送广播即可
V2XPushMessageEntity entity = new V2XPushMessageEntity();
// 盲区行人预警的sceneId-100003
entity.setSceneId("100003");
entity.setTts("前方行人,注意减速");
entity.setExpireTime(30_000);
entity.setAlarmContent("前方行人,注意减速");
ADASUtils.broadcastToADAS(V2XServiceManager.getContext(), entity);
break;
case ObuConstant.TYPE_CHANGE_LIGHT_FOR_VIP:
// vip变灯提醒
V2XObuEventEntity changeLightEvent = new V2XObuEventEntity();
changeLightEvent.setType(ObuConstant.TYPE_CHANGE_LIGHT_FOR_VIP);
changeLightEvent.setDesc(info.describe);
messageEntity.setContent(changeLightEvent);
V2XObuEventScenario.getInstance().init(messageEntity);
break;
default:
break;
}
}
}
private int parseObuEvent(String type) {
switch (type) {
case "06":
// 紧急制动预警
return ObuConstant.TYPE_URGENCY_COLLISION_WARNING;
case "13":
// 绿波车速引导
return ObuConstant.TYPE_OPTIMAL_SPEED_ADVISORY;
case "39":
// 行人碰撞预警
return ObuConstant.TYPE_ROAD_USER_COLLISION_WARNING;
case "vip变灯提醒":
return ObuConstant.TYPE_CHANGE_LIGHT_FOR_VIP;
default:
return -1;
}
}
private MogoLocation[] historyPath = new MogoLocation[2];
private float computeCarAngle(MogoLocation location) {
float angle = 0f;
if (historyPath[0] != null) {
historyPath[1] = historyPath[0];
}
historyPath[0] = location;
if (historyPath[1] != null && historyPath[0] != null) {
double carAngle =
DrivingDirectionUtils.getCarAngle(
historyPath[1].getLatitude(), historyPath[1].getLongitude(),
historyPath[0].getLatitude(), historyPath[0].getLongitude()
);
// 这里是真实的车辆角度
angle = (float) carAngle;
}
return angle;
}
private static final String CALL_ADAS_SHOW_TRAFFIC_LIGHT = "2";
private static final String CALL_ADAS_HIDE_TRAFFIC_LIGHT = "1";
private void sendTrafficLightStatusToAdas(String status, TrafficLightInfo trafficLightInfo) {
if (V2XObuEventScenario.getInstance().isInChangeLightForVip()) {
status = CALL_ADAS_HIDE_TRAFFIC_LIGHT;
}
try {
Intent intent = new Intent(ACTION_LAUNCHER_ADAS_APP_BIZ);
JSONObject json = new JSONObject();
// String action "1" - 隐藏 "2" - 显示
json.put("action", status);
if (trafficLightInfo != null) {
if (trafficLightInfo.lightStatus == null) {
json.put("lightStatus", "G");
} else {
json.put("lightStatus", trafficLightInfo.lightStatus);
}
if (trafficLightInfo.surplusTime == null) {
json.put("surplusTime", "0");
} else {
json.put("surplusTime", trafficLightInfo.surplusTime);
}
}
String data = json.toString();
Logger.d(MODULE_NAME, "发送红绿灯广播: " + data);
intent.putExtra("data", data);
intent.putExtra("type", 2);
V2XServiceManager.getContext().sendBroadcast(intent);
} catch (Exception e) {
e.printStackTrace();
Logger.e(MODULE_NAME, e, "发送红绿灯广播异常==");
}
}
@Override
public boolean handleMessage(Message msg) {
if (msg.what == MSG_HIDE_TRAFFIC_LIGHT) {
sendTrafficLightStatusToAdas(CALL_ADAS_HIDE_TRAFFIC_LIGHT, null);
return true;
}
return false;
}
}

View File

@@ -0,0 +1,43 @@
package com.mogo.module.v2x.marker;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import androidx.annotation.Nullable;
import com.mogo.module.common.entity.MarkerShowEntity;
import com.mogo.module.service.marker.MapMarkerBaseView;
import com.mogo.module.v2x.R;
/**
* 绿波速度引导在地图上打的marker
*
* @author tongchenfei
*/
public class OptimalSpeedMarkerView extends MapMarkerBaseView {
private String TAG = "OptimalSpeedMarkerView";
public OptimalSpeedMarkerView(Context context ) {
super( context );
}
public OptimalSpeedMarkerView(Context context, @Nullable AttributeSet attrs ) {
super( context, attrs );
}
public OptimalSpeedMarkerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr ) {
super( context, attrs, defStyleAttr );
}
@Override
protected void initView( Context context ) {
LayoutInflater.from( context ).inflate(R.layout.view_v2x_optimal_speed_marker, this );
}
@Override
public void updateView( MarkerShowEntity markerShowEntity ) {
}
}

View File

@@ -0,0 +1,41 @@
package com.mogo.module.v2x.scenario.scene.obu;
import com.mogo.map.MogoLatLng;
import com.mogo.map.marker.IMogoMarker;
import com.mogo.map.marker.MogoMarkerOptions;
import com.mogo.module.service.utils.ViewUtils;
import com.mogo.module.v2x.V2XServiceManager;
import com.mogo.module.v2x.marker.OptimalSpeedMarkerView;
import com.mogo.module.v2x.scenario.view.IV2XMarker;
import com.mogo.utils.logger.Logger;
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
import static com.mogo.module.v2x.V2XConst.V2X_OPTIMAL_SPEED_MARKER;
/**
* 绿波车速的marker
*/
class OptimalSpeedMarker implements IV2XMarker<MogoLatLng> {
private IMogoMarker optimalMarker = null;
@Override
public void drawPOI(MogoLatLng entity) {
Logger.d(MODULE_NAME, "绘制绿波marker===" + entity);
MogoMarkerOptions optionsRipple = new MogoMarkerOptions()
.latitude(entity.getLat())
.longitude(entity.getLon()).anchor(0.5f,0.9f).icon(ViewUtils.fromView(new OptimalSpeedMarkerView(V2XServiceManager.getContext())));
optimalMarker = V2XServiceManager.getMarkerManager().addMarker(V2X_OPTIMAL_SPEED_MARKER, optionsRipple);
optimalMarker.setClickable(false);
}
@Override
public void clearPOI() {
Logger.d(MODULE_NAME,"准备清除绿波marker");
if (optimalMarker != null) {
Logger.d(MODULE_NAME, "清除绿波marker===" + optimalMarker);
optimalMarker.remove();
optimalMarker = null;
}
}
}

View File

@@ -0,0 +1,382 @@
package com.mogo.module.v2x.scenario.scene.obu;
import android.content.Intent;
import android.graphics.Color;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import androidx.annotation.Nullable;
import com.mogo.commons.voice.AIAssist;
import com.mogo.map.MogoLatLng;
import com.mogo.map.location.MogoLocation;
import com.mogo.map.overlay.IMogoPolyline;
import com.mogo.map.overlay.MogoPolylineOptions;
import com.mogo.module.common.entity.V2XMessageEntity;
import com.mogo.module.common.entity.V2XObuEventEntity;
import com.mogo.module.service.Utils;
import com.mogo.module.v2x.V2XObuManager;
import com.mogo.module.v2x.V2XServiceManager;
import com.mogo.module.v2x.listener.V2XWindowStatusListener;
import com.mogo.module.v2x.scenario.impl.AbsV2XScenario;
import com.mogo.module.v2x.utils.DrivingDirectionUtils;
import com.mogo.utils.logger.Logger;
import com.zhidao.mogo.module.obu.ObuConstant;
import com.zhidao.smartv2x.model.obu.CarEventInfo;
import org.json.JSONObject;
import java.util.Arrays;
import java.util.List;
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
/**
* obu场景界面管理
*
* @author tongchenfei
*/
public class V2XObuEventScenario extends AbsV2XScenario<V2XObuEventEntity> implements Handler.Callback {
public static final String URGENCY_COLLISION_WARN_TEXT = "前车急刹,注意保持安全距离!";
private static final int MSG_CLOSE_OBU_WINDOW = 1001;
private static final int DEFAULT_EXPIRE_TIME = 20_000;
private static final float DEFAULT_VIP_CROSSING_DISTANCE = 100F;
/**
* 可以关闭绿波引导的距离路口的最大距离,单位是米
*/
private static final float DEFAULT_DISTANCE_TO_CLOSE_OPTIMAL = 10F;
private IMogoPolyline optimalLine = null;
private MogoLatLng defaultTarget = new MogoLatLng(39.969326, 116.407788);
private MogoLatLng optimalCrossing = new MogoLatLng(40.196431,116.738011);
// private MogoLatLng vipCrossing = new MogoLatLng(40.200467,116.745498);
private MogoLatLng vipCrossing1 = new MogoLatLng(40.200467,116.745498);
private MogoLatLng vipCrossing2 = new MogoLatLng(40.200491,116.738535);
private List<MogoLatLng> vipCrossingList = Arrays.asList(vipCrossing1, vipCrossing2);
private V2XObuEventScenario() {
}
private volatile static V2XObuEventScenario instance = null;
public static V2XObuEventScenario getInstance() {
if (instance == null) {
synchronized (V2XObuEventScenario.class) {
if (instance == null) {
instance = new V2XObuEventScenario();
instance.setV2XWindow(new V2XObuEventWindow(V2XServiceManager.getContext()));
}
}
}
return instance;
}
private V2XMessageEntity<V2XObuEventEntity> lastMessage = null;
private OptimalSpeedMarker optimalSpeedMarker = null;
private Handler handler = new Handler(Looper.getMainLooper(), this);
@Override
public void init(@Nullable V2XMessageEntity<V2XObuEventEntity> v2XMessageEntity) {
Logger.d(MODULE_NAME, "obu场景初始化: " + v2XMessageEntity);
setV2XMessageEntity(v2XMessageEntity);
if (v2XMessageEntity.getContent().getType() == ObuConstant.TYPE_OPTIMAL_SPEED_ADVISORY) {
// 如果需要区分路口,就在这里做一下判断,给默认目标点赋值
defaultTarget = optimalCrossing;
if (optimalSpeedMarker == null) {
optimalSpeedMarker = new OptimalSpeedMarker();
} else {
optimalSpeedMarker.clearPOI();
}
} else if (v2XMessageEntity.getContent().getType() == ObuConstant.TYPE_CHANGE_LIGHT_FOR_VIP) {
// vip变灯提醒
isInChangeLightForVip = true;
V2XObuManager.getInstance().showTrafficLightInfo(null);
if (optimalSpeedMarker == null) {
optimalSpeedMarker = new OptimalSpeedMarker();
} else {
optimalSpeedMarker.clearPOI();
}
}
show();
}
/**
* 展示场景
* <p>
* 此场景需要语音提示和弹窗
*/
@Override
public void show() {
AIAssist.getInstance(V2XServiceManager.getContext()).speakTTSVoice(getV2XMessageEntity().getContent().getDesc());
showWindow();
if (handler.hasMessages(MSG_CLOSE_OBU_WINDOW)) {
handler.removeMessages(MSG_CLOSE_OBU_WINDOW);
}
handler.sendEmptyMessageDelayed(MSG_CLOSE_OBU_WINDOW, DEFAULT_EXPIRE_TIME);
}
/**
* 展示Window
*/
@Override
public void showWindow() {
if (lastMessage != null && lastMessage.getContent().getType() == ObuConstant.TYPE_OPTIMAL_SPEED_ADVISORY) {
Logger.d(MODULE_NAME, "上一条消息是绿波,发送隐藏广播===");
// 上一条信息是绿波,需要隐藏上一条信息
sendBroadcastToAdas(CALL_ADAS_HIDE_OPTIMAL);
}
if (lastMessage != null && lastMessage.getContent().getType() == ObuConstant.TYPE_CHANGE_LIGHT_FOR_VIP) {
Logger.d(MODULE_NAME,"上一条是vip变灯需要先把线隐藏===");
hideLine();
}
lastMessage = getV2XMessageEntity();
getV2XWindow().show(getV2XMessageEntity().getContent());
getV2XWindow().setWindowStatusListener(new V2XWindowStatusListener() {
@Override
public void onViewShow() {
}
@Override
public void onViewClose() {
// 只在上滑关闭topview的时候回调
if (getV2XMessageEntity().getContent().getType() == ObuConstant.TYPE_OPTIMAL_SPEED_ADVISORY) {
Logger.d(MODULE_NAME, "关闭绿波浮窗通知adas==");
sendBroadcastToAdas(CALL_ADAS_HIDE_OPTIMAL);
} else if (getV2XMessageEntity().getContent().getType() == ObuConstant.TYPE_CHANGE_LIGHT_FOR_VIP) {
Logger.d(MODULE_NAME,"关闭vip变灯浮窗隐藏line");
isInChangeLightForVip = false;
hideLine();
}
lastMessage = null;
}
});
if (getV2XMessageEntity().getContent().getType() == ObuConstant.TYPE_OPTIMAL_SPEED_ADVISORY) {
// 给adas发送显示绿波的广播
Logger.d(MODULE_NAME, "收到绿波时间发送广播给adas");
sendBroadcastToAdas(CALL_ADAS_SHOW_OPTIMAL);
} else if (getV2XMessageEntity().getContent().getType() == ObuConstant.TYPE_CHANGE_LIGHT_FOR_VIP) {
Logger.d(MODULE_NAME,"收到vip变灯画线");
drawLine();
}
}
/**
* 关闭Window
*/
@Override
public void closeWindow() {
Logger.d(MODULE_NAME, "obu场景关闭window");
handler.removeMessages(MSG_CLOSE_OBU_WINDOW);
getV2XWindow().close();
// 给adas发送隐藏绿波的广播
if (getV2XMessageEntity().getContent().getType() == ObuConstant.TYPE_OPTIMAL_SPEED_ADVISORY) {
Logger.d(MODULE_NAME, "关闭绿波浮窗通知adas==");
sendBroadcastToAdas(CALL_ADAS_HIDE_OPTIMAL);
} else if (getV2XMessageEntity().getContent().getType() == ObuConstant.TYPE_CHANGE_LIGHT_FOR_VIP) {
Logger.d(MODULE_NAME,"关闭vip变灯浮窗");
isInChangeLightForVip = false;
hideLine();
}
lastMessage = null;
}
/**
* 展示按钮
*/
@Override
public void showButton() {
}
/**
* 关闭按钮
*/
@Override
public void closeButton() {
}
/**
* 绘制POI
*/
@Override
public void drawPOI() {
if (optimalSpeedMarker != null) {
Logger.d(MODULE_NAME, "绘制obu Poi点");
optimalSpeedMarker.drawPOI(defaultTarget);
}
}
/**
* 清除POI
*/
@Override
public void clearPOI() {
if (optimalSpeedMarker != null) {
Logger.d(MODULE_NAME, "清除obu Poi点");
optimalSpeedMarker.clearPOI();
optimalSpeedMarker = null;
}
}
/**
* 当定位发生变化时,调用此方法,在此方法中,根据当前状态判断是否需要消费此定位事件
* <p>
* 主要目的是更新绿波速度引导的划线
*
* @param currentLocation 更新后的定位信息
*/
public void updateLocation(MogoLocation currentLocation) {
MogoLatLng currentLatLng = new MogoLatLng(currentLocation.getLatitude(), currentLocation.getLongitude());
if (optimalLine != null) {
float distance = Utils.calculateLineDistance(defaultTarget, currentLatLng);
if (distance <= DEFAULT_DISTANCE_TO_CLOSE_OPTIMAL) {
// 目标点和自身点小于DEFAULT_DISTANCE_TO_CLOSE_OPTIMAL的时候隐藏绿波车速
closeWindow();
} else {
// 线不为空就更新位置,线为空了,也就隐藏了
optimalLine.setPoints(Arrays.asList(currentLatLng, defaultTarget));
}
}
// 判断当前位置与vip点的距离来判断是否触发vip通行
for (MogoLatLng crossing : vipCrossingList) {
float distance = Utils.calculateLineDistance(currentLatLng, crossing);
double eventAngle = DrivingDirectionUtils.getDegreeOfCar2Poi(
currentLocation.getLongitude(),
currentLocation.getLatitude(),
crossing.getLon(),
crossing.getLat(),
(int) currentLocation.getBearing()
);
Logger.d("V2X_OBU_VIP", "监测是否需要进行vip弹框提醒\ndistance: " + distance + "\neventAngle: " + eventAngle + "\ntarget: " + crossing + "\ncurrent: " + currentLatLng);
if (distance <= DEFAULT_VIP_CROSSING_DISTANCE && 0 <= eventAngle && eventAngle <= 20) {
//距离小于DEFAULT_VIP_CROSSING_DISTANCE且夹角在0~20说明在前方则触发vip通行
defaultTarget = crossing;
handler.post(() -> {
CarEventInfo eventInfo = new CarEventInfo();
eventInfo.type = "vip变灯提醒";
eventInfo.typeCode = "vip变灯提醒";
eventInfo.describe = "将为您变灯vip车辆可优先通行";
V2XObuManager.getInstance().showCarEventInfo(eventInfo);
});
break;
}
}
}
/**
* @param msg A {@link Message Message} object
* @return True if no further handling is desired
*/
@Override
public boolean handleMessage(Message msg) {
if (msg.what == MSG_CLOSE_OBU_WINDOW) {
Logger.d(MODULE_NAME, "V2X Obu scenario expire===");
closeWindow();
return true;
}
return false;
}
public static final String ACTION_LAUNCHER_ADAS_APP_BIZ = "com.mogo.launcher.adas.app.biz";
private static final String CALL_ADAS_SHOW_OPTIMAL = "2";
private static final String CALL_ADAS_HIDE_OPTIMAL = "1";
private void sendBroadcastToAdas(String status) {
if (status.equals(CALL_ADAS_SHOW_OPTIMAL)) {
// 给adas发送显示绿波的广播同时自己也要开始划线
drawLine();
} else {
// 给adas发送隐藏绿波的广播同时自己也需要结束划线动画
hideLine();
}
try {
Intent intent = new Intent(ACTION_LAUNCHER_ADAS_APP_BIZ);
JSONObject json = new JSONObject();
json.put("action", status);
String data = json.toString();
Logger.d(MODULE_NAME, "发送绿波广播: " + data);
intent.putExtra("data", data);
intent.putExtra("type", 1);
V2XServiceManager.getContext().sendBroadcast(intent);
} catch (Exception e) {
e.printStackTrace();
Logger.e(MODULE_NAME, e, "发送绿波广播异常==");
}
}
public MogoLatLng getOptimalCrossing(){
return optimalCrossing;
}
public float cacheZoomLevel = 16f;
/**
* 开始划线同时添加marker调整地图比例尺
*/
private void drawLine() {
Logger.d(MODULE_NAME, "绘制绿波车速的线=====");
if (optimalLine != null) {
optimalLine.remove();
}
// 绘制marker
drawPOI();
// 连接线参数
MogoPolylineOptions options = new MogoPolylineOptions();
// 线条粗细,渐变,渐变色值
options.width(16).useGradient(true).colorValues(Arrays.asList(Color.parseColor("#FF1DAAA5"), Color.parseColor("#3337DED9")));
// 当前车辆位置
MogoLatLng carLocation = V2XServiceManager.getNavi().getCarLocation();
if (carLocation != null) {
options.add(carLocation);
} else {
options.add(V2XServiceManager.getV2XStatusManager().getLocation());
}
// 目标车辆位置
options.add(defaultTarget);
// 绘制线的对象
optimalLine = V2XServiceManager.getMogoOverlayManager().addPolyline(options);
cacheZoomLevel = V2XServiceManager.getMapUIController().getZoomLevel();
Logger.d(MODULE_NAME, "V2xObuEventScenario cacheZoomLevel==" + cacheZoomLevel);
V2XServiceManager.getMapUIController().changeZoom(16);
// V2XServiceManager.getMapUIController().changeZoom(17);
}
/**
* 结束划线同时隐藏marker
*/
private void hideLine() {
Logger.d(MODULE_NAME, "隐藏绿波车速的线====");
clearPOI();
if (optimalLine != null) {
optimalLine.remove();
optimalLine = null;
}
V2XServiceManager.getMapUIController().changeZoom(cacheZoomLevel);
}
private volatile boolean isInChangeLightForVip = false;
/**
* 是否在显示vip通行
* @return true - 在显示vip通行
*/
public boolean isInChangeLightForVip(){
return isInChangeLightForVip;
}
}

View File

@@ -0,0 +1,154 @@
package com.mogo.module.v2x.scenario.scene.obu;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.mogo.module.common.entity.V2XObuEventEntity;
import com.mogo.module.v2x.R;
import com.mogo.module.v2x.V2XServiceManager;
import com.mogo.module.v2x.listener.V2XWindowStatusListener;
import com.mogo.module.v2x.scenario.view.IV2XWindow;
import com.mogo.service.windowview.IMogoTopViewStatusListener;
import com.mogo.utils.logger.Logger;
import com.zhidao.mogo.module.obu.ObuConstant;
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
/**
* obu事件window
*
* @author tongchenfei
*/
public class V2XObuEventWindow extends FrameLayout implements IV2XWindow<V2XObuEventEntity> {
public V2XObuEventWindow(@NonNull Context context) {
this(context,null);
}
public V2XObuEventWindow(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public V2XObuEventWindow(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
private ImageView ivTypeIcon;
private TextView tvType, tvDesc;
private void initView(Context context){
Logger.d(MODULE_NAME,"初始化obu场景view");
LayoutInflater.from(context).inflate(R.layout.window_simple_obu_event_detail, this);
ivTypeIcon = findViewById(R.id.ivObuTypeIcon);
tvType = findViewById(R.id.tvObuType);
tvDesc = findViewById(R.id.tvObuDesc);
}
/**
* 展示1/2窗口
*
* 目前只处理如下obu事件
* 绿波车速: {@link com.zhidao.mogo.module.obu.ObuConstant#TYPE_OPTIMAL_SPEED_ADVISORY}
* 前车急刹: {@link com.zhidao.mogo.module.obu.ObuConstant#TYPE_URGENCY_COLLISION_WARNING}
* vip车辆变灯提示暂无回调暂不处理
* @param entity
*/
@Override
public void show(V2XObuEventEntity entity) {
Logger.d(MODULE_NAME, "ObuEventWindow show " + entity);
switch (entity.getType()) {
case ObuConstant
.TYPE_OPTIMAL_SPEED_ADVISORY:
// 绿波车速引导
ivTypeIcon.setImageResource(R.drawable.v2x_icon_obu_optimal_speed);
tvDesc.setText(entity.getDesc());
tvType.setText("车速引导");
tvType.setBackgroundResource(R.drawable.bg_v2x_event_type_green);
break;
case ObuConstant.TYPE_URGENCY_COLLISION_WARNING:
// 前车急刹预警
ivTypeIcon.setImageResource(R.drawable.v2x_icon_obu_urgency_collision);
tvDesc.setText(entity.getDesc());
tvType.setText("前车急刹");
tvType.setBackgroundResource(R.drawable.bg_v2x_event_type_read);
break;
case ObuConstant.TYPE_CHANGE_LIGHT_FOR_VIP:
// vip变灯提醒
ivTypeIcon.setImageResource(R.drawable.v2x_icon_obu_traffic_light);
tvDesc.setText(entity.getDesc());
tvType.setText("优先通行");
tvType.setBackgroundResource(R.drawable.bg_v2x_event_type_green);
break;
default:
Logger.w(MODULE_NAME, "其他obu类型暂不处理: " + entity.getType());
break;
}
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 210);
V2XServiceManager.getMogoTopViewManager().addView(this, params,topViewStatusListener);
}
/**
* 关闭1/2窗口
*/
@Override
public void close() {
V2XServiceManager.getMogoTopViewManager().removeView(this);
}
/**
* 返回窗体
*
* @return 当前窗体
*/
@Override
public View getView() {
return this;
}
private V2XWindowStatusListener statusListener = null;
/**
* 设置Window状态监听
*
* @param listener 监听器
*/
@Override
public void setWindowStatusListener(V2XWindowStatusListener listener) {
statusListener = listener;
}
private IMogoTopViewStatusListener topViewStatusListener = new IMogoTopViewStatusListener() {
@Override
public void onViewAdded(View view) {
}
@Override
public void onViewRemoved(View view) {
if (statusListener != null) {
statusListener.onViewClose();
}
}
@Override
public void beforeViewAddAnim(View view) {
}
@Override
public void beforeViewRemoveAnim(View view) {
}
};
}

View File

@@ -0,0 +1,14 @@
package com.mogo.module.v2x.utils;
/**
* obu相关设置项
* @author tongchenfei
*/
public class ObuConfig {
/**
* 设置是否使用obu定位信息
*
* 此定位信息目前只用于obu计算绿波车速引导和vip变灯提醒
*/
public static boolean useObuLocation = false;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:angle="135"
android:endColor="#ff37DED9"
android:startColor="#ff1DAAA5" />
<corners android:radius="@dimen/dp_10" />
</shape>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:padding="1px"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
<ImageView
android:id="@+id/ivIcon"
android:layout_width="@dimen/module_service_marker_bubble_width"
android:layout_height="@dimen/module_service_marker_bubble_height"
android:layout_gravity="center"
android:src="@drawable/v2x_obu_traffic_light_pop" />
<ImageView
android:id="@+id/ivCar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/v2x_obu_green_point" />
</LinearLayout>

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_210"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/v2x_bg_simple_obu">
<!-- app:roundLayoutRadius="@dimen/dp_20"-->
<ImageView
android:id="@+id/ivObuTypeIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/v2x_icon_obu_urgency_collision"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginStart="@dimen/dp_63"/>
<TextView
android:id="@+id/tvObuType"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_20"
android:background="@drawable/bg_v2x_event_type_read"
android:gravity="center"
android:paddingLeft="@dimen/dp_10"
android:paddingTop="@dimen/dp_3"
android:paddingRight="@dimen/dp_10"
android:paddingBottom="@dimen/dp_3"
android:text="前车急刹"
android:textColor="@color/white"
android:textSize="@dimen/dp_24"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@+id/ivObuTypeIcon"
app:layout_constraintBottom_toTopOf="@+id/tvObuDesc"
app:layout_constraintVertical_chainStyle="packed"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tvObuDesc"
android:text="前车急刹,注意保持安全距离!"
android:textSize="@dimen/dp_32"
android:textColor="#fff"
android:layout_marginTop="@dimen/dp_10"
app:layout_constraintLeft_toLeftOf="@+id/tvObuType"
app:layout_constraintTop_toBottomOf="@+id/tvObuType"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>