wgs84 és eov koordinátákat megjelenítő kártyák, eov magasság
This commit is contained in:
parent
497821bb41
commit
b85cdb2596
88
lib/controls/wgs84_coordinate_formatter.dart
Normal file
88
lib/controls/wgs84_coordinate_formatter.dart
Normal file
@ -0,0 +1,88 @@
|
||||
enum Wgs84CoordinateFormat {
|
||||
decimalDegrees,
|
||||
degreesDecimalMinutes,
|
||||
degreesMinutesSeconds
|
||||
}
|
||||
|
||||
extension Wgs84CoordinateFormatLabel on Wgs84CoordinateFormat {
|
||||
String get label {
|
||||
switch (this) {
|
||||
case Wgs84CoordinateFormat.decimalDegrees:
|
||||
return 'Tizedes fok';
|
||||
case Wgs84CoordinateFormat.degreesDecimalMinutes:
|
||||
return 'Fok + tizedes perc';
|
||||
case Wgs84CoordinateFormat.degreesMinutesSeconds:
|
||||
return 'Fok - perc - másodperc';
|
||||
}
|
||||
}
|
||||
|
||||
String get shortLabel {
|
||||
switch (this) {
|
||||
case Wgs84CoordinateFormat.decimalDegrees:
|
||||
return 'DD';
|
||||
case Wgs84CoordinateFormat.degreesDecimalMinutes:
|
||||
return 'DM';
|
||||
case Wgs84CoordinateFormat.degreesMinutesSeconds:
|
||||
return 'DMS';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Wgs84CoordinateFormatter {
|
||||
static String formatLatitude(
|
||||
double? value,
|
||||
Wgs84CoordinateFormat format,
|
||||
) {
|
||||
return _format(
|
||||
value: value,
|
||||
format: format,
|
||||
positiveHemisphere: 'N',
|
||||
negativeHemisphere: 'S',
|
||||
);
|
||||
}
|
||||
|
||||
static String formatLongitude(
|
||||
double? value,
|
||||
Wgs84CoordinateFormat format,
|
||||
) {
|
||||
return _format(
|
||||
value: value,
|
||||
format: format,
|
||||
positiveHemisphere: 'E',
|
||||
negativeHemisphere: 'W',
|
||||
);
|
||||
}
|
||||
|
||||
static String _format({
|
||||
required double? value,
|
||||
required Wgs84CoordinateFormat format,
|
||||
required String positiveHemisphere,
|
||||
required String negativeHemisphere,
|
||||
}) {
|
||||
if (value == null || value.isNaN || value.isInfinite) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
final hemisphere = value >= 0 ? positiveHemisphere : negativeHemisphere;
|
||||
final absValue = value.abs();
|
||||
|
||||
switch (format) {
|
||||
case Wgs84CoordinateFormat.decimalDegrees:
|
||||
return '${absValue.toStringAsFixed(8)}° $hemisphere';
|
||||
|
||||
case Wgs84CoordinateFormat.degreesDecimalMinutes:
|
||||
final deg = absValue.floor();
|
||||
final minutes = (absValue - deg) * 60.0;
|
||||
|
||||
return '$deg° ${minutes.toStringAsFixed(5)}′ $hemisphere';
|
||||
|
||||
case Wgs84CoordinateFormat.degreesMinutesSeconds:
|
||||
final deg = absValue.floor();
|
||||
final fullMinutes = (absValue - deg) * 60.0;
|
||||
final min = fullMinutes.floor();
|
||||
final sec = (fullMinutes - min) * 60.0;
|
||||
|
||||
return '$deg° $min′ ${sec.toStringAsFixed(3)}″ $hemisphere';
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -18,6 +18,7 @@ import 'package:path_provider/path_provider.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
import 'package:terepi_seged/controls/geoid_grid.dart';
|
||||
import 'package:terepi_seged/controls/wgs84_coordinate_formatter.dart';
|
||||
import 'package:terepi_seged/enums/map_survey_mode.dart';
|
||||
import 'package:terepi_seged/eov/convert_coordinate.dart';
|
||||
import 'package:terepi_seged/eov/eov.dart';
|
||||
@ -65,6 +66,10 @@ class MapSurveyController extends GetxController {
|
||||
bool get gpsIsConnected =>
|
||||
_gnss.connectionState.value == GnssConnectionState.connected;
|
||||
|
||||
final wgs84CoordinateFormat = Wgs84CoordinateFormat.decimalDegrees.obs;
|
||||
final showWgs84Card = true.obs;
|
||||
final showEovCard = true.obs;
|
||||
|
||||
// NTRIP állapot
|
||||
RxBool get ntripIsConnected => _ntrip.isConnected;
|
||||
RxInt get ntripDataPacketNumbers => _ntrip.packetCount;
|
||||
@ -781,4 +786,26 @@ class MapSurveyController extends GetxController {
|
||||
targetEovX.value = x;
|
||||
mode.value = MapSurveyMode.stakeout;
|
||||
}
|
||||
|
||||
void setWgs84CoordinateFormat(Wgs84CoordinateFormat format) {
|
||||
wgs84CoordinateFormat.value = format;
|
||||
}
|
||||
|
||||
void toggleShowWgs84Card() {
|
||||
showWgs84Card.value = !showWgs84Card.value;
|
||||
}
|
||||
|
||||
void toggleShowEovCard() {
|
||||
showEovCard.value = !showEovCard.value;
|
||||
}
|
||||
|
||||
String get latitudeText {
|
||||
return Wgs84CoordinateFormatter.formatLatitude(
|
||||
gpsLatitude.value, wgs84CoordinateFormat.value);
|
||||
}
|
||||
|
||||
String get longitudeText {
|
||||
return Wgs84CoordinateFormatter.formatLongitude(
|
||||
gpsLongitude.value, wgs84CoordinateFormat.value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import 'package:terepi_seged/pages/map_survey/presentations/views/settings_dialo
|
||||
import 'package:terepi_seged/utils/rive_utils.dart';
|
||||
import 'package:terepi_seged/widgets/coordinate_panel.dart';
|
||||
import 'package:terepi_seged/widgets/map_bottom_panel.dart';
|
||||
import 'package:terepi_seged/widgets/map_info_card_column.dart';
|
||||
import 'package:terepi_seged/widgets/save_point_fab.dart';
|
||||
import 'package:terepi_seged/widgets/shared_map_widgets.dart';
|
||||
|
||||
@ -32,7 +33,13 @@ class MapSurveyView extends GetView<MapSurveyController> {
|
||||
],
|
||||
),
|
||||
Positioned(
|
||||
top: 8,
|
||||
top: 12,
|
||||
left: 12,
|
||||
child: MapInfoCardColumn(controller: controller),
|
||||
),
|
||||
|
||||
Positioned(
|
||||
top: 300,
|
||||
right: 60,
|
||||
left: 8,
|
||||
child: CoordinatePanel(
|
||||
|
||||
43
lib/widgets/coordinate_row.dart
Normal file
43
lib/widgets/coordinate_row.dart
Normal file
@ -0,0 +1,43 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CoordinateRow extends StatelessWidget {
|
||||
final String label;
|
||||
final String value;
|
||||
|
||||
const CoordinateRow({
|
||||
required this.label,
|
||||
required this.value,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 34,
|
||||
child: Text(
|
||||
label,
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: SelectableText(
|
||||
value,
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
fontFeatures: const [
|
||||
FontFeature.tabularFigures(),
|
||||
],
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
54
lib/widgets/eov_coordinate_card.dart
Normal file
54
lib/widgets/eov_coordinate_card.dart
Normal file
@ -0,0 +1,54 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:terepi_seged/pages/map_survey/presentations/controllers/map_survey_controller.dart';
|
||||
import 'package:terepi_seged/widgets/map_info_card.dart';
|
||||
|
||||
import 'coordinate_row.dart';
|
||||
|
||||
class EovCoordinateCard extends StatelessWidget {
|
||||
final MapSurveyController controller;
|
||||
|
||||
const EovCoordinateCard({
|
||||
super.key,
|
||||
required this.controller,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Obx(() {
|
||||
return MapInfoCard(
|
||||
onClose: controller.toggleShowEovCard,
|
||||
title: Row(
|
||||
children: [
|
||||
const Icon(Icons.grid_on, size: 18),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
'EOV',
|
||||
style: Theme.of(context).textTheme.titleSmall?.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
CoordinateRow(
|
||||
label: 'Y',
|
||||
value: controller.eovY.value.toStringAsFixed(3),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
CoordinateRow(
|
||||
label: 'X',
|
||||
value: controller.eovX.value.toStringAsFixed(3),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
CoordinateRow(
|
||||
label: 'Z',
|
||||
value: controller.eovHeight.value?.toStringAsFixed(3) ?? '-',
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
44
lib/widgets/format_menu_button.dart
Normal file
44
lib/widgets/format_menu_button.dart
Normal file
@ -0,0 +1,44 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:terepi_seged/controls/wgs84_coordinate_formatter.dart';
|
||||
import 'package:terepi_seged/pages/map_survey/presentations/controllers/map_survey_controller.dart';
|
||||
|
||||
class FormatMenuButton extends StatelessWidget {
|
||||
final MapSurveyController controller;
|
||||
|
||||
const FormatMenuButton({
|
||||
required this.controller,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PopupMenuButton<Wgs84CoordinateFormat>(
|
||||
tooltip: 'Koordinátaformátum',
|
||||
initialValue: controller.wgs84CoordinateFormat.value,
|
||||
onSelected: controller.setWgs84CoordinateFormat,
|
||||
itemBuilder: (context) {
|
||||
return Wgs84CoordinateFormat.values.map((format) {
|
||||
return CheckedPopupMenuItem<Wgs84CoordinateFormat>(
|
||||
value: format,
|
||||
checked: controller.wgs84CoordinateFormat.value == format,
|
||||
child: Text(format.label),
|
||||
);
|
||||
}).toList();
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
controller.wgs84CoordinateFormat.value.shortLabel,
|
||||
style: Theme.of(context).textTheme.labelMedium?.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
const Icon(Icons.arrow_drop_down, size: 18),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
55
lib/widgets/map_info_card.dart
Normal file
55
lib/widgets/map_info_card.dart
Normal file
@ -0,0 +1,55 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MapInfoCard extends StatelessWidget {
|
||||
final Widget title;
|
||||
final Widget child;
|
||||
final VoidCallback? onClose;
|
||||
|
||||
const MapInfoCard({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.child,
|
||||
this.onClose,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final screenWidth = MediaQuery.sizeOf(context).width;
|
||||
|
||||
return Material(
|
||||
elevation: 6,
|
||||
color: colorScheme.surface.withOpacity(0.64),
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
child: Container(
|
||||
width: screenWidth - 60,
|
||||
padding: const EdgeInsets.fromLTRB(6, 2, 6, 2),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
border: Border.all(
|
||||
color: colorScheme.outlineVariant.withOpacity(0.7),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: title),
|
||||
if (onClose != null)
|
||||
IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
tooltip: 'Kártya bezárása',
|
||||
icon: const Icon(Icons.close, size: 18),
|
||||
onPressed: onClose,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
child,
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
51
lib/widgets/map_info_card_column.dart
Normal file
51
lib/widgets/map_info_card_column.dart
Normal file
@ -0,0 +1,51 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:terepi_seged/pages/map_survey/presentations/controllers/map_survey_controller.dart';
|
||||
import 'package:terepi_seged/widgets/wgs84_coordinate_card.dart';
|
||||
|
||||
import 'eov_coordinate_card.dart';
|
||||
|
||||
class MapInfoCardColumn extends StatelessWidget {
|
||||
final MapSurveyController controller;
|
||||
|
||||
const MapInfoCardColumn({
|
||||
super.key,
|
||||
required this.controller,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final screenHeight = MediaQuery.sizeOf(context).height;
|
||||
final screenWidth = MediaQuery.sizeOf(context).width;
|
||||
|
||||
return Obx(() {
|
||||
final cards = <Widget>[];
|
||||
|
||||
if (controller.showWgs84Card.value) {
|
||||
cards.add(Wgs84CoordinateCard(controller: controller));
|
||||
}
|
||||
if (controller.showEovCard.value) {
|
||||
cards.add(EovCoordinateCard(controller: controller));
|
||||
}
|
||||
|
||||
if (cards.isEmpty) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: screenWidth - 50, maxHeight: screenHeight * 0.55),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
for (var i = 0; i < cards.length; i++) ...[
|
||||
cards[i],
|
||||
if (i != cards.length - 1) const SizedBox(height: 8)
|
||||
]
|
||||
],
|
||||
),
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
||||
52
lib/widgets/wgs84_coordinate_card.dart
Normal file
52
lib/widgets/wgs84_coordinate_card.dart
Normal file
@ -0,0 +1,52 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:terepi_seged/pages/map_survey/presentations/controllers/map_survey_controller.dart';
|
||||
|
||||
import 'map_info_card.dart';
|
||||
import 'format_menu_button.dart';
|
||||
import 'coordinate_row.dart';
|
||||
|
||||
class Wgs84CoordinateCard extends StatelessWidget {
|
||||
final MapSurveyController controller;
|
||||
|
||||
const Wgs84CoordinateCard({
|
||||
super.key,
|
||||
required this.controller,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Obx(() {
|
||||
return MapInfoCard(
|
||||
onClose: controller.toggleShowWgs84Card,
|
||||
title: Row(
|
||||
children: [
|
||||
const Icon(Icons.public, size: 18),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
'WGS84',
|
||||
style: Theme.of(context).textTheme.titleSmall?.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
FormatMenuButton(controller: controller),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
CoordinateRow(
|
||||
label: 'Lat',
|
||||
value: controller.latitudeText,
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
CoordinateRow(
|
||||
label: 'Lon',
|
||||
value: controller.longitudeText,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user