ADD: new track message, Entity class and Position class
This commit is contained in:
18
libs/geographiclib/wrapper/README.md
Normal file
18
libs/geographiclib/wrapper/README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Calling the GeographicLib C++ library from other languages
|
||||
|
||||
Here are some examples of calling the C++ library from other languages
|
||||
such as C, Octave, and Python.
|
||||
|
||||
Although the geodesic capabilities of GeographicLib have been
|
||||
implemented natively in several languages. There are no plans to do the
|
||||
same for its other capabilities since this leads to a large continuing
|
||||
obligation for maintenance and documentation. (Note however that thet
|
||||
Octave/MATLAB library includes additional capabilities, UTM, MGRS, etc.)
|
||||
|
||||
An alternative strategy is to call the C++ library directly from
|
||||
another language, possibly via some "wrapper" routines. This can be a
|
||||
good strategy for a user who only wants to call a few GeographicLib
|
||||
routines from another language.
|
||||
|
||||
Please contribute other examples, either for the languages given here or
|
||||
for other languages.
|
||||
39
libs/geographiclib/wrapper/c/CMakeLists.txt
Normal file
39
libs/geographiclib/wrapper/c/CMakeLists.txt
Normal file
@@ -0,0 +1,39 @@
|
||||
cmake_minimum_required (VERSION 3.13.0)
|
||||
project (geoidtest)
|
||||
|
||||
# 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 ()
|
||||
|
||||
# Make the compiler more picky.
|
||||
if (MSVC)
|
||||
string (REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
||||
string (REGEX REPLACE "/W[0-4]" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4")
|
||||
else ()
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra")
|
||||
endif ()
|
||||
|
||||
find_package (GeographicLib REQUIRED COMPONENTS SHARED)
|
||||
|
||||
add_executable (${PROJECT_NAME} ${PROJECT_NAME}.c cgeoid.cpp)
|
||||
target_link_libraries (${PROJECT_NAME} ${GeographicLib_LIBRARIES})
|
||||
|
||||
get_target_property (GEOGRAPHICLIB_LIB_TYPE ${GeographicLib_LIBRARIES} TYPE)
|
||||
if (GEOGRAPHICLIB_LIB_TYPE STREQUAL "SHARED_LIBRARY")
|
||||
if (WIN32)
|
||||
add_custom_command (TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E
|
||||
copy $<TARGET_FILE:${GeographicLib_LIBRARIES}> ${CMAKE_CFG_INTDIR}
|
||||
COMMENT "Installing shared library in build tree")
|
||||
else ()
|
||||
# Set the run time path for shared libraries for non-Windows machines.
|
||||
set_target_properties (${PROJECT_NAME}
|
||||
PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
endif ()
|
||||
endif ()
|
||||
52
libs/geographiclib/wrapper/c/README.md
Normal file
52
libs/geographiclib/wrapper/c/README.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# Calling the GeographicLib C++ library from C
|
||||
|
||||
The geodesic routines in GeographicLib have been implemented as a native
|
||||
C library. See
|
||||
|
||||
https://geographiclib.sourceforge.io/C/doc/
|
||||
|
||||
It is also possible to call the C++ version of GeographicLib directly
|
||||
from C and this directory contains a small example, which convert
|
||||
heights above the geoid to heights above the ellipsoid. More
|
||||
information on calling C++ from C, see
|
||||
|
||||
https://isocpp.org/wiki/faq/mixing-c-and-cpp
|
||||
|
||||
To build and install this interface, do
|
||||
```bash
|
||||
mkdir BUILD
|
||||
cd BUILD
|
||||
cmake ..
|
||||
make
|
||||
```
|
||||
This assumes that you have installed GeographicLib somewhere that cmake
|
||||
can find it. If you want just to use the version of GeographicLib that
|
||||
you have built in the top-level BUILD directory, include, e.g.,
|
||||
```bash
|
||||
-D GeographicLib_DIR=../../BUILD
|
||||
```
|
||||
|
||||
in the invocation of cmake (the directory is relative to the source
|
||||
directory, wrapper/C). To convert 20m above the geoid at 42N 75W to a
|
||||
height above the ellipsoid, use
|
||||
```bash
|
||||
$ echo 42 -75 20 | ./geoidtest
|
||||
-10.672
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
* The geoid data (`egm2008-1`) should be installed somewhere that
|
||||
GeographicLib knows about.
|
||||
|
||||
* This prescription applies to Linux machines. Similar steps can be
|
||||
used on Windows and MacOSX machines.
|
||||
|
||||
* It is essential that the application be linked with the C++ compiler,
|
||||
so that the C++ runtime library is included.
|
||||
|
||||
* In this example, the main program is compiled with the C compiler. In
|
||||
more complicated situations, it may be necessary to use the C++
|
||||
compiler. This is necessary to get static initializations of C++
|
||||
classes performed. (However, GeographicLib doesn't need any static
|
||||
initialization.)
|
||||
14
libs/geographiclib/wrapper/c/cgeoid.cpp
Normal file
14
libs/geographiclib/wrapper/c/cgeoid.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include "cgeoid.h"
|
||||
#include "GeographicLib/Geoid.hpp"
|
||||
|
||||
extern "C"
|
||||
double HeightAboveEllipsoid(double lat, double lon, double h) {
|
||||
try {
|
||||
// Declare static so that g is only constructed once
|
||||
static const GeographicLib::Geoid g("egm2008-1");
|
||||
return h + GeographicLib::Geoid::GEOIDTOELLIPSOID * g(lat, lon);
|
||||
}
|
||||
catch (...) {
|
||||
return GeographicLib::Math::NaN();
|
||||
}
|
||||
}
|
||||
9
libs/geographiclib/wrapper/c/cgeoid.h
Normal file
9
libs/geographiclib/wrapper/c/cgeoid.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#if !defined(CGEOID_H)
|
||||
#define CGEOID_H 1
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
#endif
|
||||
double HeightAboveEllipsoid(double lat, double lon, double h);
|
||||
|
||||
#endif /* CGEOID_H */
|
||||
13
libs/geographiclib/wrapper/c/geoidtest.c
Normal file
13
libs/geographiclib/wrapper/c/geoidtest.c
Normal file
@@ -0,0 +1,13 @@
|
||||
#include <stdio.h>
|
||||
#include "cgeoid.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
/* Squelch warnings about scanf */
|
||||
# pragma warning (disable: 4996)
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
double lat, lon, h;
|
||||
while(scanf("%lf %lf %lf", &lat, &lon, &h) == 3)
|
||||
printf("%.3f\n", HeightAboveEllipsoid(lat, lon, h));
|
||||
}
|
||||
53
libs/geographiclib/wrapper/excel/CMakeLists.txt
Normal file
53
libs/geographiclib/wrapper/excel/CMakeLists.txt
Normal file
@@ -0,0 +1,53 @@
|
||||
cmake_minimum_required (VERSION 3.13.0)
|
||||
project (cgeodesic)
|
||||
|
||||
# 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 ()
|
||||
|
||||
# Make the compiler more picky.
|
||||
if (MSVC)
|
||||
string (REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
||||
string (REGEX REPLACE "/W[0-4]" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4")
|
||||
else ()
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra")
|
||||
message (WARNING "This has only been tested on Windows")
|
||||
endif ()
|
||||
|
||||
find_package (GeographicLib 1.51 REQUIRED COMPONENTS SHARED)
|
||||
|
||||
set (CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
|
||||
add_library (${PROJECT_NAME} SHARED ${PROJECT_NAME}.cpp)
|
||||
target_link_libraries (${PROJECT_NAME} ${GeographicLib_LIBRARIES})
|
||||
|
||||
if (WIN32)
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set (INSTALL_MSG
|
||||
"copy DLLs fron ${CMAKE_CFG_INTDIR} to C:\\Program Files (x86)\\Microsoft Office\\root\\Office16")
|
||||
else ()
|
||||
set (INSTALL_MSG "copy DLLs from ${CMAKE_CFG_INTDIR} to C:\\Program Files\\Microsoft Office\\root\\Office16")
|
||||
endif ()
|
||||
elseif (APPLE)
|
||||
set (INSTALL_MSG "copy DYLIBs from ${CMAKE_CFG_INTDIR} to /Library/Application Support/Microsoft")
|
||||
endif ()
|
||||
|
||||
get_target_property (GEOGRAPHICLIB_LIB_TYPE ${GeographicLib_LIBRARIES} TYPE)
|
||||
if (GEOGRAPHICLIB_LIB_TYPE STREQUAL "SHARED_LIBRARY")
|
||||
if (TRUE)
|
||||
add_custom_command (TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E
|
||||
copy $<TARGET_FILE:${GeographicLib_LIBRARIES}> ${CMAKE_CFG_INTDIR}
|
||||
COMMENT "Installing shared library in build tree
|
||||
${INSTALL_MSG}")
|
||||
else ()
|
||||
# Set the run time path for shared libraries for non-Windows machines.
|
||||
set_target_properties (${PROJECT_NAME}
|
||||
PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
endif ()
|
||||
endif ()
|
||||
132
libs/geographiclib/wrapper/excel/Geodesic.bas
Normal file
132
libs/geographiclib/wrapper/excel/Geodesic.bas
Normal file
@@ -0,0 +1,132 @@
|
||||
Attribute VB_Name = "Geodesic"
|
||||
Option Explicit
|
||||
|
||||
' Declare the DLL functions
|
||||
|
||||
Private Declare PtrSafe Sub gdirect Lib "cgeodesic.dll" _
|
||||
(ByVal lat1 As Double, ByVal lon1 As Double, _
|
||||
ByVal azi1 As Double, ByVal s12 As Double, _
|
||||
ByRef lat2 As Double, ByRef lon2 As Double, ByRef azi2 As Double)
|
||||
|
||||
Private Declare PtrSafe Sub ginverse Lib "cgeodesic.dll" _
|
||||
(ByVal lat1 As Double, ByVal lon1 As Double, _
|
||||
ByVal lat2 As Double, ByVal lon2 As Double, _
|
||||
ByRef s12 As Double, ByRef azi1 As Double, ByRef azi2 As Double)
|
||||
|
||||
Private Declare PtrSafe Sub rdirect Lib "cgeodesic.dll" _
|
||||
(ByVal lat1 As Double, ByVal lon1 As Double, _
|
||||
ByVal azi12 As Double, ByVal s12 As Double, _
|
||||
ByRef lat2 As Double, ByRef lon2 As Double)
|
||||
|
||||
Private Declare PtrSafe Sub rinverse Lib "cgeodesic.dll" _
|
||||
(ByVal lat1 As Double, ByVal lon1 As Double, _
|
||||
ByVal lat2 As Double, ByVal lon2 As Double, _
|
||||
ByRef s12 As Double, ByRef azi12 As Double)
|
||||
|
||||
' Define the custom worksheet functions that call the DLL functions
|
||||
|
||||
Function geodesic_direct_lat2(lat1 As Double, lon1 As Double, _
|
||||
azi1 As Double, s12 As Double) As Double
|
||||
Attribute geodesic_direct_lat2.VB_Description = _
|
||||
"Solves direct geodesic problem for lat2."
|
||||
Dim lat2 As Double
|
||||
Dim lon2 As Double
|
||||
Dim azi2 As Double
|
||||
Call gdirect(lat1, lon1, azi1, s12, lat2, lon2, azi2)
|
||||
geodesic_direct_lat2 = lat2
|
||||
End Function
|
||||
|
||||
Function geodesic_direct_lon2(lat1 As Double, lon1 As Double, _
|
||||
azi1 As Double, s12 As Double) As Double
|
||||
Attribute geodesic_direct_lon2.VB_Description = _
|
||||
"Solves direct geodesic problem for lon2."
|
||||
Dim lat2 As Double
|
||||
Dim lon2 As Double
|
||||
Dim azi2 As Double
|
||||
Call gdirect(lat1, lon1, azi1, s12, lat2, lon2, azi2)
|
||||
geodesic_direct_lon2 = lon2
|
||||
End Function
|
||||
|
||||
Function geodesic_direct_azi2(lat1 As Double, lon1 As Double, _
|
||||
azi1 As Double, s12 As Double) As Double
|
||||
Attribute geodesic_direct_azi2.VB_Description = _
|
||||
"Solves direct geodesic problem for azi2."
|
||||
Dim lat2 As Double
|
||||
Dim lon2 As Double
|
||||
Dim azi2 As Double
|
||||
Call gdirect(lat1, lon1, azi1, s12, lat2, lon2, azi2)
|
||||
geodesic_direct_azi2 = azi2
|
||||
End Function
|
||||
|
||||
Function geodesic_inverse_s12(lat1 As Double, lon1 As Double, _
|
||||
lat2 As Double, lon2 As Double) As Double
|
||||
Attribute geodesic_inverse_s12.VB_Description = _
|
||||
"Solves inverse geodesic problem for s12."
|
||||
Dim s12 As Double
|
||||
Dim azi1 As Double
|
||||
Dim azi2 As Double
|
||||
Call ginverse(lat1, lon1, lat2, lon2, s12, azi1, azi2)
|
||||
geodesic_inverse_s12 = s12
|
||||
End Function
|
||||
|
||||
Function geodesic_inverse_azi1(lat1 As Double, lon1 As Double, _
|
||||
lat2 As Double, lon2 As Double) As Double
|
||||
Attribute geodesic_inverse_azi1.VB_Description = _
|
||||
"Solves inverse geodesic problem for azi1."
|
||||
Dim s12 As Double
|
||||
Dim azi1 As Double
|
||||
Dim azi2 As Double
|
||||
Call ginverse(lat1, lon1, lat2, lon2, s12, azi1, azi2)
|
||||
geodesic_inverse_azi1 = azi1
|
||||
End Function
|
||||
|
||||
Function geodesic_inverse_azi2(lat1 As Double, lon1 As Double, _
|
||||
lat2 As Double, lon2 As Double) As Double
|
||||
Attribute geodesic_inverse_azi2.VB_Description = _
|
||||
"Solves inverse geodesic problem for azi2."
|
||||
Dim s12 As Double
|
||||
Dim azi1 As Double
|
||||
Dim azi2 As Double
|
||||
Call ginverse(lat1, lon1, lat2, lon2, s12, azi1, azi2)
|
||||
geodesic_inverse_azi2 = azi2
|
||||
End Function
|
||||
|
||||
Function rhumb_direct_lat2(lat1 As Double, lon1 As Double, _
|
||||
azi12 As Double, s12 As Double) As Double
|
||||
Attribute rhumb_direct_lat2.VB_Description = _
|
||||
"Solves direct rhumb problem for lat2."
|
||||
Dim lat2 As Double
|
||||
Dim lon2 As Double
|
||||
Call rdirect(lat1, lon1, azi12, s12, lat2, lon2)
|
||||
rhumb_direct_lat2 = lat2
|
||||
End Function
|
||||
|
||||
Function rhumb_direct_lon2(lat1 As Double, lon1 As Double, _
|
||||
azi12 As Double, s12 As Double) As Double
|
||||
Attribute rhumb_direct_lon2.VB_Description = _
|
||||
"Solves direct rhumb problem for lon2."
|
||||
Dim lat2 As Double
|
||||
Dim lon2 As Double
|
||||
Call rdirect(lat1, lon1, azi12, s12, lat2, lon2)
|
||||
rhumb_direct_lon2 = lon2
|
||||
End Function
|
||||
|
||||
Function rhumb_inverse_s12(lat1 As Double, lon1 As Double, _
|
||||
lat2 As Double, lon2 As Double) As Double
|
||||
Attribute rhumb_inverse_s12.VB_Description = _
|
||||
"Solves inverse rhumb problem for s12."
|
||||
Dim s12 As Double
|
||||
Dim azi12 As Double
|
||||
Call rinverse(lat1, lon1, lat2, lon2, s12, azi12)
|
||||
rhumb_inverse_s12 = s12
|
||||
End Function
|
||||
|
||||
Function rhumb_inverse_azi12(lat1 As Double, lon1 As Double, _
|
||||
lat2 As Double, lon2 As Double) As Double
|
||||
Attribute rhumb_inverse_azi12.VB_Description = _
|
||||
"Solves inverse rhumb problem for azi12."
|
||||
Dim s12 As Double
|
||||
Dim azi12 As Double
|
||||
Call rinverse(lat1, lon1, lat2, lon2, s12, azi12)
|
||||
rhumb_inverse_azi12 = azi12
|
||||
End Function
|
||||
94
libs/geographiclib/wrapper/excel/README.md
Normal file
94
libs/geographiclib/wrapper/excel/README.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# Calling the GeographicLib C++ library from Excel
|
||||
|
||||
You can call GeographicLib functions from Excel. Thanks to Thomas
|
||||
Warner <warnerta@gmail.com>, for showing me how. This prescription
|
||||
has only been tested for Excel running on a Windows machine. Please
|
||||
let me know if you figure out how to get this working on MacOS
|
||||
versions of Excel.
|
||||
|
||||
Here's the overview
|
||||
|
||||
* Write and compile little interface routines to invoke the
|
||||
functionality you want.
|
||||
|
||||
* Copy the resulting DLLs to where Excel can find them.
|
||||
|
||||
* Write an interface script in Visual Basic. This tells Visual Basic
|
||||
about your interfrace routines and it includes definitions of the actual
|
||||
functions you will see exposed in Excel.
|
||||
|
||||
Here are the step-by-step instructions for compiling and using the
|
||||
sample routines given here (which solve the direct and inverse geodesic
|
||||
problems and the corresponding rhumb line problems):
|
||||
|
||||
1. Install binary distribution for GeographicLib (either 64-bit or
|
||||
32-bit to match your version of Excel).
|
||||
|
||||
2. Install a recent version of cmake.
|
||||
|
||||
3. Start a command prompt window and run
|
||||
```bash
|
||||
mkdir BUILD
|
||||
cd BUILD
|
||||
cmake -G "Visual Studio 16" -A x64 ..
|
||||
```
|
||||
This configures your build. Any of Visual Studio 14, 15, or 16
|
||||
(corresponding the VS 2015, 2017, 2019) will work. If your Excel is
|
||||
32-bit, change `-A x64` to `-A win32`. If necessary include `-D
|
||||
CMAKE_PREFIX_PATH=DIR` to specify where GeographicLib is installed
|
||||
(specified when you ran the GeographicLib installer). Compile the
|
||||
interface with
|
||||
```bash
|
||||
cmake --build . --config Release
|
||||
```
|
||||
|
||||
4. Copy
|
||||
```bash
|
||||
Release\cgeodesic.dll # the interface routines
|
||||
Release\GeographicLib.dll # the main GeographicLib library
|
||||
```
|
||||
to the directory where the Excel executable lives. You can find this
|
||||
directory by launching Excel, launching Task Manager, right-clicking on
|
||||
Excel within Task Manager and selecting Open file location. It's
|
||||
probably something like
|
||||
```bash
|
||||
C:\Program Files\Microsoft Office\root\Office16
|
||||
```
|
||||
and you will probably need administrator privileges to do the copy.
|
||||
If it's in `Program Files (x86)`, then you have a 32-bit version of
|
||||
Excel and you need to compile your interface routines in 32-bit by
|
||||
specitying `-A win32` when you first run cmake.
|
||||
|
||||
5. Open the Excel workbook within which you would like to use the
|
||||
geodesic and rhumb routines.<br>
|
||||
Type `Alt-F11` to open Excel's Visual Basic editor.<br>
|
||||
In the left sidebar, right-click on `VBAProject (%yourworksheetname%)`
|
||||
and select Import File<br>
|
||||
Browse to `Geodesic.bas`, select it and click Open<br>
|
||||
Save your Workbook as Excel Macro-Enabled Workbook (`*.xlsm`)
|
||||
|
||||
6. You will now have 10 new functions available:
|
||||
* Solve the direct geodesic problem for
|
||||
```
|
||||
lat2: geodesic_direct_lat2(lat1, lon1, azi1, s12)
|
||||
lon2: geodesic_direct_lon2(lat1, lon1, azi1, s12)
|
||||
azi2: geodesic_direct_azi2(lat1, lon1, azi1, s12)
|
||||
```
|
||||
* Solve the inverse geodesic problem for
|
||||
```
|
||||
s12: geodesic_inverse_s12(lat1, lon1, lat2, lon2)
|
||||
azi1: geodesic_inverse_azi1(lat1, lon1, lat2, lon2)
|
||||
azi2: geodesic_inverse_azi2(lat1, lon1, lat2, lon2)
|
||||
```
|
||||
* Solve the direct rhumb problem for
|
||||
```
|
||||
lat2: rhumb_direct_lat2(lat1, lon1, azi12, s12)
|
||||
lon2: rhumb_direct_lon2(lat1, lon1, azi12, s12)
|
||||
```
|
||||
* Solve the inverse rhumb problem for
|
||||
```
|
||||
s12: rhumb_inverse_s12(lat1, lon1, lat2, lon2)
|
||||
azi12: rhumb_inverse_azi12(lat1, lon1, lat2, lon2)
|
||||
```
|
||||
Latitudes, longitudes, and azimuths are in degrees. Distances are
|
||||
in meters.
|
||||
31
libs/geographiclib/wrapper/excel/cgeodesic.cpp
Normal file
31
libs/geographiclib/wrapper/excel/cgeodesic.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "cgeodesic.h"
|
||||
#include "GeographicLib/Geodesic.hpp"
|
||||
#include "GeographicLib/Rhumb.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
void gdirect(double lat1, double lon1, double azi1, double s12,
|
||||
double& lat2, double& lon2, double& azi2) {
|
||||
GeographicLib::Geodesic::WGS84().Direct(lat1, lon1, azi1, s12,
|
||||
lat2, lon2, azi2);
|
||||
}
|
||||
|
||||
void ginverse(double lat1, double lon1, double lat2, double lon2,
|
||||
double& s12, double& azi1, double& azi2) {
|
||||
GeographicLib::Geodesic::WGS84().Inverse(lat1, lon1, lat2, lon2,
|
||||
s12, azi1, azi2);
|
||||
}
|
||||
|
||||
void rdirect(double lat1, double lon1, double azi12, double s12,
|
||||
double& lat2, double& lon2) {
|
||||
GeographicLib::Rhumb::WGS84().Direct(lat1, lon1, azi12, s12,
|
||||
lat2, lon2);
|
||||
}
|
||||
|
||||
void rinverse(double lat1, double lon1, double lat2, double lon2,
|
||||
double& s12, double& azi12) {
|
||||
GeographicLib::Rhumb::WGS84().Inverse(lat1, lon1, lat2, lon2,
|
||||
s12, azi12);
|
||||
}
|
||||
|
||||
}
|
||||
24
libs/geographiclib/wrapper/excel/cgeodesic.h
Normal file
24
libs/geographiclib/wrapper/excel/cgeodesic.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#if !defined(CGEODESIC_H)
|
||||
#define CGEODESIC_H 1
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void gdirect(double lat1, double lon1, double azi1, double s12,
|
||||
double& lat2, double& lon2, double& azi2);
|
||||
|
||||
void ginverse(double lat1, double lon1, double lat2, double lon2,
|
||||
double& s12, double& azi1, double& azi2);
|
||||
|
||||
void rdirect(double lat1, double lon1, double azi12, double s12,
|
||||
double& lat2, double& lon2);
|
||||
|
||||
void rinverse(double lat1, double lon1, double lat2, double lon2,
|
||||
double& s12, double& azi12);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CGEODESIC_H */
|
||||
18
libs/geographiclib/wrapper/javascript/README.md
Normal file
18
libs/geographiclib/wrapper/javascript/README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Calling the GeographicLib C++ library from JavaScript
|
||||
|
||||
The geodesic routines in GeographicLib have been implemented in
|
||||
JavaScript package
|
||||
[geographiclib-geodesic](https://www.npmjs.com/package/geographiclib-geodesic).
|
||||
For documentation, see
|
||||
|
||||
https://geographiclib.sourceforge.io/JavaScript/doc
|
||||
|
||||
William Wall <wallw@users.sourceforge.net> has posted a method of
|
||||
automatically translating the C++ code into JavaScript
|
||||
|
||||
https://sourceforge.net/p/geographiclib/discussion/1026620/thread/f6f6b9ff/
|
||||
|
||||
This will let you use other capabilities of GeographicLib in JavaScript.
|
||||
|
||||
This is implemented in [OpenSphere
|
||||
ASM](https://github.com/ngageoint/opensphere-asm).
|
||||
4
libs/geographiclib/wrapper/octave/.gitignore
vendored
Normal file
4
libs/geographiclib/wrapper/octave/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
*.mexw32
|
||||
*.mex
|
||||
*.mexa64
|
||||
*.mexmaci64
|
||||
49
libs/geographiclib/wrapper/octave/README.md
Normal file
49
libs/geographiclib/wrapper/octave/README.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Calling GeographicLib C++ library from Octave/MATLAB
|
||||
|
||||
The Octave/MATLAB package
|
||||
[geographiclib](https://github.com/geographiclib/geographiclib-octave#readme)
|
||||
provides a native Octave/MATLAB implementation of a subset of
|
||||
GeographicLib. This is also available via the MATLAB Central Package
|
||||
[geographiclib](https://www.mathworks.com/matlabcentral/fileexchange/50605)
|
||||
|
||||
It is also possible to call the C++ GeographicLib library directly
|
||||
from Octave and MATLAB. This gives you access to the full range of
|
||||
GeographicLib's capabilities.
|
||||
|
||||
In order to make use of this facility, it is necessary to write some
|
||||
interface code. The files in this directory provide a sample of such
|
||||
interface code. This example solves the inverse geodesic problem for
|
||||
ellipsoids with arbitrary flattening. (The code `geoddistance.m` does
|
||||
this as native Matlab code; but it is limited to ellipsoids with a
|
||||
smaller flattening.)
|
||||
|
||||
For full details on how to write the interface code, see
|
||||
|
||||
https://www.mathworks.com/help/matlab/write-cc-mex-files.html
|
||||
|
||||
To compile the interface code, start Octave or MATLAB and run, e.g.,
|
||||
```Octave
|
||||
mex -setup C++
|
||||
help geographiclibinterface
|
||||
geographiclibinterface
|
||||
help geodesicinverse
|
||||
geodesicinverse([40.6, -73.8, 51.6, -0.5])
|
||||
ans =
|
||||
|
||||
5.1199e+01 1.0782e+02 5.5518e+06
|
||||
```
|
||||
|
||||
The first command allows you to select the compiler to use (which should
|
||||
be the same as that used to compile GeographicLib).
|
||||
|
||||
These routines just offer a simple interface to the corresponding C++
|
||||
class. Use the help function to get documentation,
|
||||
```Octave
|
||||
help geodesicinverse
|
||||
```
|
||||
|
||||
Unfortunately, the help function does not work for compiled functions in
|
||||
Octave; in this case, just list the .m file, e.g.,
|
||||
```Octave
|
||||
type geodesicinverse.m
|
||||
```
|
||||
116
libs/geographiclib/wrapper/octave/geodesicinverse.cpp
Normal file
116
libs/geographiclib/wrapper/octave/geodesicinverse.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* \file geodesicinverse.cpp
|
||||
* \brief Matlab mex file for geographic to UTM/UPS conversions
|
||||
*
|
||||
* Copyright (c) Charles Karney (2010-2013) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* https://geographiclib.sourceforge.io/
|
||||
**********************************************************************/
|
||||
|
||||
// Compile in Matlab with
|
||||
// [Unix]
|
||||
// mex -I/usr/local/include -L/usr/local/lib -Wl,-rpath=/usr/local/lib
|
||||
// -lGeographicLib geodesicinverse.cpp
|
||||
// [Windows]
|
||||
// mex -I../include -L../windows/Release
|
||||
// -lGeographicLib geodesicinverse.cpp
|
||||
|
||||
#include <algorithm>
|
||||
#include <GeographicLib/Geodesic.hpp>
|
||||
#include <GeographicLib/GeodesicExact.hpp>
|
||||
#include <mex.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
template<class G> void
|
||||
compute(double a, double f, mwSize m, const double* latlong,
|
||||
double* geodesic, double* aux) {
|
||||
const double* lat1 = latlong;
|
||||
const double* lon1 = latlong + m;
|
||||
const double* lat2 = latlong + 2*m;
|
||||
const double* lon2 = latlong + 3*m;
|
||||
double* azi1 = geodesic;
|
||||
double* azi2 = geodesic + m;
|
||||
double* s12 = geodesic + 2*m;
|
||||
double* a12 = NULL;
|
||||
double* m12 = NULL;
|
||||
double* M12 = NULL;
|
||||
double* M21 = NULL;
|
||||
double* S12 = NULL;
|
||||
if (aux) {
|
||||
a12 = aux;
|
||||
m12 = aux + m;
|
||||
M12 = aux + 2*m;
|
||||
M21 = aux + 3*m;
|
||||
S12 = aux + 4*m;
|
||||
}
|
||||
|
||||
const G g(a, f);
|
||||
for (mwIndex i = 0; i < m; ++i) {
|
||||
if (abs(lat1[i]) <= 90 && lon1[i] >= -540 && lon1[i] < 540 &&
|
||||
abs(lat2[i]) <= 90 && lon2[i] >= -540 && lon2[i] < 540) {
|
||||
if (aux)
|
||||
a12[i] = g.Inverse(lat1[i], lon1[i], lat2[i], lon2[i],
|
||||
s12[i], azi1[i], azi2[i],
|
||||
m12[i], M12[i], M21[i], S12[i]);
|
||||
else
|
||||
g.Inverse(lat1[i], lon1[i], lat2[i], lon2[i],
|
||||
s12[i], azi1[i], azi2[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mexFunction( int nlhs, mxArray* plhs[],
|
||||
int nrhs, const mxArray* prhs[] ) {
|
||||
|
||||
if (nrhs < 1)
|
||||
mexErrMsgTxt("One input argument required.");
|
||||
else if (nrhs > 3)
|
||||
mexErrMsgTxt("More than three input arguments specified.");
|
||||
else if (nrhs == 2)
|
||||
mexErrMsgTxt("Must specify flattening with the equatorial radius.");
|
||||
else if (nlhs > 2)
|
||||
mexErrMsgTxt("More than two output arguments specified.");
|
||||
|
||||
if (!( mxIsDouble(prhs[0]) && !mxIsComplex(prhs[0]) ))
|
||||
mexErrMsgTxt("latlong coordinates are not of type double.");
|
||||
|
||||
if (mxGetN(prhs[0]) != 4)
|
||||
mexErrMsgTxt("latlong coordinates must be M x 4 matrix.");
|
||||
|
||||
double a = Constants::WGS84_a<double>(), f = Constants::WGS84_f<double>();
|
||||
if (nrhs == 3) {
|
||||
if (!( mxIsDouble(prhs[1]) && !mxIsComplex(prhs[1]) &&
|
||||
mxGetNumberOfElements(prhs[1]) == 1 ))
|
||||
mexErrMsgTxt("Equatorial radius is not a real scalar.");
|
||||
a = mxGetScalar(prhs[1]);
|
||||
if (!( mxIsDouble(prhs[2]) && !mxIsComplex(prhs[2]) &&
|
||||
mxGetNumberOfElements(prhs[2]) == 1 ))
|
||||
mexErrMsgTxt("Flattening is not a real scalar.");
|
||||
f = mxGetScalar(prhs[2]);
|
||||
}
|
||||
|
||||
mwSize m = mxGetM(prhs[0]);
|
||||
|
||||
const double* latlong = mxGetPr(prhs[0]);
|
||||
|
||||
double* geodesic = mxGetPr(plhs[0] = mxCreateDoubleMatrix(m, 3, mxREAL));
|
||||
std::fill(geodesic, geodesic + 3*m, Math::NaN<double>());
|
||||
|
||||
double* aux =
|
||||
nlhs == 2 ? mxGetPr(plhs[1] = mxCreateDoubleMatrix(m, 5, mxREAL)) :
|
||||
NULL;
|
||||
if (aux)
|
||||
std::fill(aux, aux + 5*m, Math::NaN<double>());
|
||||
|
||||
try {
|
||||
if (std::abs(f) <= 0.02)
|
||||
compute<Geodesic>(a, f, m, latlong, geodesic, aux);
|
||||
else
|
||||
compute<GeodesicExact>(a, f, m, latlong, geodesic, aux);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
mexErrMsgTxt(e.what());
|
||||
}
|
||||
}
|
||||
33
libs/geographiclib/wrapper/octave/geodesicinverse.m
Normal file
33
libs/geographiclib/wrapper/octave/geodesicinverse.m
Normal file
@@ -0,0 +1,33 @@
|
||||
function geodesicinverse(~, ~, ~)
|
||||
%geodesicinverse Solve inverse geodesic problem
|
||||
%
|
||||
% [geodesic, aux] = geodesicinverse(latlong)
|
||||
% [geodesic, aux] = geodesicinverse(latlong, a, f)
|
||||
%
|
||||
% latlong is an M x 4 matrix
|
||||
% latitude of point 1 = latlong(:,1) in degrees
|
||||
% longitude of point 1 = latlong(:,2) in degrees
|
||||
% latitude of point 2 = latlong(:,3) in degrees
|
||||
% longitude of point 2 = latlong(:,4) in degrees
|
||||
%
|
||||
% geodesic is an M x 3 matrix
|
||||
% azimuth at point 1 = geodesic(:,1) in degrees
|
||||
% azimuth at point 2 = geodesic(:,2) in degrees
|
||||
% distance between points 1 and 2 = geodesic(:,3) in meters
|
||||
% aux is an M x 5 matrix
|
||||
% spherical arc length = aux(:,1) in degrees
|
||||
% reduced length = aux(:,2) in meters
|
||||
% geodesic scale 1 to 2 = aux(:,3)
|
||||
% geodesic scale 2 to 1 = aux(:,4)
|
||||
% area under geodesic = aux(:,5) in meters^2
|
||||
%
|
||||
% a = equatorial radius (meters)
|
||||
% f = flattening (0 means a sphere)
|
||||
% If a and f are omitted, the WGS84 values are used.
|
||||
%
|
||||
% A native MATLAB implementation is available as GEODDISTANCE.
|
||||
%
|
||||
% See also GEODDISTANCE.
|
||||
|
||||
error('Error: executing .m file instead of compiled routine');
|
||||
end
|
||||
63
libs/geographiclib/wrapper/octave/geographiclibinterface.m
Normal file
63
libs/geographiclib/wrapper/octave/geographiclibinterface.m
Normal file
@@ -0,0 +1,63 @@
|
||||
function geographiclibinterface(incdir, libdir)
|
||||
% geographiclibinterface Use mex to compile interface to GeographicLib
|
||||
%
|
||||
% geographiclibinterface
|
||||
% geographiclibinterface(INSTALLDIR)
|
||||
% geographiclibinterface(INCDIR, LIBDIR)
|
||||
%
|
||||
% With one argument the library is looked for in INSTALLDIR/lib and the
|
||||
% include files in INSTALLDIR/include.
|
||||
%
|
||||
% With no arguments, INSTALLDIR is taked to be '/usr/local', on Unix and
|
||||
% Linux systems, and 'C:/Program Files/GeographicLib', on Windows systems
|
||||
%
|
||||
% With two arguments, the library is looked for in LIBDIR and the include
|
||||
% files in INCDIR.
|
||||
%
|
||||
% This has been tested with
|
||||
%
|
||||
% Octave 3.2.3 and g++ 4.4.4 under Linux
|
||||
% Octave 3.6.4 and g++ 4.8.3 under Linux
|
||||
% Matlab 2007a and Visual Studio 2005 under Windows
|
||||
% Matlab 2008a and Visual Studio 2005 under Windows
|
||||
% Matlab 2008a and Visual Studio 2008 under Windows
|
||||
% Matlab 2010b and Visual Studio 2005 under Windows
|
||||
% Matlab 2010b and Visual Studio 2008 under Windows
|
||||
% Matlab 2010b and Visual Studio 2010 under Windows
|
||||
% Matlab 2013b and Visual Studio 2012 under Windows
|
||||
% Matlab 2014b and Mac OSX 10.10 (Yosemite)
|
||||
%
|
||||
% Run 'mex -setup' to configure the C++ compiler for Matlab to use.
|
||||
|
||||
funs = { 'geodesicinverse' };
|
||||
lib='GeographicLib';
|
||||
if (nargin < 2)
|
||||
if (nargin == 0)
|
||||
if ispc
|
||||
installdir = 'C:/Program Files/GeographicLib';
|
||||
else
|
||||
installdir = '/usr/local';
|
||||
end
|
||||
else
|
||||
installdir = incdir;
|
||||
end
|
||||
incdir=[installdir '/include'];
|
||||
libdir=[installdir '/lib'];
|
||||
end
|
||||
testheader = [incdir '/GeographicLib/Constants.hpp'];
|
||||
if (~ exist(testheader, 'file'))
|
||||
error(['Cannot find ' testheader]);
|
||||
end
|
||||
fprintf('Compiling Matlab interface to GeographicLib\n');
|
||||
fprintf('Include directory: %s\nLibrary directory: %s\n', incdir, libdir);
|
||||
for i = 1:size(funs,2)
|
||||
fprintf('Compiling %s...', funs{i});
|
||||
if ispc || ismac
|
||||
mex( ['-I' incdir], ['-L' libdir], ['-l' lib], [funs{i} '.cpp'] );
|
||||
else
|
||||
mex( ['-I' incdir], ['-L' libdir], ['-l' lib], ...
|
||||
['-Wl,-rpath=' libdir], [funs{i} '.cpp'] );
|
||||
end
|
||||
fprintf(' done.\n');
|
||||
end
|
||||
end
|
||||
57
libs/geographiclib/wrapper/python/CMakeLists.txt
Normal file
57
libs/geographiclib/wrapper/python/CMakeLists.txt
Normal file
@@ -0,0 +1,57 @@
|
||||
cmake_minimum_required (VERSION 3.13.0)
|
||||
project (PyGeographicLib)
|
||||
|
||||
# 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 ()
|
||||
|
||||
# Make the compiler more picky.
|
||||
if (MSVC)
|
||||
string (REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
||||
else ()
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
|
||||
endif ()
|
||||
|
||||
# The version of python that boost-python uses. Also used for the
|
||||
# installation directory.
|
||||
set (PYTHON_VERSION 2.7)
|
||||
|
||||
# Requires python + python devel
|
||||
find_package (PythonLibs ${PYTHON_VERSION} REQUIRED)
|
||||
|
||||
# Required boost-python + boost-devel
|
||||
find_package (Boost REQUIRED COMPONENTS python)
|
||||
|
||||
find_package (GeographicLib REQUIRED COMPONENTS SHARED)
|
||||
|
||||
include_directories (${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS})
|
||||
|
||||
add_library (${PROJECT_NAME} MODULE ${PROJECT_NAME}.cpp)
|
||||
|
||||
get_target_property (GEOGRAPHICLIB_LIB_TYPE ${GeographicLib_LIBRARIES} TYPE)
|
||||
if (GEOGRAPHICLIB_LIB_TYPE STREQUAL "SHARED_LIBRARY")
|
||||
if (WIN32)
|
||||
add_custom_command (TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E
|
||||
copy $<TARGET_FILE:${GeographicLib_LIBRARIES}> ${CMAKE_CFG_INTDIR}
|
||||
COMMENT "Installing shared library in build tree")
|
||||
else ()
|
||||
# Set the run time path for shared libraries for non-Windows machines.
|
||||
set_target_properties (${PROJECT_NAME}
|
||||
PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# Don't include the "lib" prefix on the output name
|
||||
set_target_properties (${PROJECT_NAME} PROPERTIES PREFIX "")
|
||||
target_link_libraries (${PROJECT_NAME} ${GeographicLib_LIBRARIES}
|
||||
${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
|
||||
|
||||
install (TARGETS ${PROJECT_NAME} LIBRARY
|
||||
# if CMAKE_INSTALL_PREFIX=~/.local then this specifies a directory in
|
||||
# the default path.
|
||||
DESTINATION lib/python${PYTHON_VERSION}/site-packages)
|
||||
21
libs/geographiclib/wrapper/python/PyGeographicLib.cpp
Normal file
21
libs/geographiclib/wrapper/python/PyGeographicLib.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#include <boost/python.hpp>
|
||||
#include <GeographicLib/Geoid.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace GeographicLib;
|
||||
|
||||
double EllipsoidHeight(Geoid& geoid,
|
||||
double lat, double lon, double hmsl) {
|
||||
return hmsl + Geoid::GEOIDTOELLIPSOID * geoid(lat, lon);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(PyGeographicLib) {
|
||||
|
||||
class_<Geoid, boost::noncopyable>("Geoid", init<std::string>())
|
||||
.def("EllipsoidHeight", &EllipsoidHeight,
|
||||
"Return geoid height:\n\
|
||||
input: lat, lon, height_above_geoid\n\
|
||||
output: height_above_ellipsoid")
|
||||
;
|
||||
|
||||
}
|
||||
85
libs/geographiclib/wrapper/python/README.md
Normal file
85
libs/geographiclib/wrapper/python/README.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# Calling the GeographicLib C++ library from Python
|
||||
|
||||
The geodesic routines in GeographicLib have been implemented as a
|
||||
[native Python library](http://pypi.python.org/pypi/geographiclib).
|
||||
For documentation see
|
||||
|
||||
https://geographiclib.sourceforge.io/Python/doc/
|
||||
|
||||
## boost-python
|
||||
|
||||
It is also possible to call the C++ version of GeographicLib directly
|
||||
from Python and this directory contains a small example,
|
||||
`PyGeographicLib.cpp`, which uses boost-python and the `Geoid` class to
|
||||
convert heights above the geoid to heights above the ellipsoid. More
|
||||
information on calling boost-python, see
|
||||
|
||||
https://www.boost.org/doc/libs/release/libs/python
|
||||
|
||||
To build and install this interface, do
|
||||
```bash
|
||||
mkdir BUILD
|
||||
cd BUILD
|
||||
cmake -D CMAKE_INSTALL_PREFIX=~/.local ..
|
||||
make
|
||||
make install
|
||||
```
|
||||
This assumes that you have installed GeographicLib somewhere that cmake
|
||||
can find it. If you want just to use the version of GeographicLib that
|
||||
you have built in the top-level BUILD directory, include, e.g.,
|
||||
```bash
|
||||
-D GeographicLib_DIR=../../BUILD
|
||||
```
|
||||
in the invocation of cmake (the directory is relative to the source
|
||||
directory, wrapper/python).
|
||||
|
||||
`make install` installs PyGeographicLib in
|
||||
```
|
||||
~/.local/lib/python2.7/site-packages
|
||||
```
|
||||
which is in the default search path for python 2.7. To convert 20m
|
||||
above the geoid at 42N 75W to a height above the ellipsoid, do
|
||||
```python
|
||||
$ python
|
||||
>>> from PyGeographicLib import Geoid
|
||||
>>> geoid = Geoid("egm2008-1")
|
||||
>>> geoid.EllipsoidHeight(42, -75, 20)
|
||||
-10.671887499999997
|
||||
>>> help(Geoid.EllipsoidHeight)
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
* The geoid data (`egm2008-1`) should be installed somewhere that
|
||||
GeographicLib knows about.
|
||||
|
||||
* This prescription applies to Linux machines. Similar steps can be
|
||||
used on Windows and MacOSX machines.
|
||||
|
||||
* You will need the packages boost-python, boost-devel, python, and
|
||||
python-devel installed.
|
||||
|
||||
* `CMakeLists.txt` specifies the version of python to look for (version
|
||||
2.7). This must match that used in boost-python. To check do, e.g.,
|
||||
```bash
|
||||
ldd /usr/lib64/libboost_python.so
|
||||
```
|
||||
|
||||
* `CMakeLists.txt` looks for a shared-library version of GeographicLib.
|
||||
This is the default with cmake build on non-Windows platforms. On
|
||||
Windows, use the cmake option `-D BUILD_SHARED_LIBS=ON` to specify
|
||||
building a shared library.
|
||||
|
||||
Acknowledgment:
|
||||
|
||||
Thanks to Jonathan Takahashi <jtakahashi@gmail.com> for the sample code
|
||||
in PyGeographicLib.cpp and the commands needed to compile and link this.
|
||||
|
||||
## Cython
|
||||
|
||||
An alternative to boost-python is provided by [Cython](https::/cython.org).
|
||||
Sergey Serebryakov offers the github project
|
||||
|
||||
https://github.com/megaserg/geographiclib-cython-bindings
|
||||
|
||||
which provides a fast python interface to the geodesic routines.
|
||||
Reference in New Issue
Block a user