Browse Source

Merge remote-tracking branch 'origin/dev' into dev

pull/7/head
吴远 2 weeks ago
parent
commit
9e90f69f79
  1. 2
      dk-api/api-system/src/main/java/org/dromara/system/api/RemoteDeptService.java
  2. 8
      dk-modules/business/src/main/java/org/dromara/business/controller/BusinessLayerController.java
  3. 3
      dk-modules/business/src/main/java/org/dromara/business/domain/vo/BusinessLayerVo.java
  4. 25
      dk-modules/business/src/main/java/org/dromara/business/service/impl/BusinessLayerServiceImpl.java
  5. 36
      dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/LiveStreamServiceImpl.java
  6. 22
      dk-modules/system/src/main/java/org/dromara/system/controller/system/SysDepartBoundaryController.java
  7. 11
      dk-modules/system/src/main/java/org/dromara/system/domain/SysDepartBoundary.java
  8. 25
      dk-modules/system/src/main/java/org/dromara/system/domain/kmz/KmzResult.java
  9. 15
      dk-modules/system/src/main/java/org/dromara/system/domain/kmz/Placemark.java
  10. 7
      dk-modules/system/src/main/java/org/dromara/system/dubbo/RemoteDeptServiceImpl.java
  11. 1
      dk-modules/system/src/main/java/org/dromara/system/mapper/SysDepartBoundaryMapper.java
  12. 2
      dk-modules/system/src/main/java/org/dromara/system/mapper/SysDeptMapper.java
  13. 4
      dk-modules/system/src/main/java/org/dromara/system/service/ISysDepartBoundaryService.java
  14. 2
      dk-modules/system/src/main/java/org/dromara/system/service/ISysDeptService.java
  15. 122
      dk-modules/system/src/main/java/org/dromara/system/service/impl/SysDepartBoundaryServiceImpl.java
  16. 5
      dk-modules/system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java
  17. 140
      dk-modules/system/src/main/java/org/dromara/system/utils/KmlParserUtil.java
  18. 262
      dk-modules/system/src/main/java/org/dromara/system/utils/KmzParserUtil.java
  19. 11
      dk-modules/system/src/main/java/org/dromara/system/utils/OvkmzParser.java
  20. 53
      dk-modules/system/src/main/java/org/dromara/system/utils/ShpAnalysisUtil.java
  21. 88
      dk-modules/system/src/main/resources/mapper/system/SysDepartBoundaryMapper.xml
  22. 30
      dk-modules/system/src/main/resources/mapper/system/SysDeptMapper.xml

2
dk-api/api-system/src/main/java/org/dromara/system/api/RemoteDeptService.java

@ -29,4 +29,6 @@ public interface RemoteDeptService {
List<RemoteDeptVo> selectListByParentId(String deptId); List<RemoteDeptVo> selectListByParentId(String deptId);
RemoteDeptVo getByParentId(String deptId); RemoteDeptVo getByParentId(String deptId);
List<RemoteDeptVo> listTreeDeptByChild(Long deptId);
} }

8
dk-modules/business/src/main/java/org/dromara/business/controller/BusinessLayerController.java

