Blending a point into a network is the combined process of first projecting the point onto its nearest point on its nearest edge in the network, then subdividing that edge at the location of the projected point, and finally adding the projected point as node to the network. If the location of the projected point is equal an existing node in the network, the attributes of the point will be joined to that node, instead of adding a new node.
Arguments
- x
An object of class
sfnetwork
.- y
The spatial features to be blended, either as object of class
sf
orsfc
, withPOINT
geometries.- tolerance
The tolerance distance to be used. Only features that are at least as close to the network as the tolerance distance will be blended. Should be a non-negative number preferably given as an object of class
units
. Otherwise, it will be assumed that the unit is meters. If set toInf
all features will be blended. Defaults toInf
.- ignore_duplicates
If there are multiple points in
y
that have the same projected location, only the first one of them is blended into the network. But what should happen with the others? If this argument is set toTRUE
, they will be ignored. If this argument is set toFALSE
, they will be added as isolated nodes to the returned network. Nodes at equal locations can then be merged using the spatial morpherto_spatial_unique
. Defaults toTRUE
.
Value
The blended network as an object of class sfnetwork
.
Details
When the projected location of a given point intersects with more
than one edge, it is only blended into the first of these edges. Edges are
not connected at blending locations. Use the spatial morpher
to_spatial_subdivision
for that.
To determine if a projected point is equal to an existing node, and to
determine if multiple projected points are equal to each other, sfnetworks
by default rounds coordinates to 12 decimal places. You can influence this
behavior by explicitly setting the precision of the network using
st_set_precision
.
Note
Due to internal rounding of rational numbers, it may occur that the intersection point between a line and a point is not evaluated as actually intersecting that line by the designated algorithm. Instead, the intersection point lies a tiny-bit away from the edge. Therefore, it is recommended to set the tolerance to a very small number (for example 1e-5) even if you only want to blend points that intersect an edge.
Examples
library(sf, quietly = TRUE)
oldpar = par(no.readonly = TRUE)
par(mar = c(1,1,1,1), mfrow = c(1,2))
# Create a spatial network.
n1 = st_point(c(0, 0))
n2 = st_point(c(1, 0))
n3 = st_point(c(2, 0))
e1 = st_sfc(st_linestring(c(n1, n2)), crs = 3857)
e2 = st_sfc(st_linestring(c(n2, n3)), crs = 3857)
net = as_sfnetwork(c(e1, e2))
# Create spatial points to blend in.
p1 = st_sfc(st_point(c(0.5, 0.1)))
p2 = st_sfc(st_point(c(0.5, -0.2)))
p3 = st_sfc(st_point(c(1, 0.2)))
p4 = st_sfc(st_point(c(1.75, 0.2)))
p5 = st_sfc(st_point(c(1.25, 0.1)))
pts = st_sf(foo = letters[1:5], geometry = c(p1, p2, p3, p4, p5), crs = 3857)
# Blend all points into the network.
b1 = st_network_blend(net, pts)
#> Warning: `st_network_blend()` did not blend in all requested features.
#> ! Some projected features have duplicated locations, of which all but the first
#> one are ignored.
#> ℹ If you want to add duplicated projection locations as isolated nodes instead,
#> set `ignore_duplicates` to `FALSE`.
b1
#> # A sfnetwork: 6 nodes and 5 edges
#> #
#> # A rooted tree with spatially explicit edges
#> #
#> # Dimension: XY
#> # Bounding box: xmin: 0 ymin: 0 xmax: 2 ymax: 0
#> # Projected CRS: WGS 84 / Pseudo-Mercator
#> #
#> # Node data: 6 × 2 (active)
#> x foo
#> <POINT [m]> <chr>
#> 1 (0 0) NA
#> 2 (1 0) c
#> 3 (2 0) NA
#> 4 (0.5 0) a
#> 5 (1.25 0) e
#> 6 (1.75 0) d
#> #
#> # Edge data: 5 × 3
#> from to x
#> <int> <int> <LINESTRING [m]>
#> 1 1 4 (0 0, 0.5 0)
#> 2 4 2 (0.5 0, 1 0)
#> 3 2 5 (1 0, 1.25 0)
#> # ℹ 2 more rows
plot(net)
plot(st_geometry(pts), pch = 20, col = "orange", add = TRUE)
plot(b1)
plot(st_geometry(pts), pch = 20, col = "orange", add = TRUE)
# Blend points within a tolerance distance.
tol = units::set_units(0.1, "m")
b2 = st_network_blend(net, pts, tolerance = tol)
b2
#> # A sfnetwork: 5 nodes and 4 edges
#> #
#> # A rooted tree with spatially explicit edges
#> #
#> # Dimension: XY
#> # Bounding box: xmin: 0 ymin: 0 xmax: 2 ymax: 0
#> # Projected CRS: WGS 84 / Pseudo-Mercator
#> #
#> # Node data: 5 × 2 (active)
#> x foo
#> <POINT [m]> <chr>
#> 1 (0 0) NA
#> 2 (1 0) NA
#> 3 (2 0) NA
#> 4 (0.5 0) a
#> 5 (1.25 0) e
#> #
#> # Edge data: 4 × 3
#> from to x
#> <int> <int> <LINESTRING [m]>
#> 1 1 4 (0 0, 0.5 0)
#> 2 4 2 (0.5 0, 1 0)
#> 3 2 5 (1 0, 1.25 0)
#> # ℹ 1 more row
plot(net)
plot(st_geometry(pts), pch = 20, col = "orange", add = TRUE)
plot(b2)
plot(st_geometry(pts), pch = 20, col = "orange", add = TRUE)
# Add points with duplicated projected location as isolated nodes.
b3 = st_network_blend(net, pts, ignore_duplicates = FALSE)
#> Warning: `st_network_blend()` created isolated nodes.
#> ! Some projected features have duplicated locations, of which all but the first
#> one are added as isolated nodes to the network.
#> ℹ If you want to ignore duplicated projection locations instead, set
#> `ignore_duplicates` to `TRUE`.
b3
#> # A sfnetwork: 7 nodes and 5 edges
#> #
#> # A rooted forest with 2 trees and spatially explicit edges
#> #
#> # Dimension: XY
#> # Bounding box: xmin: 0 ymin: 0 xmax: 2 ymax: 0
#> # Projected CRS: WGS 84 / Pseudo-Mercator
#> #
#> # Node data: 7 × 2 (active)
#> x foo
#> <POINT [m]> <chr>
#> 1 (0 0) NA
#> 2 (1 0) c
#> 3 (2 0) NA
#> 4 (0.5 0) a
#> 5 (1.25 0) e
#> 6 (1.75 0) d
#> # ℹ 1 more row
#> #
#> # Edge data: 5 × 3
#> from to x
#> <int> <int> <LINESTRING [m]>
#> 1 1 4 (0 0, 0.5 0)
#> 2 4 2 (0.5 0, 1 0)
#> 3 2 5 (1 0, 1.25 0)
#> # ℹ 2 more rows
par(oldpar)