Skip to content

Commit

Permalink
Updates to documentation, include links to GeometryBasics and Geometr…
Browse files Browse the repository at this point in the history
…yOps
  • Loading branch information
natgeo-wong committed Sep 29, 2024
1 parent 0606e3e commit 5849c2e
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 28 deletions.
3 changes: 2 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ makedocs(;
"GeoRegion Properties" => [
"Shape of a GeoRegion" => "basics/properties/shape.md",
"Is it in a GeoRegion?" => "basics/properties/isin.md",
"Is it on a GeoRegion?" => "basics/properties/ison.md",
"Equivalent GeoRegions" => "basics/properties/isequal.md",
]
],
Expand All @@ -44,7 +45,7 @@ makedocs(;
"Add, Read, Remove" => "api/addreadrm.md",
"Project Setup" => "api/project.md",
"Tables" => "api/tables.md",
"Is In?" => "api/isin.md",
"Is In/On?" => "api/isinon.md",
"Properties" => "api/properties.md",
],
"Ecosystem" => "ecosystem.md",
Expand Down
File renamed without changes.
8 changes: 4 additions & 4 deletions docs/src/basics/properties/isin.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

When dealing with geographic data, we often wish to check if a point or region is inside another region. GeoRegions.jl allows you to perform this check easily with the function `isinGeoRegion`.

