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 new file mode 100644 index 0000000000..eb960e4f21 --- /dev/null +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/CrossDeviceBean.kt @@ -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? +) + +data class DeviceInfoBean( + var deviceIp: String?, + var lon: Double, + var lat: Double +) 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 new file mode 100644 index 0000000000..9e05a4eb14 --- /dev/null +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/EventBean.kt @@ -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?,// 拥堵的路段 + var polygon: List?,// 施工、交通事故(延后50m的) + var origPolygon: List?// 施工、交通事故(识别的) +) + +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/Point.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/Point.kt new file mode 100644 index 0000000000..f9b7d93da4 --- /dev/null +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/Point.kt @@ -0,0 +1,3 @@ +package com.mogo.eagle.core.function.business.travelreality + +data class Point(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 new file mode 100644 index 0000000000..632d89133c --- /dev/null +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/TravelRealityModel.kt @@ -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, + onSuccess: ((List) -> Unit), onError: ((String) -> Unit)){ + request?>>{ + 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) -> Unit), onError: ((String) -> Unit)) { + request?>>{ + 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?>?) -> Unit), onError: ((String) -> Unit)) { + request?>?>>{ + 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?>?>?) -> Unit), onError: ((String) -> Unit)) { + request?>?>?>>{ + 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 ?: "") + } + } + } +} \ 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/TravelRealityService.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/TravelRealityService.kt new file mode 100644 index 0000000000..55b30de4bb --- /dev/null +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/business/travelreality/TravelRealityService.kt @@ -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 + ): Response> + + /** + * 查询路口设备 + */ + @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> + + /** + * 查询路口路网范围 + */ + @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>> + + /** + * 查询智慧道路轨迹 + */ + @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>>> +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/OverMapView.kt b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/OverMapView.kt index c2c8e9d9cc..bb8801b16a 100644 --- a/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/OverMapView.kt +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/OverMapView.kt @@ -237,9 +237,6 @@ class OverMapView @JvmOverloads constructor( if (mMapView != null) { mMapView!!.onDestroy() } - if (mMapView != null) { - mMapView!!.onDestroy() - } } // =================必须通知高德地图生命周期的变化================= 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 new file mode 100644 index 0000000000..4155ea76b0 --- /dev/null +++ b/core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/view/TravelRealityView.kt @@ -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() +// } +// +// private val pointBitmap2 by lazy { +// BitmapDescriptorFactory.fromBitmap(getBitmap2()) +// } +// +// private val markerOptionsList2 by lazy { +// ArrayList() +// } + + /** + * 低频的 + */ + private var nonFrequentHandler: NonFrequentHandler? = null + + @Volatile + private var lastTime = 0L + + private var reqData: List? = 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>() {}.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) { + 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) { + val globalList = reqData + if (eventList.isEmpty()) return + testTime = System.currentTimeMillis() + val eventOptionsList = ArrayList() + 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) { + if (crossDeviceList.isEmpty()) return + val globalList = reqData + val crossOptionsList = ArrayList() + + 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?>?) { + 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?>?>?) { + val globalList = reqData + if (roadTrajectoryList.isNullOrEmpty() || globalList.isNullOrEmpty()) return + val roadTrajectoryOptionsList = ArrayList() + + 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) { + 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) { + 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).apply { + realDrawEventMarkers(this) + } + } + + DRAW_CROSS_DEVICE -> { + removeMessages(DRAW_CROSS_DEVICE) + (msg.obj as ArrayList).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).apply { + realDrawRoadTrajectory(this) + } + } + } + } + } + + private fun realDrawGlobalPath(polylineOptions: PolylineOptions) { + mAMap?.addPolyline(polylineOptions) + } + + private fun realDrawEventMarkers(eventMarkerList: ArrayList) { + mAMap?.addMarkers(eventMarkerList, false) + Log.d(TAG, "计算到绘制事件耗时为:${System.currentTimeMillis() - testTime}") + } + + private fun realDrawCrossDeviceMarkers(eventMarkerList: ArrayList) { + mAMap?.addMarkers(eventMarkerList, false) + } + + private fun realDrawRoadRange(polylineOptions: PolylineOptions) { + mAMap?.addPolyline(polylineOptions) + } + + private fun realDrawRoadTrajectory(polylineOptionsList: ArrayList) { + polylineOptionsList.forEach { + mAMap?.addPolyline(it) + } + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_power_nor.png b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_power_nor.png new file mode 100644 index 0000000000..b1ced222ee Binary files /dev/null and b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_power_nor.png differ diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_road_over.png b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_road_over.png new file mode 100644 index 0000000000..6c2d0f5a9c Binary files /dev/null and b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_road_over.png differ diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_tanchalukou.png b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_tanchalukou.png new file mode 100644 index 0000000000..404a8ed58b Binary files /dev/null and b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_tanchalukou.png differ diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_v2x_detail_bg.png b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_v2x_detail_bg.png new file mode 100644 index 0000000000..b9ab8adac4 Binary files /dev/null and b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_v2x_detail_bg.png differ diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_xiaozhi_icon.png b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_xiaozhi_icon.png new file mode 100644 index 0000000000..63c32dc184 Binary files /dev/null and b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_xiaozhi_icon.png differ diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_xingren_pengzhuang.png b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_xingren_pengzhuang.png new file mode 100644 index 0000000000..c55bcbb4ff Binary files /dev/null and b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_xingren_pengzhuang.png differ diff --git a/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_yongdu_nor.png b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_yongdu_nor.png new file mode 100644 index 0000000000..4105161e23 Binary files /dev/null and b/core/function-impl/mogo-core-function-map/src/main/res/drawable-xhdpi/mogo_yongdu_nor.png differ diff --git a/core/function-impl/mogo-core-function-map/src/main/res/layout/module_travel_reality_view.xml b/core/function-impl/mogo-core-function-map/src/main/res/layout/module_travel_reality_view.xml new file mode 100644 index 0000000000..79561f2824 --- /dev/null +++ b/core/function-impl/mogo-core-function-map/src/main/res/layout/module_travel_reality_view.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-map/src/main/res/values/attrs.xml b/core/function-impl/mogo-core-function-map/src/main/res/values/attrs.xml index d70e4a35f8..4030c0316e 100644 --- a/core/function-impl/mogo-core-function-map/src/main/res/values/attrs.xml +++ b/core/function-impl/mogo-core-function-map/src/main/res/values/attrs.xml @@ -1,17 +1,35 @@ + + + + + + + + + + + + + + + + + + - - + + - + - + - + - + @@ -25,11 +43,31 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/core/mogo-core-res/src/main/res/drawable-xhdpi/mogo_jingzhi_nor.png b/core/mogo-core-res/src/main/res/drawable-xhdpi/mogo_jingzhi_nor.png new file mode 100644 index 0000000000..6d0901977c Binary files /dev/null and b/core/mogo-core-res/src/main/res/drawable-xhdpi/mogo_jingzhi_nor.png differ diff --git a/core/mogo-core-res/src/main/res/drawable-xhdpi/mogo_quanxi_lukou.png b/core/mogo-core-res/src/main/res/drawable-xhdpi/mogo_quanxi_lukou.png new file mode 100644 index 0000000000..338cf614d0 Binary files /dev/null and b/core/mogo-core-res/src/main/res/drawable-xhdpi/mogo_quanxi_lukou.png differ diff --git a/core/mogo-core-res/src/main/res/drawable-xhdpi/mogo_shigong_image.png b/core/mogo-core-res/src/main/res/drawable-xhdpi/mogo_shigong_image.png new file mode 100644 index 0000000000..a064b1f90d Binary files /dev/null and b/core/mogo-core-res/src/main/res/drawable-xhdpi/mogo_shigong_image.png differ diff --git a/core/mogo-core-res/src/main/res/drawable-xhdpi/mogo_shigu_nor.png b/core/mogo-core-res/src/main/res/drawable-xhdpi/mogo_shigu_nor.png new file mode 100644 index 0000000000..bf0654c7ec Binary files /dev/null and b/core/mogo-core-res/src/main/res/drawable-xhdpi/mogo_shigu_nor.png differ 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 5d709ac3cf..4c607a99b9 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 @@ -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 )
- * ( 单位:米 ) + * ( 单位:米 ) + * * @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 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; + } }