Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always use GeometryVector as column (currently a noop). #102

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/src/reference/changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add new driver framework to read files using native drivers.
- Added native driver package extensions on GeoJSON, ShapeFile, GeoParquet, GeoArrow and FlatGeobuf.
- Geometry columns are now wrapped in a GeometryVector, allowing for future improvements.
- Now exports GeoInterface methods instead of ArchGDAL methods for geometry operation.

## v0.3.11
- Changed `reproject` to work on a DataFrame, correctly setting the (crs) metadata
Expand Down
1 change: 1 addition & 0 deletions src/GeoDataFrames.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import GeoInterface as GI
using DataAPI
using Reexport

include("vector.jl")
include("exports.jl")
include("drivers.jl")
include("io.jl")
Expand Down
72 changes: 22 additions & 50 deletions src/exports.jl
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
@reexport using ArchGDAL:
@reexport using GeoInterface:
intersects, equals, disjoint, touches, crosses, within, contains, overlaps
@reexport using ArchGDAL: boundary, convexhull, buffer
@reexport using ArchGDAL: intersection, union, difference, symdifference, distance
@reexport using ArchGDAL: geomlength, geomarea, centroid
@reexport using ArchGDAL: isvalid, issimple, isring, geomarea, centroid
@reexport using ArchGDAL:
createpoint,
createlinestring,
createlinearring,
createpolygon,
createmultilinestring,
createmultipolygon
@reexport using GeoInterface: boundary, convexhull, buffer
@reexport using GeoInterface: intersection, union, difference, symdifference, distance
@reexport using GeoInterface: area, centroid
@reexport using GeoInterface: isvalid, issimple, isring, centroid
# @reexport using GeoInterface:
# createpoint,
# createlinestring,
# createlinearring,
# createpolygon,
# createmultilinestring,
# createmultipolygon

@reexport using Extents
@reexport using GeoInterface: crs
Expand Down Expand Up @@ -49,41 +49,13 @@
WellKnownText,
WellKnownText2 #=GeoJSON,=#

AG.intersects(a::Vector{AG.IGeometry{T}}, b::Vector{AG.IGeometry{X}}) where {X, T} =
AG.intersects.(a, b)
AG.equals(a::Vector{AG.IGeometry{T}}, b::Vector{AG.IGeometry{X}}) where {X, T} =
AG.equals.(a, b)
AG.disjoint(a::Vector{AG.IGeometry{T}}, b::Vector{AG.IGeometry{X}}) where {X, T} =
AG.disjoint.(a, b)
AG.touches(a::Vector{AG.IGeometry{T}}, b::Vector{AG.IGeometry{X}}) where {X, T} =
AG.touches.(a, b)
AG.crosses(a::Vector{AG.IGeometry{T}}, b::Vector{AG.IGeometry{X}}) where {X, T} =
AG.crosses.(a, b)
AG.within(a::Vector{AG.IGeometry{T}}, b::Vector{AG.IGeometry{X}}) where {X, T} =
AG.within.(a, b)
AG.contains(a::Vector{AG.IGeometry{T}}, b::Vector{AG.IGeometry{X}}) where {X, T} =
AG.contains.(a, b)
AG.overlaps(a::Vector{AG.IGeometry{T}}, b::Vector{AG.IGeometry{X}}) where {X, T} =
AG.overlaps.(a, b)
AG.intersection(a::Vector{AG.IGeometry{T}}, b::Vector{AG.IGeometry{X}}) where {X, T} =
AG.intersection.(a, b)
AG.union(a::Vector{AG.IGeometry{T}}, b::Vector{AG.IGeometry{X}}) where {X, T} =
AG.union.(a, b)
AG.difference(a::Vector{AG.IGeometry{T}}, b::Vector{AG.IGeometry{X}}) where {X, T} =
AG.difference.(a, b)
AG.symdifference(a::Vector{AG.IGeometry{T}}, b::Vector{AG.IGeometry{X}}) where {X, T} =
AG.symdifference.(a, b)
AG.distance(a::Vector{AG.IGeometry{T}}, b::Vector{AG.IGeometry{X}}) where {X, T} =
AG.distance.(a, b)

