diff --git a/NAMESPACE b/NAMESPACE index cc7b133..7087dfe 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -28,6 +28,7 @@ export(gpkg_connect) export(gpkg_contents) export(gpkg_create_contents) export(gpkg_create_dummy_features) +export(gpkg_create_spatial_view) export(gpkg_delete_contents) export(gpkg_disconnect) export(gpkg_execute) diff --git a/NEWS.md b/NEWS.md index 22ca252..148d0a5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,7 @@ +# gpkg 0.0.8 + + - Added `gpkg_create_spatial_view()` for creating spatial views, which dynamic layers that are accessible as if they were typical static geometry layers (for #6). + # gpkg 0.0.7 - Added `gpkg_bbox()` as an application of `gpkg_ogr_query()` diff --git a/R/gpkg-view.R b/R/gpkg-view.R new file mode 100644 index 0000000..4b46ed8 --- /dev/null +++ b/R/gpkg-view.R @@ -0,0 +1,41 @@ +#' Create a Spatial View +#' +#' @param g a `geopackage` +#' @param viewname _character_. Name of view. +#' @param viewquery _character_. Query for view contents. +#' @param geom_column _character_. Column name of view geometry. Default: `"geom"` +#' @param geometry_type_name _character_. View geometry type. Default: `"GEOMETRY"` +#' @param spatialite_computed _logical_. Register definition of `geom_column` as +#' the result of a Spatialite spatial function via +#' `"gdal_spatialite_computed_geom_column"` extension. +#' Default: `FALSE` +#' @param data_type _character_. View data type. Default `"features"` +#' @param srs_id _integer_. Spatial Reference System ID. Default: `4326` (WGS84) +#' @param z _integer_. Default: `0` +#' @param m _integer_. Default: `0` +#' +#' @return _integer_. Returns `1` if a new record in `gpkg_geometry_columns` is successfully made. +#' @export +#' +gpkg_create_spatial_view <- function(g, + viewname, + viewquery, + geom_column = "geom", + geometry_type_name = "GEOMETRY", + spatialite_computed = FALSE, + data_type = "features", + srs_id = 4326, + z = 0, + m = 0) { +gpkg_execute(g, sprintf("CREATE VIEW %s AS %s", viewname, viewquery)) +gpkg_execute(g, sprintf("INSERT INTO gpkg_contents (table_name, identifier, data_type, srs_id) + VALUES ('%s', '%s', '%s', %s)", + viewname, viewname, data_type, srs_id)) +gpkg_execute(g, sprintf("INSERT INTO gpkg_geometry_columns (table_name, column_name, geometry_type_name, srs_id, z, m) + VALUES ('%s', '%s', '%s', %s, %s, %s)", + viewname, geom_column, geometry_type_name, srs_id, z, m)) +if (spatialite_computed) + gpkg_execute(g, sprintf("INSERT INTO gpkg_extensions (table_name, column_name, extension_name, definition, scope) + VALUES ('%s', '%s', 'gdal_spatialite_computed_geom_column', 'https://gdal.org/drivers/vector/gpkg_spatialite_computed_geom_column.html', 'read-write');", + viewname, geom_column)) +} \ No newline at end of file diff --git a/man/gpkg_create_spatial_view.Rd b/man/gpkg_create_spatial_view.Rd new file mode 100644 index 0000000..688c60c --- /dev/null +++ b/man/gpkg_create_spatial_view.Rd @@ -0,0 +1,49 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/gpkg-view.R +\name{gpkg_create_spatial_view} +\alias{gpkg_create_spatial_view} +\title{Create a Spatial View} +\usage{ +gpkg_create_spatial_view( + g, + viewname, + viewquery, + geom_column = "geom", + geometry_type_name = "GEOMETRY", + spatialite_computed = FALSE, + data_type = "features", + srs_id = 4326, + z = 0, + m = 0 +) +} +\arguments{ +\item{g}{a \code{geopackage}} + +\item{viewname}{\emph{character}. Name of view.} + +\item{viewquery}{\emph{character}. Query for view contents.} + +\item{geom_column}{\emph{character}. Column name of view geometry. Default: \code{"geom"}} + +\item{geometry_type_name}{\emph{character}. View geometry type. Default: \code{"GEOMETRY"}} + +\item{spatialite_computed}{\emph{logical}. Register definition of \code{geom_column} as +the result of a Spatialite spatial function via +\code{"gdal_spatialite_computed_geom_column"} extension. +Default: \code{FALSE}} + +\item{data_type}{\emph{character}. View data type. Default \code{"features"}} + +\item{srs_id}{\emph{integer}. Spatial Reference System ID. Default: \code{4326} (WGS84)} + +\item{z}{\emph{integer}. Default: \code{0}} + +\item{m}{\emph{integer}. Default: \code{0}} +} +\value{ +\emph{integer}. Returns \code{1} if a new record in \code{gpkg_geometry_columns} is successfully made. +} +\description{ +Create a Spatial View +} diff --git a/misc/gpkg-view-voronoi.R b/misc/gpkg-view-voronoi.R new file mode 100644 index 0000000..04610da --- /dev/null +++ b/misc/gpkg-view-voronoi.R @@ -0,0 +1,34 @@ +library(gpkg) +library(terra) + +gpkg_tmp <- tempfile(fileext = ".gpkg") + +if (file.exists(gpkg_tmp)) + file.remove(gpkg_tmp) + +v <- vect(system.file("ex", "lux.shp", package = "terra")) + +gpkg_write(list(lux = v), destfile = gpkg_tmp, append = TRUE) + +g <- geopackage(gpkg_tmp, connect = TRUE) + +gpkg_create_spatial_view(g, "my_vor", "SELECT lux.fid AS OGC_FID, + lux.fid AS fid, + ST_VoronojDiagram(geom) AS geom2 + FROM lux WHERE ID_2 <= 3", + geom_column = "geom2", + geometry_type_name = "MULTIPOLYGON", + spatialite_computed = TRUE) + # NB: terra::vect() sensitive to geom type +gpkg_contents(g) + +plot(gpkg_vect(g, "my_vor")) +gpkg_vect(g, "lux") |> + subset(ID_2 <= 3, NSE = TRUE) |> + as.lines() |> + plot(col = "BLUE", lwd = 2, add = TRUE) + +# compare to: +plot(sf::st_read(g$dsn, layer = "my_vor")) +plot(svc(g$dsn, layer = "my_vor")[1]) +plot(query(vect(g$dsn, layer = "my_vor", proxy = TRUE)))