0
0
Fork 0
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:
Marvin W 2019-10-15 14:59:34 +02:00
parent 3c5e68404b
commit fc3e24c0ea
No known key found for this signature in database
GPG key ID: 072E9235DB996F2A
17 changed files with 350 additions and 149 deletions

View file

@ -65,9 +65,9 @@ public class CreatorImpl extends ICreator.Stub {
@Override @Override
public void initV2(IObjectWrapper resources, int flags) { 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)); //ResourcesContainer.set((Resources) ObjectWrapper.unwrap(resources));
Log.d(TAG, "initV2"); Log.d(TAG, "initV2 " + flags);
} }
@Override @Override

View file

@ -16,6 +16,7 @@
package org.microg.gms.maps.mapbox package org.microg.gms.maps.mapbox
import android.util.Log
import com.mapbox.mapboxsdk.camera.CameraPosition import com.mapbox.mapboxsdk.camera.CameraPosition
import com.mapbox.mapboxsdk.camera.CameraUpdate import com.mapbox.mapboxsdk.camera.CameraUpdate
import com.mapbox.mapboxsdk.geometry.LatLngBounds 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? { override fun getCameraPosition(map: MapboxMap): CameraPosition? {
val padding = this.padding.clone() val padding = this.padding.clone()
val widthPad = (map.padding[0] + map.padding[2])/2 val widthPad = ((map.width + map.padding[0] + map.padding[2] - width) / 2).toInt()
val heightPad = (map.padding[1] + map.padding[3])/2 val heightPad = ((map.height + map.padding[1] + map.padding[3] - height) / 2).toInt()
padding[0] += widthPad padding[0] += widthPad
padding[1] += heightPad padding[1] += heightPad
padding[2] += widthPad padding[2] += widthPad
padding[3] += heightPad 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) return map.getCameraForLatLngBounds(bounds, padding)
} }
@ -78,6 +80,6 @@ internal class CameraBoundsWithSizeUpdate(val bounds: LatLngBounds, val width: I
} }
companion object { companion object {
val TAG = "GmsCameraBounds" const val TAG = "GmsMapCameraBounds"
} }
} }

View file

