Loading...
Searching...
No Matches
multipolygon_range.cuh
Go to the documentation of this file.
1/*
2 * Copyright (c) 2023-2024, NVIDIA CORPORATION.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <cuspatial/cuda_utils.hpp>
20#include <cuspatial/detail/range/enumerate_range.cuh>
22#include <cuspatial/traits.hpp>
23#include <cuspatial/types.hpp>
24
25#include <rmm/cuda_stream_view.hpp>
26
27#include <thrust/pair.h>
28
29namespace cuspatial {
30
60template <typename GeometryIterator,
61 typename PartIterator,
62 typename RingIterator,
63 typename VecIterator>
65 public:
66 using geometry_it_t = GeometryIterator;
67 using part_it_t = PartIterator;
68 using ring_it_t = RingIterator;
69 using point_it_t = VecIterator;
70 using point_t = iterator_value_type<VecIterator>;
71
72 using index_t = iterator_value_type<GeometryIterator>;
73 using element_t = iterator_vec_base_type<VecIterator>;
74
75 multipolygon_range(GeometryIterator geometry_begin,
76 GeometryIterator geometry_end,
77 PartIterator part_begin,
78 PartIterator part_end,
79 RingIterator ring_begin,
80 RingIterator ring_end,
81 VecIterator points_begin,
82 VecIterator points_end);
83
85 CUSPATIAL_HOST_DEVICE auto size() { return num_multipolygons(); }
86
88 CUSPATIAL_HOST_DEVICE auto num_multipolygons();
89
91 CUSPATIAL_HOST_DEVICE auto num_polygons();
92
94 CUSPATIAL_HOST_DEVICE auto num_rings();
95
97 CUSPATIAL_HOST_DEVICE auto num_points();
98
100 CUSPATIAL_HOST_DEVICE auto multipolygon_begin();
101
103 CUSPATIAL_HOST_DEVICE auto multipolygon_end();
104
106 CUSPATIAL_HOST_DEVICE auto begin() { return multipolygon_begin(); }
107
109 CUSPATIAL_HOST_DEVICE auto end() { return multipolygon_end(); }
110
112 CUSPATIAL_HOST_DEVICE auto point_begin();
113
115 CUSPATIAL_HOST_DEVICE auto point_end();
116
118 CUSPATIAL_HOST_DEVICE auto geometry_offset_begin() { return _geometry_begin; }
119
121 CUSPATIAL_HOST_DEVICE auto geometry_offset_end() { return _geometry_end; }
122
124 CUSPATIAL_HOST_DEVICE auto part_offset_begin() { return _part_begin; }
125
127 CUSPATIAL_HOST_DEVICE auto part_offset_end() { return _part_end; }
128
130 CUSPATIAL_HOST_DEVICE auto ring_offset_begin() { return _ring_begin; }
131
133 CUSPATIAL_HOST_DEVICE auto ring_offset_end() { return _ring_end; }
134
136 template <typename IndexType>
137 CUSPATIAL_HOST_DEVICE auto ring_idx_from_point_idx(IndexType point_idx);
138
140 template <typename IndexType>
141 CUSPATIAL_HOST_DEVICE auto part_idx_from_ring_idx(IndexType ring_idx);
142
145 template <typename IndexType>
146 CUSPATIAL_HOST_DEVICE auto geometry_idx_from_part_idx(IndexType part_idx);
147
149 template <typename IndexType>
150 CUSPATIAL_HOST_DEVICE auto operator[](IndexType multipolygon_idx);
151
154 CUSPATIAL_HOST_DEVICE auto multipolygon_point_count_begin();
157 CUSPATIAL_HOST_DEVICE auto multipolygon_point_count_end();
158
160 CUSPATIAL_HOST_DEVICE auto multipolygon_ring_count_begin();
162 CUSPATIAL_HOST_DEVICE auto multipolygon_ring_count_end();
163
167 auto _segments(rmm::cuda_stream_view);
168
170
173 CUSPATIAL_HOST_DEVICE auto as_multipoint_range();
174
176 CUSPATIAL_HOST_DEVICE auto as_multilinestring_range();
177
178 protected:
179 GeometryIterator _geometry_begin;
180 GeometryIterator _geometry_end;
181 PartIterator _part_begin;
182 PartIterator _part_end;
183 RingIterator _ring_begin;
184 RingIterator _ring_end;
185 VecIterator _point_begin;
186 VecIterator _point_end;
187
188 private:
189 template <typename IndexType1, typename IndexType2>
190 CUSPATIAL_HOST_DEVICE bool is_valid_segment_id(IndexType1 segment_idx, IndexType2 ring_idx);
191};
192
225template <typename GeometryIteratorDiffType,
226 typename PartIteratorDiffType,
227 typename RingIteratorDiffType,
228 typename VecIteratorDiffType,
229 typename GeometryIterator,
230 typename PartIterator,
231 typename RingIterator,
232 typename VecIterator>
233multipolygon_range<GeometryIterator, PartIterator, RingIterator, VecIterator>
234make_multipolygon_range(GeometryIteratorDiffType num_multipolygons,
235 GeometryIterator geometry_begin,
236 PartIteratorDiffType num_polygons,
237 PartIterator part_begin,
238 RingIteratorDiffType num_rings,
239 RingIterator ring_begin,
240 VecIteratorDiffType num_points,
241 VecIterator point_begin)
242{
243 return multipolygon_range{
244 geometry_begin,
245 thrust::next(geometry_begin, num_multipolygons + 1),
246 part_begin,
247 thrust::next(part_begin, num_polygons + 1),
248 ring_begin,
249 thrust::next(ring_begin, num_rings + 1),
250 point_begin,
251 thrust::next(point_begin, num_points),
252 };
253}
254
261template <collection_type_id Type,
262 typename T,
263 typename IndexType,
264 typename GeometryColumnView,
265 CUSPATIAL_ENABLE_IF(Type == collection_type_id::SINGLE)>
266auto make_multipolygon_range(GeometryColumnView const& polygons_column)
267{
268 CUSPATIAL_EXPECTS(polygons_column.geometry_type() == geometry_type_id::POLYGON,
269 "Must be polygon geometry type.");
270 auto geometry_iter = thrust::make_counting_iterator(0);
271 auto const& part_offsets = polygons_column.offsets();
272 auto const& ring_offsets = polygons_column.child().child(0);
273 auto const& points_xy =
274 polygons_column.child().child(1).child(1); // Ignores x-y offset {0, 2, 4...}
275
276 auto points_it = make_vec_2d_iterator(points_xy.template begin<T>());
277
278 return multipolygon_range(geometry_iter,
279 geometry_iter + part_offsets.size(),
280 part_offsets.template begin<IndexType>(),
281 part_offsets.template end<IndexType>(),
282 ring_offsets.template begin<IndexType>(),
283 ring_offsets.template end<IndexType>(),
284 points_it,
285 points_it + points_xy.size() / 2);
286}
287
294template <collection_type_id Type,
295 typename T,
296 typename IndexType,
297 CUSPATIAL_ENABLE_IF(Type == collection_type_id::MULTI),
298 typename GeometryColumnView>
299auto make_multipolygon_range(GeometryColumnView const& polygons_column)
300{
301 CUSPATIAL_EXPECTS(polygons_column.geometry_type() == geometry_type_id::POLYGON,
302 "Must be polygon geometry type.");
303 auto const& geometry_offsets = polygons_column.offsets();
304 auto const& part_offsets = polygons_column.child().child(0);
305 auto const& ring_offsets = polygons_column.child().child(1).child(0);
306 auto const& points_xy =
307 polygons_column.child().child(1).child(1).child(1); // Ignores x-y offset {0, 2, 4...}
308
309 auto points_it = make_vec_2d_iterator(points_xy.template begin<T>());
310
311 return multipolygon_range(geometry_offsets.template begin<IndexType>(),
312 geometry_offsets.template end<IndexType>(),
313 part_offsets.template begin<IndexType>(),
314 part_offsets.template end<IndexType>(),
315 ring_offsets.template begin<IndexType>(),
316 ring_offsets.template end<IndexType>(),
317 points_it,
318 points_it + points_xy.size() / 2);
319};
320
325} // namespace cuspatial
326
327#include <cuspatial/detail/range/multipolygon_range.cuh>
Non-owning range-based interface to multipolygon data.
CUSPATIAL_HOST_DEVICE auto num_points()
Return the total number of points in the array.
CUSPATIAL_HOST_DEVICE auto multipolygon_point_count_end()
CUSPATIAL_HOST_DEVICE auto multipolygon_end()
Return the iterator to the one past the last multipolygon in the range.
CUSPATIAL_HOST_DEVICE auto ring_idx_from_point_idx(IndexType point_idx)
Given the index of a point, return the index of the ring that contains the point.
CUSPATIAL_HOST_DEVICE auto ring_offset_begin()
Return the iterator to the first ring offset in the range.
CUSPATIAL_HOST_DEVICE auto geometry_offset_begin()
Return the iterator to the first geometry offset in the range.
CUSPATIAL_HOST_DEVICE auto point_end()
Return the iterator to the one past the last point in the range.
CUSPATIAL_HOST_DEVICE auto part_offset_end()
Return the iterator to the one past the last part offset in the range.
CUSPATIAL_HOST_DEVICE auto multipolygon_begin()
Return the iterator to the first multipolygon in the range.
CUSPATIAL_HOST_DEVICE auto operator[](IndexType multipolygon_idx)
Returns the multipolygon_idxth multipolygon in the range.
CUSPATIAL_HOST_DEVICE auto num_polygons()
Return the total number of polygons in the array.
CUSPATIAL_HOST_DEVICE auto num_rings()
Return the total number of rings in the array.
CUSPATIAL_HOST_DEVICE auto point_begin()
Return the iterator to the first point in the range.
CUSPATIAL_HOST_DEVICE auto part_idx_from_ring_idx(IndexType ring_idx)
Given the index of a ring, return the index of the part (polygon) that contains the point.
CUSPATIAL_HOST_DEVICE auto num_multipolygons()
Return the number of multipolygons in the array.
CUSPATIAL_HOST_DEVICE auto size()
Return the number of multipolygons in the array.
CUSPATIAL_HOST_DEVICE auto begin()
Return the iterator to the first multipolygon in the range.
CUSPATIAL_HOST_DEVICE auto geometry_offset_end()
Return the iterator to the one past the last geometry offset in the range.
CUSPATIAL_HOST_DEVICE auto end()
Return the iterator to the one past the last multipolygon in the range.
CUSPATIAL_HOST_DEVICE auto multipolygon_point_count_begin()
CUSPATIAL_HOST_DEVICE auto part_offset_begin()
Return the iterator to the first part offset in the range.
CUSPATIAL_HOST_DEVICE auto ring_offset_end()
Return the iterator to the one past the last ring offset in the range.
CUSPATIAL_HOST_DEVICE auto as_multipoint_range()
Range Casting.
CUSPATIAL_HOST_DEVICE auto multipolygon_ring_count_end()
Returns the one past the iterator to the number of rings of the last multipolygon.
CUSPATIAL_HOST_DEVICE auto as_multilinestring_range()
Cast the range of multipolygons as a range of multilinestrings, ignoring ring relationships.
CUSPATIAL_HOST_DEVICE auto geometry_idx_from_part_idx(IndexType part_idx)
CUSPATIAL_HOST_DEVICE auto multipolygon_ring_count_begin()
Returns an iterator to the number of rings of the first multipolygon.
#define CUSPATIAL_EXPECTS(cond, reason)
Macro for checking (pre-)conditions that throws an exception when a condition is violated.
Definition error.hpp:76
multipolygon_range< GeometryIterator, PartIterator, RingIterator, VecIterator > make_multipolygon_range(GeometryIteratorDiffType num_multipolygons, GeometryIterator geometry_begin, PartIteratorDiffType num_polygons, PartIterator part_begin, RingIteratorDiffType num_rings, RingIterator ring_begin, VecIteratorDiffType num_points, VecIterator point_begin)
Create a multipoylgon_range object of from size and start iterators.
auto make_vec_2d_iterator(FirstIter first, SecondIter second)
Create an iterator to vec_2d data from two input iterators.