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,
79template <
typename GeometryArray,
typename PartArray,
typename RingArray,
typename CoordinateArray>
82 using geometry_t =
typename GeometryArray::value_type;
83 using part_t =
typename PartArray::value_type;
84 using ring_t =
typename RingArray::value_type;
85 using coord_t =
typename CoordinateArray::value_type;
88 thrust::device_vector<part_t> part_offsets_array,
89 thrust::device_vector<ring_t> ring_offsets_array,
90 thrust::device_vector<coord_t> coordinates_array)
91 : _geometry_offsets_array(geometry_offsets_array),
92 _part_offsets_array(part_offsets_array),
93 _ring_offsets_array(ring_offsets_array),
94 _coordinates_array(coordinates_array)
99 rmm::device_vector<part_t>&& part_offsets_array,
100 rmm::device_vector<ring_t>&& ring_offsets_array,
101 rmm::device_vector<coord_t>&& coordinates_array)
102 : _geometry_offsets_array(std::move(geometry_offsets_array)),
103 _part_offsets_array(std::move(part_offsets_array)),
104 _ring_offsets_array(std::move(ring_offsets_array)),
105 _coordinates_array(std::move(coordinates_array))
110 rmm::device_uvector<part_t>&& part_offsets_array,
111 rmm::device_uvector<ring_t>&& ring_offsets_array,
112 rmm::device_uvector<coord_t>&& coordinates_array)
113 : _geometry_offsets_array(std::move(geometry_offsets_array)),
114 _part_offsets_array(std::move(part_offsets_array)),
115 _ring_offsets_array(std::move(ring_offsets_array)),
116 _coordinates_array(std::move(coordinates_array))
121 auto size() {
return _geometry_offsets_array.size() - 1; }
127 _geometry_offsets_array.end(),
128 _part_offsets_array.begin(),
129 _part_offsets_array.end(),
130 _ring_offsets_array.begin(),
131 _ring_offsets_array.end(),
132 _coordinates_array.begin(),
133 _coordinates_array.end());
141 auto geometry_offsets = cuspatial::test::to_host<geometry_t>(_geometry_offsets_array);
142 auto part_offsets = cuspatial::test::to_host<part_t>(_part_offsets_array);
143 auto ring_offsets = cuspatial::test::to_host<ring_t>(_ring_offsets_array);
144 auto coordinate_offsets = cuspatial::test::to_host<coord_t>(_coordinates_array);
146 return std::tuple{geometry_offsets, part_offsets, ring_offsets, coordinate_offsets};
151 return std::tuple{std::move(_geometry_offsets_array),
152 std::move(_part_offsets_array),
153 std::move(_ring_offsets_array),
154 std::move(_coordinates_array)};
162 multipolygon_array<GeometryArray, PartArray, RingArray, CoordinateArray>
const& arr)
164 auto [geometry_offsets, part_offsets, ring_offsets, coordinates] = arr.to_host();
166 return os <<
"Geometry Offsets:\n\t{" << geometry_offsets <<
"}\n"
167 <<
"Part Offsets:\n\t{" << part_offsets <<
"}\n"
168 <<
"Ring Offsets: \n\t{" << ring_offsets <<
"}\n"
169 <<
"Coordinates: \n\t{" << coordinates <<
"}\n";
173 GeometryArray _geometry_offsets_array;
174 PartArray _part_offsets_array;
175 RingArray _ring_offsets_array;
176 CoordinateArray _coordinates_array;
179template <
typename IndexRange,
181 typename IndexType =
typename IndexRange::value_type>
182auto make_multipolygon_array(IndexRange geometry_inl,
185 CoordRange coord_inl)
187 using CoordType =
typename CoordRange::value_type;
188 using DeviceIndexVector = thrust::device_vector<IndexType>;
189 using DeviceCoordVector = thrust::device_vector<CoordType>;
191 return multipolygon_array<DeviceIndexVector,
194 DeviceCoordVector>(make_device_vector(geometry_inl),
195 make_device_vector(part_inl),
196 make_device_vector(ring_inl),
197 make_device_vector(coord_inl));
201auto make_multipolygon_array(std::initializer_list<std::size_t> geometry_inl,
202 std::initializer_list<std::size_t> part_inl,
203 std::initializer_list<std::size_t> ring_inl,
204 std::initializer_list<vec_2d<T>> coord_inl)
206 return make_multipolygon_array(range(geometry_inl.begin(), geometry_inl.end()),
207 range(part_inl.begin(), part_inl.end()),
208 range(ring_inl.begin(), ring_inl.end()),
209 range(coord_inl.begin(), coord_inl.end()));
212template <
typename IndexType,
typename CoordType>
213auto make_multipolygon_array(rmm::device_uvector<IndexType> geometry_inl,
214 rmm::device_uvector<IndexType> part_inl,
215 rmm::device_uvector<IndexType> ring_inl,
216 rmm::device_uvector<CoordType> coord_inl)
218 return multipolygon_array<rmm::device_uvector<IndexType>,
219 rmm::device_uvector<IndexType>,
220 rmm::device_uvector<IndexType>,
221 rmm::device_uvector<CoordType>>(
222 std::move(geometry_inl), std::move(part_inl), std::move(ring_inl), std::move(coord_inl));
232template <
typename GeometryArray,
typename PartArray,
typename CoordinateArray>
236 PartArray part_offsets_array,
237 CoordinateArray coordinate_array)
238 : _geometry_offset_array(std::move(geometry_offsets_array)),
239 _part_offset_array(std::move(part_offsets_array)),
240 _coordinate_array(std::move(coordinate_array))
245 auto size() {
return _geometry_offset_array.size() - 1; }
251 _geometry_offset_array.end(),
252 _part_offset_array.begin(),
253 _part_offset_array.end(),
254 _coordinate_array.begin(),
255 _coordinate_array.end());
260 return std::tuple{std::move(_geometry_offset_array),
261 std::move(_part_offset_array),
262 std::move(_coordinate_array)};
266 GeometryArray _geometry_offset_array;
267 PartArray _part_offset_array;
268 CoordinateArray _coordinate_array;
279template <
typename IndexType,
typename T>
280auto make_multilinestring_array(rmm::device_uvector<IndexType>&& geometry_inl,
281 rmm::device_uvector<IndexType>&& part_inl,
282 rmm::device_uvector<vec_2d<T>>&& coord_inl)
284 return multilinestring_array<rmm::device_uvector<IndexType>,
285 rmm::device_uvector<IndexType>,
286 rmm::device_uvector<vec_2d<T>>>(
287 std::move(geometry_inl), std::move(part_inl), std::move(coord_inl));
298template <
typename IndexType,
typename T>
299auto make_multilinestring_array(rmm::device_vector<IndexType>&& geometry_inl,
300 rmm::device_vector<IndexType>&& part_inl,
301 rmm::device_vector<vec_2d<T>>&& coord_inl)
303 return multilinestring_array<rmm::device_vector<IndexType>,
304 rmm::device_vector<IndexType>,
305 rmm::device_vector<vec_2d<T>>>(
306 std::move(geometry_inl), std::move(part_inl), std::move(coord_inl));
319auto make_multilinestring_array(std::initializer_list<std::size_t> geometry_inl,
320 std::initializer_list<std::size_t> part_inl,
321 std::initializer_list<vec_2d<T>> coord_inl)
323 return multilinestring_array(
324 rmm::device_vector<std::size_t>(
325 std::vector<std::size_t>(geometry_inl.begin(), geometry_inl.end())),
326 rmm::device_vector<std::size_t>(std::vector<unsigned int>(part_inl.begin(), part_inl.end())),
327 rmm::device_vector<vec_2d<T>>(std::vector<vec_2d<T>>(coord_inl.begin(), coord_inl.end())));
336template <
typename GeometryArray,
typename CoordinateArray>
339 using geometry_t =
typename GeometryArray::value_type;
340 using coord_t =
typename CoordinateArray::value_type;
343 thrust::device_vector<coord_t> coordinate_array)
344 : _geometry_offsets(geometry_offsets_array), _coordinates(coordinate_array)
349 rmm::device_uvector<coord_t>&& coordinate_array)
350 : _geometry_offsets(std::move(geometry_offsets_array)),
351 _coordinates(std::move(coordinate_array))
356 auto size() {
return _geometry_offsets.size() - 1; }
362 _geometry_offsets.begin(), _geometry_offsets.end(), _coordinates.begin(), _coordinates.end()};
366 auto release() {
return std::pair{std::move(_geometry_offsets), std::move(_coordinates)}; }
369 GeometryArray _geometry_offsets;
370 CoordinateArray _coordinates;
377template <
typename GeometryRange,
typename CoordRange>
378auto make_multipoint_array(GeometryRange geometry_inl, CoordRange coordinates_inl)
380 using IndexType =
typename GeometryRange::value_type;
381 using CoordType =
typename CoordRange::value_type;
382 using DeviceIndexVector = thrust::device_vector<IndexType>;
383 using DeviceCoordVector = thrust::device_vector<CoordType>;
385 return multipoint_array<DeviceIndexVector, DeviceCoordVector>{
386 make_device_vector(geometry_inl), make_device_vector(coordinates_inl)};
404auto make_multipoint_array(std::initializer_list<std::initializer_list<vec_2d<T>>> inl)
406 std::vector<std::size_t> offsets{0};
407 std::transform(inl.begin(), inl.end(), std::back_inserter(offsets), [](
auto multipoint) {
408 return multipoint.size();
410 std::inclusive_scan(offsets.begin(), offsets.end(), offsets.begin());
412 std::vector<vec_2d<T>> coordinates = std::accumulate(
413 inl.begin(), inl.end(), std::vector<vec_2d<T>>{}, [](std::vector<vec_2d<T>>& init,
auto cur) {
414 init.insert(init.end(), cur.begin(), cur.end());
418 return multipoint_array<rmm::device_vector<std::size_t>, rmm::device_vector<vec_2d<T>>>{
419 rmm::device_vector<std::size_t>(offsets), rmm::device_vector<vec_2d<T>>(coordinates)};
426template <
typename IndexType,
typename T>
427auto make_multipoint_array(rmm::device_uvector<IndexType> geometry_offsets,
428 rmm::device_uvector<vec_2d<T>> coords)
430 return multipoint_array<rmm::device_uvector<std::size_t>, rmm::device_uvector<vec_2d<T>>>{
431 std::move(geometry_offsets), std::move(coords)};
438template <
typename IndexType,
typename T>
439auto make_multipoint_array(rmm::device_vector<IndexType> geometry_offsets,
440 rmm::device_vector<vec_2d<T>> coords)
442 return multipoint_array<rmm::device_vector<std::size_t>, rmm::device_vector<vec_2d<T>>>{
443 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.