Compare commits
2 Commits
562c85079d
...
8f3b3fe05e
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f3b3fe05e | |||
| 89743886af |
@@ -5,7 +5,11 @@ import 'package:flutter_map_marker_cluster/flutter_map_marker_cluster.dart';
|
|||||||
import 'package:latlong2/latlong.dart';
|
import 'package:latlong2/latlong.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import '../model/flood_station.dart';
|
||||||
import '../services/flood_station_provider.dart';
|
import '../services/flood_station_provider.dart';
|
||||||
|
import '../widgets/custom_marker.dart';
|
||||||
|
import '../widgets/map_popup.dart';
|
||||||
|
import 'flood_station_page.dart';
|
||||||
|
|
||||||
class MapPage extends StatefulWidget {
|
class MapPage extends StatefulWidget {
|
||||||
const MapPage({super.key});
|
const MapPage({super.key});
|
||||||
@@ -17,14 +21,15 @@ class MapPage extends StatefulWidget {
|
|||||||
|
|
||||||
class _MapPageState extends State<MapPage> {
|
class _MapPageState extends State<MapPage> {
|
||||||
final mapController = MapController();
|
final mapController = MapController();
|
||||||
|
late FloodStationProvider _floodStationProvider;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final floodStationProvider = context.watch<FloodStationProvider>();
|
_floodStationProvider = context.watch<FloodStationProvider>();
|
||||||
if (floodStationProvider.allStations.isEmpty) {
|
if (_floodStationProvider.allStations.isEmpty) {
|
||||||
return Center(
|
return Center(
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: floodStationProvider.loadAllStations,
|
onPressed: _floodStationProvider.loadAllStations,
|
||||||
child: Text('Load Map'),
|
child: Text('Load Map'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -32,6 +37,12 @@ class _MapPageState extends State<MapPage> {
|
|||||||
return FlutterMap(
|
return FlutterMap(
|
||||||
mapController: mapController,
|
mapController: mapController,
|
||||||
options: MapOptions(
|
options: MapOptions(
|
||||||
|
cameraConstraint: CameraConstraint.containCenter(
|
||||||
|
bounds: LatLngBounds.fromPoints(_floodStationProvider.allStations
|
||||||
|
.map<LatLng>(
|
||||||
|
(e) => LatLng(e.lat, e.long),
|
||||||
|
)
|
||||||
|
.toList())),
|
||||||
initialCenter: LatLng(54.81, -4.42),
|
initialCenter: LatLng(54.81, -4.42),
|
||||||
initialZoom: 6,
|
initialZoom: 6,
|
||||||
),
|
),
|
||||||
@@ -44,7 +55,7 @@ class _MapPageState extends State<MapPage> {
|
|||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
padding: EdgeInsets.all(50),
|
padding: EdgeInsets.all(50),
|
||||||
maxZoom: 15,
|
maxZoom: 15,
|
||||||
markers: floodStationProvider.stationsAsMarkers,
|
markers: _stationsAsMarkers(_floodStationProvider.allStations),
|
||||||
builder: _markerBuilder),
|
builder: _markerBuilder),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
@@ -65,6 +76,32 @@ class _MapPageState extends State<MapPage> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Marker> _stationsAsMarkers(List<FloodStation> stations) {
|
||||||
|
return stations
|
||||||
|
.map<Marker>(
|
||||||
|
(station) => Marker(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
point: LatLng(station.lat, station.long),
|
||||||
|
child: CustomMarker(
|
||||||
|
onTap: () => _markerTapped(station),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
_markerTapped(FloodStation station) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => MapPopup(
|
||||||
|
station: station,
|
||||||
|
onShowTapped: () {
|
||||||
|
_floodStationProvider.selectedStation = station;
|
||||||
|
Navigator.of(context).pushNamed(FloodStationPage.routeName);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TileLayer get openStreetMapTileLayer => TileLayer(
|
TileLayer get openStreetMapTileLayer => TileLayer(
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:async/async.dart';
|
import 'package:async/async.dart';
|
||||||
import 'package:flutter_map/flutter_map.dart';
|
|
||||||
import 'package:latlong2/latlong.dart';
|
|
||||||
|
|
||||||
import '../model/flood_station.dart';
|
import '../model/flood_station.dart';
|
||||||
import '../widgets/custom_marker.dart';
|
|
||||||
import 'api.dart';
|
import 'api.dart';
|
||||||
|
|
||||||
class FloodStationProvider extends ChangeNotifier {
|
class FloodStationProvider extends ChangeNotifier {
|
||||||
@@ -16,17 +12,6 @@ class FloodStationProvider extends ChangeNotifier {
|
|||||||
|
|
||||||
List<FloodStation> get allStations => _allStations;
|
List<FloodStation> get allStations => _allStations;
|
||||||
List<FloodStation> get filteredStations => _filteredStations;
|
List<FloodStation> get filteredStations => _filteredStations;
|
||||||
List<Marker> get stationsAsMarkers {
|
|
||||||
return allStations
|
|
||||||
.map<Marker>(
|
|
||||||
(e) => Marker(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
point: LatLng(e.lat, e.long),
|
|
||||||
child: CustomMarker(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
CancelableOperation? _filteredStationsFuture;
|
CancelableOperation? _filteredStationsFuture;
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class CustomMarker extends StatelessWidget {
|
class CustomMarker extends StatelessWidget {
|
||||||
const CustomMarker({super.key, this.label});
|
const CustomMarker({super.key, required this.onTap});
|
||||||
final String? label;
|
final void Function() onTap;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Icon(
|
return GestureDetector(
|
||||||
Icons.location_on_sharp,
|
onTap: onTap,
|
||||||
color: Theme.of(context).colorScheme.primary,
|
child: Icon(
|
||||||
size: 30,
|
Icons.location_on_sharp,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
size: 30,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
60
lib/widgets/map_popup.dart
Normal file
60
lib/widgets/map_popup.dart
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart' as intl;
|
||||||
|
|
||||||
|
import '../model/flood_station.dart';
|
||||||
|
|
||||||
|
class MapPopup extends StatelessWidget {
|
||||||
|
const MapPopup(
|
||||||
|
{super.key, required this.station, required this.onShowTapped});
|
||||||
|
final FloodStation station;
|
||||||
|
final Function() onShowTapped;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: Text(station.label),
|
||||||
|
content: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.home_outlined),
|
||||||
|
Padding(padding: EdgeInsets.only(left: 8)),
|
||||||
|
Text(station.town.isEmpty ? '-' : station.town),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(Icons.water),
|
||||||
|
Padding(padding: EdgeInsets.only(left: 8)),
|
||||||
|
Text(station.riverName.isEmpty ? '-' : station.riverName),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(Icons.calendar_month_outlined),
|
||||||
|
Padding(padding: EdgeInsets.only(left: 8)),
|
||||||
|
Text(
|
||||||
|
station.dateOpened != null
|
||||||
|
? intl.DateFormat.yMd().format(station.dateOpened!)
|
||||||
|
: '-',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
child: Text('dismiss'),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: onShowTapped,
|
||||||
|
child: Text('show'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user