import 'dart:math'; import 'package:latlong2/latlong.dart'; class GeometryMeasure { static final Distance _distance = const Distance(); static double lineLengthMeters(List points) { if (points.length < 2) return 0.0; double sum = 0.0; for (var i = 1; i < points.length; i++) { sum += _distance.as( LengthUnit.Meter, points[i - 1], points[i], ); } return sum; } static double polygonAreaSquareMeters(List points) { final polygon = _normalizedPolygon(points); if (polygon.length < 3) return 0.0; final origin = _centroid(polygon); final projected = polygon.map((p) => _projectToLocalMeters(p, origin)).toList(); double area = 0.0; for (var i = 0; i < projected.length; i++) { final j = (i + 1) % projected.length; area += projected[i].x * projected[j].y - projected[j].x * projected[i].y; } return area.abs() / 2.0; } static List _normalizedPolygon(List source) { final points = List.from(source); if (points.length < 2) return points; final first = points.first; final last = points.last; final closeDistance = _distance.as( LengthUnit.Meter, first, last, ); if (closeDistance < 0.01) { points.removeLast(); } return points; } static LatLng _centroid(List points) { double lat = 0.0; double lon = 0.0; for (final p in points) { lat += p.latitude; lon += p.longitude; } return LatLng( lat / points.length, lon / points.length, ); } static _Point2D _projectToLocalMeters( LatLng point, LatLng origin, ) { const earthRadius = 6378137.0; final latRad = point.latitude * pi / 180.0; final lonRad = point.longitude * pi / 180.0; final originLatRad = origin.latitude * pi / 180.0; final originLonRad = origin.longitude * pi / 180.0; final x = earthRadius * (lonRad - originLonRad) * cos(originLatRad); final y = earthRadius * (latRad - originLatRad); return _Point2D(x, y); } } class _Point2D { final double x; final double y; const _Point2D(this.x, this.y); }