maps
maps copied to clipboard
MapView does not display CircleLayer or fire onDidFinishLoadingMap callback or onRegionDidChange callback when offline and map has never been loaded online
Describe the bug
MapView does not display CircleLayer or fire onDidFinishLoadingMap callback or onRegionDidChange callback when offline and map has never been loaded online
To Reproduce
- Delete app to ensure Mapbox has not cached/persisted anything
- Install app
- createPack
- getPack to ensure createPack result is persisted
- cut network connection so app is offline
- open map
- note that tiles load in expected zoom range and within expected bounds
- note that only SymbolLayers load but not CircleLayers
- note that onRegionDidChange MapView callback is never fired
- note that onDidFinishLoadingMap MapView callback is never fired
- re-enable network connection and reload map - note that all expected MapView layers appear, onRegionDidChange callback fires, and onDidFinishLoadingMap callback fires
Please include a single standalone React Native component.
class MapBoxMap extends Component {
// Points that never get clustered
_renderPoints = (featureDefinition, index) => {
const {
onSelectFeature,
} = this.props;
const {
featureCollection,
minZoomLevel = 1,
maxZoomLevel = MAPBOX_MAX_ZOOM_LEVEL,
styles,
} = featureDefinition;
const {
point,
pointText,
pointSelected,
pointSelectedText,
pointSymbol,
pointSymbolSelected,
} = styles;
return (
<MapboxGL.ShapeSource
key={`points ${index}`}
id={`points ${index}`}
shape={featureCollection}
ref={shape => (this.pointShape = shape)}
>
{/* Point selected */}
{ pointSelected &&
<MapboxGL.CircleLayer
id={`point_selected ${index}`}
belowLayerID={`point_selected_text ${index}`}
filter={['==', ['get', 'selected'], true]}
style={pointSelected}
minZoomLevel={minZoomLevel}
maxZoomLevel={maxZoomLevel}
/>
}
{/* Point symbol */}
{ pointSymbol &&
<MapboxGL.SymbolLayer
id={`point_symbol ${index}`}
filter={['!=', 'selected', true]}
style={pointSymbol}
minZoomLevel={minZoomLevel}
maxZoomLevel={maxZoomLevel}
/>
}
{/* Point symbol selected */}
{ pointSymbolSelected &&
<MapboxGL.SymbolLayer
id={`point_symbol_selected ${index}`}
filter={['==', ['get', 'selected'], true]}
style={pointSymbolSelected}
minZoomLevel={minZoomLevel}
maxZoomLevel={maxZoomLevel}
/>
}
</MapboxGL.ShapeSource>
);
}
render() {
const {
style,
disabled,
zoomDisabled,
onMapLayout,
} = this.props;
return (
<View style={StyleSheet.flatten([styles.mapContainer, style])}>
<MapboxGL.MapView
ref={(ref) => (this._map = ref)}
style={styles.map}
showUserLocation
scrollEnabled={!disabled}
zoomEnabled={!disabled && !zoomDisabled}
pitchEnabled={!disabled}
rotateEnabled={!disabled}
onLayout={e => {
this._layout = e.nativeEvent.layout;
if (onMapLayout) {
onMapLayout();
}
}}
onRegionDidChange={async (shape) => {
console.log('onRegionDidChange');
}}
onDidFinishLoadingMap={() => {
console.log('onDidFinishLoadingMap');
}}
minZoomLevel={1}
maxZoomLevel={MAPBOX_MAX_ZOOM_LEVEL}
compassEnabled={false}
scaleBarEnabled={false}
attributionPosition={{ bottom: 5, left: 85 }}
>
<MapboxGL.Camera
ref={(ref) => (this._camera = ref)}
zoomLevel={this.state.initialZoomLevel}
centerCoordinate={this.state.initialCenterCoordinate}
bounds={this.state.initialBounds}
minZoomLevel={1}
maxZoomLevel={MAPBOX_MAX_ZOOM_LEVEL}
animationDuration={10}
/>
<MapboxGL.UserLocation
showsUserHeadingIndicator
visible
/>
{this._renderPoints()}
</MapboxGL.MapView>
</View>
);
}
}
const ShapeStyles = {
// Parking pois
parkingPointSymbol: {
iconImage: MapParkingIcon,
iconSize: Platform.OS === 'ios' ? 0.45 : 1.0,
iconPitchAlignment: 'viewport',
iconRotationAlignment: 'viewport',
},
parkingPointSymbolSelected: {
iconImage: MapParkingPopIcon,
iconSize: Platform.OS === 'ios' ? 0.2 : 0.5,
iconAllowOverlap: true,
iconPitchAlignment: 'viewport',
iconRotationAlignment: 'viewport',
iconOffset: Platform.OS === 'ios' ? [0, -105] : [0, -40],
},
parkingPointSelected: {
circlePitchAlignment: 'map',
circleColor: AppTheme.poiPurple,
circleRadius: 2,
circleStrokeWidth: 1,
circleStrokeColor: 'white',
},
}
Expected behavior
- MapView should render pointSelected MapboxGL.CircleLayer offline without needing to first render while online
- MapView should fire onRegionDidChange offline without first loading online
- MapView should fire onDidFinishLoadingMap offline without first loading online
Actual behavior
See above description and repro steps
Versions (please complete the following information):
- Platform: iOS
- Platform OS: iOS 15.5
- Device: iPhone 13
- Emulator/ Simulator: yes
- Dev OS: MacOS 12.4
- @rnmapbox/maps "@rnmapbox/maps": "github:rnmapbox/maps#main" $RNMapboxMapsImpl = 'mapbox' $RNMapboxMapsVersion = '~> 10.6.0'
- React Native Version 0.68.2
+1
As a hacky workaround we pre-load all custom feature styling on a MapView off-screen to load custom stylings into ambient cache. Not ideal though.
Hi thanks for the report.
Can you please make the example self contained, right now there are consants, etc missing from the example. Having a self contained example makes it easy to just copy your code into our BugRepExample.js and try out.
The simpler to reproduce the issue the more likely we can look into it. Thanks for the understanding.
@mfazekas unfortunately i wasn't able to repro in the simplest MapView ShapeSource implementation with only CircleLayer and SymbolLayer. I'll try later to slowly build to only the exact configuration that causes the issue and then add the code to this issue when I've got it.
NOTE: above workaround from @wen-kai is a solution for now
I'm closing this, we'll reopen if we can reproduce