GithubHelp home page GithubHelp logo

Comments (4)

luukvdmeer avatar luukvdmeer commented on May 26, 2024

This could also be named st_add_node instead.

from sfnetworks.

luukvdmeer avatar luukvdmeer commented on May 26, 2024

After long consideration this turned into a new function name st_blend, available now on develop and ready to be tested @loreabad6 @Robinlovelace @agila5

To blend is to mix smoothly and inseparably together. Seemed appropriate to me.

Now what does it do? You provide the function a set of geospatial points. Then, blending a point into a network is the combined process of first snapping the given point to its nearest point on its nearest edge in the network, subsequently splitting that edge at the location of the snapped point, and finally adding the snapped point as node to the network. If the location of the snapped point is already a node in the network, the attributes of the point (if any) will be joined to that node.

Additionally, you can specify a tolerance (by default meters will be assumed as unit, but you can also provide a units object with any unit). Then, only points that are within the tolerance distance from the network will be blended.

Note that st_blend knows about the precision issues that cause nearest points on lines to not intersect with the line itself. It handles that internally.

Again, I am not yet sure about performance on large networks.

library(sfnetworks)
library(sf)
#> Linking to GEOS 3.7.1, GDAL 2.2.2, PROJ 4.9.2

# First, create a network and a set of points to blend.
n11 = st_point(c(0,0))
n12 = st_point(c(1,1))
e1 = st_sfc(st_linestring(c(n11, n12)), crs = 4326)

n21 = n12
n22 = st_point(c(0,2))
e2 = st_sfc(st_linestring(c(n21, n22)), crs = 4326)

n31 = n22
n32 = st_point(c(-1,1))
e3 = st_sfc(st_linestring(c(n31, n32)), crs = 4326)

net = as_sfnetwork(st_as_sf(c(e1,e2,e3)))

pts = net %>% 
  st_bbox() %>% 
  st_as_sfc() %>% 
  st_sample(10, type = "random") %>% 
  st_set_crs(4326) %>% 
  st_cast('POINT')
#> although coordinates are longitude/latitude, st_intersects assumes that they are planar
#> although coordinates are longitude/latitude, st_intersects assumes that they are planar

par(mar = c(1,1,1,1))
plot(net)
plot(pts, col = "red", pch = 20, add = T)

# Blend points into the network.
# --> By default tolerance is set to Inf
# --> Meaning that all points get blended
b1 = st_blend(net, pts)
#> Warning: Although coordinates are longitude/latitude, st_blend assumes that they
#> are planar
#> Warning: st_blend assumes attributes are constant over geometries
b1
#> # An sfnetwork with 12 nodes and 11 edges
#> #
#> # CRS:  EPSG:4326 
#> #
#> # A rooted tree with spatially explicit edges
#> #
#> # Node Data:     12 x 1 (active)
#> # Geometry type: POINT
#> # Dimension:     XY
#> # Bounding box:  xmin: -1 ymin: 0 xmax: 1 ymax: 2
#>                       x
#>             <POINT [°]>
#> 1                 (0 0)
#> 2 (0.3229385 0.3229385)
#> 3   (0.424982 0.424982)
#> 4 (0.5928614 0.5928614)
#> 5                 (1 1)
#> 6  (0.5706555 1.429344)
#> # … with 6 more rows
#> #
#> # Edge Data:     11 x 3
#> # Geometry type: LINESTRING
#> # Dimension:     XY
#> # Bounding box:  xmin: -1 ymin: 0 xmax: 1 ymax: 2
#>    from    to                                        x
#>   <int> <int>                         <LINESTRING [°]>
#> 1     1     2               (0 0, 0.3229385 0.3229385)
#> 2     2     3 (0.3229385 0.3229385, 0.424982 0.424982)
#> 3     3     4 (0.424982 0.424982, 0.5928614 0.5928614)
#> # … with 8 more rows
plot(b1)
plot(pts, col = "red", pch = 20, add = T)

# Blend points with a tolerance.
# Lets first plot the points within a tolerance
tol = units::set_units(40, "km")
within = st_is_within_distance(pts, st_geometry(net, "edges"), tol)
pts_within = pts[lengths(within) > 0]
plot(net)
plot(pts, col = "grey", pch = 20, add = T)
plot(pts_within, col = "red", pch = 20, add = T)

# Then blend with the tolerance
b2 = st_blend(net, pts, tolerance = tol)
#> Warning: Although coordinates are longitude/latitude, st_blend assumes that they
#> are planar

#> Warning: st_blend assumes attributes are constant over geometries
b2
#> # An sfnetwork with 9 nodes and 8 edges
#> #
#> # CRS:  EPSG:4326 
#> #
#> # A rooted tree with spatially explicit edges
#> #
#> # Node Data:     9 x 1 (active)
#> # Geometry type: POINT
#> # Dimension:     XY
#> # Bounding box:  xmin: -1 ymin: 0 xmax: 1 ymax: 2
#>                       x
#>             <POINT [°]>
#> 1                 (0 0)
#> 2   (0.424982 0.424982)
#> 3 (0.5928614 0.5928614)
#> 4                 (1 1)
#> 5  (0.5173618 1.482638)
#> 6                 (0 2)
#> # … with 3 more rows
#> #
#> # Edge Data:     8 x 3
#> # Geometry type: LINESTRING
#> # Dimension:     XY
#> # Bounding box:  xmin: -1 ymin: 0 xmax: 1 ymax: 2
#>    from    to                                        x
#>   <int> <int>                         <LINESTRING [°]>
#> 1     1     2                 (0 0, 0.424982 0.424982)
#> 2     2     3 (0.424982 0.424982, 0.5928614 0.5928614)
#> 3     3     4               (0.5928614 0.5928614, 1 1)
#> # … with 5 more rows
plot(b2)
plot(pts, col = "grey", pch = 20, add = T)
plot(pts_within, col = "red", pch = 20, add = T)

Created on 2020-10-29 by the reprex package (v0.3.0)

If you want the nodes to be sorted in the same order as the original network, set sort = TRUE.

from sfnetworks.

Robinlovelace avatar Robinlovelace commented on May 26, 2024

Looks good to me!

from sfnetworks.

luukvdmeer avatar luukvdmeer commented on May 26, 2024

This is now part of the new version as st_network_blend. See the join and filter vignette and the function reference.

from sfnetworks.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.