Skip to content
Merged
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
5 changes: 1 addition & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ permissions:
contents: read
jobs:
test:
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ github.event_name }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
Expand All @@ -23,14 +23,11 @@ jobs:
- ubuntu-latest
- macOS-latest
- windows-latest
arch:
- x64
steps:
- uses: actions/checkout@v5
- uses: julia-actions/setup-julia@v2
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
- uses: julia-actions/cache@v2
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1
Expand Down
2 changes: 1 addition & 1 deletion src/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Other supported kwargs are passed to the [ArchGDAL read](https://yeesian.com/Arc
The `options` keyword argument can be used to pass GDAL open options.
"""
function read(driver::ArchGDALDriver, fn::AbstractString; layer = nothing, kwargs...)
_isvalidlocal(fn) || error("File not found.")
_isvalidlocal(fn) || error("Can't find local file $fn.")
t = AG.read(fn; kwargs...) do ds
ds.ptr == C_NULL && error("Unable to open $fn.")
if AG.nlayer(ds) > 1 && isnothing(layer)
Expand Down
6 changes: 5 additions & 1 deletion src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -211,5 +211,9 @@ function _reproject(
end

function _isvalidlocal(fn)
startswith(fn, "/vsi") || occursin(":", fn) || isfile(fn) || isdir(fn)
startswith(fn, "/vsi") ||
startswith(fn, "\\\\") ||
occursin("://", fn) ||
isfile(fn) ||
isdir(fn)
end
62 changes: 45 additions & 17 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ end

@testitem "Read non-existent shapefile" setup = [Setup] begin
fne = "/bla.shp"
@test_throws ErrorException("File not found.") GDF.read(fne)
@test_throws ErrorException("Can't find local file /bla.shp.") GDF.read(fne)
end

@testitem "Read shapefile with layer id" setup = [Setup] begin
Expand Down Expand Up @@ -211,7 +211,6 @@ end
GI.isfeaturecollection(::Vector{<:NamedTuple}) = true
GI.geomtrait(::Vector{<:NamedTuple}) = GI.FeatureCollectionTrait() # TODO Make issue GeoInterface.jl
GI.crs(::GI.FeatureCollectionTrait, ::Vector{<:NamedTuple}) = nothing
GI.isfeaturecollection(::Vector{<:NamedTuple}) = true
Comment thread
evetion marked this conversation as resolved.
GI.geometrycolumns(::Vector{<:NamedTuple}) = (:foo,)
@test isfile(GDF.write(tfn, table))
end
Expand Down Expand Up @@ -250,7 +249,7 @@ end

@testitem "Non existing Windows path #78" setup = [Setup] begin
wfn = "C:\\non_existing_folder\\non_existing_file.shp"
@test_throws ErrorException("Unable to open $wfn.") GDF.read(wfn)
@test_throws ErrorException("Can't find local file $wfn.") GDF.read(wfn)
end

@testitem "Shapefile" setup = [Setup] begin
Expand Down Expand Up @@ -312,8 +311,8 @@ end
GDF.write(GDF.ArchGDALDriver(), "test.fgb", df2)
end

@testitem "GeoParquet" setup = [Setup] begin
Sys.iswindows() && return # Skip on Windows. See GDAL.jl#146
# Skip on Windows. See GDAL.jl#146
@testitem "GeoParquet" setup = [Setup] tags = [:nowindows] begin
using GeoParquet
fn = joinpath(testdatadir, "example.parquet")
df = GDF.read(fn)
Expand All @@ -333,7 +332,7 @@ end
using GeoArrow
fn = joinpath(testdatadir, "example-multipolygon_z.arrow")
df = GDF.read(fn)
ENV["OGR_ARROW_ALLOW_ALL_DIMS"] = "YES"
AG.setconfigoption("OGR_ARROW_ALLOW_ALL_DIMS", "YES")
Comment thread
asinghvi17 marked this conversation as resolved.
df2 = GDF.read(GDF.ArchGDALDriver(), fn)
@test sort(names(df)) == sort(names(df2))
@test nrow(df) == nrow(df2)
Expand All @@ -348,19 +347,46 @@ end
end

@testitem "Combination of drivers" setup = [Setup] begin
broken_combos = [
(GDF.GeoParquetDriver(), GDF.ShapefileDriver()), # ArgumentError: Shapefiles can only contain geometries of the same type
(GDF.GeoParquetDriver(), GDF.FlatGeobufDriver()), # ICreateFeature: Mismatched geometry type. Feature geometry type is Polygon, expected layer geometry type is Multi Polygon
(GDF.GeoArrowDriver(), GDF.ArchGDALDriver()), # BoundsError: attempt to access @NamedTuple{x::Union{Missing, Float64}, y::Union{Missing, Float64}, z::Union{Missing, Float64}} at index [4]
(GDF.GeoArrowDriver(), GDF.GeoJSONDriver()), # ArgumentError: reducing over an empty collection is not allowed; consider supplying `init` to the reducer
(GDF.GeoArrowDriver(), GDF.ShapefileDriver()), # BoundsError: attempt to access @NamedTuple{x::Union{Missing, Float64}, y::Union{Missing, Float64}, z::Union{Missing, Float64}} at index [4]
(GDF.GeoArrowDriver(), GDF.FlatGeobufDriver()), # BoundsError: attempt to access @NamedTuple{x::Union{Missing, Float64}, y::Union{Missing, Float64}, z::Union{Missing, Float64}} at index [4]
(GDF.GeoArrowDriver(), GDF.GeoArrowDriver()), # BoundsError: attempt to access @NamedTuple{x::Union{Missing, Float64}, y::Union{Missing, Float64}, z::Union{Missing, Float64}} at index [4]
(GDF.GeoArrowDriver(), GDF.GeoParquetDriver()), # UndefVarError: `wkbZM` not defined in `WellKnownGeometry`
(GDF.ArchGDALDriver(), GDF.GeoArrowDriver()), # exception = TypeError: in Vararg, in count, expected Int64, got a value of type Int32
]
if Sys.iswindows()
# GDAL.jl#146, GeoParquet on Windows is broken
push!(broken_combos, (GDF.ArchGDALDriver(), GDF.GeoParquetDriver()))
push!(broken_combos, (GDF.ShapefileDriver(), GDF.GeoParquetDriver()))
push!(broken_combos, (GDF.GeoJSONDriver(), GDF.GeoParquetDriver()))
push!(broken_combos, (GDF.FlatGeobufDriver(), GDF.GeoParquetDriver()))
push!(broken_combos, (GDF.GeoArrowDriver(), GDF.GeoParquetDriver()))
push!(broken_combos, (GDF.GeoParquetDriver(), GDF.ArchGDALDriver())) # not sure why this one fails
push!(broken_combos, (GDF.GeoParquetDriver(), GDF.ShapefileDriver())) # not sure why this one fails
push!(broken_combos, (GDF.GeoParquetDriver(), GDF.GeoJSONDriver())) # not sure why this one fails
push!(broken_combos, (GDF.GeoParquetDriver(), GDF.FlatGeobufDriver())) # not sure why this one fails
push!(broken_combos, (GDF.GeoParquetDriver(), GDF.GeoArrowDriver())) # not sure why this one fails
push!(broken_combos, (GDF.GeoParquetDriver(), GDF.GeoParquetDriver())) # not sure why this one fails
end

drivers = [
(GDF.ArchGDALDriver(), "test.gpkg", true, (;))
(GDF.GeoJSONDriver(), "test.geojson", true, (;))
(GDF.ShapefileDriver(), "test.shp", false, (; force = true))
(GDF.FlatGeobufDriver(), "test.fgb", false, (;)) # No write support yet
(GDF.GeoParquetDriver(), "test_native.parquet", true, (;))
(GDF.ArchGDALDriver(), "test.gpkg", (;))
(GDF.GeoJSONDriver(), "test.geojson", (;))
(GDF.ShapefileDriver(), joinpath(testdatadir, "sites.shp"), (; force = true))
(GDF.FlatGeobufDriver(), joinpath(testdatadir, "countries.fgb"), (;)) # No write support yet
(GDF.GeoParquetDriver(), joinpath(testdatadir, "example.parquet"), (;))
(GDF.GeoArrowDriver(), joinpath(testdatadir, "example-multipolygon_z.arrow"), (;)) # Broken
]
for ((driver, fn, can_write), (driver_b, fn_b, can_write_b, kwargs)) in
for ((driver_in, fn_in), (driver_out, fn_out, kwargs)) in
Iterators.product(drivers, drivers)
can_write_b || continue
@debug "Testing $driver with $driver_b"
df = GDF.read(driver, fn)
GDF.write(driver_b, "temp" * fn_b, df; kwargs...)
(driver_in, driver_out) in broken_combos && continue
@info "Testing reading with $driver_in and writing with $driver_out."
df = GDF.read(driver_in, fn_in)
GDF.write(driver_out, "temp" * basename(fn_out), df; kwargs...)
end
end

Expand Down Expand Up @@ -418,4 +444,6 @@ end
@test GI.geometrycolumns(t) == (:geom,)
end

@run_package_tests
filter(ti) = !(:nowindows in ti.tags && Sys.iswindows())

@run_package_tests filter = filter
Loading