!!! note "Point Type"
We use the `Point` Type from the package GeometryBasics.jl, which is reexported by GeoRegions.jl, as an easy way to denote points. This also allows us to use the package PolygonOps.jl to determine if a point is inside a region.
!!! note "Point2 Type"
We use the `Point2` Type from the package [GeometryBasics.jl](https://github.com/JuliaGeometry/GeometryBasics.jl), which is reexported by GeoRegions.jl, as an easy way to denote points. This also allows us to use the package [GeometryOps.jl](https://github.com/JuliaGeo/GeometryOps.jl) to determine if a point is within a GeoRegion.

```@example isin
using GeoRegions
Expand Down Expand Up @@ -62,7 +62,7 @@ But what about Point B? Point B is also very obvious within the bounds of the G
in(B,geo)
```

See the API [here](/api/isin#Base.in-Tuple{Point{%3C:Real},%20GeoRegion})
See the API [here](/api/isinon#Base.in-Tuple{Point2{%3C:Real},%20GeoRegion})

## Is a GeoRegion inside a GeoRegion?

Expand Down Expand Up @@ -124,4 +124,4 @@ in(geo_TS4,geo_BIG)

And we see that this is indeed the case.

See the API for `RectRegion` type [here](/api/isin#Base.in-Tuple{GeoRegion,%20RectRegion}), and for the `TiltRegion` and `PolyRegion` types [here](/api/isin#Base.in-Tuple{GeoRegion,%20Union{PolyRegion,%20TiltRegion}}).
See the API [here](/api/isinon#Base.in-Tuple{GeoRegion,%20GeoRegion}).
121 changes: 121 additions & 0 deletions docs/src/basics/properties/ison.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Is it on a GeoRegion Boundary?

Sometimes, we don't just want information on whether a point is _inside_ a `GeoRegion`. Sometimes, it is important to know if something is _on_ the boundary of a `GeoRegion`. This would prove useful in determining if the shapes of two different `GeoRegion`s are equivalent to each other.

!!! note "Point2 Type"
We use the `Point2` Type from the package [GeometryBasics.jl](https://github.com/JuliaGeometry/GeometryBasics.jl), which is reexported by GeoRegions.jl, as an easy way to denote points. This also allows us to use the package [GeometryOps.jl](https://github.com/JuliaGeo/GeometryOps.jl) to determine if a point is on a GeoRegion boundary.

```@example ison
using GeoRegions
using DelimitedFiles
using CairoMakie
download("https://raw.githubusercontent.com/natgeo-wong/GeoPlottingData/main/coastline_resl.txt","coast.cst")
coast = readdlm("coast.cst",comments=true)
clon = coast[:,1]
clat = coast[:,2]
nothing
```

## Is a Point on a GeoRegion Boundary?

As an example, let us test if a point is on the perimeter of the GeoRegion `AR6_EAO`, defined in the blue bounding box below.

```@example ison
geo = GeoRegion("AR6_EAO")
```

Next, we select a point along the border
```@example ison
A = Point(-25,7.6)
B = Point(335,7.6)
C = Point(-20,5)
D = Point(-45,-7.5)
```

Here, we note that A and B

```@example ison
slon,slat = coordinates(geo)
aspect = (maximum(slon)-minimum(slon))/(maximum(slat)-minimum(slat))
fig = Figure()
ax = Axis(
fig[1,1],width=750,height=750/aspect,
limits=(minimum(slon)-2,maximum(slon)+2,minimum(slat)-2,maximum(slat)+2)
)
lines!(ax,clon,clat,color=:black,linewidth=3)
lines!(ax,slon,slat,linewidth=5)
scatter!(ax,A,markersize=20)
scatter!(ax,C,markersize=20)
scatter!(ax,D,markersize=20)
resize_to_layout!(fig)
fig
```

By eye it is easy to see that Point A is on the GeoRegion perimeter. However, C and D are not. Let us now see if we are able to corroborate this with GeoRegions.jl using the function `on()`

```@example ison
on(A,geo), # Point A
on(C,geo), # Point C
on(D,geo) # Point D
```

But what about Point B? Point B is also very obviously on the bounds of the GeoRegion, it is simply that the longitude of Point B is shifted by 360º from A such that it is now in the (0,360) coordinates frame. We see that this is of no concern to GeoRegions.jl, which can detect that it is within the bounds of the GeoRegion anyway.

```@example ison
on(B,geo)
```

See the API [here](/api/isinon#GeoRegions.on-Tuple{Point2{%3C:Real},%20GeoRegion})

## Is a GeoRegion on a GeoRegion? (i.e., Are their Shapes the Same?)

We can also use the `on()` function to determine if the perimeter of a `GeoRegion` is on the perimeter of another. Or, in simpler terms, **_if two `GeoRegion`s define the same shape_**. For example:

```@example ison
on(geo,geo)
```

See the API [here](/api/isinon#GeoRegions.on-Tuple{GeoRegion,%20GeoRegion})

Which is obvious because we are comparing a `GeoRegion` against itself. However, let us try something a bit more complicated.

### 1. `circshift()` the points defining the `GeoRegion`

In this test case, we use `circshift()` to change the starting and ending coordinates of the `shape`. Therefore, we are defining the same region, just with different start and ending points.

```@example ison
lon,lat = coordinates(geo)
pop!(lon); lon = circshift(lon,2); lon = vcat(lon,lon[1])
pop!(lat); lat = circshift(lat,2); lat = vcat(lat,lat[1])
geo2 = PolyRegion("","","",lon,lat)
```

So here, we have circshifted the `lon` and `lat` values used to define the GeoRegion such that instead of the start/end points being at (-34,-10), now the start/end points are at (-50,0).

We compare the shapes of the two GeoRegions:
```@example ison
on(geo,geo2),
on(geo2,geo)
```

And see that the GeoRegions define the same area.

!!! tip "Order of GeoRegions does not matter in `on()`"
The order should not matter, because in the `on()` function, the GeoRegions are both compared against each other. So `on(geo,geo2) = on(geo2,geo)`. If you find any edge cases where this is not the case, please let me know and I will look into it.

### 2. Shifting the `GeoRegion` by 360º

In this test case, we shift the `lon` of `geo` by 360º, so that it is on a (0,360) grid instead of a (-180,180) grid.

```@example ison
lon,lat = coordinates(geo); lon = lon .+ 360
geo3 = PolyRegion("","","",lon,lat)
```

We compare the shapes of the two GeoRegions:
```@example ison
on(geo,geo3)
```

And we see that the GeoRegions define the same area.
23 changes: 15 additions & 8 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ hero:
actions:
- theme: brand
text: Getting Started
link: /georegions/intro
link: /georegions
- theme: alt
text: Basics
link: /basics/read/overview
- theme: alt
text: Tutorials
link: /using/isin
link: /tutorials/projects
- theme: alt
text: View on Github
link: https://github.com/georegionsecosystem/GeoRegions.jl
Expand All @@ -24,16 +27,20 @@ hero:
features:
- icon: <img width="64" height="64" src="https://img.icons8.com/arcade/64/markdown.png" alt="markdown"/>
title: Simple
details: Only Longitude/Latitude coordinates needed
link: /lists/default
details: Geographic Regions are defined using Longitude/Latitude coordinates
link: /basics/properties/shape
- icon: <img width="64" height="64" src="https://img.icons8.com/arcade/64/markdown.png" alt="markdown"/>
title: Predefined GeoRegions
details: Many Geographic Regions have been predefined, including regions from the IPCC AR6 report
link: /georegions
- icon: <img width="64" height="64" src="https://img.icons8.com/arcade/64/markdown.png" alt="markdown"/>
title: Customizable
details: Define your own custom Geographic Regions
link: /georegions/create
details: Define your own custom Geographic Regions and save them for later
link: /tutorials/addreadrm
- icon: <img width="64" height="64" src="https://img.icons8.com/arcade/64/markdown.png" alt="markdown"/>
title: Useful
details: Data Extraction made easy using GeoRegions.jl
link: /using/extract
details: Are points in/on a GeoRegion for extraction?
link: /basics/properties/isin
---
```

Expand Down
4 changes: 2 additions & 2 deletions src/GeoRegions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ Abstract supertype for geographical regions. All `GeoRegion` types contain the f
* `pID` - A `String` Type, the identifier for the parent GeoRegion.
* `name` - A `String` Type, the full name of the GeoRegion.
* `bound` - A vector of `Float` Types, defining the [North, South, East, West] boundaries of the GeoRegion.
* `shape` - A vector of `Point2` Types, defining a non-rectilinear shape of the GeoRegion
* `geometry` - A `Polygon` Type (see [GeometryBasics.jl]()), which is useful when doing checks on polygons using [GeometryOps.jl]().
* `shape` - A vector of `Point2` (see [GeometryBasics.jl](https://github.com/JuliaGeometry/GeometryBasics.jl)) Types, defining a non-rectilinear shape of the GeoRegion
* `geometry` - A `Polygon` Type (see [GeometryBasics.jl](https://github.com/JuliaGeometry/GeometryBasics.jl)), which is useful when doing checks on polygons using [GeometryOps.jl](https://github.com/JuliaGeo/GeometryOps.jl).
"""
abstract type GeoRegion end

Expand Down
14 changes: 7 additions & 7 deletions src/isin/isin.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""
in(
point :: Point2{<:Real},
geo :: GeoRegion;
throw :: Bool = false
point :: Point2{<:Real},
geo :: GeoRegion;
throw :: Bool = false
) -> tf :: Bool
Check if a geographical point `point` is within a GeoRegion defined by `geo`.
Expand Down Expand Up @@ -60,10 +60,10 @@ end

"""
in(
cgeo :: GeoRegion,
geo :: GeoRegion;
n :: Int = 100,
throw :: Bool = false,
cgeo :: GeoRegion,
geo :: GeoRegion;
n :: Int = 100,
throw :: Bool = false,
verbose :: Bool = false
) -> tf :: Bool
Expand Down
12 changes: 6 additions & 6 deletions src/isin/ison.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ end

"""
on(
geo1 :: GeoRegion,
geo2 :: GeoRegion;
n :: Int = 100,
throw :: Bool = false,
geo1 :: GeoRegion,
geo2 :: GeoRegion;
n :: Int = 2,
throw :: Bool = false,
verbose :: Bool = false
) -> tf :: Bool
Check if the GeoRegions `geo1` and `geo2` have the same shape.
Check if the GeoRegions `geo1` and `geo2` have the same shape. The order of `geo1` and `geo2` does not matter.
Arguments
=========
Expand All @@ -77,7 +77,7 @@ Arguments
Keyword Arguments
=================
- `n` : The number of segments to split each of the `GeoRegion`s into. Default is 2.
- `throw` : If `true`, then if `cgeo` is not within `geo`, an error is thrown and the program stops running.
- `throw` : If `true`, then if `geo1` does not have the same shape as `geo2`, an error is thrown and the program stops running.
- `verbose` : If `true`, print logs to screen.
Returns
Expand Down

0 comments on commit 5849c2e

Please sign in to comment.