Save measured point to file
This commit is contained in:
parent
7e035f1414
commit
061e64fe98
414
lib/controls/geojson_parser.dart
Normal file
414
lib/controls/geojson_parser.dart
Normal file
@ -0,0 +1,414 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_map/flutter_map.dart';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
|
||||
typedef MarkerCreationCallback = Marker Function(
|
||||
LatLng point, Map<String, dynamic> properties);
|
||||
typedef CircleMarkerCreationCallback = CircleMarker Function(
|
||||
LatLng point, Map<String, dynamic> properties);
|
||||
typedef PolylineCreationCallback = Polyline Function(
|
||||
List<LatLng> points, Map<String, dynamic> properties);
|
||||
typedef PolygonCreationCallback = Polygon Function(List<LatLng> points,
|
||||
List<List<LatLng>>? holePointsList, Map<String, dynamic> properties);
|
||||
typedef FilterFunction = bool Function(Map<String, dynamic> properties);
|
||||
|
||||
/// GeoJsonParser parses the GeoJson and fills three lists of parsed objects
|
||||
/// which are defined in flutter_map package
|
||||
/// - list of [Marker]s
|
||||
/// - list of [CircleMarker]s
|
||||
/// - list of [Polyline]s
|
||||
/// - list of [Polygon]s
|
||||
///
|
||||
/// One should pass these lists when creating adequate layers in flutter_map.
|
||||
/// For details see example.
|
||||
///
|
||||
/// Currently GeoJson parser supports only FeatureCollection and not GeometryCollection.
|
||||
/// See the GeoJson Format specification at: https://www.rfc-editor.org/rfc/rfc7946
|
||||
///
|
||||
/// For creation of [Marker], [Polyline], [CircleMarker] and [Polygon] objects the default callback functions
|
||||
/// are provided which are used in case when no user-defined callback function is provided.
|
||||
/// To fully customize the [Marker], [Polyline], [CircleMarker] and [Polygon] creation one has to write his own
|
||||
/// callback functions. As a template the default callback functions can be used.
|
||||
///
|
||||
class GeoJsonParser {
|
||||
/// list of [Marker] objects created as result of parsing
|
||||
final List<Marker> markers = [];
|
||||
|
||||
/// list of [Polyline] objects created as result of parsing
|
||||
final List<Polyline> polylines = [];
|
||||
|
||||
/// list of [Polygon] objects created as result of parsing
|
||||
final List<Polygon> polygons = [];
|
||||
|
||||
/// list of [CircleMarker] objects created as result of parsing
|
||||
final List<CircleMarker> circles = [];
|
||||
|
||||
/// user defined callback function that creates a [Marker] object
|
||||
MarkerCreationCallback? markerCreationCallback;
|
||||
|
||||
/// user defined callback function that creates a [Polyline] object
|
||||
PolylineCreationCallback? polyLineCreationCallback;
|
||||
|
||||
/// user defined callback function that creates a [Polygon] object
|
||||
PolygonCreationCallback? polygonCreationCallback;
|
||||
|
||||
/// user defined callback function that creates a [Polygon] object
|
||||
CircleMarkerCreationCallback? circleMarkerCreationCallback;
|
||||
|
||||
/// default [Marker] color
|
||||
Color? defaultMarkerColor;
|
||||
|
||||
/// default [Marker] icon
|
||||
IconData? defaultMarkerIcon;
|
||||
|
||||
/// default [Polyline] color
|
||||
Color? defaultPolylineColor;
|
||||
|
||||
/// default [Polyline] stroke
|
||||
double? defaultPolylineStroke;
|
||||
|
||||
/// default [Polygon] border color
|
||||
Color? defaultPolygonBorderColor;
|
||||
|
||||
/// default [Polygon] fill color
|
||||
Color? defaultPolygonFillColor;
|
||||
|
||||
/// default [Polygon] border stroke
|
||||
double? defaultPolygonBorderStroke;
|
||||
|
||||
/// default flag if [Polygon] is filled (default is true)
|
||||
bool? defaultPolygonIsFilled;
|
||||
|
||||
/// default [CircleMarker] border color
|
||||
Color? defaultCircleMarkerColor;
|
||||
|
||||
/// default [CircleMarker] border stroke
|
||||
Color? defaultCircleMarkerBorderColor;
|
||||
|
||||
/// default flag if [CircleMarker] is filled (default is true)
|
||||
bool? defaultCircleMarkerIsFilled;
|
||||
|
||||
/// user defined callback function called when the [Marker] is tapped
|
||||
void Function(Map<String, dynamic>)? onMarkerTapCallback;
|
||||
|
||||
/// user defined callback function called when the [CircleMarker] is tapped
|
||||
void Function(Map<String, dynamic>)? onCircleMarkerTapCallback;
|
||||
|
||||
/// user defined callback function called during parse for filtering
|
||||
FilterFunction? filterFunction;
|
||||
|
||||
/// default constructor - all parameters are optional and can be set later with setters
|
||||
GeoJsonParser({
|
||||
this.markerCreationCallback,
|
||||
this.polyLineCreationCallback,
|
||||
this.polygonCreationCallback,
|
||||
this.circleMarkerCreationCallback,
|
||||
this.filterFunction,
|
||||
this.defaultMarkerColor,
|
||||
this.defaultMarkerIcon,
|
||||
this.onMarkerTapCallback,
|
||||
this.defaultPolylineColor,
|
||||
this.defaultPolylineStroke,
|
||||
this.defaultPolygonBorderColor,
|
||||
this.defaultPolygonFillColor,
|
||||
this.defaultPolygonBorderStroke,
|
||||
this.defaultPolygonIsFilled,
|
||||
this.defaultCircleMarkerColor,
|
||||
this.defaultCircleMarkerBorderColor,
|
||||
this.defaultCircleMarkerIsFilled,
|
||||
this.onCircleMarkerTapCallback,
|
||||
});
|
||||
|
||||
/// parse GeJson in [String] format
|
||||
void parseGeoJsonAsString(String g) {
|
||||
return parseGeoJson(jsonDecode(g) as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
/// set default [Marker] color
|
||||
set setDefaultMarkerColor(Color color) {
|
||||
defaultMarkerColor = color;
|
||||
}
|
||||
|
||||
/// set default [Marker] icon
|
||||
set setDefaultMarkerIcon(IconData ic) {
|
||||
defaultMarkerIcon = ic;
|
||||
}
|
||||
|
||||
/// set default [Marker] tap callback function
|
||||
void setDefaultMarkerTapCallback(
|
||||
Function(Map<String, dynamic> f) onTapFunction) {
|
||||
onMarkerTapCallback = onTapFunction;
|
||||
}
|
||||
|
||||
/// set default [CircleMarker] color
|
||||
set setDefaultCircleMarkerColor(Color color) {
|
||||
defaultCircleMarkerColor = color;
|
||||
}
|
||||
|
||||
/// set default [CircleMarker] tap callback function
|
||||
void setDefaultCircleMarkerTapCallback(
|
||||
Function(Map<String, dynamic> f) onTapFunction) {
|
||||
onCircleMarkerTapCallback = onTapFunction;
|
||||
}
|
||||
|
||||
/// set default [Polyline] color
|
||||
set setDefaultPolylineColor(Color color) {
|
||||
defaultPolylineColor = color;
|
||||
}
|
||||
|
||||
/// set default [Polyline] stroke
|
||||
set setDefaultPolylineStroke(double stroke) {
|
||||
defaultPolylineStroke = stroke;
|
||||
}
|
||||
|
||||
/// set default [Polygon] fill color
|
||||
set setDefaultPolygonFillColor(Color color) {
|
||||
defaultPolygonFillColor = color;
|
||||
}
|
||||
|
||||
/// set default [Polygon] border stroke
|
||||
set setDefaultPolygonBorderStroke(double stroke) {
|
||||
defaultPolygonBorderStroke = stroke;
|
||||
}
|
||||
|
||||
/// set default [Polygon] border color
|
||||
set setDefaultPolygonBorderColorStroke(Color color) {
|
||||
defaultPolygonBorderColor = color;
|
||||
}
|
||||
|
||||
/// set default [Polygon] setting whether polygon is filled
|
||||
set setDefaultPolygonIsFilled(bool filled) {
|
||||
defaultPolygonIsFilled = filled;
|
||||
}
|
||||
|
||||
/// main GeoJson parsing function
|
||||
void parseGeoJson(Map<String, dynamic> g) {
|
||||
// set default values if they are not specified by constructor
|
||||
markerCreationCallback ??= createDefaultMarker;
|
||||
circleMarkerCreationCallback ??= createDefaultCircleMarker;
|
||||
polyLineCreationCallback ??= createDefaultPolyline;
|
||||
polygonCreationCallback ??= createDefaultPolygon;
|
||||
filterFunction ??= defaultFilterFunction;
|
||||
defaultMarkerColor ??= Colors.red.withOpacity(0.8);
|
||||
defaultMarkerIcon ??= Icons.location_pin;
|
||||
defaultPolylineColor ??= Colors.blue.withOpacity(0.8);
|
||||
defaultPolylineStroke ??= 3.0;
|
||||
defaultPolygonBorderColor ??= Colors.black.withOpacity(0.8);
|
||||
defaultPolygonFillColor ??= Colors.black.withOpacity(0.1);
|
||||
defaultPolygonIsFilled ??= true;
|
||||
defaultPolygonBorderStroke ??= 1.0;
|
||||
defaultCircleMarkerColor ??= Colors.blue.withOpacity(0.25);
|
||||
defaultCircleMarkerBorderColor ??= Colors.black.withOpacity(0.8);
|
||||
defaultCircleMarkerIsFilled ??= true;
|
||||
|
||||
// loop through the GeoJson Map and parse it
|
||||
for (Map f in g['features'] as List) {
|
||||
String geometryType = f['geometry']['type'].toString();
|
||||
// check if this spatial object passes the filter function
|
||||
if (!filterFunction!(f['properties'] as Map<String, dynamic>)) {
|
||||
continue;
|
||||
}
|
||||
switch (geometryType) {
|
||||
case 'Point':
|
||||
{
|
||||
markers.add(
|
||||
markerCreationCallback!(
|
||||
LatLng(f['geometry']['coordinates'][1] as double,
|
||||
f['geometry']['coordinates'][0] as double),
|
||||
f['properties'] as Map<String, dynamic>),
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'Circle':
|
||||
{
|
||||
circles.add(
|
||||
circleMarkerCreationCallback!(
|
||||
LatLng(f['geometry']['coordinates'][1] as double,
|
||||
f['geometry']['coordinates'][0] as double),
|
||||
f['properties'] as Map<String, dynamic>),
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'MultiPoint':
|
||||
{
|
||||
for (final point in f['geometry']['coordinates'] as List) {
|
||||
markers.add(
|
||||
markerCreationCallback!(
|
||||
LatLng(point[1] as double, point[0] as double),
|
||||
f['properties'] as Map<String, dynamic>),
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'LineString':
|
||||
{
|
||||
final List<LatLng> lineString = [];
|
||||
for (final coords in f['geometry']['coordinates'] as List) {
|
||||
lineString.add(LatLng(coords[1] as double, coords[0] as double));
|
||||
}
|
||||
polylines.add(polyLineCreationCallback!(
|
||||
lineString, f['properties'] as Map<String, dynamic>));
|
||||
}
|
||||
break;
|
||||
case 'MultiLineString':
|
||||
{
|
||||
for (final line in f['geometry']['coordinates'] as List) {
|
||||
final List<LatLng> lineString = [];
|
||||
for (final coords in line as List) {
|
||||
lineString
|
||||
.add(LatLng(coords[1] as double, coords[0] as double));
|
||||
}
|
||||
polylines.add(polyLineCreationCallback!(
|
||||
lineString, f['properties'] as Map<String, dynamic>));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'Polygon':
|
||||
{
|
||||
final List<LatLng> outerRing = [];
|
||||
final List<List<LatLng>> holesList = [];
|
||||
int pathIndex = 0;
|
||||
for (final path in f['geometry']['coordinates'] as List) {
|
||||
final List<LatLng> hole = [];
|
||||
for (final coords in path as List<dynamic>) {
|
||||
if (pathIndex == 0) {
|
||||
// add to polygon's outer ring
|
||||
outerRing
|
||||
.add(LatLng(coords[1] as double, coords[0] as double));
|
||||
} else {
|
||||
// add it to current hole
|
||||
hole.add(LatLng(coords[1] as double, coords[0] as double));
|
||||
}
|
||||
}
|
||||
if (pathIndex > 0) {
|
||||
// add hole to the polygon's list of holes
|
||||
holesList.add(hole);
|
||||
}
|
||||
pathIndex++;
|
||||
}
|
||||
polygons.add(polygonCreationCallback!(
|
||||
outerRing, holesList, f['properties'] as Map<String, dynamic>));
|
||||
}
|
||||
break;
|
||||
case 'MultiPolygon':
|
||||
{
|
||||
for (final polygon in f['geometry']['coordinates'] as List) {
|
||||
final List<LatLng> outerRing = [];
|
||||
final List<List<LatLng>> holesList = [];
|
||||
int pathIndex = 0;
|
||||
for (final path in polygon as List) {
|
||||
List<LatLng> hole = [];
|
||||
for (final coords in path as List<dynamic>) {
|
||||
if (pathIndex == 0) {
|
||||
// add to polygon's outer ring
|
||||
outerRing
|
||||
.add(LatLng(coords[1] as double, coords[0] as double));
|
||||
} else {
|
||||
// add it to a hole
|
||||
hole.add(LatLng(coords[1] as double, coords[0] as double));
|
||||
}
|
||||
}
|
||||
if (pathIndex > 0) {
|
||||
// add to polygon's list of holes
|
||||
holesList.add(hole);
|
||||
}
|
||||
pathIndex++;
|
||||
}
|
||||
polygons.add(polygonCreationCallback!(outerRing, holesList,
|
||||
f['properties'] as Map<String, dynamic>));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/// default function for creating tappable [Marker]
|
||||
Widget defaultTappableMarker(Map<String, dynamic> properties,
|
||||
void Function(Map<String, dynamic>) onMarkerTap) {
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
onMarkerTap(properties);
|
||||
},
|
||||
child: Icon(defaultMarkerIcon, color: defaultMarkerColor),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// default callback function for creating [Marker]
|
||||
Marker createDefaultMarker(LatLng point, Map<String, dynamic> properties) {
|
||||
return Marker(
|
||||
point: point,
|
||||
child: defaultTappableMarker(properties, markerTapped),
|
||||
);
|
||||
}
|
||||
|
||||
// /// default callback function for creating [Marker]
|
||||
// Marker createDefaultMarker(LatLng point, Map<String, dynamic> properties) {
|
||||
// return Marker(
|
||||
// point: point,
|
||||
// child: MouseRegion(
|
||||
// cursor: SystemMouseCursors.click,
|
||||
// child: GestureDetector(
|
||||
// onTap: () {
|
||||
// markerTapped(properties);
|
||||
// },
|
||||
// child: Icon(defaultMarkerIcon, color: defaultMarkerColor),
|
||||
// ),
|
||||
// ),
|
||||
// width: 60,
|
||||
// height: 60,
|
||||
// );
|
||||
// }
|
||||
|
||||
/// default callback function for creating [Polygon]
|
||||
CircleMarker createDefaultCircleMarker(
|
||||
LatLng point, Map<String, dynamic> properties) {
|
||||
return CircleMarker(
|
||||
point: point,
|
||||
radius: properties["radius"].toDouble(),
|
||||
useRadiusInMeter: true,
|
||||
color: defaultCircleMarkerColor!,
|
||||
borderColor: defaultCircleMarkerBorderColor!,
|
||||
);
|
||||
}
|
||||
|
||||
/// default callback function for creating [Polyline]
|
||||
Polyline createDefaultPolyline(
|
||||
List<LatLng> points, Map<String, dynamic> properties) {
|
||||
return Polyline(
|
||||
points: points,
|
||||
color: defaultPolylineColor!,
|
||||
strokeWidth: defaultPolylineStroke!);
|
||||
}
|
||||
|
||||
/// default callback function for creating [Polygon]
|
||||
Polygon createDefaultPolygon(List<LatLng> outerRing,
|
||||
List<List<LatLng>>? holesList, Map<String, dynamic> properties) {
|
||||
return Polygon(
|
||||
points: outerRing,
|
||||
holePointsList: holesList,
|
||||
borderColor: defaultPolygonBorderColor!,
|
||||
color: defaultPolygonFillColor!,
|
||||
// isFilled: defaultPolygonIsFilled!,
|
||||
borderStrokeWidth: defaultPolygonBorderStroke!,
|
||||
);
|
||||
}
|
||||
|
||||
/// the default filter function returns always true - therefore no filtering
|
||||
bool defaultFilterFunction(Map<String, dynamic> properties) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// default callback function called when tappable [Marker] is tapped
|
||||
void markerTapped(Map<String, dynamic> map) {
|
||||
if (onMarkerTapCallback != null) {
|
||||
onMarkerTapCallback!(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -65,11 +65,16 @@ class HomeView extends GetView<HomeViewController> {
|
||||
Get.toNamed("/field_trip");
|
||||
},
|
||||
child: Text('Field trip')),
|
||||
// TextButton(
|
||||
// onPressed: () async {
|
||||
// Get.toNamed("/tracking");
|
||||
// },
|
||||
// child: Text('Tracking')),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
Get.toNamed("/tracking");
|
||||
Get.toNamed("/map");
|
||||
},
|
||||
child: Text('Tracking'))
|
||||
child: Text('Kitűzés'))
|
||||
])),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10.0),
|
||||
|
||||
@ -29,6 +29,7 @@ import 'package:terepi_seged/models/point_to_measure.dart';
|
||||
import 'package:terepi_seged/models/point_with_description_model.dart';
|
||||
import 'package:proj4dart/proj4dart.dart' as proj4;
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:terepi_seged/pages/map/presentation/views/measured_points_table_dialog.dart';
|
||||
|
||||
class MapViewController extends GetxController {
|
||||
// String gpsAddress = "E8:31:CD:14:8B:B2";
|
||||
@ -59,6 +60,8 @@ class MapViewController extends GetxController {
|
||||
DateTime.now().add(const Duration(seconds: -30));
|
||||
|
||||
NumberFormat formatEov = NumberFormat("##0,000.0", "hu-HU");
|
||||
NumberFormat formatEovZ = NumberFormat("###0.0", "hu-HU");
|
||||
NumberFormat formatAltitudeError = NumberFormat("####0.000", "hu-HU");
|
||||
NumberFormat formatEovForFile = NumberFormat("#####0.0", "hu-HU");
|
||||
NumberFormat formatWgs84Sec = NumberFormat('00.000', 'hu-HU');
|
||||
|
||||
@ -128,6 +131,8 @@ class MapViewController extends GetxController {
|
||||
// late StateMachineController riveGpsIconController;
|
||||
|
||||
late SharedPreferences prefs;
|
||||
Rx<bool> isShowPassword = false.obs;
|
||||
final passwordFieldFocusNode = FocusNode();
|
||||
|
||||
late AuthResponse authResponse;
|
||||
late Session? session;
|
||||
@ -1062,4 +1067,63 @@ class MapViewController extends GetxController {
|
||||
}
|
||||
|
||||
void updatePointStatus(int pointId) {}
|
||||
|
||||
void toggleShowPassword() {
|
||||
isShowPassword.value = !isShowPassword.value;
|
||||
if (passwordFieldFocusNode.hasPrimaryFocus) return;
|
||||
passwordFieldFocusNode.canRequestFocus = false;
|
||||
}
|
||||
|
||||
void showMeasuredPointsTableDialog() {
|
||||
Get.to(() => MeasuredPointsTableDialog(), transition: Transition.fadeIn);
|
||||
}
|
||||
|
||||
Future<List> readMeasuredPoints() async {
|
||||
var response = await Supabase.instance.client
|
||||
.from('TerepiSeged_MeasuredPoints')
|
||||
.select()
|
||||
.eq('projectId', 2)
|
||||
.order('created_at');
|
||||
|
||||
print(response);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
void SaveMeasuredPointsToFile() async {
|
||||
var pointsDirectory = await getExternalStorageDirectory();
|
||||
print(directory!.path);
|
||||
// String newPath = '';
|
||||
// List<String> folders = directory!.path.split("/");
|
||||
// for (int i = 1; i < folders.length; i++) {
|
||||
// String folder = folders[i];
|
||||
// if (folder != "Android") {
|
||||
// newPath += "/" + folder;
|
||||
// } else {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// newPath = newPath + "/TerepisSegedApp";
|
||||
// directory = Directory(newPath);
|
||||
if (!await pointsDirectory!.exists()) {
|
||||
await pointsDirectory.create(recursive: true);
|
||||
}
|
||||
var measuredPointsFile = File("${directory!.path}/measuredsPoints.csv");
|
||||
|
||||
if (await pointsDirectory.exists()) {
|
||||
if (!await measuredPointsFile.exists()) {
|
||||
measuredPointsFile.writeAsString(
|
||||
"Id;DateTime;Description;EovX;EovY;Latitude;Longitude;Altitude;Hor.Err;Vert.Err\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
var data = await readMeasuredPoints();
|
||||
|
||||
data.forEach((d) {
|
||||
print("Data EovX: ${d['EovX']}");
|
||||
print("Data EovY: $d[EovY]");
|
||||
});
|
||||
|
||||
print('Number of data: ${data.length}');
|
||||
}
|
||||
}
|
||||
|
||||
@ -458,14 +458,7 @@ class MapView extends GetView<MapViewController> {
|
||||
FloatingActionButton(
|
||||
onPressed: () {
|
||||
// controller.isMapMoveToCenter();
|
||||
// controller.addMeasuredPoint();
|
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
|
||||
content: Text(
|
||||
"Fejlesztlés alatt",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
backgroundColor: Colors.black54,
|
||||
));
|
||||
controller.showMeasuredPointsTableDialog();
|
||||
},
|
||||
heroTag: 'Database test',
|
||||
tooltip: 'Pont bemérése',
|
||||
|
||||
@ -0,0 +1,124 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:terepi_seged/pages/map/presentation/controllers/map_controller.dart';
|
||||
|
||||
class MeasuredPointsTableDialog extends StatelessWidget {
|
||||
final controller = Get.find<MapViewController>();
|
||||
MeasuredPointsTableDialog({super.key});
|
||||
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.only(top: 20.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(children: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
},
|
||||
icon: const Icon(Icons.close)),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
controller.SaveMeasuredPointsToFile();
|
||||
},
|
||||
icon: const Icon(Icons.save)),
|
||||
]),
|
||||
TextButton(
|
||||
style: ButtonStyle(
|
||||
overlayColor:
|
||||
MaterialStateProperty.all(Colors.transparent)),
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
},
|
||||
child: const Text(
|
||||
'Bezár',
|
||||
style: TextStyle(color: Colors.blue, fontSize: 14.0),
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 40.0),
|
||||
child: Text(
|
||||
'Bemért pontok',
|
||||
style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
Expanded(
|
||||
child: FutureBuilder<List<dynamic>>(
|
||||
future: controller.readMeasuredPoints(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return Center(child: CircularProgressIndicator());
|
||||
}
|
||||
|
||||
if (snapshot.hasError) {
|
||||
return Center(
|
||||
child: Text(
|
||||
snapshot.error.toString(),
|
||||
),
|
||||
);
|
||||
}
|
||||
if (!snapshot.hasData) {
|
||||
return const Center(
|
||||
child: Text("No Data available.\n Create new Data"));
|
||||
}
|
||||
// print(snapshot.data);
|
||||
// return const Center(child: Text("Data available."));
|
||||
return ListView.builder(
|
||||
itemCount: snapshot.data!.length,
|
||||
shrinkWrap: true,
|
||||
itemBuilder: (context, int index) {
|
||||
var data = snapshot.data![index];
|
||||
print("snapshot data:");
|
||||
print(data);
|
||||
return ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: const Color(0xff764abc),
|
||||
child: Text((index + 1).toString())),
|
||||
title: Text(data['pointNumber'].toString(),
|
||||
style: TextStyle(fontWeight: FontWeight.bold)),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(data['description'],
|
||||
style: TextStyle(
|
||||
fontStyle: FontStyle.italic,
|
||||
color: Colors.grey.shade700)),
|
||||
Text(
|
||||
"EovX: ${controller.formatEov.format(data['eovY'])} - EovY: ${controller.formatEov.format(data['eovX'])}",
|
||||
style: TextStyle(
|
||||
fontStyle: FontStyle.italic,
|
||||
color: Colors.grey.shade400)),
|
||||
Text(
|
||||
"EovZ: ${controller.formatEovZ.format(data['altitude'] - data['poleHeight'])} (m)",
|
||||
style: TextStyle(
|
||||
fontStyle: FontStyle.italic,
|
||||
color: Colors.grey.shade400)),
|
||||
Text(
|
||||
"H.hiba: ${controller.formatAltitudeError.format(data['horizontalError'])} (m) - V.hiba: ${controller.formatAltitudeError.format(data['verticalError'])} (m)",
|
||||
style: TextStyle(
|
||||
fontStyle: FontStyle.italic,
|
||||
color: Colors.grey.shade400)),
|
||||
],
|
||||
));
|
||||
});
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -330,26 +330,54 @@ class SettingsDialog extends StatelessWidget {
|
||||
height: 40,
|
||||
child: TextField(
|
||||
controller: controller.ntripUsernameController,
|
||||
decoration: const InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
enableSuggestions: false,
|
||||
autocorrect: false,
|
||||
decoration: InputDecoration(
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
isDense: true,
|
||||
filled: true,
|
||||
fillColor: Colors.grey.shade300,
|
||||
border: OutlineInputBorder(
|
||||
borderSide: BorderSide.none,
|
||||
borderRadius: BorderRadius.circular(12)),
|
||||
labelText: 'Felhasználónév',
|
||||
icon: Icon(Icons.account_circle_rounded)),
|
||||
prefixIcon: Icon(Icons.account_circle_rounded)),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
obscureText: true,
|
||||
enableSuggestions: false,
|
||||
autocorrect: false,
|
||||
controller: controller.ntripPasswordController,
|
||||
decoration: const InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: 'Jelszó',
|
||||
icon: Icon(
|
||||
Icons.lock,
|
||||
)),
|
||||
Obx(
|
||||
() => SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
keyboardType: TextInputType.visiblePassword,
|
||||
obscureText: !controller.isShowPassword.value,
|
||||
focusNode: controller.passwordFieldFocusNode,
|
||||
enableSuggestions: false,
|
||||
autocorrect: false,
|
||||
controller: controller.ntripPasswordController,
|
||||
decoration: InputDecoration(
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
isDense: true,
|
||||
filled: true,
|
||||
fillColor: Colors.grey.shade300,
|
||||
border: OutlineInputBorder(
|
||||
borderSide: BorderSide.none,
|
||||
borderRadius: BorderRadius.circular(12)),
|
||||
labelText: 'Jelszó',
|
||||
prefixIcon: Icon(
|
||||
Icons.lock_rounded,
|
||||
size: 24,
|
||||
),
|
||||
suffixIcon: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0, 0, 4, 0),
|
||||
child: GestureDetector(
|
||||
onTap: controller.toggleShowPassword,
|
||||
child: Icon(
|
||||
controller.isShowPassword.value
|
||||
? Icons.visibility_rounded
|
||||
: Icons.visibility_off_rounded,
|
||||
size: 24)))),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20)
|
||||
|
||||
@ -22,6 +22,7 @@ import 'package:path_provider/path_provider.dart';
|
||||
import 'package:permission_handler/permission_handler.dart'
|
||||
as permission_handler;
|
||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
import 'package:terepi_seged/controls/geojson_parser.dart';
|
||||
import 'package:terepi_seged/eov/convert_coordinate.dart';
|
||||
import 'package:terepi_seged/eov/eov.dart';
|
||||
import 'package:terepi_seged/gnss_sentences/gngga.dart';
|
||||
@ -116,7 +117,7 @@ class NavigationViewController extends GetxController {
|
||||
late proj4.Projection eovProj, wgsProj;
|
||||
RxBool mapIsInitialized = false.obs;
|
||||
|
||||
// GeoJsonParser parser = GeoJsonParser(defaultMarkerColor: Colors.yellow);
|
||||
GeoJsonParser parser = GeoJsonParser(defaultMarkerColor: Colors.yellow);
|
||||
|
||||
final CollectionReference _vibratorTracker =
|
||||
FirebaseFirestore.instance.collection('vibratorTracker');
|
||||
@ -1028,10 +1029,10 @@ class NavigationViewController extends GetxController {
|
||||
}
|
||||
if (await file!.exists()) {
|
||||
String data = await file.readAsString();
|
||||
// parser.defaultPolylineColor = Colors.orangeAccent;
|
||||
// parser.defaultPolylineStroke = 5.0;
|
||||
// parser.parseGeoJsonAsString(data);
|
||||
// pathLayer = parser.polylines;
|
||||
parser.defaultPolylineColor = Colors.orangeAccent;
|
||||
parser.defaultPolylineStroke = 5.0;
|
||||
parser.parseGeoJsonAsString(data);
|
||||
pathLayer = parser.polylines;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -256,8 +256,8 @@ class NavigationView extends GetView<NavigationViewController> {
|
||||
PolylineLayer(polylines: controller.pathLayer),
|
||||
MarkerLayer(
|
||||
markers: controller.pointsToMeasureMarker),
|
||||
// PolylineLayer(
|
||||
// polylines: controller.parser.polylines),
|
||||
PolylineLayer(
|
||||
polylines: controller.parser.polylines),
|
||||
PolyWidgetLayer(
|
||||
polyWidgets: controller.pointsToMeasureLabel),
|
||||
],
|
||||
|
||||
@ -31,6 +31,7 @@ dependencies:
|
||||
flutter_map: ^8.2.2
|
||||
flutter_map_polygon_editor: ^0.1.2
|
||||
flutter_bluetooth_serial: ^0.4.0
|
||||
flutter_map_geojson2: ^1.0.2
|
||||
get: ^4.7.2
|
||||
latlong2: ^0.9.1
|
||||
nmea: ^3.3.2
|
||||
@ -66,6 +67,7 @@ dependencies:
|
||||
widget_zoom: ^0.0.4
|
||||
supabase_flutter: ^2.10.2
|
||||
appwrite: ^20.0.0
|
||||
# share_plus: ^12.0.1
|
||||
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
Loading…
Reference in New Issue
Block a user