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

Edits about Documentation Task #72

Merged
merged 3 commits into from
Jul 12, 2023
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
89 changes: 76 additions & 13 deletions docs/src/spatial.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,103 @@ Using the the library makes basic understanding of spatial data. The following [
- Earth-centered, Earth-fixed (ECEF)
- East, North, Up (ENU)

The `LLA` node is the standard way to represent locations. The `ECEF` and `ENU` modes uses a distance (measured in meters) from a reference point. To better understand those modes have a look at the Wikipedia pictures below:
The `LLA` node is the standard way to represent locations. The latitude is the angle between the equatorial plane and the straight line that passes through that point and through (or close to) the center of the Earth. The longitude is the angle east or west of a reference meridian to another meridian that passes through that point. The altitude is the height of a point in relation to sea level or ground level.

- Earth-centered, Earth-fixed (ECEF)
The `ECEF` and `ENU` modes uses a distance (measured in meters) from a reference point.
The `ECEF` mode is a cartesian spatial reference system that represents locations in the vicinity of the Earth as X, Y, and Z measurements from its point of origin. The ECEF that is used for the Global Positioning System (GPS) is the geocentric _WGS 84_, which currently includes its own ellipsoid definition.
The `ENU` mode is far more intuitive and practical than ECEF or Geodetic coordinates. The local ENU coordinates are formed from a plane tangent to the Earth's surface fixed to a specific location.

To better understand those modes have a look at the Wikipedia pictures below:

### Earth-centered, Earth-fixed (ECEF)

The point (0,0,0) denotes the centre of the Earth (hence the name 'Earth-Centred') and the system rotates in solidarity with the Earth. The X-Y plane is coincident with the equatorial plane with the respective versors pointing in the directions of longitude 0° and 90°, while the Z-axis orthogonal to this plane points in the direction of the North Pole. The X,Y,Z coordinates are represented in metres. ECEF coordinates are used in the GPS positioning system, as they are considered to be the conventional earth reference system.

[![ECEF](https://upload.wikimedia.org/wikipedia/commons/8/88/Ecef.png "ECEF")](https://en.wikipedia.org/wiki/ECEF)

- East, North, Up (ENU)
### East, North, Up (ENU)

These references are location-dependent. For movements across the globe, such as air or sea navigation, the references are defined as tangents to the lines of geographical coordinates:
- East-west axis, that is tangent to parallels,
- North-south axis, that is tangent to meridians, and
- Up-down axis in the direction normal to the oblate spheroid used as Earth's ellipsoid, which generally does not pass through the center of the Earth.

[![ENU](https://upload.wikimedia.org/wikipedia/commons/thumb/7/73/ECEF_ENU_Longitude_Latitude_relationships.svg/800px-ECEF_ENU_Longitude_Latitude_relationships.svg.png "ENU")](https://en.wikipedia.org/wiki/Local_tangent_plane_coordinates)


Any point can be created using `LLA` struct:
In this library, any point can be created using `LLA` struct:
```julia
fields_institute_lla = LLA(43.658813, -79.397574, 0.0)
```
LLA(43.658813, -79.397574, 0.0)


The library enables [conversion between diiferent coordinates systems](https://en.wikipedia.org/wiki/Geographic_coordinate_conversion).
### Examples
[conversion between different coordinates systems](https://en.wikipedia.org/wiki/Geographic_coordinate_conversion).


### Constructors for conversions
```julia
fields_ecef = OpenStreetMapX.ECEF(fields_institute_lla)
```
ECEF(850365.5982110817, -4.542824565319083e6, 4.380743975743749e6)
# From LLA to ECEF
ECEF(lla::LLA, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

Constructors for all-ways conversions are provided.
# From ECEF to LLA
LLA(ecef::ECEF, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

Once having a point it can be plotted (this requires installation of folium - see the README on the main project page):
# From ECEF with LLA reference point to ENU
ENU(ecef::ECEF, lla_ref::LLA, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

# From ECEF with Bound reference point to ENU
ENU(ecef::ECEF, bounds::Bounds{LLA}, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

```julia
# From ENU with LLA reference point to ECEF
ECEF(enu::ENU, lla_ref::LLA, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

# From ENU with Bound reference point to ECEF
ECEF(enu::ENU, bounds::Bounds{LLA}, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

# From LLA with LLA reference point to ENU
ENU(lla::LLA, lla_ref::LLA, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

# From LLA with Bound reference point to ENU
ENU(lla::LLA, bounds::Bounds{LLA}, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

# From ENU with LLA reference point to LLA
LLA(enu::ENU, lla_ref::LLA, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

# From ENU with Bound reference point to LLA
LLA(enu::ENU, bounds::Bounds{LLA}, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

# From LLA's dict to ECEF's dict
ECEF(nodes::Dict{Int,LLA}, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

# From ECEF's dict to LLA's dict
LLA(nodes::Dict{Int,ECEF}, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

# From LLA or ECEF with LLA reference point to ENU's dict
ENU(nodes::Dict{Int,T}, lla_ref::LLA, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84) where T<:Union{LLA,ECEF}

# From LLA or ECEF with Bound reference point to ENU's dict
ENU(nodes::Dict{Int,T}, bounds::Bounds{LLA}, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84) where T<:Union{LLA,ECEF}

# From ENU's dict to ECEF's dict with LLA reference point
ECEF(nodes::Dict{Int,ENU},lla_ref::LLA , datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

# From ENU's dict to ECEF's dict with Bound reference point
ECEF(nodes::Dict{Int,ENU}, bounds::Bounds{LLA},datum::Ellipsoid = WGS84)

# From ENU's dict to LLA's dict with LLA reference point
LLA(nodes::Dict{Int,ENU},lla_ref::LLA , datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

# From ENU's dict to LLA's dict with Bound reference point
LLA(nodes::Dict{Int,ENU}, bounds::Bounds{LLA}, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

```

Once having a point it can be plotted (this requires installation of folium - see the README on the main project page):


```julia
using PyCall
flm = pyimport("folium") #note that this requires folium to be installed
m = flm.Map()
Expand All @@ -52,5 +116,4 @@ MAP_BOUNDS = [ Tuple(m.get_bounds()[1,:].-0.005), Tuple(m.get_bounds()[2,:].+0.0
m.fit_bounds(MAP_BOUNDS)

m
```

```
11 changes: 11 additions & 0 deletions src/a_star.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,18 @@ function get_distance(A::Int, B::Int,
OpenStreetMapX.distance(nodes[A],nodes[B])
end

"""
function extract_a_star_route(parents::Vector{Int},s::Int, u::Int)

It uses the parents information to extract the A* search route from the starting node
to the destination node and returns it as an array of node indices in the correct order.

**Arguments**

* `parents::Vector{Int}` : vector of integers
* `s::Int` : start index
* `u::Int` : end index
"""
function extract_a_star_route(parents::Vector{Int},s::Int, u::Int)
route = Int[]
index = u
Expand Down
60 changes: 60 additions & 0 deletions src/classification.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,22 @@ classify_roadways(ways::Vector{OpenStreetMapX.Way}, classes::Dict{String, Int} =
### Filter and Classify Highways for Pedestrians ###
####################################################

"""
filter_walkways(ways::Vector{OpenStreetMapX.Way},
classes::Dict{String, Int} = OpenStreetMapX.PED_CLASSES;
levels::Set{Int} = Set(1:length(OpenStreetMapX.PED_CLASSES)))

Filters a vector of ways to include only those that are relevant for pedestrian walkways.
It considers the presence of a "sidewalk" tag and checks if the corresponding value or the "highway" tag value
is present in the specified classes dictionary and levels set.

**Arguments**

* `ways::Vector{OpenStreetMapX.Way}` : Way's vector
* `classes` : classes dictionary
* `levels` : set of levels useful to compare with the way tags

"""
function filter_walkways(ways::Vector{OpenStreetMapX.Way},classes::Dict{String, Int} = OpenStreetMapX.PED_CLASSES; levels::Set{Int} = Set(1:length(OpenStreetMapX.PED_CLASSES)))
walkways = OpenStreetMapX.Way[]
for way in ways
Expand All @@ -57,6 +73,20 @@ function filter_walkways(ways::Vector{OpenStreetMapX.Way},classes::Dict{String,
return walkways
end

"""
classify_walkways(ways::Vector{OpenStreetMapX.Way},
classes::Dict{String, Int} = OpenStreetMapX.PED_CLASSES)

Classifies a vector of OpenStreetMapX ways based on their pedestrian attributes.
It considers the presence of a "sidewalk" tagand checks if the corresponding value or the "highway" tag value
is present in the specified classes dictionary

**Arguments**

* `ways::Vector{OpenStreetMapX.Way}` : Way's vector
* `classes` : classes dictionary

"""
function classify_walkways(ways::Vector{OpenStreetMapX.Way},classes::Dict{String, Int} = OpenStreetMapX.PED_CLASSES)
walkways = Dict{Int,Int}()
for way in ways
Expand All @@ -76,6 +106,22 @@ end
### Filter and Classify Highways for Cycles ###
###############################################

"""
filter_cycleways(ways::Vector{OpenStreetMapX.Way},
classes::Dict{String, Int} = OpenStreetMapX.CYCLE_CLASSES;
levels::Set{Int} = Set(1:length(OpenStreetMapX.CYCLE_CLASSES)))

Filters a vector of OpenStreetMapX ways to include only those that are relevant for cycleways.
It considers the presence of "bicycle", "cycleway", and "highway" tags and checks if the corresponding values
or the constructed class strings are present in the specified classes dictionary and levels set.

**Arguments**

* `ways::Vector{OpenStreetMapX.Way}` : Way's vector
* `classes` : classes dictionary
* `levels` : set of levels useful to compare with the way tags

"""
function filter_cycleways(ways::Vector{OpenStreetMapX.Way}, classes::Dict{String, Int} = OpenStreetMapX.CYCLE_CLASSES; levels::Set{Int} = Set(1:length(OpenStreetMapX.CYCLE_CLASSES)))
cycleways = OpenStreetMapX.Way[]
for way in ways
Expand All @@ -99,6 +145,20 @@ function filter_cycleways(ways::Vector{OpenStreetMapX.Way}, classes::Dict{String
return cycleways
end

"""
classify_cycleways(ways::Vector{OpenStreetMapX.Way},
classes::Dict{String, Int} = OpenStreetMapX.CYCLE_CLASSES)

Classifies a vector of OpenStreetMapX ways based on their cycleway attributes.
It considers the presence of "bicycle", "cycleway", and "highway" tags and checks if the corresponding values
or the constructed class strings are present in the specified classes dictionary.

**Arguments**

* `ways::Vector{OpenStreetMapX.Way}` : Way's vector
* `classes` : classes dictionary

"""
function classify_cycleways(ways::Vector{OpenStreetMapX.Way}, classes::Dict{String, Int} = OpenStreetMapX.CYCLE_CLASSES)
cycleways = Dict{Int,Int}()
for way in ways
Expand Down
82 changes: 79 additions & 3 deletions src/conversion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@
##########################

"""
Create ECEF coordinates from a given `lla`
ECEF(lla::LLA, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

Create ECEF coordinates from a given `LLA` datum.

**Arguments**

* `lla::LLA` : Coordinates used
* `datum::OpenStreetMapX.Ellipsoid` : type of ellipsoid used.

"""
function ECEF(lla::LLA, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)
ϕdeg, λdeg, h = lla.lat, lla.lon, lla.alt
Expand All @@ -21,7 +29,15 @@ function ECEF(lla::LLA, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)
return ECEF(x, y, z)
end
"""
Create LLA coordinates from a given `ecef`
LLA(ecef::ECEF, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

Create LLA coordinates from a given `ECEF` datum

**Arguments**

* `lla::LLA` : Coordinates used
* `datum::OpenStreetMapX.Ellipsoid` : type of ellipsoid used.

"""
function LLA(ecef::ECEF, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)
x, y, z = ecef.x, ecef.y, ecef.z
Expand All @@ -39,8 +55,17 @@ function LLA(ecef::ECEF, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)
end

"""
ENU(ecef::ECEF, lla_ref::LLA, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

Create ENU coordinates from given `ecef` coordinates
given a reference point `lla_ref` for linarization

**Arguments**

* `ecef::ECEF` : Coordinates used
* `lla_ref::LLA` : Reference point for linarization
* `datum::OpenStreetMapX.Ellipsoid` : type of ellipsoid used.

"""
function ENU(ecef::ECEF, lla_ref::LLA, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)
ϕdeg, λdeg = lla_ref.lat, lla_ref.lon
Expand Down Expand Up @@ -74,8 +99,17 @@ ENU(ecef::ECEF, bounds::Bounds{LLA}, datum::OpenStreetMapX.Ellipsoid = OpenStree


"""
ECEF(enu::ENU, lla_ref::LLA, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

Create ECEF coordinates from given `enu` coordinates
and a reference point being center of `bounds` for linearization
given a reference point `lla_ref` for linarization

**Arguments**

* `enu::enu` : Coordinates used
* `lla_ref::LLA` : Reference point for linarization
* `datum::OpenStreetMapX.Ellipsoid` : type of ellipsoid used.

"""
function ECEF(enu::ENU, lla_ref::LLA, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)
ϕdeg, λdeg = lla_ref.lat, lla_ref.lon
Expand Down Expand Up @@ -135,8 +169,16 @@ and a reference point being center of `bounds` for linearization
LLA(enu::ENU, bounds::Bounds{LLA}, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84) = LLA(ECEF(enu,bounds))

"""
ECEF(nodes::Dict{Int,LLA}, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

Converts a dictionary of `LLA` `nodes` into a dictionary of `ECEF` values.
Uses a reference point `lla_ref` for linearization.

**Arguments**

* `nodes::Dict{Int,LLA}` : Dictionary of LLA nodes.
* `datum::OpenStreetMapX.Ellipsoid` : type of ellipsoid used.

"""
function ECEF(nodes::Dict{Int,LLA}, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)
r = Dict{Int,ECEF}()
Expand All @@ -150,7 +192,15 @@ function ECEF(nodes::Dict{Int,LLA}, datum::OpenStreetMapX.Ellipsoid = OpenStreet
end

"""
LLA(nodes::Dict{Int,ECEF}, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

Converts a dictionary of `ECEF` `nodes` into a dictionary of `LLA` values.

**Arguments**

* `nodes::Dict{Int,ECEF}` : Dictionary of ECEF nodes.
* `datum::OpenStreetMapX.Ellipsoid` : type of ellipsoid used.

"""
function LLA(nodes::Dict{Int,ECEF}, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)
r = Dict{Int,LLA}()
Expand All @@ -164,8 +214,17 @@ function LLA(nodes::Dict{Int,ECEF}, datum::OpenStreetMapX.Ellipsoid = OpenStreet
end

"""
ENU(nodes::Dict{Int,T}, lla_ref::LLA,datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84) where T<:Union{LLA,ECEF}

Converts a dictionary of `LLA` and `ECEF` `nodes` into a dictionary of `ENU` values.
Uses a reference point `lla_ref` for linearization.

**Arguments**

* `nodes::Dict{Int,T}` : Dictionary of LLA or ECEF nodes.
* `lla_ref::LLA` : Reference point for linarization
* `datum::OpenStreetMapX.Ellipsoid` : type of ellipsoid used.

"""
function ENU(nodes::Dict{Int,T}, lla_ref::LLA,
datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84) where T<:Union{LLA,ECEF}
Expand All @@ -187,8 +246,17 @@ ENU(nodes::Dict{Int,T}, bounds::Bounds{LLA}, datum::OpenStreetMapX.Ellipsoid = O


"""
ECEF(nodes::Dict{Int,ENU},lla_ref::LLA , datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

Converts a dictionary of `ENU` `nodes` into a dictionary of `ECEF` values.
Uses a reference point `lla_ref` for linearization.

**Arguments**

* `nodes::Dict{Int,ENU},` : Dictionary of ENU nodes.
* `lla_ref::LLA` : Reference point for linarization
* `datum::OpenStreetMapX.Ellipsoid` : type of ellipsoid used.

"""
function ECEF(nodes::Dict{Int,ENU},lla_ref::LLA , datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)
r = Dict{Int,ECEF}()
Expand All @@ -209,8 +277,16 @@ ECEF(nodes::Dict{Int,ENU}, bounds::Bounds{LLA}, datum::Ellipsoid = WGS84) = ECEF


"""
LLA(nodes::Dict{Int,ENU},lla_ref::LLA , datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)

Converts a dictionary of `ENU` `nodes` into a dictionary of `LLA` values.
Uses a reference point `lla_ref` for linearization.
**Arguments**

* `nodes::Dict{Int,ENU}` : Dictionary of ENU nodes.
* `lla_ref::LLA` : Reference point for linarization
* `datum::OpenStreetMapX.Ellipsoid` : type of ellipsoid used.

"""
function LLA(nodes::Dict{Int,ENU},lla_ref::LLA , datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84)
r = Dict{Int,LLA}()
Expand Down
Loading