feiyu02
2024-07-04 022af485fbd77bc3d6b01f9f779248b3c189dad2
1. 新增走航报告自动道路识别模块
已修改5个文件
已添加6个文件
已重命名1个文件
596 ■■■■■ 文件已修改
pom.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/biz/dataprocess/RoadSegment.kt 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/common/location/TrackSegment.kt 93 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/common/net/AMapService.kt 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/common/net/HttpMethod.kt 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/domain/entity/SegmentInfo.java 244 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/domain/mapper/SegmentInfoMapper.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/domain/repository/SegmentInfoRep.kt 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/RealTimeDataServiceImpl.kt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/generator/generatorConfig.xml 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/SegmentInfoMapper.xml 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/kotlin/com/flightfeather/uav/biz/dataprocess/RoadSegmentTest.kt 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
@@ -97,7 +97,7 @@
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
            <version>2.8.6</version>
        </dependency>
        <!--分页-->
src/main/kotlin/com/flightfeather/uav/biz/dataprocess/RoadSegment.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
package com.flightfeather.uav.biz.dataprocess
import com.flightfeather.uav.common.location.TrackSegment
import com.flightfeather.uav.common.net.AMapService
import com.flightfeather.uav.domain.entity.BaseRealTimeData
import com.flightfeather.uav.domain.entity.Mission
import com.flightfeather.uav.domain.entity.SegmentInfo
import com.flightfeather.uav.domain.entity.avg
import com.flightfeather.uav.domain.repository.RealTimeDataRep
import com.flightfeather.uav.domain.repository.SegmentInfoRep
import org.springframework.stereotype.Component
import java.math.BigDecimal
/**
 * èµ°èˆªè½¨è¿¹æŒ‰ç…§è·¯æ®µè¿›è¡Œåˆ†å‰²
 * @date 2024/7/4
 * @author feiyu02
 */
