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

WGS84 <--> UTM projection header-only API #1191

Merged
merged 98 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from 88 commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
cfd69ad
Add cmake infrastructure and placeholder files for projection library
harrism May 9, 2023
dcb23ef
Merge branch 'branch-23.06' into feature/projection/cmake
harrism May 9, 2023
7b2e9b9
Rename to cuproj
harrism May 10, 2023
f469cf0
Merge branch 'branch-23.06' into feature/projection/cmake
harrism May 10, 2023
68acf29
Delete cugeo dir
harrism May 11, 2023
c16e735
show more digits in vec_2d_matcher
harrism May 31, 2023
818a3e5
Add copy of PROJ license
harrism May 31, 2023
c1550cd
Initial tmerc implementation and test
harrism May 31, 2023
c2784a9
Merge branch 'branch-23.08' into feature/projection/cmake
harrism May 31, 2023
d8d851d
Remove _ctk_static_suffix
harrism May 31, 2023
dade592
if TARGET conda_env update
harrism May 31, 2023
10b0590
Merge branch 'branch-23.08' into feature/projection/cmake
harrism Jun 1, 2023
88a3760
Update version to 23.08 and PUBLIC -> PRIVATE
harrism Jun 1, 2023
c36c7eb
Merge branch 'feature/projection/cmake' into feature/projection/wgs-utm
harrism Jun 1, 2023
2be7746
Move PROJ license into the file that uses its code.
harrism Jun 1, 2023
87172f0
Remove placeholder CPU code
harrism Jun 1, 2023
8cdc8dc
Rename test.
harrism Jun 6, 2023
48ead2e
Move cuproj into cpp and build it when cuspatial builds.
harrism Jun 6, 2023
b889452
re-add cuml
harrism Jun 6, 2023
2073b1f
Add sqlite dependency
harrism Jun 6, 2023
d366ad5
Merge branch 'branch-23.08' into feature/projection/cmake
harrism Jun 6, 2023
d59cdc4
Add proj and sqlite dependencies to conda meta.yaml
harrism Jun 6, 2023
3eba34e
Merge branch 'branch-23.08' into feature/projection/cmake
harrism Jun 7, 2023
cd68e4e
Fix comment
harrism Jun 7, 2023
5243a5d
rename to get_cudf.cmake
harrism Jun 7, 2023
e27f7bb
Remove GNUInstallDirs
harrism Jun 7, 2023
a0ad375
Copyright
harrism Jun 7, 2023
e2a28ea
cuspatial-exports --> cuproj-exports
harrism Jun 7, 2023
5d395c4
PROJ namespace
harrism Jun 7, 2023
517e65b
Remove FIND_PACKAGE_ARGUMENTS
harrism Jun 7, 2023
5a00596
Get cudftestutil when BUILD_BENCHMARKS is enabled too.
harrism Jun 7, 2023
9bb736b
Merge branch 'feature/projection/cmake' into feature/projection/wgs-utm
harrism Jun 7, 2023
6a168fc
Remove extraneous comma
harrism Jun 7, 2023
fb4148a
Remove the b combinator
harrism Jun 7, 2023
4428dac
Remove unused factories
harrism Jun 7, 2023
33fa489
white space
harrism Jun 7, 2023
48c9ffc
Merge branch 'branch-23.08' into feature/projection/cmake
harrism Jun 7, 2023
1745d0b
PROJ case
harrism Jun 7, 2023
beee5a4
Remove rapids_export of PROJ
harrism Jun 7, 2023
24923f2
Make cuproj get_cudf.cmake match cuspatial's
harrism Jun 8, 2023
6e08915
Merge branch 'feature/projection/cmake' into feature/projection/wgs-utm
harrism Jun 8, 2023
5bdc59c
Refactor to use an operator base class
harrism Jun 8, 2023
95cc7df
Refactor ctor
harrism Jun 8, 2023
300e769
Remove `BUILD_INTERFACE` from `target_compile_definitions`.
harrism Jun 13, 2023
42e5103
Temporary: attempt debugging cmake find_package in CI
harrism Jun 13, 2023
8bbc369
Merge branch 'branch-23.08' into feature/projection/cmake
harrism Jun 13, 2023
725d785
Merge branch 'feature/projection/cmake' into feature/projection/wgs-utm
harrism Jun 13, 2023
2a11430
Factor operations and parameters out of projections
harrism Jun 13, 2023
3552d0c
Revert temporary cmake debugging
harrism Jun 13, 2023
d063ca9
Update cpp/CMakeLists.txt
harrism Jun 14, 2023
fcdb4bb
Update CUPROJ VERSION in update-version.sh
harrism Jun 14, 2023
b130fb3
Big refactor to a dynamic device-side pipeline
harrism Jun 15, 2023
9875d8c
Factor cartesian coord scale and offset into a separate operation, an…
harrism Jun 20, 2023
4d0727f
Inverse of clamp
harrism Jun 20, 2023
fcbed5c
inverse of deg_to_rad
harrism Jun 20, 2023
1321415
Comment out debugging message
harrism Jun 20, 2023
6d5c907
inverse tmerc
harrism Jun 20, 2023
fc47c8e
Add support for inverse transformation
harrism Jun 21, 2023
5f8235b
Test inverse transformation and major test cleanup
harrism Jun 21, 2023
2812e0d
Merge branch 'branch-23.08' into feature/projection/cmake
harrism Jun 21, 2023
da30f35
Merge branch 'feature/projection/cmake' into feature/projection/wgs-utm
harrism Jun 21, 2023
45f38d8
Clean up setup switch
harrism Jun 22, 2023
404ec69
Clean up comments
harrism Jun 22, 2023
e8f0bdc
utm projection factory, for now...
harrism Jun 22, 2023
b54aaf7
Rename clenshaw functions to get around codespell false positives
harrism Jun 22, 2023
b552b9a
detail namespace
harrism Jun 22, 2023
b31c650
Move operations to subfolder
harrism Jun 22, 2023
eb14f2e
Add projection factories
harrism Jun 22, 2023
51ba7e8
Merge branch 'branch-23.08' into feature/projection/wgs-utm
harrism Jun 27, 2023
0cd4644
Add initial README
harrism Jun 28, 2023
9e04781
Support and test UTM->WGS84 construction
harrism Jun 28, 2023
d4e2b0e
Move pipeline into a detail header
harrism Jun 28, 2023
1f7bca6
operation docs
harrism Jun 28, 2023
88cfeca
Document enums
harrism Jun 28, 2023
83727e8
Document projection_factories
harrism Jun 28, 2023
2341ffe
projection_factories docs and detail namespace
harrism Jun 28, 2023
f4ceed3
Document ellipsoid.hpp
harrism Jun 28, 2023
6485b2e
Document projection_parameters.hpp
harrism Jun 28, 2023
176642b
Document transverse_mercator operation
harrism Jun 28, 2023
57d817e
Document axis_swap
harrism Jun 28, 2023
ade7cdc
Document clamp_angular_coordinates
harrism Jun 28, 2023
2a38ecd
Document degrees_to_radians
harrism Jun 28, 2023
c323cef
Document offset_scale_cartesian_coordinates
harrism Jun 28, 2023
569c42f
Remove horizontal rules
harrism Jun 28, 2023
0c32e06
Document pipeline.cuh
harrism Jun 28, 2023
a15f94e
Brief test docs
harrism Jun 28, 2023
d79563c
Merge branch 'branch-23.08' into feature/projection/wgs-utm
harrism Jun 28, 2023
19e9699
Improve reverse construction logic and fix failing tests
harrism Jun 29, 2023
292f85e
Factor out wrapping to -PI..PI and constants
harrism Jul 4, 2023
c23db51
Remove commented out code
harrism Jul 4, 2023
ce69abc
Factor out central meridian/parallel, remove unused comments
harrism Jul 4, 2023
38fe73c
Use HOST_DEVICE_EXPECTS and comment instead of #if 0
harrism Jul 4, 2023
cc5afb2
Improve mismatch printing
harrism Jul 4, 2023
e9471a0
Test multiple places around the globe.
harrism Jul 4, 2023
6e02100
Merge branch 'branch-23.08' into feature/projection/wgs-utm
harrism Jul 11, 2023
2fe01f7
Simplify test vector conversion
harrism Jul 11, 2023
09d0b63
Move grid_generator to cuproj_test
harrism Jul 11, 2023
feba258
Merge branch 'branch-23.08' into feature/projection/wgs-utm
harrism Jul 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions cpp/cuproj/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# <div align="left"><img src="https://rapids.ai/assets/images/rapids_logo.png" width="90px"/>&nbsp;cuProj: GPU-Accelerated Coordinate Projection</div>

