This package define wrapper structs for DE9IM predicates
It provides no functionality of predicate calculation, just structs to use as a shared interface that signifies that the DE9IM standard will be followed.
- If used in Extents.jl, this would the corresponding Extents.jl predicates will be used specifially for the extents of objects.
- In GeometryOps, it could be used for Point/Line/Polygon extents.
- In Rasters.jl, for selection of raster cells.
Base dispatch can be overwritten by any package if it owns the wrapped object:
Base.func(::Covers{Package.Object}, x)
But more usually package functions will use it directly:
Package.predicate(::Covers{Nothing}, a, b) = Package.covers(a, b)
Package.predicate(pred::Covers, a) = Package.covers(a, parent(pred))
The predicate is assumed to wrap the second argument, rather than the first, similar to Base.Fix2
.
Then, e.g. predicate(Covers(b), a)
means that a
covers b
.
A real use case is something like this:
raster[Covers(geom)]
Where the vocabulary makes more sense.
Use as a "singleton" type, filled with nothing
pred = Crosses()
@assert parent(pred) === nothing
Use as a wrapper type:
pred = Crosses(1.0)
@assert parent(pred) === 1.0
@assert eltype(pred) == Float64
@assert typeof(pred) == Crosses{Float64}
Predicates may accept keywords:
pred = Intersects(1.0; manifold=:euclidian)
@assert DE9IM.keywords(pred) === (; manifold=:euclidian)
This doesn't change the basic behaviour of the object:
@assert parent(pred) === 1.0
@assert eltype(pred) === Float64
But somewhat complicates the type, with an inner wrapper:
@assert typeof(pred) == Intersects{DE9IM.ArgWithKeywords{Float64, @NamedTuple{manifold::Symbol}}}
Keyword interpretation is the responsibility of the ingesting package, any are allowed.