Coder Social home page Coder Social logo

vahancho / erkir Goto Github PK

View Code? Open in Web Editor NEW
45.0 4.0 16.0 138 KB

Երկիր (Erkir) - a C++ library for geodesic and trigonometric calculations

License: Other

C++ 95.62% CMake 4.20% C 0.18%
geodesy earth coordinates geography datum cpp cpp11 stl geometry distance distance-calculation trigonometric-calculations ellipsoidal-earth-models geodesy-functions geodetic-point coordinate-systems library geodetic geodetic-datum geodetic-aplications

erkir's Introduction

Երկիր (Erkir) - a C++ library for geodesic and trigonometric calculations

Erkir (armenian: Երկիր, means Earth) - is inspired by and based on the great work of Chris Veness, the owner of the Geodesy functions project - provides a set of comprehensive API for geodesic and trigonometric calculations. I would call it a C++ port of JavaScript functions provided by the mentioned Chris Veness' project, however I designed the library to be more object oriented. Thus the code is organized a little bit differently, but the implementation itself is preserved.

Latest release Test (CMake) codecov

Prerequisites

There are no special requirements and dependencies except C++11 compliant compiler. The class is tested with gcc 4.8.4 and MSVC 15.x (Visual Studio 2017). The library is written with pure STL without any third party dependencies. For more details see the CI badges (GitHub Actions) above.

Installation

No installation required. Just incorporate header files from the include/ and source files from src/ directories in your project and compile them. All library classes are in erkir namespace.

Integration with CMake projects

However, if you use CMake and want to integrate the library into your project you might want to install it first by invoking a CMake command from the build directory:

cmake --install . --prefix=<install_path> --config=Release

Once the library is installed you can use it from in your project by adjusting its CMake script. For example:

[..]
find_package(erkir REQUIRED)

add_executable(example main.cpp)
target_link_libraries(example erkir)
[..]

The API

The code is virtually split into three domains (namespaces) that represent spherical and ellipsoidal geodetic coordinates and cartesian (x/y/z) for geocentric ones: erkir::spherical, erkir::ellipsoidal and erkir::cartesian correspondingly. Spherical Earth model based calculations are accurate enough for most cases, however in order to gain more precise measurements use erkir::ellipsoidal classes.

erkir::spherical::Point class implements geodetic point on the basis of a spherical earth (ignoring ellipsoidal effects). It uses formulae to calculate distances between two points (using haversine formula), initial bearing from a point, final bearing to a point, etc.

erkir::ellipsoidal::Point class represents geodetic point based on ellipsoidal earth model. It includes ellipsoid parameters and datums for different coordinate systems, and methods for converting between them and to Cartesian coordinates.

erkir::Vector3d implements 3-d vector manipulation routines. With this class you can perform basic operations with the vectors, such as calculate dot (scalar) product of two vectors, multiply vectors, add and subtract them.

erkir::cartesian::Point implements ECEF (earth-centered earth-fixed) geocentric cartesian (x/y/z) coordinates.

Usage Examples:

#include "sphericalpoint.h"
#include "ellipsoidalpoint.h"

int main(int argc, char **argv)
{
  // Calculate great-circle distance between two points.
  erkir::spherical::Point p1{ 52.205, 0.119 };
  erkir::spherical::Point p2{ 48.857, 2.351 };
  auto d = p1.distanceTo(p2); // 404.3 km

  // Get destination point by given distance (shortest) and bearing from start point.
  erkir::spherical::Point p3{ 51.4778, -0.0015 };
  auto dest = p3.destinationPoint(7794.0, 300.7); // 51.5135°N, 000.0983°W

  // Convert a point from one coordinates system to another.
  erkir::ellipsoidal::Point pWGS84(51.4778, -0.0016, ellipsoidal::Datum::Type::WGS84);
  auto pOSGB = pWGS84.toDatum(ellipsoidal::Datum::Type::OSGB36); // 51.4778°N, 000.0000°E

  // Convert to Cartesian coordinates.
  auto cartesian = pWGS84.toCartesianPoint();

  // Convert Cartesian point to a geodetic one.
  auto geoPoint = cartesian->toGeoPoint();

  return 0;
}

Conversion from/to strings

Library supports latitude/longitude coordinates conversion in three formats: Degrees Minutes Seconds (D° M' S"), Decimal Minutes (D° M.M'), and Decimal Degrees (D.D°).

auto lon = Longitude::fromString("45° 46’ 47.36” W");
auto lat = Latitude::fromString("45°46′ 45.36″ N");
auto lon = Longitude{45.7790};
auto lonStr = lon.toString(Coordinate::Format::DMS); // 45° 46′ 45.36″ E

For more usage examples please refer to the unit tests at /test/test.cpp file.

Building and Testing

There are unit tests. You can find them in the test/ directory. To run them you have to build and run the test application. For doing that you must invoke the following commands from the terminal, assuming that compiler and environment are already configured:

Linux (gcc)

mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DENABLE_TESTING=True
cmake --build .
ctest

Windows (MSVC Toolchain)

mkdir build && cd build
cmake .. -DENABLE_TESTING=True -A x64
cmake --build . --config=Release
ctest -C Release

For x86 builds use -A Win32 option instead.

Performance Tests

I measured performance (on Intel Core i5 series processor) for some spherical geodesy functions (Point class). I used similar approach as Chris Veness did in his tests, i.e. called functions for 5000 random points or pairs of points. And here are my results:

Function Avg. time/calculation (nanoseconds)
Distance (haversine) 162
Initial bearing 190
Destination point 227

of course timings are machine dependent

See Also

erkir's People

Contributors

vahancho avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

erkir's Issues

Point.h and Point.cpp valid inconsistency!

The documentation for Point.h is inconsistent. It states that a default constructed point is invalid, however the default constructor sets lat lon to 0 and valid to true.

Height discrepancy and Helmert transformation

Good morning!

I am using your library and I think I have encountered a discrepancy regarding the heightof a point when converted into a different coordinate standard (i.e. when chaning its datum). In particular, if I define a point as

erkir::ellipsoidal::Point greenwichWGS84(51.47788, -0.00147, 0.0, erkir::ellipsoidal::Datum::Type::WGS84);

and then I convert it to the OSGB36 standard, I obtain an height of -45.9051.

Is this result the correct height, maybe because we are in a different standard? Or is there a mistake somewhere?

Also, in the wikipedia page the Helmert transformation is defined as:

image

while in your code it is written slightly differently. Is there a reason for that?

Thank you in advance! 🙏

Replace CMAKE_SOURCE_DIR with CMAKE_CURRENT_SOURCE_DIR

CMake is currently configured to use CMAKE_SOURCE_DIR
Conflicts may arise when the library is imported (for example, using CPM)
It is necessary to change every instance of CMAKE_SOURCE_DIR to CMAKE_CURRENT_SOURCE_DIR in order to prevent the latter

change target_include_directories() to use PUBLIC_instead of PRIVATE

target_include_directories(erkir PUBLIC include) make it easier to use this library.
It will then be enough to write target_link_libraries(<target> erkir) and the include directory will be accessible automatically.
But as it is now one have to specify erkir include dir manually with e.g include_libraries().

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.