6 #ifndef SWIFT_MISC_GEO_GEOOBJECTLIST_H
7 #define SWIFT_MISC_GEO_GEOOBJECTLIST_H
19 namespace swift::misc::geo
22 template <
class OBJ,
class CONTAINER>
27 using MinMaxAverageHeight = std::tuple<aviation::CAltitude, aviation::CAltitude, aviation::CAltitude, int>;
36 [&](
const OBJ &geoObj) {
return calculateGreatCircleDistance(geoObj, coordinate) <= range; });
46 [&](
const OBJ &geoObj) {
return calculateGreatCircleDistance(geoObj, coordinate) > range; });
53 return this->
container().findFirstByOrDefault(
54 [&](
const OBJ &geoObj) {
return calculateGreatCircleDistance(geoObj, coordinate) <= range; });
60 return this->
container().findBy(&OBJ::hasMSLGeodeticHeight,
true);
67 return this->
container().containsBy([&](
const OBJ &geoObj) {
77 return this->
container().containsBy([&](
const OBJ &geoObj) {
101 if (this->
container().isEmpty()) {
return stats; }
106 if (!obj.hasMSLGeodeticHeight()) {
continue; }
108 if (std::get<0>(stats).isNull() || std::get<0>(stats) > alt)
110 std::get<0>(stats) = alt;
112 if (std::get<1>(stats).isNull() || std::get<1>(stats) < alt)
114 std::get<1>(stats) = alt;
125 std::get<3>(stats) = count;
136 if (!obj.hasMSLGeodeticHeight()) {
continue; }
138 if (max.
isNull() || alt > max) { max = alt; }
146 const int size = this->
container().size();
147 const CONTAINER copy = this->
container().findOutsideRange(coordinate, range);
148 const int d = size - copy.size();
149 if (d > 0) { *
this = copy; }
156 const int size = this->
container().size();
157 const CONTAINER copy = this->
container().findWithinRange(coordinate, range);
158 const int d = size - copy.size();
159 if (d > 0) { *
this = copy; }
166 const int size = this->
container().size();
168 const int d = size - copy.size();
169 if (d > 0) { *
this = copy; }
176 CONTAINER closest = this->
container().partiallySorted(number, [&](
const OBJ &a,
const OBJ &b) {
177 return calculateEuclideanDistanceSquared(a, coordinate) <
178 calculateEuclideanDistanceSquared(b, coordinate);
180 closest.truncate(number);
187 CONTAINER farthest = this->
container().partiallySorted(number, [&](
const OBJ &a,
const OBJ &b) {
188 return calculateEuclideanDistanceSquared(a, coordinate) >
189 calculateEuclideanDistanceSquared(b, coordinate);
191 farthest.truncate(number);
204 if (d > range) {
continue; }
205 if (distance.
isNull() || distance > d)
217 this->
container().sort([&](
const OBJ &a,
const OBJ &b) {
218 return calculateEuclideanDistanceSquared(a, coordinate) <
219 calculateEuclideanDistanceSquared(b, coordinate);
227 copy.sortByEuclideanDistanceSquared(coordinate);
236 const CONTAINER &
container()
const {
return static_cast<const CONTAINER &
>(*this); }
239 CONTAINER &
container() {
return static_cast<CONTAINER &
>(*this); }
243 template <
class OBJ,
class CONTAINER>
252 [&](
const OBJ &a,
const OBJ &b) {
return a.getRelativeDistance() < b.getRelativeDistance(); });
260 [&](
const OBJ &a,
const OBJ &b) {
return a.getRelativeDistance() < b.getRelativeDistance(); });
267 number, [&](
const OBJ &a,
const OBJ &b) {
return a.getRelativeDistance() < b.getRelativeDistance(); });
273 if (number < 1) {
return CONTAINER(); }
276 closest.partiallySortByDistanceToReferencePosition(number);
277 Q_ASSERT_X(closest.size() <= number, Q_FUNC_INFO,
"size exceeded");
285 this->
container().removeIf([&](OBJ &geoObj) {
286 return updateValues ? geoObj.calculcateAndUpdateRelativeDistanceAndBearing(position) > maxDistance :
287 geoObj.calculateGreatCircleDistance(position) > maxDistance;
294 for (OBJ &geoObj : this->
container()) { geoObj.calculcateAndUpdateRelativeDistanceAndBearing(position); }
Altitude as used in aviation, can be AGL or MSL altitude.
static const CAltitude & null()
Null altitude (MSL)
Geodetic coordinate, a position in 3D space relative to the reference geoid.
physical_quantities::CLength calculateGreatCircleDistance(const ICoordinateGeodetic &otherCoordinate) const
Great circle distance.
virtual bool isNull() const
Is null, means vector x, y, z == 0.
bool isGeodeticHeightNull() const
Geodetic height null?
List of objects with geo coordinates.
CONTAINER findOutsideRange(const ICoordinateGeodetic &coordinate, const physical_quantities::CLength &range) const
Find 0..n objects outside range of given coordinate.
bool containsNullPosition() const
Any NULL position?
CONTAINER sortedByEuclideanDistanceSquared(const ICoordinateGeodetic &coordinate) const
Sorted by distance.
CONTAINER & container()
Container.
void sortByEuclideanDistanceSquared(const ICoordinateGeodetic &coordinate)
Sort by distance.
int removeWithoutGeodeticHeight()
Remove if there is no geodetic height.
OBJ findFirstWithinRangeOrDefault(const ICoordinateGeodetic &coordinate, const physical_quantities::CLength &range) const
Find first in range.
IGeoObjectList()
Constructor.
bool containsObjectInRange(const ICoordinateGeodetic &coordinate, const physical_quantities::CLength &range) const
Any object in range?
CONTAINER findWithinRange(const ICoordinateGeodetic &coordinate, const physical_quantities::CLength &range) const
Find 0..n objects within range of given coordinate.
OBJ findClosestWithinRange(const ICoordinateGeodetic &coordinate, const physical_quantities::CLength &range) const
Find closest within range to the given coordinate.
bool containsObjectOutsideRange(const ICoordinateGeodetic &coordinate, const physical_quantities::CLength &range) const
Any object in range?
int removeInsideRange(const ICoordinateGeodetic &coordinate, const physical_quantities::CLength &range)
Remove inside range.
const CONTAINER & container() const
Container.
int removeOutsideRange(const ICoordinateGeodetic &coordinate, const physical_quantities::CLength &range)
Remove outside range.
bool containsNullPositionOrHeight() const
Any NULL position or NULL height.
aviation::CAltitude findMaxHeight() const
Find min/max/average height.
MinMaxAverageHeight findMinMaxAverageHeight() const
Find min/max/average height.
CONTAINER findWithGeodeticMSLHeight() const
Elements with geodetic height (only MSL)
CONTAINER findClosest(int number, const ICoordinateGeodetic &coordinate) const
Find 0..n objects closest to the given coordinate.
CONTAINER findFarthest(int number, const ICoordinateGeodetic &coordinate) const
Find 0..n objects farthest to the given coordinate.
std::tuple< aviation::CAltitude, aviation::CAltitude, aviation::CAltitude, int > MinMaxAverageHeight
For statistics.
List of objects with geo coordinates.
void calculcateAndUpdateRelativeDistanceAndBearing(const ICoordinateGeodetic &position)
Calculate distances.
void partiallySortByDistanceToReferencePosition(int number)
Sort the first n closest objects.
void sortByRange(const ICoordinateGeodetic &position, bool updateValues)
Calculate distances, then sort by range.
void sortByDistanceToReferencePosition()
If distance is already set, just sort container.
CONTAINER getClosestObjects(int number) const
Get n closest objects.
void removeIfOutsideRange(const ICoordinateGeodetic &position, const physical_quantities::CLength &maxDistance, bool updateValues)
Calculate distances, remove if outside range.
IGeoObjectWithRelativePositionList()
Constructor.
Physical unit length (length)
static CLengthUnit ft()
Foot ft.
bool isNull() const
Is quantity null?
double value(MU unit) const
Value in given unit.
static const CLength & null()
NULL PQ.