Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coordinate from/to string conversion. #10

Merged
merged 13 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,19 @@ name: Test (CMake)

on:
push:
branches: [ "master" ]
branches:
- 'master'
- '*'
paths-ignore:
- .gitignore
- README.md
pull_request:
branches: [ "master" ]
branches:
- 'master'
- '*'
workflow_dispatch:
branches:
- '*'

env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
Expand All @@ -21,7 +31,7 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Configure CMake
if: matrix.os != 'windows-latest'
Expand Down Expand Up @@ -74,7 +84,7 @@ jobs:
# Upload coverage report only for Linux
- name: Upload coverage to Codecov
if: matrix.os == 'ubuntu-latest'
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ endif()
add_subdirectory(src)

if (ENABLE_TESTING)
include(CTest)
enable_testing()
include(Dart)

add_subdirectory(test)
endif()
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,22 @@ int main(int argc, char **argv)
}
```
#### 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°)*.
```cpp
auto lon = Longitude::fromString("45° 46’ 47.36” W");
auto lat = Latitude::fromString("45°46′ 45.36″ N");
```

```cpp
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
Expand Down
98 changes: 98 additions & 0 deletions include/coordinate.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,43 @@

#include "export.h"

#include <string>

namespace erkir
{

//! Implements the geographical coordinate abstraction.
class ERKIR_EXPORT Coordinate
{
public:
/// The coordinates human readable format types.
enum class Format
{
DMS, ///< Degrees Minutes Seconds (D° M' S")
DDM, ///< Decimal Minutes (D° M.M')
DD ///< Decimal Degrees (D.D°)
};

/// The cardinal points types
enum class CompassPrecision
{
///< Main compass directions: north (N), south (S), east (E), west (W)
Cardinal,
///< Ordinal directions: northeast (NE), southeast (SE), southwest (SW), northwest (NW)
Intercardinal,
/*!< Secondary intercardinal directions: north - northeast(NNE), east - northeast(ENE),
east - southeast(ESE), south - southeast(SSE), south - southwest(SSW),
west - southwest(WSW), west - northwest(WNW), north - northwest(NNW)
*/
SecondaryIntercardinal
};

//! Constructs a coordinate by the given decimal degrees.
Coordinate(double degrees);

/// Returns string representation of the coordinate in the specified \p format.
virtual std::string toString(Format format, int precision) const = 0;

//! Returns this coordinate's value in decimal degrees.
double degrees() const;

Expand All @@ -54,6 +81,29 @@ class ERKIR_EXPORT Coordinate
/// Constrain degrees to range 0..360.0 (e.g. for bearings); -1 => 359, 361 => 1.
static double wrap360(double degrees);

/// Returns compass point (to given precision) for supplied bearing.
/*!
16-wind compass rose supported - the eight principal winds and the eight half-winds
together form the 16-wind compass rose, with each compass point at a 22.5°
angle from its two neighbours. The half-winds are north-northeast (NNE),
east-northeast (ENE), east-southeast (ESE), south-southeast (SSE),
south-southwest (SSW), west-southwest (WSW), west-northwest (WNW),
and north-northwest (NNW).
@param bearing Bearing in degrees from north.
@param precision Precision (Cardinal, Intercardinal, SecondaryIntercardinal).
@returns Compass point for supplied bearing.
@example
const point = Coordinate::compassPoint(24); // point = 'NNE'
const point = Coordinate::compassPoint(24, 1); // point = 'N'
*/
static std::string compassPoint(double bearing,
CompassPrecision precision = CompassPrecision::SecondaryIntercardinal);

protected:
std::string toBaseString(Format format, int precision) const;

private:
double m_degrees;
};
Expand All @@ -69,6 +119,30 @@ class ERKIR_EXPORT Latitude : public Coordinate
\throws std::out_of_range
*/
Latitude(double degree);

std::string toString(Format format, int precision = 2) const override;

/// Returns the latitude from the human readable coordinates (formatted).
/*!
Latitude/Longitude coordinates in three formats: Degrees Minutes Seconds (D° M' S"),
Decimal Minutes (D° M.M'), and Decimal Degrees (D.D°). Each of these formats
can represent the same geographic location, but expressed differently.
For example: 45° 46' 52" N 108° 30' 14" W as displayed in Degrees Minutes Seconds (D° M' S").
This same location, in displayed Decimal Minutes (D° M.M'), is: 45° 46.8666' N 108° 30.2333' W.
In Decimal Degrees (D.D°), this same location is: 45.7811111° N 108.5038888° W
About Sign and North, South, East West
---------------------------------------------------------------------------
Latitude/Longitude is followed by an indication of hemisphere.
For example 45° 46' 52" N indicates the Northern Hemisphere (North of the equator.)
108° 30' 14" W indicates an area West of the Prime Meridian. When noting this numerically
(especially in Decimal Degrees), positive and negative values are sometimes used.
A positive value for North and East, a negative value for South and West.
Thus, in our example, when noting 45° 46' 52" N 108° 30' 14" W in Decimal Degrees,
it may appear as 45.7811111 -108.5038888 when represented numerically.
*/
static Latitude fromString(const std::string &coord);
};

//! Implements the longitude - the measurement east or west of the prime meridian.
Expand All @@ -81,6 +155,30 @@ class ERKIR_EXPORT Longitude : public Coordinate
\throws std::out_of_range
*/
Longitude(double degree);

std::string toString(Format format, int precision = 2) const override;

/// Returns the longitude from the human readable coordinates (formatted).
/*!
Latitude/Longitude coordinates in three formats: Degrees Minutes Seconds (D° M' S"),
Decimal Minutes (D° M.M'), and Decimal Degrees (D.D°). Each of these formats
can represent the same geographic location, but expressed differently.
For example: 45° 46' 52" N 108° 30' 14" W as displayed in Degrees Minutes Seconds (D° M' S").
This same location, in displayed Decimal Minutes (D° M.M'), is: 45° 46.8666' N 108° 30.2333' W.
In Decimal Degrees (D.D°), this same location is: 45.7811111° N 108.5038888° W
About Sign and North, South, East West
---------------------------------------------------------------------------
Latitude/Longitude is followed by an indication of hemisphere.
For example 45° 46' 52" N indicates the Northern Hemisphere (North of the equator.)
108° 30' 14" W indicates an area West of the Prime Meridian. When noting this numerically
(especially in Decimal Degrees), positive and negative values are sometimes used.
A positive value for North and East, a negative value for South and West.
Thus, in our example, when noting 45° 46' 52" N 108° 30' 14" W in Decimal Degrees,
it may appear as 45.7811111 -108.5038888 when represented numerically.
*/
static Longitude fromString(const std::string &coord);
};

}
Expand Down
Loading
Loading