| | |
| | | .build(); |
| | | QuartzManager.addJob( |
| | | ElectronicEffectJob.class, |
| | | (ElectronicEffectJob.name + xpElectronicFence.getId()).toUpperCase(), |
| | | (ElectronicEffectJob.effect + xpElectronicFence.getId()).toUpperCase(), |
| | | TimeJobType.ELECTRONIC_EFFECT, |
| | | DateUtils.localDateTimeToDate(dto.getEffectTime()), |
| | | maps |
| | |
| | | xpElectronicFence.setStatus(1); |
| | | } |
| | | } |
| | | if (dto.getFailureType()!=null && dto.getFailureType() == 2) { |
| | | if (dto.getFailureType() != null && dto.getFailureType() == 2) { |
| | | |
| | | if (dto.getFailureTime().isBefore(LocalDateTime.now())) { |
| | | // 设置待启用 |
| | |
| | | .build(); |
| | | QuartzManager.addJob( |
| | | ElectronicEffectJob.class, |
| | | (ElectronicEffectJob.name + xpElectronicFence.getId()).toUpperCase(), |
| | | (ElectronicEffectJob.failure + xpElectronicFence.getId()).toUpperCase(), |
| | | TimeJobType.ELECTRONIC_FAILURE, |
| | | DateUtils.localDateTimeToDate(dto.getEffectTime()), |
| | | maps |
| | |
| | | } |
| | | } |
| | | } |
| | | this.updateById(xpElectronicFence); |
| | | if (xpElectronicFence.getStatus() == 2) { |
| | | // 设置电子围栏ID并保存区域数据 |
| | | for (XpElectronicFenceArea area : newElectronicFenceAreas) { |
| | | area.setElectronicId(xpElectronicFence.getId()); |
| | | area.setAreaStatus(1); |
| | | area.setCityCode(dto.getCityCode()); |
| | | xpElectronicFenceAreaMapper.insert(area); |
| | | |
| | | } |
| | | this.updateById(xpElectronicFence); |
| | | if (xpElectronicFence.getStatus() == 2) { |
| | | // 设置电子围栏ID并保存区域数据 |
| | | for (XpElectronicFenceArea area : newElectronicFenceAreas) { |
| | | area.setElectronicId(xpElectronicFence.getId()); |
| | | area.setAreaStatus(1); |
| | | area.setCityCode(dto.getCityCode()); |
| | | xpElectronicFenceAreaMapper.insert(area); |
| | | |
| | | } |
| | | |
| | | if (dto.getStatus() == 2) { |
| | | for (XpElectronicFenceArea newElectronicFenceArea : newElectronicFenceAreas) { |
| | | if (newElectronicFenceArea.getAreaType() == 1 |
| | | && newElectronicFenceArea.getAreaStatus() == 1) { |
| | | } |
| | | |
| | | if (dto.getStatus() == 2) { |
| | | for (XpElectronicFenceArea newElectronicFenceArea : newElectronicFenceAreas) { |
| | | if (newElectronicFenceArea.getAreaType() == 1 |
| | | && newElectronicFenceArea.getAreaStatus() == 1) { |
| | | XpGeoFencingPolygon xpGeoFencingPolygon = new XpGeoFencingPolygon(); |
| | | xpGeoFencingPolygon.setFenceId(String.valueOf(xpElectronicFence.getId())); |
| | | xpGeoFencingPolygon.setName(xpElectronicFence.getElectronicName()); |
| | | xpGeoFencingPolygon.setAreaId(String.valueOf(newElectronicFenceArea.getId())); |
| | | xpGeoFencingPolygon.setCityCode("510100"); |
| | | xpGeoFencingPolygon.setOperationStrategy(xpElectronicFence.getOperationStrategy()); |
| | | // 将围栏点转换为GeoJSON多边形 |
| | | GeoJsonPolygon geoJsonPolygon = convertToGeoJsonPolygon(newElectronicFenceArea.getFencePoints()); |
| | | xpGeoFencingPolygon.setPoints(geoJsonPolygon); |
| | | mongoTemplate.insert(xpGeoFencingPolygon); |
| | | } |
| | | if (newElectronicFenceArea.getAreaType() == 2 |
| | | && newElectronicFenceArea.getAreaStatus() == 1) { |
| | | XpGeoFencingProhibitedPolygon xpGeoFencingProhibitedPolygon = new XpGeoFencingProhibitedPolygon(); |
| | | xpGeoFencingProhibitedPolygon.setFenceId(String.valueOf(xpElectronicFence.getId())); |
| | | xpGeoFencingProhibitedPolygon.setName(xpElectronicFence.getElectronicName()); |
| | | xpGeoFencingProhibitedPolygon.setAreaId(String.valueOf(newElectronicFenceArea.getId())); |
| | | // 将围栏点转换为GeoJSON多边形 |
| | | GeoJsonPolygon geoJsonPolygon = convertToGeoJsonPolygon(newElectronicFenceArea.getFencePoints()); |
| | | xpGeoFencingProhibitedPolygon.setPoints(geoJsonPolygon); |
| | | mongoTemplate.save(xpGeoFencingProhibitedPolygon); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return R.ok(); |
| | | } catch (Exception e) { |
| | | log.error("新增电子围栏失败", e); |
| | | throw new ServiceException("新增电子围栏失败", I18nKeyConstant.ADD_ELECTRONIC_ERROR); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public R editElectronic(ElectronicFenceUpdateDto dto) { |
| | | try { |
| | | // 获取现有的运营区域(areaType=1),排除当前正在编辑的电子围栏 |
| | | LambdaQueryWrapper<XpElectronicFenceArea> xpElectronicFenceAreaLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
| | | xpElectronicFenceAreaLambdaQueryWrapper.eq(XpElectronicFenceArea::getAreaType, 1); |
| | | xpElectronicFenceAreaLambdaQueryWrapper.ne(XpElectronicFenceArea::getElectronicId, dto.getId()); |
| | | List<XpElectronicFenceArea> existingOperationAreas = xpElectronicFenceAreaMapper.selectList(xpElectronicFenceAreaLambdaQueryWrapper); |
| | | |
| | | // 获取待更新的区域 |
| | | List<XpElectronicFenceArea> updatedElectronicFenceAreas = dto.getElectronicFenceAreas(); |
| | | |
| | | // 检查更新后的区域与现有运营区域是否有重叠 |
| | | for (XpElectronicFenceArea updatedArea : updatedElectronicFenceAreas) { |
| | | if (updatedArea.getAreaType() == 1) { // 只检查运营区域 |
| | | for (XpElectronicFenceArea existingArea : existingOperationAreas) { |
| | | if (polygonOverlapService.checkPolygonOverlap( |
| | | updatedArea.getFencePoints(), |
| | | existingArea.getFencePoints())) { |
| | | throw new ServiceException( |
| | | "运营区域{}与现有运营区域{}发生重叠", |
| | | I18nKeyConstant.AREA_OVERLAP, |
| | | new Object[]{existingArea.getAreaName(), existingArea.getAreaName()} |
| | | ); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // 更新主表数据 |
| | | XpElectronicFence xpElectronicFence = new XpElectronicFence(); |
| | | BeanUtils.copyProperties(dto, xpElectronicFence); |
| | | if (dto.getStatus() == 0) { |
| | | xpElectronicFence.setStatus(0); |
| | | } else if (dto.getStatus() == 1) { |
| | | if (dto.getEffectType() == 1) { |
| | | // 设置为启用中 |
| | | xpElectronicFence.setStatus(2); |
| | | xpElectronicFence.setEffectTime(LocalDateTime.now()); |
| | | } else { |
| | | if (dto.getEffectTime().isBefore(LocalDateTime.now())) { |
| | | // 设置为启用中 |
| | | xpElectronicFence.setStatus(2); |
| | | } else { |
| | | // 先删除以前的定时任务 |
| | | QuartzManager.removeJob((ElectronicEffectJob.effect + xpElectronicFence.getId()).toUpperCase(), TimeJobType.ELECTRONIC_EFFECT); |
| | | |
| | | // 添加定时任务job type=1电子围栏生效 type=2电子围栏失效 |
| | | Map<String, ? extends Object> maps = |
| | | new ImmutableMap.Builder<String, Long>(). |
| | | put("type", 1L) |
| | | .put("id", xpElectronicFence.getId()) |
| | | .build(); |
| | | QuartzManager.addJob( |
| | | ElectronicEffectJob.class, |
| | | (ElectronicEffectJob.effect + xpElectronicFence.getId()).toUpperCase(), |
| | | TimeJobType.ELECTRONIC_EFFECT, |
| | | DateUtils.localDateTimeToDate(dto.getEffectTime()), |
| | | maps |
| | | ); |
| | | xpElectronicFence.setStatus(1); |
| | | } |
| | | } |
| | | if (dto.getFailureType() != null && dto.getFailureType() == 2) { |
| | | |
| | | if (dto.getFailureTime().isBefore(LocalDateTime.now())) { |
| | | // 设置待启用 |
| | | xpElectronicFence.setStatus(1); |
| | | } else { |
| | | // 先删除以前的定时任务 |
| | | QuartzManager.removeJob((ElectronicEffectJob.failure + xpElectronicFence.getId()).toUpperCase(), TimeJobType.ELECTRONIC_FAILURE); |
| | | // 添加定时任务job type=1电子围栏生效 type=2电子围栏失效 |
| | | Map<String, ? extends Object> maps = |
| | | new ImmutableMap.Builder<String, Long>(). |
| | | put("type", 2L) |
| | | .put("id", xpElectronicFence.getId()) |
| | | .build(); |
| | | QuartzManager.addJob( |
| | | ElectronicEffectJob.class, |
| | | (ElectronicEffectJob.failure + xpElectronicFence.getId()).toUpperCase(), |
| | | TimeJobType.ELECTRONIC_FAILURE, |
| | | DateUtils.localDateTimeToDate(dto.getEffectTime()), |
| | | maps |
| | | ); |
| | | xpElectronicFence.setStatus(1); |
| | | } |
| | | } |
| | | } |
| | | xpElectronicFence.setCityCode(dto.getCityCode()); |
| | | |
| | | this.updateById(xpElectronicFence); |
| | | // 删除旧的区域数据,然后保存新的区域数据 |
| | | xpElectronicFenceAreaMapper.delete(new LambdaQueryWrapper<XpElectronicFenceArea>() |
| | | .eq(XpElectronicFenceArea::getElectronicId, dto.getId())); |
| | | for (XpElectronicFenceArea area : updatedElectronicFenceAreas) { |
| | | area.setElectronicId(dto.getId()); // 设置关联的电子围栏ID |
| | | area.setCityCode(dto.getCityCode()); |
| | | xpElectronicFenceAreaMapper.insert(area); |
| | | } |
| | | if (dto.getStatus() == 2) { |
| | | for (XpElectronicFenceArea newElectronicFenceArea : updatedElectronicFenceAreas) { |
| | | if (newElectronicFenceArea.getAreaType() == 1 |
| | | && newElectronicFenceArea.getAreaStatus() == 1) { |
| | | // 先查询出mongo里围栏相同的数据 如果有 那么更新数据 |
| | | Query query = new Query(); |
| | | query.addCriteria(Criteria.where("fenceId").is(String.valueOf(xpElectronicFence.getId()))); |
| | | query.addCriteria(Criteria.where("areaId").is(String.valueOf(newElectronicFenceArea.getId()))); |
| | | XpGeoFencingPolygon old = mongoTemplate.findOne(query, XpGeoFencingPolygon.class); |
| | | if (old == null) { |
| | | XpGeoFencingPolygon xpGeoFencingPolygon = new XpGeoFencingPolygon(); |
| | | xpGeoFencingPolygon.setFenceId(String.valueOf(xpElectronicFence.getId())); |
| | | xpGeoFencingPolygon.setName(xpElectronicFence.getElectronicName()); |
| | | xpGeoFencingPolygon.setAreaId(String.valueOf(newElectronicFenceArea.getId())); |
| | | xpGeoFencingPolygon.setCityCode("510100"); |
| | | xpGeoFencingPolygon.setOperationStrategy(xpElectronicFence.getOperationStrategy()); |
| | | // 将围栏点转换为GeoJSON多边形 |
| | | GeoJsonPolygon geoJsonPolygon = convertToGeoJsonPolygon(newElectronicFenceArea.getFencePoints()); |
| | | xpGeoFencingPolygon.setPoints(geoJsonPolygon); |
| | | mongoTemplate.insert(xpGeoFencingPolygon); |
| | | } else { |
| | | // 如果存在,则更新已有文档 |
| | | old.setFenceId(String.valueOf(xpElectronicFence.getId())); |
| | | old.setName(xpElectronicFence.getElectronicName()); |
| | | old.setAreaId(String.valueOf(newElectronicFenceArea.getId())); |
| | | old.setOperationStrategy(xpElectronicFence.getOperationStrategy()); |
| | | // 将围栏点转换为GeoJSON多边形 |
| | | GeoJsonPolygon geoJsonPolygon = convertToGeoJsonPolygon(newElectronicFenceArea.getFencePoints()); |
| | | old.setPoints(geoJsonPolygon); |
| | | // 执行更新操作 |
| | | mongoTemplate.save(old); // save() 会根据 _id 自动判断是插入还是更新 |
| | | } |
| | | if (newElectronicFenceArea.getAreaType() == 2 |
| | | && newElectronicFenceArea.getAreaStatus() == 1) { |
| | | |
| | | } |
| | | if (newElectronicFenceArea.getAreaType() == 2 |
| | | && newElectronicFenceArea.getAreaStatus() == 1) { |
| | | // 先查询出mongo里围栏相同的数据 如果有 那么更新数据 |
| | | Query query = new Query(); |
| | | query.addCriteria(Criteria.where("fenceId").is(String.valueOf(xpElectronicFence.getId()))); |
| | | query.addCriteria(Criteria.where("areaId").is(String.valueOf(newElectronicFenceArea.getId()))); |
| | | XpGeoFencingProhibitedPolygon old = mongoTemplate.findOne(query, XpGeoFencingProhibitedPolygon.class); |
| | | if (old == null) { |
| | | XpGeoFencingProhibitedPolygon xpGeoFencingProhibitedPolygon = new XpGeoFencingProhibitedPolygon(); |
| | | xpGeoFencingProhibitedPolygon.setFenceId(String.valueOf(xpElectronicFence.getId())); |
| | | xpGeoFencingProhibitedPolygon.setName(xpElectronicFence.getElectronicName()); |
| | |
| | | GeoJsonPolygon geoJsonPolygon = convertToGeoJsonPolygon(newElectronicFenceArea.getFencePoints()); |
| | | xpGeoFencingProhibitedPolygon.setPoints(geoJsonPolygon); |
| | | mongoTemplate.save(xpGeoFencingProhibitedPolygon); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return R.ok(); |
| | | } catch(Exception e){ |
| | | log.error("新增电子围栏失败", e); |
| | | throw new ServiceException("新增电子围栏失败", I18nKeyConstant.ADD_ELECTRONIC_ERROR); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public R editElectronic (ElectronicFenceUpdateDto dto){ |
| | | try { |
| | | // 获取现有的运营区域(areaType=1),排除当前正在编辑的电子围栏 |
| | | LambdaQueryWrapper<XpElectronicFenceArea> xpElectronicFenceAreaLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
| | | xpElectronicFenceAreaLambdaQueryWrapper.eq(XpElectronicFenceArea::getAreaType, 1); |
| | | xpElectronicFenceAreaLambdaQueryWrapper.ne(XpElectronicFenceArea::getElectronicId, dto.getId()); |
| | | List<XpElectronicFenceArea> existingOperationAreas = xpElectronicFenceAreaMapper.selectList(xpElectronicFenceAreaLambdaQueryWrapper); |
| | | |
| | | // 获取待更新的区域 |
| | | List<XpElectronicFenceArea> updatedElectronicFenceAreas = dto.getElectronicFenceAreas(); |
| | | |
| | | // 检查更新后的区域与现有运营区域是否有重叠 |
| | | for (XpElectronicFenceArea updatedArea : updatedElectronicFenceAreas) { |
| | | if (updatedArea.getAreaType() == 1) { // 只检查运营区域 |
| | | for (XpElectronicFenceArea existingArea : existingOperationAreas) { |
| | | if (polygonOverlapService.checkPolygonOverlap( |
| | | updatedArea.getFencePoints(), |
| | | existingArea.getFencePoints())) { |
| | | throw new ServiceException( |
| | | "运营区域{}与现有运营区域{}发生重叠", |
| | | I18nKeyConstant.AREA_OVERLAP, |
| | | new Object[]{existingArea.getAreaName(), existingArea.getAreaName()} |
| | | ); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // 更新主表数据 |
| | | XpElectronicFence xpElectronicFence = new XpElectronicFence(); |
| | | BeanUtils.copyProperties(dto, xpElectronicFence); |
| | | if (dto.getStatus() == 0) { |
| | | xpElectronicFence.setStatus(0); |
| | | } else if (dto.getStatus() == 1) { |
| | | if (dto.getEffectType() == 1) { |
| | | // 设置为启用中 |
| | | xpElectronicFence.setStatus(2); |
| | | xpElectronicFence.setEffectTime(LocalDateTime.now()); |
| | | } else { |
| | | if (dto.getEffectTime().isBefore(LocalDateTime.now())) { |
| | | // 设置为启用中 |
| | | xpElectronicFence.setStatus(2); |
| | | } else { |
| | | xpElectronicFence.setStatus(1); |
| | | old.setFenceId(String.valueOf(xpElectronicFence.getId())); |
| | | old.setName(xpElectronicFence.getElectronicName()); |
| | | old.setAreaId(String.valueOf(newElectronicFenceArea.getId())); |
| | | // 将围栏点转换为GeoJSON多边形 |
| | | GeoJsonPolygon geoJsonPolygon = convertToGeoJsonPolygon(newElectronicFenceArea.getFencePoints()); |
| | | old.setPoints(geoJsonPolygon); |
| | | mongoTemplate.save(old); |
| | | } |
| | | } |
| | | } |
| | | xpElectronicFence.setCityCode(dto.getCityCode()); |
| | | } |
| | | // 判断区域下的所有运营点位是否处于运营区域内 如果不是则更新为测试点位 |
| | | List<Long> areaIds = updatedElectronicFenceAreas.stream().map(XpElectronicFenceArea::getId).collect(Collectors.toList()); |
| | | LambdaQueryWrapper<XpPoint> pointLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
| | | pointLambdaQueryWrapper.in(XpPoint::getElectronicAreaId, areaIds).eq(XpPoint::getPointType, 1); |
| | | List<XpPoint> xpPoints = xpPointMapper.selectList(pointLambdaQueryWrapper); |
| | | List<XpPoint> updatePoints = new ArrayList<>(); |
| | | if (!xpPoints.isEmpty()) { |
| | | List<Long> electronicAreaId = xpPoints.stream().map(XpPoint::getElectronicAreaId).distinct().collect(Collectors.toList()); |
| | | if (!electronicAreaId.isEmpty()) { |
| | | Map<Long, XpElectronicFenceArea> longXpElectronicFenceAreaMap = updatedElectronicFenceAreas |
| | | .stream().collect(Collectors.toMap(XpElectronicFenceArea::getId, e -> e)); |
| | | for (XpPoint xpPoint : xpPoints) { |
| | | XpElectronicFenceArea xpElectronicFenceArea = longXpElectronicFenceAreaMap.get(xpPoint.getElectronicAreaId()); |
| | | |
| | | this.updateById(xpElectronicFence); |
| | | // 删除旧的区域数据,然后保存新的区域数据 |
| | | xpElectronicFenceAreaMapper.delete(new LambdaQueryWrapper<XpElectronicFenceArea>() |
| | | .eq(XpElectronicFenceArea::getElectronicId, dto.getId())); |
| | | for (XpElectronicFenceArea area : updatedElectronicFenceAreas) { |
| | | area.setElectronicId(dto.getId()); // 设置关联的电子围栏ID |
| | | area.setCityCode(dto.getCityCode()); |
| | | xpElectronicFenceAreaMapper.insert(area); |
| | | } |
| | | if (dto.getStatus() == 2) { |
| | | for (XpElectronicFenceArea newElectronicFenceArea : updatedElectronicFenceAreas) { |
| | | if (newElectronicFenceArea.getAreaType() == 1 |
| | | && newElectronicFenceArea.getAreaStatus() == 1) { |
| | | // 先查询出mongo里围栏相同的数据 如果有 那么更新数据 |
| | | Query query = new Query(); |
| | | query.addCriteria(Criteria.where("fenceId").is(String.valueOf(xpElectronicFence.getId()))); |
| | | query.addCriteria(Criteria.where("areaId").is(String.valueOf(newElectronicFenceArea.getId()))); |
| | | XpGeoFencingPolygon old = mongoTemplate.findOne(query, XpGeoFencingPolygon.class); |
| | | if (old == null) { |
| | | XpGeoFencingPolygon xpGeoFencingPolygon = new XpGeoFencingPolygon(); |
| | | xpGeoFencingPolygon.setFenceId(String.valueOf(xpElectronicFence.getId())); |
| | | xpGeoFencingPolygon.setName(xpElectronicFence.getElectronicName()); |
| | | xpGeoFencingPolygon.setAreaId(String.valueOf(newElectronicFenceArea.getId())); |
| | | xpGeoFencingPolygon.setOperationStrategy(xpElectronicFence.getOperationStrategy()); |
| | | // 将围栏点转换为GeoJSON多边形 |
| | | GeoJsonPolygon geoJsonPolygon = convertToGeoJsonPolygon(newElectronicFenceArea.getFencePoints()); |
| | | xpGeoFencingPolygon.setPoints(geoJsonPolygon); |
| | | mongoTemplate.insert(xpGeoFencingPolygon); |
| | | } else { |
| | | // 如果存在,则更新已有文档 |
| | | old.setFenceId(String.valueOf(xpElectronicFence.getId())); |
| | | old.setName(xpElectronicFence.getElectronicName()); |
| | | old.setAreaId(String.valueOf(newElectronicFenceArea.getId())); |
| | | old.setOperationStrategy(xpElectronicFence.getOperationStrategy()); |
| | | // 将围栏点转换为GeoJSON多边形 |
| | | GeoJsonPolygon geoJsonPolygon = convertToGeoJsonPolygon(newElectronicFenceArea.getFencePoints()); |
| | | old.setPoints(geoJsonPolygon); |
| | | // 执行更新操作 |
| | | mongoTemplate.save(old); // save() 会根据 _id 自动判断是插入还是更新 |
| | | } |
| | | |
| | | } |
| | | if (newElectronicFenceArea.getAreaType() == 2 |
| | | && newElectronicFenceArea.getAreaStatus() == 1) { |
| | | // 先查询出mongo里围栏相同的数据 如果有 那么更新数据 |
| | | Query query = new Query(); |
| | | query.addCriteria(Criteria.where("fenceId").is(String.valueOf(xpElectronicFence.getId()))); |
| | | query.addCriteria(Criteria.where("areaId").is(String.valueOf(newElectronicFenceArea.getId()))); |
| | | XpGeoFencingProhibitedPolygon old = mongoTemplate.findOne(query, XpGeoFencingProhibitedPolygon.class); |
| | | if (old == null) { |
| | | XpGeoFencingProhibitedPolygon xpGeoFencingProhibitedPolygon = new XpGeoFencingProhibitedPolygon(); |
| | | xpGeoFencingProhibitedPolygon.setFenceId(String.valueOf(xpElectronicFence.getId())); |
| | | xpGeoFencingProhibitedPolygon.setName(xpElectronicFence.getElectronicName()); |
| | | xpGeoFencingProhibitedPolygon.setAreaId(String.valueOf(newElectronicFenceArea.getId())); |
| | | // 将围栏点转换为GeoJSON多边形 |
| | | GeoJsonPolygon geoJsonPolygon = convertToGeoJsonPolygon(newElectronicFenceArea.getFencePoints()); |
| | | xpGeoFencingProhibitedPolygon.setPoints(geoJsonPolygon); |
| | | mongoTemplate.save(xpGeoFencingProhibitedPolygon); |
| | | } else { |
| | | old.setFenceId(String.valueOf(xpElectronicFence.getId())); |
| | | old.setName(xpElectronicFence.getElectronicName()); |
| | | old.setAreaId(String.valueOf(newElectronicFenceArea.getId())); |
| | | // 将围栏点转换为GeoJSON多边形 |
| | | GeoJsonPolygon geoJsonPolygon = convertToGeoJsonPolygon(newElectronicFenceArea.getFencePoints()); |
| | | old.setPoints(geoJsonPolygon); |
| | | mongoTemplate.save(old); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // 判断区域下的所有运营点位是否处于运营区域内 如果不是则更新为测试点位 |
| | | List<Long> areaIds = updatedElectronicFenceAreas.stream().map(XpElectronicFenceArea::getId).collect(Collectors.toList()); |
| | | LambdaQueryWrapper<XpPoint> pointLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
| | | pointLambdaQueryWrapper.in(XpPoint::getElectronicAreaId, areaIds).eq(XpPoint::getPointType, 1); |
| | | List<XpPoint> xpPoints = xpPointMapper.selectList(pointLambdaQueryWrapper); |
| | | List<XpPoint> updatePoints = new ArrayList<>(); |
| | | if (!xpPoints.isEmpty()) { |
| | | List<Long> electronicAreaId = xpPoints.stream().map(XpPoint::getElectronicAreaId).distinct().collect(Collectors.toList()); |
| | | if (!electronicAreaId.isEmpty()) { |
| | | Map<Long, XpElectronicFenceArea> longXpElectronicFenceAreaMap = updatedElectronicFenceAreas |
| | | .stream().collect(Collectors.toMap(XpElectronicFenceArea::getId, e -> e)); |
| | | for (XpPoint xpPoint : xpPoints) { |
| | | XpElectronicFenceArea xpElectronicFenceArea = longXpElectronicFenceAreaMap.get(xpPoint.getElectronicAreaId()); |
| | | |
| | | if (xpElectronicFenceArea != null) { |
| | | String fencePoints = xpElectronicFenceArea.getFencePoints(); |
| | | Double pointLat = xpPoint.getPointLat(); |
| | | Double pointLon = xpPoint.getPointLon(); |
| | | // 判断这个点位有没有处于当前区域 由多个经纬度点构成的面里 |
| | | if (fencePoints != null && !fencePoints.trim().isEmpty() && |
| | | pointLat != null && pointLon != null) { |
| | | boolean isInside = isPointInPolygon(fencePoints, pointLon, pointLat); |
| | | // 如果点不在区域内,更新为测试点位 |
| | | if (!isInside) { |
| | | xpPoint.setPointType(2); // |
| | | log.info("点位ID: {} 经纬度: ({}, {}) 不在电子围栏区域内,已更新为测试点位", |
| | | xpPoint.getId(), pointLon, pointLat); |
| | | UpdateWrapper<XpPoint> xpPointUpdateWrapper = new UpdateWrapper<>(); |
| | | xpPointUpdateWrapper.eq("id", xpPoint.getId()); |
| | | xpPointUpdateWrapper.set("point_type", 2); |
| | | xpPointUpdateWrapper.set("electronic_areaId", null); |
| | | xpPointMapper.update(xpPoint, xpPointUpdateWrapper); |
| | | } |
| | | if (xpElectronicFenceArea != null) { |
| | | String fencePoints = xpElectronicFenceArea.getFencePoints(); |
| | | Double pointLat = xpPoint.getPointLat(); |
| | | Double pointLon = xpPoint.getPointLon(); |
| | | // 判断这个点位有没有处于当前区域 由多个经纬度点构成的面里 |
| | | if (fencePoints != null && !fencePoints.trim().isEmpty() && |
| | | pointLat != null && pointLon != null) { |
| | | boolean isInside = isPointInPolygon(fencePoints, pointLon, pointLat); |
| | | // 如果点不在区域内,更新为测试点位 |
| | | if (!isInside) { |
| | | xpPoint.setPointType(2); // |
| | | log.info("点位ID: {} 经纬度: ({}, {}) 不在电子围栏区域内,已更新为测试点位", |
| | | xpPoint.getId(), pointLon, pointLat); |
| | | UpdateWrapper<XpPoint> xpPointUpdateWrapper = new UpdateWrapper<>(); |
| | | xpPointUpdateWrapper.eq("id", xpPoint.getId()); |
| | | xpPointUpdateWrapper.set("point_type", 2); |
| | | xpPointUpdateWrapper.set("electronic_areaId", null); |
| | | xpPointMapper.update(xpPoint, xpPointUpdateWrapper); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | return R.ok(); |
| | | } catch (Exception e) { |
| | | log.error("编辑电子围栏失败", e); |
| | | throw new ServiceException("编辑电子围栏失败", I18nKeyConstant.EDIT_ELECTRONIC_ERROR); |
| | | } |
| | | |
| | | return R.ok(); |
| | | } catch (Exception e) { |
| | | log.error("编辑电子围栏失败", e); |
| | | throw new ServiceException("编辑电子围栏失败", I18nKeyConstant.EDIT_ELECTRONIC_ERROR); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 判断点是否在多边形内 |
| | | * |
| | | * @param fencePointsStr 多边形顶点字符串,格式:经度_维度,经度_维度 |
| | | * @param pointLon 待检测点的经度 |
| | | * @param pointLat 待检测点的纬度 |
| | | * @return true表示在多边形内,false表示在多边形外 |
| | | */ |
| | | private boolean isPointInPolygon (String fencePointsStr,double pointLon, double pointLat){ |
| | | if (fencePointsStr == null || fencePointsStr.trim().isEmpty()) { |
| | | return false; |
| | | } |
| | | |
| | | // 解析多边形顶点 |
| | | String[] pointPairs = fencePointsStr.split(","); |
| | | List<double[]> polygonVertices = new ArrayList<>(); |
| | | |
| | | for (String pointPair : pointPairs) { |
| | | String[] lngLat = pointPair.trim().split("_"); |
| | | if (lngLat.length >= 2) { |
| | | try { |
| | | double longitude = Double.parseDouble(lngLat[0]); |
| | | double latitude = Double.parseDouble(lngLat[1]); |
| | | polygonVertices.add(new double[]{longitude, latitude}); |
| | | } catch (NumberFormatException e) { |
| | | log.error("解析多边形顶点坐标失败: {}", pointPair, e); |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (polygonVertices.size() < 3) { |
| | | return false; // 至少需要3个点才能构成多边形 |
| | | } |
| | | |
| | | return isPointInPolygon(polygonVertices, pointLon, pointLat); |
| | | } |
| | | |
| | | /** |
| | | * 使用射线法判断点是否在多边形内 |
| | | * |
| | | * @param polygonVertices 多边形顶点列表 |
| | | * @param pointLon 待检测点的经度 |
| | | * @param pointLat 待检测点的纬度 |
| | | * @return true表示在多边形内,false表示在多边形外 |
| | | */ |
| | | private boolean isPointInPolygon (List < double[]>polygonVertices,double pointLon, double pointLat){ |
| | | int n = polygonVertices.size(); |
| | | boolean inside = false; |
| | | |
| | | // 射线法判断点是否在多边形内 |
| | | double x = pointLon, y = pointLat; |
| | | |
| | | for (int i = 0, j = n - 1; i < n; j = i++) { |
| | | double xi = polygonVertices.get(i)[0], yi = polygonVertices.get(i)[1]; |
| | | double xj = polygonVertices.get(j)[0], yj = polygonVertices.get(j)[1]; |
| | | |
| | | // 判断当前边是否与水平射线相交 |
| | | boolean intersect = ((yi > y) != (yj > y)) && |
| | | (x < (xj - xi) * (y - yi) / (yj - yi) + xi); |
| | | |
| | | if (intersect) { |
| | | inside = !inside; |
| | | } |
| | | } |
| | | |
| | | return inside; |
| | | } |
| | | |
| | | /** |
| | | * 将围栏点字符串转换为GeoJsonPolygon |
| | | * 格式:经度_维度,经度_维度 |
| | | */ |
| | | private GeoJsonPolygon convertToGeoJsonPolygon (String fencePointsStr){ |
| | | if (fencePointsStr == null || fencePointsStr.trim().isEmpty()) { |
| | | return null; |
| | | } |
| | | |
| | | // 分割多个点对 |
| | | String[] pointPairs = fencePointsStr.split(","); |
| | | List<Point> points = new ArrayList<>(); |
| | | |
| | | for (String pointPair : pointPairs) { |
| | | String[] lngLat = pointPair.trim().split("_"); |
| | | if (lngLat.length >= 2) { |
| | | try { |
| | | double longitude = Double.parseDouble(lngLat[0]); |
| | | double latitude = Double.parseDouble(lngLat[1]); |
| | | points.add(new Point(longitude, latitude)); // Point 构造函数是 (x, y) -> (longitude, latitude) |
| | | } catch (NumberFormatException e) { |
| | | log.error("解析经纬度坐标失败: {}", pointPair, e); |
| | | throw new IllegalArgumentException("经纬度格式错误: " + pointPair); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 如果没有足够的点构成多边形,至少需要3个点 |
| | | if (points.size() < 3) { |
| | | throw new IllegalArgumentException("围栏点数量不足,至少需要3个点构成多边形"); |
| | | } |
| | | |
| | | // 确保多边形是闭合的(如果最后一个点不等于第一个点,则添加第一个点) |
| | | if (!points.get(0).equals(points.get(points.size() - 1))) { |
| | | points.add(points.get(0)); // 添加第一个点作为最后一个点,闭合多边形 |
| | | } |
| | | |
| | | return new GeoJsonPolygon(points); |
| | | } |
| | | |
| | | /** |
| | | * 检查新添加的区域之间是否有重叠 |
| | | */ |
| | | private boolean hasOverlapWithinNewAreas (List < XpElectronicFenceArea > newAreas) { |
| | | for (int i = 0; i < newAreas.size(); i++) { |
| | | XpElectronicFenceArea area1 = newAreas.get(i); |
| | | if (area1.getAreaType() != 1) continue; // 只检查运营区域 |
| | | |
| | | for (int j = i + 1; j < newAreas.size(); j++) { |
| | | XpElectronicFenceArea area2 = newAreas.get(j); |
| | | if (area2.getAreaType() == 1) { |
| | | if (polygonOverlapService.checkPolygonOverlap( |
| | | area1.getFencePoints(), |
| | | area2.getFencePoints())) { |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | /** |
| | | * 判断点是否在多边形内 |
| | | * |
| | | * @param fencePointsStr 多边形顶点字符串,格式:经度_维度,经度_维度 |
| | | * @param pointLon 待检测点的经度 |
| | | * @param pointLat 待检测点的纬度 |
| | | * @return true表示在多边形内,false表示在多边形外 |
| | | */ |
| | | private boolean isPointInPolygon(String fencePointsStr, double pointLon, double pointLat) { |
| | | if (fencePointsStr == null || fencePointsStr.trim().isEmpty()) { |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * @return |
| | | */ |
| | | @Override |
| | | public List<XpElectronicFence> getAvailableList () { |
| | | return lambdaQuery().eq(XpElectronicFence::getStatus, 2).list(); //查询已启用的围栏 |
| | | // 解析多边形顶点 |
| | | String[] pointPairs = fencePointsStr.split(","); |
| | | List<double[]> polygonVertices = new ArrayList<>(); |
| | | |
| | | for (String pointPair : pointPairs) { |
| | | String[] lngLat = pointPair.trim().split("_"); |
| | | if (lngLat.length >= 2) { |
| | | try { |
| | | double longitude = Double.parseDouble(lngLat[0]); |
| | | double latitude = Double.parseDouble(lngLat[1]); |
| | | polygonVertices.add(new double[]{longitude, latitude}); |
| | | } catch (NumberFormatException e) { |
| | | log.error("解析多边形顶点坐标失败: {}", pointPair, e); |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (polygonVertices.size() < 3) { |
| | | return false; // 至少需要3个点才能构成多边形 |
| | | } |
| | | |
| | | return isPointInPolygon(polygonVertices, pointLon, pointLat); |
| | | } |
| | | |
| | | /** |
| | | * 使用射线法判断点是否在多边形内 |
| | | * |
| | | * @param polygonVertices 多边形顶点列表 |
| | | * @param pointLon 待检测点的经度 |
| | | * @param pointLat 待检测点的纬度 |
| | | * @return true表示在多边形内,false表示在多边形外 |
| | | */ |
| | | private boolean isPointInPolygon(List<double[]> polygonVertices, double pointLon, double pointLat) { |
| | | int n = polygonVertices.size(); |
| | | boolean inside = false; |
| | | |
| | | // 射线法判断点是否在多边形内 |
| | | double x = pointLon, y = pointLat; |
| | | |
| | | for (int i = 0, j = n - 1; i < n; j = i++) { |
| | | double xi = polygonVertices.get(i)[0], yi = polygonVertices.get(i)[1]; |
| | | double xj = polygonVertices.get(j)[0], yj = polygonVertices.get(j)[1]; |
| | | |
| | | // 判断当前边是否与水平射线相交 |
| | | boolean intersect = ((yi > y) != (yj > y)) && |
| | | (x < (xj - xi) * (y - yi) / (yj - yi) + xi); |
| | | |
| | | if (intersect) { |
| | | inside = !inside; |
| | | } |
| | | } |
| | | |
| | | return inside; |
| | | } |
| | | |
| | | /** |
| | | * 将围栏点字符串转换为GeoJsonPolygon |
| | | * 格式:经度_维度,经度_维度 |
| | | */ |
| | | private GeoJsonPolygon convertToGeoJsonPolygon(String fencePointsStr) { |
| | | if (fencePointsStr == null || fencePointsStr.trim().isEmpty()) { |
| | | return null; |
| | | } |
| | | |
| | | // 分割多个点对 |
| | | String[] pointPairs = fencePointsStr.split(","); |
| | | List<Point> points = new ArrayList<>(); |
| | | |
| | | for (String pointPair : pointPairs) { |
| | | String[] lngLat = pointPair.trim().split("_"); |
| | | if (lngLat.length >= 2) { |
| | | try { |
| | | double longitude = Double.parseDouble(lngLat[0]); |
| | | double latitude = Double.parseDouble(lngLat[1]); |
| | | points.add(new Point(longitude, latitude)); // Point 构造函数是 (x, y) -> (longitude, latitude) |
| | | } catch (NumberFormatException e) { |
| | | log.error("解析经纬度坐标失败: {}", pointPair, e); |
| | | throw new IllegalArgumentException("经纬度格式错误: " + pointPair); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 如果没有足够的点构成多边形,至少需要3个点 |
| | | if (points.size() < 3) { |
| | | throw new IllegalArgumentException("围栏点数量不足,至少需要3个点构成多边形"); |
| | | } |
| | | |
| | | // 确保多边形是闭合的(如果最后一个点不等于第一个点,则添加第一个点) |
| | | if (!points.get(0).equals(points.get(points.size() - 1))) { |
| | | points.add(points.get(0)); // 添加第一个点作为最后一个点,闭合多边形 |
| | | } |
| | | |
| | | return new GeoJsonPolygon(points); |
| | | } |
| | | |
| | | /** |
| | | * 检查新添加的区域之间是否有重叠 |
| | | */ |
| | | private boolean hasOverlapWithinNewAreas(List<XpElectronicFenceArea> newAreas) { |
| | | for (int i = 0; i < newAreas.size(); i++) { |
| | | XpElectronicFenceArea area1 = newAreas.get(i); |
| | | if (area1.getAreaType() != 1) continue; // 只检查运营区域 |
| | | |
| | | for (int j = i + 1; j < newAreas.size(); j++) { |
| | | XpElectronicFenceArea area2 = newAreas.get(j); |
| | | if (area2.getAreaType() == 1) { |
| | | if (polygonOverlapService.checkPolygonOverlap( |
| | | area1.getFencePoints(), |
| | | area2.getFencePoints())) { |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * @return |
| | | */ |
| | | @Override |
| | | public List<XpElectronicFence> getAvailableList() { |
| | | return lambdaQuery().eq(XpElectronicFence::getStatus, 2).list(); //查询已启用的围栏 |
| | | } |
| | | } |