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

Add Multi-Geometry support to point_linestring_distance and build python bindings #660

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
de78310
Initial to atomics refactoring
isVoid Jun 14, 2022
6011900
Initial refactoring geometry utilities
isVoid Jun 14, 2022
9761eab
Add header only api
isVoid Jun 14, 2022
2ed60eb
Add cudf column API
isVoid Jun 14, 2022
e3ec12d
cmake updates
isVoid Jun 14, 2022
a72ac10
inline atomics to avoid compiling RDC
isVoid Jun 14, 2022
31b1e78
Rename to proper naming convention
isVoid Jun 14, 2022
f55af2f
make all atomics inline
isVoid Jun 14, 2022
e874f3b
Merge branch 'improvement/device_atomics_refactor' into feature/point…
isVoid Jun 14, 2022
e9b2ca8
Merge branch 'improvement/geometry_utilities' into feature/point_line…
isVoid Jun 14, 2022
f2277f0
Changes header only API to accept only single offset iterator
isVoid Jun 15, 2022
7bc0914
Add header only API tests
isVoid Jun 15, 2022
a8ec5ff
Update cudf column API calls
isVoid Jun 15, 2022
1fdfd59
Initial add utility method
isVoid Jun 15, 2022
0274875
Add counting transform iterators
isVoid Jun 15, 2022
df286a0
Revert "Update cudf column API calls"
isVoid Jun 15, 2022
688fbb5
Revert "Add cudf column API"
isVoid Jun 15, 2022
d0c0c4f
Merge branch 'branch-22.08' of https://github.com/rapidsai/cuspatial …
isVoid Aug 1, 2022
1c4ad61
Update refactored helper locations
isVoid Aug 1, 2022
e4038a5
Add cudf column API
isVoid Aug 1, 2022
5004bbe
Add equality test utility and fix header only tests
isVoid Aug 1, 2022
986dbb2
minor docstring updates
isVoid Aug 1, 2022
2feab4b
Add cudf column API documentation
isVoid Aug 1, 2022
5e07194
Include point-linestring distance files in docs.
isVoid Aug 1, 2022
4834aa2
Apply suggestions from code review
isVoid Aug 1, 2022
de0feb7
Address review comments
isVoid Aug 11, 2022
c897974
Merge branch 'feature/header_only_point_linestring_distance' of githu…
isVoid Aug 11, 2022
6dc34e0
Merge branch 'branch-22.10' of https://github.com/rapidsai/cuspatial …
isVoid Aug 16, 2022
624a97f
Fix broken builds
isVoid Aug 16, 2022
b65d9b2
Add missing thrust headers for `points_in_range`
isVoid Aug 16, 2022
c57cad6
Add missing thrust header
isVoid Aug 16, 2022
e2235b0
Use 256 tpb
isVoid Aug 16, 2022
45787e8
Fix Thrust includes.
bdice Aug 16, 2022
f1da463
Merge pull request #2 from bdice/fix-thrust-includes-header_only_poin…
isVoid Aug 16, 2022
b5aca2d
Address potential OOB issue
isVoid Aug 17, 2022
b88a7bb
Merge branch 'feature/header_only_point_linestring_distance' of githu…
isVoid Aug 17, 2022
b3e7fd7
Implement correct grid-stride loop behavior and last-point guard cond…
isVoid Aug 17, 2022
bd1f62b
Initial rewriting the API to geoarrow format
isVoid Aug 18, 2022
cb27513
Initial refactoring of tests
isVoid Aug 18, 2022
e2d4f9c
Fix offset iterator
isVoid Aug 18, 2022
6ac10a7
Remove constraint on output iterator
isVoid Aug 18, 2022
ecbfc2e
Address review comments
isVoid Aug 18, 2022
e006d94
Add multi-geometry capability and passing tests
isVoid Aug 19, 2022
92b1a68
Rename c++ variables to geoarrow-spec std
isVoid Aug 23, 2022
05b4f1a
Add more cpp tests for multi-geoms
isVoid Aug 23, 2022
5448e68
create cython bindings for pairwise_point_linestring_distance
isVoid Aug 23, 2022
67bb794
Merge branch 'branch-22.10' of https://github.com/rapidsai/cuspatial …
isVoid Aug 23, 2022
12ad78d
add simple test case
isVoid Aug 23, 2022
0aae6d3
add specified column accessors
isVoid Aug 23, 2022
ee0b34f
add utility to check single typed geoseries
isVoid Aug 23, 2022
20c4f89
add point_linestring_distance python API
isVoid Aug 23, 2022
95e76e0
experiment on multi geometry dispatcher
isVoid Aug 23, 2022
55764a4
Merge branch 'branch-22.10' of https://github.com/rapidsai/cuspatial …
isVoid Aug 23, 2022
b3e6f90
Merge branch 'branch-22.10' of https://github.com/rapidsai/cuspatial …
isVoid Aug 23, 2022
4d73c5a
fix certain imports for python api
isVoid Aug 23, 2022
10d309b
Add column utility for single type geometries
isVoid Aug 23, 2022
be8c9eb
minor renames
isVoid Aug 23, 2022
0df550c
include randomly generated input tests and raise tests
isVoid Aug 23, 2022
954f9c9
factor out get_geometry_iterator
isVoid Aug 24, 2022
0db51ae
rename detail functions
isVoid Aug 24, 2022
dfef5d9
add comments to kernel
isVoid Aug 24, 2022
3f4b85a
add documentation
isVoid Aug 25, 2022
08db4de
add notes section
isVoid Aug 25, 2022
88d0a21
remove unsued code
isVoid Aug 26, 2022
c12464e
remove more unused code
isVoid Aug 26, 2022
fe85767
Apply suggestions from code review
isVoid Aug 26, 2022
2183fa4
remove `cartesian_2d`
isVoid Aug 26, 2022
7329c1b
style
isVoid Aug 26, 2022
adc0e43
Merge branch 'branch-22.10' of https://github.com/rapidsai/cuspatial …
isVoid Aug 26, 2022
d8f3a6a
Update python API docs
isVoid Aug 26, 2022
f42211d
rename dispatcher, add documentation
isVoid Aug 26, 2022
fddba19
Rename multi-geom dispatch file.
isVoid Sep 6, 2022
8cbc55d
Add iterator functor docstring
isVoid Sep 6, 2022
6c57187
Update docstring
isVoid Sep 8, 2022
102cb0e
Apply suggestions from code review
isVoid Sep 8, 2022
71f199d
docstring update
isVoid Sep 8, 2022
cb66b5a
make template parameter docstring clearer
isVoid Sep 8, 2022
8307562
Apply suggestions from code review
isVoid Sep 8, 2022
c435e79
style
isVoid Sep 8, 2022
e255277
Merge branch 'feature/python_multi_linestring_distance' of github.com…
isVoid Sep 8, 2022
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
51 changes: 43 additions & 8 deletions cpp/include/cuspatial/distance/point_linestring_distance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,30 +35,65 @@ namespace cuspatial {
* Point: (1, 1)
* Linestring: (0, 0) -> (1, 1) -> (2, 0) -> (3, 0) -> (3, 1)
*
* The input of the abbove example is:
* The input of the above example is:
* multipoint_geometry_offsets: nullopt
* points_xy: {0, 1, 0, 1}
* linestring_offsets: {0, 3, 8}
* multilinestring_geometry_offsets: nullopt
* linestring_part_offsets: {0, 3, 8}
* linestring_xy: {0, 1, 1, 0, 2, 0, 0, 0, 1, 1, 2, 0, 3, 0, 3, 1}
*
* Result: {sqrt(2)/2, 0}
* ```
*
* The following example contains 3 pairs of MultiPoint and MultiLinestring.
* ```
* First pair:
* MultiPoint: (0, 1)
* MultiLinestring: (0, -1) -> (-2, -3), (-4, -5) -> (-5, -6)
*
* Second pair:
* MultiPoint: (2, 3), (4, 5)
* MultiLinestring: (7, 8) -> (8, 9)
*
* Third pair:
* MultiPoint: (6, 7), (8, 9)
* MultiLinestring: (9, 10) -> (10, 11)

* The input of the above example is:
* multipoint_geometry_offsets: {0, 1, 3, 5}
* points_xy: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
* multilinestring_geometry_offsets: {0, 2, 3, 5}
* linestring_part_offsets: {0, 2, 4, 6, 8}
* linestring_points_xy: {0, -1, -2, -3, -4, -5, -5, -6, 7, 8, 8, 9, 9, 10, 10 ,11}
*
* Result: {2.0, 4.24264, 1.41421}
* ```
*
* @param multipoint_geometry_offsets Beginning and ending indices to each geometry in the
* multi-point
* @param points_xy Interleaved x, y-coordinates of points
* @param linestring_offsets Beginning and ending indices for each linestring in the `linestring_x`
* and `linestring_y` arrays. Must satisfy `linestring_offsets.size() + 1 == points_xy.size()`.
* @param multilinestring_geometry_offsets Beginning and ending indices to each geometry in the
* multi-linestring
* @param linestring_part_offsets Beginning and ending indices for each linestring in the point
* array. Because the coordinates are interleaved, the actual starting position for the coordinate
* of linestring `i` is `2*linestring_part_offsets[i]`.
* @param linestring_points_xy Interleaved x, y-coordinates of linestring points.
* @param mr Device memory resource used to allocate the returned column.
* @return A column containing the distance between each pair of corresponding points and
* linestrings.
*
* @throws cuspatial::logic_error if the number of points and linestrings do not match.
* @throws cuspatial::logic_error if there is a size mismatch between the x- and y-coordinates of
* the points or linestring points.
* @note Any optional geometry indices, if is `nullopt`, implies the underlying geometry contains
* only one component. Otherwise, it contains multiple components.
*
* @throws cuspatial::logic_error if the number of (multi)points and (multi)linestrings do not
* match.
* @throws cuspatial::logic_error if the any of the point arrays have mismatched types.
*/
std::unique_ptr<cudf::column> pairwise_point_linestring_distance(
std::optional<cudf::device_span<cudf::size_type const>> multipoint_geometry_offsets,
cudf::column_view const& points_xy,
cudf::device_span<cudf::size_type const> linestring_offsets,
std::optional<cudf::device_span<cudf::size_type const>> multilinestring_geometry_offsets,
cudf::device_span<cudf::size_type const> linestring_part_offsets,
cudf::column_view const& linestring_points_xy,
rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,38 +42,60 @@ namespace detail {

/**
* @internal
* @brief The kernel to compute point to linestring distance
* @brief The kernel to compute multi-point to multi-linestring distance
*
* Each thread computes the distance between a line segment in the linestring and the
* corresponding point in the pair. The shortest distance is computed in the output
* array via an atomic operation.
* corresponding multi-point part in the pair. The shortest distance is computed in the
* output array via an atomic operation.
*
* @tparam Cart2dItA Iterator to 2d cartesian coordinates. Must meet requirements of
* [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible.
* @tparam Cart2dItB Iterator to 2d cartesian coordinates. Must meet requirements of
* [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible.
* @tparam OffsetIterator Iterator to linestring offsets. Must meet requirements of
* @tparam OffsetIteratorA Iterator to offsets. Must meet requirements of
* [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible.
* @tparam OffsetIteratorB Iterator to offsets. Must meet requirements of
* [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible.
* @tparam OffsetIteratorC Iterator to offsets. Must meet requirements of
* [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible.
* @tparam OutputIterator Iterator to output distances. Must meet requirements of
* [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible and mutable.
*
* @param[in] point_geometry_offset_first Iterator to the beginning of the range of the multipoint
* parts
* @param[in] point_geometry_offset_last Iterator to the end of the range of the multipoint parts
* @param[in] points_first Iterator to the beginning of the range of the points
* @param[in] points_last Iterator to the end of the range of the points
* @param[in] linestring_offsets_begin Iterator to the beginning of the range of the linestring
* @param[in] linestring_geometry_offset_first Iterator to the beginning of the range of the
* linestring parts
* @param[in] linestring_geometry_offset_last Iterator to the end of the range of the linestring
* parts
* @param[in] linestring_part_offsets_first Iterator to the beginning of the range of the linestring
* offsets
* @param[in] linestring_offsets_end Iterator to the end of the range of the linestring offsets
* @param[in] linestring_points_begin Iterator to the beginning of the range of the linestring
* @param[in] linestring_part_offsets_last Iterator to the beginning of the range of the linestring
* offsets
* @param[in] linestring_points_first Iterator to the beginning of the range of the linestring
* points
* @param[in] linestring_points_end Iterator to the end of the range of the linestring points
* @param[in] linestring_points_last Iterator to the end of the range of the linestring points
* @param[out] distances Iterator to the output range of shortest distances between pairs.
*
* [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator
* "LegacyRandomAccessIterator"
*/
template <typename Cart2dItA, typename Cart2dItB, typename OffsetIterator, typename OutputIterator>
void __global__ pairwise_point_linestring_distance(Cart2dItA points_first,
OffsetIterator linestring_offsets_first,
OffsetIterator linestring_offsets_last,
template <class Cart2dItA,
class Cart2dItB,
class OffsetIteratorA,
class OffsetIteratorB,
class OffsetIteratorC,
class OutputIterator>
void __global__ pairwise_point_linestring_distance(OffsetIteratorA point_geometry_offset_first,
OffsetIteratorA point_geometry_offset_last,
Cart2dItA points_first,
Cart2dItA points_last,
OffsetIteratorB linestring_geometry_offset_first,
OffsetIteratorB linestring_geometry_offset_last,
OffsetIteratorC linestring_part_offsets_first,
OffsetIteratorC linestring_part_offsets_last,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an entirely theoretical suggestion that relates to all the other multi arrays, particularly MultiLinestring and MultiPolygon. It seems like, instead of using an iterator for the linestring_part_offsets, and another iterator for the linestring_geometry_offsets, that we should have an iterator for the linestring_geometry_offsets which also contains the iterator for the parts. We need fewer arguments and the ability to iterate through "all linestrings and linestring parts" is encapsulated into a single iterator. A theoretical suggestion, I don't know how to do it, possible?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe you are just looking at a recursive templated iterator collection, there's some maximum level that c++ compiler allows the templates to be recursively nested within itself, but multilinestring should be well within that limit.

Does this make sense to you? https://godbolt.org/z/v95jn5G3e

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's more or less exactly what I was thinking of. Do you think it works in the context of your PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This really is just my first attempt to take a stab at the idea. I'd like to have some more feedbacks before we decide on the iterator collection interface. So no, not planning to put this in this PR.

cc @harrism

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There could be other simpler solutions, like just a MultiLinestringIteratorCollection class for example:

template<typename OffsetItA, typename OffsetItB, typename Vec2dIt>
struct MultiLinestringIteratorCollection
{
  OffsetItA geometry_offset_begin;
  OffsetItB part_offset_begin;
  Vec2dIt coordinate_begin;
};

Copy link
Contributor Author

@isVoid isVoid Sep 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This deviates a little bit from you original suggestion of having a custom iterator to represent a nested of iterator. I believe you meant to create a custom iterator that iterates over the multilinestring array, when you dereference this iterator, it returns a multilinestring - which in turn has its own iterator, and allows you to iterate into each linestring, segment and points etc. Besides, we should provide different level of iterators so that developer can pick their use-case defined parallel model as needed.

I don't have a working example, but something like:

class linestring {
    class iterator{
        std::pair<vec2d, vec2d> operator* (); // returns two end points of the line segment
        iterator operator+(diff_t i);
        iterator operator-(diff_t i);
        // other requirements of of LRAIs
    };
    iterator begin();
    iterator end();
};

class multi_linestring
{
    class linestring_iterator
    {
        linestring operator*(); // this returns a linestring
        // LRAI requirements
    };
    class segment_iterator
    {
        std::pair<vec2d, vec2d> operator* (); // returns two end points of the line segment
        // LRAI requirments
    }

    linestring_iterator linestring_begin();
    linestring_iterator linestring_end();

    segment_iterator segment_begin();
    segment_iterator segment_end();

    // The default should be the immediate next level of indirection
    auto begin() { return linestring_begin(); }
    auto end() { return linestring_end(); }
};

class multi_linestring_array
{
    class multi_linestring_iterator
    {
        multi_linestring operator*();
        // other LRAI requirements
    }
    class linestring_iterator { /* same as above */ }
    class segment_iterator { /* same as above */ }

    multilinestring_iterator multilinestring_begin();
    multilinestring_iterator multilinestring_end();

    linestring_iterator linestring_begin();
    linestring_iterator linestring_end();

    segment_iterator segment_begin();
    segment_iterator segment_end();

    // The default should be the immediate next level of indirection
    auto begin() { return multilinestring_begin(); }
    auto end() { return multilinestring_end(); }
};

But beware of the overheads you would run into when constructing these data structure per threads.

Cart2dItB linestring_points_first,
Cart2dItB linestring_points_last,
OutputIterator distances)
Expand All @@ -83,34 +105,69 @@ void __global__ pairwise_point_linestring_distance(Cart2dItA points_first,
for (auto idx = threadIdx.x + blockIdx.x * blockDim.x;
idx < std::distance(linestring_points_first, thrust::prev(linestring_points_last));
idx += gridDim.x * blockDim.x) {
auto offsets_iter =
thrust::upper_bound(thrust::seq, linestring_offsets_first, linestring_offsets_last, idx);
// Search from the part offsets array to determine the part idx of current linestring point
auto linestring_part_offsets_iter = thrust::upper_bound(
thrust::seq, linestring_part_offsets_first, linestring_part_offsets_last, idx);

// Pointer to the last point in the linestring, skip iteration.
// Note that the last point for the last linestring is guarded by the grid-stride loop.
if (offsets_iter != linestring_offsets_last and *offsets_iter - 1 == idx) { continue; }

auto point_idx = thrust::distance(linestring_offsets_first, thrust::prev(offsets_iter));
vec_2d<T> const a = linestring_points_first[idx];
vec_2d<T> const b = linestring_points_first[idx + 1];
vec_2d<T> const c = points_first[point_idx];

auto const distance_squared = point_to_segment_distance_squared(c, a, b);

atomicMin(&thrust::raw_reference_cast(*(distances + point_idx)),
static_cast<T>(std::sqrt(distance_squared)));
if (linestring_part_offsets_iter != linestring_part_offsets_last &&
*linestring_part_offsets_iter - 1 == idx) {
continue;
}

auto part_offsets_idx =
thrust::distance(linestring_part_offsets_first, thrust::prev(linestring_part_offsets_iter));

// Search from the linestring geometry offsets array to determine the geometry idx of current
// linestring point
auto geometry_offsets_iter = thrust::upper_bound(thrust::seq,
linestring_geometry_offset_first,
linestring_geometry_offset_last,
part_offsets_idx);
// geometry_idx is also the index to corresponding multipoint in the pair
auto geometry_idx =
harrism marked this conversation as resolved.
Show resolved Hide resolved
thrust::distance(linestring_geometry_offset_first, thrust::prev(geometry_offsets_iter));

// Reduce the minimum distance between different parts of the multi-point.
vec_2d<T> const a = linestring_points_first[idx];
vec_2d<T> const b = linestring_points_first[idx + 1];
T min_distance_squared = std::numeric_limits<T>::max();

for (auto point_idx = point_geometry_offset_first[geometry_idx];
point_idx < point_geometry_offset_first[geometry_idx + 1];
point_idx++) {
vec_2d<T> const c = points_first[point_idx];

// TODO: reduce redundant computation only related to `a`, `b` in this helper.
auto const distance_squared = point_to_segment_distance_squared(c, a, b);
isVoid marked this conversation as resolved.
Show resolved Hide resolved
min_distance_squared = std::min(distance_squared, min_distance_squared);
}

atomicMin(&thrust::raw_reference_cast(*(distances + geometry_idx)),
static_cast<T>(std::sqrt(min_distance_squared)));
}
}

} // namespace detail

template <class Cart2dItA, class Cart2dItB, class OffsetIterator, class OutputIt>
void pairwise_point_linestring_distance(Cart2dItA points_first,
Cart2dItA points_last,
OffsetIterator linestring_offsets_first,
Cart2dItB linestring_points_first,
Cart2dItB linestring_points_last,
OutputIt distances_first,
rmm::cuda_stream_view stream)
template <class Cart2dItA,
class Cart2dItB,
class OffsetIteratorA,
class OffsetIteratorB,
class OffsetIteratorC,
class OutputIt>
OutputIt pairwise_point_linestring_distance(OffsetIteratorA point_geometry_offset_first,
OffsetIteratorA point_geometry_offset_last,
Cart2dItA points_first,
Cart2dItA points_last,
OffsetIteratorB linestring_geometry_offset_first,
OffsetIteratorC linestring_part_offsets_first,
OffsetIteratorC linestring_part_offsets_last,
Cart2dItB linestring_points_first,
Cart2dItB linestring_points_last,
OutputIt distances_first,
rmm::cuda_stream_view stream)
{
using T = detail::iterator_vec_base_type<Cart2dItA>;

Expand All @@ -120,11 +177,12 @@ void pairwise_point_linestring_distance(Cart2dItA points_first,
static_assert(detail::is_same<vec_2d<T>,
detail::iterator_value_type<Cart2dItA>,
detail::iterator_value_type<Cart2dItB>>(),
"Inputs must be cuspatial::vec_2d<T>");
"Inputs must be cuspatial::vec_2d");

auto const num_pairs = thrust::distance(points_first, points_last);
auto const num_pairs =
thrust::distance(point_geometry_offset_first, point_geometry_offset_last) - 1;

if (num_pairs == 0) { return; }
if (num_pairs == 0) { return distances_first; }
isVoid marked this conversation as resolved.
Show resolved Hide resolved

auto const num_linestring_points =
thrust::distance(linestring_points_first, linestring_points_last);
Expand All @@ -137,14 +195,21 @@ void pairwise_point_linestring_distance(Cart2dItA points_first,
(num_linestring_points + threads_per_block - 1) / threads_per_block;

detail::pairwise_point_linestring_distance<<<num_blocks, threads_per_block, 0, stream.value()>>>(
point_geometry_offset_first,
point_geometry_offset_last,
points_first,
linestring_offsets_first,
linestring_offsets_first + num_pairs + 1,
points_last,
linestring_geometry_offset_first,
linestring_geometry_offset_first + num_pairs + 1,
linestring_part_offsets_first,
linestring_part_offsets_last,
linestring_points_first,
linestring_points_first + num_linestring_points,
linestring_points_last,
distances_first);

CUSPATIAL_CUDA_TRY(cudaGetLastError());

return distances_first + num_pairs;
}

} // namespace cuspatial
56 changes: 38 additions & 18 deletions cpp/include/cuspatial/experimental/point_linestring_distance.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,30 @@ namespace cuspatial {
* the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible.
* @tparam Cart2dItB iterator type for point array of the linestring element of each pair. Must meet
* the requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible.
* @tparam OffsetIterator iterator type for offset array. Must meet the requirements of
* [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible.
* @tparam OffsetIteratorA iterator type for `point_geometry_offset` array. Must meet the
* requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible.
* @tparam OffsetIteratorB iterator type for `linestring_geometry_offset` array. Must meet the
* requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible.
* @tparam OffsetIteratorC iterator type for `linestring_part_offset` array. Must meet the
* requirements of [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible.
* @tparam OutputIt iterator type for output array. Must meet the requirements of
* [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible.
*
* @param points_first beginning of the range of points making up the first element of each
* pair
* @param points_last end of the range of the points making up the first element of each pair
* @param linestring_offsets_first beginning of the range of the offsets to the linestring element
* of each pair
* @param linestring_points_first beginning of the range of points of the linestring element of each
* @param point_geometry_offset_first beginning of the range of multipoint geometries of each
* pair
* @param linestring_points_last end of the range of points of the linestring element of each pair
* @param distances_first beginning the output range of distances
* @param point_geometry_offset_last end of the range of multipoint geometries of each pair
* @param points_first beginning of the range of point values
* @param points_last end of the range of the point values
* @param linestring_geometry_offset_first beginning of the range of offsets to the multilinestring
* geometry of each pair, the end range is implied by linestring_geometry_offset_first +
* std::distance(`point_geometry_offset_first`, `point_geometry_offset_last`)
* @param linestring_offsets_first beginning of the range of offsets to the starting point
* of each linestring
* @param linestring_offsets_last end of the range of offsets to the starting point
* of each linestring
* @param linestring_points_first beginning of the range of linestring points
* @param linestring_points_last end of the range of linestring points
* @param distances_first beginning of the output range of distances
* @param stream The CUDA stream to use for device memory operations and kernel launches.
*
* @pre all input iterators for coordinates must have `cuspatial::vec_2d` type.
Expand All @@ -53,14 +63,24 @@ namespace cuspatial {
* [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator
* "LegacyRandomAccessIterator"
*/
template <class Cart2dItA, class Cart2dItB, class OffsetIterator, class OutputIt>
void pairwise_point_linestring_distance(Cart2dItA points_first,
Cart2dItA points_last,
OffsetIterator linestring_offsets_first,
Cart2dItB linestring_points_first,
Cart2dItB linestring_points_last,
OutputIt distances_first,
rmm::cuda_stream_view stream = rmm::cuda_stream_default);
template <class Cart2dItA,
class Cart2dItB,
class OffsetIteratorA,
class OffsetIteratorB,
class OffsetIteratorC,
class OutputIt>
OutputIt pairwise_point_linestring_distance(
OffsetIteratorA point_geometry_offset_first,
OffsetIteratorA point_geometry_offset_last,
Cart2dItA points_first,
Cart2dItA points_last,
OffsetIteratorB linestring_geometry_offset_first,
OffsetIteratorC linestring_part_offsets_first,
OffsetIteratorC linestring_part_offsets_last,
Cart2dItB linestring_points_first,
Cart2dItB linestring_points_last,
OutputIt distances_first,
rmm::cuda_stream_view stream = rmm::cuda_stream_default);

} // namespace cuspatial

Expand Down
Loading