Compare commits

...

2 Commits

Author SHA1 Message Date
Yandrik 13327da5de feat: major progress 2024-04-21 00:35:16 +02:00
Yandrik b7487fc25e feat: partial broken guesture detection 2024-04-20 21:14:11 +02:00
16 changed files with 4351 additions and 1685 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,46 @@
import 'package:flutter/material.dart';
class ColorfulChip extends StatelessWidget {
final String label;
const ColorfulChip({Key? key, required this.label}) : super(key: key);
@override
Widget build(BuildContext context) {
final color = Color(((label.hashCode) & 0xFFFFFF) | 0xFF000000);
return Chip(
label: Text(label),
backgroundColor: color,
labelStyle: TextStyle(
color: color.computeLuminance() > 0.5 ? Colors.black : Colors.white,
),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
);
}
}
class ColorfulActionChip extends StatelessWidget {
final String label;
final VoidCallback onPressed;
const ColorfulActionChip({
Key? key,
required this.label,
required this.onPressed,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final color = Color(
((label.hashCode - 5 /* randomness - */) & 0xFFFFFF) | 0xFF000000);
return ActionChip(
label: Text(label),
backgroundColor: color,
labelStyle: TextStyle(
color: color.computeLuminance() > 0.5 ? Colors.black : Colors.white,
),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
onPressed: onPressed,
);
}
}

View File

@ -0,0 +1,184 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
import 'package:uninav/components/colorful_chips.dart';
import 'package:uninav/controllers/map_controller.dart';
import 'package:uninav/data/geo/model.dart';
import 'package:uninav/util/util.dart';
final _colorfulBoxDeco = BoxDecoration(
color: Colors.black,
border: Border.all(color: Colors.orange, width: 2),
borderRadius: BorderRadius.circular(10),
);
Future<void> showFeatureBottomSheet(
Feature feature, List<Feature>? closestFeatures) {
return Get.bottomSheet(
Theme(
data: ThemeData.light(),
child: Container(
height: 300,
width: Get.mediaQuery.size.width,
decoration: const BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30), topRight: Radius.circular(30)),
),
padding: const EdgeInsets.all(20),
child: Column(children: [
Center(
child: Container(
width: 50,
height: 5,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
),
),
const SizedBox(height: 10),
Text(formatFeatureTitle(feature),
style:
const TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
const SizedBox(height: 14),
if (closestFeatures != null) ...[
const Text('Did you mean:'),
Wrap(
spacing: 8,
children: closestFeatures
.map((nearFeature) => ColorfulActionChip(
label: formatFeatureTitle(nearFeature),
onPressed: () {
Get.back();
final newClosestFeatures = closestFeatures
.where((element) => element != nearFeature)
.toList();
newClosestFeatures.add(feature);
Get.find<MyMapController>().focusOnFeature(
nearFeature,
closestFeatures: newClosestFeatures);
},
))
.toList(),
),
const SizedBox(height: 14),
],
..._buildFeatureContent(feature),
]),
),
),
isScrollControlled: true,
enterBottomSheetDuration: const Duration(milliseconds: 150),
exitBottomSheetDuration: const Duration(milliseconds: 200),
);
}
List<Widget> _buildFeatureContent(Feature feature) {
return feature.type.when(
building: () => _buildBuildingContent(feature),
lectureHall: () => _buildLectureHallContent(feature),
room: () => _buildRoomContent(feature),
door: (connects) => _buildDoorContent(feature, connects),
toilet: (toiletType) => _buildToiletContent(feature, toiletType),
stairs: (connectsLevels) => _buildStairsContent(feature, connectsLevels),
lift: (connectsLevels) => _buildLiftContent(feature, connectsLevels),
publicTransport: (busLines, tramLines) =>
_buildPublicTransportContent(feature, busLines, tramLines),
);
}
/// Builds the content for the Building feature type.
List<Widget> _buildBuildingContent(Feature feature) {
return [
Text(feature.name),
];
}
/// Builds the content for the LectureHall feature type.
List<Widget> _buildLectureHallContent(Feature feature) {
return [Text('Lecture Hall: ${feature.name}')];
}
/// Builds the content for the Room feature type.
List<Widget> _buildRoomContent(Feature feature) {
return [Text('Room: ${feature.name}')];
}
/// Builds the content for the Door feature type.
List<Widget> _buildDoorContent(Feature feature, List<String> connects) {
return [Text('Door: ${feature.name}\nConnects: $connects')];
}
/// Builds the content for the Toilet feature type.
List<Widget> _buildToiletContent(Feature feature, String toiletType) {
return [Text('Toilet: ${feature.name}\nType: $toiletType')];
}
/// Builds the content for the Stairs feature type.
List<Widget> _buildStairsContent(Feature feature, List<int> connectsLevels) {
return [Text('Stairs: ${feature.name}\nConnects Levels: $connectsLevels')];
}
/// Builds the content for the Lift feature type.
List<Widget> _buildLiftContent(Feature feature, List<int> connectsLevels) {
return [Text('Lift: ${feature.name}\nConnects Levels: $connectsLevels')];
}
/// Builds the content for the PublicTransport feature type.
List<Widget> _buildPublicTransportContent(
Feature feature, List<String> busLines, List<String> tramLines) {
return [
Text(
feature.name,
style: const TextStyle(fontSize: 18),
),
const SizedBox(height: 10),
if (busLines.isNotEmpty) ...[
const Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.only(right: 4),
child: Text(
'Bus Lines:',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
),
Align(
alignment: Alignment.centerLeft,
child: Wrap(
spacing: 8,
runSpacing: 4,
children: busLines.map((line) {
return ColorfulChip(label: line);
}).toList(),
),
),
const SizedBox(height: 10),
],
if (tramLines.isNotEmpty) ...[
const Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.only(right: 4),
child: Text(
'Tram Lines:',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
),
Align(
alignment: Alignment.centerLeft,
child: Wrap(
spacing: 8,
runSpacing: 4,
children: tramLines.map((line) {
return ColorfulChip(label: line);
}).toList(),
),
),
],
];
}

View File

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

View File

