Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unifying GeometryOps and SphericalGeodesics' approaches #2

Open
asinghvi17 opened this issue Oct 11, 2024 · 5 comments
Open

Unifying GeometryOps and SphericalGeodesics' approaches #2

asinghvi17 opened this issue Oct 11, 2024 · 5 comments

Comments

@asinghvi17
Copy link
Member

For GeometryOps, I need three things fundamentally:

  1. distance calculations
  2. arc intersections (maybe robust, maybe not)
  3. interpolation along the arc

It looks like SphericalGeodesics.jl is looking to do 1 and 3 at least, so we should probably at least use the same types to minimize complications. I recently released a GeometryOpsCore.jl that has Spherical and Geodesic (maybe this should be Ellipsoid) types, happy to also use the definition from here. Only thing is that GeometryOpsCore ideally has minimal dependencies, so it would be great to have SphericalGeodesics depend on it rather than the other way around. Beyond some renaming of the ellipsoid/geodesic type it's currently very stable and battle-tested.

The approach I want to take in GeometryOps is:

operation(Spherical(), geometry)

to indicate that the geometry should be known to be spherical. Ideally, this also checks CRS etc and automatically reprojects, but that's a project for later. We already have spherical Delaunay triangulation and Voronoi polygons in a PR on DelaunayTriangulation, for example, so you could have triangulate(Planar(), geom) that does standard Delaunay triangulation and triangulate(Spherical(), geom) or triangulate(Quickhull(Spherical()), geom) that does the spherical triangulation.

The main places I would use SphericalGeodesics are in distance or segmentize / interpolate(some_line_like_thing, arclength; normalize = false).

What do you think?

@asinghvi17
Copy link
Member Author

asinghvi17 commented Oct 11, 2024

We've also found, in rafaqz/Rasters.jl#746 and the PR rafaqz/Rasters.jl#768 (computing the area of each pixel of an image in spherical space), deg2rad often introduces errors for particularly small numbers. sind and cosd use an extended-precision version of deg2rad internally, which we may want to copy here?

@anowacki
Copy link
Collaborator

sind and cosd use an extended-precision version of deg2rad internally, which we may want to copy here?

Thank you, that's good to know.

@anowacki
Copy link
Collaborator

I recently released a GeometryOpsCore.jl that has Spherical and Geodesic [...] Beyond some renaming of the ellipsoid/geodesic type it's currently very stable and battle-tested.

I see, so you have implemented Karney's stuff as well? Or is that taken from GeographicLib.jl? Sounds good if it has been battle-tested! I thought that GeographicLib.jl was largely unused and didn't know how well-tested it was, but a number of people have asked me to register it, hence this repo.

What do you think [about depending on GeometryOpsCore]?

In principle if GeometryOpsCore wants to hold all the types and methods for Haversine, Vincenty and 'GeographicLib' (Karney), then I would be happy for them to rest there. However, I think for users like me, needing to know about geometries and such like can be quite a lot of friction. I and many of my colleagues are often not so familiar with the terminology in GeometryOps (what is a geometry?) and there seems to be a need in my community at least for something which just takes in geographic coordinates and gives them back. Likewise, I see that GeometryOpsCore depends on DataAPI, Tables and GeoInterface, three things I don't know much about and would be reluctant to bring in without good reason. Would depending on this package be too onerous if it didn't have any dependencies at all (which is currently the way it is)?

@asinghvi17
Copy link
Member Author

asinghvi17 commented Oct 11, 2024

I haven't implemented Karney's equations - currently everything goes to GeographicLib, which works well enough for what I need to do.

A bit of context on the Julia/GIS world from my perspective:

  • A geometry is a point, linestring (vector of points), polygon (vector of linestrings with some exterior and holes), or some combination thereof.
  • GeoInterface is a thin interface package that defines methods to allow you to access the contents of geometry, and query some properties about it. So geometries from C libraries like GDAL and GEOS, geometries that are defined to exactly replicate certain data structures, etc can all be accessed through a common API. GeoInterface is used in all geospatial I/O in Julia, for instance.
  • GeometryOps is a package that implements operations that usually act on geometry, like intersection testing, clipping, buffering, etc. Everything was originally planar, but I'm now trying to add spherical capabilities as well, hence wanting this package :D
  • GeometryOpsCore is basically meant to be a super lightweight package that defines types and the basic functions that GeometryOps is built on - we envision the package getting pretty big, sort of like sf in R, so we wanted to split the types out so that people can at least use the broadly applicable features that it has. Things like apply that allow you to decompose any table or geometry to some level (maybe you want to operate only on points, or only on linestrings, or something like this).
    • This also contains my current definitions of spheres and ellipsoids, but they're pretty barebones - I haven't really looked into the best ways to define those.

TLDR: depending on how large of a package SphericalGeodesics.jl ends up being, it may or may not make sense to have it as a dependency of GeometryOpsCore. We could potentially split out a package from SphericalGeodesics that GeometryOpsCore can depend on though, that just has these definitions of "manifold" structs (we need planes, spheres and ellipses in GeometryOps).

@asinghvi17
Copy link
Member Author

DataAPI and Tables are basically also thin wrapper packages that define accessors for tables and metadata, as well as common function names so you don't get errors when using multiple packages - it's all the same function but with different dispatches for each type. They are pretty thin and also what backs e.g. DataFrames, so very stable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants