[6.5.0][Feat]新增行程总览功能

This commit is contained in:
chenfufeng
2024-07-05 15:10:49 +08:00
parent 3bcacb2ca4
commit febcc2e5df
21 changed files with 1117 additions and 18 deletions

View File

@@ -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
)

View File

@@ -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)

View File

@@ -0,0 +1,3 @@
package com.mogo.eagle.core.function.business.travelreality
data class Point(var lon: Double, var lat: Double)

View File

@@ -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 ?: "")
}
}
}
}

View File

@@ -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>>>>
}

View File

@@ -237,9 +237,6 @@ class OverMapView @JvmOverloads constructor(
if (mMapView != null) {
mMapView!!.onDestroy()
}
if (mMapView != null) {
mMapView!!.onDestroy()
}
}
// =================必须通知高德地图生命周期的变化=================

View File

@@ -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)
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -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>

View File

@@ -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>