Start to implement functions: adding point, polyline and polygon to map

This commit is contained in:
torok.istvan 2025-10-11 09:26:59 +02:00
parent e986cccdd6
commit e8a6e4464a
7 changed files with 295 additions and 4 deletions

View File

@ -1,7 +1,7 @@
import 'package:get/get.dart';
import 'package:terepi_seged/pages/field_trip/presentations/controllers/field_trip_controller.dart';
class HomeBinding extends Bindings {
class FieldTripBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut(() => FieldTripController());

View File

@ -1,3 +1,162 @@
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_map_polygon_editor/polygon_editor/polygon_editor_controller.dart';
import 'package:get/get.dart';
import 'package:latlong2/latlong.dart';
class FieldTripController extends GetxController {}
class FieldTripController extends GetxController {
RxBool mapIsInitialized = false.obs;
RxBool mapInEditorMode = false.obs;
RxBool mapInPointEditorMode = false.obs;
final pointNotes = <Marker>[].obs;
final polylineNotes = <Polyline<Object>>[].obs;
final polygonNotes = <Polygon<Object>>[].obs;
late final MapController mapController;
late final MapOptions mapOptions;
late final PolygonEditorController polygonEditorController;
final PolygonLabelPlacementCalculator _labelPlacementCalculator =
const PolygonLabelPlacementCalculator.centroid();
@override
void onInit() async {
// TODO: implement onInit
super.onInit();
mapOptions = MapOptions(
onLongPress: (tapPosition, point) {
if (mapInEditorMode.value) {
polygonEditorController.addPoint(point);
}
if (mapInPointEditorMode.value) {
savePointNote(point: point);
}
},
keepAlive: true,
);
polylineNotes.add(
Polyline(
points: [
const LatLng(47.65, 19.00),
const LatLng(47.64, 19.02),
const LatLng(47.69, 19.22),
],
strokeWidth: 8,
color: const Color.fromARGB(255, 227, 238, 71),
hitValue: (
title: 'Purple Line',
subtitle: 'Nothing really special here...',
),
),
);
polygonEditorController =
PolygonEditorController(mode: PolygonEditorMode.polygon);
mapController = MapController();
mapIsInitialized.value = true;
}
@override
void dispose() {
// TODO: implement dispose
polygonEditorController.dispose();
super.dispose();
}
void cancelEditorController() {
polygonEditorController.clear();
mapInEditorMode.value = false;
}
void startPolygonEdition() {
polygonEditorController.clear();
polygonEditorController.setMode(PolygonEditorMode.polygon);
mapInEditorMode.value = true;
}
void startPolylineEdition() {
polygonEditorController.clear();
polygonEditorController.setMode(PolygonEditorMode.line);
mapInEditorMode.value = true;
}
void startPointEdition() {
mapInPointEditorMode.value = true;
}
void saveNote() {
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}");
Polyline polyline = Polyline(
points: polygonEditorController.points,
color: Colors.red,
strokeWidth: 8,
// 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();
mapInEditorMode.value = false;
}
if (polygonEditorController.mode == PolygonEditorMode.polygon) {
print(
"Points number in polygon: ${polygonEditorController.points.length}");
Polygon polygon = Polygon(
points: polygonEditorController.points,
color: Colors.purple,
borderColor: Colors.yellow,
borderStrokeWidth: 4,
label: 'Label!',
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();
mapInEditorMode.value = false;
}
}
void savePointNote({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);
pointNotes.refresh();
update();
mapInPointEditorMode.value = false;
}
}

View File

@ -1,4 +1,8 @@
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_map_location_marker/flutter_map_location_marker.dart';
import 'package:flutter_map_polygon_editor/polygon_editor.dart';
import 'package:get/get.dart';
import 'package:latlong2/latlong.dart';
import 'package:terepi_seged/pages/field_trip/presentations/controllers/field_trip_controller.dart';
import 'package:flutter/material.dart';
@ -7,6 +11,103 @@ class FieldTripView extends GetView<FieldTripController> {
@override
Widget build(BuildContext context) {
return Container();
return Scaffold(
resizeToAvoidBottomInset: false,
extendBody: true,
appBar: AppBar(
title: const Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Terepbejárás'),
],
)),
body: Column(
children: [
Expanded(
child: Stack(children: [
Obx(() => controller.mapIsInitialized.value
? FlutterMap(
mapController: controller.mapController,
options: controller.mapOptions,
children: [
TileLayer(
urlTemplate:
'http://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}',
subdomains: const ['mt0', 'mt1', 'mt2', 'mt3'],
maxNativeZoom: 18,
),
CurrentLocationLayer(
alignPositionOnUpdate: AlignOnUpdate.once,
),
MarkerLayer(markers: controller.pointNotes),
PolylineLayer(
polylines: controller.polylineNotes,
),
PolygonLayer(
polygons: controller.polygonNotes,
useAltRendering: true,
),
// PolylineLayer(polylines: [
// Polyline(
// points: [
// const LatLng(47.65, 19.00),
// const LatLng(47.64, 19.02),
// const LatLng(47.69, 19.22),
// ],
// strokeWidth: 8,
// color: const Color(0xFF60399E),
// hitValue: (
// title: 'Purple Line',
// subtitle: 'Nothing really special here...',
// ),
// ),
// ]),
PolygonEditor(
controller: controller.polygonEditorController,
throttleDuration: Duration.zero)
],
)
: const Center(child: CircularProgressIndicator())),
Positioned(
bottom: 3,
right: 3,
child: Row(
children: [
IconButton.filled(
iconSize: 32,
onPressed: () {
controller.startPointEdition();
},
icon: const Icon(Icons.flag)),
IconButton.filled(
iconSize: 32,
onPressed: () {
controller.startPolylineEdition();
},
icon: const Icon(Icons.polyline)),
IconButton.filled(
iconSize: 32,
onPressed: () {
controller.startPolygonEdition();
},
icon: const Icon(Icons.border_outer)),
IconButton.filled(
iconSize: 32,
onPressed: () {
controller.saveNote();
},
icon: const Icon(Icons.done)),
IconButton.filled(
iconSize: 32,
onPressed: () {
controller.cancelEditorController();
},
icon: const Icon(Icons.cancel))
],
))
]))
],
),
);
}
}

