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