Adds immediate migration results

This commit is contained in:
torsten committed 2026-08-18 22:12:24 +02:00
1 parent ba4121728b
commit 6a2a0667ab
2395 files changed
+357322 -2524

No files matched your search

@@ -0,0 +1,181 @@
# This CMakeLists.txt is invoked in two different ways
# (1) With "add_subdirectory (examples)" from GeographicLib's top-level
# CMakeLists.txt. This mode of invocation is flagged by the variable
#
# CALLED_FROM_TOPLEVEL
#
# In this case, the only action taken is to install the examples and
# this CMakeLists.txt in ${EXAMPLEDIR}.
# (2) As an independent invocation of
#
# cmake -S <this-directory> -B <build-directory>
#
# In this case, find_package (GeographicLib) is called and the examples
# are compiled. This mode of invocation is triggered by the
# exampleprograms target in the top-level CMakeLists.txt. In this case,
# the current version of GeographicLib is found by specifying
#
# -D GeographicLib_DIR=${PROJECT_BINARY_DIR}
cmake_minimum_required (VERSION 3.17.0)
set (EXAMPLES0
example-Accumulator.cpp
example-AlbersEqualArea.cpp
example-Angle.cpp
example-AuxAngle.cpp
example-AuxLatitude.cpp
example-AzimuthalEquidistant.cpp
example-CassiniSoldner.cpp
example-CircularEngine.cpp
example-Constants.cpp
example-DMS.cpp
example-DST.cpp
example-Ellipsoid.cpp
example-EllipticFunction.cpp
example-GARS.cpp
example-GeoCoords.cpp
example-Geocentric.cpp
example-Geodesic.cpp
example-Geodesic-small.cpp
example-GeodesicExact.cpp
example-GeodesicLine.cpp
example-GeodesicLineExact.cpp
example-GeographicErr.cpp
example-Geohash.cpp
example-Geoid.cpp
example-Georef.cpp
example-Gnomonic.cpp
example-GravityCircle.cpp
example-GravityModel.cpp
example-Intersect.cpp
example-LambertConformalConic.cpp
example-LocalCartesian.cpp
example-MGRS.cpp
example-MagneticCircle.cpp
example-MagneticModel.cpp
example-Math.cpp
example-NearestNeighbor.cpp
example-NormalGravity.cpp
example-OSGB.cpp
example-PolarStereographic.cpp
example-PolygonArea.cpp
example-Rhumb.cpp
example-RhumbLine.cpp
example-SphericalEngine.cpp
example-SphericalHarmonic.cpp
example-SphericalHarmonic1.cpp
example-SphericalHarmonic2.cpp
example-TransverseMercator.cpp
example-TransverseMercatorExact.cpp
example-Trigfun.cpp
example-TrigfunExt.cpp
example-UTMUPS.cpp
example-Utility.cpp
example-Cartesian3.cpp
example-Conformal3.cpp
example-Ellipsoid3.cpp
example-Geodesic3.cpp
example-GeodesicLine3.cpp
)
set (EXAMPLES1
GeoidToGTX.cpp make-egmcof.cpp)
if (CALLED_FROM_TOPLEVEL)
if (EXAMPLEDIR)
install (FILES CMakeLists.txt ${EXAMPLES0} ${EXAMPLES1} ${EXAMPLEHEADERS}
DESTINATION ${EXAMPLEDIR})
endif ()
# No more to do in add_subdirectory mode, so exit
return ()
endif ()
project (GeographicLib-examples)
# Set a default build type for single-configuration cmake generators if
# no build type is set.
if (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
set (CMAKE_BUILD_TYPE Release)
endif ()
if (MSVC OR CMAKE_CONFIGURATION_TYPES)
# For multi-config systems and for Visual Studio, the debug version of
# the library is called Geographic_d.
set (CMAKE_DEBUG_POSTFIX "_d" CACHE STRING "The suffix for debug objects")
else ()
set (CMAKE_DEBUG_POSTFIX "" CACHE STRING "The suffix for debug objects")
endif ()
find_package (GeographicLib 2.7 REQUIRED)
include_directories (${GeographicLib_INCLUDE_DIRS})
set (CMAKE_CXX_STANDARD 17)
set (CMAKE_CXX_STANDARD_REQUIRED ON)
option (USE_BOOST
"Look for Boost library when compiling examples" ON)
if (USE_BOOST)
# The earliest Boost version to include
# https://github.com/boostorg/multiprecision/pull/389
find_package (Boost 1.79 CONFIG COMPONENTS serialization)
elseif (GEOGRAPHICLIB_PRECISION EQUAL 4)
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
find_package (Boost 1.79 CONFIG)
endif ()
endif ()
# Compile a bunch of tiny example programs. These are built with the
# "exampleprograms" target. These are mainly for including as examples
# within the doxygen documentation; however, compiling them catches some
# obvious blunders.
if (NOT GEOGRAPHICLIB_PRECISION OR GEOGRAPHICLIB_PRECISION EQUAL 2)
# These examples all assume real = double, so check
# GEOGRAPHICLIB_PRECISION. Allow GEOGRAPHICLIB_PRECISION to be unset
# to accommodate lame FindGeographicLib.cmake.
set (EXAMPLE_SOURCES ${EXAMPLES0})
if (USE_BOOST AND Boost_FOUND)
add_definitions (-DGEOGRAPHICLIB_HAVE_BOOST_SERIALIZATION=1)
include_directories ("${Boost_INCLUDE_DIRS}")
endif ()
else ()
set (EXAMPLE_SOURCES)
endif ()
set (EXAMPLE_SOURCES ${EXAMPLE_SOURCES} ${EXAMPLES1})
set (EXAMPLES)
foreach (EXAMPLE_SOURCE ${EXAMPLE_SOURCES})
get_filename_component (EXAMPLE ${EXAMPLE_SOURCE} NAME_WE)
set (EXAMPLES ${EXAMPLES} ${EXAMPLE})
add_executable (${EXAMPLE} ${EXAMPLE_SOURCE})
target_link_libraries (${EXAMPLE}
${GeographicLib_LIBRARIES} ${GeographicLib_HIGHPREC_LIBRARIES})
endforeach ()
if (Boost_FOUND AND GEOGRAPHICLIB_PRECISION EQUAL 2)
target_link_libraries (example-NearestNeighbor ${Boost_LIBRARIES})
endif ()
find_package (OpenMP QUIET)
if (OPENMP_FOUND OR OpenMP_FOUND)
set_target_properties (GeoidToGTX PROPERTIES
COMPILE_FLAGS ${OpenMP_CXX_FLAGS})
if (OpenMP_CXX_INCLUDE_DIRS)
set_target_properties (GeoidToGTX PROPERTIES
INCLUDE_DIRECTORIES ${OpenMP_CXX_INCLUDE_DIRS})
endif ()
if (NOT WIN32)
set_target_properties (GeoidToGTX PROPERTIES
LINK_FLAGS ${OpenMP_CXX_FLAGS})
endif ()
target_link_libraries (GeoidToGTX ${OpenMP_CXX_LIBRARIES})
endif ()
if (MSVC OR CMAKE_CONFIGURATION_TYPES)
# Add _d suffix for your debug versions of the tools
set_target_properties (${EXAMPLES} PROPERTIES
DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
endif ()
@@ -0,0 +1,109 @@
// Write out a gtx file of geoid heights above the ellipsoid. For egm2008 at
// 1' resolution this takes about 10 mins on a 8-processor Intel 3.0 GHz
// machine using OpenMP.
//
// For the format of gtx files, see
// https://vdatum.noaa.gov/docs/gtx_info.html#dev_gtx_binary
//
// data is binary big-endian:
// south latitude edge (degrees double)
// west longitude edge (degrees double)
// delta latitude (degrees double)
// delta longitude (degrees double)
// nlat = number of latitude rows (integer)
// nlong = number of longitude columns (integer)
// nlat * nlong geoid heights (meters float)
#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[]) {
// Hardwired for 3 args:
// 1 = the gravity model (e.g., egm2008)
// 2 = intervals per degree
// 3 = output GTX file
if (argc != 4) {
cerr << "Usage: " << argv[0]
<< " gravity-model intervals-per-degree output.gtx\n";
return 1;
}
try {
// Will need to set the precision for each thread, so save return value
int ndigits = Utility::set_digits();
string model(argv[1]);
// Number of intervals per degree
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), // Grid spacing
latorg = -Math::qd,
lonorg = -Math::hd;
// Write results as floats in binary mode
ofstream file(filename.c_str(), ios::binary);
// Write header
{
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);
}
// Compute and store results for nbatch latitudes at a time
const int nbatch = 64;
vector< vector<float> > N(nbatch, vector<float>(nlon));
for (int ilat0 = 0; ilat0 < nlat; ilat0 += nbatch) { // Loop over batches
int nlat0 = min(nlat, ilat0 + nbatch);
#if HAVE_OPENMP
# pragma omp parallel for
#endif
for (int ilat = ilat0; ilat < nlat0; ++ilat) { // Loop over latitudes
Utility::set_digits(ndigits); // Set the precision
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) { // Loop over longitudes
Math::real lon = (lonorg * ndeg + ilon) / ndeg;
N[ilat - ilat0][ilon] = float(c.GeoidHeight(lon));
} // longitude loop
} // latitude loop -- end of parallel section
for (int ilat = ilat0; ilat < nlat0; ++ilat) // write out data
Utility::writearray<float, float, true>(file, N[ilat - ilat0]);
} // batch loop
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
catch (...) {
cerr << "Caught unknown exception\n";
return 1;
}
}
@@ -0,0 +1,24 @@
// Example of using the GeographicLib::Accumulator class
#include <iostream>
#include <exception>
#include <GeographicLib/Accumulator.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
// Compare using Accumulator and ordinary summation for a sum of large and
// small terms.
double sum = 0;
Accumulator<> acc = 0;
sum += 1e20; sum += 1; sum += 2; sum += 100; sum += 5000; sum += -1e20;
acc += 1e20; acc += 1; acc += 2; acc += 100; acc += 5000; acc += -1e20;
cout << sum << " " << acc() << "\n";
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,39 @@
// Example of using the GeographicLib::AlbersEqualArea class
#include <iostream>
#include <exception>
#include <GeographicLib/AlbersEqualArea.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
const double
a = Constants::WGS84_a(),
f = Constants::WGS84_f(),
lat1 = 40 + 58/60.0, lat2 = 39 + 56/60.0, // standard parallels
k1 = 1, // scale
lon0 = -77 - 45/60.0; // Central meridian
// Set up basic projection
const AlbersEqualArea albers(a, f, lat1, lat2, k1);
{
// Sample conversion from geodetic to Albers Equal Area
double lat = 39.95, lon = -75.17; // Philadelphia
double x, y;
albers.Forward(lon0, lat, lon, x, y);
cout << x << " " << y << "\n";
}
{
// Sample conversion from Albers Equal Area grid to geodetic
double x = 220e3, y = -53e3;
double lat, lon;
albers.Reverse(lon0, x, y, lat, lon);
cout << lat << " " << lon << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,23 @@
// Example of using the GeographicLib::Angle class.
#include <iostream>
#include <iomanip>
#include <exception>
#include <GeographicLib/Angle.hpp>
int main(int argc, const char* const argv[]) {
try {
using ang = GeographicLib::Angle;
// Print table of parametric latitudes for f = 0.5
double f = 0.5;
std::cout << std::fixed << std::setprecision(4);
for (double d = 0; d <= 90; d+=10) {
ang phi{d};
std::cout << double(d) << " " << double(phi.modang(1-f)) << "\n";
}
}
catch (const std::exception& e) {
std::cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,24 @@
// Example of using the GeographicLib::AuxAngle class.
#include <iostream>
#include <iomanip>
#include <exception>
#include <GeographicLib/AuxAngle.hpp>
int main(int argc, const char* const argv[]) {
try {
using angle = GeographicLib::AuxAngle;
// Print table of parametric latitudes for f = 0.5
double f = 0.5;
std::cout << std::fixed << std::setprecision(4);
for (int d = 0; d <= 90; d+=10) {
angle phi(angle::degrees(d)), beta(phi);
beta.y() *= (1 - f);
std::cout << d << " " << beta.degrees() << "\n";
}
}
catch (const std::exception& e) {
std::cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,43 @@
// Example of using the GeographicLib::AuxLatitude class. See the paper
//
// - C. F. F. Karney,
// On auxiliary latitudes,
// Survey Review 56(395), 165--180 (2024).
// https://doi.org/10.1080/00396265.2023.2217604
// preprint: https://arxiv.org/abs/2212.05818
#include <iostream>
#include <iomanip>
#include <exception>
#include <GeographicLib/Utility.hpp>
#include <GeographicLib/AuxLatitude.hpp>
int main(int argc, const char* const argv[]) {
try {
using latitude = GeographicLib::AuxLatitude;
using angle = GeographicLib::AuxAngle;
if (argc != 3) {
std::cerr << "Usage: example-AuxLatitude <n> <base-lat>\n";
return 1;
}
double n = GeographicLib::Utility::fract<double>(std::string(argv[1]));
int auxin = GeographicLib::Utility::val<int>(std::string(argv[2]));
double a = 1+n, b = 1-n; // Equatorial radius and polar semiaxis
latitude aux(latitude::axes(a, b));
bool exact = true; // Do the exact calculation
std::cout << std::setprecision(9) << std::fixed;
int m = 1;
for (int l = 0; l < 90*m; ++l) {
angle phi(angle::degrees((l+0.5)/m));
for (int auxout = 0; auxout < latitude::AUXNUMBER; ++auxout) {
angle eta = aux.Convert(auxin, auxout, phi, exact);
std::cout << (auxout ? " " : "") << eta.degrees();
}
std::cout << "\n";
}
}
catch (const std::exception& e) {
std::cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,36 @@
// Example of using the GeographicLib::AzimuthalEquidistant class
#include <iostream>
#include <exception>
#include <GeographicLib/Geodesic.hpp>
#include <GeographicLib/AzimuthalEquidistant.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
Geodesic geod(Constants::WGS84_a(), Constants::WGS84_f());
// Alternatively: const Geodesic& geod = Geodesic::WGS84();
const double lat0 = 48 + 50/60.0, lon0 = 2 + 20/60.0; // Paris
AzimuthalEquidistant proj(geod);
{
// Sample forward calculation
double lat = 50.9, lon = 1.8; // Calais
double x, y;
proj.Forward(lat0, lon0, lat, lon, x, y);
cout << x << " " << y << "\n";
}
{
// Sample reverse calculation
double x = -38e3, y = 230e3;
double lat, lon;
proj.Reverse(lat0, lon0, x, y, lat, lon);
cout << lat << " " << lon << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,36 @@
// Example of using the Triaxial::Cartesian3 class.
#include <iostream>
#include <iomanip>
#include <exception>
#include <random>
#include <GeographicLib/Triaxial/Cartesian3.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
using Triaxial::Cartesian3;
Cartesian3 cart(3, 2, 1);
unsigned long long
s1 = std::random_device()(),
s2 = std::random_device()();
std::seed_seq seq{s1, s2};
std::mt19937 g(seq);
cout << "10 random points on the ellipsoid with semiaxes [3, 2, 1]\n"
<< "X Y Z beta omega\n" << fixed << setprecision(3);
Cartesian3::vec3 r;
Angle bet, omg;
for (int i = 0; i < 10; ++i) {
cart.cart2rand(g, r);
cart.cart2toany(r, Cartesian3::ELLIPSOIDAL, bet, omg);
cout << r[0] << " " << r[1] << " " << r[2] << " "
<< double(bet) << " " << double(omg) << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,36 @@
// Example of using the GeographicLib::CassiniSoldner class
#include <iostream>
#include <exception>
#include <GeographicLib/Geodesic.hpp>
#include <GeographicLib/CassiniSoldner.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
Geodesic geod(Constants::WGS84_a(), Constants::WGS84_f());
// Alternatively: const Geodesic& geod = Geodesic::WGS84();
const double lat0 = 48 + 50/60.0, lon0 = 2 + 20/60.0; // Paris
CassiniSoldner proj(lat0, lon0, geod);
{
// Sample forward calculation
double lat = 50.9, lon = 1.8; // Calais
double x, y;
proj.Forward(lat, lon, x, y);
cout << x << " " << y << "\n";
}
{
// Sample reverse calculation
double x = -38e3, y = 230e3;
double lat, lon;
proj.Reverse(x, y, lat, lon);
cout << lat << " " << lon << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,35 @@
// Example of using the GeographicLib::CircularEngine class
#include <iostream>
#include <exception>
#include <vector>
#include <GeographicLib/CircularEngine.hpp>
#include <GeographicLib/SphericalHarmonic.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
// This computes the same value as example-SphericalHarmonic.cpp using a
// CircularEngine (which will be faster if many values on a circle of
// latitude are to be found).
try {
using std::hypot;
int N = 3; // The maxium degree
double ca[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; // cosine coefficients
vector<double> C(ca, ca + (N + 1) * (N + 2) / 2);
double sa[] = {6, 5, 4, 3, 2, 1}; // sine coefficients
vector<double> S(sa, sa + N * (N + 1) / 2);
double a = 1;
SphericalHarmonic h(C, S, N, a);
double x = 2, y = 3, z = 1, p = hypot(x, y);
CircularEngine circ = h.Circle(p, z, true);
double v, vx, vy, vz;
v = circ(x/p, y/p, vx, vy, vz);
cout << v << " " << vx << " " << vy << " " << vz << "\n";
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,31 @@
// Example of using the Triaxial::Conformal3 class.
#include <iostream>
#include <iomanip>
#include <exception>
#include <GeographicLib/Triaxial/Conformal3.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
Triaxial::Conformal3 proj(Triaxial::Ellipsoid3::Earth());
cout << fixed << setprecision(1)
<< "Ellipsoid parameters: a = " << proj.t().a()
<< ", b = " << proj.t().b() << ", c = " << proj.t().c() << "\n"
<< setprecision(3)
<< "Quadrants: x = " << proj.x0() << ", y = " << proj.y0() << "\n";
cout << "Coordinates angle (deg) x (m) y (m):\n";
cout << setprecision(2);
for (int i = -180; i <= 180; i += 15) {
double omg = i + 90, bet = i,
x = proj.x(Angle(omg)), y = proj.y(Angle(bet));
cout << i << " " << x << " " << y << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,20 @@
// Example of using the GeographicLib::Constants class
#include <iostream>
#include <exception>
#include <GeographicLib/Constants.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
cout << "WGS84 parameters:\n"
<< "a = " << Constants::WGS84_a() << " m\n"
<< "f = 1/" << 1/Constants::WGS84_f() << "\n";
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,29 @@
// Example of using the GeographicLib::DMS class
#include <iostream>
#include <string>
#include <exception>
#include <GeographicLib/DMS.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
{
string dms = "30d14'45.6\"S";
DMS::flag type;
double ang = DMS::Decode(dms, type);
cout << type << " " << ang << "\n";
}
{
double ang = -30.245715;
string dms = DMS::Encode(ang, 6, DMS::LATITUDE);
cout << dms << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,62 @@
// Example of using the GeographicLib::DST class
#include <iostream>
#include <exception>
#include <vector>
#include <GeographicLib/Math.hpp>
#include <GeographicLib/DST.hpp>
using namespace std;
using namespace GeographicLib;
class sawtooth {
private:
double _a;
public:
sawtooth(double a) : _a(a) {}
// only called for x in (0, pi/2]. DST assumes function is periodic, period
// 2*pi, is odd about 0, and is even about pi/2.
double operator()(double x) const { return _a * x; }
};
int main() {
try {
sawtooth f(Math::pi()/4);
DST dst;
int N = 5, K = 2*N;
vector<double> tx(N), txa(2*N);
dst.reset(N);
dst.transform(f, tx.data());
cout << "Transform of sawtooth based on " << N << " points\n"
<< "approx 1, -1/9, 1/25, -1/49, ...\n";
for (int i = 0; i < min(K,N); ++i) {
int j = (2*i+1)*(2*i+1)*(1-((i&1)<<1));
cout << i << " " << tx[i] << " " << tx[i]*j << "\n";
}
tx.resize(2*N);
dst.refine(f, tx.data());
cout << "Add another " << N << " points\n";
for (int i = 0; i < min(K,2*N); ++i) {
int j = (2*i+1)*(2*i+1)*(1-((i&1)<<1));
cout << i << " " << tx[i] << " " << tx[i]*j << "\n";
}
dst.reset(2*N);
dst.transform(f, txa.data());
cout << "Retransform of sawtooth based on " << 2*N << " points\n";
for (int i = 0; i < min(K,2*N); ++i) {
int j = (2*i+1)*(2*i+1)*(1-((i&1)<<1));
cout << i << " " << txa[i] << " " << txa[i]*j << "\n";
}
cout << "Table of values and integral\n";
for (int i = 0; i <= K; ++i) {
double x = i*Math::pi()/(2*K), sinx = sin(x), cosx = cos(x);
cout << x << " " << f(x) << " "
<< DST::eval(sinx, cosx, txa.data(), 2*N) << " "
<< DST::integral(sinx, cosx, txa.data(), 2*N) << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,42 @@
// Example of using the GeographicLib::Ellipsoid class
#include <iostream>
#include <iomanip>
#include <exception>
#include <GeographicLib/Ellipsoid.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
Ellipsoid wgs84(Constants::WGS84_a(), Constants::WGS84_f());
// Alternatively: const Ellipsoid& wgs84 = Ellipsoid::WGS84();
cout << "The latitude half way between the equator and the pole is "
<< wgs84.InverseRectifyingLatitude(45) << "\n";
cout << "Half the area of the ellipsoid lies between latitudes +/- "
<< wgs84.InverseAuthalicLatitude(30) << "\n";
cout << "The northernmost edge of a square Mercator map is at latitude "
<< wgs84.InverseIsometricLatitude(180) << "\n";
cout << "Table phi(deg) beta-phi xi-phi mu-phi chi-phi theta-phi (mins)\n"
<< fixed << setprecision(2);
for (int i = 0; i <= 90; i += 15) {
double phi = i,
bet = wgs84.ParametricLatitude(phi),
xi = wgs84.AuthalicLatitude(phi),
mu = wgs84.RectifyingLatitude(phi),
chi = wgs84.ConformalLatitude(phi),
theta = wgs84.GeocentricLatitude(phi);
cout << i << " "
<< (bet-phi)*60 << " "
<< (xi-phi)*60 << " "
<< (mu-phi)*60 << " "
<< (chi-phi)*60 << " "
<< (theta-phi)*60 << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,34 @@
// Example of using the Triaxial::Ellipsoid3 class.
#include <iostream>
#include <iomanip>
#include <exception>
#include <GeographicLib/Triaxial/Ellipsoid3.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
using Triaxial::Ellipsoid3;
using ang = Angle;
using vec3 = Ellipsoid3::vec3;
Ellipsoid3 t(3, 2, 1);
ang bet{40}, omg{20}, alp{80};
vec3 r, v;
t.elliptocart2(bet, omg, alp, r, v);
cout << fixed << setprecision(3)
<< "[bet, omg, alp] = ["
<< double(bet) << " " << double(omg) << " " << double(alp)
<< "]\n => r = [" << r[0] << " " << r[1] << " " << r[2]
<< "], v = [" << v[0] << " " << v[1] << " " << v[2] << "]\n";
ang betn, omgn, alpn;
t.cart2toellip(r, v, betn, omgn, alpn);
cout << " => [bet, omg, alp] = ["
<< double(betn) << " " << double(omgn) << " " << double(alpn) << "]\n";
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,43 @@
// Example of using the GeographicLib::EllipticFunction class
#include <iostream>
#include <iomanip>
#include <exception>
#include <cmath>
#include <GeographicLib/Math.hpp>
#include <GeographicLib/EllipticFunction.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
EllipticFunction ell(0.1); // parameter m = 0.1
// See Abramowitz and Stegun, table 17.1
cout << ell.K() << " " << ell.E() << "\n";
double phi = 20, sn, cn;
Math::sincosd(phi, sn ,cn);
// See Abramowitz and Stegun, table 17.6 with
// alpha = asin(sqrt(m)) = 18.43 deg and phi = 20 deg
cout << ell.E(phi * Math::degree()) << " "
<< ell.E(sn, cn, ell.Delta(sn, cn))
<< "\n";
// See Carlson 1995, Sec 3.
cout << fixed << setprecision(16)
<< "RF(1,2,0) = " << EllipticFunction::RF(1,2) << "\n"
<< "RF(2,3,4) = " << EllipticFunction::RF(2,3,4) << "\n"
<< "RC(0,1/4) = " << EllipticFunction::RC(0,0.25) << "\n"
<< "RC(9/4,2) = " << EllipticFunction::RC(2.25,2) << "\n"
<< "RC(1/4,-2) = " << EllipticFunction::RC(0.25,-2) << "\n"
<< "RJ(0,1,2,3) = " << EllipticFunction::RJ(0,1,2,3) << "\n"
<< "RJ(2,3,4,5) = " << EllipticFunction::RJ(2,3,4,5) << "\n"
<< "RD(0,2,1) = " << EllipticFunction::RD(0,2,1) << "\n"
<< "RD(2,3,4) = " << EllipticFunction::RD(2,3,4) << "\n"
<< "RG(0,16,16) = " << EllipticFunction::RG(16,16) << "\n"
<< "RG(2,3,4) = " << EllipticFunction::RG(2,3,4) << "\n"
<< "RG(0,0.0796,4) = " << EllipticFunction::RG(0.0796,4) << "\n";
}
catch (const exception& e) {
cout << "Caught exception: " << e.what() << "\n";
}
}
@@ -0,0 +1,39 @@
// Example of using the GeographicLib::GARS class
#include <iostream>
#include <iomanip>
#include <exception>
#include <string>
#include <GeographicLib/GARS.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
{
// Sample forward calculation
double lat = 57.64911, lon = 10.40744; // Jutland
string gars;
for (int prec = 0; prec <= 2; ++prec) {
GARS::Forward(lat, lon, prec, gars);
cout << prec << " " << gars << "\n";
}
}
{
// Sample reverse calculation
string gars = "381NH45";
double lat, lon;
cout << fixed;
for (int len = 5; len <= int(gars.size()); ++len) {
int prec;
GARS::Reverse(gars.substr(0, len), lat, lon, prec);
cout << prec << " " << lat << " " << lon << "\n";
}
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,26 @@
// Example of using the GeographicLib::GeoCoords class
#include <iostream>
#include <exception>
#include <GeographicLib/GeoCoords.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
// Miscellaneous conversions
double lat = 33.3, lon = 44.4;
GeoCoords c(lat, lon);
cout << c.MGRSRepresentation(-3) << "\n";
c.Reset("18TWN0050");
cout << c.DMSRepresentation() << "\n";
cout << c.Latitude() << " " << c.Longitude() << "\n";
c.Reset("1d38'W 55d30'N");
cout << c.GeoRepresentation() << "\n";
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,36 @@
// Example of using the GeographicLib::Geocentric class
#include <iostream>
#include <exception>
#include <cmath>
#include <GeographicLib/Geocentric.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
Geocentric earth(Constants::WGS84_a(), Constants::WGS84_f());
// Alternatively: const Geocentric& earth = Geocentric::WGS84();
{
// Sample forward calculation
double lat = 27.99, lon = 86.93, h = 8820; // Mt Everest
double X, Y, Z;
earth.Forward(lat, lon, h, X, Y, Z);
cout << floor(X / 1000 + 0.5) << " "
<< floor(Y / 1000 + 0.5) << " "
<< floor(Z / 1000 + 0.5) << "\n";
}
{
// Sample reverse calculation
double X = 302e3, Y = 5636e3, Z = 2980e3;
double lat, lon, h;
earth.Reverse(X, Y, Z, lat, lon, h);
cout << lat << " " << lon << " " << h << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,18 @@
// Small example of using the GeographicLib::Geodesic class
#include <iostream>
#include <GeographicLib/Geodesic.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
const Geodesic& geod = Geodesic::WGS84();
// Distance from JFK to LHR
double
lat1 = 40.6, lon1 = -73.8, // JFK Airport
lat2 = 51.6, lon2 = -0.5; // LHR Airport
double s12;
geod.Inverse(lat1, lon1, lat2, lon2, s12);
cout << s12 / 1000 << " km\n";
}
@@ -0,0 +1,36 @@
// Example of using the GeographicLib::Geodesic class
#include <iostream>
#include <exception>
#include <GeographicLib/Geodesic.hpp>
#include <GeographicLib/Constants.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
Geodesic geod(Constants::WGS84_a(), Constants::WGS84_f());
// Alternatively: const Geodesic& geod = Geodesic::WGS84();
{
// Sample direct calculation, travelling about NE from JFK
double lat1 = 40.6, lon1 = -73.8, s12 = 5.5e6, azi1 = 51;
double lat2, lon2;
geod.Direct(lat1, lon1, azi1, s12, lat2, lon2);
cout << lat2 << " " << lon2 << "\n";
}
{
// Sample inverse calculation, JFK to LHR
double
lat1 = 40.6, lon1 = -73.8, // JFK Airport
lat2 = 51.6, lon2 = -0.5; // LHR Airport
double s12;
geod.Inverse(lat1, lon1, lat2, lon2, s12);
cout << s12 << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,27 @@
// Example of using the Triaxial::Geodesic3 class.
#include <iostream>
#include <iomanip>
#include <exception>
#include <GeographicLib/Triaxial/Geodesic3.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
Triaxial::Geodesic3 g(Triaxial::Ellipsoid3::Earth());
double bet1 = 10, omg1 = 30, bet2 = 80, omg2 = -50,
alp1, alp2, s12;
g.Inverse(bet1, omg1, bet2, omg2, s12, alp1, alp2);
cout << "geodesic between [" << bet1 << "," << omg1 << "] and ["
<< bet2 << "," << omg2 << "]\n";
cout << fixed << setprecision(3)
<< "s12 = " << s12 << ", alp1 = "
<< alp1 << ", alp2 = " << alp2 << "\n";
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,36 @@
// Example of using the GeographicLib::GeodesicExact class
#include <iostream>
#include <exception>
#include <GeographicLib/GeodesicExact.hpp>
#include <GeographicLib/Constants.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
GeodesicExact geod(Constants::WGS84_a(), Constants::WGS84_f());
// Alternatively: const GeodesicExact& geod = GeodesicExact::WGS84();
{
// Sample direct calculation, travelling about NE from JFK
double lat1 = 40.6, lon1 = -73.8, s12 = 5.5e6, azi1 = 51;
double lat2, lon2;
geod.Direct(lat1, lon1, azi1, s12, lat2, lon2);
cout << lat2 << " " << lon2 << "\n";
}
{
// Sample inverse calculation, JFK to LHR
double
lat1 = 40.6, lon1 = -73.8, // JFK Airport
lat2 = 51.6, lon2 = -0.5; // LHR Airport
double s12;
geod.Inverse(lat1, lon1, lat2, lon2, s12);
cout << s12 << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,69 @@
// Example of using the GeographicLib::GeodesicLine class
#include <iostream>
#include <iomanip>
#include <exception>
#include <cmath>
#include <GeographicLib/Geodesic.hpp>
#include <GeographicLib/GeodesicLine.hpp>
#include <GeographicLib/Constants.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
// Print waypoints between JFK and SIN
Geodesic geod(Constants::WGS84_a(), Constants::WGS84_f());
// Alternatively: const Geodesic& geod = Geodesic::WGS84();
double
lat1 = 40.640, lon1 = -73.779, // JFK
lat2 = 1.359, lon2 = 103.989; // SIN
GeodesicLine line = geod.InverseLine(lat1, lon1, lat2, lon2);
double ds0 = 500e3; // Nominal distance between points = 500 km
int num = int(ceil(line.Distance() / ds0)); // The number of intervals
cout << fixed << setprecision(3);
{
// Use intervals of equal length
double ds = line.Distance() / num;
for (int i = 0; i <= num; ++i) {
double lat, lon;
line.Position(i * ds, lat, lon);
cout << i << " " << lat << " " << lon << "\n";
}
}
{
// Slightly faster, use intervals of equal arc length
double da = line.Arc() / num;
for (int i = 0; i <= num; ++i) {
double lat, lon;
line.ArcPosition(i * da, lat, lon);
cout << i << " " << lat << " " << lon << "\n";
}
}
{
// Check that the inspection functions for exact = true return the same
// as for GeodesicLineExact.
Geodesic geoda(6.4e6, 0.5, true);
GeodesicExact geodb(6.4e6, 0.5);
GeodesicLine linea = geoda.InverseLine(lat1, lon1, lat2, lon2);
GeodesicLineExact lineb = geodb.InverseLine(lat1, lon1, lat2, lon2);
if (! (linea.Init() == lineb.Init() &&
linea.Latitude() == lineb.Latitude() &&
linea.Longitude() == lineb.Longitude() &&
linea.Azimuth() == lineb.Azimuth() &&
linea.EquatorialAzimuth() == lineb.EquatorialAzimuth() &&
linea.EquatorialArc() == lineb.EquatorialArc() &&
linea.EquatorialRadius() == lineb.EquatorialRadius() &&
linea.Flattening() == lineb.Flattening() &&
linea.Capabilities() == lineb.Capabilities() &&
linea.Distance() == lineb.Distance() &&
linea.Arc() == lineb.Arc()) )
cerr << "Incompatible results compared to GeodesicLineExact\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,28 @@
// Example of using the Triaxial::GeodesicLine3 class.
#include <iostream>
#include <iomanip>
#include <exception>
#include <GeographicLib/Triaxial/Geodesic3.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
Triaxial::Geodesic3 g(Triaxial::Ellipsoid3::Earth());
Triaxial::GeodesicLine3 l = g.Line(90, 0, 135);
// The approximate distance between opposite umbilical points
double s0 = 20003986;
int num = 20;
for (int i = 0; i <= num; ++i) {
double bet2, omg2, alp2, s12 = i*s0/num;
l.Position(s12, bet2, omg2, alp2);
cout << s12 << " " << bet2 << " " << omg2 << " " << alp2 << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,49 @@
// Example of using the GeographicLib::GeodesicLineExact class
#include <iostream>
#include <iomanip>
#include <exception>
#include <cmath>
#include <GeographicLib/GeodesicExact.hpp>
#include <GeographicLib/GeodesicLineExact.hpp>
#include <GeographicLib/Constants.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
// Print waypoints between JFK and SIN
GeodesicExact geod(Constants::WGS84_a(), Constants::WGS84_f());
// Alternatively: const GeodesicExact& geod = GeodesicExact::WGS84();
double
lat1 = 40.640, lon1 = -73.779, // JFK
lat2 = 1.359, lon2 = 103.989; // SIN
GeodesicLineExact line = geod.InverseLine(lat1, lon1, lat2, lon2);
double ds0 = 500e3; // Nominal distance between points = 500 km
int num = int(ceil(line.Distance() / ds0)); // The number of intervals
cout << fixed << setprecision(3);
{
// Use intervals of equal length
double ds = line.Distance() / num;
for (int i = 0; i <= num; ++i) {
double lat, lon;
line.Position(i * ds, lat, lon);
cout << i << " " << lat << " " << lon << "\n";
}
}
{
// Slightly faster, use intervals of equal arc length
double da = line.Arc() / num;
for (int i = 0; i <= num; ++i) {
double lat, lon;
line.ArcPosition(i * da, lat, lon);
cout << i << " " << lat << " " << lon << "\n";
}
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,16 @@
// Example of using the GeographicLib::GeographicErr class
#include <iostream>
#include <GeographicLib/Constants.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
throw GeographicErr("Test throwing an exception");
}
catch (const GeographicErr& e) {
cout << "Caught exception: " << e.what() << "\n";
}
}
@@ -0,0 +1,45 @@
// Example of using the GeographicLib::Geohash class
#include <iostream>
#include <iomanip>
#include <exception>
#include <string>
#include <GeographicLib/Geohash.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
{
// Sample forward calculation
double lat = 57.64911, lon = 10.40744; // Jutland (the wikipedia example)
string geohash;
int maxlen = Geohash::GeohashLength(1.0e-5);
for (int len = 0; len <= maxlen; ++len) {
Geohash::Forward(lat, lon, len, geohash);
cout << len << " " << geohash << "\n";
}
}
{
// Sample reverse calculation
string geohash = "u4pruydqqvj";
double lat, lon, latres, lonres;
cout << fixed;
for (unsigned i = 0; i <= geohash.length(); ++i) {
int len;
Geohash::Reverse(geohash.substr(0, i), lat, lon, len);
latres = Geohash::LatitudeResolution(len);
lonres = Geohash::LongitudeResolution(len);
cout << setprecision(max(0, Geohash::DecimalPrecision(len)))
<< len << " "
<< lat << "+/-" << latres/2 << " "
<< lon << "+/-" << lonres/2 << "\n";
}
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,27 @@
// Example of using the GeographicLib::Geoid class
// This requires that the egm96-5 geoid model be installed; see
// https://geographiclib.sourceforge.io/C++/doc/geoid.html#geoidinst
#include <iostream>
#include <exception>
#include <GeographicLib/Geoid.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
Geoid egm96("egm96-5");
// Convert height above egm96 to height above the ellipsoid
double lat = 42, lon = -75, height_above_geoid = 20;
double
geoid_height = egm96(lat, lon),
height_above_ellipsoid = (height_above_geoid +
Geoid::GEOIDTOELLIPSOID * geoid_height);
cout << height_above_ellipsoid << "\n";
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,41 @@
// Example of using the GeographicLib::GARS class
#include <iostream>
#include <iomanip>
#include <exception>
#include <string>
#include <GeographicLib/Georef.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
{
// Sample forward calculation
double lat = 57.64911, lon = 10.40744; // Jutland
string georef;
for (int prec = -1; prec <= 11; ++prec) {
Georef::Forward(lat, lon, prec, georef);
cout << prec << " " << georef << "\n";
}
}
{
// Sample reverse calculation
string georef = "NKLN2444638946";
double lat, lon;
int prec;
cout << fixed;
Georef::Reverse(georef.substr(0, 2), lat, lon, prec);
cout << prec << " " << lat << " " << lon << "\n";
Georef::Reverse(georef.substr(0, 4), lat, lon, prec);
cout << prec << " " << lat << " " << lon << "\n";
Georef::Reverse(georef, lat, lon, prec);
cout << prec << " " << lat << " " << lon << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,36 @@
// Example of using the GeographicLib::Gnomonic class
#include <iostream>
#include <exception>
#include <GeographicLib/Geodesic.hpp>
#include <GeographicLib/Gnomonic.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
Geodesic geod(Constants::WGS84_a(), Constants::WGS84_f());
// Alternatively: const Geodesic& geod = Geodesic::WGS84();
const double lat0 = 48 + 50/60.0, lon0 = 2 + 20/60.0; // Paris
Gnomonic proj(geod);
{
// Sample forward calculation
double lat = 50.9, lon = 1.8; // Calais
double x, y;
proj.Forward(lat0, lon0, lat, lon, x, y);
cout << x << " " << y << "\n";
}
{
// Sample reverse calculation
double x = -38e3, y = 230e3;
double lat, lon;
proj.Reverse(lat0, lon0, x, y, lat, lon);
cout << lat << " " << lon << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,43 @@
// Example of using the GeographicLib::GravityCircle class
// This requires that the egm96 gravity model be installed; see
// https://geographiclib.sourceforge.io/C++/doc/gravity.html#gravityinst
#include <iostream>
#include <exception>
#include <GeographicLib/GravityModel.hpp>
#include <GeographicLib/GravityCircle.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
GravityModel grav("egm96");
double lat = 27.99, lon0 = 86.93, h = 8820; // Mt Everest
{
// Slow method of evaluating the values at several points on a circle of
// latitude.
for (int i = -5; i <= 5; ++i) {
double lon = lon0 + i * 0.2;
double gx, gy, gz;
grav.Gravity(lat, lon, h, gx, gy, gz);
cout << lon << " " << gx << " " << gy << " " << gz << "\n";
}
}
{
// Fast method of evaluating the values at several points on a circle of
// latitude using GravityCircle.
GravityCircle circ = grav.Circle(lat, h);
for (int i = -5; i <= 5; ++i) {
double lon = lon0 + i * 0.2;
double gx, gy, gz;
circ.Gravity(lon, gx, gy, gz);
cout << lon << " " << gx << " " << gy << " " << gz << "\n";
}
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,24 @@
// Example of using the GeographicLib::GravityModel class
// This requires that the egm96 gravity model be installed; see
// https://geographiclib.sourceforge.io/C++/doc/gravity.html#gravityinst
#include <iostream>
#include <exception>
#include <GeographicLib/GravityModel.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
GravityModel grav("egm96");
double lat = 27.99, lon = 86.93, h = 8820; // Mt Everest
double gx, gy, gz;
grav.Gravity(lat,lon, h, gx, gy, gz);
cout << gx << " " << gy << " " << gz << "\n";
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,33 @@
// Example of using the GeographicLib::Intersect class
#include <iostream>
#include <exception>
#include <GeographicLib/Intersect.hpp>
#include <GeographicLib/Constants.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
Geodesic geod(Constants::WGS84_a(), Constants::WGS84_f());
Intersect intersect(geod);
// Define the two geodesics
GeodesicLine lineX(geod, 0, 0, 45, Intersect::LineCaps);
GeodesicLine lineY(geod, 45, 10, 135, Intersect::LineCaps);
// Find displacement to closest intersection
Intersect::Point point = intersect.Closest(lineX, lineY);
// Check position at intersection
double latx, lonx, laty, lony;
lineX.Position(point.first, latx, lonx);
lineY.Position(point.second, laty, lony);
cout << "X intersection displacement + position "
<< point.first << " " << latx << " " << lonx << "\n";
cout << "Y intersection displacement + position "
<< point.second << " " << laty << " " << lony << "\n";
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,48 @@
// Example of using the GeographicLib::LambertConformalConic class
#include <iostream>
#include <exception>
#include <GeographicLib/LambertConformalConic.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
// Define the Pennsylvania South state coordinate system EPSG:3364
// https://www.spatialreference.org/ref/epsg/3364/
const double
a = Constants::WGS84_a(),
f = 1/298.257222101, // GRS80
lat1 = 40 + 58/60.0, lat2 = 39 + 56/60.0, // standard parallels
k1 = 1, // scale
lat0 = 39 + 20/60.0, lon0 =-77 - 45/60.0, // origin
fe = 600000, fn = 0; // false easting and northing
// Set up basic projection
const LambertConformalConic PASouth(a, f, lat1, lat2, k1);
double x0, y0;
// Transform origin point
PASouth.Forward(lon0, lat0, lon0, x0, y0);
x0 -= fe; y0 -= fn;
{
// Sample conversion from geodetic to PASouth grid
double lat = 39.95, lon = -75.17; // Philadelphia
double x, y;
PASouth.Forward(lon0, lat, lon, x, y);
x -= x0; y -= y0;
cout << x << " " << y << "\n";
}
{
// Sample conversion from PASouth grid to geodetic
double x = 820e3, y = 72e3;
double lat, lon;
x += x0; y += y0;
PASouth.Reverse(lon0, x, y, lat, lon);
cout << lat << " " << lon << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,37 @@
// Example of using the GeographicLib::LocalCartesian class
#include <iostream>
#include <exception>
#include <cmath>
#include <GeographicLib/Geocentric.hpp>
#include <GeographicLib/LocalCartesian.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
Geocentric earth(Constants::WGS84_a(), Constants::WGS84_f());
// Alternatively: const Geocentric& earth = Geocentric::WGS84();
const double lat0 = 48 + 50/60.0, lon0 = 2 + 20/60.0; // Paris
LocalCartesian proj(lat0, lon0, 0, earth);
{
// Sample forward calculation
double lat = 50.9, lon = 1.8, h = 0; // Calais
double x, y, z;
proj.Forward(lat, lon, h, x, y, z);
cout << x << " " << y << " " << z << "\n";
}
{
// Sample reverse calculation
double x = -38e3, y = 230e3, z = -4e3;
double lat, lon, h;
proj.Reverse(x, y, z, lat, lon, h);
cout << lat << " " << lon << " " << h << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,42 @@
// Example of using the GeographicLib::MGRS class
#include <iostream>
#include <exception>
#include <string>
#include <GeographicLib/UTMUPS.hpp>
#include <GeographicLib/MGRS.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
// See also example-GeoCoords.cpp
{
// Sample forward calculation
double lat = 33.3, lon = 44.4; // Baghdad
int zone;
bool northp;
double x, y;
UTMUPS::Forward(lat, lon, zone, northp, x, y);
string mgrs;
MGRS::Forward(zone, northp, x, y, lat, 5, mgrs);
cout << mgrs << "\n";
}
{
// Sample reverse calculation
string mgrs = "38SMB4488";
int zone, prec;
bool northp;
double x, y;
MGRS::Reverse(mgrs, zone, northp, x, y, prec);
double lat, lon;
UTMUPS::Reverse(zone, northp, x, y, lat, lon);
cout << prec << " " << lat << " " << lon << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,43 @@
// Example of using the GeographicLib::MagneticCircle class
// This requires that the wmm2010 magnetic model be installed; see
// https://geographiclib.sourceforge.io/C++/doc/magnetic.html#magneticinst
#include <iostream>
#include <exception>
#include <GeographicLib/MagneticModel.hpp>
#include <GeographicLib/MagneticCircle.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
MagneticModel mag("wmm2010");
double lat = 27.99, lon0 = 86.93, h = 8820, t = 2012; // Mt Everest
{
// Slow method of evaluating the values at several points on a circle of
// latitude.
for (int i = -5; i <= 5; ++i) {
double lon = lon0 + i * 0.2;
double Bx, By, Bz;
mag(t, lat, lon, h, Bx, By, Bz);
cout << lon << " " << Bx << " " << By << " " << Bz << "\n";
}
}
{
// Fast method of evaluating the values at several points on a circle of
// latitude using MagneticCircle.
MagneticCircle circ = mag.Circle(t, lat, h);
for (int i = -5; i <= 5; ++i) {
double lon = lon0 + i * 0.2;
double Bx, By, Bz;
circ(lon, Bx, By, Bz);
cout << lon << " " << Bx << " " << By << " " << Bz << "\n";
}
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,26 @@
// Example of using the GeographicLib::MagneticModel class
// This requires that the wmm2010 magnetic model be installed; see
// https://geographiclib.sourceforge.io/C++/doc/magnetic.html#magneticinst
#include <iostream>
#include <exception>
#include <GeographicLib/MagneticModel.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
MagneticModel mag("wmm2010");
double lat = 27.99, lon = 86.93, h = 8820, t = 2012; // Mt Everest
double Bx, By, Bz;
mag(t, lat,lon, h, Bx, By, Bz);
double H, F, D, I;
MagneticModel::FieldComponents(Bx, By, Bz, H, F, D, I);
cout << H << " " << F << " " << D << " " << I << "\n";
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,18 @@
// Example of using the GeographicLib::Math class
#include <iostream>
#include <exception>
#include <GeographicLib/Math.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
cout << Math::pi() << " " << Math::sq(Math::pi()) << "\n";
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,140 @@
// Example of using the GeographicLib::NearestNeighbor class. WARNING: this
// creates a file, pointset.xml or pointset.txt, in the current directory.
// Read lat/lon locations from locations.txt and lat/lon queries from
// queries.txt. For each query print to standard output: the index for the
// closest location and the distance to it. Print statistics to standard error
// at the end.
#include <iostream>
#include <exception>
#include <vector>
#include <fstream>
#include <string>
#if !defined(GEOGRAPHICLIB_HAVE_BOOST_SERIALIZATION)
#define GEOGRAPHICLIB_HAVE_BOOST_SERIALIZATION 0
#endif
#if GEOGRAPHICLIB_HAVE_BOOST_SERIALIZATION
// If Boost serialization is available, use it.
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#endif
#include <GeographicLib/NearestNeighbor.hpp>
#include <GeographicLib/Geodesic.hpp>
#include <GeographicLib/DMS.hpp>
using namespace std;
using namespace GeographicLib;
// A structure to hold a geographic coordinate.
struct pos {
double _lat, _lon;
pos(double lat = 0, double lon = 0) : _lat(lat), _lon(lon) {}
};
// A class to compute the distance between 2 positions.
class DistanceCalculator {
private:
Geodesic _geod;
public:
explicit DistanceCalculator(const Geodesic& geod) : _geod(geod) {}
double operator() (const pos& a, const pos& b) const {
double d;
_geod.Inverse(a._lat, a._lon, b._lat, b._lon, d);
if ( !(d >= 0) )
// Catch illegal positions which result in d = NaN
throw GeographicErr("distance doesn't satisfy d >= 0");
return d;
}
};
int main() {
try {
// Read in locations
vector<pos> locs;
double lat, lon;
string sa, sb;
{
ifstream is("locations.txt");
if (!is.good())
throw GeographicErr("locations.txt not readable");
while (is >> sa >> sb) {
DMS::DecodeLatLon(sa, sb, lat, lon);
locs.push_back(pos(lat, lon));
}
if (locs.size() == 0)
throw GeographicErr("need at least one location");
}
// Define a distance function object
DistanceCalculator distance(Geodesic::WGS84());
// Create NearestNeighbor object
NearestNeighbor<double, pos, DistanceCalculator> pointset;
{
// Used saved object if it is available
#if GEOGRAPHICLIB_HAVE_BOOST_SERIALIZATION
ifstream is("pointset.xml");
if (is.good()) {
boost::archive::xml_iarchive ia(is);
ia >> BOOST_SERIALIZATION_NVP(pointset);
}
#else
ifstream is("pointset.txt");
if (is.good())
is >> pointset;
#endif
}
// Is the saved pointset up-to-date?
if (pointset.NumPoints() != int(locs.size())) {
// else initialize it
pointset.Initialize(locs, distance);
// and save it
#if GEOGRAPHICLIB_HAVE_BOOST_SERIALIZATION
ofstream os("pointset.xml");
if (!os.good())
throw GeographicErr("cannot write to pointset.xml");
boost::archive::xml_oarchive oa(os);
oa << BOOST_SERIALIZATION_NVP(pointset);
#else
ofstream os("pointset.txt");
if (!os.good())
throw GeographicErr("cannot write to pointset.txt");
os << pointset << "\n";
#endif
}
ifstream is("queries.txt");
double d;
int count = 0;
vector<int> k;
while (is >> sa >> sb) {
++count;
DMS::DecodeLatLon(sa, sb, lat, lon);
d = pointset.Search(locs, distance, pos(lat, lon), k);
if (k.size() != 1)
throw GeographicErr("unexpected number of results");
cout << k[0] << " " << d << "\n";
}
int setupcost, numsearches, searchcost, mincost, maxcost;
double mean, sd;
pointset.Statistics(setupcost, numsearches, searchcost,
mincost, maxcost, mean, sd);
int
totcost = setupcost + searchcost,
exhaustivecost = count * pointset.NumPoints();
cerr
<< "Number of distance calculations = " << totcost << "\n"
<< "With an exhaustive search = " << exhaustivecost << "\n"
<< "Ratio = " << double(totcost) / exhaustivecost << "\n"
<< "Efficiency improvement = "
<< 100 * (1 - double(totcost) / exhaustivecost) << "%\n";
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,25 @@
// Example of using the GeographicLib::NormalGravity class
#include <iostream>
#include <exception>
#include <GeographicLib/NormalGravity.hpp>
#include <GeographicLib/Constants.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
NormalGravity grav(Constants::WGS84_a(), Constants::WGS84_GM(),
Constants::WGS84_omega(), Constants::WGS84_f());
// Alternatively: const NormalGravity& grav = NormalGravity::WGS84();
double lat = 27.99, h = 8820; // Mt Everest
double gammay, gammaz;
grav.Gravity(lat, h, gammay, gammaz);
cout << gammay << " " << gammaz << "\n";
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,44 @@
// Example of using the GeographicLib::OSGB class
#include <iostream>
#include <iomanip>
#include <exception>
#include <string>
#include <GeographicLib/OSGB.hpp>
#include <GeographicLib/DMS.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
{
// Sample forward calculation from
// A guide to coordinate systems in Great Britain
double
lat = DMS::Decode(52,39,27.2531),
lon = DMS::Decode( 1,43, 4.5177);
double x, y;
OSGB::Forward(lat, lon, x, y);
string gridref;
OSGB::GridReference(x, y, 2, gridref);
cout << fixed << setprecision(3)
<< x << " " << y << " " << gridref << "\n";
}
{
// Sample reverse calculation
string gridref = "TG5113";
double x, y;
int prec;
OSGB::GridReference(gridref, x, y, prec);
double lat, lon;
OSGB::Reverse(x, y, lat, lon);
cout << fixed << setprecision(8)
<< prec << " " << lat << " " << lon << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,37 @@
// Example of using the GeographicLib::PolarStereographic class
#include <iostream>
#include <iomanip>
#include <exception>
#include <GeographicLib/PolarStereographic.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
PolarStereographic proj(Constants::WGS84_a(), Constants::WGS84_f(),
Constants::UPS_k0());
// Alternatively:
// const PolarStereographic& proj = PolarStereographic::UPS();
bool northp = true;
{
// Sample forward calculation
double lat = 61.2, lon = -149.9; // Anchorage
double x, y;
proj.Forward(northp, lat, lon, x, y);
cout << x << " " << y << "\n";
}
{
// Sample reverse calculation
double x = -1637e3, y = 2824e3;
double lat, lon;
proj.Reverse(northp, x, y, lat, lon);
cout << lat << " " << lon << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,40 @@
// Example of using the GeographicLib::PolygonArea class
#include <iostream>
#include <exception>
#include <GeographicLib/PolygonArea.hpp>
#include <GeographicLib/Geodesic.hpp>
#include <GeographicLib/Constants.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
Geodesic geod(Constants::WGS84_a(), Constants::WGS84_f());
// Alternatively: const Geodesic& geod = Geodesic::WGS84();
PolygonArea poly(geod);
poly.AddPoint( 52, 0); // London
poly.AddPoint( 41,-74); // New York
poly.AddPoint(-23,-43); // Rio de Janeiro
poly.AddPoint(-26, 28); // Johannesburg
double perimeter, area;
unsigned n = poly.Compute(false, true, perimeter, area);
cout << n << " " << perimeter << " " << area << "\n";
// This adds a test for a bug fix for AddEdge. (Implements the
// Planimeter29 test in geodtest.c.)
PolygonArea poly1(geod);
poly1.AddPoint(0,0);
poly1.AddEdge(90,1000);
poly1.AddEdge(0,1000);
poly1.AddEdge(-90,1000);
n = poly1.Compute(false, true, perimeter, area);
// The area should be 1e6. Prior to the fix it was 1e6 - A/2, where
// A = ellipsoid area.
cout << n << " " << perimeter << " " << area << "\n";
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,36 @@
// Example of using the GeographicLib::Rhumb class
#include <iostream>
#include <exception>
#include <GeographicLib/Rhumb.hpp>
#include <GeographicLib/Constants.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
Rhumb rhumb(Constants::WGS84_a(), Constants::WGS84_f());
// Alternatively: const Rhumb& rhumb = Rhumb::WGS84();
{
// Sample direct calculation, travelling about NE from JFK
double lat1 = 40.6, lon1 = -73.8, s12 = 5.5e6, azi12 = 51;
double lat2, lon2;
rhumb.Direct(lat1, lon1, azi12, s12, lat2, lon2);
cout << lat2 << " " << lon2 << "\n";
}
{
// Sample inverse calculation, JFK to LHR
double
lat1 = 40.6, lon1 = -73.8, // JFK Airport
lat2 = 51.6, lon2 = -0.5; // LHR Airport
double s12, azi12;
rhumb.Inverse(lat1, lon1, lat2, lon2, s12, azi12);
cout << s12 << " " << azi12 << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,41 @@
// Example of using the GeographicLib::RhumbLine class
#include <iostream>
#include <iomanip>
#include <exception>
#include <cmath>
#include <GeographicLib/Rhumb.hpp>
#include <GeographicLib/Constants.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
// Print waypoints between JFK and SIN
Rhumb rhumb(Constants::WGS84_a(), Constants::WGS84_f());
// Alternatively: const Rhumb& rhumb = Rhumb::WGS84();
double
lat1 = 40.640, lon1 = -73.779, // JFK
lat2 = 1.359, lon2 = 103.989; // SIN
double s12, azi12;
rhumb.Inverse(lat1, lon1, lat2, lon2, s12, azi12);
RhumbLine line = rhumb.Line(lat1, lon1, azi12);
double ds0 = 500e3; // Nominal distance between points = 500 km
int num = int(ceil(s12 / ds0)); // The number of intervals
cout << fixed << setprecision(3);
{
// Use intervals of equal length
double ds = s12 / num;
for (int i = 0; i <= num; ++i) {
double lat, lon;
line.Position(i * ds, lat, lon);
cout << i << " " << lat << " " << lon << "\n";
}
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,32 @@
// Example of using the GeographicLib::SphericalEngine class
#include <iostream>
#include <exception>
#include <vector>
#include <GeographicLib/SphericalEngine.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
// See also example-SphericHarmonic.cpp
try {
int N = 3; // The maxium degree
double ca[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; // cosine coefficients
vector<double> C(ca, ca + (N + 1) * (N + 2) / 2);
double sa[] = {6, 5, 4, 3, 2, 1}; // sine coefficients
vector<double> S(sa, sa + N * (N + 1) / 2);
SphericalEngine::coeff c[1];
c[0] = SphericalEngine::coeff(C, S, N);
double f[] = {1};
double x = 2, y = 3, z = 1, a = 1;
double v, vx, vy, vz;
v = SphericalEngine::Value<true, SphericalEngine::FULL, 1>
(c, f, x, y, z, a, vx, vy, vz);
cout << v << " " << vx << " " << vy << " " << vz << "\n";
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,29 @@
// Example of using the GeographicLib::SphericalHarmonic class
#include <iostream>
#include <exception>
#include <vector>
#include <GeographicLib/SphericalHarmonic.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
int N = 3; // The maxium degree
double ca[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; // cosine coefficients
vector<double> C(ca, ca + (N + 1) * (N + 2) / 2);
double sa[] = {6, 5, 4, 3, 2, 1}; // sine coefficients
vector<double> S(sa, sa + N * (N + 1) / 2);
double a = 1;
SphericalHarmonic h(C, S, N, a);
double x = 2, y = 3, z = 1;
double v, vx, vy, vz;
v = h(x, y, z, vx, vy, vz);
cout << v << " " << vx << " " << vy << " " << vz << "\n";
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,33 @@
// Example of using the GeographicLib::SphericalHarmonic1 class
#include <iostream>
#include <exception>
#include <vector>
#include <GeographicLib/SphericalHarmonic1.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
int N = 3, N1 = 2; // The maxium degrees
double ca[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; // cosine coefficients
vector<double> C(ca, ca + (N + 1) * (N + 2) / 2);
double sa[] = {6, 5, 4, 3, 2, 1}; // sine coefficients
vector<double> S(sa, sa + N * (N + 1) / 2);
double cb[] = {1, 2, 3, 4, 5, 6};
vector<double> C1(cb, cb + (N1 + 1) * (N1 + 2) / 2);
double sb[] = {3, 2, 1};
vector<double> S1(sb, sb + N1 * (N1 + 1) / 2);
double a = 1;
SphericalHarmonic1 h(C, S, N, C1, S1, N1, a);
double tau = 0.1, x = 2, y = 3, z = 1;
double v, vx, vy, vz;
v = h(tau, x, y, z, vx, vy, vz);
cout << v << " " << vx << " " << vy << " " << vz << "\n";
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,37 @@
// Example of using the GeographicLib::SphericalHarmonic2 class
#include <iostream>
#include <exception>
#include <vector>
#include <GeographicLib/SphericalHarmonic2.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
int N = 3, N1 = 2, N2 = 1; // The maxium degrees
double ca[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; // cosine coefficients
vector<double> C(ca, ca + (N + 1) * (N + 2) / 2);
double sa[] = {6, 5, 4, 3, 2, 1}; // sine coefficients
vector<double> S(sa, sa + N * (N + 1) / 2);
double cb[] = {1, 2, 3, 4, 5, 6};
vector<double> C1(cb, cb + (N1 + 1) * (N1 + 2) / 2);
double sb[] = {3, 2, 1};
vector<double> S1(sb, sb + N1 * (N1 + 1) / 2);
double cc[] = {2, 1};
vector<double> C2(cc, cc + (N2 + 1));
vector<double> S2;
double a = 1;
SphericalHarmonic2 h(C, S, N, N, N, C1, S1, N1, N1, N1,
C2, S2, N2, N2, 0, a);
double tau1 = 0.1, tau2 = 0.05, x = 2, y = 3, z = 1;
double v, vx, vy, vz;
v = h(tau1, tau2, x, y, z, vx, vy, vz);
cout << v << " " << vx << " " << vy << " " << vz << "\n";
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,63 @@
// Example of using the GeographicLib::TransverseMercator class
#include <iostream>
#include <iomanip>
#include <exception>
#include <GeographicLib/TransverseMercator.hpp>
using namespace std;
using namespace GeographicLib;
// Define a UTM projection for an arbitrary ellipsoid
class UTMalt {
private:
TransverseMercator _tm; // The projection
double _lon0; // Central longitude
double _falseeasting, _falsenorthing;
public:
UTMalt(double a, // equatorial radius
double f, // flattening
int zone, // the UTM zone + hemisphere
bool northp)
: _tm(a, f, Constants::UTM_k0())
, _lon0(6 * zone - 183)
, _falseeasting(5e5)
, _falsenorthing(northp ? 0 : 100e5) {
if (!(zone >= 1 && zone <= 60))
throw GeographicErr("zone not in [1,60]");
}
void Forward(double lat, double lon, double& x, double& y) {
_tm.Forward(_lon0, lat, lon, x, y);
x += _falseeasting;
y += _falsenorthing;
}
void Reverse(double x, double y, double& lat, double& lon) {
x -= _falseeasting;
y -= _falsenorthing;
_tm.Reverse(_lon0, x, y, lat, lon);
}
};
int main() {
try {
UTMalt tm(6378388, 1/297.0, 30, true); // International ellipsoid, zone 30n
{
// Sample forward calculation
double lat = 40.4, lon = -3.7; // Madrid
double x, y;
tm.Forward(lat, lon, x, y);
cout << fixed << setprecision(0) << x << " " << y << "\n";
}
{
// Sample reverse calculation
double x = 441e3, y = 4472e3;
double lat, lon;
tm.Reverse(x, y, lat, lon);
cout << fixed << setprecision(5) << lat << " " << lon << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,37 @@
// Example of using the GeographicLib::TransverseMercatorExact class
#include <iostream>
#include <iomanip>
#include <exception>
#include <GeographicLib/TransverseMercatorExact.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
TransverseMercatorExact proj(Constants::WGS84_a(), Constants::WGS84_f(),
Constants::UTM_k0());
// Alternatively:
// const TransverseMercatorExact& proj = TransverseMercatorExact::UTM();
double lon0 = -75; // Central meridian for UTM zone 18
{
// Sample forward calculation
double lat = 40.3, lon = -74.7; // Princeton, NJ
double x, y;
proj.Forward(lon0, lat, lon, x, y);
cout << x << " " << y << "\n";
}
{
// Sample reverse calculation
double x = 25e3, y = 4461e3;
double lat, lon;
proj.Reverse(lon0, x, y, lat, lon);
cout << lat << " " << lon << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,29 @@
// Example of using the GeographicLib::Trigfun class.
#include <iostream>
#include <iomanip>
#include <exception>
#include <GeographicLib/Trigfun.hpp>
using namespace std;
using namespace GeographicLib;
int main(int argc, const char* const argv[]) {
try {
// Approximate 1/sqrt(1 - k2*sin(x)^2) by a Fourier series
double k2 = Math::sq(0.8);
auto f = [k2] (double x) -> double
{ return 1/sqrt(1 - k2 * Math::sq(sin(x))); };
Trigfun tf(f, false, false, Math::pi()/2);
cout << "Number of coefficients: " << tf.NCoeffs() << "\n";
cout << "x tf(x) tf(x)-f(x)\n";
for (int i = 0; i <= 20; ++i) {
double x = i/10.0;
cout << x << " " << tf(x) << " " << tf(x) - f(x) << "\n";
}
}
catch (const std::exception& e) {
std::cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,32 @@
// Example of using the GeographicLib::TrigfunExt class.
#include <iostream>
#include <iomanip>
#include <exception>
#include <GeographicLib/Trigfun.hpp>
#include <GeographicLib/EllipticFunction.hpp>
using namespace std;
using namespace GeographicLib;
int main(int argc, const char* const argv[]) {
try {
// Integrate 1/sqrt(1 - k2*sin(x)^2) and compare this to the elliptic
// integral of the first kine.
double k2 = Math::sq(0.8);
auto f = [k2] (double x) -> double
{ return 1/sqrt(1 - k2 * Math::sq(sin(x))); };
TrigfunExt tfe(f, Math::pi()/2);
cout << "Number of coefficients: " << tfe.NCoeffs() << "\n";
EllipticFunction ell(k2);
cout << "x tf(x) tf(x)-F(x)\n";
for (int i = 0; i <= 20; ++i) {
double x = i/10.0;
cout << x << " " << tfe(x) << " " << tfe(x) - ell.F(x) << "\n";
}
}
catch (const std::exception& e) {
std::cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,42 @@
// Example of using the GeographicLib::UTMUPS class
#include <iostream>
#include <iomanip>
#include <exception>
#include <string>
#include <GeographicLib/UTMUPS.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
// See also example-GeoCoords.cpp
{
// Sample forward calculation
double lat = 33.3, lon = 44.4; // Baghdad
int zone;
bool northp;
double x, y;
UTMUPS::Forward(lat, lon, zone, northp, x, y);
string zonestr = UTMUPS::EncodeZone(zone, northp);
cout << fixed << setprecision(2)
<< zonestr << " " << x << " " << y << "\n";
}
{
// Sample reverse calculation
string zonestr = "38n";
int zone;
bool northp;
UTMUPS::DecodeZone(zonestr, zone, northp);
double x = 444e3, y = 3688e3;
double lat, lon;
UTMUPS::Reverse(zone, northp, x, y, lat, lon);
cout << lat << " " << lon << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,21 @@
// Example of using the GeographicLib::Utility class
#include <iostream>
#include <exception>
#include <GeographicLib/Utility.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
int
d1 = Utility::day(1939, 9, 3), // Britain declares war on Germany
d2 = Utility::day(1945, 8, 15); // Japan surrenders
cout << d2 - d1 << "\n"; // Length of Second World War for Britain
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
@@ -0,0 +1,45 @@
// Write the coefficient files needed for approximating the normal gravity
// field with a GravityModel. WARNING: this creates files, wgs84.egm.cof and
// grs80.egm.cof, in the current directory.
#include <cmath>
#include <fstream>
#include <iostream>
#include <GeographicLib/NormalGravity.hpp>
#include <GeographicLib/Utility.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
Utility::set_digits();
const char* filenames[] = {"wgs84.egm.cof", "grs80.egm.cof"};
const char* ids[] = {"WGS1984A", "GRS1980A"};
for (int grs80 = 0; grs80 < 2; ++grs80) {
ofstream file(filenames[grs80], ios::binary);
Utility::writearray<char, char, false>(file, ids[grs80], 8);
const int N = 20, M = 0,
cnum = (M + 1) * (2 * N - M + 2) / 2; // cnum = N + 1
vector<int> num(2);
num[0] = N; num[1] = M;
Utility::writearray<int, int, false>(file, num);
vector<Math::real> c(cnum, 0);
const NormalGravity& earth(grs80 ? NormalGravity::GRS80() :
NormalGravity::WGS84());
for (int n = 2; n <= N; n += 2)
c[n] = - earth.DynamicalFormFactor(n) / sqrt(Math::real(2*n + 1));
Utility::writearray<double, Math::real, false>(file, c);
num[0] = num[1] = -1;
Utility::writearray<int, int, false>(file, num);
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
catch (...) {
cerr << "Caught unknown exception\n";
return 1;
}
}
@@ -0,0 +1,23 @@
The MIT License (MIT).
Copyright (c) 2008-2025, Charles Karney
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,24 @@
<html>
<head>
<title>GeographicLib-2.7 documentation</title>
<meta HTTP-EQUIV="Refresh"
CONTENT="0; URL=https://geographiclib.sourceforge.io/C++/2.7/index.html">
</head>
<body topmargin=10 leftmargin=10>
<h3>
<blockquote>
<em>
Online documentation for GeographicLib version
2.7 is available at
<center>
<a href="https://geographiclib.sourceforge.io/C++/2.7/index.html">
https://geographiclib.sourceforge.io/C++/2.7/index.html</a>.
</center>
<br>
You will be redirected there. Click on the link to go there
directly.
</em>
</blockquote>
</h3>
</body>
</html>
@@ -0,0 +1,24 @@
<html>
<head>
<title>GeographicLib-2.7 utilities</title>
<meta HTTP-EQUIV="Refresh"
CONTENT="0; URL=https://geographiclib.sourceforge.io/C++/2.7/utilities.html">
</head>
<body topmargin=10 leftmargin=10>
<h3>
<blockquote>
<em>
Online documentation for utilities for GeographicLib version
2.7 is available at
<center>
<a href="https://geographiclib.sourceforge.io/C++/2.7/utilities.html">
https://geographiclib.sourceforge.io/C++/2.7/utilities.html</a>.
</center>
<br>
You will be redirected there. Click on the link to go there
directly.
</em>
</blockquote>
</h3>
</body>
</html>
@@ -0,0 +1,9 @@
.TH Cart3Convert 1 "" "GeographicLib Utilities" "GeographicLib Utilities"
.SH NAME
Cart3Convert \-\- a GeographicLib utility
.SH DESCRIPTION
.B Cart3Convert
is part of GeographicLib, <https://geographiclib.sourceforge.io>. For
documentation, see
.PP
https://geographiclib.sourceforge.io/C++/2.7/Cart3Convert.1.html
@@ -0,0 +1,9 @@
.TH CartConvert 1 "" "GeographicLib Utilities" "GeographicLib Utilities"
.SH NAME
CartConvert \-\- a GeographicLib utility
.SH DESCRIPTION
.B CartConvert
is part of GeographicLib, <https://geographiclib.sourceforge.io>. For
documentation, see
.PP
https://geographiclib.sourceforge.io/C++/2.7/CartConvert.1.html
@@ -0,0 +1,9 @@
.TH Conformal3Proj 1 "" "GeographicLib Utilities" "GeographicLib Utilities"
.SH NAME
Conformal3Proj \-\- a GeographicLib utility
.SH DESCRIPTION
.B Conformal3Proj
is part of GeographicLib, <https://geographiclib.sourceforge.io>. For
documentation, see
.PP
https://geographiclib.sourceforge.io/C++/2.7/Conformal3Proj.1.html
@@ -0,0 +1,9 @@
.TH ConicProj 1 "" "GeographicLib Utilities" "GeographicLib Utilities"
.SH NAME
ConicProj \-\- a GeographicLib utility
.SH DESCRIPTION
.B ConicProj
is part of GeographicLib, <https://geographiclib.sourceforge.io>. For
documentation, see
.PP
https://geographiclib.sourceforge.io/C++/2.7/ConicProj.1.html
@@ -0,0 +1,9 @@
.TH GeoConvert 1 "" "GeographicLib Utilities" "GeographicLib Utilities"
.SH NAME
GeoConvert \-\- a GeographicLib utility
.SH DESCRIPTION
.B GeoConvert
is part of GeographicLib, <https://geographiclib.sourceforge.io>. For
documentation, see
.PP
https://geographiclib.sourceforge.io/C++/2.7/GeoConvert.1.html
@@ -0,0 +1,9 @@
.TH Geod3Solve 1 "" "GeographicLib Utilities" "GeographicLib Utilities"
.SH NAME
Geod3Solve \-\- a GeographicLib utility
.SH DESCRIPTION
.B Geod3Solve
is part of GeographicLib, <https://geographiclib.sourceforge.io>. For
documentation, see
.PP
https://geographiclib.sourceforge.io/C++/2.7/Geod3Solve.1.html
@@ -0,0 +1,9 @@
.TH GeodSolve 1 "" "GeographicLib Utilities" "GeographicLib Utilities"
.SH NAME
GeodSolve \-\- a GeographicLib utility
.SH DESCRIPTION
.B GeodSolve
is part of GeographicLib, <https://geographiclib.sourceforge.io>. For
documentation, see
.PP
https://geographiclib.sourceforge.io/C++/2.7/GeodSolve.1.html
@@ -0,0 +1,9 @@
.TH GeodesicProj 1 "" "GeographicLib Utilities" "GeographicLib Utilities"
.SH NAME
GeodesicProj \-\- a GeographicLib utility
.SH DESCRIPTION
.B GeodesicProj
is part of GeographicLib, <https://geographiclib.sourceforge.io>. For
documentation, see
.PP
https://geographiclib.sourceforge.io/C++/2.7/GeodesicProj.1.html
@@ -0,0 +1,9 @@
.TH GeoidEval 1 "" "GeographicLib Utilities" "GeographicLib Utilities"
.SH NAME
GeoidEval \-\- a GeographicLib utility
.SH DESCRIPTION
.B GeoidEval
is part of GeographicLib, <https://geographiclib.sourceforge.io>. For
documentation, see
.PP
https://geographiclib.sourceforge.io/C++/2.7/GeoidEval.1.html
@@ -0,0 +1,9 @@
.TH Gravity 1 "" "GeographicLib Utilities" "GeographicLib Utilities"
.SH NAME
Gravity \-\- a GeographicLib utility
.SH DESCRIPTION
.B Gravity
is part of GeographicLib, <https://geographiclib.sourceforge.io>. For
documentation, see
.PP
https://geographiclib.sourceforge.io/C++/2.7/Gravity.1.html
@@ -0,0 +1,9 @@
.TH IntersectTool 1 "" "GeographicLib Utilities" "GeographicLib Utilities"
.SH NAME
IntersectTool \-\- a GeographicLib utility
.SH DESCRIPTION
.B IntersectTool
is part of GeographicLib, <https://geographiclib.sourceforge.io>. For
documentation, see
.PP
https://geographiclib.sourceforge.io/C++/2.7/IntersectTool.1.html
@@ -0,0 +1,9 @@
.TH MagneticField 1 "" "GeographicLib Utilities" "GeographicLib Utilities"
.SH NAME
MagneticField \-\- a GeographicLib utility
.SH DESCRIPTION
.B MagneticField
is part of GeographicLib, <https://geographiclib.sourceforge.io>. For
documentation, see
.PP
https://geographiclib.sourceforge.io/C++/2.7/MagneticField.1.html
@@ -0,0 +1,9 @@
.TH Planimeter 1 "" "GeographicLib Utilities" "GeographicLib Utilities"
.SH NAME
Planimeter \-\- a GeographicLib utility
.SH DESCRIPTION
.B Planimeter
is part of GeographicLib, <https://geographiclib.sourceforge.io>. For
documentation, see
.PP
https://geographiclib.sourceforge.io/C++/2.7/Planimeter.1.html
@@ -0,0 +1,9 @@
.TH RhumbSolve 1 "" "GeographicLib Utilities" "GeographicLib Utilities"
.SH NAME
RhumbSolve \-\- a GeographicLib utility
.SH DESCRIPTION
.B RhumbSolve
is part of GeographicLib, <https://geographiclib.sourceforge.io>. For
documentation, see
.PP
https://geographiclib.sourceforge.io/C++/2.7/RhumbSolve.1.html
@@ -0,0 +1,9 @@
.TH TransverseMercatorProj 1 "" "GeographicLib Utilities" "GeographicLib Utilities"
.SH NAME
TransverseMercatorProj \-\- a GeographicLib utility
.SH DESCRIPTION
.B TransverseMercatorProj
is part of GeographicLib, <https://geographiclib.sourceforge.io>. For
documentation, see
.PP
https://geographiclib.sourceforge.io/C++/2.7/TransverseMercatorProj.1.html
@@ -0,0 +1,15 @@
.TH geographiclib-get-geoids 8 "" GeographicLib GeographicLib
.SH NAME
geographiclib-get-geoids \-\- a GeographicLib administrative tool
.SH DESCRIPTION
.B geographiclib-get-geoids
downloads and installs the geoids datasets used by GeographicLib,
<https://geographiclib.sourceforge.io>. For documentation, supply the
.B \-h
option:
.PP
geographiclib-get-geoids \-h
.PP
By default, the datasets are installed in
.I /usr/local/share/GeographicLib/geoids
and the script requires write access to this directory.
@@ -0,0 +1,15 @@
.TH geographiclib-get-gravity 8 "" GeographicLib GeographicLib
.SH NAME
geographiclib-get-gravity \-\- a GeographicLib administrative tool
.SH DESCRIPTION
.B geographiclib-get-gravity
downloads and installs the gravity datasets used by GeographicLib,
<https://geographiclib.sourceforge.io>. For documentation, supply the
.B \-h
option:
.PP
geographiclib-get-gravity \-h
.PP
By default, the datasets are installed in
.I /usr/local/share/GeographicLib/gravity
and the script requires write access to this directory.
@@ -0,0 +1,15 @@
.TH geographiclib-get-magnetic 8 "" GeographicLib GeographicLib
.SH NAME
geographiclib-get-magnetic \-\- a GeographicLib administrative tool
.SH DESCRIPTION
.B geographiclib-get-magnetic
downloads and installs the magnetic datasets used by GeographicLib,
<https://geographiclib.sourceforge.io>. For documentation, supply the
.B \-h
option:
.PP
geographiclib-get-magnetic \-h
.PP
By default, the datasets are installed in
.I /usr/local/share/GeographicLib/magnetic
and the script requires write access to this directory.