mirror of
https://github.com/YTVanced/VancedMicroG
synced 2024-11-24 12:15:12 +00:00
Various improvements and fixes for MapBox maps implementation
This commit is contained in:
parent
3c5e68404b
commit
fc3e24c0ea
17 changed files with 350 additions and 149 deletions
|
@ -65,9 +65,9 @@ public class CreatorImpl extends ICreator.Stub {
|
|||
|
||||
@Override
|
||||
public void initV2(IObjectWrapper resources, int flags) {
|
||||
BitmapDescriptorFactoryImpl.INSTANCE.initialize(ObjectWrapper.unwrapTyped(resources, Resources.class));
|
||||
BitmapDescriptorFactoryImpl.INSTANCE.initialize(ObjectWrapper.unwrapTyped(resources, Resources.class), null);
|
||||
//ResourcesContainer.set((Resources) ObjectWrapper.unwrap(resources));
|
||||
Log.d(TAG, "initV2");
|
||||
Log.d(TAG, "initV2 " + flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.microg.gms.maps.mapbox
|
||||
|
||||
import android.util.Log
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdate
|
||||
import com.mapbox.mapboxsdk.geometry.LatLngBounds
|
||||
|
@ -28,12 +29,13 @@ internal class CameraBoundsWithSizeUpdate(val bounds: LatLngBounds, val width: I
|
|||
|
||||
override fun getCameraPosition(map: MapboxMap): CameraPosition? {
|
||||
val padding = this.padding.clone()
|
||||
val widthPad = (map.padding[0] + map.padding[2])/2
|
||||
val heightPad = (map.padding[1] + map.padding[3])/2
|
||||
val widthPad = ((map.width + map.padding[0] + map.padding[2] - width) / 2).toInt()
|
||||
val heightPad = ((map.height + map.padding[1] + map.padding[3] - height) / 2).toInt()
|
||||
padding[0] += widthPad
|
||||
padding[1] += heightPad
|
||||
padding[2] += widthPad
|
||||
padding[3] += heightPad
|
||||
Log.d(TAG, "map ${map.width} ${map.height}, set $width $height -> ${padding.map { it.toString() }.reduce { a, b -> "$a,$b"}}")
|
||||
return map.getCameraForLatLngBounds(bounds, padding)
|
||||
}
|
||||
|
||||
|
@ -78,6 +80,6 @@ internal class CameraBoundsWithSizeUpdate(val bounds: LatLngBounds, val width: I
|
|||
}
|
||||
|
||||
companion object {
|
||||
val TAG = "GmsCameraBounds"
|
||||
const val TAG = "GmsMapCameraBounds"
|
||||
}
|
||||
}
|
|
@ -61,11 +61,8 @@ class CameraUpdateFactoryImpl : ICameraUpdateFactoryDelegate.Stub() {
|
|||
return ObjectWrapper.wrap(NoCameraUpdate())
|
||||
}
|
||||
|
||||
override fun newLatLngBoundsWithSize(bounds: LatLngBounds, width: Int, height: Int, padding: Int): IObjectWrapper {
|
||||
Log.d(TAG, "unimplemented Method: newLatLngBoundsWithSize")
|
||||
|
||||
return ObjectWrapper.wrap(CameraBoundsWithSizeUpdate(bounds.toMapbox(), width, height, padding))
|
||||
}
|
||||
override fun newLatLngBoundsWithSize(bounds: LatLngBounds, width: Int, height: Int, padding: Int): IObjectWrapper =
|
||||
ObjectWrapper.wrap(CameraBoundsWithSizeUpdate(bounds.toMapbox(), width, height, padding))
|
||||
|
||||
override fun onTransact(code: Int, data: Parcel?, reply: Parcel?, flags: Int): Boolean =
|
||||
if (super.onTransact(code, data, reply, flags)) {
|
||||
|
|
|
@ -20,6 +20,7 @@ import android.annotation.SuppressLint
|
|||
import android.content.Context
|
||||
import android.location.Location
|
||||
import android.os.Bundle
|
||||
import android.os.IBinder
|
||||
import android.os.Parcel
|
||||
import android.support.annotation.IdRes
|
||||
import android.support.annotation.Keep
|
||||
|
@ -66,12 +67,14 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
|
|||
val dpiFactor: Float
|
||||
get() = context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT
|
||||
|
||||
private var mapView: MapView?
|
||||
private var mapView: MapView? = null
|
||||
private var created = false
|
||||
private var initialized = false
|
||||
private val initializedCallbackList = mutableListOf<IOnMapReadyCallback>()
|
||||
private var loaded = false
|
||||
private val mapLock = Object()
|
||||
|
||||
private val initializedCallbackList = mutableListOf<IOnMapReadyCallback>()
|
||||
private var loadedCallback : IOnMapLoadedCallback? = null
|
||||
private var cameraChangeListener: IOnCameraChangeListener? = null
|
||||
private var cameraMoveListener: IOnCameraMoveListener? = null
|
||||
private var cameraMoveCanceledListener: IOnCameraMoveCanceledListener? = null
|
||||
|
@ -83,7 +86,12 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
|
|||
private var markerDragListener: IOnMarkerDragListener? = null
|
||||
|
||||
var lineManager: LineManager? = null
|
||||
val pendingLines = mutableSetOf<PolylineImpl>()
|
||||
var lineId = 0L
|
||||
|
||||
var fillManager: FillManager? = null
|
||||
val pendingFills = mutableSetOf<PolygonImpl>()
|
||||
var fillId = 0L
|
||||
|
||||
var circleManager: CircleManager? = null
|
||||
val pendingCircles = mutableSetOf<CircleImpl>()
|
||||
|
@ -99,6 +107,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
|
|||
|
||||
init {
|
||||
val mapContext = MapContext(context)
|
||||
BitmapDescriptorFactoryImpl.initialize(mapContext.resources, context.resources)
|
||||
LibraryLoader.setLibraryLoader(MultiArchLoader(mapContext, context))
|
||||
Mapbox.getInstance(mapContext, BuildConfig.MAPBOX_KEY)
|
||||
|
||||
|
@ -137,8 +146,6 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
|
|||
return null
|
||||
}
|
||||
}
|
||||
this.mapView = MapView(mapContext)
|
||||
this.view.addView(this.mapView)
|
||||
}
|
||||
|
||||
override fun getCameraPosition(): CameraPosition? = map?.cameraPosition?.toGms()
|
||||
|
@ -147,43 +154,57 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
|
|||
|
||||
override fun moveCamera(cameraUpdate: IObjectWrapper?) {
|
||||
val update = cameraUpdate.unwrap<CameraUpdate>() ?: return
|
||||
val map = this.map
|
||||
if (map != null) {
|
||||
map.moveCamera(update)
|
||||
synchronized(mapLock) {
|
||||
if (initialized) {
|
||||
this.map?.moveCamera(update)
|
||||
} else {
|
||||
waitingCameraUpdates.add(update)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun animateCamera(cameraUpdate: IObjectWrapper?) {
|
||||
val update = cameraUpdate.unwrap<CameraUpdate>() ?: return
|
||||
val map = this.map
|
||||
if (map != null) {
|
||||
map.animateCamera(update)
|
||||
synchronized(mapLock) {
|
||||
if (initialized) {
|
||||
this.map?.animateCamera(update)
|
||||
} else {
|
||||
waitingCameraUpdates.add(update)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun afterInitialized(runnable: () -> Unit) {
|
||||
initializedCallbackList.add(object : IOnMapReadyCallback {
|
||||
override fun onMapReady(map: IGoogleMapDelegate?) {
|
||||
runnable()
|
||||
}
|
||||
|
||||
override fun asBinder(): IBinder? = null
|
||||
})
|
||||
}
|
||||
|
||||
override fun animateCameraWithCallback(cameraUpdate: IObjectWrapper?, callback: ICancelableCallback?) {
|
||||
val update = cameraUpdate.unwrap<CameraUpdate>() ?: return
|
||||
val map = this.map
|
||||
if (map != null) {
|
||||
map.animateCamera(update, callback?.toMapbox())
|
||||
synchronized(mapLock) {
|
||||
if (initialized) {
|
||||
this.map?.animateCamera(update, callback?.toMapbox())
|
||||
} else {
|
||||
waitingCameraUpdates.add(update)
|
||||
callback?.onFinish()
|
||||
afterInitialized { callback?.onFinish() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun animateCameraWithDurationAndCallback(cameraUpdate: IObjectWrapper?, duration: Int, callback: ICancelableCallback?) {
|
||||
val update = cameraUpdate.unwrap<CameraUpdate>() ?: return
|
||||
val map = this.map
|
||||
if (map != null) {
|
||||
map.animateCamera(update, duration, callback?.toMapbox())
|
||||
synchronized(mapLock) {
|
||||
if (initialized) {
|
||||
this.map?.animateCamera(update, duration, callback?.toMapbox())
|
||||
} else {
|
||||
waitingCameraUpdates.add(update)
|
||||
callback?.onFinish()
|
||||
afterInitialized { callback?.onFinish() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,21 +228,30 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
|
|||
}
|
||||
|
||||
override fun addPolyline(options: PolylineOptions): IPolylineDelegate? {
|
||||
val lineOptions = LineOptions()
|
||||
.withLatLngs(options.points.map { it.toMapbox() })
|
||||
.withLineWidth(options.width / dpiFactor)
|
||||
.withLineColor(ColorUtils.colorToRgbaString(options.color))
|
||||
.withLineOpacity(if (options.isVisible) 1f else 0f)
|
||||
return lineManager?.let { PolylineImpl(this, it.create(lineOptions)) }
|
||||
val line = PolylineImpl(this, "l${lineId++}", options)
|
||||
synchronized(this) {
|
||||
val lineManager = lineManager
|
||||
if (lineManager == null) {
|
||||
pendingLines.add(line)
|
||||
} else {
|
||||
line.update(lineManager)
|
||||
}
|
||||
}
|
||||
return line
|
||||
}
|
||||
|
||||
|
||||
override fun addPolygon(options: PolygonOptions): IPolygonDelegate? {
|
||||
val fillOptions = FillOptions()
|
||||
.withLatLngs(listOf(options.points.map { it.toMapbox() }))
|
||||
.withFillColor(ColorUtils.colorToRgbaString(options.fillColor))
|
||||
.withFillOpacity(if (options.isVisible) 1f else 0f)
|
||||
return fillManager?.let { PolygonImpl(this, it.create(fillOptions)) }
|
||||
val fill = PolygonImpl(this, "p${fillId++}", options)
|
||||
synchronized(this) {
|
||||
val fillManager = fillManager
|
||||
if (fillManager == null) {
|
||||
pendingFills.add(fill)
|
||||
} else {
|
||||
fill.update(fillManager)
|
||||
}
|
||||
}
|
||||
return fill
|
||||
}
|
||||
|
||||
override fun addMarker(options: MarkerOptions): IMarkerDelegate? {
|
||||
|
@ -412,7 +442,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
|
|||
}
|
||||
|
||||
override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) {
|
||||
Log.d(TAG, "padding: $left, $top, $right, $bottom")
|
||||
Log.d(TAG, "setPadding: $left $top $right $bottom")
|
||||
map?.setPadding(left, top, right, bottom)
|
||||
val fourDp = mapView?.context?.resources?.getDimension(R.dimen.mapbox_four_dp)?.toInt() ?: 0
|
||||
val ninetyTwoDp = mapView?.context?.resources?.getDimension(R.dimen.mapbox_ninety_two_dp)?.toInt()
|
||||
|
@ -433,8 +463,23 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
|
|||
}
|
||||
|
||||
override fun setOnMapLoadedCallback(callback: IOnMapLoadedCallback?) {
|
||||
Log.d(TAG, "unimplemented Method: setOnMapLoadedCallback")
|
||||
|
||||
if (callback != null) {
|
||||
synchronized(mapLock) {
|
||||
if (loaded) {
|
||||
Log.d(TAG, "Invoking callback instantly, as map is loaded")
|
||||
try {
|
||||
callback.onMapLoaded()
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, e)
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "Delay callback invocation, as map is not yet loaded")
|
||||
loadedCallback = callback
|
||||
}
|
||||
}
|
||||
} else {
|
||||
loadedCallback = null
|
||||
}
|
||||
}
|
||||
|
||||
override fun setCameraMoveStartedListener(listener: IOnCameraMoveStartedListener?) {
|
||||
|
@ -455,8 +500,12 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
|
|||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
if (!created) {
|
||||
mapView?.onCreate(savedInstanceState?.toMapbox())
|
||||
mapView?.getMapAsync(this::initMap)
|
||||
Log.d(TAG, "create");
|
||||
val mapView = MapView(MapContext(context))
|
||||
this.mapView = mapView
|
||||
view.addView(mapView)
|
||||
mapView.onCreate(savedInstanceState?.toMapbox())
|
||||
mapView.getMapAsync(this::initMap)
|
||||
created = true
|
||||
}
|
||||
}
|
||||
|
@ -533,9 +582,11 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
|
|||
options.scrollGesturesEnabled?.let { map.uiSettings.isScrollGesturesEnabled = it }
|
||||
options.tiltGesturesEnabled?.let { map.uiSettings.isTiltGesturesEnabled = it }
|
||||
options.camera?.let { map.cameraPosition = it.toMapbox() }
|
||||
waitingCameraUpdates.forEach { map.moveCamera(it) }
|
||||
|
||||
synchronized(mapLock) {
|
||||
initialized = true
|
||||
waitingCameraUpdates.forEach { map.moveCamera(it) }
|
||||
val initializedCallbackList = ArrayList(initializedCallbackList)
|
||||
Log.d(TAG, "Invoking ${initializedCallbackList.size} callbacks delayed, as map is initialized")
|
||||
for (callback in initializedCallbackList) {
|
||||
try {
|
||||
|
@ -544,30 +595,37 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
|
|||
Log.w(TAG, e)
|
||||
}
|
||||
}
|
||||
initialized = true
|
||||
}
|
||||
|
||||
map.getStyle {
|
||||
mapView?.let { view ->
|
||||
if (loaded) return@let
|
||||
val symbolManager: SymbolManager
|
||||
val lineManager: LineManager
|
||||
val circleManager: CircleManager
|
||||
val fillManager: FillManager
|
||||
|
||||
synchronized(mapLock) {
|
||||
circleManager = CircleManager(view, map, it)
|
||||
lineManager = LineManager(view, map, it)
|
||||
fillManager = FillManager(view, map, it)
|
||||
lineManager?.lineCap = LINE_CAP_ROUND
|
||||
synchronized(this) {
|
||||
val symbolManager = SymbolManager(view, map, it)
|
||||
pendingMarkers.forEach { it.update(symbolManager) }
|
||||
pendingMarkers.clear()
|
||||
symbolManager = SymbolManager(view, map, it)
|
||||
lineManager = LineManager(view, map, it)
|
||||
lineManager.lineCap = LINE_CAP_ROUND
|
||||
|
||||
this.symbolManager = symbolManager
|
||||
this.lineManager = lineManager
|
||||
this.circleManager = circleManager
|
||||
this.fillManager = fillManager
|
||||
}
|
||||
symbolManager?.iconAllowOverlap = true
|
||||
symbolManager?.addClickListener {
|
||||
symbolManager.iconAllowOverlap = true
|
||||
symbolManager.addClickListener {
|
||||
try {
|
||||
markers[it.id]?.let { markerClickListener?.onMarkerClick(it) }
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, e)
|
||||
}
|
||||
}
|
||||
symbolManager?.addDragListener(object : OnSymbolDragListener {
|
||||
symbolManager.addDragListener(object : OnSymbolDragListener {
|
||||
override fun onAnnotationDragStarted(annotation: Symbol?) {
|
||||
try {
|
||||
markers[annotation?.id]?.let { markerDragListener?.onMarkerDragStart(it) }
|
||||
|
@ -591,9 +649,23 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
|
|||
Log.w(TAG, e)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
pendingCircles.forEach { it.update(circleManager) }
|
||||
pendingCircles.clear()
|
||||
pendingFills.forEach { it.update(fillManager) }
|
||||
pendingFills.clear()
|
||||
pendingLines.forEach { it.update(lineManager) }
|
||||
pendingLines.clear()
|
||||
pendingMarkers.forEach { it.update(symbolManager) }
|
||||
pendingMarkers.clear()
|
||||
|
||||
synchronized(mapLock) {
|
||||
loaded = true
|
||||
if (loadedCallback != null) {
|
||||
Log.d(TAG, "Invoking callback delayed, as map is loaded")
|
||||
loadedCallback?.onMapLoaded()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -606,6 +678,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
|
|||
override fun onResume() = mapView?.onResume() ?: Unit
|
||||
override fun onPause() = mapView?.onPause() ?: Unit
|
||||
override fun onDestroy() {
|
||||
Log.d(TAG, "destroy");
|
||||
circleManager?.onDestroy()
|
||||
circleManager = null
|
||||
lineManager?.onDestroy()
|
||||
|
@ -621,14 +694,18 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
|
|||
// TODO can crash?
|
||||
mapView?.onDestroy()
|
||||
mapView = null
|
||||
map = null
|
||||
created = false
|
||||
initialized = false
|
||||
loaded = false
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
Log.d(TAG, "unimplemented Method: onStart")
|
||||
mapView?.onStart()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
Log.d(TAG, "unimplemented Method: onStop")
|
||||
mapView?.onStop()
|
||||
}
|
||||
|
||||
override fun onEnterAmbient(bundle: Bundle?) {
|
||||
|
|
|
@ -78,7 +78,6 @@ class MapFragmentImpl(private val activity: Activity) : IMapFragmentDelegate.Stu
|
|||
|
||||
override fun onDestroyView() {
|
||||
map?.onDestroy()
|
||||
map = null
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
|
|
@ -17,23 +17,26 @@
|
|||
package org.microg.gms.maps.mapbox.model
|
||||
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.*
|
||||
import android.os.Parcel
|
||||
import android.util.Log
|
||||
import com.google.android.gms.dynamic.IObjectWrapper
|
||||
import com.google.android.gms.dynamic.ObjectWrapper
|
||||
import com.google.android.gms.maps.model.internal.IBitmapDescriptorFactoryDelegate
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import org.microg.gms.maps.mapbox.R
|
||||
|
||||
|
||||
object BitmapDescriptorFactoryImpl : IBitmapDescriptorFactoryDelegate.Stub() {
|
||||
private val TAG = "GmsMapBitmap"
|
||||
private var resources: Resources? = null
|
||||
private var mapResources: Resources? = null
|
||||
private val maps = hashSetOf<MapboxMap>()
|
||||
private val bitmaps = hashMapOf<String, Bitmap>()
|
||||
|
||||
fun initialize(resources: Resources) {
|
||||
BitmapDescriptorFactoryImpl.resources = resources
|
||||
fun initialize(mapResources: Resources?, resources: Resources?) {
|
||||
BitmapDescriptorFactoryImpl.mapResources = mapResources ?: resources
|
||||
BitmapDescriptorFactoryImpl.resources = resources ?: mapResources
|
||||
}
|
||||
|
||||
fun registerMap(map: MapboxMap) {
|
||||
|
@ -56,9 +59,13 @@ object BitmapDescriptorFactoryImpl : IBitmapDescriptorFactoryDelegate.Stub() {
|
|||
?: floatArrayOf(0f, 0f)
|
||||
|
||||
private fun registerBitmap(id: String, bitmapCreator: () -> Bitmap?) {
|
||||
val bitmap = synchronized(bitmaps) {
|
||||
val bitmap: Bitmap = synchronized(bitmaps) {
|
||||
if (bitmaps.contains(id)) return
|
||||
val bitmap = bitmapCreator() ?: return
|
||||
val bitmap = bitmapCreator()
|
||||
if (bitmap == null) {
|
||||
Log.w(TAG, "Failed to register bitmap $id, creator returned null")
|
||||
return
|
||||
}
|
||||
bitmaps[id] = bitmap
|
||||
bitmap
|
||||
}
|
||||
|
@ -69,7 +76,17 @@ object BitmapDescriptorFactoryImpl : IBitmapDescriptorFactoryDelegate.Stub() {
|
|||
|
||||
override fun fromResource(resourceId: Int): IObjectWrapper? {
|
||||
val id = "resource-$resourceId"
|
||||
registerBitmap(id) { BitmapFactory.decodeResource(resources, resourceId) }
|
||||
registerBitmap(id) {
|
||||
val bitmap = BitmapFactory.decodeResource(resources, resourceId)
|
||||
if (bitmap == null) {
|
||||
try {
|
||||
Log.d(TAG, "Resource $resourceId not found in $resources (${resources?.getResourceName(resourceId)})")
|
||||
} catch (e: Resources.NotFoundException) {
|
||||
Log.d(TAG, "Resource $resourceId not found in $resources")
|
||||
}
|
||||
}
|
||||
bitmap
|
||||
}
|
||||
return ObjectWrapper.wrap(BitmapDescriptorImpl(id, bitmapSize(id)))
|
||||
}
|
||||
|
||||
|
@ -86,15 +103,45 @@ object BitmapDescriptorFactoryImpl : IBitmapDescriptorFactoryDelegate.Stub() {
|
|||
}
|
||||
|
||||
override fun defaultMarker(): IObjectWrapper? {
|
||||
Log.d(TAG, "unimplemented Method: defaultMarker")
|
||||
val id = "marker"
|
||||
return ObjectWrapper.wrap(BitmapDescriptorImpl("marker", bitmapSize(id)))
|
||||
registerBitmap(id) { BitmapFactory.decodeResource(mapResources, R.drawable.maps_default_marker) }
|
||||
return ObjectWrapper.wrap(BitmapDescriptorImpl(id, bitmapSize(id)))
|
||||
}
|
||||
|
||||
private fun adjustHue(cm: ColorMatrix, value: Float) {
|
||||
var value = value
|
||||
value = cleanValue(value, 180f) / 180f * Math.PI.toFloat()
|
||||
if (value == 0f) {
|
||||
return
|
||||
}
|
||||
val cosVal = Math.cos(value.toDouble()).toFloat()
|
||||
val sinVal = Math.sin(value.toDouble()).toFloat()
|
||||
val lumR = 0.213f
|
||||
val lumG = 0.715f
|
||||
val lumB = 0.072f
|
||||
val mat = floatArrayOf(lumR + cosVal * (1 - lumR) + sinVal * -lumR, lumG + cosVal * -lumG + sinVal * -lumG, lumB + cosVal * -lumB + sinVal * (1 - lumB), 0f, 0f, lumR + cosVal * -lumR + sinVal * 0.143f, lumG + cosVal * (1 - lumG) + sinVal * 0.140f, lumB + cosVal * -lumB + sinVal * -0.283f, 0f, 0f, lumR + cosVal * -lumR + sinVal * -(1 - lumR), lumG + cosVal * -lumG + sinVal * lumG, lumB + cosVal * (1 - lumB) + sinVal * lumB, 0f, 0f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 0f, 1f)
|
||||
cm.postConcat(ColorMatrix(mat))
|
||||
}
|
||||
|
||||
private fun cleanValue(p_val: Float, p_limit: Float): Float {
|
||||
return Math.min(p_limit, Math.max(-p_limit, p_val))
|
||||
}
|
||||
|
||||
override fun defaultMarkerWithHue(hue: Float): IObjectWrapper? {
|
||||
val id = "marker"
|
||||
Log.d(TAG, "unimplemented Method: defaultMarkerWithHue")
|
||||
return ObjectWrapper.wrap(ColorBitmapDescriptorImpl("marker", bitmapSize(id), hue))
|
||||
val id = "marker-${hue.toInt()}"
|
||||
registerBitmap(id) {
|
||||
val bitmap = BitmapFactory.decodeResource(mapResources, R.drawable.maps_default_marker).copy(Bitmap.Config.ARGB_8888, true)
|
||||
val paint = Paint()
|
||||
val matrix = ColorMatrix()
|
||||
val huex = hue % 360f
|
||||
adjustHue(matrix, if (huex > 180f) huex - 360f else huex)
|
||||
paint.setColorFilter(ColorMatrixColorFilter(matrix))
|
||||
|
||||
val canvas = Canvas(bitmap)
|
||||
canvas.drawBitmap(bitmap, 0f, 0f, paint)
|
||||
bitmap
|
||||
}
|
||||
return ObjectWrapper.wrap(ColorBitmapDescriptorImpl(id, bitmapSize(id), hue))
|
||||
}
|
||||
|
||||
override fun fromBitmap(bitmap: Bitmap): IObjectWrapper? {
|
||||
|
|
|
@ -116,6 +116,14 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options
|
|||
|
||||
override fun hashCodeRemote(): Int = hashCode()
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return id.hashCode()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return id
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other is CircleImpl) {
|
||||
return other.id == id
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.microg.gms.maps.mapbox.model
|
||||
|
||||
import android.util.Log
|
||||
import com.mapbox.mapboxsdk.plugins.annotation.Annotation
|
||||
import com.mapbox.mapboxsdk.plugins.annotation.AnnotationManager
|
||||
import com.mapbox.mapboxsdk.plugins.annotation.Options
|
||||
|
@ -37,4 +38,8 @@ interface Markup<T : Annotation<*>, S : Options<T>> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = "GmsMapMarkup"
|
||||
}
|
||||
}
|
|
@ -19,57 +19,93 @@ package org.microg.gms.maps.mapbox.model
|
|||
import android.os.Parcel
|
||||
import android.util.Log
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.android.gms.maps.model.PolygonOptions
|
||||
import com.google.android.gms.maps.model.PolylineOptions
|
||||
import com.google.android.gms.maps.model.internal.IPolygonDelegate
|
||||
import com.mapbox.mapboxsdk.plugins.annotation.AnnotationManager
|
||||
import com.mapbox.mapboxsdk.plugins.annotation.Fill
|
||||
import com.mapbox.mapboxsdk.plugins.annotation.FillOptions
|
||||
import com.mapbox.mapboxsdk.utils.ColorUtils
|
||||
import org.microg.gms.maps.mapbox.GoogleMapImpl
|
||||
import org.microg.gms.maps.mapbox.utils.toGms
|
||||
import org.microg.gms.maps.mapbox.utils.toMapbox
|
||||
|
||||
class PolygonImpl(private val map: GoogleMapImpl, private val fill: Fill) : IPolygonDelegate.Stub() {
|
||||
class PolygonImpl(private val map: GoogleMapImpl, private val id: String, options: PolygonOptions) : IPolygonDelegate.Stub(), Markup<Fill, FillOptions> {
|
||||
private var points = ArrayList(options.points)
|
||||
private var holes: List<List<LatLng>> = ArrayList(options.holes.map { ArrayList(it) })
|
||||
private var fillColor = options.fillColor
|
||||
private var strokeColor = options.strokeColor
|
||||
private var strokeWidth = options.strokeWidth
|
||||
private var visible: Boolean = options.isVisible
|
||||
|
||||
private var strokes = (listOf(PolylineImpl(map, "$id-stroke-main", PolylineOptions().color(strokeColor).width(strokeWidth).addAll(points)))
|
||||
+ holes.mapIndexed { idx, it -> PolylineImpl(map, "$id-stroke-hole-$idx", PolylineOptions().color(strokeColor).width(strokeWidth).addAll(it)) }).toMutableList()
|
||||
|
||||
override var annotation: Fill? = null
|
||||
override var removed: Boolean = false
|
||||
override val annotationOptions: FillOptions
|
||||
get() = FillOptions()
|
||||
.withLatLngs(mutableListOf(points.map { it.toMapbox() }).plus(holes.map { it.map { it.toMapbox() } }))
|
||||
.withFillColor(ColorUtils.colorToRgbaString(fillColor))
|
||||
.withFillOpacity(if (visible) 1f else 0f)
|
||||
|
||||
override fun remove() {
|
||||
map.fillManager?.delete(fill)
|
||||
removed = true
|
||||
map.fillManager?.let { update(it) }
|
||||
strokes.forEach { it.remove() }
|
||||
}
|
||||
|
||||
override fun getId(): String = "p" + fill.id.toString()
|
||||
override fun update(manager: AnnotationManager<*, Fill, FillOptions, *, *, *>) {
|
||||
super.update(manager)
|
||||
map.lineManager?.let { lineManager -> strokes.forEach { it.update(lineManager) } }
|
||||
}
|
||||
|
||||
override fun getId(): String = id
|
||||
|
||||
override fun setPoints(points: List<LatLng>) {
|
||||
fill.latLngs = listOf(points.map { it.toMapbox() })
|
||||
map.fillManager?.update(fill)
|
||||
this.points = ArrayList(points)
|
||||
annotation?.latLngs = mutableListOf(points.map { it.toMapbox() }).plus(holes.map { it.map { it.toMapbox() } })
|
||||
map.fillManager?.let { update(it) }
|
||||
strokes[0].points = points
|
||||
}
|
||||
|
||||
override fun getPoints(): List<LatLng> = fill.latLngs[0]?.map { it.toGms() } ?: emptyList()
|
||||
override fun getPoints(): List<LatLng> = points
|
||||
|
||||
override fun setHoles(holes: List<Any?>?) {
|
||||
Log.d(TAG, "unimplemented Method: setHoles")
|
||||
this.holes = if (holes == null) emptyList() else ArrayList(holes.mapNotNull { if (it is List<*>) it.mapNotNull { if (it is LatLng) it else null }.let { if (it.isNotEmpty()) it else null } else null })
|
||||
annotation?.latLngs = mutableListOf(points.map { it.toMapbox() }).plus(this.holes.map { it.map { it.toMapbox() } })
|
||||
while (this.holes.size < strokes.size) {
|
||||
val last = strokes.last()
|
||||
last.remove()
|
||||
strokes.remove(last)
|
||||
}
|
||||
strokes.forEachIndexed { idx, it -> it.points = this.holes[idx] }
|
||||
strokes.addAll(this.holes.subList(strokes.size, this.holes.lastIndex).mapIndexed { idx, it -> PolylineImpl(map, "$id-stroke-hole-${strokes.size + idx}", PolylineOptions().color(strokeColor).width(strokeWidth).addAll(it)) })
|
||||
map.fillManager?.let { update(it) }
|
||||
}
|
||||
|
||||
override fun getHoles(): List<Any?> {
|
||||
Log.d(TAG, "unimplemented Method: getHoles")
|
||||
return emptyList()
|
||||
}
|
||||
override fun getHoles(): List<Any?> = holes
|
||||
|
||||
override fun setStrokeWidth(width: Float) {
|
||||
Log.d(TAG, "unimplemented Method: setStrokeWidth")
|
||||
this.strokeWidth = width
|
||||
strokes.forEach { it.width = width }
|
||||
}
|
||||
|
||||
override fun getStrokeWidth(): Float {
|
||||
Log.d(TAG, "unimplemented Method: getStrokeWidth")
|
||||
return 0f
|
||||
}
|
||||
override fun getStrokeWidth(): Float = strokeWidth
|
||||
|
||||
override fun setStrokeColor(color: Int) {
|
||||
fill.setFillOutlineColor(color)
|
||||
map.fillManager?.update(fill)
|
||||
this.strokeColor = color
|
||||
strokes.forEach { it.color = color }
|
||||
}
|
||||
|
||||
override fun getStrokeColor(): Int = fill.fillOutlineColorAsInt
|
||||
override fun getStrokeColor(): Int = strokeColor
|
||||
|
||||
override fun setFillColor(color: Int) {
|
||||
fill.setFillColor(color)
|
||||
map.fillManager?.update(fill)
|
||||
this.fillColor = color
|
||||
annotation?.setFillColor(color)
|
||||
map.fillManager?.let { update(it) }
|
||||
}
|
||||
|
||||
override fun getFillColor(): Int = fill.fillColorAsInt
|
||||
override fun getFillColor(): Int = fillColor
|
||||
|
||||
override fun setZIndex(zIndex: Float) {
|
||||
Log.d(TAG, "unimplemented Method: setZIndex")
|
||||
|
@ -81,11 +117,12 @@ class PolygonImpl(private val map: GoogleMapImpl, private val fill: Fill) : IPol
|
|||
}
|
||||
|
||||
override fun setVisible(visible: Boolean) {
|
||||
fill.fillOpacity = if (visible) 1f else 0f
|
||||
map.fillManager?.update(fill)
|
||||
this.visible = visible
|
||||
annotation?.fillOpacity = if (visible) 1f else 0f
|
||||
map.fillManager?.let { update(it) }
|
||||
}
|
||||
|
||||
override fun isVisible(): Boolean = fill.fillOpacity != 0f
|
||||
override fun isVisible(): Boolean = visible
|
||||
|
||||
override fun setGeodesic(geod: Boolean) {
|
||||
Log.d(TAG, "unimplemented Method: setGeodesic")
|
||||
|
@ -100,9 +137,17 @@ class PolygonImpl(private val map: GoogleMapImpl, private val fill: Fill) : IPol
|
|||
|
||||
override fun hashCodeRemote(): Int = hashCode()
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return id.hashCode()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return id
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other is PolygonImpl) {
|
||||
return other.fill == fill
|
||||
return other.id == id
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -21,37 +21,57 @@ import android.util.Log
|
|||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.android.gms.maps.model.internal.IPolylineDelegate
|
||||
import com.mapbox.mapboxsdk.plugins.annotation.Line
|
||||
import com.mapbox.mapboxsdk.plugins.annotation.LineOptions
|
||||
import com.mapbox.mapboxsdk.utils.ColorUtils
|
||||
import org.microg.gms.maps.mapbox.GoogleMapImpl
|
||||
import org.microg.gms.maps.mapbox.utils.toGms
|
||||
import org.microg.gms.maps.mapbox.utils.toMapbox
|
||||
import com.google.android.gms.maps.model.PolylineOptions as GmsLineOptions
|
||||
|
||||
class PolylineImpl(private val map: GoogleMapImpl, private val id: String, options: GmsLineOptions) : IPolylineDelegate.Stub(), Markup<Line, LineOptions> {
|
||||
private var points = ArrayList(options.points)
|
||||
private var width = options.width
|
||||
private var color = options.color
|
||||
private var visible: Boolean = options.isVisible
|
||||
|
||||
override var annotation: Line? = null
|
||||
override var removed: Boolean = false
|
||||
override val annotationOptions: LineOptions
|
||||
get() = LineOptions()
|
||||
.withLatLngs(points.map { it.toMapbox() })
|
||||
.withLineWidth(width / map.dpiFactor)
|
||||
.withLineColor(ColorUtils.colorToRgbaString(color))
|
||||
.withLineOpacity(if (visible) 1f else 0f)
|
||||
|
||||
class PolylineImpl(private val map: GoogleMapImpl, private val line: Line) : IPolylineDelegate.Stub() {
|
||||
override fun remove() {
|
||||
map.lineManager?.delete(line)
|
||||
removed = true
|
||||
map.lineManager?.let { update(it) }
|
||||
}
|
||||
|
||||
override fun getId(): String = "l" + line.id.toString()
|
||||
override fun getId(): String = id
|
||||
|
||||
override fun setPoints(points: List<LatLng>) {
|
||||
line.latLngs = points.map { it.toMapbox() }
|
||||
map.lineManager?.update(line)
|
||||
this.points = ArrayList(points)
|
||||
annotation?.latLngs = points.map { it.toMapbox() }
|
||||
map.lineManager?.let { update(it) }
|
||||
}
|
||||
|
||||
override fun getPoints(): List<LatLng> = line.latLngs.map { it.toGms() }
|
||||
override fun getPoints(): List<LatLng> = points
|
||||
|
||||
override fun setWidth(width: Float) {
|
||||
line.lineWidth = width / map.dpiFactor
|
||||
map.lineManager?.update(line)
|
||||
this.width = width
|
||||
annotation?.lineWidth = width / map.dpiFactor
|
||||
map.lineManager?.let { update(it) }
|
||||
}
|
||||
|
||||
override fun getWidth(): Float = line.lineWidth * map.dpiFactor
|
||||
override fun getWidth(): Float = width
|
||||
|
||||
override fun setColor(color: Int) {
|
||||
line.setLineColor(color)
|
||||
map.lineManager?.update(line)
|
||||
this.color = color
|
||||
annotation?.setLineColor(color)
|
||||
map.lineManager?.let { update(it) }
|
||||
}
|
||||
|
||||
override fun getColor(): Int = line.lineColorAsInt
|
||||
override fun getColor(): Int = color
|
||||
|
||||
override fun setZIndex(zIndex: Float) {
|
||||
Log.d(TAG, "unimplemented Method: setZIndex")
|
||||
|
@ -63,11 +83,12 @@ class PolylineImpl(private val map: GoogleMapImpl, private val line: Line) : IPo
|
|||
}
|
||||
|
||||
override fun setVisible(visible: Boolean) {
|
||||
line.lineOpacity = if (visible) 1f else 0f
|
||||
map.lineManager?.update(line)
|
||||
this.visible = visible
|
||||
annotation?.lineOpacity = if (visible) 1f else 0f
|
||||
map.lineManager?.let { update(it) }
|
||||
}
|
||||
|
||||
override fun isVisible(): Boolean = line.lineOpacity != 0f
|
||||
override fun isVisible(): Boolean = visible
|
||||
|
||||
override fun setGeodesic(geod: Boolean) {
|
||||
Log.d(TAG, "unimplemented Method: setGeodesic")
|
||||
|
@ -82,9 +103,17 @@ class PolylineImpl(private val map: GoogleMapImpl, private val line: Line) : IPo
|
|||
|
||||
override fun hashCodeRemote(): Int = hashCode()
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return id.hashCode()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return id
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other is PolylineImpl) {
|
||||
return other.line == line
|
||||
return other.id == id
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -17,30 +17,24 @@
|
|||
package org.microg.gms.maps.mapbox.utils
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import com.google.android.gms.maps.internal.ICancelableCallback
|
||||
import com.google.android.gms.maps.model.CircleOptions
|
||||
import com.google.android.gms.maps.model.MarkerOptions
|
||||
import com.google.android.gms.maps.model.PolylineOptions
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.geometry.LatLngBounds
|
||||
import com.mapbox.mapboxsdk.geometry.VisibleRegion
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.plugins.annotation.LineOptions
|
||||
import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions
|
||||
import com.mapbox.mapboxsdk.style.layers.Property.ICON_ANCHOR_TOP_LEFT
|
||||
import com.mapbox.mapboxsdk.utils.ColorUtils
|
||||
import org.microg.gms.kotlin.unwrap
|
||||
import org.microg.gms.maps.mapbox.model.BitmapDescriptorImpl
|
||||
import com.google.android.gms.maps.model.CameraPosition as GmsCameraPosition
|
||||
import com.google.android.gms.maps.model.LatLng as GmsLatLng
|
||||
import com.google.android.gms.maps.model.LatLngBounds as GmsLatLngBounds
|
||||
import com.google.android.gms.maps.model.VisibleRegion as GmsVisibleRegion
|
||||
|
||||
fun com.google.android.gms.maps.model.LatLng.toMapbox(): LatLng =
|
||||
fun GmsLatLng.toMapbox(): LatLng =
|
||||
LatLng(latitude, longitude)
|
||||
|
||||
fun com.google.android.gms.maps.model.LatLngBounds.toMapbox(): LatLngBounds =
|
||||
fun GmsLatLngBounds.toMapbox(): LatLngBounds =
|
||||
LatLngBounds.from(this.northeast.latitude, this.northeast.longitude, this.southwest.latitude, this.southwest.longitude)
|
||||
|
||||
fun com.google.android.gms.maps.model.CameraPosition.toMapbox(): CameraPosition =
|
||||
fun GmsCameraPosition.toMapbox(): CameraPosition =
|
||||
CameraPosition.Builder()
|
||||
.target(target.toMapbox())
|
||||
.zoom(zoom.toDouble() - 1.0)
|
||||
|
@ -60,23 +54,21 @@ fun Bundle.toMapbox(): Bundle {
|
|||
for (key in newBundle.keySet()) {
|
||||
val value = newBundle.get(key)
|
||||
when (value) {
|
||||
is com.google.android.gms.maps.model.CameraPosition -> newBundle.putParcelable(key, value.toMapbox())
|
||||
is com.google.android.gms.maps.model.LatLng -> newBundle.putParcelable(key, value.toMapbox())
|
||||
is com.google.android.gms.maps.model.LatLngBounds -> newBundle.putParcelable(key, value.toMapbox())
|
||||
is GmsCameraPosition -> newBundle.putParcelable(key, value.toMapbox())
|
||||
is GmsLatLng -> newBundle.putParcelable(key, value.toMapbox())
|
||||
is GmsLatLngBounds -> newBundle.putParcelable(key, value.toMapbox())
|
||||
is Bundle -> newBundle.putBundle(key, value.toMapbox())
|
||||
}
|
||||
}
|
||||
return newBundle
|
||||
}
|
||||
|
||||
fun LatLng.toGms(): com.google.android.gms.maps.model.LatLng =
|
||||
com.google.android.gms.maps.model.LatLng(latitude, longitude)
|
||||
fun LatLng.toGms(): GmsLatLng = GmsLatLng(latitude, longitude)
|
||||
|
||||
fun LatLngBounds.toGms(): com.google.android.gms.maps.model.LatLngBounds =
|
||||
com.google.android.gms.maps.model.LatLngBounds(southWest.toGms(), northEast.toGms())
|
||||
fun LatLngBounds.toGms(): GmsLatLngBounds = GmsLatLngBounds(southWest.toGms(), northEast.toGms())
|
||||
|
||||
fun CameraPosition.toGms(): com.google.android.gms.maps.model.CameraPosition =
|
||||
com.google.android.gms.maps.model.CameraPosition(target.toGms(), zoom.toFloat() + 1.0f, tilt.toFloat(), bearing.toFloat())
|
||||
fun CameraPosition.toGms(): GmsCameraPosition =
|
||||
GmsCameraPosition(target.toGms(), zoom.toFloat() + 1.0f, tilt.toFloat(), bearing.toFloat())
|
||||
|
||||
fun Bundle.toGms(): Bundle {
|
||||
val newBundle = Bundle(this)
|
||||
|
@ -92,5 +84,5 @@ fun Bundle.toGms(): Bundle {
|
|||
return newBundle
|
||||
}
|
||||
|
||||
fun VisibleRegion.toGms(): com.google.android.gms.maps.model.VisibleRegion =
|
||||
com.google.android.gms.maps.model.VisibleRegion(nearLeft.toGms(), nearRight.toGms(), farLeft.toGms(), farRight.toGms(), latLngBounds.toGms())
|
||||
fun VisibleRegion.toGms(): GmsVisibleRegion =
|
||||
GmsVisibleRegion(nearLeft.toGms(), nearRight.toGms(), farLeft.toGms(), farRight.toGms(), latLngBounds.toGms())
|
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 946 B |
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.8 KiB |
Loading…
Reference in a new issue