rsflutterapp

Bahnhofsfoto-App for Android and iOS using Flutter
git clone git://archive.git.mtrnord.blog/MTRNord/rsflutterapp.git
Log | Files | Refs | README

MapTab.dart (5680B)


      1 import 'package:flutter/material.dart';
      2 import 'package:flutter_bloc/flutter_bloc.dart';
      3 import 'package:flutter_map/flutter_map.dart';
      4 import 'package:flutter_map_marker_cluster/flutter_map_marker_cluster.dart';
      5 import 'package:latlong/latlong.dart';
      6 
      7 import '../../blocs/MapBloc.dart';
      8 import '../../events/MapEvent.dart';
      9 import '../../models/models.dart';
     10 import '../../repos/repositories.dart';
     11 import '../../states/MapState.dart';
     12 import '../DetailsPage.dart';
     13 
     14 class MapTab extends StatefulWidget {
     15   final RailwayStationsRepository railwayStationsRepository;
     16 
     17   MapTab({@required this.railwayStationsRepository})
     18       : assert(railwayStationsRepository != null);
     19 
     20   @override
     21   MapTabState createState() => MapTabState();
     22 }
     23 
     24 class MapTabState extends State<MapTab>
     25     with AutomaticKeepAliveClientMixin<MapTab> {
     26   MapTabState();
     27 
     28   List<Station> stations;
     29   final _initialCenter = LatLng(51.133481, 10.018343);
     30   final _initialZoom = 6.0;
     31 
     32   List<Marker> _makeStationMarkers(List<Station> stations) {
     33     List<Marker> stationMarkers = List();
     34     stations.forEach((element) {
     35       if (element.active) {
     36         stationMarkers.add(Marker(
     37           anchorPos: AnchorPos.align(AnchorAlign.center),
     38           height: 30,
     39           width: 30,
     40           point: LatLng(element.lat, element.lon),
     41           builder: (BuildContext context) => Icon(Icons.pin_drop),
     42         ));
     43       }
     44       // Todo calculate an extra layer for deactivated stations
     45     });
     46     return stationMarkers;
     47   }
     48 
     49   @override
     50   Widget build(BuildContext context) {
     51     super.build(context);
     52 
     53     // Fetch map data on opening
     54     if (stations == null) {
     55       BlocProvider.of<MapBloc>(context).add(FetchStations());
     56     }
     57 
     58     return BlocBuilder<MapBloc, MapState>(builder: (context, state) {
     59       if (state is MapLoading) {
     60         return Center(child: CircularProgressIndicator());
     61       }
     62       if (state is MapRender) {
     63         return FlutterMap(
     64           options: MapOptions(
     65             center: _initialCenter,
     66             zoom: _initialZoom,
     67             plugins: [
     68               MarkerClusterPlugin(),
     69             ],
     70           ),
     71           layers: [
     72             // Mapbox
     73             /*TileLayerOptions(
     74               //tileSize: 1024,
     75               zoomOffset: -1,
     76               urlTemplate:
     77                   "https://api.mapbox.com/styles/v1/mapbox/{id}/tiles/256/{z}/{x}/{y}@2x?access_token={accessToken}",
     78               additionalOptions: {
     79                 'accessToken':
     80                     'pk.eyJ1IjoibXRybm9yZCIsImEiOiJjaXIyZTRhNDcwMDhwaTJtZzBseTNkancxIn0.09m6ZCFvkKL6Ppss7XAnfA',
     81                 'id': 'streets-v11',
     82               },
     83             ),*/
     84             // Openstreetmap
     85             /*TileLayerOptions(
     86               urlTemplate: "https://{s}.tile.openstreetmap.de/{z}/{x}/{y}.png",
     87               subdomains: ['a', 'b', 'c'],
     88             ),*/
     89             // Transport Map
     90             TileLayerOptions(
     91               urlTemplate: "http://tile.memomaps.de/tilegen/{z}/{x}/{y}.png",
     92               subdomains: [],
     93             ),
     94             // Railway overlay
     95             /*TileLayerOptions(
     96               urlTemplate:
     97                   "https://{s}.tiles.openrailwaymap.org/standard/{z}/{x}/{y}.png",
     98               subdomains: ['a', 'b', 'c'],
     99               opacity: 0.2,
    100             ),*/
    101             MarkerClusterLayerOptions(
    102               maxClusterRadius: 120,
    103               size: Size(50, 50),
    104               fitBoundsOptions: FitBoundsOptions(
    105                 padding: EdgeInsets.all(50),
    106               ),
    107               markers: _makeStationMarkers(stations),
    108               polygonOptions: PolygonOptions(
    109                 borderColor: Colors.blueAccent,
    110                 color: Colors.black12,
    111                 borderStrokeWidth: 3,
    112               ),
    113               onMarkerTap: (Marker marker) {
    114                 Station station = stations.firstWhere((element) =>
    115                     element.lat == marker.point.latitude &&
    116                     element.lon == marker.point.longitude);
    117                 Navigator.of(context).push(
    118                   MaterialPageRoute(
    119                     builder: (BuildContext context) => DetailsPage(
    120                       station: station,
    121                       railwayStationsRepository:
    122                           widget.railwayStationsRepository,
    123                     ),
    124                   ),
    125                 );
    126               },
    127               builder: (context, markers) {
    128                 return ClipRRect(
    129                   borderRadius: BorderRadius.circular(50),
    130                   child: Container(
    131                     color: Theme.of(context).primaryColor,
    132                     child: Center(
    133                       child: Text(
    134                         markers.length.toString(),
    135                       ),
    136                     ),
    137                   ),
    138                 );
    139               },
    140             ),
    141           ],
    142         );
    143       }
    144       if (state is MapLoaded) {
    145         return FutureBuilder(
    146           future: _cacheData(state.stations),
    147           builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
    148             return Center(child: CircularProgressIndicator());
    149           },
    150         );
    151       }
    152       // Todo show reload button on error
    153       if (state is MapError) {
    154         return Text(
    155           'Something went wrong!',
    156           style: TextStyle(color: Colors.red),
    157         );
    158       }
    159       return Text(
    160         'Something went wrong2!',
    161         style: TextStyle(color: Colors.red),
    162       );
    163     });
    164   }
    165 
    166   _cacheData(List<Station> stations) async {
    167     setState(() {
    168       this.stations = stations;
    169       BlocProvider.of<MapBloc>(context).add(RenderMap());
    170     });
    171   }
    172 
    173   @override
    174   bool get wantKeepAlive => true;
    175 }