[6.5.0][Feat]新增行程总览功能
@@ -0,0 +1,15 @@
|
||||
package com.mogo.eagle.core.function.business.travelreality
|
||||
|
||||
data class CrossDeviceBean(
|
||||
var crossingId: String?,
|
||||
var lon: Double,
|
||||
var roadUniqueId: String?,
|
||||
var lat: Double,
|
||||
var deviceInfoList: List<DeviceInfoBean>?
|
||||
)
|
||||
|
||||
data class DeviceInfoBean(
|
||||
var deviceIp: String?,
|
||||
var lon: Double,
|
||||
var lat: Double
|
||||
)
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.mogo.eagle.core.function.business.travelreality
|
||||
data class EventBean(
|
||||
var poiType: String?,// 事件类型
|
||||
var ip: String?,// 摄像头ip
|
||||
var id: String?,
|
||||
var lon: Double,// 施工、交通事故的中心点坐标
|
||||
var lat: Double,// 拥堵事件的第一个点
|
||||
var centerJwdLine: List<GeoCoord>?,// 拥堵的路段
|
||||
var polygon: List<GeoCoord>?,// 施工、交通事故(延后50m的)
|
||||
var origPolygon: List<GeoCoord>?// 施工、交通事故(识别的)
|
||||
)
|
||||
|
||||
data class GeoCoord(var lon: Double, var lat: Double)
|
||||
@@ -0,0 +1,3 @@
|
||||
package com.mogo.eagle.core.function.business.travelreality
|
||||
|
||||
data class Point(var lon: Double, var lat: Double)
|
||||
@@ -0,0 +1,115 @@
|
||||
package com.mogo.eagle.core.function.business.travelreality
|
||||
|
||||
import com.mogo.commons.constants.HostConst
|
||||
import com.mogo.eagle.core.data.BaseResponse
|
||||
import com.mogo.eagle.core.data.Response
|
||||
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.GsonUtils
|
||||
import com.mogo.eagle.core.utilcode.util.Md5Util
|
||||
import retrofit2.http.Query
|
||||
import java.util.Locale
|
||||
|
||||
class TravelRealityModel private constructor() {
|
||||
|
||||
companion object {
|
||||
val travelNetWorkModel by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
|
||||
TravelRealityModel()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getNetWorkApi(baseUrl: String = HostConst.getNDEHost()): TravelRealityService {
|
||||
return MoGoRetrofitFactory.getInstanceNoCallAdapter(baseUrl)
|
||||
.create(TravelRealityService::class.java)
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询道路事件
|
||||
*/
|
||||
fun getEventsWithTrajRequest(reqData: List<Point>,
|
||||
onSuccess: ((List<EventBean>) -> Unit), onError: ((String) -> Unit)){
|
||||
request<Response<List<EventBean>?>>{
|
||||
loader {
|
||||
apiResponseCall{
|
||||
val time = System.currentTimeMillis().toString()
|
||||
val md5String = "${ROAD_EVENT_TRAJECTORY.uppercase(Locale.getDefault())}$time"
|
||||
getNetWorkApi(HostConst.getNDEHost()).getEventsWithTrajRequest(Md5Util.getMD5Result(md5String), time, reqData)
|
||||
}
|
||||
}
|
||||
onSuccess {
|
||||
onSuccess.invoke(it.data ?: ArrayList())
|
||||
}
|
||||
onError{
|
||||
onError.invoke(it.message ?: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询路口设备
|
||||
*/
|
||||
fun getCrossDevice(lon: Double, lat: Double, cityCode: String?,
|
||||
onSuccess: ((List<CrossDeviceBean>) -> Unit), onError: ((String) -> Unit)) {
|
||||
request<BaseResponse<List<CrossDeviceBean>?>>{
|
||||
loader {
|
||||
apiCall{
|
||||
val time = System.currentTimeMillis().toString()
|
||||
val md5String = "${CROSS_DEVICE.uppercase(Locale.getDefault())}$time"
|
||||
getNetWorkApi(HostConst.getNDEHost()).getCrossDevice(Md5Util.getMD5Result(md5String), time, "", lon, lat, cityCode)
|
||||
}
|
||||
}
|
||||
onSuccess {
|
||||
onSuccess.invoke(it.result ?: ArrayList())
|
||||
}
|
||||
onError{
|
||||
onError.invoke(it.message ?: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 智慧路口路网范围
|
||||
*/
|
||||
fun getCityRoadRange(lon: Double, lat: Double, cityCode: String?,
|
||||
onSuccess: ((List<List<Double>?>?) -> Unit), onError: ((String) -> Unit)) {
|
||||
request<BaseResponse<List<List<Double>?>?>>{
|
||||
loader {
|
||||
apiCall{
|
||||
val time = System.currentTimeMillis().toString()
|
||||
val md5String = "${CITY_ROAD_RANGE.uppercase(Locale.getDefault())}$time"
|
||||
getNetWorkApi(HostConst.getNDEHost()).getCityRoadRange(Md5Util.getMD5Result(md5String), time, lon, lat, cityCode)
|
||||
}
|
||||
}
|
||||
onSuccess {
|
||||
onSuccess.invoke(it.result)
|
||||
}
|
||||
onError{
|
||||
onError.invoke(it.message ?: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 智慧道路轨迹
|
||||
*/
|
||||
fun getCityRoadTrack(lon: Double, lat: Double, cityCode: String?,
|
||||
onSuccess: ((List<List<List<Double>?>?>?) -> Unit), onError: ((String) -> Unit)) {
|
||||
request<BaseResponse<List<List<List<Double>?>?>?>>{
|
||||
loader {
|
||||
apiCall{
|
||||
val time = System.currentTimeMillis().toString()
|
||||
val md5String = "${CITY_ROAD_TRACK.uppercase(Locale.getDefault())}$time"
|
||||
getNetWorkApi(HostConst.getNDEHost()).getCityRoadTrack(Md5Util.getMD5Result(md5String), time, lon, lat, cityCode)
|
||||
}
|
||||
}
|
||||
onSuccess {
|
||||
onSuccess.invoke(it.result)
|
||||
}
|
||||
onError{
|
||||
onError.invoke(it.message ?: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.mogo.eagle.core.function.business.travelreality
|
||||
|
||||
import com.mogo.eagle.core.data.BaseResponse
|
||||
import com.mogo.eagle.core.data.Response
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Header
|
||||
import retrofit2.http.Headers
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.Query
|
||||
|
||||
const val ROAD_EVENT_TRAJECTORY = "/abilitySupport/trajInfo/getEventsWithTrajectories"
|
||||
const val CROSS_DEVICE = "/abilitySupport/rss/crossDevice"
|
||||
const val CITY_ROAD_RANGE = "/abilitySupport/rss/cityRoadRange"
|
||||
const val CITY_ROAD_TRACK = "/abilitySupport/rss/cityRoadTrack"
|
||||
|
||||
interface TravelRealityService {
|
||||
|
||||
/**
|
||||
* 根据做标记集合获取道路事件
|
||||
*/
|
||||
@Headers("Content-type:application/json;charset=UTF-8")
|
||||
@POST(ROAD_EVENT_TRAJECTORY)
|
||||
suspend fun getEventsWithTrajRequest(
|
||||
@Header("MogoAuthKey") authKey: String,
|
||||
@Header("MogoReqTime") time: String,
|
||||
@Body reqData: List<Point>
|
||||
): Response<List<EventBean>>
|
||||
|
||||
/**
|
||||
* 查询路口设备
|
||||
*/
|
||||
@Headers("Content-type:application/json;charset=UTF-8")
|
||||
@GET(CROSS_DEVICE)
|
||||
suspend fun getCrossDevice(
|
||||
@Header("MogoAuthKey") authKey: String,
|
||||
@Header("MogoReqTime") time: String,
|
||||
@Query("roadUniqueId") roadUniqueId: String?,
|
||||
@Query("lon") lon: Double,
|
||||
@Query("lat") lat: Double,
|
||||
@Query("cityCode") cityCode: String?
|
||||
): BaseResponse<List<CrossDeviceBean>>
|
||||
|
||||
/**
|
||||
* 查询路口路网范围
|
||||
*/
|
||||
@Headers("Content-type:application/json;charset=UTF-8")
|
||||
@GET(CITY_ROAD_RANGE)
|
||||
suspend fun getCityRoadRange(
|
||||
@Header("MogoAuthKey") authKey: String,
|
||||
@Header("MogoReqTime") time: String,
|
||||
@Query("lon") lon: Double,
|
||||
@Query("lat") lat: Double,
|
||||
@Query("cityCode") cityCode: String?
|
||||
): BaseResponse<List<List<Double>>>
|
||||
|
||||
/**
|
||||
* 查询智慧道路轨迹
|
||||
*/
|
||||
@Headers("Content-type:application/json;charset=UTF-8")
|
||||
@GET(CITY_ROAD_TRACK)
|
||||
suspend fun getCityRoadTrack(
|
||||
@Header("MogoAuthKey") authKey: String,
|
||||
@Header("MogoReqTime") time: String,
|
||||
@Query("lon") lon: Double,
|
||||
@Query("lat") lat: Double,
|
||||
@Query("cityCode") cityCode: String?
|
||||
): BaseResponse<List<List<List<Double>>>>
|
||||
}
|
||||
@@ -237,9 +237,6 @@ class OverMapView @JvmOverloads constructor(
|
||||
if (mMapView != null) {
|
||||
mMapView!!.onDestroy()
|
||||
}
|
||||
if (mMapView != null) {
|
||||
mMapView!!.onDestroy()
|
||||
}
|
||||
}
|
||||
// =================必须通知高德地图生命周期的变化=================
|
||||
|
||||
|
||||
@@ -0,0 +1,732 @@
|
||||
package com.mogo.eagle.core.function.view
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.os.Looper
|
||||
import android.os.Message
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.amap.api.maps.AMap
|
||||
import com.amap.api.maps.CameraUpdate
|
||||
import com.amap.api.maps.CameraUpdateFactory
|
||||
import com.amap.api.maps.CoordinateConverter
|
||||
import com.amap.api.maps.TextureMapView
|
||||
import com.amap.api.maps.model.BitmapDescriptor
|
||||
import com.amap.api.maps.model.BitmapDescriptorFactory
|
||||
import com.amap.api.maps.model.CameraPosition
|
||||
import com.amap.api.maps.model.CustomMapStyleOptions
|
||||
import com.amap.api.maps.model.LatLng
|
||||
import com.amap.api.maps.model.LatLngBounds
|
||||
import com.amap.api.maps.model.MarkerOptions
|
||||
import com.amap.api.maps.model.PolylineOptions
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.mogo.eagle.core.data.map.MogoLocation
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoPlanningRottingListener
|
||||
import com.mogo.eagle.core.function.business.travelreality.CrossDeviceBean
|
||||
import com.mogo.eagle.core.function.business.travelreality.EventBean
|
||||
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.call.autopilot.CallerChassisLocationGCJ02ListenerManager
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListenerManager
|
||||
import com.mogo.eagle.core.function.map.R
|
||||
import com.mogo.eagle.core.utilcode.mogo.MapAssetStyleUtils
|
||||
import com.mogo.eagle.core.utilcode.util.DrivingDirectionUtils
|
||||
import com.mogo.eagle.core.utilcode.util.GsonUtils
|
||||
import com.mogo.eagle.core.utilcode.util.LocationUtils
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils
|
||||
import me.jessyan.autosize.utils.AutoSizeUtils
|
||||
import mogo.telematics.pad.MessagePad
|
||||
|
||||
/**
|
||||
* 行程实况View
|
||||
*
|
||||
* @author chenfufeng
|
||||
*/
|
||||
class TravelRealityView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoChassisLocationGCJ02Listener,
|
||||
IMoGoPlanningRottingListener {
|
||||
|
||||
private var mContext: Context? = null
|
||||
|
||||
private var mMapView: TextureMapView? = null
|
||||
private var mAMap: AMap? = null
|
||||
|
||||
// =============自定义属性相关=============
|
||||
private var mapStylePath: String? = null
|
||||
private var mapStyleExtraPath: String? = null
|
||||
private var carDrawable: Int = -1
|
||||
private var compassDrawable: Int = -1
|
||||
private var startPointDrawable: Int = -1
|
||||
private var endPointDrawable: Int = -1
|
||||
private var leftPadding: Int = 100
|
||||
private var topPadding: Int = 150
|
||||
private var rightPadding: Int = 100
|
||||
private var bottomPadding: Int = 250
|
||||
|
||||
|
||||
private var roadRangeBitmap: BitmapDescriptor? = null
|
||||
private var roadRangeDrawable: Int = -1
|
||||
private val roadTrajectoryBitmap by lazy {
|
||||
BitmapDescriptorFactory.fromResource(R.drawable.mogo_road_over)
|
||||
}
|
||||
|
||||
// 测试时使用
|
||||
// private val pointBitmap1 by lazy {
|
||||
// BitmapDescriptorFactory.fromBitmap(getBitmap1())
|
||||
// }
|
||||
//
|
||||
// private val markerOptionsList1 by lazy {
|
||||
// ArrayList<MarkerOptions>()
|
||||
// }
|
||||
//
|
||||
// private val pointBitmap2 by lazy {
|
||||
// BitmapDescriptorFactory.fromBitmap(getBitmap2())
|
||||
// }
|
||||
//
|
||||
// private val markerOptionsList2 by lazy {
|
||||
// ArrayList<MarkerOptions>()
|
||||
// }
|
||||
|
||||
/**
|
||||
* 低频的
|
||||
*/
|
||||
private var nonFrequentHandler: NonFrequentHandler? = null
|
||||
|
||||
@Volatile
|
||||
private var lastTime = 0L
|
||||
|
||||
private var reqData: List<Point>? = null
|
||||
|
||||
private var testTime = 0L
|
||||
|
||||
companion object {
|
||||
private const val TAG = "TravelRealityView"
|
||||
|
||||
private const val DRAW_POLY_LINE = 1
|
||||
private const val DRAW_CAR_LOCATION = 2
|
||||
private const val DRAW_ROAD_EVENT = 3
|
||||
private const val DRAW_CROSS_DEVICE = 4
|
||||
private const val DRAW_ROAD_RANGE = 5
|
||||
private const val DRAW_ROAD_TRAJECTORY = 6
|
||||
}
|
||||
|
||||
init {
|
||||
try {
|
||||
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.TravelRealityView)
|
||||
mapStylePath = typedArray.getString(R.styleable.TravelRealityView_mapStylePath)
|
||||
mapStyleExtraPath =
|
||||
typedArray.getString(R.styleable.TravelRealityView_mapStyleExtraPath)
|
||||
carDrawable = typedArray.getResourceId(R.styleable.TravelRealityView_carDrawable, -1)
|
||||
compassDrawable =
|
||||
typedArray.getResourceId(R.styleable.TravelRealityView_compassDrawable, -1)
|
||||
roadRangeDrawable =
|
||||
typedArray.getResourceId(R.styleable.TravelRealityView_roadRangeDrawable, -1)
|
||||
startPointDrawable =
|
||||
typedArray.getResourceId(R.styleable.TravelRealityView_startPointDrawable, -1)
|
||||
endPointDrawable =
|
||||
typedArray.getResourceId(R.styleable.TravelRealityView_endPointDrawable, -1)
|
||||
leftPadding = typedArray.getInt(R.styleable.TravelRealityView_leftPadding, 0)
|
||||
topPadding = typedArray.getInt(R.styleable.TravelRealityView_topPadding, 0)
|
||||
rightPadding = typedArray.getInt(R.styleable.TravelRealityView_rightPadding, 0)
|
||||
bottomPadding = typedArray.getInt(R.styleable.TravelRealityView_bottomPadding, 0)
|
||||
typedArray.recycle()
|
||||
initView(context)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
// =================必须通知高德地图生命周期的变化=================
|
||||
fun onCreateView(savedInstanceState: Bundle?) {
|
||||
mMapView?.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
fun onResume() {
|
||||
mMapView?.onResume()
|
||||
}
|
||||
|
||||
fun onPause() {
|
||||
mMapView?.onPause()
|
||||
}
|
||||
|
||||
fun onDestroy() {
|
||||
mMapView?.onDestroy()
|
||||
}
|
||||
// =================必须通知高德地图生命周期的变化=================
|
||||
|
||||
private fun initView(context: Context) {
|
||||
mContext = context
|
||||
val mapView =
|
||||
LayoutInflater.from(context).inflate(R.layout.module_travel_reality_view, this)
|
||||
mMapView = mapView.findViewById(R.id.travelMapView)
|
||||
roadRangeBitmap =
|
||||
BitmapDescriptorFactory.fromResource(if (roadRangeDrawable != -1) roadRangeDrawable else R.drawable.taxi_map_arrow_arrived)
|
||||
initAMapView()
|
||||
}
|
||||
|
||||
private fun getBitmap1(): Bitmap {
|
||||
val options = BitmapFactory.Options()
|
||||
options.inSampleSize = 2
|
||||
options.inJustDecodeBounds = false
|
||||
return BitmapFactory.decodeResource(resources, R.drawable.loc_azure_bg, options)
|
||||
}
|
||||
|
||||
private fun getBitmap2(): Bitmap {
|
||||
val options = BitmapFactory.Options()
|
||||
options.inSampleSize = 2
|
||||
options.inJustDecodeBounds = false
|
||||
return BitmapFactory.decodeResource(resources, R.drawable.count_bg, options)
|
||||
}
|
||||
|
||||
private fun initAMapView() {
|
||||
mAMap = mMapView?.map
|
||||
val mapStyleOptions = CustomMapStyleOptions()
|
||||
if (!mapStylePath.isNullOrEmpty() && !mapStyleExtraPath.isNullOrEmpty()) {
|
||||
mapStyleOptions.styleData =
|
||||
MapAssetStyleUtils.getAssetsStyle(context, mapStylePath)
|
||||
mapStyleOptions.styleExtraData =
|
||||
MapAssetStyleUtils.getAssetsExtraStyle(context, mapStyleExtraPath)
|
||||
mapStyleOptions.isEnable = true
|
||||
}
|
||||
// 地图文字标注
|
||||
mAMap?.showMapText(true)
|
||||
//设置希望展示的地图缩放级别
|
||||
mAMap?.moveCamera(CameraUpdateFactory.zoomTo(14f))
|
||||
//设置地图的样式
|
||||
mAMap?.uiSettings?.let {
|
||||
//地图缩放级别的交换按钮
|
||||
it.isZoomControlsEnabled = true
|
||||
//所有手势
|
||||
it.setAllGesturesEnabled(true)
|
||||
//指南针
|
||||
it.isCompassEnabled = false
|
||||
//设置倾斜手势是否可用。
|
||||
it.isTiltGesturesEnabled = false
|
||||
//定位按钮
|
||||
it.isMyLocationButtonEnabled = true
|
||||
}
|
||||
|
||||
mAMap?.setOnMapLoadedListener {
|
||||
mAMap?.setCustomMapStyle(mapStyleOptions)
|
||||
// 实时路况图层关闭,必须添加在loaded结束之后,其他位置不生效
|
||||
mAMap?.isTrafficEnabled = false
|
||||
mAMap?.showBuildings(false)
|
||||
// mAMap?.uiSettings?.isZoomControlsEnabled = false
|
||||
// mAMap?.animateCamera(CameraUpdateFactory.changeTilt(30f))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
CallerPlanningRottingListenerManager.addListener(TAG, this)
|
||||
// 注册定位监听
|
||||
CallerChassisLocationGCJ02ListenerManager.addListener(TAG, this)
|
||||
initHandlers()
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
// 注册定位监听
|
||||
CallerChassisLocationGCJ02ListenerManager.removeListener(TAG)
|
||||
CallerPlanningRottingListenerManager.removeListener(TAG)
|
||||
nonFrequentHandler?.looper?.quitSafely()
|
||||
nonFrequentHandler = null
|
||||
}
|
||||
|
||||
private fun initHandlers() {
|
||||
val nonFrequentThread = HandlerThread("travel_reality_thread")
|
||||
nonFrequentThread.start()
|
||||
nonFrequentHandler = NonFrequentHandler(nonFrequentThread.looper)
|
||||
}
|
||||
|
||||
private fun reqTrajectoryTest() {
|
||||
val json =
|
||||
"[{\"lat\":26.81937733437377,\"lon\":112.57535281567407},{\"lat\":26.81945931447823,\"lon\":112.57532226983858}," +
|
||||
"{\"lat\":26.820654610710495,\"lon\":112.5747724572884},{\"lat\":26.82123411157205,\"lon\":112.57446700543453}," +
|
||||
"{\"lat\":26.82192608026401,\"lon\":112.5741080926201},{\"lat\":26.822091924747422,\"lon\":112.57402409051497}," +
|
||||
"{\"lat\":26.82217198311328,\"lon\":112.57397827179898},{\"lat\":26.822751478727742,\"lon\":112.57368044319112}," +
|
||||
"{\"lat\":26.823003074132348,\"lon\":112.57352007651988},{\"lat\":26.82327753332255,\"lon\":112.57333679968579}," +
|
||||
"{\"lat\":26.823437581007436,\"lon\":112.57316880115862},{\"lat\":26.82353473462254,\"lon\":112.57304662092753}," +
|
||||
"{\"lat\":26.823599481049378,\"lon\":112.57293971409484},{\"lat\":26.82373275263248,\"lon\":112.57268771854648}," +
|
||||
"{\"lat\":26.823812678691333,\"lon\":112.57249681223165},{\"lat\":26.823863914316153,\"lon\":112.57221427243014}," +
|
||||
"{\"lat\":26.823863543155838,\"lon\":112.57180955163894},{\"lat\":26.823848051950634,\"lon\":112.57155755260963}," +
|
||||
"{\"lat\":26.82376752893978,\"lon\":112.57110700477688},{\"lat\":26.82321958288029,\"lon\":112.5686097226906}," +
|
||||
"{\"lat\":26.82319656741949,\"lon\":112.56848752320151},{\"lat\":26.82317357600292,\"lon\":112.56838823588228}," +
|
||||
"{\"lat\":26.822583129427166,\"lon\":112.56568437427828},{\"lat\":26.822567763188122,\"lon\":112.56559271125079}," +
|
||||
"{\"lat\":26.822567763188122,\"lon\":112.56559271125079},{\"lat\":26.822613311780497,\"lon\":112.56540937833189}," +
|
||||
"{\"lat\":26.822778835723827,\"lon\":112.56508853541045},{\"lat\":26.822778835723827,\"lon\":112.56508853541045}," +
|
||||
"{\"lat\":26.82335830821441,\"lon\":112.56486696378353},{\"lat\":26.825073836123234,\"lon\":112.5642098752998}," +
|
||||
"{\"lat\":26.82587831132585,\"lon\":112.56397299890796},{\"lat\":26.826602716871196,\"lon\":112.56375904383397}," +
|
||||
"{\"lat\":26.826757011379495,\"lon\":112.56362152304669},{\"lat\":26.826757011379495,\"lon\":112.56362152304669}," +
|
||||
"{\"lat\":26.826665118069972,\"lon\":112.56334650820811},{\"lat\":26.826515909977296,\"lon\":112.56299509732794}," +
|
||||
"{\"lat\":26.826273047969202,\"lon\":112.56249089072236},{\"lat\":26.825741353462305,\"lon\":112.56136019981324}," +
|
||||
"{\"lat\":26.825545885183946,\"lon\":112.5606802184245},{\"lat\":26.825515221290765,\"lon\":112.56057325303}," +
|
||||
"{\"lat\":26.82537828319818,\"lon\":112.55950355643967},{\"lat\":26.825358966712418,\"lon\":112.55933545613247}," +
|
||||
"{\"lat\":26.82533550731808,\"lon\":112.55894576231651},{\"lat\":26.825329684542123,\"lon\":112.55761615913678}," +
|
||||
"{\"lat\":26.82531512968552,\"lon\":112.555644526428},{\"lat\":26.825332951146304,\"lon\":112.55488027750438}," +
|
||||
"{\"lat\":26.825332951146304,\"lon\":112.55488027750438},{\"lat\":26.825582749368,\"lon\":112.55486497384544}," +
|
||||
"{\"lat\":26.832195779849293,\"lon\":112.55566694572363},{\"lat\":26.83305984045991,\"lon\":112.55577387436938}," +
|
||||
"{\"lat\":26.833412716051612,\"lon\":112.55581970205667},{\"lat\":26.833983005722352,\"lon\":112.55587315586395}," +
|
||||
"{\"lat\":26.834465509986607,\"lon\":112.55588840477134},{\"lat\":26.83493085073919,\"lon\":112.55590365493417}," +
|
||||
"{\"lat\":26.835735483067072,\"lon\":112.55581953062685},{\"lat\":26.83602718493831,\"lon\":112.55577365536547}," +
|
||||
"{\"lat\":26.837897224427703,\"lon\":112.55530733220453},{\"lat\":26.840266626992527,\"lon\":112.55468046640051}," +
|
||||
"{\"lat\":26.842555914048862,\"lon\":112.5540535884595},{\"lat\":26.842969582911035,\"lon\":112.55396184290737}," +
|
||||
"{\"lat\":26.84317738357361,\"lon\":112.55392361286312},{\"lat\":26.843375636130915,\"lon\":112.55387774049657}," +
|
||||
"{\"lat\":26.84422222305707,\"lon\":112.55380124821464},{\"lat\":26.845488430408043,\"lon\":112.553770582712}," +
|
||||
"{\"lat\":26.845890797709917,\"lon\":112.55376290998989},{\"lat\":26.8462931778245,\"lon\":112.55376288026709}," +
|
||||
"{\"lat\":26.846994945978572,\"lon\":112.55375518542454},{\"lat\":26.84857199311408,\"lon\":112.55372449688247}," +
|
||||
"{\"lat\":26.850915603316924,\"lon\":112.55366317952681},{\"lat\":26.851264598540528,\"lon\":112.55367079677764}," +
|
||||
"{\"lat\":26.851613580683804,\"lon\":112.55367077099322},{\"lat\":26.852782561801757,\"lon\":112.55366304158481}," +
|
||||
"{\"lat\":26.854128918956658,\"lon\":112.55367058513775},{\"lat\":26.85416133799072,\"lon\":112.55367058274223}," +
|
||||
"{\"lat\":26.854773485472688,\"lon\":112.55367053750845},{\"lat\":26.85698175172949,\"lon\":112.55364744520502}," +
|
||||
"{\"lat\":26.859598084724535,\"lon\":112.55360903659395},{\"lat\":26.862271647879098,\"lon\":112.55358590979833}," +
|
||||
"{\"lat\":26.865147332784925,\"lon\":112.55355512493922},{\"lat\":26.865349473200677,\"lon\":112.55355510999556}," +
|
||||
"{\"lat\":26.86715728059924,\"lon\":112.5535473332667},{\"lat\":26.8700749470803,\"lon\":112.55353947446217}," +
|
||||
"{\"lat\":26.87053068868336,\"lon\":112.55352415459471},{\"lat\":26.872084848173277,\"lon\":112.55350875349178}," +
|
||||
"{\"lat\":26.87280568452292,\"lon\":112.55350870018658},{\"lat\":26.874220619342925,\"lon\":112.55348566625867}," +
|
||||
"{\"lat\":26.874220619342925,\"lon\":112.55348566625867},{\"lat\":26.8743981499678,\"lon\":112.55359265628044}," +
|
||||
"{\"lat\":26.876129653094548,\"lon\":112.55357724209203},{\"lat\":26.876238350333104,\"lon\":112.55357723405288}," +
|
||||
"{\"lat\":26.87722422693687,\"lon\":112.55356187499282},{\"lat\":26.878499948626235,\"lon\":112.55353885139881}," +
|
||||
"{\"lat\":26.878742146279425,\"lon\":112.5535464765656},{\"lat\":26.87904156585159,\"lon\":112.55356174057314}," +
|
||||
"{\"lat\":26.879174347427238,\"lon\":112.55314900085355},{\"lat\":26.879174347427238,\"lon\":112.55314900085355}," +
|
||||
"{\"lat\":26.879116545005985,\"lon\":112.55280505766768},{\"lat\":26.878943245115085,\"lon\":112.55184963298143}," +
|
||||
"{\"lat\":26.878806472640868,\"lon\":112.55107761984246},{\"lat\":26.878713941862863,\"lon\":112.55052725736591}," +
|
||||
"{\"lat\":26.878437158373803,\"lon\":112.5483333129957},{\"lat\":26.878283777019536,\"lon\":112.54691898636362}," +
|
||||
"{\"lat\":26.8782233056314,\"lon\":112.54623090393771},{\"lat\":26.878174442724657,\"lon\":112.54563454956121}," +
|
||||
"{\"lat\":26.878164554891434,\"lon\":112.54545869832023},{\"lat\":26.878123256507333,\"lon\":112.54483938643703}," +
|
||||
"{\"lat\":26.878067664889805,\"lon\":112.54376893263695},{\"lat\":26.87802073724931,\"lon\":112.54141376662929}," +
|
||||
"{\"lat\":26.878020473600568,\"lon\":112.54129141419749},{\"lat\":26.878006686433814,\"lon\":112.54021315914473}," +
|
||||
"{\"lat\":26.877995617191544,\"lon\":112.53951724050327},{\"lat\":26.87798902932084,\"lon\":112.53912721215966}," +
|
||||
"{\"lat\":26.87798417185096,\"lon\":112.53866069993084},{\"lat\":26.87797034314032,\"lon\":112.5376052819373}," +
|
||||
"{\"lat\":26.877904771969245,\"lon\":112.53244233742839},{\"lat\":26.87789134593889,\"lon\":112.53163148144348}," +
|
||||
"{\"lat\":26.87786602244677,\"lon\":112.53064465683066},{\"lat\":26.87782568523666,\"lon\":112.52976490461232}," +
|
||||
"{\"lat\":26.877809833418425,\"lon\":112.52952775023115},{\"lat\":26.877809660077073,\"lon\":112.52945889830228}," +
|
||||
"{\"lat\":26.877793497045896,\"lon\":112.52909933698427},{\"lat\":26.877765422377227,\"lon\":112.52855616264061}," +
|
||||
"{\"lat\":26.877765422377227,\"lon\":112.52855616264061},{\"lat\":26.877651755590847,\"lon\":112.52662055504709}," +
|
||||
"{\"lat\":26.87759103383806,\"lon\":112.52527397999641},{\"lat\":26.877578807673792,\"lon\":112.52497558422694}," +
|
||||
"{\"lat\":26.877550150107766,\"lon\":112.5242334096616},{\"lat\":26.8775454631642,\"lon\":112.52390439907114}," +
|
||||
"{\"lat\":26.8775705911727,\"lon\":112.52331523086403},{\"lat\":26.877599976720568,\"lon\":112.52289438998851}," +
|
||||
"{\"lat\":26.877700379351634,\"lon\":112.52193791396827},{\"lat\":26.87783653603692,\"lon\":112.52081306743382}," +
|
||||
"{\"lat\":26.87794659907845,\"lon\":112.51991775931802},{\"lat\":26.87803420576694,\"lon\":112.51918313363727}," +
|
||||
"{\"lat\":26.878091905110153,\"lon\":112.51867041904868},{\"lat\":26.878169213335745,\"lon\":112.51766793293663}," +
|
||||
"{\"lat\":26.878242581649566,\"lon\":112.5166271615322},{\"lat\":26.878273796063315,\"lon\":112.51619860194072}," +
|
||||
"{\"lat\":26.878303472199264,\"lon\":112.51522667932018},{\"lat\":26.87829062072998,\"lon\":112.51472923351307}," +
|
||||
"{\"lat\":26.878258848003124,\"lon\":112.51428535631486},{\"lat\":26.87790199901372,\"lon\":112.51153784231195}," +
|
||||
"{\"lat\":26.87790199901372,\"lon\":112.51153784231195},{\"lat\":26.878286565374772,\"lon\":112.5113158617034}," +
|
||||
"{\"lat\":26.878286565374772,\"lon\":112.5113158617034},{\"lat\":26.878431428456157,\"lon\":112.51129289027774}," +
|
||||
"{\"lat\":26.878667958535303,\"lon\":112.5113158331442},{\"lat\":26.878667958535303,\"lon\":112.5113158331442}," +
|
||||
"{\"lat\":26.878678138797152,\"lon\":112.51087957995009},{\"lat\":26.878690352202895,\"lon\":112.509831030359}," +
|
||||
"{\"lat\":26.878699530812526,\"lon\":112.50970857034845},{\"lat\":26.878737491943227,\"lon\":112.5096473377598}," +
|
||||
"{\"lat\":26.878737491943227,\"lon\":112.5096473377598},{\"lat\":26.87879075331014,\"lon\":112.5096014114246}," +
|
||||
"{\"lat\":26.881275571457582,\"lon\":112.50961653268486},{\"lat\":26.881767589811375,\"lon\":112.50962414954007}," +
|
||||
"{\"lat\":26.882122440471107,\"lon\":112.50967769900092},{\"lat\":26.88221980681574,\"lon\":112.50971596028774}," +
|
||||
"{\"lat\":26.88257321771232,\"lon\":112.50993023747169},{\"lat\":26.88257321771232,\"lon\":112.50993023747169}," +
|
||||
"{\"lat\":26.88351446532152,\"lon\":112.50900406412066},{\"lat\":26.883643691685222,\"lon\":112.50885097840336}," +
|
||||
"{\"lat\":26.88371196217497,\"lon\":112.5087208584019},{\"lat\":26.884099751766627,\"lon\":112.5076492862477}," +
|
||||
"{\"lat\":26.884099751766627,\"lon\":112.5076492862477},{\"lat\":26.884364549439884,\"lon\":112.50755741913363}," +
|
||||
"{\"lat\":26.884829689791164,\"lon\":112.50750380663162},{\"lat\":26.884919429072728,\"lon\":112.50754206963039}," +
|
||||
"{\"lat\":26.88496340137097,\"lon\":112.5075803360432},{\"lat\":26.88500174259158,\"lon\":112.50764921859975}," +
|
||||
"{\"lat\":26.885013476143417,\"lon\":112.50774871879156},{\"lat\":26.885055608713724,\"lon\":112.50780994699682}," +
|
||||
"{\"lat\":26.885055608713724,\"lon\":112.50780994699682},{\"lat\":26.885056259143553,\"lon\":112.50803191023526}," +
|
||||
"{\"lat\":26.885018276929266,\"lon\":112.50808549033137},{\"lat\":26.884766782736666,\"lon\":112.50816204804912}," +
|
||||
"{\"lat\":26.884722922723803,\"lon\":112.50816205133796},{\"lat\":26.884677447004925,\"lon\":112.50826155514717}," +
|
||||
"{\"lat\":26.884616984162705,\"lon\":112.50845290622735},{\"lat\":26.884527446696502,\"lon\":112.50848352834187}," +
|
||||
"{\"lat\":26.884367351784473,\"lon\":112.50851415573345},{\"lat\":26.884312184268587,\"lon\":112.50856008292808}," +
|
||||
"{\"lat\":26.88427096917155,\"lon\":112.50881266232054},{\"lat\":26.884292303244706,\"lon\":112.50893512163981}," +
|
||||
"{\"lat\":26.88426006366657,\"lon\":112.50899635443699},{\"lat\":26.884183964013573,\"lon\":112.50905759046893}," +
|
||||
"{\"lat\":26.884146025794323,\"lon\":112.50912647736762},{\"lat\":26.884156260593674,\"lon\":112.51002196307275}," +
|
||||
"{\"lat\":26.88423087653796,\"lon\":112.51010614790864},{\"lat\":26.884343609318197,\"lon\":112.51018267612086}," +
|
||||
"{\"lat\":26.884452616959017,\"lon\":112.51028981912732},{\"lat\":26.88451038077976,\"lon\":112.51048115574633}," +
|
||||
"{\"lat\":26.884507321034185,\"lon\":112.51074137875689},{\"lat\":26.884454856613047,\"lon\":112.51106283289384}," +
|
||||
"{\"lat\":26.88435289830749,\"lon\":112.51141490315304},{\"lat\":26.884321054331565,\"lon\":112.51161389656696}]\n"
|
||||
|
||||
reqData = GsonUtils.fromJson(json, object : TypeToken<List<Point>>() {}.type)
|
||||
handleGlobalPath(reqData!!)
|
||||
// 获取道路事件
|
||||
travelNetWorkModel.getEventsWithTrajRequest(reqData!!, onSuccess = {
|
||||
Log.d(TAG, "111$it")
|
||||
handleRoadEvent(it)
|
||||
}, onError = {
|
||||
Log.d(TAG, "111$it")
|
||||
})
|
||||
// 获取路口设备
|
||||
travelNetWorkModel.getCrossDevice(112.583797, 26.817827, "0734", onSuccess = {
|
||||
Log.d(TAG, "222$it")
|
||||
handleCrossDevices(it)
|
||||
}, onError = {
|
||||
Log.d(TAG, "222$it")
|
||||
})
|
||||
// 获取智慧道路轨迹
|
||||
travelNetWorkModel.getCityRoadTrack(112.583797, 26.817827, "0734", onSuccess = {
|
||||
Log.d(TAG, "333$it")
|
||||
handleRoadTrajectories(it)
|
||||
}, onError = {
|
||||
Log.d(TAG, "333$it")
|
||||
})
|
||||
// // 获取智慧路口路网范围
|
||||
// travelNetWorkModel.getCityRoadRange(112.583797, 26.817827, "0734", onSuccess = {
|
||||
// Log.d(TAG, "444$it")
|
||||
// handleRoadRange(it)
|
||||
// }, onError = {
|
||||
// Log.d(TAG, "444$it")
|
||||
// })
|
||||
}
|
||||
|
||||
private fun handleGlobalPath(globalData: List<Point>) {
|
||||
if (globalData.isEmpty() || globalData.size < 2) return
|
||||
val boundsBuilder = LatLngBounds.Builder()
|
||||
|
||||
val globalOptions = PolylineOptions()
|
||||
globalOptions.width(AutoSizeUtils.dp2px(context, 20f).toFloat())
|
||||
globalOptions.lineJoinType(PolylineOptions.LineJoinType.LineJoinRound)
|
||||
globalOptions.lineCapType(PolylineOptions.LineCapType.LineCapRound)
|
||||
globalOptions.color(Color.parseColor("#49DEAE"))
|
||||
|
||||
globalData.forEach { globalPoint ->
|
||||
val point = coordinateConverterWgsToGcj(globalPoint.lat, globalPoint.lon)
|
||||
// markerOptionsList1.add(MarkerOptions().also {
|
||||
// it.position(point)
|
||||
// it.anchor(0.5f, 0.5f)
|
||||
// it.icon(pointBitmap1)
|
||||
// })
|
||||
boundsBuilder.include(point)
|
||||
globalOptions.add(coordinateConverterWgsToGcj(globalPoint.lat, globalPoint.lon))
|
||||
}
|
||||
|
||||
val cameraUpdate = CameraUpdateFactory.newLatLngBoundsRect(
|
||||
boundsBuilder.build(),
|
||||
AutoSizeUtils.dp2px(context, leftPadding.toFloat()),
|
||||
AutoSizeUtils.dp2px(context, rightPadding.toFloat()),
|
||||
AutoSizeUtils.dp2px(context, topPadding.toFloat()),
|
||||
AutoSizeUtils.dp2px(context, bottomPadding.toFloat())
|
||||
)
|
||||
mAMap?.moveCamera(cameraUpdate)
|
||||
|
||||
// val startPoint = globalData[0]
|
||||
// val endPoint = globalData[globalData.size - 1]
|
||||
// val angle = DrivingDirectionUtils.getLineAngle(endPoint.lon, endPoint.lat, startPoint.lon, startPoint.lat)
|
||||
// mAMap?.moveCamera(CameraUpdateFactory.changeBearing(LocationUtils.rotateTo90(angle).toFloat()))
|
||||
// mAMap?.setMapStatusLimits(boundsBuilder.build())
|
||||
|
||||
// mAMap?.addMarkers(markerOptionsList1, false)
|
||||
drawPolyline(DRAW_POLY_LINE, globalOptions)
|
||||
}
|
||||
|
||||
private fun handleRoadEvent(eventList: List<EventBean>) {
|
||||
val globalList = reqData
|
||||
if (eventList.isEmpty()) return
|
||||
testTime = System.currentTimeMillis()
|
||||
val eventOptionsList = ArrayList<MarkerOptions>()
|
||||
globalList?.forEachIndexed { index, globalPoint ->
|
||||
if (index >= 0 && index < globalList.size - 1) {
|
||||
eventList.forEach { eventBean ->
|
||||
if (LocationUtils.pointToLine(
|
||||
globalPoint.lon,
|
||||
globalPoint.lat,
|
||||
globalList[index + 1].lon,
|
||||
globalList[index + 1].lat,
|
||||
eventBean.lon,
|
||||
eventBean.lat
|
||||
) > 5
|
||||
) {
|
||||
return@forEach
|
||||
}
|
||||
when (eventBean.poiType) {
|
||||
"10032" -> {// 交通事故
|
||||
eventOptionsList.add(MarkerOptions().apply {
|
||||
position(coordinateConverterWgsToGcj(eventBean.lat, eventBean.lon))
|
||||
anchor(0.5f, 0.5f)
|
||||
icon(BitmapDescriptorFactory.fromResource(R.drawable.mogo_shigu_nor))
|
||||
})
|
||||
}
|
||||
|
||||
"10006" -> {// 施工
|
||||
eventOptionsList.add(MarkerOptions().apply {
|
||||
position(coordinateConverterWgsToGcj(eventBean.lat, eventBean.lon))
|
||||
anchor(0.5f, 0.5f)
|
||||
icon(BitmapDescriptorFactory.fromResource(R.drawable.mogo_shigong_image))
|
||||
})
|
||||
}
|
||||
|
||||
"10007" -> {// 拥堵
|
||||
eventOptionsList.add(MarkerOptions().apply {
|
||||
position(coordinateConverterWgsToGcj(eventBean.lat, eventBean.lon))
|
||||
anchor(0.5f, 0.5f)
|
||||
icon(BitmapDescriptorFactory.fromResource(R.drawable.mogo_yongdu_nor))
|
||||
})
|
||||
}
|
||||
|
||||
"10025" -> {// 静止事件
|
||||
eventOptionsList.add(MarkerOptions().apply {
|
||||
position(coordinateConverterWgsToGcj(eventBean.lat, eventBean.lon))
|
||||
anchor(0.5f, 0.5f)
|
||||
icon(BitmapDescriptorFactory.fromResource(R.drawable.mogo_jingzhi_nor))
|
||||
})
|
||||
}
|
||||
|
||||
else -> {
|
||||
eventOptionsList.add(MarkerOptions().apply {
|
||||
position(coordinateConverterWgsToGcj(eventBean.lat, eventBean.lon))
|
||||
anchor(0.5f, 0.5f)
|
||||
icon(BitmapDescriptorFactory.fromResource(R.drawable.mogo_jingzhi_nor))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "过滤掉的事件个数为:${eventList.size - eventOptionsList.size}")
|
||||
drawMarkers(DRAW_ROAD_EVENT, eventOptionsList)
|
||||
}
|
||||
|
||||
private fun handleCrossDevices(crossDeviceList: List<CrossDeviceBean>) {
|
||||
if (crossDeviceList.isEmpty()) return
|
||||
val globalList = reqData
|
||||
val crossOptionsList = ArrayList<MarkerOptions>()
|
||||
|
||||
globalList?.forEachIndexed { index, globalPoint ->
|
||||
if (index >= 0 && index < globalList.size - 1) {
|
||||
crossDeviceList.forEach {
|
||||
it.deviceInfoList?.forEach loop@ { deviceBean ->
|
||||
if (LocationUtils.pointToLine(
|
||||
globalPoint.lon,
|
||||
globalPoint.lat,
|
||||
globalList[index + 1].lon,
|
||||
globalList[index + 1].lat,
|
||||
deviceBean.lon,
|
||||
deviceBean.lat
|
||||
) > 5
|
||||
) {
|
||||
return@loop
|
||||
}
|
||||
|
||||
crossOptionsList.add(MarkerOptions().apply {
|
||||
position(coordinateConverterWgsToGcj(deviceBean.lat, deviceBean.lon))
|
||||
anchor(0.5f, 0.5f)
|
||||
icon(BitmapDescriptorFactory.fromResource(R.drawable.mogo_quanxi_lukou))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
drawMarkers(DRAW_CROSS_DEVICE, crossOptionsList)
|
||||
}
|
||||
|
||||
private fun handleRoadRange(roadRangeList: List<List<Double>?>?) {
|
||||
if (roadRangeList.isNullOrEmpty()) return
|
||||
val roadRangeOptions = PolylineOptions()
|
||||
roadRangeOptions.width(AutoSizeUtils.dp2px(context, 32f).toFloat())
|
||||
roadRangeOptions.isUseTexture = true
|
||||
roadRangeOptions.lineJoinType(PolylineOptions.LineJoinType.LineJoinRound)
|
||||
roadRangeOptions.lineCapType(PolylineOptions.LineCapType.LineCapSquare)
|
||||
roadRangeOptions.customTexture = roadTrajectoryBitmap
|
||||
|
||||
roadRangeList.forEach { pointList ->
|
||||
pointList?.let {
|
||||
if (it.size < 2) return@let
|
||||
roadRangeOptions.add(coordinateConverterWgsToGcj(it[1], it[0]))
|
||||
}
|
||||
}
|
||||
// drawPolyline(DRAW_ROAD_RANGE, roadRangeOptions)
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理智慧道路轨迹的数据
|
||||
*/
|
||||
private fun handleRoadTrajectories(roadTrajectoryList: List<List<List<Double>?>?>?) {
|
||||
val globalList = reqData
|
||||
if (roadTrajectoryList.isNullOrEmpty() || globalList.isNullOrEmpty()) return
|
||||
val roadTrajectoryOptionsList = ArrayList<PolylineOptions>()
|
||||
|
||||
roadTrajectoryList.forEach { trajectoryList ->
|
||||
var distanceTmp = 0.0
|
||||
var lastIndex = -1
|
||||
var polylineOptionTmp: PolylineOptions? = null
|
||||
trajectoryList?.forEachIndexed { index, trajPointList ->
|
||||
if (trajPointList.isNullOrEmpty()) return@forEachIndexed
|
||||
// // 待绘制的所有智慧道路轨迹点
|
||||
// markerOptionsList2.add(MarkerOptions().also { markerOption ->
|
||||
// markerOption.position(coordinateConverterWgsToGcj(trajPointList[1], trajPointList[0]))
|
||||
// markerOption.anchor(0.5f, 0.5f)
|
||||
// markerOption.icon(pointBitmap2)
|
||||
// })
|
||||
|
||||
if (index >= 0 && index < trajectoryList.size - 1) {
|
||||
if (trajPointList.isEmpty() || trajectoryList[index + 1].isNullOrEmpty()
|
||||
||trajPointList.size < 2 || trajectoryList[index + 1]!!.size < 2) return
|
||||
// 遍历所有轨迹点到智慧轨迹线段上的距离
|
||||
globalList.forEach { globalPoint ->
|
||||
distanceTmp = LocationUtils.pointToLine(
|
||||
trajPointList[0],
|
||||
trajPointList[1],
|
||||
trajectoryList[index + 1]!![0],
|
||||
trajectoryList[index + 1]!![1],
|
||||
globalPoint.lon,
|
||||
globalPoint.lat
|
||||
)
|
||||
// 如果距离小于50m则认为在智慧道路内
|
||||
if (distanceTmp < 50) {
|
||||
if (lastIndex < 0 || index - lastIndex > 1) {
|
||||
// 绘制新的智慧路段轨迹
|
||||
polylineOptionTmp = PolylineOptions()
|
||||
polylineOptionTmp?.let { optionTmp ->
|
||||
optionTmp.width(AutoSizeUtils.dp2px(context, 52f).toFloat())
|
||||
optionTmp.isUseTexture = true
|
||||
optionTmp.lineJoinType(PolylineOptions.LineJoinType.LineJoinRound)
|
||||
optionTmp.lineCapType(PolylineOptions.LineCapType.LineCapSquare)
|
||||
optionTmp.customTexture = roadTrajectoryBitmap
|
||||
optionTmp.add(coordinateConverterWgsToGcj(trajPointList[1], trajPointList[0]))
|
||||
optionTmp.add(coordinateConverterWgsToGcj(trajectoryList[index + 1]!![1],
|
||||
trajectoryList[index + 1]!![0]))
|
||||
// 待绘制多段智慧道路的轨迹线
|
||||
roadTrajectoryOptionsList.add(optionTmp)
|
||||
}
|
||||
lastIndex = index + 1
|
||||
} else if (index == lastIndex) {
|
||||
polylineOptionTmp?.add(coordinateConverterWgsToGcj(trajectoryList[index + 1]!![1],
|
||||
trajectoryList[index + 1]!![0]))
|
||||
lastIndex = index + 1
|
||||
} else if (index - lastIndex == 1) {
|
||||
polylineOptionTmp?.add(coordinateConverterWgsToGcj(trajPointList[1], trajPointList[0]))
|
||||
polylineOptionTmp?.add(coordinateConverterWgsToGcj(trajectoryList[index + 1]!![1],
|
||||
trajectoryList[index + 1]!![0]))
|
||||
lastIndex = index + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// mAMap?.addMarkers(markerOptionsList2, false)
|
||||
drawPolylineList(DRAW_ROAD_TRAJECTORY, roadTrajectoryOptionsList)
|
||||
}
|
||||
|
||||
private fun drawMarkers(type: Int, optionList: ArrayList<MarkerOptions>) {
|
||||
Message.obtain().apply {
|
||||
what = type
|
||||
obj = optionList
|
||||
nonFrequentHandler?.sendMessage(this)
|
||||
}
|
||||
}
|
||||
|
||||
private fun drawPolyline(type: Int, polylineOptions: PolylineOptions) {
|
||||
Message.obtain().apply {
|
||||
what = type
|
||||
obj = polylineOptions
|
||||
nonFrequentHandler?.sendMessage(this)
|
||||
}
|
||||
}
|
||||
|
||||
private fun drawPolylineList(type: Int, polylineOptionsList: ArrayList<PolylineOptions>) {
|
||||
Message.obtain().apply {
|
||||
what = type
|
||||
obj = polylineOptionsList
|
||||
nonFrequentHandler?.sendMessage(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun coordinateConverterWgsToGcj(
|
||||
lat: Double, lon: Double
|
||||
): LatLng {
|
||||
val coordinateConverter =
|
||||
CoordinateConverter(context)
|
||||
coordinateConverter.from(CoordinateConverter.CoordType.GPS)
|
||||
coordinateConverter.coord(LatLng(lat, lon))
|
||||
return coordinateConverter.convert()
|
||||
}
|
||||
|
||||
override fun onChassisLocationGCJ02(mogoLocation: MogoLocation?) {
|
||||
// TODO("绘制自车")
|
||||
|
||||
}
|
||||
|
||||
override fun onAutopilotRotting(globalPathResp: MessagePad.GlobalPathResp?) {
|
||||
// 上一步调用处已经加锁,这里就不加了
|
||||
if (lastTime > 0 && System.currentTimeMillis() - lastTime <= 1000) {
|
||||
return
|
||||
} else {
|
||||
lastTime = System.currentTimeMillis()
|
||||
}
|
||||
globalPathResp?.let {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private inner class NonFrequentHandler(looper: Looper) : Handler(looper) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun handleMessage(msg: Message) {
|
||||
super.handleMessage(msg)
|
||||
when (msg.what) {
|
||||
DRAW_POLY_LINE -> {
|
||||
removeMessages(DRAW_POLY_LINE)
|
||||
(msg.obj as PolylineOptions).apply {
|
||||
realDrawGlobalPath(this)
|
||||
}
|
||||
}
|
||||
|
||||
DRAW_ROAD_EVENT -> {
|
||||
removeMessages(DRAW_ROAD_EVENT)
|
||||
(msg.obj as ArrayList<MarkerOptions>).apply {
|
||||
realDrawEventMarkers(this)
|
||||
}
|
||||
}
|
||||
|
||||
DRAW_CROSS_DEVICE -> {
|
||||
removeMessages(DRAW_CROSS_DEVICE)
|
||||
(msg.obj as ArrayList<MarkerOptions>).apply {
|
||||
realDrawCrossDeviceMarkers(this)
|
||||
}
|
||||
}
|
||||
|
||||
DRAW_ROAD_RANGE -> {
|
||||
removeMessages(DRAW_ROAD_RANGE)
|
||||
(msg.obj as PolylineOptions).apply {
|
||||
realDrawRoadRange(this)
|
||||
}
|
||||
}
|
||||
|
||||
DRAW_ROAD_TRAJECTORY -> {
|
||||
removeMessages(DRAW_ROAD_TRAJECTORY)
|
||||
(msg.obj as ArrayList<PolylineOptions>).apply {
|
||||
realDrawRoadTrajectory(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun realDrawGlobalPath(polylineOptions: PolylineOptions) {
|
||||
mAMap?.addPolyline(polylineOptions)
|
||||
}
|
||||
|
||||
private fun realDrawEventMarkers(eventMarkerList: ArrayList<MarkerOptions>) {
|
||||
mAMap?.addMarkers(eventMarkerList, false)
|
||||
Log.d(TAG, "计算到绘制事件耗时为:${System.currentTimeMillis() - testTime}")
|
||||
}
|
||||
|
||||
private fun realDrawCrossDeviceMarkers(eventMarkerList: ArrayList<MarkerOptions>) {
|
||||
mAMap?.addMarkers(eventMarkerList, false)
|
||||
}
|
||||
|
||||
private fun realDrawRoadRange(polylineOptions: PolylineOptions) {
|
||||
mAMap?.addPolyline(polylineOptions)
|
||||
}
|
||||
|
||||
private fun realDrawRoadTrajectory(polylineOptionsList: ArrayList<PolylineOptions>) {
|
||||
polylineOptionsList.forEach {
|
||||
mAMap?.addPolyline(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 680 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:parentTag="RelativeLayout"
|
||||
tools:ignore="MissingDefaultResource">
|
||||
|
||||
<com.amap.api.maps.TextureMapView
|
||||
android:id="@+id/travelMapView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -1,17 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- 复用属性名 -->
|
||||
<!-- 地图样式asset目录下的路径 -->
|
||||
<attr name="mapStylePath" format="string" />
|
||||
<attr name="mapStyleExtraPath" format="string" />
|
||||
<!-- 自车模型图片 -->
|
||||
<attr name="carDrawable" format="reference" />
|
||||
<!-- 罗盘图片 -->
|
||||
<attr name="compassDrawable" format="reference" />
|
||||
<!-- 起点图片 -->
|
||||
<attr name="startPointDrawable" format="reference" />
|
||||
<!-- 终点图片 -->
|
||||
<attr name="endPointDrawable" format="reference" />
|
||||
<!-- 规定屏幕范围的padding -->
|
||||
<attr name="leftPadding" format="integer" />
|
||||
<attr name="topPadding" format="integer" />
|
||||
<attr name="rightPadding" format="integer" />
|
||||
<attr name="bottomPadding" format="integer" />
|
||||
|
||||
<declare-styleable name="OverMapView">
|
||||
<!-- 地图样式asset目录下的路径 -->
|
||||
<attr name="mapStylePath" format="string" />
|
||||
<attr name="mapStyleExtraPath" format="string" />
|
||||
<attr name="mapStylePath" />
|
||||
<attr name="mapStyleExtraPath" />
|
||||
<!-- 自车模型图片 -->
|
||||
<attr name="carDrawable" format="reference" />
|
||||
<attr name="carDrawable" />
|
||||
<!-- 罗盘图片 -->
|
||||
<attr name="compassDrawable" format="reference" />
|
||||
<attr name="compassDrawable" />
|
||||
<!-- 起点图片 -->
|
||||
<attr name="startPointDrawable" format="reference" />
|
||||
<attr name="startPointDrawable" />
|
||||
<!-- 终点图片 -->
|
||||
<attr name="endPointDrawable" format="reference" />
|
||||
<attr name="endPointDrawable" />
|
||||
<!-- 已走过路线的图片 -->
|
||||
<attr name="arrivedDrawable" format="reference" />
|
||||
<!-- 未走过路线的图片 -->
|
||||
@@ -25,11 +43,31 @@
|
||||
<!-- 是否擦除已走过的路线 -->
|
||||
<attr name="isClearArrived" format="boolean" />
|
||||
<!-- 规定屏幕范围的padding -->
|
||||
<attr name="leftPadding" format="integer" />
|
||||
<attr name="topPadding" format="integer" />
|
||||
<attr name="rightPadding" format="integer" />
|
||||
<attr name="bottomPadding" format="integer" />
|
||||
<attr name="leftPadding" />
|
||||
<attr name="topPadding" />
|
||||
<attr name="rightPadding" />
|
||||
<attr name="bottomPadding" />
|
||||
<!-- 倾斜角 -->
|
||||
<attr name="mapTilt" format="float" />
|
||||
</declare-styleable>
|
||||
<declare-styleable name="TravelRealityView">
|
||||
<!-- 地图样式asset目录下的路径 -->
|
||||
<attr name="mapStylePath" />
|
||||
<attr name="mapStyleExtraPath" />
|
||||
<!-- 自车模型图片 -->
|
||||
<attr name="carDrawable" />
|
||||
<!-- 罗盘图片 -->
|
||||
<attr name="compassDrawable" />
|
||||
<!-- 智慧道路范围纹理 -->
|
||||
<attr name="roadRangeDrawable" format="reference" />
|
||||
<!-- 起点图片 -->
|
||||
<attr name="startPointDrawable" />
|
||||
<!-- 终点图片 -->
|
||||
<attr name="endPointDrawable" />
|
||||
<!-- 规定屏幕范围的padding -->
|
||||
<attr name="leftPadding" />
|
||||
<attr name="topPadding" />
|
||||
<attr name="rightPadding" />
|
||||
<attr name="bottomPadding" />
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
@@ -1,25 +1,28 @@
|
||||
package com.mogo.eagle.core.utilcode.util;
|
||||
|
||||
import android.util.Pair;
|
||||
|
||||
public class LocationUtils {
|
||||
/**
|
||||
* 地球半径
|
||||
*/
|
||||
private static double EARTH_RADIUS = 6378.137;
|
||||
|
||||
private static double rad( double d ) {
|
||||
private static double rad(double d) {
|
||||
return d * Math.PI / 180.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算两点间距离( 单位:米 )
|
||||
*
|
||||
* @param lat1
|
||||
* @param lng1
|
||||
* @param lat2
|
||||
* @param lng2
|
||||
* @return
|
||||
*/
|
||||
public static double getDistance( double lat1, double lng1, double lat2, double lng2 ) {
|
||||
double radLat1 = rad( lat1 );
|
||||
public static double getDistance(double lat1, double lng1, double lat2, double lng2) {
|
||||
double radLat1 = rad(lat1);
|
||||
double radLat2 = rad(lat2);
|
||||
double a = radLat1 - radLat2;
|
||||
double b = rad(lng1) - rad(lng2);
|
||||
@@ -35,7 +38,8 @@ public class LocationUtils {
|
||||
|
||||
/**
|
||||
* 点到直线的最短距离的判断 点(x0,y0) 到由两点组成的线段(x1,y1) ,( x2,y2 ) <br>
|
||||
* ( 单位:米 )
|
||||
* ( 单位:米 )
|
||||
*
|
||||
* @param x1
|
||||
* @param y1
|
||||
* @param x2
|
||||
@@ -44,7 +48,7 @@ public class LocationUtils {
|
||||
* @param y0
|
||||
* @return
|
||||
*/
|
||||
public static double pointToLine( double x1, double y1, double x2, double y2, double x0, double y0 ) {
|
||||
public static double pointToLine(double x1, double y1, double x2, double y2, double x0, double y0) {
|
||||
double space;
|
||||
double a, b, c;
|
||||
a = getDistance(y1, x1, y2, x2);// 线段的长度
|
||||
@@ -73,4 +77,103 @@ public class LocationUtils {
|
||||
space = 2 * s / a;// 返回点到线的距离(利用三角形面积公式求高)
|
||||
return space;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算向量的点积
|
||||
*
|
||||
* @param xa
|
||||
* @param ya
|
||||
* @param xb
|
||||
* @param yb
|
||||
* @return
|
||||
*/
|
||||
private static double dotProduct(double xa, double ya, double xb, double yb) {
|
||||
return xa * xb + ya * yb;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算向量的模长
|
||||
* @param xa
|
||||
* @param ya
|
||||
* @return
|
||||
*/
|
||||
private static double magnitude(double xa, double ya) {
|
||||
return Math.sqrt(xa * xa + ya * ya);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算点p到点a和点b组成的线段的垂足
|
||||
*
|
||||
* @param xp
|
||||
* @param yp
|
||||
* @param xa
|
||||
* @param ya
|
||||
* @param xb
|
||||
* @param yb
|
||||
* @return 垂足
|
||||
*/
|
||||
public static Pair<Double, Double> footPoint(double xp, double yp, double xa, double ya, double xb, double yb) {
|
||||
// 计算线段的向量v,即b - a
|
||||
double xv = xb - xa;
|
||||
double yv = yb - ya;
|
||||
// 计算点p相对于线段起点a的向量w,即p - a
|
||||
double xw = xp - xa;
|
||||
double yw = yp - ya;
|
||||
|
||||
double c1 = dotProduct(xw, yw, xv, yv);
|
||||
double c2 = dotProduct(xv, yv, xv, yv);
|
||||
double t = c1 / c2;
|
||||
if (t < 0) {
|
||||
t = 0;
|
||||
} else if (t > 1) {
|
||||
t = 1;
|
||||
}
|
||||
return new Pair<>(xa + t * xv, ya + t * yv);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算a-b线段和c-d线段之间的夹角
|
||||
* @param xa
|
||||
* @param ya
|
||||
* @param xb
|
||||
* @param yb
|
||||
* @param xc
|
||||
* @param yc
|
||||
* @param xd
|
||||
* @param yd
|
||||
* @return
|
||||
*/
|
||||
public static double angleBetweenLineSegments(double xa, double ya, double xb, double yb, double xc, double yc, double xd, double yd) {
|
||||
double xv = xb - xa;
|
||||
double yv = yb - ya;
|
||||
|
||||
double xw = xd - xc;
|
||||
double yw = yd - yc;
|
||||
|
||||
double dot = dotProduct(xv, yv, xw, yw);
|
||||
double mag1 = magnitude(xv, yv);
|
||||
double mag2 = magnitude(xw, yw);
|
||||
double cosTheta = dot / (mag1 * mag2);
|
||||
// 由于反余弦函数的取值范围,需要对结果进行调整
|
||||
if (cosTheta > 1) {
|
||||
cosTheta = 1;
|
||||
} else if (cosTheta < -1) {
|
||||
cosTheta = -1;
|
||||
}
|
||||
double angleInRadians = Math.acos(cosTheta);
|
||||
return Math.toDegrees(angleInRadians);
|
||||
}
|
||||
|
||||
/**
|
||||
* 逆时针旋转到90度(和地图坐标系正北为0顺指针的方向相反)
|
||||
* @param angle
|
||||
* @return
|
||||
*/
|
||||
public static double rotateTo90(double angle) {
|
||||
double difference = angle - 90;
|
||||
if (difference < 0) {
|
||||
difference += 360;
|
||||
}
|
||||
return difference;
|
||||
}
|
||||
}
|
||||
|
||||