uninav/lib/components/map_render_level.dart

354 lines
10 KiB
Dart

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';
import 'package:uninav/controllers/map_controller.dart';
import 'package:uninav/data/geo/model.dart';
import 'package:uninav/map.dart';
import 'package:uninav/util/geomath.dart';
import 'package:uninav/util/util.dart';
List<Widget> renderLevel(
int level,
) {
return <Widget>[
// Lecture Halls
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,
borderStrokeWidth: 2,
),
)
.unwrap(),
markerConstructor: (feature) => Marker(
width: 50,
height: 20,
point: feature.getPoint().unwrap(),
child: Column(
children: [
Icon(
Icons.class_,
color: Colors.black,
),
Text('${feature.name}'),
],
),
alignment: Alignment.center,
),
),
// Rooms (Seminar Rooms)
LevelLayer(
filter: (feature) => feature.level == level && feature.type is Room,
polyConstructor: (feature) => feature
.getPolygon(
constructor: (pts) => Polygon(
points: pts,
color: Colors.green.withOpacity(1.2),
borderColor: Colors.green,
borderStrokeWidth: 2,
),
)
.unwrap(),
markerConstructor: (feature) => Marker(
width: 100,
height: 70,
point: feature.getPoint().unwrap(),
child: Column(
children: [
const Icon(
Icons.co_present_rounded,
color: Colors.amber,
),
Text(
(feature.type as Room).roomNumber,
style: const TextStyle(color: Colors.black),
),
],
),
alignment: Alignment.center,
)),
// Doors Layer
LevelLayer(
filter: (feature) => feature.level == level && feature.type is Door,
markerConstructor: (feature) {
final point = feature.getPoint().unwrap();
return Marker(
width: 21,
height: 21,
point: point,
child: const Icon(
Icons.door_front_door,
color: Colors.brown,
),
alignment: Alignment.center,
);
},
),
// Food and Drink Layer
LevelLayer(
filter: (feature) => feature.level == level && feature.type is FoodDrink,
markerConstructor: (feature) {
final point = feature.getPoint().unwrap();
return Marker(
width: 21,
height: 21,
point: point,
child: const Icon(
Icons.restaurant,
color: Colors.deepOrange,
),
alignment: Alignment.center,
);
},
polyConstructor: (feature) => feature
.getPolygon(
constructor: (pts) => Polygon(
points: pts,
color: Colors.deepOrange.withOpacity(0.2),
borderColor: Colors.deepOrange,
borderStrokeWidth: 2,
),
)
.unwrap(),
),
// PC Pools layer
LevelLayer(
filter: (feature) => feature.level == level && feature.type is PcPool,
markerConstructor: (feature) {
final point = feature.getPoint().unwrap();
return Marker(
width: 100,
height: 70,
point: point,
child: Column(
children: [
const Icon(
Icons.computer,
color: Colors.cyan,
),
Text(
(feature.type as PcPool).roomNumber,
style: const TextStyle(color: Colors.black),
),
],
),
alignment: Alignment.center,
);
},
polyConstructor: (feature) => feature
.getPolygon(
constructor: (pts) => Polygon(
points: pts,
color: Colors.cyan.withOpacity(0.2),
borderColor: Colors.cyan,
borderStrokeWidth: 2,
),
)
.unwrap(),
),
// Toilets Layer
LevelLayer(
filter: (feature) => feature.level == level && feature.type is Toilet,
markerConstructor: (feature) {
final type = (feature.type as Toilet).toilet_type;
final point = feature.getPoint().unwrap();
return Marker(
width: 21,
height: 21,
point: point,
child: Icon(
findToiletIcon(type),
color: Colors.blue.shade700,
),
alignment: Alignment.center,
);
},
),
// Stairs layer
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: 21,
height: 21,
point: point,
child: Icon(
Icons.stairs_outlined,
color: Colors.deepPurple.shade300,
),
alignment: Alignment.center,
);
},
),
// Lift layer
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: 21,
height: 21,
point: point,
child: const Icon(
Icons.elevator_outlined,
color: Colors.deepPurple,
),
alignment: Alignment.center,
);
},
),
];
}
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(
constructor: (points) => Polygon(
points: points,
borderColor: Colors.black26,
borderStrokeWidth: 2.0,
))
.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,
child: Center(
child: Text(
feature.name,
style: const TextStyle(
color: Colors.black54,
// backgroundColor: Colors.white,
),
),
),
alignment: Alignment.center,
));
}
} 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,
child: Center(
child: Text(
feature.name,
style: const TextStyle(
color: Colors.black54,
// backgroundColor: Colors.white,
),
),
),
alignment: Alignment.center,
));
}
}
}
}
// print(filteredPolygons.length);
// print(filteredPolygons);
// 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(TranslucentPointer(
child: PolygonLayer(
polygons: filteredPolygons,
),
));
} else {
widgets.add(TranslucentPointer(
child: PolygonLayer(
polygons: filteredPolygons,
),
));
}
widgets.add(TranslucentPointer(
child: MarkerLayer(
markers: polygonCenterMarkers,
rotate: true,
),
));
}
if (filteredMarkers.isNotEmpty) {
widgets.add(TranslucentPointer(
child: MarkerLayer(markers: filteredMarkers, rotate: true),
));
}
return Stack(children: widgets);
});
}
}