diff --git a/android/src/main/java/org/maplibre/reactnative/components/mapview/MLRNMapView.java b/android/src/main/java/org/maplibre/reactnative/components/mapview/MLRNMapView.java index 4ea17fd5f..0f4ccf692 100644 --- a/android/src/main/java/org/maplibre/reactnative/components/mapview/MLRNMapView.java +++ b/android/src/main/java/org/maplibre/reactnative/components/mapview/MLRNMapView.java @@ -8,7 +8,6 @@ import android.location.Location; import android.os.Handler; import androidx.annotation.NonNull; -import androidx.annotation.UiThread; import android.util.DisplayMetrics; import android.util.Pair; @@ -53,7 +52,6 @@ import org.maplibre.reactnative.components.AbstractMapFeature; import org.maplibre.reactnative.components.annotation.MLRNPointAnnotation; import org.maplibre.reactnative.components.annotation.MLRNMarkerView; -import org.maplibre.reactnative.components.annotation.MarkerView; import org.maplibre.reactnative.components.annotation.MarkerViewManager; import org.maplibre.reactnative.components.camera.MLRNCamera; import org.maplibre.reactnative.components.images.MLRNImages; @@ -69,6 +67,7 @@ import org.maplibre.reactnative.events.MapChangeEvent; import org.maplibre.reactnative.events.MapClickEvent; import org.maplibre.reactnative.events.constants.EventTypes; +import org.maplibre.reactnative.modules.MLRNModule; import org.maplibre.reactnative.utils.BitmapUtils; import org.maplibre.reactnative.utils.GeoJSONUtils; import org.maplibre.reactnative.utils.GeoViewport; @@ -85,7 +84,6 @@ import javax.annotation.Nullable; import static org.maplibre.android.style.layers.PropertyFactory.visibility; -import static org.maplibre.reactnative.modules.MLRNOfflineModule.DEFAULT_STYLE_URL; @SuppressWarnings({ "MissingPermission" }) public class MLRNMapView extends MapView implements OnMapReadyCallback, MapLibreMap.OnMapClickListener, @@ -117,7 +115,7 @@ public class MLRNMapView extends MapView implements OnMapReadyCallback, MapLibre private LocalizationPlugin mLocalizationPlugin; - private String mStyleURL; + private String mMapStyle; private Integer mPreferredFramesPerSecond; private boolean mLocalizeLabels; @@ -171,7 +169,7 @@ public MLRNMapView(Context context, MLRNMapViewManager manager, MapLibreMapOptio mHandler = new Handler(); - mStyleURL = DEFAULT_STYLE_URL; + mMapStyle = MLRNModule.DEFAULT_STYLE_URL; setLifecycleListeners(); @@ -436,10 +434,10 @@ public boolean isJSONValid(String test) { public void onMapReady(final MapLibreMap mapboxMap) { mMap = mapboxMap; - if (isJSONValid(mStyleURL)) { - mMap.setStyle(new Style.Builder().fromJson(mStyleURL)); + if (isJSONValid(mMapStyle)) { + mMap.setStyle(new Style.Builder().fromJson(mMapStyle)); } else { - mMap.setStyle(new Style.Builder().fromUri(mStyleURL)); + mMap.setStyle(new Style.Builder().fromUri(mMapStyle)); } reflow(); @@ -776,21 +774,21 @@ private float getDisplayDensity() { return mContext.getResources().getDisplayMetrics().density; } - public void setReactStyleURL(String styleURL) { - mStyleURL = styleURL; + public void setReactMapStyle(String mapStyle) { + mMapStyle = mapStyle; if (mMap != null) { removeAllSourcesFromMap(); - if (isJSONValid(mStyleURL)) { - mMap.setStyle(new Style.Builder().fromJson(mStyleURL), new Style.OnStyleLoaded() { + if (isJSONValid(mMapStyle)) { + mMap.setStyle(new Style.Builder().fromJson(mMapStyle), new Style.OnStyleLoaded() { @Override public void onStyleLoaded(@NonNull Style style) { addAllSourcesToMap(); } }); } else { - mMap.setStyle(styleURL, new Style.OnStyleLoaded() { + mMap.setStyle(mapStyle, new Style.OnStyleLoaded() { @Override public void onStyleLoaded(@NonNull Style style) { addAllSourcesToMap(); diff --git a/android/src/main/java/org/maplibre/reactnative/components/mapview/MLRNMapViewManager.java b/android/src/main/java/org/maplibre/reactnative/components/mapview/MLRNMapViewManager.java index 9e34fb958..bbf50d94c 100644 --- a/android/src/main/java/org/maplibre/reactnative/components/mapview/MLRNMapViewManager.java +++ b/android/src/main/java/org/maplibre/reactnative/components/mapview/MLRNMapViewManager.java @@ -1,7 +1,6 @@ package org.maplibre.reactnative.components.mapview; import android.util.Log; -import android.view.Gravity; import android.view.View; import com.facebook.react.bridge.ReactApplicationContext; @@ -11,23 +10,17 @@ import com.facebook.react.uimanager.LayoutShadowNode; import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.annotations.ReactProp; -import org.maplibre.android.geometry.LatLngBounds; -import org.maplibre.android.log.Logger; + import org.maplibre.android.maps.MapLibreMap; import org.maplibre.reactnative.components.AbstractEventEmitter; import org.maplibre.reactnative.events.constants.EventKeys; import org.maplibre.reactnative.utils.ConvertUtils; import org.maplibre.reactnative.utils.ExpressionParser; import org.maplibre.reactnative.utils.GeoJSONUtils; -import org.maplibre.geojson.FeatureCollection; -import org.maplibre.geojson.Point; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.FutureTask; -import java.util.concurrent.RunnableFuture; import javax.annotation.Nullable; @@ -111,9 +104,9 @@ public MLRNMapView getByReactTag(int reactTag) { //region React Props - @ReactProp(name="styleURL") - public void setStyleURL(MLRNMapView mapView, String styleURL) { - mapView.setReactStyleURL(styleURL); + @ReactProp(name="mapStyle") + public void setMapStyle(MLRNMapView mapView, String mapStyle) { + mapView.setReactMapStyle(mapStyle); } @ReactProp(name="preferredFramesPerSecond") diff --git a/android/src/main/java/org/maplibre/reactnative/modules/MLRNModule.java b/android/src/main/java/org/maplibre/reactnative/modules/MLRNModule.java index b35d8741f..6fc0628a3 100644 --- a/android/src/main/java/org/maplibre/reactnative/modules/MLRNModule.java +++ b/android/src/main/java/org/maplibre/reactnative/modules/MLRNModule.java @@ -32,6 +32,8 @@ public class MLRNModule extends ReactContextBaseJavaModule { public static final String REACT_CLASS = "MLRNModule"; + public static final String DEFAULT_STYLE_URL = "https://demotiles.maplibre.org/style.json"; + private static boolean customHeaderInterceptorAdded = false; private Handler mUiThreadHandler; @@ -52,7 +54,7 @@ public String getName() { public Map getConstants() { // map style urls Map styleURLS = new HashMap<>(); - styleURLS.put("Default", "https://demotiles.maplibre.org/style.json"); + styleURLS.put("Default", DEFAULT_STYLE_URL); // events Map eventTypes = new HashMap<>(); diff --git a/android/src/main/java/org/maplibre/reactnative/modules/MLRNOfflineModule.java b/android/src/main/java/org/maplibre/reactnative/modules/MLRNOfflineModule.java index 5f5e66e19..7703e4cef 100644 --- a/android/src/main/java/org/maplibre/reactnative/modules/MLRNOfflineModule.java +++ b/android/src/main/java/org/maplibre/reactnative/modules/MLRNOfflineModule.java @@ -9,7 +9,6 @@ import com.facebook.react.module.annotations.ReactModule; import com.facebook.react.modules.core.RCTNativeAppEventEmitter; import org.maplibre.geojson.FeatureCollection; -// import org.maplibre.android.constants.Style; import org.maplibre.android.geometry.LatLngBounds; import org.maplibre.android.offline.OfflineManager; import org.maplibre.android.offline.OfflineRegion; @@ -43,7 +42,6 @@ public class MLRNOfflineModule extends ReactContextBaseJavaModule { public static final String OFFLINE_ERROR = "MapboxOfflineRegionError"; public static final String OFFLINE_PROGRESS = "MapboxOfflineRegionProgress"; - public static final String DEFAULT_STYLE_URL = "https://demotiles.maplibre.org/style.json"; public static final Double DEFAULT_MIN_ZOOM_LEVEL = 10.0; public static final Double DEFAULT_MAX_ZOOM_LEVEL = 20.0; @@ -426,7 +424,7 @@ public void setProgressEventThrottle(double eventThrottle) { private OfflineRegionDefinition makeDefinition(LatLngBounds latLngBounds, ReadableMap options) { return new OfflineTilePyramidRegionDefinition( - ConvertUtils.getString("styleURL", options, DEFAULT_STYLE_URL), + ConvertUtils.getString("styleURL", options, MLRNModule.DEFAULT_STYLE_URL), latLngBounds, ConvertUtils.getDouble("minZoom", options, DEFAULT_MIN_ZOOM_LEVEL), ConvertUtils.getDouble("maxZoom", options, DEFAULT_MAX_ZOOM_LEVEL), diff --git a/docs/components/MapView.md b/docs/components/MapView.md index 2f4dd62b8..e7284c617 100644 --- a/docs/components/MapView.md +++ b/docs/components/MapView.md @@ -8,8 +8,7 @@ MapView backed by MapLibre Native | ---- | :--: | :-----: | :------: | :----------: | | contentInset | `number[] \| number` | `none` | `false` | The distance from the edges of the map view’s frame to the edges of the map view’s logical viewport. | | style | `ViewProps["style"]` | `none` | `false` | Style for wrapping React Native View | -| styleURL | `string` | `none` | `false` | Style URL for map - notice, if non is set it _will_ default to `MapLibreGL.StyleURL.Default` | -| styleJSON | `string` | `none` | `false` | StyleJSON for map - according to TileJSON specs: https://github.com/mapbox/tilejson-spec | +| mapStyle | `string \| object` | `none` | `false` | Style for map - either a URL or a Style JSON (https://maplibre.org/maplibre-style-spec/). Default: `MapLibreRN.StyleURL.Default` | | preferredFramesPerSecond | `number` | `none` | `false` | iOS: The preferred frame rate at which the map view is rendered.
The default value for this property is MLNMapViewPreferredFramesPerSecondDefault,
which will adaptively set the preferred frame rate based on the capability of
the user’s device to maintain a smooth experience. This property can be set to arbitrary integer values.

Android: The maximum frame rate at which the map view is rendered, but it can't excess the ability of device hardware.
This property can be set to arbitrary integer values. | | localizeLabels | `boolean` | `false` | `false` | Automatically change the language of the map labels to the system’s preferred language,
this is not something that can be toggled on/off | | zoomEnabled | `boolean` | `none` | `false` | Enable/Disable zoom on the map | diff --git a/docs/docs.json b/docs/docs.json index cfcb91f01..6d929e9a9 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -2405,18 +2405,11 @@ "description": "Style for wrapping React Native View" }, { - "name": "styleURL", + "name": "mapStyle", "required": false, - "type": "string", - "default": "none", - "description": "Style URL for map - notice, if non is set it _will_ default to `MapLibreGL.StyleURL.Default`" - }, - { - "name": "styleJSON", - "required": false, - "type": "string", + "type": "string \\| object", "default": "none", - "description": "StyleJSON for map - according to TileJSON specs: https://github.com/mapbox/tilejson-spec" + "description": "Style for map - either a URL or a Style JSON (https://maplibre.org/maplibre-style-spec/). Default: `MapLibreRN.StyleURL.Default`" }, { "name": "preferredFramesPerSecond", diff --git a/ios/MLRN/MLRNMapView.h b/ios/MLRN/MLRNMapView.h index e6efa3368..b95e47e4c 100644 --- a/ios/MLRN/MLRNMapView.h +++ b/ios/MLRN/MLRNMapView.h @@ -47,7 +47,7 @@ typedef void (^StyleLoadedBlock) (MLNStyle* __nonnull style); @property (nonatomic, assign) NSInteger *reactCompassViewPosition; @property (nonatomic, assign) CGPoint reactCompassViewMargins; -@property (nonatomic, copy) NSString *reactStyleURL; +@property (nonatomic, copy) NSString *reactMapStyle; @property (nonatomic, assign) NSInteger reactPreferredFramesPerSecond; @property (nonatomic, assign) MLNCoordinateBounds maxBounds; diff --git a/ios/MLRN/MLRNMapView.m b/ios/MLRN/MLRNMapView.m index a6690cdee..fbbea9363 100644 --- a/ios/MLRN/MLRNMapView.m +++ b/ios/MLRN/MLRNMapView.m @@ -374,11 +374,11 @@ - (void)setReactContentInset:(NSArray *)reactContentInset self.contentInset = UIEdgeInsetsMake(top, left, bottom, right); } -- (void)setReactStyleURL:(NSString *)reactStyleURL +- (void)setReactMapStyle:(NSString *)reactMapStyle { - _reactStyleURL = reactStyleURL; + _reactMapStyle = reactMapStyle; [self _removeAllSourcesFromMap]; - self.styleURL = [self _getStyleURLFromKey:_reactStyleURL]; + self.styleURL = [self _getStyleURLFromKey:_reactMapStyle]; } - (void)setReactPreferredFramesPerSecond:(NSInteger)reactPreferredFramesPerSecond @@ -500,13 +500,13 @@ - (MLRNSource *)getTouchableSourceWithHighestZIndex:(NSArray *)tou return nil; } -- (NSURL*)_getStyleURLFromKey:(NSString *)styleURL +- (NSURL*)_getStyleURLFromKey:(NSString *)mapStyle { - NSURL *url = [NSURL URLWithString:styleURL]; + NSURL *url = [NSURL URLWithString:mapStyle]; if (url) { return url; - } else if (RCTJSONParse(styleURL, nil)) { - return [MLRNUtils styleURLFromStyleJSON:styleURL]; + } else if (RCTJSONParse(mapStyle, nil)) { + return [MLRNUtils styleURLFromStyleJSON:mapStyle]; } return url; } diff --git a/ios/MLRN/MLRNMapViewManager.m b/ios/MLRN/MLRNMapViewManager.m index a8b6cc5d5..df7b34ed6 100644 --- a/ios/MLRN/MLRNMapViewManager.m +++ b/ios/MLRN/MLRNMapViewManager.m @@ -80,7 +80,7 @@ - (UIView *)view RCT_REMAP_VIEW_PROPERTY(compassViewMargins, reactCompassViewMargins, CGPoint) RCT_REMAP_VIEW_PROPERTY(contentInset, reactContentInset, NSArray) -RCT_REMAP_VIEW_PROPERTY(styleURL, reactStyleURL, NSString) +RCT_REMAP_VIEW_PROPERTY(mapStyle, reactMapStyle, NSString) RCT_REMAP_VIEW_PROPERTY(preferredFramesPerSecond, reactPreferredFramesPerSecond, NSInteger) RCT_EXPORT_VIEW_PROPERTY(tintColor, UIColor) diff --git a/ios/MLRN/MLRNModule.m b/ios/MLRN/MLRNModule.m index 33aa9359e..14a8c01db 100644 --- a/ios/MLRN/MLRNModule.m +++ b/ios/MLRN/MLRNModule.m @@ -19,10 +19,6 @@ + (BOOL)requiresMainQueueSetup { // style urls NSMutableDictionary *styleURLS = [[NSMutableDictionary alloc] init]; - - for (MLNDefaultStyle* style in [MLNStyle predefinedStyles]) { - [styleURLS setObject:[style.url absoluteString] forKey:style.name]; - } [styleURLS setObject:[[MLNStyle defaultStyleURL] absoluteString] forKey:@"Default"]; // event types diff --git a/packages/examples/src/examples/Map/CreateOfflineRegion.tsx b/packages/examples/src/examples/Map/CreateOfflineRegion.tsx index bf006c353..8214f71ad 100755 --- a/packages/examples/src/examples/Map/CreateOfflineRegion.tsx +++ b/packages/examples/src/examples/Map/CreateOfflineRegion.tsx @@ -182,7 +182,7 @@ export default function CreateOfflineRegion() { - {isLoading === false && ( + {!isLoading && ( {offlineRegionStatus === null && ( diff --git a/packages/examples/src/examples/Map/LocalStyleJSON.tsx b/packages/examples/src/examples/Map/LocalStyleJSON.tsx index b83eba854..ab75bc8bd 100644 --- a/packages/examples/src/examples/Map/LocalStyleJSON.tsx +++ b/packages/examples/src/examples/Map/LocalStyleJSON.tsx @@ -7,9 +7,6 @@ import MapLibreDemoTilesWhite from "../../assets/styles/maplibre-demo-tiles-whit import Bubble from "../../components/Bubble"; import { sheet } from "../../styles/sheet"; -const STYLE_BLUE = JSON.stringify(MapLibreDemoTilesBlue); -const STYLE_WHITE = JSON.stringify(MapLibreDemoTilesWhite); - export default function LocalStyleJSON() { const [color, setColor] = useState<"blue" | "white">("blue"); @@ -17,7 +14,9 @@ export default function LocalStyleJSON() { <> diff --git a/packages/examples/src/examples/UserLocation/FollowUserLocationRenderMode.tsx b/packages/examples/src/examples/UserLocation/FollowUserLocationRenderMode.tsx index 8d95c7d76..389cb81cf 100755 --- a/packages/examples/src/examples/UserLocation/FollowUserLocationRenderMode.tsx +++ b/packages/examples/src/examples/UserLocation/FollowUserLocationRenderMode.tsx @@ -96,10 +96,7 @@ export default function FollowUserLocationRenderMode() { )} - + ; getAccessToken(): Promise; diff --git a/src/components/MapView.tsx b/src/components/MapView.tsx index ece9160a6..25868082e 100644 --- a/src/components/MapView.tsx +++ b/src/components/MapView.tsx @@ -46,8 +46,6 @@ const styles = StyleSheet.create({ matchParent: { flex: 1 }, }); -const defaultStyleURL = MapLibreRN.StyleURL.Street; - export interface RegionPayload { zoomLevel: number; heading: number; @@ -69,13 +67,9 @@ interface MapViewProps extends BaseProps { */ style?: ViewProps["style"]; /** - * Style URL for map - notice, if non is set it _will_ default to `MapLibreGL.StyleURL.Default` - */ - styleURL?: string; - /** - * StyleJSON for map - according to TileJSON specs: https://github.com/mapbox/tilejson-spec + * Style for map - either a URL or a Style JSON (https://maplibre.org/maplibre-style-spec/). Default: `MapLibreRN.StyleURL.Default` */ - styleJSON?: string; + mapStyle?: string | object; /** * iOS: The preferred frame rate at which the map view is rendered. * The default value for this property is MLNMapViewPreferredFramesPerSecondDefault, @@ -165,7 +159,7 @@ interface MapViewProps extends BaseProps { /** * This event is triggered whenever the currently displayed map region is about to change. * - * @param {PointFeature} feature - The geojson point feature at the camera center, properties contains zoomLevel, visibleBounds + * @param {GeoJSON.Feature} feature - The geojson point feature at the camera center, properties contains zoomLevel, visibleBounds */ onRegionWillChange?( feature: GeoJSON.Feature, @@ -173,7 +167,7 @@ interface MapViewProps extends BaseProps { /** * This event is triggered whenever the currently displayed map region is changing. * - * @param {PointFeature} feature - The geojson point feature at the camera center, properties contains zoomLevel, visibleBounds + * @param {GeoJSON.Feature} feature - The geojson point feature at the camera center, properties contains zoomLevel, visibleBounds */ onRegionIsChanging?( feature: GeoJSON.Feature, @@ -181,7 +175,7 @@ interface MapViewProps extends BaseProps { /** * This event is triggered whenever the currently displayed map region finished changing * - * @param {PointFeature} feature - The geojson point feature at the camera center, properties contains zoomLevel, visibleBounds + * @param {GeoJSON.Feature} feature - The geojson point feature at the camera center, properties contains zoomLevel, visibleBounds */ onRegionDidChange?( feature: GeoJSON.Feature, @@ -250,6 +244,7 @@ type CallableProps = { }[keyof MapViewProps]; interface NativeProps extends Omit { + mapStyle?: string; onPress(event: NativeSyntheticEvent<{ payload: GeoJSON.Feature }>): void; onLongPress(event: NativeSyntheticEvent<{ payload: GeoJSON.Feature }>): void; } @@ -771,27 +766,20 @@ const MapView = memo( } }; - const _setStyleURL = (props: MapViewProps): void => { - // user set a styleURL, no need to alter props - if (props.styleURL) { - return; - } - - // user set styleJSON pass it to styleURL - if (props.styleJSON && !props.styleURL) { - props.styleURL = props.styleJSON; - } - - // user neither set styleJSON nor styleURL - // set defaultStyleUrl - if (!props.styleJSON || !props.styleURL) { - props.styleURL = defaultStyleURL; + const nativeProps = useMemo(() => { + const { mapStyle, ...otherProps } = props; + + let nativeMapStyle = undefined; + if (mapStyle) { + if (typeof mapStyle === "string") { + nativeMapStyle = mapStyle; + } else if (typeof mapStyle === "object") { + nativeMapStyle = JSON.stringify(mapStyle); + } } - }; - const nativeProps = useMemo(() => { return { - ...props, + ...otherProps, localizeLabels, scrollEnabled, pitchEnabled, @@ -801,10 +789,12 @@ const MapView = memo( surfaceView, regionWillChangeDebounceTime, regionDidChangeDebounceTime, + mapStyle: nativeMapStyle, contentInset: contentInsetValue, style: styles.matchParent, }; }, [ + props, localizeLabels, scrollEnabled, pitchEnabled, @@ -814,12 +804,9 @@ const MapView = memo( surfaceView, regionWillChangeDebounceTime, regionDidChangeDebounceTime, - props, contentInsetValue, ]); - _setStyleURL(nativeProps); - const callbacks = { ref: (ref: MLRNMapViewRefType): void => _setNativeRef(ref), onPress: _onPress, diff --git a/src/types/StyleURL.ts b/src/types/StyleURL.ts deleted file mode 100644 index 728218f2f..000000000 --- a/src/types/StyleURL.ts +++ /dev/null @@ -1,3 +0,0 @@ -export enum StyleURL { - Default = "https://demotiles.maplibre.org/style.json", -}