====== std.geo ====== Geografische Koordinaten im WGS-84-System als ''GeoPoint'' (Längengrad/Breitengrad in Mikro-Grad: 1 Grad = 1.000.000 Einheiten). Berechnet Abstände über die Haversine-Formel (sphärische Erde, Erdradius 6.371.000 m), Peilung (''Bearing''), Mittelpunkte, Bounding-Boxes und prüft Punkt-in-Rechteck. Unterstützt DMS-Format (Grad, Minuten, Sekunden) und Umrechnung. Einsatzbereiche: Standortdienste, Kartenanwendungen, Geo-Fencing, Umkreissuche (SEO-Local-Pack), Routenberechnungen, Point-of-Interest-Filterung. **Autor:** Andreas Röne\\ **Copyright:** 2024-2025 Andreas Röne ---- ===== Typen ===== ==== GeoPoint (struct) ==== ^ Feld ^ Typ ^ Bedeutung ^ | ''x'' | ''int64'' | Längengrad in Mikro-Grad (1 Grad = 1.000.000) | | ''y'' | ''int64'' | Breitengrad in Mikro-Grad | ==== GeoBBox (struct) ==== Achsenparallele Bounding-Box. Felder sind flach (keine verschachtelten Structs — von Lyx nicht unterstützt); Min-/Max-GeoPoint über ''GeoBBoxGetMin''/''GeoBBoxGetMax'' extrahieren. ^ Feld ^ Typ ^ Bedeutung ^ | ''minX'' | ''int64'' | Minimaler Längengrad (Mikro-Grad) | | ''minY'' | ''int64'' | Minimaler Breitengrad (Mikro-Grad) | | ''maxX'' | ''int64'' | Maximaler Längengrad (Mikro-Grad) | | ''maxY'' | ''int64'' | Maximaler Breitengrad (Mikro-Grad) | ---- ===== Konstanten ===== ^ Name ^ Typ ^ Wert ^ Sichtbarkeit ^ ---- ===== Funktionen ===== ^ Signatur ^ Sichtbarkeit ^ Beschreibung ^ | ''ParseLat(s: pchar): int64'' | pub | Parst Breitengrad-String zu Mikro-Grad | | ''ParseLon(s: pchar): int64'' | pub | Parst Längengrad-String zu Mikro-Grad | | ''FormatDecimal(coord: int64): pchar'' | pub | Formatiert Mikro-Grad als Dezimalstring | | ''IsValidLat(lat: int64): bool'' | pub | Prüft Breitengrad auf WGS-84-Gültigkeit | | ''IsValidLon(lon: int64): bool'' | pub | Prüft Längengrad auf WGS-84-Gültigkeit | | ''IsValidGeoPoint(p: GeoPoint): bool'' | pub | Prüft GeoPoint auf gültige Koordinaten | | ''GeoPointNew(lon: int64, lat: int64): GeoPoint'' | pub | Erstellt neuen GeoPoint aus Koordinaten | | ''DistanceM(p1: GeoPoint, p2: GeoPoint): int64'' | pub | Berechnet Abstand in Metern (Haversine) | | ''DistanceMLegacy(lat1: int64, lon1: int64, lat2: int64, lon2: int64): int64'' | pub | Berechnet Abstand aus Einzelkoordinaten | | ''DistanceKm(p1: GeoPoint, p2: GeoPoint): int64'' | pub | Berechnet Abstand in Kilometern | | ''DistanceSq(p1: GeoPoint, p2: GeoPoint): int64'' | pub | Berechnet quadratischen Näherungsabstand | | ''IsWithinDistanceM(p1: GeoPoint, p2: GeoPoint, thresholdM: int64): bool'' | pub | Prüft ob Abstand unter Schwellenwert liegt | | ''Midpoint(p1: GeoPoint, p2: GeoPoint): GeoPoint'' | pub | Berechnet geografischen Mittelpunkt zweier Punkte | | ''MidpointLat(lat1: int64, lat2: int64): int64'' | pub | Berechnet Mittel-Breitengrad | | ''MidpointLon(lon1: int64, lon2: int64): int64'' | pub | Berechnet Mittel-Längengrad | | ''IsPointInRect(p: GeoPoint, min: GeoPoint, max: GeoPoint): bool'' | pub | Prüft ob Punkt in Bounding-Box liegt | | ''BoundingBoxMin(p1: GeoPoint, p2: GeoPoint): GeoPoint'' | pub | Berechnet Minimaleckpunkt der Bounding-Box | | ''BoundingBoxMax(p1: GeoPoint, p2: GeoPoint): GeoPoint'' | pub | Berechnet Maximaleckpunkt der Bounding-Box | | ''DoBoundingBoxesOverlap(min1: GeoPoint, max1: GeoPoint, min2: GeoPoint, max2: GeoPoint): bool'' | pub | Prüft Überschneidung zweier Bounding-Boxes | | ''BoundingBoxCenter(min: GeoPoint, max: GeoPoint): GeoPoint'' | pub | Berechnet Mittelpunkt einer Bounding-Box | | ''Bearing(p1: GeoPoint, p2: GeoPoint): int64'' | pub | Berechnet Peilwinkel zwischen zwei Punkten | | ''HaversineDistanceM(p1: GeoPoint, p2: GeoPoint): int64'' | pub | Berechnet Haversine-Abstand in Metern | | ''ParseDMS(degrees: int64, minutes: int64, seconds: int64, direction: int64): int64'' | pub | Parst Grad-Minuten-Sekunden zu Mikro-Grad | | ''FormatDMS(coord: int64, isLatitude: bool): pchar'' | pub | Formatiert Koordinate als DMS-String | | ''IsPointInRect2(p: GeoPoint, minLat: int64, minLon: int64, maxLat: int64, maxLon: int64): bool'' | pub | Prüft Punkt gegen explizite Bounding-Box | | ''CalculateBoundingBoxMin(center: GeoPoint, radiusM: int64): GeoPoint'' | pub | Berechnet Min-Eckpunkt für Umkreis | | ''CalculateBoundingBoxMax(center: GeoPoint, radiusM: int64): GeoPoint'' | pub | Berechnet Max-Eckpunkt für Umkreis | | ''AddOffsetM(center: GeoPoint, bearing: int64, distanceM: int64): GeoPoint'' | pub | Verschiebt GeoPoint um Distanz in Richtung | | ''CorrectLongitudeForLatitude(dLon: int64, lat: int64): int64'' | pub | Korrigiert Längengrad-Delta für Breite | | ''DistanceMCorrected(p1: GeoPoint, p2: GeoPoint): int64'' | pub | Berechnet breitengradkorrigierten Abstand | | ''BoundingBoxFromPoints(p1: GeoPoint, p2: GeoPoint): GeoBBox'' | pub | Kleinste Bounding-Box um zwei Punkte | | ''CalculateBoundingBox(center: GeoPoint, radiusM: int64): GeoBBox'' | pub | Bounding-Box um Mittelpunkt mit Radius in Metern | | ''GeoBBoxGetMin(bb: GeoBBox): GeoPoint'' | pub | Extrahiert Min-Eckpunkt (''minX''/''minY'') als ''GeoPoint'' | | ''GeoBBoxGetMax(bb: GeoBBox): GeoPoint'' | pub | Extrahiert Max-Eckpunkt (''maxX''/''maxY'') als ''GeoPoint'' | | ''GeoBBoxContains(bb: GeoBBox, p: GeoPoint): bool'' | pub | Prüft ob Punkt innerhalb der Bounding-Box liegt | | ''GeoBBoxOverlaps(a: GeoBBox, b: GeoBBox): bool'' | pub | Prüft ob zwei Bounding-Boxes sich überschneiden | | ''GeoBBoxCenter(bb: GeoBBox): GeoPoint'' | pub | Berechnet Mittelpunkt einer Bounding-Box | ---- ===== Hinweise ===== * **GeoBBox vs. alte BoundingBox-Helfer**: Die Funktionen ''BoundingBoxMin''/''BoundingBoxMax''/''DoBoundingBoxesOverlap''/''BoundingBoxCenter'' arbeiten mit zwei losen ''GeoPoint''-Argumenten. ''GeoBBox'' ist eine zusammengesetzte Struktur — bevorzuge die ''GeoBBox...''-API für neuen Code. * **Flache Felder**: Lyx unterstützt keine Structs als Struct-Felder. ''GeoBBox'' speichert deshalb ''minX''/''minY''/''maxX''/''maxY'' direkt als ''int64''. ''GeoBBoxGetMin(bb)'' und ''GeoBBoxGetMax(bb)'' bauen daraus einen ''GeoPoint''. * **GeoPoint anlegen**: Immer ''GeoPointNew(lon, lat)'' verwenden — keine Struct-Literal-Syntax (''GeoPoint{x:…}'' ist ein Compiler-Fehler). Reihenfolge: **Lon zuerst, dann Lat** (x = Längengrad, y = Breitengrad). * **Mikro-Grad-Divisor**: Distanzberechnungen dividieren intern durch ''1.000.000'' (Mikro-Grad → Grad). Ältere Code-Versionen verwendeten fälschlicherweise ''/ 1000'' — das erzeugte Werte um Faktor 1000 zu groß. * **CalculateBoundingBox vs. CalculateBoundingBoxMin/Max**: ''CalculateBoundingBox'' gibt eine vollständige ''GeoBBox'' in einem Aufruf zurück; ''CalculateBoundingBoxMin''/''Max'' sind die Einzelfunktionen für Min- bzw. Max-Eckpunkt.