package com.dji.sample.patches.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.dji.sample.patches.config.pojo.PatchesConfigPojo; import com.dji.sample.patches.constant.FileSufConstant; import com.dji.sample.patches.dao.ShpToDataSourceMapper; import com.dji.sample.patches.kml.KmlData; import com.dji.sample.patches.kml.KmlLine; import com.dji.sample.patches.kml.KmlPoint; import com.dji.sample.patches.kml.KmlPolygon; import com.dji.sample.patches.model.dto.ShpDTO; import com.dji.sample.patches.model.entity.LotInfo; import com.dji.sample.patches.service.ShpToDataSourceService; import com.dji.sample.patches.utils.*; import com.dji.sample.patches.xml.mode.XMLTemplateModel; import com.dji.sample.patches.xml.utils.CreateWaylineFileUtils; import com.dji.sample.territory.model.entity.TbDkjbxxEntity; import com.dji.sample.wayline.service.IWaylineFileService; import de.micromata.opengis.kml.v_2_2_0.Coordinate; import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.locationtech.jts.io.ParseException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.UUID; import static com.dji.sample.patches.utils.FormatConversionUtil.getCentros; import static com.dji.sample.patches.utils.MultipartFileTOFileUtil.convert; import static com.dji.sample.patches.utils.TimerUtil.getNowDay; import static com.dji.sample.patches.utils.ZipUtil.*; import static com.dji.sample.territory.utils.CoordinateSystemUtil.*; import static org.locationtech.jts.io.WKTConstants.POLYGON; @Service @Slf4j public class ShpToDataSourceServiceImpl implements ShpToDataSourceService { @Autowired private ShpToDataSourceMapper shpToDataSourceMapper; private String head = POLYGON; private MultipartFile multipartFile; String json; @Autowired private PatchesConfigPojo patchesConfigPojo; @Transactional public MultipartFile insertGeo(MultipartFile file, String workspaceId, String waylineName, double airportLat, double airportLon, String creator){ // zip 格式 if (file.getOriginalFilename().endsWith(FileSufConstant.FILE_SUFFIX_ZIP)) { List list = new ArrayList<>(); File file1 = MultipartFileTOFileUtil.multipartFile2File(file, patchesConfigPojo.getUnzip()); List shpData = null; try { shpData = ShapeFileUtil.shpToGeoJson(file1); } catch (IOException | ParseException e) { throw new RuntimeException(e); } for (ShpDTO shpDatum : shpData) { LotInfo lotInfo = new LotInfo(); String uuid = UUID.randomUUID().toString(); String bsm = uuid.replaceAll("-", ""); lotInfo.setBsm(bsm); lotInfo.setUserName(creator); lotInfo.setWorkspaceId(workspaceId); lotInfo.setDkfw(poylonCGCStoWGS(convertToWKT(shpDatum.getDKFW()))); lotInfo.setDkbh(shpDatum.getDKBH()); lotInfo.setXzb(shpDatum.getXZB()); lotInfo.setYzb(shpDatum.getYZB()); lotInfo.setXzqdm(shpDatum.getXZQDM()); lotInfo.setXmc(DistrictCodeUtils.codeToName(lotInfo.getXzqdm())); list.add(lotInfo); shpToDataSourceMapper.insert(lotInfo); } MultipartFile multipartFile = createWaylineFile(waylineName, airportLat, airportLon, list); MultipartFileTOFileUtil.deleteFile(file1); return multipartFile; } // kmz 格式 if (file.getOriginalFilename().endsWith(FileSufConstant.FILE_SUFFIX_KMZ)){ try { InputStream inputStream = file.getInputStream(); // 转换 kmz 文件并获取数据 KmlData kmlData = ParsingKmlUtil.parseKMZFile(inputStream); log.info("kmlData:{}",kmlData); MultipartFile multipartFile = insertLOTAndGetMultipartFile(workspaceId, waylineName, airportLat, airportLon, creator, kmlData); // 返回 if (multipartFile != null) return multipartFile; } catch (IOException e) { throw new RuntimeException(e); } } // kml 格式 if (file.getOriginalFilename().endsWith(FileSufConstant.FILE_SUFFIX_KML)) { try { InputStream inputStream = file.getInputStream(); KmlData kmlData = ParsingKmlUtil.parseKmlByInputstream(inputStream); log.info("kmlData:{}",kmlData); MultipartFile multipartFile = insertLOTAndGetMultipartFile(workspaceId, waylineName, airportLat, airportLon, creator, kmlData); // 返回 if (multipartFile != null) return multipartFile; } catch (IOException e) { throw new RuntimeException(e); } } return null; } /** * 保存图斑信息和生成航线文件 * @param workspaceId * @param waylineName * @param airportLat * @param airportLon * @param creator * @param kmlData * @return * @throws IOException */ @Nullable public MultipartFile insertLOTAndGetMultipartFile(String workspaceId, String waylineName, double airportLat, double airportLon, String creator, KmlData kmlData ) { if (null!=kmlData){ List list = new ArrayList<>(); // 点、线暂不处理 if (null!=kmlData.getKmlPoints() && kmlData.getKmlPoints().size()>0){ List kmlPointList = kmlData.getKmlPoints(); } if (null!=kmlData.getKmlLines() && kmlData.getKmlLines().size()>0){ List kmlLineList = kmlData.getKmlLines(); } // 处理面状数据 if (null!=kmlData.getKmlPolygons() && kmlData.getKmlPolygons().size()>0){ List kmlPolygonList = kmlData.getKmlPolygons(); // 保存图斑信息 this.saveLot(workspaceId, creator, list, kmlPolygonList); // 生成航线文件 MultipartFile multipartFile = createWaylineFile(waylineName, airportLat, airportLon, list); // 返回 return multipartFile; } } return null; } /** * 创建航线文件 * @param waylineName 航线名称 * @param airportLat * @param airportLon * @param list * @return * @throws IOException */ @NotNull public MultipartFile createWaylineFile(String waylineName, double airportLat, double airportLon, List list) { try { List coordinates = GeoToolsUtil.getRoutePointOrder(list, airportLat, airportLon); XMLTemplateModel xmlModel = XMLTemplateModel.init(coordinates, list); CreateWaylineFileUtils.createWaylineFile(xmlModel, patchesConfigPojo.getTemplate(), patchesConfigPojo.getTargetTemplate(), patchesConfigPojo.getWaylines(), patchesConfigPojo.getTargetWaylines()); // 压缩文件夹中的内容 String destKMZFile = patchesConfigPojo.getDestKMZFile() + waylineName + ".kmz"; // 输出的KMZ文件路径 zipFolder(patchesConfigPojo.getSourceDir(), destKMZFile); return convert(new File(destKMZFile)); }catch (IOException e){ throw new RuntimeException(e); } } /** * 保存图斑信息 * @param workspaceId * @param creator * @param list * @param kmlPolygonList */ public void saveLot(String workspaceId, String creator, List list, List kmlPolygonList) { for (KmlPolygon kmlPolygon : kmlPolygonList) { LotInfo lotInfo = new LotInfo(); String uuid = UUID.randomUUID().toString(); String bsm = uuid.replaceAll("-", ""); lotInfo.setBsm(bsm); lotInfo.setUserName(creator); lotInfo.setWorkspaceId(workspaceId); lotInfo.setDkbh(getNowDay()); lotInfo.setDkfw(handlePolygon(kmlPolygon.getPoints())); list.add(lotInfo); shpToDataSourceMapper.insert(lotInfo); } } /** * 处理面状数据 * @param coordinates * @return */ private String handlePolygon(List coordinates) { // 转换为WKT格式 StringBuilder wkt = new StringBuilder("POLYGON(("); for (Coordinate coordinate : coordinates) { wkt.append(coordinate.getLongitude()).append(" ").append(coordinate.getLatitude()).append(","); } // 添加第一个点的坐标以闭合多边形 wkt.append(coordinates.get(0).getLongitude()).append(" ").append(coordinates.get(0).getLatitude()).append("))"); // 返回 return wkt.toString(); } @Transactional public void savaInMysql(List list, String workspaceId,String id,String name) { for (int i = 0; i < list.size(); i++) { LotInfo lotInfo = new LotInfo(); lotInfo.setWorkspaceId(workspaceId); lotInfo.setTaskId(id); lotInfo.setType(2); lotInfo.setTaskName(name); lotInfo = dbConvertToEntity(list.get(i), workspaceId, id, name); shpToDataSourceMapper.insert(lotInfo); } } /** * 将SQlite数据库中DKJBXX对象转换为LotInfo对象。 * * @param file 需要转换的DKJBXX对象。 * @return 返回一个构建好的LotInfo对象,包含从数据库实体中转换来的信息。 */ private LotInfo dbConvertToEntity(TbDkjbxxEntity file, String workspaceId,String id,String name) { LotInfo.LotInfoBuilder builder = LotInfo.builder(); builder.bsm(file.getFId()) .xzqdm(file.getFXzqdm()) .dkbh(file.getFTbbh()) .dkfw(file.getFShape()) .workspaceId(workspaceId) .isPlan(0) .isPush(0) .xmc(DistrictCodeUtils.nameToCode(file.getFXzqdm())) .investigate(0) .taskId(id) .taskName(name) .build(); return builder.build(); } // private LotInfo shpDtoToLotInfo(ShpDTO shpDTO){ // LotInfo.LotInfoBuilder builder=LotInfo.builder(); // builder. // // } public List getNoPlan(){ return shpToDataSourceMapper.selectList(new LambdaQueryWrapper().eq(LotInfo::getIsPlan,0)); } public static String convertToWKT(String coordinates) { // Remove outermost square brackets and split by comma String cleanedCoordinates = coordinates.substring(4, coordinates.length() - 4); String[] polygons = cleanedCoordinates.split("\\]\\],\\[\\["); StringBuilder wkt = new StringBuilder("MULTIPOLYGON("); for (String polygon : polygons) { wkt.append("(("); String[] points = polygon.split("\\],\\["); for (String point : points) { String[] coords = point.split(","); double x = Double.parseDouble(coords[0]); double y = Double.parseDouble(coords[1]); wkt.append(x).append(" ").append(y).append(", "); } // Remove the last comma and space wkt.setLength(wkt.length() - 2); wkt.append(")), "); } // Remove the last comma and space, and close the polygon wkt.setLength(wkt.length() - 2); wkt.append(")"); return wkt.toString(); } }