mapbox / mapbox/mapbox-maps-flutter
[Android] Strange map rendering problems when 3D terrain is enabled
Nobody has claimed this yet.
- Dominant language
- Dart
- Stars
- 380
- Forks
- 204
- PR merge metrics
- No merged PRs in 30d
Description
We have a custom style with 3D terrain enabled and clustered data on the map. When user clicks on the cluster we get the maximum expansion zoom and zoom to that location to uncluster data. If there is more clustered data on that zoom we repeat the step until certain zoom level or until there is no more clustered data and then zoom to level 19 and show some information accordingly. But sometimes when we zoom to certain location it seems like the tiles are failing to load (assumed) until we zoom out to certain level.
In the repro code bellow i removed the clusters logic to simplify it but the problem is reproducible even with 1 feature, and happens only with 3D terrain enabled.
Reproduction code:
```dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
late MapboxMap _map;
void _mapCreated(MapboxMap map) {
_map = map;
}
void _styleLoaded(StyleLoadedEventData event) async {
// not actually needed but we are using mercator projection in the recording
// and in Outdoors v12 style default is globe.
await _map.style.setProjection('mercator');
// This is enabled in Mapbox studio in our apps style.
await _map.style.addSource(RasterDemSource(
id: 'mapbox-dem',
url: 'mapbox://mapbox.mapbox-terrain-dem-v1',
maxzoom: 14,
tileSize: 512,
));
await _map.style.setStyleTerrain(jsonEncode({'source': 'mapbox-dem', 'exaggeration': 1}));
await _map.style.addSource(GeoJsonSource(
id: 'ex_source_id',
data: jsonEncode(data),
));
await _map.style.addLayer(SymbolLayer(
id: 'ex_layer_id',
sourceId: 'ex_source_id',
// we are using custom icon in the recording but issue is the same
iconImage: 'airport',
iconAnchor: IconAnchor.CENTER,
));
}
Future _onTap(ScreenCoordinate coord) async {
final QueriedFeature? feature = await _getRenderedFeature(coord);
if(feature == null)
return;
Position center = Position.fromJson(
(feature.feature['geometry'] as Map)['coordinates']!.cast(),
);
final CameraOptions camOpt = CameraOptions(
center: Point(coordinates: center).toJson(),
zoom: 19,
);
await _map.flyTo(
camOpt,
MapAnimationOptions(duration: 1000),
);
}
Future _getRenderedFeature(ScreenCoordinate coord) async {
final ScreenCoordinate conv = await _map.pixelForCoordinate(
Point(coordinates: Position(coord.y, coord.x)).toJson(),
);
final List features = await _map.queryRenderedFeatures(
RenderedQueryGeometry(
value: jsonEncode(conv.encode()),
type: Type.SCREEN_COORDINATE,
),
RenderedQueryOptions(layerIds: ['ex_layer_id']),
);
if(features.isEmpty)
return null;
return features.first;
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Mapbox Example')),
body: MapWidget(
resourceOptions: ResourceOptions(
accessToken: ,
),
styleUri: 'mapbox://styles/mapbox/outdoors-v12',
onMapCreated: _mapCreated,
onStyleLoadedListener: _styleLoaded,
onTapListener: _onTap,
),
),
);
}
}
const Map data = {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'id': 1,
'geometry': {
'type': 'Point',
'coordinates': [0, 0],
},
},
],
};
```
Here is the screen recording of the issue. In the example above there are some differences to the screen recording but still, the issue is the same. The issue is more reproducible when clicking on the feature from higher zoom levels but it happens even on lower zoom levels.
https://user-images.githubusercontent.com/76993460/219371733-f3c41311-36c7-4faa-ab69-bbb9cd43bb49.mp4
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the reproduction code, especially _styleLoaded, the RasterDemSource terrain setup, and the flyTo call in _onTap. Reproduce the issue with the provided MapWidget and terrain configuration, then verify that tiles continue rendering correctly while zooming to level 19 with 3D terrain enabled.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- dart, flutter
- Domain
- mobile
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100