@ -1,13 +1,20 @@
import 'dart:convert';
import 'package:anyhow/anyhow.dart';
import 'package:geojson/geojson.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_map/src/gestures/positioned_tap_detector_2.dart';
import 'package:geojson_vi/geojson_vi.dart';
import 'package:get/get.dart';
import 'package:latlong2/latlong.dart';
import 'package:uninav/components/feature_bottom_sheet.dart';
import 'package:uninav/data/geo/model.dart';
import 'package:uninav/data/geo/parser.dart';
import 'package:uninav/util/geojson_util.dart';
import 'package:uninav/util/geomath.dart';
class MyMapController extends GetxController {
// constructor that calls loadgeojson with a default geojson string
final MapController mapController = MapController();
final RxList<Feature> features = <Feature>[].obs;
final currentLevel = 1.obs;
final levels = <int>[1].obs;
@ -40,20 +47,56 @@ class MyMapController extends GetxController {
return const Ok(());
}
List<Feature> computeHits(LatLng position, {bool Function(Feature)? filter}) {
final hits = <(Feature, double)>[];
for (final feature in features) {
if (filter != null && !filter(feature)) {
continue;
}
if (feature.isPolygon()) {
if ((feature.geometry as GeoJSONPolygon)
.isPointInside(latLonToGeoJSON(position))) {
// compute distance to center of polygon
final distance = distanceBetweenLatLng(
polygonCenterMinmax((feature.geometry as GeoJSONPolygon)
.coordinates[0]
.map(geoJSONToLatLon)
.toList()),
position,
'meters');
hits.add((feature, distance));
}
} else if (feature.isPoint()) {
final distance = distanceBetweenLatLng(
geoJSONToLatLon((feature.geometry as GeoJSONPoint).coordinates),
position,
'meters');
if (distance <= 5) {
hits.add((feature, distance));
}
}
}
hits.sort((a, b) => a.$2.compareTo(b.$2));
return hits.map((e) => e.$1).toList();
}
Future<void> loadGeoJson(String geoJsonString) async {
try {
// print(geoJsonString);
final featuresList = <Feature>[];
final geojson = GeoJson();
await geojson.parse(geoJsonString);
print('doing');
final geojson = GeoJSONFeatureCollection.fromJSON(geoJsonString);
print('done');
for (final feature in geojson.features) {
print(feature);
print(feature?.properties);
if (feature == null) continue;
print(feature.properties);
final parsed =
parseFeature(feature.properties ?? <String, dynamic>{}, feature);
final parsed = parseFeature(
feature.properties ?? <String, dynamic>{}, feature.geometry);
if (parsed case Ok(:final ok)) {
featuresList.add(ok);
}
@ -64,4 +107,35 @@ class MyMapController extends GetxController {
print('Error parsing GeoJSON: $e');
}
}
void handleTap(TapPosition tapPosition, LatLng point) {
final hits = Get.find<MyMapController>().computeHits(point,
filter: (feature) =>
feature.isOnLevel(null) /* is not on a level */ ||
feature.isOnLevel(Get.find<MyMapController>().currentLevel.value));
print('Hits: ${hits.map((e) => e.name)}');
if (hits.isNotEmpty) {
focusOnFeature(hits[0],
move: false,
closestFeatures:
hits.length > 1 ? hits.skip(1).toList() : null); // closest match
}
}
void focusOnFeature(Feature feature,
{bool move = true, List<Feature>? closestFeatures}) {
try {
if (move) {
mapController.move(
feature
.getCenterPoint()
.expect("Couldn't find Center Point of target geometry"),
mapController.camera.zoom,
);
}
} catch (e) {
print("Error moving map controller: $e");
}
showFeatureBottomSheet(feature, closestFeatures);
}
}

View File

@ -2,8 +2,10 @@ import 'package:anyhow/anyhow.dart';
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.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:uninav/util/geojson_util.dart';
import 'package:uninav/util/geomath.dart';
part 'model.freezed.dart';
@ -15,27 +17,32 @@ class Feature with _$Feature {
required String name,
required FeatureType type,
String? description,
required dynamic geometry,
required GeoJSONGeometry geometry,
int? level,
String? building,
}) = _Feature;
bool isPolygon() {
return geometry is GeoJsonFeature<GeoJsonPolygon>;
return geometry is GeoJSONPolygon;
}
bool isPoint() {
return geometry is GeoJsonFeature<GeoJsonPoint>;
return geometry is GeoJSONPoint;
}
Result<Polygon> getPolygon({Polygon Function(List<LatLng>)? constructor}) {
if (isPolygon()) {
constructor ??= (pts) => Polygon(
points: pts, borderColor: Colors.black26, borderStrokeWidth: 2.0);
final polygon = geometry as GeoJsonFeature<GeoJsonPolygon>;
points: pts,
borderColor: Colors.black26,
borderStrokeWidth: 2.0,
hitValue: 'test${pts.length}',
);
final polygon = geometry as GeoJSONPolygon;
// print(polygon.geometry!.geoSeries[0].geoPoints);
final points = polygon.geometry!.geoSeries[0].geoPoints
.map((e) => LatLng(e.latitude, e.longitude))
.toList();
final points =
// polygon.coordinates[0].map((e) => LatLng(e[0], e[1])).toList();
polygon.coordinates[0].map(geoJSONToLatLon).toList();
// print(points);
return Ok(constructor(points));
@ -46,13 +53,45 @@ class Feature with _$Feature {
Result<LatLng> getPoint() {
if (isPoint()) {
final point = geometry as GeoJsonFeature<GeoJsonPoint>;
return Ok(LatLng(point.geometry!.geoPoint.latitude,
point.geometry!.geoPoint.longitude));
final point = geometry as GeoJSONPoint;
return Ok(geoJSONToLatLon(point.coordinates));
} else {
return bail("Feature Geometry is not a Point");
}
}
/// Checks if the current feature is on the specified layer.
///
/// For features that represent lifts or stairs, this method checks if the
/// feature's `connects_levels` list contains the specified layer.
///
/// For other feature types, this method simply checks if the feature's `level`
/// property matches the specified layer.
///
/// @param layer The layer to check for. **Layer can be `null`!**
/// `null` matches things such as Buildings without a layer.
/// @return `true` if the feature is on the specified layer, `false` otherwise.
bool isOnLevel(int? layer) {
if (type is Lift) {
return (type as Lift).connects_levels.contains(layer);
} else if (type is Stairs) {
return (type as Stairs).connects_levels.contains(layer);
}
return level == layer;
}
Result<LatLng> getCenterPoint() {
if (isPolygon()) {
final polygon = geometry as GeoJSONPolygon;
final points = polygon.coordinates[0].map(geoJSONToLatLon).toList();
return Ok(polygonCenterMinmax(points));
} else if (isPoint()) {
final point = geometry as GeoJSONPoint;
return Ok(geoJSONToLatLon(point.coordinates));
} else {
return bail("Feature Geometry is not a Polygon or Point");
}
}
}
@freezed

View File

@ -19,8 +19,9 @@ mixin _$Feature {
String get name => throw _privateConstructorUsedError;
FeatureType get type => throw _privateConstructorUsedError;
String? get description => throw _privateConstructorUsedError;
dynamic get geometry => throw _privateConstructorUsedError;
GeoJSONGeometry get geometry => throw _privateConstructorUsedError;
int? get level => throw _privateConstructorUsedError;
String? get building => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$FeatureCopyWith<Feature> get copyWith => throw _privateConstructorUsedError;
@ -35,8 +36,9 @@ abstract class $FeatureCopyWith<$Res> {
{String name,
FeatureType type,
String? description,
dynamic geometry,
int? level});
GeoJSONGeometry geometry,
int? level,
String? building});
$FeatureTypeCopyWith<$Res> get type;
}
@ -57,8 +59,9 @@ class _$FeatureCopyWithImpl<$Res, $Val extends Feature>
Object? name = null,
Object? type = null,
Object? description = freezed,
Object? geometry = freezed,
Object? geometry = null,
Object? level = freezed,
Object? building = freezed,
}) {
return _then(_value.copyWith(
name: null == name
@ -73,14 +76,18 @@ class _$FeatureCopyWithImpl<$Res, $Val extends Feature>
? _value.description
: description // ignore: cast_nullable_to_non_nullable
as String?,
geometry: freezed == geometry
geometry: null == geometry
? _value.geometry
: geometry // ignore: cast_nullable_to_non_nullable
as dynamic,
as GeoJSONGeometry,
level: freezed == level
? _value.level
: level // ignore: cast_nullable_to_non_nullable
as int?,
building: freezed == building
? _value.building
: building // ignore: cast_nullable_to_non_nullable
as String?,
) as $Val);
}
@ -104,8 +111,9 @@ abstract class _$$FeatureImplCopyWith<$Res> implements $FeatureCopyWith<$Res> {
{String name,
FeatureType type,
String? description,
dynamic geometry,
int? level});
GeoJSONGeometry geometry,
int? level,
String? building});
@override
$FeatureTypeCopyWith<$Res> get type;
@ -125,8 +133,9 @@ class __$$FeatureImplCopyWithImpl<$Res>
Object? name = null,
Object? type = null,
Object? description = freezed,
Object? geometry = freezed,
Object? geometry = null,
Object? level = freezed,
Object? building = freezed,
}) {
return _then(_$FeatureImpl(
name: null == name
@ -141,14 +150,18 @@ class __$$FeatureImplCopyWithImpl<$Res>
? _value.description
: description // ignore: cast_nullable_to_non_nullable
as String?,
geometry: freezed == geometry
geometry: null == geometry
? _value.geometry
: geometry // ignore: cast_nullable_to_non_nullable
as dynamic,
as GeoJSONGeometry,
level: freezed == level
? _value.level
: level // ignore: cast_nullable_to_non_nullable
as int?,
building: freezed == building
? _value.building
: building // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
@ -161,7 +174,8 @@ class _$FeatureImpl extends _Feature {
required this.type,
this.description,
required this.geometry,
this.level})
this.level,
this.building})
: super._();
@override
@ -171,13 +185,15 @@ class _$FeatureImpl extends _Feature {
@override
final String? description;
@override
final dynamic geometry;
final GeoJSONGeometry geometry;
@override
final int? level;
@override
final String? building;
@override
String toString() {
return 'Feature(name: $name, type: $type, description: $description, geometry: $geometry, level: $level)';
return 'Feature(name: $name, type: $type, description: $description, geometry: $geometry, level: $level, building: $building)';
}
@override
@ -189,13 +205,16 @@ class _$FeatureImpl extends _Feature {
(identical(other.type, type) || other.type == type) &&
(identical(other.description, description) ||
other.description == description) &&
const DeepCollectionEquality().equals(other.geometry, geometry) &&
(identical(other.level, level) || other.level == level));
(identical(other.geometry, geometry) ||
other.geometry == geometry) &&
(identical(other.level, level) || other.level == level) &&
(identical(other.building, building) ||
other.building == building));
}
@override
int get hashCode => Object.hash(runtimeType, name, type, description,
const DeepCollectionEquality().hash(geometry), level);
int get hashCode => Object.hash(
runtimeType, name, type, description, geometry, level, building);
@JsonKey(ignore: true)
@override
@ -209,8 +228,9 @@ abstract class _Feature extends Feature {
{required final String name,
required final FeatureType type,
final String? description,
required final dynamic geometry,
final int? level}) = _$FeatureImpl;
required final GeoJSONGeometry geometry,
final int? level,
final String? building}) = _$FeatureImpl;
const _Feature._() : super._();
@override
@ -220,10 +240,12 @@ abstract class _Feature extends Feature {
@override
String? get description;
@override
dynamic get geometry;
GeoJSONGeometry get geometry;
@override
int? get level;
@override
String? get building;
@override
@JsonKey(ignore: true)
_$$FeatureImplCopyWith<_$FeatureImpl> get copyWith =>
throw _privateConstructorUsedError;
@ -238,7 +260,6 @@ mixin _$FeatureType {
required TResult Function() room,
required TResult Function(List<String> connects) door,
required TResult Function(String toilet_type) toilet,
required TResult Function() entrance,
required TResult Function(List<int> connects_levels) stairs,
required TResult Function(List<int> connects_levels) lift,
required TResult Function(List<String> bus_lines, List<String> tram_lines)
@ -252,7 +273,6 @@ mixin _$FeatureType {
TResult? Function()? room,
TResult? Function(List<String> connects)? door,
TResult? Function(String toilet_type)? toilet,
TResult? Function()? entrance,
TResult? Function(List<int> connects_levels)? stairs,
TResult? Function(List<int> connects_levels)? lift,
TResult? Function(List<String> bus_lines, List<String> tram_lines)?
@ -266,7 +286,6 @@ mixin _$FeatureType {
TResult Function()? room,
TResult Function(List<String> connects)? door,
TResult Function(String toilet_type)? toilet,
TResult Function()? entrance,
TResult Function(List<int> connects_levels)? stairs,
TResult Function(List<int> connects_levels)? lift,
TResult Function(List<String> bus_lines, List<String> tram_lines)?
@ -281,7 +300,6 @@ mixin _$FeatureType {
required TResult Function(Room value) room,
required TResult Function(Door value) door,
required TResult Function(Toilet value) toilet,
required TResult Function(Entrance value) entrance,
required TResult Function(Stairs value) stairs,
required TResult Function(Lift value) lift,
required TResult Function(PublicTransport value) publicTransport,
@ -294,7 +312,6 @@ mixin _$FeatureType {
TResult? Function(Room value)? room,
TResult? Function(Door value)? door,
TResult? Function(Toilet value)? toilet,
TResult? Function(Entrance value)? entrance,
TResult? Function(Stairs value)? stairs,
TResult? Function(Lift value)? lift,
TResult? Function(PublicTransport value)? publicTransport,
@ -307,7 +324,6 @@ mixin _$FeatureType {
TResult Function(Room value)? room,
TResult Function(Door value)? door,
TResult Function(Toilet value)? toilet,
TResult Function(Entrance value)? entrance,
TResult Function(Stairs value)? stairs,
TResult Function(Lift value)? lift,
TResult Function(PublicTransport value)? publicTransport,
@ -377,7 +393,6 @@ class _$BuildingImpl implements Building {
required TResult Function() room,
required TResult Function(List<String> connects) door,
required TResult Function(String toilet_type) toilet,
required TResult Function() entrance,
required TResult Function(List<int> connects_levels) stairs,
required TResult Function(List<int> connects_levels) lift,
required TResult Function(List<String> bus_lines, List<String> tram_lines)
@ -394,7 +409,6 @@ class _$BuildingImpl implements Building {
TResult? Function()? room,
TResult? Function(List<String> connects)? door,
TResult? Function(String toilet_type)? toilet,
TResult? Function()? entrance,
TResult? Function(List<int> connects_levels)? stairs,
TResult? Function(List<int> connects_levels)? lift,
TResult? Function(List<String> bus_lines, List<String> tram_lines)?
@ -411,7 +425,6 @@ class _$BuildingImpl implements Building {
TResult Function()? room,
TResult Function(List<String> connects)? door,
TResult Function(String toilet_type)? toilet,
TResult Function()? entrance,
TResult Function(List<int> connects_levels)? stairs,
TResult Function(List<int> connects_levels)? lift,
TResult Function(List<String> bus_lines, List<String> tram_lines)?
@ -432,7 +445,6 @@ class _$BuildingImpl implements Building {
required TResult Function(Room value) room,
required TResult Function(Door value) door,
required TResult Function(Toilet value) toilet,
required TResult Function(Entrance value) entrance,
required TResult Function(Stairs value) stairs,
required TResult Function(Lift value) lift,
required TResult Function(PublicTransport value) publicTransport,
@ -448,7 +460,6 @@ class _$BuildingImpl implements Building {
TResult? Function(Room value)? room,
TResult? Function(Door value)? door,
TResult? Function(Toilet value)? toilet,
TResult? Function(Entrance value)? entrance,
TResult? Function(Stairs value)? stairs,
TResult? Function(Lift value)? lift,
TResult? Function(PublicTransport value)? publicTransport,
@ -464,7 +475,6 @@ class _$BuildingImpl implements Building {
TResult Function(Room value)? room,
TResult Function(Door value)? door,
TResult Function(Toilet value)? toilet,
TResult Function(Entrance value)? entrance,
TResult Function(Stairs value)? stairs,
TResult Function(Lift value)? lift,
TResult Function(PublicTransport value)? publicTransport,
@ -524,7 +534,6 @@ class _$LectureHallImpl implements LectureHall {
required TResult Function() room,
required TResult Function(List<String> connects) door,
required TResult Function(String toilet_type) toilet,
required TResult Function() entrance,
required TResult Function(List<int> connects_levels) stairs,
required TResult Function(List<int> connects_levels) lift,
required TResult Function(List<String> bus_lines, List<String> tram_lines)
@ -541,7 +550,6 @@ class _$LectureHallImpl implements LectureHall {
TResult? Function()? room,
TResult? Function(List<String> connects)? door,
TResult? Function(String toilet_type)? toilet,
TResult? Function()? entrance,
TResult? Function(List<int> connects_levels)? stairs,
TResult? Function(List<int> connects_levels)? lift,
TResult? Function(List<String> bus_lines, List<String> tram_lines)?
@ -558,7 +566,6 @@ class _$LectureHallImpl implements LectureHall {
TResult Function()? room,
TResult Function(List<String> connects)? door,
TResult Function(String toilet_type)? toilet,
TResult Function()? entrance,
TResult Function(List<int> connects_levels)? stairs,
TResult Function(List<int> connects_levels)? lift,
TResult Function(List<String> bus_lines, List<String> tram_lines)?
@ -579,7 +586,6 @@ class _$LectureHallImpl implements LectureHall {
required TResult Function(Room value) room,
required TResult Function(Door value) door,
required TResult Function(Toilet value) toilet,
required TResult Function(Entrance value) entrance,
required TResult Function(Stairs value) stairs,
required TResult Function(Lift value) lift,
required TResult Function(PublicTransport value) publicTransport,
@ -595,7 +601,6 @@ class _$LectureHallImpl implements LectureHall {
TResult? Function(Room value)? room,
TResult? Function(Door value)? door,
TResult? Function(Toilet value)? toilet,
TResult? Function(Entrance value)? entrance,
TResult? Function(Stairs value)? stairs,
TResult? Function(Lift value)? lift,
TResult? Function(PublicTransport value)? publicTransport,
@ -611,7 +616,6 @@ class _$LectureHallImpl implements LectureHall {
TResult Function(Room value)? room,
TResult Function(Door value)? door,
TResult Function(Toilet value)? toilet,
TResult Function(Entrance value)? entrance,
TResult Function(Stairs value)? stairs,
TResult Function(Lift value)? lift,
TResult Function(PublicTransport value)? publicTransport,
@ -670,7 +674,6 @@ class _$RoomImpl implements Room {
required TResult Function() room,
required TResult Function(List<String> connects) door,
required TResult Function(String toilet_type) toilet,
required TResult Function() entrance,
required TResult Function(List<int> connects_levels) stairs,
required TResult Function(List<int> connects_levels) lift,
required TResult Function(List<String> bus_lines, List<String> tram_lines)
@ -687,7 +690,6 @@ class _$RoomImpl implements Room {
TResult? Function()? room,
TResult? Function(List<String> connects)? door,
TResult? Function(String toilet_type)? toilet,
TResult? Function()? entrance,
TResult? Function(List<int> connects_levels)? stairs,
TResult? Function(List<int> connects_levels)? lift,
TResult? Function(List<String> bus_lines, List<String> tram_lines)?
@ -704,7 +706,6 @@ class _$RoomImpl implements Room {
TResult Function()? room,
TResult Function(List<String> connects)? door,
TResult Function(String toilet_type)? toilet,
TResult Function()? entrance,
TResult Function(List<int> connects_levels)? stairs,
TResult Function(List<int> connects_levels)? lift,
TResult Function(List<String> bus_lines, List<String> tram_lines)?
@ -725,7 +726,6 @@ class _$RoomImpl implements Room {
required TResult Function(Room value) room,
required TResult Function(Door value) door,
required TResult Function(Toilet value) toilet,
required TResult Function(Entrance value) entrance,
required TResult Function(Stairs value) stairs,
required TResult Function(Lift value) lift,
required TResult Function(PublicTransport value) publicTransport,
@ -741,7 +741,6 @@ class _$RoomImpl implements Room {
TResult? Function(Room value)? room,
TResult? Function(Door value)? door,
TResult? Function(Toilet value)? toilet,
TResult? Function(Entrance value)? entrance,
TResult? Function(Stairs value)? stairs,
TResult? Function(Lift value)? lift,
TResult? Function(PublicTransport value)? publicTransport,
@ -757,7 +756,6 @@ class _$RoomImpl implements Room {
TResult Function(Room value)? room,
TResult Function(Door value)? door,
TResult Function(Toilet value)? toilet,
TResult Function(Entrance value)? entrance,
TResult Function(Stairs value)? stairs,
TResult Function(Lift value)? lift,
TResult Function(PublicTransport value)? publicTransport,
@ -848,7 +846,6 @@ class _$DoorImpl implements Door {
required TResult Function() room,
required TResult Function(List<String> connects) door,
required TResult Function(String toilet_type) toilet,
required TResult Function() entrance,
required TResult Function(List<int> connects_levels) stairs,
required TResult Function(List<int> connects_levels) lift,
required TResult Function(List<String> bus_lines, List<String> tram_lines)
@ -865,7 +862,6 @@ class _$DoorImpl implements Door {
TResult? Function()? room,
TResult? Function(List<String> connects)? door,
TResult? Function(String toilet_type)? toilet,
TResult? Function()? entrance,
TResult? Function(List<int> connects_levels)? stairs,
TResult? Function(List<int> connects_levels)? lift,
TResult? Function(List<String> bus_lines, List<String> tram_lines)?
@ -882,7 +878,6 @@ class _$DoorImpl implements Door {
TResult Function()? room,
TResult Function(List<String> connects)? door,
TResult Function(String toilet_type)? toilet,
TResult Function()? entrance,
TResult Function(List<int> connects_levels)? stairs,
TResult Function(List<int> connects_levels)? lift,
TResult Function(List<String> bus_lines, List<String> tram_lines)?
@ -903,7 +898,6 @@ class _$DoorImpl implements Door {
required TResult Function(Room value) room,
required TResult Function(Door value) door,
required TResult Function(Toilet value) toilet,
required TResult Function(Entrance value) entrance,
required TResult Function(Stairs value) stairs,
required TResult Function(Lift value) lift,
required TResult Function(PublicTransport value) publicTransport,
@ -919,7 +913,6 @@ class _$DoorImpl implements Door {
TResult? Function(Room value)? room,
TResult? Function(Door value)? door,
TResult? Function(Toilet value)? toilet,
TResult? Function(Entrance value)? entrance,
TResult? Function(Stairs value)? stairs,
TResult? Function(Lift value)? lift,
TResult? Function(PublicTransport value)? publicTransport,
@ -935,7 +928,6 @@ class _$DoorImpl implements Door {
TResult Function(Room value)? room,
TResult Function(Door value)? door,
TResult Function(Toilet value)? toilet,
TResult Function(Entrance value)? entrance,
TResult Function(Stairs value)? stairs,
TResult Function(Lift value)? lift,
TResult Function(PublicTransport value)? publicTransport,
@ -1027,7 +1019,6 @@ class _$ToiletImpl implements Toilet {
required TResult Function() room,
required TResult Function(List<String> connects) door,
required TResult Function(String toilet_type) toilet,
required TResult Function() entrance,
required TResult Function(List<int> connects_levels) stairs,
required TResult Function(List<int> connects_levels) lift,
required TResult Function(List<String> bus_lines, List<String> tram_lines)
@ -1044,7 +1035,6 @@ class _$ToiletImpl implements Toilet {
TResult? Function()? room,
TResult? Function(List<String> connects)? door,
TResult? Function(String toilet_type)? toilet,
TResult? Function()? entrance,
TResult? Function(List<int> connects_levels)? stairs,
TResult? Function(List<int> connects_levels)? lift,
TResult? Function(List<String> bus_lines, List<String> tram_lines)?
@ -1061,7 +1051,6 @@ class _$ToiletImpl implements Toilet {
TResult Function()? room,
TResult Function(List<String> connects)? door,
TResult Function(String toilet_type)? toilet,
TResult Function()? entrance,
TResult Function(List<int> connects_levels)? stairs,
TResult Function(List<int> connects_levels)? lift,
TResult Function(List<String> bus_lines, List<String> tram_lines)?
@ -1082,7 +1071,6 @@ class _$ToiletImpl implements Toilet {
required TResult Function(Room value) room,
required TResult Function(Door value) door,
required TResult Function(Toilet value) toilet,
required TResult Function(Entrance value) entrance,
required TResult Function(Stairs value) stairs,
required TResult Function(Lift value) lift,
required TResult Function(PublicTransport value) publicTransport,
@ -1098,7 +1086,6 @@ class _$ToiletImpl implements Toilet {
TResult? Function(Room value)? room,
TResult? Function(Door value)? door,
TResult? Function(Toilet value)? toilet,
TResult? Function(Entrance value)? entrance,
TResult? Function(Stairs value)? stairs,
TResult? Function(Lift value)? lift,
TResult? Function(PublicTransport value)? publicTransport,
@ -1114,7 +1101,6 @@ class _$ToiletImpl implements Toilet {
TResult Function(Room value)? room,
TResult Function(Door value)? door,
TResult Function(Toilet value)? toilet,
TResult Function(Entrance value)? entrance,
TResult Function(Stairs value)? stairs,
TResult Function(Lift value)? lift,
TResult Function(PublicTransport value)? publicTransport,
@ -1136,153 +1122,6 @@ abstract class Toilet implements FeatureType {
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class _$$EntranceImplCopyWith<$Res> {
factory _$$EntranceImplCopyWith(
_$EntranceImpl value, $Res Function(_$EntranceImpl) then) =
__$$EntranceImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$EntranceImplCopyWithImpl<$Res>
extends _$FeatureTypeCopyWithImpl<$Res, _$EntranceImpl>
implements _$$EntranceImplCopyWith<$Res> {
__$$EntranceImplCopyWithImpl(
_$EntranceImpl _value, $Res Function(_$EntranceImpl) _then)
: super(_value, _then);
}
/// @nodoc
class _$EntranceImpl implements Entrance {
const _$EntranceImpl();
@override
String toString() {
return 'FeatureType.entrance()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$EntranceImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() building,
required TResult Function() lectureHall,
required TResult Function() room,
required TResult Function(List<String> connects) door,
required TResult Function(String toilet_type) toilet,
required TResult Function() entrance,
required TResult Function(List<int> connects_levels) stairs,
required TResult Function(List<int> connects_levels) lift,
required TResult Function(List<String> bus_lines, List<String> tram_lines)
publicTransport,
}) {
return entrance();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? building,
TResult? Function()? lectureHall,
TResult? Function()? room,
TResult? Function(List<String> connects)? door,
TResult? Function(String toilet_type)? toilet,
TResult? Function()? entrance,
TResult? Function(List<int> connects_levels)? stairs,
TResult? Function(List<int> connects_levels)? lift,
TResult? Function(List<String> bus_lines, List<String> tram_lines)?
publicTransport,
}) {
return entrance?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? building,
TResult Function()? lectureHall,
TResult Function()? room,
TResult Function(List<String> connects)? door,
TResult Function(String toilet_type)? toilet,
TResult Function()? entrance,
TResult Function(List<int> connects_levels)? stairs,
TResult Function(List<int> connects_levels)? lift,
TResult Function(List<String> bus_lines, List<String> tram_lines)?
publicTransport,
required TResult orElse(),
}) {
if (entrance != null) {
return entrance();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(Building value) building,
required TResult Function(LectureHall value) lectureHall,
required TResult Function(Room value) room,
required TResult Function(Door value) door,
required TResult Function(Toilet value) toilet,
required TResult Function(Entrance value) entrance,
required TResult Function(Stairs value) stairs,
required TResult Function(Lift value) lift,
required TResult Function(PublicTransport value) publicTransport,
}) {
return entrance(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(Building value)? building,
TResult? Function(LectureHall value)? lectureHall,
TResult? Function(Room value)? room,
TResult? Function(Door value)? door,
TResult? Function(Toilet value)? toilet,
TResult? Function(Entrance value)? entrance,
TResult? Function(Stairs value)? stairs,
TResult? Function(Lift value)? lift,
TResult? Function(PublicTransport value)? publicTransport,
}) {
return entrance?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(Building value)? building,
TResult Function(LectureHall value)? lectureHall,
TResult Function(Room value)? room,
TResult Function(Door value)? door,
TResult Function(Toilet value)? toilet,
TResult Function(Entrance value)? entrance,
TResult Function(Stairs value)? stairs,
TResult Function(Lift value)? lift,
TResult Function(PublicTransport value)? publicTransport,
required TResult orElse(),
}) {
if (entrance != null) {
return entrance(this);
}
return orElse();
}
}
abstract class Entrance implements FeatureType {
const factory Entrance() = _$EntranceImpl;
}
/// @nodoc
abstract class _$$StairsImplCopyWith<$Res> {
factory _$$StairsImplCopyWith(
@ -1360,7 +1199,6 @@ class _$StairsImpl implements Stairs {
required TResult Function() room,
required TResult Function(List<String> connects) door,
required TResult Function(String toilet_type) toilet,
required TResult Function() entrance,
required TResult Function(List<int> connects_levels) stairs,
required TResult Function(List<int> connects_levels) lift,
required TResult Function(List<String> bus_lines, List<String> tram_lines)
@ -1377,7 +1215,6 @@ class _$StairsImpl implements Stairs {
TResult? Function()? room,
TResult? Function(List<String> connects)? door,
TResult? Function(String toilet_type)? toilet,
TResult? Function()? entrance,
TResult? Function(List<int> connects_levels)? stairs,
TResult? Function(List<int> connects_levels)? lift,
TResult? Function(List<String> bus_lines, List<String> tram_lines)?
@ -1394,7 +1231,6 @@ class _$StairsImpl implements Stairs {
TResult Function()? room,
TResult Function(List<String> connects)? door,
TResult Function(String toilet_type)? toilet,
TResult Function()? entrance,
TResult Function(List<int> connects_levels)? stairs,
TResult Function(List<int> connects_levels)? lift,
TResult Function(List<String> bus_lines, List<String> tram_lines)?
@ -1415,7 +1251,6 @@ class _$StairsImpl implements Stairs {
required TResult Function(Room value) room,
required TResult Function(Door value) door,
required TResult Function(Toilet value) toilet,
required TResult Function(Entrance value) entrance,
required TResult Function(Stairs value) stairs,
required TResult Function(Lift value) lift,
required TResult Function(PublicTransport value) publicTransport,
@ -1431,7 +1266,6 @@ class _$StairsImpl implements Stairs {
TResult? Function(Room value)? room,
TResult? Function(Door value)? door,
TResult? Function(Toilet value)? toilet,
TResult? Function(Entrance value)? entrance,
TResult? Function(Stairs value)? stairs,
TResult? Function(Lift value)? lift,
TResult? Function(PublicTransport value)? publicTransport,
@ -1447,7 +1281,6 @@ class _$StairsImpl implements Stairs {
TResult Function(Room value)? room,
TResult Function(Door value)? door,
TResult Function(Toilet value)? toilet,
TResult Function(Entrance value)? entrance,
TResult Function(Stairs value)? stairs,
TResult Function(Lift value)? lift,
TResult Function(PublicTransport value)? publicTransport,
@ -1545,7 +1378,6 @@ class _$LiftImpl implements Lift {
required TResult Function() room,
required TResult Function(List<String> connects) door,
required TResult Function(String toilet_type) toilet,
required TResult Function() entrance,
required TResult Function(List<int> connects_levels) stairs,
required TResult Function(List<int> connects_levels) lift,
required TResult Function(List<String> bus_lines, List<String> tram_lines)
@ -1562,7 +1394,6 @@ class _$LiftImpl implements Lift {
TResult? Function()? room,
TResult? Function(List<String> connects)? door,
TResult? Function(String toilet_type)? toilet,
TResult? Function()? entrance,
TResult? Function(List<int> connects_levels)? stairs,
TResult? Function(List<int> connects_levels)? lift,
TResult? Function(List<String> bus_lines, List<String> tram_lines)?
@ -1579,7 +1410,6 @@ class _$LiftImpl implements Lift {
TResult Function()? room,
TResult Function(List<String> connects)? door,
TResult Function(String toilet_type)? toilet,
TResult Function()? entrance,
TResult Function(List<int> connects_levels)? stairs,
TResult Function(List<int> connects_levels)? lift,
TResult Function(List<String> bus_lines, List<String> tram_lines)?
@ -1600,7 +1430,6 @@ class _$LiftImpl implements Lift {
required TResult Function(Room value) room,
required TResult Function(Door value) door,
required TResult Function(Toilet value) toilet,
required TResult Function(Entrance value) entrance,
required TResult Function(Stairs value) stairs,
required TResult Function(Lift value) lift,
required TResult Function(PublicTransport value) publicTransport,
@ -1616,7 +1445,6 @@ class _$LiftImpl implements Lift {
TResult? Function(Room value)? room,
TResult? Function(Door value)? door,
TResult? Function(Toilet value)? toilet,
TResult? Function(Entrance value)? entrance,
TResult? Function(Stairs value)? stairs,
TResult? Function(Lift value)? lift,
TResult? Function(PublicTransport value)? publicTransport,
@ -1632,7 +1460,6 @@ class _$LiftImpl implements Lift {
TResult Function(Room value)? room,
TResult Function(Door value)? door,
TResult Function(Toilet value)? toilet,
TResult Function(Entrance value)? entrance,
TResult Function(Stairs value)? stairs,
TResult Function(Lift value)? lift,
TResult Function(PublicTransport value)? publicTransport,
@ -1751,7 +1578,6 @@ class _$PublicTransportImpl implements PublicTransport {
required TResult Function() room,
required TResult Function(List<String> connects) door,
required TResult Function(String toilet_type) toilet,
required TResult Function() entrance,
required TResult Function(List<int> connects_levels) stairs,
required TResult Function(List<int> connects_levels) lift,
required TResult Function(List<String> bus_lines, List<String> tram_lines)
@ -1768,7 +1594,6 @@ class _$PublicTransportImpl implements PublicTransport {
TResult? Function()? room,
TResult? Function(List<String> connects)? door,
TResult? Function(String toilet_type)? toilet,
TResult? Function()? entrance,
TResult? Function(List<int> connects_levels)? stairs,
TResult? Function(List<int> connects_levels)? lift,
TResult? Function(List<String> bus_lines, List<String> tram_lines)?
@ -1785,7 +1610,6 @@ class _$PublicTransportImpl implements PublicTransport {
TResult Function()? room,
TResult Function(List<String> connects)? door,
TResult Function(String toilet_type)? toilet,
TResult Function()? entrance,
TResult Function(List<int> connects_levels)? stairs,
TResult Function(List<int> connects_levels)? lift,
TResult Function(List<String> bus_lines, List<String> tram_lines)?
@ -1806,7 +1630,6 @@ class _$PublicTransportImpl implements PublicTransport {
required TResult Function(Room value) room,
required TResult Function(Door value) door,
required TResult Function(Toilet value) toilet,
required TResult Function(Entrance value) entrance,
required TResult Function(Stairs value) stairs,
required TResult Function(Lift value) lift,
required TResult Function(PublicTransport value) publicTransport,
@ -1822,7 +1645,6 @@ class _$PublicTransportImpl implements PublicTransport {
TResult? Function(Room value)? room,
TResult? Function(Door value)? door,
TResult? Function(Toilet value)? toilet,
TResult? Function(Entrance value)? entrance,
TResult? Function(Stairs value)? stairs,
TResult? Function(Lift value)? lift,
TResult? Function(PublicTransport value)? publicTransport,
@ -1838,7 +1660,6 @@ class _$PublicTransportImpl implements PublicTransport {
TResult Function(Room value)? room,
TResult Function(Door value)? door,
TResult Function(Toilet value)? toilet,
TResult Function(Entrance value)? entrance,
TResult Function(Stairs value)? stairs,
TResult Function(Lift value)? lift,
TResult Function(PublicTransport value)? publicTransport,

View File

@ -1,10 +1,10 @@
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:yaml/yaml.dart';
Result<Feature> parseFeature(
Map<String, dynamic> properties, dynamic geometry) {
Map<String, dynamic> properties, GeoJSONGeometry geometry) {
final name = properties['name'] as String?;
final description_yaml = properties['description'] as String? ?? '';
final layer = properties['layer'] as String?;
@ -36,6 +36,8 @@ Result<Feature> parseFeature(
yaml = yaml as YamlMap? ?? {};
final description = yaml['desription'] as String?;
final building = yaml['building'] as String?;
print("yaml: $yaml");
var raw_type = yaml['type'] as String?;
@ -105,6 +107,7 @@ Result<Feature> parseFeature(
description: description,
geometry: geometry,
level: level,
building: building,
));
}

View File

@ -18,24 +18,17 @@ class MyApp extends StatelessWidget {
return GetMaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// TRY THIS: Try running your application with "flutter run". You'll see
// the application has a purple toolbar. Then, without quitting the app,
// try changing the seedColor in the colorScheme below to Colors.green
// and then invoke "hot reload" (save your changes or press the "hot
// reload" button in a Flutter-supported IDE, or press "r" if you used
// the command line to start the app).
//
// Notice that the counter didn't reset back to zero; the application
// state is not lost during the reload. To reset the state, use hot
// restart instead.
//
// This works for code too, not just values: Most code changes can be
// tested with just a hot reload.
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
darkTheme: ThemeData.dark(
useMaterial3: true,
).copyWith(
colorScheme: ColorScheme.fromSeed(
brightness: Brightness.dark,
seedColor: Colors.deepPurple,
),
),
initialRoute: '/map',
getPages: [
GetPage(name: '/map', page: () => const MapPage()),
@ -44,91 +37,3 @@ class MyApp extends StatelessWidget {
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// TRY THIS: Try changing the color here to a specific color (to
// Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
// change color while the other colors stay the same.
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
// Column is also a layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
//
// TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint"
// action in the IDE, or press "p" in the console), to see the
// wireframe for each widget.
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}

View File

@ -2,14 +2,15 @@ import 'package:anim_search_bar/anim_search_bar.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_map/plugin_api.dart';
import 'package:get/get.dart';
import 'package:latlong2/latlong.dart';
import 'package:rust_core/slice.dart';
import 'package:uninav/components/drawer.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/data/geo/model.dart';
import 'package:uninav/util/geojson_util.dart';
import 'package:uninav/util/geomath.dart';
import 'package:url_launcher/url_launcher.dart';
@ -18,6 +19,7 @@ class MapPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final LayerHitNotifier hitNotifier = ValueNotifier(null);
return Scaffold(
drawer: MyDrawer(),
appBar: AppBar(
@ -49,66 +51,66 @@ class MapPage extends StatelessWidget {
body: Stack(
children: [
FlutterMap(
mapController: MapController(),
mapController: Get.find<MyMapController>().mapController,
options: MapOptions(
center: LatLng(48.422766, 9.9564),
zoom: 16.0,
initialCenter: const LatLng(48.422766, 9.9564),
initialZoom: 16.0,
// camera constraints
maxZoom: 19,
onTap: (tapPosition, point) {
print('Tap: $tapPosition, $point');
Get.find<MyMapController>().handleTap(tapPosition, point);
},
),
children: [
TileLayer(
urlTemplate: "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
maxZoom: 19,
),
// buildings
LevelLayer(
filter: (feature) => feature.type is Building,
TranslucentPointer(
child: 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,
builder: (cx) => const Center(
child: Icon(
TranslucentPointer(
child: 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,
),
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')),
// )
// ]),
children: renderLevel(
Get.find<MyMapController>().currentLevel.value,
hitNotifier: hitNotifier)),
),
],
),
Positioned(
@ -152,251 +154,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

@ -0,0 +1,96 @@
import 'package:geojson_vi/geojson_vi.dart';
import 'package:latlong2/latlong.dart';
import 'dart:math';
void swapLatLonGeojsonGeometry(GeoJSONGeometry geometry) {
if (geometry is GeoJSONPolygon) {
geometry.coordinates[0] =
geometry.coordinates[0].map((e) => [e[1], e[0]]).toList();
} else if (geometry is GeoJSONPoint) {
geometry.coordinates = [geometry.coordinates[1], geometry.coordinates[0]];
} else {
throw UnimplementedError(
"Geometry of type ${geometry.runtimeType} point swapping is unimplemented");
}
}
List<double> latLonToGeoJSON(LatLng point) {
return [point.longitude, point.latitude];
}
LatLng geoJSONToLatLon(List<double> point) {
return LatLng(point[1], point[0]);
}
double degreesToRadians(double degrees) {
return degrees * (pi / 180);
}
double radiansToDegrees(double radians) {
return radians * (180 / pi);
}
double bearingBetweenLatLng(LatLng point1, LatLng point2) {
return bearingBetween(
point1.latitude,
point1.longitude,
point2.latitude,
point2.longitude,
);
}
double bearingBetween(double lat1, double lon1, double lat2, double lon2) {
var dLon = degreesToRadians(lon2 - lon1);
var y = sin(dLon) * cos(degreesToRadians(lat2));
var x = cos(degreesToRadians(lat1)) * sin(degreesToRadians(lat2)) -
sin(degreesToRadians(lat1)) * cos(degreesToRadians(lat2)) * cos(dLon);
var angle = atan2(y, x);
return (radiansToDegrees(angle) + 360) % 360;
}
double distanceBetweenLatLng(LatLng point1, LatLng point2, String unit) {
return distanceBetween(point1.latitude, point1.longitude, point2.latitude,
point2.longitude, unit);
}
double distanceBetween(
double lat1, double lon1, double lat2, double lon2, String unit) {
const earthRadius = 6371; // in km
// assuming earth is a perfect sphere(it's not)
// Convert degrees to radians
final lat1Rad = degreesToRadians(lat1);
final lon1Rad = degreesToRadians(lon1);
final lat2Rad = degreesToRadians(lat2);
final lon2Rad = degreesToRadians(lon2);
final dLat = lat2Rad - lat1Rad;
final dLon = lon2Rad - lon1Rad;
// Haversine formula
final a = pow(sin(dLat / 2), 2) +
cos(lat1Rad) * cos(lat2Rad) * pow(sin(dLon / 2), 2);
final c = 2 * atan2(sqrt(a), sqrt(1 - a));
final distance = earthRadius * c;
return toRequestedUnit(unit, distance);
// return distance; // in km
}
double toRequestedUnit(String unit, double distanceInKm) {
switch (unit) {
case 'kilometers':
return distanceInKm;
case 'meters':
return distanceInKm * 1000;
case 'miles':
return (distanceInKm * 1000) / 1609.344;
case 'yards':
return distanceInKm * 1093.61;
case '':
return distanceInKm;
}
return distanceInKm;
}

View File

@ -35,3 +35,24 @@ LatLng polygonCenterAvg(List<LatLng> polygon) {
return LatLng(centerLat, centerLng);
}
bool isPointInPolygonRaycast(LatLng point, List<LatLng> polygon) {
bool inside = false;
int len = polygon.length;
for (int i = 0, j = len - 1; i < len; j = i++) {
LatLng pi = polygon[i];
LatLng pj = polygon[j];
if (((pi.latitude > point.latitude) != (pj.latitude > point.latitude)) &&
(point.longitude <
(pj.longitude - pi.longitude) *
(point.latitude - pi.latitude) /
(pj.latitude - pi.latitude) +
pi.longitude)) {
inside = !inside;
}
}
return inside;
}

67
lib/util/util.dart Normal file
View File

@ -0,0 +1,67 @@
import 'package:uninav/data/geo/model.dart';
String formatDuration(Duration duration) {
final days = duration.inDays;
final hours = duration.inHours.remainder(24);
final minutes = duration.inMinutes.remainder(60);
final seconds = duration.inSeconds.remainder(60);
String plural(int thing) => thing == 1 ? '' : 's';
if (days > 0) {
return '$days day${plural(days)}, $hours hour${plural(hours)}';
} else if (hours > 0) {
return '$hours hour${plural(hours)}, $minutes minute${plural(minutes)}';
} else if (minutes > 0) {
return '$minutes minute${plural(minutes)}, $seconds second${plural(seconds)}';
} else {
return '$seconds second${plural(seconds)}';
}
}
String formatFeatureTitle(Feature feature) {
return feature.type.when(
building: () => '${feature.name} (Building)',
lectureHall: () => '${feature.name} (Lecture Hall)',
room: () => 'Room ${feature.name}',
door: (_) => 'Door',
toilet: (type) => 'Toilet (${formatToiletType(feature.type as Toilet)})',
stairs: (_) => 'Stairs',
lift: (_) => 'Lift',
publicTransport: (_, __) => 'Public Transport',
);
}
String formatToiletType(Toilet toilet) {
final type = toilet.toilet_type.toLowerCase();
switch (type) {
case 'male':
return 'Male';
case 'female':
return 'Female';
case 'handicap':
return 'Handicap';
default:
return 'Unknown';
}
}
String formatDistance(int distanceInMeters) {
if (distanceInMeters < 1000) {
// If the distance is less than 1 kilometer, display it in meters.
return '${distanceInMeters}m';
} else {
// If the distance is 1 kilometer or more, display it in kilometers and meters.
final kilometers =
distanceInMeters ~/ 1000; // Integer division to get whole kilometers.
final meters =
distanceInMeters % 1000; // Remainder to get the remaining meters.
if (meters == 0) {
// If there are no remaining meters, display only kilometers.
return '${kilometers}km';
} else {
// If there are remaining meters, display both kilometers and meters.
return '${kilometers}km ${meters}m';
}
}
}

View File

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

View File

@ -38,9 +38,12 @@ dependencies:
get: ^4.6.6
yaml: ^3.1.2
surrealdb: ^0.8.0
geojson: ^1.0.0
# geojson: ^1.0.0
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
anim_search_bar: ^2.0.3
freezed_annotation: ^2.4.1