feat: major progress
This commit is contained in:
@ -1,13 +1,20 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:anyhow/anyhow.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,6 +47,39 @@ 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);
|
||||
@ -67,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);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user