package com.shoyoo.react.anavi import android.content.Context import android.content.res.Resources import android.graphics.Bitmap import android.graphics.BitmapFactory import android.util.Base64 import com.amap.api.maps.model.LatLng import com.amap.api.maps.model.LatLngBounds import com.amap.api.navi.enums.TravelStrategy import com.amap.api.navi.model.AMapNaviLocation import com.amap.api.navi.model.NaviLatLng import com.amap.api.navi.model.NaviPoi import com.amap.api.services.core.LatLonPoint import com.amap.api.services.route.RidePath import com.amap.api.services.route.RideStep import com.amap.api.services.route.WalkPath import com.amap.api.services.route.WalkStep import com.facebook.react.bridge.Arguments import com.facebook.react.bridge.ReadableArray import com.facebook.react.bridge.ReadableMap import com.facebook.react.bridge.WritableMap import java.lang.Exception import java.lang.IllegalArgumentException import java.net.URL import kotlin.collections.ArrayList import kotlin.math.* fun Float.toPx(): Int { return (this * Resources.getSystem().displayMetrics.density).toInt() } fun ReadableMap.toLatLng(): LatLng { return LatLng(getDouble("latitude"), getDouble("longitude")) } fun ReadableMap.toNaviLatLng(): NaviLatLng { return NaviLatLng(getDouble("latitude"), getDouble("longitude")) } fun ReadableMap.toLatLngPoint(): LatLonPoint { return LatLonPoint(getDouble("latitude"), getDouble("longitude")) } fun ReadableArray.toLatLngList(): ArrayList { return ArrayList((0 until size()).map { getMap(it)!!.toLatLng() }) } fun ReadableArray.toLatLngPointList(): List { return ArrayList((0 until size()).map { getMap(it)!!.toLatLngPoint() }) } fun LatLng.toWritableMap(): WritableMap { val map = Arguments.createMap() map.putDouble("latitude", latitude) map.putDouble("longitude", longitude) return map } fun NaviLatLng.toWritableMap(): WritableMap { val map = Arguments.createMap() map.putDouble("latitude", latitude) map.putDouble("longitude", longitude) return map } fun LatLngBounds.toWritableMap(): WritableMap { val map = Arguments.createMap() map.putDouble("latitude", abs((southwest.latitude + northeast.latitude) / 2)) map.putDouble("longitude", abs((southwest.longitude + northeast.longitude) / 2)) map.putDouble("latitudeDelta", abs(southwest.latitude - northeast.latitude)) map.putDouble("longitudeDelta", abs(southwest.longitude - northeast.longitude)) return map } fun ReadableMap.toLatLngBounds(): LatLngBounds { val latitude = getDouble("latitude") val longitude = getDouble("longitude") val latitudeDelta = getDouble("latitudeDelta") val longitudeDelta = getDouble("longitudeDelta") return LatLngBounds( LatLng(latitude - latitudeDelta / 2, longitude - longitudeDelta / 2), LatLng(latitude + latitudeDelta / 2, longitude + longitudeDelta / 2) ) } fun LatLonPoint.toLatLog() = LatLng(latitude, longitude) fun LatLng.toLatLogPoint() = LatLonPoint(latitude, longitude) fun calculateDistance(start: LatLng, end: LatLng): Int { val x1 = start.longitude val y1 = start.latitude val x2 = end.longitude val y2 = end.latitude return calculateDistance(x1, y1, x2, y2) } fun calculateDistance(x1: Double, x2: Double, y1: Double, y2: Double): Int { val nfPi = 0.01745329251994329 // 弧度 PI/180 val sx1 = sin(x1 * nfPi) val sy1 = sin(y1 * nfPi) val cx1 = cos(x1 * nfPi) val cy1 = cos(y1 * nfPi) val sx2 = sin(x2 * nfPi) val sy2 = sin(y2 * nfPi) val cx2 = cos(x2 * nfPi) val cy2 = cos(y2 * nfPi) val v1 = DoubleArray(3) v1[0] = cy1 * cx1 - cy2 * cx2 v1[1] = cy1 * sx1 - cy2 * sx2 v1[2] = sy1 - sy2 val dist = sqrt(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]) return (asin(dist / 2) * 12742001.5798544).toInt() } fun String.toBitmap(): Bitmap? { try { val data = Base64.decode(this, Base64.DEFAULT) return BitmapFactory.decodeByteArray(data, 0, data.size) } catch (e: Exception) { e.printStackTrace() } return null } fun AMapNaviLocation.toWritableMap(): WritableMap { return Arguments.createMap().apply { putDouble("accuracy", accuracy.toDouble()) putDouble("altitude", altitude) putDouble("bearing", bearing.toDouble()) putMap("coord", coord.toWritableMap()) putInt("curLinkIndex", curLinkIndex) putInt("curPointIndex", curPointIndex) putInt("curStepIndex", curStepIndex) putInt("locationType", locationType) putBoolean("isMatchNaviPath", isMatchNaviPath) putDouble("speed", speed.toDouble()) putInt("time", time.toInt()) } } fun ReadableMap.toNaviPoi(): NaviPoi { if (!hasKey("name") || !hasKey("coordinate") || !hasKey("poiId")) { throw IllegalArgumentException("NaviPoi must be has arguments 'name', 'coordinate' and 'poiId'") } val name = getString("name") val coord = getMap("coordinate")!! val latLng = LatLng(coord.getDouble("latitude"), coord.getDouble("longitude"), coord.getBoolean("isCheck")) val poiId = getString("poiId") val direction = if (hasKey("direction")) getDouble("direction").toFloat() else null return NaviPoi(name, latLng, poiId).apply { if (direction != null) this.direction = direction } } fun Int.toTravelStrategy(): TravelStrategy { return when (this) { 1000 -> TravelStrategy.SINGLE 1001 -> TravelStrategy.MULTIPLE else -> TravelStrategy.SINGLE } } fun ReadableMap.toBitmap(context: Context): Bitmap? { if (!this.hasKey("uri")) { return null } val uri = this.getString("uri")!! if (uri.startsWith("data:") && uri.contains("base64") && (uri.contains("img") || uri.contains("image"))) { return uri.split("base64,")[1].toBitmap() } if (uri.startsWith("http://") || uri.startsWith("https://") || uri.startsWith("file://")) { val url = URL(uri) return BitmapFactory.decodeStream(url.openStream()) } val resId = context.resources.getIdentifier(uri, "drawable", context.packageName) return BitmapFactory.decodeResource(context.resources, resId) } fun RidePath.toMap(): WritableMap { return Arguments.createMap().apply { putArray("steps", Arguments.createArray().apply { this@toMap.steps.forEach { pushMap(it.toMap()) } }) } } fun RideStep.toMap(): WritableMap { return Arguments.createMap().apply { putString("action", action) putString("assistantAction", assistantAction) putDouble("distance", distance.toDouble()) putDouble("duration", duration.toDouble()) putString("instruction", instruction) putString("orientation", orientation) putArray("polyline", Arguments.createArray().apply { polyline.forEach { pushMap(it.toLatLog().toWritableMap()) } }) putString("road", road) } } fun WalkPath.toMap(): WritableMap { return Arguments.createMap().apply { putArray("steps", Arguments.createArray().apply { this@toMap.steps.forEach { pushMap(it.toMap()) } }) } } fun WalkStep.toMap(): WritableMap { return Arguments.createMap().apply { putString("action", action) putString("assistantAction", assistantAction) putDouble("distance", distance.toDouble()) putDouble("duration", duration.toDouble()) putString("instruction", instruction) putString("orientation", orientation) putArray("polyline", Arguments.createArray().apply { polyline.forEach { pushMap(it.toLatLog().toWritableMap()) } }) putString("road", road) } }