% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/geom.R
\name{g_util}
\alias{g_util}
\alias{g_make_valid}
\alias{g_normalize}
\alias{g_set_3D}
\alias{g_set_measured}
\alias{g_swap_xy}
\title{Geometry utility functions operating on WKB or WKT}
\usage{
g_make_valid(
  geom,
  method = "LINEWORK",
  keep_collapsed = FALSE,
  as_wkb = TRUE,
  as_iso = FALSE,
  byte_order = "LSB",
  quiet = FALSE
)

g_normalize(
  geom,
  as_wkb = TRUE,
  as_iso = FALSE,
  byte_order = "LSB",
  quiet = FALSE
)

g_set_3D(
  geom,
  is_3d,
  as_wkb = TRUE,
  as_iso = FALSE,
  byte_order = "LSB",
  quiet = FALSE
)

g_set_measured(
  geom,
  is_measured,
  as_wkb = TRUE,
  as_iso = FALSE,
  byte_order = "LSB",
  quiet = FALSE
)

g_swap_xy(
  geom,
  as_wkb = TRUE,
  as_iso = FALSE,
  byte_order = "LSB",
  quiet = FALSE
)
}
\arguments{
\item{geom}{Either a raw vector of WKB or list of raw vectors, or a
character vector containing one or more WKT strings.}

\item{method}{Character string. One of \code{"LINEWORK"} (the default) or
\code{"STRUCTURE"} (requires GEOS >= 3.10 and GDAL >= 3.4). See Details.}

\item{keep_collapsed}{Logical value, applies only to the STRUCTURE method.
Defaults to \code{FALSE}. See Details.}

\item{as_wkb}{Logical value, \code{TRUE} to return the output geometry in WKB
format (the default), or \code{FALSE} to return as WKT.}

\item{as_iso}{Logical value, \code{TRUE} to export as ISO WKB/WKT (ISO 13249
SQL/MM Part 3), or \code{FALSE} (the default) to export as "Extended WKB/WKT".}

\item{byte_order}{Character string specifying the byte order when output is
WKB. One of \code{"LSB"} (the default) or \code{"MSB"} (uncommon).}

\item{quiet}{Logical value, \code{TRUE} to suppress warnings. Defaults to \code{FALSE}.}

\item{is_3d}{Logical value, \code{TRUE} if the input geometries should have a Z
dimension, or \code{FALSE} to remove the Z dimension.}

\item{is_measured}{Logical value, \code{TRUE} if the input geometries should have
a M dimension, or \code{FALSE} to remove the M dimension.}
}
\value{
A geometry as WKB raw vector or WKT string, or a list/character vector of
geometries as WKB/WKT with length equal to \code{length(geom)}. \code{NULL} is returned
with a warning if WKB input cannot be converted into an OGR geometry object,
or if an error occurs in the call to the underlying OGR API (see Note).
}
\description{
These functions operate on input geometries in OGC WKB or WKT format to
perform various manipulations for utility purposes.
}
\details{
These functions use the GEOS library via GDAL headers.

\code{g_make_valid()} attempts to make an invalid geometry valid without losing
vertices. Already-valid geometries are cloned without further intervention.
Wrapper of \code{OGR_G_MakeValidEx()} in the GDAL API.
Requires GEOS >= 3.8 library. If GDAL is built without GEOS >= 3.8, this
function will return a clone of the input geometry if it is valid, or \code{NULL}
(\code{as_wkb = TRUE}) / \code{NA} (\code{as_wkb = FALSE}) if it is invalid. For detailed
explanations of geometry validity checking and repair, see
\url{https://gdal.org/en/latest/user/geometry_validity.html}.
\itemize{
\item \code{"LINEWORK"} is the default method, which combines all rings into a set
of noded lines and then extracts valid polygons from that linework
(requires GEOS >= 3.10 and GDAL >= 3.4). The \code{"STRUCTURE"} method first
makes all rings valid, then merges shells and subtracts holes from shells to
generate a valid result. Assumes that holes and shells are correctly
categorized.
\item \code{keep_collapsed} only applies to the \code{"STRUCTURE"} method:
\itemize{
\item \code{FALSE} (the default): collapses are converted to empty geometries
\item \code{TRUE}: collapses are converted to a valid geometry of lower dimension
}
}

\code{g_normalize()} organizes the elements, rings, and coordinate order of
geometries in a consistent way, so that geometries that represent the same
object can be easily compared. Wrapper of \code{OGR_G_Normalize()} in the GDAL
API. Requires GDAL >= 3.3. Normalization ensures the following:
\itemize{
\item Lines are oriented to have smallest coordinate first (apart from duplicate
endpoints)
\item Rings start with their smallest coordinate (using XY ordering)
\item Polygon shell rings are oriented clockwise, and holes counter-clockwise
\item Collection elements are sorted by their first coordinate
}

\code{g_set_3D()} adds or removes the explicit Z coordinate dimension. Removing
the Z coordinate dimension of a geometry will remove any existing Z values.
Adding the Z dimension to a geometry collection, a compound curve, a
polygon, etc. will affect the children geometries.
Wrapper of \code{OGR_G_Set3D()} in the GDAL API.

\code{g_set_measured()} adds or removes the explicit M coordinate dimension.
Removing the M coordinate dimension of a geometry will remove any existing M
values. Adding the M dimension to a geometry collection, a compound curve, a
polygon, etc. will affect the children geometries.
Wrapper of \code{OGR_G_SetMeasured()} in the GDAL API.

\code{g_swap_xy()} swaps x and y coordinates of the input geometry.
Wrapper of \code{OGR_G_SwapXY()} in the GDAL API.
}
\note{
\code{MakeValid()} in GDAL >= 3.13: Certain geometries cannot be read using GEOS,
e.g., if Polygon rings are not closed or do not contain enough vertices. If
a geometry cannot be read by GEOS, \code{NULL} will be returned. Starting with
GDAL 3.13, GDAL will attempt to modify these geometries such that they can
be read and repaired by GEOS.
}
\examples{
## g_make_valid() requires GEOS >= 3.8, otherwise is only a validity test
geos_version()

# valid
wkt <- "POINT (0 0)"
g_make_valid(wkt, as_wkb = FALSE)

# invalid to valid
wkt <- "POLYGON ((0 0,10 10,0 10,10 0,0 0))"
g_make_valid(wkt, as_wkb = FALSE)

# invalid, note that GDAL >= 3.13 will modify to valid in this case
wkt <- "LINESTRING (0 0)"
# NULL if GDAL < 3.13, or "POINT (0 0)" with GDAL >= 3.13:
g_make_valid(wkt)

## g_normalize() requires GDAL >= 3.3
if (gdal_version_num() >= gdal_compute_version(3, 3, 0)) {
  g <- "POLYGON ((0 1,1 1,1 0,0 0,0 1))"
  g_normalize(g) |> g_wk2wk()
}

## set 3D / set measured
pt_xyzm <- g_create("POINT", c(1, 9, 100, 2000))

g_wk2wk(pt_xyzm, as_iso = TRUE)

g_set_3D(pt_xyzm, is_3d = FALSE) |> g_wk2wk(as_iso = TRUE)

g_set_measured(pt_xyzm, is_measured = FALSE) |> g_wk2wk(as_iso = TRUE)

## swap XY
g <- "GEOMETRYCOLLECTION(POINT(1 2),
                         LINESTRING(1 2,2 3),
                         POLYGON((0 0,0 1,1 1,0 0)))"

g_swap_xy(g, as_wkb = FALSE)
}
\seealso{
\code{\link[=g_is_valid]{g_is_valid()}}, \code{\link[=g_is_3D]{g_is_3D()}}, \code{\link[=g_is_measured]{g_is_measured()}}\cr\cr

GDAL documentation on geometry validity and repair:
\url{https://gdal.org/en/latest/user/geometry_validity.html}
}
