{"id":15893649,"url":"https://github.com/brownag/gpkg","last_synced_at":"2025-03-20T14:30:39.398Z","repository":{"id":62049654,"uuid":"490017682","full_name":"brownag/gpkg","owner":"brownag","description":"Utilities for the Open Geospatial Consortium (OGC) 'GeoPackage' Format in R","archived":false,"fork":false,"pushed_at":"2025-03-16T19:11:04.000Z","size":809,"stargazers_count":21,"open_issues_count":7,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-16T19:12:18.849Z","etag":null,"topics":["dbi","geopackage","geospatial","gis","r","raster","spatial","sqlite","vector"],"latest_commit_sha":null,"homepage":"http://humus.rocks/gpkg/","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brownag.png","metadata":{"files":{"readme":"README.Rmd","changelog":"NEWS.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-08T17:58:54.000Z","updated_at":"2025-03-16T18:12:45.000Z","dependencies_parsed_at":"2023-11-21T07:52:37.718Z","dependency_job_id":"ff06d999-4ed5-4ff7-b96d-683a45ffadda","html_url":"https://github.com/brownag/gpkg","commit_stats":{"total_commits":101,"total_committers":1,"mean_commits":101.0,"dds":0.0,"last_synced_commit":"8646ba8d79b7b32290e3153b7dea43606e1de796"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brownag%2Fgpkg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brownag%2Fgpkg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brownag%2Fgpkg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brownag%2Fgpkg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brownag","download_url":"https://codeload.github.com/brownag/gpkg/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244075595,"owners_count":20393979,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dbi","geopackage","geospatial","gis","r","raster","spatial","sqlite","vector"],"created_at":"2024-10-06T08:12:26.541Z","updated_at":"2025-03-20T14:30:39.386Z","avatar_url":"https://github.com/brownag.png","language":"R","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\noutput: github_document\n---\n\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n```{r, include = FALSE}\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  fig.path = \"man/figures/README-\",\n  out.width = \"100%\"\n)\n```\n\n# gpkg - Utilities for the Open Geospatial Consortium 'GeoPackage' Format\n\n\u003c!-- badges: start --\u003e\n[![R-CMD-check](https://github.com/brownag/gpkg/actions/workflows/R-CMD-check.yml/badge.svg?branch=main)](https://github.com/brownag/gpkg/actions/workflows/R-CMD-check.yml)\n[![gpkg HTML Manual](http://img.shields.io/badge/docs-HTML-informational)](https://humus.rocks/gpkg/)\n[![CRAN status](https://www.r-pkg.org/badges/version/gpkg)](https://CRAN.R-project.org/package=gpkg)\n[![Codecov test coverage](https://codecov.io/gh/brownag/gpkg/branch/main/graph/badge.svg)](https://app.codecov.io/gh/brownag/gpkg?branch=main)\n\u003c!-- badges: end --\u003e\n\nHigh-level wrapper functions to build [Open Geospatial Consortium (OGC) 'GeoPackage' files](https://www.geopackage.org/). [GDAL](https://gdal.org/) utilities for read and write of spatial data ([vector](https://gdal.org/en/stable/drivers/vector/gpkg.html) and [gridded](https://gdal.org/en/stable/drivers/raster/gpkg.html)) are provided via the {[terra](https://cran.r-project.org/package=terra)} package. Additional 'GeoPackage' and 'SQLite' specific functions manipulate attributes and tabular data via the {[RSQLite](https://cran.r-project.org/package=RSQLite)} package.\n\n\n\u003ca href=\"https://raw.githubusercontent.com/brownag/gpkg/main/man/figures/gpkg_sticker_v1.png\"\u003e\n\u003cimg src = \"https://raw.githubusercontent.com/brownag/gpkg/main/man/figures/gpkg_sticker_v1.png\" alt = \"gpkg hexsticker\" title = \"gpkg hexsticker: {gpkg} provides high-level wrapper functions to build GeoPackages containing a variety of different data.\" width = \"35%\" height = \"35%\" hspace=\"25\" vspace=\"25\" align=\"right\"/\u003e\u003c/a\u003e\n\n## Installation\n\nInstall the latest release from CRAN:\n\n```r\ninstall.packages(\"gpkg\")\n```\n\nThe development package can be installed from GitHub with {remotes}\n\n```r\nif (!requireNamespace(\"remotes\")) \n  install.packages(\"remotes\")\nremotes::install_github(\"brownag/gpkg\")\n```\n\n## Background\n### What is a GeoPackage?\n\n[GeoPackage](https://www.geopackage.org/) is an open, standards-based, platform-independent, portable, self-describing, compact format for transferring geospatial information. The [GeoPackage Encoding Standard](https://www.ogc.org/publications/standard/geopackage/) describes a set of conventions for storing the following within an SQLite database:\n\n  *  vector features\n  \n  *  tile matrix sets of imagery and raster maps at various scales\n  \n  *  attributes (non-spatial data)\n  \n  *  extensions\n\n## Create a Geopackage\n\n`gpkg_write()` can handle a variety of different input types. Here we start by adding two DEM (GeoTIFF) files.\n\n```{r}\nlibrary(gpkg)\nlibrary(terra)\n\ndem \u003c- system.file(\"extdata\", \"dem.tif\", package = \"gpkg\")\nstopifnot(nchar(dem) \u003e 0)\ngpkg_tmp \u003c- tempfile(fileext = \".gpkg\")\n\nif (file.exists(gpkg_tmp))\n  file.remove(gpkg_tmp)\n\n# write a gpkg with two DEMs in it\ngpkg_write(\n  dem,\n  destfile = gpkg_tmp,\n  RASTER_TABLE = \"DEM1\",\n  FIELD_NAME = \"Elevation\"\n)\n\ngpkg_write(\n  dem,\n  destfile = gpkg_tmp,\n  append = TRUE,\n  RASTER_TABLE = \"DEM2\",\n  FIELD_NAME = \"Elevation\",\n  NoData = -9999\n)\n```\n\n## Insert Vector Layers\n\nWe can also write vector data to GeoPackage. Here we use `gpkg_write()` to add a bounding box polygon layer derived from extent of `\"DEM1\"`.\n\n```{r}\n# add bounding polygon vector layer via named list\nr \u003c- gpkg_tables(gpkg_tmp)[['DEM1']]\nv \u003c- terra::as.polygons(r, ext = TRUE)\ngpkg_write(list(bbox = v), destfile = gpkg_tmp)\n```\n\n## Insert Attribute Table\n\nSimilarly, `data.frame`-like objects (non-spatial \"attributes\") can be written to GeoPackage.\n\n```{r}\nz \u003c- data.frame(a = 1:10, b = LETTERS[1:10])\ngpkg_write(list(myattr = z), destfile = gpkg_tmp)\n```\n\n## Read a GeoPackage\n\n`geopackage()` is a constructor that can create a simple container for working with geopackages from several types of inputs. Often you will have a _character_ file path to a GeoPackage (.gpkg) file. \n\n```{r}\ng \u003c- geopackage(gpkg_tmp, connect = TRUE)\ng\nclass(g)\n```\n\nOther times you may have a list of tables and layers you want to be in a GeoPackage that does not exist yet. \n\n```{r}\ng2 \u003c- geopackage(list(dem = r, bbox = v))\ng2\nclass(g2)\n```\n\nNote that a temporary GeoPackage (`{r, eval=exists(g2)} gpkg_source(g2)`) is automatically created when using the `geopackage(\u003clist\u003e)` constructor. \n\nYou also may have a _DBIConnection_ to a GeoPackage database already opened that you want to use. In any case (_character_, _list_, _SQLiteConnection_) there is an S3 method to facilitate creating the basic _geopackage_ class provided by {gpkg}. All other methods are designed to be able to work smoothly with _geopackage_ class input.\n\n## Inspect Contents of GeoPackage\n\nWe can list the table names in a GeoPackage with `gpkg_list_tables()` and fetch pointers (SpatRaster, SpatVectorProxy, and lazy data.frame) to the data in them with `gpkg_table()`. We can check the status of the internal `geopackage` class `SQLiteConnection` with `gpkg_is_connected()` and disconnect it with `gpkg_disconnect()`.\n\n```{r}\n# enumerate tables\ngpkg_list_tables(g)\n\n# inspect tables\ngpkg_tables(g)\n\n# inspect a specific table\ngpkg_table(g, \"myattr\", collect = TRUE)\n```\n\nNote that the `collect = TRUE` forces data be loaded into R memory for vector and attribute data; this is the difference in result object class of _SpatVectorProxy_/_SpatVector_ and _tbl_SQLiteConnection_/_data.frame_ for vector and attribute data, respectively.\n\n`gpkg_collect()` is a helper method to call `gpkg_table(..., collect = TRUE)` for in-memory loading of specific tables.\n\n```{r}\ngpkg_collect(g, \"DEM1\")\n```\n\nNote that with grid data returned from `gpkg_collect()` you get a table result with the tile contents in a blob column of a _data.frame_ instead of _SpatRaster_ object.\n\nThe inverse function of `gpkg_collect()` is `gpkg_tbl()` which always returns a _tbl_SQLiteConnection_.\n\n```{r}\ntb \u003c- gpkg_tbl(g, \"gpkg_contents\")\ntb\n```\n\nNote that with this lazy reference to table, the internal _SQLiteConnection_ in `g` is the same as the source in `tb`:\n\n```{r}\ngpkg_connection(g)@ptr\ngpkg_connection(tb)@ptr\n```\n\nThis means that you can handle all of your connections via the `connect` argument when creating a geopackage object, along with the `gpkg_connect()` and `gpkg_disconnect()` commands.\n\nThere are also a variety of convenience functions for the standard required tables in a geopackage. \n\nFor instance, `gpkg_contents()` collects the `\"gpkg_contents\"` table.\n\n```{r}\ngpkg_contents(g)\n```\n\n### Lazy Data Access\n\nThere are several other methods that can be used for working with tabular data in a GeoPackage in a \"lazy\" fashion.\n\n#### Method 1: `gpkg_table_pragma()`\n\n`gpkg_table_pragma()` is a low-frills `data.frame` result containing important table information, but not values.  The `PRAGMA table_info()` is stored as a nested data.frame `table_info`. This representation has no dependencies beyond {RSQLite} and is efficient for inspection of table structure and attributes, though it is less useful for data analysis.\n\n```{r}\nhead(gpkg_table_pragma(g))\n```\n\n#### Method 2:  `gpkg_vect()` and `gpkg_query()`\n\n`gpkg_vect()` is a wrapper around `terra::vect()` you can use to create 'terra' `SpatVector` objects from the tables found in a GeoPackage. \n```{r}\ngpkg_vect(g, 'bbox')\n```\n\nThe table of interest need not have a geometry column, but this method does not work on GeoPackage that contain only gridded data, and some layer in the GeoPackage must have some geometry. \n\n```{r}\ngpkg_vect(g, 'gpkg_ogr_contents')\n```\n\nThe _SpatVectorProxy_ is used for \"lazy\" references to of vector and attribute contents of a GeoPackage; this object for vector data is analogous to the _SpatRaster_ for gridded data. The 'terra' package provides \"GDAL plumbing\" for filter and query utilities. \n\n`gpkg_query()` by default uses the 'RSQLite' driver, but the richer capabilities of OGR data sources can be harnessed with [SQLite SQL dialect](https://gdal.org/en/stable/user/sql_sqlite_dialect.html). These additional features can be utilized with the `ogr=TRUE` argument to `gpkg_query()`, or `gpkg_ogr_query()` for short. This assumes that GDAL is built with support for SQLite (and ideally also with support for Spatialite).\n\nFor example, we use built-in functions such as `ST_MinX()` to calculate summaries for `\"bbox\"` table, geometry column `\"geom\"`. In this case we expect the calculated quantities to match the coordinates/boundaries of the bounding box:\n\n```{r}\nres \u003c- gpkg_ogr_query(g, \"SELECT \n                           ST_MinX(geom) AS xmin,\n                           ST_MinY(geom) AS ymin, \n                           ST_MaxX(geom) AS xmax, \n                           ST_MaxY(geom) AS ymax \n                          FROM bbox\")\nas.data.frame(res)\n```\n\n#### Method 3: `gpkg_rast()`\n\nUsing `gpkg_rast()` you can quickly access references to all tile/gridded datasets in a GeoPackage.\n\nFor example: \n\n```{r}\ngpkg_rast(g)\n```\n\n#### Method 4: `gpkg_table()`\n\nWith the `gpkg_table()` method you access a specific table (by name) and get a \"lazy\" `tibble` object referencing that table. \n\nThis is achieved via {dplyr} and the {dbplyr} database connection to the GeoPackage via the {RSQLite} driver. The resulting object's data can be used in more complex analyses by using other {dbplyr}/{tidyverse} functions.\n\nFor example, we inspect the contents of the `gpkg_contents` table that contains critical information on the data contained in a GeoPackage.\n\n```{r}\ngpkg_table(g, \"gpkg_contents\")\n```\n\nAs a more complicated example we access the `gpkg_2d_gridded_tile_ancillary` table, and perform some data processing.\n\nWe `dplyr::select()` `mean` and `std_dev` columns from the `dplyr::filter()`ed rows where `tpudt_name == \"DEM2\"`. Finally we materialize a `tibble`  with `dplyr::collect()`:\n\n```{r}\nlibrary(dplyr, warn.conflicts = FALSE)\n\ngpkg_table(g, \"gpkg_2d_gridded_tile_ancillary\") %\u003e% \n  filter(tpudt_name == \"DEM2\") %\u003e% \n  select(mean, std_dev) %\u003e% \n  collect()\n```\n\n### Managing Connections\n\nSeveral helper methods are available for checking GeoPackage `SQLiteConnection` status, as well as connecting and disconnecting an existing `geopackage` object (`g`).\n\n```{r}\n# still connected\ngpkg_is_connected(g)\n\n# disconnect \ngpkg_disconnect(g)\n\n# reconnect\ngpkg_connect(g)\n\n# disconnect\ngpkg_disconnect(g)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrownag%2Fgpkg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrownag%2Fgpkg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrownag%2Fgpkg/lists"}