package com.okgoincar.base
|
|
import android.content.Context
|
import android.graphics.Bitmap
|
import android.os.Bundle
|
import android.os.Handler
|
import android.os.Looper
|
import android.text.TextUtils
|
import android.view.View
|
import androidx.core.content.ContextCompat
|
import cn.sinata.xldutils.utils.sysErr
|
import com.amap.api.location.AMapLocationClient
|
import com.amap.api.location.AMapLocationClientOption
|
import com.amap.api.location.AMapLocationListener
|
import com.amap.api.maps.*
|
import com.amap.api.maps.model.*
|
import com.amap.api.services.core.LatLonPoint
|
import com.amap.api.services.route.*
|
import com.amap.api.services.route.RouteSearch.DriveRouteQuery
|
import com.amap.api.services.route.RouteSearch.FromAndTo
|
import com.okgoincar.R
|
import java.util.*
|
|
|
object AMapKit {
|
|
fun initLocation(context: Context, lisener: AMapLocationListener) { //初始化定位
|
var mlocationClient = AMapLocationClient(context)
|
//初始化定位参数
|
var mLocationOption = AMapLocationClientOption()
|
//设置定位回调监听
|
mlocationClient.setLocationListener(lisener)
|
//设置为高精度定位模式
|
// mLocationOption.isNeedAddress = true
|
mLocationOption.interval = 5000
|
// mLocationOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
|
mLocationOption.locationMode = AMapLocationClientOption.AMapLocationMode.Device_Sensors
|
//设置定位参数
|
mlocationClient.setLocationOption(mLocationOption)
|
// 此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗,
|
// 注意设置合适的定位时间的间隔(最小间隔支持为2000ms),并且在合适时间调用stopLocation()方法来取消定位请求
|
// 在定位结束后,在合适的生命周期调用onDestroy()方法
|
// 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除
|
mlocationClient.startLocation() //启动定位
|
}
|
|
fun initMap(savedInstanceState: Bundle?, mapView: MapView): AMap {
|
mapView.onCreate(savedInstanceState)
|
val aMap = mapView.map
|
val mMyLocationStyle = MyLocationStyle()
|
mMyLocationStyle.interval(5000)
|
mMyLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER)
|
mMyLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.mipmap.gps_point))
|
aMap.myLocationStyle = mMyLocationStyle
|
aMap.isMyLocationEnabled = false
|
aMap.animateCamera(CameraUpdateFactory.zoomTo(aMap.maxZoomLevel - 3))
|
// 设置定位的类型为定位模式,有定位、跟随或地图根据面向方向旋转几种
|
aMap.setMyLocationType(AMap.LOCATION_TYPE_LOCATE)
|
val uiSettings: UiSettings = aMap.uiSettings
|
uiSettings.isZoomControlsEnabled = false
|
return aMap
|
}
|
|
fun drawLine(context: Context,aMap: AMap, start: LatLng, end: LatLng): Polyline? {
|
val latLngs: MutableList<LatLng> = ArrayList()
|
latLngs.add(start)
|
latLngs.add(end)
|
return aMap.addPolyline(
|
PolylineOptions().addAll(latLngs).width(10f).color(
|
ContextCompat.getColor(context, R.color.main_yellow_qia)
|
)
|
)
|
}
|
|
fun drawLineAndMove(context: Context,aMap: AMap, start: LatLng, end: LatLng, padd: Int) {
|
drawLine(context,aMap, start, end)
|
moveCamera(aMap, start, end, padd)
|
}
|
|
|
fun drawLine(context: Context, aMap: AMap, latLngs: List<LatLng?>?): Polyline? {
|
val options = PolylineOptions().addAll(latLngs).width(20f)
|
.color(ContextCompat.getColor(context, R.color.qing))
|
return aMap.addPolyline(options)
|
}
|
|
fun moveCamera(aMap: AMap, latlng: LatLng?) {
|
val mCameraUpdate = CameraUpdateFactory.newCameraPosition(
|
CameraPosition(latlng, 16f, 0f, 0f)
|
)
|
aMap.animateCamera(mCameraUpdate)
|
}
|
|
fun moveCamera(aMap: AMap, start: LatLng?, end: LatLng?) {
|
var bounds: LatLngBounds? = null
|
if (start!!.latitude < end!!.latitude)
|
bounds = LatLngBounds(start, end)
|
else
|
bounds = LatLngBounds(end, start)
|
val mCameraUpdate = CameraUpdateFactory.newLatLngBounds(bounds, 150)
|
aMap.animateCamera(mCameraUpdate, object : AMap.CancelableCallback {
|
override fun onFinish() {
|
sysErr("onFinish")
|
}
|
|
override fun onCancel() {
|
sysErr("onCancel")
|
}
|
|
})
|
}
|
|
fun moveCamera(aMap: AMap, start: LatLng?, end: LatLng?, padd: Int) {
|
val bounds = LatLngBounds(start, end)
|
val mCameraUpdate = CameraUpdateFactory.newLatLngBounds(bounds, padd)
|
aMap.animateCamera(mCameraUpdate)
|
}
|
|
fun getOption(
|
latLng: LatLng,
|
view: View
|
): MarkerOptions {
|
return MarkerOptions().anchor(0.5f, 1f)
|
.position(latLng)
|
.icon(BitmapDescriptorFactory.fromBitmap(convertViewToBitmap(view)))
|
.draggable(true).setFlat(true)
|
}
|
|
/**
|
* 吧iew转化为bitmap
|
*
|
* @param view
|
* @return
|
*/
|
fun convertViewToBitmap(view: View): Bitmap? {
|
view.isDrawingCacheEnabled = true
|
view.measure(
|
View.MeasureSpec.makeMeasureSpec(
|
0,
|
View.MeasureSpec.UNSPECIFIED
|
),
|
View.MeasureSpec.makeMeasureSpec(
|
0,
|
View.MeasureSpec.UNSPECIFIED
|
)
|
)
|
view.layout(0, 0, view.measuredWidth, view.measuredHeight)
|
view.buildDrawingCache()
|
val mCacheBitmap = view.drawingCache
|
return Bitmap.createBitmap(mCacheBitmap)
|
}
|
|
/***
|
* 修改marker的view
|
*/
|
fun getIcon(view: View): BitmapDescriptor {
|
return BitmapDescriptorFactory.fromBitmap(convertViewToBitmap(view))
|
}
|
|
/**
|
* 添加marker点
|
*/
|
fun addMarker(
|
aMap: AMap,
|
mLat: Double?,
|
mLng: Double?,
|
view: View,
|
peopleId: String
|
): Marker? {
|
if (mLat == null || mLng == null){
|
return null
|
}
|
val options: MarkerOptions = getOption(LatLng(mLat, mLng), view)
|
val marker: Marker = aMap.addMarker(options)
|
if (!TextUtils.isEmpty(peopleId)) {
|
marker.setObject(peopleId)
|
}
|
return marker
|
}
|
|
fun getTanceStr(start: LatLng, end: LatLng): String {
|
val distance = AMapUtils.calculateLineDistance(start, end)
|
return if (distance > 1000) {
|
String.format("%.1fm", (distance / 1000f).toString()) + "公里"
|
} else {
|
String.format("%.1fm", distance.toString()) + "米"
|
}
|
}
|
|
fun getTance(tance: Float): String {
|
if (tance == 0f) {
|
return "0米"
|
}
|
return if (tance > 1000) {
|
String.format("%.1f公里", (tance / 1000f))
|
} else {
|
String.format("%.1f米", tance)
|
}
|
}
|
|
fun getTimeType(num: Int): String {
|
if (num in 0..60) {
|
return num.toString() + "s"
|
}
|
if (num in 60..60 * 60) {
|
return (num / 60).toString() + ":" + (num % 60).toString() + "s"
|
}
|
if (num in 60..60 * 60 * 24) {
|
return (num / 3600).toString() + ":" + ((num % 3600) / 60).toString() + ":" + (((num % 3600) % 60) % 60).toString() + "s"
|
}
|
return ""
|
}
|
|
fun initRouteLine(
|
context: Context,
|
start: LatLng, end: LatLng,
|
onClick: (latLngs: MutableList<LatLng>, lineTance: Float, lineTime: Long) -> Unit
|
) {
|
var routeSearch = RouteSearch(context)
|
val fromAndTo = FromAndTo(
|
LatLonPoint(start.latitude, start.longitude),
|
LatLonPoint(end.latitude, end.longitude)
|
)
|
val query =
|
DriveRouteQuery(
|
fromAndTo,
|
RouteSearch.DRIVING_SINGLE_SAVE_MONEY,
|
null,
|
null,
|
""
|
)
|
routeSearch.calculateDriveRouteAsyn(query)
|
routeSearch.setRouteSearchListener(object : RouteSearch.OnRouteSearchListener {
|
override fun onDriveRouteSearched(p0: DriveRouteResult?, p1: Int) {
|
if (p1 == 1000) { //获取规划路线成功,获取到的是了,路线坐标点的集合
|
val paths: List<DrivePath> = p0!!.paths
|
var allDistance = 0f
|
if (paths.isNotEmpty()) {
|
val drivePath = paths[0]
|
//创建存储坐标点的集合
|
val latLngs: MutableList<LatLng> =
|
ArrayList()
|
//遍历获取规划的所有路线坐标点
|
for (mDriveStep in drivePath.steps) {
|
allDistance += mDriveStep.distance
|
for (mLatLonPoint in mDriveStep.polyline) {
|
latLngs.add(
|
LatLng(
|
mLatLonPoint.latitude,
|
mLatLonPoint.longitude
|
)
|
)
|
}
|
}
|
val lineTance = allDistance
|
val lineTime = (drivePath.duration / 60) //lineTime 分钟
|
Handler(Looper.getMainLooper()).post {
|
onClick(latLngs, lineTance, lineTime)
|
}
|
}
|
}
|
}
|
|
override fun onBusRouteSearched(p0: BusRouteResult?, p1: Int) {
|
}
|
|
override fun onRideRouteSearched(p0: RideRouteResult?, p1: Int) {
|
}
|
|
override fun onWalkRouteSearched(p0: WalkRouteResult?, p1: Int) {
|
}
|
|
})
|
|
|
}
|
|
|
// 计算方位角,正北向为0度,以顺时针方向递增
|
fun computeAzimuth(la1: LatLng, la2: LatLng): Double {
|
var lat1 = la1.latitude
|
var lon1 = la1.longitude
|
var lat2 = la2.latitude
|
var lon2 = la2.longitude
|
var result = 0.0
|
val ilat1 = (0.50 + lat1 * 360000.0).toInt()
|
val ilat2 = (0.50 + lat2 * 360000.0).toInt()
|
val ilon1 = (0.50 + lon1 * 360000.0).toInt()
|
val ilon2 = (0.50 + lon2 * 360000.0).toInt()
|
lat1 = Math.toRadians(lat1)
|
lon1 = Math.toRadians(lon1)
|
lat2 = Math.toRadians(lat2)
|
lon2 = Math.toRadians(lon2)
|
if (ilat1 == ilat2 && ilon1 == ilon2) {
|
return result
|
} else if (ilon1 == ilon2) {
|
if (ilat1 > ilat2) result = 180.0
|
} else {
|
val c = Math
|
.acos(
|
Math.sin(lat2) * Math.sin(lat1) + (Math.cos(lat2)
|
* Math.cos(lat1) * Math.cos(lon2 - lon1))
|
)
|
val A = Math.asin(
|
Math.cos(lat2) * Math.sin(lon2 - lon1)
|
/ Math.sin(c)
|
)
|
result = Math.toDegrees(A)
|
if (ilat2 > ilat1 && ilon2 > ilon1) {
|
} else if (ilat2 < ilat1 && ilon2 < ilon1) {
|
result = 180.0 - result
|
} else if (ilat2 < ilat1 && ilon2 > ilon1) {
|
result = 180.0 - result
|
} else if (ilat2 > ilat1 && ilon2 < ilon1) {
|
result += 360.0
|
}
|
}
|
return result
|
}
|
|
}
|