## Overview

cuProj is a GPU-accelerated generic coordinate transformation library that transforms geospatial
coordinates from one coordinate reference system (CRS) to another. cuProj is inspired by
[PROJ](https://proj.org/en/9.2/), and aims to be compatible with it.
120 changes: 120 additions & 0 deletions cpp/cuproj/include/cuproj/detail/pipeline.cuh
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* Copyright (c) 2023, NVIDIA CORPORATION.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <cuproj/operation/axis_swap.cuh>
#include <cuproj/operation/clamp_angular_coordinates.cuh>
#include <cuproj/operation/degrees_to_radians.cuh>
#include <cuproj/operation/offset_scale_cartesian_coordinates.cuh>
#include <cuproj/operation/operation.cuh>
#include <cuproj/operation/transverse_mercator.cuh>

#include <thrust/for_each.h>

#include <iterator>

namespace cuproj {

namespace detail {

/**
* @internal
* @brief A pipeline of projection operations applied in order to a coordinate
*
* @tparam Coordinate the coordinate type
* @tparam dir The direction of the pipeline, FORWARD or INVERSE
* @tparam T the coordinate value type
*/
template <typename Coordinate,
direction dir = direction::FORWARD,
typename T = typename Coordinate::value_type>
class pipeline {
public:
using iterator_type = std::conditional_t<dir == direction::FORWARD,
operation_type const*,
std::reverse_iterator<operation_type const*>>;

/**
* @brief Construct a new pipeline object with the given operations and parameters
*
* @param params The projection parameters
* @param ops The operations to apply
* @param num_stages The number of operations to apply
*/
pipeline(projection_parameters<T> const& params,
operation_type const* ops,
std::size_t num_stages)
: params_(params), d_ops(ops), num_stages(num_stages)
{
if constexpr (dir == direction::FORWARD) {
first_ = d_ops;
} else {
first_ = std::reverse_iterator(d_ops + num_stages);
}
}

/**
* @brief Apply the pipeline to the given coordinate
*
* @param c The coordinate to transform
* @return The transformed coordinate
*/
__device__ Coordinate operator()(Coordinate const& c) const
{
Coordinate c_out{c};
thrust::for_each_n(thrust::seq, first_, num_stages, [&](auto const& op) {
switch (op) {
case operation_type::AXIS_SWAP: {
auto op = axis_swap<Coordinate>{};
c_out = op(c_out, dir);
break;
}
case operation_type::DEGREES_TO_RADIANS: {
auto op = degrees_to_radians<Coordinate>{};
c_out = op(c_out, dir);
break;
}
case operation_type::CLAMP_ANGULAR_COORDINATES: {
auto op = clamp_angular_coordinates<Coordinate>{params_};
c_out = op(c_out, dir);
break;
}
case operation_type::OFFSET_SCALE_CARTESIAN_COORDINATES: {
auto op = offset_scale_cartesian_coordinates<Coordinate>{params_};
c_out = op(c_out, dir);
break;
}
case operation_type::TRANSVERSE_MERCATOR: {
auto op = transverse_mercator<Coordinate>{params_};
c_out = op(c_out, dir);
break;
}
}
});
return c_out;
}

private:
projection_parameters<T> params_;
operation_type const* d_ops;
iterator_type first_;
std::size_t num_stages;
};

} // namespace detail

} // namespace cuproj
71 changes: 71 additions & 0 deletions cpp/cuproj/include/cuproj/ellipsoid.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright (c) 2023, NVIDIA CORPORATION.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <cassert>
#include <cmath>

namespace cuproj {

/**
* @brief Ellipsoid parameters
*
* @tparam T Floating point type
*/
template <typename T>
struct ellipsoid {
ellipsoid() = default;

/**
* @brief Construct an ellipsoid from semi-major axis and inverse flattening
*
* @param a Semi-major axis
* @param inverse_flattening Inverse flattening (a / (a - b), where b is the semi-minor axis)
*/
constexpr ellipsoid(T a, T inverse_flattening) : a(a)
{
assert(inverse_flattening != 0.0);
b = a * (1. - 1. / inverse_flattening);
f = 1.0 / inverse_flattening;
es = 2 * f - f * f;
e = sqrt(es);
alpha = asin(e);
n = pow(tan(alpha / 2), 2);
}

T a{}; // semi-major axis
T b{}; // semi-minor axis
T e{}; // first eccentricity
T es{}; // first eccentricity squared
T alpha{}; // angular eccentricity
T f{}; // flattening
T n{}; // third flattening
};

/**
* @brief Create the WGS84 ellipsoid
*
* @tparam T Floating point type
* @return The WGS84 ellipsoid
*/
template <typename T>
constexpr ellipsoid<T> make_ellipsoid_wgs84()
{
return ellipsoid<T>{T{6378137.0}, T{298.257223563}};
}

} // namespace cuproj
24 changes: 12 additions & 12 deletions cpp/cuproj/include/cuproj/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ namespace cuproj {
* @{
*/

/**---------------------------------------------------------------------------*
/**
* @brief Exception thrown when logical precondition is violated.
*
* This exception should not be thrown directly and is instead thrown by the
* CUPROJ_EXPECTS macro.
*
*---------------------------------------------------------------------------**/
*/
struct logic_error : public std::logic_error {
logic_error(char const* const message) : std::logic_error(message) {}
logic_error(std::string const& message) : std::logic_error(message) {}
Expand All @@ -58,7 +58,7 @@ struct cuda_error : public std::runtime_error {
#define CUPROJ_STRINGIFY_DETAIL(x) #x
#define CUPROJ_STRINGIFY(x) CUPROJ_STRINGIFY_DETAIL(x)

/**---------------------------------------------------------------------------*
/**
* @brief Macro for checking (pre-)conditions that throws an exception when
* a condition is violated.
*
Expand All @@ -72,13 +72,13 @@ struct cuda_error : public std::runtime_error {
* @param[in] reason String literal description of the reason that cond is
* expected to be true
* @throw cuproj::logic_error if the condition evaluates to false.
*---------------------------------------------------------------------------**/
#define CUPROJ_EXPECTS(cond, reason) \
(!!(cond)) ? static_cast<void>(0) \
: throw cuspatial::logic_error("cuProj failure at: " __FILE__ \
":" CUPROJ_STRINGIFY(__LINE__) ": " reason)
*/
#define CUPROJ_EXPECTS(cond, reason) \
(!!(cond)) ? static_cast<void>(0) \
: throw cuproj::logic_error("cuProj failure at: " __FILE__ \
":" CUPROJ_STRINGIFY(__LINE__) ": " reason)

/**---------------------------------------------------------------------------*
/**
* @brief Macro for checking (pre-)conditions that throws an exception when
* a condition is violated.
*
Expand All @@ -97,14 +97,14 @@ struct cuda_error : public std::runtime_error {
* @throw cuproj::logic_error if the condition evaluates to false.
* (if on device)
* program terminates and assertion error message is printed to stderr.
*---------------------------------------------------------------------------**/
*/
#ifndef __CUDA_ARCH__
#define CUPROJ_HOST_DEVICE_EXPECTS(cond, reason) CUPROJ_EXPECTS(cond, reason)
#else
#define CUPROJ_HOST_DEVICE_EXPECTS(cond, reason) cuproj_assert(cond&& reason)
#endif

/**---------------------------------------------------------------------------*
/**
* @brief Indicates that an erroneous code path has been taken.
*
* In host code, throws a `cuproj::logic_error`.
Expand All @@ -116,7 +116,7 @@ struct cuda_error : public std::runtime_error {
* ```
*
* @param[in] reason String literal description of the reason
*---------------------------------------------------------------------------**/
*/
#define CUPROJ_FAIL(reason) \
throw cuproj::logic_error("cuProj failure at: " __FILE__ ":" CUPROJ_STRINGIFY( \
__LINE__) ":" \
Expand Down
43 changes: 43 additions & 0 deletions cpp/cuproj/include/cuproj/operation/axis_swap.cuh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2023, NVIDIA CORPORATION.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <cuproj/operation/operation.cuh>

namespace cuproj {

/**
* @brief Axis swap operation: swap x and y coordinates
*
* @tparam Coordinate the coordinate type
*/
template <typename Coordinate>
struct axis_swap : operation<Coordinate> {
/**
* @brief Swap x and y coordinates
*
* @param coord the coordinate to swap
* @param dir (unused) the direction of the operation
* @return the swapped coordinate
*/
__host__ __device__ Coordinate operator()(Coordinate const& coord, direction) const
{
return Coordinate{coord.y, coord.x};
}
};

} // namespace cuproj
Loading