Commit e3b7c942 authored by zhoushiguang's avatar zhoushiguang

车辆礼让行人停车误检为疑似事故问题修改

parent 81c64a90
......@@ -178,18 +178,18 @@ public class AccidentEventMainNew implements Serializable {
.name("事故检测-右转无灯态停车时间计算");
//检测直左放行情况(addd)
SingleOutputStreamOperator<AccidentFrameModel> straightleftThoughtProcess = checkRightVehiclProcess
.keyBy(AccidentFrameModel::getCrossId)
.process(new AccidentStraightLeftThroughKeyedProcess())
.setParallelism(1)
.name("事故检测-直左放行情况停车时间计算");
// SingleOutputStreamOperator<AccidentFrameModel> straightleftThoughtProcess = checkRightVehiclProcess
// .keyBy(AccidentFrameModel::getCrossId)
// .process(new AccidentStraightLeftThroughKeyedProcess())
// .setParallelism(1)
// .name("事故检测-直左放行情况停车时间计算");
//计算绕行停驶车辆特征
SingleOutputStreamOperator<AccidentFrameModel> checkDetourKeyedProcess = straightleftThoughtProcess
.keyBy(AccidentFrameModel::getCrossId)
.process(new AccidentCheckDetourKeyedProcess())
.setParallelism(1)
.name("事故检测-计算车辆绕行特征");
// SingleOutputStreamOperator<AccidentFrameModel> checkDetourKeyedProcess = straightleftThoughtProcess
// .keyBy(AccidentFrameModel::getCrossId)
// .process(new AccidentCheckDetourKeyedProcess())
// .setParallelism(1)
// .name("事故检测-计算车辆绕行特征");
//检测是否为正常停车(addd)
//// SingleOutputStreamOperator<AccidentFrameModel> checkNormalStopKeyedProcess = straightleftThoughtProcess
......@@ -199,7 +199,7 @@ public class AccidentEventMainNew implements Serializable {
//// .name("事故检测-计算是停车是否为无灯态正常停车");
//根据事故持续时间计算事故结果
SingleOutputStreamOperator<AccidentFrameModel> accidentFrameFlatMap = checkDetourKeyedProcess
SingleOutputStreamOperator<AccidentFrameModel> accidentFrameFlatMap = checkRightVehiclProcess
.flatMap(new AccidentCheckTimeFlatMap())
.setParallelism(1)
.name("事故检测-根据事故持续时间计算事故结果");
......
......@@ -62,15 +62,18 @@ public class AbnormalDeadlockConflictCheckKeyedProcess extends KeyedProcessFunct
Map<String, List<AccidentFrameModel.CarTrack>> groupList = trackList.stream().collect(Collectors.groupingBy(o -> o.getRoadnet().getRid()));
if (groupList.size() >= 2) {
//存放按RID+转向分组
//存放按RID+方向+转向分组后的车辆集合
Map<String, List<AccidentFrameModel.CarTrack>> ridTurnCarList = new HashMap<>();
for (Map.Entry<String, List<AccidentFrameModel.CarTrack>> entry : groupList.entrySet()) {
List<AccidentFrameModel.CarTrack> value = entry.getValue();
for (AccidentFrameModel.CarTrack ridCar : value) {
String laneFunc = TurnEnum.getLaneFunction(ridCar.getRoadnet().getTurn());
String[] sps = laneFunc.split(Constant.COMMA);
for (String func : sps) {
String ridTurnKey = this.getKey(ridCar,func);
List<AccidentFrameModel.CarTrack> tmplist = ridTurnCarList.get(ridTurnKey);
if (Objects.isNull(tmplist)) {
tmplist = new ArrayList<>();
......@@ -82,10 +85,10 @@ public class AbnormalDeadlockConflictCheckKeyedProcess extends KeyedProcessFunct
}
//List<AccidentFrameModel.CarTrack> stopCarList = trackList.stream().filter(o -> o.isStop()).collect(Collectors.toList());
for (AccidentFrameModel.CarTrack carTrack : trackList) {
String time = "2023-12-04 09:36:00";
long ts = DateUtil.StringToMillis(time, "yyyy-MM-dd HH:mm:ss");
String dt = DateUtil.toDateTime(carTrack.getGlobalTimeStamp(), "yyyy-MM-dd HH:mm:ss");
// if ("鲁A38M0T".equals(carTrack.getPicLicense()) && carTrack.getGlobalTimeStamp() >= ts) {
// String time = "2024-02-02 09:03:10";
// long ts = DateUtil.StringToMillis(time, "yyyy-MM-dd HH:mm:ss");
// String dt = DateUtil.toDateTime(carTrack.getGlobalTimeStamp(), "yyyy-MM-dd HH:mm:ss");
// if ("鲁A7D9P0".equals(carTrack.getPicLicense()) && carTrack.getGlobalTimeStamp() >= ts) {
// System.out.println();
// }
// if (carTrack.getId()==7607768){
......@@ -123,8 +126,7 @@ public class AbnormalDeadlockConflictCheckKeyedProcess extends KeyedProcessFunct
carTrack.getRoadnet().getRid() +
Constant.MARK +
carTrack.getRoadnet().getRidDir8()+
Constant.MARK +
func
Constant.MARK + func
;
}
......
......@@ -37,17 +37,25 @@ public class AccidentCheckTimeFlatMap implements FlatMapFunction<AccidentFrameMo
// if (carTrack.getId() == 28687) {
// System.out.println();
// }
if (/*carTrack.getDetourNum() >=2 && */carTrack.isHasSameTurnCar() && carTrack.getSameTurnStopDuration() > configModel.getAbnormalParkHaveSameFlowStopDuration()) {
//有同行车流运行时、判断停车时间是否超过阈值 超过阈值则加入疑似事故车辆集合
listAccident.add(carTrack);
log.info("LOG_EVENT_ACCIDENT_CHECK_TIME >>> 无灯态 有同行车流运行时、异常停车超过阈值 " + carTrack.getRoadnet().getCrossId() +
//前方无行人、非机动车阻碍时判断异常停车
if (carTrack.getObstacleCount()<=0) {
if (carTrack.isHasSameTurnCar() && carTrack.getSameTurnStopDuration() > configModel.getAbnormalParkHaveSameFlowStopDuration()) {
//有同行车流运行时、判断停车时间是否超过阈值 超过阈值则加入疑似事故车辆集合
listAccident.add(carTrack);
log.info("LOG_EVENT_ACCIDENT_CHECK_TIME >>> 无灯态 有同行车流运行时、异常停车超过阈值 " + carTrack.getRoadnet().getCrossId() +
"-" + carTrack.getId() + "-" + carTrack.getPicLicense() +
" stopDuration: " + carTrack.getStopDuration() +
" stopTime: " + DateUtil.toDateTime(carTrack.getStopTime(), "yyyy-MM-dd HH:mm:ss.SSS") +
" 有同行车流车辆停车持续时长: " + carTrack.getSameTurnStopDuration() +
" 是否有冲突方向车辆:" + carTrack.isHasConflictCar()
);
}
} else {
log.info("LOG_EVENT_ACCIDENT_CHECK_TIME >>> 礼让行人、非机动车导致的停车 " + carTrack.getRoadnet().getCrossId() +
"-" + carTrack.getId() + "-" + carTrack.getPicLicense() +
" stopDuration: " + carTrack.getStopDuration() +
" stopTime: " + DateUtil.toDateTime(carTrack.getStopTime(),"yyyy-MM-dd HH:mm:ss.SSS") +
" 有同行车流车辆停车持续时长: " + carTrack.getSameTurnStopDuration() +
" 是否有冲突方向车辆:"+carTrack.isHasConflictCar()
" ObstacleCount: " + carTrack.getObstacleCount()
);
}
......
package com.wanji.indicators.event.cross.accident.funcnew;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import com.wanji.indicators.cache.PedestrianDataCache;
import com.wanji.indicators.constant.Constant;
import com.wanji.indicators.constant.TurnEnum;
......@@ -39,58 +41,59 @@ public class AccidentFlatMap implements FlatMapFunction<CrossFrameModel, Acciden
List<CrossRidTurnLampStatusModel> lampStatusList = frameModel.getRidTurnLampList();
try {
List<CarTrackModel> trackList = frameModel.getTrackList();
ConfigModel configModel = frameModel.getConfigModel();
if (configModel.getAbnormalParkIsOpen() == Constant.OPEN) {
for (CarTrackModel carTrack : trackList) {
String crossId = carTrack.getRoadnet().getCrossId();
String rid = carTrack.getRoadnet().getRid();
Integer ridDir = carTrack.getRoadnet().getRidDir8();
Integer laneFunction = carTrack.getRoadnet().getTurn();
String[] turns = TurnEnum.getLaneTurnValue(laneFunction);
List<String> turnList = Arrays.asList(turns);
//进口道本车道灯态
List<CrossRidTurnLampStatusModel> dirLampList = lampStatusList.stream().filter(o -> o.getDir().equals(ridDir) && turnList.contains(o.getTurn())).collect(Collectors.toList());
carTrack.setRidTurnLampStatusModel(dirLampList);
boolean isMotor = VehicleTypeEnum.isMotorVehicles(carTrack.getOriginalType().shortValue());
int inCrossingFlag = carTrack.getRoadnet().getInCrossFlag();
//路口内机动车
if (isMotor && inCrossingFlag == Constant.CROSSING) {
AccidentFrameModel.CarTrack car = new AccidentFrameModel.CarTrack();
BeanUtils.copyProperties(carTrack, car);
String laneEndPoint = car.getRoadnet().getLaneEndPoint();
if (Objects.isNull(laneEndPoint)) {
continue;
}
String[] sps = laneEndPoint.split(",");
Double angeleToLane = PtInPolyUtil.getAngle(carTrack.getLongitude(), carTrack.getLatitude(), Double.parseDouble(sps[0]), Double.parseDouble(sps[1]));
//通过车辆与车道终点坐标得出的角度与车道方位角度判断是否驶出停止线
double angleX = Math.abs(angeleToLane - carTrack.getRoadnet().getLaneAngle());
boolean isReverseDir = false;
if (angleX > 160.0 && angleX < 200.0) {
isReverseDir = true;
}
//距离停止线距离
double stopLineDist = GeomsConvertUtil.getDistance(car.getLongitude(), car.getLatitude(), Double.parseDouble(sps[0]), Double.parseDouble(sps[1]));
car.setStopLineDist(stopLineDist);
boolean isInWaitArea = false;
List<WaitingAreaDo> waitAreaList = PedestrianDataCache.getInstance().getWaitingTurnAreaMap().get(rid);
if (Objects.nonNull(waitAreaList)) {
for (WaitingAreaDo model : waitAreaList) {
String geom = model.getGeomWkt();
isInWaitArea = GeomsConvertUtil.withinGeo(carTrack.getLongitude() + "," + carTrack.getLatitude(), geom);
if (isInWaitArea) {
break;
}
//筛选行人、非机动车目标
List<CarTrackModel> nonMotorList = trackList.stream().filter(o -> !VehicleTypeEnum.isMotorVehicles(o.getOriginalType().shortValue())).collect(Collectors.toList());
for (CarTrackModel carTrack : trackList) {
String crossId = carTrack.getRoadnet().getCrossId();
String rid = carTrack.getRoadnet().getRid();
Integer ridDir = carTrack.getRoadnet().getRidDir8();
Integer laneFunction = carTrack.getRoadnet().getTurn();
String[] turns = TurnEnum.getLaneTurnValue(laneFunction);
List<String> turnList = Arrays.asList(turns);
//进口道本车道灯态
List<CrossRidTurnLampStatusModel> dirLampList = lampStatusList.stream().filter(o -> o.getDir().equals(ridDir) && turnList.contains(o.getTurn())).collect(Collectors.toList());
carTrack.setRidTurnLampStatusModel(dirLampList);
boolean isMotor = VehicleTypeEnum.isMotorVehicles(carTrack.getOriginalType().shortValue());
int inCrossingFlag = carTrack.getRoadnet().getInCrossFlag();
//路口内机动车
if (isMotor && inCrossingFlag == Constant.CROSSING) {
AccidentFrameModel.CarTrack car = new AccidentFrameModel.CarTrack();
BeanUtils.copyProperties(carTrack, car);
String laneEndPoint = car.getRoadnet().getLaneEndPoint();
if (Objects.isNull(laneEndPoint)) {
continue;
}
String[] sps = laneEndPoint.split(",");
Double angeleToLane = PtInPolyUtil.getAngle(carTrack.getLongitude(), carTrack.getLatitude(), Double.parseDouble(sps[0]), Double.parseDouble(sps[1]));
//通过车辆与车道终点坐标得出的角度与车道方位角度判断是否驶出停止线
double angleX = Math.abs(angeleToLane - carTrack.getRoadnet().getLaneAngle());
boolean isReverseDir = false;
if (angleX > 160.0 && angleX < 200.0) {
isReverseDir = true;
}
//距离停止线距离
double stopLineDist = GeomsConvertUtil.getDistance(car.getLongitude(), car.getLatitude(), Double.parseDouble(sps[0]), Double.parseDouble(sps[1]));
car.setStopLineDist(stopLineDist);
boolean isInWaitArea = false;
List<WaitingAreaDo> waitAreaList = PedestrianDataCache.getInstance().getWaitingTurnAreaMap().get(rid);
if (Objects.nonNull(waitAreaList)) {
for (WaitingAreaDo model : waitAreaList) {
String geom = model.getGeomWkt();
isInWaitArea = GeomsConvertUtil.withinGeo(carTrack.getLongitude() + "," + carTrack.getLatitude(), geom);
if (isInWaitArea) {
break;
}
}
//排除掉待转区车辆
if (!isInWaitArea) {
list.add(car);
}
}
//排除掉待转区车辆
if (!isInWaitArea) {
list.add(car);
}
}
if (!list.isEmpty()) {
AccidentFrameModel model = new AccidentFrameModel();
......@@ -99,6 +102,9 @@ public class AccidentFlatMap implements FlatMapFunction<CrossFrameModel, Acciden
model.setTrackList(list);
model.setRidTurnLampList(frameModel.getRidTurnLampList());
model.setConfigModel(frameModel.getConfigModel());
this.checkFrontObstacleCount(list, nonMotorList);
collector.collect(model);
}
}
......@@ -107,4 +113,31 @@ public class AccidentFlatMap implements FlatMapFunction<CrossFrameModel, Acciden
}
}
//车辆前方左右20度,半径5m的扇形区域内是否有非机动车、行人目标
private void checkFrontObstacleCount(List<AccidentFrameModel.CarTrack> motorList, List<CarTrackModel> nonMotorList) {
for (AccidentFrameModel.CarTrack motor : motorList) {
double lng = motor.getLongitude();
double lat = motor.getLatitude();
double angle = motor.getCourseAngle();
double langle = angle - 20;
if (langle < 0) {
langle = 360 + langle;
}
double rangle = angle + 20;
if (rangle >= 360) {
rangle = rangle - 360;
}
Polygon polygon = GeomsConvertUtil.createSector(lng, lat, 5, langle, rangle, 20);
int obstacleCount = 0;
for (CarTrackModel nonMotor : nonMotorList) {
Point point = GeomsConvertUtil.createPoint(nonMotor.getLongitude() + "," + nonMotor.getLatitude());
if (point.within(polygon)) {
obstacleCount++;
}
}
motor.setObstacleCount(obstacleCount);
}
}
}
......@@ -34,8 +34,8 @@ public class OfflineEventTestMain {
//加载配置项 并获取工作路径
String inPath = "d:/flink/workspace";
String outPath = "d:/flink/out/";
String startTime = "2024-02-18 07:00:00";
String endTime = "2024-02-18 08:00:00";
String startTime = "2024-02-02 09:00:00";
String endTime = "2024-02-02 10:00:00";
//读取离线数据
DataStreamSource<String> streamSource = env.addSource(new DebugSourceGlobalFrameDtFile(inPath,startTime,endTime));
......@@ -50,7 +50,7 @@ public class OfflineEventTestMain {
.keyBy(CrossFrameModel::getCrossId)
.countWindow(1)
.maxBy("globalTimeStamp")
.name("数据抽帧");;
.name("数据抽帧");
// SingleOutputStreamOperator<CrossFrameModel> joinLaneStream = thinningStream
// .connect(env.addSource(new LaneInfoSource()).broadcast())
......
......@@ -63,10 +63,11 @@ public class RefBaseRidInfoCoFlatMap implements FlatMapFunction<CrossFrameModel,
carTrack.getRoadnet().setLaneAngle(laneAngle);
carTrack.getRoadnet().setCrossId(baseLaneInfo.getCrossId());
frameModel.setCrossId(baseLaneInfo.getCrossId());
resList.add(carTrack);
}
}
frameModel.getTrackList().clear();
frameModel.setTrackList(resList);
collector.collect(frameModel);
......
......@@ -127,5 +127,8 @@ public class AccidentFrameModel implements Serializable {
//灯态
private List<CrossRidTurnLampStatusModel> ridTurnLampStatusModel;
//机动车前方非机动车目标数量
int obstacleCount;
}
}
......@@ -132,7 +132,6 @@ public class BaseLaneInfoServiceImpl extends ServiceImpl<BaseLaneInfoMapper, Bas
Integer[] turns = new Integer[]{1, 2};
for (Integer turn : turns) {
String key = crid + Constant.MARK + turn;
List<String> conflictTurnList = new ArrayList<>();
if (turn == 2) {
if (ridDirMap.containsKey(clockwise)) {
......
......@@ -12,6 +12,7 @@ import com.vividsolutions.jts.operation.buffer.BufferParameters;
import com.vividsolutions.jts.operation.buffer.OffsetCurveBuilder;
import com.vividsolutions.jts.operation.distance.DistanceOp;
import com.vividsolutions.jts.operation.linemerge.LineMerger;
import com.vividsolutions.jts.util.GeometricShapeFactory;
import org.apache.commons.lang.StringUtils;
import java.awt.geom.GeneralPath;
......@@ -23,6 +24,9 @@ import java.util.List;
public class GeomsConvertUtil {
private static GeometryFactory geometryFactory = new GeometryFactory();
//生成工厂类
private static GeometricShapeFactory shapeFactory = new GeometricShapeFactory();
private static int pointCxNum = 10;// 连续抽稀pointCxNum个点
private static int distance = 2;// 抽稀距离 distance 米
// 地球的赤道半径是6378137米
......@@ -30,6 +34,35 @@ public class GeomsConvertUtil {
// 地球的极半径是6356725米
public final static double Rj = 6356725;
/**
* 根据中心点经纬度、半径、起止角度生成扇形
* @param x 经度
* @param y 纬度
* @param radius 半径(米)
* @param bAngle 起始角度
* @param eAngle 终止角度
* @param pointsNum 点数
* @return
*/
public static Polygon createSector(double x,double y,double radius,double bAngle,double eAngle,int pointsNum){
//将半径转换为度数
double radiusDegree = meterToDu(radius);
//将起始角度转换为弧度
double bAngleRadian = Math.toRadians(bAngle);
//将终止角度-起始角度计算扇形夹角
double angleRadian = Math.toRadians((eAngle - bAngle + 360) % 360);
//设置点数
shapeFactory.setNumPoints(pointsNum);
//设置中心点经纬度
shapeFactory.setCentre(new Coordinate(x, y));
//设置直径
shapeFactory.setSize(radiusDegree * 2);
//传入起始角度和扇形夹角,生成扇形
Polygon sector = shapeFactory.createArcPolygon(bAngleRadian,angleRadian);
return sector;
}
/**
* 按距离缓冲偏移坐标
*
......
jdbc.driver=com.mysql.cj.jdbc.Driver
#jdbc.url=jdbc:mysql://10.102.1.182:3306/holo_roadnet_jn?userUnicode=true&characterEncoding=utf-8
#jdbc.url=jdbc:mysql://10.102.1.182:3306/holo_roadnet_mz?userUnicode=true&characterEncoding=utf-8
#\u6D4E\u5357
#jdbc.url=jdbc:mysql://37.12.182.29:3306/holo_roadnet?userUnicode=true&characterEncoding=utf-8
#\u5F00\u53D1\u73AF\u5883
#jdbc.url=jdbc:mysql://106.120.201.126:14726/holo_roadnet_jn?userUnicode=true&characterEncoding=utf-8
jdbc.url=jdbc:mysql://43.5.252.70:3306/holo_roadnet_changsha?userUnicode=true&characterEncoding=utf-8
#jdbc.url=jdbc:mysql://192.168.3.141:3306/holo_roadnet?userUnicode=true&characterEncoding=utf-8
#\u957F\u6C99
#jdbc.url=jdbc:mysql://43.5.252.70:3306/holo_roadnet_changsha?userUnicode=true&characterEncoding=utf-8
#\u8499\u81EA
jdbc.url=jdbc:mysql://192.168.3.141:3306/holo_roadnet?userUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=Wanji300552
\ No newline at end of file
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://43.5.252.70:3306/holo_roadnet_changsha?userUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=Wanji300552
\ No newline at end of file
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://10.102.1.182:3306/holo_roadnet_jn?userUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=Wanji300552
\ No newline at end of file
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://37.12.182.29:3306/holo_roadnet?userUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=Wanji300552
\ No newline at end of file
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.3.141:3306/holo_roadnet?userUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=Wanji300552
\ No newline at end of file
......@@ -153,7 +153,7 @@
JOIN (<!-- 取end_cross_id -->
select a.id,a.end_cross_id cross_id,a.in_dir as dir, 2 as type,a.wkt,if(a.road_id='#',concat_ws('',a.id,'#'),a.road_id) road_id
from t_base_rid_info a
JOIN t_base_cross_info b on a.start_cross_id=b.id
JOIN t_base_cross_info b on a.end_cross_id=b.id
where b.is_signal=1
<if test="crossList != null and crossList.size>0">
and end_cross_id in
......@@ -190,11 +190,11 @@
</if>
</select>
<!-- 用于生成转向关系 -->
<select id="findRidInfo" resultType="map">
select a.end_cross_id as cross_id,a.id as rid,a.in_dir rid_dir,a.end_angle
from t_base_rid_info a
JOIN t_base_cross_info b on a.start_cross_id=b.id
JOIN t_base_cross_info b on a.end_cross_id=b.id
where b.is_signal=1
<if test="crossList != null and crossList.size>0">
and end_cross_id in
......
......@@ -2,14 +2,15 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mybatis="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
xmlns:mybatis="http://mybatis.org/schema/mybatis-spring" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd">
http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- 加载配置文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!--<context:property-placeholder location="classpath:db.properties"/>-->
<context:property-placeholder location="classpath:db/mengzi/db.properties"/>
<!-- 配置数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment