Terepbejárás oldalon vonal és terület tulajdonságainak szerkesztése, mentés

This commit is contained in:
2026-06-16 14:12:44 +02:00
parent 537897005c
commit 1276ac0610
19 changed files with 1206 additions and 17 deletions
@@ -8,6 +8,7 @@ import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_map_polygon_editor/polygon_editor/polygon_editor_controller.dart';
// import 'package:flutter_map_geojson/flutter_map_geojson.dart';
import 'package:flutter_map_polywidget/flutter_map_polywidget.dart';
import 'package:geolocator/geolocator.dart';
@@ -20,6 +21,7 @@ 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_edit_tool.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';
@@ -35,6 +37,7 @@ import 'package:terepi_seged/services/gnss/gnss_connection.dart';
import 'package:terepi_seged/services/gnss/gnss_device_service.dart';
import 'package:terepi_seged/services/gnss/gnss_service.dart';
import 'package:terepi_seged/services/ntrip_service.dart';
import 'package:terepi_seged/widgets/map_edit_tools/map_feature_save_sheet.dart';
class MapSurveyController extends GetxController {
static MapSurveyController get to => Get.find();
@@ -159,6 +162,26 @@ class MapSurveyController extends GetxController {
// ── Supabase ──────────────────────────────────────────────────────
RealtimeChannel? _supaChannel;
// ------- Map edit ----------------
final activeEditTool = MapEditTool.none.obs;
final editorPointCount = 0.obs;
final pointNotes = <Marker>[].obs;
final polylineNotes = <Polyline<Object>>[].obs;
final polygonNotes = <Polygon<Object>>[].obs;
late final PolygonEditorController polygonEditorController;
final activeEditColor = const Color(0xFF185FA5).obs;
final activeEditOpacity = 0.5.obs;
final activeEditStrokeWidth = 3.0.obs;
final activeEditStrokeColor = const Color(0xFFFFD700).obs;
final activeEditLabel = ''.obs;
final PolygonLabelPlacementCalculator _labelPlacementCalculator =
const PolygonLabelPlacementCalculator.centroid();
bool get isMapEditing => activeEditTool.value != MapEditTool.none;
// ─────────────────────────────────────────────────────────────────
// Lifecycle
// ─────────────────────────────────────────────────────────────────
@@ -190,6 +213,12 @@ class MapSurveyController extends GetxController {
)
.subscribe();
polygonEditorController =
PolygonEditorController(mode: PolygonEditorMode.polygon);
polygonEditorController.addListener(() {
editorPointCount.value = polygonEditorController.points.length;
});
mapIsInitialized.value = true;
}
@@ -214,6 +243,7 @@ class MapSurveyController extends GetxController {
gpsHeightController.dispose();
pointPrefixController.dispose();
pointPostfixController.dispose();
polygonEditorController.dispose();
super.onClose();
}
@@ -846,4 +876,202 @@ class MapSurveyController extends GetxController {
return '${value.toStringAsFixed(1)}m';
}
// --------- Térkép szerkesztési műveletek
IconData get activeEditToolIcon {
switch (activeEditTool.value) {
case MapEditTool.point:
return Icons.add_location_alt_outlined;
case MapEditTool.line:
return Icons.polyline_outlined;
case MapEditTool.polygon:
return Icons.border_outer_outlined;
case MapEditTool.none:
return Icons.edit_location_alt_outlined;
}
}
String get activeEditToolTitle {
switch (activeEditTool.value) {
case MapEditTool.point:
return 'Pont hozzáadása';
case MapEditTool.line:
return 'Vonal rögzítése';
case MapEditTool.polygon:
return 'Terület rögzítése';
case MapEditTool.none:
return '';
}
}
String get activeEditToolHint {
switch (activeEditTool.value) {
case MapEditTool.point:
return 'Koppints a térképre a pont helyéhez.';
case MapEditTool.line:
return 'Hosszan nyomj a térképre a töréspontokhoz';
case MapEditTool.polygon:
return 'Hosszan nyomj a térképre a sarokpontokhoz.';
case MapEditTool.none:
return '';
}
}
bool get canFinishGeometry {
switch (activeEditTool.value) {
case MapEditTool.point:
return editorPointCount == 1;
case MapEditTool.line:
return editorPointCount >= 2;
case MapEditTool.polygon:
return editorPointCount >= 3;
case MapEditTool.none:
return false;
}
}
String get finishButtonText {
switch (activeEditTool.value) {
case MapEditTool.point:
return 'Kész';
case MapEditTool.line:
return 'Kész';
case MapEditTool.polygon:
return 'Lezárás';
case MapEditTool.none:
return 'Kész';
}
}
void startPointTool() {
activeEditTool.value = MapEditTool.point;
}
void startLineTool() {
polygonEditorController.clear();
polygonEditorController.setMode(PolygonEditorMode.line);
activeEditTool.value = MapEditTool.line;
}
void startPolygonTool() {
polygonEditorController.clear();
polygonEditorController.setMode(PolygonEditorMode.polygon);
activeEditTool.value = MapEditTool.polygon;
}
void cancelEditing() {
polygonEditorController.clear();
activeEditTool.value = MapEditTool.none;
}
void openFeatureList() {
// TODO: DraggableScrollableSheet / bottom sheet lista
}
void openLayerPanel() {
// TODO: rétegek sheet
}
void finishGeometry() {
if (!canFinishGeometry) return;
// Itt nyisd majd meg a szerkesztő sheetet:
// openFeatureEditorSheet();
// Példa:
// Get.bottomSheet(
// FeatureEditorSheet(
// tool: activeTool.value,
// points: List<LatLng>.from(draftPoints),
// ),
// isScrollControlled: true,
// );
Get.bottomSheet(
DraggableScrollableSheet(
initialChildSize: 0.52,
minChildSize: 0.35,
maxChildSize: 0.85,
snap: true,
snapSizes: const [0.35, 0.52, 0.85],
expand: false,
builder: (_, scrollCtrl) =>
MapFeatureSaveSheet(ctrl: this, scrollCtrl: scrollCtrl)),
isScrollControlled: true,
backgroundColor: Colors.transparent,
ignoreSafeArea: false);
//activeEditTool.value = MapEditTool.none;
//draftPoints.clear();
}
Future<void> finishDraft() async {
if (polygonEditorController.mode == PolygonEditorMode.line) {
print("Points number in line: ${polygonEditorController.points.length}");
print(
"1. point coords: ${polygonEditorController.points[0].latitude} - ${polygonEditorController.points[0].longitude}");
if (polygonEditorController.points.length < 2) return;
Polyline polyline = Polyline(
points: List.from(polygonEditorController.points),
color: activeEditColor.value,
strokeWidth: activeEditStrokeWidth.value,
// hitValue: (
// title: 'Purple Line',
// subtitle: 'Nothing really special here...',
// ),
);
polylineNotes.add(polyline);
// polylineNotes.refresh();
print("Points number in polylineNotes: ${polylineNotes.length}");
print(
"1. point coords of polyline: ${polyline.points[0].latitude} - ${polyline.points[0].longitude}");
polygonEditorController.clear();
activeEditTool.value = MapEditTool.none;
}
if (polygonEditorController.mode == PolygonEditorMode.polygon) {
print(
"Points number in polygon: ${polygonEditorController.points.length}");
Polygon polygon = Polygon(
points: List.from(polygonEditorController.points),
color: activeEditColor.value.withValues(alpha: activeEditOpacity.value),
borderColor: activeEditStrokeColor.value,
borderStrokeWidth: activeEditStrokeWidth.value,
label: activeEditLabel.value,
labelPlacementCalculator: _labelPlacementCalculator,
// hitValue: (
// title: 'Basic Filled Polygon',
// subtitle: 'Nothing really special here...',
);
polygonNotes.add(polygon);
//polygonNotes.refresh();
//update();
print("Points number in polygonNotes: ${polygonNotes.length}");
polygonEditorController.clear();
activeEditTool.value = MapEditTool.none;
}
}
void saveEditedPoint({required LatLng point}) {
Marker marker = Marker(
point: point,
width: 15.0,
height: 15.0,
child: Container(
width: 15.0,
height: 15.0,
decoration: BoxDecoration(
color: Colors.amber[700],
shape: BoxShape.circle,
border: Border.all(width: 1.0, color: Colors.black)),
));
pointNotes.add(marker);
activeEditTool.value = MapEditTool.none;
}
}