uninav/lib/data/geo/model.dart

125 lines
4.0 KiB
Dart
Raw Permalink Normal View History

2024-04-20 14:32:01 +00:00
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_vi/geojson_vi.dart';
2024-04-20 14:32:01 +00:00
import 'package:latlong2/latlong.dart';
2024-04-20 22:35:16 +00:00
import 'package:uninav/util/geojson_util.dart';
import 'package:uninav/util/geomath.dart';
2024-04-20 14:32:01 +00:00
part 'model.freezed.dart';
@freezed
class Feature with _$Feature {
const Feature._();
const factory Feature({
required String name,
required FeatureType type,
String? description,
required GeoJSONGeometry geometry,
2024-04-20 14:32:01 +00:00
int? level,
2024-04-20 22:35:16 +00:00
String? building,
required String id,
2024-04-20 14:32:01 +00:00
}) = _Feature;
bool isPolygon() {
return geometry is GeoJSONPolygon;
2024-04-20 14:32:01 +00:00
}
bool isPoint() {
return geometry is GeoJSONPoint;
2024-04-20 14:32:01 +00:00
}
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 GeoJSONPolygon;
2024-04-20 14:32:01 +00:00
// print(polygon.geometry!.geoSeries[0].geoPoints);
final points =
// polygon.coordinates[0].map((e) => LatLng(e[0], e[1])).toList();
2024-04-20 22:35:16 +00:00
polygon.coordinates[0].map(geoJSONToLatLon).toList();
2024-04-20 14:32:01 +00:00
// print(points);
return Ok(constructor(points));
} else {
return bail("Feature Geometry is not a Polygon");
}
}
Result<LatLng> getPoint() {
if (isPoint()) {
final point = geometry as GeoJSONPoint;
2024-04-20 22:35:16 +00:00
return Ok(geoJSONToLatLon(point.coordinates));
2024-04-20 14:32:01 +00:00
} else {
return bail("Feature Geometry is not a Point");
}
}
2024-04-20 22:35:16 +00:00
/// 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");
}
}
2024-04-21 14:27:48 +00:00
String? get buildingName => type.when(
building: () => name,
lectureHall: () => building,
room: (_) => building,
door: (_) => null,
toilet: (_) => building,
stairs: (_) => building,
lift: (_) => building,
foodDrink: () => building,
publicTransport: (_, __) => null,
pcPool: (_) => building,
);
2024-04-20 14:32:01 +00:00
}
@freezed
class FeatureType with _$FeatureType {
// multiple feature types like lecture hall, toliet, ...
const factory FeatureType.building() = Building;
const factory FeatureType.lectureHall() = LectureHall;
2024-04-21 12:21:31 +00:00
const factory FeatureType.room(String roomNumber) = Room;
2024-04-20 14:32:01 +00:00
const factory FeatureType.door(List<String> connects) = Door;
const factory FeatureType.toilet(String toilet_type) = Toilet;
const factory FeatureType.stairs(List<int> connects_levels) = Stairs;
const factory FeatureType.lift(List<int> connects_levels) = Lift;
2024-04-21 12:21:31 +00:00
const factory FeatureType.foodDrink() = FoodDrink;
2024-04-20 14:32:01 +00:00
const factory FeatureType.publicTransport(
List<String> bus_lines, List<String> tram_lines) = PublicTransport;
2024-04-21 12:21:31 +00:00
const factory FeatureType.pcPool(String roomNumber) = PcPool;
2024-04-20 14:32:01 +00:00
}