@ -38,7 +38,7 @@ public class BusinessLayerController extends BaseController {
* 图层模块列表 * 图层模块列表
*/ */
@Operation(summary ="图层模块列表",description = "图层模块列表") @Operation(summary ="图层模块列表",description = "图层模块列表")
@SaCheckPermission("business:layer:list") // @SaCheckPermission("business:layer:list")
@GetMapping("/list") @GetMapping("/list")
public R<TableDataInfo<BusinessLayerVo>> list(BusinessLayerBo bo, PageQuery pageQuery) { public R<TableDataInfo<BusinessLayerVo>> list(BusinessLayerBo bo, PageQuery pageQuery) {
return R.ok(businessLayerService.queryPageList(bo, pageQuery)); return R.ok(businessLayerService.queryPageList(bo, pageQuery));
@ -54,7 +54,7 @@ public class BusinessLayerController extends BaseController {
* 图层新增 * 图层新增
*/ */
@Operation(summary ="图层新增",description = "图层新增") @Operation(summary ="图层新增",description = "图层新增")
@SaCheckPermission("business:layer:add") // @SaCheckPermission("business:layer:add")
@Log(title = "图层新增", businessType = BusinessType.INSERT) @Log(title = "图层新增", businessType = BusinessType.INSERT)
@RepeatSubmit() @RepeatSubmit()
@PostMapping() @PostMapping()
@ -65,7 +65,7 @@ public class BusinessLayerController extends BaseController {
/** /**
* 图层修改 * 图层修改
*/ */
@SaCheckPermission("business:layer:edit") // @SaCheckPermission("business:layer:edit")
@Operation(summary ="图层修改",description = "图层修改") @Operation(summary ="图层修改",description = "图层修改")
@Log(title = "图层修改", businessType = BusinessType.UPDATE) @Log(title = "图层修改", businessType = BusinessType.UPDATE)
@RepeatSubmit() @RepeatSubmit()
@ -79,7 +79,7 @@ public class BusinessLayerController extends BaseController {
* *
* @param id 主键 * @param id 主键
*/ */
@SaCheckPermission("business:task:remove") // @SaCheckPermission("business:task:remove")
@Operation(summary ="图层删除",description = "图层删除") @Operation(summary ="图层删除",description = "图层删除")
@Log(title = "图层删除", businessType = BusinessType.DELETE) @Log(title = "图层删除", businessType = BusinessType.DELETE)
@GetMapping("/delete") @GetMapping("/delete")

3
dk-modules/business/src/main/java/org/dromara/business/domain/vo/BusinessLayerVo.java

@ -70,4 +70,7 @@ public class BusinessLayerVo {
private List<BusinessLayerVo> children; private List<BusinessLayerVo> children;
//用于前端回显
private List<Long> deptIdList;
} }

25
dk-modules/business/src/main/java/org/dromara/business/service/impl/BusinessLayerServiceImpl.java

@ -20,10 +20,7 @@ import org.dromara.system.api.domain.vo.RemoteDeptVo;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j @Slf4j
@ -33,7 +30,7 @@ public class BusinessLayerServiceImpl implements IBusinessLayerService {
private final BusinessLayerMapper baseMapper; private final BusinessLayerMapper baseMapper;
@DubboReference @DubboReference(timeout = 30000)
RemoteDeptService remoteDeptService; RemoteDeptService remoteDeptService;
@Override @Override
@ -41,10 +38,16 @@ public class BusinessLayerServiceImpl implements IBusinessLayerService {
Page<BusinessLayerVo> result = baseMapper.queryPageList(pageQuery.build(), bo); Page<BusinessLayerVo> result = baseMapper.queryPageList(pageQuery.build(), bo);
result.getRecords().forEach(businessLayerVo -> { result.getRecords().forEach(businessLayerVo -> {
List<RemoteDeptVo> deptList = remoteDeptService.listTreeDeptByChild(businessLayerVo.getDeptId());
LinkedList<Long> deptIdList = new LinkedList<>();
deptList.forEach(deptVo -> {
deptIdList.add(deptVo.getDeptId());
});
List<BusinessLayerVo> layerVoList = baseMapper.selectInfoByParent(businessLayerVo.getId()); List<BusinessLayerVo> layerVoList = baseMapper.selectInfoByParent(businessLayerVo.getId());
businessLayerVo.setChildren(buildTree(layerVoList,businessLayerVo.getId())); businessLayerVo.setChildren(buildTree(layerVoList,businessLayerVo.getId()));
businessLayerVo.setDeptIdList(deptIdList);
}); });
return TableDataInfo.build(result); return TableDataInfo.build(result);
@ -101,7 +104,7 @@ public class BusinessLayerServiceImpl implements IBusinessLayerService {
* @param allNodes * @param allNodes
* @return * @return
*/ */
public static List<BusinessLayerVo> buildTree(List<BusinessLayerVo> allNodes, Long parentId) { public List<BusinessLayerVo> buildTree(List<BusinessLayerVo> allNodes, Long parentId) {
// 创建一个Map来存储所有节点,键为ID,值为节点 // 创建一个Map来存储所有节点,键为ID,值为节点
Map<Long, BusinessLayerVo> nodeMap = new HashMap<>(); Map<Long, BusinessLayerVo> nodeMap = new HashMap<>();
for (BusinessLayerVo node : allNodes) { for (BusinessLayerVo node : allNodes) {
@ -113,6 +116,14 @@ public class BusinessLayerServiceImpl implements IBusinessLayerService {
// 遍历所有节点,将子节点添加到父节点的 children 列表中 // 遍历所有节点,将子节点添加到父节点的 children 列表中
for (BusinessLayerVo node : allNodes) { for (BusinessLayerVo node : allNodes) {
List<RemoteDeptVo> deptList = remoteDeptService.listTreeDeptByChild(node.getDeptId());
LinkedList<Long> deptIdList = new LinkedList<>();
deptList.forEach(deptVo -> {
deptIdList.add(deptVo.getDeptId());
});
node.setDeptIdList(deptIdList);
if (node.getParentId().equals(parentId)) { if (node.getParentId().equals(parentId)) {
rootNodes.add(node); // 当前节点的 parentId 与传入的 parentId 匹配,作为根节点 rootNodes.add(node); // 当前节点的 parentId 与传入的 parentId 匹配,作为根节点
} else { } else {

36
dk-modules/sample/src/main/java/org/dromara/sample/manage/service/impl/LiveStreamServiceImpl.java

@ -1,29 +1,27 @@
package org.dromara.sample.manage.service.impl; package org.dromara.sample.manage.service.impl;
import cn.hutool.core.convert.Convert; import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils; import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.common.rocketmq.producer.MessageProducerUtil;
import org.dromara.common.sdk.cloudapi.device.DeviceDomainEnum; import org.dromara.common.sdk.cloudapi.device.DeviceDomainEnum;
import org.dromara.common.sdk.cloudapi.device.VideoId; import org.dromara.common.sdk.cloudapi.device.VideoId;
import org.dromara.common.sdk.cloudapi.livestream.*; import org.dromara.common.sdk.cloudapi.livestream.*;
import org.dromara.common.sdk.cloudapi.livestream.api.AbstractLivestreamService; import org.dromara.common.sdk.cloudapi.livestream.api.AbstractLivestreamService;
import org.dromara.common.sdk.cloudapi.wayline.FlighttaskProgress;
import org.dromara.common.sdk.common.HttpResultResponse; import org.dromara.common.sdk.common.HttpResultResponse;
import org.dromara.common.sdk.common.SDKManager; import org.dromara.common.sdk.common.SDKManager;
import org.dromara.common.sdk.mqtt.CommonTopicRequest;
import org.dromara.common.sdk.mqtt.MqttGatewayPublish; import org.dromara.common.sdk.mqtt.MqttGatewayPublish;
import org.dromara.common.sdk.mqtt.services.ServicesReplyData; import org.dromara.common.sdk.mqtt.services.ServicesReplyData;
import org.dromara.common.sdk.mqtt.services.TopicServicesResponse; import org.dromara.common.sdk.mqtt.services.TopicServicesResponse;
import org.dromara.sample.component.mqtt.model.EventsReceiver;
import org.dromara.sample.feign.RemoteSystemFeign; import org.dromara.sample.feign.RemoteSystemFeign;
import org.dromara.sample.manage.model.dto.*; import org.dromara.sample.manage.model.dto.*;
import org.dromara.sample.manage.model.entity.DeviceEntity;
import org.dromara.sample.manage.model.param.DeviceQueryParam; import org.dromara.sample.manage.model.param.DeviceQueryParam;
import org.dromara.sample.manage.service.*; import org.dromara.sample.manage.service.*;
import org.dromara.sample.wayline.model.dto.WaylineJobDTO;
import org.dromara.sample.wayline.service.IWaylineJobService; import org.dromara.sample.wayline.service.IWaylineJobService;
import org.dromara.sample.wayline.service.IWaylineRedisService; import org.dromara.sample.wayline.service.IWaylineRedisService;
import org.dromara.system.api.RemoteDictService;
import org.dromara.system.api.domain.vo.RemoteDictDataVo;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -70,6 +68,9 @@ public class LiveStreamServiceImpl implements ILiveStreamService {
@Resource @Resource
private RemoteSystemFeign remoteSystemFeign; private RemoteSystemFeign remoteSystemFeign;
@DubboReference
private RemoteDictService remoteDictService;
@Override @Override
public List<CapacityDeviceDTO> getLiveCapacity(String workspaceId) { public List<CapacityDeviceDTO> getLiveCapacity(String workspaceId) {
@ -290,6 +291,25 @@ public class LiveStreamServiceImpl implements ILiveStreamService {
return agoraUrl.setSn(videoId.getDroneSn()); return agoraUrl.setSn(videoId.getDroneSn());
case RTMP: case RTMP:
LivestreamRtmpUrl rtmpUrl = (LivestreamRtmpUrl) url.clone(); LivestreamRtmpUrl rtmpUrl = (LivestreamRtmpUrl) url.clone();
//南通设备指定固定rtmpl路径 功能关闭
/* List<RemoteDictDataVo> dictDataVoList = remoteDictService.selectDictDataByType("drone_stream_rtmp");
for (RemoteDictDataVo remoteDictDataVo : dictDataVoList) {
if(JSONUtil.isTypeJSON(remoteDictDataVo.getRemark())){
JSONArray jsonArr = JSONUtil.parseArray(remoteDictDataVo.getRemark());
for (Object obj : jsonArr) {
JSONObject entries = new JSONObject(obj);
String droneSnStr = entries.getStr("droneSn");
String rtmpUrlStr = entries.getStr("rtmpUrl");
if(videoId.getDroneSn().equals(droneSnStr) ){
rtmpUrl.setUrl(rtmpUrlStr);
}
}
}
}*/
// if(videoId.getDroneSn().equals("7CTXN2T00B07C5") || videoId.getDroneSn().equals("1581F6Q8X24CC00G02JB")){
// rtmpUrl.setUrl("rtmp://106.13.57.190/live/livesteam/");
// }
return rtmpUrl.setUrl(rtmpUrl.getUrl() + videoId.getDroneSn() + "-" + videoId.getPayloadIndex().toString()); return rtmpUrl.setUrl(rtmpUrl.getUrl() + videoId.getDroneSn() + "-" + videoId.getPayloadIndex().toString());
case GB28181: case GB28181:
String random = String.valueOf(Math.abs(videoId.getDroneSn().hashCode()) % 1000); String random = String.valueOf(Math.abs(videoId.getDroneSn().hashCode()) % 1000);

22
dk-modules/system/src/main/java/org/dromara/system/controller/system/SysDepartBoundaryController.java

@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController; import org.dromara.common.web.core.BaseController;
@ -58,15 +59,30 @@ public class SysDepartBoundaryController extends BaseController {
* 解析shp文件 * 解析shp文件
* @return * @return
*/ */
@RepeatSubmit()
@Operation(summary ="新增部门区域",description = "新增部门区域(areaType: 0:市级 1:区级(县) 2:镇级(街道) 3:村级)") @Operation(summary ="新增部门区域",description = "新增部门区域(areaType: 0:市级 1:区级(县) 2:镇级(街道) 3:村级)")
@RequestMapping(value = "/upload", method = RequestMethod.POST) @RequestMapping(value = "/{areaType}/{parentId}/upload", method = RequestMethod.POST)
public R<Void> uploadShpFile(@RequestParam("file") MultipartFile file, public R<Void> uploadShpFile(@RequestParam("file") MultipartFile file,
@RequestParam("areaType") Integer areaType, @PathVariable Integer areaType,
@RequestParam("parentId") Long parentId) { @PathVariable Long parentId) {
return toAjax(departBoundaryService.uploadShpFile(file,areaType,parentId)); return toAjax(departBoundaryService.uploadShpFile(file,areaType,parentId));
} }
/**
* 根据经纬度查询部门信息
* @param latlng
* @return
*/
@Operation(summary ="根据经纬度查询部门信息",description = "根据经纬度查询部门信息")
@GetMapping(value = "/location/list")
public R<List<SysDepartBoundary>> listDepartBoundaryByLngAndLat(@RequestParam("lat") Double lat,
@RequestParam("lng") Double lng) {
List<SysDepartBoundary> listJson = departBoundaryService.listDepartBoundaryByLngAndLat(lng,lat);
return R.ok(listJson);
}
/** /**
* 通过id删除 * 通过id删除
* *

11
dk-modules/system/src/main/java/org/dromara/system/domain/SysDepartBoundary.java

@ -1,6 +1,7 @@
package org.dromara.system.domain; package org.dromara.system.domain;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
@ -23,7 +24,7 @@ public class SysDepartBoundary extends BaseEntity {
/**ID*/ /**ID*/
@TableId(type = IdType.AUTO) @TableId(type = IdType.AUTO)
private String id; private Long id;
/**机构ID*/ /**机构ID*/
private Long deptId; private Long deptId;
@ -42,7 +43,15 @@ public class SysDepartBoundary extends BaseEntity {
*/ */
private Integer areaType; private Integer areaType;
/**
* 父类id
*/
private Long parentId;
/**删除状态(0,正常,1已删除)*/ /**删除状态(0,正常,1已删除)*/
private String delFlag; private String delFlag;
@TableField(exist = false)
private List<Long> deptIds;
} }

25
dk-modules/system/src/main/java/org/dromara/system/domain/kmz/KmzResult.java

@ -0,0 +1,25 @@
package org.dromara.system.domain.kmz;
import lombok.Data;
import java.util.Map;
@Data
public class KmzResult {
private String name;
private Map<String, String> attributes;
private String wkt;
public KmzResult(String name, Map<String, String> attributes, String wkt) {
this.name = name;
this.attributes = attributes;
this.wkt = wkt;
}
public KmzResult() {
}
}

15
dk-modules/system/src/main/java/org/dromara/system/domain/kmz/Placemark.java

@ -0,0 +1,15 @@
package org.dromara.system.domain.kmz;
import lombok.Data;
import java.util.Map;
@Data
public class Placemark {
private String name;
private String coordinates;
private Map<String, String> attributes;
}

7
dk-modules/system/src/main/java/org/dromara/system/dubbo/RemoteDeptServiceImpl.java

@ -66,4 +66,11 @@ public class RemoteDeptServiceImpl implements RemoteDeptService {
SysDeptVo sysDeptVo = sysDeptService.getByParentId(deptId); SysDeptVo sysDeptVo = sysDeptService.getByParentId(deptId);
return BeanUtil.copyProperties(sysDeptVo, RemoteDeptVo.class); return BeanUtil.copyProperties(sysDeptVo, RemoteDeptVo.class);
} }
@Override
public List<RemoteDeptVo> listTreeDeptByChild(Long deptId) {
List<SysDeptVo> deptVoList = sysDeptService.listTreeDeptByChild(deptId);
return BeanUtil.copyToList(deptVoList, RemoteDeptVo.class);
}
} }

1
dk-modules/system/src/main/java/org/dromara/system/mapper/SysDepartBoundaryMapper.java

@ -26,4 +26,5 @@ public interface SysDepartBoundaryMapper extends BaseMapper<SysDepartBoundary> {
String listJson(@Param("deptId") String deptId); String listJson(@Param("deptId") String deptId);
List<SysDepartBoundary> listDepartBoundaryByLngAndLat(@Param("lng") Double lng,@Param("lat") Double lat);
} }

2
dk-modules/system/src/main/java/org/dromara/system/mapper/SysDeptMapper.java

@ -74,4 +74,6 @@ public interface SysDeptMapper extends BaseMapperPlus<SysDept, SysDeptVo> {
List<Map<String,Object>> getNamePathList(@Param("deptId") Long deptId); List<Map<String,Object>> getNamePathList(@Param("deptId") Long deptId);
List<SysDeptVo> listTreeDept(@Param("deptId") Long deptId, @Param("tbPrefix") ProjectTablePrefixConfig tbPrefix); List<SysDeptVo> listTreeDept(@Param("deptId") Long deptId, @Param("tbPrefix") ProjectTablePrefixConfig tbPrefix);
List<SysDeptVo> listTreeDeptByChild(@Param("deptId") Long deptId);
} }

4
dk-modules/system/src/main/java/org/dromara/system/service/ISysDepartBoundaryService.java

@ -22,11 +22,13 @@ public interface ISysDepartBoundaryService extends IService<SysDepartBoundary>{
boolean uploadShpFile(MultipartFile file,Integer areaType,Long parentId); boolean uploadShpFile(MultipartFile file,Integer areaType,Long parentId);
boolean deleteDepartBoundary(String id); boolean deleteDepartBoundary(String deptId);
boolean updateDepartBoundary(SysDepartBoundary departBoundary); boolean updateDepartBoundary(SysDepartBoundary departBoundary);
boolean addDepartBoundary(SysDepartBoundary departBoundary); boolean addDepartBoundary(SysDepartBoundary departBoundary);
List<SysDepartBoundaryBo> listJson(SysDepartBoundary departBoundary); List<SysDepartBoundaryBo> listJson(SysDepartBoundary departBoundary);
List<SysDepartBoundary> listDepartBoundaryByLngAndLat(Double lng, Double lat);
} }

2
dk-modules/system/src/main/java/org/dromara/system/service/ISysDeptService.java

@ -160,4 +160,6 @@ public interface ISysDeptService {
List<SysDeptVo> listTreeDept(Long deptId); List<SysDeptVo> listTreeDept(Long deptId);
SysDept addBoundaryDept(SysDeptBo sysDeptBo); SysDept addBoundaryDept(SysDeptBo sysDeptBo);
List<SysDeptVo> listTreeDeptByChild(Long deptId);
} }

122
dk-modules/system/src/main/java/org/dromara/system/service/impl/SysDepartBoundaryServiceImpl.java

@ -1,6 +1,7 @@
package org.dromara.system.service.impl; package org.dromara.system.service.impl;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -13,12 +14,15 @@ import org.dromara.system.domain.SysGeospatialVectors;
import org.dromara.system.domain.SysVectorDict; import org.dromara.system.domain.SysVectorDict;
import org.dromara.system.domain.bo.SysDepartBoundaryBo; import org.dromara.system.domain.bo.SysDepartBoundaryBo;
import org.dromara.system.domain.bo.SysDeptBo; import org.dromara.system.domain.bo.SysDeptBo;
import org.dromara.system.domain.kmz.KmzResult;
import org.dromara.system.domain.vo.SysDeptVo; import org.dromara.system.domain.vo.SysDeptVo;
import org.dromara.system.mapper.SysDepartBoundaryMapper; import org.dromara.system.mapper.SysDepartBoundaryMapper;
import org.dromara.system.service.ISysDepartBoundaryService; import org.dromara.system.service.ISysDepartBoundaryService;
import org.dromara.system.service.ISysDeptService; import org.dromara.system.service.ISysDeptService;
import org.dromara.system.service.ISysVectorDictService; import org.dromara.system.service.ISysVectorDictService;
import org.dromara.system.utils.BatchProcessorUtil; import org.dromara.system.utils.BatchProcessorUtil;
import org.dromara.system.utils.KmlParserUtil;
import org.dromara.system.utils.KmzParserUtil;
import org.dromara.system.utils.ShpAnalysisUtil; import org.dromara.system.utils.ShpAnalysisUtil;
import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
@ -30,10 +34,7 @@ import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.*;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -50,6 +51,13 @@ public class SysDepartBoundaryServiceImpl extends ServiceImpl<SysDepartBoundaryM
@Override @Override
public TableDataInfo<SysDepartBoundary> listSysDepartBoundary(PageQuery pageQuery, SysDepartBoundary departBoundary) { public TableDataInfo<SysDepartBoundary> listSysDepartBoundary(PageQuery pageQuery, SysDepartBoundary departBoundary) {
if (ObjectUtil.isNotEmpty(departBoundary.getDeptId())){
List<SysDeptVo> deptList = deptService.listTreeDept(departBoundary.getDeptId());
departBoundary.setDeptIds(deptList.stream().map(SysDeptVo::getDeptId).distinct().toList());
}
Page<SysDepartBoundary> page = baseMapper.listSysDepartBoundary(pageQuery.build(),departBoundary); Page<SysDepartBoundary> page = baseMapper.listSysDepartBoundary(pageQuery.build(),departBoundary);
return TableDataInfo.build(page); return TableDataInfo.build(page);
@ -70,11 +78,14 @@ public class SysDepartBoundaryServiceImpl extends ServiceImpl<SysDepartBoundaryM
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public boolean uploadShpFile(MultipartFile file,Integer areaType,Long parentId) { public boolean uploadShpFile(MultipartFile file,Integer areaType,Long parentId) {
try { try {
List<SysGeospatialVectors> geospatialVectorsList = buildGeospatialVector(file); List<SysGeospatialVectors> geospatialVectorsList = buildGeospatialVector(file);
//6、生成新的对象集合存储数据表中 //6、生成新的对象集合存储数据表中
List<SysDepartBoundary> boundaryList = buildBusinessDepartBoundary(geospatialVectorsList,areaType,parentId); List<SysDepartBoundary> boundaryList = buildBusinessDepartBoundary(geospatialVectorsList,areaType,parentId);
boundaryList = boundaryList.stream().filter(p-> ObjectUtil.isNotEmpty(p.getBoundary())).toList();
// 分批处理 // 分批处理
int startIndex = 0; // 从第 0 条开始 int startIndex = 0; // 从第 0 条开始
int batchSize = 2000; // 每批处理 2000 条 int batchSize = 2000; // 每批处理 2000 条
@ -97,10 +108,35 @@ public class SysDepartBoundaryServiceImpl extends ServiceImpl<SysDepartBoundaryM
private List<SysGeospatialVectors> buildGeospatialVector(MultipartFile file){ private List<SysGeospatialVectors> buildGeospatialVector(MultipartFile file){
List<SysGeospatialVectors> geospatialVectorsList = new ArrayList<>(); List<SysGeospatialVectors> geospatialVectorsList = new ArrayList<>();
try { try {
List<Map<String, String>> mapList = new ArrayList<>();
//1、首先调用解析工具拿到解析的字段集合 //1、首先调用解析工具拿到解析的字段集合
InputStream inputStream = file.getInputStream(); if (file.getOriginalFilename().endsWith(".zip")) {
List<Map<String, String>> mapList = ShpAnalysisUtil.analysisShpFile(inputStream);
mapList = ShpAnalysisUtil.analysisShpFile(file.getInputStream());
} else if (file.getOriginalFilename().endsWith(".kmz") || file.getOriginalFilename().endsWith(".ovkmz")) {
List<KmzResult> kmzResults = KmzParserUtil.parseKmz(file.getInputStream());
List<Map<String, String>> kmzList = new ArrayList<>();
kmzResults.forEach(kmzResult -> {
Map<String, String> map = new HashMap<>();
Map<String, String> attributes = kmzResult.getAttributes();
if (ObjectUtil.isNotEmpty(attributes)) {
map.putAll(attributes);
}
map.put("O_NAME", kmzResult.getName());
map.put("the_geom", kmzResult.getWkt());
kmzList.add(map);
});
mapList = kmzList;
} else if (file.getOriginalFilename().endsWith(".kml") || file.getOriginalFilename().endsWith(".ovkml")) {
mapList = KmlParserUtil.parseKml(file.getInputStream());
}
// 3. 构建字典map // 3. 构建字典map
List<SysVectorDict> fieldsInfoList = vectorDictService.listVectorField(); List<SysVectorDict> fieldsInfoList = vectorDictService.listVectorField();
@ -197,16 +233,31 @@ public class SysDepartBoundaryServiceImpl extends ServiceImpl<SysDepartBoundaryM
return List.of(child,parent); return List.of(child,parent);
} }
/**
* 根据经纬度查询部门信息
* @param lng
* @param lat
* @return
*/
@Override @Override
public boolean deleteDepartBoundary(String id) { public List<SysDepartBoundary> listDepartBoundaryByLngAndLat(Double lng, Double lat) {
SysDepartBoundary departBoundary = this.baseMapper.selectById(id);
return this.baseMapper.listDepartBoundaryByLngAndLat(lng,lat);
}
if (ObjectUtil.isEmpty(departBoundary)) { @Override
public boolean deleteDepartBoundary(String deptId) {
LambdaQueryWrapper<SysDepartBoundary> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SysDepartBoundary::getDeptId,deptId);
List<SysDepartBoundary> sysDepartBoundaries = this.baseMapper.selectList(wrapper);
if (ObjectUtil.isEmpty(sysDepartBoundaries)) {
throw new ServiceException("实体不存在!"); throw new ServiceException("实体不存在!");
} }
return this.baseMapper.deleteById(departBoundary.getId())>0; return this.baseMapper.deleteByIds(sysDepartBoundaries.stream().map(SysDepartBoundary::getId).distinct().toList())>0;
} }
@ -224,11 +275,38 @@ public class SysDepartBoundaryServiceImpl extends ServiceImpl<SysDepartBoundaryM
.collect(Collectors.groupingBy(item -> item.get("deptName").toString())); .collect(Collectors.groupingBy(item -> item.get("deptName").toString()));
geospatialVectorsList.forEach(param->{ geospatialVectorsList.forEach(param->{
SysDepartBoundary businessDepartBoundary = new SysDepartBoundary();
//获取区划名称 //获取区划名称
String divisionName = param.getAdminDivisionName(); String divisionName = param.getAdminDivisionName();
//是集合
if (isCollectionString(param.getLandCategories())){
List<String> geomList = convertStringToList(param.getLandCategories());
geomList.forEach(item->{
SysDepartBoundary businessDepartBoundary = new SysDepartBoundary();
businessDepartBoundary.setBoundary(item);
createBoundary(businessDepartBoundary,namePathMap,divisionName,areaType,parentId);
resultList.add(businessDepartBoundary);
});
}else {
SysDepartBoundary businessDepartBoundary = new SysDepartBoundary();
businessDepartBoundary.setBoundary(param.getLandCategories()); businessDepartBoundary.setBoundary(param.getLandCategories());
createBoundary(businessDepartBoundary,namePathMap,divisionName,areaType,parentId);
resultList.add(businessDepartBoundary);
}
});
return resultList;
}
private void createBoundary(SysDepartBoundary businessDepartBoundary, Map<String, List<Map<String, Object>>> namePathMap, String divisionName, Integer areaType, Long parentId) {
businessDepartBoundary.setParentId(parentId);
//判断是否存在表中,在表中更新部门区域中的部门id信息 //判断是否存在表中,在表中更新部门区域中的部门id信息
if (ObjectUtil.isNotEmpty(namePathMap.get(divisionName))){ if (ObjectUtil.isNotEmpty(namePathMap.get(divisionName))){
Map<String, Object> objectMap = namePathMap.get(divisionName).get(0); Map<String, Object> objectMap = namePathMap.get(divisionName).get(0);
@ -236,12 +314,11 @@ public class SysDepartBoundaryServiceImpl extends ServiceImpl<SysDepartBoundaryM
businessDepartBoundary.setDeptId(Long.valueOf(objectMap.get("deptId") + "")); businessDepartBoundary.setDeptId(Long.valueOf(objectMap.get("deptId") + ""));
businessDepartBoundary.setNamePath(objectMap.get("namePath") + ""); businessDepartBoundary.setNamePath(objectMap.get("namePath") + "");
businessDepartBoundary.setAreaType(areaType); businessDepartBoundary.setAreaType(areaType);
resultList.add(businessDepartBoundary);
}else { }else {
//如果不存在在部门表中则添加 //如果不存在在部门表中则添加
SysDeptBo sysDeptBo = new SysDeptBo(); SysDeptBo sysDeptBo = new SysDeptBo();
sysDeptBo.setParentId(parentId); sysDeptBo.setParentId(parentId);
sysDeptBo.setDeptName(param.getAdminDivisionName()); sysDeptBo.setDeptName(divisionName);
SysDept sysDept = deptService.addBoundaryDept(sysDeptBo); SysDept sysDept = deptService.addBoundaryDept(sysDeptBo);
@ -251,11 +328,24 @@ public class SysDepartBoundaryServiceImpl extends ServiceImpl<SysDepartBoundaryM
businessDepartBoundary.setDeptId(sysDept.getDeptId()); businessDepartBoundary.setDeptId(sysDept.getDeptId());
businessDepartBoundary.setNamePath(deptNamePath.getFirst().get("namePath").toString()); businessDepartBoundary.setNamePath(deptNamePath.getFirst().get("namePath").toString());
businessDepartBoundary.setAreaType(areaType); businessDepartBoundary.setAreaType(areaType);
resultList.add(businessDepartBoundary); }
}
public static List<String> convertStringToList(String str) {
// 去除首尾的 "[" 和 "]"
str = str.substring(1, str.length() - 1);
// 使用逗号分割
String[] items = str.split(", ");
// 返回新的 List
return Arrays.asList(items);
} }
});
return resultList; // 判断字符串是否是集合的字符串形式
public static boolean isCollectionString(String str) {
return str != null && str.startsWith("[") && str.endsWith("]") && str.contains(",");
} }

5
dk-modules/system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java

@ -407,4 +407,9 @@ public class SysDeptServiceImpl implements ISysDeptService {
return dept; return dept;
} }
@Override
public List<SysDeptVo> listTreeDeptByChild(Long deptId) {
return baseMapper.listTreeDeptByChild(deptId); //.getTableCloud()
}
} }

140
dk-modules/system/src/main/java/org/dromara/system/utils/KmlParserUtil.java

@ -0,0 +1,140 @@
package org.dromara.system.utils;
import cn.hutool.core.util.ObjectUtil;
import java.io.*;
import java.util.*;
/**
* KML文件解析器
* KML是Google Earth使用的标记语言格式
*/
public class KmlParserUtil {
/**
* 从KML内容中提取所有Placemark数据
*
* @param kmlContent KML内容
* @return 包含name和coordinates的Map列表
*/
public static List<Map<String, String>> extractPlacemarks(String kmlContent) {
List<Map<String, String>> placemarkList = new ArrayList<>();
int startIndex = 0;
while (true) {
// 查找Placemark开始标签
int startPlacemark = kmlContent.indexOf("<Placemark>", startIndex);
if (startPlacemark == -1) {
break;
}
// 查找Placemark结束标签
int endPlacemark = kmlContent.indexOf("</Placemark>", startPlacemark);
if (endPlacemark == -1) {
break;
}
// 提取当前Placemark的内容
String placemarkContent = kmlContent.substring(startPlacemark, endPlacemark + "</Placemark>".length());
// 提取name
String name = "";
int nameStart = placemarkContent.indexOf("<name>");
int nameEnd = placemarkContent.indexOf("</name>");
if (nameStart != -1 && nameEnd != -1) {
name = placemarkContent.substring(nameStart + "<name>".length(), nameEnd).trim();
}
// 提取coordinates
String coordinates = "";
int coordStart = placemarkContent.indexOf("<coordinates>");
int coordEnd = placemarkContent.indexOf("</coordinates>");
if (coordStart != -1 && coordEnd != -1) {
coordinates = placemarkContent.substring(coordStart + "<coordinates>".length(), coordEnd).trim();
}
//提取<Data name ="name">
if (ObjectUtil.isEmpty(name)){
int dataStart = placemarkContent.indexOf("Data name =\"name\"");
if (dataStart != -1) {
int valueStart = placemarkContent.indexOf("<value>", dataStart);
int valueEnd = placemarkContent.indexOf("</value>", valueStart);
if (valueStart != -1 && valueEnd != -1) {
name = placemarkContent.substring(valueStart + "<value>".length(), valueEnd).trim();
}
}
}
// 创建Map并添加到列表
Map<String, String> placemarkMap = new HashMap<>();
placemarkMap.put("O_NAME", name);
String wkt = convertToWKT(coordinates);
placemarkMap.put("the_geom", wkt);
placemarkList.add(placemarkMap);
// 更新搜索起始位置
startIndex = endPlacemark + "</Placemark>".length();
}
return placemarkList;
}
/**
* 将坐标字符串转换为WKTWell-Known Text格式
*
* @param coordinates 坐标字符串
* @return WKT格式的字符串
*/
public static String convertToWKT(String coordinates) {
if (coordinates == null || coordinates.trim().isEmpty()) {
return "";
}
// 构建WKT格式的多边形
StringBuilder wkt = new StringBuilder("POLYGON((");
String[] coordPairs = coordinates.trim().split("\\s+");
// 处理每个坐标对
for (int i = 0; i < coordPairs.length; i++) {
String[] coords = coordPairs[i].split(",");
if (coords.length >= 2) {
wkt.append(coords[0]).append(" ").append(coords[1]);
if (i < coordPairs.length - 1) {
wkt.append(", ");
}
}
}
wkt.append("))");
StringBuffer polygonSb = new StringBuffer("GEOMETRYCOLLECTION(");
polygonSb.append(wkt);
polygonSb.append(")");
return polygonSb.toString();
}
/**
* 解析KML文件的主方法
*
* @param inputStream KML文件的输入流
* @return 包含name和coordinates的Map列表
* @throws IOException 如果文件读取或处理过程中发生错误
*/
public static List<Map<String, String>> parseKml(InputStream inputStream) throws IOException {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
StringBuilder kmlContent = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
kmlContent.append(line).append("\n");
}
return extractPlacemarks(kmlContent.toString());
}
}
}

262
dk-modules/system/src/main/java/org/dromara/system/utils/KmzParserUtil.java

@ -0,0 +1,262 @@
package org.dromara.system.utils;
import cn.hutool.core.util.ObjectUtil;
import org.dromara.system.domain.kmz.KmzResult;
import org.dromara.system.domain.kmz.Placemark;
import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* KMZ文件解析器
* KMZ是Google Earth使用的压缩格式包含KML文件和其他资源
*/
public class KmzParserUtil {
/**
* 解析KMZ文件的主方法
*
* @param inputStream KMZ文件的路径
* @return 解析结果列表
* @throws IOException 如果文件读取或处理过程中发生错误
*/
public static List<KmzResult> parseKmz(InputStream inputStream) throws IOException {
// 存储解析出的地标信息
List<Placemark> placemarks = new ArrayList<>();
// 存储最终结果
List<KmzResult> results = new ArrayList<>();
// 创建临时目录用于解压KMZ文件
Path tempDir = Files.createTempDirectory("kmz_parser_");
try {
// 将KMZ文件解压到临时目录
extractKmz(inputStream, tempDir.toString());
// 遍历临时目录,查找并解析所有KML文件
Files.walk(tempDir)
.filter(path -> path.toString().endsWith(".kml"))
.forEach(path -> {
try {
String kmlContent = new String(Files.readAllBytes(path));
parseKmlContent(kmlContent, placemarks);
} catch (IOException e) {
e.printStackTrace();
}
});
// 将解析出的地标信息转换为最终结果格式
for (Placemark placemark : placemarks) {
String wkt = convertToWKT(placemark.getCoordinates());
results.add(new KmzResult(placemark.getName(), placemark.getAttributes(), wkt));
}
} finally {
// 清理临时目录
deleteDirectory(tempDir);
}
return results;
}
/**
* 解压KMZ文件到指定目录
*
* @param inputStream KMZ文件路径
* @param outputDir 输出目录
*/
private static void extractKmz(InputStream inputStream, String outputDir) throws IOException {
try (ZipInputStream zis = new ZipInputStream(inputStream)) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
Path outputPath = Paths.get(outputDir, entry.getName());
// 创建必要的父目录
Files.createDirectories(outputPath.getParent());
// 跳过目录条目
if (entry.isDirectory()) {
continue;
}
// 解压文件内容
try (OutputStream out = Files.newOutputStream(outputPath)) {
byte[] buffer = new byte[1024];
int len;
while ((len = zis.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
}
}
}
}
/**
* 递归删除目录及其内容
*
* @param directory 要删除的目录
*/
private static void deleteDirectory(Path directory) throws IOException {
Files.walk(directory)
.sorted(Comparator.reverseOrder())
.forEach(path -> {
try {
Files.delete(path);
} catch (IOException e) {
e.printStackTrace();
}
});
}
/**
* 处理当前Placemark的所有坐标为每个坐标创建新的Placemark对象
*
* @param currentPlacemark 当前Placemark对象
* @param currentCoordinates 当前Placemark的所有坐标
* @param placemarks 存储所有Placemark的列表
*/
private static void processCurrentPlacemarkCoordinates(Placemark currentPlacemark, List<String> currentCoordinates, List<Placemark> placemarks) {
if (currentPlacemark != null && !currentCoordinates.isEmpty()) {
for (String coords : currentCoordinates) {
Placemark newPlacemark = new Placemark();
newPlacemark.setName(currentPlacemark.getName());
if (ObjectUtil.isNotEmpty(currentPlacemark.getAttributes())){
newPlacemark.setAttributes(new HashMap<>(currentPlacemark.getAttributes()));
}
newPlacemark.setCoordinates(coords);
placemarks.add(newPlacemark);
}
}
}
/**
* 解析KML文件内容
*
* @param kmlContent KML文件内容
* @param placemarks 存储解析出的地标信息
*/
private static void parseKmlContent(String kmlContent, List<Placemark> placemarks) {
String[] lines = kmlContent.split("\n");
Placemark currentPlacemark = null;
boolean inDescription = false;
StringBuilder descriptionContent = new StringBuilder();
List<String> currentCoordinates = new ArrayList<>();
// 添加调试日志
System.out.println("开始解析KML内容,总行数: " + lines.length);
for (String line : lines) {
line = line.trim();
if (line.startsWith("<Placemark>")) {
// 处理当前Placemark的所有坐标
processCurrentPlacemarkCoordinates(currentPlacemark, currentCoordinates, placemarks);
currentPlacemark = new Placemark();
currentCoordinates = new ArrayList<>();
System.out.println("发现新的Placemark");
} else if (line.startsWith("<name>")) {
if (currentPlacemark != null) {
String name = line.replace("<name>", "").replace("</name>", "").trim();
currentPlacemark.setName(name);
System.out.println("解析到名称: " + name);
}
} else if (line.startsWith("<description>")) {
inDescription = true;
descriptionContent = new StringBuilder();
System.out.println("开始解析描述");
} else if (line.endsWith("</description>")) {
inDescription = false;
if (currentPlacemark != null) {
String desc = descriptionContent.toString();
System.out.println("描述内容: " + desc);
parseDescription(desc, currentPlacemark);
}
} else if (inDescription) {
descriptionContent.append(line).append("\n");
} else if (line.startsWith("<coordinates>")) {
if (currentPlacemark != null) {
String coords = line.replace("<coordinates>", "").replace("</coordinates>", "").trim();
currentCoordinates.add(coords);
System.out.println("解析到坐标: " + coords);
}
}
}
// 处理最后一个Placemark
processCurrentPlacemarkCoordinates(currentPlacemark, currentCoordinates, placemarks);
// 打印解析结果
System.out.println("解析完成,共找到 " + placemarks.size() + " 个地标");
for (Placemark p : placemarks) {
System.out.println("地标信息:");
System.out.println(" 名称: " + p.getName());
System.out.println(" 属性: " + p.getAttributes());
System.out.println(" 坐标: " + p.getCoordinates());
}
}
/**
* 解析描述内容提取属性信息
*
* @param description 描述内容
* @param placemark 地标对象
*/
private static void parseDescription(String description, Placemark placemark) {
System.out.println("开始解析描述内容: " + description);
String[] lines = description.split("\n");
Map<String, String> attributes = new HashMap<>();
for (String line : lines) {
line = line.trim();
if (line.contains("\":")) {
String[] parts = line.split("\":");
if (parts.length == 2) {
String key = parts[0].replace("\"", "").trim();
String value = parts[1].replace("\"", "").trim();
attributes.put(key, value);
System.out.println("解析到属性 - 键: " + key + ", 值: " + value);
}
}
}
placemark.setAttributes(attributes);
}
/**
* 将坐标字符串转换为WKTWell-Known Text格式
*
* @param coordinates 坐标字符串
* @return WKT格式的字符串
*/
public static String convertToWKT(String coordinates) {
if (coordinates == null || coordinates.trim().isEmpty()) {
return "";
}
// 构建WKT格式的多边形
StringBuilder wkt = new StringBuilder("POLYGON((");
String[] coordPairs = coordinates.trim().split("\\s+");
// 处理每个坐标对
for (int i = 0; i < coordPairs.length; i++) {
String[] coords = coordPairs[i].split(",");
if (coords.length >= 2) {
wkt.append(coords[0]).append(" ").append(coords[1]);
if (i < coordPairs.length - 1) {
wkt.append(", ");
}
}
}
wkt.append("))");
StringBuffer polygonSb = new StringBuffer("GEOMETRYCOLLECTION(");
polygonSb.append(wkt);
polygonSb.append(")");
return polygonSb.toString();
}
}

11
dk-modules/system/src/main/java/org/dromara/system/utils/OvkmzParser.java

@ -1,11 +0,0 @@
package org.dromara.system.utils;
/**
* 解析ovkmz文件
*/
public class OvkmzParser {
}

53
dk-modules/system/src/main/java/org/dromara/system/utils/ShpAnalysisUtil.java

@ -45,6 +45,7 @@ public class ShpAnalysisUtil {
/** /**
* 读取shp文件返回要素集合 * 读取shp文件返回要素集合
*
* @param shpPath shp文件路径 * @param shpPath shp文件路径
* @return 要素集合包含地理位置和属性信息 * @return 要素集合包含地理位置和属性信息
*/ */
@ -52,7 +53,7 @@ public class ShpAnalysisUtil {
List<Map<String, String>> resultList = new ArrayList<>(); List<Map<String, String>> resultList = new ArrayList<>();
try { try {
resultList=analysisShpFile(shpPath, "GBK"); resultList = analysisShpFile(shpPath, "GBK");
} catch (Exception e) { } catch (Exception e) {
log.error("无法使用支持的字符编码读取shp文件: {}", e.getMessage()); log.error("无法使用支持的字符编码读取shp文件: {}", e.getMessage());
} }
@ -62,6 +63,7 @@ public class ShpAnalysisUtil {
/** /**
* 读取shp文件返回要素集合 * 读取shp文件返回要素集合
*
* @param shpInputStream shp文件输入流 * @param shpInputStream shp文件输入流
* @return 要素集合包含地理位置和属性信息 * @return 要素集合包含地理位置和属性信息
*/ */
@ -102,7 +104,7 @@ public class ShpAnalysisUtil {
boolean shpFound = false; boolean shpFound = false;
while ((entry = zipInputStream.getNextEntry()) != null) { while ((entry = zipInputStream.getNextEntry()) != null) {
// 处理文件名编码问题 // 处理文件名编码问题
log.info("文件名字:{}",entry.getName()); log.info("文件名字:{}", entry.getName());
File outputFile = new File(tempDir, entry.getName()); File outputFile = new File(tempDir, entry.getName());
// 创建父目录 // 创建父目录
@ -296,20 +298,23 @@ public class ShpAnalysisUtil {
} }
private static String analysisGeometry(Geometry geometry, MathTransform transform) throws TransformException { private static Object analysisGeometry(Geometry geometry, MathTransform transform) throws TransformException {
String resultStr = "";
// 对每个 Polygon 进行坐标转换 // 对每个 Polygon 进行坐标转换
Geometry transformedGeometry = JTS.transform(geometry, transform); Geometry transformedGeometry = JTS.transform(geometry, transform);
MultiPolygon multiPolygon = (MultiPolygon) transformedGeometry; MultiPolygon multiPolygon = (MultiPolygon) transformedGeometry;
Geometry unionGeometry = UnaryUnionOp.union(multiPolygon); Geometry unionGeometry = UnaryUnionOp.union(multiPolygon);
if (unionGeometry instanceof Polygon) { if (unionGeometry instanceof Polygon) {
Polygon polygon = (Polygon) unionGeometry; Polygon polygon = (Polygon) unionGeometry;
resultStr = convertPolygonToWKT(polygon); return convertPolygonToWKT(polygon);
}
} else if (unionGeometry instanceof MultiPolygon) {
MultiPolygon muPolygon = (MultiPolygon) unionGeometry;
return resultStr; return convertMultiPolygonToWKT(muPolygon);
} }
return "";
}
private static String convertPolygonToWKT(Polygon polygon) { private static String convertPolygonToWKT(Polygon polygon) {
@ -321,16 +326,45 @@ public class ShpAnalysisUtil {
if (i > 0) polygonSb.append(","); if (i > 0) polygonSb.append(",");
polygonSb.append(coord.y + " " + coord.x); polygonSb.append(coord.y + " " + coord.x);
} }
if(coordinates[0].x !=coordinates[coordinates.length-1].x){ if (coordinates[0].x != coordinates[coordinates.length - 1].x) {
polygonSb.append(","+coordinates[0].y + " " + coordinates[0].x); polygonSb.append("," + coordinates[0].y + " " + coordinates[0].x);
} }
polygonSb.append(")))"); polygonSb.append(")))");
return polygonSb.toString(); return polygonSb.toString();
} }
private static List<String> convertMultiPolygonToWKT(MultiPolygon multiPolygon) {
List<String> resultList = new ArrayList<>();
// 获取 MultiPolygon 中的每个 Polygon
for (int j = 0; j < multiPolygon.getNumGeometries(); j++) {
Polygon polygon = (Polygon) multiPolygon.getGeometryN(j);
StringBuffer polygonSb = new StringBuffer("GEOMETRYCOLLECTION(POLYGON((");
Coordinate[] coordinates = polygon.getCoordinates();
for (int i = 0; i < coordinates.length; i++) {
Coordinate coord = coordinates[i];
if (i > 0) polygonSb.append(",");
polygonSb.append(coord.y + " " + coord.x);
}
if (coordinates[0].x != coordinates[coordinates.length - 1].x) {
polygonSb.append("," + coordinates[0].y + " " + coordinates[0].x);
}
polygonSb.append(")))");
resultList.add(polygonSb.toString());
}
return resultList;
}
/** /**
* 递归删除目录 * 递归删除目录
*
* @param directory 要删除的目录 * @param directory 要删除的目录
*/ */
private static void deleteDirectory(File directory) { private static void deleteDirectory(File directory) {
@ -356,6 +390,7 @@ public class ShpAnalysisUtil {
/** /**
* 在指定目录中查找第一个.shp文件 * 在指定目录中查找第一个.shp文件
*
* @param directory 搜索目录 * @param directory 搜索目录
* @return 找到的第一个.shp文件未找到返回null * @return 找到的第一个.shp文件未找到返回null
*/ */

88
dk-modules/system/src/main/resources/mapper/system/SysDepartBoundaryMapper.xml

@ -3,28 +3,61 @@
<mapper namespace="org.dromara.system.mapper.SysDepartBoundaryMapper"> <mapper namespace="org.dromara.system.mapper.SysDepartBoundaryMapper">
<select id="listSysDepartBoundary" resultType="org.dromara.system.domain.SysDepartBoundary"> <select id="listSysDepartBoundary" resultType="org.dromara.system.domain.SysDepartBoundary">
SELECT SELECT
db.id, t.*,
db.dept_id, (
db.dept_name, SELECT
db.type, JSON_OBJECT(
db.community_name, 'type', 'FeatureCollection',
CONCAT( 'features', COALESCE (
REPLACE ( REPLACE ( REPLACE ( REPLACE ( ST_AsText ( db.boundary ), 'GEOMETRYCOLLECTION(POLYGON((', '[[' ), ')))', ']]' ), ',', '],[' ), ' ', ',' ) JSON_ARRAYAGG(
) AS boundary, JSON_OBJECT(
db.create_by, 'type', 'Feature',
db.create_time 'properties', JSON_OBJECT(
'deptId', l.dept_id,
'deptName', l.dept_name,
'name', l.name_path,
'community_name', l.name_path
),
'geometry', ST_AsGeoJSON(l.boundary)
)
),
JSON_ARRAY() -- 如果没有数据,则返回空数组
)
) AS landCategoriesJson
FROM FROM
sys_depart_boundary db sys_depart_boundary l
LEft JOIN sys_dept d on db.dept_id = d.dept_id WHERE
l.dept_id = t.dept_id
) AS boundary
FROM
(
SELECT
dept_id,
MAX(dept_name) AS dept_name,
area_type,
MAX(name_path) as name_path,
MAX(create_time) AS create_time
FROM
sys_depart_boundary
GROUP BY
dept_id, area_type
) t
<where> <where>
<if test="condition.deptId != null and condition.deptId != ''"> <if test="condition.namePath != null and condition.namePath != ''">
and (db.dept_id = #{condition.deptId} or d.parent_id = #{condition.deptId}) and t.name_path like concat(concat('%',#{condition.namePath}),'%')
</if> </if>
<if test="condition.communityName != null and condition.communityName != ''"> <if test="condition.deptName != null and condition.deptName != ''">
and db.community_name like concat(concat('%',#{condition.communityName}),'%') and t.dept_name like concat(concat('%',#{condition.deptName}),'%')
</if> </if>
<if test="condition.deptIds != null and condition.deptIds.size > 0">
and t.dept_id in
<foreach collection="condition.deptIds" open="(" close=")" separator="," item="item">
#{item}
</foreach>
</if>
</where> </where>
order by t.create_time desc
</select> </select>
@ -33,8 +66,8 @@
db.id, db.id,
db.dept_id, db.dept_id,
db.dept_name, db.dept_name,
db.type, db.area_type,
db.community_name, db.name_path,
CONCAT( CONCAT(
REPLACE ( REPLACE ( REPLACE ( REPLACE ( ST_AsText ( db.boundary ), 'GEOMETRYCOLLECTION(POLYGON((', '[[' ), ')))', ']]' ), ',', '],[' ), ' ', ',' ) REPLACE ( REPLACE ( REPLACE ( REPLACE ( ST_AsText ( db.boundary ), 'GEOMETRYCOLLECTION(POLYGON((', '[[' ), ')))', ']]' ), ',', '],[' ), ' ', ',' )
) AS boundary, ) AS boundary,
@ -62,8 +95,8 @@
db.id, db.id,
db.dept_id, db.dept_id,
db.dept_name, db.dept_name,
db.type, db.area_type,
db.community_name, db.name_path,
CONCAT( CONCAT(
REPLACE ( REPLACE ( REPLACE ( REPLACE ( ST_AsText ( db.boundary ), 'GEOMETRYCOLLECTION(POLYGON((', '[[' ), ')))', ']]' ), ',', '],[' ), ' ', ',' ) REPLACE ( REPLACE ( REPLACE ( REPLACE ( ST_AsText ( db.boundary ), 'GEOMETRYCOLLECTION(POLYGON((', '[[' ), ')))', ']]' ), ',', '],[' ), ' ', ',' )
) AS boundary, ) AS boundary,
@ -82,6 +115,7 @@
name_path, name_path,
boundary, boundary,
area_type, area_type,
parent_id,
create_by, create_by,
create_time, create_time,
update_by, update_by,
@ -95,6 +129,7 @@
#{item.namePath}, #{item.namePath},
ST_GeomFromText(#{item.boundary}), ST_GeomFromText(#{item.boundary}),
#{item.areaType}, #{item.areaType},
#{item.parentId},
#{item.createBy}, #{item.createBy},
#{item.createTime}, #{item.createTime},
#{item.updateBy}, #{item.updateBy},
@ -135,4 +170,17 @@
d.dept_id = #{deptId} d.dept_id = #{deptId}
</select> </select>
<select id="listDepartBoundaryByLngAndLat" resultType="org.dromara.system.domain.SysDepartBoundary">
select
db.id,
db.dept_id,
db.dept_name,
db.area_type,
db.name_path
FROM
sys_depart_boundary db
WHERE ST_Contains(db.boundary, ST_GeomFromText(CONCAT('POINT(', #{lng}, ' ', #{lat}, ')')))
ORDER BY area_type
</select>
</mapper> </mapper>

30
dk-modules/system/src/main/resources/mapper/system/SysDeptMapper.xml

@ -112,4 +112,34 @@
)select * from warning_summary )select * from warning_summary
</select> </select>
<select id="listTreeDeptByChild" resultType="org.dromara.system.domain.vo.SysDeptVo">
WITH RECURSIVE warning_summary AS (
-- 基础查询:选择当前部门的信息
SELECT
sd1.dept_id,
sd1.dept_name,
sd1.parent_id
FROM
sys_dept sd1
WHERE
sd1.dept_id = #{deptId} -- 这里指定了需要查询的部门ID
UNION ALL
-- 递归查询:找到当前部门的上级部门
SELECT
sd2.dept_id,
sd2.dept_name,
sd2.parent_id
FROM
sys_dept sd2
JOIN warning_summary pd ON sd2.dept_id = pd.parent_id -- 找到上级部门
)
-- 返回所有上级部门信息
SELECT *
FROM warning_summary;
</select>
</mapper> </mapper>

Loading…
Cancel
Save