zrj
2024-08-20 8b7b86f12fab51fe21b5575f4ffd524fbeaf412b
图斑上传新增kmz,kml 上传解析代码同步
6 files modified
11 files added
945 ■■■■■ changed files
pom.xml 23 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/patches/constant/FileSufConstant.java 13 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/patches/controller/PatchesController.java 21 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/patches/kml/KmlBaseEntity.java 40 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/patches/kml/KmlData.java 13 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/patches/kml/KmlLine.java 18 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/patches/kml/KmlParser.java 176 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/patches/kml/KmlPoint.java 24 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/patches/kml/KmlPointTypeEnum.java 18 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/patches/kml/KmlPolygon.java 14 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/patches/kml/KmlProperty.java 34 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/patches/service/ShpToDataSourceService.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/patches/service/impl/ShpToDataSourceServiceImpl.java 165 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/patches/utils/ParseKmlFileUtil.java 125 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/patches/utils/ParsingKmlUtil.java 236 ●●●●● patch | view | raw | blame | history
src/main/java/com/dji/sample/patches/xml/utils/CreateWaylineFileUtils.java 1 ●●●● patch | view | raw | blame | history
src/main/resources/application-dev.yml 22 ●●●● patch | view | raw | blame | history
pom.xml
@@ -328,6 +328,29 @@
            <artifactId>bcprov-jdk18on</artifactId>
            <version>1.78.1</version>
        </dependency>
        <dependency>
            <groupId>org.geotools.xsd</groupId>
            <artifactId>gt-xsd-kml</artifactId>
            <version>28.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/de.micromata.jak/JavaAPIforKml -->
        <dependency>
            <groupId>de.micromata.jak</groupId>
            <artifactId>JavaAPIforKml</artifactId>
            <version>2.2.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-compress</artifactId>
            <version>1.21</version>
        </dependency>
        <dependency>
            <groupId>com.vividsolutions</groupId>
            <artifactId>jts</artifactId>
            <version>1.13</version>
        </dependency>
    </dependencies>
src/main/java/com/dji/sample/patches/constant/FileSufConstant.java
New file
@@ -0,0 +1,13 @@
package com.dji.sample.patches.constant;
/**
 * 文件后缀常量
 */
