package com.abbidot.tracker.ui.fragment.map.baidumap

import android.content.Context
import android.graphics.Bitmap
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import com.abbidot.baselibrary.util.AppUtils
import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.tracker.R
import com.abbidot.tracker.base.BaseFragment
import com.abbidot.tracker.bean.FencesBean
import com.abbidot.tracker.bean.HistoryDataBean
import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.databinding.FragmentBaseBaiduMapBinding
import com.abbidot.tracker.ui.fragment.map.googlemap.GoogleBitmapHelper
import com.abbidot.tracker.util.ImageUtil
import com.abbidot.tracker.util.LonAndLatUtil
import com.abbidot.tracker.widget.TypefaceTextView
import com.baidu.location.BDAbstractLocationListener
import com.baidu.location.BDLocation
import com.baidu.location.LocationClient
import com.baidu.location.LocationClientOption
import com.baidu.mapapi.map.BaiduMap
import com.baidu.mapapi.map.BitmapDescriptorFactory
import com.baidu.mapapi.map.Circle
import com.baidu.mapapi.map.CircleDottedStrokeType
import com.baidu.mapapi.map.CircleOptions
import com.baidu.mapapi.map.InfoWindow
import com.baidu.mapapi.map.MapStatusUpdateFactory
import com.baidu.mapapi.map.MarkerOptions
import com.baidu.mapapi.map.MyLocationConfiguration
import com.baidu.mapapi.map.MyLocationData
import com.baidu.mapapi.map.Overlay
import com.baidu.mapapi.map.PolygonOptions
import com.baidu.mapapi.map.PolylineDottedLineType
import com.baidu.mapapi.map.PolylineOptions
import com.baidu.mapapi.map.Stroke
import com.baidu.mapapi.map.TextureMapView
import com.baidu.mapapi.model.LatLng
import com.baidu.mapapi.utils.DistanceUtil
import com.qmuiteam.qmui.util.QMUIDisplayHelper
import kotlinx.coroutines.launch
import kotlin.math.abs


/**
 * 百度地图
 */
abstract class BaseBaiduMapFragment :
    BaseFragment<FragmentBaseBaiduMapBinding>(FragmentBaseBaiduMapBinding::inflate) {

    private lateinit var mMapView: TextureMapView
    var mBaiduMap: BaiduMap? = null

    private var mMapviewBundleKey = this.javaClass.simpleName

    //地图是否加载准备好了
    var isMapLoadOk = false

    //地图放大
    private var mBaiduMapZoom = 19f

    //自定显示宠物头像地点信息图层
    protected var mMarker: Overlay? = null

    //宠物大头针设置自定义头像
    private var mPetHeadIconBitmap: Bitmap? = null

    //宠物头像地址
    var mPetHeadUrl = ""

    //头像为空，用默认类型的头像
    private var mPetType = ConstantInt.DogPetType

    //坐标类型,定位SDK默认输出GCJ02坐标，地图SDK默认输出BD09ll坐标。火星GCJ02坐标https://lbsyun.baidu.com/faq/api?title=androidsdk/guide/create-map/location
    private val mCoordType = "GCJ02"
    private var mLocationClient: LocationClient? = null
    private var mLocationListener: BDAbstractLocationListener? = null

    private var mSensorManager: SensorManager? = null
    private var mSensor: Sensor? = null
    private var mSensorEventListener: SensorEventListener? = null
    private var mLastX = 0f

    //用户位置经纬度
    var mUserLatLng: LatLng? = null

    //宠物位置经纬度
    var mPetLatLng: LatLng? = null

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View {
        mViewBinding = this.inflater(inflater, container, false)
        LogUtil.e("${mMapviewBundleKey}===BaiduMapFragment--->onCreateView---$container")

//        var mapViewBundle: Bundle? = null
//        if (null != savedInstanceState) {
//            mapViewBundle = savedInstanceState.getBundle(mMapviewBundleKey)
//        }
        mMapView = mViewBinding.baiduMapView
        //不显示缩放按钮控件
        mMapView.showZoomControls(false)
        mBaiduMap = mMapView.map
//        mMapView.onCreate(mContext, mapViewBundle)
        return mViewBinding.root
    }

    override fun initData() {
        super.initData()
        mBaiduMap?.apply {
            //开启地图的定位图层
            isMyLocationEnabled = true
            val locationConfiguration =
                MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL, true, null)
            //自定义精度圈边框颜色
            setMyLocationConfiguration(locationConfiguration)

            //设置是否允许俯视手势
            uiSettings.isOverlookingGesturesEnabled = false
            //设置是否允许抛出惯性手势
            uiSettings.setFlingEnable(false)

            setOnMapLoadedCallback {
                LogUtil.e("百度地图加载好了")
                isMapLoadOk = true

                onMapLoadOk(this)
            }
        }
    }

