Compare commits
2 Commits
be359980bb
...
13327da5de
Author | SHA1 | Date | |
---|---|---|---|
13327da5de | |||
b7487fc25e |
2293
assets/geo/uulm_beta copy.geojson
Normal file
2293
assets/geo/uulm_beta copy.geojson
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
46
lib/components/colorful_chips.dart
Normal file
46
lib/components/colorful_chips.dart
Normal 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,
|
||||
);
|
||||
}
|
||||
}
|
184
lib/components/feature_bottom_sheet.dart
Normal file
184
lib/components/feature_bottom_sheet.dart
Normal 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(),
|
||||
),
|
||||
),
|
||||
],
|
||||
];
|
||||
}
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
));
|
||||
}
|
||||
|
||||
|
111
lib/main.dart
111
lib/main.dart
@ -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.
|
||||
);
|
||||
}
|
||||
}
|
||||
|
328
lib/map.dart
328
lib/map.dart
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
96
lib/util/geojson_util.dart
Normal file
96
lib/util/geojson_util.dart
Normal 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;
|
||||
}
|
@ -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
67
lib/util/util.dart
Normal 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';
|
||||
}
|
||||
}
|
||||
}
|
92
pubspec.lock
92
pubspec.lock
@ -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:
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user