cesium-native 0.50.0
Loading...
Searching...
No Matches
GeoJsonObject.h
1#pragma once
2
3#include <CesiumGeometry/AxisAlignedBox.h>
4#include <CesiumVectorData/GeoJsonObjectTypes.h>
5#include <CesiumVectorData/VectorStyle.h>
6
7#include <array>
8#include <vector>
9
10namespace CesiumVectorData {
11
14template <typename TSingle, typename TMulti, typename TValue>
16template <typename TObject> struct ConstGeoJsonObjectTypeIterator;
17
31 std::vector<glm::dvec3>>;
39 std::vector<std::vector<glm::dvec3>>>;
40
49 template <typename TIterator> struct IteratorProvider {
53 TIterator begin() { return TIterator(*this->_pObject); }
54
58 TIterator end() { return TIterator(); }
59
60 private:
61 IteratorProvider(const GeoJsonObject* pObject) : _pObject(pObject) {}
62
63 const GeoJsonObject* _pObject;
64 friend struct GeoJsonObject;
65 };
66
83
100
109
119
129
137 template <typename TObject>
141
146 const std::optional<CesiumGeometry::AxisAlignedBox>& getBoundingBox() const;
147
152 std::optional<CesiumGeometry::AxisAlignedBox>& getBoundingBox();
153
159
165
169 const std::optional<VectorStyle>& getStyle() const;
170
174 std::optional<VectorStyle>& getStyle();
175
181
186 template <typename T> bool isType() const {
187 return std::holds_alternative<T>(this->value);
188 }
189
196 template <typename T> const T& get() const {
197 return std::get<T>(this->value);
198 }
199
206 template <typename T> T& get() { return std::get<T>(this->value); }
207
212 template <typename T> const T* getIf() const {
213 return std::get_if<T>(&this->value);
214 }
215
220 template <typename T> T* getIf() { return std::get_if<T>(&this->value); }
221
225 template <typename Visitor> decltype(auto) visit(Visitor&& visitor) {
226 return std::visit(std::forward<Visitor>(visitor), this->value);
227 }
228
232 template <typename Visitor> decltype(auto) visit(Visitor&& visitor) const {
233 return std::visit(std::forward<Visitor>(visitor), this->value);
234 }
235
240};
241
246private:
247 static constexpr size_t StackSize = 8;
248 struct IteratorStackState {
249 GeoJsonObject* pObject;
250 int64_t nextPos;
251 };
252
253public:
254 // Ignore Doxygen warnings for iterator tags.
256 using iterator_category = std::forward_iterator_tag;
257 using difference_type = std::ptrdiff_t;
258 using value_type = GeoJsonObject;
259 using pointer = GeoJsonObject*;
260 using reference = GeoJsonObject&;
262
264 reference operator*() const { return *_pCurrentObject; }
266 pointer operator->() { return _pCurrentObject; }
267
275 for (int64_t i = this->_stackPos; i >= 0; i--) {
276 if (this->_stack[(size_t)i].pObject->isType<GeoJsonFeature>()) {
277 return this->_stack[(size_t)i].pObject;
278 }
279 }
280
281 return nullptr;
282 }
283
288 bool isEnded() const {
289 return this->_stackPos == -1 && this->_pCurrentObject == nullptr;
290 }
291
297 this->iterate();
298 return *this;
299 }
300
305 GeoJsonObjectIterator tmp = *this;
306 this->iterate();
307 return tmp;
308 }
309
313 friend bool
315 if (a._pCurrentObject != b._pCurrentObject || a._stackPos != b._stackPos) {
316 return false;
317 }
318
319 if (a._stackPos >= 0 && b._stackPos >= 0) {
320 if (a._stack[(size_t)a._stackPos].nextPos !=
321 b._stack[(size_t)b._stackPos].nextPos) {
322 return false;
323 }
324 if (a._stack[(size_t)a._stackPos].pObject !=
325 b._stack[(size_t)b._stackPos].pObject) {
326 return false;
327 }
328 }
329
330 return true;
331 }
332
336 friend bool
338 return !(a == b);
339 }
340
349 : _stackPos(0), _pCurrentObject(nullptr) {
350 this->_stack[0].pObject = &rootObject;
351 this->_stack[0].nextPos = -1;
352 this->iterate();
353 }
354
359 GeoJsonObjectIterator() : _stackPos(-1), _pCurrentObject(nullptr) {}
360
361private:
362 void handleChild(GeoJsonObject& child) {
363 this->_pCurrentObject = &child;
364
365 if ((this->_stackPos - 1) <= (int64_t)StackSize &&
368 child.isType<GeoJsonFeature>())) {
369
370 ++this->_stackPos;
371 this->_stack[(size_t)this->_stackPos].pObject = &child;
372 this->_stack[(size_t)this->_stackPos].nextPos = 0;
373 }
374 }
375
376 void iterate() {
377 this->_pCurrentObject = nullptr;
378 while (this->_stackPos >= 0 && this->_stackPos < (int64_t)StackSize &&
379 this->_pCurrentObject == nullptr) {
380 IteratorStackState& stackState = this->_stack[(size_t)this->_stackPos];
381 GeoJsonObject* pNext = stackState.pObject;
382 if (stackState.nextPos == -1) {
383 this->_pCurrentObject = pNext;
384 ++stackState.nextPos;
385 continue;
386 } else if (
387 GeoJsonGeometryCollection* pCollection =
388 std::get_if<GeoJsonGeometryCollection>(&pNext->value)) {
389 if ((size_t)stackState.nextPos >= pCollection->geometries.size()) {
390 // No children left
391 --this->_stackPos;
392 continue;
393 }
394
395 GeoJsonObject& child =
396 pCollection->geometries[(size_t)stackState.nextPos];
397 ++stackState.nextPos;
398 this->handleChild(child);
399 continue;
400 } else if (
401 GeoJsonFeatureCollection* pFeatureCollection =
402 std::get_if<GeoJsonFeatureCollection>(&pNext->value)) {
403 if ((size_t)stackState.nextPos >= pFeatureCollection->features.size()) {
404 // No children left
405 --this->_stackPos;
406 continue;
407 }
408
409 GeoJsonObject& child =
410 pFeatureCollection->features[(size_t)stackState.nextPos];
411 ++stackState.nextPos;
412 this->handleChild(child);
413 continue;
414 } else if (
415 GeoJsonFeature* pFeature =
416 std::get_if<GeoJsonFeature>(&pNext->value)) {
417 const size_t expectedSize = pFeature->geometry == nullptr ? 0 : 1;
418 if ((size_t)stackState.nextPos >= expectedSize) {
419 // Feature only has zero or one child
420 --this->_stackPos;
421 continue;
422 }
423
424 ++stackState.nextPos;
425 this->handleChild(*pFeature->geometry);
426 continue;
427 } else {
428 // This object was a dud, try another
429 --this->_stackPos;
430 }
431 }
432 }
433
434 std::array<IteratorStackState, StackSize> _stack;
435 int64_t _stackPos = -1;
436 GeoJsonObject* _pCurrentObject;
437
438 friend struct ConstGeoJsonObjectIterator;
439};
440
445 // Ignore Doxygen warnings for iterator tags.
447 using iterator_category = std::forward_iterator_tag;
448 using difference_type = std::ptrdiff_t;
449 using value_type = GeoJsonObject;
450 using pointer = const GeoJsonObject*;
451 using reference = const GeoJsonObject&;
453
455 reference operator*() const { return *this->_it; }
457 pointer operator->() { return this->_it._pCurrentObject; }
458
465 const GeoJsonObject* getFeature() { return this->_it.getFeature(); }
466
471 bool isEnded() const { return this->_it.isEnded(); }
472
478 ++this->_it;
479 return *this;
480 }
481
486 ConstGeoJsonObjectIterator tmp = *this;
487 ++this->_it;
488 return tmp;
489 }
490
493 friend bool operator==(
496 return a._it == b._it;
497 }
498
503 friend bool operator!=(
506 return a._it != b._it;
507 }
508
517 : _it(const_cast<GeoJsonObject&>(rootObject)) {}
518
523
524private:
526};
527
538template <typename TSingle, typename TMulti, typename TValue>
540 // Ignore Doxygen warnings for iterator tags.
542 using iterator_category = std::forward_iterator_tag;
543 using difference_type = std::ptrdiff_t;
544 using value_type = TValue;
545 using pointer = const TValue*;
546 using reference = const TValue&;
548
552 reference operator*() const {
553 const TMulti* pMultiPoint = (*this->_it).template getIf<TMulti>();
554 if (pMultiPoint) {
555 return pMultiPoint->coordinates[this->_currentMultiIdx];
556 }
557
558 return (*this->_it).template get<TSingle>().coordinates;
559 }
560
563 pointer operator->() { return &**this; }
564
569 this->iterate();
570 return *this;
571 }
572
578 this->iterate();
579 return tmp;
580 }
581
585 friend bool operator==(
588 return a._it == b._it;
589 }
590
594 friend bool operator!=(
597 return a._it != b._it;
598 }
599
605 : _it(const_cast<GeoJsonObject&>(rootObject)) {
606 if (!_it.isEnded() &&
607 !(_it->template isType<TSingle>() || _it->template isType<TMulti>())) {
608 this->iterate();
609 }
610 }
611
616
617private:
618 void iterate() {
619 if (!this->_it.isEnded() && this->_it->template isType<TMulti>()) {
620 const TMulti& multi = this->_it->template get<TMulti>();
621 if ((int64_t)this->_currentMultiIdx <
622 ((int64_t)multi.coordinates.size() - 1)) {
623 ++this->_currentMultiIdx;
624 return;
625 }
626 }
627
628 this->_currentMultiIdx = 0;
629 do {
630 ++this->_it;
631 } while (!this->_it.isEnded() &&
632 !(this->_it->template isType<TSingle>() ||
633 (this->_it->template isType<TMulti>() &&
634 !this->_it->template get<TMulti>().coordinates.empty())));
635 }
636
638 size_t _currentMultiIdx = 0;
639};
640
645template <typename TObject> struct ConstGeoJsonObjectTypeIterator {
646 // Ignore Doxygen warnings for iterator tags.
648 using iterator_category = std::forward_iterator_tag;
649 using difference_type = std::ptrdiff_t;
650 using value_type = TObject;
651 using pointer = const TObject*;
652 using reference = const TObject&;
654
656 reference operator*() const { return (*this->_it).template get<TObject>(); }
658 pointer operator->() { return &**this; }
659
665 this->iterate();
666 return *this;
667 }
668
674 this->iterate();
675 return tmp;
676 }
677
681 friend bool operator==(
684 return a._it == b._it;
685 }
686
690 friend bool operator!=(
693 return a._it != b._it;
694 }
695
704 : _it(const_cast<GeoJsonObject&>(rootObject)) {
705 if (!this->_it.isEnded() && !this->_it->template isType<TObject>()) {
706 this->iterate();
707 }
708 }
709
714
715private:
716 void iterate() {
717 do {
718 ++this->_it;
719 } while (!this->_it.isEnded() && !this->_it->template isType<TObject>());
720 }
721
723 size_t _currentMultiPointIdx = 0;
724};
725} // namespace CesiumVectorData
std::map< std::string, JsonValue > Object
The type to represent an Object JSON value.
Definition JsonValue.h:73
Classes for loading vector data such as GeoJSON.
ConstGeoJsonPrimitiveIterator< GeoJsonPolygon, GeoJsonMultiPolygon, std::vector< std::vector< glm::dvec3 > > > ConstGeoJsonPolygonIterator
An iterator over all Polygon and MultiPolygon objects in and including a root GeoJSON object.
ConstGeoJsonPrimitiveIterator< GeoJsonPoint, GeoJsonMultiPoint, glm::dvec3 > ConstGeoJsonPointIterator
An iterator over all Point and MultiPoint objects in and including a root GeoJSON object.
std::variant< GeoJsonPoint, GeoJsonMultiPoint, GeoJsonLineString, GeoJsonMultiLineString, GeoJsonPolygon, GeoJsonMultiPolygon, GeoJsonGeometryCollection, GeoJsonFeature, GeoJsonFeatureCollection > GeoJsonObjectVariant
Every possible object that can be specified in a GeoJSON document.
GeoJsonObjectType
A type of object in GeoJson data.
ConstGeoJsonPrimitiveIterator< GeoJsonLineString, GeoJsonMultiLineString, std::vector< glm::dvec3 > > ConstGeoJsonLineStringIterator
An iterator over all LineString and MultiLineString objects in and including a root GeoJSON object.
The const equivalent of GeoJsonObjectIterator.
friend bool operator==(const ConstGeoJsonObjectIterator &a, const ConstGeoJsonObjectIterator &b)
Checks if two ConstGeoJsonObjectIterator iterators are equal.
ConstGeoJsonObjectIterator operator++(int)
Iterates to the next GeoJsonObject, returning the previous state of the iterator.
bool isEnded() const
Returns true if this is an "end" iterator (points past the end of all objects).
friend bool operator!=(const ConstGeoJsonObjectIterator &a, const ConstGeoJsonObjectIterator &b)
Checks if two ConstGeoJsonObjectIterator iterators are not equal.
ConstGeoJsonObjectIterator(const GeoJsonObject &rootObject)
Creates a new ConstGeoJsonObjectIterator with the given GeoJsonObject as the root object.
ConstGeoJsonObjectIterator()=default
Creates a new ConstGeoJsonObjectIterator without any GeoJsonObject. This is equivalent to an "end" it...
const GeoJsonObject * getFeature()
Attempts to find the Feature that contains the current item the iterator is pointing to.
pointer operator->()
Returns a pointer to the current object.
ConstGeoJsonObjectIterator & operator++()
Iterates to the next GeoJsonObject, returning this modified iterator.
reference operator*() const
Returns a reference to the current object.
An iterator over all GeoJsonObject objects that contain a value of type ObjectType.
ConstGeoJsonObjectTypeIterator(const GeoJsonObject &rootObject)
Creates a new ConstGeoJsonObjectTypeIterator with the given GeoJsonObject as the root object.
ConstGeoJsonObjectTypeIterator & operator++()
Iterates to the next ObjectType, returning this modified iterator.
ConstGeoJsonObjectTypeIterator operator++(int)
Iterates to the next ObjectType, returning the previous state of the iterator.
ConstGeoJsonObjectTypeIterator()=default
Creates a new ConstGeoJsonObjectTypeIterator without any GeoJsonObject. This is equivalent to an "end...
pointer operator->()
Returns a pointer to the current object.
friend bool operator!=(const ConstGeoJsonObjectTypeIterator &a, const ConstGeoJsonObjectTypeIterator &b)
Checks if two ConstGeoJsonObjectTypeIterator iterators are not equal.
friend bool operator==(const ConstGeoJsonObjectTypeIterator &a, const ConstGeoJsonObjectTypeIterator &b)
Checks if two ConstGeoJsonObjectTypeIterator iterators are equal.
reference operator*() const
Returns a reference to the current object.
Returns all geometry data of a given type from a GeoJsonObject.
ConstGeoJsonPrimitiveIterator & operator++()
Iterates to the next value, returning the modified iterator.
friend bool operator!=(const ConstGeoJsonPrimitiveIterator &a, const ConstGeoJsonPrimitiveIterator &b)
Checks if two ConstGeoJsonPrimitiveIterator iterators are not equal.
friend bool operator==(const ConstGeoJsonPrimitiveIterator &a, const ConstGeoJsonPrimitiveIterator &b)
Checks if two ConstGeoJsonPrimitiveIterator iterators are equal.
ConstGeoJsonPrimitiveIterator(const GeoJsonObject &rootObject)
Creates a new ConstGeoJsonPrimitiveIterator from the given root GeoJsonObject.
reference operator*() const
Returns a reference to the current value.
ConstGeoJsonPrimitiveIterator operator++(int)
Iterates to the next value, returning the previous state of the iterator.
ConstGeoJsonPrimitiveIterator()=default
Creates an empty ConstGeoJsonPrimitiveIterator.
pointer operator->()
Returns a pointer to the current value.
A FeatureCollection represents any number of GeoJsonFeature objects.
A GeoJsonFeature object represents a spatially bounded "thing." It is a collection of information tha...
A GeometryCollection represents any number of GeoJsonObject objects.
A LineString geometry object.
A MultiLineString geometry object.
A 'MultiPolygon' geometry object.
Iterates over a GeoJsonObject and all of its children.
bool isEnded() const
Returns true if this is an "end" iterator (points past the end of all objects).
pointer operator->()
Returns a pointer to the current object.
friend bool operator!=(const GeoJsonObjectIterator &a, const GeoJsonObjectIterator &b)
Checks if two GeoJsonObjectIterator iterators are not equal.
GeoJsonObject * getFeature() const
Attempts to find the Feature that contains the current item the iterator is pointing to.
GeoJsonObjectIterator()
Creates a new GeoJsonObjectIterator without any GeoJsonObject. This is equivalent to an "end" iterato...
GeoJsonObjectIterator & operator++()
Iterates to the next GeoJsonObject, returning this modified iterator.
GeoJsonObjectIterator(GeoJsonObject &rootObject)
Creates a new GeoJsonObjectIterator with the given GeoJsonObject as the root object.
GeoJsonObjectIterator operator++(int)
Iterates to the next GeoJsonObject, returning the previous state of the iterator.
reference operator*() const
Returns a reference to the current object.
friend bool operator==(const GeoJsonObjectIterator &a, const GeoJsonObjectIterator &b)
Checks if two GeoJsonObjectIterator iterators are equal.
An object providing begin and end methods for creating iterators of the given type for a GeoJsonObjec...
TIterator begin()
Returns an iterator pointing to the first element.
TIterator end()
Returns an iterator pointing "past the end" of all the elements.
An object in a GeoJSON document.
T * getIf()
Obtains a pointer to the value of this GeoJsonObject if the value is of the given type....
GeoJsonObjectType getType() const
Returns the GeoJsonObjectType that this GeoJsonObject is wrapping.
IteratorProvider< ConstGeoJsonPointIterator > points() const
Allows iterating over all points defined in this object or any child objects. This will include both ...
GeoJsonObjectIterator begin()
Returns an iterator pointing to this object. Iterating this will provide all children of this object.
decltype(auto) visit(Visitor &&visitor) const
Applies the visitor visitor to the value variant.
ConstGeoJsonObjectIterator end() const
Returns an iterator pointing "past the end" of the list of children of this object.
CesiumUtility::JsonValue::Object & getForeignMembers()
Returns the CesiumUtility::JsonValue::Object containing any foreign members on this GeoJSON object.
std::optional< CesiumGeometry::AxisAlignedBox > & getBoundingBox()
Returns the bounding box defined in the GeoJSON for this object, if any.
const T & get() const
Obtains a reference to the value of this GeoJsonObject if the value is of the given type.
decltype(auto) visit(Visitor &&visitor)
Applies the visitor visitor to the value variant.
const std::optional< CesiumGeometry::AxisAlignedBox > & getBoundingBox() const
Returns the bounding box defined in the GeoJSON for this object, if any.
const CesiumUtility::JsonValue::Object & getForeignMembers() const
Returns the CesiumUtility::JsonValue::Object containing any foreign members on this GeoJSON object.
const std::optional< VectorStyle > & getStyle() const
Returns the style set on this GeoJSON object, if any.
IteratorProvider< ConstGeoJsonPolygonIterator > polygons() const
Allows iterating over all polygons defined in this object or any child objects. This will include bot...
const T * getIf() const
Obtains a pointer to the value of this GeoJsonObject if the value is of the given type....
IteratorProvider< ConstGeoJsonLineStringIterator > lines() const
Allows iterating over all lines defined in this object or any child objects. This will include both L...
bool isType() const
Returns whether the value of this GeoJsonObject is of the given type.
std::optional< VectorStyle > & getStyle()
Returns the style set on this GeoJSON object, if any.
GeoJsonObjectIterator end()
Returns an iterator pointing "past the end" of the list of children of this object.
IteratorProvider< ConstGeoJsonObjectTypeIterator< TObject > > allOfType() const
Returns all GeoJsonObject values matching the given type in this object or in any children.
GeoJsonObjectVariant value
A variant containing the GeoJSON object.
T & get()
Obtains a reference to the value of this GeoJsonObject if the value is of the given type.
ConstGeoJsonObjectIterator begin() const
Returns an iterator pointing to this object. Iterating this will provide all children of this object.