新增通视分析函数;新增第三方库地理距离计算库Erkir,利用该库封装了两个距离函数.
parent
cb3a310221
commit
fa6b6d00a4
Binary file not shown.
Binary file not shown.
@ -0,0 +1,62 @@
|
||||
|
||||
#include "geospatialanalysis.h"
|
||||
#include <QMessageBox>
|
||||
|
||||
GeoSpatialAnalysis::GeoSpatialAnalysis()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*@brief 两点间的可视性
|
||||
* @param pntView 观察点
|
||||
* @param pntObject 目标点
|
||||
*/
|
||||
UG3DAnalyst::SingleResult *GeoSpatialAnalysis::DoublePointVisibility(QMapControl* pMapControl,UGPoint2D pntView, UGPoint2D pntObject)
|
||||
{
|
||||
//通过下面的方法首先判断点所在的位置是否存在高程数据;
|
||||
UGDatasetRasterPtr viewPtDataset = pMapControl->getDemDataSet(pntView);
|
||||
UGDatasetRasterPtr objectPtDataset = pMapControl->getDemDataSet(pntObject);
|
||||
|
||||
if(viewPtDataset == NULL || objectPtDataset == NULL)
|
||||
{
|
||||
QMessageBox::about(NULL,"提示","无高程数据 ");
|
||||
return NULL;//-1
|
||||
}
|
||||
|
||||
if(viewPtDataset != objectPtDataset)
|
||||
{
|
||||
QMessageBox::about(NULL,"提示","观测点与被观测点不属于同一个高程数据集 ");
|
||||
return NULL;//-1
|
||||
}
|
||||
|
||||
UGDatasetRasterPtr datasetRaster = viewPtDataset;
|
||||
|
||||
//3D分析分析实例对象
|
||||
UG3DAnalyst visAnalsyt;
|
||||
UGPoint3D pntView3D,pntObject3D;
|
||||
|
||||
//高程值需根据x,y查询数据集得到
|
||||
//得到当前测量点的高程值
|
||||
// 1.首先将坐标点转换为栅格数据集对应的行和列
|
||||
UGPoint pntviewImg;
|
||||
double altitude;
|
||||
datasetRaster->XYToImg(pntView,pntviewImg);
|
||||
altitude = datasetRaster->GetValue(pntviewImg.x,pntviewImg.y);
|
||||
pntView3D.x = pntView.x;
|
||||
pntView3D.y = pntView.y;
|
||||
pntView3D.z = altitude;
|
||||
|
||||
UGPoint pntObjectImg;
|
||||
//坐标点转换为栅格数据集对应的行和列
|
||||
datasetRaster->XYToImg(pntObject,pntObjectImg);
|
||||
altitude = datasetRaster->GetValue(pntObjectImg.x,pntObjectImg.y);
|
||||
pntObject3D.x = pntObject.x;
|
||||
pntObject3D.y = pntObject.y;
|
||||
pntObject3D.z = altitude;
|
||||
|
||||
//进行通视分析查询;
|
||||
UG3DAnalyst::SingleResult* result = visAnalsyt.IsVisible(datasetRaster,pntView3D,pntObject3D);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
@ -0,0 +1,148 @@
|
||||
# Երկիր (Erkir) - a C++ library for geodesic and trigonometric calculations
|
||||
|
||||
[Erkir (armenian: Երկիր, means Earth)](https://github.com/vahancho/erkir) - is inspired
|
||||
by and based on the great work of [Chris Veness](https://github.com/chrisveness),
|
||||
the owner of the [Geodesy functions](https://github.com/chrisveness/geodesy)
|
||||
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.
|
||||
|
||||
[](https://github.com/vahancho/erkir/releases)
|
||||
[](https://github.com/vahancho/erkir/actions/workflows/cmake.yml)
|
||||
[](https://codecov.io/gh/vahancho/erkir)
|
||||
|
||||
### 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:
|
||||
|
||||
```cpp
|
||||
#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;
|
||||
}
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
* [Movable Type Scripts Latitude/Longitude Calculations Reference](http://www.movable-type.co.uk/scripts/latlong.html)
|
||||
|
@ -0,0 +1,120 @@
|
||||
/**********************************************************************************
|
||||
* MIT License *
|
||||
* *
|
||||
* Copyright (c) 2020 Vahan Aghajanyan <vahancho@gmail.com> *
|
||||
* *
|
||||
* Geodesy tools for conversions between (historical) datums *
|
||||
* (c) Chris Veness 2005-2019 *
|
||||
* www.movable-type.co.uk/scripts/latlong-convert-coords.html *
|
||||
* www.movable-type.co.uk/scripts/geodesy-library.html#latlon-ellipsoidal-datum *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy *
|
||||
* of this software and associated documentation files (the "Software"), to deal *
|
||||
* in the Software without restriction, including without limitation the rights *
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell *
|
||||
* copies of the Software, and to permit persons to whom the Software is *
|
||||
* furnished to do so, subject to the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all *
|
||||
* copies or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
|
||||
* SOFTWARE. *
|
||||
***********************************************************************************/
|
||||
|
||||
#ifndef DATUM_H
|
||||
#define DATUM_H
|
||||
|
||||
#include "export.h"
|
||||
|
||||
namespace erkir
|
||||
{
|
||||
|
||||
namespace cartesian
|
||||
{
|
||||
class Point;
|
||||
}
|
||||
|
||||
namespace ellipsoidal
|
||||
{
|
||||
|
||||
/// Implements a geodetic datum.
|
||||
/*!
|
||||
Note that precision of various datums will vary, and WGS-84 (original) is not defined to be
|
||||
accurate to better than ±1 metre. No transformation should be assumed to be accurate to better
|
||||
than a meter; for many datums somewhat less.
|
||||
*/
|
||||
class ERKIR_EXPORT Datum
|
||||
{
|
||||
public:
|
||||
enum class Type
|
||||
{
|
||||
ED50, /*!< The older European Datum */
|
||||
Irl1975,
|
||||
NAD27, /*!< The older North American Datum, of which NAD83 was basically a readjustment */
|
||||
NAD83, /*!< The North American Datum which is very similar to WGS 84 */
|
||||
NTF, /*!< Nouvelle Triangulation Francaise */
|
||||
OSGB36, /*!< Of the Ordnance Survey of Great Britain */
|
||||
Potsdam, /*!< The local datum of Germany with underlying Bessel ellipsoid */
|
||||
TokyoJapan,
|
||||
WGS72, /*!< 72 of the World Geodetic System */
|
||||
WGS84 /*!< 84 of the World Geodetic System */
|
||||
};
|
||||
|
||||
//! Constructs a datum with the given \p type. WGS84 is the default datum.
|
||||
Datum(Type type = Type::WGS84);
|
||||
|
||||
//! Implements a reference ellipsoid.
|
||||
struct Ellipsoid
|
||||
{
|
||||
enum class Type
|
||||
{
|
||||
WGS84,
|
||||
Airy1830,
|
||||
AiryModified,
|
||||
Bessel1841,
|
||||
Clarke1866,
|
||||
Clarke1880IGN,
|
||||
GRS80,
|
||||
Intl1924, // aka Hayford
|
||||
WGS72
|
||||
};
|
||||
|
||||
Ellipsoid(double a, double b, double f);
|
||||
|
||||
/// Major axis (a).
|
||||
double m_a{0.0};
|
||||
|
||||
/// Minor axis (b).
|
||||
double m_b{0.0};
|
||||
|
||||
/// Flattening (f).
|
||||
double m_f{0.0};
|
||||
};
|
||||
|
||||
/// Returns the reference ellipsoid for this datum.
|
||||
const Ellipsoid &ellipsoid() const;
|
||||
|
||||
/// Returns the type of this datum.
|
||||
Type type() const;
|
||||
|
||||
/// Converts the given cartesian \p point to the \p targetDatum.
|
||||
void toDatum(cartesian::Point &point, Type targetDatum) const;
|
||||
|
||||
/// Compares two datums.
|
||||
bool operator==(const Datum &other) const;
|
||||
|
||||
private:
|
||||
Type m_type{Type::WGS84};
|
||||
};
|
||||
|
||||
} // ellipsoidal
|
||||
|
||||
} // erkir
|
||||
|
||||
#endif // DATUM_H
|
@ -0,0 +1,14 @@
|
||||
#ifndef __EXPORT_H_
|
||||
#define __EXPORT_H_
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef MAKEDLL
|
||||
# define ERKIR_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
# define ERKIR_EXPORT __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define ERKIR_EXPORT
|
||||
#endif
|
||||
|
||||
#endif // __EXPORT_H_
|
@ -0,0 +1,70 @@
|
||||
/**********************************************************************************
|
||||
* MIT License *
|
||||
* *
|
||||
* Copyright (c) 2018-2019 Vahan Aghajanyan <vahancho@gmail.com> *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy *
|
||||
* of this software and associated documentation files (the "Software"), to deal *
|
||||
* in the Software without restriction, including without limitation the rights *
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell *
|
||||
* copies of the Software, and to permit persons to whom the Software is *
|
||||
* furnished to do so, subject to the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all *
|
||||
* copies or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
|
||||
* SOFTWARE. *
|
||||
***********************************************************************************/
|
||||
|
||||
#ifndef POINT_H
|
||||
#define POINT_H
|
||||
|
||||
#include "coordinate.h"
|
||||
#include "export.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace erkir
|
||||
{
|
||||
|
||||
/// Base class for all types of geodetic points.
|
||||
class ERKIR_EXPORT Point
|
||||
{
|
||||
public:
|
||||
//! Constructs an invalid point object.
|
||||
Point();
|
||||
|
||||
//! Constructs a point with the given \p latitude and \p longitude.
|
||||
Point(const Latitude &latitude, const Longitude &longitude);
|
||||
|
||||
//! Returns the latitude of this point.
|
||||
const Latitude &latitude() const;
|
||||
|
||||
//! Returns the longitude of this point.
|
||||
const Longitude &longitude() const;
|
||||
|
||||
//! Returns true if this point is a valid one and false otherwise.
|
||||
bool isValid() const;
|
||||
|
||||
/// Returns true if two points are equal and false otherwise.
|
||||
bool operator==(const Point &other) const;
|
||||
|
||||
/// Returns true if two points are different and false otherwise.
|
||||
bool operator!=(const Point &other) const;
|
||||
|
||||
private:
|
||||
Latitude m_latitude;
|
||||
Longitude m_longitude;
|
||||
bool m_isValid;
|
||||
};
|
||||
|
||||
} // erkir
|
||||
|
||||
#endif // POINT_H
|
||||
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue