package com.fd.server.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.fd.constant.Command; import com.fd.constant.MsgCode; import com.fd.constant.TypeCode; import com.fd.dto.ConfigJsonDto; import com.fd.dto.PageDto; import com.fd.dto.StyleDto; import com.fd.entity.FileEntity; import com.fd.entity.OutputFileEntity; import com.fd.entity.StyleEntity; import com.fd.repository.FileRepository; import com.fd.repository.OutputFileRepository; import com.fd.repository.StyleRepository; import com.fd.server.CmdServer; import com.fd.server.VectorServer; import com.fd.util.FileUtils; import com.fd.util.R; import com.fd.util.RegexUtils; import lombok.extern.log4j.Log4j2; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; 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 2019/11/21 0021 15:29 */ @Log4j2 @Service //@Transactional public class VectorServerImpl implements VectorServer { @Value("${input.file.path.vector}") private String INPUT_FILE_PATH; @Value("${output.file.path.vector}") private String OUTPUT_FILE_PATH; @Value("${copy.file.path.vector}") private String MOVE_FILE_TO_SERVER; // config.json 地址 @Value("${config.path}") private String CONFIG_JSON_PATH; // config.json teileset 的相对路径 @Value("${config.tileset}") private String CONFIG_TILESET; @Autowired private FileRepository fileRepository; @Autowired private OutputFileRepository outputFileRepository; @Autowired private CmdServer cmdServer; @Autowired private StyleRepository styleRepository; // @Override // public R moveFileToServer(Long fileId, ConfigJsonDto param) { // Optional o = outputFileRepository.findById(fileId); // if (!o.isPresent()) { // log.info("id:{} 不存在", fileId); // return new R(50002, MsgCode.E50002); // } // OutputFileEntity entity = o.get(); // FileUtils.createDir(MOVE_FILE_TO_SERVER); // // try { // org.apache.commons.io.FileUtils.copyDirectoryToDirectory(new File(entity.getSlicePath()), new File(MOVE_FILE_TO_SERVER)); // // 修改前端的config.json 文件 // writeJsonFile(param, entity.getDirectory(), entity); // // //修改linux 文件权限 // String cmd = Command.CMD_CHOMD_755; // String slice = MOVE_FILE_TO_SERVER + entity.getDirectory(); // cmd = cmd.replace("@path", slice); // log.info("cmd: {}", cmd); // cmdServer.exeCmdInt(cmd); // // // entity.setStatus(8); // entity.setServicePath(slice); // entity.setUpdateTime(new Date()); // outputFileRepository.save(entity); // return new R(200, MsgCode.SUCCESS); // } catch (IOException e) { // e.printStackTrace(); // // 服务发布失败 // entity.setStatus(10); // entity.setUpdateTime(new Date()); // outputFileRepository.save(entity); // return new R(51004, MsgCode.E51004, e); // } // } @Override public R moveFileToServer(Long fileId, ConfigJsonDto param) { Optional o = outputFileRepository.findById(fileId); if (!o.isPresent()) { log.info("id:{} 不存在", fileId); return new R(50002, MsgCode.E50002); } OutputFileEntity entity = o.get(); // FileUtils.createDir(MOVE_FILE_TO_SERVER); try { // org.apache.commons.io.FileUtils.copyDirectoryToDirectory(new File(entity.getSlicePath()), new File(MOVE_FILE_TO_SERVER)); // 修改前端的config.json 文件 writeJsonFile(param, entity.getDirectory(), entity); //修改linux 文件权限 // String cmd = Command.CMD_CHOMD_755; // String slice = MOVE_FILE_TO_SERVER + entity.getDirectory(); // cmd = cmd.replace("@path", slice); // log.info("cmd: {}", cmd); // cmdServer.exeCmdInt(cmd); entity.setStatus(8); entity.setServicePath(entity.getSlicePath()); entity.setUpdateTime(new Date()); outputFileRepository.save(entity); return new R(200, MsgCode.SUCCESS); } catch (Exception e) { e.printStackTrace(); // 服务发布失败 entity.setStatus(10); entity.setUpdateTime(new Date()); outputFileRepository.save(entity); return new R(51004, MsgCode.E51004, e); } } @Override public R deleteById(Long fileId) { // 删除服务器文件 Optional e = outputFileRepository.findById(fileId); if (!e.isPresent()) { return new R(50002, MsgCode.E50002); } OutputFileEntity entity = e.get(); // 删除配置文件config.json制定行 StyleEntity styleEntity = styleRepository.findByOutputFileIdTop(fileId); if (styleEntity != null) { deleteRowConfigJson(styleEntity); } // 删除数据库记录 outputFileRepository.deleteById(fileId); fileRepository.deleteById(entity.getUploadId()); styleRepository.deleteByOutputFileId(fileId); // 删除文件 if (entity.getUploadPath() != null) { String path = entity.getUploadPath(); deleteFolder(path, entity); } if (entity.getUnZipPath() != null) { FileUtils.delFolder(entity.getUnZipPath()); } if (entity.getCoordGeneralPath() != null) { String path = entity.getCoordGeneralPath(); deleteFolder(path, entity); } if (entity.getCoordStrictPath() != null) { String path = entity.getCoordStrictPath(); deleteFolder(path, entity); } // 文件类型 if (entity.getGeojsonPath() != null) { log.info("test file geojson"); String path = entity.getGeojsonPath(); deleteFolder(path, entity); } if (entity.getSlicePath() != null) { FileUtils.delFolder(entity.getSlicePath()); } // 目录类型 // if (entity.getServicePath() != null) { // FileUtils.delFolder(entity.getServicePath()); // } return new R(200, MsgCode.SUCCESS); } // 以目录形式删除 private void deleteFolder(String path, OutputFileEntity entity) { String directory = entity.getDirectory(); int length = directory.length(); path = path.substring(0, path.lastIndexOf(directory) + length); log.warn("delete vector file: {}", path); FileUtils.delFolder(path); } // @Override // public R uploadDirectoryFile(MultipartFile file, String directoryName, String coord) { // // log.warn("run uploadBigFile"); // long start = System.currentTimeMillis(); // if (file.isEmpty() || file.getSize() <= 0) { // log.info("文件为空"); // return new R(50001, MsgCode.E50001); // } // // // 文件名全名 // String fullFileName = file.getOriginalFilename(); // // // 创建目录路径 // String filePath = INPUT_FILE_PATH + directoryName + File.separator; // FileUtils.createDir(filePath); // // // // 文件保存路径 // filePath = filePath + fullFileName; // // // 写文件到本地 // // try { // FileUtils.bigFileWrite(file.getInputStream(), filePath); // } catch (IOException e) { // e.printStackTrace(); // } // log.info("filePath: {}", filePath); // // // 保存信息到db // FileEntity entity = new FileEntity(); // entity.setFileName(fullFileName); // entity.setDirectory(directoryName); // entity.setFileUrl(filePath); // entity.setCreateTime(new Date()); // entity.setUpdateTime(new Date()); // entity.setType(TypeCode.FILE_TYPE_VECTOR); // entity.setCoord(coord); // entity.setStatus(2); // fileRepository.save(entity); // // OutputFileEntity outputFile = null; // String s = StringUtils.substringAfterLast(fullFileName, "."); // if ("shp".equals(s)) { // // outputFile = new OutputFileEntity(); // outputFile.setUploadId(entity.getId()); // outputFile.setUploadPath(entity.getFileUrl()); // outputFile.setFileName(entity.getFileName()); // outputFile.setStatus(2); // outputFile.setType(TypeCode.FILE_TYPE_VECTOR); // outputFile.setCoord(entity.getCoord()); // outputFile.setCreateTime(new Date()); // outputFile.setUpdateTime(new Date()); // // outputFile = outputFileRepository.save(outputFile); // } // // // long end = System.currentTimeMillis(); // log.info("end uploadBigFile, total time: {} s", (end - start) / 1000); // return new R(200, outputFile); // } @Override public R uploadDirectoryFileMul(MultipartFile[] files, String directoryName, String coord) { log.warn("run uploadDirectoryFileMul"); // 判断目录重名 // List en = fileRepository.findByDirectory(directoryName); List en = fileRepository.findByDirectoryAndResStatus(directoryName, 0); if (en.size() > 0) { return new R(51007, MsgCode.E51007); } // 创建目录路径 String filePath = INPUT_FILE_PATH + directoryName + File.separator; FileUtils.createDir(filePath); FileEntity entity = new FileEntity(); StringBuilder sb = new StringBuilder(); // 检查文件名、格式 int suffixCheckInt = 0; HashSet setPrefix = new HashSet<>(); // 记录shp 信息 boolean shpFlag = false; String shpName = ""; if (files != null && files.length > 0) { for (MultipartFile f : files) { String filename = f.getOriginalFilename(); // 文件是否包含中文字符 if (RegexUtils.regexChinese(filename)) { return new R(51005, MsgCode.E51005); } log.info("fileName : {}", filename); String s = StringUtils.substringAfterLast(filename, "."); // 判断后缀名,需要包含这以下四个 String [] suffixCheck = {"dbf","shp","shx","prj"}; if (Arrays.asList(suffixCheck).contains(s)) { suffixCheckInt += 1; // 判断前缀名字是否一致 String prefix = StringUtils.substringBeforeLast(filename, "."); setPrefix.add(prefix); } if ("shp".equals(s)) { shpFlag = true; shpName = filename; } try { FileUtils.bigFileWrite(f.getInputStream(), filePath + filename); } catch (IOException e) { e.printStackTrace(); } sb.append(filename).append(","); } } // 上传文件名是否一致 if (setPrefix.size() > 1) { log.info("文件名前缀不一致"); return new R(51009, MsgCode.E51009); } // 上传文件格式有误 if (suffixCheckInt != 4) { log.info("文件后缀名有误"); return new R(51008, MsgCode.E51008); } OutputFileEntity outputFile = new OutputFileEntity(); if (shpFlag) { entity.setDirectory(directoryName); entity.setFileName(sb.toString()); entity.setFileUrl(filePath + shpName); entity.setCreateTime(new Date()); entity.setUpdateTime(new Date()); entity.setType(TypeCode.FILE_TYPE_VECTOR); entity.setCoord(coord); entity.setResStatus(0); entity = fileRepository.save(entity); outputFile.setUploadId(entity.getId()); outputFile.setUploadPath(entity.getFileUrl()); outputFile.setDirectory(entity.getDirectory()); outputFile.setFileName(shpName); outputFile.setStatus(2); outputFile.setType(TypeCode.FILE_TYPE_VECTOR); outputFile.setCoord(entity.getCoord()); outputFile.setCreateTime(new Date()); outputFile.setUpdateTime(new Date()); outputFile.setResStatus(0); outputFile = outputFileRepository.save(outputFile); } return new R(200, outputFile); } // @Override // public R findByType(String type, PageDto pageDto) { // Page page = outputFileRepository.findByType(type, PageRequest.of(pageDto.getPageNum(), pageDto.getPageSize(), Sort.by("createTime").descending())); // return new R(200, page); // } @Override public R findByType(String type, PageDto pageDto) { Page page = outputFileRepository.findByTypeAndResStatus(type, 0, PageRequest.of(pageDto.getPageNum(), pageDto.getPageSize(), Sort.by("createTime").descending())); return new R(200, page); } @Override public List findByDirectory(String directory) { // return fileRepository.findByDirectory(directory); return fileRepository.findByDirectoryAndResStatus(directory, 0); } @Override public FileEntity findByUploadId(Long uploadId) { Optional o = fileRepository.findById(uploadId); if (o.isPresent()) { return o.get(); } return null; } /** * 修改样式 * * @param entity * @return */ @Override public R editStyle(StyleDto entity) { StyleEntity styleEntity = styleRepository.findByOutputFileIdTop(entity.getOutputFileId()); Optional o = outputFileRepository.findById(entity.getOutputFileId()); OutputFileEntity outputFileEntity = null; if (o.isPresent()) { outputFileEntity = o.get(); outputFileEntity.setStatus(11); outputFileEntity.setUpdateTime(new Date()); outputFileRepository.save(outputFileEntity); } styleEntity.setUpdateTime(new Date()); styleEntity.setContent(entity.getContent()); StyleEntity save = styleRepository.save(styleEntity); /** * 发布完成才允许这一步操作,因为第一次发布时,还没有样式在config里面 * * 发布时数据,已经把样式提交过去config了 */ editStyleConfigJson(save); return new R(200, save.getOutputFileId()); } @Override public StyleEntity saveStyle(StyleEntity entity) { return styleRepository.save(entity); } @Override public R getStyle(Long id) { return new R(200, styleRepository.findByOutputFileIdTop(id)); } @Override 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; } /** * 这个进度输出是从getErrorStream 输出 * @param commandStr * @param entity * @return */ @Override public Integer cmdSlice(String commandStr, OutputFileEntity entity) { log.info("run vector cmdSlice"); // 命令运行结果 1:失败, 0:成功 Integer isCmd = 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())); StringBuffer sb = new StringBuffer(); StringBuffer errorStr = new StringBuffer(); // error : 坑, 控制台信息是从errorBuf这里出来的 String errorLine; while ((errorLine = errorBuf.readLine()) != null) { errorStr.append(errorLine).append("\n"); log.info("error: {}", errorLine); // 获取进度 if (errorLine.contains("%")) { String s = StringUtils.substringBefore(errorLine, "%"); // 去除空白字符串 s = StringUtils.deleteWhitespace(s); // 只有是数字的 if (RegexUtils.regexInt(s)) { Integer round = (int) Math.round(Double.valueOf(s)); // log.info("round: {}", round); if (round % 5 == 0 ) { // log.info("round1: {}", round); entity.setUpdateTime(new Date()); entity.setProgress(round - 1); if (s.equals("99.9")) { entity.setProgress(100); } outputFileRepository.save(entity); } } } } if (StringUtils.isNotEmpty(errorStr)){ log.info("error result: {}", errorStr.toString()); } // success ,没有获取到信息 String line; while ((line = br.readLine()) != null) { //执行结果加上回车 sb.append(line).append("\n"); log.info("data: {}", 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); } else { log.info("wsitFore cmd run error : {}", isCmd); } return isCmd; } @Override public FileEntity findByInputFileId(Long fileId) { Optional o = fileRepository.findById(fileId); if (o.isPresent()){ FileEntity fileEntity = o.get(); return fileEntity; } return null; } @Override public FileEntity saveInputFile(FileEntity fileEntity) { FileEntity save = fileRepository.save(fileEntity); return save; } /** * 获取经纬度平均值 * * @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 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 map = new HashMap<>(); map.put("longitude", longitude); map.put("latitude", latitude); return map; } @Override public OutputFileEntity findById(Long fileId) { Optional o = outputFileRepository.findById(fileId); if (o.isPresent()) { return o.get(); } return null; } @Override public OutputFileEntity save(OutputFileEntity fileSchedule) { return outputFileRepository.save(fileSchedule); } /** * 发布服务 * 修改config.json */ // private void writeJsonFile(ConfigJsonDto param, String lastName, OutputFileEntity entity) { // // StyleEntity styleEntity = styleRepository.findByOutputFileIdTop(entity.getId()); // // String s = FileUtils.readFile(CONFIG_JSON_PATH); // // JSONObject original = JSON.parseObject(s); // // log.info("original: {}", s); // // JSONArray layers = JSON.parseArray(original.getString("layers")); // // JSONObject subJson = new JSONObject(); // long cu = System.currentTimeMillis(); // String name = "vector_" + cu; // // 需要唯一 // subJson.put("name", name); // // subJson.put("text", param.getText()); // // vector 就用这个类型geodata // subJson.put("type", "geodata"); // subJson.put("checked", false); // subJson.put("show", true); // subJson.put("url", "../data/" + lastName); //// subJson.put("style", JSON.parse(styleEntity.getContent())); // layers.add(subJson); // // original.put("layers", layers); // // log.info("original update: {}", original.toJSONString()); // try { // FileUtils.fileWriter(JSON.toJSONString(original), CONFIG_JSON_PATH); // // // 将图层信息保存到db // // 前端需要layer信息 // styleEntity.setLayer(subJson.toJSONString()); // styleEntity.setUpdateTime(new Date()); // styleEntity.setName(name); //// log.info("check test 2"); // styleRepository.save(styleEntity); //// log.info("check test 3"); // // } catch (IOException e) { // e.printStackTrace(); // } // } private void writeJsonFile(ConfigJsonDto param, String lastName, OutputFileEntity entity) { StyleEntity styleEntity = styleRepository.findByOutputFileIdTop(entity.getId()); String s = FileUtils.readFile(CONFIG_JSON_PATH); JSONObject original = JSON.parseObject(s); log.info("original: {}", s); JSONArray layers = JSON.parseArray(original.getString("layers")); JSONObject subJson = new JSONObject(); long cu = System.currentTimeMillis(); String name = "vector_" + cu; // 需要唯一 subJson.put("name", name); subJson.put("text", param.getText()); // vector 就用这个类型geodata subJson.put("type", "geodata"); subJson.put("checked", false); subJson.put("show", true); // subJson.put("url", "../data/" + lastName); String slicePath = entity.getSlicePath(); slicePath = slicePath.replace("/root/gis/cesium", ""); subJson.put("url", slicePath); layers.add(subJson); original.put("layers", layers); log.info("original update: {}", original.toJSONString()); try { FileUtils.fileWriter(JSON.toJSONString(original), CONFIG_JSON_PATH); // 将图层信息保存到db // 前端需要layer信息 styleEntity.setLayer(subJson.toJSONString()); styleEntity.setUpdateTime(new Date()); styleEntity.setName(name); styleRepository.save(styleEntity); } catch (IOException e) { e.printStackTrace(); } } /** * 删除指定行的config.json 数据 */ private void deleteRowConfigJson(StyleEntity entity) { String s = FileUtils.readFile(CONFIG_JSON_PATH); JSONObject original = JSON.parseObject(s); log.info("original: {}", s); JSONArray layers = JSON.parseArray(original.getString("layers")); for (int i = 0; i < layers.size(); i++) { JSONObject o = (JSONObject) layers.get(i); if (o.getString("name").equals(entity.getName())) { // 删除对象 layers.remove(i); } } // 更新json original.put("layers", layers); log.info("original update: {}", original.toJSONString()); // 更新config.json try { FileUtils.fileWriter(JSON.toJSONString(original), CONFIG_JSON_PATH); } catch (IOException e) { e.printStackTrace(); } } /** * 编辑样式,指定行的config.json 数据 * 添加样式 */ private void editStyleConfigJson(StyleEntity entity) { String s = FileUtils.readFile(CONFIG_JSON_PATH); JSONObject original = JSON.parseObject(s); log.info("original: {}", s); JSONArray layers = JSON.parseArray(original.getString("layers")); for (int i = 0; i < layers.size(); i++) { JSONObject o = (JSONObject) layers.get(i); if (o.getString("name").equals(entity.getName())) { log.warn("old sytle: {}", o.toJSONString()); //修改样式 o.put("style", JSON.parse(entity.getContent())); } } log.warn("update sytle: {}", layers.toJSONString()); // 更新json original.put("layers", layers); log.info("original update: {}", original.toJSONString()); // 更新config.json try { FileUtils.fileWriter(JSON.toJSONString(original), CONFIG_JSON_PATH); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws IOException { String inPath = "F:\\test\\clip\\aaa\\wwww"; String outPath = "F:\\test\\copy\\aaa\\123.com"; System.out.println(inPath.substring(0, inPath.lastIndexOf("aaa") + 3)); System.out.println(outPath.substring(0, outPath.lastIndexOf("aaa") + 3)); } }