View File

@ -55,6 +55,22 @@ class HomeView extends GetView<HomeViewController> {
// child: const Text('RTCM teszt'))
],
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
TextButton(
onPressed: () async {
Get.toNamed("/field_trip");
},
child: Text('Field trip')),
TextButton(
onPressed: () async {
Get.toNamed("/tracking");
},
child: Text('Tracking'))
])),
Padding(
padding: const EdgeInsets.only(top: 10.0),
child: Row(

View File

@ -1,6 +1,8 @@
import 'package:get/get.dart';
import 'package:terepi_seged/pages/bleutooth/bindings/bluetooth_bindings.dart';
import 'package:terepi_seged/pages/bleutooth/presentation/views/bluetooth_test_view.dart';
import 'package:terepi_seged/pages/field_trip/bindings/field_trip_bindings.dart';
import 'package:terepi_seged/pages/field_trip/presentations/views/fiels_trip_view.dart';
import 'package:terepi_seged/pages/home/bindings/home_bindings.dart';
import 'package:terepi_seged/pages/home/presentation/views/home_view.dart';
import 'package:terepi_seged/pages/map/bindings/map_bindings.dart';
@ -20,6 +22,8 @@ import 'package:terepi_seged/pages/socket_test/bindings/socket_test_bindings.dar
import 'package:terepi_seged/pages/socket_test/presentation/views/socket_test_view.dart';
import 'package:terepi_seged/pages/start/bindings/start_page_bindings.dart';
import 'package:terepi_seged/pages/start/presentation/views/start_page.dart';
import 'package:terepi_seged/pages/tracking/bindings/tracking_bindings.dart';
import 'package:terepi_seged/pages/tracking/presentation/views/tracking_view.dart';
import '../pages/map_test/bindings/map_test_bindings.dart';
import '../pages/map_test/presentation/views/map_test_view.dart';
@ -79,6 +83,14 @@ class AppPages {
GetPage(
name: Routes.MAPSURVEY,
binding: MapSurveyBinding(),
page: () => const MapSurveyView())
page: () => const MapSurveyView()),
GetPage(
name: Routes.FIELDTRIP,
binding: FieldTripBinding(),
page: () => const FieldTripView()),
GetPage(
name: Routes.TRACKING,
binding: TrackingBinding(),
page: () => const TrackingView())
];
}

View File

@ -15,6 +15,8 @@ abstract class Routes {
static const PROPERTYLIST = '/property_list';
static const MEASUREDDATA = '/measured_data';
static const MAPSURVEY = '/map_survey';
static const FIELDTRIP = '/field_trip';
static const TRACKING = '/tracking';
static const MAPADDPOINTDIALOG = "/map_add_point_dialog";
}

View File

@ -29,6 +29,7 @@ environment:
dependencies:
cupertino_icons: ^1.0.8
flutter_map: ^8.2.2
flutter_map_polygon_editor: ^0.1.2
flutter_bluetooth_serial: ^0.4.0
get: ^4.7.2
latlong2: ^0.9.1