diff --git a/src/GeometryOps.jl b/src/GeometryOps.jl index dc52c7d17..40d26349d 100644 --- a/src/GeometryOps.jl +++ b/src/GeometryOps.jl @@ -20,6 +20,11 @@ const Edge{T} = Tuple{TuplePoint{T},TuplePoint{T}} where T include("primitives.jl") include("utils.jl") +include("preparations/prepared_geometries.jl") +include("preparations/monotone_chain.jl") +include("preparations/sorted_edge_list.jl") +include("preparations/rtree.jl") + include("methods/angles.jl") include("methods/area.jl") include("methods/barycentric.jl") diff --git a/src/preparations/monotone_chain.jl b/src/preparations/monotone_chain.jl new file mode 100644 index 000000000..9499e85e7 --- /dev/null +++ b/src/preparations/monotone_chain.jl @@ -0,0 +1,10 @@ +#= +# Monotone chain + +A monotone chain is a continuous list of edges whose slopes are _monotonic_, i.e. all oriented towards the same quadrant. + +This speeds up polygon set operations and boolean ops tremendously, since it allows us to skip a lot of the expensive `O(n^2)` operations. + +## Example +=# + diff --git a/src/preparations/prepared_geometries.jl b/src/preparations/prepared_geometries.jl new file mode 100644 index 000000000..45633c82c --- /dev/null +++ b/src/preparations/prepared_geometries.jl @@ -0,0 +1,56 @@ +struct Prepared{Pa,Pr} + parent::Pa + preparations::Pr +end + +Base.parent(x::Prepared) = x.parent +@inline getprep(p::Prepared, x::Symbol) = getproperty(p.preparations, x) + +GI.trait(p::Prepared) = GI.trait(parent(p)) +GI.geomtrait(p::Prepared) = GI.geomtrait(parent(p)) + +GI.isgeometry(::Type{<:Prepared{T}}) where {T} = GI.isgeometry(T) +GI.isfeature(::Type{<:Prepared{T}}) where {T} = GI.isfeature(T) +GI.isfeaturecollection(::Type{<:Prepared{T}}) where {T} = GI.isfeaturecollection(T) + +GI.geometry(x::Prepared) = GI.geometry(parent(x)) +GI.properties(x::Prepared) = GI.properties(parent(x)) + +for f in (:extent, :crs) + @eval GI.$f(t::GI.AbstractTrait, x::Prepared) = GI.$f(t, parent(x)) +end +for f in (:coordnames, :is3d, :ismeasured, :isempty, :coordinates, :getgeom) + @eval GI.$f(t::GI.AbstractGeometryTrait, geom::Prepared, args...) = GI.$f(t, parent(geom), args...) +end + +for f in (:x, :y, :z, :m, :coordinates, :getcoord, :ngeom, :getgeom) + @eval GI.$f(t::GI.AbstractPointTrait, geom::Prepared, args...) = GI.$f(t, parent(geom), args...) +end +for f in (:npoint, :getpoint, :startpoint, :endpoint, :npoint, :issimple, :isclosed, :isring) + @eval GI.$f(t::GI.AbstractCurveTrait, geom::Prepared, args...) = GI.$f(t, parent(geom), args...) +end +for f in (:nring, :getring, :getexterior, :nhole, :gethole, :npoint, :getpoint, :startpoint, :endpoint) + @eval GI.$f(t::GI.AbstractPolygonTrait, geom::Prepared, args...) = GI.$f(t, parent(geom), args...) +end +for f in (:npoint, :getpoint, :issimple) + @eval GI.$f(t::GI.AbstractMultiPointTrait, geom::Prepared, args...) = GI.$f(t, parent(geom), args...) + @eval GI.$f(t::GI.AbstractMultiCurveTrait, geom::Prepared, args...) = GI.$f(t, parent(geom), args...) +end +for f in (:nring, :getring, :npoint, :getpoint) + @eval GI.$f(t::GI.AbstractMultiPolygonTrait, geom::Prepared, args...) = GI.$f(t, parent(geom), args...) +end + +getpoint(t::GI.AbstractPolyhedralSurfaceTrait, geom::Prepared) = GI.getpoint(t, parent(geom)) +isclosed(t::GI.AbstractMultiCurveTrait, geom::Prepared) = GI.isclosed(t, parent(geom)) + +for f in (:getfeature, :coordinates) + @eval GI.$f(t::GI.AbstractFeatureTrait, geom::Prepared, args...) = $f(t, parent(geom), args...) +end + +# Ambiguity +for T in (:LineTrait, :TriangleTrait, :PentagonTrait, :HexagonTrait, :RectangleTrait, :QuadTrait) + @eval GI.npoint(t::GI.$T, geom::Prepared) = GI.npoint(t, parent(geom)) +end +for T in (:RectangleTrait, :QuadTrait, :PentagonTrait, :HexagonTrait, :TriangleTrait) + @eval GI.nring(t::GI.$T, geom::Prepared) = GI.nring(t, parent(geom)) +end diff --git a/src/preparations/rtree.jl b/src/preparations/rtree.jl new file mode 100644 index 000000000..3325b5b4a --- /dev/null +++ b/src/preparations/rtree.jl @@ -0,0 +1,7 @@ +#= +# RTree/STRtree + +An interface for any arbitrary RTree/STRtree. This should allow reconstruction from SQL like databases. + +Applicable to geometrycollections, multi geometries, and feature collections. +=# \ No newline at end of file diff --git a/src/preparations/sorted_edge_list.jl b/src/preparations/sorted_edge_list.jl new file mode 100644 index 000000000..69ec7a447 --- /dev/null +++ b/src/preparations/sorted_edge_list.jl @@ -0,0 +1,7 @@ +#= +# Sorted edge list + +Soted edge lists are essentially the edges of the linestring, linearring, or polygon, sorted by the initial `y` coordinate. + +## Example +=# \ No newline at end of file