@Component
class RoadSegment(
    private val realTimeDataRep: RealTimeDataRep,
    private val segmentInfoRep: SegmentInfoRep,
) {
    fun handle(mission: Mission) {
        // èŽ·å–æ•°æ®åˆ†æ®µ
        val data = mutableListOf<BaseRealTimeData>()
        realTimeDataRep.fetchData(mission).forEach {
            // åŽ»é™¤æ— æ•ˆç»çº¬åº¦
            if ((it.longitude != null && it.longitude != BigDecimal.ZERO)
                && (it.latitude != null && it.latitude != BigDecimal.ZERO)
            ) {
                data.add(it)
            }
        }
        val sData = TrackSegment.segmentWithRoad(data)
        // æ ¹æ®æ¯ä¸ªåˆ†æ®µçš„GPS坐标均值通过高德API转换为高德坐标
        val avgGPS = mutableListOf<Pair<Double, Double>>()
        sData.forEach {
            val d = it.avg()
            if (d.longitude != null && d.latitude != null) {
                avgGPS.add(d.longitude!!.toDouble() to d.latitude!!.toDouble())
            }
        }
        val gdGPS = AMapService.coordinateConvert(avgGPS)
        // é€šè¿‡é«˜å¾·API查询坐标对应的路段
        val segmentInfoList = mutableListOf<SegmentInfo>()
        gdGPS.forEachIndexed { i, pair ->
            val address = AMapService.reGeo(pair)
            segmentInfoList.add(SegmentInfo().apply {
                missionCode = mission.missionCode
                deviceCode = mission.deviceCode
                startTime = sData[i][0].dataTime
                endTime = sData[i].last().dataTime
                provinceName = address.province
                cityCode = address.citycode
                districtCode = address.adcode
                districtName = address.district
                townCode = address.towncode
                towmName = address.township
                street = address.street
            })
        }
        // ç»“果入库
        segmentInfoRep.insert(segmentInfoList)
    }
}
src/main/kotlin/com/flightfeather/uav/common/location/TrackSegment.kt
ÎļþÃû´Ó src/main/kotlin/com/flightfeather/uav/biz/dataprocess/TrackSegment.kt ÐÞ¸Ä
@@ -1,9 +1,11 @@
package com.flightfeather.uav.biz.dataprocess
package com.flightfeather.uav.common.location
import com.flightfeather.uav.common.location.CoordinateUtil
import com.flightfeather.uav.domain.entity.BaseRealTimeData
import java.math.BigDecimal
import kotlin.math.abs
import kotlin.math.atan
import kotlin.math.cos
import kotlin.math.sin
/**
 * èµ°èˆªè½¨è¿¹åˆ†å‰²åˆ†ç±»
@@ -13,10 +15,10 @@
object TrackSegment {
    // åæ ‡ç‚¹é—´æœ€å°è·ç¦»ï¼Œå•位米
    private const val MIN_DISTANCE = 10
    private const val MIN_DISTANCE = 6
    // ä¸¤æ¡ç›´çº¿å¤¹è§’为90度时,认为垂直。实际情况中,角度允许有一定偏差,允许偏差角度
    private const val VERTICAL_OFFSET_DEG = 22.5
    private const val VERTICAL_OFFSET_DEG = 45
    /**
     * æŒ‰ç…§é“路对走航轨迹进行分割
@@ -34,13 +36,13 @@
        val closeList = mutableListOf<BaseRealTimeData>()
        records.add(mutableListOf())
        data.forEachIndexed { i, d ->
            if (records.size == 33) {
            if (records.size == 23) {
                println(records.size)
            }
            var isSame = false
            if (i > 0) {
                // å‰ä¸€ä¸ªæœ‰æ•ˆç›‘测点
                val lastData = data[i - 1]
                var lastData = data[i - 1]
                // ç¡®ä¿ä¸¤ç‚¹åæ ‡åˆæ³•
                if ((lastData.longitude != null && lastData.longitude != BigDecimal.ZERO)
                    && (lastData.latitude != null && lastData.latitude != BigDecimal.ZERO)
@@ -57,6 +59,7 @@
                        // å¦‚果已经有距离过近的点集合,则还需要和第一个点进行距离判断,
                        // è§£å†³å½“车辆行驶速度过低时,连续点的距离都过近导致都判定为同一点的问题
                        val firstCloseData = closeList[0]
//                        lastData = closeList.toList().avg()
                        distance = CoordinateUtil.calculateDistance(
                            firstCloseData.longitude!!.toDouble(), firstCloseData.latitude!!.toDouble(),
                            d.longitude!!.toDouble(), d.latitude!!.toDouble())
@@ -69,27 +72,43 @@
                        )
                        isSame = if (lastDegList.isNotEmpty()) {
                            var bool = true
                            // å‡ºçŽ°è§’åº¦æŽ¥è¿‘åž‚ç›´çŠ¶æ€çš„æ¬¡æ•°
                            var unSameCount = 0
                            // æ¯”较当前方位角和上一组每个方位角的差值是否都处于范围内
                            for (lastDeg in lastDegList) {
                                val diffDeg = abs(deg - lastDeg)
                                if (diffDeg in (90.0 - VERTICAL_OFFSET_DEG)..(90.0 + VERTICAL_OFFSET_DEG)
                                    || diffDeg in (270.0 - VERTICAL_OFFSET_DEG)..(270.0 + VERTICAL_OFFSET_DEG)
                                ) {
                                    unSameCount++
                                }
//                            // å‡ºçŽ°è§’åº¦æŽ¥è¿‘åž‚ç›´çŠ¶æ€çš„æ¬¡æ•°
//                            var unSameCount = 0
//                            // æ¯”较当前方位角和上一组每个方位角的差值是否都处于范围内
//                            for (lastDeg in lastDegList) {
//                                val diffDeg = abs(deg - lastDeg)
//                                if (diffDeg in (90.0 - VERTICAL_OFFSET_DEG)..(90.0 + VERTICAL_OFFSET_DEG)
//                                    || diffDeg in (270.0 - VERTICAL_OFFSET_DEG)..(270.0 + VERTICAL_OFFSET_DEG)
//                                ) {
//                                    unSameCount++
//                                }
//                            }
//                            // å½“接近垂直的角度超过上一组平行角度的一半时,认为从该点轨迹转弯(消除个别坐标点由于定位误差导致的错误影响)
//                            bool = unSameCount < (lastDegList.size / 3 + 1)
                            val avgDeg = avgDegree(lastDegList)
                            val diffDeg = abs(deg - avgDeg)
                            if (diffDeg in (90.0 - VERTICAL_OFFSET_DEG)..(90.0 + VERTICAL_OFFSET_DEG)
                                || diffDeg in (270.0 - VERTICAL_OFFSET_DEG)..(270.0 + VERTICAL_OFFSET_DEG)
                            ) {
                                bool = false
                            }
                            // å½“接近垂直的角度超过上一组平行角度的一半时,认为从该点轨迹转弯(消除个别坐标点由于定位误差导致的错误影响)
                            bool = unSameCount < (lastDegList.size / 3 + 1)
                            // å½“出现转弯点时,清空历史角度,并且舍弃转弯点相对于前一个点的角度(解决一种极端情况,当连续出现转弯点时,当前坐标点会被单独分割为一段)
                            if (!bool) lastDegList.clear()
                            if (!bool) {
                                lastDegList.clear()
                            } else {
                                lastDegList.add(deg)
                            }
                            bool
                        } else {
                            // å½“坐标点形成有效路径时,记录为上一个坐标点
                            lastDegList.add(deg)
                            true
                        }
                        closeList.clear()
                    } else {
                        closeList.add(d)
                        isSame = true
@@ -110,4 +129,40 @@
        return records
    }
    /**
     * æ±‚转向角度的均值
     */
    private fun avgDegree(degList: List<Double>): Double {
        if (degList.isEmpty()) return .0
        //采用单位矢量法求取均值
        var u = .0//东西方位分量总和
        var v = .0//南北方位分量总和
        var c = 0//数据计数
        degList.forEach {
            val r = Math.toRadians(it)
            u += sin(r)
            v += cos(r)
            c++
        }
        val avgU = u / c
        val avgV = v / c
        var a = atan(avgU / avgV)
        a = Math.toDegrees(a)
        /**
         * avgU>0;avgV>0: çœŸå®žè§’度处于第一象限,修正值为+0°
         * avgU>0;avgV<0: çœŸå®žè§’度处于第二象限,修正值为+180°
         * avgU<0;avgV<0: çœŸå®žè§’度处于第三象限,修正值为+180°
         * avgU<0;avgV>0: çœŸå®žè§’度处于第四象限,修正值为+360°
         */
        a += if (avgV > 0) {
            if (avgU > 0) 0 else 360
        } else {
            180
        }
        return a
    }
}
src/main/kotlin/com/flightfeather/uav/common/net/AMapService.kt
@@ -1,19 +1,106 @@
package com.flightfeather.uav.common.net
import com.flightfeather.uav.common.exception.BizException
import com.google.gson.Gson
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import java.nio.charset.Charset
/**
 * é«˜å¾·åœ°å›¾Web服务API
 */
