diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/CrossDeviceBean.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/CrossDeviceBean.kt index eb960e4f21..f3224caab7 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/CrossDeviceBean.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/CrossDeviceBean.kt @@ -12,4 +12,10 @@ data class DeviceInfoBean( var deviceIp: String?, var lon: Double, var lat: Double -) +) { + /** + * 该点相对于最近轨迹线段AB的位置 + * 0:左,1:上,2:右,3:下 + */ + var orientation: Int = 0 +} diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/EventBean.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/EventBean.kt index 9e05a4eb14..4fd1cc15f3 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/EventBean.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/EventBean.kt @@ -8,6 +8,13 @@ data class EventBean( var centerJwdLine: List?,// 拥堵的路段 var polygon: List?,// 施工、交通事故(延后50m的) var origPolygon: List?// 施工、交通事故(识别的) -) +) { + /** + * 该点相对于最近轨迹线段AB的位置 + * 0:左,1:上,2:右,3:下 + */ + var orientation: Int = 0 + var title: String? = "" +} data class GeoCoord(var lon: Double, var lat: Double) \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/TravelRealityModel.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/TravelRealityModel.kt index c8395575df..dbe4727c42 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/TravelRealityModel.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/TravelRealityModel.kt @@ -18,6 +18,8 @@ import com.mogo.eagle.core.network.MoGoRetrofitFactory import com.mogo.eagle.core.network.apiCall import com.mogo.eagle.core.network.apiResponseCall import com.mogo.eagle.core.network.request +import com.mogo.eagle.core.utilcode.util.DrivingDirectionUtils +import com.mogo.eagle.core.utilcode.util.LocationUtils import com.mogo.eagle.core.utilcode.util.Md5Util import me.jessyan.autosize.utils.AutoSizeUtils import java.util.Locale @@ -132,7 +134,7 @@ class TravelRealityModel private constructor() { onFailed: ((LatLng) -> Unit) ) { if (url.isNullOrEmpty()) return - val radiusPx = AutoSizeUtils.dp2px(context, 15f).toFloat() + val radiusPx = AutoSizeUtils.dp2px(context, 24f).toFloat() val options = RequestOptions().transform( GranularRoundedCorners(radiusPx, radiusPx,0f,0f) ) @@ -153,4 +155,114 @@ class TravelRealityModel private constructor() { } }) } + + /** + * 计算Marker相对最近线段ab应该摆放的位置 + * 0:左,1:上,2:右,3:下 + */ + fun calculateOrientation(pLon: Double, pLat: Double, aLon: Double, aLat: Double, bLon: Double, bLat: Double): Int { + // 0:左,1:上,2:右,3:下 + var orientation = 0 + // 线段与正北方向的夹角,范围[0,360] + val abAngle = DrivingDirectionUtils.getLineAngle(aLon, aLat, bLon, bLat) + + if (abAngle in 70.0..110.0 || abAngle in 250.0..290.0) {// 接近水平方向 + // 先比较纬度,然后比较向量叉积 + if (pLat > aLat && pLat > bLat) { + orientation = 1 + } else if (pLat < aLat && pLat < bLat) { + orientation = 3 + } else { + // 0:在线段上,1:左侧,2:右侧,3:上方,4:下方(逆时针方向看左、上) + when (LocationUtils.checkLocation(pLon, pLat, aLon, aLat, bLon, bLat)) { + 1 -> { + orientation = if (abAngle > 180) {// 地图上从右往左的左侧 + 3 + } else {// 地图上从左往右的左侧 + 1 + } + } + 2 -> { + orientation = if (abAngle > 180) { + 1 + } else { + 3 + } + } + else -> {// 点p在线段ab所在的直线上 + orientation = 1// 未计算后面线段,写死上方 + } + } + } + } else { + when (LocationUtils.checkLocation(pLon, pLat, aLon, aLat, bLon, bLat)) { + 1 -> {// 逆时针方向为左侧 + orientation = when { + abAngle in 0.0..90.0 -> { + 0// 地图上的左侧 + } + + abAngle > 90.0 && abAngle <= 180 -> { + 2// 地图上的右侧 + } + + abAngle > 180.0 && abAngle <= 270.0 -> { + 2// 地图上的右侧 + } + + else -> { + 0// 地图上的左侧 + } + } + } + 2 -> {// 顺时针方向为右侧 + orientation = when { + abAngle in 0.0..90.0 -> { + 2// 地图上的右侧 + } + + abAngle > 90.0 && abAngle <= 180 -> { + 0// 地图上的左侧 + } + + abAngle > 180.0 && abAngle <= 270.0 -> { + 0// 地图上的左侧 + } + + else -> { + 2// 地图上的右侧 + } + } + } + else -> {// 点p在线段ab所在的直线上 + orientation = 0// 未计算后面线段,写死左侧 + } + } + } + return orientation + } + + /** + * 锚点和EventVideoView相关联的 + */ + fun calculateAnchor(orientation: Int): Pair { + // 0:左,1:上,2:右,3:下 + return when (orientation) { + 0 -> { + Pair(0.94f, 0.48f) + } + + 1 -> { + Pair(0.49f, 0.94f) + } + + 2 -> { + Pair(0.05f, 0.47f) + } + + else -> { + Pair(0.50f, 0.04f) + } + } + } } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/view/EventVideoView.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/view/EventVideoView.kt index 7c545d9bb3..7b14131b7d 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/view/EventVideoView.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/view/EventVideoView.kt @@ -15,7 +15,8 @@ class EventVideoView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, - private val title: String? = "全息路口" + val title: String? = "", + val orientation: Int = 0 ) : ConstraintLayout ( context, attrs, @@ -23,7 +24,21 @@ class EventVideoView @JvmOverloads constructor( ) { init { - LayoutInflater.from(context).inflate(R.layout.layout_event_video_maker, this, true) + // 0:左,1:上,2:右,3:下 + when (orientation) { + 0 -> { + LayoutInflater.from(context).inflate(R.layout.layout_event_toward_right_maker, this, true) + } + 1 -> { + LayoutInflater.from(context).inflate(R.layout.layout_event_toward_down_maker, this, true) + } + 2 -> { + LayoutInflater.from(context).inflate(R.layout.layout_event_toward_left_maker, this, true) + } + else -> { + LayoutInflater.from(context).inflate(R.layout.layout_event_toward_up_maker, this, true) + } + } initView() } diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/view/VideoMarkerEntity.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/view/VideoMarkerEntity.kt new file mode 100644 index 0000000000..ec947927c7 --- /dev/null +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/view/VideoMarkerEntity.kt @@ -0,0 +1,5 @@ +package com.mogo.eagle.core.function.business.travelreality.view + +import com.amap.api.maps.model.LatLng + +data class VideoMarkerEntity(var latLng: LatLng, var title: String? = "", var orientation: Int = 0) diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/TravelRealityView.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/TravelRealityView.kt index 34983e08ac..8f1704be1b 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/TravelRealityView.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/TravelRealityView.kt @@ -38,6 +38,7 @@ import com.mogo.eagle.core.function.business.travelreality.EventReqEntity import com.mogo.eagle.core.function.business.travelreality.Point import com.mogo.eagle.core.function.business.travelreality.TravelRealityModel.Companion.travelNetWorkModel import com.mogo.eagle.core.function.business.travelreality.view.EventVideoView +import com.mogo.eagle.core.function.business.travelreality.view.VideoMarkerEntity import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListenerManager import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager @@ -175,6 +176,10 @@ class TravelRealityView @JvmOverloads constructor( @Volatile private var deviceList: List? = null + + /** + * 在轨迹点附近的路口设备 + */ @Volatile private var deviceInPathList: List? = null @@ -184,11 +189,14 @@ class TravelRealityView @JvmOverloads constructor( @Volatile private var isRoadTrackReq = false + /** + * 在轨迹点附近的道路事件 + */ private val roadEventList by lazy { ArrayList() } private val ipPointMap by lazy { - HashMap() + HashMap() } private var testTime = 0L @@ -443,39 +451,46 @@ class TravelRealityView @JvmOverloads constructor( ) { return@forEach } + eventBean.orientation = travelNetWorkModel.calculateOrientation(eventBean.lon, eventBean.lat, globalPoint.lon, + globalPoint.lat, globalList[index + 1].lon, globalList[index + 1].lat,) filterEventWithType(eventBean, eventOptionsList) } } } + // 事件不足3个则用路口设备补齐 + completeQuantity() + Log.d(TAG, "过滤掉的事件个数为:${eventList.size - eventOptionsList.size}") + // 绘制道路事件 + drawMarkers(DRAW_ROAD_EVENT, eventOptionsList) + } + + private fun completeQuantity() { ipPointMap.clear() + // 全部展示事件,事件数不足则用路口设备补齐 if (roadEventList.size >= 3) { val ipList = mutableListOf() - roadEventList[0].ip?.let { - ipPointMap[it] = - coordinateConverterWgsToGcj(roadEventList[0].lat, roadEventList[0].lon) - ipList.add(it) + roadEventList[0].let { + it.ip?.let { ip -> + ipPointMap[ip] = VideoMarkerEntity(coordinateConverterWgsToGcj(it.lat, it.lon), it.title, it.orientation) + ipList.add(ip) + } } - roadEventList[(roadEventList.size - 1) / 2].ip?.let { - ipPointMap[it] = coordinateConverterWgsToGcj( - roadEventList[(roadEventList.size - 1) / 2].lat, - roadEventList[(roadEventList.size - 1) / 2].lon - ) - ipList.add(it) + roadEventList[(roadEventList.size - 1) / 2].let { + it.ip?.let { ip -> + ipPointMap[ip] = VideoMarkerEntity(coordinateConverterWgsToGcj(it.lat, it.lon), it.title, it.orientation) + ipList.add(ip) + } } - roadEventList[roadEventList.size - 1].ip?.let { - ipPointMap[it] = coordinateConverterWgsToGcj( - roadEventList[roadEventList.size - 1].lat, - roadEventList[roadEventList.size - 1].lon - ) - ipList.add(it) + roadEventList[roadEventList.size - 1].let { + it.ip?.let { ip -> + ipPointMap[ip] = VideoMarkerEntity(coordinateConverterWgsToGcj(it.lat, it.lon), it.title, it.orientation) + ipList.add(ip) + } } reqCrossLive(ipList) } else { retryGetCrossDevice() } - Log.d(TAG, "过滤掉的事件个数为:${eventList.size - eventOptionsList.size}") - // 绘制道路事件 - drawMarkers(DRAW_ROAD_EVENT, eventOptionsList) } private fun filterEventWithType( @@ -491,6 +506,7 @@ class TravelRealityView @JvmOverloads constructor( zIndex(0.8f) icon(BitmapDescriptorFactory.fromResource(R.drawable.mogo_shigu_nor)) }) + eventBean.title = "交通事故" roadEventList.add(eventBean) } @@ -501,6 +517,7 @@ class TravelRealityView @JvmOverloads constructor( zIndex(0.8f) icon(BitmapDescriptorFactory.fromResource(R.drawable.mogo_shigong_image)) }) + eventBean.title = "道路施工" roadEventList.add(eventBean) } @@ -520,6 +537,7 @@ class TravelRealityView @JvmOverloads constructor( zIndex(0.8f) icon(BitmapDescriptorFactory.fromResource(R.drawable.mogo_jingzhi_nor)) }) + eventBean.title = "静止事件" roadEventList.add(eventBean) } @@ -530,11 +548,17 @@ class TravelRealityView @JvmOverloads constructor( zIndex(0.8f) icon(BitmapDescriptorFactory.fromResource(R.drawable.mogo_jingzhi_nor)) }) + eventBean.title = "未知事件" roadEventList.add(eventBean) } } } + /** + * 等待路口设备数据请求结束 + * handleRoadEvent -> 计算Marker方向 -> completeQuantity -> retryGetCrossDevice(等待缓存deviceInPathList结束) -> 获取deviceInPathList -> 获取Marker方向 + * handleCrossDevices -> 计算Marker方向 -> 缓存deviceInPathList + */ private fun retryGetCrossDevice() { val crossDeviceListTmp = deviceInPathList if (crossDeviceListTmp.isNullOrEmpty()) { @@ -548,16 +572,19 @@ class TravelRealityView @JvmOverloads constructor( if (maxSize <= 0) return val ipList = mutableListOf() roadEventList.forEach { - ipList.add(it.ip ?: "") + it.ip?.let { ip -> + ipPointMap[ip] = VideoMarkerEntity(coordinateConverterWgsToGcj(it.lat, it.lon), it.title, it.orientation) + ipList.add(ip) + } } // 轨迹线附近的路口设备取几个进行卡片展示 for (i in crossDeviceListTmp.indices) { if (maxSize > 0 && !crossDeviceListTmp[i].deviceInfoList.isNullOrEmpty()) { crossDeviceListTmp[i].deviceInfoList!![0].deviceIp?.let { - ipPointMap[it] = coordinateConverterWgsToGcj( + ipPointMap[it] = VideoMarkerEntity(coordinateConverterWgsToGcj( crossDeviceListTmp[i].deviceInfoList!![0].lat, crossDeviceListTmp[i].deviceInfoList!![0].lon - ) + ), "全息路口", crossDeviceListTmp[i].deviceInfoList!![0].orientation) ipList.add(it) maxSize-- } @@ -571,14 +598,14 @@ class TravelRealityView @JvmOverloads constructor( * 先下载图片,然后设置给View, * 再转换成BitmapDescriptor,最后进行渲染 */ - private fun downloadImage(url: String, latLng: LatLng?) { - if (latLng == null) return + private fun downloadImage(url: String, latLng: LatLng?, title: String?, orientation: Int = 0) { + if (latLng == null || url.isEmpty()) return travelNetWorkModel.downloadImage(context, url, latLng, onSuccess = { bitmap, latLng -> - val view = EventVideoView(context) + val view = EventVideoView(context, title = title, orientation = orientation) view.setBitmap(bitmap) updateVideoMarker(view, latLng) }, onFailed = { - val view = EventVideoView(context) + val view = EventVideoView(context, title = title, orientation = orientation) view.setPlaceHolder() updateVideoMarker(view, latLng) }) @@ -588,15 +615,31 @@ class TravelRealityView @JvmOverloads constructor( ndeRoadCameraNetWorkModel.batchRequestCrossLive(ipList, onSuccess = { val liveOptionsList = ArrayList() var markerOption: MarkerOptions + var pair: Pair it.forEach { roadCamera -> roadCamera.ip?.let { ip -> - roadCamera.imageUrl?.let { url -> - downloadImage(url, ipPointMap[ip]) - } markerOption = MarkerOptions() - markerOption.position(ipPointMap[ip]) - markerOption.anchor(0.5f, 0.5f) markerOption.zIndex(0.9f) + if (roadCamera.imageUrl.isNullOrEmpty()) { + var view: EventVideoView + if (ipPointMap[ip] != null) { + markerOption.position(ipPointMap[ip]?.latLng) + view = EventVideoView(context, title = ipPointMap[ip]!!.title, orientation = ipPointMap[ip]!!.orientation) + pair = travelNetWorkModel.calculateAnchor(ipPointMap[ip]!!.orientation) + Log.d(TAG, "绘制时位置为:${ipPointMap[ip]?.latLng},标题为:${ipPointMap[ip]!!.title},方向为:${ipPointMap[ip]!!.orientation},锚点为:${pair}") + markerOption.anchor(pair.first, pair.second) + } else { + return@let + } + view.setPlaceHolder() + markerOption.icon(BitmapDescriptorFactory.fromView(view)) + } else { + markerOption.icon(null) + markerOption.position(ipPointMap[ip]?.latLng) + pair = travelNetWorkModel.calculateAnchor(ipPointMap[ip]?.orientation ?: 0) + markerOption.anchor(pair.first, pair.second) + downloadImage(roadCamera.imageUrl!!, ipPointMap[ip]?.latLng, ipPointMap[ip]?.title, ipPointMap[ip]?.orientation ?: 0) + } liveOptionsList.add(markerOption) } } @@ -628,6 +671,9 @@ class TravelRealityView @JvmOverloads constructor( ) { return@loop } + // 计算事件Marker朝向 + deviceBean.orientation = travelNetWorkModel.calculateOrientation(deviceBean.lon, deviceBean.lat, + globalPoint.lon, globalPoint.lat, globalList[index + 1].lon, globalList[index + 1].lat) deviceInPaths.add(deviceBean) crossOptionsList.add(MarkerOptions().apply { position( @@ -868,6 +914,7 @@ class TravelRealityView @JvmOverloads constructor( val options = MarkerOptions() options.position(latLng) options.icon(BitmapDescriptorFactory.fromView(view)) + Log.d(TAG, "更新时位置为:${latLng},标题为:${view.title}") Message.obtain().apply { what = UPDATE_VIDEO_MARKER obj = options @@ -1026,6 +1073,7 @@ class TravelRealityView @JvmOverloads constructor( DRAW_LIVE_DETAIL -> { removeMessages(DRAW_LIVE_DETAIL) + removeMessages(UPDATE_VIDEO_MARKER) (msg.obj as ArrayList).apply { realDrawLiveMarkers(this) } @@ -1156,6 +1204,7 @@ class TravelRealityView @JvmOverloads constructor( } private fun realDrawLiveMarkers(liveOptionList: ArrayList) { + Log.d(TAG, "realDrawLiveMarkers") liveMarkerList.forEach { it.destroy() } @@ -1166,6 +1215,7 @@ class TravelRealityView @JvmOverloads constructor( } private fun realUpdateVideoMarker(options: MarkerOptions) { + Log.d(TAG, "realUpdateVideoMarker") liveMarkerList.forEach { if (it.position == options.position) { it.setIcon(options.icon) diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_video_bg.png b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_video_bg.png deleted file mode 100644 index 91a52d3150..0000000000 Binary files a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_video_bg.png and /dev/null differ diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_video_down_bg.png b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_video_down_bg.png new file mode 100644 index 0000000000..23552bd341 Binary files /dev/null and b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_video_down_bg.png differ diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_video_left_bg.png b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_video_left_bg.png new file mode 100644 index 0000000000..aba2bc61fc Binary files /dev/null and b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_video_left_bg.png differ diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_video_right_bg.png b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_video_right_bg.png new file mode 100644 index 0000000000..75477c8466 Binary files /dev/null and b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_video_right_bg.png differ diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_video_up_bg.png b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_video_up_bg.png new file mode 100644 index 0000000000..99517bdff1 Binary files /dev/null and b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/event_video_up_bg.png differ diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_test.jpg b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_test.jpg new file mode 100644 index 0000000000..f7990ce3a0 Binary files /dev/null and b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_test.jpg differ diff --git a/core/function-impl/mogo-core-function-map/src/main/res/layout/layout_event_toward_down_maker.xml b/core/function-impl/mogo-core-function-map/src/main/res/layout/layout_event_toward_down_maker.xml new file mode 100644 index 0000000000..4f03120e6b --- /dev/null +++ b/core/function-impl/mogo-core-function-map/src/main/res/layout/layout_event_toward_down_maker.xml @@ -0,0 +1,44 @@ + + + + + + + + + + \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-map/src/main/res/layout/layout_event_toward_left_maker.xml b/core/function-impl/mogo-core-function-map/src/main/res/layout/layout_event_toward_left_maker.xml new file mode 100644 index 0000000000..225cdd109a --- /dev/null +++ b/core/function-impl/mogo-core-function-map/src/main/res/layout/layout_event_toward_left_maker.xml @@ -0,0 +1,46 @@ + + + + + + + + + + \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-map/src/main/res/layout/layout_event_toward_right_maker.xml b/core/function-impl/mogo-core-function-map/src/main/res/layout/layout_event_toward_right_maker.xml new file mode 100644 index 0000000000..98f8b48e9a --- /dev/null +++ b/core/function-impl/mogo-core-function-map/src/main/res/layout/layout_event_toward_right_maker.xml @@ -0,0 +1,44 @@ + + + + + + + + + + \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-map/src/main/res/layout/layout_event_video_maker.xml b/core/function-impl/mogo-core-function-map/src/main/res/layout/layout_event_toward_up_maker.xml similarity index 75% rename from core/function-impl/mogo-core-function-map/src/main/res/layout/layout_event_video_maker.xml rename to core/function-impl/mogo-core-function-map/src/main/res/layout/layout_event_toward_up_maker.xml index 8e24de19c3..fe668d1160 100644 --- a/core/function-impl/mogo-core-function-map/src/main/res/layout/layout_event_video_maker.xml +++ b/core/function-impl/mogo-core-function-map/src/main/res/layout/layout_event_toward_up_maker.xml @@ -1,31 +1,31 @@ \ No newline at end of file diff --git a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/util/DrivingDirectionUtils.java b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/util/DrivingDirectionUtils.java index 6d0c419431..c9a76e7c91 100644 --- a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/util/DrivingDirectionUtils.java +++ b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/util/DrivingDirectionUtils.java @@ -154,7 +154,7 @@ public class DrivingDirectionUtils { } /** - * + * 取值范围[0,360] * @param dx1 * @param dy1 * @param dx2 diff --git a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/util/LocationUtils.java b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/util/LocationUtils.java index 4c607a99b9..cf5f7042b1 100644 --- a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/util/LocationUtils.java +++ b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/util/LocationUtils.java @@ -176,4 +176,47 @@ public class LocationUtils { } return difference; } + + /** + * 计算向量叉乘 + * @return + */ + public static double crossProduct(double xa, double ya, double xb, double yb, double xp, double yp) { + return (xb - xa) * (yp - ya) - (yb - ya) * (xp - xa); + } + + /** + * + * @return 点P是否在线段AB上 + */ + public static boolean isOnSegment(double xa, double ya, double xb, double yb, double xp, double yp) { + return (xp >= Math.min(xa, xb) && xp <= Math.max(xa, xb) && yp >= Math.min(ya, yb) && yp <= Math.max(ya, yb)); + } + + /** + * 判断点P相对于点A和点B组成的线段的位置(逆时针方向看左、上) + * @return 0:在线段上,1:左侧,2:右侧,3:上方,4:下方 + */ + public static int checkLocation(double xp, double yp, double xa, double ya, double xb, double yb) { + // 计算向量的叉乘 + double cp = crossProduct(xa, ya, xb, yb, xp, yp); + if (cp > 0) { + return 1; + } else if (cp < 0) { + return 2; + } else { + // 叉乘为0时,点p在线段AB所在的直线上,此时先判断是否在AB线段上 + if (isOnSegment(xa, ya, xb, yb, xp, yp)) { + return 0; + } else { + double slopeAB = (yb - ya) / (xb - xa); + double slopeAP = (yp - ya) / (xp - xa); + if (slopeAP > slopeAB) { + return 3; + } else { + return 4; + } + } + } + } }