//    override fun onSaveInstanceState(outState: Bundle) {
//        super.onSaveInstanceState(outState)
//
//        var mapViewBundle = outState.getBundle(mMapviewBundleKey)
//        if (null == mapViewBundle) {
//            mapViewBundle = Bundle()
//            outState.putBundle(mMapviewBundleKey, mapViewBundle)
//        }
//        mMapView.onSaveInstanceState(mapViewBundle)
//    }

    override fun onResume() {
        super.onResume()
        //在activity执行onResume时执行mMapView. onResume ()，实现地图生命周期管理
        mMapView.onResume()
    }

    override fun onPause() {
        super.onPause()
        //在activity执行onPause时执行mMapView. onPause ()，实现地图生命周期管理
        mMapView.onPause()
    }

    override fun liveDataObserve() {

    }

    /**
     * 卫星标准地图模式切换
     */
    fun switchSatelliteAndNormalMapType() {
        if (mBaiduMap!!.mapType == BaiduMap.MAP_TYPE_NORMAL) {
            setMapType(BaiduMap.MAP_TYPE_SATELLITE)
        } else {
            setMapType(BaiduMap.MAP_TYPE_NORMAL)
        }
    }

    /**
     * 设置地图样式
     */
    private fun setMapType(type: Int) {
        if (null != mBaiduMap) {
            mBaiduMap!!.mapType = type
        }
    }

    /**
     * 设置地图显示级别
     */
    fun setBaiduMapZoom(zoom: Float) {
        mBaiduMapZoom = zoom
    }

    /**
     * 获取地图显示级别
     */
    fun getBaiduMapZoom() = mBaiduMapZoom

    /**
     * 切换用户和宠物的位置居中显示,移动摄像头中心
     */
    fun switchShowLocation(@ConstantInt type: Int) {
        val latLng = if (type == ConstantInt.PetLocationType) {
            mPetLatLng
        } else mUserLatLng

        latLng?.apply {
            moveCameraLocation(latLng)
        }
    }

    /**
     * 设置大头针宠物头像
     */
    fun setPetHeadIconUrl(petHeadUrl: String) {
        mPetHeadUrl = petHeadUrl
        mPetHeadIconBitmap?.recycle()
        mPetHeadIconBitmap = null
    }

    /**
     * @param needConvertGCJ02 是否需要转换GCJ02坐标
     */
    fun getBaiduMapLatLng(
        lat: Double, lon: Double, needConvertGCJ02: Boolean = true
    ): LatLng {
        val latLng = if (needConvertGCJ02) {
            val convertLonLat = LonAndLatUtil.convertFromWGS84ToGCJ02(lat, lon)
            LatLng(convertLonLat[0], convertLonLat[1])
        } else {
            LatLng(lat, lon)
        }
        return latLng
    }

    /**
     * 设置宠物头像地图Marker
     */
    private suspend fun setPetHeadMarker(
        lat: Double,
        lon: Double,
        needConvertGCJ02: Boolean = true,
        headBgResId: Int = R.drawable.pic_map_gps_avatar
    ) {
        if (null == mPetHeadIconBitmap) {
            //设置头像
            mPetHeadIconBitmap =
                GoogleBitmapHelper.headToBitmap(mContext!!, headBgResId, mPetHeadUrl, mPetType)
        }
        mMarker?.remove()

        val latLng = getBaiduMapLatLng(lat, lon, needConvertGCJ02)

        mPetLatLng = latLng

        //构建MarkerOption，用于在地图上添加Marker
        val option =
            MarkerOptions().position(latLng).animateType(MarkerOptions.MarkerAnimateType.grow)
                .icon(BitmapDescriptorFactory.fromBitmap(mPetHeadIconBitmap))
        //在地图上添加Marker，并显示
        mMarker = mBaiduMap!!.addOverlay(option)
    }

    /**
     * 地图添加图片
     */
    private fun addImageMarker(
        lat: Double, lon: Double, imageTypeResId: Int, needConvertGCJ02: Boolean = true
    ) {
        mBaiduMap?.apply {
            val latLng = getBaiduMapLatLng(lat, lon, needConvertGCJ02)

            val bitmap = ImageUtil.getBitmapFromDrawableAndSvg(mContext!!, imageTypeResId)
            //构建MarkerOption，用于在地图上添加Marker
            val option =
                MarkerOptions().position(latLng).animateType(MarkerOptions.MarkerAnimateType.grow)
                    .icon(BitmapDescriptorFactory.fromBitmap(bitmap)).apply {
                        anchor(anchorX, anchorY / 2)
                    }
            addOverlay(option)
            bitmap?.recycle()
        }
    }

    /**
     * 当前宠物位置刷新
     * @param needConvertGCJ02 是否需要转换GCJ02坐标
     * @param isAnimMoveCamera 移动使用动画
     */
    fun refreshPetCurrentLocation(
        lat: Double,
        lon: Double,
        needMoveCamera: Boolean = true,
        isAnimMoveCamera: Boolean = false,
        needConvertGCJ02: Boolean = true,
        headBgResId: Int = R.drawable.pic_map_gps_avatar
    ) {
        mBaiduMap?.let {
            lifecycleScope.launch(lifecycleScope.coroutineContext) {

                setPetHeadMarker(lat, lon, needConvertGCJ02, headBgResId)

                //是否需要移动到地图中心点
                if (needMoveCamera) {
                    //animateCamera使用动画
                    moveCameraLocation(lat, lon, isAnimMoveCamera = isAnimMoveCamera)
                }

                //刷新当前位置ok
                onRefreshPetCurrentLocationOk(mBaiduMap!!)
            }
        }
    }

    fun refreshPetCurrentLocation(
        latLng: LatLng,
        needMoveCamera: Boolean = true,
        isAnimMoveCamera: Boolean = false,
        headBgResId: Int = R.drawable.pic_map_gps_avatar
    ) {
        refreshPetCurrentLocation(
            latLng.latitude, latLng.longitude, needMoveCamera, isAnimMoveCamera, false, headBgResId
        )
    }

    /**
     * 设置宠物当前位置经纬度
     */
    fun setPetCurrentLocation(
        petHeadUrl: String, lat: Double, lon: Double, needConvertGCJ02: Boolean = true
    ) {
        lifecycleScope.launch(lifecycleScope.coroutineContext) {
            setPetHeadIconUrl(petHeadUrl)
            setPetHeadMarker(lat, lon, needConvertGCJ02)
        }
    }

    /**
     * 改变地图手势的中心点（地图的中心点）
     * @param needConvertGCJ02 是否需要转换GCJ02坐标
     */
    fun moveCameraLocation(
        lat: Double, lon: Double, needConvertGCJ02: Boolean = true, isAnimMoveCamera: Boolean = false
    ) {
        val latLng = getBaiduMapLatLng(lat, lon, needConvertGCJ02)

        if (isAnimMoveCamera) {
            //animateCamera使用动画,以动画方式更新地图状态，默认动画耗时 300 ms
            mBaiduMap!!.animateMapStatus(MapStatusUpdateFactory.newLatLng(latLng), 2)
        } else {
            mBaiduMap!!.setMapStatus(MapStatusUpdateFactory.newLatLng(latLng))
        }
        //直接缩放至缩放级别
        mBaiduMap!!.setMapStatus(MapStatusUpdateFactory.zoomTo(mBaiduMapZoom))
    }

    /**
     * 改变地图手势的中心点（地图的中心点）
     * @param latLng 已经是转换好的坐标
     */
    fun moveCameraLocation(latLng: LatLng, isAnimMoveCamera: Boolean = false) {
        moveCameraLocation(latLng.latitude, latLng.longitude, false, isAnimMoveCamera)
    }

    /**
     * 显示信息窗（弹窗覆盖物InfoWindow）
     */
    fun showMarkerInfoWindow(historyDataBean: HistoryDataBean) {
        historyDataBean.apply {
            val convertLatLng = getBaiduMapLatLng(latitude, longitude)
            val view = LayoutInflater.from(mContext).inflate(R.layout.marker_info_contents, null)
            val addressTextView = view.findViewById<TypefaceTextView>(R.id.map_pet_current_location)
            val timeTextView =
                view.findViewById<TypefaceTextView>(R.id.map_pet_location_update_time)
            addressTextView.text = address
            timeTextView.text = dayTime
            val mInfoWindow = InfoWindow(
                view, convertLatLng, -(mPetHeadIconBitmap?.width!! + 30)
            )
            mBaiduMap?.showInfoWindow(mInfoWindow)
        }
    }


    //在地图上画圆形、矩形和多边形围栏集合
    private var mMapFencesList: MutableList<Overlay>? = null

