Skip to content

Quick start

Use ordinary DataFrames with one or more columns of GeoInterface-compatible geometries.

julia
using GeoDataFrames

points = GeoInterface.Point.([(4.89, 52.37), (4.90, 52.38)])  # point geometry
df = DataFrame(geometry=points, name="test");
2×2 DataFrame
Rowgeometryname
Point…String
1Point((4.89,52.37))test
2Point((4.9,52.38))test

Read and inspect

Read a vector file into a DataFrame by providing a filename or url:

julia
df = GeoDataFrames.read("https://github.com/yeesian/ArchGDALDatasets/raw/refs/heads/master/ospy/data1/sites.shp")
(rows=nrow(df), geometrycolumns=GeoInterface.geometrycolumns(df), crs=GeoInterface.crs(df))
(rows = 42, geometrycolumns = (:geometry,), crs = WellKnownText{GeoFormatTypes.CRS}(GeoFormatTypes.CRS(), "PROJCS[\"WGS 84 / UTM zone 12N\",GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4326\"]],PROJECTION[\"Transverse_Mercator\"],PARAMETER[\"latitude_of_origin\",0],PARAMETER[\"central_meridian\",-111],PARAMETER[\"scale_factor\",0.9996],PARAMETER[\"false_easting\",500000],PARAMETER[\"false_northing\",0],UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],AXIS[\"Easting\",EAST],AXIS[\"Northing\",NORTH],AUTHORITY[\"EPSG\",\"32612\"]]"))

Basic operation with lines and polygons

Geometry operations apply to GeoInterface geometries in your table.

julia
using NaturalEarth
using GeoDataFrames: setcrs!

countries = select(
    DataFrame(naturalearth("admin_0_countries", 50)),
    :NAME,
    :geometry,
)
rivers = select(
    DataFrame(naturalearth("rivers_lake_centerlines", 50)),
    :name_en,
    :geometry,
)

candidate_countries = subset(
    countries,
    :NAME => ByRow(
        name -> name in ["Austria", "Germany", "Hungary", "Poland", "Romania"],
    ),
)
danube = subset(rivers, :name_en => ByRow(isequal("Danube")))

selected = subset(
    candidate_countries,
    :geometry => ByRow(
        country -> any(
            river -> intersects(country, river),
            danube.geometry,
        ),
    ),
)
selected.NAME
4-element Vector{String}:
 "Romania"
 "Hungary"
 "Germany"
 "Austria"

Plot geometries

julia
using CairoMakie

fig = plot(
    candidate_countries.geometry;
    color = (:lightgray, 0.35),
    strokecolor = :gray,
    axis = (; title = "Countries intersected by the Danube"),
)
plot!(selected.geometry; color = (:tomato, 0.5), strokecolor = :tomato)
plot!(danube.geometry; color = :dodgerblue, linewidth = 3)
fig

Write

Write any Tables.jl-compatible table that has geometry metadata (or pass geometrycolumn/crs keywords when needed):

julia
tmp = mktempdir()
path = joinpath(tmp, "zones.gpkg")
GeoDataFrames.write(path, candidate_countries)
isfile(path)
true

For layers, advanced ArchGDAL options, native-driver behavior, metadata management, reprojection, spatial joins, and performance trade-offs, use the how-to guides and reference.