buildFlutterMapWidget function
- required MapController mapController,
- required Animation<
double> fadeAnimation, - required MapSettings mapSettings,
- required TileProvider tileProvider,
- required bool applyFilter,
- required List<
MarkerData> filteredMarkers, - required bool shouldAnimate,
- required bool showNewsMarkers,
- required List<
NewsMarker> visibleNewsMarkers, - required void onTap(),
- required void onLongPress(),
- required void onPositionChanged(),
- required void onDeletePlace(),
- required BuildContext context,
- required LatLng initialCenter,
- required double initialZoom,
- required LatLng? userLocation,
- double? maxZoom,
Builds the core FlutterMap widget with all layers.
Performance optimizations:
- Uses RepaintBoundary to isolate map repaints from overlay UI
- Defers marker layer updates when not animating.
Implementation
Widget buildFlutterMapWidget({
required MapController mapController,
required Animation<double> fadeAnimation,
required MapSettings mapSettings,
required TileProvider tileProvider,
required bool applyFilter,
required List<MarkerData> filteredMarkers,
required bool shouldAnimate,
required bool showNewsMarkers,
required List<NewsMarker> visibleNewsMarkers,
required void Function(TapPosition, LatLng) onTap,
required void Function(TapPosition, LatLng) onLongPress,
required void Function(MapCamera, bool) onPositionChanged,
required void Function(MarkerData) onDeletePlace,
required BuildContext context,
required LatLng initialCenter,
required double initialZoom,
required LatLng? userLocation,
double? maxZoom,
}) {
return RepaintBoundary(
child: FadeTransition(
opacity: fadeAnimation,
child: FlutterMap(
// Remove key to allow FlutterMap to properly handle tileProvider changes
// The TileLayer's ObjectKey will handle proper recreation when needed.
mapController: mapController,
options: MapOptions(
initialCenter: initialCenter,
initialZoom: initialZoom,
minZoom: 3.0,
maxZoom: maxZoom ?? mapSettings.mapSource.maxNativeZoom.toDouble(),
// Constrain latitude to ±85.11° (Web Mercator projection limits)
// Longitude is unrestricted to allow horizontal map wrapping.
cameraConstraint: const CameraConstraint.containLatitude(
85.051129,
-85.051129,
),
onTap: onTap,
onLongPress: onLongPress,
onPositionChanged: onPositionChanged,
),
children: [
buildMapTileLayer(
mapSettings: mapSettings,
tileProvider: tileProvider,
applyFilter: applyFilter,
),
// Wrap marker layer in RepaintBoundary to isolate marker animations.
RepaintBoundary(
child: buildPlacesMarkerLayer(
context: context,
markers: filteredMarkers,
shouldAnimate: shouldAnimate,
onDelete: onDeletePlace,
),
),
if (showNewsMarkers)
RepaintBoundary(
child: buildNewsMarkerLayer(
context: context,
newsMarkers: visibleNewsMarkers,
),
),
// User location marker layer (always on top)
...() {
final userLocationLayer = buildUserLocationMarkerLayer(
userLocation: userLocation,
);
if (userLocationLayer == null) return const <Widget>[];
return [RepaintBoundary(child: userLocationLayer)];
}(),
],
),
),
);
}