RouteOverlay.kt 8.75 KB
package cn.feewee.amap3d.map_view.route

import android.annotation.SuppressLint
import android.app.AlertDialog
import android.content.Context
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.widget.TextView
import cn.feewee.amap3d.*
import cn.feewee.amap3d.map_view.Overlay
import com.amap.api.maps.AMap
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.model.*
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.route.*
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.views.view.ReactViewGroup

abstract class RouteOverlay(context: Context) : ReactViewGroup(context), Overlay {
    lateinit var map: AMap
    private var stationMarkers: MutableList<Marker> = ArrayList()
    private var allPolyLines: MutableList<Polyline> = ArrayList()
    private var startPoint: LatLng? = null
    private var endPoint: LatLng? = null
    private var startMarker: Marker? = null
    private var endMarker: Marker? = null
    private var roadColor: Int = Color.parseColor("#537edc")
    private var progDialog: AlertDialog? = null

    protected var mRouteSearch: RouteSearch? = null

    abstract fun searchRouteResult()

    /**
     * 路段节点图标控制显示接口。
     * @param visible true为显示节点图标,false为不显示。
     * @since V2.3.1
     */
    protected var nodeIconVisible = true
    fun setNodeIconVisibility(visible: Boolean) {
        try {
            nodeIconVisible = visible
            if (stationMarkers.size > 0) {
                for (i in stationMarkers.indices) {
                    stationMarkers[i].isVisible = visible
                }
            }
        } catch (e: Throwable) {
            e.printStackTrace()
        }
    }


    fun setStartPoint(start: LatLonPoint?) {
        start?.let {
            startPoint = start.convertToLatLng()
        }
    }

    fun getStartPoint(): LatLng? {
        return startPoint
    }

    fun setEndPoint(end: LatLonPoint?) {
        end?.let {
            endPoint = end.convertToLatLng()
        }
    }

    fun getEndPoint(): LatLng? {
        return endPoint
    }

    /**
     * 起点Marker图标。
     */
    private var startBit: BitmapDescriptor? = null

    fun setStartBit(source: ReadableMap) {
        fetchImage(source) {
            startBit = it
        }
    }

    fun getStartBit(): BitmapDescriptor {
        return startBit ?: BitmapDescriptorFactory.fromResource(R.drawable.cqfw_amap_start)
    }

    /**
     * 终点Marker图标。
     */
    private var endBit: BitmapDescriptor? = null

    fun setEndBit(source: ReadableMap) {
        fetchImage(source) {
            endBit = it
        }
    }

    fun getEndBit(): BitmapDescriptor {
        return endBit ?: BitmapDescriptorFactory.fromResource(R.drawable.cqfw_amap_end)
    }

    /**
     * 途经点图标
     */
    private var throughBit: BitmapDescriptor? = null

    fun setThroughBit(source: ReadableMap) {
        fetchImage(source) {
            throughBit = it
        }
    }

    fun getThroughBit(): BitmapDescriptor {
        return throughBit ?: BitmapDescriptorFactory.fromResource(R.drawable.cqfw_amap_through)
    }

    /**
     * 驾车Marker图标
     */
    private var driveBit: BitmapDescriptor? = null

    fun setDriveBit(source: ReadableMap) {
        fetchImage(source) {
            driveBit = it
        }
    }

    fun getDriveBit(): BitmapDescriptor {
        return driveBit ?: BitmapDescriptorFactory.fromResource(R.drawable.cqfw_amap_car)
    }

    /**
     * 骑行Marker图标
     */
    private var rideBit: BitmapDescriptor? = null

    fun setRideBit(source: ReadableMap) {
        fetchImage(source) {
            rideBit = it
        }
    }

    fun getRideBit(): BitmapDescriptor {
        return rideBit ?: BitmapDescriptorFactory.fromResource(R.drawable.cqfw_amap_ride)
    }

    /**
     * 公交Marker图标
     */
    private var busBit: BitmapDescriptor? = null

    fun setBusBit(source: ReadableMap) {
        fetchImage(source) {
            busBit = it
        }
    }

    fun getBusBit(): BitmapDescriptor {
        return busBit ?: BitmapDescriptorFactory.fromResource(R.drawable.cqfw_amap_bus)
    }

    /**
     * 步行Marker图标
     */
    private var walkBit: BitmapDescriptor? = null

    fun setWalkBit(source: ReadableMap) {
        fetchImage(source) {
            walkBit = it
        }
    }

