Terepbejárás: geometriák hosszának és területének számítása és jelzése
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:latlong2/latlong.dart';
|
||||
|
||||
class GeometryMeasure {
|
||||
static final Distance _distance = const Distance();
|
||||
|
||||
static double lineLengthMeters(List<LatLng> 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<LatLng> 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<LatLng> _normalizedPolygon(List<LatLng> source) {
|
||||
final points = List<LatLng>.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<LatLng> 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);
|
||||
}
|
||||
Reference in New Issue
Block a user