library(stplanr)
data(routes_fast)

# convert SpatialLinesDataFrame into  SpatialLinesNetwork
rnet <- overline(routes_fast, attrib = "length")
library(sp)
SLN <- SpatialLinesNetwork(rnet)

# identify nodes
sln_nodes = sln2points(SLN)

# Here is a bus stop which should be added as a node
new_point <- SpatialPointsDataFrame(coords = cbind(-1.535, 53.809), data= data.frame(id="new"))

# plot
plot(SLN, col = "gray")                 # network
plot(sln_nodes, col="red", add = TRUE)  # nodes
plot(new_point, add=T, col="blue")      # s

library(silicate)
routes_segments <- SC(sf::st_as_sf(routes_fast))
library(spatstat)
## Loading required package: spatstat.data
## Loading required package: nlme
## Loading required package: rpart
## 
## spatstat 1.55-0       (nickname: 'Stunned Mullet') 
## For an introduction to spatstat, type 'beginner'
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following object is masked from 'package:nlme':
## 
##     collapse
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
ow <- owin(range(routes_segments$vertex$x_),
           range(routes_segments$vertex$y_))
xy1 <- inner_join(routes_segments$edge, routes_segments$vertex, c(".vertex0" = "vertex_"))
xy2 <- inner_join(routes_segments$edge, routes_segments$vertex, c(".vertex1" = "vertex_"))

sptst_segs <- psp(x0 = xy1$x_, xy1$y_, x1 = xy2$x_, y1 = xy2$y_, window = ow)
sptst_pt <- ppp(coordinates(new_point)[1], coordinates(new_point)[2], window = ow)
inearest <- nearestsegment(sptst_pt, sptst_segs)
npt <- project2segment(sptst_pt, sptst_segs[inearest])

print(npt)
## $Xproj
## Planar point pattern: 1 point
## window: rectangle = [-1.550964, -1.510987] x [53.80248, 53.83041] units
## 
## $mapXY
## [1] 1
## 
## $d
## [1] 0.0001271516
## 
## $tp
## [1] 0.05574457
plot(rbind(xy1[inearest, c("x_", "y_")], xy2[inearest, c("x_", "y_")],
           setNames(as.data.frame(coordinates(new_point)), c("x_", "y_"))))
segments(c(xy1$x_[inearest], npt$Xproj$x),
          c(xy1$y_[inearest], npt$Xproj$y),
         c(npt$Xproj$x, xy2$x_[inearest]),
          c(npt$Xproj$y, xy2$y_[inearest]),
         col = c("firebrick", "dodgerblue"), lwd = 8)
plot(SLN, add = TRUE)


points(new_point, pch = "X")

## -  move out the inearest segment and replace with two
## -  ensure groupings are maintained from inearest
## -  reconstruct the SLN (use the SLN in the first place ...)