AG.boundary(v::Vector{AG.IGeometry{T}}) where {T} = AG.boundary.(v)
AG.convexhull(v::Vector{AG.IGeometry{T}}) where {T} = AG.convexhull.(v)
AG.buffer(v::Vector{AG.IGeometry{T}}, d) where {T} = AG.buffer.(v, d)
AG.transform!(v::Vector{AG.IGeometry{T}}, d) where {T} = AG.buffer.(v, d)
AG.geomlength(v::Vector{AG.IGeometry{T}}) where {T} = AG.geomlength.(v)
AG.geomarea(v::Vector{AG.IGeometry{T}}) where {T} = AG.geomarea.(v)
AG.centroid(v::Vector{AG.IGeometry{T}}) where {T} = AG.centroid.(v)
AG.isempty(v::Vector{AG.IGeometry{T}}) where {T} = AG.isempty.(v)
AG.isvalid(v::Vector{AG.IGeometry{T}}) where {T} = AG.isvalid.(v)
AG.issimple(v::Vector{AG.IGeometry{T}}) where {T} = AG.issimple.(v)
AG.isring(v::Vector{AG.IGeometry{T}}) where {T} = AG.isring.(v)
GI.boundary(v::GeometryVector) = GI.boundary.(v)
GI.convexhull(v::GeometryVector) = GI.convexhull.(v)

Check warning on line 53 in src/exports.jl

View check run for this annotation

Codecov / codecov/patch

src/exports.jl#L52-L53

Added lines #L52 - L53 were not covered by tests
GI.buffer(v::GeometryVector, d) = GI.buffer.(v, d)
GI.length(v::GeometryVector) = GI.geomlength.(v)
GI.area(v::GeometryVector) = GI.area.(v)
GI.centroid(v::GeometryVector) = GI.centroid.(v)
GI.isempty(v::GeometryVector) = GI.isempty.(v)
GI.isvalid(v::GeometryVector) = GI.isvalid.(v)
GI.issimple(v::GeometryVector) = GI.issimple.(v)
GI.isring(v::GeometryVector) = GI.isring.(v)

Check warning on line 61 in src/exports.jl

View check run for this annotation

Codecov / codecov/patch

src/exports.jl#L55-L61

Added lines #L55 - L61 were not covered by tests
12 changes: 5 additions & 7 deletions src/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ Read a file into a DataFrame. Any kwargs are passed to the driver, by default se
function read(fn; kwargs...)
ext = last(splitext(fn))
dr = driver(ext)
read(dr, fn; kwargs...)
df = read(dr, fn; kwargs...)
for geom in getgeometrycolumns(df)
df[!, geom] = GeometryVector(df[!, geom])
end
df
end

@deprecate read(fn::AbstractString, layer::Union{AbstractString, Integer}; kwargs...) read(
Expand Down Expand Up @@ -93,12 +97,6 @@ function read(driver::ArchGDALDriver, fn::AbstractString; layer=nothing, kwargs.
return t
end

@deprecate read(fn::AbstractString, layer::Union{AbstractString, Integer}; kwargs...) read(
fn;
layer,
kwargs...,
)

function read(::ArchGDALDriver, ds, layer)
df, gnames, sr = AG.getlayer(ds, layer) do table
if table.ptr == C_NULL
Expand Down
21 changes: 21 additions & 0 deletions src/vector.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""
GeometryVector(A)

A vector of geometries, as used in GeoDataFrames.
"""
struct GeometryVector{T} <: AbstractArray{T, 1}
A::Vector{T}
# TODO Add spatial index
# TODO Add crs
end

Base.parent(G::GeometryVector) = G.A
Base.size(G::GeometryVector) = size(parent(G))
Base.length(G::GeometryVector) = length(parent(G))
Base.IndexStyle(::Type{<:GeometryVector}) = IndexLinear()
# TODO Invalidate spatial index
Base.getindex(G::GeometryVector, i::Int) = getindex(parent(G), i)
Base.setindex!(G::GeometryVector, v, i::Int) = setindex!(parent(G), v, i)

# https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-array
Base.similar(G::GeometryVector, ::Type{T}, dims::Dims) where {T} = GeometryVector(similar(parent(G), T, dims))
4 changes: 2 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,10 @@ unknown_crs = GFT.WellKnownText(
end

@testset "Spatial operations" begin
table = DataFrame(; geometry = AG.createpoint.(coords), name = "test")
table = DataFrame(; geometry = GDF.GeometryVector(AG.createpoint.(coords)), name = "test")

# Buffer to also write polygons
table.geometry = AG.buffer(table.geometry, 10)
table.geometry = GDF.buffer(table.geometry, 10)
GDF.write(joinpath(testdatadir, "test_polygons.shp"), table)
GDF.write(joinpath(testdatadir, "test_polygons.gpkg"), table)
GDF.write(joinpath(testdatadir, "test_polygons.geojson"), table)
Expand Down
Loading