% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/add_spatial_relations.R
\name{add_spatial_distance}
\alias{add_spatial_distance}
\title{Add distance-threshold spatial relations}
\usage{
add_spatial_distance(
  x,
  coords = NULL,
  max_distance,
  name = "distance",
  weight_mode = c("constant", "inverse", "inverse_sq"),
  distance_eps = 1e-09
)
}
\arguments{
\item{x}{A \code{Problem} object created with \code{\link{create_problem}}.}

\item{coords}{Optional coordinates specification, following the same rules as
in \code{\link{add_spatial_knn}}.}

\item{max_distance}{Positive numeric scalar giving the maximum distance for
an edge.}

\item{name}{Character string giving the key under which the relation is
stored.}

\item{weight_mode}{Character string indicating how distance is converted to
weight. Must be one of \code{"constant"}, \code{"inverse"}, or
\code{"inverse_sq"}.}

\item{distance_eps}{Small positive numeric constant used to avoid division by
zero in inverse-distance weighting.}
}
\value{
An updated \code{Problem} object.
}
\description{
Build and register a spatial relation connecting planning units whose
Euclidean distance is less than or equal to a user-defined threshold.

This constructor does not require polygon geometry and instead uses
planning-unit coordinates.
}
\details{
Use this function when neighbourhood should be defined by a fixed distance
radius rather than by polygon topology or a fixed number of neighbours.

Let \eqn{s_i = (x_i, y_i)} denote the coordinates of planning unit
\eqn{i}. Let \eqn{d_{ij}} be the Euclidean distance between planning units
\eqn{i} and \eqn{j}.

For a user-supplied threshold \eqn{d_{\max}}, this constructor creates an
edge between \eqn{i} and \eqn{j} whenever:
\deqn{
d_{ij} \le d_{\max}.
}

Edge weights are assigned according to \code{weight_mode}:
\itemize{
\item \code{"constant"}:
\deqn{\omega_{ij} = 1,}
\item \code{"inverse"}:
\deqn{\omega_{ij} = \frac{1}{\max(d_{ij}, \varepsilon)},}
\item \code{"inverse_sq"}:
\deqn{\omega_{ij} = \frac{1}{\max(d_{ij}, \varepsilon)^2},}
}
where \eqn{\varepsilon} = \code{distance_eps} is a small constant.

The implementation computes an \eqn{O(n^2)} distance matrix and is therefore
best suited to small or moderate numbers of planning units. For large
problems, \code{\link{add_spatial_knn}} is often more scalable.

The resulting relation is registered as undirected.
}
\examples{
pu_tbl <- data.frame(
  id = 1:4,
  cost = c(1, 2, 3, 4),
  x = c(0, 1, 0, 1),
  y = c(0, 0, 1, 1)
)

feat_tbl <- data.frame(
  id = 1:2,
  name = c("feature_1", "feature_2")
)

dist_feat_tbl <- data.frame(
  pu = c(1, 1, 2, 3, 4),
  feature = c(1, 2, 2, 1, 2),
  amount = c(5, 2, 3, 4, 1)
)

p <- create_problem(
  pu = pu_tbl,
  features = feat_tbl,
  dist_features = dist_feat_tbl,
  cost = "cost"
)

p <- add_spatial_distance(
  x = p,
  max_distance = 1.01,
  name = "within_1",
  weight_mode = "constant"
)

p$data$spatial_relations$within_1

}
\seealso{
\code{\link{add_spatial_knn}},
\code{\link{add_spatial_relations}}
}