    fun getWalkBit(): BitmapDescriptor {
        return walkBit ?: BitmapDescriptorFactory.fromResource(R.drawable.cqfw_amap_man)
    }

    private var roadLine: BitmapDescriptor? = null

    fun setRoadLine(source: ReadableMap) {
        fetchImage(source) {
            roadLine = it
        }
    }

    fun getRoadLine(): BitmapDescriptor {
        return roadLine ?: BitmapDescriptorFactory.fromResource(R.drawable.cqfw_custtexture)
    }

    private var routeWidth: Float = 18F

    /**
     * 自定义路线宽度
     * @param width
     */

    fun setRouteWidth(width: Float?) {
        width?.let {
            routeWidth = width
        }
    }

    fun getRouteWidth(): Float {
        return routeWidth
    }

    /**
     * 自定义路线颜色
     *
     * @param color
     */
    fun setRoadColor(color: Int) {
        roadColor = color
    }

    fun getRoadColor(): Int {
        return roadColor
    }

    protected fun addStartAndEndMarker() {
        removeMarkerFromMap()
        startMarker = map.addMarker(
            MarkerOptions()
                .position(startPoint)
                .icon(getStartBit())
                .title("\u8D77\u70B9")
        )
        endMarker = map.addMarker(
            MarkerOptions()
                .position(endPoint)
                .icon(getEndBit())
                .title("\u7EC8\u70B9")
        )
    }

    protected fun addStationMarker(options: MarkerOptions?) {
        if (options == null) {
            return
        }
        val marker = map.addMarker(options)
        if (marker != null) {
            stationMarkers.add(marker)
        }
    }

    protected fun addPolyLine(options: PolylineOptions?) {
        if (options == null) {
            return
        }
        val polyline = map.addPolyline(options)
        if (polyline != null) {
            allPolyLines.add(polyline)
        }
    }

    /**
     * 移动镜头到当前的视角。
     * @since V2.1.0
     */
    protected fun zoomToSpan() {
        if (startPoint != null) {
            try {
                val bounds = getLatLngBounds()
                val newLatLngBounds = CameraUpdateFactory
                    .newLatLngBounds(bounds, 100)

                map.animateCamera(newLatLngBounds)
            } catch (e: Throwable) {
                e.printStackTrace()
            }
        }
    }

    protected open fun getLatLngBounds(): LatLngBounds {
        return LatLngBounds.builder()
            .include(LatLng(startPoint!!.latitude, startPoint!!.longitude))
            .include(LatLng(endPoint!!.latitude, endPoint!!.longitude))
            .build()
    }

    /**
     * 移除所有的Marker。
     */
    protected fun removeMarkerFromMap() {
        startMarker?.destroy()
        endMarker?.destroy()

    }

    /**
     * 移除所有的路线。
     */
    protected fun removeLineFromMap() {
        for (marker in stationMarkers) {
            marker.destroy()
        }
        for (line in allPolyLines) {
            line.remove()
        }
    }

    /**
     * 开始搜索路径规划方案
     */
    protected fun createFromAndTo(): RouteSearch.FromAndTo? {
        if (startPoint == null) {
            show(context, "起点未设置")
            return null
        }
        if (endPoint == null) {
            show(context, "终点未设置")
            return null
        }
        return RouteSearch.FromAndTo(
            startPoint!!.convertToLatLonPoint(),
            endPoint!!.convertToLatLonPoint()
        )
    }

    /**
     * 隐藏进度框
     */
    protected fun dissmissProgressDialog() {
        progDialog?.dismiss()
    }

    /**
     * 显示进度框
     */
    protected fun showProgressDialog() {
        if (progDialog == null) {
            progDialog = progressBarCircleDialog()
        }
        progDialog?.setCanceledOnTouchOutside(false);
        progDialog?.setCancelable(false);
        progDialog?.show();
    }


    private fun progressBarCircleDialog(): AlertDialog {
        val builder = AlertDialog.Builder(
            context,
            AlertDialog.THEME_HOLO_LIGHT
        )
        val inflater = LayoutInflater.from(context.applicationContext);
        @SuppressLint("InflateParams")
        val view: View = inflater.inflate(R.layout.dialog_progressbar_circle, null);
        val tv: TextView = view.findViewById(R.id.tv);
        tv.text = "正在搜索...";
        builder.setView(view);
        return builder.create();
    }
}