@@ -14,6 +14,8 @@ import com.ruoyi.common.enums.BusinessType; | |||
import com.ruoyi.common.utils.pdf.PdfUtils; | |||
import com.ruoyi.common.utils.poi.ExcelUtil; | |||
import com.ruoyi.common.utils.translation.TranslateUtils; | |||
import com.ruoyi.geo.service.GeoExportHandlerService; | |||
import com.ruoyi.geo.service.GeoImportHandlerService; | |||
import com.ruoyi.system.service.ISysDeptService; | |||
import org.apache.commons.compress.utils.Lists; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
@@ -38,7 +40,9 @@ public class TTaskExportController extends BaseController | |||
private ITTaskExportService tTaskExportService; | |||
@Autowired | |||
private ISysDeptService deptService; | |||
private ISysDeptService deptService; | |||
@Autowired | |||
private GeoExportHandlerService exportHandlerService; | |||
/** | |||
* 查询导出任务列表 | |||
@@ -198,4 +202,47 @@ public class TTaskExportController extends BaseController | |||
PdfUtils.initPdf(response, pdf); | |||
} | |||
/** | |||
* 开始导出任务 | |||
*/ | |||
@PreAuthorize("@ss.hasPermi('business:export:do')") | |||
@Log(title = "开始导入任务", businessType = BusinessType.UPDATE) | |||
@PostMapping("/start/{taskId}") | |||
public AjaxResult start(@PathVariable Long taskId) | |||
{ | |||
return AjaxResult.success(exportHandlerService.startTask(taskId)); | |||
} | |||
/** | |||
* 获取导出任务日志 | |||
*/ | |||
@PreAuthorize("@ss.hasPermi('business:export:do')") | |||
@GetMapping("/log/{taskId}") | |||
public AjaxResult log(@PathVariable Long taskId, Integer offset) | |||
{ | |||
if(null == offset) | |||
offset = 0; | |||
return AjaxResult.success(exportHandlerService.loadExportLog(taskId, offset)); | |||
} | |||
/** | |||
* 下载导出任务日志 | |||
*/ | |||
@PreAuthorize("@ss.hasPermi('business:export:do')") | |||
@GetMapping("/downloadLog/{taskId}") | |||
public void downloadLog(@PathVariable Long taskId, HttpServletResponse response) | |||
{ | |||
exportHandlerService.downloadLog(taskId, response); | |||
} | |||
/** | |||
* 下载导出任务文件 | |||
*/ | |||
@PreAuthorize("@ss.hasPermi('business:export:down')") | |||
@GetMapping("/downloadFile/{taskId}") | |||
public void downloadFile(@PathVariable Long taskId, HttpServletResponse response) | |||
{ | |||
exportHandlerService.downloadFile(taskId, response); | |||
} | |||
} |
@@ -214,7 +214,7 @@ public class TTaskImportController extends BaseController | |||
@PostMapping("/start/{taskId}") | |||
public AjaxResult start(@PathVariable Long taskId) | |||
{ | |||
return AjaxResult.success(importHandlerService.StartTask(taskId)); | |||
return AjaxResult.success(importHandlerService.startTask(taskId)); | |||
} | |||
/** | |||
@@ -226,7 +226,7 @@ public class TTaskImportController extends BaseController | |||
{ | |||
if(null == offset) | |||
offset = 0; | |||
return AjaxResult.success(importHandlerService.GetImportLog(taskId, offset)); | |||
return AjaxResult.success(importHandlerService.loadImportLog(taskId, offset)); | |||
} | |||
/** | |||
@@ -236,6 +236,6 @@ public class TTaskImportController extends BaseController | |||
@GetMapping("/downloadLog/{taskId}") | |||
public void downloadLog(@PathVariable Long taskId, HttpServletResponse response) | |||
{ | |||
importHandlerService.DownloadLog(taskId, response); | |||
importHandlerService.downloadLog(taskId, response); | |||
} | |||
} |
@@ -135,6 +135,12 @@ xss: | |||
urlPatterns: /system/*,/monitor/*,/tool/* | |||
importTask: | |||
# 是否启动时执行等待中的任务 | |||
startOnBoot: false | |||
# 下次建议读取日志的间隔(毫秒) | |||
logNextPoll: 2000 | |||
exportTask: | |||
# 是否启动时执行等待中的任务 | |||
startOnBoot: false | |||
# 下次建议读取日志的间隔(毫秒) |
@@ -1,15 +1,21 @@ | |||
import cn.hutool.core.io.FileUtil; | |||
import cn.hutool.core.thread.ThreadUtil; | |||
import com.alibaba.fastjson2.JSON; | |||
import com.ruoyi.RuoYiApplication; | |||
import com.ruoyi.common.geo.GeoParser; | |||
import com.ruoyi.common.geo.GeoWriter; | |||
import com.ruoyi.geo.service.GeoExportHandlerService; | |||
import com.ruoyi.geo.service.GeoImportHandlerService; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.junit.jupiter.api.Test; | |||
import org.junit.jupiter.api.extension.ExtendWith; | |||
import org.locationtech.jts.geom.MultiPolygon; | |||
import org.springframework.boot.test.context.SpringBootTest; | |||
import org.springframework.test.context.junit.jupiter.SpringExtension; | |||
import javax.annotation.Resource; | |||
import java.math.BigDecimal; | |||
import java.util.LinkedHashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
@@ -19,13 +25,16 @@ import java.util.Map; | |||
public final class GeoTest | |||
{ | |||
@Resource | |||
private GeoImportHandlerService service; | |||
private GeoImportHandlerService importer; | |||
@Resource | |||
private GeoExportHandlerService exporter; | |||
@Test | |||
public void test() | |||
{ | |||
service.StartTask(4L); | |||
//service.startTask(4L); | |||
//new Scanner(System.in).next(); | |||
exporter.startTask(3L); | |||
ThreadUtil.sleep(5000); | |||
} | |||
@@ -36,18 +45,39 @@ public final class GeoTest | |||
PATH = "D:/m/胜利村_shp_3857/dk.shp"; // dk | |||
PATH = "D:/m/胜利村_shp_3857/zyhycg.shp"; // zyhycg | |||
PATH = "D:/m/胜利村_shp_3857/jtzy.shp"; // jtzy | |||
try(GeoParser geo = new GeoParser()) | |||
String OUT; | |||
OUT = "D:/m/output_胜利村_shp_3857/jtzyxx.shp"; | |||
FileUtil.mkParentDirs(OUT); | |||
try(GeoParser parser = new GeoParser()) | |||
{ | |||
geo.Open(PATH, "UTF-8"); | |||
System.err.println(geo.GetTypeNames()); | |||
geo.SetSource(0); | |||
List<Map<String, Object>> cjqies = geo.GetMapList(); | |||
//List<GeoCJQY> cjqies = geo.GetList(GeoCJQY.class); | |||
//List<GeoJTZY> cjqies = geo.GetList(GeoJTZY.class); | |||
//List<GeoZYHYCG> cjqies = geo.GetList(GeoZYHYCG.class); | |||
//List<GeoDK> cjqies = geo.GetList(GeoDK.class); | |||
System.err.println(JSON.toJSONString(cjqies)); | |||
parser.Open(PATH, "UTF-8"); | |||
System.out.println(parser.GetTypeNames()); | |||
parser.SetSource(0); | |||
List<Map<String, Object>> cjqies = parser.GetMapList(); | |||
//List<GeoCJQY> cjqies = parser.GetList(GeoCJQY.class); | |||
//List<GeoJTZY> cjqies = parser.GetList(GeoJTZY.class); | |||
//List<GeoZYHYCG> cjqies = parser.GetList(GeoZYHYCG.class); | |||
//List<GeoDK> cjqies = parser.GetList(GeoDK.class); | |||
System.out.println(JSON.toJSONString(cjqies)); | |||
System.out.println("-------------------------"); | |||
try(GeoWriter writer = new GeoWriter()) | |||
{ | |||
writer.Open(OUT, "UTF-8"); | |||
Map<String, Class<?>> classes = new LinkedHashMap<>(); | |||
classes.put("QSDWDM", String.class); | |||
classes.put("QSDWMC", String.class); | |||
classes.put("Shape_Area", BigDecimal.class); | |||
classes.put("the_geom", MultiPolygon.class); | |||
writer.AddSchema("test123", classes); | |||
System.out.println(writer.GetTypeNames()); | |||
writer.SetSource(0, false); | |||
writer.WriteMapList(cjqies); | |||
} | |||
} | |||
} | |||
} |
@@ -2,6 +2,7 @@ package com.ruoyi.business.mapper; | |||
import java.util.List; | |||
import com.ruoyi.business.domain.TTaskExport; | |||
import com.ruoyi.business.domain.TTaskImport; | |||
/** | |||
* 导出任务Mapper接口 | |||
@@ -74,4 +75,7 @@ public interface TTaskExportMapper | |||
* @return 结果 | |||
*/ | |||
public int deleteTTaskExportByIds(Long[] ids); | |||
public int terminateRunningTask(); | |||
public TTaskExport getForUpdate(Long id); | |||
} |
@@ -0,0 +1,22 @@ | |||
package com.ruoyi.geo.config; | |||
import org.springframework.boot.context.properties.ConfigurationProperties; | |||
import org.springframework.stereotype.Component; | |||
@Component | |||
@ConfigurationProperties(prefix = "export-task") | |||
public class GeoExportTaskConfig | |||
{ | |||
public static boolean startOnBoot = false; // 是否启动时执行等待中的任务 | |||
public static long logNextPoll = 2000; // 下次建议读取日志的间隔(毫秒) | |||
public void setStartOnBoot(boolean startOnBoot) | |||
{ | |||
GeoExportTaskConfig.startOnBoot = startOnBoot; | |||
} | |||
public void setLogNextPoll(long logNextPoll) | |||
{ | |||
GeoExportTaskConfig.logNextPoll = logNextPoll; | |||
} | |||
} |
@@ -6,9 +6,25 @@ import com.ruoyi.common.utils.StringUtils; | |||
public final class GeoSysDir | |||
{ | |||
// 导入日志路径 | |||
public static final String LOG = "/log"; | |||
public static final String LOG = "/log"; | |||
// 导入zip临时解压路径 | |||
public static final String ZIP_EXTRACT_TEMP = "/unzip"; | |||
public static final String UNZIP_DECOMPRESS_TEMP = "/unzip"; | |||
// 导出zip临时生成路径 | |||
public static final String ZIP_COMPRESS_TEMP = "/zip"; | |||
// 导出zip临时生成路径 | |||
public static final String ZIP_FILE_TEMP = "/zip_temp"; | |||
// 导出zip临时生成路径 | |||
public static final String ZIP_DOWNLOAD = "/zip"; | |||
public static String TrimProfile(String path) | |||
{ | |||
if(StringUtils.isEmpty(path)) | |||
return ""; | |||
else if(path.startsWith("/profile")) | |||
return path.substring("/profile".length()); | |||
else | |||
return path; | |||
} | |||
public static String GetDir(String path) | |||
{ | |||
@@ -68,5 +84,17 @@ public final class GeoSysDir | |||
return "<profile directory>" + fpath.substring(fprofile.length()); | |||
} | |||
public static String TrimNormalized(String path) | |||
{ | |||
if(StringUtils.isEmpty(path)) | |||
return path; | |||
String fpath = path.replaceAll("\\\\", "/"); | |||
String fprofile = RuoYiConfig.getProfile().replaceAll("\\\\", "/"); | |||
if(!fpath.startsWith(fprofile)) | |||
return path; | |||
return fpath.substring(fprofile.length()); | |||
} | |||
private GeoSysDir() {} | |||
} |
@@ -0,0 +1,62 @@ | |||
package com.ruoyi.geo.framework; | |||
import com.ruoyi.business.domain.TGisCjqy; | |||
import com.ruoyi.common.geo.GeoCreator; | |||
import com.ruoyi.geo.service.GeoMapperService; | |||
import com.ruoyi.geo.structs.GeoCJQY; | |||
import org.locationtech.jts.geom.MultiPolygon; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.stream.Collectors; | |||
public class GeoCjqyExportTask implements GeoDBExportTaskInterface | |||
{ | |||
private final static String TYPE_NAME = "村级区域"; | |||
private final GeoExportTask exportTask; | |||
private List<TGisCjqy> list; | |||
public GeoCjqyExportTask(GeoExportTask exportTask) | |||
{ | |||
this.exportTask = exportTask; | |||
} | |||
public int LoadDataList() | |||
{ | |||
TGisCjqy cond = new TGisCjqy(); | |||
cond.setImportCode(exportTask.dept.getImportCode()); | |||
list = GeoMapperService.GisCjqyMapper().selectTGisCjqyList(cond); | |||
exportTask.logFile.WriteLine(TYPE_NAME + "读取系统数据条数: 区划代码={}, 条数={}", exportTask.dept.getImportCode(), list.size()); | |||
return list.size(); | |||
} | |||
private GeoCJQY ConvertData(TGisCjqy src, GeoCJQY dst) | |||
{ | |||
if(null == dst) | |||
dst = new GeoCJQY(); | |||
dst.the_geom = src.getTheGeom(); | |||
dst.BSM = src.getBsm().intValue(); | |||
dst.YSDM = src.getYsdm(); | |||
dst.CJQYDM = src.getCjqydm(); | |||
dst.CJQYMC = src.getCjqymc(); | |||
return dst; | |||
} | |||
public void SaveData() | |||
{ | |||
exportTask.logFile.WriteLine(TYPE_NAME + "开始导出数据: 区划代码={}, 条数={}", exportTask.dept.getDeptName(), list.size()); | |||
List<GeoCJQY> dataList = list.stream().map((x) -> ConvertData(x, null)).collect(Collectors.toList()); | |||
exportTask.writer.WriteList(dataList); | |||
} | |||
public Map<String, Class<?>> GetTypes() | |||
{ | |||
Map<String, Class<?>> types = GeoCreator.GetClassTypes(GeoCJQY.class); | |||
types.put("the_geom", MultiPolygon.class); | |||
return types; | |||
} | |||
} |
@@ -6,7 +6,9 @@ import com.ruoyi.business.mapper.TGisCjqyMapper; | |||
import com.ruoyi.common.core.domain.entity.SysDept; | |||
import com.ruoyi.common.utils.StringUtils; | |||
import com.ruoyi.geo.service.GeoImportHandlerService; | |||
import com.ruoyi.geo.service.GeoMapperService; | |||
import com.ruoyi.geo.structs.GeoCJQY; | |||
import static com.ruoyi.business.constants.TaskEnums.ImportType; | |||
import java.util.ArrayList; | |||
@@ -14,14 +16,14 @@ import java.util.List; | |||
import java.util.Map; | |||
import java.util.stream.Collectors; | |||
public class GeoCjqyTask implements GeoDBTaskInterface | |||
public class GeoCjqyImportTask implements GeoDBImportTaskInterface | |||
{ | |||
private final static String TYPE_NAME = "村级区域"; | |||
private final GeoImportTask importTask; | |||
private List<GeoCJQY> list; | |||
public GeoCjqyTask(GeoImportTask importTask) | |||
public GeoCjqyImportTask(GeoImportTask importTask) | |||
{ | |||
this.importTask = importTask; | |||
} | |||
@@ -64,7 +66,7 @@ public class GeoCjqyTask implements GeoDBTaskInterface | |||
{ | |||
TGisCjqy cond = new TGisCjqy(); | |||
cond.setCjqydm(qydm); | |||
List<TGisCjqy> cjqies = GeoImportHandlerService.GisCjqyMapper().selectTGisCjqyList(cond); | |||
List<TGisCjqy> cjqies = GeoMapperService.GisCjqyMapper().selectTGisCjqyList(cond); | |||
importTask.logFile.WriteLine(TYPE_NAME + "读取系统已存在的条数: 区划代码={}, 条数={}", qydm, cjqies.size()); | |||
return cjqies; | |||
} | |||
@@ -87,7 +89,7 @@ public class GeoCjqyTask implements GeoDBTaskInterface | |||
if(ImportType.IT_OVERRIDE.equals(importTask.taskImport.getImportType())) | |||
{ | |||
importTask.logFile.WriteLine(TYPE_NAME + "覆盖导入, 需清空现有数据, 然后再插入, 区划代码={}", importCode); | |||
int ret = GeoImportHandlerService.GisCjqyMapper().deleteByCode(importCode); | |||
int ret = GeoMapperService.GisCjqyMapper().deleteByCode(importCode); | |||
importTask.logFile.WriteLine(TYPE_NAME + "清空现有数据: {}, 区划代码={}", ret, importCode); | |||
return ret; | |||
} | |||
@@ -100,7 +102,7 @@ public class GeoCjqyTask implements GeoDBTaskInterface | |||
private int WriteData(List<TGisCjqy> insertList, List<TGisCjqy> updateList, SysDept dept) | |||
{ | |||
TGisCjqyMapper gisCjqyMapper = GeoImportHandlerService.GisCjqyMapper(); | |||
TGisCjqyMapper gisCjqyMapper = GeoMapperService.GisCjqyMapper(); | |||
int i = ListUtil.split(insertList, 50).stream().map(gisCjqyMapper::insertTGisCjqyBatch).reduce(0, Integer::sum); | |||
importTask.logFile.WriteLine(TYPE_NAME + "新增数据: 区划代码={}, 条数={}", dept.getDeptName(), i); | |||
int u = ListUtil.split(updateList, 50).stream().map(gisCjqyMapper::updateTGisCjqyBatch).reduce(0, Integer::sum); | |||
@@ -111,21 +113,29 @@ public class GeoCjqyTask implements GeoDBTaskInterface | |||
private int SaveDeptData(SysDept dept, List<GeoCJQY> datas) | |||
{ | |||
importTask.logFile.WriteLine(TYPE_NAME + "开始处理数据: 区划代码={}, 条数={}", dept.getDeptName(), datas.size()); | |||
List<TGisCjqy> databases = LoadDatabase(dept.getImportCode()); | |||
Map<String, TGisCjqy> exists = databases.stream().collect(Collectors.toMap(TGisCjqy::getCjqydm, x->x)); | |||
boolean needCheck = !ImportType.IT_OVERRIDE.equals(importTask.taskImport.getImportType()); | |||
Map<String, TGisCjqy> exists = null; | |||
if(needCheck) | |||
{ | |||
List<TGisCjqy> databases = LoadDatabase(dept.getImportCode()); | |||
exists = databases.stream().collect(Collectors.toMap(TGisCjqy::getCjqydm, x->x)); | |||
} | |||
List<TGisCjqy> insertList = new ArrayList<>(); | |||
List<TGisCjqy> updateList = new ArrayList<>(); | |||
for(GeoCJQY data : datas) | |||
{ | |||
TGisCjqy db = exists.get(data.CJQYDM); | |||
boolean has = null == db; | |||
db = ConvertData(data, db, dept); | |||
if(has) | |||
insertList.add(db); | |||
TGisCjqy db = null; | |||
if(needCheck) | |||
{ | |||
db = exists.get(data.CJQYDM); | |||
} | |||
TGisCjqy item = ConvertData(data, db, dept); | |||
if(null == db) | |||
insertList.add(item); | |||
else | |||
updateList.add(db); | |||
updateList.add(item); | |||
} | |||
CleanDatabase(dept.getImportCode()); |
@@ -0,0 +1,11 @@ | |||
package com.ruoyi.geo.framework; | |||
import java.util.List; | |||
import java.util.Map; | |||
public interface GeoDBExportTaskInterface | |||
{ | |||
public Map<String, Class<?>> GetTypes(); | |||
public int LoadDataList(); | |||
public void SaveData(); | |||
} |
@@ -1,6 +1,6 @@ | |||
package com.ruoyi.geo.framework; | |||
public interface GeoDBTaskInterface | |||
public interface GeoDBImportTaskInterface | |||
{ | |||
public int LoadDataList(); | |||
public void CheckData(); |
@@ -0,0 +1,315 @@ | |||
package com.ruoyi.geo.framework; | |||
import cn.hutool.core.collection.CollectionUtil; | |||
import cn.hutool.core.date.DateUtil; | |||
import cn.hutool.core.io.FileUtil; | |||
import cn.hutool.core.util.ZipUtil; | |||
import com.ruoyi.business.domain.TTaskExport; | |||
import com.ruoyi.common.config.RuoYiConfig; | |||
import com.ruoyi.common.core.domain.entity.SysDept; | |||
import com.ruoyi.common.geo.GeoWriter; | |||
import com.ruoyi.common.utils.ExceptionUtil; | |||
import com.ruoyi.common.utils.StringUtils; | |||
import com.ruoyi.common.utils.spring.SpringUtils; | |||
import com.ruoyi.common.utils.sql.DB; | |||
import com.ruoyi.geo.constants.GeoShpType; | |||
import com.ruoyi.geo.constants.GeoSysDir; | |||
import com.ruoyi.geo.service.GeoExportHandlerService; | |||
import com.ruoyi.geo.service.GeoMapperService; | |||
import com.ruoyi.system.mapper.SysDeptMapper; | |||
import lombok.extern.slf4j.Slf4j; | |||
import java.io.File; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Date; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.stream.Collectors; | |||
import static com.ruoyi.business.constants.TaskEnums.TaskStatus; | |||
@Slf4j | |||
public class GeoExportTask implements Runnable | |||
{ | |||
private final Long taskId; | |||
TTaskExport taskExport; | |||
GeoTaskLog logFile; | |||
GeoWriter writer; | |||
private final List<String> typeNames = Arrays.asList( | |||
GeoShpType.CJQY, | |||
GeoShpType.JTZY, | |||
GeoShpType.ZYHYCG | |||
); | |||
private Map<String, Class<?>> typeClasses; | |||
private String shpFile; | |||
private String type; | |||
String username; | |||
Date now; | |||
SysDept dept; | |||
private GeoDBExportTaskInterface task; | |||
public GeoExportTask(Long taskId) | |||
{ | |||
this.taskId = taskId; | |||
} | |||
public void Init() | |||
{ | |||
now = new Date(); | |||
username = "admin"; //SecurityUtils.getUsername(); | |||
String path = LogPath(); | |||
log.info("任务{}日志文件: {}", taskId, path); | |||
logFile = new GeoTaskLog(path); | |||
logFile.Open(); | |||
logFile.WriteLine("任务初始化: {} - {}", taskId, DateUtil.format(now, "yyyy-MM-dd HH:mm:ss.SSS")); | |||
} | |||
public void Shutdown() | |||
{ | |||
//CleanTempFiles(); | |||
logFile.WriteLine("任务结束: {} - {}", taskId, DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss.SSS")); | |||
if(null != logFile) | |||
{ | |||
logFile.close(); | |||
} | |||
log.info("任务{}日志文件: {}", taskId, GeoSysDir.DesensitizedNormalized(LogPath())); | |||
} | |||
private String ZipCachePath() | |||
{ | |||
return GeoSysDir.CacheDir(GeoSysDir.ZIP_COMPRESS_TEMP + "/" + taskId); | |||
} | |||
private String ZipTempFilePath() | |||
{ | |||
return GeoSysDir.CacheDir(GeoSysDir.ZIP_FILE_TEMP + "/" + taskId + ".zip.temp"); | |||
} | |||
private String ZipFilePath() | |||
{ | |||
return GeoSysDir.ExportDir(GeoSysDir.ZIP_DOWNLOAD + "/" + taskId + ".zip"); | |||
} | |||
public String LogPath() | |||
{ | |||
return GeoSysDir.ExportDir(GeoSysDir.LOG) + "/" + taskId + ".log"; | |||
} | |||
private void Ready() | |||
{ | |||
// 先清空源临时解压文件 | |||
CleanTempFiles(); | |||
String toDir = ZipCachePath(); | |||
FileUtil.mkdir(toDir); | |||
FileUtil.mkParentDirs(ZipFilePath()); | |||
} | |||
private void CleanTempFiles() | |||
{ | |||
String toDir = ZipCachePath(); | |||
logFile.WriteLine("清理临时文件: " + GeoSysDir.DesensitizedNormalized(toDir)); | |||
FileUtil.del(toDir); | |||
} | |||
private void Compress() | |||
{ | |||
String cacheDir = ZipCachePath(); | |||
logFile.WriteLine("开始压缩临时shp文件: " + GeoSysDir.DesensitizedNormalized(cacheDir)); | |||
String zipTempFile = ZipTempFilePath(); | |||
FileUtil.mkParentDirs(zipTempFile); | |||
logFile.WriteLine("生成临时zip文件: " + GeoSysDir.DesensitizedNormalized(zipTempFile)); | |||
ZipUtil.zip(cacheDir, ZipTempFilePath()); | |||
String zipFile = ZipFilePath(); | |||
FileUtil.mkParentDirs(zipFile); | |||
if(StringUtils.isNotEmpty(taskExport.getFileUrl())) | |||
{ | |||
File file = new File(RuoYiConfig.getProfile() + "/" + GeoSysDir.TrimProfile(taskExport.getFileUrl())); | |||
if(file.isFile()) | |||
{ | |||
logFile.WriteLine("删除之前的zip文件: " + GeoSysDir.DesensitizedNormalized(file.getAbsolutePath())); | |||
file.delete(); | |||
} | |||
} | |||
logFile.WriteLine("复制zip到下载目录: " + GeoSysDir.DesensitizedNormalized(zipFile)); | |||
FileUtil.move(new File(zipTempFile), new File(zipFile), true); | |||
taskExport.setFileUrl("/profile" + GeoSysDir.TrimNormalized(zipFile)); | |||
} | |||
private void CreateShp() | |||
{ | |||
writer = new GeoWriter(); | |||
if(!writer.Open(shpFile, "UTF-8")) | |||
{ | |||
logFile.ErrorLine("打开shp文件错误: " + shpFile); | |||
} | |||
try | |||
{ | |||
writer.AddSchema(type, typeClasses); | |||
System.out.println(writer.GetTypeNames()); | |||
if(!writer.SetSource(type, false)) | |||
{ | |||
logFile.ErrorLine("shp文件未找到支持源: " + type); | |||
return; | |||
} | |||
task.SaveData(); | |||
} | |||
catch(Exception e) | |||
{ | |||
e.printStackTrace(); | |||
} | |||
finally | |||
{ | |||
writer.close(); | |||
writer = null; | |||
} | |||
} | |||
private void LoadDept() | |||
{ | |||
dept = GeoMapperService.DeptMapper().selectDeptByOrgCode(taskExport.getOrgCode()); | |||
} | |||
private void LoadTask() | |||
{ | |||
TTaskExport task = GeoMapperService.TaskExportMapper().getForUpdate(taskId); | |||
if(null == task) | |||
{ | |||
logFile.ErrorLine("任务配置不存在: " + taskId); | |||
return; | |||
} | |||
if(!TaskStatus.ST_WAIT.equals(task.getTaskStatus())) | |||
{ | |||
logFile.ErrorLine("任务非等待状态: " + taskId); | |||
return; | |||
} | |||
taskExport = task; | |||
} | |||
private void SaveTask(String st) | |||
{ | |||
if(null != taskExport) | |||
{ | |||
taskExport.setTaskStatus(st); | |||
GeoMapperService.TaskExportMapper().updateTTaskExport(taskExport); | |||
} | |||
} | |||
private void HandleShpTypes() | |||
{ | |||
for(String shpType : typeNames) | |||
{ | |||
type = shpType; | |||
// 2. 分发任务 | |||
DispatchTask(); | |||
} | |||
} | |||
private void DispatchTask() | |||
{ | |||
// 1. 选择任务类型 | |||
switch(type.toLowerCase()) | |||
{ | |||
case GeoShpType.CJQY: | |||
task = new GeoCjqyExportTask(this); | |||
break; | |||
case GeoShpType.JTZY: | |||
task = new GeoJtzyExportTask(this); | |||
break; | |||
case GeoShpType.ZYHYCG: | |||
task = new GeoZyhycgExportTask(this); | |||
break; | |||
default: | |||
logFile.WriteLine("数据类型不支持: " + type); | |||
return; | |||
} | |||
// 2. 处理导入任务 | |||
DoTask(); | |||
} | |||
private void CreateShpFile() | |||
{ | |||
shpFile = ZipCachePath() + "/"/* + group + "/"*/ + type.toLowerCase() + ".shp"; | |||
FileUtil.mkParentDirs(shpFile); | |||
} | |||
private void DoTask() | |||
{ | |||
typeClasses = task.GetTypes(); | |||
int num = task.LoadDataList(); | |||
if(num == 0) | |||
{ | |||
logFile.WriteLine("数据库支持源未读取到数据: " + type); | |||
return; | |||
} | |||
CreateShpFile(); | |||
CreateShp(); | |||
} | |||
private void Handle() | |||
{ | |||
// 0. 初始化任务: 打开日志系统 | |||
Init(); | |||
// 1. 加载任务配置, 并检查 | |||
LoadTask(); | |||
// 2. 读取文件, 解压文件到工作目录 | |||
Ready(); | |||
// 3. 加载部门数据 | |||
LoadDept(); | |||
// 4. 依次处理所有shp文件 | |||
HandleShpTypes(); | |||
// 5. 压缩 | |||
Compress(); | |||
} | |||
@Override | |||
public void run() | |||
{ | |||
Object handle = null; | |||
try | |||
{ | |||
handle = DB.BeginTransaction(); | |||
Handle(); | |||
// 更改任务状态为已完成 | |||
SaveTask(TaskStatus.ST_FINISH); | |||
} | |||
catch(Exception e) | |||
{ | |||
e.printStackTrace(); | |||
logFile.WriteLine(ExceptionUtil.getExceptionMessage(e)); | |||
SaveTask(TaskStatus.ST_FAIL); | |||
} | |||
finally | |||
{ | |||
DB.EndTransaction(handle); | |||
// -1: 终止任务, 关闭日志系统 | |||
Shutdown(); | |||
} | |||
} | |||
public Long GetTaskId() | |||
{ | |||
return taskId; | |||
} | |||
} |
@@ -14,6 +14,7 @@ import com.ruoyi.common.utils.sql.DB; | |||
import com.ruoyi.geo.constants.GeoShpType; | |||
import com.ruoyi.geo.constants.GeoSysDir; | |||
import com.ruoyi.geo.service.GeoImportHandlerService; | |||
import com.ruoyi.geo.service.GeoMapperService; | |||
import com.ruoyi.system.mapper.SysDeptMapper; | |||
import lombok.extern.slf4j.Slf4j; | |||
import static com.ruoyi.business.constants.TaskEnums.TaskStatus; | |||
@@ -40,7 +41,7 @@ public class GeoImportTask implements Runnable | |||
String username; | |||
Date now; | |||
private GeoDBTaskInterface task; | |||
private GeoDBImportTaskInterface task; | |||
public GeoImportTask(Long taskId) | |||
{ | |||
@@ -72,7 +73,7 @@ public class GeoImportTask implements Runnable | |||
private String UnzipCachePath() | |||
{ | |||
return GeoSysDir.CacheDir(GeoSysDir.ZIP_EXTRACT_TEMP + "/" + taskId); | |||
return GeoSysDir.CacheDir(GeoSysDir.UNZIP_DECOMPRESS_TEMP + "/" + taskId); | |||
} | |||
public String LogPath() | |||
@@ -157,15 +158,14 @@ public class GeoImportTask implements Runnable | |||
private void LoadDept() | |||
{ | |||
SysDept cond = new SysDept(); | |||
SysDeptMapper deptMapper = SpringUtils.getBean(SysDeptMapper.class); | |||
List<SysDept> sysDepts = deptMapper.selectDeptList(cond); | |||
List<SysDept> sysDepts = GeoMapperService.DeptMapper().selectDeptList(cond); | |||
importDeptMap = sysDepts.stream().collect(Collectors.toMap(SysDept::getImportCode, x -> x)); | |||
sysDeptMap = sysDepts.stream().collect(Collectors.toMap(SysDept::getOrgCode, x -> x)); | |||
} | |||
private void LoadTask() | |||
{ | |||
TTaskImport task = GeoImportHandlerService.TaskImportMapper().getForUpdate(taskId); | |||
TTaskImport task = GeoMapperService.TaskImportMapper().getForUpdate(taskId); | |||
if(null == task) | |||
{ | |||
logFile.ErrorLine("任务配置不存在: " + taskId); | |||
@@ -184,7 +184,7 @@ public class GeoImportTask implements Runnable | |||
if(null != taskImport) | |||
{ | |||
taskImport.setTaskStatus(st); | |||
GeoImportHandlerService.TaskImportMapper().updateTTaskImport(taskImport); | |||
GeoMapperService.TaskImportMapper().updateTTaskImport(taskImport); | |||
} | |||
} | |||
@@ -215,13 +215,13 @@ public class GeoImportTask implements Runnable | |||
switch(type.toLowerCase()) | |||
{ | |||
case GeoShpType.CJQY: | |||
task = new GeoCjqyTask(this); | |||
task = new GeoCjqyImportTask(this); | |||
break; | |||
case GeoShpType.JTZY: | |||
task = new GeoJtzyTask(this); | |||
task = new GeoJtzyImportTask(this); | |||
break; | |||
case GeoShpType.ZYHYCG: | |||
task = new GeoZyhycgTask(this); | |||
task = new GeoZyhycgImportTask(this); | |||
break; | |||
default: | |||
logFile.WriteLine("数据类型不支持: " + type); | |||
@@ -0,0 +1,79 @@ | |||
package com.ruoyi.geo.framework; | |||
import com.ruoyi.common.geo.GeoCreator; | |||
import com.ruoyi.geo.service.GeoExportHandlerService; | |||
import com.ruoyi.geo.service.GeoMapperService; | |||
import com.ruoyi.geo.structs.GeoJTZY; | |||
import com.ruoyi.resource.domain.TResourceLand; | |||
import org.locationtech.jts.geom.MultiPolygon; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.stream.Collectors; | |||
public class GeoJtzyExportTask implements GeoDBExportTaskInterface | |||
{ | |||
private final static String TYPE_NAME = "地块属性"; | |||
private final GeoExportTask exportTask; | |||
private List<TResourceLand> list; | |||
public GeoJtzyExportTask(GeoExportTask exportTask) | |||
{ | |||
this.exportTask = exportTask; | |||
} | |||
public int LoadDataList() | |||
{ | |||
TResourceLand cond = new TResourceLand(); | |||
cond.setImportCode(exportTask.dept.getImportCode()); | |||
list = GeoMapperService.ResourceLandMapper().selectTResourceLandList(cond); | |||
exportTask.logFile.WriteLine(TYPE_NAME + "读取系统数据条数: 区划代码={}, 条数={}", exportTask.dept.getImportCode(), list.size()); | |||
return list.size(); | |||
} | |||
private GeoJTZY ConvertData(TResourceLand src, GeoJTZY dst) | |||
{ | |||
if(null == dst) | |||
dst = new GeoJTZY(); | |||
dst.the_geom = src.getTheGeom(); | |||
dst.BSM = src.getBsm(); | |||
dst.YSDM = src.getYsdm(); | |||
dst.DKBM = src.getDkbm(); | |||
dst.DKMC = src.getDkmc(); | |||
dst.SYQXZ = src.getSyqxz(); | |||
dst.DKLB = src.getDklb(); | |||
dst.DLDJ = src.getDldj(); | |||
dst.TDYT = src.getTdyt(); | |||
dst.SFJBNT = src.getSfjbnt(); | |||
dst.DKDZ = src.getDkdz(); | |||
dst.DKXZ = src.getDkxz(); | |||
dst.DKNZ = src.getDknz(); | |||
dst.DKBZ = src.getDkbz(); | |||
dst.ZJRXM = src.getZjrxm(); | |||
dst.DKBZXX = src.getDkbzxx(); | |||
dst.TXMJ = src.getTxmj(); | |||
dst.QSDWDM = src.getQsdwdm(); | |||
dst.QSDWMC = src.getQsdwmc(); | |||
dst.SFZWD = src.getSfzwd(); | |||
dst.SCMJM = src.getScmjm(); | |||
return dst; | |||
} | |||
public void SaveData() | |||
{ | |||
exportTask.logFile.WriteLine(TYPE_NAME + "开始导出数据: 区划代码={}, 条数={}", exportTask.dept.getDeptName(), list.size()); | |||
List<GeoJTZY> dataList = list.stream().map((x) -> ConvertData(x, null)).collect(Collectors.toList()); | |||
exportTask.writer.WriteList(dataList); | |||
} | |||
public Map<String, Class<?>> GetTypes() | |||
{ | |||
Map<String, Class<?>> types = GeoCreator.GetClassTypes(GeoJTZY.class); | |||
types.put("the_geom", MultiPolygon.class); | |||
return types; | |||
} | |||
} |
@@ -4,6 +4,7 @@ import cn.hutool.core.collection.ListUtil; | |||
import com.ruoyi.common.core.domain.entity.SysDept; | |||
import com.ruoyi.common.utils.StringUtils; | |||
import com.ruoyi.geo.service.GeoImportHandlerService; | |||
import com.ruoyi.geo.service.GeoMapperService; | |||
import com.ruoyi.geo.structs.GeoJTZY; | |||
import com.ruoyi.resource.domain.TResourceLand; | |||
import com.ruoyi.resource.mapper.TResourceLandMapper; | |||
@@ -15,14 +16,14 @@ import java.util.stream.Collectors; | |||
import static com.ruoyi.business.constants.TaskEnums.ImportType; | |||
public class GeoJtzyTask implements GeoDBTaskInterface | |||
public class GeoJtzyImportTask implements GeoDBImportTaskInterface | |||
{ | |||
private final static String TYPE_NAME = "地块属性"; | |||
private final GeoImportTask importTask; | |||
private List<GeoJTZY> list; | |||
public GeoJtzyTask(GeoImportTask importTask) | |||
public GeoJtzyImportTask(GeoImportTask importTask) | |||
{ | |||
this.importTask = importTask; | |||
} | |||
@@ -65,7 +66,7 @@ public class GeoJtzyTask implements GeoDBTaskInterface | |||
{ | |||
TResourceLand cond = new TResourceLand(); | |||
cond.setImportCode(qydm); | |||
List<TResourceLand> cjqies = GeoImportHandlerService.ResourceLandMapper().selectTResourceLandList(cond); | |||
List<TResourceLand> cjqies = GeoMapperService.ResourceLandMapper().selectTResourceLandList(cond); | |||
importTask.logFile.WriteLine(TYPE_NAME + "读取系统已存在的条数: 区划代码={}, 条数={}", qydm, cjqies.size()); | |||
return cjqies; | |||
} | |||
@@ -117,7 +118,7 @@ public class GeoJtzyTask implements GeoDBTaskInterface | |||
if(ImportType.IT_OVERRIDE.equals(importTask.taskImport.getImportType())) | |||
{ | |||
importTask.logFile.WriteLine(TYPE_NAME + "覆盖导入, 需清空现有数据, 然后再插入, 区划代码={}", importCode); | |||
int ret = GeoImportHandlerService.ResourceLandMapper().deleteByCode(importCode); | |||
int ret = GeoMapperService.ResourceLandMapper().deleteByCode(importCode); | |||
importTask.logFile.WriteLine(TYPE_NAME + "清空现有数据: {}, 区划代码={}", ret, importCode); | |||
return ret; | |||
} | |||
@@ -130,7 +131,7 @@ public class GeoJtzyTask implements GeoDBTaskInterface | |||
private int WriteData(List<TResourceLand> insertList, List<TResourceLand> updateList, SysDept dept) | |||
{ | |||
TResourceLandMapper gisCjqyMapper = GeoImportHandlerService.ResourceLandMapper(); | |||
TResourceLandMapper gisCjqyMapper = GeoMapperService.ResourceLandMapper(); | |||
int i = ListUtil.split(insertList, 30).stream().map(gisCjqyMapper::insertTResourceLandBatch).reduce(0, Integer::sum); | |||
importTask.logFile.WriteLine(TYPE_NAME + "新增数据: 区划代码={}, 条数={}", dept.getDeptName(), i); | |||
int u = ListUtil.split(updateList, 1).stream().map(gisCjqyMapper::updateTResourceLandBatch).reduce(0, Integer::sum); | |||
@@ -141,21 +142,29 @@ public class GeoJtzyTask implements GeoDBTaskInterface | |||
private int SaveDeptData(SysDept dept, List<GeoJTZY> datas) | |||
{ | |||
importTask.logFile.WriteLine(TYPE_NAME + "开始处理数据: 区划代码={}, 条数={}", dept.getDeptName(), datas.size()); | |||
List<TResourceLand> databases = LoadDatabase(dept.getImportCode()); | |||
Map<String, TResourceLand> exists = databases.stream().collect(Collectors.toMap(TResourceLand::getDkbm, x->x)); | |||
boolean needCheck = !ImportType.IT_OVERRIDE.equals(importTask.taskImport.getImportType()); | |||
Map<String, TResourceLand> exists = null; | |||
if(needCheck) | |||
{ | |||
List<TResourceLand> databases = LoadDatabase(dept.getImportCode()); | |||
exists = databases.stream().collect(Collectors.toMap(TResourceLand::getDkbm, x->x)); | |||
} | |||
List<TResourceLand> insertList = new ArrayList<>(); | |||
List<TResourceLand> updateList = new ArrayList<>(); | |||
for(GeoJTZY data : datas) | |||
{ | |||
TResourceLand db = exists.get(data.DKBM); | |||
boolean notExists = null == db; | |||
db = ConvertData(data, db, dept); | |||
if(notExists) | |||
insertList.add(db); | |||
TResourceLand db = null; | |||
if(needCheck) | |||
{ | |||
db = exists.get(data.DKBM); | |||
} | |||
TResourceLand item = ConvertData(data, db, dept); | |||
if(null == db) | |||
insertList.add(item); | |||
else | |||
updateList.add(db); | |||
updateList.add(item); | |||
} | |||
CleanDatabase(dept.getImportCode()); |
@@ -0,0 +1,74 @@ | |||
package com.ruoyi.geo.framework; | |||
import cn.hutool.core.util.StrUtil; | |||
import com.ruoyi.common.geo.GeoCreator; | |||
import com.ruoyi.common.utils.DecimalUtils; | |||
import com.ruoyi.geo.service.GeoMapperService; | |||
import com.ruoyi.geo.structs.GeoZYHYCG; | |||
import com.ruoyi.resource.domain.TResourceOperation; | |||
import org.locationtech.jts.geom.MultiPolygon; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.stream.Collectors; | |||
public class GeoZyhycgExportTask implements GeoDBExportTaskInterface | |||
{ | |||
private final static String TYPE_NAME = "地块经营"; | |||
private final GeoExportTask exportTask; | |||
private List<TResourceOperation> list; | |||
public GeoZyhycgExportTask(GeoExportTask exportTask) | |||
{ | |||
this.exportTask = exportTask; | |||
} | |||
public int LoadDataList() | |||
{ | |||
TResourceOperation cond = new TResourceOperation(); | |||
cond.setImportCode(exportTask.dept.getImportCode()); | |||
list = GeoMapperService.ResourceOperationMapper().selectTResourceOperationList(cond); | |||
exportTask.logFile.WriteLine(TYPE_NAME + "读取系统数据条数: 区划代码={}, 条数={}", exportTask.dept.getImportCode(), list.size()); | |||
return list.size(); | |||
} | |||
private GeoZYHYCG ConvertData(TResourceOperation src, GeoZYHYCG dst) | |||
{ | |||
if(null == dst) | |||
dst = new GeoZYHYCG(); | |||
dst.DKBM = src.getDkbm(); | |||
dst.DKMC = src.getDkmc(); | |||
dst.SYQXZ = src.getDkdz(); | |||
dst.JYMJ = src.getJymj(); | |||
dst.JYDXLX = src.getJydxlx(); | |||
dst.JYDXMC = src.getJydxmc(); | |||
dst.JYDXZJLX = src.getJydxzjlx(); | |||
dst.JYDXZJHM = src.getJydxzjhm(); | |||
dst.SFQDHT = src.getSfqdht(); | |||
dst.JYKSSJ = src.getJykssj(); | |||
dst.JYJSSJ = src.getJyjssj(); | |||
dst.CBJE = src.getCbje(); | |||
dst.DXJE = src.getDxje(); | |||
dst.SQJE = src.getSqje(); | |||
dst.NSY = src.getNsy(); | |||
dst.BZXX = src.getBzxx(); | |||
dst.JYFS = src.getJyfs(); | |||
return dst; | |||
} | |||
public void SaveData() | |||
{ | |||
exportTask.logFile.WriteLine(TYPE_NAME + "开始导出数据: 区划代码={}, 条数={}", exportTask.dept.getDeptName(), list.size()); | |||
List<GeoZYHYCG> dataList = list.stream().map((x) -> ConvertData(x, null)).collect(Collectors.toList()); | |||
exportTask.writer.WriteList(dataList); | |||
} | |||
public Map<String, Class<?>> GetTypes() | |||
{ | |||
return GeoCreator.GetClassTypes(GeoZYHYCG.class); | |||
} | |||
} |
@@ -5,7 +5,7 @@ import cn.hutool.core.util.StrUtil; | |||
import com.ruoyi.common.core.domain.entity.SysDept; | |||
import com.ruoyi.common.utils.DecimalUtils; | |||
import com.ruoyi.common.utils.StringUtils; | |||
import com.ruoyi.geo.service.GeoImportHandlerService; | |||
import com.ruoyi.geo.service.GeoMapperService; | |||
import com.ruoyi.geo.structs.GeoZYHYCG; | |||
import com.ruoyi.resource.domain.TResourceOperation; | |||
import com.ruoyi.resource.mapper.TResourceOperationMapper; | |||
@@ -17,14 +17,14 @@ import java.util.stream.Collectors; | |||
import static com.ruoyi.business.constants.TaskEnums.ImportType; | |||
public class GeoZyhycgTask implements GeoDBTaskInterface | |||
public class GeoZyhycgImportTask implements GeoDBImportTaskInterface | |||
{ | |||
private final static String TYPE_NAME = "地块经营"; | |||
private final GeoImportTask importTask; | |||
private List<GeoZYHYCG> list; | |||
public GeoZyhycgTask(GeoImportTask importTask) | |||
public GeoZyhycgImportTask(GeoImportTask importTask) | |||
{ | |||
this.importTask = importTask; | |||
} | |||
@@ -67,7 +67,7 @@ public class GeoZyhycgTask implements GeoDBTaskInterface | |||
{ | |||
TResourceOperation cond = new TResourceOperation(); | |||
cond.setImportCode(qydm); | |||
List<TResourceOperation> cjqies = GeoImportHandlerService.ResourceOperationMapper().selectTResourceOperationList(cond); | |||
List<TResourceOperation> cjqies = GeoMapperService.ResourceOperationMapper().selectTResourceOperationList(cond); | |||
importTask.logFile.WriteLine(TYPE_NAME + "读取系统已存在的条数: 区划代码={}, 条数={}", qydm, cjqies.size()); | |||
return cjqies; | |||
} | |||
@@ -115,7 +115,7 @@ public class GeoZyhycgTask implements GeoDBTaskInterface | |||
if(ImportType.IT_OVERRIDE.equals(importTask.taskImport.getImportType())) | |||
{ | |||
importTask.logFile.WriteLine(TYPE_NAME + "覆盖导入, 需清空现有数据, 然后再插入, 区划代码={}", importCode); | |||
int ret = GeoImportHandlerService.ResourceOperationMapper().deleteByCode(importCode); | |||
int ret = GeoMapperService.ResourceOperationMapper().deleteByCode(importCode); | |||
importTask.logFile.WriteLine(TYPE_NAME + "清空现有数据: {}, 区划代码={}", ret, importCode); | |||
return ret; | |||
} | |||
@@ -128,7 +128,7 @@ public class GeoZyhycgTask implements GeoDBTaskInterface | |||
private int WriteData(List<TResourceOperation> insertList, List<TResourceOperation> updateList, SysDept dept) | |||
{ | |||
TResourceOperationMapper gisCjqyMapper = GeoImportHandlerService.ResourceOperationMapper(); | |||
TResourceOperationMapper gisCjqyMapper = GeoMapperService.ResourceOperationMapper(); | |||
int i = ListUtil.split(insertList, 30).stream().map(gisCjqyMapper::insertTResourceOperationBatch).reduce(0, Integer::sum); | |||
importTask.logFile.WriteLine(TYPE_NAME + "新增数据: 区划代码={}, 条数={}", dept.getDeptName(), i); | |||
int u = ListUtil.split(updateList, 1).stream().map(gisCjqyMapper::updateTResourceOperationBatch).reduce(0, Integer::sum); | |||
@@ -139,21 +139,29 @@ public class GeoZyhycgTask implements GeoDBTaskInterface | |||
private int SaveDeptData(SysDept dept, List<GeoZYHYCG> datas) | |||
{ | |||
importTask.logFile.WriteLine(TYPE_NAME + "开始处理数据: 区划代码={}, 条数={}", dept.getDeptName(), datas.size()); | |||
List<TResourceOperation> databases = LoadDatabase(dept.getImportCode()); | |||
Map<String, TResourceOperation> exists = databases.stream().collect(Collectors.toMap(TResourceOperation::getDkbm, x->x)); | |||
boolean needCheck = !ImportType.IT_OVERRIDE.equals(importTask.taskImport.getImportType()); | |||
Map<String, TResourceOperation> exists = null; | |||
if(needCheck) | |||
{ | |||
List<TResourceOperation> databases = LoadDatabase(dept.getImportCode()); | |||
exists = databases.stream().collect(Collectors.toMap(TResourceOperation::getDkbm, x->x)); | |||
} | |||
List<TResourceOperation> insertList = new ArrayList<>(); | |||
List<TResourceOperation> updateList = new ArrayList<>(); | |||
for(GeoZYHYCG data : datas) | |||
{ | |||
TResourceOperation db = exists.get(data.DKBM); | |||
boolean notExists = null == db; | |||
db = ConvertData(data, db, dept); | |||
if(notExists) | |||
insertList.add(db); | |||
TResourceOperation db = null; | |||
if(needCheck) | |||
{ | |||
db = exists.get(data.DKBM); | |||
} | |||
TResourceOperation item = ConvertData(data, db, dept); | |||
if(null == db) | |||
insertList.add(item); | |||
else | |||
updateList.add(db); | |||
updateList.add(item); | |||
} | |||
CleanDatabase(dept.getImportCode()); |
@@ -0,0 +1,268 @@ | |||
package com.ruoyi.geo.service; | |||
import cn.hutool.core.io.FileUtil; | |||
import cn.hutool.core.io.file.FileNameUtil; | |||
import cn.hutool.core.lang.Assert; | |||
import cn.hutool.extra.servlet.ServletUtil; | |||
import com.ruoyi.business.domain.TTaskExport; | |||
import com.ruoyi.business.mapper.TTaskExportMapper; | |||
import com.ruoyi.common.constant.HttpStatus; | |||
import com.ruoyi.common.utils.StringUtils; | |||
import com.ruoyi.common.utils.sql.DB; | |||
import com.ruoyi.geo.config.GeoExportTaskConfig; | |||
import com.ruoyi.geo.constants.GeoSysDir; | |||
import com.ruoyi.geo.framework.GeoExportTask; | |||
import com.ruoyi.geo.framework.GeoTaskQueue; | |||
import com.ruoyi.geo.object.GeoLogInfo; | |||
import com.ruoyi.system.mapper.SysDeptMapper; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.springframework.stereotype.Service; | |||
import javax.annotation.PostConstruct; | |||
import javax.annotation.PreDestroy; | |||
import javax.annotation.Resource; | |||
import javax.servlet.http.HttpServletResponse; | |||
import java.io.File; | |||
import java.io.UnsupportedEncodingException; | |||
import java.net.URLEncoder; | |||
import java.nio.charset.StandardCharsets; | |||
import java.util.List; | |||
import java.util.stream.Collectors; | |||
import static com.ruoyi.business.constants.TaskEnums.TaskStatus; | |||
@Service | |||
@Slf4j | |||
public class GeoExportHandlerService | |||
{ | |||
@Resource | |||
private SysDeptMapper deptMapper; | |||
@Resource | |||
private TTaskExportMapper taskExportMapper; | |||
private GeoTaskQueue taskQueue; | |||
private synchronized GeoTaskQueue TaskQueue() | |||
{ | |||
if(null == taskQueue) | |||
taskQueue = new GeoTaskQueue(true); | |||
return taskQueue; | |||
} | |||
@PostConstruct | |||
public synchronized void Init() | |||
{ | |||
SyncTask(); | |||
LoadTask(); | |||
} | |||
@PreDestroy | |||
public synchronized void Shutdown() | |||
{ | |||
if(null != taskQueue) | |||
taskQueue.Quit(); | |||
} | |||
private void SyncTask() | |||
{ | |||
log.info("更改运行中的任务状态为中止......"); | |||
// 更改运行中的任务状态为中止 | |||
int i = taskExportMapper.terminateRunningTask(); | |||
log.info("已设置运行中的任务状态为中止: " + i); | |||
} | |||
private void LoadTask() | |||
{ | |||
if(!GeoExportTaskConfig.startOnBoot) | |||
return; | |||
log.info("拉取排队中的任务......"); | |||
TTaskExport cond = new TTaskExport(); | |||
cond.setTaskStatus(TaskStatus.ST_WAIT); | |||
List<TTaskExport> taskExports = taskExportMapper.selectTTaskExportList(cond); | |||
log.info("拉取到排队中的任务: " + taskExports.size()); | |||
List<Runnable> tasks = taskExports.stream().map((x) -> new GeoExportTask(x.getId())).collect(Collectors.toList()); | |||
if(!tasks.isEmpty()) | |||
TaskQueue().StartTask(tasks); | |||
} | |||
public GeoLogInfo loadExportLog(Long taskId, int offset) | |||
{ | |||
GeoLogInfo info = new GeoLogInfo(); | |||
info.setNextPollDelay(GeoExportTaskConfig.logNextPoll); | |||
TTaskExport taskExport = taskExportMapper.selectTTaskExportById(taskId); | |||
Assert.notNull(taskExport, "导出任务不存在"); | |||
info.setTaskStatus(taskExport.getTaskStatus()); | |||
if(TaskStatus.ST_READY.equals(taskExport.getTaskStatus())/* || TaskStatus.ST_WAIT.equals(taskExport.getTaskStatus())*/) | |||
{ | |||
info.setEof(true); | |||
info.setLength(-1); | |||
return info; | |||
} | |||
String path = GeoSysDir.ExportDir(GeoSysDir.LOG) + "/" + taskId + ".log"; | |||
if(!FileUtil.isFile(path)) | |||
{ | |||
info.setEof(true); | |||
info.setLength(-1); | |||
return info; | |||
} | |||
info.setEof(!TaskStatus.ST_RUNNING.equals(info.getTaskStatus()) && !TaskStatus.ST_WAIT.equals(info.getTaskStatus())); | |||
String str = FileUtil.readUtf8String(path); | |||
info.setLength(str.length()); | |||
String text; | |||
if(offset >= str.length() - 1) | |||
text = ""; | |||
else if(offset > 0) | |||
text = str.substring(offset); | |||
else | |||
text = str; | |||
info.setText(text); | |||
return info; | |||
} | |||
public synchronized int startTask(Long id) | |||
{ | |||
if(null != taskQueue) | |||
{ | |||
GeoExportTask task = (GeoExportTask)taskQueue.GetCurrentTask(); | |||
Assert.isFalse(null != task && task.GetTaskId().equals(id), "任务正在执行"); | |||
boolean exists = null != taskQueue.FindTask((x) -> { | |||
GeoExportTask t = (GeoExportTask) x; | |||
return(t.GetTaskId().equals(id)); | |||
}); | |||
Assert.isFalse(exists, "任务已在队列中"); | |||
} | |||
Object handler = DB.BeginTransaction(); | |||
try | |||
{ | |||
TTaskExport taskExport = taskExportMapper.getForUpdate(id); | |||
Assert.notNull(taskExport, "任务不存在"); | |||
Assert.isTrue(TaskStatus.ST_READY.equals(taskExport.getTaskStatus()), "任务非准备状态"); | |||
taskExport.setTaskStatus(TaskStatus.ST_WAIT); | |||
taskExportMapper.updateTTaskExport(taskExport); | |||
DB.CommitTransaction(handler); | |||
} | |||
catch(Exception e) | |||
{ | |||
e.printStackTrace(); | |||
DB.RollbackTransaction(handler); | |||
return 0; | |||
} | |||
int ret = null != taskQueue && taskQueue.HasTask() ? 1 : 2; | |||
TaskQueue().StartTask(new GeoExportTask(id)); | |||
return ret; | |||
} | |||
public void downloadLog(Long taskId, HttpServletResponse response) | |||
{ | |||
String path = GeoSysDir.ExportDir(GeoSysDir.LOG) + "/" + taskId + ".log"; | |||
String dlFileName; | |||
try | |||
{ | |||
dlFileName = URLEncoder.encode(FileNameUtil.getName(path), "UTF-8"); | |||
} | |||
catch(UnsupportedEncodingException e) | |||
{ | |||
e.printStackTrace(); | |||
dlFileName = ""; | |||
} | |||
int bytes = 0; | |||
response.reset(); | |||
response.addHeader("Access-Control-Allow-Origin", "*"); | |||
response.addHeader("Access-Control-Expose-Headers", "Content-Disposition"); | |||
response.setHeader("Content-Disposition", "attachment; filename=\"" + dlFileName + "\""); | |||
response.setContentType("application/octet-stream; charset=UTF-8"); | |||
TTaskExport taskExport = taskExportMapper.selectTTaskExportById(taskId); | |||
if(null == taskExport) | |||
{ | |||
response.setStatus(HttpStatus.NOT_FOUND); | |||
ServletUtil.write(response, "导出任务不存在", "application/octet-stream; charset=UTF-8"); | |||
bytes = "导出任务不存在".getBytes(StandardCharsets.UTF_8).length; | |||
response.addHeader("Content-Length", "" + bytes); | |||
return; | |||
} | |||
File file = new File(path); | |||
if(!file.isFile()) | |||
{ | |||
response.setStatus(HttpStatus.NOT_FOUND); | |||
ServletUtil.write(response, "日志文件不存在", "application/octet-stream; charset=UTF-8"); | |||
bytes = "日志文件不存在".getBytes(StandardCharsets.UTF_8).length; | |||
response.addHeader("Content-Length", "" + bytes); | |||
return; | |||
} | |||
ServletUtil.write(response, file); | |||
response.addHeader("Content-Length", "" + file.length()); | |||
} | |||
public void downloadFile(Long taskId, HttpServletResponse response) | |||
{ | |||
int bytes = 0; | |||
response.reset(); | |||
response.addHeader("Access-Control-Allow-Origin", "*"); | |||
response.addHeader("Access-Control-Expose-Headers", "Content-Disposition"); | |||
response.setHeader("Content-Disposition", "attachment; filename=\"" + taskId + ".zip\""); | |||
response.setContentType("application/octet-stream; charset=UTF-8"); | |||
TTaskExport taskExport = taskExportMapper.selectTTaskExportById(taskId); | |||
if(null == taskExport) | |||
{ | |||
response.setStatus(HttpStatus.NOT_FOUND); | |||
ServletUtil.write(response, "导出任务不存在", "application/octet-stream; charset=UTF-8"); | |||
bytes = "导出任务不存在".getBytes(StandardCharsets.UTF_8).length; | |||
response.addHeader("Content-Length", "" + bytes); | |||
return; | |||
} | |||
if(!TaskStatus.ST_FINISH.equals(taskExport.getTaskStatus())) | |||
{ | |||
response.setStatus(HttpStatus.FORBIDDEN); | |||
ServletUtil.write(response, "导出任务未完成", "application/octet-stream; charset=UTF-8"); | |||
bytes = "导出任务未完成".getBytes(StandardCharsets.UTF_8).length; | |||
response.addHeader("Content-Length", "" + bytes); | |||
return; | |||
} | |||
if(StringUtils.isEmpty(taskExport.getFileUrl())) | |||
{ | |||
response.setStatus(HttpStatus.NOT_FOUND); | |||
ServletUtil.write(response, "导出文件未生成", "application/octet-stream; charset=UTF-8"); | |||
bytes = "导出文件未生成".getBytes(StandardCharsets.UTF_8).length; | |||
response.addHeader("Content-Length", "" + bytes); | |||
return; | |||
} | |||
String path = GeoSysDir.GetDir(GeoSysDir.TrimProfile(taskExport.getFileUrl())); | |||
String dlFileName; | |||
try | |||
{ | |||
dlFileName = URLEncoder.encode(FileNameUtil.getName(path), "UTF-8"); | |||
} | |||
catch(UnsupportedEncodingException e) | |||
{ | |||
e.printStackTrace(); | |||
dlFileName = ""; | |||
} | |||
response.setHeader("Content-Disposition", "attachment; filename=\"" + dlFileName + "\""); | |||
File file = new File(path); | |||
if(!file.isFile()) | |||
{ | |||
ServletUtil.write(response, "导出文件不存在", "application/octet-stream; charset=UTF-8"); | |||
bytes = "导出文件不存在".getBytes(StandardCharsets.UTF_8).length; | |||
response.addHeader("Content-Length", "" + bytes); | |||
return; | |||
} | |||
ServletUtil.write(response, file); | |||
response.addHeader("Content-Length", "" + file.length()); | |||
} | |||
} |
@@ -6,7 +6,9 @@ import cn.hutool.core.lang.Assert; | |||
import cn.hutool.extra.servlet.ServletUtil; | |||
import com.ruoyi.business.domain.TTaskImport; | |||
import com.ruoyi.business.mapper.TGisCjqyMapper; | |||
import com.ruoyi.business.mapper.TTaskExportMapper; | |||
import com.ruoyi.business.mapper.TTaskImportMapper; | |||
import com.ruoyi.common.constant.HttpStatus; | |||
import com.ruoyi.common.utils.sql.DB; | |||
import com.ruoyi.geo.config.GeoImportTaskConfig; | |||
import com.ruoyi.geo.constants.GeoSysDir; | |||
@@ -38,57 +40,11 @@ public class GeoImportHandlerService | |||
{ | |||
@Resource | |||
private SysDeptMapper deptMapper; | |||
private static TTaskImportMapper taskImportMapper; | |||
private static TGisCjqyMapper gisCjqyMapper; | |||
private static TResourceLandMapper resourceLandMapper; | |||
private static TResourceOperationMapper resourceOperationMapper; | |||
@Resource | |||
private TTaskImportMapper taskImportMapper; | |||
private GeoTaskQueue taskQueue; | |||
@Autowired | |||
public void setTaskImportMapper(TTaskImportMapper taskImportMapper) | |||
{ | |||
GeoImportHandlerService.taskImportMapper = taskImportMapper; | |||
} | |||
@Autowired | |||
public void setGisCjqyMapper(TGisCjqyMapper gisCjqyMapper) | |||
{ | |||
GeoImportHandlerService.gisCjqyMapper = gisCjqyMapper; | |||
} | |||
@Autowired | |||
public void setResourceLandMapper(TResourceLandMapper resourceLandMapper) | |||
{ | |||
GeoImportHandlerService.resourceLandMapper = resourceLandMapper; | |||
} | |||
@Autowired | |||
public void setResourceOperationMapper(TResourceOperationMapper resourceOperationMapper) | |||
{ | |||
GeoImportHandlerService.resourceOperationMapper = resourceOperationMapper; | |||
} | |||
public static TTaskImportMapper TaskImportMapper() | |||
{ | |||
return taskImportMapper; | |||
} | |||
public static TGisCjqyMapper GisCjqyMapper() | |||
{ | |||
return gisCjqyMapper; | |||
} | |||
public static TResourceLandMapper ResourceLandMapper() | |||
{ | |||
return resourceLandMapper; | |||
} | |||
public static TResourceOperationMapper ResourceOperationMapper() | |||
{ | |||
return resourceOperationMapper; | |||
} | |||
private synchronized GeoTaskQueue TaskQueue() | |||
{ | |||
if(null == taskQueue) | |||
@@ -133,7 +89,7 @@ public class GeoImportHandlerService | |||
TaskQueue().StartTask(tasks); | |||
} | |||
public GeoLogInfo GetImportLog(Long taskId, int offset) | |||
public GeoLogInfo loadImportLog(Long taskId, int offset) | |||
{ | |||
GeoLogInfo info = new GeoLogInfo(); | |||
info.setNextPollDelay(GeoImportTaskConfig.logNextPoll); | |||
@@ -170,7 +126,7 @@ public class GeoImportHandlerService | |||
return info; | |||
} | |||
public synchronized int StartTask(Long id) | |||
public synchronized int startTask(Long id) | |||
{ | |||
if(null != taskQueue) | |||
{ | |||
@@ -205,7 +161,7 @@ public class GeoImportHandlerService | |||
return ret; | |||
} | |||
public void DownloadLog(Long taskId, HttpServletResponse response) | |||
public void downloadLog(Long taskId, HttpServletResponse response) | |||
{ | |||
String path = GeoSysDir.ImportDir(GeoSysDir.LOG) + "/" + taskId + ".log"; | |||
String dlFileName; | |||
@@ -230,18 +186,24 @@ public class GeoImportHandlerService | |||
TTaskImport taskImport = taskImportMapper.selectTTaskImportById(taskId); | |||
if(null == taskImport) | |||
{ | |||
response.setStatus(HttpStatus.NOT_FOUND); | |||
ServletUtil.write(response, "导入任务不存在", "application/octet-stream; charset=UTF-8"); | |||
bytes = "导入任务不存在".getBytes(StandardCharsets.UTF_8).length; | |||
response.addHeader("Content-Length", "" + bytes); | |||
return; | |||
} | |||
File file = new File(path); | |||
if(!file.isFile()) | |||
{ | |||
response.setStatus(HttpStatus.NOT_FOUND); | |||
ServletUtil.write(response, "日志文件不存在", "application/octet-stream; charset=UTF-8"); | |||
bytes = "日志文件不存在".getBytes(StandardCharsets.UTF_8).length; | |||
response.addHeader("Content-Length", "" + bytes); | |||
return; | |||
} | |||
ServletUtil.write(response, file); | |||
response.addHeader("Content-Length", "" + bytes); | |||
response.addHeader("Content-Length", "" + file.length()); | |||
} | |||
} |
@@ -0,0 +1,92 @@ | |||
package com.ruoyi.geo.service; | |||
import com.ruoyi.business.mapper.TGisCjqyMapper; | |||
import com.ruoyi.business.mapper.TTaskExportMapper; | |||
import com.ruoyi.business.mapper.TTaskImportMapper; | |||
import com.ruoyi.resource.mapper.TResourceLandMapper; | |||
import com.ruoyi.resource.mapper.TResourceOperationMapper; | |||
import com.ruoyi.system.mapper.SysDeptMapper; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.stereotype.Service; | |||
import javax.annotation.Resource; | |||
@Service | |||
@Slf4j | |||
public class GeoMapperService | |||
{ | |||
private static SysDeptMapper deptMapper; | |||
private static TTaskImportMapper taskImportMapper; | |||
private static TTaskExportMapper taskExportMapper; | |||
private static TGisCjqyMapper gisCjqyMapper; | |||
private static TResourceLandMapper resourceLandMapper; | |||
private static TResourceOperationMapper resourceOperationMapper; | |||
@Autowired | |||
public void setTaskImportMapper(TTaskImportMapper taskImportMapper) | |||
{ | |||
GeoMapperService.taskImportMapper = taskImportMapper; | |||
} | |||
@Autowired | |||
public void setTaskExportMapper(TTaskExportMapper taskExportMapper) | |||
{ | |||
GeoMapperService.taskExportMapper = taskExportMapper; | |||
} | |||
@Autowired | |||
public void setGisCjqyMapper(TGisCjqyMapper gisCjqyMapper) | |||
{ | |||
GeoMapperService.gisCjqyMapper = gisCjqyMapper; | |||
} | |||
@Autowired | |||
public void setResourceLandMapper(TResourceLandMapper resourceLandMapper) | |||
{ | |||
GeoMapperService.resourceLandMapper = resourceLandMapper; | |||
} | |||
@Autowired | |||
public void setResourceOperationMapper(TResourceOperationMapper resourceOperationMapper) | |||
{ | |||
GeoMapperService.resourceOperationMapper = resourceOperationMapper; | |||
} | |||
@Autowired | |||
public void setSysDeptMapper(SysDeptMapper deptMapper) | |||
{ | |||
GeoMapperService.deptMapper = deptMapper; | |||
} | |||
public static TTaskImportMapper TaskImportMapper() | |||
{ | |||
return taskImportMapper; | |||
} | |||
public static TTaskExportMapper TaskExportMapper() | |||
{ | |||
return taskExportMapper; | |||
} | |||
public static TGisCjqyMapper GisCjqyMapper() | |||
{ | |||
return gisCjqyMapper; | |||
} | |||
public static TResourceLandMapper ResourceLandMapper() | |||
{ | |||
return resourceLandMapper; | |||
} | |||
public static TResourceOperationMapper ResourceOperationMapper() | |||
{ | |||
return resourceOperationMapper; | |||
} | |||
public static SysDeptMapper DeptMapper() | |||
{ | |||
return deptMapper; | |||
} | |||
} |
@@ -153,4 +153,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
#{id} | |||
</foreach> | |||
</delete> | |||
<update id="terminateRunningTask"> | |||
update t_task_export | |||
set task_status = '5' | |||
where task_status = '2' | |||
</update> | |||
<select id="getForUpdate" parameterType="Long" resultMap="TTaskExportResult"> | |||
<include refid="selectTTaskExportVo"/> | |||
where id = #{id} FOR UPDATE | |||
</select> | |||
</mapper> |
@@ -2,6 +2,7 @@ package com.ruoyi.common.core.domain.entity; | |||
import com.ruoyi.common.annotation.Excel; | |||
import com.ruoyi.common.core.domain.BaseEntity; | |||
import lombok.Data; | |||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||
import org.apache.commons.lang3.builder.ToStringStyle; | |||
@@ -17,6 +18,7 @@ import java.util.List; | |||
* | |||
* @author ruoyi | |||
*/ | |||
@Data | |||
public class SysDept extends BaseEntity | |||
{ | |||
private static final long serialVersionUID = 1L; | |||
@@ -74,6 +76,10 @@ public class SysDept extends BaseEntity | |||
private List<SysDept> children = new ArrayList<SysDept>(); | |||
/** 祖先ID */ | |||
private Long rootId; | |||
public Long getDeptId() | |||
{ | |||
@@ -0,0 +1,160 @@ | |||
package com.ruoyi.common.geo; | |||
import cn.hutool.core.util.ClassUtil; | |||
import org.locationtech.jts.geom.GeometryFactory; | |||
import org.locationtech.jts.geom.LineString; | |||
import org.locationtech.jts.geom.LinearRing; | |||
import org.locationtech.jts.geom.MultiLineString; | |||
import org.locationtech.jts.geom.MultiPoint; | |||
import org.locationtech.jts.geom.MultiPolygon; | |||
import org.locationtech.jts.geom.Point; | |||
import org.locationtech.jts.geom.Polygon; | |||
import org.locationtech.jts.io.ParseException; | |||
import org.locationtech.jts.io.WKTReader; | |||
import java.lang.reflect.Field; | |||
import java.lang.reflect.Modifier; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
public final class GeoCreator | |||
{ | |||
private static GeoCreator geometryCreator = null; | |||
private static GeometryFactory geometryFactory = new GeometryFactory(); | |||
private GeoCreator() { | |||
} | |||
/** | |||
* 1.2根据几何对象的WKT描述【String】创建几何对象: 点 【Point】 | |||
* @return | |||
* @throws ParseException | |||
*/ | |||
public static Point PointByWKT(String PointWKT) { | |||
WKTReader reader = new WKTReader(geometryFactory); | |||
try | |||
{ | |||
return (Point) reader.read(PointWKT); | |||
} | |||
catch(ParseException e) | |||
{ | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
/** | |||
* 1.3根据几何对象的WKT描述【String】创建几何对象:多点 【MultiPoint】 | |||
* @return | |||
* @throws ParseException | |||
*/ | |||
public static MultiPoint MultiPointByWKT(String MPointWKT) { | |||
WKTReader reader = new WKTReader( geometryFactory ); | |||
try | |||
{ | |||
return (MultiPoint) reader.read(MPointWKT); | |||
} | |||
catch(ParseException e) | |||
{ | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
public static LineString LineStringByWKT(String LineStringWKT) { | |||
WKTReader reader = new WKTReader( geometryFactory ); | |||
try | |||
{ | |||
return (LineString) reader.read(LineStringWKT); | |||
} | |||
catch(ParseException e) | |||
{ | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
/** | |||
* 2.4根据几何对象的WKT描述【String】创建几何对象 : 多线【MultiLineString】 | |||
* @param MLineStringWKT | |||
* @return | |||
* @throws ParseException | |||
*/ | |||
public static MultiLineString MultiLineByWKT(String MLineStringWKT) { | |||
WKTReader reader = new WKTReader( geometryFactory ); | |||
try | |||
{ | |||
return (MultiLineString) reader.read(MLineStringWKT); | |||
} | |||
catch(ParseException e) | |||
{ | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
/** | |||
* 3.1 根据几何对象的WKT描述【String】创建几何对象:多边形 【Polygon】 | |||
* @param PolygonWKT | |||
* @return | |||
* @throws ParseException | |||
*/ | |||
public static Polygon PolygonByWKT(String PolygonWKT) { | |||
WKTReader reader = new WKTReader( geometryFactory ); | |||
try | |||
{ | |||
return (Polygon) reader.read(PolygonWKT); | |||
} | |||
catch(ParseException e) | |||
{ | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
/** | |||
* 3.2 根据几何对象的WKT描述【String】创建几何对象: 多多边形 【MultiPolygon】 | |||
* @param MPolygonWKT | |||
* @return | |||
* @throws ParseException | |||
*/ | |||
public static MultiPolygon MultiPolygonByWKT(String MPolygonWKT) { | |||
WKTReader reader = new WKTReader( geometryFactory ); | |||
try | |||
{ | |||
return (MultiPolygon) reader.read(MPolygonWKT); | |||
} | |||
catch(ParseException e) | |||
{ | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
/** | |||
* 6.1 根据WKT创建环 | |||
* @param ringWKT | |||
* @return | |||
* @throws ParseException | |||
*/ | |||
public static LinearRing LinearRingByWKT(String ringWKT) { | |||
WKTReader reader = new WKTReader( geometryFactory ); | |||
try | |||
{ | |||
return (LinearRing) reader.read(ringWKT); | |||
} | |||
catch(ParseException e) | |||
{ | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
public static Map<String, Class<?>> GetClassTypes(Class<?> clazz) | |||
{ | |||
Field[] fields = clazz.getDeclaredFields(); | |||
Map<String, Class<?>> ret = new HashMap<>(); | |||
for(Field field : fields) | |||
{ | |||
int modifiers = field.getModifiers(); | |||
if(Modifier.isStatic(modifiers) || Modifier.isFinal(modifiers) || !Modifier.isPublic(modifiers)) | |||
continue; | |||
ret.put(field.getName(), field.getType()); | |||
} | |||
return ret; | |||
} | |||
} |
@@ -0,0 +1,278 @@ | |||
package com.ruoyi.common.geo; | |||
import cn.hutool.core.bean.BeanUtil; | |||
import cn.hutool.core.bean.copier.CopyOptions; | |||
import cn.hutool.core.io.IoUtil; | |||
import cn.hutool.core.lang.Assert; | |||
import org.geotools.data.FeatureWriter; | |||
import org.geotools.data.Transaction; | |||
import org.geotools.data.shapefile.ShapefileDataStore; | |||
import org.geotools.data.shapefile.ShapefileDataStoreFactory; | |||
import org.geotools.data.simple.SimpleFeatureIterator; | |||
import org.geotools.data.simple.SimpleFeatureSource; | |||
import org.geotools.feature.simple.SimpleFeatureTypeBuilder; | |||
import org.geotools.referencing.crs.DefaultGeographicCRS; | |||
import org.locationtech.jts.geom.Geometry; | |||
import org.locationtech.jts.geom.LineString; | |||
import org.locationtech.jts.geom.LinearRing; | |||
import org.locationtech.jts.geom.MultiLineString; | |||
import org.locationtech.jts.geom.MultiPoint; | |||
import org.locationtech.jts.geom.MultiPolygon; | |||
import org.locationtech.jts.geom.Point; | |||
import org.locationtech.jts.geom.Polygon; | |||
import org.opengis.feature.simple.SimpleFeature; | |||
import org.opengis.feature.simple.SimpleFeatureType; | |||
import org.opengis.feature.type.AttributeDescriptor; | |||
import java.io.Closeable; | |||
import java.io.File; | |||
import java.io.Serializable; | |||
import java.nio.charset.Charset; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.HashMap; | |||
import java.util.LinkedHashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Set; | |||
import java.util.stream.Collectors; | |||
public final class GeoWriter implements Closeable | |||
{ | |||
private ShapefileDataStore dataStore; | |||
private FeatureWriter<SimpleFeatureType, SimpleFeature> writer; | |||
private SimpleFeatureSource source; | |||
private Map<String, Class<?>> columnMap; | |||
public GeoWriter() | |||
{ | |||
} | |||
public void Init() | |||
{ | |||
} | |||
@Override | |||
public void close() | |||
{ | |||
CloseSource(); | |||
if(null != dataStore) | |||
{ | |||
dataStore.dispose(); | |||
dataStore = null; | |||
} | |||
} | |||
public boolean Open(String path, String charsetName) | |||
{ | |||
return Open(new File(path), charsetName); | |||
} | |||
public boolean Open(File file, String charsetName) | |||
{ | |||
close(); | |||
try { | |||
Map<String, Serializable> params = new HashMap<>(); | |||
// 2、用于捕获参数需求的数据类 URLP:url to the .shp file. | |||
params.put(ShapefileDataStoreFactory.URLP.key, file.toURI().toURL()); | |||
dataStore = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params); | |||
Charset charset = Charset.forName(charsetName); | |||
dataStore.setCharset(charset); | |||
return true; | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
return false; | |||
} | |||
} | |||
private void CheckDataStore() | |||
{ | |||
Assert.notNull(dataStore, "请先打开"); | |||
} | |||
private void CheckWriter() | |||
{ | |||
Assert.notNull(writer, "请先打开写入"); | |||
} | |||
public void AddSchema(String name, Map<String, Class<?>> parms) | |||
{ | |||
CheckDataStore(); | |||
try { | |||
SimpleFeatureTypeBuilder tBuilder = new SimpleFeatureTypeBuilder(); | |||
// 5、设置 -- WGS84:一个二维地理坐标参考系统,使用WGS84数据 | |||
tBuilder.setCRS(DefaultGeographicCRS.WGS84); | |||
tBuilder.setName(name); | |||
parms.forEach(tBuilder::add); | |||
dataStore.createSchema(tBuilder.buildFeatureType()); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
public boolean SetSource(String typeName, boolean append) | |||
{ | |||
CloseSource(); | |||
CheckDataStore(); | |||
try { | |||
if(append) | |||
writer = dataStore.getFeatureWriterAppend(typeName, Transaction.AUTO_COMMIT); | |||
else | |||
writer = dataStore.getFeatureWriter(typeName, Transaction.AUTO_COMMIT); | |||
source = dataStore.getFeatureSource(typeName); | |||
return InitSource(); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
return false; | |||
} | |||
} | |||
public List<String> GetTypeNames() | |||
{ | |||
CheckDataStore(); | |||
try { | |||
return Arrays.stream(dataStore.getTypeNames()).collect(Collectors.toList()); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
return null; | |||
} | |||
} | |||
public boolean SetSource(int index, boolean append) | |||
{ | |||
CloseSource(); | |||
if(index < 0) | |||
return true; | |||
CheckDataStore(); | |||
return SetSource(GetTypeNames().get(index), append); | |||
} | |||
private void CloseSource() | |||
{ | |||
columnMap = null; | |||
if(null != writer) | |||
{ | |||
IoUtil.close(writer); | |||
writer = null; | |||
} | |||
} | |||
private boolean InitSource() | |||
{ | |||
if(null == writer) | |||
return false; | |||
try { | |||
if(null == columnMap) | |||
columnMap = new LinkedHashMap<>(); | |||
else | |||
columnMap.clear(); | |||
SimpleFeatureType schema = source.getSchema(); | |||
for(int i = 0; i < schema.getAttributeCount(); i++) | |||
{ | |||
AttributeDescriptor descriptor = schema.getDescriptor(i); | |||
columnMap.put(descriptor.getLocalName(), descriptor.getType().getBinding()); | |||
} | |||
return true; | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
return false; | |||
} | |||
} | |||
public Object ConvertValue(Class<?> clazz, Object value) | |||
{ | |||
if(Point.class.isAssignableFrom(clazz)) | |||
{ | |||
if(value instanceof Point) | |||
return value; | |||
else | |||
return GeoCreator.PointByWKT(value.toString()); | |||
} | |||
else if(MultiPoint.class.isAssignableFrom(clazz)) | |||
{ | |||
if(value instanceof MultiPoint) | |||
return value; | |||
else | |||
return GeoCreator.MultiPointByWKT(value.toString()); | |||
} | |||
else if(LineString.class.isAssignableFrom(clazz)) | |||
{ | |||
if(value instanceof LineString) | |||
return value; | |||
else | |||
return GeoCreator.LineStringByWKT(value.toString()); | |||
} | |||
else if(MultiLineString.class.isAssignableFrom(clazz)) | |||
{ | |||
if(value instanceof MultiLineString) | |||
return value; | |||
else | |||
return GeoCreator.MultiLineByWKT(value.toString()); | |||
} | |||
else if(Polygon.class.isAssignableFrom(clazz)) | |||
{ | |||
if(value instanceof Polygon) | |||
return value; | |||
else | |||
return GeoCreator.PolygonByWKT(value.toString()); | |||
} | |||
else if(MultiPolygon.class.isAssignableFrom(clazz)) | |||
{ | |||
if(value instanceof MultiPolygon) | |||
return value; | |||
else | |||
return GeoCreator.MultiPolygonByWKT(value.toString()); | |||
} | |||
else if(LinearRing.class.isAssignableFrom(clazz)) | |||
{ | |||
if(value instanceof LinearRing) | |||
return value; | |||
else | |||
return GeoCreator.LinearRingByWKT(value.toString()); | |||
} | |||
else | |||
return value; | |||
} | |||
public void WriteMapList(List<Map<String, Object>> list) | |||
{ | |||
CheckWriter(); | |||
try { | |||
Set<String> headers = columnMap.keySet(); | |||
for(Map<String, Object> map : list) | |||
{ | |||
SimpleFeature feature = writer.next(); | |||
for(String header : headers) | |||
{ | |||
Object value = map.get(header); | |||
if(null == value) | |||
continue; | |||
Class<?> clazz = columnMap.get(header); | |||
feature.setAttribute(header, ConvertValue(clazz, value)); | |||
} | |||
} | |||
writer.write(); | |||
} catch (Exception e) { | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
public void WriteList(List<?> list) | |||
{ | |||
List<Map<String, Object>> mapList = list.stream().map((x) -> BeanUtil.beanToMap(x, false, true)).collect(Collectors.toList()); | |||
WriteMapList(mapList); | |||
} | |||
} |
@@ -54,6 +54,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
<if test="status != null and status != ''"> | |||
AND status = #{status} | |||
</if> | |||
<if test="rootId != null ">and (dept_id = #{rootId} OR dept_id IN ( SELECT t.dept_id FROM sys_dept t WHERE find_in_set(#{rootId}, ancestors) ))</if> | |||
<!-- 数据范围过滤 --> | |||
${params.dataScope} | |||
</select> | |||