| Title: | The SpatialGraph Class and Utilities |
|---|---|
| Description: | Provision of the S4 SpatialGraph class built on top of objects provided by 'igraph' and 'sp' packages, and associated utilities. See the documentation of the SpatialGraph-class within this package for further description. An example of how from a few points one can arrive to a SpatialGraph is provided in the function sl2sg(). |
| Authors: | Javier Garcia-Pintado |
| Maintainer: | Javier Garcia-Pintado <[email protected]> |
| License: | GPL (>=2) |
| Version: | 1.0-4 |
| Built: | 2026-05-11 07:17:06 UTC |
| Source: | https://github.com/garciapintado/spatialgraph |
Provision of the S4 SpatialGraph class built on top of objects provided by 'igraph' and 'sp' packages, and associated utilities. See the documentation of the SpatialGraph-class within this package for further description. An example of how from a few points one can arrive to a SpatialGraph is provided in the function sl2sg().
The DESCRIPTION file:
| Package: | SpatialGraph |
| Version: | 1.0-4 |
| Type: | Package |
| Title: | The SpatialGraph Class and Utilities |
| Date: | 2023-07-21 |
| Imports: | igraph, methods, pracma, sf, shape, sp, splancs |
| Author: | Javier Garcia-Pintado |
| Maintainer: | Javier Garcia-Pintado <[email protected]> |
| Description: | Provision of the S4 SpatialGraph class built on top of objects provided by 'igraph' and 'sp' packages, and associated utilities. See the documentation of the SpatialGraph-class within this package for further description. An example of how from a few points one can arrive to a SpatialGraph is provided in the function sl2sg(). |
| License: | GPL (>=2) |
| URL: | https://github.com/garciapintado/SpatialGraph |
| Config/pak/sysreqs: | libabsl-dev cmake libgdal-dev gdal-bin libgeos-dev libglpk-dev libxml2-dev libssl-dev libproj-dev libsqlite3-dev libudunits2-dev |
| Repository: | https://garciapintado.r-universe.dev |
| Date/Publication: | 2023-07-24 08:09:31 UTC |
| RemoteUrl: | https://github.com/garciapintado/spatialgraph |
| RemoteRef: | HEAD |
| RemoteSha: | b0557352b0cef9101dbcf6bf6a01a7c80f7d7e65 |
Index of help topics:
attSGe Add or Modify attributes in SpatialGraph edges
distSG Calculate across-network distance for a set of
sparse points
distSGv Calculate the distance slot in a SpatialGraph
explodeSLDF Explode Lines in a SpatialLinesDataFrame
pointLineD Euclidean distance from a set of points to a
line segment
pointOnLine Snap a points to a line
pointOnSegment Snap a points to a segment
pointsPolylineD closest points in a polyline to a set of points
pointsSLDFchain Obtain chainage from sparse points along a
SpatialLinesDataFrame
pointsToLines Snap a set of points to a set of lines
polylineChainage Obtain the chainage of nodes along a polyline
polylineLength Obtain the length of a polyline
revSGe Reverse Lines in a SpatialGraph
rotation Rotate 2D points
routeSDG Accumulate sources/sinks along a directed
SpatialGraph
sg2igraph Map a SpatialGraph into an igraph
sgChVIDs Change vertex IDs in a SpatialGraph
sl2sg Map a SpatialLinesDataFrame into a SpatialGraph
SpatialGraph Create a SpatialGraph object
SpatialGraph-class Class "SpatialGraph"
SpatialGraph-package The SpatialGraph Class and Utilities
splitPolyline Split a polyline into a number of transects
splitSLDF Split 1-Line Lines in a SpatialLines or a
SpatialLinesDataFrame by intersection with a
point dataset
textSGe Label edges in a SpatialGraph plot
see the documentation of the function sl2sg in this package to get a start. A case study making use if this package is Garcia-Pintado et al (2015)
Javier Garcia-Pintado
Maintainer: Javier Garcia-Pintado <[email protected]>
The first published application of this package is Garcia-Pintado, J. et al. (2015). Satellite-supported flood forecasting in river networks: a real case study. J. Hydrol. 523, 705-724.
Add or Modify attributes in SpatialGraph edges
attSGe(SG, att, eID, val, default)attSGe(SG, att, eID, val, default)
SG |
|
att |
name of the field [column] in the edge dataframe to be added/modified |
eID |
edge identifiers [row.names of the edge data.frame] |
val |
values corresponding the |
default |
default values for edges not considered in |
This function obtains the across-network distance for a set
of sparse points, by using the distance slot in a SpatialGraph. The
calculation is supported by a previously calculated between vertex
distance matrix
[via a call to the library igraph by the function distSGv].
The SpatialGraph is considered as undirected for distance
calculation.
If euc=TRUE [default], the distance between two points is defined within this function
as the maximum of both the minimum along-network distance and the Euclidean
distance. The distance itself between the points
in x,y and the network is neglected in the function for the
along-network distance.
Both, x and y, are SpatialPointsDataFrame
objects, which must contain at least the fields
eID and chain, which describe their relationship with
the SpatialGraph object defined by SG. These can be
obtained with either the function pointsSLDFchain or
pointsToLines (the latter is faster, but depends on GEOS)
distSG(SG, x, y = NULL, euc = TRUE, wei = NULL, getpath = FALSE)distSG(SG, x, y = NULL, euc = TRUE, wei = NULL, getpath = FALSE)
SG |
|
x |
|
y |
|
euc |
boolean scalar, whether to use Euclidean distance as minimum threshold for resulting distances |
wei |
if not null, field in |
getpath |
if TRUE (and wei != NULL), |
The application of state-related weights in this version is a simple
state-dependent weight matrix related to some field in SG@e [i.e. the
edges in the input SpatialGraph]. The only current calculation
evaluates the path between queried points (x,y), and along the path, for
every junction and jump into a new edge, the ratio for the evaluated state variable (taken as
the highest value divided by the lowest value) between the two edges at
the junction is obtained. Currently a
maximum ratio equal to 10.0 is hard-coded. The product
of ratios along the path gives the weight.
If wei=NULL, a matrix of distances between x and
y. If wei is not NULL, a list with a distance
matrix and weight matrix (plus a matrix with eID identifiers
for the path, if getpath=TRUE) is returned.
Javier Garcia-Pintado, e-mail: [email protected]
if (1 > 2) { # not run dem <- readGDAL(file.path(system.file('external',package='hydrosim'), 'watershed1','IDRISI_maps','dem','dem.rst')) # SpatialGridDataFrame plotGmeta(layer=dem, xlim=662500 + 2500 * c(-1,+1), ylim=4227500 + 2500 * c(-1,1), zlim='strloc', as.na=0) # generate some crossing lines zz <- list() zz[[1]] <- digitGmeta(layer=dem, type='Lines', ID=1) zz[[2]] <- digitGmeta(layer=dem, type='Lines', ID=2) zz[[3]] <- digitGmeta(layer=dem, type='Lines', ID=3) SL <- SpatialLines(zz) SG <- sl2sg(SL, getpath=TRUE) points(SG@v, cex=2) # plot SpatialGraph vertices apath <- SG@path[[1,2]] # iteratively plot a path as an example for (iv in 1:length(apath$v)) { points(SG@v[apath$v[iv],], cex=2,pch=2) if (iv == length(apath$v)) break lines(SG@e[apath$e[iv],],col='blue',lwd=2,lty=2) Sys.sleep(1) } # sample a few points [as a matrix] close to some edges xy <- digit() # sample locations xych <- pointsToLines(xy, SG@e) # SpatialPointsDataFrame mapping points(xy, col='blue', pch=3) points(xych, col='darkgreen', pch=19) # along-network distance xyndis <- distSG(SG, xych) # state-dependent weighted along-network distance SG@e@data$wxs <- 3+round(runif(nrow(SG@e@data)),2) # [m2] foo wetted cross-section areas SG@e@data xywdis <- distSG(SG, xych, wei='wxs') xywdis <- xywdis$dis * xywdis$wei # Schur weight application into distance estimation }if (1 > 2) { # not run dem <- readGDAL(file.path(system.file('external',package='hydrosim'), 'watershed1','IDRISI_maps','dem','dem.rst')) # SpatialGridDataFrame plotGmeta(layer=dem, xlim=662500 + 2500 * c(-1,+1), ylim=4227500 + 2500 * c(-1,1), zlim='strloc', as.na=0) # generate some crossing lines zz <- list() zz[[1]] <- digitGmeta(layer=dem, type='Lines', ID=1) zz[[2]] <- digitGmeta(layer=dem, type='Lines', ID=2) zz[[3]] <- digitGmeta(layer=dem, type='Lines', ID=3) SL <- SpatialLines(zz) SG <- sl2sg(SL, getpath=TRUE) points(SG@v, cex=2) # plot SpatialGraph vertices apath <- SG@path[[1,2]] # iteratively plot a path as an example for (iv in 1:length(apath$v)) { points(SG@v[apath$v[iv],], cex=2,pch=2) if (iv == length(apath$v)) break lines(SG@e[apath$e[iv],],col='blue',lwd=2,lty=2) Sys.sleep(1) } # sample a few points [as a matrix] close to some edges xy <- digit() # sample locations xych <- pointsToLines(xy, SG@e) # SpatialPointsDataFrame mapping points(xy, col='blue', pch=3) points(xych, col='darkgreen', pch=19) # along-network distance xyndis <- distSG(SG, xych) # state-dependent weighted along-network distance SG@e@data$wxs <- 3+round(runif(nrow(SG@e@data)),2) # [m2] foo wetted cross-section areas SG@e@data xywdis <- distSG(SG, xych, wei='wxs') xywdis <- xywdis$dis * xywdis$wei # Schur weight application into distance estimation }
Calculate the distance slot in a SpatialGraph. This
is done via a call to the library igraph, which does the
calculation. Distances are undirected.
distSGv(SG, getpath = FALSE)distSGv(SG, getpath = FALSE)
SG |
|
getpath |
boolean. Whether to calculate the |
A SpatialGraph with the slot dist (and
path if requested) recalculated
explode Lines in a SpatialLinesDataFrame, so that each single Line, within each Lines slot, is upgraded as a new 1-Line Lines slot
explodeSLDF(SLDF, FID)explodeSLDF(SLDF, FID)
SLDF |
a SpatialLinesDataFrame |
FID |
if not NULL, field name, within the attribute table considered as additional unique identifier, so that incremental numeric values will added to this field to avoid duplicate values |
a SpatialLinesDataFrame
pointLineD returns a list with a number of components from a points to line segment analysis
pointLineD(xy, xyp)pointLineD(xy, xyp)
xy |
2 x 2 [x,y] matrix defining the start and end of the segment |
xyp |
p x 2 [x,y] matrix with a point set |
pointLineD conduct a detailed points to segment distance analysis, returned as a list
A list with the input components xy and xyp, and the aditional components: d, point-line distance (distance between the points in xyp and their perpendicular projections of the line); dc, diferential chainage over [x0,y0] (> 0 if the projection goes in the segment direction); cross, boolean vector indicating whether the perpendicular projection of the points crosses the segment, or not
This function snaps a point to a line based on the minimum distance between the point and the line
pointOnLine(cool, coop)pointOnLine(cool, coop)
cool |
2-col matrix giving the coordinates of the line |
coop |
2-length vector repsenting the point |
A 4-length vector, with 'x','y' [coordinates of the point snapped to the line], 'd' [distance from the input point to the new snapped point], and 'chain' [accumulated along-line distance from the starting of the line to the snapped point]
Javier Garcia-Pintado
This function snaps a point to a segment based on the minimum distance between the point and the segment
pointOnSegment(s, p)pointOnSegment(s, p)
s |
[2,2] matrix giving the coordinates of the line, one point per row |
p |
2-length vector repsenting the point |
A 4-length vector, with 'x','y' [coordinates of the point snapped to the segment], 'd' [distance from the input point to the new snapped point], and 'chain' [distance from the starting of the segment to the snapped point]
Javier Garcia-Pintado
pointsPolylineD returns a list with a number of components from a points to polyline analysis
pointsPolylineD(xy, xyp)pointsPolylineD(xy, xyp)
xy |
n x 2 [x,y] matrix defining the polyline |
xyp |
p x 2 [x,y] matrix with a point set |
pointsPolylineD conducts a detailed points to polyline distance analysis. First the distance from the set of points to the lines defined by every single segment in the polyline is obtained by succesive calls to pointLineD, then the distance to every single node in the polyline are also obtained. The lower distance is chosen.
A data.frame with the columns: inode is the index of the first node in the closest segment to each point, x0 and y0 are the corresponding coordinates of those nodes, xc and yc are the coordinates of the point in the polyline closest to each point in xyp, these may be but are not necessarily one the polyline nodes, dis it the distance from each point tho the polyline, chain0 is the chainage of x0,y0 with the polyline, and dc is the differential chainage from xc,yc to x0,y0
For a set of points, obtains the closest Line object in a
SpatialLinesDataFrame. The function assumes that each Feature (entry
in the DataFrame part of the SpatialLinesDataFrame) just contains one
Line (i.e. one polyline). The within-polyine chainage (that is,
distance from the initial point of the poyline to the mapping of the
point into the polyline) is also returned. If mask is NULL, each point
in the set is assigned a line in SLDF by Euclidean distance. If mask
is provided, the match between mask and the SLmsk
field in SLDF is used instead for polyline assignation.
pointsSLDFchain(SLDF, xy, SLmsk='FEAT_ID', mask=NULL, type='SpatialPointsDataFrame')pointsSLDFchain(SLDF, xy, SLmsk='FEAT_ID', mask=NULL, type='SpatialPointsDataFrame')
SLDF |
|
xy |
REAL [n,2] matrix of points, or a |
SLmsk |
is !is.null(mask) this is the field in the SLDF data.frame matching the values in mask |
mask |
REAL, OPT, [n] a vector indicating to which line in SLDF is related each point |
type |
character. Either 'SpatialPointsDataFrame' or 'mapping'. In the latter case, just the chainage in line feature identifiers are returned |
A data.frame with two columns, 'chai', and 'eIDs', where 'eIDs' are the row names of the data.frame component of the input SpatialLinesDataFrame
Javier Garcia-Pintado, e-mail: [email protected]
This function snaps a set of points to a set of lines based on the minimum distance of each point to any of the lines
pointsToLines(points, lines, withAttrs = TRUE, withDis = TRUE, withChain = TRUE)pointsToLines(points, lines, withAttrs = TRUE, withDis = TRUE, withChain = TRUE)
points |
An object of the class SpatialPoints or SpatialPointsDataFrame, or a 2-col matrix of [x,y] coordinates |
lines |
An object of the class SpatialLines or SpatialLinesDataFrame |
withAttrs |
Boolean value for preserving (TRUE) or getting rid (FALSE) of the original point attributes. Default: TRUE. This parameter is optional |
withDis |
Boolean value for including distance from source points to snapped-to-lines points |
withChain |
Boolean value for including the chainage of the snapped points in their corresponding lines |
A SpatialPointsDataFrame object as defined by the R package 'sp'. This object contains the snapped points, therefore all of them lie on the lines. The returned object contains the fields 'lid', 'eID', and 'chain', providing information about the relationship between the source data points, the snapped data points, and its location within the network: 'lid', and 'eID' are the line index and line ID, respectively, of the lines in which the new snapped points lie; 'dis' is the distance between the input points and the snapped points, and 'chain' is the chainage of the snapped point within the corresponding line
Javier Garcia-Pintado
Obtain the chainage of nodes along a polyline [2-col matrix]
polylineChainage(xy)polylineChainage(xy)
xy |
a 2-column matrix representing the polyline nodes |
polylineChainage calculates a vector of chainage values
[along-polyline distances] from each node in a polyline to the initial node
A vector
Obtain the length a polyline [2-col matrix]
polylineLength(xy)polylineLength(xy)
xy |
a 2-column matrix representing the polyline nodes |
polylineLength calculates the
[along-polyline] length of the polyline
A scalar
A SpatialGraph contains a SpatialLinesDataFrame,
describing the network topology. The input eID indicates the
identifiers of a set of lines (edges) in the network to be reversed. Note
eID does not refer to the line index within SG@e, but to
the Feature Identifiers, as extracted from row.names(SG@e@data)
revSGe(SG, eID)revSGe(SG, eID)
SG |
|
eID |
vector of Feature Identifiers for lines to be reversed |
Note eID does not refer to the line index within SG@e, but to
the Feature Identifiers, as extracted from
row.names(SG@e@data). Accordingly to the reversed coordiantes,
the corresponding fields ["v0","v1"], are interchanged.
rotate points, counterclockwise for positive angles, and clockwise for negative ones
rotation(coords, radian)rotation(coords, radian)
coords |
2-col matrix of [x,y] coordinates |
radian |
rotation angle |
a 2-col matrix with the points rotated around [0,0]
Assume a SpatialGraph is directed and conduct an accumulation of source/sink values at nodes across the network. The accumulation assumes no delay in transmission
routeSDG(SDG, FUN='cumsum', ifld='inflow')routeSDG(SDG, FUN='cumsum', ifld='inflow')
SDG |
|
FUN |
name of a function to be applied for the routing |
ifld |
name on the field in the |
The SpatialGraph, used as input, must have the ifld field
to be used as input, in the vertices slot v (a SpatialPointsDataFrame). The accumulated output is provided
as the new field ofld in v. The edges slot e
serves to route the input across the network
A SpatialGraph with the added ofld field in the vertex slot
The vertex and edge information in a SpatialGraph is
mapped into an igraph object
sg2igraph(sg, directed=FALSE)sg2igraph(sg, directed=FALSE)
sg |
|
directed |
whether the resulting |
It is assumed that the SpatialGraph, used as input, is correct
(i.e.g all records in sg@e@data have the two first field correctly
identifying the field 'ID' in sg@v. It is also assumed that the
sg@e@data data.frame has the fields div and
len. These two are highly useful to conduct network operations
on the resulting igraph
An igraph
Change the field "ID" in the vertex slot, v, of a
SpatialGraph. The fields v0 and v1 of the edge
slot, e, are accordingly updated
sgChVIDs(obj, IDa, IDp = NULL)sgChVIDs(obj, IDa, IDp = NULL)
obj |
A SpatialGraph object |
IDa |
A vector indicating the updated vertex IDs |
IDp |
A vector indicating the prior vertex IDs |
If IDp is not provided, it is assumed that the vector of
updated indexes is sorted equally to the order in which the vertices
are stored in the slot v of the SpatialGraph. If
IDp is provided, the mapping IDp -> IDa is used
for reclassifying the vertices.
A SpatialGraph object
This function is the major workhorse to map an input
SpatialLinesDataFrame, as defined in the package sp, into a
SpatialGraph by using the spatial connectivity. Input is first
exploded by using explodeSLDF, and then all vertices in the
SpatialGraph are automatically generated according to crossings
in the input polylines.
sl2sg(SL, clipd = NULL, getdist = TRUE, getpath = FALSE)sl2sg(SL, clipd = NULL, getdist = TRUE, getpath = FALSE)
SL |
|
clipd |
distance threshold for clipping features, If NULL, a value of 1.0E-04 of the domain side size is used |
getdist |
calculate the |
getpath |
calculate the |
A SpatialGraph is generated
A SpatialGraph
Javier Garcia-Pintado, e-mail: [email protected]
# x y # create list of Line objects if (1 > 2) { library(sp) library(SpatialGraph) zz <- list() zz[[1]] <- Line(matrix( c(661750, 4229150, 662650, 4229450, 663550, 4227650, 663550, 4226850), ncol=2, byrow=TRUE)) zz[[2]] <- Line(matrix( c(660250, 4229650, 661050, 4226450, 662550, 4225350, 664850, 4225850, 664650, 4229150, 662350, 4228850), ncol=2, byrow=TRUE)) # upgrade Line as Lines for (i in 1:length(zz)) { zz[[i]] <- Lines(list(zz[[i]]), ID=i) } # as SpatialLines SL <- sp::SpatialLines(zz) # as SpatialGraph including path calculation SG <- sl2sg(SL, getpath=TRUE) plot(SL, axes=TRUE) points(SG@v, cex=2) lines(SG@e, lwd=2) points(SG@v, cex=2, col='grey', pch=19) text(SG@v, labels=SG@v$ID) # label edges and directions textSGe(SG) # show a distance matrix between nodes SG@dist # show path from node 1 to 3 SG@path[1,3] }# x y # create list of Line objects if (1 > 2) { library(sp) library(SpatialGraph) zz <- list() zz[[1]] <- Line(matrix( c(661750, 4229150, 662650, 4229450, 663550, 4227650, 663550, 4226850), ncol=2, byrow=TRUE)) zz[[2]] <- Line(matrix( c(660250, 4229650, 661050, 4226450, 662550, 4225350, 664850, 4225850, 664650, 4229150, 662350, 4228850), ncol=2, byrow=TRUE)) # upgrade Line as Lines for (i in 1:length(zz)) { zz[[i]] <- Lines(list(zz[[i]]), ID=i) } # as SpatialLines SL <- sp::SpatialLines(zz) # as SpatialGraph including path calculation SG <- sl2sg(SL, getpath=TRUE) plot(SL, axes=TRUE) points(SG@v, cex=2) lines(SG@e, lwd=2) points(SG@v, cex=2, col='grey', pch=19) text(SG@v, labels=SG@v$ID) # label edges and directions textSGe(SG) # show a distance matrix between nodes SG@dist # show path from node 1 to 3 SG@path[1,3] }
A SpatialGraph object is created
SpatialGraph(v, e, dist = NULL, path = NULL)SpatialGraph(v, e, dist = NULL, path = NULL)
v |
|
e |
|
dist |
along-network (symmetric) distance matrix |
path |
matrix of lists with paths corresponding to
|
SpatialGraph returns an object of class SpatialGraph-class
Class for spatial networks
Objects can be created by calls to the function SpatialGraph
v:Object of class "SpatialPointsDataFrame",
whose data.frame must contain the "ID" field as unique identifier
e:Object of class "SpatialLinesDataFrame",
whose data.frame must contain the fields v0 and v1
matching the unique identifiers "ID" in the slot v data.frame
dist:Matrix, representing the undirected along-graph distance between all vertices in the network
path:list with variable length arrays describing the minimum distance path between vertices
Javier Garcia-Pintado, e-mail: [email protected]
splitPolyline returns a list with a number of transects along a
polyline
splitPolyline(xy, xyp, dmax)splitPolyline(xy, xyp, dmax)
xy |
2-column [x,y] matrix defining the polyline nodes |
xyp |
2-column [x,y] matrix with a point set |
dmax |
maximum distance between points in |
splitPolyline obtain the closest points in a polyline to a
given input set of points. Those closest points are used to divide the
polyline in a number of transects. The indivudual transects are
clipped to the input point dataset, so the different transects are
continuous in space. Note that if the input points is quite appart
from the polyline, the output seqence of transect may substantially
differ form the input polyline at rupture zones
A list in which each element is a matrix representing an individual polyline
splitSLDF divides the 1-Line Lines in the SpatialLines or the
SpatialLinesDataFrame at intersections with the input point dataset
splitSLDF(SLDF, SPDF, dmax=NULL)splitSLDF(SLDF, SPDF, dmax=NULL)
SLDF |
length-1 SpatialLinesDataFrame or SpatialLines object |
SPDF |
SpatialPointsDataFrame |
dmax |
maximum distance between points in |
splitPolyline obtain the closest points in the SpatialLinesDataFrame to a
given input set of points. Those closest points are used to divide the
polylines in a number of transects. The individual transects are
clipped to the input point dataset, so the different transects are
continuous in space. Note that if the input points is quite appart
from the polyline, the output sequence of transects may substantially
differ form the input polyline at rupture zones. The input parameter
dmax is provided as a mean to avoid too strange splitting
results. Setting dmax to a ver low value will reduce the spureous
results, but also the input points need to be closer to the lines for
the adequate recognition of splitting points
A SpatialLinesDataFrame or a SpatialLines, according to the input
A SpatialGraph contains a SpatialLinesDataFrame,
describing the network topology. This function adds line IDs
and direction arrows to an existing plot of a SpatialGraph.
textSGe(SG, acol='wheat', tcol='navyblue', arr.length=0.4)textSGe(SG, acol='wheat', tcol='navyblue', arr.length=0.4)
SG |
|
acol |
color of the graph direction arrows |
tcol |
color of the text for graph edge IDs |
arr.length |
length of the direction arrows |
Arrows and edge IDs added to a SpatialGraph plot