Commit 7513fe06 authored by Nicolas Richard Walter Boeckh's avatar Nicolas Richard Walter Boeckh 💬
Browse files

Map (Zoom + Location) Fixes

Added :
- Map -> Observer to trigger redraw
- Dedicated map widget

Fixed:
- Consistent zoom level through redraw
- PM marker does not need refresh to redraw (... map not stateful lol)
parent 1a468d40
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"app_settings","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\app_settings-4.0.3\\\\","dependencies":[]},{"name":"connectivity","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity-0.4.9+2\\\\","dependencies":[]},{"name":"flutter_blue","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_blue-0.7.2\\\\","dependencies":[]},{"name":"geolocator","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\geolocator-5.2.1\\\\","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\google_api_availability-2.0.2\\\\","dependencies":[]},{"name":"location_permissions","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\location_permissions-2.0.4+1\\\\","dependencies":[]},{"name":"path_provider","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider-1.6.0\\\\","dependencies":[]},{"name":"permission_handler","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\permission_handler-4.2.0+hotfix.3\\\\","dependencies":[]},{"name":"shared_preferences","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences-0.5.7+2\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"android":[{"name":"app_settings","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\app_settings-4.0.3\\\\","dependencies":[]},{"name":"connectivity","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity-0.4.9+2\\\\","dependencies":[]},{"name":"flutter_blue","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_blue-0.7.2\\\\","dependencies":[]},{"name":"geolocator","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\geolocator-5.2.1\\\\","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\google_api_availability-2.0.2\\\\","dependencies":[]},{"name":"location_permissions","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\location_permissions-2.0.4+1\\\\","dependencies":[]},{"name":"path_provider","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider-1.6.0\\\\","dependencies":[]},{"name":"permission_handler","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\permission_handler-4.2.0+hotfix.3\\\\","dependencies":[]},{"name":"shared_preferences","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences-0.5.7+2\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"macos":[{"name":"connectivity_macos","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity_macos-0.1.0+4\\\\","dependencies":[]},{"name":"shared_preferences_macos","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_macos-0.0.1+8\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"connectivity_for_web","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity_for_web-0.3.1+2\\\\","dependencies":[]},{"name":"shared_preferences_web","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_web-0.1.2+5\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"app_settings","dependencies":[]},{"name":"connectivity","dependencies":["connectivity_macos","connectivity_for_web"]},{"name":"connectivity_for_web","dependencies":[]},{"name":"connectivity_macos","dependencies":[]},{"name":"flutter_blue","dependencies":[]},{"name":"geolocator","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","dependencies":[]},{"name":"location_permissions","dependencies":[]},{"name":"path_provider","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-09-17 10:48:44.241489","version":"1.22.0-2.0.pre.18"}
\ No newline at end of file
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"app_settings","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\app_settings-4.0.3\\\\","dependencies":[]},{"name":"connectivity","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity-0.4.9+2\\\\","dependencies":[]},{"name":"flutter_blue","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_blue-0.7.2\\\\","dependencies":[]},{"name":"geolocator","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\geolocator-5.2.1\\\\","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\google_api_availability-2.0.2\\\\","dependencies":[]},{"name":"location_permissions","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\location_permissions-2.0.4+1\\\\","dependencies":[]},{"name":"path_provider","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider-1.6.17\\\\","dependencies":[]},{"name":"permission_handler","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\permission_handler-4.2.0+hotfix.3\\\\","dependencies":[]},{"name":"shared_preferences","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences-0.5.7+2\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"android":[{"name":"app_settings","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\app_settings-4.0.3\\\\","dependencies":[]},{"name":"connectivity","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity-0.4.9+2\\\\","dependencies":[]},{"name":"flutter_blue","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_blue-0.7.2\\\\","dependencies":[]},{"name":"geolocator","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\geolocator-5.2.1\\\\","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\google_api_availability-2.0.2\\\\","dependencies":[]},{"name":"location_permissions","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\location_permissions-2.0.4+1\\\\","dependencies":[]},{"name":"path_provider","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider-1.6.17\\\\","dependencies":[]},{"name":"permission_handler","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\permission_handler-4.2.0+hotfix.3\\\\","dependencies":[]},{"name":"shared_preferences","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences-0.5.7+2\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"macos":[{"name":"connectivity_macos","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity_macos-0.1.0+4\\\\","dependencies":[]},{"name":"path_provider_macos","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_macos-0.0.4+4\\\\","dependencies":[]},{"name":"shared_preferences_macos","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_macos-0.0.1+8\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.2.0\\\\","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_linux-0.0.1+2\\\\","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_windows-0.0.4+1\\\\","dependencies":[]}],"web":[{"name":"connectivity_for_web","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\connectivity_for_web-0.3.1+2\\\\","dependencies":[]},{"name":"shared_preferences_web","path":"C:\\\\src\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_web-0.1.2+5\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"app_settings","dependencies":[]},{"name":"connectivity","dependencies":["connectivity_macos","connectivity_for_web"]},{"name":"connectivity_for_web","dependencies":[]},{"name":"connectivity_macos","dependencies":[]},{"name":"flutter_blue","dependencies":[]},{"name":"geolocator","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","dependencies":[]},{"name":"location_permissions","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux","path_provider_windows"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-09-22 23:59:42.093030","version":"1.21.0-10.0.pre.193"}
\ No newline at end of file
......@@ -2,14 +2,15 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_map/plugin_api.dart';
import 'package:geolocator/geolocator.dart';
import 'package:latlong/latlong.dart';
import 'package:logair_application/logic/handlers/data_handler.dart';
import 'package:logair_application/logic/handlers/main_database_handler.dart';
import 'package:logair_application/logic/handlers/network_handler.dart';
import 'package:logair_application/logic/data_header.dart';
import 'package:logair_application/logic/data_packet.dart';
import 'package:logair_application/logic/handlers/position_handler.dart';
import 'package:logair_application/utils/enums/pm_symbol.dart';
import 'package:rxdart/rxdart.dart';
/// The [MapDisplayController] is a singleton that handles the mapping of information.
class MapDisplayController {
......@@ -23,7 +24,9 @@ class MapDisplayController {
LatLng _lastPos;
/// The [FlutterMap]'s zoom level, used to keep centering stable.
double _zoom;
double _zoom = 13;
double get zoom => _zoom;
/// The [FlutterMap]s [MapController], kept unique in order to avoid incessant reloading of resources.
MapController _controller;
......@@ -34,6 +37,8 @@ class MapDisplayController {
/// [Marker] representing the user's current [Position].
Marker _marker;
BehaviorSubject shouldRedraw = BehaviorSubject();
Future<void> _rebuildMarkers() async {
List<DataPacket> packets = await MainDatabaseHandler().getLastPackets(200);
packets.forEach((DataPacket packet) {
......@@ -61,11 +66,17 @@ class MapDisplayController {
/// [Singleton]() instantiation factory.
factory MapDisplayController() => _singleton;
final BehaviorSubject<Position> _positionObserver = PositionHandler().devicePosition;
/// @Getter for [_polylines].
List<Polyline> get polylines => this._polylines;
/// @Getter for [_marker].
Marker get marker => this._marker != null ? this._marker : _buildLocationMarker(LatLng(0, 0));
Marker get marker {
print('MARKER ${this._marker} OBSVAL ${this._positionObserver.value}');
return this._marker != null ? this._marker : _buildLocationMarker(this._positionObserver.value == null ? LatLng(0, 0) : LatLng(this._positionObserver.value.latitude, this._positionObserver.value.longitude));
}
/// Object used to calculate the real-life distance of two [Position]s
final Distance _distance = new Distance();
......@@ -103,7 +114,8 @@ class MapDisplayController {
return;
/// If a [BluetoothDevice] is connected, then the [DataHandler] will have a [DataPacket] available.
DataPacket latest = null;
DataPacket latest;
/// If the [DataPacket] is older than 5 seconds we invalidate it.
if (latest != null && latest.timestamp <= (DateTime.now().millisecondsSinceEpoch - 5000))
latest = null;
......@@ -121,6 +133,8 @@ class MapDisplayController {
/// Move the [Marker] to the current [Position].
// TODO: Use StreamBuilder in Map.
this._marker = this._buildLocationMarker(this._currentPos);
if (this._currentPos != this._lastPos)
this.shouldRedraw.value = null;
if ((this._lastPos != null && this._currentPos != null)) {// && this._distance.as(LengthUnit.Meter, this._lastPos, this._currentPos) >= 2)) {
if (this._polylines.length == 0) {
......
import 'dart:async';
import 'package:geolocator/geolocator.dart';
import 'package:logair_application/logic/handlers/preference_handler.dart';
import 'package:logair_application/services/permission_service.dart';
import 'package:logair_application/utils/enums/preference_keys.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:rxdart/rxdart.dart';
/// Handler enabling the frequent polling of the devices [Position]
class PositionHandler {
......@@ -11,8 +14,24 @@ class PositionHandler {
PositionHandler._internal() {
new Timer.periodic(Duration(seconds: 1), (timer) => this._timeSinceLastChange += 1);
/// Retrieve the accuracy value that the GPS should use. (default: 2 ~> High accuracy).
PreferencesHandler().getPreferencesInt(PreferenceKeys.GPS__ACCURACY.key).then((value) => this._locationAccuracy.value = value);
/// Retrieve the interval between attempts to acquire GPS signal. (default: 1 second).
PreferencesHandler().getPreferencesInt(PreferenceKeys.GPS__INTERVAL_SECONDS.key).then((value) => this._locationInterval.value = value);
/// Checks the [PreferencesHandler] every 20 seconds on Preference updates.
new Timer.periodic(Duration(seconds: 20), (Timer t) async {
this._locationAccuracy.value = await PreferencesHandler().getPreferencesInt(PreferenceKeys.GPS__ACCURACY.key);
this._locationInterval.value = await PreferencesHandler().getPreferencesInt(PreferenceKeys.GPS__INTERVAL_SECONDS.key);
});
}
/// [BehaviorSubject] concerning the desired location accuracy.
BehaviorSubject<int> _locationAccuracy = BehaviorSubject<int>();
BehaviorSubject<int> _locationInterval = BehaviorSubject<int>();
/// Internal static [PositionHandler] reference.
static final PositionHandler _singleton = new PositionHandler._internal();
......@@ -31,15 +50,29 @@ class PositionHandler {
/// The time since the [Position] was last updated.
int _timeSinceLastChange = 0;
// TODO: GPS.ACCURACY integrate
/// Default location tweaking options.
LocationOptions locationOptions = LocationOptions(accuracy: LocationAccuracy.high, distanceFilter: 0, timeInterval: 1);
BehaviorSubject<Position> devicePosition = BehaviorSubject();
@override
PositionHandler.dispose() {
devicePosition.close();
_locationAccuracy.close();
_locationInterval.close();
}
LocationAccuracy _accuracyFrom(int setting) {
switch(setting) {
case 0: return LocationAccuracy.low; break;
case 0: return LocationAccuracy.medium; break;
case 0: return LocationAccuracy.high; break;
case 0: return LocationAccuracy.best; break;
default: return LocationAccuracy.medium;
}
}
/// Get whether the user has granted the location permissions.
Stream<GeolocationStatus> getGeolocationStatus() async* {
while (true) {
yield this._geolocationStatus;
this._timeSinceLastChange = 0;
await Future.delayed(Duration(seconds: 1));
}
......@@ -61,18 +94,23 @@ class PositionHandler {
/// Try getting the current [Position], and if that fails get the last known [Position]
Stream<Position> getCurrentOrLastPosition() async* {
while (true) {
print('requesting');
Position currentPosition;
if (!_permissionChecked) {
await this._getGeolocationPermission();
_permissionChecked = true;
}
if (_geolocationStatus == GeolocationStatus.granted)
currentPosition = await _geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
if (_geolocationStatus == GeolocationStatus.granted) {
currentPosition = await _geolocator.getCurrentPosition(desiredAccuracy: _accuracyFrom(this._locationAccuracy.value ?? 1));
if (currentPosition != this._lastPosition)
devicePosition.value = currentPosition;
}
if (currentPosition != null)
_lastPosition = currentPosition;
this._lastPosition = currentPosition;
if (this._timeSinceLastChange >= 10 && _lastPosition != null && currentPosition == null)
this._lastPosition = null;
......@@ -86,7 +124,7 @@ class PositionHandler {
} else
yield null;
await Future.delayed(Duration(milliseconds: 1000));
await Future.delayed(Duration(milliseconds: (this._locationInterval.value ?? 1) * 1000));
}
}
......
......@@ -7,6 +7,7 @@ import 'package:logair_application/ui/components/body/data/locations_of_interest
import 'package:logair_application/ui/components/common/carousel_card.dart';
import 'package:logair_application/ui/components/body/data/graph/graph.dart';
import 'package:logair_application/ui/components/body/data/tiles/data_tile.dart';
import 'package:logair_application/utils/decorations.dart';
class DataWidget extends StatelessWidget {
DataWidget();
......@@ -25,11 +26,12 @@ class DataWidget extends StatelessWidget {
Divider(indent: 20, endIndent: 20, color: Colors.black, height: 20, thickness: 3,),
// Bar (Locations + Add new -> Pop to new route)
Container(
decoration: BoxDecoration(
color: Colors.blue[300],
borderRadius: BorderRadius.vertical(
top: Radius.circular(5)
decoration: containerNeumorphicDecoration.copyWith(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(5),
bottomRight: Radius.circular(5),
),
color: Colors.blue[300]
),
child: Row(
children: [
......
......@@ -21,7 +21,11 @@ class _LocationsOfInterestWidgetState extends State<LocationsOfInterestWidget> {
Future<List<DataTile>> _generateChildren() async {
List<LocationOfInterest> loi = await LocationsOfInterestDatabaseHandler().data;
return [];
return loi.map((LocationOfInterest l) => DataTile(
stream: NetworkHandler().generateLocationOfInterestStream(loi: l),
isDistant: true,
loi: l,
));
}
@override
......@@ -52,7 +56,12 @@ class _LocationsOfInterestWidgetState extends State<LocationsOfInterestWidget> {
)
),
isDistant: true,
locationName: 'FacLab',
loi: LocationOfInterest(
id: 0,
latitude: 46.1764826,
longitude: 6.1400497,
name: 'FacLab'
),
),
]
).toList() + [
......
......@@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:logair_application/logic/data_packet.dart';
import 'package:logair_application/utils/enums/pm_symbol.dart';
import 'package:logair_application/utils/helpers/location_of_interest.dart';
//TODO Add weather ? (Not feasible unless negotiate free API access)
/// Widget that displays the data specific to a specific place, depending on the stream provided.
......@@ -17,13 +18,13 @@ class DataTile extends StatefulWidget {
final bool isDistant;
final String locationName;
final LocationOfInterest loi;
DataTile({@required this.stream, this.isDistant = true, this.locationName = '', Key key}) : super(key: key);
DataTile({@required this.stream, this.isDistant = true, this.loi, Key key}) : super(key: key);
/// Provides [stream] to the [_DataTileState]
@override
State<DataTile> createState() => _DataTileState(this.stream, this.isDistant, this.locationName);
State<DataTile> createState() => _DataTileState(this.stream, this.isDistant, this.loi);
}
/// [State] of a [DataTile] displaying [stream] specific data.
......@@ -35,7 +36,7 @@ class _DataTileState extends State<DataTile> {
final bool isDistant;
/// The name of the location if the data has been pooled from there.
final String locationName;
final LocationOfInterest loi;
/// Value of the PM1 metric.
double _pm1 = -1;
......@@ -59,7 +60,7 @@ class _DataTileState extends State<DataTile> {
double _relativeHumidity = -1;
/// Creates a [_DataTileState] that listens to [stream] and changes the state whenever a new [DataPacket] is available.
_DataTileState(this.stream, this.isDistant, this.locationName) {
_DataTileState(this.stream, this.isDistant, this.loi) {
stream.listen((DataPacket newPacket) {
// Checks that the packet contains actual data.
if (newPacket != null && this.mounted) {
......@@ -197,11 +198,11 @@ class _DataTileState extends State<DataTile> {
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
(this.isDistant != null && this.locationName != null && this.isDistant) ? Container(
(this.isDistant != null && this.loi != null && this.isDistant) ? Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 4),
child: Text(
'${this.locationName}',
'${this.loi.name}',
textAlign: TextAlign.left,
style: Theme.of(context).textTheme.headline6.copyWith(
fontWeight: FontWeight.bold
......@@ -212,9 +213,9 @@ class _DataTileState extends State<DataTile> {
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
_buildEnvironmentalDataCells(title: 'Temp.', unit: '(C°)', value: this._temperature),
_buildEnvironmentalDataCells(title: 'Pres.', unit: '(hPa)', value: this._pressure),
_buildEnvironmentalDataCells(title: 'Rel. Hum.', unit: '(%)', value: this._relativeHumidity),
_buildEnvironmentalDataCells(title: 'Temperature', unit: '(C°)', value: this._temperature),
_buildEnvironmentalDataCells(title: 'Pressure', unit: '(hPa)', value: this._pressure),
_buildEnvironmentalDataCells(title: 'Humidity', unit: '(%)', value: this._relativeHumidity),
],
),
]
......@@ -230,7 +231,7 @@ class _DataTileState extends State<DataTile> {
child: tile,
splashColor: Color.fromARGB(0xAA, 0xFF, 0x00, 0x00),
// Delete location function (Remove from db) TODO
onLongPress: () => print(this.locationName),
onLongPress: () => print('LOI: ${loi.id}~>${loi.name}'),
)
);
} else {
......
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong/latlong.dart';
import 'package:logair_application/logic/controllers/map_display_controller.dart';
import 'package:logair_application/logic/handlers/position_handler.dart';
import 'package:rxdart/subjects.dart';
class MapWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() => _MapWidgetState();
}
class _MapWidgetState extends State<MapWidget> {
int time = 0;
_MapWidgetState() {
MapDisplayController().shouldRedraw.listen((value) { setState(() => time += 1 ); });
}
@override
Widget build(BuildContext context) {
return FlutterMap(
mapController: MapDisplayController().controller(),
options: new MapOptions(
onPositionChanged: (position, hasGesture) => MapDisplayController().setControllerChange(position.center, position.zoom),
center: MapDisplayController().currentPosition(),
zoom: MapDisplayController().zoom,
controller: MapDisplayController().controller(),
),
layers: [
TileLayerOptions(
urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
subdomains: ['a', 'b', 'c']
),
PolylineLayerOptions(
polylines: MapDisplayController().polylines,
),
// TODO: Make circle Behavior subject dependent.
CircleLayerOptions(
circles: MapDisplayController().pmMarkers,
),
MarkerLayerOptions(
markers: [
MapDisplayController().marker,
],
),
],
);
}
Marker _buildLocationMarker(LatLng position) => Marker(
width: 20.0,
height: 20.0,
point: position,
builder: (ctx) => Container(
child: Icon(Icons.location_on, color: Colors.red,),
),
);
}
\ No newline at end of file
......@@ -4,6 +4,7 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:logair_application/logic/controllers/map_display_controller.dart';
import 'package:logair_application/ui/components/body/map/map.dart';
import 'package:logair_application/ui/components/common/base_widget.dart';
import 'package:logair_application/ui/components/common/carousel_card.dart';
import 'package:logair_application/utils/enums/pm_symbol.dart';
......@@ -11,35 +12,6 @@ import 'package:logair_application/utils/enums/pm_symbol.dart';
class MapContainer extends BaseWidget {
MapContainer();
FlutterMap _buildMap() {
return FlutterMap(
mapController: MapDisplayController().controller(),
options: new MapOptions(
onPositionChanged: (position, hasGesture) => MapDisplayController().setControllerChange(position.center, position.zoom),
center: MapDisplayController().currentPosition(),
zoom: 13.0,
),
layers: [
TileLayerOptions(
urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
subdomains: ['a', 'b', 'c']
),
PolylineLayerOptions(
polylines: MapDisplayController().polylines,
),
// TODO: Make circle Behavior subject dependent.
CircleLayerOptions(
circles: MapDisplayController().pmMarkers,
),
MarkerLayerOptions(
markers: [
MapDisplayController().marker,
],
),
],
);
}
@override
Widget build(BuildContext context) {
TextEditingController _fromController = TextEditingController();
......@@ -159,7 +131,7 @@ class MapContainer extends BaseWidget {
height: sizingInformation.unnotchedHeight * 33/40 * 0.75,
child: Listener(
behavior: HitTestBehavior.deferToChild,
child: _buildMap()
child: MapWidget()
)
),
),
......
......@@ -118,6 +118,12 @@ class _BluetoothButtonState extends State<BluetoothButton> {
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
offset: Offset(2, -2),
color: Colors.blueGrey[100]
)
],
gradient: RadialGradient(
center: Alignment.center,
colors: [
......
......@@ -133,7 +133,6 @@ class _HomeViewState extends State<HomeView> {
),
],
),
);
}
);
......
......@@ -190,6 +190,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0-nullsafety"
ffi:
dependency: transitive
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.3"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "5.2.1"
fixnum:
dependency: transitive
description:
......@@ -248,7 +262,7 @@ packages:
name: flutter_map
url: "https://pub.dartlang.org"
source: hosted
version: "0.8.2"
version: "0.10.1+1"
flutter_test:
dependency: "direct dev"
description: flutter
......@@ -371,6 +385,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.1"
lists:
dependency: transitive
description:
name: lists
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.6"
location_permissions:
dependency: transitive
description:
......@@ -406,6 +427,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0-nullsafety.2"
mgrs_dart:
dependency: transitive
description:
name: mgrs_dart
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
mime:
dependency: transitive
description:
......@@ -482,7 +510,35 @@ packages:
name: path_provider
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.0"
version: "1.6.17"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.1+2"
path_provider_macos:
dependency: transitive
description:
name: path_provider_macos
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4+4"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4+1"
pedantic:
dependency: transitive
description:
......@@ -532,6 +588,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
process:
dependency: transitive
description:
name: process
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.13"
proj4dart:
dependency: transitive
description:
name: proj4dart
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.5"
protobuf:
dependency: transitive
description:
......@@ -733,6 +803,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0-nullsafety.2"
unicode:
dependency: transitive
description:
name: unicode
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.4"
uuid:
dependency: "direct main"
description:
......@@ -782,6 +859,27 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.0"
win32:
dependency: transitive
description:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.3"
wkt_parser:
dependency: transitive
description:
name: wkt_parser
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.7"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.2"
yaml:
dependency: transitive
description:
......
......@@ -18,7 +18,7 @@ dependencies:
carousel_slider: ^1.4.1
provider: null
geolocator: ^5.2.1
flutter_map: ^0.8.2
flutter_map: ^0.10.1+1