diff --git a/src/blackmisc/geo/geoobjectlist.cpp b/src/blackmisc/geo/geoobjectlist.cpp index 5790c27e9..59666f9ee 100644 --- a/src/blackmisc/geo/geoobjectlist.cpp +++ b/src/blackmisc/geo/geoobjectlist.cpp @@ -48,6 +48,17 @@ namespace BlackMisc }); } + template + CONTAINER IGeoObjectList::findClosest(int number, const ICoordinateGeodetic &coordinate) const + { + CONTAINER closest = this->container().partiallySorted(number, [ & ](const OBJ & a, const OBJ & b) + { + return calculateEuclideanDistanceSquared(a, coordinate) < calculateEuclideanDistanceSquared(b, coordinate); + }); + closest.truncate(number); + return closest; + } + template void IGeoObjectWithRelativePositionList::calculcateDistanceAndBearingToPosition(const ICoordinateGeodetic &position) { @@ -82,13 +93,19 @@ namespace BlackMisc this->container().sort([ & ](const OBJ & a, const OBJ & b) { return a.getDistanceToOwnAircraft() < b.getDistanceToOwnAircraft(); }); } + template + void IGeoObjectWithRelativePositionList::partiallySortByDistanceToOwnAircraft(int number) + { + this->container().partiallySort(number, [ & ](const OBJ & a, const OBJ & b) { return a.getDistanceToOwnAircraft() < b.getDistanceToOwnAircraft(); }); + } + template CONTAINER IGeoObjectWithRelativePositionList::getClosestObjects(int number) const { if (number < 1) { return CONTAINER(); } if (this->container().size() >= number) { return (this->container()); } CONTAINER closest(this->container()); - closest.sortByDistanceToOwnAircraft(); + closest.partiallySortByDistanceToOwnAircraft(number); closest.truncate(number); return closest; } diff --git a/src/blackmisc/geo/geoobjectlist.h b/src/blackmisc/geo/geoobjectlist.h index 072047fb7..2d8bdd1af 100644 --- a/src/blackmisc/geo/geoobjectlist.h +++ b/src/blackmisc/geo/geoobjectlist.h @@ -50,6 +50,11 @@ namespace BlackMisc */ CONTAINER findWithinRange(const BlackMisc::Geo::ICoordinateGeodetic &coordinate, const BlackMisc::PhysicalQuantities::CLength &range) const; + /*! + * Find 0..n objects closest to the given coordinate. + */ + CONTAINER findClosest(int number, const BlackMisc::Geo::ICoordinateGeodetic &coordinate) const; + protected: //! Constructor IGeoObjectList(); @@ -79,6 +84,9 @@ namespace BlackMisc //! If distance is already set, just sort void sortByDistanceToOwnAircraft(); + //! Sort the first n closest objects + void partiallySortByDistanceToOwnAircraft(int number); + //! Get n closest objects CONTAINER getClosestObjects(int number) const;