maps
maps copied to clipboard
[Bug]: Existing layers when the map is offline
Mapbox Implementation
Mapbox
Mapbox Version
10.16.1
Platform
Android
@rnmapbox/maps version
#main
Standalone component to reproduce
import Mapbox, { Camera, MapView } from '@rnmapbox/maps';
import React, { useState } from 'react';
import { Button } from 'react-native';
const getStyles = (isDark) => ({
mapView: { flex: 1 },
overlay: {
fillColor: isDark ? 'hsl(76,26%,75%)' : 'hsl(200,46%,69%)',
},
});
const { Dark, Light } = Mapbox.StyleURL;
const BugReportExample = () => {
const [styleUrl, setStyleUrl] = useState(Light);
const isDark = styleUrl === Dark;
const buttonTitle = isDark ? 'Set Light' : 'Set Dark';
const styles = getStyles(isDark);
return (
<>
<Button
title={buttonTitle}
onPress={() => setStyleUrl(isDark ? Light : Dark)}
/>
<MapView style={styles.mapView} styleURL={styleUrl}>
<Camera centerCoordinate={[-74.00597, 40.71427]} zoomLevel={14} />
<Mapbox.VectorSource id="composite">
<Mapbox.FillLayer
id="national-park"
sourceLayerID="landuse_overlay"
sourceID="composite"
style={styles.overlay}
/>
</Mapbox.VectorSource>
</MapView>
</>
);
};
export default BugReportExample;
Observed behavior and steps to reproduce
In our app we experience this issue when styles are switched in 2 scenarios
- Fast switching between dark and satellite mode (can't reproduce it in Example app). Our workaround is to apply(mount) custom sources and layers only after
onDidFinishLoadingMapis fired - In offline mode between switching dark and light mode
The second scenario could be reproducable by using BugReportExample
- In online mode open Bug Report Template TS
- Go Offline
- Switch to Dark mode. Dark styles will be missed as no connection
- Switch back to Light mode.
Actual result:
Error while updating property 'reactStyle' of a view managed by: RNMBXFillLayer null Set layer property "fill-color" failed: Layer national-park is not in style:
Expected behavior
No issues
Notes / preliminary analysis
It happens only when color is dynamically changed:
fillColor: isDark ? 'hsl(76,26%,75%)' : 'hsl(200,46%,69%)',
No issues in this case:
fillColor: 'hsl(76,26%,75%)'
Additional links and references
No response
I got some similar errors when changing the styleURL. This one seems to be caused by the compass:
Error while updating property 'reactStyle' of a view managed by: RCTMGLSymbolLayer
...
Caused by com.mapbox.maps.MapboxStyleException: Set layer property "icon-rotate" failed:
Layer mapboxUserLocationHeadingIndicator is not in style
159.71372985839844
at com.mapbox.maps.extension.style.layers.Layer.updateProperty(Layer.kt:152)
at com.mapbox.maps.extension.style.layers.Layer.setProperty$extension_style_publicRelease(Layer.kt:141)
at com.mapbox.maps.extension.style.layers.generated.SymbolLayer.iconRotate(SymbolLayer.kt:809)
at com.mapbox.rctmgl.components.styles.RCTMGLStyleFactory.setIconRotate(RCTMGLStyleFactory.java:1318)
at com.mapbox.rctmgl.components.styles.RCTMGLStyleFactory.setSymbolLayerStyle(RCTMGLStyleFactory.java:255)
at com.mapbox.rctmgl.components.styles.layers.RCTMGLSymbolLayer.addStyles(RCTMGLSymbolLayer.kt:31)
at com.mapbox.rctmgl.components.styles.layers.RCTLayer.setReactStyle(RCTLayer.kt:124)
at com.mapbox.rctmgl.components.styles.layers.RCTMGLSymbolLayerManager.setReactStyle(RCTMGLSymbolLayerManager.kt:60)
at java.lang.reflect.Method.invoke(Method.java)
...
I don't see this warning on main.
I've needed to add existing flags for the source and layer as those were referring to existing layers in the style:
import Mapbox, { Camera, MapView } from '@rnmapbox/maps';
import React, { useState } from 'react';
import { Button } from 'react-native';
const getStyles = (isDark) => ({
mapView: { flex: 1 },
overlay: {
fillColor: isDark ? 'hsl(76,26%,75%)' : 'hsl(200,46%,69%)',
},
});
const { Dark, Light } = Mapbox.StyleURL;
const BugReportExample = () => {
const [styleUrl, setStyleUrl] = useState(Light);
const isDark = styleUrl === Dark;
const buttonTitle = isDark ? 'Set Light' : 'Set Dark';
const styles = getStyles(isDark);
return (
<>
<Button
title={buttonTitle}
onPress={() => setStyleUrl(isDark ? Light : Dark)}
/>
<MapView style={styles.mapView} styleURL={styleUrl}>
<Camera centerCoordinate={[-74.00597, 40.71427]} zoomLevel={14} />
<Mapbox.VectorSource id="composite" existing>
<Mapbox.FillLayer
id="national-park"
sourceLayerID="landuse_overlay"
sourceID="composite"
existing
style={styles.overlay}
/>
</Mapbox.VectorSource>
</MapView>
</>
);
};
export default BugReportExample;
@mfazekas It always reproduces even with existing property.
The problem is the next: once the new styles are applied, all features will be removed from map including "existing", but the logic to recreate them doesn't exist. Should not they be skipped, as creating/deleting "existing" features should be handled by mapbox itself
@mfazekas It always reproduces even with
existingproperty. The problem is the next: once the new styles are applied, all features will be removed from map including "existing", but the logic to recreate them doesn't exist. Should not they be skipped, as creating/deleting "existing" features should be handled by mapbox itself
@orca-nazar can you be please more specific. Which @rnmapbox/maps version have you tested with , which component you've tried? The one in my comment? - https://github.com/rnmapbox/maps/issues/3152#issuecomment-1810898667
Correct, I use the latest version and your component
@orca-nazar I don't see the issue on current #main.
import Mapbox, { Camera, MapView } from '@rnmapbox/maps';
import React, { useState } from 'react';
import { Button } from 'react-native';
const getStyles = (isDark) => ({
mapView: { flex: 1 },
overlay: {
fillColor: isDark ? 'hsl(76,26%,75%)' : 'hsl(200,46%,69%)',
},
});
const { Dark, Light } = Mapbox.StyleURL;
const BugReportExample = () => {
const [styleUrl, setStyleUrl] = useState(Light);
const isDark = styleUrl === Dark;
const buttonTitle = isDark ? 'Set Light' : 'Set Dark';
const styles = getStyles(isDark);
return (
<>
<Button
title={buttonTitle}
onPress={() => setStyleUrl(isDark ? Light : Dark)}
/>
<MapView style={styles.mapView} styleURL={styleUrl}>
<Camera
defaultSettings={{
centerCoordinate: [-74.00597, 40.71427],
zoomLevel: 8,
}}
/>
<Mapbox.VectorSource id="composite" existing>
<Mapbox.FillLayer
id="national-park"
sourceLayerID="landuse_overlay"
sourceID="composite"
existing
style={styles.overlay}
/>
</Mapbox.VectorSource>
</MapView>
</>
);
};
export default BugReportExample;
https://github.com/rnmapbox/maps/assets/52435/4aa3d02e-8064-44d5-95a0-612805cec2e6
Please check the steps to reproduce, the main point here was to go to offline mode. But before it, you need to clear the map data. You can go to app settings and clear data storage or delete/install the app. Then please follow the steps in the video. Thanks :) @mfazekas
I think we need to add a check that if component is declared mExisitng but layer doesn't exists then we need to defer adding the layer until it's available, ideally we can use mapView.waitForLayer( for that.
https://github.com/rnmapbox/maps/blob/12946ef74f3fe98e9bf967c7ea46049a5a3e1e2c/android/src/main/java/com/rnmapbox/rnmbx/components/styles/layers/RNMBXLayer.kt#L286-L299
Sounds good. Also, I'm wondering if this technique can be useful for the next case:
Fast switching between dark and satellite mode (can't reproduce it in Example app). Our workaround is to apply(mount) custom sources and layers only after onDidFinishLoadingMap is fired
So it could applied to filters and styles props updates
Hi, any updates on this issue? I'm experiencing the same issue on Android, on iOS it looks without any problem. Thank you