Skip to content

Commit 4c94600

Browse files
authored
refactor: seperate coordinate system into coordinate representations, reference systems, frames (#25)
docs: add coordinate system terminology
1 parent d409be3 commit 4c94600

File tree

8 files changed

+121
-58
lines changed

8 files changed

+121
-58
lines changed

docs/Project.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
[deps]
2+
Chairmarks = "0ca39b1e-fe0b-4e98-acfc-b1656634c4de"
23
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
3-
SpaceDataModel = "0b37b92c-f0c5-4a52-bd5c-390dec20857c"
4+
SpaceDataModel = "0b37b92c-f0c5-4a52-bd5c-390dec20857c"

docs/make.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ makedocs(
1010
pages = [
1111
"Home" => "index.md",
1212
"Interface" => "interface.md",
13+
"Coordinate Systems" => "coordinate.md",
1314
"API" => "api.md",
1415
],
1516
checkdocs = :exports,

docs/src/coordinate.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Coordinate Systems
2+
3+
Similart to the definitions in [Astropy](https://docs.astropy.org/en/stable/coordinates/definitions.html): we adopt the following terminology:
4+
5+
- A **Coordinate Representation** (chart) is a particular way of describing a unique point in a vector space.
6+
Common ones include `Cartesian3`, `Spherical`, and `Geodetic` based on [`AbstractRepresentation`](@ref).
7+
- A **Reference System** is a scheme for orienting points in a space and describing how they transform to other systems.
8+
For example, the Earth-centered, Earth-fixed (ECEF) reference system tells you (i) origin at the geocenter, (ii) axes rotate with the Earth. But it does not uniquely specify: (i) whether Z is ITRF pole, [Conventional International Origin pole](https://www.wikiwand.com/en/articles/Conventional_International_Origin), "instantaneous rotation axis", etc (ii) whether the axes are aligned to a particular [geodetic datum](https://www.wikiwand.com/en/articles/Geodetic_datum).
9+
- A **Reference Frame** is a specific realization of a reference system (e.g., the [ICRF](https://www.wikiwand.com/en/articles/International_Celestial_Reference_System_and_its_realizations), or J2000 equatorial coordinates).
10+
For example, GEO is a simplified ECEF realization suitable for space-physics transformations (GEO↔GSE/GSM/SM/MAG). It differs from “true” geodesy realization like [ITRF](https://www.wikiwand.com/en/articles/International_Terrestrial_Reference_System_and_Frame) in that it ignores small corrections like polar motion and uses a simplified Earth rotation model.
11+
- A **Coordinate** is a combination of all of the above that specifies a unique point.
12+
13+
<!-- - A **Coordinate Transformation** is a mapping between different coordinate systems. -->
14+
15+
The package exports the following types [`AbstractReferenceSystem`](@ref), [`AbstractRepresentation`](@ref), [`AbstractReferenceFrame`](@ref), and [`AbstractCoordinateVector`](@ref):
16+
17+
And related functions:
18+
19+
- [`getcsys`](@ref): Function to retrieve the coordinate system from an object
20+
21+
22+
!!! note "Notes"
23+
Because of the ambiguity of meaning of "coordinate system", this term should be avoided wherever possible. However, for backward compatibility, we still export [`AbstractCoordinateSystem`](@ref) which serves a practical purpose of combining reference frame and coordinate representation.
24+
25+
## Implementation Approaches
26+
27+
Here we demonstrate two approaches to implementing coordinate vectors and their associated systems:
28+
29+
### Approach 1: Explicit Coordinate System Field
30+
31+
Store the coordinate system directly as a field in the vector type:
32+
33+
```@repl coord
34+
using SpaceDataModel: Cartesian3, AbstractReferenceFrame, AbstractCoordinateVector
35+
import SpaceDataModel: getcsys
36+
# Define a reference frame
37+
struct GEO <: AbstractReferenceFrame end
38+
39+
# Define a vector with an explicit reference frame and representation
40+
struct CoordinateVector{F, R, T} <: AbstractCoordinateVector
41+
x::T
42+
y::T
43+
z::T
44+
end
45+
46+
𝐫 = CoordinateVector{GEO, Cartesian3, Float64}(1, 2, 3)
47+
48+
# Implementation of getcsys
49+
getcsys(::CoordinateVector{F, R}) where {F, R} = (F(), R())
50+
getcsys(𝐫)
51+
```
52+
53+
### Approach 2: Implicit Coordinate System
54+
55+
Associate a specific coordinate system with a vector type:
56+
57+
```@repl coord
58+
# Define a vector type specific to a coordinate system
59+
struct GEOVector{D} <: AbstractCoordinateVector
60+
data::D
61+
end
62+
63+
# Implementation of getcsys returns the appropriate system
64+
getcsys(::GEOVector) = (GEO(), Cartesian3())
65+
𝐫2 = GEOVector([1, 2, 3])
66+
getcsys(𝐫2)
67+
```
68+
69+
Both approaches are highly efficient and provide equivalent performance due to Julia's type inference system.
70+
71+
```@example coord
72+
using Chairmarks
73+
@b getcsys($𝐫), getcsys($𝐫2)
74+
```
75+
76+
## Elsewhere
77+
78+
- [Astronomical Coordinate Systems (astropy.coordinates) — Astropy](https://docs.astropy.org/en/stable/coordinates/index.html)
79+
- [CoordRefSystems.jl](https://github.com/JuliaEarth/CoordRefSystems.jl) provides conversions between Coordinate Reference Systems (CRS) for cartography use cases.
80+
- [Geodesy.jl](https://github.com/JuliaGeo/Geodesy.jl) for working with points in various world and local coordinate systems.
81+
- [WCS.jl](https://juliaastro.org/WCS/stable/) : Astronomical World Coordinate System library

docs/src/interface.md

Lines changed: 1 addition & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -20,58 +20,4 @@ These functions are generic and can be extended to support custom data types.
2020
getmeta
2121
setmeta
2222
setmeta!
23-
```
24-
25-
## Coordinate Systems
26-
27-
The package exports three key components for coordinate system handling:
28-
29-
- [`AbstractCoordinateSystem`](@ref): Base abstract type for all coordinate system implementations
30-
- [`AbstractCoordinateVector`](@ref): Base abstract type to represent coordinates in a coordinate systems
31-
- [`getcsys`](@ref): Function to retrieve the coordinate system from an object
32-
33-
34-
There are two main approaches to implementing coordinate vectors and their associated systems:
35-
36-
### Approach 1: Explicit Coordinate System Field
37-
38-
Store the coordinate system directly as a field in the vector type:
39-
40-
```julia
41-
# Define a coordinate system
42-
struct GEO <: AbstractCoordinateSystem end
43-
44-
# Define a vector with an explicit coordinate system field
45-
struct CoordinateVector{D, T} <: AbstractCoordinateVector
46-
data::D
47-
csys::T
48-
end
49-
50-
# Implementation of getcsys simply returns the stored field
51-
getcsys(x::CoordinateVector) = x.csys
52-
```
53-
54-
### Approach 2: Implicit Coordinate System
55-
56-
Associate a specific coordinate system with a vector type:
57-
58-
```julia
59-
# Define a coordinate system
60-
struct GEO <: AbstractCoordinateSystem end
61-
62-
# Define a vector type specific to a coordinate system
63-
struct GEOVector{D} <: AbstractCoordinateVector
64-
data::D
65-
end
66-
67-
# Implementation of getcsys returns the appropriate system
68-
getcsys(x::GEOVector) = GEO()
69-
```
70-
71-
Both approaches are highly efficient and provide equivalent performance due to Julia's type inference system.
72-
73-
### Elsewhere
74-
75-
- [CoordRefSystems.jl](https://github.com/JuliaEarth/CoordRefSystems.jl) provides conversions between Coordinate Reference Systems (CRS) for cartography use cases.
76-
- [Geodesy.jl](https://github.com/JuliaGeo/Geodesy.jl) for working with points in various world and local coordinate systems.
77-
- [WCS.jl](https://juliaastro.org/WCS/stable/) : Astronomical World Coordinate System library
23+
```

src/SpaceDataModel.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export AbstractModel, AbstractProject, AbstractInstrument, AbstractProduct, Abst
99
export AbstractDataVariable
1010
export Project, Instrument, DataSet, LDataSet, Product
1111
export Event
12+
export AbstractReferenceFrame, AbstractRepresentation
1213
export AbstractCoordinateSystem, AbstractCoordinateVector, getcsys
1314
export getmeta, setmeta!, setmeta
1415
export getdim, tdimnum
@@ -24,6 +25,9 @@ include("catalog.jl")
2425
include("coord.jl")
2526
include("workload.jl")
2627

28+
include("coordinates/reference_frame.jl")
29+
include("coordinates/representation.jl")
30+
2731
include("variable_interface.jl")
2832
const getdim = dim
2933

src/coord.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import Base: String
22

3-
43
"""
54
AbstractCoordinateSystem
65
@@ -18,7 +17,7 @@ abstract type AbstractCoordinateVector end
1817
"""
1918
getcsys(x)
2019
21-
Get the coordinate system of `x`.
20+
Get the coordinate system of `x`. Ideally, this should return both the reference frame and coordinate representation.
2221
2322
If `x` is a instance of `AbstractCoordinateSystem`, return `x` itself.
2423
If `x` is a type of `AbstractCoordinateSystem`, return an instance of the coordinate system, i.e. `x()`.

src/coordinates/reference_frame.jl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# https://docs.astropy.org/en/stable/coordinates/frames.html
2+
# https://docs.sunpy.org/en/stable/reference/coordinates/index.html
3+
4+
"""
5+
A Reference System is a scheme for orienting points in a space and describing how they transform to other systems.
6+
7+
See also: [`AbstractReferenceFrame`](@ref)
8+
"""
9+
abstract type AbstractReferenceSystem end
10+
11+
"""
12+
A specific realization of a reference system.
13+
"""
14+
abstract type AbstractReferenceFrame end
15+
16+
"""
17+
Frames can depend on epoch and planetary orientation models
18+
"""
19+
abstract type TimeDependentFrame <: AbstractReferenceFrame end

src/coordinates/representation.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
"""
2+
Abstract base for representing a point in a 3D coordinate system.
3+
4+
# Reference:
5+
- https://docs.astropy.org/en/stable/coordinates/representations.html
6+
- https://github.com/JuliaEarth/CoordRefSystems.jl/blob/main/src/crs.jl
7+
"""
8+
abstract type AbstractRepresentation end
9+
10+
struct Cartesian3 <: AbstractRepresentation end
11+
struct Spherical <: AbstractRepresentation end # (r, θ, ϕ) or (r, lat, lon)—define explicitly!
12+
struct Geodetic <: AbstractRepresentation end # (lat, lon, h) on ellipsoid

0 commit comments

Comments
 (0)