Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
def defaultMapboxMapsImpl = "mabpox"
def defaultMapboxMapsVersion = "10.16.0"
def defaultMapboxMapsVersion = "10.16.1"

def safeExtGet(prop, fallback) {
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import com.rnmapbox.rnmbx.components.images.RNMBXImagesManager
import com.rnmapbox.rnmbx.components.AbstractMapFeature
import com.rnmapbox.rnmbx.utils.ImageEntry
import android.graphics.drawable.BitmapDrawable
import android.util.DisplayMetrics
import androidx.core.content.res.ResourcesCompat
import com.mapbox.bindgen.DataRef
import com.mapbox.bindgen.Expected
import com.mapbox.bindgen.None
import com.mapbox.maps.Image
Expand All @@ -28,6 +30,9 @@ import java.util.HashMap
import java.util.HashSet

import com.rnmapbox.rnmbx.v11compat.image.*;
import java.lang.Float.max
import java.lang.Math.ceil
import kotlin.math.ceil

fun Style.addBitmapImage(imageId: String, bitmap: Bitmap, sdf: Boolean = false, stretchX: List<ImageStretches> = listOf(), stretchY: List<ImageStretches> = listOf(), content: ImageContent? = null, scale: Double = 1.0) : Expected<String, None> {
val byteBuffer = ByteBuffer.allocate(bitmap.byteCount)
Expand All @@ -49,7 +54,7 @@ fun Style.addBitmapImage(nativeImage: NativeImage) : Expected<String, None> {
}

data class ImageInfo(val name: String, val scale: Double? = 1.0, val sdf: Boolean = false, val stretchX: List<ImageStretches> = listOf(),
val stretchY: List<ImageStretches> = listOf(), val content: ImageContent? = null)
val stretchY: List<ImageStretches> = listOf(), val content: ImageContent? = null, val width: Double? = null, val height: Double? = null)
{
fun getScaleOr(default: Double): Double {
return scale ?: default;
Expand Down Expand Up @@ -213,11 +218,33 @@ class RNMBXImages(context: Context, private val mManager: RNMBXImagesManager) :
}
}

private fun placeholderImageFor(info: ImageInfo): Image? {
if (info.width != null && info.height != null) {
val width = (info.width * info.getScaleOr(1.0)).toInt()
val height = (info.width * info.getScaleOr(1.0)).toInt()

return emptyImage(width, height)
} else if (info.stretchX.isNotEmpty() || info.stretchY.isNotEmpty() || info.content != null) {
var maxY = info.stretchY.maxOfOrNull { max(it.first, it.second) } ?: 0.0f
var maxX = info.stretchX.maxOfOrNull { max(it.first, it.second) } ?: 0.0f
if (info.content != null) {
maxX = max(max(info.content.left,info.content.right), maxX)
maxY = max(max(info.content.top,info.content.bottom), maxY)
}
return emptyImage(ceil(maxX).toInt()+1, ceil(maxY).toInt()+1)
} else {
return mImagePlaceholder?.toMapboxImage() ?: emptyImage(16, 16)
}
}

private fun addRemoteImages(imageEntries: List<Map.Entry<String, ImageEntry>>?, map: MapboxMap) {
val style = map.getStyle()
if (style == null || imageEntries == null) return
val missingImages: MutableList<Map.Entry<String, ImageEntry>> = ArrayList()

val metrics = context.resources.displayMetrics
val screenDensity = (metrics?.density ?: DisplayMetrics.DENSITY_DEFAULT).toDouble()

// Add image placeholder for images that are not yet available in the style. This way
// we can load the images asynchronously and add the ShapeSource to the map without delay.
// The same is required when this ShapeSource is updated with new/added images and the
Expand All @@ -227,7 +254,11 @@ class RNMBXImages(context: Context, private val mManager: RNMBXImagesManager) :
// See also: https://github.com/mapbox/mapbox-gl-native/pull/14253#issuecomment-478827792
for (imageEntry in imageEntries) {
if (!hasImage(imageEntry.key, map)) {
mImagePlaceholder?.let { style.addBitmapImage(imageEntry.key, it, false, listOf(), listOf(), null,1.0) }
val info = imageEntry.value.info;
val placeholderImage = placeholderImageFor(info)
placeholderImage?.let {
style.addStyleImage(imageEntry.key, it, info)
}
missingImages.add(imageEntry)
mCurrentImages.add(imageEntry.key)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import com.rnmapbox.rnmbx.utils.ImageEntry
import com.rnmapbox.rnmbx.utils.Logger
import com.rnmapbox.rnmbx.utils.ResourceUtils
import com.rnmapbox.rnmbx.utils.extensions.forEach
import com.rnmapbox.rnmbx.utils.extensions.getIfDouble
import java.util.*

class RNMBXImagesManager(private val mContext: ReactApplicationContext) :
Expand All @@ -28,12 +29,14 @@ class RNMBXImagesManager(private val mContext: ReactApplicationContext) :
return RNMBXImages(context, this)
}

fun imageInfo(name: String, map: ReadableMap): ImageInfo {
fun imageInfo(name: String, map: ReadableMap, secondScale: Double? = null): ImageInfo {
var sdf = false
var stretchX = listOf<ImageStretches>()
var stretchY = listOf<ImageStretches>()
var content : ImageContent? = null
var scale : Double? = null
var width : Double? = null
var height : Double? = null
if (map.hasKey("sdf")) {
sdf = map.getBoolean("sdf");
}
Expand All @@ -50,9 +53,17 @@ class RNMBXImagesManager(private val mContext: ReactApplicationContext) :
if (map.getType("scale") != ReadableType.Number) {
Logger.e("RNMBXImages", "scale should be a number found: $scale in $map")
}
scale = map.getDouble("scale")
scale = map.getDouble("scale") * (secondScale ?: 1.0);
} else if (secondScale != null) {
scale = secondScale
}
return ImageInfo(name=name, sdf=sdf, scale=scale, content=content, stretchX = stretchX, stretchY = stretchY)
if (map.hasKey("width")) {
width = map.getDouble("width")
}
if (map.hasKey("height")) {
height = map.getDouble("height")
}
return ImageInfo(name=name, sdf=sdf, scale=scale, content=content, stretchX = stretchX, stretchY = stretchY, width = width, height = height)
}

@ReactProp(name = "images")
Expand All @@ -61,11 +72,47 @@ class RNMBXImagesManager(private val mContext: ReactApplicationContext) :
map.forEach { imageName, imageInfo ->
when (imageInfo) {
is ReadableMap -> {
val uri = imageInfo.getString("uri") ?: imageInfo.getString("url")
val uri = imageInfo.getString("uri")
if (uri != null) {
imagesList.add(AbstractMap.SimpleEntry(imageName, ImageEntry(uri, imageInfo(imageName, imageInfo))))
imagesList.add(
AbstractMap.SimpleEntry(
imageName,
ImageEntry(uri, imageInfo(imageName, imageInfo))
)
)
} else {
Logger.e("RNMBXImagesManager", "Unexpected value for key: $imageName in images property, no uri/url found!")
val imageMap = imageInfo.getMap("resolvedImage")
val uri = imageMap?.getString("uri")
if (uri != null) {
imagesList.add(
AbstractMap.SimpleEntry(
imageName,
ImageEntry(
uri,
imageInfo(imageName, imageInfo, imageMap.getIfDouble("scale"))
)
)
)
} else {
var url = imageInfo.getString("url")
if (url != null) {
imagesList.add(
AbstractMap.SimpleEntry(
imageName,
ImageEntry(
url,
imageInfo(imageName, imageInfo)
)
)
)

} else {
Logger.e(
"RNMBXImagesManager",
"Unexpected value for key: $imageName in images property, no uri/url found!"
)
}
}
}
}
is String -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,5 @@ object CustomHttpHeaders : HttpServiceBase() {
override fun onResponse(response: HttpResponse): HttpResponse {
return response
}

/*
override fun onUpload(options: UploadOptions): UploadOptions {
return options;
}
*/
}

Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import java.lang.ref.WeakReference
import java.util.AbstractMap
import java.util.ArrayList
import java.util.HashMap
import com.rnmapbox.rnmbx.v11compat.image.*

data class DownloadedImage(val name: String, val bitmap: Bitmap, val info: ImageInfo)

Expand Down Expand Up @@ -125,9 +126,8 @@ class DownloadMapImageTask(context: Context, map: MapboxMap, callback: OnAllImag
for (image in images) {
bitmapImages[image.name] = image.bitmap
val info = image.info
style.addBitmapImage(image.name, image.bitmap,sdf = info.sdf, stretchX = info.stretchX, stretchY = info.stretchY,
content = info.content,scale = info.getScaleOr(1.0)
)

style.addBitmapImage(image.name, image.bitmap, info)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.rnmapbox.rnmbx.utils.extensions

import com.facebook.react.bridge.ReadableMap
import com.facebook.react.bridge.ReadableType

fun ReadableMap.forEach(action: (String, Any) -> Unit) {
val iterator = this.entryIterator
Expand All @@ -9,3 +10,10 @@ fun ReadableMap.forEach(action: (String, Any) -> Unit) {
action(next.key, next.value)
}
}
fun ReadableMap.getIfDouble(key: String): Double? {
return if (hasKey(key) && (getType(key) == ReadableType.Number)) {
getDouble(key)
} else {
null
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
package com.rnmapbox.rnmbx.v11compat.image;

import android.content.Context
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.graphics.drawable.VectorDrawable
import androidx.annotation.DrawableRes
import androidx.appcompat.content.res.AppCompatResources
import com.mapbox.maps.Image
import com.mapbox.maps.Style
import com.rnmapbox.rnmbx.components.images.ImageInfo
import com.rnmapbox.rnmbx.components.images.addBitmapImage
import java.nio.ByteBuffer

typealias ImageHolder = Drawable;

Expand All @@ -20,6 +26,24 @@ fun VectorDrawable.toBitmapImageHolder(): Drawable {
return this
}

fun emptyImage(width: Int, height: Int): Image {
return Image(width, height, ByteArray(width * height * 4) /* ByteBuffer.allocateDirect(width * height * 4).array()*/)
}

fun Bitmap.toMapboxImage(): Image {
val byteBuffer = ByteBuffer.allocate(byteCount)
copyPixelsToBuffer(byteBuffer)
return Image(width, height, byteBuffer.array())
}

fun Style.addStyleImage(imageId: String, image: Image, info: ImageInfo, scale: Double = 1.0) {
addStyleImage(imageId, (info.getScaleOr(1.0) * scale).toFloat(), image, info.sdf, info.stretchX, info.stretchY, info.content)
}

fun Style.addBitmapImage(imageId: String, bitmap: Bitmap, info: ImageInfo, scale: Double = 1.0) {
addStyleImage(imageId, bitmap.toMapboxImage(), info, scale)
}

class AppCompatResourcesV11 {
companion object {
fun getDrawableImageHolder(context: Context, @DrawableRes resId: Int) : ImageHolder? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,35 @@ package com.rnmapbox.rnmbx.v11compat.httpinterceptor;
import com.mapbox.common.*

open class HttpServiceBase : HttpServiceInterceptorInterface {
override fun onRequest(request: HttpRequest): HttpRequest {

override fun onRequest(
request: HttpRequest,
continuation: HttpServiceInterceptorRequestContinuation
) {
val request = onRequest(request)
continuation.run(HttpRequestOrResponse(request))
}

override fun onResponse(
response: HttpResponse,
continuation: HttpServiceInterceptorResponseContinuation
) {
continuation.run(onResponse(response))
}

open fun onRequest(request: HttpRequest): HttpRequest {
return request
}

override fun onDownload(download: DownloadOptions): DownloadOptions {
open fun onDownload(download: DownloadOptions): DownloadOptions {
return download
}

override fun onResponse(response: HttpResponse): HttpResponse {
open fun onResponse(response: HttpResponse): HttpResponse {
return response
}

override fun onUpload(options: UploadOptions): UploadOptions {
open fun onUpload(options: UploadOptions): UploadOptions {
return options
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package com.rnmapbox.rnmbx.v11compat.image;

import android.content.Context
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.graphics.drawable.VectorDrawable
import androidx.annotation.DrawableRes
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.graphics.drawable.toBitmap
import com.mapbox.bindgen.DataRef
import com.mapbox.maps.Image
import com.mapbox.maps.ImageHolder
import com.mapbox.maps.Style
import com.mapbox.maps.toMapboxImage
import com.rnmapbox.rnmbx.components.images.ImageInfo
import java.nio.ByteBuffer
import com.mapbox.maps.toMapboxImage as _toMapboxImage

typealias ImageHolder = com.mapbox.maps.ImageHolder

Expand Down Expand Up @@ -38,3 +44,25 @@ class AppCompatResourcesV11 {
}
}
}

fun Bitmap.toMapboxImage(): Image {
return this._toMapboxImage()
}

fun Style.addStyleImage(imageId: String, image: Image, info: ImageInfo, scale: Double = 1.0) {
addStyleImage(imageId, (info.getScaleOr(1.0) * scale).toFloat(), image, info.sdf, info.stretchX, info.stretchY, info.content)
}

fun Style.addBitmapImage(imageId: String, bitmap: Bitmap, info: ImageInfo) {
return this.addStyleImage(
imageId,
bitmap.toMapboxImage(),
info,
)
}

fun emptyImage(width: Int, height: Int): Image {
return Image(
width, height, DataRef.allocateNative(width * height * 4)
)
}
4 changes: 2 additions & 2 deletions example/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ buildscript {

if (project.hasProperty('RNMBX11') && project.getProperty('RNMBX11').toBoolean()) {
RNMapboxMapsUseV11 = true
RNMapboxMapsVersion = '11.0.0-beta.4'
RNMapboxMapsVersion = '11.0.0-beta.5'
}

useCustomMapbox = false
Expand All @@ -16,7 +16,7 @@ buildscript {
kotlinVersion = '1.6.21'
} else if (System.getenv('CI_MAP_IMPL').equals('mapbox11')) {
RNMapboxMapsUseV11 = true
RNMapboxMapsVersion = '11.0.0-beta.3'
RNMapboxMapsVersion = '11.0.0-beta.5'
RNMapboxMapsImpl = "mapbox"
}

Expand Down
Binary file added example/src/assets/scale-test-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added example/src/assets/scale-test-icon2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added example/src/assets/scale-test-icon2@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added example/src/assets/scale-test-icon3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added example/src/assets/scale-test-icon4@3x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added example/src/assets/scale-test-icon@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added example/src/assets/scale-test-icon@3x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading