overtureR 0.3.0
Faster queries
open_curtain()now reads only the Parquet files whose bounding box touchesspatial_filter, using the per-file bounding boxes in Overture’s STAC catalog, instead of every file in the partition. A cold city-sizedbuildingquery drops from about 87 seconds to a few seconds, because DuckDB reads 1 to 3 Parquet footers rather than 512. The catalog is read once per release, type and session and cached on disk undertools::R_user_dir("overtureR", "cache")(releases never change, so the cache never goes stale). Turn pruning off withoptions(overturer_prune = FALSE), move or disable the cache withoptions(overturer_cache_dir = )andoptions(overturer_cache = FALSE), or clear it with the newclear_overture_cache().sf_as_dbplyr()(and sosfandsfcspatial filters) sends geometry to DuckDB as well-known binary instead of well-known text. Uploading 5,000 polygons drops from about 14 seconds to under 0.1 seconds, and coordinates keep full precision.An
sfspatial filter is now uploaded once and its union kept in a small temporary table, instead of leaving a registered data frame and two views behind and re-runningST_Union_Agg()on every query.Connections created by
stage_conn()(and any connection passed toopen_curtain()) enable DuckDB’s Parquet metadata and HTTP metadata caches, so repeated queries against the same files skip re-reading their footers.
New
open_curtain()gains areleaseargument to pin a query to one Overture release, such as"2026-08-19.0", instead of whichever release is latest when the script runs. Setoptions(overturer_release = )to pin a whole session. The release is recorded on the result, and the newprint()method foroverture_callobjects shows it.base_urlnow defaults toNULLand is built fromrelease.open_curtain()gains apredicateargument:"intersects"(the default),"within"or"contains", so a polygon filter can keep only the features fully inside it, or a point can find the feature around it.overture_releases()lists the releases Overture currently hosts.overture_types()lists thetypeandthemepairs in a release, read from Overture’s catalog, so new types appear without a package update. The built-in table (now includingbathymetry) is the offline fallback, andopen_curtain()names the valid types when given one it doesn’t know.clear_overture_cache()removes the catalog cache.
Local copies
record_overture()writes an_overture.jsonmanifest into eachtype=directory it creates, recording the source release and the bounding box of every file.open_curtain()on such a copy reads only the files that touchspatial_filter, and labels the result with the release it came from.record_overture()gainspartition_by, for extra partition columns belowthemeandtype, andgrid, which partitions the copy into cells of a given size in degrees so large local copies also skip files by location.record_overture()can download in one call: pass a type name and aspatial_filter(plus any otheropen_curtain()arguments) instead of anoverture_call.record_overture()withoverwrite = TRUEreplaces thetheme=/type=directories it is about to write instead of writing new files next to the old ones, so a re-recorded copy holds only the new rows. Other files inoutput_dirare untouched. Written files get unique names (data_<uuid>.parquet), so DuckDB’s Parquet metadata cache never serves a stale footer for a rewritten copy.record_overture()quotesoutput_dir, so a path containing'works.
Fixes
open_curtain()withtype = "*"setsunion_by_name = TRUE, so the different columns of the types in a theme read together.overtureR installs and loads DuckDB’s
jsonextension, which the duckdb R package stopped bundling in 1.5.5, so reading Overture’s catalog works there.sf,sfcandbboxspatial filters in a coordinate reference system other than EPSG:4326 are transformed before filtering. Previously their raw coordinates were compared with Overture’s longitude and latitude, which silently returned no rows or the wrong rows. A filter with no coordinate reference system is assumed to be EPSG:4326, with a warning.stage_conn()now passesdbdir,read_only,bigintandconfigon to duckdb. Before, only...reachedDBI::dbConnect(), sostage_conn(dbdir = "x.duckdb")silently opened an in-memory database.stage_conn()registers its shutdown finalizer once rather than on every call, andstrike_stage()no longer opens a new connection just to close it when none is cached.collect()checks the geometry column’s type before converting it. A column that is already well-known binary (for example aftermutate(geometry = ST_AsWKB(geometry))) is used as is, and a non-spatial column namedgeometryis left alone, where both used to fail with a binder error. Geometry is converted withsf::st_as_sfc()rather than through GDAL, which removes theOGR: Unsupported geometry typemessage on places data. Extra arguments such ascollect(x, crs = 3857)now work.latest_overture_release()no longer falls back to a hardcoded release when the catalog is unreachable, because Overture removes releases after a few months and the hardcoded one would itself fail. It now uses the newest release in the local catalog cache with a warning, or fails with an error that points tobase_url.An unnamed numeric
spatial_filtergives a clear error instead ofsubscript out of bounds. Passing a singlesfgpoint works.record_overture()checks its input before touching the connection.Fixed examples that called a non-existent
exit_stage()and passed an undefinedbbox, and the getting-started article’s references tocollect_sf.
Dependencies
- overtureR now requires duckdb 1.1.0 or later, and drops the code paths for older versions (manual WKB casts and the duckdb 1.1.3 extension workaround).
Tests
- The test suite now runs offline against a few hundred Overture features saved under
tests/testthat/fixtures/, plus a miniature of Overture’s STAC catalog. It covers each SQL builder, every filter kind, the catalog cache, and a regression test for each fix above. Three tests still read the live release; they run locally and on a weekly schedule, not on every push.
overtureR 0.2.6
Bundle an agent skill at
inst/skills/overturer/teaching AI coding agents the package’s API and idioms - chiefly accessing Overture’s nested struct columns with$(names$primary), lazy-then-collect()evaluation, and thetype->thememapping. ShipsSKILL.mdplusreferences/data-model.md(schema and type/theme table) andreferences/overture-context.md(Overture themes, GERS stable ids, licensing/attribution, release cadence, and links). Discoverable by tools following theinst/skills/convention (e.g. Posit’sbtw).open_curtain()’sbase_urlno longer hardcodes a specific Overture release. It now defaults to the latest release, discovered dynamically via the new exportedlatest_overture_release()(queries Overture’s STAC catalog and caches the result for the session), so the package doesn’t need a release-bump update every time Overture cuts a new release.Fix
record_overture()producing local Parquet files that couldn’t becollect()-ed back on duckdb >= 1.1: geometry was being pre-cast to WKB before writing, which loses the GeoParquet metadata that tells DuckDB to read the column back as nativeGEOMETRY, so the laterST_AsWKB()call incollect()failed on what was now a plainBLOBcolumn. The WKB cast is now skipped on duckdb >= 1.1, matching howopen_curtain()already treats those versions.
overtureR 0.2.3
CRAN release: 2024-09-04
- Fix for bug in
duckdb1.1.3. - Update for post 1.1.0 native duckdb geometry reading
- Update URL to November 2024 Overture release.
overtureR 0.2.0
Add support for downloading Overture Maps data via
record_overtureandsnapshot_overture. These functions return a lazy ‘overture_call’ dataframe linked to the new local dataset.The second parameter to
open_curtainhas changed from ‘bbox’ to ‘spatial_filter’, which allows both bounding boxes (named vector or class ‘bbox’), ‘sf’ objects, or anotherdbplyrdataframe (e.g. a differentovertureRdataset/table. In the latter two cases, the data will first be filtered by the bounding box ofspatial_filter, then geographically if necessary. Filtering is currently by intersection.open_curtainparameter ‘bbox’ is deprecated, and will likely be removed in a future release.Class ‘overture_call’ has been added to facilitate
collectcalls directly assfobjects.collect_sfis now deprecated, usecollect.
