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>
32#include <thrust/device_vector.h>
33#include <thrust/host_vector.h>
35#include <initializer_list>
43template <
typename Range>
44auto make_device_vector(Range rng)
46 using T =
typename Range::value_type;
47 return rmm::device_vector<T>(rng.begin(), rng.end());
51auto make_device_vector(std::initializer_list<T> inl)
53 return rmm::device_vector<T>(inl.begin(), inl.end());
57auto make_device_uvector(std::initializer_list<T> inl,
58 rmm::cuda_stream_view stream,
59 rmm::mr::device_memory_resource* mr)
61 std::vector<T> hvec(inl.begin(), inl.end());
62 auto res = rmm::device_uvector<T>(inl.size(), stream, mr);
63 cudaMemcpyAsync(res.data(),
65 hvec.size() *
sizeof(T),
66 cudaMemcpyKind::cudaMemcpyHostToDevice,
72auto make_host_vector(std::initializer_list<T> inl)
74 return thrust::host_vector<T>{inl.begin(), inl.end()};
85template <
typename GeometryArray,
typename PartArray,
typename RingArray,
typename CoordinateArray>
88 using geometry_t =
typename GeometryArray::value_type;
89 using part_t =
typename PartArray::value_type;
90 using ring_t =
typename RingArray::value_type;
91 using coord_t =
typename CoordinateArray::value_type;
94 thrust::device_vector<part_t> part_offsets_array,
95 thrust::device_vector<ring_t> ring_offsets_array,
96 thrust::device_vector<coord_t> coordinates_array)
97 : _geometry_offsets_array(geometry_offsets_array),
98 _part_offsets_array(part_offsets_array),
99 _ring_offsets_array(ring_offsets_array),
100 _coordinates_array(coordinates_array)
105 rmm::device_vector<part_t>&& part_offsets_array,
106 rmm::device_vector<ring_t>&& ring_offsets_array,
107 rmm::device_vector<coord_t>&& coordinates_array)
108 : _geometry_offsets_array(std::move(geometry_offsets_array)),
109 _part_offsets_array(std::move(part_offsets_array)),
110 _ring_offsets_array(std::move(ring_offsets_array)),
111 _coordinates_array(std::move(coordinates_array))
116 rmm::device_uvector<part_t>&& part_offsets_array,
117 rmm::device_uvector<ring_t>&& ring_offsets_array,
118 rmm::device_uvector<coord_t>&& coordinates_array)
119 : _geometry_offsets_array(std::move(geometry_offsets_array)),
120 _part_offsets_array(std::move(part_offsets_array)),
121 _ring_offsets_array(std::move(ring_offsets_array)),
122 _coordinates_array(std::move(coordinates_array))
127 auto size() {
return _geometry_offsets_array.size() - 1; }
133 _geometry_offsets_array.end(),
134 _part_offsets_array.begin(),
135 _part_offsets_array.end(),
136 _ring_offsets_array.begin(),
137 _ring_offsets_array.end(),
138 _coordinates_array.begin(),
139 _coordinates_array.end());
147 auto geometry_offsets = cuspatial::test::to_host<geometry_t>(_geometry_offsets_array);
148 auto part_offsets = cuspatial::test::to_host<part_t>(_part_offsets_array);
149 auto ring_offsets = cuspatial::test::to_host<ring_t>(_ring_offsets_array);
150 auto coordinate_offsets = cuspatial::test::to_host<coord_t>(_coordinates_array);
152 return std::tuple{geometry_offsets, part_offsets, ring_offsets, coordinate_offsets};
157 return std::tuple{std::move(_geometry_offsets_array),
158 std::move(_part_offsets_array),
159 std::move(_ring_offsets_array),
160 std::move(_coordinates_array)};
168 multipolygon_array<GeometryArray, PartArray, RingArray, CoordinateArray>
const& arr)
170 auto [geometry_offsets, part_offsets, ring_offsets, coordinates] = arr.to_host();
172 return os <<
"Geometry Offsets:\n\t{" << geometry_offsets <<
"}\n"
173 <<
"Part Offsets:\n\t{" << part_offsets <<
"}\n"
174 <<
"Ring Offsets: \n\t{" << ring_offsets <<
"}\n"
175 <<
"Coordinates: \n\t{" << coordinates <<
"}\n";
179 GeometryArray _geometry_offsets_array;
180 PartArray _part_offsets_array;
181 RingArray _ring_offsets_array;
182 CoordinateArray _coordinates_array;
185template <
typename IndexRange,
187 typename IndexType =
typename IndexRange::value_type>
188auto make_multipolygon_array(IndexRange geometry_inl,
191 CoordRange coord_inl)
193 using CoordType =
typename CoordRange::value_type;
194 using DeviceIndexVector = thrust::device_vector<IndexType>;
195 using DeviceCoordVector = thrust::device_vector<CoordType>;
197 return multipolygon_array<DeviceIndexVector,
200 DeviceCoordVector>(make_device_vector(geometry_inl),
201 make_device_vector(part_inl),
202 make_device_vector(ring_inl),
203 make_device_vector(coord_inl));
207auto make_multipolygon_array(std::initializer_list<std::size_t> geometry_inl,
208 std::initializer_list<std::size_t> part_inl,
209 std::initializer_list<std::size_t> ring_inl,
210 std::initializer_list<vec_2d<T>> coord_inl)
212 return make_multipolygon_array(range(geometry_inl.begin(), geometry_inl.end()),
213 range(part_inl.begin(), part_inl.end()),
214 range(ring_inl.begin(), ring_inl.end()),
215 range(coord_inl.begin(), coord_inl.end()));
218template <
typename IndexType,
typename CoordType>
219auto make_multipolygon_array(rmm::device_uvector<IndexType> geometry_inl,
220 rmm::device_uvector<IndexType> part_inl,
221 rmm::device_uvector<IndexType> ring_inl,
222 rmm::device_uvector<CoordType> coord_inl)
224 return multipolygon_array<rmm::device_uvector<IndexType>,
225 rmm::device_uvector<IndexType>,
226 rmm::device_uvector<IndexType>,
227 rmm::device_uvector<CoordType>>(
228 std::move(geometry_inl), std::move(part_inl), std::move(ring_inl), std::move(coord_inl));
238template <
typename GeometryArray,
typename PartArray,
typename CoordinateArray>
242 PartArray part_offsets_array,
243 CoordinateArray coordinate_array)
244 : _geometry_offset_array(std::move(geometry_offsets_array)),
245 _part_offset_array(std::move(part_offsets_array)),
246 _coordinate_array(std::move(coordinate_array))
251 auto size() {
return _geometry_offset_array.size() - 1; }
257 _geometry_offset_array.end(),
258 _part_offset_array.begin(),
259 _part_offset_array.end(),
260 _coordinate_array.begin(),
261 _coordinate_array.end());
266 return std::tuple{std::move(_geometry_offset_array),
267 std::move(_part_offset_array),
268 std::move(_coordinate_array)};
272 GeometryArray _geometry_offset_array;
273 PartArray _part_offset_array;
274 CoordinateArray _coordinate_array;
285template <
typename IndexType,
typename T>
286auto make_multilinestring_array(rmm::device_uvector<IndexType>&& geometry_inl,
287 rmm::device_uvector<IndexType>&& part_inl,
288 rmm::device_uvector<vec_2d<T>>&& coord_inl)
290 return multilinestring_array<rmm::device_uvector<IndexType>,
291 rmm::device_uvector<IndexType>,
292 rmm::device_uvector<vec_2d<T>>>(
293 std::move(geometry_inl), std::move(part_inl), std::move(coord_inl));
304template <
typename IndexType,
typename T>
305auto make_multilinestring_array(rmm::device_vector<IndexType>&& geometry_inl,
306 rmm::device_vector<IndexType>&& part_inl,
307 rmm::device_vector<vec_2d<T>>&& coord_inl)
309 return multilinestring_array<rmm::device_vector<IndexType>,
310 rmm::device_vector<IndexType>,
311 rmm::device_vector<vec_2d<T>>>(
312 std::move(geometry_inl), std::move(part_inl), std::move(coord_inl));
325auto make_multilinestring_array(std::initializer_list<std::size_t> geometry_inl,
326 std::initializer_list<std::size_t> part_inl,
327 std::initializer_list<vec_2d<T>> coord_inl)
329 return multilinestring_array(
330 rmm::device_vector<std::size_t>(
331 std::vector<std::size_t>(geometry_inl.begin(), geometry_inl.end())),
332 rmm::device_vector<std::size_t>(std::vector<unsigned int>(part_inl.begin(), part_inl.end())),
333 rmm::device_vector<vec_2d<T>>(std::vector<vec_2d<T>>(coord_inl.begin(), coord_inl.end())));
342template <
typename GeometryArray,
typename CoordinateArray>
345 using geometry_t =
typename GeometryArray::value_type;
346 using coord_t =
typename CoordinateArray::value_type;
349 thrust::device_vector<coord_t> coordinate_array)
350 : _geometry_offsets(geometry_offsets_array), _coordinates(coordinate_array)
355 rmm::device_uvector<coord_t>&& coordinate_array)
356 : _geometry_offsets(std::move(geometry_offsets_array)),
357 _coordinates(std::move(coordinate_array))
362 auto size() {
return _geometry_offsets.size() - 1; }
368 _geometry_offsets.begin(), _geometry_offsets.end(), _coordinates.begin(), _coordinates.end()};
372 auto release() {
return std::pair{std::move(_geometry_offsets), std::move(_coordinates)}; }
375 GeometryArray _geometry_offsets;
376 CoordinateArray _coordinates;
383template <
typename GeometryRange,
typename CoordRange>
384auto make_multipoint_array(GeometryRange geometry_inl, CoordRange coordinates_inl)
386 using IndexType =
typename GeometryRange::value_type;
387 using CoordType =
typename CoordRange::value_type;
388 using DeviceIndexVector = thrust::device_vector<IndexType>;
389 using DeviceCoordVector = thrust::device_vector<CoordType>;
391 return multipoint_array<DeviceIndexVector, DeviceCoordVector>{
392 make_device_vector(geometry_inl), make_device_vector(coordinates_inl)};
410auto make_multipoint_array(std::initializer_list<std::initializer_list<vec_2d<T>>> inl)
412 std::vector<std::size_t> offsets{0};
413 std::transform(inl.begin(), inl.end(), std::back_inserter(offsets), [](
auto multipoint) {
414 return multipoint.size();
416 std::inclusive_scan(offsets.begin(), offsets.end(), offsets.begin());
418 std::vector<vec_2d<T>> coordinates = std::accumulate(
419 inl.begin(), inl.end(), std::vector<vec_2d<T>>{}, [](std::vector<vec_2d<T>>& init,
auto cur) {
420 init.insert(init.end(), cur.begin(), cur.end());
424 return multipoint_array<rmm::device_vector<std::size_t>, rmm::device_vector<vec_2d<T>>>{
425 rmm::device_vector<std::size_t>(offsets), rmm::device_vector<vec_2d<T>>(coordinates)};
432template <
typename IndexType,
typename T>
433auto make_multipoint_array(rmm::device_uvector<IndexType> geometry_offsets,
434 rmm::device_uvector<vec_2d<T>> coords)
436 return multipoint_array<rmm::device_uvector<std::size_t>, rmm::device_uvector<vec_2d<T>>>{
437 std::move(geometry_offsets), std::move(coords)};
444template <
typename IndexType,
typename T>
445auto make_multipoint_array(rmm::device_vector<IndexType> geometry_offsets,
446 rmm::device_vector<vec_2d<T>> coords)
448 return multipoint_array<rmm::device_vector<std::size_t>, rmm::device_vector<vec_2d<T>>>{
449 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 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.