GeoDataAccess.jl

GeoDataAccess.jl is a Julia package for collecting geospatial data from multiple public APIs. It provides a unified interface across weather, hydrology, seismology, air quality, and more — with built-in caching and GeoInterface.jl integration for flexible spatial queries.

Data Sources

Source Type Coverage Resolution API Key
OpenMeteoArchive Raster (ERA5) Global, 1940–present Hourly/Daily, 25 km No
OpenMeteoForecast Raster Global, 16-day forecast Hourly/Daily, 9 km No
NOAANCEI Station-based Global stations, 1763–present Daily No
NASAPower Raster Global, 1981–present Daily, 55 km No
TomorrowIO Raster Global, 2000–present Hourly/Daily, 4 km Yes
VisualCrossing Raster Global, ~50 years Daily/Hourly, 1 km Yes
USGSEarthquake Event-based Global catalog Event-based No
USGSWaterServices Station-based US, 1.5M+ sites Daily/15-min No
OpenAQ Station-based Global, 11K+ stations Hourly/Daily Yes
NASAFIRMS Event-based Global, near real-time 375 m / 1 km Yes
EPAAQS Station-based US stations Hourly/Daily Yes
LandfireSource Raster CONUS, AK, HI 30 m No (email)
NOAAGFS Raster (GRIB2) Global, forecast 0.25° (~25 km) No
ERA5 Raster (NetCDF/GRIB) Global, 1940–present 0.25° (~25 km) Yes

Installation

using Pkg
Pkg.add("GeoDataAccess")

Quickstart

The core workflow is: create a DataAccessPlan, inspect it, then fetch to download the data as JSON files.

using GeoDataAccess
using GeoDataAccess: DataAccessPlan, fetch, OpenMeteoArchive
using Dates

# Create a plan: hourly temperature and precipitation for NYC
plan = DataAccessPlan(OpenMeteoArchive(), (-74.0, 40.7),
    Date(2024, 7, 1), Date(2024, 7, 3);
    variables = [:temperature_2m, :precipitation],
    frequency = :hourly)
DataAccessPlan for openmeteoarchive
  Extent:    Point(40.7, -74.0)
  Time:      2024-07-01 to 2024-07-03 (3 days)
  Variables: temperature_2m, precipitation
  frequency: hourly
  timezone: GMT
  API calls: 1
  Est. size: 1.125 KiB

  Request 1: GET 1 point(s), hourly 3 days → openmeteoarchive/3669ebf219e4f089.json
# Execute the plan — returns file paths to cached JSON
files = fetch(plan)
1-element Vector{String}:
 "/home/runner/.julia/scratchspac" ⋯ 68 bytes ⋯ "oarchive/3669ebf219e4f089.json"
# Read the JSON data
using JSON
data = JSON.parsefile(files[1])
keys(data)
KeySet for a JSON.Object{String, Any} with 9 entries. Keys:
  "latitude"
  "longitude"
  "generationtime_ms"
  "utc_offset_seconds"
  "timezone"
  "timezone_abbreviation"
  "elevation"
  "hourly_units"
  "hourly"

Or skip the plan and call fetch directly on a source:

using GeoDataAccess: fetch, OpenMeteoArchive

files = fetch(OpenMeteoArchive(), (-74.0, 40.7),
    Date(2024, 7, 1), Date(2024, 7, 3);
    variables = [:temperature_2m, :precipitation],
    frequency = :hourly)
1-element Vector{String}:
 "/home/runner/.julia/scratchspac" ⋯ 68 bytes ⋯ "oarchive/3669ebf219e4f089.json"