1、实时统计道路的拥堵的情况,判断标准是统计15分钟内的车流量和平均车速,每一分钟计算一次
public class Demo05Car {
public static void main(String[] args) throws Exception{
/**需求:实时的统计道路的拥堵的情况,使用有界数据流来模拟数据
* 实现的方式可以通过统计15分钟内的车流量,每分钟计算一次
* 判断是否拥堵的条件:
* 计算一段时间内通过平均车速和车流量判断
*/
//首先构建Flink的环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(1);
//读取有界数据流:
DataStream<String> lineDS = env.readTextFile("flink/data/cars_sample.txt");
/**
* 以为是每分钟计算的是15分钟车流量,所以根据需求选择滑动的事件时间窗口,所有需要指定事件时间和水位线
*/
//对数据进行解析
DataStream<Car> carDS = lineDS.map(kv -> {
String[] split = kv.split(",");
//从数据表可以知道数据表中有很多的元素,使用元组接受时会比较麻烦,所以可以创建一个类来分装这些数据。
Car car = new Car(split[0], split[1], split[2], split[3], split[4], split[5], split[6], Long.parseLong(split[7]), Double.parseDouble(split[8]));
return car;
});
//指定对应的事件事件和水位线
SingleOutputStreamOperator<Car> assCarDS = carDS.assignTimestampsAndWatermarks(
WatermarkStrategy
//指定水位线,默认最新的一条数据的时间戳
.<Car>forMonotonousTimestamps()
.withTimestampAssigner((car, ts) -> car.getTime())
);
//按照道路的编号进行分组
KeyedStream<Car, String> carRoadIdDS = assCarDS.keyBy(kv -> kv.getRoadId());
//划分窗口.使用的时滑动的事件时间窗口,指定窗口的大小和滑动的间隔
WindowedStream<Car, String, TimeWindow> windowDS = carRoadIdDS
.window(SlidingEventTimeWindows.of(Time.minutes(15), Time.minutes(1)));
//统计车流量和平均速度
/**
* process方法每一个窗口执行一次,是作用在每一个窗口上面
* @param key :分组的key(道路编号)
* @param context :flink上下文对象。可以或flink执行的环境信息
* @param cars : 同一个窗口内所有的车辆数据
* @param out:用于将数据发送到下游
*/
SingleOutputStreamOperator<Result> resultDS = windowDS.process(new ProcessWindowFunction<Car, Result, String, TimeWindow>() {
@Override
public void process(String key,
ProcessWindowFunction<Car, Result, String, TimeWindow>.Context context,
Iterable<Car> cars, //同一个窗口的所有的数据量
Collector<Result> out) throws Exception {
long flow = 0;
Double sumSpeed = 0.0;
for (Car car : cars) {
flow++;
sumSpeed = sumSpeed + car.getSpeed();
}
double avgSpeed = sumSpeed / flow;
//将数据发送到下游
out.collect(new Result(key, flow, avgSpeed));
}
});
resultDS.print();
env.execute();
}
}
//创建一个类负责接收处理好后的数据:
class Result {
private String roadId;
private Long flow;
private Double avgSpeed;
@Override
public String toString() {
return "Result{" +
"roadId='" + roadId + '\'' +
", flow=" + flow +
", avgSpeed=" + avgSpeed +
'}';
}
public String getRoadId() {
return roadId;
}
public void setRoadId(String roadId) {
this.roadId = roadId;
}
public Long getFlow() {
return flow;
}
public void setFlow(Long flow) {
this.flow = flow;
}
public Double getAvgSpeed() {
return avgSpeed;
}
public void setAvgSpeed(Double avgSpeed) {
this.avgSpeed = avgSpeed;
}
public Result(String roadId, Long flow, Double avgSpeed) {
this.roadId = roadId;
this.flow = flow;
this.avgSpeed = avgSpeed;
}
}
//创建一个Car类来封装后的数据
class Car {
private String cardId;//车牌号
private String roadId;//道路编号
private String cityId;//城市编号
private String carId;//卡口编号
private String comId;//摄像头编号
private String fx;//方向
private String countyId;//区县
private Long time;//时间
private Double speed;//速度
public Car(String cardId, String roadId, String cityId, String carId, String comId, String fx, String countyId, Long time, Double speed) {
this.cardId = cardId;
this.roadId = roadId;
this.cityId = cityId;
this.carId = carId;
this.comId = comId;
this.fx = fx;
this.countyId = countyId;
this.time = time;
this.speed = speed;
}
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public String getRoadId() {
return roadId;
}
public void setRoadId(String roadId) {
this.roadId = roadId;
}
public String getCityId() {
return cityId;
}
public void setCityId(String cityId) {
this.cityId = cityId;
}
public String getCarId() {
return carId;
}
public void setCarId(String carId) {
this.carId = carId;
}
public String getComId() {
return comId;
}
public void setComId(String comId) {
this.comId = comId;
}
public String getFx() {
return fx;
}
public void setFx(String fx) {
this.fx = fx;
}
public String getCountyId() {
return countyId;
}
public void setCountyId(String countyId) {
this.countyId = countyId;
}
public Long getTime() {
return time;
}
public void setTime(Long time) {
this.time = time;
}
public Double getSpeed() {
return speed;
}
public void setSpeed(Double speed) {
this.speed = speed;
}
@Override
public String toString() {
return "Car{" +
"cardId='" + cardId + '\'' +
", roadId='" + roadId + '\'' +
", cityId='" + cityId + '\'' +
", carId='" + carId + '\'' +
", comId='" + comId + '\'' +
", fx='" + fx + '\'' +
", countyId='" + countyId + '\'' +
", time=" + time +
", speed=" + speed +
'}';
}
}