# \[ANN\] CoordRefSystems.jl

**URL:** <https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950>\
**Category:** Package Announcements\
**Tags:** package, announcement, geo, geodesy\
**Created:** [March 21, 2024, 8:34pm UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950 "2024-03-21T20:34:49Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [March 21, 2024, 8:34pm UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950/1 "2024-03-21T20:34:49Z")

</div>

# Coordinate Reference Systems (CRS) in native Julia

@eliascarv and I are happy to share

 ![image](https://global.discourse-cdn.com/julialang/original/3X/e/0/e0bf2d69efd5699d4140db3978d37847a6bc7d3a.png)

with the geospatial community.

CoordRefSystems.jl provides conversions between Coordinate Reference Systems (CRS) in native Julia. It was designed to work with units from [Unitful.jl](https://github.com/PainterQubits/Unitful.jl), respects projection bounds catalogued in [https://epsg.io](https://epsg.io/), and is very fast thanks to advanced parametrizations at compile-time.

This package addresses various design issues encountered in previous attempts such as [Geodesy.jl](https://github.com/JuliaGeo/Geodesy.jl) and [MapMaths.jl](https://github.com/subnero1/MapMaths.jl). Our [benchmarks](https://github.com/JuliaEarth/CoordRefSystems.jl/blob/main/benchmark/output.csv) show that CoordRefSystems.jl is often faster than [PROJ](https://github.com/OSGeo/PROJ), which is the most widely used software library for cartography in the world (written in C/C++).

Examples of usage are available in the README:

> **[GitHub - JuliaEarth/CoordRefSystems.jl: Unitful coordinate reference systems for...](https://github.com/JuliaEarth/CoordRefSystems.jl)**
>
> Unitful coordinate reference systems for geographic maps in Julia

With this package, we are one step closer from a complete GIS experience with GeoStats.jl in native Julia. We are planning to refactor the stack in the following months to accommodate this CRS work.

The package is awaiting registration in the General registry.

## Acknowledgements

We would like to thank @cormullion for the awesome logo made with Luxor.jl, and the C/C++ PROJ software from where we got inspiration for this new Julia design.

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [March 21, 2024, 8:42pm UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950/2 "2024-03-21T20:42:37Z")

</div>

It has always been a pain to use GeoMakie.jl - not due to GeoMakie’s fault, but because in essense all arguments for the projection where passed as “old C command line arguments” to PROJ, and that made it difficult for me at least to reason with the code and get the results I expected.

It is a very welcomed sight to see a pure Julia alternatve to PROJ!

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [March 21, 2024, 8:45pm UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950/3 "2024-03-21T20:45:39Z")

</div>

Not only that, we will now be able to dispatch algorithms in Meshes.jl (and therefore GeoStats.jl) based on CRS, meaning that we will never compute an area with angular coordinates for example.

We carefully designed CoordRefSystems.jl to be able to send `GeoTable`s for visualization without manual selection of axis, like it is done in GeoMakie.jl and the PROJ strings.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [March 22, 2024, 11:47pm UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950/4 "2024-03-22T23:47:20Z")

</div>

The package was renamed to CoordRefSystems.jl given feedback in the General registry, and to avoid confusion with drawing/plotting libraries.

---

<div class="post-metadata">

**Author:** ![ettersi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ettersi/32/6829_2.png) [@ettersi](https://discourse.julialang.org/u/ettersi)\
**Post date:** [March 25, 2024, 4:56am UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950/5 "2024-03-25T04:56:49Z")

</div>

Awesome package, thank you very much for sharing all the expertise and hard work that went into this! CoordRefSystems fixes most of the usability beefs I had with Geodesy.jl and implements a much larger set of coordinate conversions than MapMaths.jl, so I can see myself giving up on MapMaths.jl soon and adopting this package instead. However, CoordRefSystems currently lacks a few features which would make this move somewhat painful, so I’m curious to hear whether you would be willing to add them.

- Would it be possible to add fallback conversions between `Cartesian` and `Projected` coordinate types to cover conversions such as this one?

- Another missing conversion:

- Do you have any plans for adding local coordinates systems (e.g. [ENU](https://en.wikipedia.org/wiki/Local_tangent_plane_coordinates#Local_east,_north,_up_(ENU)_coordinates))? Local coordinates can be very convenient e.g. for computing the LatLon of a point 500m to the east of a given point. Further bonus points will be awarded if you support both cartesian local coordinates and “wrapping” local coordinates (i.e. a non-cartesian local coordinate system such that `alt = 0` is always on the surface of the sea).

- AFAICT, if you want to convert say `latlon::LatLon` to a pair of `WebMercator` coordinates _without_ the `WebMercator` wrapper type, you currently have to do this:

- If you are agreeable to adding something like `cstrip()`, would it be possible to also add a function `cwrap()` such that `x -> cwrap(args..., cstrip(args..., x)` becomes the identity and `cstrip()` returns an `SVector`? Such a pair of functions would make it very easy to express a lot of highly useful coordinate arithmetic. For example:

- Minor nitpick: The docstring for `LatLon` currently only shows up if you query for `GeodeticLatLon`.

---

<div class="post-metadata">

**Author:** ![johnh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnh/32/3615_2.png) [@johnh](https://discourse.julialang.org/u/johnh)\
**Post date:** [March 25, 2024, 6:09am UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950/6 "2024-03-25T06:09:06Z")

</div>

The Juliahub page is currently 404 error. I guess part of the pipeline is not completing?

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [March 25, 2024, 10:08am UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950/7 "2024-03-25T10:08:33Z")

</div>

Nice package, I like how coordinate handling in Julia matures (:

Some parts of the interface seem really similar or just relevant to astronomical coordinates as well (and maybe other spherical scenarios?). We’ve had a successful [GitHub - JuliaAstro/SkyCoords.jl: Astronomical coordinate systems in Julia](https://github.com/JuliaAstro/SkyCoords.jl) with lat-lon and cartesian parametrizations (+ projected, PR stuck unfortunately [add simple projected coordinates by aplavin · Pull Request #43 · JuliaAstro/SkyCoords.jl · GitHub](https://github.com/JuliaAstro/SkyCoords.jl/pull/43)).

Would be nice to understand if there’s something that can be reused or done consistently. Especially given that earth and sky coordinates are used together sometimes.

---

<div class="post-metadata">

**Author:** ![johnh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnh/32/3615_2.png) [@johnh](https://discourse.julialang.org/u/johnh)\
**Post date:** [March 25, 2024, 10:10am UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950/8 "2024-03-25T10:10:28Z")

</div>

Stupid question from me, regarding astro coordinate systems.  
What coordinate system to the astronauts in the International Space Station use?  
I would guess htey use UTC time also.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [March 25, 2024, 10:38am UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950/9 "2024-03-25T10:38:42Z")

</div>

Thank you @ettersi for your feedback! We would be happy to fix all issues raised. Can you please copy/paste the bullet points into new GitHub issues in CoordRefSystems.jl?

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [March 25, 2024, 10:39am UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950/10 "2024-03-25T10:39:15Z")

</div>

Hi @johnh this is because the package is waiting the registration period. I think JuliaHub only lists registered packages.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [March 25, 2024, 10:42am UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950/11 "2024-03-25T10:42:33Z")

</div>

Thank you @aplavin! Let’s join forces in CoordRefSystems.jl and absorb any missing CRS from SkyCoords.jl. We need a central place to evolve these systems to be able to seamlessly track objects on Earth and on the Sky.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [March 25, 2024, 9:35pm UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950/12 "2024-03-25T21:35:17Z")

</div>

> [@johnh](#):
>
> What coordinate system to the astronauts in the International Space Station use?

If the question is to me, then I have no idea (: By astro coordinates, I mean coordinates of astronomical objects on the celestial sphere.

> [@juliohm](#):
>
> Let’s join forces in [CoordRefSystems.jl](https://juliahub.com/ui/Packages/General/CoordRefSystems) and absorb any missing CRS from [SkyCoords.jl](https://juliahub.com/ui/Packages/General/SkyCoords).

Hm, first it would be nice to understand what are the relevant differences in the design/API. I just noticed a lot of surface-level similarities, and commented on that.  
I’m familiar with SkyCoords.jl, and it has generally been good enough for me (aside from the stalled projected coords PR).  
Then the best approaches from both could be unified.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [March 25, 2024, 11:45pm UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950/13 "2024-03-25T23:45:17Z")

</div>

> [@aplavin](#):
>
> Hm, first it would be nice to understand what are the relevant differences in the design/API. I just noticed a lot of surface-level similarities, and commented on that.

I can tell you already that SkyCoords.jl is minimal in functionality compared to CoordRefSystems.jl. It doesn’t have the notion of datum, nor explicit units. CoordRefSystems.jl has a much more ambitious scope.

---

<div class="post-metadata">

**Author:** ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)\
**Post date:** [March 26, 2024, 12:03am UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950/14 "2024-03-26T00:03:05Z")

</div>

This looks great. My question is that

- Can I used it to convert GPS Datum for example from Datum AGD56 to WGS84, ie from old maps to current Datum

- Can I use it to correct for the correct continental drift of Australia from old maps?

Oh by the way. Australia is the fastest continent on earth bar none!

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [March 26, 2024, 1:39am UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950/15 "2024-03-26T01:39:53Z")

</div>

> [@StevenSiew](#):
>
> Can I used it to convert GPS Datum for example from Datum AGD56 to WGS84, ie from old maps to current Datum

Yes, you just need to define the AGD56 datum, which is a set of constants. The rest is already implemented, and we ported all datum supported by PROJ.

> [@StevenSiew](#):
>
> Can I use it to correct for the correct continental drift of Australia from old maps?

Yes, and this is possible due to our design that attaches epochs to datum. We will add a new function soon that takes any datum and adjusts the epoch for dynamic updates. There is an issue already for this: [Add epoch shift to datum · Issue #41 · JuliaEarth/CoordRefSystems.jl · GitHub](https://github.com/JuliaEarth/CoordRefSystems.jl/issues/41)

---

<div class="post-metadata">

**Author:** ![lazarusA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lazarusa/32/6571_2.png) [@lazarusA](https://discourse.julialang.org/u/lazarusA)\
**Post date:** [March 26, 2024, 9:24am UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950/16 "2024-03-26T09:24:47Z")

</div>

I always struggle with the convention `LatLon`, I prefer LonLat. For understanding purposes, what’s the reason behind this convention?

Note also, in the docs, when doing (looks inconsistent)

```julia
julia> convert(Mercator, latlon)
Mercator{WGS84Latest} coordinates
├─ x: 6.679169447596414e6 m # this is to Lon, right?
└─ y: 3.482189085408618e6 m # and this to lat? 

```

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [March 26, 2024, 9:31am UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950/17 "2024-03-26T09:31:51Z")

</div>

> [@lazarusA](#):
>
> I always struggle with the convention `LatLon`, I prefer LonLat. For understanding purposes, what’s the reason behind this convention?

No major reason as far as I know. The latitude is the most difficult coordinate to compute in the pair, and perhaps people decided to place it first historically in EPSG codes, and textbooks.

> [@lazarusA](#):
>
> Note also, in the docs, when doing (looks inconsistent)
> 
> ```julia
> julia> convert(Mercator, latlon)
> Mercator{WGS84Latest} coordinates
> ├─ x: 6.679169447596414e6 m # this is to Lon, right?
> └─ y: 3.482189085408618e6 m # and this to lat? 
> 
> ```

This is not inconsistent, it is actually nice that the package explicitly names things to avoid confusion. Projected coordinates are x and y in meters, and they are usually associated with longitude and latitude (reversed) order in degrees.

PROJ handled this issue with the `swap_xy` option everywhere, but CoordRefSystems.jl avoided that altogether by enforcing structs with well-defined fields and types in a specific order. We could introduce another struct `LonLat` for convenience later, but there is no use case that really justifies it yet.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [March 26, 2024, 10:58am UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950/18 "2024-03-26T10:58:06Z")

</div>

Heh, I also noticed that “projected” coordinates here don’t mean what I expected (:  
In CRS.jl, you mean projection of the whole sphere onto some surface, like Mercator and similar – right?  
What about projection to the tangent plane? Basically, a system that has a reference `(lon, lat)` position on the sphere, and coordinates are represented in terms of (projected) offsets from that point. In astronomy, this is very common: you may have an image centered at some lon, lat, and coordinates within the image are “relative lat” + “relative projected lon”.

Or both senses of “projected” are the same general beast?..

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [March 26, 2024, 11:05am UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950/19 "2024-03-26T11:05:23Z")

</div>

> [@aplavin](#):
>
> What about projection to the tangent plane? Basically, a system that has a reference `(lon, lat)` position on the sphere, and coordinates are represented in terms of (projected) offsets from that point. In astronomy, this is very common: you may have an image centered at some lon, lat, and coordinates within the image are “relative lat” + “relative projected lon”.

I believe you are discussing East/Northing/Up coordinates, there is an issue open already for that: [Add local coordinates · Issue #48 · JuliaEarth/CoordRefSystems.jl · GitHub](https://github.com/JuliaEarth/CoordRefSystems.jl/issues/48)

---

<div class="post-metadata">

**Author:** ![ElOceanografo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eloceanografo/32/624_2.png) [@ElOceanografo](https://discourse.julialang.org/u/ElOceanografo)\
**Post date:** [March 26, 2024, 11:22am UTC](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950/20 "2024-03-26T11:22:43Z")

</div>

Any historians on here are free to correct me if I’m wrong, but I believe it’s because latitude is the easier of the two to measure, and was used in navigation for centuries before longitude could be reliably calculated. I imagine ships’ masters were used to logging latitude, then started adding longitude second when [accurate lunar almanacs and chronometers](https://en.wikipedia.org/wiki/History_of_longitude#Lunar_distances_versus_chronometers) became available in around the turn of the 19th century. So the answer is “maritime tradition,” though it is also now an official [ISO Standard](https://en.wikipedia.org/wiki/ISO_6709#Order,_sign,_and_units) to quote latitude before longitude.

[Next page](https://discourse.julialang.org/t/ann-coordrefsystems-jl/111950.md?page=2)
