import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.data.report.domain.dto.MineInfoCacheDTO;
import com.ruoyi.data.report.domain.dto.PointDTO;
import com.ruoyi.data.report.domain.dto.TbDataUploadConfigDTO;
import com.ruoyi.data.report.domain.vo.MonitorRailInfoVO;
import com.ruoyi.data.report.service.cache.DataUploadConfigCacheService;
import com.ruoyi.data.report.service.cache.MineInfoCacheService;
import com.ruoyi.data.report.service.cache.UploadRailInfoCacheService;
import lombok.extern.slf4j.Slf4j;
import org.locationtech.jts.geom.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
/**
* 围栏工具类
*
* @since 2023/12/22 10:54
*/
@Component
@Slf4j
public class RailUtil {
@Autowired
private UploadRailInfoCacheService uploadRailInfoCacheService;
@Autowired
private DataUploadConfigCacheService configCacheService;
@Autowired
private MineInfoCacheService mineInfoCacheService;
public double getArea(MonitorRailInfoVO monitorRailInfoVO){
if (Objects.isNull(monitorRailInfoVO)
|| CollUtil.isEmpty(monitorRailInfoVO.getWgs84RailPoint())){
// 围栏为空,点为空或点经纬度为空时直接返回不在围栏内,不做报错处理阻断流程
return 0.0;
}
// 补偿初始点,形成闭环
List<String> tmpPointList = CollUtil.newArrayList(monitorRailInfoVO.getWgs84RailPoint());
tmpPointList.add(tmpPointList.get(0));
Coordinate[] coordinates = tmpPointList.stream().map(tmp->{
String[] point = tmp.split(",");
double longitude = Convert.toDouble(point[0]);
double latitude = Convert.toDouble(point[1]);
return new Coordinate(longitude, latitude);
}).toArray(Coordinate[]::new);
LinearRing linearRing = new GeometryFactory().createLinearRing(coordinates); // 将顶点数组转换为线性环
return calculateArea3(linearRing);
}
/**
* 判断点是否在围栏内
* @param pointDTO
* @return
*/
public static boolean pointIsInRail(PointDTO pointDTO, MonitorRailInfoVO monitorRailInfoVO){
if (Objects.isNull(monitorRailInfoVO)
|| Objects.isNull(pointDTO)
|| CollUtil.isEmpty(monitorRailInfoVO.getRailPoint())
|| Objects.isNull(pointDTO.getLatitude())
|| Objects.isNull(pointDTO.getLongitude())){
// 围栏为空,点为空或点经纬度为空时直接返回不在围栏内,不做报错处理阻断流程
return false;
}
// 补偿初始点,形成闭环
List<String> wgs84RailPoint = CollUtil.newArrayList(monitorRailInfoVO.getWgs84RailPoint());
wgs84RailPoint.add(wgs84RailPoint.get(0));
Coordinate[] coordinates = wgs84RailPoint.stream().map(tmp->{
String[] point = tmp.split(",");
double longitude = Convert.toDouble(point[0]);
double latitude = Convert.toDouble(point[1]);
return new Coordinate(longitude, latitude);
}).toArray(Coordinate[]::new);
LinearRing linearRing = new GeometryFactory().createLinearRing(coordinates); // 将顶点数组转换为线性环
Polygon polygon = new GeometryFactory().createPolygon(linearRing, null); // 根据线性环创建多边形
Point point = new GeometryFactory().createPoint(new Coordinate(pointDTO.getLongitude().doubleValue(), pointDTO.getLatitude().doubleValue())); // 定义一个点坐标
return polygon.contains(point); // 判断点是否在多边形内部
}
/**
* 判断点是否在全局围栏内,如果在则返回最小的围栏
* @param pointDTO
* @return 如果点不在大围栏内则返回空,其他情况返回当前所在最小的围栏
*/
public String pointInRail(PointDTO pointDTO){
TbDataUploadConfigDTO config = configCacheService.getDataUploadConfig();
if (Objects.isNull(config) || StringUtils.isBlank(config.getRailCode())){
// 当前没有配置围栏范围;若所选电子围栏未标注,则认为无区域,车辆设备人员不在区域内,不上传实时信息;
return null;
}
if (Objects.isNull(pointDTO)
|| Objects.isNull(pointDTO.getLongitude())
|| Objects.isNull(pointDTO.getLatitude())) {
return null;
}
// 全局围栏
List<MonitorRailInfoVO> railList = uploadRailInfoCacheService.getRailList();
if (CollUtil.isEmpty(railList)){
// 当前没有配置任何围栏
return null;
}
// 首先判断是否在全局围栏内
// 获取煤矿编码
MineInfoCacheDTO mineBaseInfo = mineInfoCacheService.getMineBaseInfo();
String areaCode = StringUtils.leftPad( mineBaseInfo.getMineCode(),12,"0")+0+StringUtils.leftPad( config.getRailCode().substring(0,4), 4,"0");
Optional<MonitorRailInfoVO> largestRail = railList.stream().filter(tmp->areaCode.equals(tmp.getRailCode())).findFirst();
if (!largestRail.isPresent()){
// 全局围栏失效,不上传数据
return null;
}
if (pointIsInRail(pointDTO, largestRail.get())){
// 在全局围栏内,依序判断
for (MonitorRailInfoVO monitorRailInfoVO : railList) {
if (pointIsInRail(pointDTO, monitorRailInfoVO)){
// 返回满足在围栏条件的第一条围栏
return monitorRailInfoVO.getRailName();
}
}
}
// 不在全局围栏内,直接返回空
return null;
}
public static double calculateArea(LinearRing polygon) {
int numPoints = polygon.getNumPoints();
if (numPoints < 3) {
throw new IllegalArgumentException("至少需要三个点才能构成多边形");
}
double area = 0;
for (int i = 0; i < numPoints - 1; i++) {
Point p1 = polygon.getPointN(i);
Point p2 = polygon.getPointN((i + 1) % numPoints);
area += (p1.getX() * p2.getY()) - (p1.getY() * p2.getX());
}
return Math.abs(area / 2);
}
public static double calculateArea2(LinearRing polygon){
int numPoints = polygon.getNumPoints();
if (numPoints < 3) {
throw new IllegalArgumentException("至少需要三个点才能构成多边形");
}
int i, j;
int area = 0;
for (i = 0; i < numPoints; i++)
{
j = (i + 1) % numPoints;
area += polygon.getPointN(i).getX() * polygon.getPointN(j).getY();
area -= polygon.getPointN(i).getY() * polygon.getPointN(j).getX();
}
return Math.abs(area / 2);
}
public static double calculateArea3(LinearRing linearRing){
Polygon polygon = new GeometryFactory().createPolygon(linearRing, null); // 根据线性环创建多边形
return polygon.getArea();
}
private static void testPointInRail(PointDTO pointDTO){
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(100); // 设置最大连接数
jedisPoolConfig.setMaxIdle(10); // 设置最大空闲连接数
JedisPool jedisPool = new JedisPool(jedisPoolConfig, "192.168.30.26", 6379);
Jedis jedis = jedisPool.getResource();
String conf = jedis.get("vehicleSafetydb:dataProcess:dataUpload:config");
String rails = jedis.get("vehicleSafetydb:dataProcess:dataUpload:railInfo");
jedisPool.close();
TbDataUploadConfigDTO configDTO = JSON.parseObject(conf, TbDataUploadConfigDTO.class);
log.info("数据上传配置的围栏编码"+ Optional.ofNullable(configDTO).orElse(new TbDataUploadConfigDTO()).getRailCode());
List<MonitorRailInfoVO> railList = JSONArray.parseArray(rails, MonitorRailInfoVO.class);
log.info(JSON.toJSONString(railList));
for (MonitorRailInfoVO monitorRailInfoVO : railList) {
log.info(monitorRailInfoVO.getRailName()+" "+monitorRailInfoVO.getRailCode()+" "+pointIsInRail(pointDTO, monitorRailInfoVO));
}
}
public static void main(String[] args) {
// MonitorRailInfoVO monitorRailInfoVO = new MonitorRailInfoVO();
// 漏斗
// monitorRailInfoVO.setRailPoint(CollUtil.newArrayList("0,0","6,0","0,6","6,6"));
// 正方
// monitorRailInfoVO.setRailPoint(CollUtil.newArrayList("0,0","6,0","6,6","0,6"));
// 漏斗内
// System.out.println(pointIsInRail(new PointDTO(3.0,1.0,0.0), monitorRailInfoVO));
// 漏斗外
// monitorRailInfoVO.setWgs84RailPoint(CollUtil.newArrayList(
// "112.55829096,37.80848749,0",
// "112.56965870,37.80851027,0",
// "112.57004195,37.79914526,0",
// "112.55822657,37.79971515,0"
// ));
// monitorRailInfoVO.setWgs84RailPoint(CollUtil.newArrayList(
// "112.55202017090623,37.807970416154156,0.0",
// "112.56340765953608,37.80801002434173,0.0",
// "112.56379253544473,37.798644260311264,0.0",
// "112.55195666578163,37.799196815255726,0.0"
// ));
// System.out.println(pointIsInRail(new PointDTO(112.5624,37.805181,0.0), monitorRailInfoVO));
// System.out.println(pointIsInRail(new PointDTO(112.554133,37.80557,0.0), monitorRailInfoVO));
// System.out.println((new RailUtil()).getArea(monitorRailInfoVO));
// 漏斗外
// monitorRailInfoVO.setWgs84RailPoint(CollUtil.newArrayList(
// "90.31417085,44.54428293,0",
// "90.31520082,44.50033762,0",
// "90.37450982,44.49982264,0",
// "90.37244989,44.54651453,0"
// ));
//
// System.out.println(pointIsInRail(new PointDTO(90.32366497846226,44.517821758247244,0.0), monitorRailInfoVO));
testPointInRail(new PointDTO(112.5624,37.805181,0.0));
}
}
根据点的经纬度判断是否在围栏内 JAVA 工具类
最新推荐文章于 2024-07-22 14:15:06 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)