mirror of https://github.com/YTVanced/VancedMicroG
Various fixes and improvements to Maps API
This commit is contained in:
parent
73fd85a8c7
commit
73aca6ea10
|
@ -1 +1 @@
|
||||||
Subproject commit 7197b8320b4e6d55d15b76d4faf05adaba36bf72
|
Subproject commit bfe649fc36a40e2498f1ecf123edfb9278fe0a1d
|
|
@ -16,18 +16,20 @@
|
||||||
|
|
||||||
package org.microg.gms.maps.mapbox
|
package org.microg.gms.maps.mapbox
|
||||||
|
|
||||||
|
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.Parcel
|
import android.os.Parcel
|
||||||
import android.os.RemoteException
|
|
||||||
import android.support.annotation.IdRes
|
import android.support.annotation.IdRes
|
||||||
import android.support.annotation.Keep
|
import android.support.annotation.Keep
|
||||||
import android.support.v4.util.LongSparseArray
|
import android.support.v4.util.LongSparseArray
|
||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.view.Gravity
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.RelativeLayout
|
||||||
import com.google.android.gms.dynamic.IObjectWrapper
|
import com.google.android.gms.dynamic.IObjectWrapper
|
||||||
import com.google.android.gms.maps.GoogleMapOptions
|
import com.google.android.gms.maps.GoogleMapOptions
|
||||||
import com.google.android.gms.maps.internal.*
|
import com.google.android.gms.maps.internal.*
|
||||||
|
@ -38,6 +40,7 @@ import com.mapbox.mapboxsdk.LibraryLoader
|
||||||
import com.mapbox.mapboxsdk.Mapbox
|
import com.mapbox.mapboxsdk.Mapbox
|
||||||
import com.mapbox.mapboxsdk.R
|
import com.mapbox.mapboxsdk.R
|
||||||
import com.mapbox.mapboxsdk.camera.CameraUpdate
|
import com.mapbox.mapboxsdk.camera.CameraUpdate
|
||||||
|
import com.mapbox.mapboxsdk.constants.MapboxConstants
|
||||||
import com.mapbox.mapboxsdk.maps.MapView
|
import com.mapbox.mapboxsdk.maps.MapView
|
||||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||||
import com.mapbox.mapboxsdk.maps.Style
|
import com.mapbox.mapboxsdk.maps.Style
|
||||||
|
@ -53,9 +56,9 @@ import org.microg.gms.maps.mapbox.utils.MultiArchLoader
|
||||||
import org.microg.gms.maps.mapbox.utils.toGms
|
import org.microg.gms.maps.mapbox.utils.toGms
|
||||||
import org.microg.gms.maps.mapbox.utils.toMapbox
|
import org.microg.gms.maps.mapbox.utils.toMapbox
|
||||||
|
|
||||||
fun <T : Any> LongSparseArray<T>.values() = (0..size()).map { valueAt(it) }.mapNotNull { it }
|
private fun <T : Any> LongSparseArray<T>.values() = (0..size()).map { valueAt(it) }.mapNotNull { it }
|
||||||
|
|
||||||
class GoogleMapImpl(private val context: Context, private val options: GoogleMapOptions) : IGoogleMapDelegate.Stub() {
|
class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) : IGoogleMapDelegate.Stub() {
|
||||||
|
|
||||||
val view: FrameLayout
|
val view: FrameLayout
|
||||||
var map: MapboxMap? = null
|
var map: MapboxMap? = null
|
||||||
|
@ -64,10 +67,10 @@ class GoogleMapImpl(private val context: Context, private val options: GoogleMap
|
||||||
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?
|
||||||
|
private var created = false
|
||||||
private var initialized = false
|
private var initialized = false
|
||||||
private val initializedCallbackList = mutableListOf<IOnMapReadyCallback>()
|
private val initializedCallbackList = mutableListOf<IOnMapReadyCallback>()
|
||||||
private val mapLock = Object()
|
private val mapLock = Object()
|
||||||
val markers = mutableMapOf<Long, MarkerImpl>()
|
|
||||||
|
|
||||||
private var cameraChangeListener: IOnCameraChangeListener? = null
|
private var cameraChangeListener: IOnCameraChangeListener? = null
|
||||||
private var cameraMoveListener: IOnCameraMoveListener? = null
|
private var cameraMoveListener: IOnCameraMoveListener? = null
|
||||||
|
@ -79,47 +82,130 @@ class GoogleMapImpl(private val context: Context, private val options: GoogleMap
|
||||||
private var markerClickListener: IOnMarkerClickListener? = null
|
private var markerClickListener: IOnMarkerClickListener? = null
|
||||||
private var markerDragListener: IOnMarkerDragListener? = null
|
private var markerDragListener: IOnMarkerDragListener? = null
|
||||||
|
|
||||||
var circleManager: CircleManager? = null
|
|
||||||
var lineManager: LineManager? = null
|
var lineManager: LineManager? = null
|
||||||
var fillManager: FillManager? = null
|
var fillManager: FillManager? = null
|
||||||
|
|
||||||
|
var circleManager: CircleManager? = null
|
||||||
|
val pendingCircles = mutableSetOf<CircleImpl>()
|
||||||
|
var circleId = 0L
|
||||||
|
|
||||||
var symbolManager: SymbolManager? = null
|
var symbolManager: SymbolManager? = null
|
||||||
var storedMapType: Int = MAP_TYPE_NORMAL
|
val pendingMarkers = mutableSetOf<MarkerImpl>()
|
||||||
|
val markers = mutableMapOf<Long, MarkerImpl>()
|
||||||
|
var markerId = 0L
|
||||||
|
|
||||||
|
var storedMapType: Int = options.mapType
|
||||||
|
val waitingCameraUpdates = mutableListOf<CameraUpdate>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val mapContext = MapContext(context)
|
val mapContext = MapContext(context)
|
||||||
LibraryLoader.setLibraryLoader(MultiArchLoader(mapContext, context))
|
LibraryLoader.setLibraryLoader(MultiArchLoader(mapContext, context))
|
||||||
Mapbox.getInstance(mapContext, BuildConfig.MAPBOX_KEY)
|
Mapbox.getInstance(mapContext, BuildConfig.MAPBOX_KEY)
|
||||||
|
|
||||||
|
val fakeWatermark = View(mapContext)
|
||||||
|
fakeWatermark.layoutParams = object : RelativeLayout.LayoutParams(0, 0) {
|
||||||
|
@SuppressLint("RtlHardcoded")
|
||||||
|
override fun addRule(verb: Int, subject: Int) {
|
||||||
|
super.addRule(verb, subject)
|
||||||
|
val rules = this.rules
|
||||||
|
var gravity = 0
|
||||||
|
if (rules[RelativeLayout.ALIGN_PARENT_BOTTOM] == RelativeLayout.TRUE) gravity = gravity or Gravity.BOTTOM
|
||||||
|
if (rules[RelativeLayout.ALIGN_PARENT_TOP] == RelativeLayout.TRUE) gravity = gravity or Gravity.TOP
|
||||||
|
if (rules[RelativeLayout.ALIGN_PARENT_LEFT] == RelativeLayout.TRUE) gravity = gravity or Gravity.LEFT
|
||||||
|
if (rules[RelativeLayout.ALIGN_PARENT_RIGHT] == RelativeLayout.TRUE) gravity = gravity or Gravity.RIGHT
|
||||||
|
if (rules[RelativeLayout.ALIGN_PARENT_START] == RelativeLayout.TRUE) gravity = gravity or Gravity.START
|
||||||
|
if (rules[RelativeLayout.ALIGN_PARENT_END] == RelativeLayout.TRUE) gravity = gravity or Gravity.END
|
||||||
|
map?.uiSettings?.logoGravity = gravity
|
||||||
|
}
|
||||||
|
}
|
||||||
this.view = object : FrameLayout(mapContext) {
|
this.view = object : FrameLayout(mapContext) {
|
||||||
@Keep
|
@Keep
|
||||||
fun <T : View> findViewTraversal(@IdRes id: Int): T? {
|
fun <T : View> findViewTraversal(@IdRes id: Int): T? {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Keep
|
||||||
|
fun <T : View> findViewWithTagTraversal(tag: Any): T? {
|
||||||
|
if ("GoogleWatermark" == tag) {
|
||||||
|
return try {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
fakeWatermark as T
|
||||||
|
} catch (e: ClassCastException) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.mapView = MapView(mapContext)
|
this.mapView = MapView(mapContext)
|
||||||
this.view.addView(this.mapView)
|
this.view.addView(this.mapView)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getCameraPosition(): CameraPosition? = map?.cameraPosition?.toGms()
|
override fun getCameraPosition(): CameraPosition? = map?.cameraPosition?.toGms()
|
||||||
override fun getMaxZoomLevel(): Float = map?.maxZoomLevel?.toFloat() ?: 20f
|
override fun getMaxZoomLevel(): Float = (map?.maxZoomLevel?.toFloat() ?: 20f) + 1f
|
||||||
override fun getMinZoomLevel(): Float = map?.minZoomLevel?.toFloat() ?: 1f
|
override fun getMinZoomLevel(): Float = (map?.minZoomLevel?.toFloat() ?: 0f) + 1f
|
||||||
|
|
||||||
override fun moveCamera(cameraUpdate: IObjectWrapper?) =
|
override fun moveCamera(cameraUpdate: IObjectWrapper?) {
|
||||||
cameraUpdate.unwrap<CameraUpdate>()?.let { map?.moveCamera(it) } ?: Unit
|
val update = cameraUpdate.unwrap<CameraUpdate>() ?: return
|
||||||
|
val map = this.map
|
||||||
|
if (map != null) {
|
||||||
|
map.moveCamera(update)
|
||||||
|
} else {
|
||||||
|
waitingCameraUpdates.add(update)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun animateCamera(cameraUpdate: IObjectWrapper?) =
|
override fun animateCamera(cameraUpdate: IObjectWrapper?) {
|
||||||
cameraUpdate.unwrap<CameraUpdate>()?.let { map?.animateCamera(it) } ?: Unit
|
val update = cameraUpdate.unwrap<CameraUpdate>() ?: return
|
||||||
|
val map = this.map
|
||||||
|
if (map != null) {
|
||||||
|
map.animateCamera(update)
|
||||||
|
} else {
|
||||||
|
waitingCameraUpdates.add(update)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun animateCameraWithCallback(cameraUpdate: IObjectWrapper?, callback: ICancelableCallback?) =
|
override fun animateCameraWithCallback(cameraUpdate: IObjectWrapper?, callback: ICancelableCallback?) {
|
||||||
cameraUpdate.unwrap<CameraUpdate>()?.let { map?.animateCamera(it, callback?.toMapbox()) }
|
val update = cameraUpdate.unwrap<CameraUpdate>() ?: return
|
||||||
?: Unit
|
val map = this.map
|
||||||
|
if (map != null) {
|
||||||
|
map.animateCamera(update, callback?.toMapbox())
|
||||||
|
} else {
|
||||||
|
waitingCameraUpdates.add(update)
|
||||||
|
callback?.onFinish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun animateCameraWithDurationAndCallback(cameraUpdate: IObjectWrapper?, duration: Int, callback: ICancelableCallback?) =
|
override fun animateCameraWithDurationAndCallback(cameraUpdate: IObjectWrapper?, duration: Int, callback: ICancelableCallback?) {
|
||||||
cameraUpdate.unwrap<CameraUpdate>()?.let { map?.animateCamera(it, duration, callback?.toMapbox()) }
|
val update = cameraUpdate.unwrap<CameraUpdate>() ?: return
|
||||||
?: Unit
|
val map = this.map
|
||||||
|
if (map != null) {
|
||||||
|
map.animateCamera(update, duration, callback?.toMapbox())
|
||||||
|
} else {
|
||||||
|
waitingCameraUpdates.add(update)
|
||||||
|
callback?.onFinish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun stopAnimation() = map?.cancelTransitions() ?: Unit
|
override fun stopAnimation() = map?.cancelTransitions() ?: Unit
|
||||||
|
|
||||||
|
override fun setMinZoomPreference(minZoom: Float) {
|
||||||
|
map?.setMinZoomPreference(minZoom.toDouble() - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setMaxZoomPreference(maxZoom: Float) {
|
||||||
|
map?.setMaxZoomPreference(maxZoom.toDouble() - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun resetMinMaxZoomPreference() {
|
||||||
|
map?.setMinZoomPreference(MapboxConstants.MINIMUM_ZOOM.toDouble())
|
||||||
|
map?.setMaxZoomPreference(MapboxConstants.MAXIMUM_ZOOM.toDouble())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setLatLngBoundsForCameraTarget(bounds: LatLngBounds?) {
|
||||||
|
map?.setLatLngBoundsForCameraTarget(bounds?.toMapbox())
|
||||||
|
}
|
||||||
|
|
||||||
override fun addPolyline(options: PolylineOptions): IPolylineDelegate? {
|
override fun addPolyline(options: PolylineOptions): IPolylineDelegate? {
|
||||||
val lineOptions = LineOptions()
|
val lineOptions = LineOptions()
|
||||||
.withLatLngs(options.points.map { it.toMapbox() })
|
.withLatLngs(options.points.map { it.toMapbox() })
|
||||||
|
@ -131,26 +217,23 @@ class GoogleMapImpl(private val context: Context, private val options: GoogleMap
|
||||||
|
|
||||||
|
|
||||||
override fun addPolygon(options: PolygonOptions): IPolygonDelegate? {
|
override fun addPolygon(options: PolygonOptions): IPolygonDelegate? {
|
||||||
Log.d(TAG, "unimplemented Method: addPolygon")
|
val fillOptions = FillOptions()
|
||||||
return null
|
.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)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addMarker(options: MarkerOptions): IMarkerDelegate? {
|
override fun addMarker(options: MarkerOptions): IMarkerDelegate? {
|
||||||
var intBits = java.lang.Float.floatToIntBits(options.zIndex)
|
val marker = MarkerImpl(this, "m${markerId++}", options)
|
||||||
if (intBits < 0) intBits = intBits xor 0x7fffffff
|
synchronized(this) {
|
||||||
|
val symbolManager = symbolManager
|
||||||
val symbolOptions = SymbolOptions()
|
if (symbolManager == null) {
|
||||||
.withIconOpacity(if (options.isVisible) options.alpha else 0f)
|
pendingMarkers.add(marker)
|
||||||
.withIconRotate(options.rotation)
|
} else {
|
||||||
.withZIndex(intBits)
|
marker.update(symbolManager)
|
||||||
.withDraggable(options.isDraggable)
|
}
|
||||||
|
}
|
||||||
options.position?.let { symbolOptions.withLatLng(it.toMapbox()) }
|
|
||||||
options.icon?.remoteObject.unwrap<BitmapDescriptorImpl>()?.applyTo(symbolOptions, floatArrayOf(options.anchorU, options.anchorV), dpiFactor)
|
|
||||||
|
|
||||||
val symbol = symbolManager?.create(symbolOptions) ?: return null
|
|
||||||
val marker = MarkerImpl(this, symbol, floatArrayOf(options.anchorU, options.anchorV), options.icon?.remoteObject.unwrap<BitmapDescriptorImpl>(), options.alpha, options.title, options.snippet)
|
|
||||||
markers.put(symbol.id, marker)
|
|
||||||
return marker
|
return marker
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,16 +248,16 @@ class GoogleMapImpl(private val context: Context, private val options: GoogleMap
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addCircle(options: CircleOptions): ICircleDelegate? {
|
override fun addCircle(options: CircleOptions): ICircleDelegate? {
|
||||||
val circleOptions = com.mapbox.mapboxsdk.plugins.annotation.CircleOptions()
|
val circle = CircleImpl(this, "c${circleId++}", options)
|
||||||
.withLatLng(options.center.toMapbox())
|
synchronized(this) {
|
||||||
.withCircleColor(ColorUtils.colorToRgbaString(options.fillColor))
|
val circleManager = circleManager
|
||||||
.withCircleRadius(options.radius.toFloat())
|
if (circleManager == null) {
|
||||||
.withCircleStrokeColor(ColorUtils.colorToRgbaString(options.strokeColor))
|
pendingCircles.add(circle)
|
||||||
.withCircleStrokeWidth(options.strokeWidth / dpiFactor)
|
} else {
|
||||||
.withCircleOpacity(if (options.isVisible) 1f else 0f)
|
circle.update(circleManager)
|
||||||
.withCircleStrokeOpacity(if (options.isVisible) 1f else 0f)
|
}
|
||||||
|
}
|
||||||
return circleManager?.let { CircleImpl(this, it.create(circleOptions)) }
|
return circle
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun clear() {
|
override fun clear() {
|
||||||
|
@ -208,20 +291,27 @@ class GoogleMapImpl(private val context: Context, private val options: GoogleMap
|
||||||
val fills = fillManager?.annotations?.values()
|
val fills = fillManager?.annotations?.values()
|
||||||
val symbols = symbolManager?.annotations?.values()
|
val symbols = symbolManager?.annotations?.values()
|
||||||
val update: (Style) -> Unit = {
|
val update: (Style) -> Unit = {
|
||||||
circles?.let { circleManager?.update(it) }
|
circles?.let { runCatching { circleManager?.update(it) } }
|
||||||
lines?.let { lineManager?.update(it) }
|
lines?.let { runCatching { lineManager?.update(it) } }
|
||||||
fills?.let { fillManager?.update(it) }
|
fills?.let { runCatching { fillManager?.update(it) } }
|
||||||
symbols?.let { symbolManager?.update(it) }
|
symbols?.let { runCatching { symbolManager?.update(it) } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Serve map styles locally
|
||||||
when (storedMapType) {
|
when (storedMapType) {
|
||||||
MAP_TYPE_NORMAL -> map?.setStyle(Style.Builder().fromUrl("mapbox://styles/microg/cjui4020201oo1fmca7yuwbor"), update)
|
MAP_TYPE_SATELLITE -> map?.setStyle(Style.Builder().fromUrl("mapbox://styles/microg/cjxgloted25ap1ct4uex7m6hi"), update)
|
||||||
MAP_TYPE_SATELLITE -> map?.setStyle(Style.SATELLITE, update)
|
|
||||||
MAP_TYPE_TERRAIN -> map?.setStyle(Style.OUTDOORS, update)
|
MAP_TYPE_TERRAIN -> map?.setStyle(Style.OUTDOORS, update)
|
||||||
MAP_TYPE_HYBRID -> map?.setStyle(Style.SATELLITE_STREETS, update)
|
MAP_TYPE_HYBRID -> map?.setStyle(Style.Builder().fromUrl("mapbox://styles/microg/cjxgloted25ap1ct4uex7m6hi"), update)
|
||||||
else -> map?.setStyle(Style.LIGHT, update)
|
//MAP_TYPE_NONE, MAP_TYPE_NORMAL,
|
||||||
|
else -> map?.setStyle(Style.Builder().fromUrl("mapbox://styles/microg/cjui4020201oo1fmca7yuwbor"), update)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
map?.let { BitmapDescriptorFactoryImpl.registerMap(it) }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setWatermarkEnabled(watermark: Boolean) {
|
||||||
|
map?.uiSettings?.isLogoEnabled = watermark
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isTrafficEnabled(): Boolean {
|
override fun isTrafficEnabled(): Boolean {
|
||||||
|
@ -261,7 +351,10 @@ class GoogleMapImpl(private val context: Context, private val options: GoogleMap
|
||||||
|
|
||||||
override fun setLocationSource(locationSource: ILocationSourceDelegate) {
|
override fun setLocationSource(locationSource: ILocationSourceDelegate) {
|
||||||
Log.d(TAG, "unimplemented Method: setLocationSource")
|
Log.d(TAG, "unimplemented Method: setLocationSource")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setContentDescription(desc: String?) {
|
||||||
|
mapView?.contentDescription = desc
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getUiSettings(): IUiSettingsDelegate? = map?.uiSettings?.let { UiSettingsImpl(it) }
|
override fun getUiSettings(): IUiSettingsDelegate? = map?.uiSettings?.let { UiSettingsImpl(it) }
|
||||||
|
@ -360,80 +453,159 @@ class GoogleMapImpl(private val context: Context, private val options: GoogleMap
|
||||||
cameraIdleListener = listener
|
cameraIdleListener = listener
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
mapView?.onCreate(savedInstanceState?.toMapbox())
|
if (!created) {
|
||||||
mapView?.getMapAsync(this::initMap)
|
mapView?.onCreate(savedInstanceState?.toMapbox())
|
||||||
|
mapView?.getMapAsync(this::initMap)
|
||||||
|
created = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun hasSymbolAt(latlng: com.mapbox.mapboxsdk.geometry.LatLng): Boolean {
|
private fun hasSymbolAt(latlng: com.mapbox.mapboxsdk.geometry.LatLng): Boolean {
|
||||||
val point = map?.projection?.toScreenLocation(latlng) ?: return false
|
val point = map?.projection?.toScreenLocation(latlng) ?: return false
|
||||||
val features = map?.queryRenderedFeatures(point, SymbolManager.ID_GEOJSON_LAYER)
|
val features = map?.queryRenderedFeatures(point, SymbolManager.ID_GEOJSON_LAYER)
|
||||||
?: return false
|
?: return false
|
||||||
return !features.isEmpty()
|
return features.isNotEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initMap(map: MapboxMap) {
|
private fun initMap(map: MapboxMap) {
|
||||||
if (this.map != null) return
|
if (this.map != null) return
|
||||||
this.map = map
|
this.map = map
|
||||||
|
|
||||||
|
map.addOnCameraIdleListener {
|
||||||
|
try {
|
||||||
|
cameraChangeListener?.onCameraChange(map.cameraPosition.toGms())
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
map.addOnCameraIdleListener {
|
||||||
|
try {
|
||||||
|
cameraIdleListener?.onCameraIdle()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
map.addOnCameraMoveListener {
|
||||||
|
try {
|
||||||
|
cameraMoveListener?.onCameraMove()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
map.addOnCameraMoveStartedListener {
|
||||||
|
try {
|
||||||
|
cameraMoveStartedListener?.onCameraMoveStarted(it)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
map.addOnCameraMoveCancelListener {
|
||||||
|
try {
|
||||||
|
cameraMoveCanceledListener?.onCameraMoveCanceled()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
map.addOnMapClickListener { latlng ->
|
||||||
|
try {
|
||||||
|
mapClickListener?.let { if (!hasSymbolAt(latlng)) it.onMapClick(latlng.toGms()); }
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, e)
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
map.addOnMapLongClickListener { latlng ->
|
||||||
|
try {
|
||||||
|
mapLongClickListener?.let { if (!hasSymbolAt(latlng)) it.onMapLongClick(latlng.toGms()); }
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, e)
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
applyMapType()
|
applyMapType()
|
||||||
|
options.minZoomPreference?.let { if (it != 0f) map.setMinZoomPreference(it.toDouble()) }
|
||||||
|
options.maxZoomPreference?.let { if (it != 0f) map.setMaxZoomPreference(it.toDouble()) }
|
||||||
|
options.latLngBoundsForCameraTarget?.let { map.setLatLngBoundsForCameraTarget(it.toMapbox()) }
|
||||||
|
options.compassEnabled?.let { map.uiSettings.isCompassEnabled = it }
|
||||||
|
options.rotateGesturesEnabled?.let { map.uiSettings.isRotateGesturesEnabled = it }
|
||||||
|
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) {
|
||||||
|
Log.d(TAG, "Invoking ${initializedCallbackList.size} callbacks delayed, as map is initialized")
|
||||||
|
for (callback in initializedCallbackList) {
|
||||||
|
try {
|
||||||
|
callback.onMapReady(this)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
initialized = true
|
||||||
|
}
|
||||||
|
|
||||||
map.getStyle {
|
map.getStyle {
|
||||||
mapView?.let { view ->
|
mapView?.let { view ->
|
||||||
BitmapDescriptorFactoryImpl.registerMap(map)
|
|
||||||
circleManager = CircleManager(view, map, it)
|
circleManager = CircleManager(view, map, it)
|
||||||
lineManager = LineManager(view, map, it)
|
lineManager = LineManager(view, map, it)
|
||||||
lineManager?.lineCap = LINE_CAP_ROUND
|
|
||||||
fillManager = FillManager(view, map, it)
|
fillManager = FillManager(view, map, it)
|
||||||
symbolManager = SymbolManager(view, map, it)
|
lineManager?.lineCap = LINE_CAP_ROUND
|
||||||
|
synchronized(this) {
|
||||||
|
val symbolManager = SymbolManager(view, map, it)
|
||||||
|
pendingMarkers.forEach { it.update(symbolManager) }
|
||||||
|
pendingMarkers.clear()
|
||||||
|
this.symbolManager = symbolManager
|
||||||
|
}
|
||||||
symbolManager?.iconAllowOverlap = true
|
symbolManager?.iconAllowOverlap = true
|
||||||
symbolManager?.addClickListener { markers[it.id]?.let { markerClickListener?.onMarkerClick(it) } }
|
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?) {
|
override fun onAnnotationDragStarted(annotation: Symbol?) {
|
||||||
markers[annotation?.id]?.let { markerDragListener?.onMarkerDragStart(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onAnnotationDrag(annotation: Symbol?) {
|
|
||||||
markers[annotation?.id]?.let { markerDragListener?.onMarkerDrag(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onAnnotationDragFinished(annotation: Symbol?) {
|
|
||||||
markers[annotation?.id]?.let { markerDragListener?.onMarkerDragEnd(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
map.addOnCameraIdleListener { cameraChangeListener?.onCameraChange(map.cameraPosition.toGms()) }
|
|
||||||
map.addOnCameraIdleListener { cameraIdleListener?.onCameraIdle() }
|
|
||||||
map.addOnCameraMoveListener { cameraMoveListener?.onCameraMove() }
|
|
||||||
map.addOnCameraMoveStartedListener { cameraMoveStartedListener?.onCameraMoveStarted(it) }
|
|
||||||
map.addOnCameraMoveCancelListener { cameraMoveCanceledListener?.onCameraMoveCanceled() }
|
|
||||||
map.addOnMapClickListener {
|
|
||||||
val latlng = it
|
|
||||||
mapClickListener?.let { if (!hasSymbolAt(latlng)) it.onMapClick(latlng.toGms()); }
|
|
||||||
false
|
|
||||||
}
|
|
||||||
map.addOnMapLongClickListener {
|
|
||||||
val latlng = it
|
|
||||||
mapLongClickListener?.let { if (!hasSymbolAt(latlng)) it.onMapLongClick(latlng.toGms()); }
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized(mapLock) {
|
|
||||||
for (callback in initializedCallbackList) {
|
|
||||||
try {
|
try {
|
||||||
callback.onMapReady(this)
|
markers[annotation?.id]?.let { markerDragListener?.onMarkerDragStart(it) }
|
||||||
} catch (e: RemoteException) {
|
} catch (e: Exception) {
|
||||||
Log.w(TAG, e)
|
Log.w(TAG, e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
initialized = true
|
|
||||||
}
|
override fun onAnnotationDrag(annotation: Symbol?) {
|
||||||
|
try {
|
||||||
|
markers[annotation?.id]?.let { markerDragListener?.onMarkerDrag(it) }
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAnnotationDragFinished(annotation: Symbol?) {
|
||||||
|
try {
|
||||||
|
markers[annotation?.id]?.let { markerDragListener?.onMarkerDragEnd(it) }
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onResume() = mapView?.onResume()
|
override fun useViewLifecycleWhenInFragment(): Boolean {
|
||||||
fun onPause() = mapView?.onPause()
|
Log.d(TAG, "unimplemented Method: useViewLifecycleWhenInFragment")
|
||||||
fun onDestroy() {
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() = mapView?.onResume() ?: Unit
|
||||||
|
override fun onPause() = mapView?.onPause() ?: Unit
|
||||||
|
override fun onDestroy() {
|
||||||
circleManager?.onDestroy()
|
circleManager?.onDestroy()
|
||||||
circleManager = null
|
circleManager = null
|
||||||
lineManager?.onDestroy()
|
lineManager?.onDestroy()
|
||||||
|
@ -442,6 +614,8 @@ class GoogleMapImpl(private val context: Context, private val options: GoogleMap
|
||||||
fillManager = null
|
fillManager = null
|
||||||
symbolManager?.onDestroy()
|
symbolManager?.onDestroy()
|
||||||
symbolManager = null
|
symbolManager = null
|
||||||
|
pendingMarkers.clear()
|
||||||
|
markers.clear()
|
||||||
BitmapDescriptorFactoryImpl.unregisterMap(map)
|
BitmapDescriptorFactoryImpl.unregisterMap(map)
|
||||||
view.removeView(mapView)
|
view.removeView(mapView)
|
||||||
// TODO can crash?
|
// TODO can crash?
|
||||||
|
@ -449,8 +623,24 @@ class GoogleMapImpl(private val context: Context, private val options: GoogleMap
|
||||||
mapView = null
|
mapView = null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onLowMemory() = mapView?.onLowMemory()
|
override fun onStart() {
|
||||||
fun onSaveInstanceState(outState: Bundle) {
|
Log.d(TAG, "unimplemented Method: onStart")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
Log.d(TAG, "unimplemented Method: onStop")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onEnterAmbient(bundle: Bundle?) {
|
||||||
|
Log.d(TAG, "unimplemented Method: onEnterAmbient")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onExitAmbient() {
|
||||||
|
Log.d(TAG, "unimplemented Method: onExitAmbient")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLowMemory() = mapView?.onLowMemory() ?: Unit
|
||||||
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
val newBundle = Bundle()
|
val newBundle = Bundle()
|
||||||
mapView?.onSaveInstanceState(newBundle)
|
mapView?.onSaveInstanceState(newBundle)
|
||||||
outState.putAll(newBundle.toGms())
|
outState.putAll(newBundle.toGms())
|
||||||
|
@ -459,8 +649,14 @@ class GoogleMapImpl(private val context: Context, private val options: GoogleMap
|
||||||
fun getMapAsync(callback: IOnMapReadyCallback) {
|
fun getMapAsync(callback: IOnMapReadyCallback) {
|
||||||
synchronized(mapLock) {
|
synchronized(mapLock) {
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
callback.onMapReady(this)
|
Log.d(TAG, "Invoking callback instantly, as map is initialized")
|
||||||
|
try {
|
||||||
|
callback.onMapReady(this)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, e)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
Log.d(TAG, "Delay callback invocation, as map is not yet initialized")
|
||||||
initializedCallbackList.add(callback)
|
initializedCallbackList.add(callback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,9 @@ package org.microg.gms.maps.mapbox
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Parcel
|
import android.os.Parcel
|
||||||
|
import android.util.Base64
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
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
|
||||||
|
@ -34,32 +36,42 @@ class MapFragmentImpl(private val activity: Activity) : IMapFragmentDelegate.Stu
|
||||||
private var options: GoogleMapOptions? = null
|
private var options: GoogleMapOptions? = null
|
||||||
|
|
||||||
override fun onInflate(activity: IObjectWrapper, options: GoogleMapOptions, savedInstanceState: Bundle) {
|
override fun onInflate(activity: IObjectWrapper, options: GoogleMapOptions, savedInstanceState: Bundle) {
|
||||||
|
Log.d(TAG, "onInflate: ${options.camera.target}")
|
||||||
this.options = options
|
this.options = options
|
||||||
|
map?.options = options
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
if (options == null) {
|
if (options == null) {
|
||||||
options = savedInstanceState.getParcelable("MapOptions")
|
options = savedInstanceState?.getParcelable("MapOptions")
|
||||||
}
|
}
|
||||||
if (options == null) {
|
if (options == null) {
|
||||||
options = GoogleMapOptions()
|
options = GoogleMapOptions()
|
||||||
}
|
}
|
||||||
|
Log.d(TAG, "onCreate: ${options?.camera?.target}")
|
||||||
|
map = GoogleMapImpl(activity, options ?: GoogleMapOptions())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(layoutInflater: IObjectWrapper, container: IObjectWrapper, savedInstanceState: Bundle?): IObjectWrapper {
|
override fun onCreateView(layoutInflater: IObjectWrapper, container: IObjectWrapper, savedInstanceState: Bundle?): IObjectWrapper {
|
||||||
|
if (options == null) {
|
||||||
|
options = savedInstanceState?.getParcelable("MapOptions")
|
||||||
|
}
|
||||||
|
Log.d(TAG, "onCreateView: ${options?.camera?.target}")
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
map = GoogleMapImpl(activity, options ?: GoogleMapOptions())
|
map = GoogleMapImpl(activity, options ?: GoogleMapOptions())
|
||||||
map!!.onCreate(savedInstanceState)
|
|
||||||
return ObjectWrapper.wrap(map!!.view)
|
|
||||||
} else {
|
|
||||||
val view = map!!.view
|
|
||||||
val parent = view.parent as ViewGroup
|
|
||||||
parent.removeView(view)
|
|
||||||
return ObjectWrapper.wrap(view)
|
|
||||||
}
|
}
|
||||||
|
map!!.onCreate(savedInstanceState)
|
||||||
|
val view = map!!.view
|
||||||
|
val parent = view.parent as ViewGroup?
|
||||||
|
parent?.removeView(view)
|
||||||
|
return ObjectWrapper.wrap(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMap(): IGoogleMapDelegate? = map
|
override fun getMap(): IGoogleMapDelegate? = map
|
||||||
|
override fun onEnterAmbient(bundle: Bundle?) = map?.onEnterAmbient(bundle) ?: Unit
|
||||||
|
override fun onExitAmbient() = map?.onExitAmbient() ?: Unit
|
||||||
|
override fun onStart() = map?.onStart() ?: Unit
|
||||||
|
override fun onStop() = map?.onStop() ?: Unit
|
||||||
override fun onResume() = map?.onResume() ?: Unit
|
override fun onResume() = map?.onResume() ?: Unit
|
||||||
override fun onPause() = map?.onPause() ?: Unit
|
override fun onPause() = map?.onPause() ?: Unit
|
||||||
override fun onLowMemory() = map?.onLowMemory() ?: Unit
|
override fun onLowMemory() = map?.onLowMemory() ?: Unit
|
||||||
|
@ -84,12 +96,14 @@ class MapFragmentImpl(private val activity: Activity) : IMapFragmentDelegate.Stu
|
||||||
map?.onSaveInstanceState(outState)
|
map?.onSaveInstanceState(outState)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)) {
|
||||||
true
|
return true
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false
|
Log.d(TAG, "onTransact [unknown]: $code, $data, $flags")
|
||||||
}
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val TAG = "GmsMapFragment"
|
private val TAG = "GmsMapFragment"
|
||||||
|
|
|
@ -28,25 +28,28 @@ import com.google.android.gms.maps.internal.IMapViewDelegate
|
||||||
import com.google.android.gms.maps.internal.IOnMapReadyCallback
|
import com.google.android.gms.maps.internal.IOnMapReadyCallback
|
||||||
|
|
||||||
class MapViewImpl(private val context: Context, options: GoogleMapOptions?) : IMapViewDelegate.Stub() {
|
class MapViewImpl(private val context: Context, options: GoogleMapOptions?) : IMapViewDelegate.Stub() {
|
||||||
private val options: GoogleMapOptions
|
|
||||||
|
private val options: GoogleMapOptions = options ?: GoogleMapOptions()
|
||||||
private var map: GoogleMapImpl? = null
|
private var map: GoogleMapImpl? = null
|
||||||
|
|
||||||
init {
|
|
||||||
this.options = options ?: GoogleMapOptions()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
Log.d(TAG, "onCreate: ${options?.camera?.target}")
|
||||||
map = GoogleMapImpl(context, options)
|
map = GoogleMapImpl(context, options)
|
||||||
map?.onCreate(savedInstanceState)
|
map!!.onCreate(savedInstanceState)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMap(): IGoogleMapDelegate? = map
|
override fun getMap(): IGoogleMapDelegate? = map
|
||||||
|
override fun onEnterAmbient(bundle: Bundle?) = map?.onEnterAmbient(bundle) ?: Unit
|
||||||
|
override fun onExitAmbient() = map?.onExitAmbient() ?: Unit
|
||||||
|
override fun onStart() = map?.onStart() ?: Unit
|
||||||
|
override fun onStop() = map?.onStop() ?: Unit
|
||||||
override fun onResume() = map?.onResume() ?: Unit
|
override fun onResume() = map?.onResume() ?: Unit
|
||||||
override fun onPause() = map?.onPause() ?: Unit
|
override fun onPause() = map?.onPause() ?: Unit
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
map?.onDestroy()
|
map?.onDestroy()
|
||||||
map = null
|
map = null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLowMemory() = map?.onLowMemory() ?: Unit
|
override fun onLowMemory() = map?.onLowMemory() ?: Unit
|
||||||
override fun onSaveInstanceState(outState: Bundle) = map?.onSaveInstanceState(outState) ?: Unit
|
override fun onSaveInstanceState(outState: Bundle) = map?.onSaveInstanceState(outState) ?: Unit
|
||||||
override fun getView(): IObjectWrapper = ObjectWrapper.wrap(map?.view)
|
override fun getView(): IObjectWrapper = ObjectWrapper.wrap(map?.view)
|
||||||
|
|
|
@ -30,16 +30,21 @@ 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 ProjectionImpl(private val projection: Projection) : IProjectionDelegate.Stub() {
|
class ProjectionImpl(private val projection: Projection) : IProjectionDelegate.Stub() {
|
||||||
|
private val visibleRegion = projection.visibleRegion
|
||||||
|
private val farLeft = projection.toScreenLocation(visibleRegion.farLeft)
|
||||||
|
private val farRight = projection.toScreenLocation(visibleRegion.farRight)
|
||||||
|
private val nearLeft = projection.toScreenLocation(visibleRegion.nearLeft)
|
||||||
|
private val nearRight = projection.toScreenLocation(visibleRegion.nearRight)
|
||||||
|
|
||||||
override fun fromScreenLocation(obj: IObjectWrapper?): LatLng? =
|
override fun fromScreenLocation(obj: IObjectWrapper?): LatLng? =
|
||||||
obj.unwrap<Point>()?.let { projection.fromScreenLocation(PointF(it)) }?.toGms()
|
obj.unwrap<Point>()?.let { projection.fromScreenLocation(PointF(it)) }?.toGms()
|
||||||
|
|
||||||
override fun toScreenLocation(latLng: LatLng?): IObjectWrapper =
|
override fun toScreenLocation(latLng: LatLng?): IObjectWrapper = try {
|
||||||
ObjectWrapper.wrap(latLng?.toMapbox()?.let { projection.toScreenLocation(it) }?.let { Point(it.x.toInt(), it.y.toInt()) })
|
ObjectWrapper.wrap(latLng?.toMapbox()?.let { projection.toScreenLocation(it) }?.let { Point(it.x.toInt(), it.y.toInt()) })
|
||||||
|
|
||||||
override fun getVisibleRegion(): VisibleRegion = try {
|
|
||||||
projection.visibleRegion.toGms()
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
VisibleRegion(LatLngBounds(LatLng(0.0, 0.0), LatLng(0.0, 0.0)))
|
ObjectWrapper.wrap(Point(0, 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getVisibleRegion(): VisibleRegion = visibleRegion.toGms()
|
||||||
|
|
||||||
}
|
}
|
|
@ -78,6 +78,33 @@ class UiSettingsImpl(private val uiSettings: UiSettings) : IUiSettingsDelegate.S
|
||||||
|
|
||||||
override fun isRotateGesturesEnabled(): Boolean = uiSettings.isRotateGesturesEnabled
|
override fun isRotateGesturesEnabled(): Boolean = uiSettings.isRotateGesturesEnabled
|
||||||
|
|
||||||
|
override fun setIndoorLevelPickerEnabled(indoorLevelPicker: Boolean) {
|
||||||
|
Log.d(TAG, "unimplemented Method: setIndoorLevelPickerEnabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isIndoorLevelPickerEnabled(): Boolean {
|
||||||
|
Log.d(TAG, "unimplemented Method: isIndoorLevelPickerEnabled")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setMapToolbarEnabled(mapToolbar: Boolean) {
|
||||||
|
Log.d(TAG, "unimplemented Method: setMapToolbarEnabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isMapToolbarEnabled(): Boolean {
|
||||||
|
Log.d(TAG, "unimplemented Method: isMapToolbarEnabled")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setScrollGesturesEnabledDuringRotateOrZoom(scrollDuringZoom: Boolean) {
|
||||||
|
Log.d(TAG, "unimplemented Method: setScrollGesturesEnabledDuringRotateOrZoom")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isScrollGesturesEnabledDuringRotateOrZoom(): Boolean {
|
||||||
|
Log.d(TAG, "unimplemented Method: isScrollGesturesEnabledDuringRotateOrZoom")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
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)) {
|
||||||
true
|
true
|
||||||
|
|
|
@ -37,10 +37,13 @@ object BitmapDescriptorFactoryImpl : IBitmapDescriptorFactoryDelegate.Stub() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun registerMap(map: MapboxMap) {
|
fun registerMap(map: MapboxMap) {
|
||||||
|
Log.d(TAG, "registerMap")
|
||||||
map.getStyle {
|
map.getStyle {
|
||||||
it.addImages(bitmaps)
|
synchronized(bitmaps) {
|
||||||
maps.add(map)
|
it.addImages(bitmaps)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
maps.add(map)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun unregisterMap(map: MapboxMap?) {
|
fun unregisterMap(map: MapboxMap?) {
|
||||||
|
@ -53,9 +56,12 @@ object BitmapDescriptorFactoryImpl : IBitmapDescriptorFactoryDelegate.Stub() {
|
||||||
?: floatArrayOf(0f, 0f)
|
?: floatArrayOf(0f, 0f)
|
||||||
|
|
||||||
private fun registerBitmap(id: String, bitmapCreator: () -> Bitmap?) {
|
private fun registerBitmap(id: String, bitmapCreator: () -> Bitmap?) {
|
||||||
if (bitmaps.contains(id)) return
|
val bitmap = synchronized(bitmaps) {
|
||||||
val bitmap = bitmapCreator() ?: return
|
if (bitmaps.contains(id)) return
|
||||||
bitmaps[id] = bitmap
|
val bitmap = bitmapCreator() ?: return
|
||||||
|
bitmaps[id] = bitmap
|
||||||
|
bitmap
|
||||||
|
}
|
||||||
for (map in maps) {
|
for (map in maps) {
|
||||||
map.getStyle { it.addImage(id, bitmap) }
|
map.getStyle { it.addImage(id, bitmap) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,51 +21,78 @@ 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.ICircleDelegate
|
import com.google.android.gms.maps.model.internal.ICircleDelegate
|
||||||
import com.mapbox.mapboxsdk.plugins.annotation.Circle
|
import com.mapbox.mapboxsdk.plugins.annotation.Circle
|
||||||
|
import com.mapbox.mapboxsdk.plugins.annotation.CircleOptions
|
||||||
|
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.CircleOptions as GmsCircleOptions
|
||||||
|
|
||||||
|
class CircleImpl(private val map: GoogleMapImpl, private val id: String, options: GmsCircleOptions) : ICircleDelegate.Stub(), Markup<Circle, CircleOptions> {
|
||||||
|
private var center: LatLng = options.center
|
||||||
|
private var radius: Double = options.radius
|
||||||
|
private var strokeWidth: Float = options.strokeWidth
|
||||||
|
private var strokeColor: Int = options.strokeColor
|
||||||
|
private var fillColor: Int = options.fillColor
|
||||||
|
private var visible: Boolean = options.isVisible
|
||||||
|
|
||||||
|
override var annotation: Circle? = null
|
||||||
|
override var removed: Boolean = false
|
||||||
|
override val annotationOptions: CircleOptions
|
||||||
|
get() = CircleOptions()
|
||||||
|
.withLatLng(center.toMapbox())
|
||||||
|
.withCircleColor(ColorUtils.colorToRgbaString(fillColor))
|
||||||
|
.withCircleRadius(radius.toFloat())
|
||||||
|
.withCircleStrokeColor(ColorUtils.colorToRgbaString(strokeColor))
|
||||||
|
.withCircleStrokeWidth(strokeWidth / map.dpiFactor)
|
||||||
|
.withCircleOpacity(if (visible) 1f else 0f)
|
||||||
|
.withCircleStrokeOpacity(if (visible) 1f else 0f)
|
||||||
|
|
||||||
class CircleImpl(private val map: GoogleMapImpl, private val circle: Circle) : ICircleDelegate.Stub() {
|
|
||||||
override fun remove() {
|
override fun remove() {
|
||||||
map.circleManager?.delete(circle)
|
removed = true
|
||||||
|
map.circleManager?.let { update(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getId(): String = "c" + circle.id.toString()
|
override fun getId(): String = id
|
||||||
|
|
||||||
override fun setCenter(center: LatLng) {
|
override fun setCenter(center: LatLng) {
|
||||||
circle.latLng = center.toMapbox()
|
this.center = center
|
||||||
map.circleManager?.update(circle)
|
annotation?.latLng = center.toMapbox()
|
||||||
|
map.circleManager?.let { update(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getCenter(): LatLng = circle.latLng.toGms()
|
override fun getCenter(): LatLng = center
|
||||||
|
|
||||||
override fun setRadius(radius: Double) {
|
override fun setRadius(radius: Double) {
|
||||||
circle.circleRadius = radius.toFloat()
|
this.radius = radius
|
||||||
map.circleManager?.update(circle)
|
annotation?.circleRadius = radius.toFloat()
|
||||||
|
map.circleManager?.let { update(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getRadius(): Double = circle.circleRadius.toDouble()
|
override fun getRadius(): Double = radius
|
||||||
|
|
||||||
override fun setStrokeWidth(width: Float) {
|
override fun setStrokeWidth(width: Float) {
|
||||||
circle.circleStrokeWidth = width / map.dpiFactor
|
this.strokeWidth = width
|
||||||
map.circleManager?.update(circle)
|
annotation?.circleStrokeWidth = width / map.dpiFactor
|
||||||
|
map.circleManager?.let { update(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getStrokeWidth(): Float = circle.circleStrokeWidth * map.dpiFactor
|
override fun getStrokeWidth(): Float = strokeWidth
|
||||||
|
|
||||||
override fun setStrokeColor(color: Int) {
|
override fun setStrokeColor(color: Int) {
|
||||||
circle.setCircleStrokeColor(color)
|
this.strokeColor = color
|
||||||
map.circleManager?.update(circle)
|
annotation?.setCircleStrokeColor(color)
|
||||||
|
map.circleManager?.let { update(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getStrokeColor(): Int = circle.circleStrokeColorAsInt
|
override fun getStrokeColor(): Int = strokeColor
|
||||||
|
|
||||||
override fun setFillColor(color: Int) {
|
override fun setFillColor(color: Int) {
|
||||||
circle.setCircleColor(color)
|
this.fillColor = color
|
||||||
map.circleManager?.update(circle)
|
annotation?.setCircleColor(color)
|
||||||
|
map.circleManager?.let { update(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFillColor(): Int = circle.circleColorAsInt
|
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")
|
||||||
|
@ -77,12 +104,13 @@ class CircleImpl(private val map: GoogleMapImpl, private val circle: Circle) : I
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setVisible(visible: Boolean) {
|
override fun setVisible(visible: Boolean) {
|
||||||
circle.circleOpacity = if (visible) 1f else 0f
|
this.visible = visible
|
||||||
circle.circleStrokeOpacity = if (visible) 1f else 0f
|
annotation?.circleOpacity = if (visible) 1f else 0f
|
||||||
map.circleManager?.update(circle)
|
annotation?.circleStrokeOpacity = if (visible) 1f else 0f
|
||||||
|
map.circleManager?.let { update(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isVisible(): Boolean = circle.circleOpacity != 0f || circle.circleStrokeOpacity != 0f
|
override fun isVisible(): Boolean = visible
|
||||||
|
|
||||||
override fun equalsRemote(other: ICircleDelegate?): Boolean = equals(other)
|
override fun equalsRemote(other: ICircleDelegate?): Boolean = equals(other)
|
||||||
|
|
||||||
|
@ -90,7 +118,7 @@ class CircleImpl(private val map: GoogleMapImpl, private val circle: Circle) : I
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other is CircleImpl) {
|
if (other is CircleImpl) {
|
||||||
return other.circle == circle
|
return other.id == id
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,35 +19,74 @@ package org.microg.gms.maps.mapbox.model
|
||||||
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.maps.model.LatLng
|
import com.google.android.gms.maps.model.LatLng
|
||||||
|
import com.google.android.gms.maps.model.MarkerOptions
|
||||||
import com.google.android.gms.maps.model.internal.IMarkerDelegate
|
import com.google.android.gms.maps.model.internal.IMarkerDelegate
|
||||||
|
import com.mapbox.mapboxsdk.plugins.annotation.AnnotationManager
|
||||||
import com.mapbox.mapboxsdk.plugins.annotation.Symbol
|
import com.mapbox.mapboxsdk.plugins.annotation.Symbol
|
||||||
|
import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions
|
||||||
import org.microg.gms.kotlin.unwrap
|
import org.microg.gms.kotlin.unwrap
|
||||||
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 MarkerImpl(private val map: GoogleMapImpl,
|
class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options: MarkerOptions) : IMarkerDelegate.Stub(), Markup<Symbol, SymbolOptions> {
|
||||||
private val symbol: Symbol,
|
private var position: LatLng = options.position
|
||||||
private var anchor: FloatArray,
|
private var visible: Boolean = options.isVisible
|
||||||
private var icon: BitmapDescriptorImpl?,
|
private var rotation: Float = options.rotation
|
||||||
private var alpha: Float = symbol.iconOpacity,
|
private var anchor: FloatArray = floatArrayOf(options.anchorU, options.anchorV)
|
||||||
private var title: String? = null,
|
private var icon: BitmapDescriptorImpl? = options.icon?.remoteObject.unwrap()
|
||||||
private var snippet: String? = null) : IMarkerDelegate.Stub() {
|
private var alpha: Float = options.alpha
|
||||||
|
private var title: String? = options.title
|
||||||
|
private var snippet: String? = options.snippet
|
||||||
|
private var zIndex: Float = options.zIndex
|
||||||
|
private var draggable: Boolean = options.isDraggable
|
||||||
private var tag: IObjectWrapper? = null
|
private var tag: IObjectWrapper? = null
|
||||||
|
|
||||||
|
override var annotation: Symbol? = null
|
||||||
|
override var removed: Boolean = false
|
||||||
|
override val annotationOptions: SymbolOptions
|
||||||
|
get() {
|
||||||
|
var intBits = java.lang.Float.floatToIntBits(zIndex)
|
||||||
|
if (intBits < 0) intBits = intBits xor 0x7fffffff
|
||||||
|
|
||||||
|
val symbolOptions = SymbolOptions()
|
||||||
|
.withIconOpacity(if (visible) alpha else 0f)
|
||||||
|
.withIconRotate(rotation)
|
||||||
|
.withZIndex(intBits)
|
||||||
|
.withDraggable(draggable)
|
||||||
|
|
||||||
|
position.let { symbolOptions.withLatLng(it.toMapbox()) }
|
||||||
|
icon?.applyTo(symbolOptions, anchor, map.dpiFactor)
|
||||||
|
return symbolOptions
|
||||||
|
}
|
||||||
|
|
||||||
override fun remove() {
|
override fun remove() {
|
||||||
map.symbolManager?.delete(symbol)
|
removed = true
|
||||||
map.markers.remove(symbol.id)
|
map.symbolManager?.let { update(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getId(): String = "m" + symbol.id.toString()
|
override fun update(manager: AnnotationManager<*, Symbol, SymbolOptions, *, *, *>) {
|
||||||
|
synchronized(this) {
|
||||||
override fun setPosition(pos: LatLng?) {
|
val id = annotation?.id
|
||||||
pos?.let { symbol.latLng = it.toMapbox() }
|
if (removed && id != null) {
|
||||||
map.symbolManager?.update(symbol)
|
map.markers.remove(id)
|
||||||
|
}
|
||||||
|
super.update(manager)
|
||||||
|
val annotation = annotation
|
||||||
|
if (annotation != null && id == null) {
|
||||||
|
map.markers[annotation.id] = this
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPosition(): LatLng = symbol.latLng.toGms()
|
override fun getId(): String = id
|
||||||
|
|
||||||
|
override fun setPosition(position: LatLng?) {
|
||||||
|
this.position = position ?: return
|
||||||
|
annotation?.latLng = position.toMapbox()
|
||||||
|
map.symbolManager?.let { update(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPosition(): LatLng = position
|
||||||
|
|
||||||
override fun setTitle(title: String?) {
|
override fun setTitle(title: String?) {
|
||||||
this.title = title
|
this.title = title
|
||||||
|
@ -61,12 +100,13 @@ class MarkerImpl(private val map: GoogleMapImpl,
|
||||||
|
|
||||||
override fun getSnippet(): String? = snippet
|
override fun getSnippet(): String? = snippet
|
||||||
|
|
||||||
override fun setDraggable(drag: Boolean) {
|
override fun setDraggable(draggable: Boolean) {
|
||||||
symbol.isDraggable = drag
|
this.draggable = draggable
|
||||||
map.symbolManager?.update(symbol)
|
annotation?.isDraggable = draggable
|
||||||
|
map.symbolManager?.let { update(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isDraggable(): Boolean = symbol.isDraggable
|
override fun isDraggable(): Boolean = draggable
|
||||||
|
|
||||||
override fun showInfoWindow() {
|
override fun showInfoWindow() {
|
||||||
Log.d(TAG, "unimplemented Method: showInfoWindow")
|
Log.d(TAG, "unimplemented Method: showInfoWindow")
|
||||||
|
@ -82,11 +122,12 @@ class MarkerImpl(private val map: GoogleMapImpl,
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setVisible(visible: Boolean) {
|
override fun setVisible(visible: Boolean) {
|
||||||
symbol.iconOpacity = if (visible) 0f else alpha
|
this.visible = visible
|
||||||
map.symbolManager?.update(symbol)
|
annotation?.iconOpacity = if (visible) alpha else 0f
|
||||||
|
map.symbolManager?.let { update(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isVisible(): Boolean = symbol.iconOpacity != 0f
|
override fun isVisible(): Boolean = visible
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
|
@ -107,15 +148,17 @@ class MarkerImpl(private val map: GoogleMapImpl,
|
||||||
override fun hashCodeRemote(): Int = hashCode()
|
override fun hashCodeRemote(): Int = hashCode()
|
||||||
|
|
||||||
override fun setIcon(obj: IObjectWrapper?) {
|
override fun setIcon(obj: IObjectWrapper?) {
|
||||||
obj.unwrap<BitmapDescriptorImpl>()?.let { icon = it }
|
obj.unwrap<BitmapDescriptorImpl>()?.let { icon ->
|
||||||
icon?.applyTo(symbol, anchor, map.dpiFactor)
|
this.icon = icon
|
||||||
map.symbolManager?.update(symbol)
|
annotation?.let { icon.applyTo(it, anchor, map.dpiFactor) }
|
||||||
|
}
|
||||||
|
map.symbolManager?.let { update(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setAnchor(x: Float, y: Float) {
|
override fun setAnchor(x: Float, y: Float) {
|
||||||
anchor = floatArrayOf(x, y)
|
anchor = floatArrayOf(x, y)
|
||||||
icon?.applyTo(symbol, anchor, map.dpiFactor)
|
annotation?.let { icon?.applyTo(it, anchor, map.dpiFactor) }
|
||||||
map.symbolManager?.update(symbol)
|
map.symbolManager?.let { update(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setFlat(flat: Boolean) {
|
override fun setFlat(flat: Boolean) {
|
||||||
|
@ -128,11 +171,12 @@ class MarkerImpl(private val map: GoogleMapImpl,
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setRotation(rotation: Float) {
|
override fun setRotation(rotation: Float) {
|
||||||
symbol.iconRotate = rotation
|
this.rotation = rotation
|
||||||
map.symbolManager?.update(symbol)
|
annotation?.iconRotate = rotation
|
||||||
|
map.symbolManager?.let { update(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getRotation(): Float = symbol.iconRotate
|
override fun getRotation(): Float = rotation
|
||||||
|
|
||||||
override fun setInfoWindowAnchor(x: Float, y: Float) {
|
override fun setInfoWindowAnchor(x: Float, y: Float) {
|
||||||
Log.d(TAG, "unimplemented Method: setInfoWindowAnchor")
|
Log.d(TAG, "unimplemented Method: setInfoWindowAnchor")
|
||||||
|
@ -140,24 +184,21 @@ class MarkerImpl(private val map: GoogleMapImpl,
|
||||||
|
|
||||||
override fun setAlpha(alpha: Float) {
|
override fun setAlpha(alpha: Float) {
|
||||||
this.alpha = alpha
|
this.alpha = alpha
|
||||||
symbol.iconOpacity = alpha
|
annotation?.iconOpacity = if (visible) alpha else 0f
|
||||||
map.symbolManager?.update(symbol)
|
map.symbolManager?.let { update(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getAlpha(): Float = alpha
|
override fun getAlpha(): Float = alpha
|
||||||
|
|
||||||
override fun setZIndex(zIndex: Float) {
|
override fun setZIndex(zIndex: Float) {
|
||||||
|
this.zIndex = zIndex
|
||||||
var intBits = java.lang.Float.floatToIntBits(zIndex)
|
var intBits = java.lang.Float.floatToIntBits(zIndex)
|
||||||
if (intBits < 0) intBits = intBits xor 0x7fffffff
|
if (intBits < 0) intBits = intBits xor 0x7fffffff
|
||||||
symbol.zIndex = intBits
|
annotation?.zIndex = intBits
|
||||||
map.symbolManager?.update(symbol)
|
map.symbolManager?.let { update(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getZIndex(): Float {
|
override fun getZIndex(): Float = zIndex
|
||||||
var intBits = symbol.zIndex
|
|
||||||
if (intBits < 0) intBits = intBits xor 0x7fffffff
|
|
||||||
return java.lang.Float.intBitsToFloat(intBits)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setTag(obj: IObjectWrapper?) {
|
override fun setTag(obj: IObjectWrapper?) {
|
||||||
this.tag = obj
|
this.tag = obj
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 microG Project Team
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.maps.mapbox.model
|
||||||
|
|
||||||
|
import com.mapbox.mapboxsdk.plugins.annotation.Annotation
|
||||||
|
import com.mapbox.mapboxsdk.plugins.annotation.AnnotationManager
|
||||||
|
import com.mapbox.mapboxsdk.plugins.annotation.Options
|
||||||
|
|
||||||
|
interface Markup<T : Annotation<*>, S : Options<T>> {
|
||||||
|
var annotation: T?
|
||||||
|
val annotationOptions: S
|
||||||
|
val removed: Boolean
|
||||||
|
|
||||||
|
fun update(manager: AnnotationManager<*, T, S, *, *, *>) {
|
||||||
|
synchronized(this) {
|
||||||
|
if (removed && annotation != null) {
|
||||||
|
manager.delete(annotation)
|
||||||
|
annotation = null
|
||||||
|
} else if (annotation != null) {
|
||||||
|
manager.update(annotation)
|
||||||
|
} else if (!removed) {
|
||||||
|
annotation = manager.create(annotationOptions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 microG Project Team
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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.internal.IPolygonDelegate
|
||||||
|
import com.mapbox.mapboxsdk.plugins.annotation.Fill
|
||||||
|
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() {
|
||||||
|
override fun remove() {
|
||||||
|
map.fillManager?.delete(fill)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getId(): String = "p" + fill.id.toString()
|
||||||
|
|
||||||
|
override fun setPoints(points: List<LatLng>) {
|
||||||
|
fill.latLngs = listOf(points.map { it.toMapbox() })
|
||||||
|
map.fillManager?.update(fill)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPoints(): List<LatLng> = fill.latLngs[0]?.map { it.toGms() } ?: emptyList()
|
||||||
|
|
||||||
|
override fun setHoles(holes: List<Any?>?) {
|
||||||
|
Log.d(TAG, "unimplemented Method: setHoles")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getHoles(): List<Any?> {
|
||||||
|
Log.d(TAG, "unimplemented Method: getHoles")
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setStrokeWidth(width: Float) {
|
||||||
|
Log.d(TAG, "unimplemented Method: setStrokeWidth")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStrokeWidth(): Float {
|
||||||
|
Log.d(TAG, "unimplemented Method: getStrokeWidth")
|
||||||
|
return 0f
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setStrokeColor(color: Int) {
|
||||||
|
fill.setFillOutlineColor(color)
|
||||||
|
map.fillManager?.update(fill)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStrokeColor(): Int = fill.fillOutlineColorAsInt
|
||||||
|
|
||||||
|
override fun setFillColor(color: Int) {
|
||||||
|
fill.setFillColor(color)
|
||||||
|
map.fillManager?.update(fill)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFillColor(): Int = fill.fillColorAsInt
|
||||||
|
|
||||||
|
override fun setZIndex(zIndex: Float) {
|
||||||
|
Log.d(TAG, "unimplemented Method: setZIndex")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getZIndex(): Float {
|
||||||
|
Log.d(TAG, "unimplemented Method: getZIndex")
|
||||||
|
return 0f
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setVisible(visible: Boolean) {
|
||||||
|
fill.fillOpacity = if (visible) 1f else 0f
|
||||||
|
map.fillManager?.update(fill)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isVisible(): Boolean = fill.fillOpacity != 0f
|
||||||
|
|
||||||
|
override fun setGeodesic(geod: Boolean) {
|
||||||
|
Log.d(TAG, "unimplemented Method: setGeodesic")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isGeodesic(): Boolean {
|
||||||
|
Log.d(TAG, "unimplemented Method: isGeodesic")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equalsRemote(other: IPolygonDelegate?): Boolean = equals(other)
|
||||||
|
|
||||||
|
override fun hashCodeRemote(): Int = hashCode()
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (other is PolygonImpl) {
|
||||||
|
return other.fill == fill
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTransact(code: Int, data: Parcel?, reply: Parcel?, flags: Int): Boolean =
|
||||||
|
if (super.onTransact(code, data, reply, flags)) {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val TAG = "GmsMapPolygon"
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,7 +32,7 @@ class PolylineImpl(private val map: GoogleMapImpl, private val line: Line) : IPo
|
||||||
|
|
||||||
override fun getId(): String = "l" + line.id.toString()
|
override fun getId(): String = "l" + line.id.toString()
|
||||||
|
|
||||||
override fun setPoints(points: MutableList<LatLng>) {
|
override fun setPoints(points: List<LatLng>) {
|
||||||
line.latLngs = points.map { it.toMapbox() }
|
line.latLngs = points.map { it.toMapbox() }
|
||||||
map.lineManager?.update(line)
|
map.lineManager?.update(line)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
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.CircleOptions
|
||||||
import com.google.android.gms.maps.model.MarkerOptions
|
import com.google.android.gms.maps.model.MarkerOptions
|
||||||
|
|
|
@ -57,6 +57,7 @@ import com.google.android.gms.maps.internal.IUiSettingsDelegate;
|
||||||
import com.google.android.gms.maps.model.CameraPosition;
|
import com.google.android.gms.maps.model.CameraPosition;
|
||||||
import com.google.android.gms.maps.model.CircleOptions;
|
import com.google.android.gms.maps.model.CircleOptions;
|
||||||
import com.google.android.gms.maps.model.GroundOverlayOptions;
|
import com.google.android.gms.maps.model.GroundOverlayOptions;
|
||||||
|
import com.google.android.gms.maps.model.LatLngBounds;
|
||||||
import com.google.android.gms.maps.model.MarkerOptions;
|
import com.google.android.gms.maps.model.MarkerOptions;
|
||||||
import com.google.android.gms.maps.model.PolygonOptions;
|
import com.google.android.gms.maps.model.PolygonOptions;
|
||||||
import com.google.android.gms.maps.model.PolylineOptions;
|
import com.google.android.gms.maps.model.PolylineOptions;
|
||||||
|
@ -155,7 +156,7 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
|
||||||
|
|
||||||
private void initFromOptions() {
|
private void initFromOptions() {
|
||||||
try {
|
try {
|
||||||
uiSettings.setCompassEnabled(options.isCompassEnabled());
|
uiSettings.setCompassEnabled(options.getCompassEnabled());
|
||||||
uiSettings.setRotateGesturesEnabled(options.isRotateGesturesEnabled());
|
uiSettings.setRotateGesturesEnabled(options.isRotateGesturesEnabled());
|
||||||
uiSettings.setTiltGesturesEnabled(options.isTiltGesturesEnabled());
|
uiSettings.setTiltGesturesEnabled(options.isTiltGesturesEnabled());
|
||||||
uiSettings.setScrollGesturesEnabled(options.isScrollGesturesEnabled());
|
uiSettings.setScrollGesturesEnabled(options.isScrollGesturesEnabled());
|
||||||
|
@ -173,6 +174,66 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
|
||||||
backendMap.destroy();
|
backendMap.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLowMemory() throws RemoteException {
|
||||||
|
Log.d(TAG, "unimplemented Method: onLowMemory");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean useViewLifecycleWhenInFragment() throws RemoteException {
|
||||||
|
Log.d(TAG, "unimplemented Method: useViewLifecycleWhenInFragment");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSaveInstanceState(Bundle outState) throws RemoteException {
|
||||||
|
Log.d(TAG, "unimplemented Method: onSaveInstanceState");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setContentDescription(String desc) throws RemoteException {
|
||||||
|
Log.d(TAG, "unimplemented Method: setContentDescription");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnterAmbient(Bundle bundle) throws RemoteException {
|
||||||
|
Log.d(TAG, "unimplemented Method: onEnterAmbient");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onExitAmbient() throws RemoteException {
|
||||||
|
Log.d(TAG, "unimplemented Method: onExitAmbient");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMinZoomPreference(float minZoom) throws RemoteException {
|
||||||
|
Log.d(TAG, "unimplemented Method: setMinZoomPreference");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMaxZoomPreference(float maxZoom) throws RemoteException {
|
||||||
|
Log.d(TAG, "unimplemented Method: setMaxZoomPreference");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetMinMaxZoomPreference() throws RemoteException {
|
||||||
|
Log.d(TAG, "unimplemented Method: resetMinMaxZoomPreference");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLatLngBoundsForCameraTarget(LatLngBounds bounds) throws RemoteException {
|
||||||
|
Log.d(TAG, "unimplemented Method: setLatLngBoundsForCameraTarget");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
backendMap.onResume();
|
backendMap.onResume();
|
||||||
}
|
}
|
||||||
|
@ -556,6 +617,18 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
|
||||||
}, 5000);
|
}, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setWatermarkEnabled(boolean watermark) throws RemoteException {
|
||||||
|
Log.d(TAG, "unimplemented Method: setWatermarkEnabled");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) throws RemoteException {
|
||||||
|
Log.d(TAG, "unimplemented Method: onCreate");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCameraMoveStartedListener(IOnCameraMoveStartedListener listener) throws RemoteException {
|
public void setCameraMoveStartedListener(IOnCameraMoveStartedListener listener) throws RemoteException {
|
||||||
Log.d(TAG, "unimplemented Method: setCameraMoveStartedListener");
|
Log.d(TAG, "unimplemented Method: setCameraMoveStartedListener");
|
||||||
|
@ -579,6 +652,18 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
|
||||||
Log.d(TAG, "unimplemented Method: setCameraIdleListener");
|
Log.d(TAG, "unimplemented Method: setCameraIdleListener");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() throws RemoteException {
|
||||||
|
Log.d(TAG, "unimplemented Method: onStart");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() throws RemoteException {
|
||||||
|
Log.d(TAG, "unimplemented Method: onStop");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Misc
|
Misc
|
||||||
|
|
|
@ -125,6 +125,26 @@ public class MapFragmentImpl extends IMapFragmentDelegate.Stub {
|
||||||
Log.d(TAG, "onLowMemory");
|
Log.d(TAG, "onLowMemory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnterAmbient(Bundle bundle) throws RemoteException {
|
||||||
|
map.onEnterAmbient(bundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onExitAmbient() throws RemoteException {
|
||||||
|
map.onExitAmbient();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() throws RemoteException {
|
||||||
|
map.onStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() throws RemoteException {
|
||||||
|
map.onStop();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSaveInstanceState(Bundle outState) throws RemoteException {
|
public void onSaveInstanceState(Bundle outState) throws RemoteException {
|
||||||
Log.d(TAG, "onSaveInstanceState: " + outState);
|
Log.d(TAG, "onSaveInstanceState: " + outState);
|
||||||
|
|
|
@ -122,6 +122,26 @@ public class MapViewImpl extends IMapViewDelegate.Stub {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnterAmbient(Bundle bundle) throws RemoteException {
|
||||||
|
map.onEnterAmbient(bundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onExitAmbient() throws RemoteException {
|
||||||
|
map.onExitAmbient();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() throws RemoteException {
|
||||||
|
map.onStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() throws RemoteException {
|
||||||
|
map.onStop();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
|
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
|
||||||
if (super.onTransact(code, data, reply, flags)) return true;
|
if (super.onTransact(code, data, reply, flags)) return true;
|
||||||
|
|
|
@ -28,6 +28,9 @@ public class UiSettingsImpl extends IUiSettingsDelegate.Stub {
|
||||||
private boolean tiltGesturesEnabled = true;
|
private boolean tiltGesturesEnabled = true;
|
||||||
private boolean rotateGesturesEnabled = true;
|
private boolean rotateGesturesEnabled = true;
|
||||||
private boolean allGesturesEnabled = true;
|
private boolean allGesturesEnabled = true;
|
||||||
|
private boolean indoorLevelPickerEnabled = false;
|
||||||
|
private boolean mapToolbarEnabled = false;
|
||||||
|
private boolean scrollGesturesEnabledDuringRotateOrZoom = true;
|
||||||
|
|
||||||
private UiSettingsListener listener;
|
private UiSettingsListener listener;
|
||||||
|
|
||||||
|
@ -127,7 +130,40 @@ public class UiSettingsImpl extends IUiSettingsDelegate.Stub {
|
||||||
public boolean isRotateGesturesEnabled() throws RemoteException {
|
public boolean isRotateGesturesEnabled() throws RemoteException {
|
||||||
return rotateGesturesEnabled;
|
return rotateGesturesEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setIndoorLevelPickerEnabled(boolean indoorLevelPicker) throws RemoteException {
|
||||||
|
this.indoorLevelPickerEnabled = indoorLevelPicker;
|
||||||
|
listener.onUiSettingsChanged(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isIndoorLevelPickerEnabled() throws RemoteException {
|
||||||
|
return indoorLevelPickerEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMapToolbarEnabled(boolean mapToolbar) throws RemoteException {
|
||||||
|
this.mapToolbarEnabled = mapToolbar;
|
||||||
|
listener.onUiSettingsChanged(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMapToolbarEnabled() throws RemoteException {
|
||||||
|
return mapToolbarEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setScrollGesturesEnabledDuringRotateOrZoom(boolean scrollDuringZoom) throws RemoteException {
|
||||||
|
this.scrollGesturesEnabledDuringRotateOrZoom = scrollDuringZoom;
|
||||||
|
listener.onUiSettingsChanged(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isScrollGesturesEnabledDuringRotateOrZoom() throws RemoteException {
|
||||||
|
return scrollGesturesEnabledDuringRotateOrZoom;
|
||||||
|
}
|
||||||
|
|
||||||
public static interface UiSettingsListener {
|
public static interface UiSettingsListener {
|
||||||
void onUiSettingsChanged(UiSettingsImpl settings) throws RemoteException;
|
void onUiSettingsChanged(UiSettingsImpl settings) throws RemoteException;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue