screen-job/src/main/java/com/moral/api/controller/PubController.java
@@ -54,6 +54,9 @@ @Autowired private DeviceService deviceService; @Autowired private ManageCoordinateDetailService manageCoordinateDetailService; private final EmailSpringUtil emailSpringUtil; private final CityWeatherForecastService cityWeatherForecastService; @@ -160,6 +163,15 @@ return new ResultMessage(); } @GetMapping("insertCoordinateDetail") @ApiOperation(value = "路段录入", notes = "路段录入") public ResultMessage insertCoordinateDetail() { String startTime ="2024-06-06 00:07:01"; String endTime ="2024-06-06 23:07:01"; manageCoordinateDetailService.insertCoordinateDetail(startTime,endTime); return new ResultMessage(); } public static void main(String[] args) { String host = "https://pair.market.alicloudapi.com"; screen-job/src/main/java/com/moral/api/entity/CruiserDTO.java
New file @@ -0,0 +1,62 @@ package com.moral.api.entity; import lombok.Data; import java.util.Objects; import com.fasterxml.jackson.annotation.JsonProperty; /** * Description //todo * * @author swb * @ClassName CruiserDTO * @date 2024.06.19 09:15 */ @Data public class CruiserDTO { /** * 数据时间 */ private String time; /** * 纬度 */ @JsonProperty(value = "flylat") private Double flyLat; /** * 经度 */ @JsonProperty(value = "flylon") private Double flyLon; private String data; private String state; public CruiserDTO() { this.state = "1"; // 设置state字段默认值为1 } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; CruiserDTO cruiser = (CruiserDTO) o; //当type、color 内容都相等的时候,才返回true return Objects.equals(flyLat, cruiser.flyLat) && Objects.equals(flyLon, cruiser.flyLon); } @Override public int hashCode() { return Objects.hash(flyLat, flyLon); } } screen-job/src/main/java/com/moral/api/entity/ManageCoordinate.java
New file @@ -0,0 +1,76 @@ package com.moral.api.entity; import lombok.Data; import lombok.EqualsAndHashCode; import java.util.Date; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.extension.activerecord.Model; /** * Description //todo * * @author swb * @ClassName ManageCoordinate * @date 2024.06.19 09:13 */ @Data @EqualsAndHashCode(callSuper = false) public class ManageCoordinate extends Model<ManageCoordinate> { private static final long serialVersionUID = 1L; /** * 路段id */ @TableId(value = "coordinate_id", type = IdType.AUTO) private Integer coordinateId; /** * 起点名称 */ private String startPoint; /** * 终点名称 */ private String endPoint; /** *是否删除 */ private Integer isDel; /** * 创建时间 */ private Date createTime; /** * 修改时间 */ private Date updateTime; /** * 修改人id * */ private Integer updateUserId; /** * 修改人名称 */ private String updayeUserName; private Integer organizationId; /** * 经纬度点位 */ private String value; /** * 百度经纬度点位 */ private String bdValue; } screen-job/src/main/java/com/moral/api/entity/ManageCoordinateDetail.java
New file @@ -0,0 +1,70 @@ package com.moral.api.entity; import lombok.Data; import lombok.EqualsAndHashCode; import java.util.Date; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.extension.activerecord.Model; /** * Description //todo * * @author swb * @ClassName ManageCoordinateDetail * @date 2024.06.19 09:21 */ @Data @EqualsAndHashCode(callSuper = false) public class ManageCoordinateDetail extends Model<ManageCoordinateDetail> { private static final long serialVersionUID = 1L; /** * 经纬度id */ @TableId(value = "id", type = IdType.AUTO) private Integer id; /** * 路段id */ private Integer coordinateId; /** * 经度 */ private Double longitude; /** *纬度 */ private Double latitude; /** * 创建时间 */ private Date createTime; /** * 修改时间 */ private Date updateTime; /** * 修改人id * */ private Integer updateUserId; /** * 修改人名称 */ private String updayeUserName; private String state; @TableField(exist = false) private String code; } screen-job/src/main/java/com/moral/api/mapper/ManageCoordinateDetailMapper.java
New file @@ -0,0 +1,16 @@ package com.moral.api.mapper; import java.util.List; import java.util.Map; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.moral.api.entity.CruiserDTO; import com.moral.api.entity.ManageCoordinate; import com.moral.api.entity.ManageCoordinateDetail; public interface ManageCoordinateDetailMapper extends BaseMapper<ManageCoordinateDetail> { List<ManageCoordinate> selectCoordinate(); List<CruiserDTO> getCruiserInfo(Map<String,Object> params); } screen-job/src/main/java/com/moral/api/service/ManageCoordinateDetailService.java
New file @@ -0,0 +1,14 @@ package com.moral.api.service; import com.baomidou.mybatisplus.extension.service.IService; import com.moral.api.entity.ManageCoordinateDetail; public interface ManageCoordinateDetailService extends IService<ManageCoordinateDetail> { /** * 路段信息录入 */ void insertCoordinateDetail(String startTime,String endTime); } screen-job/src/main/java/com/moral/api/service/impl/ManageCoordinateDetailServiceImpl.java
New file @@ -0,0 +1,203 @@ package com.moral.api.service.impl; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import com.alibaba.fastjson.JSONArray; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.moral.api.entity.CruiserDTO; import com.moral.api.entity.ManageCoordinate; import com.moral.api.entity.ManageCoordinateDetail; import com.moral.api.mapper.ManageCoordinateDetailMapper; import com.moral.api.service.ManageCoordinateDetailService; import com.moral.util.DateUtils; /** * Description //todo * * @author swb * @ClassName ManageCoordinateDetailServiceImpl * @date 2024.06.19 09:23 */ @Service @Slf4j public class ManageCoordinateDetailServiceImpl extends ServiceImpl<ManageCoordinateDetailMapper, ManageCoordinateDetail> implements ManageCoordinateDetailService { @Autowired private ManageCoordinateDetailMapper manageCoordinateDetailMapper; @Override @Transactional public void insertCoordinateDetail(String startTime,String endTime) { HashMap<String, Object> params = new HashMap<>(); if (ObjectUtils.isEmpty(startTime)&&ObjectUtils.isEmpty(endTime)){ //当前时间的前一天 startTime = DateUtils.getDateStringOfDay(-1, DateUtils.yyyy_MM_dd_HH_mm_ss_EN); //获取当前时间 endTime = DateUtils.getCurDate(DateUtils.yyyy_MM_dd_HH_mm_ss_EN); } params.put("startTime",startTime); params.put("endTime",endTime); //获取路段信息 List<ManageCoordinate> coordinates = manageCoordinateDetailMapper.selectCoordinate(); //获取走航车数据 List<CruiserDTO> cruiserInfo = manageCoordinateDetailMapper.getCruiserInfo(params); cruiserInfo = cruiserInfo.stream().distinct().collect(Collectors.toList()); List<ManageCoordinateDetail> result = new ArrayList<>(); for (ManageCoordinate coordinate : coordinates) { String value = coordinate.getValue(); if (!ObjectUtils.isEmpty(value)){ List<Map<String, Object>> parse = (List<Map<String, Object>>) JSONArray.parse(value); for (int i = 0; i < cruiserInfo.size(); i++) { CruiserDTO cruiserDTO = cruiserInfo.get(i); if (ObjectUtils.isEmpty(cruiserDTO)){ continue; } Double flyLat = cruiserDTO.getFlyLat(); Double flyLon = cruiserDTO.getFlyLon(); if (ObjectUtils.isEmpty(flyLat)||ObjectUtils.isEmpty(flyLon)){ continue; } boolean inPolygon = isInPolygon(flyLon, flyLat, parse); if (inPolygon){ LambdaQueryWrapper<ManageCoordinateDetail> wr = new LambdaQueryWrapper<>(); wr.eq(ManageCoordinateDetail::getLongitude,flyLon); wr.eq(ManageCoordinateDetail::getLatitude,flyLat); List<ManageCoordinateDetail> manageCoordinateDetails = manageCoordinateDetailMapper.selectList(wr); if (ObjectUtils.isEmpty(manageCoordinateDetails)){ ManageCoordinateDetail rsDTO = new ManageCoordinateDetail(); rsDTO.setLatitude(flyLat); rsDTO.setLongitude(flyLon); rsDTO.setState("2"); rsDTO.setCreateTime(new Date()); rsDTO.setUpdateTime(new Date()); rsDTO.setCoordinateId(coordinate.getCoordinateId()); result.add(rsDTO); cruiserInfo.remove(i); i--; } } } } } if(!CollectionUtils.isEmpty(result)){ this.saveBatch(result); // log.info(result.size()+""); } } /** * 判断当前位置是否在多边形区域内 * @param * @param mapList 区域顶点 * @return */ public static boolean isInPolygon(Double X,Double Y,List<Map<String, Object>> mapList){ Point2D.Double point = new Point2D.Double(X, Y); List<Point2D.Double> pointList= new ArrayList<Point2D.Double>(); for (Map<String, Object> param : mapList) { //纬度 String lat = param.get("lat").toString(); //经度 String lng = param.get("lng").toString(); Point2D.Double polygonPoint = new Point2D.Double(Double.parseDouble(lng),Double.parseDouble(lat)); pointList.add(polygonPoint); } return IsPtInPoly(point,pointList); } /** * 判断点是否在多边形内,如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true * @param point 检测点 * @param pts 多边形的顶点 * @return 点在多边形内返回true,否则返回false */ public static boolean IsPtInPoly(Point2D.Double point, List<Point2D.Double> pts){ int N = pts.size(); boolean boundOrVertex = true; //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true int intersectCount = 0;//cross points count of x double precision = 2e-10; //浮点类型计算时候与0比较时候的容差 Point2D.Double p1, p2;//neighbour bound vertices Point2D.Double p = point; //当前点 p1 = pts.get(0);//left vertex for(int i = 1; i <= N; ++i){//check all rays if(p.equals(p1)){ return boundOrVertex;//p is an vertex } p2 = pts.get(i % N); if(p.x < Math.min(p1.x, p2.x) || p.x > Math.max(p1.x, p2.x)){ p1 = p2; continue; } if(p.x > Math.min(p1.x, p2.x) && p.x < Math.max(p1.x, p2.x)){ if(p.y <= Math.max(p1.y, p2.y)){ if(p1.x == p2.x && p.y >= Math.min(p1.y, p2.y)){ return boundOrVertex; } if(p1.y == p2.y){ if(p1.y == p.y){ return boundOrVertex; }else{//before ray ++intersectCount; } }else{ double xinters = (p.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y; if(Math.abs(p.y - xinters) < precision){ return boundOrVertex; } if(p.y < xinters){ ++intersectCount; } } } }else{ if(p.x == p2.x && p.y <= p2.y){ Point2D.Double p3 = pts.get((i+1) % N); if(p.x >= Math.min(p1.x, p3.x) && p.x <= Math.max(p1.x, p3.x)){ ++intersectCount; }else{ intersectCount += 2; } } } p1 = p2; } if(intersectCount % 2 == 0){//偶数在多边形外 return false; } else { //奇数在多边形内 return true; } } } screen-job/src/main/java/com/moral/api/task/HistoryTableInsertTask.java
@@ -8,6 +8,7 @@ import com.moral.api.service.HistoryHourlyService; import com.moral.api.service.HistoryMonthlyService; import com.moral.api.service.HistoryWeeklyService; import com.moral.api.service.ManageCoordinateDetailService; import com.xxl.job.core.biz.model.ReturnT; import com.xxl.job.core.context.XxlJobHelper; import com.xxl.job.core.handler.annotation.XxlJob; @@ -32,6 +33,10 @@ @Autowired private HistoryMonthlyService historyMonthlyService; @Autowired private ManageCoordinateDetailService manageCoordinateDetailService; //5分钟数据统计 @XxlJob("insertHistoryFiveMinutely") @@ -143,4 +148,21 @@ } /** * 路段信息录入 * @return */ @XxlJob("manageCoordinateDetail") public ReturnT manageCoordinateDetail(){ try { manageCoordinateDetailService.insertCoordinateDetail(null,null); } catch (Exception e) { XxlJobHelper.log(e.getMessage()); return new ReturnT(ReturnT.FAIL_CODE, e.getMessage()); } return ReturnT.SUCCESS; } } screen-job/src/main/resources/mapper/ManageCoordinateDetailMapper.xml
New file @@ -0,0 +1,31 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.moral.api.mapper.ManageCoordinateDetailMapper"> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.moral.api.entity.ManageCoordinateDetail"> <id column="id" property="id" /> <result column="coordinate_id" property="coordinateId" /> <result column="longitude" property="longitude" /> <result column="latitude" property="latitude" /> <result column="create_time" property="createTime" /> <result column="update_time" property="updateTime" /> <result column="update_user_id" property="updateUserId" /> <result column="updaye_user_name" property="updayeUserName" /> </resultMap> <select id="selectCoordinate" resultType="com.moral.api.entity.ManageCoordinate"> SELECT * FROM manage_coordinate WHERE is_del =0 </select> <select id="getCruiserInfo" resultType="com.moral.api.entity.CruiserDTO"> select DATE_FORMAT(`time`, #{dateFormat}) AS time,value ->>'$.flylat' as flyLat,value ->>'$.flylon' as flyLon from history_second_cruiser WHERE `time` <![CDATA[>=]]> #{startTime} AND `time` <![CDATA[<=]]> #{endTime} order by time </select> </mapper>