11#=
22# Types
33
4- This file defines some fundamental types used in GeometryOps.
4+ This file defines some types used in GeometryOps.
55
66!!! warning
7- Unlike in other Julia packages, only some types are defined in this file, not all.
8- This is because we define types in the files where they are used, to make it easier to understand the code.
7+ Many type definitions are in `GeometryOpsCore`, not here. Look there for the definitions of the basic types like `Manifold`, `Algorithm`, etc.
8+
9+
10+ ## Naming
11+
12+ We force all our external algorithm types to be uppercase, to make them different
13+ from the package names. This is really relevant for the `PROJ` algorithm, since
14+ the Julia package is called `Proj.jl`. If we called our type `Proj`, it would
15+ conflict with the package's name - as we saw with GeoFormatTypes' `GeoJSON` and `GeoJSON.jl`.
916
1017=#
11- export GEOS
18+ export GEOS, TG, PROJ
1219#=
1320
1421## `GEOS`
@@ -23,6 +30,62 @@ useful for two reasons:
2330
2431=#
2532
33+ # ## C-library planar algorithms
34+ """
35+ abstract type CLibraryPlanarAlgorithm <: GeometryOpsCore.SingleManifoldAlgorithm{Planar} end
36+
37+ This is a type which extends `GeometryOpsCore.SingleManifoldAlgorithm{Planar}`,
38+ and is used as an abstract supertype for some C library based algorithms.
39+
40+ The type requires that algorithm structs be arranged as:
41+ ```
42+ struct MyAlgorithm <: CLibraryPlanarAlgorithm
43+ manifold::Planar
44+ params::NamedTuple
45+ end
46+ ```
47+
48+ Then you get a nice constructor for free, as well as the
49+ `get(alg, key, value)` and `get(alg, key) do ...` syntax.
50+ Plus the [`enforce`](@ref) method, which will check that given keyword arguments
51+ are present.
52+ """
53+ abstract type CLibraryPlanarAlgorithm <: GeometryOpsCore.SingleManifoldAlgorithm{Planar} end
54+
55+
56+ function (:: Type{T} )(; params... ) where {T <: CLibraryPlanarAlgorithm }
57+ nt = NamedTuple (params)
58+ return T (Planar (), nt)
59+ end
60+ (T:: Type{<: CLibraryPlanarAlgorithm} )(params:: NamedTuple ) = T (Planar (), params)
61+
62+
63+ # These are definitions for convenience, so we don't have to type out
64+ # `alg.params` every time.
65+
66+ Base. get (alg:: CLibraryPlanarAlgorithm , key, value) = Base. get (alg. params, key, value)
67+ Base. get (f:: Function , alg:: CLibraryPlanarAlgorithm , key) = Base. get (f, alg. params, key)
68+
69+ """
70+ enforce(alg::CLibraryPlanarAlgorithm, kw::Symbol, f)
71+
72+ Enforce the presence of a keyword argument in a `GEOS` algorithm, and return `alg.params[kw]`.
73+
74+ Throws an error if the key is not present, and mentions `f` in the error message (since there isn't
75+ a good way to get the name of the function that called this method).
76+
77+ This applies to all `CLibraryPlanarAlgorithm` types, like [`GEOS`](@ref) and [`TG`](@ref).
78+ """
79+ function enforce (alg:: CLibraryPlanarAlgorithm , kw:: Symbol , f)
80+ if haskey (alg. params, kw)
81+ return alg. params[kw]
82+ else
83+ error (" $(f) requires a `$(kw) ` keyword argument to the `GEOS` algorithm, which was not provided." )
84+ end
85+ end
86+
87+ # ## GEOS - call into LibGEOS.jl
88+
2689"""
2790 GEOS(; params...)
2891
@@ -33,31 +96,66 @@ Dispatch is generally carried out using the names of the keyword arguments.
3396For example, `segmentize` will only accept a `GEOS` struct with only a
3497`max_distance` keyword, and no other.
3598
36- It's generally a lot slower than the native Julia implementations, since
99+ It's generally somewhat slower than the native Julia implementations, since
37100it must convert to the LibGEOS implementation and back - so be warned!
101+
102+ ## Extended help
103+
104+ This uses the [LibGEOS.jl](https://github.com/JuliaGeometry/LibGEOS.jl) package,
105+ which is a Julia wrapper around the C library GEOS (https://trac.osgeo.org/geos).
38106"""
39- struct GEOS
107+ struct GEOS <: CLibraryPlanarAlgorithm # SingleManifoldAlgorithm{Planar}
108+ manifold:: Planar
40109 params:: NamedTuple
41110end
42111
43- function GEOS (; params... )
44- nt = NamedTuple (params)
45- return GEOS (nt)
112+ # ## TG - call into TGGeometry.jl
113+
114+ """
115+ TG(; params...)
116+
117+ A struct which instructs the method it's passed to as an algorithm
118+ to use the appropriate TG function via `TGGeometry.jl` for the operation.
119+
120+ It's generally a lot faster than the native Julia implementations, but only
121+ supports planar manifolds / operations. Also, it only supports geometric predicates,
122+ specifically the ones which the underlying `tg` library supports. These are:
123+
124+ [`equals`](@ref), [`intersects`](@ref), [`disjoint`](@ref), [`contains`](@ref),
125+ [`within`](@ref), [`covers`](@ref), [`coveredby`](@ref), and [`touches`](@ref).
126+
127+ ## Extended help
128+
129+ This uses the [TGGeometry.jl](https://github.com/JuliaGeo/TGGeometry.jl) package,
130+ which is a Julia wrapper around the `tg` C library (https://github.com/tidwall/tg).
131+ """
132+ struct TG <: CLibraryPlanarAlgorithm
133+ manifold:: Planar
134+ params:: NamedTuple
46135end
47- # These are definitions for convenience, so we don't have to type out
48- # `alg.params` every time.
49- Base. get (alg:: GEOS , key, value) = Base. get (alg. params, key, value)
50- Base. get (f:: Function , alg:: GEOS , key) = Base. get (f, alg. params, key)
136+
137+ # ## PROJ - call into Proj.jl
51138
52139"""
53- enforce(alg::GO.GEOS, kw::Symbol, f )
140+ PROJ(; params... )
54141
55- Enforce the presence of a keyword argument in a `GEOS` algorithm, and return `alg.params[kw]`.
142+ A struct which instructs the method it's passed to as an algorithm
143+ to use the appropriate PROJ function via `Proj.jl` for the operation.
56144
57- Throws an error if the key is not present, and mentions `f` in the error message (since there isn't
58- a good way to get the name of the function that called this method).
145+ ## Extended help
146+
147+ This is the default algorithm for [`reproject`](@ref), and is also the default algorithm for
59148"""
60- function enforce (alg:: GEOS , kw:: Symbol , f)
149+ struct PROJ{M <: Manifold } <: Algorithm{M}
150+ manifold:: M
151+ params:: NamedTuple
152+ end
153+
154+ # We repeat these functions here because PROJ does not subtype `CLibraryPlanarAlgorithm`.
155+
156+ Base. get (alg:: PROJ , key, value) = Base. get (alg. params, key, value)
157+ Base. get (f:: Function , alg:: PROJ , key) = Base. get (f, alg. params, key)
158+ function enforce (alg:: PROJ , kw:: Symbol , f)
61159 if haskey (alg. params, kw)
62160 return alg. params[kw]
63161 else
0 commit comments