19#include <cuspatial_test/test_util.cuh>
26#include <cuspatial/traits.hpp>
28#include <rmm/cuda_stream_view.hpp>
29#include <rmm/device_uvector.hpp>
30#include <rmm/device_vector.hpp>
31#include <rmm/resource_ref.hpp>
33#include <thrust/device_vector.h>
34#include <thrust/host_vector.h>
36#include <initializer_list>
44template <
typename Range>
45auto make_device_vector(Range rng)
47 using T =
typename Range::value_type;
48 return rmm::device_vector<T>(rng.begin(), rng.end());
52auto make_device_vector(std::initializer_list<T> inl)
54 return rmm::device_vector<T>(inl.begin(), inl.end());
58auto make_device_uvector(std::initializer_list<T> inl,
59 rmm::cuda_stream_view stream,
60 rmm::device_async_resource_ref mr)
62 std::vector<T> hvec(inl.begin(), inl.end());
63 auto res = rmm::device_uvector<T>(inl.size(), stream, mr);
64 cudaMemcpyAsync(res.data(),
66 hvec.size() *
sizeof(T),
67 cudaMemcpyKind::cudaMemcpyHostToDevice,
80template <
typename GeometryArray,
typename PartArray,
typename RingArray,
typename CoordinateArray>
83 using geometry_t =
typename GeometryArray::value_type;
84 using part_t =
typename PartArray::value_type;
85 using ring_t =
typename RingArray::value_type;
86 using coord_t =
typename CoordinateArray::value_type;
89 thrust::device_vector<part_t> part_offsets_array,
90 thrust::device_vector<ring_t> ring_offsets_array,
91 thrust::device_vector<coord_t> coordinates_array)
92 : _geometry_offsets_array(geometry_offsets_array),
93 _part_offsets_array(part_offsets_array),
94 _ring_offsets_array(ring_offsets_array),
95 _coordinates_array(coordinates_array)
100 rmm::device_vector<part_t>&& part_offsets_array,
101 rmm::device_vector<ring_t>&& ring_offsets_array,
102 rmm::device_vector<coord_t>&& coordinates_array)
103 : _geometry_offsets_array(std::move(geometry_offsets_array)),
104 _part_offsets_array(std::move(part_offsets_array)),
105 _ring_offsets_array(std::move(ring_offsets_array)),
106 _coordinates_array(std::move(coordinates_array))
111 rmm::device_uvector<part_t>&& part_offsets_array,
112 rmm::device_uvector<ring_t>&& ring_offsets_array,
113 rmm::device_uvector<coord_t>&& coordinates_array)
114 : _geometry_offsets_array(std::move(geometry_offsets_array)),
115 _part_offsets_array(std::move(part_offsets_array)),
116 _ring_offsets_array(std::move(ring_offsets_array)),
117 _coordinates_array(std::move(coordinates_array))
122 auto size() {
return _geometry_offsets_array.size() - 1; }
128 _geometry_offsets_array.end(),
129 _part_offsets_array.begin(),
130 _part_offsets_array.end(),
131 _ring_offsets_array.begin(),
132 _ring_offsets_array.end(),
133 _coordinates_array.begin(),
134 _coordinates_array.end());
142 auto geometry_offsets = cuspatial::test::to_host<geometry_t>(_geometry_offsets_array);
143 auto part_offsets = cuspatial::test::to_host<part_t>(_part_offsets_array);
144 auto ring_offsets = cuspatial::test::to_host<ring_t>(_ring_offsets_array);
145 auto coordinate_offsets = cuspatial::test::to_host<coord_t>(_coordinates_array);
147 return std::tuple{geometry_offsets, part_offsets, ring_offsets, coordinate_offsets};
152 return std::tuple{std::move(_geometry_offsets_array),
153 std::move(_part_offsets_array),
154 std::move(_ring_offsets_array),
155 std::move(_coordinates_array)};
163 multipolygon_array<GeometryArray, PartArray, RingArray, CoordinateArray>
const& arr)
165 auto [geometry_offsets, part_offsets, ring_offsets, coordinates] = arr.to_host();
167 auto print_vector = [&](
auto const& vec) {
168 for (
auto it = vec.begin(); it != vec.end(); it++) {
170 if (std::next(it) != vec.end()) { os <<
", "; }
174 os <<
"Geometry Offsets:\n\t{";
175 print_vector(geometry_offsets);
177 os <<
"Part Offsets:\n\t{";
178 print_vector(part_offsets);
180 os <<
"Ring Offsets: \n\t{";
181 print_vector(ring_offsets);
183 os <<
"Coordinates: \n\t{";
184 print_vector(coordinates);
190 GeometryArray _geometry_offsets_array;
191 PartArray _part_offsets_array;
192 RingArray _ring_offsets_array;
193 CoordinateArray _coordinates_array;
196template <
typename IndexRange,
198 typename IndexType =
typename IndexRange::value_type>
199auto make_multipolygon_array(IndexRange geometry_inl,
202 CoordRange coord_inl)
204 using CoordType =
typename CoordRange::value_type;
205 using DeviceIndexVector = thrust::device_vector<IndexType>;
206 using DeviceCoordVector = thrust::device_vector<CoordType>;
208 return multipolygon_array<DeviceIndexVector,
211 DeviceCoordVector>(make_device_vector(geometry_inl),
212 make_device_vector(part_inl),
213 make_device_vector(ring_inl),
214 make_device_vector(coord_inl));
218auto make_multipolygon_array(std::initializer_list<std::size_t> geometry_inl,
219 std::initializer_list<std::size_t> part_inl,
220 std::initializer_list<std::size_t> ring_inl,
221 std::initializer_list<vec_2d<T>> coord_inl)
223 return make_multipolygon_array(range(geometry_inl.begin(), geometry_inl.end()),
224 range(part_inl.begin(), part_inl.end()),
225 range(ring_inl.begin(), ring_inl.end()),
226 range(coord_inl.begin(), coord_inl.end()));
229template <
typename IndexType,
typename CoordType>
230auto make_multipolygon_array(rmm::device_uvector<IndexType> geometry_inl,
231 rmm::device_uvector<IndexType> part_inl,
232 rmm::device_uvector<IndexType> ring_inl,
233 rmm::device_uvector<CoordType> coord_inl)
235 return multipolygon_array<rmm::device_uvector<IndexType>,
236 rmm::device_uvector<IndexType>,
237 rmm::device_uvector<IndexType>,
238 rmm::device_uvector<CoordType>>(
239 std::move(geometry_inl), std::move(part_inl), std::move(ring_inl), std::move(coord_inl));
249template <
typename GeometryArray,
typename PartArray,
typename CoordinateArray>
253 PartArray part_offsets_array,
254 CoordinateArray coordinate_array)
255 : _geometry_offset_array(std::move(geometry_offsets_array)),
256 _part_offset_array(std::move(part_offsets_array)),
257 _coordinate_array(std::move(coordinate_array))
262 auto size() {
return _geometry_offset_array.size() - 1; }
268 _geometry_offset_array.end(),
269 _part_offset_array.begin(),
270 _part_offset_array.end(),
271 _coordinate_array.begin(),
272 _coordinate_array.end());
277 return std::tuple{std::move(_geometry_offset_array),
278 std::move(_part_offset_array),
279 std::move(_coordinate_array)};
283 GeometryArray _geometry_offset_array;
284 PartArray _part_offset_array;
285 CoordinateArray _coordinate_array;
296template <
typename IndexType,
typename T>
297auto make_multilinestring_array(rmm::device_uvector<IndexType>&& geometry_inl,
298 rmm::device_uvector<IndexType>&& part_inl,
299 rmm::device_uvector<vec_2d<T>>&& coord_inl)
301 return multilinestring_array<rmm::device_uvector<IndexType>,
302 rmm::device_uvector<IndexType>,
303 rmm::device_uvector<vec_2d<T>>>(
304 std::move(geometry_inl), std::move(part_inl), std::move(coord_inl));
315template <
typename IndexType,
typename T>
316auto make_multilinestring_array(rmm::device_vector<IndexType>&& geometry_inl,
317 rmm::device_vector<IndexType>&& part_inl,
318 rmm::device_vector<vec_2d<T>>&& coord_inl)
320 return multilinestring_array<rmm::device_vector<IndexType>,
321 rmm::device_vector<IndexType>,
322 rmm::device_vector<vec_2d<T>>>(
323 std::move(geometry_inl), std::move(part_inl), std::move(coord_inl));
336auto make_multilinestring_array(std::initializer_list<std::size_t> geometry_inl,
337 std::initializer_list<std::size_t> part_inl,
338 std::initializer_list<vec_2d<T>> coord_inl)
340 return multilinestring_array(
341 rmm::device_vector<std::size_t>(
342 std::vector<std::size_t>(geometry_inl.begin(), geometry_inl.end())),
343 rmm::device_vector<std::size_t>(std::vector<unsigned int>(part_inl.begin(), part_inl.end())),
344 rmm::device_vector<vec_2d<T>>(std::vector<vec_2d<T>>(coord_inl.begin(), coord_inl.end())));
353template <
typename GeometryArray,
typename CoordinateArray>
356 using geometry_t =
typename GeometryArray::value_type;
357 using coord_t =
typename CoordinateArray::value_type;
360 thrust::device_vector<coord_t> coordinate_array)
361 : _geometry_offsets(geometry_offsets_array), _coordinates(coordinate_array)
366 rmm::device_uvector<coord_t>&& coordinate_array)
367 : _geometry_offsets(std::move(geometry_offsets_array)),
368 _coordinates(std::move(coordinate_array))
373 auto size() {
return _geometry_offsets.size() - 1; }
379 _geometry_offsets.begin(), _geometry_offsets.end(), _coordinates.begin(), _coordinates.end()};
387 auto geometry_offsets = cuspatial::test::to_host<geometry_t>(_geometry_offsets);
388 auto coordinate_offsets = cuspatial::test::to_host<coord_t>(_coordinates);
390 return std::tuple{geometry_offsets, coordinate_offsets};
394 auto release() {
return std::pair{std::move(_geometry_offsets), std::move(_coordinates)}; }
397 GeometryArray _geometry_offsets;
398 CoordinateArray _coordinates;
405template <
typename GeometryRange,
typename CoordRange>
406auto make_multipoint_array(GeometryRange geometry_inl, CoordRange coordinates_inl)
408 using IndexType =
typename GeometryRange::value_type;
409 using CoordType =
typename CoordRange::value_type;
410 using DeviceIndexVector = thrust::device_vector<IndexType>;
411 using DeviceCoordVector = thrust::device_vector<CoordType>;
413 return multipoint_array<DeviceIndexVector, DeviceCoordVector>{
414 make_device_vector(geometry_inl), make_device_vector(coordinates_inl)};
432auto make_multipoint_array(std::initializer_list<std::initializer_list<vec_2d<T>>> inl)
434 std::vector<std::size_t> offsets{0};
435 std::transform(inl.begin(), inl.end(), std::back_inserter(offsets), [](
auto multipoint) {
436 return multipoint.size();
438 std::inclusive_scan(offsets.begin(), offsets.end(), offsets.begin());
440 std::vector<vec_2d<T>> coordinates = std::accumulate(
441 inl.begin(), inl.end(), std::vector<vec_2d<T>>{}, [](std::vector<vec_2d<T>>& init,
auto cur) {
442 init.insert(init.end(), cur.begin(), cur.end());
446 return multipoint_array<rmm::device_vector<std::size_t>, rmm::device_vector<vec_2d<T>>>{
447 rmm::device_vector<std::size_t>(offsets), rmm::device_vector<vec_2d<T>>(coordinates)};
454template <
typename IndexType,
typename T>
455auto make_multipoint_array(rmm::device_uvector<IndexType> geometry_offsets,
456 rmm::device_uvector<vec_2d<T>> coords)
458 return multipoint_array<rmm::device_uvector<std::size_t>, rmm::device_uvector<vec_2d<T>>>{
459 std::move(geometry_offsets), std::move(coords)};
466template <
typename IndexType,
typename T>
467auto make_multipoint_array(rmm::device_vector<IndexType> geometry_offsets,
468 rmm::device_vector<vec_2d<T>> coords)
470 return multipoint_array<rmm::device_vector<std::size_t>, rmm::device_vector<vec_2d<T>>>{
471 std::move(geometry_offsets), std::move(coords)};
Non-owning range-based interface to multilinestring data.
Non-owning range-based interface to multipoint data.
Non-owning range-based interface to multipolygon data.
Owning object of a multilinestring array following geoarrow layout.
auto size()
Return the number of multilinestrings.
auto range()
Return range object of the multilinestring array.
Owning object of a multipoint array following geoarrow format.
auto size()
Return the number of multipoints.
auto to_host() const
Copy the offset arrays to host.
auto release()
Release ownership.
auto range()
Return range object of the multipoint array.
Owning object of a multipolygon array following geoarrow layout.
auto range()
Return range object of the multipolygon array.
auto to_host() const
Copy the offset arrays to host.
friend std::ostream & operator<<(std::ostream &os, multipolygon_array< GeometryArray, PartArray, RingArray, CoordinateArray > const &arr)
Output stream operator for multipolygon_array for human-readable formatting.
auto size()
Return the number of multipolygons.