# Read Geopackage Layers to dataframe

**URL:** https://discourse.julialang.org/t/read-geopackage-layers-to-dataframe/35837
**Category:** Geo
**Tags:** question
**Created:** [March 11, 2020, 10:29am UTC](https://discourse.julialang.org/t/read-geopackage-layers-to-dataframe/35837 "2020-03-11T10:29:33Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![patrickplagowski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/patrickplagowski/32/8469_2.png) [@patrickplagowski](https://discourse.julialang.org/u/patrickplagowski)
#### Post date: [March 11, 2020, 10:29am UTC](https://discourse.julialang.org/t/read-geopackage-layers-to-dataframe/35837/1 "2020-03-11T10:29:33Z")

</div>

Hi everyone,  
I started applying ArchGDAL to read geopackage layers. How can one read geopackage layers to dataframes (like geopandas in python)?  
Motivation: I’d like to avoid for loops and many if/else statements in the loop because I think the codes are more readable and compact with dataframe filters.

---

<div class="post-metadata">

### Author: ![visr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/visr/32/17204_2.png) [@visr](https://discourse.julialang.org/u/visr)
#### Post date: [March 11, 2020, 3:15pm UTC](https://discourse.julialang.org/t/read-geopackage-layers-to-dataframe/35837/2 "2020-03-11T15:15:10Z")

</div>

For this to become easy, we’d probably need to add Tables.jl support to ArchGDAL.jl first ([Update from DataStreams.jl to Tables.jl · Issue #69 · yeesian/ArchGDAL.jl · GitHub](https://github.com/yeesian/ArchGDAL.jl/issues/69)). However looking at the old DataStreams support code in ArchGDAL, we can relatively easily hack something together:

```julia
using ArchGDAL
const AG = ArchGDAL
using DataFrames

dataset = AG.read("point.geojson")
layer = AG.getlayer(dataset, 0)

nfeat = AG.nfeature(layer)
nfield = AG.nfield(layer)

# prepare Dict with empty vectors of the right type for each field
d = Dict{String, Vector}()
featuredefn = AG.layerdefn(layer)
for field_no in 0:nfield-1
    field = AG.getfielddefn(featuredefn, field_no)
    name = AG.getname(field)
    typ = AG._FIELDTYPE[AG.gettype(field)]
    d[name] = typ[]
end
d["geometry"] = AG.IGeometry[]

# loop over the features to fill the vectors in the Dict
for fid in 0:nfeat-1
    AG.getfeature(layer, fid) do feature
        for (k, v) in pairs(d)
            if k == "geometry"
                val = AG.getgeom(feature, 0)
            else
                val = AG.getfield(feature, k)
            end
            push!(v, val)
        end
    end
end

# construct a DataFrame from the Dict
df = DataFrame(d)
println(df)

```

Which gives:

```nohighlight
4×3 DataFrame
│ Row │ FID │ geometry │ pointname │
│ │ Float64 │ ArchGDAL.IGeometry │ String │
├─────┼─────────┼───────────────────────────────────┼───────────┤
│ 1 │ 2.0 │ Geometry: POINT (100 0) │ point-a │
│ 2 │ 3.0 │ Geometry: POINT (100.2785 0.0893) │ point-b │
│ 3 │ 0.0 │ Geometry: POINT (100 0) │ a │
│ 4 │ 3.0 │ Geometry: POINT (100.2785 0.0893) │ b │

```

This is assuming you want to keep the geometries as GDAL objects. If you want you can also first convert the geometries to a different representation, depending on your needs.

Note that this is just a DataFrame with a geometry column, and you don’t get special geospatial behavior (spatial joins etc.) with it, as in geopandas. That said, this is something I’d like to work towards. There is [GeoDataFrames.jl](https://github.com/yeesian/GeoDataFrames.jl) which could be revived. But I also shared some thoughts on it here: [JuliaGeo talk at FOSS4G 2019 - #8 by visr](https://discourse.julialang.org/t/juliageo-talk-at-foss4g-2019/28425/8) and in the [README of GeoJSONTables.jl](https://github.com/visr/GeoJSONTables.jl). Finishing up [GeoInterfaceRFC.jl](https://github.com/yeesian/GeoInterfaceRFC.jl) will also help here. Plenty of work to do, any help is more than welcome 🙂
