#include <vector>
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#if defined(_OPENMP)
#define HAVE_OPENMP 1
#else
#define HAVE_OPENMP 0
#endif
#if HAVE_OPENMP
# include <omp.h>
#endif
#include <GeographicLib/GravityModel.hpp>
#include <GeographicLib/GravityCircle.hpp>
#include <GeographicLib/Utility.hpp>
using namespace std;
using namespace GeographicLib;
int main(int argc, const char* const argv[]) {
if (argc != 4) {
cerr << "Usage: " << argv[0]
<< " gravity-model intervals-per-degree output.gtx\n";
return 1;
}
try {
int ndigits = Utility::set_digits();
string model(argv[1]);
int ndeg = Utility::val<int>(string(argv[2]));
string filename(argv[3]);
GravityModel g(model);
int
nlat = Math::hd * ndeg + 1,
nlon = Math::td * ndeg;
Math::real
delta = 1 / Math::real(ndeg), latorg = -Math::qd,
lonorg = -Math::hd;
ofstream file(filename.c_str(), ios::binary);
{
Math::real transform[] = {latorg, lonorg,
1/Math::real(ndeg), 1/Math::real(ndeg)};
unsigned sizes[] = {unsigned(nlat), unsigned(nlon)};
Utility::writearray<double, Math::real, true>(file, transform, 4);
Utility::writearray<unsigned, unsigned, true>(file, sizes, 2);
}
const int nbatch = 64;
vector< vector<float> > N(nbatch, vector<float>(nlon));
for (int ilat0 = 0; ilat0 < nlat; ilat0 += nbatch) { int nlat0 = min(nlat, ilat0 + nbatch);
#if HAVE_OPENMP
# pragma omp parallel for
#endif
for (int ilat = ilat0; ilat < nlat0; ++ilat) { Utility::set_digits(ndigits); Math::real lat = (latorg * ndeg + ilat) / ndeg, h = 0;
GravityCircle c(g.Circle(lat, h, GravityModel::GEOID_HEIGHT));
for (int ilon = 0; ilon < nlon; ++ilon) { Math::real lon = (lonorg * ndeg + ilon) / ndeg;
N[ilat - ilat0][ilon] = float(c.GeoidHeight(lon));
} }
for (int ilat = ilat0; ilat < nlat0; ++ilat) Utility::writearray<float, float, true>(file, N[ilat - ilat0]);
} }
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
catch (...) {
cerr << "Caught unknown exception\n";
return 1;
}
}