I am trying to make a widget using Flutter Map to display a Mapbox map. The widget has been working fine until I attempt to add the ability to cache the map with the Flutter Map Tile Caching package. After adding the code to cache the map and read the cached map from storage I receive an unknown error when compiling the widget.
Here is the code I have:
// Automatic FlutterFlow imports
import '/backend/backend.dart';
import '/backend/schema/enums/enums.dart';
import '/actions/actions.dart' as action_blocks;
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/widgets/index.dart'; // Imports other custom widgets
import '/custom_code/actions/index.dart'; // Imports custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom widget code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!
import 'dart:io';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart' as ll;
import 'package:flutter_map_location_marker/flutter_map_location_marker.dart';
import 'package:flutter_map_tile_caching/flutter_map_tile_caching.dart';
import 'package:http/http.dart' as http;
class MapboxMap extends StatefulWidget {
const MapboxMap({
super.key,
this.width,
this.height,
this.points,
required this.accessToken,
required this.startingPoint,
required this.startingZoom,
});
final double? width;
final double? height;
final List<LatLng>? points;
final String accessToken;
final LatLng startingPoint;
final double startingZoom;
@override
State<MapboxMap> createState() => _MapboxMapState();
}
class _MapboxMapState extends State<MapboxMap> {
List<Marker> allMarkers = [];
@override
void initState() {
super.initState();
_downloadTiles();
}
void _downloadTiles() async {
try {
await FMTCObjectBoxBackend().initialise;
final region = RectangleRegion(
LatLngBounds(
ll.LatLng(
36.49734506982594, -80.8356480216374), // North West coordinate
ll.LatLng(
36.46740696712976, -80.88972365413852), // South East coordinate
),
);
final downloadableRegion = region.toDownloadable(
minZoom: 10,
maxZoom: 16,
options: TileLayer(
urlTemplate:
TILE URL),
);
final progressStream = FMTCStore('mapStore').download.startForeground(
region: downloadableRegion,
// other options...
);
progressStream.listen((progress) {
print('Download progress: ${progress.percentageProgress}');
});
} catch (e) {
print('Error downloading tiles: $e');
}
}
Future<String> fetchTileLayerUrl() async {
final url =
TILE URL;
try {
final response = await http.head(Uri.parse(url));
if (response.statusCode == 200) {
return url;
} else if (response.statusCode == 404) {
throw HttpException('Error 404: Tile layer not found.');
} else {
throw HttpException(
'Failed to load tiles, status code: ${response.statusCode}');
}
} on SocketException catch (e) {
throw HttpException('SocketException: ${e.message}');
} catch (e) {
throw HttpException('Exception: ${e.toString()}');
}
}
@override
Widget build(BuildContext context) {
return FutureBuilder<String>(
future: fetchTileLayerUrl(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(
child: Card(
color: Colors.redAccent,
margin: EdgeInsets.all(16),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.error_outline, color: Colors.white, size: 48),
SizedBox(height: 16),
Text(
'Error loading map',
style: TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 8),
Text(
'An error occurred while trying to load the map tiles. Please check your internet connection and try again.',
style: TextStyle(color: Colors.white, fontSize: 16),
textAlign: TextAlign.center,
),
SizedBox(height: 8),
Text(
'Error details: ${snapshot.error}',
style: TextStyle(color: Colors.white70, fontSize: 14),
textAlign: TextAlign.center,
),
],
),
),
),
);
} else if (snapshot.hasData) {
return FlutterMap(
options: MapOptions(
initialCenter: ll.LatLng(widget.startingPoint.latitude,
widget.startingPoint.longitude),
initialZoom: widget.startingZoom,
// Only allow users to drag and double tap to zoom, NO rotation
interactionOptions: InteractionOptions(
flags: InteractiveFlag.pinchZoom |
InteractiveFlag.drag |
InteractiveFlag.doubleTapZoom),
// Restrict Camera to bounds of CRK for limited calls
cameraConstraint: CameraConstraint.contain(
bounds: LatLngBounds(
ll.LatLng(36.49734506982594, -80.8356480216374),
ll.LatLng(36.46740696712976, -80.88972365413852))),
),
children: [
TileLayer(
urlTemplate:
TILE URL,
tileProvider: FMTCStore('mapStore').getTileProvider(),
),
CurrentLocationLayer(),
RichAttributionWidget(
animationConfig:
const ScaleRAWA(), // Or `FadeRAWA` as is default
attributions: [
LogoSourceAttribution(Image.network(
'https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/camp-raven-knob-passport-omzklm/assets/elkdn3q1s625/mapbox-logo-black.png')),
TextSourceAttribution(
'Mapbox',
onTap: () =>
launchURL('https://www.mapbox.com/about/maps/'),
),
TextSourceAttribution(
'OpenStreetMap',
onTap: () =>
launchURL('http://www.openstreetmap.org/copyright'),
),
TextSourceAttribution(
'Improve this map',
prependCopyright: false,
onTap: () =>
launchURL('https://www.mapbox.com/map-feedback/'),
),
TextSourceAttribution('Made with "flutter_map"',
prependCopyright: false),
],
showFlutterMapAttribution: false,
),
// MarkerLayer(
// markers: allMarkers,
// )
],
);
} else {
return Center(child: Text('Unexpected error'));
}
},
);
}
}