Eov magassági korrekció rácshálóból (gtx)
This commit is contained in:
parent
688922808b
commit
7ee47e65bd
67
lib/controls/geoid_grid.dart
Normal file
67
lib/controls/geoid_grid.dart
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import 'dart:typed_data';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
class GeoidGrid {
|
||||||
|
final double southLat, westLon, latStep, lonStep;
|
||||||
|
final int nRows, nCols;
|
||||||
|
final Float32List grid; // big-endian, south-to-north
|
||||||
|
|
||||||
|
GeoidGrid._(this.southLat, this.westLon, this.latStep, this.lonStep,
|
||||||
|
this.nRows, this.nCols, this.grid);
|
||||||
|
|
||||||
|
static Future<GeoidGrid> load(String assetPath) async {
|
||||||
|
final bytes = (await rootBundle.load(assetPath)).buffer.asByteData();
|
||||||
|
final southLat = bytes.getFloat64(0, Endian.big);
|
||||||
|
final westLon = bytes.getFloat64(8, Endian.big);
|
||||||
|
final latStep = bytes.getFloat64(16, Endian.big);
|
||||||
|
final lonStep = bytes.getFloat64(24, Endian.big);
|
||||||
|
final nRows = bytes.getInt32(32, Endian.big);
|
||||||
|
final nCols = bytes.getInt32(36, Endian.big);
|
||||||
|
|
||||||
|
final grid = Float32List(nRows * nCols);
|
||||||
|
for (int i = 0; i < grid.length; i++) {
|
||||||
|
grid[i] = bytes.getFloat32(40 + i * 4, Endian.big);
|
||||||
|
}
|
||||||
|
return GeoidGrid._(southLat, westLon, latStep, lonStep, nRows, nCols, grid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns EHT2014 geoid undulation [m] at (lat, lon) via bilinear interpolation.
|
||||||
|
/// Returns null if outside grid or in no-data area.
|
||||||
|
double? getUndulation(double lat, double lon) {
|
||||||
|
final rowF = (lat - southLat) / latStep;
|
||||||
|
final colF = (lon - westLon) / lonStep;
|
||||||
|
final r0 = rowF.floor();
|
||||||
|
final c0 = colF.floor();
|
||||||
|
if (r0 < 0 || r0 >= nRows - 1 || c0 < 0 || c0 >= nCols - 1) return null;
|
||||||
|
|
||||||
|
final dr = rowF - r0;
|
||||||
|
final dc = colF - c0;
|
||||||
|
|
||||||
|
double v(int r, int c) => grid[r * nCols + c].toDouble();
|
||||||
|
final noData = -80.0;
|
||||||
|
final v00 = v(r0, c0);
|
||||||
|
if (v00 < noData) return null;
|
||||||
|
final v10 = v(r0 + 1, c0);
|
||||||
|
if (v10 < noData) return null;
|
||||||
|
final v01 = v(r0, c0 + 1);
|
||||||
|
if (v01 < noData) return null;
|
||||||
|
final v11 = v(r0 + 1, c0 + 1);
|
||||||
|
if (v11 < noData) return null;
|
||||||
|
|
||||||
|
return v00 * (1 - dr) * (1 - dc) +
|
||||||
|
v10 * dr * (1 - dc) +
|
||||||
|
v01 * (1 - dr) * dc +
|
||||||
|
v11 * dr * dc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Orthometric height in the Hungarian EHT2014 system.
|
||||||
|
/// [nmea_ortho] = GGA field 9 (altitudeAboveMeanSeaLevel)
|
||||||
|
/// [nmea_sep] = GGA field 11 (geoidSeparation from receiver)
|
||||||
|
double? toEovHeight(
|
||||||
|
double lat, double lon, double nmeaOrtho, double nmeaSep) {
|
||||||
|
final nEht2014 = getUndulation(lat, lon);
|
||||||
|
if (nEht2014 == null) return null;
|
||||||
|
final ellipsoidal = nmeaOrtho + nmeaSep; // h = H + N_receiver
|
||||||
|
return ellipsoidal - nEht2014; // H_EOV = h - N_EHT2014
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -21,6 +21,7 @@ import 'package:permission_handler/permission_handler.dart'
|
|||||||
as permission_handler;
|
as permission_handler;
|
||||||
import 'package:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||||
|
import 'package:terepi_seged/controls/geoid_grid.dart';
|
||||||
import 'package:terepi_seged/eov/convert_coordinate.dart';
|
import 'package:terepi_seged/eov/convert_coordinate.dart';
|
||||||
import 'package:terepi_seged/eov/eov.dart';
|
import 'package:terepi_seged/eov/eov.dart';
|
||||||
import 'package:terepi_seged/gnss_sentences/gngga.dart';
|
import 'package:terepi_seged/gnss_sentences/gngga.dart';
|
||||||
@ -78,6 +79,8 @@ class MapViewController extends GetxController {
|
|||||||
RxDouble gpsAltitudeError = 0.0.obs;
|
RxDouble gpsAltitudeError = 0.0.obs;
|
||||||
Rx<DateTime> gpsDateTime = DateTime(2000).obs;
|
Rx<DateTime> gpsDateTime = DateTime(2000).obs;
|
||||||
Rx<Eov> eov = Eov(0, 0).obs;
|
Rx<Eov> eov = Eov(0, 0).obs;
|
||||||
|
Rx<double?> eovHeight = 0.0.obs;
|
||||||
|
|
||||||
RxInt latDegree = 0.obs;
|
RxInt latDegree = 0.obs;
|
||||||
RxInt latMin = 0.obs;
|
RxInt latMin = 0.obs;
|
||||||
RxDouble latSec = 0.0.obs;
|
RxDouble latSec = 0.0.obs;
|
||||||
@ -99,6 +102,8 @@ class MapViewController extends GetxController {
|
|||||||
RxInt pointsToMeasureSelectedValue = (-1).obs;
|
RxInt pointsToMeasureSelectedValue = (-1).obs;
|
||||||
RxDouble distance = 0.0.obs;
|
RxDouble distance = 0.0.obs;
|
||||||
|
|
||||||
|
late GeoidGrid geoidGrid;
|
||||||
|
|
||||||
TextEditingController pointIdController = TextEditingController();
|
TextEditingController pointIdController = TextEditingController();
|
||||||
TextEditingController pointDescriptionController = TextEditingController();
|
TextEditingController pointDescriptionController = TextEditingController();
|
||||||
TextEditingController gpsHeightController = TextEditingController();
|
TextEditingController gpsHeightController = TextEditingController();
|
||||||
@ -180,6 +185,8 @@ class MapViewController extends GetxController {
|
|||||||
})
|
})
|
||||||
.subscribe();
|
.subscribe();
|
||||||
|
|
||||||
|
geoidGrid = await GeoidGrid.load('assets/Grids/geoid_eht2014.gtx');
|
||||||
|
|
||||||
mapController = MapController();
|
mapController = MapController();
|
||||||
|
|
||||||
// riveGpsIconController = RiveUtils.getRiveController(Artboard(),
|
// riveGpsIconController = RiveUtils.getRiveController(Artboard(),
|
||||||
@ -482,6 +489,11 @@ class MapViewController extends GetxController {
|
|||||||
gpsQuality.value = sentence.gpsQualityIndicator;
|
gpsQuality.value = sentence.gpsQualityIndicator;
|
||||||
eov.value = ConvertCoordinate.ConvertWgsToEov(
|
eov.value = ConvertCoordinate.ConvertWgsToEov(
|
||||||
gpsLatitude.value, gpsLongitude.value);
|
gpsLatitude.value, gpsLongitude.value);
|
||||||
|
eovHeight.value = geoidGrid?.toEovHeight(
|
||||||
|
gpsLatitude.value,
|
||||||
|
gpsLongitude.value,
|
||||||
|
gpsAltitude.value,
|
||||||
|
gpsGeoidSeparation.value);
|
||||||
|
|
||||||
if (pointsToMeasureSelectedValue.value >= 0) {
|
if (pointsToMeasureSelectedValue.value >= 0) {
|
||||||
double coordX =
|
double coordX =
|
||||||
|
|||||||
@ -154,7 +154,7 @@ class MapView extends GetView<MapViewController> {
|
|||||||
"EovX: ${controller.formatEov.format(controller.eov.value.Y)}"),
|
"EovX: ${controller.formatEov.format(controller.eov.value.Y)}"),
|
||||||
Text(
|
Text(
|
||||||
"EovY: ${controller.formatEov.format(controller.eov.value.X)}"),
|
"EovY: ${controller.formatEov.format(controller.eov.value.X)}"),
|
||||||
Text("Alt: ${controller.gpsAltitude} (m)"),
|
Text("Alt: ${controller.eovHeight.value} (m)"),
|
||||||
const Divider(
|
const Divider(
|
||||||
height: 5.0,
|
height: 5.0,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user