From b2e89ca1b11f33417f3e83223c4aa188186c8155 Mon Sep 17 00:00:00 2001 From: feiyu02 <risaku@163.com> Date: 星期五, 05 七月 2024 17:38:18 +0800 Subject: [PATCH] 1. 新增走航报告自动道路识别模块 --- /dev/null | 150 ------------------------- src/main/kotlin/com/flightfeather/uav/biz/dataprocess/RoadSegment.kt | 51 ++++++++ src/main/kotlin/com/flightfeather/uav/common/net/AMapService.kt | 16 +- src/main/kotlin/com/flightfeather/uav/domain/repository/SegmentInfoRep.kt | 4 src/main/kotlin/com/flightfeather/uav/common/net/HttpMethod.kt | 86 +++++++------ src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/RealTimeDataServiceImpl.kt | 23 +++ pom.xml | 8 7 files changed, 131 insertions(+), 207 deletions(-) diff --git a/pom.xml b/pom.xml index 8436d7e..23dbb36 100644 --- a/pom.xml +++ b/pom.xml @@ -211,11 +211,11 @@ <artifactId>jfreechart</artifactId> <version>1.5.3</version> </dependency> - + <!-- Httpclient--> <dependency> - <groupId>commons-httpclient</groupId> - <artifactId>commons-httpclient</artifactId> - <version>3.0</version> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpmime</artifactId> + <version>4.5.14</version> </dependency> </dependencies> diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataprocess/RoadSegment.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataprocess/RoadSegment.kt index e2fbd29..1b099a3 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataprocess/RoadSegment.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataprocess/RoadSegment.kt @@ -42,7 +42,11 @@ avgGPS.add(d.longitude!!.toDouble() to d.latitude!!.toDouble()) } } - val gdGPS = AMapService.coordinateConvert(avgGPS) + val gdGPS = mutableListOf<Pair<Double, Double>>() + val _avgGPS = prepareForConvert(avgGPS) + _avgGPS.forEach { + gdGPS.addAll(AMapService.coordinateConvert(it)) + } // 閫氳繃楂樺痉API鏌ヨ鍧愭爣瀵瑰簲鐨勮矾娈� val segmentInfoList = mutableListOf<SegmentInfo>() gdGPS.forEachIndexed { i, pair -> @@ -62,6 +66,49 @@ }) } // 缁撴灉鍏ュ簱 - segmentInfoRep.insert(segmentInfoList) + saveResult(segmentInfoList) + } + + /** + * 鍧愭爣杞崲鍒嗘鍑嗗 + * 楂樺痉API鐨勫潗鏍囪浆鎹㈡帴鍙d竴娆¤闂渶澶氭敮鎸�40瀵瑰潗鏍� + */ + private fun prepareForConvert(gpsList: List<Pair<Double, Double>>): List<List<Pair<Double, Double>>> { + val res = mutableListOf<List<Pair<Double, Double>>>() + val maxLen = 40 + var start = 0 + var end = start + maxLen + while (end < gpsList.size) { + res.add(gpsList.subList(start, end)) + start += maxLen + end += maxLen + } + if (start < gpsList.size) { + res.add(gpsList.subList(start, gpsList.size)) + } + return res + } + + /** + * 缁撴灉鍏ュ簱 + * 鍏ュ簱涔嬪墠锛屽皢杩炵画骞跺睘浜庡悓涓�閬撹矾鐨勮褰曞悎骞� + */ + private fun saveResult(segmentInfoList:List<SegmentInfo>) { + val res = mutableListOf<SegmentInfo>() + segmentInfoList.forEach { s -> + // 鍒ゆ柇褰撳墠璁板綍鍜屼笂涓褰曟槸鍚︽暟鎹悓涓�鏉¢亾璺� + if (res.isNotEmpty()) { + val lastOne = res.last() + // 鑻ュ睘浜庡悓涓�閬撹矾锛屽悎骞� + if (lastOne.street == s.street) { + lastOne.endTime = s.endTime + } else { + res.add(s) + } + } else { + res.add(s) + } + } + segmentInfoRep.insert(res) } } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/common/net/AMapService.kt b/src/main/kotlin/com/flightfeather/uav/common/net/AMapService.kt index a9c5497..4ea338d 100644 --- a/src/main/kotlin/com/flightfeather/uav/common/net/AMapService.kt +++ b/src/main/kotlin/com/flightfeather/uav/common/net/AMapService.kt @@ -5,6 +5,8 @@ import com.google.gson.JsonElement import com.google.gson.JsonObject import com.google.gson.JsonParser +import org.apache.http.util.EntityUtils +import java.net.URLEncoder import java.nio.charset.Charset /** @@ -13,7 +15,7 @@ object AMapService { private const val TAG = "AMapService" - private const val KEY = "520c5e5cf44c7793104e500cbf0ed711" + private const val KEY = "b36a93bac8950d3d7c6c06f21133de51" private val httpMethod = HttpMethod("restapi.amap.com", 443, true) @@ -64,9 +66,10 @@ * @param coordsys 鍘熷潗鏍囩郴锛屽彲閫夊�硷細gps;mapbar;baidu;autonavi(涓嶈繘琛岃浆鎹�) */ fun coordinateConvert(locations: List<Pair<Double, Double>>, coordsys:String="gps"): List<Pair<Double, Double>> { + val locationsStr = URLEncoder.encode(locations.joinToString("|") { "${it.first},${it.second}" }, "UTF-8") val res = httpMethod.get("/v3/assistant/coordinate/convert", listOf( "key" to KEY, - "locations" to locations.joinToString("|") { "${it.first},${it.second}" }, + "locations" to locationsStr, "coordsys" to coordsys )) val obj = handleRes(res) @@ -82,16 +85,11 @@ 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 str = EntityUtils.toString(res.m.entity) val json = JsonParser.parseString(str) return resCheck(json) } else { - throw BizException("楂樺痉API缃戣矾閾炬帴閿欒锛岀姸鎬佺爜锛�${res.m.statusCode}") + throw BizException("楂樺痉API缃戣矾閾炬帴閿欒锛岀姸鎬佺爜锛�${res.m.statusLine.statusCode}") } } diff --git a/src/main/kotlin/com/flightfeather/uav/common/net/HttpMethod.kt b/src/main/kotlin/com/flightfeather/uav/common/net/HttpMethod.kt index 7593aba..ec25f84 100644 --- a/src/main/kotlin/com/flightfeather/uav/common/net/HttpMethod.kt +++ b/src/main/kotlin/com/flightfeather/uav/common/net/HttpMethod.kt @@ -1,41 +1,33 @@ package com.flightfeather.uav.common.net -import org.apache.commons.httpclient.HttpClient -import org.apache.commons.httpclient.HttpMethodBase -import org.apache.commons.httpclient.methods.GetMethod -import org.apache.commons.httpclient.methods.PostMethod -import org.apache.commons.httpclient.methods.StringRequestEntity -import org.apache.commons.httpclient.protocol.Protocol -import org.slf4j.LoggerFactory +import org.apache.http.HttpEntity +import org.apache.http.client.methods.CloseableHttpResponse +import org.apache.http.client.methods.HttpGet +import org.apache.http.client.methods.HttpPost +import org.apache.http.client.methods.HttpRequestBase +import org.apache.http.entity.ContentType +import org.apache.http.entity.StringEntity +import org.apache.http.impl.client.HttpClients /** * @author riku * Date: 2020/10/14 */ class HttpMethod( - private val host: String, private val port: Int, private val isHttps: Boolean = false + private val host: String, private val port: Int, private val isHttps: Boolean = false, ) { - private val logger = LoggerFactory.getLogger(HttpMethod::class.java) data class MyResponse( val success: Boolean, - val m: HttpMethodBase, + val m: CloseableHttpResponse, ) object Head { val TEXT_PLAIN = Pair("Content-Type", "text/plain") } - private val httpClient = HttpClient() - - init { - Protocol.registerProtocol("https", Protocol("https", SkipCertificateValidation.MySecureProtocolSocketFactory(), port)) - if (isHttps) { - httpClient.hostConfiguration.setHost(host, port, Protocol.getProtocol("https")) - } else { - httpClient.hostConfiguration.setHost(host, port) - } - } + private val httpClient = HttpClients.createDefault() + private val baseUrl = "${if (isHttps) "https" else "http"}://${host}:${port}" fun get(url: String, params: List<Pair<String, String>> = emptyList(), headers: List<Pair<String, String>> = emptyList()): MyResponse { var p: String = "" @@ -46,46 +38,58 @@ "&" + it.first + "=" + it.second } } - val getMethod = GetMethod("$url?$p") + val getMethod = HttpGet("$baseUrl$url?$p") defaultConfig(getMethod) headers.forEach { - getMethod.setRequestHeader(it.first, it.second) + getMethod.addHeader(it.first, it.second) } - return when (httpClient.executeMethod(getMethod)) { - 200 -> MyResponse(true, getMethod) - else -> MyResponse(false, getMethod) + val res = httpClient.execute(getMethod) + return when (res.statusLine.statusCode) { + 200 -> MyResponse(true, res) + else -> MyResponse(false, res) } } fun post(url: String, data: String = "", headers: List<Pair<String, String>> = emptyList()): MyResponse { - val postMethod = PostMethod(url) + val postMethod = HttpPost(baseUrl + url) defaultConfig(postMethod) headers.forEach { - postMethod.setRequestHeader(it.first, it.second) + postMethod.setHeader(it.first, it.second) } if (data.isNotBlank()) { - postMethod.requestEntity = StringRequestEntity(data, "application/json", "utf-8") + postMethod.entity = StringEntity(data, ContentType.APPLICATION_JSON) } - return try { - when (httpClient.executeMethod(postMethod)) { - 200 -> MyResponse(true, postMethod) - else -> MyResponse(false, postMethod) - } - } catch (e: Exception) { - logger.error(e.message) - MyResponse(false, postMethod) + val res = httpClient.execute(postMethod) + return when (res.statusLine.statusCode) { + 200 -> MyResponse(true, res) + else -> MyResponse(false, res) } } - private fun defaultConfig(method: HttpMethodBase) { - method.setRequestHeader("Accept", "*/*"); - method.setRequestHeader("Connection", "Keep-Alive"); + fun post(url: String, entity: HttpEntity, headers: List<Pair<String, String>> = emptyList()): + MyResponse { + val postMethod = HttpPost(baseUrl + url) + headers.forEach { + postMethod.addHeader(it.first, it.second) + } + postMethod.entity = entity + + val res = httpClient.execute(postMethod) + return when (res.statusLine.statusCode) { + 200 -> MyResponse(true, res) + else -> MyResponse(false, res) + } + } + + private fun defaultConfig(method: HttpRequestBase) { + method.addHeader("Accept", "*/*"); + method.addHeader("Connection", "Keep-Alive"); // method.setRequestHeader("Accept-Language", "zh-cn,zh;q=0.5"); - method.setRequestHeader("Accept-Encoding", "gzip,deflate,br"); + method.addHeader("Accept-Encoding", "gzip,deflate,br"); // method.setRequestHeader("Content-Type", "application/json;charset=utf-8") - method.setRequestHeader("Content-Type", "application/json") + method.addHeader("Content-Type", "application/json") // method.setRequestHeader("Content-Type", "application/json;charset=GBK") } diff --git a/src/main/kotlin/com/flightfeather/uav/common/net/SkipCertificateValidation.kt b/src/main/kotlin/com/flightfeather/uav/common/net/SkipCertificateValidation.kt deleted file mode 100644 index 8cc7cb1..0000000 --- a/src/main/kotlin/com/flightfeather/uav/common/net/SkipCertificateValidation.kt +++ /dev/null @@ -1,150 +0,0 @@ -package com.flightfeather.uav.common.net - -import org.apache.commons.httpclient.ConnectTimeoutException -import org.apache.commons.httpclient.HttpClientError -import org.apache.commons.httpclient.params.HttpConnectionParams -import org.apache.commons.httpclient.protocol.ControllerThreadSocketFactory -import org.apache.commons.httpclient.protocol.ProtocolSocketFactory -import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory -import java.io.IOException -import java.net.InetAddress -import java.net.Socket -import java.net.UnknownHostException -import java.security.cert.CertificateException -import java.security.cert.X509Certificate -import javax.net.ssl.* - - -/** - * 閫氳繃java 杩涜璁块棶鏈夋椂鍊欎細鏈夎瘉涔﹁繘琛屾嫤鎴� - */ -object SkipCertificateValidation { - /** - * 蹇界暐HTTPS璇锋眰鐨凷SL璇佷功锛屽繀椤诲湪openConnection涔嬪墠璋冪敤 - * @throws Exception - */ - @Throws(Exception::class) - fun ignoreSsl() { - val hv = HostnameVerifier { urlHostName, session -> - println("Warning: URL Host: " + urlHostName + " vs. " + session.peerHost) - true - } - trustAllHttpsCertificates() - HttpsURLConnection.setDefaultHostnameVerifier(hv) - } - - @Throws(Exception::class) - private fun trustAllHttpsCertificates() { - val trustAllCerts = arrayOfNulls<TrustManager>(1) - val tm: TrustManager = MiTM() - trustAllCerts[0] = tm - val sc = SSLContext.getInstance("SSL") - sc.init(null, trustAllCerts, null) - HttpsURLConnection.setDefaultSSLSocketFactory(sc.socketFactory) - } - - internal class MiTM : X509TrustManager { - override fun getAcceptedIssuers(): Array<X509Certificate>? { - return null - } - - @Throws(CertificateException::class) - override fun checkServerTrusted(certs: Array<X509Certificate>, authType: String) { - return - } - - @Throws(CertificateException::class) - override fun checkClientTrusted(certs: Array<X509Certificate>, authType: String) { - return - } - } - - class MySecureProtocolSocketFactory : ProtocolSocketFactory { - //杩欓噷娣诲姞涓�涓睘鎬э紝涓昏鐩殑灏辨槸鏉ヨ幏鍙杝sl璺宠繃楠岃瘉 - private var sslContext: SSLContext? = null - - /** - * 鍒ゆ柇鑾峰彇SSLContext - * @return - */ - private val sSLContext: SSLContext? - get() { - if (sslContext == null) { - sslContext = createEasySSLContext() - } - return sslContext - } - - //鍚庨潰鐨勬柟娉曞熀鏈笂灏辨槸甯﹀叆鐩稿叧鍙傛暟灏卞彲浠ヤ簡 - /* - * (non-Javadoc) - * - * @see org.apache.commons.httpclient.protocol.ProtocolSocketFactory#createSocket(java.lang.String, - * int, java.net.InetAddress, int) - */ - @Throws(IOException::class, UnknownHostException::class) - override fun createSocket(host: String, port: Int, clientHost: InetAddress?, clientPort: Int): Socket { - return sSLContext!!.socketFactory.createSocket(host, port, clientHost, clientPort) - } - - /* - * (non-Javadoc) - * - * @see org.apache.commons.httpclient.protocol.ProtocolSocketFactory#createSocket(java.lang.String, - * int, java.net.InetAddress, int, - * org.apache.commons.httpclient.params.HttpConnectionParams) - */ - @Throws(IOException::class, UnknownHostException::class, ConnectTimeoutException::class) - override fun createSocket( - host: String, port: Int, localAddress: InetAddress?, localPort: Int, - params: HttpConnectionParams? - ): Socket { - requireNotNull(params) { "Parameters may not be null" } - val timeout: Int = params.connectionTimeout - return if (timeout == 0) { - createSocket(host, port, localAddress, localPort) - } else { - ControllerThreadSocketFactory.createSocket(this, host, port, localAddress, localPort, timeout) - } - } - - /* - * (non-Javadoc) - * - * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int) - */ - @Throws(IOException::class, UnknownHostException::class) - override fun createSocket(host: String, port: Int): Socket { - return sSLContext!!.socketFactory.createSocket(host, port) - } - - /* - * (non-Javadoc) - * - * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean) - */ -// @Throws(IOException::class, UnknownHostException::class) -// override fun createSocket(socket: Socket?, host: String?, port: Int, autoClose: Boolean): Socket { -// return sSLContext!!.socketFactory.createSocket(socket, host, port, autoClose) -// } - - companion object { - /** - * 杩欎釜鍒涘缓涓�涓幏鍙朣SLContext鐨勬柟娉曪紝瀵煎叆MyX509TrustManager杩涜鍒濆鍖� - * @return - */ - private fun createEasySSLContext(): SSLContext { - return try { - val context = SSLContext.getInstance("SSL") - context.init( - null, arrayOf(MiTM()), - null - ) - context - } catch (e: Exception) { - throw HttpClientError(e.toString()) - } - } - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/domain/repository/SegmentInfoRep.kt b/src/main/kotlin/com/flightfeather/uav/domain/repository/SegmentInfoRep.kt index e508d45..b5daa84 100644 --- a/src/main/kotlin/com/flightfeather/uav/domain/repository/SegmentInfoRep.kt +++ b/src/main/kotlin/com/flightfeather/uav/domain/repository/SegmentInfoRep.kt @@ -15,4 +15,8 @@ fun insert(list: List<SegmentInfo>):Int { return segmentInfoMapper.insertList(list) } + + fun findList(segmentInfo: SegmentInfo): List<SegmentInfo?> { + return segmentInfoMapper.select(segmentInfo) + } } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/RealTimeDataServiceImpl.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/RealTimeDataServiceImpl.kt index ee7dd04..057472d 100644 --- a/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/RealTimeDataServiceImpl.kt +++ b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/RealTimeDataServiceImpl.kt @@ -11,6 +11,7 @@ import com.flightfeather.uav.domain.mapper.* import com.flightfeather.uav.domain.repository.MissionRep import com.flightfeather.uav.domain.repository.RealTimeDataRep +import com.flightfeather.uav.domain.repository.SegmentInfoRep import com.flightfeather.uav.lightshare.bean.* import com.flightfeather.uav.lightshare.service.RealTimeDataService import com.flightfeather.uav.model.epw.EPWDataPrep @@ -45,6 +46,7 @@ private val missionMapper: MissionMapper, private val missionRep: MissionRep, private val realTimeDataRep: RealTimeDataRep, + private val segmentInfoRep: SegmentInfoRep, ) : RealTimeDataService { @Value("\${filePath}") @@ -189,7 +191,26 @@ override fun getSegmentData(missionCode: String): List<List<DataVo>> { val mission = missionRep.findOne(missionCode) ?: throw BizException("浠诲姟涓嶅瓨鍦�") val data = realTimeDataRep.fetchData(mission) - return TrackSegment.segmentWithRoad(data).map { it.map { b -> b.toDataVo() } } + + val segInfo = SegmentInfo().apply { this.missionCode = missionCode } + val segList = segmentInfoRep.findList(segInfo) +// return TrackSegment.segmentWithRoad(data).map { it.map { b -> b.toDataVo() } } + val res = mutableListOf<MutableList<DataVo>>() + res.add(mutableListOf()) + var index = 0 + data.forEach { + if (it.dataTime == null) return@forEach + if (it.dataTime!! <= segList[index]?.endTime) { + res[index].add(it.toDataVo()) + if (it.dataTime!! == segList[index]?.endTime) { + index++ + res.add(mutableListOf()) + } + } + } + // 绉婚櫎鏈�鍚庝竴涓┖闆嗗悎 + if (res.last().isEmpty()) res.removeLast() + return res } override fun importData(file: MultipartFile): BaseResponse<DataImportResult> { -- Gitblit v1.9.3