| 166 | } |
| 167 | |
| 168 | void WKBGeometryBounder::MergeGeometryInternal(WKBBuffer* src, bool record_wkb_type, |
| 169 | int depth) { |
| 170 | if (depth > 128) { |
| 171 | throw ParquetException("WKB geometry has too many levels of nesting"); |
| 172 | } |
| 173 | |
| 174 | uint8_t endian = src->ReadUInt8(); |
| 175 | #if ARROW_LITTLE_ENDIAN |
| 176 | bool swap = endian != 0x01; |
| 177 | #else |
| 178 | bool swap = endian != 0x00; |
| 179 | #endif |
| 180 | |
| 181 | uint32_t wkb_geometry_type = src->ReadUInt32(swap); |
| 182 | auto geometry_type_and_dimensions = ParseGeometryType(wkb_geometry_type); |
| 183 | auto [geometry_type, dimensions] = geometry_type_and_dimensions; |
| 184 | |
| 185 | // Keep track of geometry types encountered if at the top level |
| 186 | if (record_wkb_type) { |
| 187 | geospatial_types_.insert(static_cast<int32_t>(wkb_geometry_type)); |
| 188 | } |
| 189 | |
| 190 | switch (geometry_type) { |
| 191 | case GeometryType::kPoint: |
| 192 | MergeSequence(src, dimensions, 1, swap); |
| 193 | break; |
| 194 | |
| 195 | case GeometryType::kLinestring: { |
| 196 | uint32_t n_coords = src->ReadUInt32(swap); |
| 197 | MergeSequence(src, dimensions, n_coords, swap); |
| 198 | break; |
| 199 | } |
| 200 | case GeometryType::kPolygon: { |
| 201 | uint32_t n_parts = src->ReadUInt32(swap); |
| 202 | for (uint32_t i = 0; i < n_parts; i++) { |
| 203 | uint32_t n_coords = src->ReadUInt32(swap); |
| 204 | MergeSequence(src, dimensions, n_coords, swap); |
| 205 | } |
| 206 | break; |
| 207 | } |
| 208 | |
| 209 | // These are all encoded the same in WKB, even though this encoding would |
| 210 | // allow for parts to be of a different geometry type or different dimensions. |
| 211 | // For the purposes of bounding, this does not cause us problems. We pass |
| 212 | // record_wkb_type = false because we do not want the child geometry to be |
| 213 | // added to the geometry_types list (e.g., for a MultiPoint, we only want |
| 214 | // the code for MultiPoint to be added, not the code for Point). |
| 215 | case GeometryType::kMultiPoint: |
| 216 | case GeometryType::kMultiLinestring: |
| 217 | case GeometryType::kMultiPolygon: |
| 218 | case GeometryType::kGeometryCollection: { |
| 219 | uint32_t n_parts = src->ReadUInt32(swap); |
| 220 | for (uint32_t i = 0; i < n_parts; i++) { |
| 221 | MergeGeometryInternal(src, /*record_wkb_type*/ false, depth + 1); |
| 222 | } |
| 223 | break; |
| 224 | } |
| 225 | } |
nothing calls this directly
no test coverage detected