-
Notifications
You must be signed in to change notification settings - Fork 15
Display distance and time info for wind/skew-t sources #48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
5f1e2c4
23bd1c2
9622f62
a4005c1
07ba966
f40cd41
a750948
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -96,7 +96,7 @@ class LongPressScreenState extends State<LongPressScreen> { | |
| LatLng ll = LatLng(Storage().position.latitude, Storage().position.longitude); | ||
| double distance = geo.calculateDistance(ll, widget.destinations[0].coordinate); | ||
| double bearing = geo.calculateBearing(ll, widget.destinations[0].coordinate); | ||
| String direction = ("${distance.round()} ${GeoCalculations.getGeneralDirectionFrom(bearing, Storage().area.variation)}"); | ||
| String direction = ("${distance.round()} ${Storage().units.distanceName} ${GeoCalculations.getGeneralDirectionFrom(bearing, Storage().area.variation)}"); | ||
| String facility = showDestination.facilityName.length > 16 ? showDestination.facilityName.substring(0, 16) : showDestination.facilityName; | ||
| List<Widget?> pages = List.generate(labels.length, (index) => null); | ||
| String label = "$facility (${showDestination.locationID}) $direction${showDestination.elevation != null ? "; EL ${showDestination.elevation!.round()}" : ""}"; | ||
|
|
@@ -123,7 +123,7 @@ class LongPressScreenState extends State<LongPressScreen> { | |
| ]); | ||
| } | ||
| pages[labels.indexOf("NOTAM")] = FutureBuilder(future: Storage().notam.getSync(showDestination.locationID), | ||
| builder: (context, snapshot) { // notmas are downloaded when not in cache and can be slow to download so do async | ||
| builder: (context, snapshot) { // notams are downloaded when not in cache and can be slow to download so do async | ||
| if (snapshot.hasData) { | ||
| return snapshot.data != null ? | ||
| SingleChildScrollView(child: Padding(padding: const EdgeInsets.all(10), child:Text((snapshot.data as Notam).text))) | ||
|
|
@@ -159,13 +159,13 @@ class LongPressScreenState extends State<LongPressScreen> { | |
| } | ||
|
|
||
| Weather? winds; | ||
| String? station = WindsCache.locateNearestStation(showDestination.coordinate); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How does this work with weather received from ADSB? |
||
| var (station, dist, stationBearing) = WindsCache.locateNearestStation(showDestination.coordinate); | ||
| if(station != null) { | ||
| winds = Storage().winds.get("${station}06H"); // 6HR wind | ||
| if(winds != null) { | ||
| WindsAloft wa = winds as WindsAloft; | ||
| pages[labels.indexOf("Wind")] = ListView(children: [ | ||
| ListTile(title: Text(winds.toString())), | ||
| ListTile(title: Text('${dist.round()} ${Storage().units.distanceName} ${GeoCalculations.getGeneralDirectionFrom(stationBearing, 0)} @ ${winds.toString()}')), | ||
| for((String, String) wl in wa.toList()) | ||
| ListTile(leading: Text(wl.$1), title: Text(wl.$2)), | ||
| ]); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
|
|
||
| class TimeZone { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There should be a package for it 'tz' in pubspec.yaml. |
||
| //calculates the timestamp from the passed Zulu time in METAR format (e.g. DDHHMMZ) | ||
| //any trailing values after the Z are disregarded | ||
| //if there isn't 7 characters to create a Zulu time, or letters in first six locations, returns null | ||
| static DateTime? parseZuluTime(String s) | ||
| { | ||
| if(s.length < 7 || int.tryParse(s.substring(0,5)) == null) | ||
| { | ||
| return null; | ||
| } | ||
| DateTime now = DateTime.now().toUtc(); | ||
| DateTime expires = DateTime.utc( | ||
| now.year, | ||
| now.month, | ||
| now.day, //day | ||
| 0, | ||
| 0); | ||
| int from = int.parse(s[2]!); | ||
| int to = int.parse(s[3]!); | ||
| // if from > to then its next day | ||
| expires = expires.add(Duration(days: to < from ? 1 : 0, hours: int.parse(s[3]!.substring(0, 2)), minutes: int.parse(s[5]!.substring(0, 2)))); | ||
| return expires; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ class UnitConversion { | |
| mpsTo = 2.23694; | ||
| toMps = 0.44704; | ||
| knotsTo = 1.15078; | ||
| distanceName = 'mi'; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have all the places that use this been added this info? For example measuring tool? |
||
| } | ||
| } | ||
|
|
||
|
|
@@ -28,4 +29,7 @@ class UnitConversion { | |
| // knots for wind. | ||
| double knotsTo = 1; | ||
|
|
||
| } | ||
| //name of distance unit | ||
| String distanceName = 'nm'; | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,20 +7,27 @@ import '../geo_calculations.dart'; | |
|
|
||
| class Sounding { | ||
|
|
||
| static String? _locateNearestStation(LatLng location) { | ||
| static (String?, double, double) _locateNearestStation(LatLng location) { | ||
|
|
||
| // find distance | ||
| GeoCalculations geo = GeoCalculations(); | ||
| double distanceMin = double.maxFinite; | ||
| String? station; | ||
| LatLng? stationLocation; | ||
| for(MapEntry<String, LatLng> map in _stationMap.entries) { | ||
| double distance = geo.calculateDistance(map.value, location); | ||
| if(distance < distanceMin) { | ||
| distanceMin = distance; | ||
| station = map.key; | ||
| stationLocation = map.value; | ||
| } | ||
| } | ||
| return station; | ||
| double? bearing; | ||
| if(stationLocation != null) | ||
| { | ||
| bearing = geo.calculateBearing(stationLocation, location); | ||
| } | ||
| return (station, distanceMin, bearing ?? 0); | ||
| } | ||
|
|
||
| static Widget? getSoundingImage(LatLng coordinate, BuildContext context) { | ||
|
|
@@ -29,20 +36,35 @@ class Sounding { | |
| return const Center(child: Text('Error downloading the Sounding Analysis for this area.')); | ||
| } | ||
|
|
||
| String? station = _locateNearestStation(coordinate); | ||
| var (station, dist, bearing) = _locateNearestStation(coordinate); | ||
| if(null == station) { | ||
| return null; | ||
| } | ||
| DateTime now = DateTime.now().toUtc(); | ||
| DateTime now = DateTime.timestamp(); | ||
| now = now.subtract(const Duration(hours: 1)); // 1 hour delayed on website | ||
| String hour = ((now.hour / 12).floor() * 12).toString().padLeft(2, '0'); | ||
| String year = now.year.toString().substring(2); | ||
| String day = now.day.toString().padLeft(2, '0'); | ||
| String month = now.month.toString().padLeft(2, '0'); | ||
| DateTime obsTime = DateTime.utc(now.year, now.month, now.day, (now.hour/ 12).floor() * 12); | ||
| String hour = obsTime.hour.toString().padLeft(2, '0'); | ||
| String year = obsTime.year.toString().substring(2); | ||
| String day = obsTime.day.toString().padLeft(2, '0'); | ||
| String month = obsTime.month.toString().padLeft(2, '0'); | ||
| String url = "https://www.spc.noaa.gov/exper/soundings/$year$month$day${hour}_OBS/$station.gif"; | ||
| Duration timeSinceObs = DateTime.timestamp().difference(obsTime); | ||
| CachedNetworkImage image = CachedNetworkImage(imageUrl: url, cacheManager: FileCacheManager().networkCacheManager, errorWidget: errorImage,); | ||
| return Container(padding: const EdgeInsets.all(10), child: | ||
| InteractiveViewer(child: Container(color: Colors.white , alignment: Alignment.center, child: image))); | ||
| return ListView( | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Stack is a better widget here |
||
| children: <Widget>[ | ||
| ListTile(title: Text("${dist.round()} ${Storage().units.distanceName} ${GeoCalculations.getGeneralDirectionFrom(bearing, 0)} @ ${station} (${timeSinceObs.inHours}:${(timeSinceObs.inMinutes % 60).toString().padLeft(2, '0')} ago)")), | ||
| Container( | ||
| padding: const EdgeInsets.symmetric(horizontal: 10), | ||
| child: InteractiveViewer( | ||
| child: Container( | ||
| color: Colors.white, | ||
| alignment: Alignment.center, | ||
| child: image | ||
| ) | ||
| ) | ||
| ) | ||
| ] | ||
| ); | ||
| } | ||
|
|
||
| // List of station codes from the HTML area elements | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -47,6 +47,10 @@ class WindsAloft extends Weather { | |
| return(dir, (speed.toDouble() * Storage().units.knotsTo).round()); | ||
| } | ||
|
|
||
| static String invertTemperature(String wind) { | ||
| return wind.replaceRange(4,4,'-'); | ||
| } | ||
|
|
||
| (double?, double?) getWindAtAltitude(double altitude) { // dir, speed | ||
| String wHigher; | ||
| String wLower; | ||
|
|
@@ -176,13 +180,13 @@ class WindsAloft extends Weather { | |
| return w24k; | ||
| } | ||
| else if (altitude == 30000) { | ||
| return w30k; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is confusing as pilots are used to seeing negative temps. |
||
| return invertTemperature(w30k); | ||
| } | ||
| else if (altitude == 34000) { | ||
| return w34k; | ||
| return invertTemperature(w34k); | ||
| } | ||
| else if (altitude == 39000) { | ||
| return w39k; | ||
| return invertTemperature(w39k); | ||
| } | ||
| return "N/A"; | ||
| } | ||
|
|
@@ -242,7 +246,7 @@ class WindsAloft extends Weather { | |
| toString() { | ||
| DateTime zulu = expires.toUtc(); // winds in Zulu time | ||
| // boilerplate | ||
| String wind = "$station (Temps negative above 24000)\nValid till ${zulu.day .toString().padLeft(2, "0")}${zulu.hour.toString().padLeft(2, "0")}00Z"; | ||
| String wind = "$station\nValid till ${expires.hour.toString().padLeft(2, '0')}:${expires.minute.toString().padLeft(2, '0')} (${zulu.day.toString().padLeft(2, '0')}${zulu.hour.toString().padLeft(2, '0')}00Z)"; | ||
| return wind; | ||
| } | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an issue as the direction is from the point touched. Of is required you are off of this heading