object AMapService {
    private const val TAG = "AMapService"
    private const val KEY = "520c5e5cf44c7793104e500cbf0ed711"
    private val httpMethod = HttpMethod("restapi.amap.com", 443, true)
    private val KEY = ""
    data class AMapAddress(
        val country: String,
        val province: String,
        val city: String,
        val citycode: String,
        val district: String,
        val adcode: String,
        val township: String,
        val towncode: String,
        val street: String,
    )
    /**
     * åœ°ç†é€†ç¼–码
     * @param location åæ ‡ç‚¹
     * @return æ‰€åœ¨è¡—道
     */
    fun reGeo(location:List<Pair<Double, Double>>) {
        httpMethod.get("v3/geocode/regeo", listOf(
    fun reGeo(location:Pair<Double, Double>):AMapAddress {
        val res = httpMethod.get("/v3/geocode/regeo", listOf(
            "key" to KEY,
            "location" to "${location.first},${location.second}"
        ))
        val obj = handleRes(res)
        try {
            val a = obj["regeocode"].asJsonObject["addressComponent"].asJsonObject
            return AMapAddress(
                a["country"].asString,
                a["province"].asString,
                "",
                a["citycode"].asString,
                a["district"].asString,
                a["adcode"].asString,
                a["township"].asString,
                a["towncode"].asString,
                a["streetNumber"].asJsonObject["street"].asString,
            )
        } catch (e: Exception) {
            throw BizException("高德API坐标转换错误,${e.message}")
        }
    }
    /**
     * åæ ‡è½¬æ¢
     * @param locations åŽŸå§‹åæ ‡
     * @param coordsys åŽŸåæ ‡ç³»ï¼Œå¯é€‰å€¼ï¼šgps;mapbar;baidu;autonavi(不进行转换)
     */
    fun coordinateConvert(locations: List<Pair<Double, Double>>, coordsys:String="gps"): List<Pair<Double, Double>> {
        val res = httpMethod.get("/v3/assistant/coordinate/convert", listOf(
            "key" to KEY,
            "locations" to locations.joinToString("|") { "${it.first},${it.second}" },
            "coordsys" to coordsys
        ))
        val obj = handleRes(res)
        try {
            return obj["locations"].asString.split(";").map {
                val l = it.split(",")
                l[0].toDouble() to l[1].toDouble()
            }
        } catch (e: Exception) {
            throw BizException("高德API坐标转换错误,${e.message}")
        }
    }
    private fun handleRes(res: HttpMethod.MyResponse):JsonObject {
        if (res.success) {
//            val str = if (res.m.responseCharSet == "utf-8") {
//                res.m.responseBodyAsString
//            } else {
//                String(res.m.responseBody, Charset.forName("utf-8"))
//            }
            val str = res.m.responseBodyAsString
            val json = JsonParser.parseString(str)
            return resCheck(json)
        } else {
            throw BizException("高德API网路链接错误,状态码:${res.m.statusCode}")
        }
    }
    private fun resCheck(json: JsonElement): JsonObject {
        if (!json.isJsonObject) throw BizException("高德API失败,返回值不是一个object")
        val jo = json.asJsonObject
        if (jo["status"].asInt != 1) throw BizException("高德API失败,错误${jo["info"]}")
        return jo
    }
}
src/main/kotlin/com/flightfeather/uav/common/net/HttpMethod.kt
@@ -18,8 +18,8 @@
    private val logger = LoggerFactory.getLogger(HttpMethod::class.java)
    data class MyResponse(
            val success: Boolean,
            val m: HttpMethodBase
        val success: Boolean,
        val m: HttpMethodBase,
    )
    object Head {
src/main/kotlin/com/flightfeather/uav/domain/entity/SegmentInfo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,244 @@
package com.flightfeather.uav.domain.entity;
import java.util.Date;
import javax.persistence.*;
@Table(name = "segment_info")
public class SegmentInfo {
    @Id
    private Integer id;
    @Column(name = "mission_code")
    private String missionCode;
    @Column(name = "device_code")
    private String deviceCode;
    @Column(name = "start_time")
    private Date startTime;
    @Column(name = "end_time")
    private Date endTime;
    @Column(name = "district_code")
    private String districtCode;
    @Column(name = "district_name")
    private String districtName;
    @Column(name = "town_code")
    private String townCode;
    @Column(name = "towm_name")
    private String towmName;
    @Column(name = "province_code")
    private String provinceCode;
    @Column(name = "province_name")
    private String provinceName;
    @Column(name = "city_code")
    private String cityCode;
    @Column(name = "city_name")
    private String cityName;
    private String street;
    /**
     * @return id
     */
    public Integer getId() {
        return id;
    }
    /**
     * @param id
     */
    public void setId(Integer id) {
        this.id = id;
    }
    /**
     * @return mission_code
     */
    public String getMissionCode() {
        return missionCode;
    }
    /**
     * @param missionCode
     */
    public void setMissionCode(String missionCode) {
        this.missionCode = missionCode == null ? null : missionCode.trim();
    }
    /**
     * @return device_code
     */
    public String getDeviceCode() {
        return deviceCode;
    }
    /**
     * @param deviceCode
     */
    public void setDeviceCode(String deviceCode) {
        this.deviceCode = deviceCode == null ? null : deviceCode.trim();
    }
    /**
     * @return start_time
     */
    public Date getStartTime() {
        return startTime;
    }
    /**
     * @param startTime
     */
    public void setStartTime(Date startTime) {
        this.startTime = startTime;
    }
    /**
     * @return end_time
     */
    public Date getEndTime() {
        return endTime;
    }
    /**
     * @param endTime
     */
    public void setEndTime(Date endTime) {
        this.endTime = endTime;
    }
    /**
     * @return district_code
     */
    public String getDistrictCode() {
        return districtCode;
    }
    /**
     * @param districtCode
     */
    public void setDistrictCode(String districtCode) {
        this.districtCode = districtCode == null ? null : districtCode.trim();
    }
    /**
     * @return district_name
     */
    public String getDistrictName() {
        return districtName;
    }
    /**
     * @param districtName
     */
    public void setDistrictName(String districtName) {
        this.districtName = districtName == null ? null : districtName.trim();
    }
    /**
     * @return town_code
     */
    public String getTownCode() {
        return townCode;
    }
    /**
     * @param townCode
     */
    public void setTownCode(String townCode) {
        this.townCode = townCode == null ? null : townCode.trim();
    }
    /**
     * @return towm_name
     */
    public String getTowmName() {
        return towmName;
    }
    /**
     * @param towmName
     */
    public void setTowmName(String towmName) {
        this.towmName = towmName == null ? null : towmName.trim();
    }
    /**
     * @return province_code
     */
    public String getProvinceCode() {
        return provinceCode;
    }
    /**
     * @param provinceCode
     */
    public void setProvinceCode(String provinceCode) {
        this.provinceCode = provinceCode == null ? null : provinceCode.trim();
    }
    /**
     * @return province_name
     */
    public String getProvinceName() {
        return provinceName;
    }
    /**
     * @param provinceName
     */
    public void setProvinceName(String provinceName) {
        this.provinceName = provinceName == null ? null : provinceName.trim();
    }
    /**
     * @return city_code
     */
    public String getCityCode() {
        return cityCode;
    }
    /**
     * @param cityCode
     */
    public void setCityCode(String cityCode) {
        this.cityCode = cityCode == null ? null : cityCode.trim();
    }
    /**
     * @return city_name
     */
    public String getCityName() {
        return cityName;
    }
    /**
     * @param cityName
     */
    public void setCityName(String cityName) {
        this.cityName = cityName == null ? null : cityName.trim();
    }
    /**
     * @return street
     */
    public String getStreet() {
        return street;
    }
    /**
     * @param street
     */
    public void setStreet(String street) {
        this.street = street == null ? null : street.trim();
    }
}
src/main/kotlin/com/flightfeather/uav/domain/mapper/SegmentInfoMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,9 @@
package com.flightfeather.uav.domain.mapper;
import com.flightfeather.uav.domain.MyMapper;
import com.flightfeather.uav.domain.entity.SegmentInfo;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface SegmentInfoMapper extends MyMapper<SegmentInfo> {
}
src/main/kotlin/com/flightfeather/uav/domain/repository/SegmentInfoRep.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.flightfeather.uav.domain.repository
import com.flightfeather.uav.domain.entity.SegmentInfo
import com.flightfeather.uav.domain.mapper.SegmentInfoMapper
import org.springframework.stereotype.Repository
/**
 * è½¨è¿¹åˆ†é𔿕°æ®åº“操作
 * @date 2024/7/4
 * @author feiyu02
 */
@Repository
class SegmentInfoRep(private val segmentInfoMapper: SegmentInfoMapper) {
    fun insert(list: List<SegmentInfo>):Int {
        return segmentInfoMapper.insertList(list)
    }
}
src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/RealTimeDataServiceImpl.kt
@@ -6,7 +6,7 @@
import com.flightfeather.uav.common.utils.ExcelUtil
import com.flightfeather.uav.common.utils.FileExchange
import com.flightfeather.uav.biz.dataprocess.AverageUtil
import com.flightfeather.uav.biz.dataprocess.TrackSegment
import com.flightfeather.uav.common.location.TrackSegment
import com.flightfeather.uav.domain.entity.*
import com.flightfeather.uav.domain.mapper.*
import com.flightfeather.uav.domain.repository.MissionRep
src/main/resources/generator/generatorConfig.xml
@@ -47,7 +47,7 @@
        </javaClientGenerator>
        <!-- è¦ç”Ÿæˆçš„表 tableName是数据库中的表名或视图名 domainObjectName是实体类名-->
<!--        <table tableName="air_real_time_data" domainObjectName="RealTimeData" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>-->
        <table tableName="mission" domainObjectName="Mission" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>
<!--        <table tableName="mission" domainObjectName="Mission" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>-->
<!--        <table tableName="el_minutevalue" domainObjectName="ElectricMinuteValue" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>-->
<!--        <table tableName="el_company_device" domainObjectName="CompanyDevice" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>-->
<!--        <table tableName="co_complaint" domainObjectName="Complaint" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>-->
@@ -60,5 +60,7 @@
<!--        <table tableName="real_time_data_grid_min" domainObjectName="RealTimeDataGridMin" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>-->
<!--        <table tableName="real_time_data_grid_opt" domainObjectName="RealTimeDataGridOpt" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>-->
<!--        <table tableName="scene_info" domainObjectName="SceneInfo" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>-->
        <table tableName="segment_info" domainObjectName="SegmentInfo" enableCountByExample="false"
               enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>
    </context>
</generatorConfiguration>
src/main/resources/mapper/SegmentInfoMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.flightfeather.uav.domain.mapper.SegmentInfoMapper">
  <resultMap id="BaseResultMap" type="com.flightfeather.uav.domain.entity.SegmentInfo">
    <!--
      WARNING - @mbg.generated
    -->
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="mission_code" jdbcType="VARCHAR" property="missionCode" />
    <result column="device_code" jdbcType="VARCHAR" property="deviceCode" />
    <result column="start_time" jdbcType="TIMESTAMP" property="startTime" />
    <result column="end_time" jdbcType="TIMESTAMP" property="endTime" />
    <result column="district_code" jdbcType="VARCHAR" property="districtCode" />
    <result column="district_name" jdbcType="VARCHAR" property="districtName" />
    <result column="town_code" jdbcType="VARCHAR" property="townCode" />
    <result column="towm_name" jdbcType="VARCHAR" property="towmName" />
    <result column="province_code" jdbcType="VARCHAR" property="provinceCode" />
    <result column="province_name" jdbcType="VARCHAR" property="provinceName" />
    <result column="city_code" jdbcType="VARCHAR" property="cityCode" />
    <result column="city_name" jdbcType="VARCHAR" property="cityName" />
    <result column="street" jdbcType="VARCHAR" property="street" />
  </resultMap>
  <sql id="Base_Column_List">
    <!--
      WARNING - @mbg.generated
    -->
    id, mission_code, device_code, start_time, end_time, district_code, district_name,
    town_code, towm_name, province_code, province_name, city_code, city_name, street
  </sql>
</mapper>
src/test/kotlin/com/flightfeather/uav/biz/dataprocess/RoadSegmentTest.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.flightfeather.uav.biz.dataprocess
import com.flightfeather.uav.common.exception.BizException
import com.flightfeather.uav.domain.repository.MissionRep
import org.junit.Test
import org.junit.Assert.*
import org.junit.runner.RunWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit4.SpringRunner
@RunWith(SpringRunner::class)
@SpringBootTest
class RoadSegmentTest {
    @Autowired
    lateinit var roadSegment: RoadSegment
    @Autowired
    lateinit var missionRep: MissionRep
    @Test
    fun handle() {
        val mission = missionRep.findOne("SH-CN-20240514") ?: throw BizException("任务不存在")
        roadSegment.handle(mission)
    }
}