% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/ddbs_join.R
\name{ddbs_join}
\alias{ddbs_join}
\title{Perform a spatial join of two geometries}
\usage{
ddbs_join(
  x,
  y,
  join = "intersects",
  conn = NULL,
  conn_x = NULL,
  conn_y = NULL,
  name = NULL,
  distance = NULL,
  mode = NULL,
  overwrite = FALSE,
  quiet = FALSE
)
}
\arguments{
\item{x}{Input spatial data. Can be:
\itemize{
\item A \code{duckspatial_df} object (lazy spatial data frame via dbplyr)
\item An \code{sf} object
\item A \code{tbl_lazy} from dbplyr
\item A character string naming a table/view in \code{conn}
}
Data is returned from this object.}

\item{y}{Input spatial data. Can be:
\itemize{
\item A \code{duckspatial_df} object (lazy spatial data frame via dbplyr)
\item An \code{sf} object
\item A \code{tbl_lazy} from dbplyr
\item A character string naming a table/view in \code{conn}
}}

\item{join}{A geometry predicate function. Defaults to \code{"intersects"}. See
the details for other options.}

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

\item{conn_x}{A \code{DBIConnection} object to a DuckDB database for the input \code{x}.
If \code{NULL} (default), it is resolved from \code{conn} or extracted from \code{x}.}

\item{conn_y}{A \code{DBIConnection} object to a DuckDB database for the input \code{y}.
If \code{NULL} (default), it is resolved from \code{conn} or extracted from \code{y}.}

\item{name}{A character string of length one specifying the name of the table,
or a character string of length two specifying the schema and table
names. If \code{NULL} (the default), the function returns the result as an
\code{sf} object}

\item{distance}{a numeric value specifying the distance for ST_DWithin. The units
should be specified in meters}

\item{mode}{Character. Controls the return type. Options:
\itemize{
\item \code{"duckspatial"} (default): Lazy spatial data frame backed by dbplyr/DuckDB
\item \code{"sf"}: Eagerly collected sf object (uses memory)
}
Can be set globally via \code{\link{ddbs_options}(mode = "...")} or
per-function via this argument. Per-function overrides global setting.}

\item{overwrite}{Boolean. whether to overwrite the existing table if it exists. Defaults
to \code{FALSE}. This argument is ignored when \code{name} is \code{NULL}.}

\item{quiet}{A logical value. If \code{TRUE}, suppresses any informational messages.
Defaults to \code{FALSE}.}
}
\value{
Depends on the \code{mode} argument (or global preference set by \code{\link{ddbs_options}}):
\itemize{
\item \code{duckspatial} (default): A \code{duckspatial_df} (lazy spatial data frame) backed by dbplyr/DuckDB.
\item \code{sf}: An eagerly collected object in R memory, that will return the same data type as the
\code{sf} equivalent (e.g. \code{sf} or \code{units} vector).
}
When \code{name} is provided, the result is also written as a table or view in DuckDB and the function returns \code{TRUE} (invisibly).
}
\description{
Combines two sets of geometries based on spatial relationships, such as
intersection or containment, attaching attributes from one set to the other.
}
\details{
Spatial Join Predicates:

A spatial predicate is really just a function that evaluates some spatial
relation between two geometries and returns true or false, e.g., “does a
contain b” or “is a within distance x of b”. Here is a quick overview of the
most commonly used ones, taking two geometries a and b:
\itemize{
\item \code{"ST_Intersects"}: Whether a intersects b
\item \code{"ST_Contains"}: Whether a contains b
\item \code{"ST_ContainsProperly"}: Whether a contains b without b touching a's boundary
\item \code{"ST_Within"}: Whether a is within b
\item \code{"ST_Overlaps"}: Whether a overlaps b
\item \code{"ST_Touches"}: Whether a touches b
\item \code{"ST_Equals"}: Whether a is equal to b
\item \code{"ST_Crosses"}: Whether a crosses b
\item \code{"ST_Covers"}: Whether a covers b
\item \code{"ST_CoveredBy"}: Whether a is covered by b
\item \code{"ST_DWithin"}: x)	Whether a is within distance x of b
}
}
\examples{
\dontrun{
# RECOMMENDED: Efficient lazy workflow using ddbs_open_dataset
library(duckspatial)

# Load data directly as lazy spatial data frames (CRS auto-detected)
countries <- ddbs_open_dataset(
  system.file("spatial/countries.geojson", package = "duckspatial")
)

# Create random points
n <- 100
points <- data.frame(
    id = 1:n,
    x = runif(n, min = -180, max = 180),
    y = runif(n, min = -90, max = 90)
) |> 
  sf::st_as_sf(coords = c("x", "y"), crs = 4326) |>
  as_duckspatial_df()

# Lazy join - computation stays in DuckDB
result <- ddbs_join(points, countries, join = "within")

# Collect to sf when needed
result_sf <- dplyr::collect(result) |> sf::st_as_sf()
plot(result_sf["CNTR_NAME"])


# Alternative: using sf objects directly (legacy compatibility)
library(sf)

countries_sf <- sf::st_read(system.file("spatial/countries.geojson", package = "duckspatial"))

output <- duckspatial::ddbs_join(
    x = points,
    y = countries_sf,
    join = "within"
)


# Alternative: using table names in a duckdb connection
conn <- duckspatial::ddbs_create_conn()

ddbs_write_table(conn, points, "points", overwrite = TRUE)
ddbs_write_table(conn, countries_sf, "countries", overwrite = TRUE)

output2 <- ddbs_join(
    conn = conn,
    x = "points",
    y = "countries",
    join = "within"
)

}
}
