break up map_view

This commit is contained in:
stopflock committed 2025-08-21 19:15:59 -05:00
1 parent 4cc8929378
commit 1272eb9409
4 files changed
+298 -199

No files matched your search

+76
View File
@@ -0,0 +1,76 @@
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import '../../app_state.dart';
import '../../dev_config.dart';
import '../../models/osm_camera_node.dart';
/// Helper class to build direction cone polygons for cameras
class DirectionConesBuilder {
static List<Polygon> buildDirectionCones({
required List<OsmCameraNode> cameras,
required double zoom,
AddCameraSession? session,
}) {
final overlays = <Polygon>[];
// Add session cone if in add-camera mode
if (session != null && session.target != null) {
overlays.add(_buildCone(
session.target!,
session.directionDegrees,
zoom,
));
}
// Add cones for cameras with direction
overlays.addAll(
cameras
.where((n) => n.hasDirection && n.directionDeg != null)
.where((n) => n.coord.latitude != 0 || n.coord.longitude != 0)
.where((n) => n.coord.latitude.abs() <= 90 && n.coord.longitude.abs() <= 180)
.map((n) => _buildCone(
n.coord,
n.directionDeg!,
zoom,
isPending: n.tags.containsKey('_pending_upload') &&
n.tags['_pending_upload'] == 'true',
))
);
return overlays;
}
static Polygon _buildCone(
LatLng origin,
double bearingDeg,
double zoom, {
bool isPending = false,
}) {
final halfAngle = kDirectionConeHalfAngle;
final length = kDirectionConeBaseLength * math.pow(2, 15 - zoom);
LatLng project(double deg) {
final rad = deg * math.pi / 180;
final dLat = length * math.cos(rad);
final dLon =
length * math.sin(rad) / math.cos(origin.latitude * math.pi / 180);
return LatLng(origin.latitude + dLat, origin.longitude + dLon);
}
final left = project(bearingDeg - halfAngle);
final right = project(bearingDeg + halfAngle);
// Use purple color for pending uploads
final color = isPending ? Colors.purple : Colors.redAccent;
return Polygon(
points: [origin, left, right, origin],
color: color.withOpacity(0.25),
borderColor: color,
borderStrokeWidth: 1,
);
}
}