package com.zhaoyang.driver.base.gaode
|
|
import android.content.Context
|
import android.content.Intent
|
import android.graphics.Color
|
import android.location.LocationManager
|
import android.net.Uri
|
import android.os.Bundle
|
import android.os.Handler
|
import android.os.Looper
|
import android.text.TextUtils
|
import android.view.View
|
import android.widget.Toast
|
import androidx.core.content.ContextCompat
|
import cn.sinata.xldutils.utils.sysErr
|
import com.amap.api.fence.GeoFenceClient
|
import com.amap.api.fence.GeoFenceListener
|
import com.amap.api.location.AMapLocationClient
|
import com.amap.api.location.AMapLocationClientOption
|
import com.amap.api.location.AMapLocationListener
|
import com.amap.api.location.DPoint
|
import com.amap.api.maps.*
|
import com.amap.api.maps.model.*
|
import com.amap.api.services.core.LatLonPoint
|
import com.amap.api.services.district.DistrictSearch
|
import com.amap.api.services.district.DistrictSearchQuery
|
import com.amap.api.services.geocoder.*
|
import com.amap.api.services.help.Inputtips
|
import com.amap.api.services.help.Inputtips.InputtipsListener
|
import com.amap.api.services.help.InputtipsQuery
|
import com.amap.api.services.poisearch.PoiSearch
|
import com.amap.api.services.route.*
|
import com.amap.api.services.route.RouteSearch.DriveRouteQuery
|
import com.amap.api.services.route.RouteSearch.FromAndTo
|
import com.zhaoyang.driver.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
|
//设置定位参数
|
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 addMapMoveListener(aMap: AMap, marker: Marker, finishPosition: (LatLng) -> Unit) {
|
aMap.setOnCameraChangeListener(object : AMap.OnCameraChangeListener {
|
override fun onCameraChangeFinish(p0: CameraPosition?) {
|
p0?.let {
|
finishPosition(p0.target)
|
|
}
|
}
|
|
override fun onCameraChange(p0: CameraPosition?) {
|
p0?.let {
|
marker.position = p0!!.target
|
}
|
}
|
|
})
|
}
|
|
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 drawLine(context: Context, aMap: AMap, latLngs: List<LatLng?>?,color:Int): Polyline? {
|
val options = PolylineOptions().addAll(latLngs).width(20f)
|
.color(ContextCompat.getColor(context, color))
|
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, latlng: LatLng?,zoom:Float) {
|
val mCameraUpdate = CameraUpdateFactory.newCameraPosition(
|
CameraPosition(latlng, zoom, 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(BaseMapActivity.convertViewToBitmap(view)))
|
.draggable(true).setFlat(true)
|
}
|
|
/***
|
* 修改marker的view
|
*/
|
fun getIcon(view: View): BitmapDescriptor {
|
return BitmapDescriptorFactory.fromBitmap(BaseMapActivity.convertViewToBitmap(view))
|
}
|
|
/**
|
* 添加marker点
|
*/
|
fun addMarker(
|
aMap: AMap,
|
mLat: Double,
|
mLng: Double,
|
view: View,
|
peopleId: String
|
): Marker? {
|
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 searchDistrict(
|
context: Context,
|
name: String,
|
var1: DistrictSearch.OnDistrictSearchListener
|
) {
|
val search = DistrictSearch(context)
|
val query = DistrictSearchQuery()
|
query.keywords = name//传入关键字
|
query.isShowBoundary = true//是否返回边界值
|
search.query = query
|
search.setOnDistrictSearchListener(var1)//绑定监听器
|
search.searchDistrictAnsy()//开始搜索
|
}
|
|
fun drawFenceByCity(context: Context, city: String, va1: GeoFenceListener) {
|
val mGeoFenceClient = GeoFenceClient(context)
|
mGeoFenceClient.setActivateAction(GeoFenceClient.GEOFENCE_IN)
|
mGeoFenceClient.addGeoFence(city, "");
|
mGeoFenceClient.setGeoFenceListener(va1);
|
|
}
|
|
/***
|
* 绘制多边形围栏
|
*/
|
fun drawFenceByPoint(context: Context, dPoint: List<DPoint>, va1: GeoFenceListener) {
|
val mGeoFenceClient = GeoFenceClient(context)
|
mGeoFenceClient.setActivateAction(GeoFenceClient.GEOFENCE_IN)
|
mGeoFenceClient.addGeoFence(dPoint, "")
|
mGeoFenceClient.setGeoFenceListener(va1);
|
}
|
/***
|
* 绘制圆形形围栏
|
*/
|
fun drawFenceByCricle(context: Context, dPoint: DPoint,bg:Float, va1: GeoFenceListener) {
|
val mGeoFenceClient = GeoFenceClient(context)
|
mGeoFenceClient.setActivateAction(GeoFenceClient.GEOFENCE_IN)
|
mGeoFenceClient.addGeoFence("", "",dPoint,bg,-1,"")
|
mGeoFenceClient.setGeoFenceListener(va1);
|
}
|
|
|
fun drawFace(context: Context, aMap: AMap, latLngs: List<LatLng?>?): Polygon? {
|
var po = PolygonOptions().addAll(latLngs)
|
.fillColor(ContextCompat.getColor(context, R.color.l_transparent_10)).strokeColor(
|
Color.RED
|
).strokeWidth(1f)
|
return aMap.addPolygon(po)
|
}
|
|
fun drawCricle(context: Context, aMap: AMap, latLng: LatLng,bg:Double): Circle? {
|
return aMap.addCircle(CircleOptions().
|
center(latLng).
|
radius(bg).
|
fillColor(ContextCompat.getColor(context, R.color.l_transparent_10)).
|
strokeColor( Color.RED).
|
strokeWidth(1f));
|
}
|
|
|
fun toGaode(context: Context, endSite: LatLng) {
|
try {
|
val intent = Intent()
|
intent.setPackage("com.autonavi.minimap")
|
intent.action = "android.intent.action.VIEW"
|
intent.addCategory("android.intent.category.DEFAULT")
|
// LatLng newEnd = convertBaiduToGPS(new LatLng(latitude, longtitude));//转换坐标系
|
intent.data =
|
Uri.parse("androidamap://route?sourceApplication=艾亚科技&dlat=" + endSite.latitude.toString() + "&dlon=" + endSite.longitude.toString() + "&dname=目的地" + "&dev=0&t=0")
|
context.startActivity(intent)
|
} catch (e: Exception) {
|
Toast.makeText(context, "暂无高德地图", Toast.LENGTH_SHORT).show()
|
}
|
}
|
|
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
|
) {
|
initRouteLine(context, start, end, null, onClick)
|
}
|
|
fun initRouteLine(
|
context: Context,
|
start: LatLng, end: LatLng, centerPoint: List<LatLonPoint>?,
|
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,
|
centerPoint,
|
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) {
|
}
|
|
})
|
}
|
|
/***
|
* 是否开启gps
|
*/
|
public fun isLocServiceEnable(context: Context): Boolean {
|
val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
var gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
|
var network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
|
if (gps || network) {
|
return true
|
}
|
return false
|
}
|
|
// 计算方位角,正北向为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
|
}
|
|
/***
|
* 关键字检索
|
* @param s
|
*/
|
fun searchByText(
|
context: Context,
|
s: String,
|
cityName: String,
|
var1: PoiSearch.OnPoiSearchListener
|
) {
|
if (s.isEmpty()) {
|
return
|
}
|
val query = PoiSearch.Query(s, "190000", cityName)
|
query.pageSize = 10
|
query.pageNum = 1
|
val poiSearch = PoiSearch(context, query)
|
poiSearch.setOnPoiSearchListener(var1)
|
poiSearch.searchPOIAsyn()
|
}
|
|
/***
|
* 周边检索
|
* @param lat
|
* @param lng
|
*/
|
fun searchPoint(
|
context: Context,
|
lat: Double,
|
lng: Double,
|
var1: PoiSearch.OnPoiSearchListener
|
) {
|
// val query = PoiSearch.Query("", "190000", "")
|
val query = PoiSearch.Query("", "190000", "")
|
query.pageSize = 10 // 设置每页最多返回多少条poiitem
|
query.pageNum = 1 //设置查询页码
|
val poiSearch = PoiSearch(context, query)
|
poiSearch.setOnPoiSearchListener(var1)
|
poiSearch.bound = PoiSearch.SearchBound(
|
LatLonPoint(
|
lat,
|
lng
|
), 200
|
) //设置周边搜索的中心点以及半径
|
poiSearch.searchPOIAsyn()
|
}
|
|
/***
|
* 输入内容自动提示
|
* @param str
|
* @param var1
|
*/
|
fun searchSite(context: Context, content: String?, cityName: String, var1: InputtipsListener?) {
|
val inputquery = InputtipsQuery(content, cityName)
|
val inputTips = Inputtips(context, inputquery)
|
inputTips.setInputtipsListener(var1)
|
inputTips.requestInputtipsAsyn()
|
}
|
|
fun LatByDpoint(itemP: List<DPoint>): List<LatLng> {
|
var listLat = mutableListOf<LatLng>()
|
for (item in itemP) {
|
var lat = LatLng(item.latitude, item.longitude)
|
listLat.add(lat)
|
}
|
return listLat
|
}
|
|
/***
|
* 逆地址编码
|
*/
|
fun getAddress(context: Context,lat:Double,lon:Double,function:(String)->Unit) {
|
var geocoderSearch = GeocodeSearch(context);
|
// 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系
|
var query = RegeocodeQuery(LatLonPoint(lat,lon), 500f,GeocodeSearch.AMAP);
|
geocoderSearch.getFromLocationAsyn(query);
|
geocoderSearch.setOnGeocodeSearchListener(object : GeocodeSearch.OnGeocodeSearchListener {
|
override fun onRegeocodeSearched(p0: RegeocodeResult?, p1: Int) {
|
p0?.let {
|
if (p1 != 1000){
|
function("")
|
}else{
|
function(it.regeocodeAddress.adCode)
|
}
|
}
|
}
|
|
override fun onGeocodeSearched(p0: GeocodeResult?, p1: Int) {
|
|
}
|
|
})
|
}
|
|
|
}
|