ard-work/src/main/java/com/ruoyi/app/position/service/IArdAppPositionService.java
@@ -73,4 +73,11 @@ * 2023/8/17 13:56:36 */ public List<SysUser>getNearAppUsers(SchedulingParam param); /** * 获取封控圈内所有在线app用户(多边形) * 刘苏义 * 2023/8/17 13:56:36 */ public List<SysUser>getNearAppUsersWithPolygon(SchedulingParam param); } ard-work/src/main/java/com/ruoyi/app/position/service/impl/ArdAppPositionServiceImpl.java
@@ -13,11 +13,13 @@ import com.ruoyi.scheduling.domian.SchedulingParam; import com.ruoyi.system.service.ISysUserService; import com.ruoyi.utils.tools.GisTool; import com.ruoyi.utils.tools.Point; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -172,5 +174,50 @@ } return filteredList; } /** * 获取封控圈内所有在线app用户(多边形) * 刘苏义 * 2023/8/17 13:56:36 */ @Override public List<SysUser> getNearAppUsersWithPolygon(SchedulingParam param) { List<SysUser> filteredList = new ArrayList<>(); try { Long deptId = SecurityUtils.getLoginUser().getUser().getDeptId(); List<Point> partitionLocation = param.getPartitionLocation(); SysUser user = new SysUser(); user.setDeptId(deptId); List<SysUser> appUserList = iSysUserService.selectAllAppUserList(user); //过滤在线 List<SysUser> onLineList = appUserList.stream() .filter(sysUser -> (sysUser.getAppOnlineState().equals("1"))) .collect(Collectors.toList()); //过滤范围 for (SysUser sysUser : onLineList) { ArdAppPosition ardAppPosition = ardAppPositionMapper.selectLastArdAppPositionByUserId(sysUser.getUserId()); if (ardAppPosition != null) { Double lon = ardAppPosition.getLongitude(); Double lat = ardAppPosition.getLatitude(); if (lon == null || lat == null) { continue; } Point point2D=new Point(); point2D.setLongitude(lon); point2D.setLatitude(lat); boolean inPolygon = GisTool.isInPolygon(point2D, partitionLocation); if (inPolygon) { Map<String, Object> params = new HashMap<>(); params.put("longitude", lon); params.put("latitude", lat); sysUser.setParams(params); filteredList.add(sysUser); // 将满足条件的用户添加到筛选列表中 } } } } catch (Exception ex) { log.error("获取封控圈内所有在线app用户异常" + ex.getMessage()); } return filteredList; } } ard-work/src/main/java/com/ruoyi/device/camera/service/IArdCamerasService.java
@@ -86,9 +86,15 @@ public TreeMap getNearCamerasBycoordinate(CameraCmd cmd); /** * 获取监控圈内所有在线光电 * 获取监控圈内所有在线光电(半径) * 刘苏义 * 2023/8/17 13:56:36 */ List<ArdCameras> getNearCameras(SchedulingParam param); /** * 获取监控圈内所有在线光电(多边形) * 刘苏义 * 2023/8/17 13:56:36 */ public List<ArdCameras> getNearCamerasWithPolygon(SchedulingParam param); } ard-work/src/main/java/com/ruoyi/device/camera/service/impl/ArdCamerasServiceImpl.java
@@ -1,5 +1,6 @@ package com.ruoyi.device.camera.service.impl; import java.awt.geom.Point2D; import java.time.LocalTime; import java.util.*; import java.util.stream.Collectors; @@ -25,6 +26,7 @@ import com.ruoyi.common.annotation.DataScope; import com.ruoyi.system.mapper.SysDeptMapper; import com.ruoyi.utils.tools.GisTool; import com.ruoyi.utils.tools.Point; import com.sun.org.apache.bcel.internal.generic.NEW; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -329,7 +331,60 @@ double[] camPosition = new double[]{camera.getLongitude(), camera.getLatitude()}; double distance = GisTool.getDistance(new double[]{longitude, latitude}, camPosition); if (distance <= radius) { camera.setChanNo(ArdTool.getChannelBydayNightTime(dayNightTime)); /*获取通道列表*/ ArdChannel ardChannel=new ArdChannel(); ardChannel.setDeviceId(camera.getId()); List<ArdChannel> ardChannels = ardChannelMapper.selectArdChannelList(ardChannel); camera.setChannelList(ardChannels); ardCameras.add(camera); } } //过滤在线相机 List<ArdCameras> onlineList = ardCameras.stream() .filter(ardCamera -> (!ardCamera.getLoginId().equals(-1))) .collect(Collectors.toList()); return onlineList; } catch (Exception ex) { log.error("获取附近相机异常:" + ex.getMessage()); } return null; } /** * 获取监控圈内所有在线光电 * 刘苏义 * 2023/8/17 13:57:21 */ @Override public List<ArdCameras> getNearCamerasWithPolygon(SchedulingParam param) { try { Long deptId=SecurityUtils.getLoginUser().getUser().getDeptId(); List<Point> partitionLocation = param.getPartitionLocation(); if(partitionLocation==null) { log.debug("多边形坐标集合为空"); return null; } String dayNightTime = redisCache.getCacheObject("sys_config:dayNightTime"); //获取所有光电(按部门) ArdCameras cameras= new ArdCameras(); cameras.setDeptId(deptId); List<ArdCameras> ardCamerasList = ardCamerasMapper.selectArdCamerasList(cameras); List<ArdCameras> ardCameras = new ArrayList<>(); for (ArdCameras camera : ardCamerasList) { if (camera.getLongitude() == null && camera.getLatitude() == null) { continue; } /*判断坐标是否在多边形范围内*/ Point camPosition=new Point(); camPosition.setLongitude(camera.getLongitude()); camPosition.setLatitude(camera.getLatitude()); boolean inPolygon = GisTool.isInPolygon(camPosition, partitionLocation); if (inPolygon) { /*获取通道列表*/ ArdChannel ardChannel=new ArdChannel(); ardChannel.setDeviceId(camera.getId()); List<ArdChannel> ardChannels = ardChannelMapper.selectArdChannelList(ardChannel); camera.setChannelList(ardChannels); ardCameras.add(camera); } } ard-work/src/main/java/com/ruoyi/device/hiksdk/controller/SdkController.java
@@ -83,6 +83,7 @@ @Log(title = "在线状态", businessType = BusinessType.CONTROL) public @ResponseBody AjaxResult getOnlineState(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); return toAjax(sdk.isOnLine(cmd)); } @@ -104,6 +105,7 @@ @Log(title = "调用预置点", businessType = BusinessType.CONTROL) public @ResponseBody AjaxResult gotoPreset(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); return toAjax(sdk.gotoPreset(cmd)); } @@ -113,6 +115,7 @@ @Log(title = "设置预置点", businessType = BusinessType.CONTROL) public @ResponseBody AjaxResult setPreset(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); return toAjax(sdk.setPreset(cmd)); } @@ -122,6 +125,7 @@ @Log(title = "获取聚焦值", businessType = BusinessType.CONTROL) public @ResponseBody AjaxResult getFocusPos(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); Map<String, Object> Map = sdk.getFocusPos(cmd); return AjaxResult.success("获取聚焦值", Map); } @@ -132,6 +136,7 @@ @Log(title = "设置聚焦值", businessType = BusinessType.CONTROL) public @ResponseBody AjaxResult setFocusPos(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); return toAjax(sdk.setFocusPos(cmd)); } @@ -141,6 +146,7 @@ @Log(title = "获取PTZ", businessType = BusinessType.CONTROL) public @ResponseBody AjaxResult GetPTZ(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); Map<String, Object> ptzMap = sdk.getPtz(cmd); return AjaxResult.success("获取ptz", ptzMap); } @@ -151,6 +157,7 @@ @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.channelNum"}) public @ResponseBody AjaxResult GetPTZScope(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); Map<String, Object> ptzMap = sdk.getPtzScope(cmd); return AjaxResult.success("获取ptz范围", ptzMap); } @@ -171,6 +178,7 @@ @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.channelNum", "cmd.targetPosition"}) public @ResponseBody AjaxResult setTargetPosition(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); return toAjax(sdk.guideTargetPosition(cmd)); } @@ -181,6 +189,7 @@ @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.channelNum"}) public @ResponseBody AjaxResult SetZeroPTZ(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); return toAjax(sdk.setZeroPtz(cmd)); } @@ -210,6 +219,7 @@ @Log(title = "获取云台锁定信息", businessType = BusinessType.CONTROL) public @ResponseBody AjaxResult getPTZLockInfo(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); int byWorkMode = sdk.getPTZLockInfo(cmd); if (byWorkMode == 0) { return AjaxResult.success("云台锁定状态:解锁"); @@ -226,6 +236,7 @@ @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.channelNum", "cmd.enable"}) public @ResponseBody AjaxResult defogcfg(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); return toAjax(sdk.controlDefogcfg(cmd)); } @@ -235,6 +246,7 @@ @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.channelNum", "cmd.enable"}) public @ResponseBody AjaxResult infrarecfg(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); return toAjax(sdk.controlInfrarecfg(cmd)); } @@ -244,6 +256,7 @@ @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.channelNum", "cmd.enable"}) public @ResponseBody AjaxResult enableFocusMode(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); return toAjax(sdk.controlFocusMode(cmd)); } @@ -251,6 +264,7 @@ @PostMapping("/getFocusMode") public @ResponseBody AjaxResult getFocusMode(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); String focusMode = sdk.getFocusMode(cmd); return AjaxResult.success(focusMode); } @@ -261,6 +275,7 @@ @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.channelNum", "cmd.enable"}) public @ResponseBody AjaxResult HeateRpwron(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); return toAjax(sdk.controlPTHeateRpwron(cmd)); } @@ -271,12 +286,14 @@ @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.channelNum", "cmd.enable"}) public @ResponseBody AjaxResult CameraDeicing(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); return toAjax(sdk.controlCameraDeicing(cmd)); } @PostMapping("/captureJPEGPicture") public @ResponseBody AjaxResult captureJPEGPicture(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); String base64Str = sdk.captureJPEGPicture(cmd); return toAjaxString(base64Str, "相机抓图"); } @@ -287,6 +304,7 @@ @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.channelNum"}) public @ResponseBody AjaxResult picCutCate(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); String path = sdk.picCutCate(cmd); return toAjaxString(path, "相机抓图"); } @@ -297,6 +315,7 @@ @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.channelNum", "cmd.enable"}) public @ResponseBody AjaxResult record(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); String path = sdk.record(cmd); return toAjaxString(path, "手动录像"); } ard-work/src/main/java/com/ruoyi/scheduling/controller/SchedulingController.java
@@ -38,7 +38,7 @@ IArdAppPositionService iArdAppPositionService; @GetMapping("/getNearVehiPersonCam") @ApiOperation("获取附近的车人相机") @ApiOperation("获取附近的车人相机(半径)") AjaxResult getNearVehiPersonCam(SchedulingParam param) { Map<String, Object> nearMap = new HashMap<>(); @@ -51,4 +51,16 @@ return AjaxResult.success(nearMap); } @PostMapping("/getPolygonVehiPersonCam") @ApiOperation("获取附近的车人相机(多边形)") AjaxResult getPolygonVehiPersonCam(@RequestBody SchedulingParam param) { Map<String, Object> nearMap = new HashMap<>(); List<Map<String, Object>> Cars = iArdSyCarService.getNearCarWithPolygon(param); nearMap.put("car", Cars); List<ArdCameras> Cameras = iArdCamerasService.getNearCamerasWithPolygon(param); nearMap.put("camera", Cameras); List<SysUser> AppUsers = iArdAppPositionService.getNearAppUsersWithPolygon(param); nearMap.put("users", AppUsers); return AjaxResult.success(nearMap); } } ard-work/src/main/java/com/ruoyi/scheduling/domian/SchedulingParam.java
@@ -1,6 +1,9 @@ package com.ruoyi.scheduling.domian; import com.ruoyi.utils.tools.Point; import lombok.Data; import java.util.List; /** * @Description: @@ -16,4 +19,6 @@ Integer monitoringRadius; Double longitude; Double latitude; //多边形坐标集合 List<Point> partitionLocation; } ard-work/src/main/java/com/ruoyi/sy/service/IArdSyCarService.java
@@ -139,4 +139,8 @@ * 获取附近范围内的车辆信息 * */ List<Map<String, Object>> getNearCar(SchedulingParam param); /** * 获取附近范围内的车辆信息(多边形) * */ List<Map<String, Object>> getNearCarWithPolygon(SchedulingParam param); } ard-work/src/main/java/com/ruoyi/sy/service/impl/ArdSyCarServiceImpl.java
@@ -1,10 +1,12 @@ package com.ruoyi.sy.service.impl; import java.awt.geom.Point2D; import java.io.IOException; import java.io.InputStream; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.Predicate; @@ -16,6 +18,7 @@ import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.uuid.IdUtils; import com.ruoyi.utils.tools.Point; import com.ruoyi.scheduling.domian.SchedulingParam; import com.ruoyi.sy.domain.ArdSyCarDay; import com.ruoyi.sy.mapper.ArdSyCarDayMapper; @@ -1032,7 +1035,6 @@ /** * 获取附近范围内的车辆信息 */ @Override public List<Map<String, Object>> getNearCar(SchedulingParam param) { Double longitude = param.getLongitude(); @@ -1092,4 +1094,70 @@ } return filteredList; } /** * 获取范围内的车辆信息(多边形) */ @Override public List<Map<String, Object>> getNearCarWithPolygon(SchedulingParam param) { List<Map<String, Object>> filteredList = new ArrayList<>(); try { List<Point> partitionLocation = param.getPartitionLocation(); if (partitionLocation == null) { log.debug("多边形坐标集合为空"); return null; } String userId = SecurityUtils.getUserId(); ArdSyUser syUser = new ArdSyUser(); syUser.setSysUserId(userId); List<ArdSyUser> ardSyUserList = ardSyUserMapper.selectArdSyUserList(syUser); if (ardSyUserList.size() == 0) { log.debug("用户未挂接三一车辆"); return null; } ArdSyUser ardSyUser = ardSyUserList.get(0); String syUrl = redisCache.getCacheObject("sys_config:syCarPT"); String passwordMd5 = DigestUtils.md5Hex(ardSyUser.getPassword()); Map<String, Object> LogInResult = sYClient.logIn(syUrl, passwordMd5, ardSyUser.getUserId()); String sessionId = (String) LogInResult.get("sessionId"); Map<String, Object> teamList = sYClient.getTeamList(syUrl, ardSyUser.getUserId(), sessionId); List<Map<String, Object>> listMap = (List<Map<String, Object>>) teamList.get("list"); List<Map<String, Object>> allList = new ArrayList<>(); for (Map<String, Object> team : listMap) { String teamId = (String) team.get("teamId"); Map<String, Object> carListMap = sYClient.getCarList1(syUrl, teamId, ardSyUser.getUserId(), sessionId); if (((String) carListMap.get("rspCode")).equals("1")) { List<Map<String, Object>> list = (List<Map<String, Object>>) carListMap.get("list"); allList.addAll(list); } } //过滤在线车辆 List<Map<String, Object>> onlineList = allList.stream() .filter(map -> !"离线".equals(map.get("stateCn"))) .collect(Collectors.toList()); //过滤半径 for (Map<String, Object> carMap : onlineList) { String carId = (String) carMap.get("carId"); Map<String, Object> carGPSTrack = sYClient.getCarNearPositionByCarId(syUrl, carId, ardSyUser.getUserId(), sessionId); List<Map<String, Object>> carGPSMap = (List<Map<String, Object>>) carGPSTrack.get("list"); Double lng = Double.valueOf((String) carGPSMap.get(0).get("lng")); Double lat = Double.valueOf((String) carGPSMap.get(0).get("lat")); Point point = new Point(); point.setLongitude(lng); point.setLatitude(lat); boolean inPolygon = GisTool.isInPolygon(point, partitionLocation); if (inPolygon) { carMap.put("longitude", lng); carMap.put("latitude", lat); filteredList.add(carMap); // 将满足条件的车辆添加到筛选列表中 } } } catch (Exception ex) { log.error("获取范围内的车辆信息(多边形)异常:" + ex.getMessage()); } return filteredList; } } ard-work/src/main/java/com/ruoyi/utils/tools/GisTool.java
@@ -4,6 +4,10 @@ import org.gavaghan.geodesy.GeodeticCalculator; import org.gavaghan.geodesy.GlobalCoordinates; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.List; /** * @Description: * @ClassName: GisTool @@ -29,4 +33,109 @@ GlobalCoordinates target = new GlobalCoordinates(latitudeTo, longitudeTo); return geodeticCalculator.calculateGeodeticCurve(Ellipsoid.WGS84, source, target).getEllipsoidalDistance(); } public static void main(String[] args) { // // 被检测的经纬度点 // Point point= new Point(126.649261,45.687377); // // 商业区域(百度多边形区域经纬度集合) // List<Point> partitionLocation = new ArrayList<>(); // partitionLocation.add(new Point(126.64459,45.688548)); // partitionLocation.add(new Point(126.653376,45.68938)); // partitionLocation.add(new Point(126.645776,45.685048)); // partitionLocation.add(new Point(126.654184,45.685778)); // System.out.println(isInPolygon(point,partitionLocation)); } /** * 判断当前位置是否在多边形区域内 * @param orderLocation 当前点 * @param partitionLocation 区域顶点 * @return */ public static boolean isInPolygon(Point orderLocation,List<Point> partitionLocation){ double p_x =orderLocation.getLongitude(); double p_y =orderLocation.getLatitude(); Point2D.Double point = new Point2D.Double(p_x, p_y); List<Point2D.Double> pointList= new ArrayList<Point2D.Double>(); for (Point points : partitionLocation){ double polygonPoint_x=points.getLongitude(); double polygonPoint_y=points.getLatitude(); Point2D.Double polygonPoint = new Point2D.Double(polygonPoint_x,polygonPoint_y); 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; } } } ard-work/src/main/java/com/ruoyi/utils/tools/Point.java
New file @@ -0,0 +1,18 @@ package com.ruoyi.utils.tools; import lombok.AllArgsConstructor; import lombok.Data; /** * @Description: * @ClassName: Point * @Author: 刘苏义 * @Date: 2023年08月22日9:56:58 * @Version: 1.0 **/ @Data public class Point{ private static final long serialVersionUID = 1L; private Double longitude; private Double latitude; } ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/SdkOperateAspect.java
@@ -100,6 +100,10 @@ } else { /*当前控制者为普通用户*/ SysUser sysUser = sysUserService.selectUserById(currentOperator); if(StringUtils.isNull(sysUser)) { return true; } currentLevel = Integer.valueOf(sysUser.getCameraPriority()); } Integer operatorLevel = 0;//获取申请者的优先级