From f9719494be4843c986f14211e9604b9918bf81d4 Mon Sep 17 00:00:00 2001 From: Anshul Singhvi Date: Wed, 23 Apr 2025 23:06:20 -0400 Subject: [PATCH 1/5] add a geometrycolumn option we should phase out the `geocolumn` optional argument in favour of the keyword argument, this is backwards compatible and nonbreaking but we should, at some point, raise a depwarn and then make a breaking release that removes that argument. --- src/io.jl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/io.jl b/src/io.jl index 53ee59b..247671e 100644 --- a/src/io.jl +++ b/src/io.jl @@ -9,7 +9,7 @@ Write a dataframe with a geometry column to a Parquet file. Returns `ofn` on suc The geometry column should be a `Vector{GeoFormat.WellKnownBinary}` or its elements should support GeoInterface. You can construct one with WellKnownGeometry for geometries that support GeoInterface. """ -function write(ofn::Union{AbstractString,Parquet2.FilePathsBase.AbstractPath}, df, geocolumns=GI.geometrycolumns(df), crs::Union{GFT.ProjJSON,Nothing}=nothing, bbox::Union{Nothing,Vector{Float64}}=nothing; kwargs...) +function write(ofn::Union{AbstractString,Parquet2.FilePathsBase.AbstractPath}, df, geocolumns=GI.geometrycolumns(df), crs::Union{GFT.ProjJSON,Nothing}=nothing, bbox::Union{Nothing,Vector{Float64}}=nothing; geometrycolumn = geocolumns, kwargs...) # Tables.istable(df) || throw(ArgumentError("`df` must be a table")) @@ -19,7 +19,13 @@ function write(ofn::Union{AbstractString,Parquet2.FilePathsBase.AbstractPath}, d # For on the fly conversion to WKB ndf = DataFrame(df; copycols=false) - for column in geocolumns + geometrycolumns = if geometrycolumn isa Tuple || geometrycolumn isa Vector + geometrycolumn + else + (geometrycolumn,) + end + + for column in geometrycolumns column in Tables.columnnames(tcols) || error("Geometry column $column not found in table") data = Tables.getcolumn(tcols, column) GI.isgeometry(first(data)) || error("Geometry in $column must support the GeoInterface") From cbcd29bd0cc91f04d1a9c807916d10031dbd42bd Mon Sep 17 00:00:00 2001 From: Anshul Singhvi Date: Wed, 23 Apr 2025 23:06:33 -0400 Subject: [PATCH 2/5] remove Ref --- src/io.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/io.jl b/src/io.jl index 247671e..9c43f25 100644 --- a/src/io.jl +++ b/src/io.jl @@ -34,7 +34,7 @@ function write(ofn::Union{AbstractString,Parquet2.FilePathsBase.AbstractPath}, d ndf[!, column] = _getwkb.(data) end types = typeof.(unique(GI.geomtrait.(data))) - gtypes = getindex.(Ref(geowkb), types) + gtypes = getindex.((geowkb,), types) mc = MetaColumn(geometry_types=gtypes, bbox=bbox, crs=crs) columns[String(column)] = mc end From 1fd55bd1f2a99ee24b6fcf0a318228bed2a911b3 Mon Sep 17 00:00:00 2001 From: Anshul Singhvi Date: Thu, 15 May 2025 17:40:02 -0400 Subject: [PATCH 3/5] nice errors --- src/io.jl | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/io.jl b/src/io.jl index 9c43f25..603cc6a 100644 --- a/src/io.jl +++ b/src/io.jl @@ -3,14 +3,36 @@ struct Parquet2Driver <: Driver end struct QuackIODriver <: Driver end """ - write(ofn, t, columns=(:geom), crs::Union{GFT.ProjJSON,Nothing}=nothing, bbox::Union{Nothing,Vector{Float64}}=nothing; kwargs...) + write(ofn, t; geometrycolumn::Symbol, crs::Union{GFT.ProjJSON,Nothing}=nothing, bbox::Union{Nothing,Vector{Float64}}=nothing; kwargs...) Write a dataframe with a geometry column to a Parquet file. Returns `ofn` on succes. Keyword arguments are passed to Parquet2 writefile method. The geometry column should be a `Vector{GeoFormat.WellKnownBinary}` or its elements should support GeoInterface. You can construct one with WellKnownGeometry for geometries that support GeoInterface. """ -function write(ofn::Union{AbstractString,Parquet2.FilePathsBase.AbstractPath}, df, geocolumns=GI.geometrycolumns(df), crs::Union{GFT.ProjJSON,Nothing}=nothing, bbox::Union{Nothing,Vector{Float64}}=nothing; geometrycolumn = geocolumns, kwargs...) +function write(ofn::Union{AbstractString,Parquet2.FilePathsBase.AbstractPath}, df, geocolumns=nothing, crs::Union{GFT.ProjJSON,Nothing}=nothing, bbox::Union{Nothing,Vector{Float64}}=nothing; geometrycolumn = nothing, kwargs...) + if isnothing(geometrycolumn) + if isnothing(geocolumns) + # the happy path, everything is fine + geometrycolumn = GI.geometrycolumns(df) + else # the user has provided something to geocolumns + Base.depwarn("The `geocolumns` positional argument to `GeoParquet.write` is deprecated, please use the `geometrycolumn` keyword argument instead.", :var"GeoParquet.write") + geometrycolumn = geocolumns + end + else + if isnothing(geocolumns) + error(""" + It looks like you invoked `GeoParquet.write` with three arguments, but also + provided a `geometrycolumns` keyword argument. + + The third positional argument in this method, `geocolumns`, is deprecated. + Please pass geometry column information as a Symbol or Tuple of Symbols to + the `geometrycolumn` keyword argument instead, such that you only have two + positional arguments as input. + """) + end + end + # Tables.istable(df) || throw(ArgumentError("`df` must be a table")) columns = Dict{String,Any}() From af36116a35d3ef079bf1f15cb3c4578498b3cf7a Mon Sep 17 00:00:00 2001 From: Anshul Singhvi Date: Thu, 15 May 2025 17:46:34 -0400 Subject: [PATCH 4/5] final fixes --- src/io.jl | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/io.jl b/src/io.jl index 603cc6a..cd0397e 100644 --- a/src/io.jl +++ b/src/io.jl @@ -19,18 +19,16 @@ function write(ofn::Union{AbstractString,Parquet2.FilePathsBase.AbstractPath}, d Base.depwarn("The `geocolumns` positional argument to `GeoParquet.write` is deprecated, please use the `geometrycolumn` keyword argument instead.", :var"GeoParquet.write") geometrycolumn = geocolumns end - else - if isnothing(geocolumns) - error(""" - It looks like you invoked `GeoParquet.write` with three arguments, but also - provided a `geometrycolumns` keyword argument. + elseif !isnothing(geocolumns) + error(""" + It looks like you invoked `GeoParquet.write` with three arguments, but also + provided a `geometrycolumns` keyword argument. - The third positional argument in this method, `geocolumns`, is deprecated. - Please pass geometry column information as a Symbol or Tuple of Symbols to - the `geometrycolumn` keyword argument instead, such that you only have two - positional arguments as input. - """) - end + The third positional argument in this method, `geocolumns`, is deprecated. + Please pass geometry column information as a Symbol or Tuple of Symbols to + the `geometrycolumn` keyword argument instead, such that you only have two + positional arguments as input. + """) end # Tables.istable(df) || throw(ArgumentError("`df` must be a table")) @@ -61,12 +59,12 @@ function write(ofn::Union{AbstractString,Parquet2.FilePathsBase.AbstractPath}, d columns[String(column)] = mc end - md = Dict("geo" => JSON3.write(GeoParquet.MetaRoot(columns=columns, primary_column=String(geocolumns[1])))) + md = Dict("geo" => JSON3.write(GeoParquet.MetaRoot(columns=columns, primary_column=String(first(geometrycolumn)))) kw = Dict{Symbol,Any}(kwargs) get!(kw, :compression_codec, :zstd) Parquet2.writefile(ofn, ndf; metadata=md, pairs(kw)...) - ofn + return ofn end """ From c8fdd726b0c7c7c6a5b2bb51b505b1961752741d Mon Sep 17 00:00:00 2001 From: Anshul Singhvi Date: Fri, 11 Jul 2025 10:00:26 -0400 Subject: [PATCH 5/5] Update src/io.jl --- src/io.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/io.jl b/src/io.jl index cd0397e..34301c0 100644 --- a/src/io.jl +++ b/src/io.jl @@ -59,7 +59,7 @@ function write(ofn::Union{AbstractString,Parquet2.FilePathsBase.AbstractPath}, d columns[String(column)] = mc end - md = Dict("geo" => JSON3.write(GeoParquet.MetaRoot(columns=columns, primary_column=String(first(geometrycolumn)))) + md = Dict("geo" => JSON3.write(GeoParquet.MetaRoot(columns=columns, primary_column=String(first(geometrycolumn))))) kw = Dict{Symbol,Any}(kwargs) get!(kw, :compression_codec, :zstd)