% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/gdalraster_proc.R
\name{is_los_visible}
\alias{is_los_visible}
\title{Check line of sight between pairs of point locations}
\usage{
is_los_visible(
  dem,
  ptsA,
  ptsB,
  band = 1L,
  srsA = NULL,
  srsB = NULL,
  ZinterpA = "RELATIVE_TO_DEM",
  ZinterpB = "RELATIVE_TO_DEM",
  quiet = FALSE
)
}
\arguments{
\item{dem}{Either a character string giving the filename of the DEM
raster, or an object of class \code{GDALRaster} for the DEM.}

\item{ptsA}{A data frame or numeric matrix containing geospatial point
coordinates, or point geometries (with Z values) as a list of WKB raw vectors
or character vector of WKT strings. If data frame or matrix, the number of
columns must be three (x, y, z). May be also be given as a numeric vector for
one point (\code{c(x, y, z)}). If this argument contains a single point, then
line of sight will be checked between it and each point in \code{ptsB}, otherwise
\code{length(ptsA)} must equal \code{length(ptsB)}, and line of sight will be checked
pairwise.}

\item{ptsB}{The second set of points, as described above for \code{ptsA}.}

\item{band}{An integer value specifying the band number in \code{dem} to use.
Defaults to \code{1L}.}

\item{srsA}{An optional character string specifying the spatial reference
system for \code{ptsA}. May be in WKT format or any of the formats supported by
\code{\link[=srs_to_wkt]{srs_to_wkt()}}. If this argument is \code{NULL} (the default), then \code{ptsA} are
assumed to be in the same coordinate reference system as \code{dem}. Otherwise,
\code{ptsA} will be reprojected from \code{srsA} to the spatial reference of \code{dem}.}

\item{srsB}{An optional character string specifying the spatial reference
system for \code{ptsB} (see above). Defaults to \code{NULL}. If not \code{NULL}, \code{ptsB} will
be reprojected from \code{srsB} to the spatial reference of \code{dem}.}

\item{ZinterpA}{A character string specifying the interpretation of the Z
values for \code{ptsA}. The default is \code{"RELATIVE_TO_DEM"}, in which case the
location heights of \code{ptsA} are obtained by querying the DEM surface and
adding the Z value given in \code{ptsA}. Alternatively, the Z values can be
interpreted as absolute heights to be used unmodified by setting this
argument to \code{"ACTUAL"}.}

\item{ZinterpB}{A character string specifying the interpretation of the Z
values for \code{ptsB}. See the description above for \code{ZinterpA}.}

\item{quiet}{A logical value with default of \code{FALSE}. If set to \code{TRUE}, will
suppress a progress bar and informational messages.}
}
\value{
A logical vector of \code{length(ptsB)}, \code{TRUE} for each pair of points
that are within line of sight, otherwise \code{FALSE}.
The checks are done pairwise if \code{(length(ptsA) == length(ptsB))}, or
one-to-many if \code{length(ptsA) == 1} and multiple points are given in \code{ptsB}.
}
\description{
\code{is_los_visible()} is an interface to GDAL's line-of-sight algorithm
implemented by \code{GDALIsLineOfSightVisible()} in the Algorithms C API
(\url{https://gdal.org/en/stable/api/gdal_alg.html}). It checks line of sight
across a DEM surface using a Bresenham algorithm. The function can operate
pairwise on sets of input points, or one-to-many. Requires GDAL >= 3.9.
}
\note{
Input coordinates must be within the raster bounds. \code{NA} will be returned if
either coordinate is outside the raster extent, or is missing a Z value.

The GDAL documentation notes that line of sight is computed in raster
coordinate space, and thus may not be appropriate for some applications. For
example, datasets referenced against geographic coordinates at high latitudes
may have issues.

In GDAL 3.9 through 3.12, a point exactly on the surface of the DEM is never
visible with \code{GDALIsLineOfSightVisible()}, even if viewed from a point
directly above. For a detailed description, see
\url{https://github.com/OSGeo/gdal/issues/12458}. A workaround for that case
is to set a small but negligible positive Z value (if using
\code{"RELATIVE_TO_DEM"}) for points that are intended to be on the DEM surface,
if appropriate for the use case. GDAL as of version 3.13 treats a point
exactly on the surface as visible
(\url{https://github.com/OSGeo/gdal/pull/14237}).
}
\examples{
\dontshow{if (gdal_version_num() >= gdal_compute_version(3, 9, 0)) withAutoprint(\{ # examplesIf}
dem <- system.file("extdata/storml_elev.tif", package="gdalraster")

## no reprojection, the point coordinates are in the same projection as DEM

## one-to-many
ptA <- c(324625.0, 5104724.0, 1.7)
ptsB <-c(324803.0, 5104517.0, 10,
         325286.0, 5102923.0, 10,
         323847.0, 5104538.0, 10)
ptsB <- matrix(ptsB, nrow = 3, ncol = 3, byrow = TRUE)

is_los_visible(dem, ptA, ptsB)

## pairwise, same ptA location with varying height
ptsA <- c(324625.0, 5104724.0, 1,
          324625.0, 5104724.0, 10,
          324625.0, 5104724.0, 1000)
ptsA <- matrix(ptsA, nrow = 3, ncol = 3, byrow = TRUE)

is_los_visible(dem, ptsA, ptsB)

## WKB points
(ptsA_wkb <- g_create("POINT", ptsA))

# as WKT
g_wk2wk(ptsA_wkb)

# or as ISO WKT
g_wk2wk(ptsA_wkb, as_iso = TRUE)

is_los_visible(dem, ptsA_wkb, ptsB)

## reprojecting ptsA, and the DEM given as a dataset object
(ds <- new(GDALRaster, dem))

ptsA_wkb_wgs84 <- g_transform(ptsA_wkb, ds$getSpatialRef(), "WGS84")
g_wk2wk(ptsA_wkb_wgs84)

is_los_visible(ds, ptsA_wkb_wgs84, ptsB, srsA = "WGS84")

## read ptsB from a vector dataset, use original ptA

dsn <- system.file("extdata/storml_los_pts_b.geojson", package="gdalraster")
(lyr <- new(GDALVector, dsn))

(features <- lyr$fetch(-1))

is_los_visible(ds, ptA, features$geom, srsB = lyr$getSpatialRef(),
               ZinterpB = "ACTUAL")

ds$close()
lyr$close()
\dontshow{\}) # examplesIf}
}
\references{
Roberto de Beauclair Seixas, Maur Riguette Mediano and Marcelo Gattass. 1999.
Efficient Line-of-Sight Algorithms for Real Terrain Data.
}
