Skip to content

Commit

Permalink
Python support for int epsg codes
Browse files Browse the repository at this point in the history
  • Loading branch information
harrism committed Jul 19, 2023
1 parent ca38108 commit 4a37d07
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 5 deletions.
2 changes: 2 additions & 0 deletions python/cuproj/cuproj/_lib/cpp/cuprojshim.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ cdef extern from "cuprojshim.hpp" namespace "cuproj" nogil:
cdef extern from "cuprojshim.hpp" namespace "cuprojshim" nogil:
projection[vec_2d[double]]* make_projection(string, string) except +

projection[vec_2d[double]]* make_projection(int, int) except +

void transform(
projection[vec_2d[double]],
vec_2d[double]*,
Expand Down
12 changes: 10 additions & 2 deletions python/cuproj/cuproj/_lib/transform.pyx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import cupy as cp

from libc.stdint cimport uintptr_t
from libcpp.string cimport string

from cuproj._lib.cpp.cuprojshim cimport make_projection, transform, vec_2d
from cuproj._lib.cpp.operation cimport direction
Expand All @@ -14,8 +15,15 @@ cdef class Transformer:
cdef projection[vec_2d[double]]* proj

def __init__(self, crs_from, crs_to):
self.proj = make_projection(
crs_from.encode('utf-8'), crs_to.encode('utf-8'))
if (isinstance(crs_from, str) & isinstance(crs_to, str)):
crs_from_b = crs_from.encode('utf-8')
crs_to_b = crs_to.encode('utf-8')
self.proj = make_projection(<string> crs_from_b, <string> crs_to_b)
elif (isinstance(crs_from, int) & isinstance(crs_to, int)):
self.proj = make_projection(<int> crs_from, <int> crs_to)
else:
raise TypeError(
"crs_from and crs_to must be both strings or both integers")

def __del__(self):
del self.proj
Expand Down
5 changes: 4 additions & 1 deletion python/cuproj/cuproj/cuprojshim/include/cuprojshim.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@

namespace cuprojshim {

cuproj::projection<cuproj::vec_2d<double>>*
cuproj::projection<cuproj::vec_2d<double>> *
make_projection(std::string const &src_epsg, std::string const &dst_epsg);

cuproj::projection<cuproj::vec_2d<double>> *make_projection(int src_epsg,
int dst_epsg);

void transform(cuproj::projection<cuproj::vec_2d<double>> const &proj,
cuproj::vec_2d<double> *xy_in, cuproj::vec_2d<double> *xy_out,
std::size_t n, cuproj::direction dir);
Expand Down
5 changes: 5 additions & 0 deletions python/cuproj/cuproj/cuprojshim/src/cuprojshim.cu
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ make_projection(std::string const &src_epsg, std::string const &dst_epsg) {
return cuproj::make_projection<cuproj::vec_2d<double>>(src_epsg, dst_epsg);
}

cuproj::projection<cuproj::vec_2d<double>> *make_projection(int src_epsg,
int dst_epsg) {
return cuproj::make_projection<cuproj::vec_2d<double>>(src_epsg, dst_epsg);
}

void transform(cuproj::projection<cuproj::vec_2d<double>> const &proj,
cuproj::vec_2d<double> *xy_in, cuproj::vec_2d<double> *xy_out,
std::size_t n, cuproj::direction dir) {
Expand Down
48 changes: 48 additions & 0 deletions python/cuproj/cuproj/tests/test_transform.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,55 @@

import pytest
from numpy.testing import assert_allclose
from pyproj import Transformer

from cuproj import Transformer as cuTransformer

valid_crs_combos = [
(4326, 32756),
(32756, 4326),
(4326, 32610),
(32610, 4326)]

invalid_crs_combos = [
(4326, 4326),
(32756, 32756),
(4326, 756),
(756, 4326)]


def to_epsg_string(code):
return f"epsg:{code}"


@pytest.mark.parametrize("crs_from, crs_to", valid_crs_combos)
def test_valid_epsg_codes(crs_from, crs_to):
Transformer.from_crs(crs_from, crs_to)


@pytest.mark.parametrize("crs_from, crs_to", valid_crs_combos)
def test_valid_epsg_strings(crs_from, crs_to):
Transformer.from_crs(to_epsg_string(crs_from), to_epsg_string(crs_to))


@pytest.mark.parametrize("crs_from, crs_to", valid_crs_combos)
def test_valid_uppercase_epsg_strings(crs_from, crs_to):
Transformer.from_crs(
to_epsg_string(crs_from).upper(), to_epsg_string(crs_to).upper())


@pytest.mark.parametrize("crs_from, crs_to", invalid_crs_combos)
def test_invalid_epsg_codes(crs_from, crs_to):
with pytest.raises(RuntimeError):
cuTransformer.from_crs(crs_from, crs_to)


@pytest.mark.parametrize("crs_from, crs_to", invalid_crs_combos)
def test_invalid_epsg_strings(crs_from, crs_to):
with pytest.raises(RuntimeError):
cuTransformer.from_crs(
to_epsg_string(crs_from), to_epsg_string(crs_to))


def test_wgs84_to_utm_one_point():
# Sydney opera house latitude and longitude
Expand All @@ -22,13 +68,15 @@ def test_wgs84_to_utm_one_point():
assert_allclose(cuproj_x, pyproj_x)
assert_allclose(cuproj_y, pyproj_y)


# def grid_generator(min_corner, max_corner, num_points_x, num_points_y):
# spacing = ((max_corner[0] - min_corner[0]) / num_points_x,
# (max_corner[1] - min_corner[1]) / num_points_y)
# for i in range(num_points_x * num_points_y):
# yield (min_corner[0] + (i % num_points_x) * spacing[0],
# min_corner[1] + (i // num_points_x) * spacing[1])


# # test with a grid of points around san francisco
# def test_wgs84_to_utm_grid():
# # San Francisco bounding box
Expand Down
4 changes: 2 additions & 2 deletions python/cuproj/cuproj/transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ def from_crs(crs_from, crs_to):
Parameters
----------
crs_from : CRS
The source CRS.
int or "auth:code" string. The source CRS.
crs_to : CRS
The target CRS.
int or "auth:code" string. The target CRS.
Returns
-------
Expand Down

0 comments on commit 4a37d07

Please sign in to comment.