//    fun initFenceList() {
//        if (null == mCircleAndRectFenceList) mCircleAndRectFenceList = mutableListOf()
//    }

    /**
     * Adds a [Circle] around the provided
     * 地图上画一个圆形围栏
     * @param isDashedPattern 是否是虚线
     */
    fun addCircleFence(
        centerLat: Double,
        centerLon: Double,
        radius: Double = 700.0,
        strokeColor: Int = ContextCompat.getColor(mContext!!, R.color.select_color2),
        fillColor: Int = ContextCompat.getColor(mContext!!, R.color.select_color4),
        isDashedPattern: Boolean = false
    ) {
        if (null == mBaiduMap) return
        //转换坐标
        val convertLatLng = getBaiduMapLatLng(centerLat, centerLon)
        //构造CircleOptions对象
        val circleOptions = CircleOptions().center(convertLatLng).radius(radius.toInt())
            //是否显示虚线
            .dottedStroke(isDashedPattern)
            .dottedStrokeType(CircleDottedStrokeType.DOTTED_LINE_SQUARE)
            //填充颜色
            .fillColor(fillColor)
            //边框宽和边框颜色
            .stroke(Stroke(AppUtils.dpToPx(1), strokeColor))

        //在地图上显示圆形围栏
        val circleFence = mBaiduMap!!.addOverlay(circleOptions)

        if (null == mMapFencesList) mMapFencesList = mutableListOf()
        mMapFencesList?.add(circleFence)
    }

    /**
     * 地图上画多边形
     * @param isDashedPattern 是否是虚线
     */
    private fun mapDrawPolygon(
        points: MutableList<LatLng>,
        strokeColor: Int = ContextCompat.getColor(mContext!!, R.color.select_color2),
        fillColor: Int = ContextCompat.getColor(mContext!!, R.color.select_color4),
        isDashedPattern: Boolean = false
    ) {
        if (null == mBaiduMap) return

        //构造PolygonOptions
        val polygonOptions = PolygonOptions().points(points)
            //是否显示虚线
            .dottedStroke(isDashedPattern)
            .dottedStrokeType(PolylineDottedLineType.DOTTED_LINE_SQUARE)
            //填充颜色
            .fillColor(fillColor)
            //边框宽和边框颜色
            .stroke(Stroke(AppUtils.dpToPx(1), strokeColor))

        //在地图上显示矩形围栏
        val rectFence = mBaiduMap!!.addOverlay(polygonOptions)

        if (null == mMapFencesList) mMapFencesList = mutableListOf()
        mMapFencesList?.add(rectFence)
    }

    /**
     * 地图上画一个矩形围栏
     * @param isDashedPattern 是否是虚线
     */
    fun addRectFence(
        fencesBean: FencesBean,
        strokeColor: Int = ContextCompat.getColor(mContext!!, R.color.select_color2),
        fillColor: Int = ContextCompat.getColor(mContext!!, R.color.select_color4),
        isDashedPattern: Boolean = false
    ) {
        fencesBean.apply {
            val points = mutableListOf<LatLng>()
            setRectFencePointData(points, latitudeA, longitudeA)
            setRectFencePointData(points, latitudeB, longitudeB)
            setRectFencePointData(points, latitudeC, longitudeC)
            setRectFencePointData(points, latitudeD, longitudeD)

            mapDrawPolygon(points, strokeColor, fillColor, isDashedPattern)
        }
    }

    /**
     * 地图上画一个多边形围栏
     */
    fun addPolygonFence(
        fencesBean: FencesBean,
        strokeColor: Int = ContextCompat.getColor(mContext!!, R.color.select_color2),
        fillColor: Int = ContextCompat.getColor(mContext!!, R.color.select_color4),
        isDashedPattern: Boolean = false
    ) {
        fencesBean.apply {
            val points = mutableListOf<LatLng>()
            setRectFencePointData(points, latitudeA, longitudeA)
            setRectFencePointData(points, latitudeB, longitudeB)
            setRectFencePointData(points, latitudeC, longitudeC)
            setRectFencePointData(points, latitudeD, longitudeD)
            setRectFencePointData(points, latitudeE, longitudeE)
            setRectFencePointData(points, latitudeF, longitudeF)
            mapDrawPolygon(points, strokeColor, fillColor, isDashedPattern)
        }
    }

    /**
     *
     * 地图上画一个圆形虚线围栏
     */
    fun addCircleDashedAndImageFence(
        centerLat: Double,
        centerLon: Double,
        radius: Double = 700.0,
        imageTypeResId: Int = 0,
        strokeColor: Int = ContextCompat.getColor(mContext!!, R.color.select_color),
        fillColor: Int = ContextCompat.getColor(mContext!!, R.color.select_color4)
    ) {
        if (imageTypeResId > 0) addImageMarker(centerLat, centerLon, imageTypeResId)
        addCircleFence(centerLat, centerLon, radius, strokeColor, fillColor, true)
    }

    /**
     *
     * 地图上画一个矩形虚线有中心图片围栏
     */
    fun addRectDashedAndImageFence(
        fencesBean: FencesBean, imageTypeResId: Int = 0,
        strokeColor: Int = ContextCompat.getColor(mContext!!, R.color.select_color2),
        fillColor: Int = ContextCompat.getColor(mContext!!, R.color.select_color4),
    ) {
        if (imageTypeResId > 0) addImageMarker(
            fencesBean.latitudeCenter, fencesBean.longitudeCenter, imageTypeResId
        )
        addRectFence(fencesBean, strokeColor, fillColor, true)
    }

    fun addRectDashedAndImageEditFence(
        fencesBean: FencesBean, imageTypeResId: Int = 0,
        strokeColor: Int = ContextCompat.getColor(mContext!!, R.color.select_color2),
        fillColor: Int = ContextCompat.getColor(mContext!!, R.color.select_color4),
    ) {
        fencesBean.apply {
            addRectDashedAndImageFence(this, imageTypeResId, strokeColor, fillColor)
            addImageMarker(latitudeA, longitudeA, R.drawable.icon_fence_dot_svg)
            addImageMarker(latitudeB, longitudeB, R.drawable.icon_fence_dot_svg)
            addImageMarker(latitudeC, longitudeC, R.drawable.icon_fence_dot_svg)
            addImageMarker(latitudeD, longitudeD, R.drawable.icon_fence_dot_svg)
        }
    }

    /**
     *
     * 地图上画一个多边形虚线有中心图片围栏
     */
    fun addPolygonDashedAndImageFence(
        fencesBean: FencesBean, imageTypeResId: Int = 0,
        strokeColor: Int = ContextCompat.getColor(mContext!!, R.color.select_color2),
        fillColor: Int = ContextCompat.getColor(mContext!!, R.color.select_color4),
    ) {
        if (imageTypeResId > 0) addImageMarker(
            fencesBean.latitudeCenter, fencesBean.longitudeCenter, imageTypeResId
        )
        addPolygonFence(fencesBean, strokeColor, fillColor, true)
    }

    /**
     *
     * 地图上画一个正在预览的矩形虚线围栏
     */
    fun addPolygonDashedAndImageEditFence(
        fencesBean: FencesBean, imageTypeResId: Int = 0,
        strokeColor: Int = ContextCompat.getColor(mContext!!, R.color.select_color2),
        fillColor: Int = ContextCompat.getColor(mContext!!, R.color.select_color4),
    ) {
        fencesBean.apply {
            addPolygonDashedAndImageFence(this, imageTypeResId, strokeColor, fillColor)
            addImageMarker(latitudeA, longitudeA, R.drawable.icon_fence_polygon_operate_svg)
            addImageMarker(latitudeB, longitudeB, R.drawable.icon_fence_polygon_operate_svg)
            addImageMarker(latitudeC, longitudeC, R.drawable.icon_fence_polygon_operate_svg)
            addImageMarker(latitudeD, longitudeD, R.drawable.icon_fence_polygon_operate_svg)
            addImageMarker(latitudeE, longitudeE, R.drawable.icon_fence_polygon_operate_svg)
            addImageMarker(latitudeF, longitudeF, R.drawable.icon_fence_polygon_operate_svg)
        }
    }

    /**
     * 设置矩形围栏点的数据
     */
    private fun setRectFencePointData(points: MutableList<LatLng>, lat: Double, lon: Double) {
        //转换坐标
        val convertLonLat = getBaiduMapLatLng(lat, lon)
        points.add(convertLonLat)
    }

    /**
     * 清除地图有多个围栏圈
     */
    fun clearFenceList() {
//        if (null == mCircleAndRectFenceList) throw NullPointerException(
//            "mCircleAndRectFenceList空指针,请在onMapLoadOk重写方法中实例化mCircleAndRectFenceList,执行方法initFenceList()"
//        )
        mMapFencesList?.forEach {
            it.remove()
        }
        mMapFencesList?.clear()
    }

    private var mBlackPolyline: Overlay? = null
    private var mYellowPolyline: Overlay? = null

    /**
     * 画线，传入已经转换好的经纬度坐标
     * @param needBlackPolyline 是否需要黑线
     */
    fun addPolyline(
        baiduMap: BaiduMap,
        latLngList: MutableList<LatLng>,
        needBlackPolyline: Boolean = true,
        startCapImageRes: Int = 0
    ) {
        //至少需要2个点
        if (latLngList.size < 2) {
            return
        }

        if (needBlackPolyline) {
            val blackOverlayOptions = PolylineOptions().width(QMUIDisplayHelper.dpToPx(4))
                .color(ContextCompat.getColor(mContext!!, R.color.txt_button)).points(latLngList)
            mBlackPolyline?.remove()
            //在地图上绘制折线
            mBlackPolyline = baiduMap.addOverlay(blackOverlayOptions)
        }

        //设置折线的属性
        val yellowOverlayOptions = PolylineOptions().width(QMUIDisplayHelper.dpToPx(3))
            .color(ContextCompat.getColor(mContext!!, R.color.select_color2)).points(latLngList)
        mYellowPolyline?.remove()
        mYellowPolyline = baiduMap.addOverlay(yellowOverlayOptions)
        //添加起始点图片
        if (startCapImageRes > 0) {
            //构建MarkerOption，用于在地图上添加Marker
            val option = MarkerOptions().position(latLngList[0])
                .animateType(MarkerOptions.MarkerAnimateType.grow)
                .icon(BitmapDescriptorFactory.fromResource(startCapImageRes))
            //在地图上添加Marker，并显示
            baiduMap.addOverlay(option)
        }
    }

    /**
     * 清空所有图层
     */
    open fun clearAllMarker() {
        mBaiduMap?.clear()
        clearFenceList()
    }

    /**
     * 开始定位,请求用户当前的位置
     */
    fun startLocation(locationPeriod: Int = 1, needStopLocation: Boolean = true) {
        initSensorEvent(mContext!!)
        //定位初始化
        mLocationClient = LocationClient(mContext)
        //通过LocationClientOption设置LocationClient相关参数
        val option = LocationClientOption()
        // 打开gps
        option.openGps = true
        // 设置坐标类型
        option.setCoorType(mCoordType)
        //设置定位刷新间隔
        option.setScanSpan(locationPeriod * 1000)
        //设置locationClientOption
        mLocationClient!!.locOption = option
        //注册LocationListener监听器
        mLocationListener = object : BDAbstractLocationListener() {
            override fun onReceiveLocation(location: BDLocation?) {
                //mapView 销毁后不在处理新接收的位置
                if (null == location) {
                    return
                }
                val locData = MyLocationData.Builder().accuracy(location.radius)
                    // 此处设置开发者获取到的方向信息，顺时针0-360
                    .direction(location.direction).latitude(location.latitude)
                    .longitude(location.longitude).build()
                mBaiduMap!!.setMyLocationData(locData)
                if (needStopLocation) stopLocation()
                location.city
                mUserLatLng = LatLng(location.latitude, location.longitude)
                locationSuccess(location)
            }
        }
        mLocationClient!!.registerLocationListener(mLocationListener)
        //开启定位
        mLocationClient!!.start()
    }

    /**
     * 设置方向感应器,百度地图使用
     */
    private fun initSensorEvent(context: Context) {
        // 获得传感器管理器
        mSensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
        if (mSensorManager != null) {
            //获得方向传感器
            mSensor = mSensorManager?.getDefaultSensor(Sensor.TYPE_ORIENTATION)
        }
        // 注册
        if (mSensor != null) {
            mSensorEventListener = object : SensorEventListener {
                override fun onSensorChanged(event: SensorEvent?) {
                    // 接受方向感应器的类型
                    if (event?.sensor?.type == Sensor.TYPE_ORIENTATION) {
                        val x = event.values[SensorManager.DATA_X]
                        if (abs(x - mLastX) > 1.0) {
                            mLastX = x
                            mBaiduMap?.apply {
                                setLocationData(locationData, x)
                            }
                        }
                    }
                }

                override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
                }
            }
            mSensorManager?.registerListener(
                mSensorEventListener, mSensor, SensorManager.SENSOR_DELAY_UI
            )
        }
    }

    /**
     * 设置定位的方向信息
     */
    private fun setLocationData(locData: MyLocationData?, direction: Float) {
        if (null == locData || null == mBaiduMap) return
        val myLocData = MyLocationData.Builder().accuracy(locData.accuracy)
            // 此处设置开发者获取到的方向信息，顺时针0-360
            .direction(direction).latitude(locData.latitude).longitude(locData.longitude).build()
        mBaiduMap!!.setMyLocationData(myLocData)
    }

    /**
     * 停止定位
     */
    private fun stopLocation() {
        mLocationClient?.apply {
            unRegisterLocationListener(mLocationListener)
            stop()
        }
    }

    /**
     * 根据轨迹获取地图缩放比例
     */
    fun getDistanceZoom(max: LatLng, min: LatLng): Float {
        var jl = DistanceUtil.getDistance(max, min)
        if (jl < 1) {
            jl = 50.0
        }
        LogUtil.e("最大和最小间经纬度直线距离 = $jl")
//        var i = 0
//        while (i < scale.size - 2) {
//            if (scale[i] < jl && scale[i + 1] >= jl) {
//                break
//            }
//            i++
//        }
        return getDistanceZoom(jl)
    }

    /**
     * 根据显示距离获取缩放地图等级
     */
    fun getDistanceZoom(distance: Double): Float {
        val scaleOld = intArrayOf(
            1,
            20,
            50,
            100,
            200,
            500,
            1000,
            2000,
            5000,
            10000,
            20000,
            25000,
            50000,
            100000,
            200000,
            500000,
            1000000,
            2000000,
            5000000
        )
        val scaleNew = intArrayOf(
            5,
            10,
            20,
            50,
            100,
            200,
            500,
            1000,
            2000,
            5000,
            10000,
            20000,
            25000,
            50000,
            100000,
            200000,
            500000,
            1000000
        )
        val scale = scaleNew
        var jl = distance
        if (jl < 5) {
            jl = 50.0
        }
        var i = 0
        while (i < scale.size - 2) {
            if (scale[i] < jl && scale[i + 1] >= jl) {
                break
            }
            i++
        }
        LogUtil.e("根据显示距离获取缩放地图等级 = $jl,zoom=${21f - i}")
        return 21f - i
    }

    /**
     * 定位成功返回
     */
    open fun locationSuccess(location: BDLocation?) {}

    /**
     * 地图加载完毕
     */
    abstract fun onMapLoadOk(baiduMap: BaiduMap)

    /**
     * 宠物位置刷新完成
     */
    open fun onRefreshPetCurrentLocationOk(baiduMap: BaiduMap) {}

    override fun onDestroy() {
        super.onDestroy()
        mSensorManager?.unregisterListener(mSensorEventListener)
        mPetHeadIconBitmap?.recycle()
        stopLocation()
        //在activity执行onDestroy时执行mMapView.onDestroy()，实现地图生命周期管理
        mMapView.onDestroy()
    }
}