public class FileSufConstant {
    public static final String FILE_SUFFIX_ZIP = ".zip";
    public static final String FILE_SUFFIX_KMZ = ".kmz";
    public static final String FILE_SUFFIX_KML = ".kml";
}
src/main/java/com/dji/sample/patches/controller/PatchesController.java
@@ -6,6 +6,7 @@
import com.dji.sample.common.util.MinioUrlUtils;
import com.dji.sample.media.model.MediaFileEntity;
import com.dji.sample.media.service.impl.FileServiceImpl;
import com.dji.sample.patches.constant.FileSufConstant;
import com.dji.sample.patches.model.Param.PatchesParam;
import com.dji.sample.patches.model.entity.LotInfo;
import com.dji.sample.patches.service.GetPatchesService;
@@ -255,6 +256,10 @@
                                 @RequestParam double airportLat,
                                 @RequestParam double airportLon,
                                 HttpServletRequest request) throws Exception {
        // 检查格式是否正确
        if(!checkFileType(file.getOriginalFilename())){
            throw new RuntimeException("文件格式异常");
        }
        CustomClaim customClaim = (CustomClaim) request.getAttribute(TOKEN_CLAIM);
        String creator = customClaim.getUsername();
        MultipartFile multipartFile = shpToDataSourceService.insertGeo(file, workspaceId, waylineName, airportLat, airportLon, creator);
@@ -272,6 +277,22 @@
        return ResponseResult.success(infoMap);
    }
    /**
     * 检查文件格式是否正确
     * @param originalFilename
     * @return
     */
    private boolean checkFileType(String originalFilename) {
        if (originalFilename.endsWith(FileSufConstant.FILE_SUFFIX_ZIP) ||
                originalFilename.endsWith(FileSufConstant.FILE_SUFFIX_KML) ||
                originalFilename.endsWith(FileSufConstant.FILE_SUFFIX_KMZ)
        ){
            return true;
        }
        // 返回
        return false;
    }
    @GetMapping("/getExcel")
    public ResponseEntity<byte[]> exportExcel(@RequestParam String ids) {
//        List<LotInfo> lotInfos = getPatchesService.listLotinfo(workspaceId);
src/main/java/com/dji/sample/patches/kml/KmlBaseEntity.java
New file
@@ -0,0 +1,40 @@
package com.dji.sample.patches.kml;
import java.util.List;
import de.micromata.opengis.kml.v_2_2_0.Coordinate;
/**
 * kml 基类,将name、description、List<Coordinate>进行统一封装
 * @author 夜郎king
 */
public class KmlBaseEntity {
    private List<Coordinate> points;
    private String name;
    private String description;
    public List<Coordinate> getPoints() {
        return points;
    }
    public void setPoints(List<Coordinate> points) {
        this.points = points;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public KmlBaseEntity(List<Coordinate> points, String name, String description) {
        super();
        this.points = points;
        this.name = name;
        this.description = description;
    }
    public KmlBaseEntity() {
        super();
    }
}
src/main/java/com/dji/sample/patches/kml/KmlData.java
New file
@@ -0,0 +1,13 @@
package com.dji.sample.patches.kml;
import lombok.Data;
import java.util.List;
@Data
public class KmlData {
    private List<KmlPoint> kmlPoints;
    private List<KmlLine> kmlLines;
    private List<KmlPolygon> kmlPolygons;
}
src/main/java/com/dji/sample/patches/kml/KmlLine.java
New file
@@ -0,0 +1,18 @@
package com.dji.sample.patches.kml;
public class KmlLine extends KmlBaseEntity {
    private String color;
    private long width;
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public long getWidth() {
        return width;
    }
    public void setWidth(long width) {
        this.width = width;
    }
}
src/main/java/com/dji/sample/patches/kml/KmlParser.java
New file
@@ -0,0 +1,176 @@
package com.dji.sample.patches.kml;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import de.micromata.opengis.kml.v_2_2_0.*;
import java.io.File;
import java.io.InputStream;
import java.util.List;
import java.util.Objects;
public class KmlParser {
    private final Snowflake snowflake = IdUtil.getSnowflake(1, 1);
    /**
     * 保存kml数据到临时表
     *
     * @param file 上传的文件实体
     * @return 自定义的KML文件实体
     */
    public static KmlProperty toData(File file) {
        Kml kml = Kml.unmarshal(file);
        Feature feature = kml.getFeature();
        KmlProperty kmlProperty = new KmlProperty();
        if (Objects.isNull(feature)) {
            return kmlProperty;
        }
        kmlProperty.setName(feature.getName());
        KmlParser kmlParser = new KmlParser();
        kmlParser.parseFeature(feature, kmlProperty);
        return kmlProperty;
    }
    public static KmlProperty toData(InputStream content) {
        Kml kml = Kml.unmarshal(content);
        Feature feature = kml.getFeature();
        KmlProperty kmlProperty = new KmlProperty();
        if (Objects.isNull(feature)) {
            return kmlProperty;
        }
        kmlProperty.setName(feature.getName());
        KmlParser kmlParser = new KmlParser();
        kmlParser.parseFeature(feature, kmlProperty);
        return kmlProperty;
    }
    private void parseFeature(Feature feature, KmlProperty kmlProperty) {
        if (feature instanceof Document) {
            List<Feature> featureList = ((Document) feature).getFeature();
            List<KmlProperty> kmlPropertyList = kmlProperty.getKmlPropertyList();
            featureList.forEach(d -> {
                if (d instanceof Placemark) {
                    getPlaceMark((Placemark) d, kmlProperty);
                } else {
                    KmlProperty kmlProperty1 = new KmlProperty();
                    kmlProperty1.setName(d.getName());
                    kmlProperty1.setId(snowflake.nextIdStr());
                    kmlPropertyList.add(kmlProperty1);
                    parseFeature(d, kmlProperty1);
                }
            });
        } else if (feature instanceof Folder) {
            List<Feature> featureList = ((Folder) feature).getFeature();
            List<KmlProperty> kmlPropertyList = kmlProperty.getKmlPropertyList();
            featureList.forEach(d -> {
                if (d instanceof Placemark) {
                    getPlaceMark((Placemark) d, kmlProperty);
                } else {
                    KmlProperty kmlProperty1 = new KmlProperty();
                    kmlProperty1.setName(d.getName());
                    kmlProperty1.setId(snowflake.nextIdStr());
                    kmlPropertyList.add(kmlProperty1);
                    parseFeature(d, kmlProperty1);
                }
            });
        }
    }
    private void getPlaceMark(Placemark placemark, KmlProperty kmlProperty) {
        Geometry geometry = placemark.getGeometry();
        String name = placemark.getName();
        String description = placemark.getDescription();
        parseGeometry(name, geometry, description, kmlProperty);
    }
    private void parseGeometry(String name, Geometry geometry, String description, KmlProperty kmlProperty) {
        if (geometry != null) {
            if (geometry instanceof Polygon) {
                Polygon polygon = (Polygon) geometry;
                Boundary outerBoundaryIs = polygon.getOuterBoundaryIs();
                if (outerBoundaryIs != null) {
                    LinearRing linearRing = outerBoundaryIs.getLinearRing();
                    if (linearRing != null) {
                        List<Coordinate> coordinates = linearRing.getCoordinates();
                        if (coordinates != null) {
                            outerBoundaryIs = ((Polygon) geometry).getOuterBoundaryIs();
                            addPolygonToList(name, outerBoundaryIs, description, kmlProperty);
                        }
                    }
                }
            } else if (geometry instanceof LineString) {
                LineString lineString = (LineString) geometry;
                List<Coordinate> coordinates = lineString.getCoordinates();
                if (coordinates != null) {
                    int width = 0;
                    coordinates = ((LineString) geometry).getCoordinates();
                    addLineStringToList(coordinates, name, description, kmlProperty);
                }
            } else if (geometry instanceof Point) {
                Point point = (Point) geometry;
                List<Coordinate> coordinates = point.getCoordinates();
                if (coordinates != null) {
                    coordinates = ((Point) geometry).getCoordinates();
                    addPointToList(coordinates, name, description, kmlProperty);
                }
            } else if (geometry instanceof MultiGeometry) {
                List<Geometry> geometries = ((MultiGeometry) geometry).getGeometry();
                for (Geometry geometryToMult : geometries) {
                    Boundary outerBoundaryIs;
                    List<Coordinate> coordinates;
                    if (geometryToMult instanceof Point) {
                        coordinates = ((Point) geometryToMult).getCoordinates();
                        addPointToList(coordinates, name, description, kmlProperty);
                    } else if (geometryToMult instanceof LineString) {
                        coordinates = ((LineString) geometryToMult).getCoordinates();
                        addLineStringToList(coordinates, name, description, kmlProperty);
                    } else if (geometryToMult instanceof Polygon) {
                        outerBoundaryIs = ((Polygon) geometryToMult).getOuterBoundaryIs();
                        addPolygonToList(name, outerBoundaryIs, description, kmlProperty);
                    }
                }
            }
        }
    }
    private void addPolygonToList(String name, Boundary outerBoundaryIs, String description, KmlProperty kmlProperty) {
        LinearRing linearRing = outerBoundaryIs.getLinearRing();//面
        List<Coordinate> coordinates = linearRing.getCoordinates();
        KmlProperty kmlProperty1 = new KmlProperty();
        kmlProperty1.setId(snowflake.nextIdStr());
        kmlProperty1.setName(name);
        kmlProperty1.setPoints(coordinates);
        kmlProperty1.setDescription(description);
        kmlProperty1.setType(KmlPointTypeEnum.POLYGON.getCode());
        List<KmlProperty> kmlPropertyList = kmlProperty.getKmlPropertyList();
        kmlPropertyList.add(kmlProperty1);
    }
    private void addLineStringToList(List<Coordinate> coordinates, String name, String description, KmlProperty kmlProperty) {
        KmlProperty kmlProperty1 = new KmlProperty();
        kmlProperty1.setId(snowflake.nextIdStr());
        kmlProperty1.setName(name);
        kmlProperty1.setPoints(coordinates);
        kmlProperty1.setDescription(description);
        kmlProperty1.setType(KmlPointTypeEnum.LINE.getCode());
        List<KmlProperty> kmlPropertyList = kmlProperty.getKmlPropertyList();
        kmlPropertyList.add(kmlProperty1);
    }
    private void addPointToList(List<Coordinate> coordinates, String name, String description, KmlProperty kmlProperty) {
        KmlProperty kmlProperty1 = new KmlProperty();
        kmlProperty1.setId(snowflake.nextIdStr());
        kmlProperty1.setName(name);
        kmlProperty1.setPoints(coordinates);
        kmlProperty1.setDescription(description);
        kmlProperty1.setType(KmlPointTypeEnum.POINT.getCode());
        List<KmlProperty> kmlPropertyList = kmlProperty.getKmlPropertyList();
        kmlPropertyList.add(kmlProperty1);
    }
}
src/main/java/com/dji/sample/patches/kml/KmlPoint.java
New file
@@ -0,0 +1,24 @@
package com.dji.sample.patches.kml;
import java.util.List;
import de.micromata.opengis.kml.v_2_2_0.Coordinate;
/**
 * 点
 */
public class KmlPoint extends KmlBaseEntity{
    private String color;
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public KmlPoint(List<Coordinate> points,String name,String description,String color){
        super(points, name, description);
        this.color = color;
    }
    public KmlPoint() {
        super();
    }
}
src/main/java/com/dji/sample/patches/kml/KmlPointTypeEnum.java
New file
@@ -0,0 +1,18 @@
package com.dji.sample.patches.kml;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum KmlPointTypeEnum {
    //kml文件数据类型
    POINT(0, "点"),
    LINE(1, "线"),
    POLYGON(2, "面");
    private final Integer code;
    private final String name;
}
src/main/java/com/dji/sample/patches/kml/KmlPolygon.java
New file
@@ -0,0 +1,14 @@
package com.dji.sample.patches.kml;
/**
 * @program: 面状实体
 **/
public class KmlPolygon extends KmlBaseEntity {
    private String color;
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
}
src/main/java/com/dji/sample/patches/kml/KmlProperty.java
New file
@@ -0,0 +1,34 @@
package com.dji.sample.patches.kml;
import de.micromata.opengis.kml.v_2_2_0.Coordinate;
import lombok.Data;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Data
public class KmlProperty implements Serializable {
    private static final long serialVersionUID = 1L;
    private String id = "0";
    private Set<String> ids = new HashSet<>();
    private String name;
    private String description;
    private List<Coordinate> points = new ArrayList<>();
    //0:点     1:线     2:面
    private Integer type;
    private List<KmlProperty> kmlPropertyList = new ArrayList<>();
}
src/main/java/com/dji/sample/patches/service/ShpToDataSourceService.java
@@ -25,7 +25,7 @@
     * @return 图斑生成的航线
     * @throws Exception 处理过程中可能出现的任何异常
     */
    MultipartFile insertGeo(MultipartFile file , String workspaceId,String waylineName, double airportLat, double airportLon,String creator) throws Exception;
    MultipartFile insertGeo(MultipartFile file , String workspaceId,String waylineName, double airportLat, double airportLon,String creator) ;
    /**
     * 将List<TbDkjbxxEntity>类型的数据批量插入到数据库中。
src/main/java/com/dji/sample/patches/service/impl/ShpToDataSourceServiceImpl.java
@@ -2,7 +2,12 @@
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;
@@ -11,7 +16,11 @@
import com.dji.sample.patches.xml.utils.CreateWaylineFileUtils;
import com.dji.sample.territory.model.entity.TbDkjbxxEntity;
import com.dji.sample.wayline.service.IWaylineFileService;
import org.locationtech.jts.geom.Coordinate;
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;
@@ -19,6 +28,8 @@
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;
@@ -26,11 +37,13 @@
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
@@ -45,10 +58,22 @@
    private PatchesConfigPojo patchesConfigPojo;
    @Transactional
    public MultipartFile insertGeo(MultipartFile file, String workspaceId, String waylineName, double airportLat, double airportLon,String creator) throws Exception {
    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<LotInfo> list = new ArrayList<>();
        File file1 = MultipartFileTOFileUtil.multipartFile2File(file, patchesConfigPojo.getUnzip());
        List<ShpDTO> shpData = ShapeFileUtil.shpToGeoJson(file1);
            List<ShpDTO> 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();
@@ -65,15 +90,143 @@
            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<LotInfo> list = new ArrayList<>();
            // 点、线暂不处理
            if (null!=kmlData.getKmlPoints() && kmlData.getKmlPoints().size()>0){
                List<KmlPoint> kmlPointList = kmlData.getKmlPoints();
            }
            if (null!=kmlData.getKmlLines() && kmlData.getKmlLines().size()>0){
                List<KmlLine> kmlLineList = kmlData.getKmlLines();
            }
            // 处理面状数据
            if (null!=kmlData.getKmlPolygons() && kmlData.getKmlPolygons().size()>0){
                List<KmlPolygon> 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<LotInfo> list) {
        try {
        List<PointPO> 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);
        multipartFile = convert(new File(destKMZFile));
        MultipartFileTOFileUtil.deleteFile(file1);
        return multipartFile;
            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<LotInfo> list, List<KmlPolygon> 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<de.micromata.opengis.kml.v_2_2_0.Coordinate> 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
src/main/java/com/dji/sample/patches/utils/ParseKmlFileUtil.java
New file
@@ -0,0 +1,125 @@
package com.dji.sample.patches.utils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.InputStream;
import java.util.List;
/**
 * 解析KML文件工具类
 */
public class ParseKmlFileUtil {
    /**
     * 解析kml中的数据
     * @param inputStream
     * @return
     */
    public static String kmlParseData(InputStream inputStream) {
        SAXReader reader = new SAXReader();
        Document doc = null;
        try {
            doc = reader.read(inputStream);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return getResultJSON(doc);
    }
    private static String getResultJSON(Document doc) {
        JSONObject jObj = new JSONObject();
        if (doc == null) {
            return null;
        }
        JSONArray jArray = new JSONArray();
        int index = 0;
        String autoFlightSpeed = "";
        String actionOnFinish = "";
        List<Element> rootEls = doc.getRootElement().elements();
        for (Element rootEl : rootEls) {
            List<Element> docEls = rootEl.elements();
            for (Element docEl : docEls) {
                if (docEl.getName().equals("Folder")) {
                    List<Element> folderEls = docEl.elements();
                    for (Element folderEl : folderEls) {
                        if (folderEl.getName().equals("Placemark")) {
                            JSONObject wayPointObj = new JSONObject();
                            List<Element> placeMarkEls = folderEl.elements();
                            index++;
                            for (Element placeMarkEl : placeMarkEls) {
                                if (placeMarkEl.getName().equals("ExtendedData")) {
                                    String heading = placeMarkEl.elementTextTrim("heading");
                                    String speed = placeMarkEl.elementTextTrim("speed");
                                    String turnMode = placeMarkEl.elementTextTrim("turnMode");
                                    wayPointObj.put("index", index);
                                    wayPointObj.put("heading", Integer.parseInt(heading));
                                    wayPointObj.put("speed", Integer.parseInt(speed));
                                    wayPointObj.put("turnMode", turnMode);
                                    //航点动作
                                    JSONArray actionsArr = new JSONArray();
                                    if (placeMarkEl.elements("actions") != null) {
                                        int hIndex = 1;
                                        List<Element> elList = placeMarkEl.elements("actions");
                                        for (Element el : elList) {
                                            JSONObject wayAction = new JSONObject();
                                            String actionsName = el.getTextTrim();
                                            //这里只解析航点动作,其余的参数可以根据情况自行取值
                                            if (!(actionsName.equals("ShootPhoto")) && !(actionsName.equals("StartRecording")) && !(actionsName.equals("Hovering")) && !(actionsName.equals("StopRecording"))) {
                                                continue;
                                            }
                                            String actionParam = "";//动作参数
                                            if (actionsName.equals("ShootPhoto")) {//拍照
                                                actionParam = el.attribute("targetMode").getValue();
                                            } else if (actionsName.equals("StartRecording")) {//开始录影
                                                actionParam = el.attribute("targetMode").getValue();
                                            } else if (actionsName.equals("Hovering")) {//悬停
                                                actionParam = el.attribute("param").getValue();
                                            } else if (actionsName.equals("StopRecording")) {//结束录影
                                                actionParam = el.attribute("targetMode").getValue();
                                            }
                                            String actionName = el.attribute("label").getValue();//动作名称
                                            wayAction.put("index", hIndex++);
                                            wayAction.put("actionParam", Integer.parseInt(actionParam));
                                            wayAction.put("actionName", actionName);
                                            actionsArr.add(wayAction);
                                        }
                                    }
                                    wayPointObj.put("wayPoint", actionsArr);
                                }
                                if (placeMarkEl.getName().equals("Point")) {
                                    String coordinates = placeMarkEl.elementTextTrim("coordinates");
                                    wayPointObj.put("latitude", Double.parseDouble(coordinates.split(",")[1]));//纬度
                                    wayPointObj.put("longitude", Double.parseDouble(coordinates.split(",")[0]));//经度
                                    wayPointObj.put("altitude", Float.parseFloat(coordinates.split(",")[2]));//海拔高度
                                }
                            }
                            jArray.add(wayPointObj);
                        }
                    }
                }
                if (docEl.getName().equals("Placemark")) {
                    List<Element> extendedDataEls = docEl.elements();
                    for (Element extendedDataEl : extendedDataEls) {
                        if (extendedDataEl.getName().equals("ExtendedData")) {
                            autoFlightSpeed = extendedDataEl.elementTextTrim("autoFlightSpeed");
                            actionOnFinish = extendedDataEl.elementTextTrim("actionOnFinish");
                        }
                    }
                }
            }
        }
        jObj.put("autoFlightSpeed", autoFlightSpeed);
        jObj.put("actionOnFinish", actionOnFinish);
        jObj.put("wayPoint", jArray);
        return JSONObject.toJSONString(jObj);
    }
}
src/main/java/com/dji/sample/patches/utils/ParsingKmlUtil.java
New file
@@ -0,0 +1,236 @@
package com.dji.sample.patches.utils;
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 de.micromata.opengis.kml.v_2_2_0.*;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
 * @description: KML文件解析
 **/
public class ParsingKmlUtil {
    /**
     *   解析kml文件
     */
    public static KmlData parseKmlByFile(File file) {
        Kml kml = Kml.unmarshal(file);
        return getByKml(kml);
    }
    /**
     *  解析kml文件流
     *
     * @param inputstream
     * @return
     */
    public static KmlData parseKmlByInputstream(InputStream inputstream) {
        Kml kml = Kml.unmarshal(inputstream);
        return getByKml(kml);
    }
    /**
     * Kml对象转自定义存储对象
     *
     * @param kml
     * @return
     */
    public static KmlData getByKml(Kml kml) {
        KmlData kmlData = new KmlData();
        kmlData.setKmlPoints(new ArrayList<>());
        kmlData.setKmlLines(new ArrayList<>());
        kmlData.setKmlPolygons(new ArrayList<>());
        Feature feature = kml.getFeature();
        parseFeature(feature, kmlData);
        return kmlData;
    }
    /**
     *  解析kml节点
     * @param feature
     * @param kmlData
     */
    private static void parseFeature(Feature feature, KmlData kmlData) {
        if (feature != null) {
            if (feature instanceof Document) {
                List<Feature> featureList = ((Document) feature).getFeature();
                featureList.forEach(documentFeature -> {
                    if (documentFeature instanceof Placemark) {
                        getPlaceMark((Placemark) documentFeature, kmlData);
                    } else {
                        parseFeature(documentFeature, kmlData);
                    }
                });
            } else if (feature instanceof Folder) {
                List<Feature> featureList = ((Folder) feature).getFeature();
                featureList.forEach(documentFeature -> {
                    if (documentFeature instanceof Placemark) {
                        getPlaceMark((Placemark) documentFeature, kmlData);
                    } else {
                        parseFeature(documentFeature, kmlData);
                    }
                });
            }
        }
    }
    private static void getPlaceMark(Placemark placemark, KmlData kmlData) {
        Geometry geometry = placemark.getGeometry();
        /*String name = placemark.getName();
        placemark.getDescription();
        System.out.println(placemark.getDescription());
        if (name == null) {
            name = placemark.getDescription();
        }
        parseGeometry(name, geometry, kmlData);*/
        parseGeometry(placemark,geometry,kmlData);
    }
    /**
     *   解析点线面形状的数据分别放入存储对象
     * @param placemark placemark对象
     * @param geometry 形状类型
     * @param kmlData  存储对象
     */
    private static void parseGeometry(Placemark placemark, Geometry geometry, KmlData kmlData) {
        if (geometry != null) {
            if (geometry instanceof Polygon) {
                Polygon polygon = (Polygon) geometry;
                Boundary outerBoundaryIs = polygon.getOuterBoundaryIs();
                if (outerBoundaryIs != null) {
                    LinearRing linearRing = outerBoundaryIs.getLinearRing();
                    if (linearRing != null) {
                        List<Coordinate> coordinates = linearRing.getCoordinates();
                        if (coordinates != null) {
                            outerBoundaryIs = ((Polygon) geometry).getOuterBoundaryIs();
                            addPolygonToList(kmlData.getKmlPolygons(), placemark, outerBoundaryIs);
                        }
                    }
                }
            } else if (geometry instanceof LineString) {
                LineString lineString = (LineString) geometry;
                List<Coordinate> coordinates = lineString.getCoordinates();
                if (coordinates != null) {
                    coordinates = ((LineString) geometry).getCoordinates();
                    addLineStringToList(kmlData.getKmlLines(), coordinates, placemark);
                }
            } else if (geometry instanceof Point) {
                Point point = (Point) geometry;
                List<Coordinate> coordinates = point.getCoordinates();
                if (coordinates != null) {
                    coordinates = ((Point) geometry).getCoordinates();
                    addPointToList(kmlData.getKmlPoints(), coordinates, placemark);
                }
            } else if (geometry instanceof MultiGeometry) {
                List<Geometry> geometries = ((MultiGeometry) geometry).getGeometry();
                for (Geometry geometryToMult : geometries) {
                    Boundary outerBoundaryIs;
                    List<Coordinate> coordinates;
                    if (geometryToMult instanceof Point) {
                        coordinates = ((Point) geometryToMult).getCoordinates();
                        addPointToList(kmlData.getKmlPoints(), coordinates, placemark);
                    } else if (geometryToMult instanceof LineString) {
                        coordinates = ((LineString) geometryToMult).getCoordinates();
                        addLineStringToList(kmlData.getKmlLines(), coordinates, placemark);
                    } else if (geometryToMult instanceof Polygon) {
                        outerBoundaryIs = ((Polygon) geometryToMult).getOuterBoundaryIs();
                        addPolygonToList(kmlData.getKmlPolygons(), placemark, outerBoundaryIs);
                    }
                }
            }
        }
    }
    /**
     *   保存面状数据
     *
     * @param kmlPolygonList  已有面状数据
     * @param placemark       placemark对象
     * @param outerBoundaryIs 面状信息
     */
    private static void addPolygonToList(List<KmlPolygon> kmlPolygonList, Placemark placemark, Boundary outerBoundaryIs) {
        LinearRing linearRing = outerBoundaryIs.getLinearRing();// 面
        KmlPolygon kmlPolygon = new KmlPolygon();
        kmlPolygon.setPoints(linearRing.getCoordinates());
        kmlPolygon.setName(placemark.getName());
        kmlPolygon.setDescription(placemark.getDescription());
        kmlPolygonList.add(kmlPolygon);
    }
    /**
     * 保存线状数据
     *
     * @param kmlLineList 已有线状数据
     * @param coordinates 线状经纬度数据
     * @param placemark   线状名称
     */
    private static void addLineStringToList(List<KmlLine> kmlLineList, List<Coordinate> coordinates, Placemark placemark) {
        KmlLine kmlLine = new KmlLine();
        kmlLine.setPoints(coordinates);
        kmlLine.setName(placemark.getName());
        kmlLine.setDescription(placemark.getDescription());
        kmlLineList.add(kmlLine);
    }
    /**
     * 保存点状数据
     *
     * @param kmlPointList 已有点状数据
     * @param coordinates  点状经纬度数据
     * @param placemark    点状名称
     */
    private static void addPointToList(List<KmlPoint> kmlPointList, List<Coordinate> coordinates, Placemark placemark) {
        KmlPoint kmlPoint = new KmlPoint();
        kmlPoint.setName(placemark.getName());
        kmlPoint.setDescription(placemark.getDescription());
        kmlPoint.setPoints(coordinates);
        kmlPointList.add(kmlPoint);
    }
    /**
     * kmz 文件解析
     * @param inputStream
     * @throws IOException
     */
    public static KmlData parseKMZFile(InputStream inputStream) throws IOException {
        KmlData kmlData = new KmlData();
        ArchiveInputStream archiveInputStream = new ZipArchiveInputStream(inputStream);
        ArchiveEntry entry;
        while ((entry = archiveInputStream.getNextEntry()) != null) {
            String name = entry.getName();
            if (name.toLowerCase().endsWith(".kml") || name.toLowerCase().endsWith(".kmz")) {
                // 如果发现.kml或.kmz文件,可以将其内容读取出来并传递给KMLParser处理
                kmlData = parseKML(archiveInputStream,kmlData);
            }
        }
        return kmlData;
    }
    /**
     * 解析kml 文件
     * @param kmlInputStream
     * @throws IOException
     */
    public static KmlData parseKML(InputStream kmlInputStream, KmlData kmlData) {
        // 取出kml中的内容
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(kmlInputStream))) {
            String line;
            StringBuffer xmlContent = new StringBuffer(1024);
            while ((line = reader.readLine()) != null) {
                // 处理每一行KML数据
                xmlContent.append(line);
            }
            // System.out.println(xmlContent);
            Kml kml = Kml.unmarshal(xmlContent.toString());
            ParsingKmlUtil pku = new ParsingKmlUtil();
            // 赋值
            kmlData = pku.getByKml(kml);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 返回
        return kmlData;
    }
}
src/main/java/com/dji/sample/patches/xml/utils/CreateWaylineFileUtils.java
@@ -75,6 +75,7 @@
            out.close();
        } catch (Exception e) {
            log.error("write xml failed:", e);
            throw new RuntimeException(e);
        } finally {
            if (out != null) {
                try {
src/main/resources/application-dev.yml
@@ -12,7 +12,7 @@
#          url: jdbc:mysql://182.108.40.114:3308/drone_zt_test?useSSL=false&allowPublicKeyRetrieval=true
#          username: root
#          password: yshb@123
          url: jdbc:mysql://139.196.74.78:3306/drone_test?useSSL=false&allowPublicKeyRetrieval=true
          url: jdbc:mysql://139.196.74.78:3306/drone_o_test?useSSL=false&allowPublicKeyRetrieval=true
          username: root
          password: jxpskj_2018
        sqlite-resource:
@@ -62,10 +62,10 @@
  # BASIC parameters are required.
  BASIC:
    protocol: MQTT # @see com.dji.sample.component.mqtt.model.MqttProtocolEnum
    host: 139.196.74.78
    port: 1883
    username: manage
    password: 123456
    host: 182.108.40.114
    port: 31883
    username: root
    password: root
#    host: 127.0.0.1
#    port: 1883
#    username: guest
@@ -74,13 +74,13 @@
    # If the protocol is ws/wss, this value is required.
    path:
    # 最初连接到mqtt时需要订阅的主题 多个订阅用 "," .
    inbound-topic: sys/product/+/status,thing/product/+/requests,thing/product/+/osd
#    inbound-topic: sys/product/+/+,thing/product/+/+
#    inbound-topic: sys/product/+/status,thing/product/+/requests,thing/product/+/osd
    inbound-topic: sys/product/+/+,thing/product/+/+
  DRC:
    protocol: WS # @see com.dji.sample.component.mqtt.model.MqttProtocolEnum
    host: 139.196.74.78
    port: 8083
    path: /mqtt
    protocol: ws # @see com.dji.sample.component.mqtt.model.MqttProtocolEnum
    host: 182.108.40.114
    port: 35675
    path: /ws
oss:
  enable: true