ADD: new track message, Entity class and Position class

This commit is contained in:
Henry Winkel
2022-12-20 17:20:35 +01:00
parent 469ecfb099
commit 98ebb563a8
2114 changed files with 482360 additions and 24 deletions

View File

@@ -0,0 +1,4 @@
*.mexw32
*.mex
*.mexa64
*.mexmaci64

View 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
```

View 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());
}
}

View 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

View 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