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 };