feat: partial broken guesture detection

This commit is contained in:
Yandrik 2024-04-20 21:14:11 +02:00
parent be359980bb
commit b7487fc25e
9 changed files with 3670 additions and 1369 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,6 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_map/flutter_map.dart'; import 'package:flutter_map/flutter_map.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:latlong2/latlong.dart'; import 'package:latlong2/latlong.dart';
@ -7,7 +9,7 @@ import 'package:uninav/data/geo/model.dart';
import 'package:uninav/map.dart'; import 'package:uninav/map.dart';
import 'package:uninav/util/geomath.dart'; import 'package:uninav/util/geomath.dart';
List<Widget> renderLevel(int level) { List<Widget> renderLevel(int level, {LayerHitNotifier? hitNotifier}) {
return <Widget>[ return <Widget>[
LevelLayer( LevelLayer(
filter: (feature) => filter: (feature) =>
@ -18,55 +20,58 @@ List<Widget> renderLevel(int level) {
points: pts, points: pts,
color: Colors.orange.withOpacity(0.2), color: Colors.orange.withOpacity(0.2),
borderColor: Colors.orange, borderColor: Colors.orange,
isFilled: true, borderStrokeWidth: 2,
borderStrokeWidth: 1, hitValue: feature,
), ),
) )
.unwrap(), .unwrap(),
markerConstructor: (feature) => Marker( markerConstructor: (feature) => Marker(
width: 150, width: 50,
height: 60, height: 20,
point: feature.getPoint().unwrap(), point: feature.getPoint().unwrap(),
builder: (cx) => Center( child: Column(
child: Column( children: [
children: [ Icon(
Icon( Icons.class_,
Icons.class_, color: Colors.black,
color: Colors.black, ),
), Text('${feature.name}'),
Text('${feature.name}'), ],
],
),
), ),
)), alignment: Alignment.center,
),
notifier: hitNotifier),
LevelLayer( LevelLayer(
filter: (feature) => feature.level == level && feature.type is Room, filter: (feature) => feature.level == level && feature.type is Room,
polyConstructor: (feature) => feature polyConstructor: (feature) => feature
.getPolygon( .getPolygon(
constructor: (pts) => Polygon( constructor: (pts) => Polygon(
points: pts, points: pts,
color: Colors.green.withOpacity(0.2), color: Colors.green.withOpacity(1.2),
borderColor: Colors.green, borderColor: Colors.green,
isFilled: true, borderStrokeWidth: 2,
borderStrokeWidth: 1, hitValue: feature,
), ),
) )
.unwrap(), .unwrap(),
notifier: hitNotifier,
), ),
LevelLayer( LevelLayer(
filter: (feature) => feature.level == level && feature.type is Door, filter: (feature) => feature.level == level && feature.type is Door,
markerConstructor: (feature) { markerConstructor: (feature) {
final point = feature.getPoint().unwrap(); final point = feature.getPoint().unwrap();
return Marker( return Marker(
width: 20, width: 21,
height: 20, height: 21,
point: point, point: point,
builder: (ctx) => const Icon( child: const Icon(
Icons.door_front_door, Icons.door_front_door,
color: Colors.brown, color: Colors.brown,
), ),
alignment: Alignment.center,
); );
}, },
notifier: hitNotifier,
), ),
LevelLayer( LevelLayer(
filter: (feature) => feature.level == level && feature.type is Toilet, filter: (feature) => feature.level == level && feature.type is Toilet,
@ -93,16 +98,17 @@ List<Widget> renderLevel(int level) {
final point = feature.getPoint().unwrap(); final point = feature.getPoint().unwrap();
return Marker( return Marker(
width: 20, width: 21,
height: 20, height: 21,
point: point, point: point,
builder: (ctx) => Icon( child: Icon(
icon, icon,
color: Colors.purple, color: Colors.purple,
), ),
rotateAlignment: Alignment.center, alignment: Alignment.center,
); );
}, },
notifier: hitNotifier,
), ),
LevelLayer( LevelLayer(
filter: (feature) => filter: (feature) =>
@ -111,15 +117,17 @@ List<Widget> renderLevel(int level) {
markerConstructor: (feature) { markerConstructor: (feature) {
final point = feature.getPoint().unwrap(); final point = feature.getPoint().unwrap();
return Marker( return Marker(
width: 20, width: 21,
height: 20, height: 21,
point: point, point: point,
builder: (ctx) => Icon( child: Icon(
Icons.stairs_outlined, Icons.stairs_outlined,
color: Colors.deepPurple.shade300, color: Colors.deepPurple.shade300,
), ),
alignment: Alignment.center,
); );
}, },
notifier: hitNotifier,
), ),
LevelLayer( LevelLayer(
filter: (feature) => filter: (feature) =>
@ -128,15 +136,17 @@ List<Widget> renderLevel(int level) {
markerConstructor: (feature) { markerConstructor: (feature) {
final point = feature.getPoint().unwrap(); final point = feature.getPoint().unwrap();
return Marker( return Marker(
width: 20, width: 21,
height: 20, height: 21,
point: point, point: point,
builder: (ctx) => const Icon( child: const Icon(
Icons.elevator_outlined, Icons.elevator_outlined,
color: Colors.deepPurple, color: Colors.deepPurple,
), ),
alignment: Alignment.center,
); );
}, },
notifier: hitNotifier,
), ),
]; ];
} }
@ -147,6 +157,7 @@ class LevelLayer extends StatelessWidget {
final Marker Function(LatLng, String)? polyCenterMarkerConstructor; final Marker Function(LatLng, String)? polyCenterMarkerConstructor;
final Marker Function(Feature)? markerConstructor; final Marker Function(Feature)? markerConstructor;
final int? level; final int? level;
final LayerHitNotifier? notifier;
const LevelLayer({ const LevelLayer({
this.level, this.level,
@ -154,6 +165,7 @@ class LevelLayer extends StatelessWidget {
this.polyConstructor, this.polyConstructor,
this.polyCenterMarkerConstructor, this.polyCenterMarkerConstructor,
this.markerConstructor, this.markerConstructor,
this.notifier,
super.key, super.key,
}); });
@ -172,7 +184,15 @@ class LevelLayer extends StatelessWidget {
if (polyConstructor != null) { if (polyConstructor != null) {
filteredPolygons.add(polyConstructor!(feature)); filteredPolygons.add(polyConstructor!(feature));
} else { } else {
filteredPolygons.add(feature.getPolygon().unwrap()); filteredPolygons.add(feature
.getPolygon(
constructor: (points) => Polygon(
points: points,
borderColor: Colors.black26,
borderStrokeWidth: 2.0,
hitValue: feature,
))
.unwrap());
} }
// calculate polygon center // calculate polygon center
@ -186,7 +206,7 @@ class LevelLayer extends StatelessWidget {
width: 100, width: 100,
height: 100, height: 100,
point: center, point: center,
builder: (cx) => Center( child: Center(
child: Text( child: Text(
feature.name, feature.name,
style: const TextStyle( style: const TextStyle(
@ -195,6 +215,7 @@ class LevelLayer extends StatelessWidget {
), ),
), ),
), ),
alignment: Alignment.center,
)); ));
} }
} else if (feature.isPoint()) { } else if (feature.isPoint()) {
@ -206,7 +227,7 @@ class LevelLayer extends StatelessWidget {
width: 100, width: 100,
height: 100, height: 100,
point: point, point: point,
builder: (cx) => Center( child: Center(
child: Text( child: Text(
feature.name, feature.name,
style: const TextStyle( style: const TextStyle(
@ -215,6 +236,7 @@ class LevelLayer extends StatelessWidget {
), ),
), ),
), ),
alignment: Alignment.center,
)); ));
} }
} }
@ -226,28 +248,39 @@ class LevelLayer extends StatelessWidget {
// print(filteredPolygons[0].points[0]); // print(filteredPolygons[0].points[0]);
// print(myMapController.features.length); // print(myMapController.features.length);
// filteredPolygons.forEach((element) {
// print(element.hitValue);
// });
final List<Widget> widgets = []; final List<Widget> widgets = [];
if (filteredPolygons.isNotEmpty) { if (filteredPolygons.isNotEmpty) {
if (polyConstructor != null) { if (polyConstructor != null) {
widgets.add(PolygonLayer(polygons: filteredPolygons)); widgets.add(TranslucentPointer(
child: PolygonLayer(
polygons: filteredPolygons,
hitNotifier: notifier,
),
));
} else { } else {
widgets.add(PolygonLayer( widgets.add(TranslucentPointer(
polygons: filteredPolygons child: PolygonLayer(
.map((poly) => Polygon( polygons: filteredPolygons,
points: poly.points, hitNotifier: notifier,
borderColor: Colors.black26, ),
borderStrokeWidth: 2.0, ));
))
.toList()));
} }
widgets.add(MarkerLayer( widgets.add(TranslucentPointer(
markers: polygonCenterMarkers, child: MarkerLayer(
rotate: true, markers: polygonCenterMarkers,
rotate: true,
),
)); ));
} }
if (filteredMarkers.isNotEmpty) { if (filteredMarkers.isNotEmpty) {
widgets.add(MarkerLayer(markers: filteredMarkers, rotate: true)); widgets.add(TranslucentPointer(
child: MarkerLayer(markers: filteredMarkers, rotate: true),
));
} }
return Stack(children: widgets); return Stack(children: widgets);

View File

@ -1,7 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:anyhow/anyhow.dart'; import 'package:anyhow/anyhow.dart';
import 'package:geojson/geojson.dart'; import 'package:geojson_vi/geojson_vi.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:uninav/data/geo/model.dart'; import 'package:uninav/data/geo/model.dart';
import 'package:uninav/data/geo/parser.dart'; import 'package:uninav/data/geo/parser.dart';
@ -46,14 +46,17 @@ class MyMapController extends GetxController {
final featuresList = <Feature>[]; final featuresList = <Feature>[];
final geojson = GeoJson(); print('doing');
final geojson = GeoJSONFeatureCollection.fromJSON(geoJsonString);
await geojson.parse(geoJsonString); print('done');
for (final feature in geojson.features) { for (final feature in geojson.features) {
print(feature);
print(feature?.properties);
if (feature == null) continue;
print(feature.properties); print(feature.properties);
final parsed = final parsed = parseFeature(
parseFeature(feature.properties ?? <String, dynamic>{}, feature); feature.properties ?? <String, dynamic>{}, feature.geometry);
if (parsed case Ok(:final ok)) { if (parsed case Ok(:final ok)) {
featuresList.add(ok); featuresList.add(ok);
} }

View File

@ -2,7 +2,7 @@ import 'package:anyhow/anyhow.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart'; import 'package:flutter_map/flutter_map.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:geojson/geojson.dart'; import 'package:geojson_vi/geojson_vi.dart';
import 'package:latlong2/latlong.dart'; import 'package:latlong2/latlong.dart';
part 'model.freezed.dart'; part 'model.freezed.dart';
@ -15,27 +15,30 @@ class Feature with _$Feature {
required String name, required String name,
required FeatureType type, required FeatureType type,
String? description, String? description,
required dynamic geometry, required GeoJSONGeometry geometry,
int? level, int? level,
}) = _Feature; }) = _Feature;
bool isPolygon() { bool isPolygon() {
return geometry is GeoJsonFeature<GeoJsonPolygon>; return geometry is GeoJSONPolygon;
} }
bool isPoint() { bool isPoint() {
return geometry is GeoJsonFeature<GeoJsonPoint>; return geometry is GeoJSONPoint;
} }
Result<Polygon> getPolygon({Polygon Function(List<LatLng>)? constructor}) { Result<Polygon> getPolygon({Polygon Function(List<LatLng>)? constructor}) {
if (isPolygon()) { if (isPolygon()) {
constructor ??= (pts) => Polygon( constructor ??= (pts) => Polygon(
points: pts, borderColor: Colors.black26, borderStrokeWidth: 2.0); points: pts,
final polygon = geometry as GeoJsonFeature<GeoJsonPolygon>; borderColor: Colors.black26,
borderStrokeWidth: 2.0,
);
final polygon = geometry as GeoJSONPolygon;
// print(polygon.geometry!.geoSeries[0].geoPoints); // print(polygon.geometry!.geoSeries[0].geoPoints);
final points = polygon.geometry!.geoSeries[0].geoPoints final points =
.map((e) => LatLng(e.latitude, e.longitude)) // polygon.coordinates[0].map((e) => LatLng(e[0], e[1])).toList();
.toList(); polygon.coordinates[0].map((e) => LatLng(e[1], e[0])).toList();
// print(points); // print(points);
return Ok(constructor(points)); return Ok(constructor(points));
@ -46,9 +49,8 @@ class Feature with _$Feature {
Result<LatLng> getPoint() { Result<LatLng> getPoint() {
if (isPoint()) { if (isPoint()) {
final point = geometry as GeoJsonFeature<GeoJsonPoint>; final point = geometry as GeoJSONPoint;
return Ok(LatLng(point.geometry!.geoPoint.latitude, return Ok(LatLng(point.coordinates[1], point.coordinates[0]));
point.geometry!.geoPoint.longitude));
} else { } else {
return bail("Feature Geometry is not a Point"); return bail("Feature Geometry is not a Point");
} }

View File

@ -1,10 +1,10 @@
import 'package:anyhow/anyhow.dart'; import 'package:anyhow/anyhow.dart';
import 'package:geojson/geojson.dart'; import 'package:geojson_vi/geojson_vi.dart';
import 'package:uninav/data/geo/model.dart'; import 'package:uninav/data/geo/model.dart';
import 'package:yaml/yaml.dart'; import 'package:yaml/yaml.dart';
Result<Feature> parseFeature( Result<Feature> parseFeature(
Map<String, dynamic> properties, dynamic geometry) { Map<String, dynamic> properties, GeoJSONGeometry geometry) {
final name = properties['name'] as String?; final name = properties['name'] as String?;
final description_yaml = properties['description'] as String? ?? ''; final description_yaml = properties['description'] as String? ?? '';
final layer = properties['layer'] as String?; final layer = properties['layer'] as String?;

View File

@ -2,12 +2,12 @@ import 'package:anim_search_bar/anim_search_bar.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_map/flutter_map.dart'; import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_map/plugin_api.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:latlong2/latlong.dart'; import 'package:latlong2/latlong.dart';
import 'package:rust_core/slice.dart'; import 'package:rust_core/slice.dart';
import 'package:uninav/components/drawer.dart'; import 'package:uninav/components/drawer.dart';
import 'package:uninav/components/hamburger_menu.dart'; import 'package:uninav/components/hamburger_menu.dart';
import 'package:uninav/components/map_render_level.dart';
import 'package:uninav/controllers/map_controller.dart'; import 'package:uninav/controllers/map_controller.dart';
import 'package:uninav/data/geo/model.dart'; import 'package:uninav/data/geo/model.dart';
import 'package:uninav/util/geomath.dart'; import 'package:uninav/util/geomath.dart';
@ -18,6 +18,7 @@ class MapPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final LayerHitNotifier hitNotifier = ValueNotifier(null);
return Scaffold( return Scaffold(
drawer: MyDrawer(), drawer: MyDrawer(),
appBar: AppBar( appBar: AppBar(
@ -51,64 +52,95 @@ class MapPage extends StatelessWidget {
FlutterMap( FlutterMap(
mapController: MapController(), mapController: MapController(),
options: MapOptions( options: MapOptions(
center: LatLng(48.422766, 9.9564), initialCenter: const LatLng(48.422766, 9.9564),
zoom: 16.0, initialZoom: 16.0,
// camera constraints // camera constraints
maxZoom: 19, maxZoom: 19,
onTap: (tapPosition, latlng) => print(tapPosition),
), ),
children: [ children: [
TileLayer( TileLayer(
urlTemplate: "https://tile.openstreetmap.org/{z}/{x}/{y}.png", urlTemplate: "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
maxZoom: 19, maxZoom: 19,
), ),
GestureDetector(
onTap: () {
print("tap");
final LayerHitResult? hit = hitNotifier.value;
if (hit == null) {
return;
}
// buildings print("not null");
LevelLayer( print(hit.coordinate);
filter: (feature) => feature.type is Building, hit.printInfo();
), print(hit.hitValues);
// public transport for (final hitValue in hit.hitValues) {
LevelLayer( print(hitValue);
filter: (feature) => }
feature.level == null && feature.type is PublicTransport, // Handle the hit, which in this case is a tap
polyCenterMarkerConstructor: (center, name) => Marker( // For example, see the example in Hit Handling (below)
width: 100, },
height: 100, child: MouseRegion(
point: center, cursor: SystemMouseCursors.click,
builder: (cx) => const Center( child: Stack(
child: Icon( children: [
Icons.train, // buildings
color: Colors.black, LevelLayer(
), filter: (feature) => feature.type is Building,
notifier: hitNotifier,
),
// public transport
LevelLayer(
filter: (feature) =>
feature.level == null &&
feature.type is PublicTransport,
polyCenterMarkerConstructor: (center, name) => Marker(
width: 100,
height: 100,
point: center,
child: const Icon(
Icons.train,
color: Colors.black,
),
alignment: Alignment.center,
),
polyConstructor: (feature) => feature
.getPolygon(
constructor: (pts) => Polygon(
points: pts,
color: Colors.green.withOpacity(0.2),
borderColor: Colors.green,
borderStrokeWidth: 1,
hitValue: feature,
))
.unwrap(),
notifier: hitNotifier,
),
// current level
Obx(
() => Stack(
children: renderLevel(
Get.find<MyMapController>()
.currentLevel
.value,
hitNotifier: hitNotifier)),
),
// RichAttributionWidget(attributions: [
// TextSourceAttribution(
// 'OpenStreetMap contributors',
// onTap: () =>
// launchUrl(Uri.parse('https://openstreetmap.org/copyright')),
// )
// ]),
],
), ),
), ),
polyConstructor: (feature) => feature
.getPolygon(
constructor: (pts) => Polygon(
points: pts,
color: Colors.green.withOpacity(0.2),
borderColor: Colors.green,
isFilled: true,
borderStrokeWidth: 1,
))
.unwrap(),
), ),
// current level
Obx(
() => Stack(
children: renderLevel(
Get.find<MyMapController>().currentLevel.value),
),
)
// RichAttributionWidget(attributions: [
// TextSourceAttribution(
// 'OpenStreetMap contributors',
// onTap: () =>
// launchUrl(Uri.parse('https://openstreetmap.org/copyright')),
// )
// ]),
], ],
), ),
Positioned( Positioned(
@ -152,251 +184,3 @@ class MapPage extends StatelessWidget {
)); ));
} }
} }
List<Widget> renderLevel(int level) {
return <Widget>[
LevelLayer(
filter: (feature) =>
feature.level == level && feature.type is LectureHall,
polyConstructor: (feature) => feature
.getPolygon(
constructor: (pts) => Polygon(
points: pts,
color: Colors.orange.withOpacity(0.2),
borderColor: Colors.orange,
isFilled: true,
borderStrokeWidth: 1,
),
)
.unwrap(),
markerConstructor: (feature) => Marker(
width: 150,
height: 60,
point: feature.getPoint().unwrap(),
builder: (cx) => Center(
child: Column(
children: [
Icon(
Icons.class_,
color: Colors.black,
),
Text('${feature.name}'),
],
),
),
)),
LevelLayer(
filter: (feature) => feature.level == level && feature.type is Room,
polyConstructor: (feature) => feature
.getPolygon(
constructor: (pts) => Polygon(
points: pts,
color: Colors.green.withOpacity(0.2),
borderColor: Colors.green,
isFilled: true,
borderStrokeWidth: 1,
),
)
.unwrap(),
),
LevelLayer(
filter: (feature) => feature.level == level && feature.type is Door,
markerConstructor: (feature) {
final point = feature.getPoint().unwrap();
return Marker(
width: 20,
height: 20,
point: point,
builder: (ctx) => const Icon(
Icons.door_front_door,
color: Colors.brown,
),
);
},
),
LevelLayer(
filter: (feature) => feature.level == level && feature.type is Toilet,
markerConstructor: (feature) {
final type = (feature.type as Toilet).toilet_type;
IconData icon;
switch (type.toLowerCase()) {
case 'male':
icon = Icons.male;
break;
case 'female':
icon = Icons.female;
break;
case 'handicap':
icon = Icons.wheelchair_pickup;
break;
default:
print("WARN: Toilet didn't have recognizable type! "
"(Level ${feature.level}, Name ${feature.name}, "
"Location: ${feature.getPoint().unwrap()})");
icon = Icons.wc;
break;
}
final point = feature.getPoint().unwrap();
return Marker(
width: 20,
height: 20,
point: point,
builder: (ctx) => Icon(
icon,
color: Colors.purple,
),
rotateAlignment: Alignment.center,
);
},
),
LevelLayer(
filter: (feature) =>
feature.type is Stairs &&
(feature.type as Stairs).connects_levels.contains(level),
markerConstructor: (feature) {
final point = feature.getPoint().unwrap();
return Marker(
width: 20,
height: 20,
point: point,
builder: (ctx) => Icon(
Icons.stairs_outlined,
color: Colors.deepPurple.shade300,
),
);
},
),
LevelLayer(
filter: (feature) =>
feature.type is Lift &&
(feature.type as Lift).connects_levels.contains(level),
markerConstructor: (feature) {
final point = feature.getPoint().unwrap();
return Marker(
width: 20,
height: 20,
point: point,
builder: (ctx) => const Icon(
Icons.elevator_outlined,
color: Colors.deepPurple,
),
);
},
),
];
}
class LevelLayer extends StatelessWidget {
final bool Function(Feature)? filter;
final Polygon Function(Feature)? polyConstructor;
final Marker Function(LatLng, String)? polyCenterMarkerConstructor;
final Marker Function(Feature)? markerConstructor;
final int? level;
const LevelLayer({
this.level,
this.filter,
this.polyConstructor,
this.polyCenterMarkerConstructor,
this.markerConstructor,
super.key,
});
@override
Widget build(BuildContext context) {
final myMapController = Get.find<MyMapController>();
return Obx(() {
final List<Polygon> filteredPolygons = [];
final List<Marker> polygonCenterMarkers = [];
final List<Marker> filteredMarkers = [];
for (final feature in myMapController.features) {
if (filter == null || filter!(feature)) {
if (feature.isPolygon()) {
if (polyConstructor != null) {
filteredPolygons.add(polyConstructor!(feature));
} else {
filteredPolygons.add(feature.getPolygon().unwrap());
}
// calculate polygon center
final center =
polygonCenterMinmax(feature.getPolygon().unwrap().points);
if (polyCenterMarkerConstructor != null) {
polygonCenterMarkers
.add(polyCenterMarkerConstructor!(center, feature.name));
} else {
polygonCenterMarkers.add(Marker(
width: 100,
height: 100,
point: center,
builder: (cx) => Center(
child: Text(
feature.name,
style: const TextStyle(
color: Colors.black54,
// backgroundColor: Colors.white,
),
),
),
));
}
} else if (feature.isPoint()) {
if (markerConstructor != null) {
filteredMarkers.add(markerConstructor!(feature));
} else {
final point = feature.getPoint().unwrap();
filteredMarkers.add(Marker(
width: 100,
height: 100,
point: point,
builder: (cx) => Center(
child: Text(
feature.name,
style: const TextStyle(
color: Colors.black54,
// backgroundColor: Colors.white,
),
),
),
));
}
}
}
}
// print(filteredPolygons.length);
// print(filteredPolygons);
// print(filteredPolygons[0].points[0]);
// print(myMapController.features.length);
final List<Widget> widgets = [];
if (filteredPolygons.isNotEmpty) {
if (polyConstructor != null) {
widgets.add(PolygonLayer(polygons: filteredPolygons));
} else {
widgets.add(PolygonLayer(
polygons: filteredPolygons
.map((poly) => Polygon(
points: poly.points,
borderColor: Colors.black26,
borderStrokeWidth: 2.0,
))
.toList()));
}
widgets.add(MarkerLayer(
markers: polygonCenterMarkers,
rotate: true,
));
}
if (filteredMarkers.isNotEmpty) {
widgets.add(MarkerLayer(markers: filteredMarkers, rotate: true));
}
return Stack(children: widgets);
});
}
}

View File

@ -185,6 +185,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.8" version: "1.0.8"
dart_earcut:
dependency: transitive
description:
name: dart_earcut
sha256: "41b493147e30a051efb2da1e3acb7f38fe0db60afba24ac1ea5684cee272721e"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
dart_style: dart_style:
dependency: transitive dependency: transitive
description: description:
@ -193,14 +201,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.6" version: "2.3.6"
extra_pedantic:
dependency: transitive
description:
name: extra_pedantic
sha256: eb9cc0842dc1c980f00fd226364456d2169d54f7118b8ae16443188063edce0b
url: "https://pub.dev"
source: hosted
version: "1.5.0"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
@ -242,10 +242,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_map name: flutter_map
sha256: "52c65a977daae42f9aae6748418dd1535eaf27186e9bac9bf431843082bc75a3" sha256: bee8c5bacb49a68aabcf6009c050a8b3b07ac75403f29f741d8c00d4a725e086
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.0" version: "7.0.0-dev.1"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -280,30 +280,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.0" version: "4.0.0"
geodesy: geojson_vi:
dependency: transitive
description:
name: geodesy
sha256: d9959000de938adf760f946546ccbf9ebdff8f4f6d0b5c54e8b8b1ed350b1028
url: "https://pub.dev"
source: hosted
version: "0.4.0-nullsafety.0"
geojson:
dependency: "direct main" dependency: "direct main"
description: description:
name: geojson name: geojson_vi
sha256: "8aab8116d074e92ef2d1ade25ec5ae90ea8bf024a920ab46703c433ffe08878f" sha256: ffba1991df4d3f98cfd7fee02bcde00b76a39d4daa838ba8a0ba8b83cbff0705
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.0" version: "2.2.3"
geopoint:
dependency: transitive
description:
name: geopoint
sha256: "594afb50a689e6584b80b7de8332c83a78e50725dc4324b2c014d19c56de5e3f"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
get: get:
dependency: "direct main" dependency: "direct main"
description: description:
@ -332,10 +316,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: http name: http
sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.13.6" version: "1.2.1"
http_multi_server: http_multi_server:
dependency: transitive dependency: transitive
description: description:
@ -368,14 +352,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.4" version: "1.0.4"
iso:
dependency: transitive
description:
name: iso
sha256: "7030a1a096f7924deb6cccde6c7d80473dddd54eeedf20402e3d6e51b1672b27"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
js: js:
dependency: transitive dependency: transitive
description: description:
@ -404,10 +380,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: latlong2 name: latlong2
sha256: "08ef7282ba9f76e8495e49e2dc4d653015ac929dce5f92b375a415d30b407ea0" sha256: "98227922caf49e6056f91b6c56945ea1c7b166f28ffcd5fb8e72fc0b453cc8fe"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.8.2" version: "0.9.1"
leak_tracker: leak_tracker:
dependency: transitive dependency: transitive
description: description:
@ -448,6 +424,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.1" version: "1.0.1"
logger:
dependency: transitive
description:
name: logger
sha256: "8c94b8c219e7e50194efc8771cd0e9f10807d8d3e219af473d89b06cc2ee4e04"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
logging: logging:
dependency: transitive dependency: transitive
description: description:
@ -512,14 +496,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.9.0" version: "1.9.0"
pedantic:
dependency: transitive
description:
name: pedantic
sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602"
url: "https://pub.dev"
source: hosted
version: "1.11.1"
plugin_platform_interface: plugin_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -597,14 +573,6 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.99" version: "0.0.99"
slugify:
dependency: transitive
description:
name: slugify
sha256: b272501565cb28050cac2d96b7bf28a2d24c8dae359280361d124f3093d337c3
url: "https://pub.dev"
source: hosted
version: "2.0.0"
source_gen: source_gen:
dependency: transitive dependency: transitive
description: description:
@ -701,14 +669,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.1" version: "1.0.1"
tuple:
dependency: transitive
description:
name: tuple
sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151
url: "https://pub.dev"
source: hosted
version: "2.0.2"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:

View File

@ -38,9 +38,12 @@ dependencies:
get: ^4.6.6 get: ^4.6.6
yaml: ^3.1.2 yaml: ^3.1.2
surrealdb: ^0.8.0 surrealdb: ^0.8.0
geojson: ^1.0.0 # geojson: ^1.0.0
flutter_map: 7.0.0-dev.1 flutter_map: 7.0.0-dev.1
# latlong2: ^0.9.0 # flutter_map: ^4.0.0
latlong2: ^0.9.0
# latlong2: ^0.8.0
geojson_vi: ^2.2.3
url_launcher: ^6.2.6 url_launcher: ^6.2.6
anim_search_bar: ^2.0.3 anim_search_bar: ^2.0.3
freezed_annotation: ^2.4.1 freezed_annotation: ^2.4.1