Commit e0a57a35 authored by p x's avatar p x
Browse files

录一个召泊车数据

parent 1da693ec
...@@ -85,6 +85,8 @@ dependencies { ...@@ -85,6 +85,8 @@ dependencies {
implementation("com.github.JessYanCoding:AndroidAutoSize:v1.2.1") implementation("com.github.JessYanCoding:AndroidAutoSize:v1.2.1")
//用于坐标重投影的Proj.4库的Java端口 //用于坐标重投影的Proj.4库的Java端口
implementation("org.locationtech.proj4j:proj4j:1.4.1") implementation("org.locationtech.proj4j:proj4j:1.4.1")
// https://mvnrepository.com/artifact/org.locationtech.proj4j/proj4j-epsg
implementation("org.locationtech.proj4j:proj4j-epsg:1.3.0")// 包含EPSG定义
//sm4 加密 //sm4 加密
implementation("org.bouncycastle:bcprov-jdk15on:1.70") implementation("org.bouncycastle:bcprov-jdk15on:1.70")
......
...@@ -74,11 +74,11 @@ class ExampleInstrumentedTest { ...@@ -74,11 +74,11 @@ class ExampleInstrumentedTest {
// 计算投影 // 计算投影
// double[] result = CoordinateProjectionUtils.calculatePointProjection(testPoint, coordinateSeries); // double[] result = CoordinateProjectionUtils.calculatePointProjection(testPoint, coordinateSeries);
testPoint.forEachIndexed { index, it -> testPoint.forEachIndexed { index, it ->
val result = Proj4jCoord.calculatePointProjection(it, coordinateSeries) // val result = Proj4jCoord.calculatePointProjection(it, coordinateSeries)
println("车当前下标: (" + index + ") " + "车当前位置:" + it[0] + " " + it[1] + " 最近线段索引: " + result[2].toInt()) // println("车当前下标: (" + index + ") " + "车当前位置:" + it[0] + " " + it[1] + " 最近线段索引: " + result[2].toInt())
// println("投影点坐标: (" + result[0] + ", " + result[1] + ")") // println("投影点坐标: (" + result[0] + ", " + result[1] + ")")
// println("最近线段索引: " + result[2].toInt()) // println("最近线段索引: " + result[2].toInt())
println("最小距离: " + result[3] + " 米") // println("最小距离: " + result[3] + " 米")
} }
} }
......
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
...@@ -8,8 +8,8 @@ package com.sd.cavphmi.bean ...@@ -8,8 +8,8 @@ package com.sd.cavphmi.bean
data class AvpStatuBean( data class AvpStatuBean(
val businessType: String, val businessType: String,
val drivenDecision: DrivenDecision, val drivenDecision: DrivenDecision,
val exceptionCode: Any, // val exceptionCode: Any,
val exceptionMessage: Any, // val exceptionMessage: Any,
val haulingNo: String, val haulingNo: String,
val haulingStageState: String, val haulingStageState: String,
val space: Space, val space: Space,
...@@ -20,8 +20,8 @@ data class AvpStatuBean( ...@@ -20,8 +20,8 @@ data class AvpStatuBean(
data class DrivenDecision( data class DrivenDecision(
val endPoint: EndPoint, val endPoint: EndPoint,
val progress: Any, // val progress: Any,
val routing: Any, // val routing: Any,
val startPoint: StartPoint, val startPoint: StartPoint,
val trajectory: Trajectory val trajectory: Trajectory
) )
...@@ -30,15 +30,15 @@ data class Space( ...@@ -30,15 +30,15 @@ data class Space(
val centerLatitude: Double, val centerLatitude: Double,
val centerLongitude: Double, val centerLongitude: Double,
val code: String, val code: String,
val createdAt: Int, // val createdAt: Long,
val elevation: Any, // val elevation: Any,
val entranceLatitude: Double, val entranceLatitude: Double,
val entranceLongitude: Double, val entranceLongitude: Double,
val id: Long, val id: Long,
val line: Any, // val line: Any,
val name: String, val name: String,
val occupySource: String, // val occupySource: String,
val occupyTime: String, // val occupyTime: String,
val placeId: Int, val placeId: Int,
val spaceType: String, val spaceType: String,
val state: String, val state: String,
...@@ -48,9 +48,9 @@ data class Space( ...@@ -48,9 +48,9 @@ data class Space(
data class VehicleContext( data class VehicleContext(
val online: Boolean, val online: Boolean,
val perceptionContext: Any, // val perceptionContext: Any,
val vehicleBasic: VehicleBasic, val vehicleBasic: VehicleBasic,
val vehicleBusinessType: Any, val vehicleBusinessType: String,
val vehicleDynamic: VehicleDynamic, val vehicleDynamic: VehicleDynamic,
val vin: String val vin: String
) )
......
...@@ -59,7 +59,7 @@ class LoginActivity : AppCompatActivity() { ...@@ -59,7 +59,7 @@ class LoginActivity : AppCompatActivity() {
lifecycleScope.launch { lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) { repeatOnLifecycle(Lifecycle.State.STARTED) {
loginVm.login(user, PWD, VERIFYCODE).collect { loginVm.login(user, PWD, VERIFYCODE).collect {
println("-----------登录回调 = ${it}") // println("-----------登录回调 = ${it}")
//获取可绑定车辆 //获取可绑定车辆
if (it == 1) { if (it == 1) {
getBinderCars() getBinderCars()
......
...@@ -221,26 +221,22 @@ class MainActivity : BaseActivity<ActivityMainBinding, MyBaseViewModel>() { ...@@ -221,26 +221,22 @@ class MainActivity : BaseActivity<ActivityMainBinding, MyBaseViewModel>() {
return return
//业务类型 //业务类型
var businessType = avpStatu.businessType//NIL Park Call var businessType = avpStatu.businessType//NIL Park Call
if (businessType == AvpContants.NIL_TYPE) {
clearAllEffect(businessType)
return
}
//业务状态 //业务状态
var businessStatus = avpStatu.haulingStageState var businessStatus = avpStatu.haulingStageState
//获取档位 //获取档位
var gearType = avpStatu.vehicleContext.vehicleDynamic.gearType var gearType = avpStatu.vehicleContext.vehicleDynamic.gearType
//画全局路径 //画全局路径
mapOpt.drawAllLines(avpStatu.drivenDecision) mapOpt.drawAllLines(avpStatu.drivenDecision,businessStatus)
//生成小地图路线以及二维坐标点 //生成小地图路线
mapOpt.takeSmallMapLine(avpStatu.drivenDecision) mapOpt.takeSmallMapLine(avpStatu.drivenDecision,businessStatus)
//画终点 //画终点
mapOpt.addEndMarker(avpStatu.drivenDecision.endPoint) mapOpt.addEndMarker(avpStatu.drivenDecision.endPoint,businessStatus)
//是否显示车位流光效果 //是否显示车位流光效果
mapOpt.showParkLight(businessType, avpStatu.space) mapOpt.showParkLight(businessType, businessStatus,avpStatu.space)
//判断在泊车状态下的倒挡绘制倒车路线,改变镜头视角,,判断车是否到达停车点 //判断在泊车状态下的倒挡绘制倒车路线,改变镜头视角,,判断车是否到达停车点
mapOpt.drawReversePark(businessType, businessStatus, gearType, avpStatu.space) mapOpt.drawReversePark(businessType, businessStatus, gearType, avpStatu.space)
//根据AVP任务状态判停车特效是否关闭 //根据AVP任务状态判停车特效是否关闭
mapOpt.showEffectAvpStatu(businessType, businessStatus) // mapOpt.showEffectAvpStatu(businessType, businessStatus)
} }
/***是否展示车内视频****/ /***是否展示车内视频****/
...@@ -254,26 +250,40 @@ class MainActivity : BaseActivity<ActivityMainBinding, MyBaseViewModel>() { ...@@ -254,26 +250,40 @@ class MainActivity : BaseActivity<ActivityMainBinding, MyBaseViewModel>() {
} }
/**清除所有特效****/ /**清除所有特效****/
private fun clearAllEffect(businessType: String) { private fun clearAllEffect(businessType: String, businessStatus: String): Boolean {
if (businessType == AvpContants.NIL_TYPE) { if (businessStatus == AvpContants.TRANSPORT_COMPLETED) {
//消除车位流光特效
HighMapApi.parkRoundLight("")
//消除泊车特效
HighMapApi.setParkComplete(true)
//消除全局路径 //消除全局路径
HighMapApi.setCarNavPath(emptyList()) HighMapApi.setCarNavPath(emptyList())
//清除所有绘制 //清除所有绘制
mapOpt.clearAllEffect() mapOpt.clearAllEffect()
//重置变量
resetVariable(businessType)
} }
if (businessType == AvpContants.CALL_TYPE) {
if (businessStatus == AvpContants.TRANSPORT_COMPLETED) {
//重置变量
resetVariable(businessStatus)
}
} else if (businessType == AvpContants.Park_TYPE) {
if (businessStatus == AvpContants.TRANSPORT_COMPLETED) {
} else if (businessStatus == AvpContants.PARK_COMPLETED) {
//消除车位流光特效
HighMapApi.parkRoundLight("")
//消除泊车特效
HighMapApi.setParkComplete(true)
//重置变量
resetVariable(businessStatus)
}
}
return false
} }
/***重置变量**/ /***重置变量**/
private fun resetVariable(businessType: String) { private fun resetVariable(businessStatus: String) {
if (businessType == AvpContants.NIL_TYPE) { if (businessStatus == AvpContants.TRANSPORT_COMPLETED) {
mainVm.isGetVehDetail = false mainVm.isGetVehDetail = false
mapOpt.smallMapLine = false // mapOpt.smallMapLine = false
} }
} }
...@@ -294,22 +304,27 @@ class MainActivity : BaseActivity<ActivityMainBinding, MyBaseViewModel>() { ...@@ -294,22 +304,27 @@ class MainActivity : BaseActivity<ActivityMainBinding, MyBaseViewModel>() {
return return
if (car.vehiclePos == null || car.vehiclePos.count() < 3) if (car.vehiclePos == null || car.vehiclePos.count() < 3)
return return
// setCarCamera(1) try {
//画小地图小车 var tHead = car.vehiclePos.get(2)
mapOpt.drawSmallCar(car) //画小地图小车
//刷新右下角小车位置 mapOpt.drawSmallCar(car)
mapOpt.showNavingCarPosition(car) //刷新右下角小车位置
//刷新右下角小地图路径 mapOpt.showNavingCarPosition(car)
mapOpt.upSmallMapLine(car) //刷新右下角小地图路径
mapOpt.upSmallMapLine(car)
// println("----car.heading ${car.heading}") // println("----car.heading ${car.heading}")
//刷新主车位置 //刷新主车位置
HighMapApi.setCarPosition( HighMapApi.setCarPosition(
car.vehiclePos!!.get(2), car.vehiclePos!!.get(2),
car.vehiclePos.get(1), car.vehiclePos.get(1),
car.vehiclePos.get(0), car.vehiclePos.get(0),
20.80189 20.80189
// car.elevation // car.elevation
) )
} catch (e: NullPointerException) {
//隐藏小车
}
// setCarCamera(1)
} }
//联网车辆感知物 //联网车辆感知物
......
package com.sd.cavphmi.utils
import android.graphics.Point
import com.minedata.minenavi.mapdal.LatLng
import com.minedata.minenavi.util.Tools
object AvpMapUtils {
//找到离车最近点的下标
suspend fun findNearPointIndex(
point: LatLng,
sLatLngs: List<Point>
): Int {
var minDistance = Double.Companion.MAX_VALUE
var nearestIndex = -1
var series = sLatLngs.map {
Tools.pointToLatLng(it)
}
//获取起点和终点
var sPoi = series.first()
var ePoi = series.last()
//离起点距离
var sDis =
MyMapUtils.cauMyLocDistance(
point.longitude, point.latitude,
sPoi.longitude, sPoi.latitude
)
// println("---------------distance = ${distance}")
//线段长度
var lineSeg = MyMapUtils.cauMyLocDistance(
sPoi.longitude, sPoi.latitude,
ePoi.longitude, ePoi.latitude
)
if (sDis > lineSeg * 2) {
return 0
}
series.forEachIndexed { index, latLng ->
val distance = MyMapUtils.cauMyLocDistance(
point.longitude,
point.latitude,
latLng.longitude,
latLng.latitude
)
// println("---------distance = ${distance} index = ${index}")
if (distance < minDistance) {
minDistance = distance
nearestIndex = index
}
}
return nearestIndex
}
}
\ No newline at end of file
package com.sd.cavphmi.utils; package com.sd.cavphmi.utils;
import android.graphics.Point;
import android.location.Location; import android.location.Location;
import com.minedata.minenavi.mapdal.LatLng; import com.minedata.minenavi.mapdal.LatLng;
import java.lang.reflect.Array;
public class MyMapUtils { public class MyMapUtils {
...@@ -121,4 +124,7 @@ public class MyMapUtils { ...@@ -121,4 +124,7 @@ public class MyMapUtils {
} }
} }
package com.sd.cavphmi.utils package com.sd.cavphmi.utils
import org.locationtech.proj4j.CRSFactory import org.locationtech.proj4j.CRSFactory
import org.locationtech.proj4j.CoordinateReferenceSystem
import org.locationtech.proj4j.CoordinateTransform
import org.locationtech.proj4j.CoordinateTransformFactory
import org.locationtech.proj4j.Proj4jException import org.locationtech.proj4j.Proj4jException
import org.locationtech.proj4j.ProjCoordinate import org.locationtech.proj4j.ProjCoordinate
import kotlin.math.atan2 import kotlin.math.atan2
...@@ -10,11 +13,35 @@ import kotlin.math.min ...@@ -10,11 +13,35 @@ import kotlin.math.min
import kotlin.math.sin import kotlin.math.sin
import kotlin.math.sqrt import kotlin.math.sqrt
class CoordResultBean {
//最近点
var nearPoi: ProjCoordinate? = null
//线段下标
var nearIndex: Int = 0
var distance = 0
}
/**坐标投影转换工具***/ /**坐标投影转换工具***/
object Proj4jCoord { object Proj4jCoord {
private val crsFactory: CRSFactory = CRSFactory() private val crsFactory: CRSFactory = CRSFactory()
private var transformFactory: CoordinateTransformFactory = CoordinateTransformFactory()
// 定义 WGS84 (经纬度) 和 Web墨卡托 (用于计算) 坐标系
var wgs84: CoordinateReferenceSystem = crsFactory.createFromName("epsg:4326") // 经纬度源坐标
// var webMercator: CoordinateReferenceSystem = crsFactory.createFromName("epsg:3857") // 投影目标坐标
var webMercator: CoordinateReferenceSystem = crsFactory.createFromName("EPSG:32650") // 投影目标坐标
// 创建转换器
var wgsToMercator: CoordinateTransform = transformFactory.createTransform(wgs84, webMercator)
// 创建逆转换器 (墨卡托 -> WGS84)
var mercatorToWgs: CoordinateTransform = transformFactory.createTransform(webMercator, wgs84)
//返回结果 //返回结果
private val resultArray=doubleArrayOf(0.0, 0.0, 0.0, 0.0) private val resultBean = CoordResultBean()
// private val resultArray = doubleArrayOf(0.0, 0.0, 0.0, 0.0)
// 定义坐标系参数 // 定义坐标系参数
private const val WGS84_PARAMS = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs" private const val WGS84_PARAMS = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"
...@@ -33,23 +60,18 @@ object Proj4jCoord { ...@@ -33,23 +60,18 @@ object Proj4jCoord {
suspend fun calculatePointProjection( suspend fun calculatePointProjection(
point: DoubleArray, point: DoubleArray,
coordinateSeries: MutableList<DoubleArray> coordinateSeries: MutableList<DoubleArray>
): DoubleArray { ): CoordResultBean {
try { try {
// 创建坐标系 // 转换点到投影坐标
/* val wgs84: CoordinateReferenceSystem? = val pointWgs = ProjCoordinate(point[0], point[1]) // 你的点经纬度
crsFactory.createFromParameters( val pointMercator = ProjCoordinate()
"WGS84", wgsToMercator.transform(pointWgs, pointMercator)
WGS84_PARAMS
) // val projectedPoint = doubleArrayOf(pointMercator.x, pointMercator.y)
val cgcs2000: CoordinateReferenceSystem? =
crsFactory.createFromParameters( // //直接使用02坐标系
"CGCS2000", // val dstCoord = ProjCoordinate(point[0], point[1])
CGCS2000_BEIJING_3_DEGREE_ZONE_39 // val projectedPoint = doubleArrayOf(dstCoord.x, dstCoord.y)
)*/
//直接使用02坐标系
val dstCoord = ProjCoordinate(point[0], point[1])
val projectedPoint = doubleArrayOf(dstCoord.x, dstCoord.y)
// 转换坐标点串到CGCS2000坐标系 // 转换坐标点串到CGCS2000坐标系
// var projectedSeries = mutableListOf<DoubleArray>() // var projectedSeries = mutableListOf<DoubleArray>()
...@@ -58,10 +80,10 @@ object Proj4jCoord { ...@@ -58,10 +80,10 @@ object Proj4jCoord {
// } // }
// 计算点到线串的最短距离和投影点 // 计算点到线串的最短距离和投影点
return findNearestProjection(projectedPoint, coordinateSeries) return findNearestProjection(pointMercator, coordinateSeries)
} catch (e: Proj4jException) { } catch (e: Proj4jException) {
e.printStackTrace() e.printStackTrace()
return doubleArrayOf(0.0, 0.0, -1.0, -1.0) return CoordResultBean()
} }
} }
...@@ -70,48 +92,83 @@ object Proj4jCoord { ...@@ -70,48 +92,83 @@ object Proj4jCoord {
* 在投影后的坐标系中查找最近投影点 * 在投影后的坐标系中查找最近投影点
*/ */
private fun findNearestProjection( private fun findNearestProjection(
point: DoubleArray, point: ProjCoordinate,
series: MutableList<DoubleArray> series: MutableList<DoubleArray>
): DoubleArray { ): CoordResultBean {
var minDistance = Double.Companion.MAX_VALUE var minDistance = Double.Companion.MAX_VALUE
var nearestIndex = -1 var nearestIndex = -1
var projectionPoint = DoubleArray(2) var nearPoi: ProjCoordinate? = null
// 遍历所有线段计算投影 // 遍历所有线段计算投影
for (i in 0..<series.size - 1) { for (i in 0..<series.size - 1) {
val start = series.get(i) val start = series.get(i)
val end = series.get(i + 1) val end = series.get(i + 1)
val currentProjection: DoubleArray = projectPointToLine(point, start, end) // 同样转换线段的两个端点
val lineStartWgs = ProjCoordinate(start[0], start[1])
val lineEndWgs = ProjCoordinate(end[0], end[1])
val lineStartMercator = ProjCoordinate()
val lineEndMercator = ProjCoordinate()
wgsToMercator.transform(lineStartWgs, lineStartMercator)
wgsToMercator.transform(lineEndWgs, lineEndMercator)
// val currentProjection: DoubleArray = projectPointToLine(point, start, end)
// val currentProjection: DoubleArray = series.get(i) // val currentProjection: DoubleArray = series.get(i)
var closestPointWgs = closestPointOnSegment(point, lineStartMercator, lineEndMercator)
// 转换最近点回 WGS84
nearPoi = ProjCoordinate()
mercatorToWgs.transform(closestPointWgs, nearPoi)
//计算点距离 //计算点距离
val distance: Double = calculateDistance(point, currentProjection) val distance: Double = calculateDistance(point, closestPointWgs)
// var distance = MyMapUtils.cauMyLocDistance( // println("-------nearPoi = ${nearPoi.x} ${nearPoi.y} i = ${i}")
// point[0], // println("---------------distance = ${distance} i = ${i}")
// point[1],
// currentProjection[0],
// currentProjection[1]
// )
println("-------distance = ${distance} i= ${i}")
if (distance < minDistance) { if (distance < minDistance) {
minDistance = distance minDistance = distance
nearestIndex = i nearestIndex = i
projectionPoint = currentProjection
} }
} }
resultArray.set(0,projectionPoint[0]) resultBean.nearPoi = nearPoi
resultArray.set(1,projectionPoint[1]) return resultBean
resultArray.set(2,nearestIndex.toDouble()) }
resultArray.set(3,minDistance)
//在投影坐标下,使用向量投影法计算点到线段的最近点
return resultArray fun closestPointOnSegment(
point: ProjCoordinate,
// return doubleArrayOf( lineStart: ProjCoordinate,
// projectionPoint[0], lineEnd: ProjCoordinate
// projectionPoint[1], ): ProjCoordinate {
// nearestIndex.toDouble(), // 计算方向向量 d = lineEnd - lineStart
// minDistance val dx = lineEnd.x - lineStart.x
// ) val dy = lineEnd.y - lineStart.y
// 如果线段退化为一个点,直接返回起点
if (dx == 0.0 && dy == 0.0) {
return ProjCoordinate(lineStart.x, lineStart.y)
}
// 计算向量 AP = point - lineStart
val apx = point.x - lineStart.x
val apy = point.x - lineStart.y
// 计算投影参数 t = (AP · d) / (d · d)
// 点积公式: ap dot d = apx * dx + apy * dy
val dot = apx * dx + apy * dy
val lenSq = dx * dx + dy * dy
val t = dot / lenSq
// val t = if (lenSq != 0.0) max(0.0, min(1.0, dot / lenSq)) else 0.0
// 检查最近点是否在线段范围内
if (t < 0.0) {
return ProjCoordinate(lineStart.x, lineStart.y) // 最近点是起点
} else if (t > 1.0) {
return ProjCoordinate(lineEnd.x, lineEnd.y) // 最近点是终点
} else {
// 最近点在线段上: lineStart + t * d
val closestX = lineStart.x + t * dx
val closestY = lineStart.y + t * dy
return ProjCoordinate(closestX, closestY)
}
} }
...@@ -145,13 +202,13 @@ object Proj4jCoord { ...@@ -145,13 +202,13 @@ object Proj4jCoord {
/** /**
* 计算两点间距离 * 计算两点间距离
*/ */
private fun calculateDistance(p1: DoubleArray, p2: DoubleArray): Double { private fun calculateDistance(p1: ProjCoordinate, p2: ProjCoordinate): Double {
var dx = p1[0] - p2[0] val dx: Double = p2.x - p1.y
var dy = p1[1] - p2[1] val dy: Double = p2.y - p1.y
return Math.sqrt(Math.pow(dx, 2.0) + Math.pow(dy, 2.0)) return sqrt(dx * dx + dy * dy)
// 角度转弧度 // 角度转弧度
val radLat1 = Math.toRadians(p1[1]) /* val radLat1 = Math.toRadians(p1[1])
val radLon1 = Math.toRadians(p1[0]) val radLon1 = Math.toRadians(p1[0])
val radLat2 = Math.toRadians(p2[1]) val radLat2 = Math.toRadians(p2[1])
val radLon2 = Math.toRadians(p2[0]) val radLon2 = Math.toRadians(p2[0])
...@@ -166,7 +223,7 @@ object Proj4jCoord { ...@@ -166,7 +223,7 @@ object Proj4jCoord {
val c = 2 * atan2(sqrt(a), sqrt(1 - a)) val c = 2 * atan2(sqrt(a), sqrt(1 - a))
// 距离 = 地球半径 × 圆心角 // 距离 = 地球半径 × 圆心角
return EARTH_RADIUS * c return EARTH_RADIUS * c*/
} }
......
...@@ -93,7 +93,7 @@ class MainVm @Inject constructor( ...@@ -93,7 +93,7 @@ class MainVm @Inject constructor(
lateinit var mockVM: MockVM lateinit var mockVM: MockVM
//是否需要模拟 //是否需要模拟
var isMock = false var isMock = true
//车辆位姿数据 //车辆位姿数据
// var carVehicle = MutableLiveData<CarVehicle>() // var carVehicle = MutableLiveData<CarVehicle>()
...@@ -186,14 +186,14 @@ class MainVm @Inject constructor( ...@@ -186,14 +186,14 @@ class MainVm @Inject constructor(
//HTTP获取AVP状态 //HTTP获取AVP状态
fun getAvpStatus(): SharedFlow<AvpStatuBean> { fun getAvpStatus(): SharedFlow<AvpStatuBean> {
// if (isMock) { if (isMock) {
mockVM.subAvpStatus(avpStatu) mockVM.subAvpStatus(avpStatu)
// } else { } else {
// var url = "${MyContants.HOST}/api/avpweb/hmi/monitor/v1/taskStatus" var url = "${MyContants.HOST}/api/avpweb/hmi/monitor/v1/taskStatus"
// avpCb.url = url avpCb.url = url
// var body = RequestBodyUtil.toRequestBody(mapOf("id" to MyContants.VEHICLEID)) var body = RequestBodyUtil.toRequestBody(mapOf("id" to MyContants.VEHICLEID))
// avpDataRepo.getAvpStatus(url, body, avpCb) avpDataRepo.getAvpStatus(url, body, avpCb)
// } }
return avpStatu return avpStatu
} }
...@@ -208,7 +208,7 @@ class MainVm @Inject constructor( ...@@ -208,7 +208,7 @@ class MainVm @Inject constructor(
override fun onEvent(data: String) { override fun onEvent(data: String) {
viewModelScope.launch { viewModelScope.launch {
if (data.isNotEmpty()) { if (data.isNotEmpty()) {
println("-------AVP状态 = ${data}") // println("-------AVP状态 = ${data}")
FileIoUtils.writeToFile(data, "avp_status.txt") FileIoUtils.writeToFile(data, "avp_status.txt")
var result = gson.fromJson<AvpStatuBean>(data, AvpStatuBean::class.java) var result = gson.fromJson<AvpStatuBean>(data, AvpStatuBean::class.java)
avpStatu.emit(result) avpStatu.emit(result)
...@@ -217,8 +217,11 @@ class MainVm @Inject constructor( ...@@ -217,8 +217,11 @@ class MainVm @Inject constructor(
} }
override fun onError(throwable: Throwable) { override fun onError(throwable: Throwable) {
println("------开启AVP状态连接是失败 throwable = ${throwable}") println("------开启AVP状态连接是失败 throwable = ${throwable} 2秒重连")
getAvpStatus() viewModelScope.launch {
delay(2000)
getAvpStatus()
}
} }
override fun onClosed() { override fun onClosed() {
......
...@@ -23,7 +23,7 @@ import com.sd.cavphmi.highmap.AllLine ...@@ -23,7 +23,7 @@ import com.sd.cavphmi.highmap.AllLine
import com.sd.cavphmi.highmap.HighMapApi import com.sd.cavphmi.highmap.HighMapApi
import com.sd.cavphmi.highmap.ReverCar import com.sd.cavphmi.highmap.ReverCar
import com.sd.cavphmi.utils.AvpContants import com.sd.cavphmi.utils.AvpContants
import com.sd.cavphmi.utils.Proj4jCoord import com.sd.cavphmi.utils.AvpMapUtils
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
...@@ -48,7 +48,7 @@ class MapOpt @Inject constructor( ...@@ -48,7 +48,7 @@ class MapOpt @Inject constructor(
private var sLatLngs: Array<Point>? = null private var sLatLngs: Array<Point>? = null
// 小地图路径坐标点串 (02坐标系) // 小地图路径坐标点串 (02坐标系)
private var coordinateSeries = ArrayList<DoubleArray>() // private var coordinateSeries = ArrayList<DoubleArray>()
private var sPolyline: Polyline? = null private var sPolyline: Polyline? = null
//是否进入泊车倒车状态 //是否进入泊车倒车状态
...@@ -61,7 +61,12 @@ class MapOpt @Inject constructor( ...@@ -61,7 +61,12 @@ class MapOpt @Inject constructor(
private var allLines: List<AllLine>? = null private var allLines: List<AllLine>? = null
//画全局路径 //画全局路径
fun drawAllLines(drivenDecision: DrivenDecision) { fun drawAllLines(drivenDecision: DrivenDecision, businessStatus: String) {
if (businessStatus == AvpContants.TRANSPORT_COMPLETED || businessStatus == AvpContants.PARK_COMPLETED) {
//清除全局路径
HighMapApi.setCarNavPath(emptyList())
return
}
if (drivenDecision.trajectory.points.count() > 0) { if (drivenDecision.trajectory.points.count() > 0) {
//全局路径这里只执行一次 //全局路径这里只执行一次
// if (allLines == null || allLines?.count() == 0) { // if (allLines == null || allLines?.count() == 0) {
...@@ -102,18 +107,20 @@ class MapOpt @Inject constructor( ...@@ -102,18 +107,20 @@ class MapOpt @Inject constructor(
/****根据车辆位置 画局部图小车*/ /****根据车辆位置 画局部图小车*/
fun drawSmallCar(car: CarVehicle) { fun drawSmallCar(car: CarVehicle) {
synchronized(this) { synchronized(this) {
if (mSmallMapCar == null && car.vehiclePos != null) { if (mMineMap != null && car.vehiclePos != null) {
var point = if (mSmallMapCar == null) {
LatLng(car.vehiclePos.get(1), car.vehiclePos.get(0)) var point =
mSmallMapCar = MyLocationStyle("res/icons/carIconInSmallMap.png", true) LatLng(car.vehiclePos.get(1), car.vehiclePos.get(0))
mSmallMapCar?.myLocationType(MyLocationStyle.LOCATION_TYPE_EXTERNAL) mSmallMapCar = MyLocationStyle("res/icons/carIconInSmallMap.png", true)
val scaleFactor = - mSmallMapCar?.myLocationType(MyLocationStyle.LOCATION_TYPE_EXTERNAL)
Math.round(((10 * NativeEnv.getDpi() * 2) * 10 / (160 * 48)).toFloat()) val scaleFactor = -
.toFloat() / 10 Math.round(((10 * NativeEnv.getDpi() * 2) * 10 / (160 * 48)).toFloat())
mSmallMapCar?.scaleFactor(scaleFactor) .toFloat() / 10
mSmallMapCar?.anchor(0.5f, 0.5f) mSmallMapCar?.scaleFactor(scaleFactor)
mSmallMapCar?.setPosition(point) mSmallMapCar?.anchor(0.5f, 0.5f)
mMineMap?.setMyLocationStyle(mSmallMapCar) mSmallMapCar?.setPosition(point)
mMineMap?.setMyLocationStyle(mSmallMapCar)
}
} }
} }
} }
...@@ -126,76 +133,87 @@ class MapOpt @Inject constructor( ...@@ -126,76 +133,87 @@ class MapOpt @Inject constructor(
return return
synchronized(NativeEnv.SyncObject) { synchronized(NativeEnv.SyncObject) {
var ndsLatLng = LatLng(carVehicle.vehiclePos.get(1), carVehicle.vehiclePos.get(0)) var ndsLatLng = LatLng(carVehicle.vehiclePos.get(1), carVehicle.vehiclePos.get(0))
var tHead = carVehicle.vehiclePos.get(2) var tHead = carVehicle.vehiclePos.get(2).toFloat()
var heading = 0f
if (tHead != null) {
heading = tHead.toFloat()
}
//刷新小地图自车位置 //刷新小地图自车位置
if (mSmallMapCar != null) { if (mSmallMapCar != null) {
// mSmallMapCar!!.orientAngle((heading + 40) % 360) // mSmallMapCar!!.orientAngle((heading + 40) % 360)
mSmallMapCar!!.orientAngle(0f - 180f - heading) mSmallMapCar!!.orientAngle(0f - 180f - tHead)
// mSmallMapCar!!.orientAngle((heading + 180) % 360) // mSmallMapCar!!.orientAngle((heading + 180) % 360)
mSmallMapCar!!.setPositionNds(ndsLatLng) mSmallMapCar!!.setPositionNds(ndsLatLng)
// val point = Tools.latLngToPoint(ndsLatLng)
// mMineMap?.setPointToCenter(point.x, point.y)
} }
} }
} }
/***生成小地图路线 并转化为二维坐标系*/ /***生成小地图路线 并转化为二维坐标系*/
fun takeSmallMapLine(drivenDecision: DrivenDecision) { fun takeSmallMapLine(drivenDecision: DrivenDecision, businessStatus: String) {
if (smallMapLine) if (businessStatus == AvpContants.TRANSPORT_COMPLETED) {
return //清除全局路径
if (coordinateSeries.count() > 0) sLatLngs?.toMutableList()?.clear()
sLatLngs = null
return return
}
// if (smallMapLine)
// return
// if (coordinateSeries.count() > 0)
// return
if (drivenDecision.trajectory.points.count() > 0) { if (drivenDecision.trajectory.points.count() > 0) {
smallMapLine = true // smallMapLine = true
//转换小弟提路径点 //转换小弟提路径点
sLatLngs = drivenDecision.trajectory.points.map { sLatLngs = drivenDecision.trajectory.points.map {
Tools.latLngToPoint(LatLng(it.latitude, it.longitude)) Tools.latLngToPoint(LatLng(it.latitude, it.longitude))
}.toTypedArray() }.toTypedArray()
//生成DoubleArray //生成DoubleArray
sLatLngs?.forEach { // sLatLngs?.forEach {
var ll = Tools.pointToLatLng(it) // var ll = Tools.pointToLatLng(it)
var temp = doubleArrayOf(ll.longitude, ll.latitude) // var temp = doubleArrayOf(ll.longitude, ll.latitude)
coordinateSeries.add(temp) // coordinateSeries.add(temp)
} // }
} }
} }
//更新小地图路径 //更新小地图路径
fun upSmallMapLine(carVehicle: CarVehicle) { fun upSmallMapLine(carVehicle: CarVehicle) {
// deleteSmapLine() if (sLatLngs != null && (sLatLngs?.count() ?: 0) > 0) {
viewModelScope.launch(Dispatchers.Default) { //当前车辆位置
if (coordinateSeries.count() > 0) { var latlng = LatLng(carVehicle.vehiclePos!!.get(1), carVehicle.vehiclePos.get(0))
//当前车辆位置 //投影计算结果
var latlng = LatLng(carVehicle.vehiclePos!!.get(1), carVehicle.vehiclePos.get(0)) // var result = Proj4jCoord.calculatePointProjection(
//投影计算结果 // doubleArrayOf(latlng.longitude, latlng.latitude),
var result = Proj4jCoord.calculatePointProjection( // coordinateSeries
doubleArrayOf(latlng.latitude, latlng.longitude), // )
coordinateSeries viewModelScope.launch(Dispatchers.Default) {
) var index = AvpMapUtils.findNearPointIndex(latlng, sLatLngs!!.toList())
// println("----最近线段索引: " + result[2].toInt()) // println("----最近线段索引: " + index)
var index = result[2].toInt() // var index = result.nearIndex
//截取线段
var nPoints = sLatLngs?.sliceArray(index..sLatLngs!!.lastIndex)
//删除线 //删除线
deleteSmapLine() deleteSmapLine()
// if (sPolyline == null) { synchronized(NativeEnv.SyncObject) {
sPolyline = Polyline(nPoints, false) //截取线段
sPolyline?.setStrokeStyle(Overlay.StrokeStyle.solidWithButt) var nPoints = sLatLngs!!.sliceArray(index..sLatLngs!!.lastIndex)
sPolyline?.setWidth(8f) sPolyline = Polyline(nPoints, false)
sPolyline?.setColor(0xFF00B578.toInt()) sPolyline?.setStrokeStyle(Overlay.StrokeStyle.solidWithButt)
mMineMap?.addOverlay(sPolyline) sPolyline?.setWidth(8f)
// } sPolyline?.setColor(0xFF00B578.toInt())
mMineMap?.addOverlay(sPolyline)
}
} }
} else {
deleteSmapLine()
} }
// }
} }
/**画路径起终点***/ /**画路径起终点***/
fun addEndMarker(endPoint: EndPoint) { fun addEndMarker(endPoint: EndPoint, businessStatus: String) {
//删除终点marker if (businessStatus == AvpContants.TRANSPORT_COMPLETED) {
// deleteEndMarker() //删除终点marker
deleteEndMarker()
return
}
if (pEndMarker == null) { if (pEndMarker == null) {
var mEndPoint = LatLng(endPoint.latitude, endPoint.longitude) var mEndPoint = LatLng(endPoint.latitude, endPoint.longitude)
val end_icon = BitmapFactory.decodeResource(context.resources, R.drawable.plan_end) val end_icon = BitmapFactory.decodeResource(context.resources, R.drawable.plan_end)
...@@ -227,6 +245,9 @@ class MapOpt @Inject constructor( ...@@ -227,6 +245,9 @@ class MapOpt @Inject constructor(
this.code = space.code this.code = space.code
} }
HighMapApi.setParkRever(reverCar) HighMapApi.setParkRever(reverCar)
} else if (businessStatus == AvpContants.PARK_COMPLETED) {
//消除泊车特效
HighMapApi.setParkComplete(true)
} else { } else {
HighMapApi.setCameraAngle(30f) HighMapApi.setCameraAngle(30f)
HighMapApi.setCameraDistance(6f) HighMapApi.setCameraDistance(6f)
...@@ -242,9 +263,14 @@ class MapOpt @Inject constructor( ...@@ -242,9 +263,14 @@ class MapOpt @Inject constructor(
//是否显示车位流光效果 //是否显示车位流光效果
fun showParkLight(businessType: String, space: Space) { fun showParkLight(businessType: String, businessStatus: String, space: Space) {
if (businessType == AvpContants.Park_TYPE) { if (businessType == AvpContants.Park_TYPE) {
HighMapApi.parkRoundLight(space.name) if (businessStatus == AvpContants.PARK_COMPLETED) {
//消除车位流光特效
HighMapApi.parkRoundLight("")
} else {
HighMapApi.parkRoundLight(space.name)
}
} else { } else {
// HighMapApi.parkRoundLight("") // HighMapApi.parkRoundLight("")
} }
...@@ -264,7 +290,7 @@ class MapOpt @Inject constructor( ...@@ -264,7 +290,7 @@ class MapOpt @Inject constructor(
} }
//倒车完成 //倒车完成
if (businessType == AvpContants.Park_TYPE) { if (businessType == AvpContants.Park_TYPE) {
if (businessStatus == AvpContants.PARK_COMPLETED) { if (businessStatus == AvpContants.PARK_COMPLETED || businessStatus == AvpContants.PARK_CANCELED) {
//消除车位流光特效 //消除车位流光特效
HighMapApi.parkRoundLight("") HighMapApi.parkRoundLight("")
//消除泊车特效 //消除泊车特效
...@@ -315,7 +341,7 @@ class MapOpt @Inject constructor( ...@@ -315,7 +341,7 @@ class MapOpt @Inject constructor(
//清除小地图路径数据 //清除小地图路径数据
fun clearSmallLineData() { fun clearSmallLineData() {
coordinateSeries.clear() // coordinateSeries.clear()
sLatLngs?.toMutableList()?.clear() sLatLngs?.toMutableList()?.clear()
} }
......
...@@ -237,13 +237,13 @@ class MockVM @Inject constructor( ...@@ -237,13 +237,13 @@ class MockVM @Inject constructor(
viewModelScope.launch { viewModelScope.launch {
var gson = Gson() var gson = Gson()
var datas = mutableListOf<String>() var datas = mutableListOf<String>()
FileIoUtils.getAssetMock(context, "mock/CarVehicle_Test.txt", datas) FileIoUtils.getAssetMock(context, "mock/shiche/CarVehicle_Call.txt", datas)
datas.forEach { str -> datas.forEach { str ->
val cCar = gson.fromJson<CarVehicle>(str, CarVehicle::class.java) val cCar = gson.fromJson<CarVehicle>(str, CarVehicle::class.java)
if (cCar.vehiclePos != null) { if (cCar.vehiclePos != null) {
carLiveData.value = cCar carLiveData.value = cCar
// carLiveData.postValue(cCar) // carLiveData.postValue(cCar)
delay(200) delay(300)
} }
} }
} }
...@@ -440,7 +440,7 @@ class MockVM @Inject constructor( ...@@ -440,7 +440,7 @@ class MockVM @Inject constructor(
viewModelScope.launch { viewModelScope.launch {
var gson = Gson() var gson = Gson()
var datas = mutableListOf<String>() var datas = mutableListOf<String>()
FileIoUtils.getAssetMock(context, "mock/avp_status.txt", datas) FileIoUtils.getAssetMock(context, "mock/shiche/avp_status_call.txt", datas)
var str = datas.first() var str = datas.first()
val statu = gson.fromJson<AvpStatuBean>(str, AvpStatuBean::class.java) val statu = gson.fromJson<AvpStatuBean>(str, AvpStatuBean::class.java)
for (i in 0..10000) { for (i in 0..10000) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment