Skip to content

Commit

Permalink
Add support for the GeoParquet file format (#4)
Browse files Browse the repository at this point in the history
* Add support for the GeoParquet file format

* Apply suggestions from code review
  • Loading branch information
eliascarv authored Aug 30, 2023
1 parent 81b0b94 commit 5a1eb89
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
GADM = "a8dd9ffe-31dc-4cf5-a379-ea69100a8233"
GeoInterface = "cf35fbd7-0cd7-5166-be24-54bfbe79505f"
GeoJSON = "61d90e0f-e114-555e-ac52-39dfb47a3ef9"
GeoParquet = "e99870d8-ce00-4fdd-aeee-e09192881159"
ImageIO = "82e4d734-157c-48bb-816b-45c225c6df19"
Meshes = "eacbb407-ea5a-433e-ab97-5258b1ca43fa"
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
Expand All @@ -21,6 +22,7 @@ FileIO = "1.16"
GADM = "1.0"
GeoInterface = "1.0"
GeoJSON = "0.7"
GeoParquet = "0.1"
ImageIO = "0.6"
Meshes = "0.33, 0.34"
PrecompileTools = "1.2"
Expand Down
5 changes: 5 additions & 0 deletions src/GeoIO.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import FileIO
import Shapefile as SHP
import GeoJSON as GJS
import ArchGDAL as AG
import GeoParquet as GPQ
import GeoInterface as GI

include("conversion.jl")
Expand Down Expand Up @@ -57,6 +58,8 @@ function load(fname; layer=0, lazy=false, kwargs...)
elseif endswith(fname, ".geojson")
data = Base.read(fname)
GJS.read(data; kwargs...)
elseif endswith(fname, ".parquet")
GPQ.read(fname; kwargs...)
else # fallback to GDAL
data = AG.read(fname; kwargs...)
AG.getlayer(data, layer)
Expand Down Expand Up @@ -86,6 +89,8 @@ function save(fname, geotable; kwargs...)
SHP.write(fname, geotable; kwargs...)
elseif endswith(fname, ".geojson")
GJS.write(fname, geotable; kwargs...)
elseif endswith(fname, ".parquet")
GPQ.write(fname, geotable, (:geometry,); kwargs...)
else # fallback to GDAL
agwrite(fname, geotable; kwargs...)
end
Expand Down
2 changes: 1 addition & 1 deletion src/conversion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ end

function tochain(geom, is3d::Bool)
points = topoints(geom, is3d)
if GI.isclosed(geom)
if first(points) == last(points)
# fix backend issues: https://github.com/JuliaEarth/GeoTables.jl/issues/32
while first(points) == last(points) && length(points) 2
pop!(points)
Expand Down
3 changes: 3 additions & 0 deletions src/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ using PrecompileTools
load(joinpath(datadir, "points.geojson"))
load(joinpath(datadir, "lines.geojson"))
load(joinpath(datadir, "polygons.geojson"))
load(joinpath(datadir, "points.parquet"))
load(joinpath(datadir, "lines.parquet"))
load(joinpath(datadir, "polygons.parquet"))
load(joinpath(datadir, "field.kml"))
load(joinpath(datadir, "points.gpkg"))
load(joinpath(datadir, "lines.gpkg"))
Expand Down
Binary file added test/data/lines.parquet
Binary file not shown.
Binary file added test/data/points.parquet
Binary file not shown.
Binary file added test/data/polygons.parquet
Binary file not shown.
30 changes: 30 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,36 @@ end
@test GeoIO.load(joinpath(datadir, "lines.gpkg")) isa Meshes.MeshData
@test GeoIO.load(joinpath(datadir, "lines.gpkg"), lazy=true) isa GeoIO.GeoTable
end

@testset "GeoParquet" begin
table = GeoIO.load(joinpath(datadir, "points.parquet"))
@test length(table.geometry) == 5
@test table.code[1] isa Integer
@test table.name[1] isa String
@test table.variable[1] isa Real
@test table.geometry isa PointSet
@test table.geometry[1] isa Point

table = GeoIO.load(joinpath(datadir, "lines.parquet"))
@test length(table.geometry) == 5
@test table.code[1] isa Integer
@test table.name[1] isa String
@test table.variable[1] isa Real
@test table.geometry isa GeometrySet
@test table.geometry[1] isa Chain

table = GeoIO.load(joinpath(datadir, "polygons.parquet"))
@test length(table.geometry) == 5
@test table.code[1] isa Integer
@test table.name[1] isa String
@test table.variable[1] isa Real
@test table.geometry isa GeometrySet
@test table.geometry[1] isa PolyArea

# lazy loading
@test GeoIO.load(joinpath(datadir, "lines.parquet")) isa Meshes.MeshData
@test GeoIO.load(joinpath(datadir, "lines.parquet"), lazy=true) isa GeoIO.GeoTable
end
end

@testset "save" begin
Expand Down

0 comments on commit 5a1eb89

Please sign in to comment.