From ad10470eb177d56a687e032831cee65ab5a279aa Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Sat, 28 Apr 2018 19:04:06 +0200 Subject: [PATCH] Ref T261, improved "finding" for elevation, "findFirst" for small radius --- src/blackmisc/geo/geoobjectlist.cpp | 9 +++++++++ src/blackmisc/geo/geoobjectlist.h | 3 +++ .../simulation/simulationenvironmentprovider.cpp | 8 ++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/blackmisc/geo/geoobjectlist.cpp b/src/blackmisc/geo/geoobjectlist.cpp index eecc9c8c4..3321e7910 100644 --- a/src/blackmisc/geo/geoobjectlist.cpp +++ b/src/blackmisc/geo/geoobjectlist.cpp @@ -53,6 +53,15 @@ namespace BlackMisc }); } + template + OBJ IGeoObjectList::findFirstWithinRangeOrDefault(const ICoordinateGeodetic &coordinate, const CLength &range) const + { + return this->container().findFirstByOrDefault([&](const OBJ & geoObj) + { + return calculateGreatCircleDistance(geoObj, coordinate) <= range; + }); + } + template CONTAINER IGeoObjectList::findWithGeodeticMSLHeight() const { diff --git a/src/blackmisc/geo/geoobjectlist.h b/src/blackmisc/geo/geoobjectlist.h index cdcc5d392..f44369416 100644 --- a/src/blackmisc/geo/geoobjectlist.h +++ b/src/blackmisc/geo/geoobjectlist.h @@ -63,6 +63,9 @@ namespace BlackMisc //! \param range within range of other position CONTAINER findWithinRange(const ICoordinateGeodetic &coordinate, const PhysicalQuantities::CLength &range) const; + //! Find first in range + OBJ findFirstWithinRangeOrDefault(const ICoordinateGeodetic &coordinate, const PhysicalQuantities::CLength &range) const; + //! Elements with geodetic height (only MSL) CONTAINER findWithGeodeticMSLHeight() const; diff --git a/src/blackmisc/simulation/simulationenvironmentprovider.cpp b/src/blackmisc/simulation/simulationenvironmentprovider.cpp index 0516bf4d4..fb8f97b5f 100644 --- a/src/blackmisc/simulation/simulationenvironmentprovider.cpp +++ b/src/blackmisc/simulation/simulationenvironmentprovider.cpp @@ -91,9 +91,13 @@ namespace BlackMisc return delta; } - CElevationPlane ISimulationEnvironmentProvider::findClosestElevationWithinRange(const ICoordinateGeodetic &reference, const PhysicalQuantities::CLength &range) const + CElevationPlane ISimulationEnvironmentProvider::findClosestElevationWithinRange(const ICoordinateGeodetic &reference, const CLength &range) const { - const CCoordinateGeodetic coordinate = this->getElevationCoordinates().findClosestWithinRange(reference, minRange(range)); + // for single point we use a slightly optimized version + const bool singlePoint = (range <= CElevationPlane::singlePointRadius()); + const CCoordinateGeodetic coordinate = singlePoint ? + this->getElevationCoordinates().findFirstWithinRangeOrDefault(reference, CElevationPlane::singlePointRadius()) : + this->getElevationCoordinates().findClosestWithinRange(reference, range); const bool found = !coordinate.isNull(); { QWriteLocker l{&m_lockElvCoordinates };