perf: do not filter markers

This commit is contained in:
wuzihao051119 2025-07-16 18:18:51 +08:00 committed by mertalev
parent fca27e1cee
commit bcac0983d7
No known key found for this signature in database
GPG Key ID: DF6ABC77AAD98C95
3 changed files with 22 additions and 12 deletions

View File

@ -41,7 +41,7 @@ class MapStateNotifier extends Notifier<MapState> {
// This provider watches the markers from the map service and serves the markers. // This provider watches the markers from the map service and serves the markers.
// It should be used only after the map service provider is overridden // It should be used only after the map service provider is overridden
final mapMarkerProvider = final mapMarkerProvider =
StreamProvider.family<Map<String, dynamic>, LatLngBounds>( StreamProvider.family<Map<String, dynamic>, LatLngBounds?>(
(ref, bounds) async* { (ref, bounds) async* {
final mapService = ref.watch(mapServiceProvider); final mapService = ref.watch(mapServiceProvider);
yield* mapService.watchMarkers(bounds).map((markers) { yield* mapService.watchMarkers(bounds).map((markers) {

View File

@ -24,7 +24,7 @@ class DriftMapWithMarker extends ConsumerStatefulWidget {
class _DriftMapWithMarkerState extends ConsumerState<DriftMapWithMarker> { class _DriftMapWithMarkerState extends ConsumerState<DriftMapWithMarker> {
MapLibreMapController? mapController; MapLibreMapController? mapController;
static const mapZoomToAssetLevel = 12.0; bool loadAllMarkers = false;
@override @override
void initState() { void initState() {
@ -51,14 +51,17 @@ class _DriftMapWithMarkerState extends ConsumerState<DriftMapWithMarker> {
ref.read(mapStateProvider.notifier).setBounds(bounds); ref.read(mapStateProvider.notifier).setBounds(bounds);
} }
Future<void> reloadMarkers(Map<String, dynamic> markers) async { Future<void> reloadMarkers(
if (mapController == null) return; Map<String, dynamic> markers, {
bool isLoadAllMarkers = false,
}) async {
if (mapController == null || loadAllMarkers) return;
// Wait for previous reload to complete // Wait for previous reload to complete
if (!MapUtils.completer.isCompleted) { if (!MapUtils.markerCompleter.isCompleted) {
return MapUtils.completer.future; return MapUtils.markerCompleter.future;
} }
MapUtils.completer = Completer(); MapUtils.markerCompleter = Completer();
// !! Make sure to remove layers before sources else the native // !! Make sure to remove layers before sources else the native
// maplibre library would crash when removing the source saying that // maplibre library would crash when removing the source saying that
@ -92,7 +95,9 @@ class _DriftMapWithMarkerState extends ConsumerState<DriftMapWithMarker> {
); );
} }
MapUtils.completer.complete(); if (isLoadAllMarkers) loadAllMarkers = true;
MapUtils.markerCompleter.complete();
} }
Future<void> onZoomToLocation() async { Future<void> onZoomToLocation() async {
@ -114,7 +119,7 @@ class _DriftMapWithMarkerState extends ConsumerState<DriftMapWithMarker> {
mapController!.animateCamera( mapController!.animateCamera(
CameraUpdate.newLatLngZoom( CameraUpdate.newLatLngZoom(
LatLng(location.latitude, location.longitude), LatLng(location.latitude, location.longitude),
mapZoomToAssetLevel, MapUtils.mapZoomToAssetLevel,
), ),
duration: const Duration(milliseconds: 800), duration: const Duration(milliseconds: 800),
); );
@ -168,19 +173,23 @@ class _Map extends StatelessWidget {
class _Markers extends ConsumerWidget { class _Markers extends ConsumerWidget {
const _Markers({required this.reloadMarkers}); const _Markers({required this.reloadMarkers});
final Function(Map<String, dynamic>) reloadMarkers; final Function(Map<String, dynamic>, {bool isLoadAllMarkers}) reloadMarkers;
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final bounds = ref.watch(mapStateProvider.select((s) => s.bounds)); final bounds = ref.watch(mapStateProvider.select((s) => s.bounds));
AsyncValue<Map<String, dynamic>> markers = AsyncValue<Map<String, dynamic>> markers =
ref.watch(mapMarkerProvider(bounds)); ref.watch(mapMarkerProvider(bounds));
AsyncValue<Map<String, dynamic>> allMarkers =
ref.watch(mapMarkerProvider(null));
ref.listen(mapStateProvider, (previous, next) async { ref.listen(mapStateProvider, (previous, next) async {
markers = ref.watch(mapMarkerProvider(next.bounds)); markers = ref.watch(mapMarkerProvider(bounds));
}); });
markers.whenData((markers) => reloadMarkers(markers)); markers.whenData((markers) => reloadMarkers(markers));
allMarkers
.whenData((markers) => reloadMarkers(markers, isLoadAllMarkers: true));
return const MapBottomSheet(); return const MapBottomSheet();
} }

View File

@ -10,9 +10,10 @@ import 'package:maplibre_gl/maplibre_gl.dart';
class MapUtils { class MapUtils {
static final Logger _logger = Logger("MapUtils"); static final Logger _logger = Logger("MapUtils");
static const mapZoomToAssetLevel = 12.0;
static const defaultSourceId = 'asset-map-markers'; static const defaultSourceId = 'asset-map-markers';
static const defaultHeatMapLayerId = 'asset-heatmap-layer'; static const defaultHeatMapLayerId = 'asset-heatmap-layer';
static var completer = Completer()..complete(); static var markerCompleter = Completer()..complete();
static const defaultCircleLayerLayerProperties = CircleLayerProperties( static const defaultCircleLayerLayerProperties = CircleLayerProperties(
circleRadius: 10, circleRadius: 10,