|
@@ -0,0 +1,523 @@
|
|
|
+package com.gis.service.impl;
|
|
|
+
|
|
|
+import cn.hutool.core.date.DateTime;
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import cn.hutool.core.io.FileUtil;
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
+import com.gis.common.constant.Command;
|
|
|
+import com.gis.common.constant.ConfigConstant;
|
|
|
+import com.gis.common.constant.TypeCode;
|
|
|
+import com.gis.common.util.CmdUtils;
|
|
|
+import com.gis.common.util.RegexUtils;
|
|
|
+import com.gis.common.util.Result;
|
|
|
+import com.gis.domain.entity.VectorEntity;
|
|
|
+import com.gis.domain.request.PageDto;
|
|
|
+import com.gis.mapper.IBaseMapper;
|
|
|
+import com.gis.mapper.VectorMapper;
|
|
|
+import com.gis.service.VectorService;
|
|
|
+import com.github.pagehelper.PageInfo;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
+
|
|
|
+import java.io.BufferedReader;
|
|
|
+import java.io.File;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStreamReader;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * Created by owen on 2020/3/11 0011 16:16
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+public class VectorServiceImpl extends IBaseServiceImpl<VectorEntity, Long> implements VectorService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private VectorMapper entityMapper;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IBaseMapper<VectorEntity, Long> getBaseMapper() {
|
|
|
+ return this.entityMapper;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ ConfigConstant configConstant;
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 需要坐标转换
|
|
|
+ * CGCS_2000
|
|
|
+ */
|
|
|
+ private static int COORD_CONVERT_CGCS_2000 = 1000;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 需要坐标转换
|
|
|
+ * _XIAN_1980
|
|
|
+ */
|
|
|
+ private static int COORD_CONVERT_XIAN_1980 = 1001;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 不需要坐标转换
|
|
|
+ * WGS84
|
|
|
+ */
|
|
|
+ private static int COORD_NOT_WGS84 = 0;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Result upload(MultipartFile[] files, String[] coord) {
|
|
|
+
|
|
|
+ // 文件名前缀必须一致
|
|
|
+ // 必须包含以下四个后缀:"dbf","shp","shx","prj"
|
|
|
+ // 上传的文件名,字符拼接存到一个字段里
|
|
|
+ // 前端只显示shp的文件名
|
|
|
+ String time = DateUtil.format(new Date(), "yyyyMMdd_HHmmssSSS");
|
|
|
+ String basePath = configConstant.serverBasePath + time + "/";
|
|
|
+ VectorEntity entity = new VectorEntity();
|
|
|
+ String shpName = "";
|
|
|
+ String savePath = "";
|
|
|
+ // 文件名拼接
|
|
|
+ StringBuffer allFileName = new StringBuffer();
|
|
|
+
|
|
|
+ // 文件名前缀
|
|
|
+ String prefixName = "";
|
|
|
+ // 检查文件名、格式
|
|
|
+ int suffixCheckInt = 0;
|
|
|
+
|
|
|
+
|
|
|
+ // 判断后缀名,需要包含这以下四个
|
|
|
+ String [] suffixCheck = {"dbf","shp","shx","prj"};
|
|
|
+
|
|
|
+ try {
|
|
|
+ int i = 1;
|
|
|
+ for (MultipartFile file: files) {
|
|
|
+
|
|
|
+ String fileName = file.getOriginalFilename();
|
|
|
+ // 上传的文件名,字符串拼接存到一个字段里
|
|
|
+ allFileName.append(fileName).append(",");
|
|
|
+
|
|
|
+
|
|
|
+ // 拿第一个文件名做为前缀
|
|
|
+ if (i == 1) {
|
|
|
+ prefixName = StringUtils.substringBeforeLast(fileName, ".");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 文件名前缀必须一致
|
|
|
+ if (!StringUtils.startsWith(fileName, prefixName)) {
|
|
|
+ log.info("文件名前缀不一致");
|
|
|
+ return Result.failure("文件名前缀不一致");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 后缀名
|
|
|
+ String suffix = StringUtils.substringAfterLast(fileName, ".");
|
|
|
+ // 必须包含以下四个后缀:"dbf","shp","shx","prj"
|
|
|
+ if (Arrays.asList(suffixCheck).contains(suffix)) {
|
|
|
+ suffixCheckInt += 1;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 保存shp信息
|
|
|
+ if (StringUtils.endsWith(fileName, ".shp")) {
|
|
|
+ shpName = fileName;
|
|
|
+ savePath = basePath + fileName;
|
|
|
+ }
|
|
|
+ FileUtil.writeFromStream(file.getInputStream(), basePath+fileName);
|
|
|
+
|
|
|
+ i ++;
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // 上传文件格式有误
|
|
|
+ if (suffixCheckInt != 4) {
|
|
|
+ log.info("文件后缀名有误");
|
|
|
+ return Result.failure("文件后缀名有误,请检查清楚再上传");
|
|
|
+ }
|
|
|
+
|
|
|
+ entity.setFileName(shpName);
|
|
|
+ entity.setCode(time);
|
|
|
+ entity.setFilePath(savePath);
|
|
|
+ entity.setCoord(Arrays.toString(coord));
|
|
|
+ entity.setOriginalName(allFileName.toString());
|
|
|
+ this.save(entity);
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ return Result.success(entity);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Result search(PageDto param) {
|
|
|
+ startPage(param);
|
|
|
+ List<VectorEntity> all = this.findAll();
|
|
|
+ return Result.success(new PageInfo<>(all));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Result remove(Long id) {
|
|
|
+ VectorEntity entity = this.findById(id);
|
|
|
+ if (entity == null) {
|
|
|
+ log.info("对象不存在: " + id);
|
|
|
+ return Result.failure("对象不存在");
|
|
|
+ }
|
|
|
+ String code = entity.getCode();
|
|
|
+ // 安全校验,rm -rf 删除需要严谨
|
|
|
+ if (StringUtils.isBlank(code)) {
|
|
|
+ log.error("目录编码不能为空");
|
|
|
+ return Result.failure("目录编码不能为空");
|
|
|
+ }
|
|
|
+ String fileDir = configConstant.serverBasePath + code;
|
|
|
+
|
|
|
+ String cmd = Command.remove;
|
|
|
+ cmd = cmd.replace("@input", fileDir);
|
|
|
+ log.info("cmd: " + cmd);
|
|
|
+ long stat = System.currentTimeMillis();
|
|
|
+ CmdUtils.callShell(cmd);
|
|
|
+ long end = System.currentTimeMillis();
|
|
|
+ log.info("文件删除完成,耗时: {} s" , (end-stat)/1000);
|
|
|
+
|
|
|
+ entity.setIsDelete(1);
|
|
|
+ entity.setUpdateTime(new Date());
|
|
|
+ this.update(entity);
|
|
|
+ return Result.success();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Result slice(Long id, String layerMin, String layerMax) {
|
|
|
+
|
|
|
+ if (!RegexUtils.regexInt(layerMin)) {
|
|
|
+ return Result.failure("非数字类型");
|
|
|
+ }
|
|
|
+ if (!RegexUtils.regexInt(layerMax)) {
|
|
|
+ return Result.failure("非数字类型");
|
|
|
+ }
|
|
|
+
|
|
|
+ VectorEntity entity = this.findById(id);
|
|
|
+ if (entity == null) {
|
|
|
+ log.info("对象不存在: " + id);
|
|
|
+ return Result.failure("对象不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ String outputPath = configConstant.serverBasePath + entity.getCode() + "/slice";
|
|
|
+ // 命令不会主动创建目录
|
|
|
+ FileUtil.mkdir(outputPath);
|
|
|
+ // 传入的是目录
|
|
|
+ String cmd = Command.VECTOR_SLICE_TIPPECANOE;
|
|
|
+ cmd = cmd.replace("@inputFile", entity.getGeojsonPath());
|
|
|
+ cmd = cmd.replace("@outputFile", outputPath);
|
|
|
+ cmd = cmd.replace("@layerMin", layerMin);
|
|
|
+ cmd = cmd.replace("@layerMax", layerMax);
|
|
|
+ log.info("cmd: {}", cmd);
|
|
|
+
|
|
|
+ // todo 可能需要做进度条
|
|
|
+ long stat = System.currentTimeMillis();
|
|
|
+ CmdUtils.cmdShell(cmd);
|
|
|
+ long end = System.currentTimeMillis();
|
|
|
+ log.info("栅格数据切片完成,耗时: {} s, id: {}" , (end-stat)/1000, id);
|
|
|
+
|
|
|
+ // todo 数据切片完成,这里可能需要一个切片中的状态
|
|
|
+ entity.setStatus(3);
|
|
|
+ entity.setSlicePath(outputPath);
|
|
|
+ entity.setLayerMin(layerMin);
|
|
|
+ entity.setLayerMax(layerMax);
|
|
|
+ entity.setUpdateTime(new Date());
|
|
|
+ this.update(entity);
|
|
|
+ return Result.success(entity);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 上传后判断坐标,显示原始坐标
|
|
|
+ * 20210312
|
|
|
+ * 需要把样式的经纬度显示出来(还没做)
|
|
|
+ *
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Result coordJudge(Long id) {
|
|
|
+ VectorEntity entity = this.findById(id);
|
|
|
+ if (entity == null) {
|
|
|
+ log.info("对象不存在: " + id);
|
|
|
+ return Result.failure("对象不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取坐标类型
|
|
|
+ String coordType = getCoordType(entity.getFilePath());
|
|
|
+
|
|
|
+ entity.setCoordType(coordType);
|
|
|
+ entity.setUpdateTime(new Date());
|
|
|
+
|
|
|
+ Map<String, String> strictMap = getStrict(entity);
|
|
|
+ // 有错误日志
|
|
|
+ if (strictMap.get("log") != null) {
|
|
|
+ return Result.failure(strictMap.get("log"));
|
|
|
+ }
|
|
|
+ entity.setCoordStrictPath(strictMap.get("strictPath"));
|
|
|
+ this.update(entity);
|
|
|
+
|
|
|
+ return Result.success(entity);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private String getCoordType(String filePath){
|
|
|
+ // 判断是否需要坐标转换
|
|
|
+ String cmd = Command.VECTOR_JUDGE_COORD;
|
|
|
+ cmd = cmd.replace("@inputFile", filePath);
|
|
|
+ log.info("cmd: {}", cmd);
|
|
|
+ Map map = cmdJudgeCoord(cmd);
|
|
|
+ Integer code = (int) map.get("code");
|
|
|
+ log.info("judgeCoord code: {}", code);
|
|
|
+
|
|
|
+ String coordType = null;
|
|
|
+
|
|
|
+
|
|
|
+ // 转换坐标 普通坐标转换
|
|
|
+ if (code == COORD_CONVERT_CGCS_2000) {
|
|
|
+ // 普通坐标转换
|
|
|
+ log.info("need to general transform");
|
|
|
+ coordType = TypeCode.COORD_SYSTEM_2000;
|
|
|
+ } else if (code == COORD_CONVERT_XIAN_1980) {
|
|
|
+
|
|
|
+ // 严格坐标转换 (西安80转wgs84),需要参数
|
|
|
+ log.info("need to strict transform, code: {}", code);
|
|
|
+ coordType = TypeCode.COORD_XIAN_1980;
|
|
|
+
|
|
|
+ } else if (0 == COORD_NOT_WGS84) {
|
|
|
+ // 不转换坐标 把文件信息移动到CoordStrictPath 这路径下
|
|
|
+ log.info("not to transform");
|
|
|
+ coordType = TypeCode.COORD_WGS84;
|
|
|
+
|
|
|
+ }
|
|
|
+ return coordType;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Result toGeoJson(Long id) {
|
|
|
+ VectorEntity entity = this.findById(id);
|
|
|
+ if (entity == null) {
|
|
|
+ log.info("对象不存在: " + id);
|
|
|
+ return Result.failure("对象不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ String fileName = StringUtils.substringBefore(entity.getFileName(), ".");
|
|
|
+ String geoJsonPath = configConstant.serverBasePath+entity.getCode() +"/" + fileName + ".json";
|
|
|
+
|
|
|
+ String cmd = Command.VECTOR_TO_GEOJSON;
|
|
|
+ cmd = cmd.replace("@inputFile", entity.getCoordStrictPath());
|
|
|
+ cmd = cmd.replace("@outputFile", geoJsonPath);
|
|
|
+ log.info("cmd: {}", cmd);
|
|
|
+ CmdUtils.cmdShell(cmd);
|
|
|
+ log.info("矢量数据转geoJson完成: {}", cmd);
|
|
|
+
|
|
|
+ entity.setGeojsonPath(geoJsonPath);
|
|
|
+ entity.setUpdateTime(new Date());
|
|
|
+ this.update(entity);
|
|
|
+ return Result.success(entity);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 坐标判断
|
|
|
+ public Map cmdJudgeCoord(String commandStr) {
|
|
|
+ // 命令运行结果 1:失败, 0:成功
|
|
|
+ Integer isCmd = null;
|
|
|
+
|
|
|
+ StringBuffer sb = new StringBuffer();
|
|
|
+ StringBuffer errorStr = new StringBuffer();
|
|
|
+
|
|
|
+ Map map = null;
|
|
|
+ try {
|
|
|
+ String[] cmd = new String[]{"/bin/sh", "-c", commandStr};
|
|
|
+ Process ps = Runtime.getRuntime().exec(cmd);
|
|
|
+
|
|
|
+ BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));
|
|
|
+ BufferedReader errorBuf = new BufferedReader(new InputStreamReader(ps.getErrorStream()));
|
|
|
+
|
|
|
+ // error : 坑, 控制台信息是从errorBuf这里出来的
|
|
|
+ String errorLine;
|
|
|
+ while ((errorLine = errorBuf.readLine()) != null) {
|
|
|
+ errorStr.append(errorLine).append("\n");
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotEmpty(errorStr)) {
|
|
|
+ log.info("error result: {}", errorStr.toString());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // success ,没有获取到信息
|
|
|
+ String line;
|
|
|
+ while ((line = br.readLine()) != null) {
|
|
|
+ //执行结果加上回车
|
|
|
+ sb.append(line).append("\n");
|
|
|
+ // 获取经纬度
|
|
|
+
|
|
|
+ if (line.contains("Extent: (")) {
|
|
|
+ log.info("extent: {}", line);
|
|
|
+ map = getExtent(line);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ log.info("result: {}", sb.toString());
|
|
|
+
|
|
|
+ // 结束命令行
|
|
|
+ isCmd = ps.waitFor();
|
|
|
+
|
|
|
+
|
|
|
+ // 关闭流
|
|
|
+ br.close();
|
|
|
+ errorBuf.close();
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (isCmd == 0) {
|
|
|
+ log.info("end exeCmd : {}", isCmd);
|
|
|
+ // 判断坐标
|
|
|
+ if (sb.toString().contains("GEOGCS[\"China Geodetic Coordinate System 2000\"")) {
|
|
|
+ // 需要普通坐标转换
|
|
|
+ isCmd = 1000;
|
|
|
+ map.put("code", isCmd);
|
|
|
+ log.info("需要坐标转换code:{}, GEOGCS[\"China Geodetic Coordinate System 2000\"", isCmd);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (sb.toString().contains("GEOGCS[\"Xian 1980\"")) {
|
|
|
+ // 需要严格坐标转换
|
|
|
+ isCmd = 1001;
|
|
|
+ map.put("code", isCmd);
|
|
|
+ log.info("需要严格坐标转换code:{}, GEOGCS[\"Xian 1980\"", isCmd);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (sb.toString().contains("GEOGCS[\"WGS 84\"")) {
|
|
|
+ // 不需要坐标转换
|
|
|
+ isCmd = 0;
|
|
|
+ map.put("code", isCmd);
|
|
|
+ log.info("不需要坐标转换code:{}, GEOGCS[\"WGS 84\"", isCmd);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ } else {
|
|
|
+ map.put("code", isCmd);
|
|
|
+ log.info("error exeCmd wsitFore: {}", isCmd);
|
|
|
+ }
|
|
|
+
|
|
|
+ return map;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取经纬度平均值
|
|
|
+ *
|
|
|
+ * @param str 传入参数
|
|
|
+ * @return map
|
|
|
+ */
|
|
|
+ private Map getExtent(String str) {
|
|
|
+
|
|
|
+ str = str.replace("Extent: (", "");
|
|
|
+ str = str.replaceAll("\\(", "");
|
|
|
+ str = str.replaceAll("\\)", "");
|
|
|
+ str = str.replaceAll(" -", ",");
|
|
|
+
|
|
|
+ // 去除所有空白字符
|
|
|
+ str = StringUtils.deleteWhitespace(str);
|
|
|
+ String[] strArray = str.split(",");
|
|
|
+ List<String> list = Arrays.asList(strArray);
|
|
|
+ log.info("extent list: {}", Arrays.asList(strArray));
|
|
|
+
|
|
|
+ BigDecimal b0 = new BigDecimal(list.get(0));
|
|
|
+ BigDecimal b1 = new BigDecimal(list.get(1));
|
|
|
+ BigDecimal b2 = new BigDecimal(list.get(2));
|
|
|
+ BigDecimal b3 = new BigDecimal(list.get(3));
|
|
|
+
|
|
|
+ // 经度
|
|
|
+ BigDecimal longitude = b0.add(b2);
|
|
|
+ longitude = longitude.divide(new BigDecimal(2), 6, BigDecimal.ROUND_HALF_UP);
|
|
|
+ // 纬度
|
|
|
+ BigDecimal latitude = b1.add(b3);
|
|
|
+ latitude = latitude.divide(new BigDecimal(2), 6, BigDecimal.ROUND_HALF_UP);
|
|
|
+
|
|
|
+ HashMap<Object, Object> map = new HashMap<>();
|
|
|
+ map.put("longitude", longitude);
|
|
|
+ map.put("latitude", latitude);
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * vector 严格坐标转换
|
|
|
+ * 矢量数据转坐标只转一次就成功了
|
|
|
+ * 获取严格坐标转换后的地址
|
|
|
+ */
|
|
|
+ private Map<String, String> getStrict(VectorEntity entity) {
|
|
|
+
|
|
|
+ String basePath = configConstant.serverBasePath + entity.getCode();
|
|
|
+ String strictCoordPath = basePath + "/strict";
|
|
|
+ FileUtil.mkdir(strictCoordPath);
|
|
|
+ strictCoordPath = strictCoordPath + "/" + entity.getFileName();
|
|
|
+
|
|
|
+ // 坐标处理
|
|
|
+ String coord = entity.getCoord();
|
|
|
+ String filePath = entity.getFilePath();
|
|
|
+ log.info("convert coord: {}", coord);
|
|
|
+ JSONArray arrayCoord = JSON.parseArray(coord);
|
|
|
+
|
|
|
+ HashMap<String, String> map = new HashMap<>();
|
|
|
+ String errorLog = null;
|
|
|
+
|
|
|
+ // 转换坐标 普通坐标转换
|
|
|
+ if (TypeCode.COORD_SYSTEM_2000.equals(entity.getCoordType())) {
|
|
|
+ // 普通坐标转换
|
|
|
+ log.info("need to general transform");
|
|
|
+ if (arrayCoord.size() == 0) {
|
|
|
+ // 没有坐标参数,执行普通坐标转换(ogrinfo)
|
|
|
+ log.info("run generalCoordTransform");
|
|
|
+ coordTransform(Command.VECTOR_TRANSFORM_GENERAL, filePath, strictCoordPath);
|
|
|
+
|
|
|
+ } else {
|
|
|
+ // 有坐标参数,执行严格坐标转换(CGCS2000转wgs80)
|
|
|
+ log.info("run strictCoordTransform");
|
|
|
+ coordTransform(Command.VECTOR_TRANSFORM_STRICT_WGS80, filePath, strictCoordPath);
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if (TypeCode.COORD_XIAN_1980.equals(entity.getCoordType())) {
|
|
|
+
|
|
|
+ // 严格坐标转换 (西安80转wgs84),需要参数
|
|
|
+ log.info("need to strict transform, CoordType: {}", entity.getCoordType());
|
|
|
+ if (arrayCoord.size() == 0) {
|
|
|
+ errorLog = "西安80转wgs84需要坐标参数,转换失败";
|
|
|
+ log.error("errorLog");
|
|
|
+ } else {
|
|
|
+ log.info("run strictCoordTransform");
|
|
|
+ coordTransform(Command.VECTOR_TRANSFORM_STRICT_WGS84, filePath, strictCoordPath);
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if (TypeCode.COORD_WGS84.equals(entity.getCoordType())) {
|
|
|
+ // 不转换坐标 把文件信息移动到CoordStrictPath 这路径下
|
|
|
+ log.info("not to transform");
|
|
|
+ strictCoordPath = filePath;
|
|
|
+ }
|
|
|
+
|
|
|
+ map.put("strictPath", strictCoordPath);
|
|
|
+ map.put("log", errorLog);
|
|
|
+
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 坐标转换
|
|
|
+ */
|
|
|
+ private void coordTransform(String cmd, String inputPath, String outPath) {
|
|
|
+
|
|
|
+ cmd = cmd.replace("@inputFile", inputPath);
|
|
|
+ cmd = cmd.replace("@outputFile", outPath);
|
|
|
+ log.info("cmd: {}", cmd);
|
|
|
+ CmdUtils.cmdShell(cmd);
|
|
|
+ log.info("坐标转换完成");
|
|
|
+ }
|
|
|
+
|
|
|
+}
|