Skip to content

Commit

Permalink
feat: allow Images/Image component in NativeUserLocation
Browse files Browse the repository at this point in the history
  • Loading branch information
mfazekas committed Nov 12, 2023
1 parent 4347b88 commit e646fa1
Show file tree
Hide file tree
Showing 42 changed files with 1,173 additions and 307 deletions.
6 changes: 3 additions & 3 deletions android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ class RNMBXPackage : TurboReactPackage() {
fun getViewTagResolver(context: ReactApplicationContext) : ViewTagResolver {
val viewTagResolver = viewTagResolver
if (viewTagResolver == null) {
val viewTagResolver = ViewTagResolver(context)
this.viewTagResolver = viewTagResolver
return viewTagResolver
val result = ViewTagResolver(context)
this.viewTagResolver = result
return result
}
return viewTagResolver
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -334,10 +334,10 @@ class RNMBXCamera(private val mContext: Context, private val mManager: RNMBXCame
if (location?.puckBearingEnabled == true) {
when (location.puckBearingSource) {

PuckBearingSource.HEADING -> {
PuckBearing.HEADING -> {
UserTrackingMode.FollowWithHeading
}
PuckBearingSource.COURSE -> {
PuckBearing.COURSE -> {
UserTrackingMode.FollowWithCourse
}
else -> {
Expand Down Expand Up @@ -468,12 +468,12 @@ class RNMBXCamera(private val mContext: Context, private val mManager: RNMBXCame
when (mFollowUserMode ?: "normal") {
"compass" -> {
location.puckBearingEnabled = true
location.puckBearingSource = PuckBearingSource.HEADING
location.puckBearingSource = PuckBearing.HEADING
followOptions.bearing(FollowPuckViewportStateBearing.SyncWithLocationPuck)
}
"course" -> {
location.puckBearingEnabled = true
location.puckBearingSource = PuckBearingSource.COURSE
location.puckBearingSource = PuckBearing.COURSE
followOptions.bearing(FollowPuckViewportStateBearing.SyncWithLocationPuck)
}
"normal" -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.rnmapbox.rnmbx.components.images

import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import com.rnmapbox.rnmbx.v11compat.Cancelable
import com.mapbox.maps.Image
import com.rnmapbox.rnmbx.v11compat.image.toMapboxImage

/**
ImageManager helps to resolve images defined by any of RNMBXImages component.
*/

fun interface Resolver {
fun resolved(name: String, image: Image)
}
class Subscription(val name:String, val resolver: Resolver, val manager: ImageManager): Cancelable {

fun resolved(name: String, image: Image) {
resolver.resolved(name, image)
}
override fun cancel() {
manager.unsubscribe(this)
}
}

class ImageManager {
var subscriptions: MutableMap<String, MutableList<Subscription>> = hashMapOf()

fun subscribe(name: String, resolved: Resolver) : Subscription {
val list = subscriptions.getOrPut(name) { mutableListOf() }
val result = Subscription(name, resolved, this)
list.add(result)
return result
}
fun unsubscribe(subscription: Subscription) {
var list = subscriptions[subscription.name]
list?.removeAll { it === subscription }
}

fun resolve(name: String, image: Image) {
subscriptions[name]?.forEach {
it.resolved(name, image)
}
}

fun resolve(name: String, image: Bitmap) {
resolve(name, image.toMapboxImage())
}

fun resolve(name: String, image: BitmapDrawable) {
resolve(name, image.bitmap)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ class RNMBXImages(context: Context, private val mManager: RNMBXImagesManager) :
val name = nativeImage.info.name
if (!hasImage(name, map)) {
val bitmap = nativeImage.drawable
mMapView!!.imageManager.resolve(name, nativeImage.drawable)
style.addBitmapImage(nativeImage)
mCurrentImages.add(name)
}
Expand Down Expand Up @@ -264,7 +265,7 @@ class RNMBXImages(context: Context, private val mManager: RNMBXImagesManager) :
}
}
if (missingImages.size > 0) {
val task = DownloadMapImageTask(context, map, null)
val task = DownloadMapImageTask(context, map, mMapView!!.imageManager)
val params = missingImages.toTypedArray()
task.execute(*params)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import com.rnmapbox.rnmbx.v11compat.image.ImageHolder
import com.rnmapbox.rnmbx.v11compat.image.toBitmapImageHolder
import com.rnmapbox.rnmbx.v11compat.image.toByteArray
import com.rnmapbox.rnmbx.v11compat.image.toImageData
import com.rnmapbox.rnmbx.v11compat.location.PuckBearingSource
import com.rnmapbox.rnmbx.v11compat.location.PuckBearing

/**
* The LocationComponent on android implements display of user's current location.
Expand Down Expand Up @@ -53,9 +53,10 @@ class LocationComponentManager(mapView: RNMBXMapView, context: Context) {
var bearingImage: ImageHolder?, // The image used as the middle of the location indicator.
var topImage: ImageHolder?, // The image to use as the top layer for the location indicator.
var shadowImage: ImageHolder?, // The image that acts as a background of the location indicator.
var puckBearingSource: PuckBearingSource?, // bearing source
var puckBearingSource: PuckBearing?, // bearing source
var pulsing: Boolean = true,
var scale: Double = 1.0,
var nativeUserLocation: Boolean = false, // LocaitonPuck managed by RNMBXNativeUserLocation
) {
val enabled: Boolean
get() = showUserLocation || followUserLocation
Expand Down Expand Up @@ -98,49 +99,52 @@ class LocationComponentManager(mapView: RNMBXMapView, context: Context) {
if (fullUpdate ||
newState.hidden != oldState.hidden ||
newState.tintColor != oldState.tintColor ||
newState.bearingImage != oldState.bearingImage ||
newState.topImage != oldState.topImage ||
newState.shadowImage != oldState.shadowImage ||
newState.scale != oldState.scale
newState.scale != oldState.scale ||
newState.nativeUserLocation != oldState.nativeUserLocation
) {
if (newState.hidden) {
var emptyLocationPuck = LocationPuck2D()
val empty =
AppCompatResourcesV11.getDrawableImageHolder(mContext, R.drawable.empty)
emptyLocationPuck.bearingImage = empty
emptyLocationPuck.shadowImage = empty
emptyLocationPuck.topImage = empty
//emptyLocationPuck.opacity = 0.0
locationPuck = emptyLocationPuck
pulsingEnabled = false
} else {
val tintColor = newState.tintColor
var topImage = newState.topImage
if (tintColor != null && topImage != null) {
val imageData = (topImage as ByteArray).toImageData().toByteArray()
val drawable = BitmapDrawable(mContext.resources, BitmapFactory.decodeByteArray(imageData, 0, imageData.size))
drawable.setTint(tintColor)
topImage = drawable.toBitmapImageHolder()
if (!newState.nativeUserLocation) {
if (newState.hidden) {
var emptyLocationPuck = LocationPuck2D()
val empty =
AppCompatResourcesV11.getDrawableImageHolder(mContext, R.drawable.empty)
emptyLocationPuck.bearingImage = empty
emptyLocationPuck.shadowImage = empty
emptyLocationPuck.topImage = empty
//emptyLocationPuck.opacity = 0.0
locationPuck = emptyLocationPuck
pulsingEnabled = false
} else {
val tintColor = newState.tintColor
var topImage = newState.topImage
if (tintColor != null && topImage != null) {
val imageData = (topImage as ByteArray).toImageData().toByteArray()
val drawable = BitmapDrawable(
mContext.resources,
BitmapFactory.decodeByteArray(imageData, 0, imageData.size)
)
drawable.setTint(tintColor)
topImage = drawable.toBitmapImageHolder()
}
val scaleExpression = if (newState.scale != 1.0) {
interpolate {
linear()
zoom()
stop {
literal(0)
literal(newState.scale)
}
}.toJson()
} else null

locationPuck = LocationPuck2D(
topImage = topImage,
bearingImage = newState.bearingImage,
shadowImage = newState.shadowImage,
scaleExpression = scaleExpression,
)
pulsingEnabled = newState.pulsing
pulsingColor = tintColor ?: MAPBOX_BLUE_COLOR
}
val scaleExpression = if (newState.scale != 1.0) {
interpolate {
linear()
zoom()
stop {
literal(0)
literal(newState.scale)
}
}.toJson()
} else null

locationPuck = LocationPuck2D(
topImage = topImage,
bearingImage = newState.bearingImage,
shadowImage = newState.shadowImage,
scaleExpression = scaleExpression,
)
pulsingEnabled = newState.pulsing
pulsingColor = tintColor ?: MAPBOX_BLUE_COLOR
}
}

Expand Down Expand Up @@ -179,7 +183,7 @@ class LocationComponentManager(mapView: RNMBXMapView, context: Context) {

fun showNativeUserLocation(showUserLocation: Boolean) {
update {
it.copy(showUserLocation = showUserLocation)
it.copy(showUserLocation = showUserLocation, nativeUserLocation= showUserLocation)
}
}

Expand Down
Loading

0 comments on commit e646fa1

Please sign in to comment.