Skip to content

Commit a741edc

Browse files
authored
Documentation improvements (#170)
1 parent 2ca2a3c commit a741edc

File tree

23 files changed

+415
-77
lines changed

23 files changed

+415
-77
lines changed

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
3636
MakieThemes = "e296ed71-da82-5faf-88ab-0034a9761098"
3737
Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7"
3838
MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca"
39+
Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
3940
MultiFloats = "bdf0d083-296b-4888-a5b6-7498122e68a5"
4041
NaturalEarth = "436b0209-26ab-4e65-94a9-6526d86fea76"
4142
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"

docs/make.jl

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ function current_module_from_paths(source_path, relative_path)
6464
return "GeometryOps"
6565
elseif endswith(source_path, "ext")
6666
return "Base.get_extension(GeometryOps, :$(splitpath(relative_path)[1]))"
67+
elseif contains(relative_path, "SpatialTreeInterface")
68+
return "GeometryOps.SpatialTreeInterface"
69+
elseif contains(relative_path, "LoopStateMachine")
70+
return "GeometryOps.LoopStateMachine"
71+
elseif contains(relative_path, "NaturalIndexing")
72+
return "GeometryOps.NaturalIndexing"
73+
else
74+
return "GeometryOps" # default to GO as a last resort
6775
end
6876
end
6977

@@ -111,7 +119,8 @@ withenv("JULIA_DEBUG" => "Literate") do # allow Literate debug output to escape
111119
end
112120

113121
# Now that the Literate stuff is done, we also download the call notes from HackMD:
114-
download("https://hackmd.io/kpIqAR8YRJOZQDJjUKVAUQ/download", joinpath(@__DIR__, "src", "call_notes.md"))
122+
# download("https://hackmd.io/kpIqAR8YRJOZQDJjUKVAUQ/download", joinpath(@__DIR__, "src", "call_notes.md"))
123+
# This is a bit unreliable especially at high volumes of traffic, so we don't call this for now.
115124

116125
# Finally, make the docs!
117126
makedocs(;
@@ -131,8 +140,15 @@ makedocs(;
131140
],
132141
"Explanations" => [
133142
"Paradigms" => "explanations/paradigms.md",
134-
"Peculiarities" => "explanations/peculiarities.md",
135143
"Manifolds" => "explanations/manifolds.md",
144+
"Peculiarities" => "explanations/peculiarities.md",
145+
"GIS terminology" => [
146+
"CRS" => "explanations/crs.md",
147+
"Winding order" => "explanations/winding_order.md",
148+
# "Geometry types and lack of support" => "explanations/well_known_geometry.md", # TODO write this
149+
# "When you should use LibGEOS or ArchGDAL" => "explanations/notgeometryops.md", # TODO write this
150+
],
151+
"Developer docs" => "explanations/devdocs.md",
136152
],
137153
"Source code" => literate_pages,
138154
],
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#=
2+
# A random walk through [GeometryOps.jl](https://juliageo.org/GeometryOps.jl)
3+
4+
In this tutorial, we'll take a random walk through GeometryOps and its capabilities, just to show off what it can do.
5+
6+
7+
=#
8+
import GeometryOps as GO
9+
## ecosystem packages we'll need
10+
import GeoInterface as GI
11+
using CairoMakie # for plotting
12+
#
13+
14+
#=
15+
## The `apply` interface
16+
17+
- my_coord_op
18+
- my_linestring_op
19+
=#
20+
21+
22+
#=
23+
## The `applyreduce` interface
24+
This one is arguably more useful for daily tasks.
25+
26+
- my_centroid on a linestring/ring level
27+
-
28+
29+
=#
30+
31+
#=
32+
## The `fix` interface
33+
- Choose your fixes
34+
- How to make a new fix (antimeridian cutting)
35+
=#
36+
37+
38+
#=
39+
## LibGEOS extension
40+
> If you can't do it yourself, then use something else.
41+
TODO: chatgpt this quote
42+
43+
=#
44+
import LibGEOS # we will never actually call LibGEOS here
45+
46+
GO.buffer(poly, 1) |> Makie.poly

docs/src/explanations/crs.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Coordinate Reference Systems
2+
3+
[Coordinate Reference System](https://en.wikipedia.com/wiki/Spatial_reference_system)s are simply descriptions of what some set of coordinates really mean in reference to some standard.
4+
5+
In a mathematical sense, coordinate reference systems can be thought of defining a _space_, with associated transformations from and to latitude-longitude space (plate-carree, long-lat, WGS84) which is the default CRS we assume.
6+
7+
## Geographic CRS
8+
9+
If a CRS is _geographic_, that means that it refers to coordinates on a sphere. Such coordinates should ideally be handled using a spherical geometry library like Google's s2. GeometryOps does not currently handle spherical geometry computations except in special cases (e.g., [`segmentize`](@ref) with the [`Geodesic`](@ref) manifold).
10+
11+
A non-geographic CRS is assumed to be in Cartesian space.
12+
13+
## Projected CRS
14+
15+
Projected CRS are generally treated as Cartesian.
16+
17+
## Ways to describe CRS
18+
19+
Completely separate from the _meaning_ of the CRS is the way you describe or define it. There are a [dizzying array of ways](@ref crs-format-table) to do this, but two easy ones are Proj strings and Well Known Text.
20+
21+
The geographic community seems to be standardizing on [Well Known Text]() as the "best" CRS identifier. This is quite verbose, but is unambiguous and easy enough to read once you get the hang of it.
22+
23+
To indicate the type of CRS definition you're using, you can wrap a string in its corresponding `GeoFormatTypes` type.
24+
25+
## [CRS format table](@id crs-format-table)
26+
<!-- TODO: convert this to a Markdown table-->
27+
- Proj-strings: a brief but powerful way to describe a set of known CRS + some transformations to them. Really useful when plotting and interactively adjusting CRS. See the Proj docs.
28+
- EPSG codes: a short way to refer to a known coordinate system in the database of the European Petroleum Survey Group. Example: `EPSG:4236`.
29+
- ESRI codes: similar to EPSG codes, but referring to CRS known to ESRI instead. Example: `ESRI:12345`
30+
- ProjJSON: a more structured way to express Proj-strings using JSON.
31+
- KML: key-markup language, an XML extension, used in web feature services
32+
- Mapinfo CoordSys:

docs/src/explanations/devdocs.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Developer documentation
2+
3+
This is mostly some notes about how GeometryOps is structured, geared towards developers
4+
and folks interested in learning about the internals of GeometryOps.
5+
6+
## Coding standards
7+
8+
Every source file is also compiled into the documentation via Literate.jl, so
9+
it should have a Markdown section at the top that describes what that file does.
10+
11+
For most cases, each function has a single file, and so that file should:
12+
- have a header which is the capitalized name of that function
13+
- have a docstring that is visible when you first load the page (collapsed or opened is up to you)
14+
- have some visual examples, rendered in the documentation, of what that function does!
15+
Since this is geometry, it's very easy to plot with e.g Makie.
16+
17+
We also request that you define [`Algorithm`](@ref) types and use those to define the behaviour of your function. We don't have an operations interface yet (coming soon!) but that should be done as well!
18+
19+
## Geometry representation
20+
21+
In Julia there is no one fixed geometry representation; instead we can use any memory layout in a standardized way via [GeoInterface.jl](https://github.com/JuliaGeo/GeoInterface.jl). This means
22+
iterating over `enumerate(GI.getpoint(geom))` rather than `1:length(geom)`, and similar.
23+
24+
However, sometimes you want a fast, in-Julia geometry with known layout. For example, `getpoint` on
25+
GEOS or GDAL geoms is quite slow because you have to make a `ccall` with a pointer. For cases like these
26+
you can simply use `GO.tuples` to convert geometries to [GeoInterface wrapper geometries](https://juliageo.org/GeoInterface.jl/dev/guides/defaults/#Wrapper-types) that wrap (usually) 2-tuple points in vectors.
27+
28+
When returning geometries you can generally return any GeoInterface geometry but should prefer such
29+
GeoInterface tuple geometries as mentioned above.
30+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Winding order
2+
3+
Winding order refers specifically to the "direction" that a polygon's rings go in. This has several different and conflicting definitions, which you can find some discussion of in the following articles:
4+
- [GIS Stack Exchange: Order of polygon vertices?](https://gis.stackexchange.com/questions/119150/order-of-polygon-vertices-in-general-gis-clockwise-or-counterclockwise)
5+
- [ObservableHQ winding order article](https://observablehq.com/@d3/winding-order)
6+
7+
GeometryOps assumes that polygon exteriors are clockwise and interiors are counterclockwise. However, most algorithms are agnostic to winding order, and instead rely on the GeoInterface `getexterior` and `gethole` functions to distinguish holes from exteriors. Notably, _most_ GIS implementations agree that polygons can have only one exterior but several holes.
8+
9+
## What other libraries do
10+
11+
TODO: Markdown table with a bunch of libraries/standards, their winding orders, and references.

docs/src/tutorials/creating_geometry.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ fig
5757
x = [-5, -5, 5, 5];
5858
y = [-5, 5, 5, -5];
5959
multipoint = GI.MultiPoint(GI.Point.(zip(x, y)));
60-
plot!(ax, multipoint; marker = '☁', markersize = 30)
60+
# TODO: GeoInterfaceMakie.jl can't plot multipoints due to breaking changes
61+
# in Makie.jl. We should fix that.
62+
plot!(ax, multipoint.geom; marker = '☁', markersize = 30)
6163
fig
6264
````
6365

docs/src/tutorials/spatial_joins.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Spatial joins
1+
# [Spatial joins](@id tutorial-spatial-joins)
22

33
Spatial joins are [table joins](https://www.geeksforgeeks.org/sql-join-set-1-inner-left-right-and-full-joins/) which are based not on equality, but on some predicate ``p(x, y)``, which takes two geometries, and returns a value of either `true` or `false`. For geometries, the [`DE-9IM`](https://en.wikipedia.org/wiki/DE-9IM) spatial relationship model is used to determine the spatial relationship between two geometries.
44

ext/GeometryOpsFlexiJoinsExt/GeometryOpsFlexiJoinsExt.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
# # FlexiJoins extension
2+
#=
3+
This is an extension on FlexiJoins.jl that provides spatial tree acceleration to join
4+
arbitrary tables, using GeometryOps predicates.
5+
6+
The implementation is specialized on GO predicates.
7+
8+
See the [Spatial Joins tutorial](@ref tutorial-spatial-joins) for more information and for how to use this.
9+
=#
110
module GeometryOpsFlexiJoinsExt
211

312
using GeometryOps

ext/GeometryOpsLibGEOSExt/GeometryOpsLibGEOSExt.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# # LibGEOS extension
2+
3+
# This is the main file for the LibGEOS extension of GeometryOps.
4+
15
module GeometryOpsLibGEOSExt
26

37
import GeometryOps as GO, LibGEOS as LG
@@ -11,6 +15,9 @@ using GeometryOps
1115
# However, if you import those from another module (which you would with `all=true`),
1216
# that creates an ambiguity which causes a warning during precompile/load time.
1317
# In order to avoid this, we filter out these special functions.
18+
19+
# This is kind of like ImportAll.jl but without the macro. It only imports the functions
20+
# in names(GeometryOps; all=false).
1421
for name in filter(!in((:var"#eval", :eval, :var"#include", :include)), names(GeometryOps))
1522
@eval import GeometryOps: $name
1623
end

0 commit comments

Comments
 (0)