% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/io_write_dataset.R
\name{ddbs_write_dataset}
\alias{ddbs_write_dataset}
\title{Write spatial dataset to disk}
\usage{
ddbs_write_dataset(
  data,
  path,
  gdal_driver = NULL,
  conn = NULL,
  overwrite = FALSE,
  crs = NULL,
  layer = "spatial",
  options = list(),
  partitioning = if (inherits(data, c("tbl_lazy", "duckspatial_df")))
    dplyr::group_vars(data) else NULL,
  parquet_compression = NULL,
  parquet_row_group_size = NULL,
  layer_creation_options = NULL,
  quiet = FALSE,
  duckdb_storage_version = duckspatial_storage_default()
)
}
\arguments{
\item{data}{A \code{duckspatial_df}, \code{tbl_lazy} (DuckDB), or \code{sf} object.}

\item{path}{Path to output file.}

\item{gdal_driver}{GDAL driver name for writing spatial formats. If \code{NULL} (default),
the driver is auto-detected from the file extension for common formats:
\itemize{
\item \code{.geojson}, \code{.json} → "GeoJSON"
\item \code{.shp} → "ESRI Shapefile"
\item \code{.gpkg} → "GPKG"
\item \code{.fgb} → "FlatGeobuf"
\item \code{.kml} → "KML"
\item \code{.gpx} → "GPX"
\item \code{.gml} → "GML"
\item \code{.sqlite} → "SQLite"
}

For \strong{non-standard file extensions} (e.g., \code{.dat}, \code{.xyz}) or to \strong{explicitly override}
auto-detection, specify the exact driver name as it appears in \code{ddbs_drivers()$short_name}.
Examples: \code{gdal_driver = "GeoJSON"}, \code{gdal_driver = "ESRI Shapefile"}.

\strong{Note}: If you specify a driver that doesn't match the file extension (e.g.,
\code{path = "output.shp"} with \code{gdal_driver = "GeoJSON"}), a warning will be issued but
your explicit driver choice will be honored (creating a GeoJSON file with \code{.shp} extension).

The function validates that the specified driver is available and writable on your
system. Note: \code{.parquet} and \code{.csv} files use native DuckDB writers and do not
require a GDAL driver.}

\item{conn}{A connection object to a DuckDB database. If \code{NULL}, the function
runs on a temporary DuckDB database.}

\item{overwrite}{Logical. If \code{TRUE}, overwrites existing file.}

\item{crs}{Output CRS (e.g., "EPSG:4326"). Passed to GDAL as \code{SRS} option. Ignored for Parquet.}

\item{layer}{Table name for native DuckDB database output.}

\item{options}{Named list of additional options passed to \code{COPY}.}

\item{partitioning}{Character vector of columns to partition by (Parquet/CSV only).}

\item{parquet_compression}{Compression codec for Parquet.}

\item{parquet_row_group_size}{Row group size for Parquet.}

\item{layer_creation_options}{GDAL layer creation options.}

\item{quiet}{A logical value. If \code{TRUE}, suppresses any informational messages.
Defaults to \code{FALSE}.}

\item{duckdb_storage_version}{Storage compatibility for newly created native
DuckDB database files (\code{.duckdb}, \code{.db}, \code{.ddb}). See
\url{https://duckdb.org/docs/internals/storage} for more information on
DuckDB storage versions and compatibility.
\itemize{
\item \code{"v1.5.0"} (\strong{Native Spatial Storage}, Default): Preserves
CRS metadata in native DuckDB \code{GEOMETRY} columns. Requires
DuckDB >= 1.5.0 to open the file.
\item \code{"v1.0.0"} (\strong{Legacy Compatibility}): Creates
files readable by older DuckDB versions (>= 1.0.0). Persists CRS
metadata in duckspatial-managed column comments (a convention not
recognized by other spatial software).
\item \code{"latest"}: Use the highest storage version supported by your
installed DuckDB engine.
}
Other major version strings like \code{"v1.4.0"}, \code{"v1.3.0"}, etc., are also supported.}
}
\value{
The \code{path} invisibly.
}
\description{
Writes spatial data to disk using DuckDB's \code{COPY} command for Parquet and
GDAL spatial formats, or as a native DuckDB database for \code{.duckdb}, \code{.db},
and \code{.ddb} paths. Format is auto-detected from file extension for common
formats, or can be specified explicitly via \code{gdal_driver}.
}
\details{
Persistent DuckDB database files created by duckspatial use \strong{Native
Spatial Storage} (\code{storage_version = "v1.5.0"}) by default so CRS metadata is
retained in native \code{GEOMETRY} columns. These files require DuckDB >= 1.5.0
to open; use \strong{Legacy Compatibility} (\code{storage_version = "v1.0.0"})
when the output must be readable by older DuckDB versions.
}
\examples{
\dontrun{
library(duckspatial)

# Read example data
path <- system.file("spatial/countries.geojson", package = "duckspatial")
ds <- ddbs_open_dataset(path)

# Auto-detect format from extension
ddbs_write_dataset(ds, "output.geojson")
ddbs_write_dataset(ds, "output.gpkg")
ddbs_write_dataset(ds, "output.parquet")

# Explicit GDAL driver for non-standard extension
ddbs_write_dataset(ds, "mydata.dat", gdal_driver = "GeoJSON")

# See available drivers on your system
drivers <- ddbs_drivers()
writable <- drivers[drivers$can_create == TRUE, ]
head(writable)

# CRS override
ddbs_write_dataset(ds, "output_3857.geojson", crs = "EPSG:3857")

# Overwrite existing file
ddbs_write_dataset(ds, "output.gpkg", overwrite = TRUE)
}
}
\references{
This function is inspired by and builds upon the logic found in the
\code{duckdbfs} package (\url{https://github.com/cboettig/duckdbfs}),
particularly its \code{write_dataset} and \code{write_geo} functions.
For advanced features like cloud storage (S3) support, the
\code{duckdbfs} package is highly recommended.
}
\seealso{
\code{\link[=ddbs_drivers]{ddbs_drivers()}} to list all available GDAL drivers and formats.
}
