110 lines
3.2 KiB
Ada
110 lines
3.2 KiB
Ada
package Grl.Coordinates with
|
|
SPARK_Mode => On
|
|
is
|
|
|
|
-- ------------ --
|
|
-- Helper Units --
|
|
-- ------------ --
|
|
|
|
-- DD Meter Scale
|
|
type DD_Meter_Scale_Lat is delta 1.0E-5 range -90.0 .. 90.0;
|
|
type DD_Meter_Scale_Lon is delta 1.0E-5 range -180.0 .. 180.0;
|
|
|
|
-- DD Centimeter Scale
|
|
type DD_Centimeter_Scale_Lat is delta 1.0E-7 range -90.0 .. 90.0;
|
|
type DD_Centimeter_Scale_Lon is delta 1.0E-7 range -180.0 .. 180.0;
|
|
|
|
-- DM Scale
|
|
type DM_Degree_Lat is range 0 .. 90;
|
|
type DM_Degree_Lon is range 0 .. 180;
|
|
-- 1° = 60'; each Lat minute = 1.852km / 1 Naut Mile
|
|
type DM_Minutes is range 0 .. 60;
|
|
-- 1° = 60'; each Lat minute = 1.852km / 1 Naut Mile
|
|
type DDM_Minutes is delta 1.0E-3 range 0.0 .. 60.000;
|
|
-- 1' = 60''; 1° = 3600''; 1'' ~ 30.9m
|
|
type DM_Seconds is delta 1.0E-1 range 0.0 .. 60.0;
|
|
|
|
-- Cardinal directions
|
|
type Cardinal is (North, South, East, West);
|
|
type Ordinal is (North_East, South_East, South_West, North_West);
|
|
|
|
-- ------------------ --
|
|
-- Coordinate Formats --
|
|
-- ------------------ --
|
|
|
|
-- Meter precision DD coordinates
|
|
type Format_DD is record
|
|
Latitude : DD_Meter_Scale_Lat;
|
|
Longitude : DD_Meter_Scale_Lon;
|
|
end record;
|
|
|
|
-- Centimeter precision DD coordinates
|
|
type Format_DD_Fine is record
|
|
Latitude : DD_Centimeter_Scale_Lat;
|
|
Longitude : DD_Centimeter_Scale_Lon;
|
|
end record;
|
|
|
|
-- DMS
|
|
type Format_DMS is record
|
|
Degree_Lat : DM_Degree_Lat;
|
|
Degree_Lon : DM_Degree_Lon;
|
|
Minutes_Lat : DM_Minutes;
|
|
Minutes_Lon : DM_Minutes;
|
|
Seconds_Lat : DM_Seconds;
|
|
Seconds_Lon : DM_Seconds;
|
|
Cardinal_Lat : Cardinal;
|
|
Cardinal_Lon : Cardinal;
|
|
end record with
|
|
Dynamic_Predicate =>
|
|
Format_DMS.Cardinal_Lat in North | South
|
|
and then Format_DMS.Cardinal_Lon in East | West;
|
|
|
|
-- DDM
|
|
type Format_DDM is record
|
|
Degree_Lat : DM_Degree_Lat;
|
|
Degree_Lon : DM_Degree_Lon;
|
|
Minutes_Lat : DDM_Minutes;
|
|
Minutes_Lon : DDM_Minutes;
|
|
Cardinal_Lat : Cardinal;
|
|
Cardinal_Lon : Cardinal;
|
|
end record with
|
|
Dynamic_Predicate =>
|
|
Format_DDM.Cardinal_Lat in North | South
|
|
and then Format_DDM.Cardinal_Lon in East | West;
|
|
|
|
-- -------------------------- --
|
|
-- Coordinate Type Definition --
|
|
-- -------------------------- --
|
|
|
|
type Format is (Relative, DD, DD_Fine, DMS, DDM);
|
|
type Coordinate (Form : Format := Relative) is record
|
|
case Form is
|
|
when Relative =>
|
|
null;
|
|
when DD =>
|
|
DD : Format_DD;
|
|
when DD_Fine =>
|
|
DD_Fine : Format_DD_Fine;
|
|
when DMS =>
|
|
DMS : Format_DMS;
|
|
when DDM =>
|
|
DDM : Format_DDM;
|
|
end case;
|
|
end record;
|
|
|
|
-- ---------------------------- --
|
|
-- Converter / helper functions --
|
|
-- ---------------------------- --
|
|
|
|
-- Converter with DD target
|
|
-- @name To_DD
|
|
-- @return Coordinate
|
|
-- @parameter DM_Base : Coordinate
|
|
-- @description Take any coordinate and return a DD formatted coordinate.
|
|
function To_DD (DM_Base : Coordinate) return Coordinate with
|
|
Pre =>
|
|
(DM_Base.Form = DD) or else (DM_Base.Form = DMS)
|
|
or else (DM_Base.Form = DDM);
|
|
|
|
end Grl.Coordinates;
|