-
Notifications
You must be signed in to change notification settings - Fork 193
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement a class to load and sample an EGM96 grid #835
base: main
Are you sure you want to change the base?
Conversation
CesiumGeospatial/include/CesiumGeospatial/EarthGravitationalModel96Grid.h
Outdated
Show resolved
Hide resolved
@timoore Updated review based on your comments. Latitude values are now clamped. |
I'm ready to merge this, but I notice that the WW15MGH.DAC file is only test data. What's the plan to make this more official? Egm96 height will very useful to users and should be easy to use from cesium-native. Perhaps the source data file should be transformed into C++ source by a python script or something and linked in? |
We could definitely include WW15MGH.DAC in the binary, by generating a header file either manually or as part of the build process. However, I wonder if it doesn't just make more sense to have users bring their own WW15MGH.DAC? After all, most users probably won't touch the EGM96 grid, so it would save on 2MB of extra dependencies for people who don't. We'll definitely have to do this if we decide to add other models (the EGM08 grid is 128MB) and it makes sense to me to keep it consistent, even if 2MB isn't that much. |
I see a lot of forum posts that boil down to ellipsoid vs geoid confusion, so I think this functionality is useful; on the other hand, I don't see users bringing their own WW15MGH.DAC file; where would they even get it? In other words, the set of users helped by this new functionality is a lot larger than the set than know how to help themselves. I don't care much if the data is a built-in array or read from a file. Do we have any external data files in cesium-native that need to be installed and used by the clients? The clients e.g. cesium-omniverse already have external data dependencies. |
For our integrations (Unreal, Unity, Omniverse), we should include the WW15MGH.DAC file with the distribution so users don't have to think about it. For cesium-native, users should supply the file or its contents when constructing an instance of the type, as is already done in this PR. But we should make it easy for them to do so by telling people in the reference docs (doxygen comments) where to get it. It used to be really easy to get this file directly from NGA, but that doesn't seem to be true anymore. So we should probably also include it in a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lots of little comments, but it looks great overall @azrogers! Also please update CHANGES.md.
* @brief Allows elevation data in the format provided by the Earth | ||
* Gravitational Model 1996 to be loaded and queried. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Active voice would be better:
* @brief Allows elevation data in the format provided by the Earth | |
* Gravitational Model 1996 to be loaded and queried. | |
* @brief Loads and queries heights from the Earth Gravity Model 1996 (EGM96). |
Just call me the MS Word grammar checker. 😎
Also elevation -> height. The word elevation tends to imply a height above sea level, so we avoid it.
* @returns The height representing the difference in meters of mean sea-level | ||
* from the surface of a WGS84 ellipsoid. | ||
*/ | ||
double sampleHeight(Cartographic& position) const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
double sampleHeight(Cartographic& position) const; | |
double sampleHeight(const Cartographic& position) const; |
* @returns The height representing the difference in meters of mean sea-level | ||
* from the surface of a WGS84 ellipsoid. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we state this a little more clearly? The current wording doesn't make it clear to me whether the returned value is positive or negative when the EGM96 surface is above the ellipsoid. Something like:
"The height (in meters) of the EGM96 surface above the WGS84 ellipsoid. A positive value indicates that the EGM96 surface is above the ellipsoid, while a negative value indicates that the MSL surface is below the ellipsoid."
(Please double check I have that right! I can never remember if it's that or the opposite. 😆)
double sampleHeight(Cartographic& position) const; | ||
|
||
private: | ||
EarthGravitationalModel96Grid(const std::vector<int16_t>& gridValues); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Save a copy!
EarthGravitationalModel96Grid(const std::vector<int16_t>& gridValues); | |
EarthGravitationalModel96Grid(std::vector<int16_t>&& gridValues); |
gridValues.push_back(gridValue); | ||
} | ||
|
||
return EarthGravitationalModel96Grid(gridValues); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return EarthGravitationalModel96Grid(gridValues); | |
return EarthGravitationalModel96Grid(std::move(gridValues)); |
const double longitude = | ||
std::remainder(position.longitude - Math::OnePi, Math::TwoPi) + | ||
Math::OnePi; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use CesiumUtility::Math::zeroToTwoPi
.
const double latitude = | ||
std::clamp(position.latitude, -Math::PiOverTwo, Math::PiOverTwo); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const double latitude = | |
std::clamp(position.latitude, -Math::PiOverTwo, Math::PiOverTwo); | |
const double latitude = | |
Math::clamp(position.latitude, -Math::PiOverTwo, Math::PiOverTwo); |
clampedVertical = NUM_ROWS - 1; | ||
} | ||
|
||
const std::vector<int16_t>::size_type index = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can just use size_t
instead of std::vector<int16_t>::size_type
.
const std::vector<int16_t>::size_type index = | ||
static_cast<std::vector<int16_t>::size_type>( | ||
clampedVertical * NUM_COLUMNS + horizontal); | ||
const double result = static_cast<double>(_gridValues[index]) / 100.0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this static_cast needed? I think it shouldn't be.
57.79), | ||
Egm96TestCase( | ||
Cartographic::fromDegrees(179.78766535213848, -66.77911223257036, 0), | ||
-57.37), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're testing both positive and negative values, so my fears about sign extension are unfounded. Up to you if you like the code I suggested better anyway.
@azrogers bump! Not sure if you saw that I reviewed this. |
Closes #637.
Users often have data with heights referenced to mean sea-level (MSL), but Cesium uses the WGS84 ellipsoid internally, which can differ from MSL by dozens of meters in some locations. Accurately determining MSL requires an external geopotential model. This change allows users to load the EGM96 model and sample heights from it, allowing for MSL heights to be converted to ellipsoid heights. Converting from MSL to the ellipsoid becomes as simple as: