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

[WIP]Update from DataStreams to Tables #113

Closed
wants to merge 8 commits into from
Closed
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
7 changes: 3 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,21 @@ desc = "A high level API for GDAL - Geospatial Data Abstraction Library"
version = "0.3.1"

[deps]
DataStreams = "9a8bc11e-79be-5b39-94d7-1ccc349a1a85"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
GDAL = "add2ef01-049f-52c4-9ee2-e494f65e021a"
GeoInterface = "cf35fbd7-0cd7-5166-be24-54bfbe79505f"
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"

[compat]
DataStreams = "0.4.2"
GDAL = "1.0.2"
GeoInterface = "0.4, 0.5"
Tables = "1"
julia = "1"

[extras]
BinaryProvider = "b99e7846-7c00-51b0-8f62-c81ae34c0232"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Dates", "Statistics", "Test", "BinaryProvider"]
test = ["BinaryProvider", "Statistics", "Test"]
4 changes: 2 additions & 2 deletions src/ArchGDAL.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module ArchGDAL

import GDAL, GeoInterface
import DataStreams: Data
using Tables: Tables
import GeoInterface: coordinates, geotype
using Dates

Expand All @@ -26,7 +26,7 @@ module ArchGDAL
include("context.jl")
include("base/iterators.jl")
include("base/display.jl")
include("datastreams.jl")
include("tables.jl")
include("geointerface.jl")

mutable struct DriverManager
Expand Down
68 changes: 68 additions & 0 deletions src/tables.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
struct GeoTable{T <: NamedTuple} <:AbstractVector{T}
parsed_shapefile::T
end

function geotable(layer::Union{IFeatureLayer, FeatureLayer}, i::Int)
featuredefn = layerdefn(layer)
ngeometries = ngeom(featuredefn)
nfield = ArchGDAL.nfield(featuredefn)
featuredefn = layerdefn(layer)
nfeat = nfeature(layer)

d = Dict{String, Vector}()

for field_no in 0:nfield-1
field = getfielddefn(featuredefn, field_no)
name = getname(field)
typ = _FIELDTYPE[gettype(field)]
d[name] = typ[]
end

d["geometry"] = IGeometry[]

for fid in 0:nfeat-1
getfeature(layer, fid) do feature
for (k, v) in pairs(d)
if k == "geometry"
val = getgeom(feature, 0)
else
val = getfield(feature, k)
end
push!(v, val)
end
end
end
keys_tup = ()
for _key in keys(d)
keys_tup = (keys_tup..., Symbol(_key))
end
vals_tup = Tuple(values(d))

#Using the tables interface
RowTable = rowtable(NamedTuple{keys_tup}(vals_tup))
return GeoTable(reshape(RowTable, (1,length(RowTable))))
end

# "Struct representing a singe record in a shapefile"
# struct Row{T}
# ######
# end

Tables.istable(::Type{<:GeoTable}) = true
Tables.rowaccess(::Type{<:GeoTable}) = true
Tables.rows(g::GeoTable) = g

# Base.IteratorSize(::Type{<:GeoTable}) = Base.HasLength()
# Base.length(fc::GeoTable) = length(geotable(g))
# Base.IteratorEltype(::Type{<:GeoTable}) = Base.HasEltype()


# "Iterate over the rows of a Shapefile.Table, yielding a Shapefile.Row for each row"
# Base.iterate(g::GeoTable, st=1) = st > length(g) ? nothing : (Row(st, g), st + 1




# Tables.schema(g::geotable) = Tables.Schema()


2 changes: 1 addition & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ include("remotefiles.jl")
@testset "ArchGDAL" begin
cd(dirname(@__FILE__)) do
isdir("tmp") || mkpath("tmp")
include("test_datastreams.jl")
include("test_tables.jl")
include("test_gdal_tutorials.jl")
include("test_geometry.jl")
include("test_types.jl")
Expand Down
64 changes: 64 additions & 0 deletions test/test_tables.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using Test
import ArchGDAL; const AG = ArchGDAL
using Tables

# @testset "DataStream Support" begin
# df = AG.read("data/point.geojson") do dataset
# DataStreams.Data.close!(DataStreams.Data.stream!(
# AG.Source(AG.getlayer(dataset,0)), DataStreams.Data.Table
# ))
# end
# @test df.FID == [2.0, 3.0, 0.0, 3.0]
# @test df.pointname == ["point-a", "point-b", "a", "b"]
# @test AG.toWKT.(df.geometry0) == [
# "POINT (100 0)",
# "POINT (100.2785 0.0893)",
# "POINT (100 0)",
# "POINT (100.2785 0.0893)"
# ]
# end

dataset = AG.read(joinpath(@__DIR__, "data/point.geojson"))
layer = AG.getlayer(dataset, 0)

nfeat = AG.nfeature(layer)
nfield = AG.nfield(layer)
featuredefn = AG.layerdefn(layer)
ngeometries = AG.ngeom(featuredefn)

Tables.istable(layer::AG.AbstractFeatureLayer) = true
Tables.rowaccess(layer::AG.AbstractFeatureLayer) = true

function Tables.schema(layer::AG.AbstractFeatureLayer)
# TODO include names and types of geometry columns
featuredefn = AG.layerdefn(layer)
fielddefns = (AG.getfielddefn(featuredefn, i) for i in 0:nfield-1)
names = Tuple(AG.getname(fielddefn) for fielddefn in fielddefns)
types = Tuple(AG._FIELDTYPE[AG.gettype(fielddefn)] for fielddefn in fielddefns)
Tables.Schema(names, types)
end

schema = Tables.schema(layer)

function Tables.rows(layer::AG.AbstractFeatureLayer)
# TODO return an iterator rather than a vector of NamedTuples
schema = Tables.schema(layer)
T = NamedTuple{schema.names, Tuple{schema.types...}}
AG.resetreading!(layer)
nfeat = AG.nfeature(layer)
nfield = AG.nfield(layer)
rows = T[]
for _ in 1:nfeat
AG.nextfeature(layer) do feature
# AG.getgeom(feature, 0) # TODO
push!(rows, T(AG.getfield(feature, j) for j in 0:nfield-1))
end
end
return rows
end

Tables.rows(layer)

# TODO getcolumn support
# using DataFrames
# DataFrame(layer)