From 5bb4c5b9de1bd0f5a7be67de17c0cf3a8e71b5f1 Mon Sep 17 00:00:00 2001 From: Aditya Date: Wed, 6 Jul 2022 01:59:16 -0700 Subject: [PATCH] Changed isNonEarthDem usage, added custom surface support Signed-off-by: Aditya --- .../include/gz/common/geospatial/Dem.hh | 4 +- geospatial/src/Dem.cc | 48 +++++++++++++------ geospatial/src/Dem_TEST.cc | 33 ++++++++++--- 3 files changed, 63 insertions(+), 22 deletions(-) diff --git a/geospatial/include/gz/common/geospatial/Dem.hh b/geospatial/include/gz/common/geospatial/Dem.hh index 0530f3468..3f0b3789e 100644 --- a/geospatial/include/gz/common/geospatial/Dem.hh +++ b/geospatial/include/gz/common/geospatial/Dem.hh @@ -60,12 +60,12 @@ namespace gz /// \brief Indicate that this is a non Earth DEM. /// \param[in] _isNonEarthDem Should be true if this is a /// non earth DEM, otherwise false. - public: void SetNonEarthDEM(bool _isNonEarthDem); + public: void SetUnknownDEM(bool _isNonEarthDem); /// \brief Check if the loaded DEM is not from the Earth. /// \return True if the loaded DEM is from the Earth, otherwise /// returns False. - public: bool GetNonEarthDEM(); + public: bool UnknownDEM(); /// \brief Get the elevation of a terrain's point in meters. /// \param[in] _x X coordinate of the terrain. diff --git a/geospatial/src/Dem.cc b/geospatial/src/Dem.cc index 0a4cbe519..dfe8c8fa4 100644 --- a/geospatial/src/Dem.cc +++ b/geospatial/src/Dem.cc @@ -58,10 +58,10 @@ class gz::common::Dem::Implementation /// \brief Full filename used to load the dem. public: std::string filename; - /// \brief Whether the DEM will be handled as from non-Earth. + /// \brief Whether the DEM will be handled as unknown. /// If true, worldWidth & worldHeight = -1 /// and GeoReference[Origin] can not be used (will return false) - public: bool isNonEarthDem = false; + public: bool isUnknownDem = false; /// \brief Holds the spherical coordinates object from the world. public : math::SphericalCoordinates sphericalCoordinates = @@ -93,15 +93,15 @@ void Dem::SetSphericalCoordinates( } ////////////////////////////////////////////////// -void Dem::SetNonEarthDEM(bool _isNonEarthDem) +void Dem::SetUnknownDEM(bool _isUnknownDem) { - this->dataPtr->isNonEarthDem = _isNonEarthDem; + this->dataPtr->isUnknownDem = _isUnknownDem; } ////////////////////////////////////////////////// -bool Dem::GetNonEarthDEM() +bool Dem::UnknownDEM() { - return this->dataPtr->isNonEarthDem; + return this->dataPtr->isUnknownDem; } ////////////////////////////////////////////////// @@ -181,7 +181,7 @@ int Dem::Load(const std::string &_filename) << std::endl; this->dataPtr->worldWidth = this->dataPtr->worldHeight = -1; - this->dataPtr->isNonEarthDem = true; + this->dataPtr->isUnknownDem = true; } // Set the terrain's side (the terrain will be squared after the padding) @@ -285,9 +285,9 @@ float Dem::MaxElevation() const bool Dem::GeoReference(double _x, double _y, gz::math::Angle &_latitude, gz::math::Angle &_longitude) const { - if (this->dataPtr->isNonEarthDem) + if (this->dataPtr->isUnknownDem) { - gzerr << "Can not retrieve WGS84 coordinates from non-Earth DEM." + gzerr << "Can not retrieve WGS84 coordinates from unknown DEM." << std::endl; return false; } @@ -295,7 +295,7 @@ bool Dem::GeoReference(double _x, double _y, double geoTransf[6]; if (this->dataPtr->dataSet->GetGeoTransform(geoTransf) == CE_None) { - OGRCoordinateTransformation *cT; + OGRCoordinateTransformation *cT = nullptr; double xGeoDeg, yGeoDeg; if (this->dataPtr->sphericalCoordinates.Surface() == @@ -329,6 +329,26 @@ bool Dem::GeoReference(double _x, double _y, cT = OGRCreateCoordinateTransformation( sourceCs, &targetCs); } + else if (this->dataPtr->sphericalCoordinates.Surface() == + math::SphericalCoordinates::CUSTOM_SURFACE) + { + auto sourceCs = this->dataPtr->dataSet->GetSpatialRef(); + OGRSpatialReference targetCs = OGRSpatialReference(); + + int axisEquatorial = + this->dataPtr->sphericalCoordinates.SurfaceAxisEquatorial(); + int axisPolar = + this->dataPtr->sphericalCoordinates.SurfaceAxisPolar(); + + std::string CUSTOM_SURFACE_LAT_LON_PROJ_STR = + "+proj=latlong +a=" + std::to_string(axisEquatorial) + + " +b=" + std::to_string(axisPolar); + + targetCs.importFromProj4(CUSTOM_SURFACE_LAT_LON_PROJ_STR.c_str()); + + cT = OGRCreateCoordinateTransformation( + sourceCs, &targetCs); + } else { gzerr << "Unsupported spherical coordinates found" << std::endl; @@ -383,9 +403,9 @@ unsigned int Dem::Width() const ////////////////////////////////////////////////// double Dem::WorldWidth() const { - if (this->dataPtr->isNonEarthDem) + if (this->dataPtr->isUnknownDem) { - gzwarn << "Unable to determine world width of non-Earth DEM." + gzwarn << "Unable to determine world width of unknown DEM." << std::endl; } return this->dataPtr->worldWidth; @@ -394,9 +414,9 @@ double Dem::WorldWidth() const ////////////////////////////////////////////////// double Dem::WorldHeight() const { - if (this->dataPtr->isNonEarthDem) + if (this->dataPtr->isUnknownDem) { - gzwarn << "Unable to determine world height of non-Earth DEM." + gzwarn << "Unable to determine world height of unknown DEM." << std::endl; } return this->dataPtr->worldHeight; diff --git a/geospatial/src/Dem_TEST.cc b/geospatial/src/Dem_TEST.cc index 13f690522..99a8401c9 100644 --- a/geospatial/src/Dem_TEST.cc +++ b/geospatial/src/Dem_TEST.cc @@ -127,6 +127,18 @@ TEST_F(DemTest, BasicAPI) EXPECT_TRUE(dem.GeoReferenceOrigin(latitude, longitude)); EXPECT_FLOAT_EQ(38.001667f, latitude.Degree()); EXPECT_FLOAT_EQ(-122.22278f, longitude.Degree()); + + // Emulate Earth as a custom surface. + common::Dem demCustomSurface; + auto earthSc = math::SphericalCoordinates(); + auto customSc = math::SphericalCoordinates( + math::SphericalCoordinates::CUSTOM_SURFACE, + earthSc.SurfaceRadius(), + earthSc.SurfaceRadius()); + demCustomSurface.SetSphericalCoordinates(customSc); + EXPECT_EQ(demCustomSurface.Load(path), 0); + EXPECT_FLOAT_EQ(3984.4849f, demCustomSurface.WorldHeight()); + EXPECT_FLOAT_EQ(3139.7456f, demCustomSurface.WorldWidth()); } ///////////////////////////////////////////////// @@ -226,7 +238,7 @@ TEST_F(DemTest, NaNNoData) } ///////////////////////////////////////////////// -TEST_F(DemTest, NonEarthDem) +TEST_F(DemTest, UnknownDem) { // moon common::Dem dem; @@ -247,17 +259,17 @@ TEST_F(DemTest, NonEarthDem) EXPECT_FALSE(dem.GeoReferenceOrigin(latitude, longitude)); // The Load() method in Dem.cc should set the - // isNonEarthDEM flag. - EXPECT_TRUE(dem.GetNonEarthDEM()); + // isUnknownDEM flag. + EXPECT_TRUE(dem.UnknownDEM()); // This flag can be overridden externally. - dem.SetNonEarthDEM(false); - EXPECT_FALSE(dem.GetNonEarthDEM()); + dem.SetUnknownDEM(false); + EXPECT_FALSE(dem.UnknownDEM()); } TEST_F(DemTest, LunarDemLoad) { - // moon + // Load Moon DEM common::Dem dem; auto path = common::testing::TestFile("data", "dem_moon.tif"); // Providing spherical coordinates object. @@ -265,7 +277,16 @@ TEST_F(DemTest, LunarDemLoad) math::SphericalCoordinates::MOON_SCS); dem.SetSphericalCoordinates(moonSc); EXPECT_EQ(dem.Load(path), 0); + EXPECT_NEAR(dem.WorldWidth(), 80.0417, 1e-2); + EXPECT_NEAR(dem.WorldHeight(), 80.0417, 1e-2); + // Use custom spherical coordinates object with same axes as the moon. + auto customSc = math::SphericalCoordinates( + math::SphericalCoordinates::CUSTOM_SURFACE, + moonSc.SurfaceRadius(), + moonSc.SurfaceRadius()); + dem.SetSphericalCoordinates(customSc); + EXPECT_EQ(dem.Load(path), 0); EXPECT_NEAR(dem.WorldWidth(), 80.0417, 1e-2); EXPECT_NEAR(dem.WorldHeight(), 80.0417, 1e-2); }