@ -61,11 +61,8 @@ class CameraUpdateFactoryImpl : ICameraUpdateFactoryDelegate.Stub() {
return ObjectWrapper.wrap(NoCameraUpdate()) return ObjectWrapper.wrap(NoCameraUpdate())
} }
override fun newLatLngBoundsWithSize(bounds: LatLngBounds, width: Int, height: Int, padding: Int): IObjectWrapper { override fun newLatLngBoundsWithSize(bounds: LatLngBounds, width: Int, height: Int, padding: Int): IObjectWrapper =
Log.d(TAG, "unimplemented Method: newLatLngBoundsWithSize") ObjectWrapper.wrap(CameraBoundsWithSizeUpdate(bounds.toMapbox(), width, height, padding))
return ObjectWrapper.wrap(CameraBoundsWithSizeUpdate(bounds.toMapbox(), width, height, padding))
}
override fun onTransact(code: Int, data: Parcel?, reply: Parcel?, flags: Int): Boolean = override fun onTransact(code: Int, data: Parcel?, reply: Parcel?, flags: Int): Boolean =
if (super.onTransact(code, data, reply, flags)) { if (super.onTransact(code, data, reply, flags)) {

View file

@ -20,6 +20,7 @@ import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.location.Location import android.location.Location
import android.os.Bundle import android.os.Bundle
import android.os.IBinder
import android.os.Parcel import android.os.Parcel
import android.support.annotation.IdRes import android.support.annotation.IdRes
import android.support.annotation.Keep import android.support.annotation.Keep
@ -66,12 +67,14 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
val dpiFactor: Float val dpiFactor: Float
get() = context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT get() = context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT
private var mapView: MapView? private var mapView: MapView? = null
private var created = false private var created = false
private var initialized = false private var initialized = false
private val initializedCallbackList = mutableListOf<IOnMapReadyCallback>() private var loaded = false
private val mapLock = Object() private val mapLock = Object()
private val initializedCallbackList = mutableListOf<IOnMapReadyCallback>()
private var loadedCallback : IOnMapLoadedCallback? = null
private var cameraChangeListener: IOnCameraChangeListener? = null private var cameraChangeListener: IOnCameraChangeListener? = null
private var cameraMoveListener: IOnCameraMoveListener? = null private var cameraMoveListener: IOnCameraMoveListener? = null
private var cameraMoveCanceledListener: IOnCameraMoveCanceledListener? = null private var cameraMoveCanceledListener: IOnCameraMoveCanceledListener? = null
@ -83,7 +86,12 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
private var markerDragListener: IOnMarkerDragListener? = null private var markerDragListener: IOnMarkerDragListener? = null
var lineManager: LineManager? = null var lineManager: LineManager? = null
val pendingLines = mutableSetOf<PolylineImpl>()
var lineId = 0L
var fillManager: FillManager? = null var fillManager: FillManager? = null
val pendingFills = mutableSetOf<PolygonImpl>()
var fillId = 0L
var circleManager: CircleManager? = null var circleManager: CircleManager? = null
val pendingCircles = mutableSetOf<CircleImpl>() val pendingCircles = mutableSetOf<CircleImpl>()
@ -99,6 +107,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
init { init {
val mapContext = MapContext(context) val mapContext = MapContext(context)
BitmapDescriptorFactoryImpl.initialize(mapContext.resources, context.resources)
LibraryLoader.setLibraryLoader(MultiArchLoader(mapContext, context)) LibraryLoader.setLibraryLoader(MultiArchLoader(mapContext, context))
Mapbox.getInstance(mapContext, BuildConfig.MAPBOX_KEY) Mapbox.getInstance(mapContext, BuildConfig.MAPBOX_KEY)
@ -137,8 +146,6 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
return null return null
} }
} }
this.mapView = MapView(mapContext)
this.view.addView(this.mapView)
} }
override fun getCameraPosition(): CameraPosition? = map?.cameraPosition?.toGms() 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?) { override fun moveCamera(cameraUpdate: IObjectWrapper?) {
val update = cameraUpdate.unwrap<CameraUpdate>() ?: return val update = cameraUpdate.unwrap<CameraUpdate>() ?: return
val map = this.map synchronized(mapLock) {
if (map != null) { if (initialized) {
map.moveCamera(update) this.map?.moveCamera(update)
} else { } else {
waitingCameraUpdates.add(update) waitingCameraUpdates.add(update)
} }
} }
}
override fun animateCamera(cameraUpdate: IObjectWrapper?) { override fun animateCamera(cameraUpdate: IObjectWrapper?) {
val update = cameraUpdate.unwrap<CameraUpdate>() ?: return val update = cameraUpdate.unwrap<CameraUpdate>() ?: return
val map = this.map synchronized(mapLock) {
if (map != null) { if (initialized) {
map.animateCamera(update) this.map?.animateCamera(update)
} else { } else {
waitingCameraUpdates.add(update) 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?) { override fun animateCameraWithCallback(cameraUpdate: IObjectWrapper?, callback: ICancelableCallback?) {
val update = cameraUpdate.unwrap<CameraUpdate>() ?: return val update = cameraUpdate.unwrap<CameraUpdate>() ?: return
val map = this.map synchronized(mapLock) {
if (map != null) { if (initialized) {
map.animateCamera(update, callback?.toMapbox()) this.map?.animateCamera(update, callback?.toMapbox())
} else { } else {
waitingCameraUpdates.add(update) waitingCameraUpdates.add(update)
callback?.onFinish() afterInitialized { callback?.onFinish() }
}
} }
} }
override fun animateCameraWithDurationAndCallback(cameraUpdate: IObjectWrapper?, duration: Int, callback: ICancelableCallback?) { override fun animateCameraWithDurationAndCallback(cameraUpdate: IObjectWrapper?, duration: Int, callback: ICancelableCallback?) {
val update = cameraUpdate.unwrap<CameraUpdate>() ?: return val update = cameraUpdate.unwrap<CameraUpdate>() ?: return
val map = this.map synchronized(mapLock) {
if (map != null) { if (initialized) {
map.animateCamera(update, duration, callback?.toMapbox()) this.map?.animateCamera(update, duration, callback?.toMapbox())
} else { } else {
waitingCameraUpdates.add(update) 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? { override fun addPolyline(options: PolylineOptions): IPolylineDelegate? {
val lineOptions = LineOptions() val line = PolylineImpl(this, "l${lineId++}", options)
.withLatLngs(options.points.map { it.toMapbox() }) synchronized(this) {
.withLineWidth(options.width / dpiFactor) val lineManager = lineManager
.withLineColor(ColorUtils.colorToRgbaString(options.color)) if (lineManager == null) {
.withLineOpacity(if (options.isVisible) 1f else 0f) pendingLines.add(line)
return lineManager?.let { PolylineImpl(this, it.create(lineOptions)) } } else {
line.update(lineManager)
}
}
return line
} }
override fun addPolygon(options: PolygonOptions): IPolygonDelegate? { override fun addPolygon(options: PolygonOptions): IPolygonDelegate? {
val fillOptions = FillOptions() val fill = PolygonImpl(this, "p${fillId++}", options)
.withLatLngs(listOf(options.points.map { it.toMapbox() })) synchronized(this) {
.withFillColor(ColorUtils.colorToRgbaString(options.fillColor)) val fillManager = fillManager
.withFillOpacity(if (options.isVisible) 1f else 0f) if (fillManager == null) {
return fillManager?.let { PolygonImpl(this, it.create(fillOptions)) } pendingFills.add(fill)
} else {
fill.update(fillManager)
}
}
return fill
} }
override fun addMarker(options: MarkerOptions): IMarkerDelegate? { 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) { 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) map?.setPadding(left, top, right, bottom)
val fourDp = mapView?.context?.resources?.getDimension(R.dimen.mapbox_four_dp)?.toInt() ?: 0 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() 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?) { 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?) { override fun setCameraMoveStartedListener(listener: IOnCameraMoveStartedListener?) {
@ -455,8 +500,12 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
if (!created) { if (!created) {
mapView?.onCreate(savedInstanceState?.toMapbox()) Log.d(TAG, "create");
mapView?.getMapAsync(this::initMap) val mapView = MapView(MapContext(context))
this.mapView = mapView
view.addView(mapView)
mapView.onCreate(savedInstanceState?.toMapbox())
mapView.getMapAsync(this::initMap)
created = true created = true
} }
} }
@ -533,9 +582,11 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
options.scrollGesturesEnabled?.let { map.uiSettings.isScrollGesturesEnabled = it } options.scrollGesturesEnabled?.let { map.uiSettings.isScrollGesturesEnabled = it }
options.tiltGesturesEnabled?.let { map.uiSettings.isTiltGesturesEnabled = it } options.tiltGesturesEnabled?.let { map.uiSettings.isTiltGesturesEnabled = it }
options.camera?.let { map.cameraPosition = it.toMapbox() } options.camera?.let { map.cameraPosition = it.toMapbox() }
waitingCameraUpdates.forEach { map.moveCamera(it) }
synchronized(mapLock) { 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") Log.d(TAG, "Invoking ${initializedCallbackList.size} callbacks delayed, as map is initialized")
for (callback in initializedCallbackList) { for (callback in initializedCallbackList) {
try { try {
@ -544,30 +595,37 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
Log.w(TAG, e) Log.w(TAG, e)
} }
} }
initialized = true
} }
map.getStyle { map.getStyle {
mapView?.let { view -> 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) circleManager = CircleManager(view, map, it)
lineManager = LineManager(view, map, it)
fillManager = FillManager(view, map, it) fillManager = FillManager(view, map, it)
lineManager?.lineCap = LINE_CAP_ROUND symbolManager = SymbolManager(view, map, it)
synchronized(this) { lineManager = LineManager(view, map, it)
val symbolManager = SymbolManager(view, map, it) lineManager.lineCap = LINE_CAP_ROUND
pendingMarkers.forEach { it.update(symbolManager) }
pendingMarkers.clear()
this.symbolManager = symbolManager this.symbolManager = symbolManager
this.lineManager = lineManager
this.circleManager = circleManager
this.fillManager = fillManager
} }
symbolManager?.iconAllowOverlap = true symbolManager.iconAllowOverlap = true
symbolManager?.addClickListener { symbolManager.addClickListener {
try { try {
markers[it.id]?.let { markerClickListener?.onMarkerClick(it) } markers[it.id]?.let { markerClickListener?.onMarkerClick(it) }
} catch (e: Exception) { } catch (e: Exception) {
Log.w(TAG, e) Log.w(TAG, e)
} }
} }
symbolManager?.addDragListener(object : OnSymbolDragListener { symbolManager.addDragListener(object : OnSymbolDragListener {
override fun onAnnotationDragStarted(annotation: Symbol?) { override fun onAnnotationDragStarted(annotation: Symbol?) {
try { try {
markers[annotation?.id]?.let { markerDragListener?.onMarkerDragStart(it) } markers[annotation?.id]?.let { markerDragListener?.onMarkerDragStart(it) }
@ -591,9 +649,23 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
Log.w(TAG, e) 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 onResume() = mapView?.onResume() ?: Unit
override fun onPause() = mapView?.onPause() ?: Unit override fun onPause() = mapView?.onPause() ?: Unit
override fun onDestroy() { override fun onDestroy() {
Log.d(TAG, "destroy");
circleManager?.onDestroy() circleManager?.onDestroy()
circleManager = null circleManager = null
lineManager?.onDestroy() lineManager?.onDestroy()
@ -621,14 +694,18 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions)
// TODO can crash? // TODO can crash?
mapView?.onDestroy() mapView?.onDestroy()
mapView = null mapView = null
map = null
created = false
initialized = false
loaded = false
} }
override fun onStart() { override fun onStart() {
Log.d(TAG, "unimplemented Method: onStart") mapView?.onStart()
} }
override fun onStop() { override fun onStop() {
Log.d(TAG, "unimplemented Method: onStop") mapView?.onStop()
} }
override fun onEnterAmbient(bundle: Bundle?) { override fun onEnterAmbient(bundle: Bundle?) {

View file

@ -78,7 +78,6 @@ class MapFragmentImpl(private val activity: Activity) : IMapFragmentDelegate.Stu
override fun onDestroyView() { override fun onDestroyView() {
map?.onDestroy() map?.onDestroy()
map = null
} }
override fun onDestroy() { override fun onDestroy() {

View file

@ -17,23 +17,26 @@
package org.microg.gms.maps.mapbox.model package org.microg.gms.maps.mapbox.model
import android.content.res.Resources import android.content.res.Resources
import android.graphics.Bitmap import android.graphics.*
import android.graphics.BitmapFactory
import android.os.Parcel import android.os.Parcel
import android.util.Log import android.util.Log
import com.google.android.gms.dynamic.IObjectWrapper import com.google.android.gms.dynamic.IObjectWrapper
import com.google.android.gms.dynamic.ObjectWrapper import com.google.android.gms.dynamic.ObjectWrapper
import com.google.android.gms.maps.model.internal.IBitmapDescriptorFactoryDelegate import com.google.android.gms.maps.model.internal.IBitmapDescriptorFactoryDelegate
import com.mapbox.mapboxsdk.maps.MapboxMap import com.mapbox.mapboxsdk.maps.MapboxMap
import org.microg.gms.maps.mapbox.R
object BitmapDescriptorFactoryImpl : IBitmapDescriptorFactoryDelegate.Stub() { object BitmapDescriptorFactoryImpl : IBitmapDescriptorFactoryDelegate.Stub() {
private val TAG = "GmsMapBitmap" private val TAG = "GmsMapBitmap"
private var resources: Resources? = null private var resources: Resources? = null
private var mapResources: Resources? = null
private val maps = hashSetOf<MapboxMap>() private val maps = hashSetOf<MapboxMap>()
private val bitmaps = hashMapOf<String, Bitmap>() private val bitmaps = hashMapOf<String, Bitmap>()
fun initialize(resources: Resources) { fun initialize(mapResources: Resources?, resources: Resources?) {
BitmapDescriptorFactoryImpl.resources = resources BitmapDescriptorFactoryImpl.mapResources = mapResources ?: resources
BitmapDescriptorFactoryImpl.resources = resources ?: mapResources
} }
fun registerMap(map: MapboxMap) { fun registerMap(map: MapboxMap) {
@ -56,9 +59,13 @@ object BitmapDescriptorFactoryImpl : IBitmapDescriptorFactoryDelegate.Stub() {
?: floatArrayOf(0f, 0f) ?: floatArrayOf(0f, 0f)
private fun registerBitmap(id: String, bitmapCreator: () -> Bitmap?) { private fun registerBitmap(id: String, bitmapCreator: () -> Bitmap?) {
val bitmap = synchronized(bitmaps) { val bitmap: Bitmap = synchronized(bitmaps) {
if (bitmaps.contains(id)) return 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 bitmaps[id] = bitmap
bitmap bitmap
} }
@ -69,7 +76,17 @@ object BitmapDescriptorFactoryImpl : IBitmapDescriptorFactoryDelegate.Stub() {
override fun fromResource(resourceId: Int): IObjectWrapper? { override fun fromResource(resourceId: Int): IObjectWrapper? {
val id = "resource-$resourceId" 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))) return ObjectWrapper.wrap(BitmapDescriptorImpl(id, bitmapSize(id)))
} }
@ -86,15 +103,45 @@ object BitmapDescriptorFactoryImpl : IBitmapDescriptorFactoryDelegate.Stub() {
} }
override fun defaultMarker(): IObjectWrapper? { override fun defaultMarker(): IObjectWrapper? {
Log.d(TAG, "unimplemented Method: defaultMarker")
val id = "marker" 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? { override fun defaultMarkerWithHue(hue: Float): IObjectWrapper? {
val id = "marker" val id = "marker-${hue.toInt()}"
Log.d(TAG, "unimplemented Method: defaultMarkerWithHue") registerBitmap(id) {
return ObjectWrapper.wrap(ColorBitmapDescriptorImpl("marker", bitmapSize(id), hue)) 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? { override fun fromBitmap(bitmap: Bitmap): IObjectWrapper? {

View file

@ -116,6 +116,14 @@ class CircleImpl(private val map: GoogleMapImpl, private val id: String, options
override fun hashCodeRemote(): Int = hashCode() override fun hashCodeRemote(): Int = hashCode()
override fun hashCode(): Int {
return id.hashCode()
}
override fun toString(): String {
return id
}
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (other is CircleImpl) { if (other is CircleImpl) {
return other.id == id return other.id == id

View file

@ -16,6 +16,7 @@
package org.microg.gms.maps.mapbox.model package org.microg.gms.maps.mapbox.model
import android.util.Log
import com.mapbox.mapboxsdk.plugins.annotation.Annotation import com.mapbox.mapboxsdk.plugins.annotation.Annotation
import com.mapbox.mapboxsdk.plugins.annotation.AnnotationManager import com.mapbox.mapboxsdk.plugins.annotation.AnnotationManager
import com.mapbox.mapboxsdk.plugins.annotation.Options import com.mapbox.mapboxsdk.plugins.annotation.Options
@ -37,4 +38,8 @@ interface Markup<T : Annotation<*>, S : Options<T>> {
} }
} }
} }
companion object {
private val TAG = "GmsMapMarkup"
}
} }

View file

@ -19,57 +19,93 @@ package org.microg.gms.maps.mapbox.model
import android.os.Parcel import android.os.Parcel
import android.util.Log import android.util.Log
import com.google.android.gms.maps.model.LatLng 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.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.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.GoogleMapImpl
import org.microg.gms.maps.mapbox.utils.toGms
import org.microg.gms.maps.mapbox.utils.toMapbox 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() { 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>) { override fun setPoints(points: List<LatLng>) {
fill.latLngs = listOf(points.map { it.toMapbox() }) this.points = ArrayList(points)
map.fillManager?.update(fill) 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?>?) { 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?> { override fun getHoles(): List<Any?> = holes
Log.d(TAG, "unimplemented Method: getHoles")
return emptyList()
}
override fun setStrokeWidth(width: Float) { override fun setStrokeWidth(width: Float) {
Log.d(TAG, "unimplemented Method: setStrokeWidth") this.strokeWidth = width
strokes.forEach { it.width = width }
} }
override fun getStrokeWidth(): Float { override fun getStrokeWidth(): Float = strokeWidth
Log.d(TAG, "unimplemented Method: getStrokeWidth")
return 0f
}
override fun setStrokeColor(color: Int) { override fun setStrokeColor(color: Int) {
fill.setFillOutlineColor(color) this.strokeColor = color
map.fillManager?.update(fill) strokes.forEach { it.color = color }
} }
override fun getStrokeColor(): Int = fill.fillOutlineColorAsInt override fun getStrokeColor(): Int = strokeColor
override fun setFillColor(color: Int) { override fun setFillColor(color: Int) {
fill.setFillColor(color) this.fillColor = color
map.fillManager?.update(fill) annotation?.setFillColor(color)
map.fillManager?.let { update(it) }
} }
override fun getFillColor(): Int = fill.fillColorAsInt override fun getFillColor(): Int = fillColor
override fun setZIndex(zIndex: Float) { override fun setZIndex(zIndex: Float) {
Log.d(TAG, "unimplemented Method: setZIndex") 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) { override fun setVisible(visible: Boolean) {
fill.fillOpacity = if (visible) 1f else 0f this.visible = visible
map.fillManager?.update(fill) 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) { override fun setGeodesic(geod: Boolean) {
Log.d(TAG, "unimplemented Method: setGeodesic") 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 hashCodeRemote(): Int = hashCode()
override fun hashCode(): Int {
return id.hashCode()
}
override fun toString(): String {
return id
}
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (other is PolygonImpl) { if (other is PolygonImpl) {
return other.fill == fill return other.id == id
} }
return false return false
} }

View file

@ -21,37 +21,57 @@ import android.util.Log
import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.internal.IPolylineDelegate import com.google.android.gms.maps.model.internal.IPolylineDelegate
import com.mapbox.mapboxsdk.plugins.annotation.Line 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.GoogleMapImpl
import org.microg.gms.maps.mapbox.utils.toGms
import org.microg.gms.maps.mapbox.utils.toMapbox 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() { 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>) { override fun setPoints(points: List<LatLng>) {
line.latLngs = points.map { it.toMapbox() } this.points = ArrayList(points)
map.lineManager?.update(line) 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) { override fun setWidth(width: Float) {
line.lineWidth = width / map.dpiFactor this.width = width
map.lineManager?.update(line) 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) { override fun setColor(color: Int) {
line.setLineColor(color) this.color = color
map.lineManager?.update(line) annotation?.setLineColor(color)
map.lineManager?.let { update(it) }
} }
override fun getColor(): Int = line.lineColorAsInt override fun getColor(): Int = color
override fun setZIndex(zIndex: Float) { override fun setZIndex(zIndex: Float) {
Log.d(TAG, "unimplemented Method: setZIndex") 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) { override fun setVisible(visible: Boolean) {
line.lineOpacity = if (visible) 1f else 0f this.visible = visible
map.lineManager?.update(line) 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) { override fun setGeodesic(geod: Boolean) {
Log.d(TAG, "unimplemented Method: setGeodesic") 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 hashCodeRemote(): Int = hashCode()
override fun hashCode(): Int {
return id.hashCode()
}
override fun toString(): String {
return id
}
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (other is PolylineImpl) { if (other is PolylineImpl) {
return other.line == line return other.id == id
} }
return false return false
} }

View file

@ -17,30 +17,24 @@
package org.microg.gms.maps.mapbox.utils package org.microg.gms.maps.mapbox.utils
import android.os.Bundle import android.os.Bundle
import android.util.Log
import com.google.android.gms.maps.internal.ICancelableCallback 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.camera.CameraPosition
import com.mapbox.mapboxsdk.geometry.LatLng import com.mapbox.mapboxsdk.geometry.LatLng
import com.mapbox.mapboxsdk.geometry.LatLngBounds import com.mapbox.mapboxsdk.geometry.LatLngBounds
import com.mapbox.mapboxsdk.geometry.VisibleRegion import com.mapbox.mapboxsdk.geometry.VisibleRegion
import com.mapbox.mapboxsdk.maps.MapboxMap import com.mapbox.mapboxsdk.maps.MapboxMap
import com.mapbox.mapboxsdk.plugins.annotation.LineOptions import com.google.android.gms.maps.model.CameraPosition as GmsCameraPosition
import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions import com.google.android.gms.maps.model.LatLng as GmsLatLng
import com.mapbox.mapboxsdk.style.layers.Property.ICON_ANCHOR_TOP_LEFT import com.google.android.gms.maps.model.LatLngBounds as GmsLatLngBounds
import com.mapbox.mapboxsdk.utils.ColorUtils import com.google.android.gms.maps.model.VisibleRegion as GmsVisibleRegion
import org.microg.gms.kotlin.unwrap
import org.microg.gms.maps.mapbox.model.BitmapDescriptorImpl
fun com.google.android.gms.maps.model.LatLng.toMapbox(): LatLng = fun GmsLatLng.toMapbox(): LatLng =
LatLng(latitude, longitude) 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) 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() CameraPosition.Builder()
.target(target.toMapbox()) .target(target.toMapbox())
.zoom(zoom.toDouble() - 1.0) .zoom(zoom.toDouble() - 1.0)
@ -60,23 +54,21 @@ fun Bundle.toMapbox(): Bundle {
for (key in newBundle.keySet()) { for (key in newBundle.keySet()) {
val value = newBundle.get(key) val value = newBundle.get(key)
when (value) { when (value) {
is com.google.android.gms.maps.model.CameraPosition -> newBundle.putParcelable(key, value.toMapbox()) is GmsCameraPosition -> newBundle.putParcelable(key, value.toMapbox())
is com.google.android.gms.maps.model.LatLng -> newBundle.putParcelable(key, value.toMapbox()) is GmsLatLng -> newBundle.putParcelable(key, value.toMapbox())
is com.google.android.gms.maps.model.LatLngBounds -> newBundle.putParcelable(key, value.toMapbox()) is GmsLatLngBounds -> newBundle.putParcelable(key, value.toMapbox())
is Bundle -> newBundle.putBundle(key, value.toMapbox()) is Bundle -> newBundle.putBundle(key, value.toMapbox())
} }
} }
return newBundle return newBundle
} }
fun LatLng.toGms(): com.google.android.gms.maps.model.LatLng = fun LatLng.toGms(): GmsLatLng = GmsLatLng(latitude, longitude)
com.google.android.gms.maps.model.LatLng(latitude, longitude)
fun LatLngBounds.toGms(): com.google.android.gms.maps.model.LatLngBounds = fun LatLngBounds.toGms(): GmsLatLngBounds = GmsLatLngBounds(southWest.toGms(), northEast.toGms())
com.google.android.gms.maps.model.LatLngBounds(southWest.toGms(), northEast.toGms())
fun CameraPosition.toGms(): com.google.android.gms.maps.model.CameraPosition = fun CameraPosition.toGms(): GmsCameraPosition =
com.google.android.gms.maps.model.CameraPosition(target.toGms(), zoom.toFloat() + 1.0f, tilt.toFloat(), bearing.toFloat()) GmsCameraPosition(target.toGms(), zoom.toFloat() + 1.0f, tilt.toFloat(), bearing.toFloat())
fun Bundle.toGms(): Bundle { fun Bundle.toGms(): Bundle {
val newBundle = Bundle(this) val newBundle = Bundle(this)
@ -92,5 +84,5 @@ fun Bundle.toGms(): Bundle {
return newBundle return newBundle
} }
fun VisibleRegion.toGms(): com.google.android.gms.maps.model.VisibleRegion = fun VisibleRegion.toGms(): GmsVisibleRegion =
com.google.android.gms.maps.model.VisibleRegion(nearLeft.toGms(), nearRight.toGms(), farLeft.toGms(), farRight.toGms(), latLngBounds.toGms()) 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