Skip to content

Commit

Permalink
feat: Add bounds to raster source (#3672)
Browse files Browse the repository at this point in the history
* feat: Add bounds to raster source

* apply changes from code review
  • Loading branch information
Elter71 authored Oct 30, 2024
1 parent 06fd719 commit 63d74fc
Show file tree
Hide file tree
Showing 13 changed files with 97 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,8 @@ class RNMBXRasterSource(context: Context?) : RNMBXTileSource<RasterSource?>(cont
companion object {
const val DEFAULT_TILE_SIZE = 512
}
}

fun setSourceBounds(value: Array<Double>) {
bounds = value
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import com.facebook.react.viewmanagers.RNMBXRasterSourceManagerInterface
import com.rnmapbox.rnmbx.events.constants.EventKeys
import com.rnmapbox.rnmbx.events.constants.eventMapOf
import javax.annotation.Nonnull
import com.facebook.react.bridge.ReadableType
import com.rnmapbox.rnmbx.utils.Logger

class RNMBXRasterSourceManager(reactApplicationContext: ReactApplicationContext) :
RNMBXTileSourceManager<RNMBXRasterSource>(reactApplicationContext),
Expand Down Expand Up @@ -42,4 +44,32 @@ class RNMBXRasterSourceManager(reactApplicationContext: ReactApplicationContext)
override fun setExisting(source: RNMBXRasterSource, value: Dynamic) {
source.mExisting = value.asBoolean()
}
}

@ReactProp(name = "sourceBounds")
override fun setSourceBounds(source: RNMBXRasterSource, value: Dynamic) {
if (value.type != ReadableType.Array || value.asArray().size() != 4) {
Logger.e(REACT_CLASS, "source bounds must be an array with left, bottom, top, and right values")
return
}
val bboxArray = Array(4) { i -> value.asArray().getDouble(i) }

if(!this.validateBbox(bboxArray)){
Logger.e(REACT_CLASS, "source bounds contain invalid bbox")
return
}

source.setSourceBounds(bboxArray)
}

private fun validateBbox(bbox: Array<Double>): Boolean {
if (bbox.size != 4) return false

val (swLng, swLat, neLng, neLat) = bbox

val isLngValid = swLng in -180.0..180.0 && neLng in -180.0..180.0
val isLatValid = swLat in -90.0..90.0 && neLat in -90.0..90.0
val isSouthWestOfNorthEast = swLng < neLng && swLat < neLat

return isLngValid && isLatValid && isSouthWestOfNorthEast
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ abstract class RNMBXTileSource<T : Source?>(context: Context?) : RNMBXSource<T>(
var attribution: String? = null
var minZoomLevel: Int? = null
var maxZoomLevel: Int? = null
var bounds: Array<Double>? = null
var tMS = false
fun buildTileset(): TileSet {
val tileUrlTemplates =
Expand All @@ -35,10 +36,13 @@ abstract class RNMBXTileSource<T : Source?>(context: Context?) : RNMBXSource<T>(
if (attribution != null) {
builder.attribution(attribution)
}
bounds?.let {
builder.bounds(it.toList())
}
return builder.build()
}

companion object {
const val TILE_SPEC_VERSION = "2.1.0"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ public void setProperty(T view, String propName, @Nullable Object value) {
case "attribution":
mViewManager.setAttribution(view, new DynamicFromObject(value));
break;
case "sourceBounds":
mViewManager.setSourceBounds(view, new DynamicFromObject(value));
break;
default:
super.setProperty(view, propName, value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ public interface RNMBXRasterSourceManagerInterface<T extends View> {
void setTileSize(T view, Dynamic value);
void setTms(T view, Dynamic value);
void setAttribution(T view, Dynamic value);
void setSourceBounds(T view, Dynamic value);
}
11 changes: 11 additions & 0 deletions docs/RasterSource.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,17 @@ FIX ME NO DESCRIPTION



### sourceBounds

```tsx
Array
```
An array containing the longitude and latitude of the southwest and northeast corners of
the source's bounding box in the following order: `[sw.lng, sw.lat, ne.lng, ne.lat]`.
When this property is included in a source, no tiles outside of the given bounds are requested by Mapbox GL.






Expand Down
7 changes: 7 additions & 0 deletions docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -5052,6 +5052,13 @@
"type": "React.ReactElement \\| React.ReactElement[]",
"default": "none",
"description": "FIX ME NO DESCRIPTION"
},
{
"name": "sourceBounds",
"required": false,
"type": "Array",
"default": "none",
"description": "An array containing the longitude and latitude of the southwest and northeast corners of\nthe source's bounding box in the following order: `[sw.lng, sw.lat, ne.lng, ne.lat]`.\nWhen this property is included in a source, no tiles outside of the given bounds are requested by Mapbox GL."
}
],
"fileNameWithExt": "RasterSource.tsx",
Expand Down
4 changes: 4 additions & 0 deletions example/src/examples/FillRasterLayer/RasterSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export default function RasterSourceExample() {
<RasterSource
id="stamen-watercolor"
tileSize={256}
sourceBounds={[
-74.01010105570786, 40.7096750598196, -74.00028742807824,
40.71670107507063,
]}
tileUrlTemplates={['https://tile.openstreetmap.org/{z}/{x}/{y}.png']}
/>
<RasterLayer
Expand Down
26 changes: 16 additions & 10 deletions ios/RNMBX/RNMBXRasterSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@ public class RNMBXRasterSource : RNMBXSource {
typealias SourceType = RasterSource

@objc public var url: String? = nil

@objc public var tileUrlTemplates: [String]? = nil

@objc public var minZoomLevel: NSNumber?
@objc public var maxZoomLevel: NSNumber?
@objc public var tileSize: NSNumber?

@objc public var tms: Bool = false

@objc public var attribution: String?

@objc public var sourceBounds: [NSNumber]? = nil

override func makeSource() -> Source
{
#if RNMBX_11
Expand All @@ -28,27 +30,31 @@ public class RNMBXRasterSource : RNMBXSource {
} else {
result.tiles = tileUrlTemplates
}

if let tileSize = tileSize {
result.tileSize = tileSize.doubleValue
}

if let minZoomLevel = minZoomLevel {
result.minzoom = minZoomLevel.doubleValue
}

if let maxZoomLevel = maxZoomLevel {
result.maxzoom = maxZoomLevel.doubleValue
}

if tms {
result.scheme = .tms
}

if let attribution = attribution {
result.attribution = attribution
}


if let bounds = sourceBounds {
result.bounds = bounds.map { $0.doubleValue }
}

return result
}

Expand Down
8 changes: 6 additions & 2 deletions ios/RNMBX/RNMBXRasterSourceComponentView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ + (ComponentDescriptorProvider)componentDescriptorProvider

- (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps
{
const auto &newProps = static_cast<const RNMBXRasterSourceProps &>(*props);
const auto &newProps = static_cast<const RNMBXRasterSourceProps &>(*props);
id idx = RNMBXConvertFollyDynamicToId(newProps.id);
if (idx != nil) {
_view.id = idx;
Expand Down Expand Up @@ -113,7 +113,11 @@ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &
if (attribution != nil) {
_view.attribution = attribution;
}

id sourceBounds = RNMBXConvertFollyDynamicToId(newProps.sourceBounds);
if (sourceBounds != nil) {
_view.sourceBounds = sourceBounds;
}

[super updateProps:props oldProps:oldProps];
}

Expand Down
2 changes: 1 addition & 1 deletion ios/RNMBX/RNMBXRasterSourceViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ @interface RCT_EXTERN_REMAP_MODULE(RNMBXRasterSource, RNMBXRasterSourceViewManag

RCT_EXPORT_VIEW_PROPERTY(tms, BOOL)
RCT_EXPORT_VIEW_PROPERTY(attribution, NSString)

RCT_EXPORT_VIEW_PROPERTY(sourceBounds, NSArray)

@end
6 changes: 6 additions & 0 deletions src/components/RasterSource.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ type Props = BaseProps & {
attribution?: string;

children?: React.ReactElement | React.ReactElement[];
/**
* An array containing the longitude and latitude of the southwest and northeast corners of
* the source's bounding box in the following order: `[sw.lng, sw.lat, ne.lng, ne.lat]`.
* When this property is included in a source, no tiles outside of the given bounds are requested by Mapbox GL.
*/
sourceBounds?: number[];
};

type NativeProps = Props;
Expand Down
1 change: 1 addition & 0 deletions src/specs/RNMBXRasterSourceNativeComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface NativeProps extends ViewProps {
tileSize: UnsafeMixed<Double>;
tms: UnsafeMixed<boolean>;
attribution: UnsafeMixed<string>;
sourceBounds: UnsafeMixed<Array<number>>;
}

export default codegenNativeComponent<NativeProps>(
Expand Down

0 comments on commit 63d74fc

Please sign in to comment.