1

I'm trying to use the v.net.steiner function within R, using the grass tools. But I get this error:

Error in execGRASS("v.net.steiner", input = "lx", output = "st", node_layer = "px",  : 
  The command:
v.net.steiner --overwrite --verbose input=lx output=st node_layer=px terminal_cats=0-1000000
produced an error (1) during execution:
Number of terminals: 0
ERROR: Terminales insuficientes (<2)

Using this code (where all seems to work just fine until the steiner process):

library(rgrass7)
library(rgdal)
library(rgeos)
library(sf)
library(raster)
library(mapview)

# PARAMETERS
lpath <- "./ls.gpkg"
ppath <- "./ps.gpkg"
output <- "./Output/"
crs <- "+init=epsg:25829"

#-------------------------------------------------------------------------------
# GRASS config
#-------------------------------------------------------------------------------
G <- initGRASS(gisBase = "/usr/lib/grass76",
               home = getwd(),
               gisDbase = getwd(),
               location = 'grassdata',
               mapset = "PERMANENT",
               override = TRUE)
G
use_sf()
execGRASS("g.proj", flags = "c", epsg = 25829)

#-------------------------------------------------------------------------------
# PROCESS
#-------------------------------------------------------------------------------
l <- readOGR(lpath)
p <- readOGR(ppath)

# MAP OF LINES, NODES AND POINTS OF INTEREST
mapview(l, cex = 1, map.types = c("OpenStreetMap")) +
    mapview(p, color="red")+
    mapview(st_combine(st_as_sf(l)), color= "blue")

#-------------------------------------------------------------------------------
# DISSOLVE
#-------------------------------------------------------------------------------
lx <- aggregate(l, dissolve = TRUE)
# or
lx <- st_cast(st_as_sf(lx),'MULTILINESTRING')
#or 
lx <- gLineMerge(lx)

# save layer to test it within qgis
st_write(st_as_sf(lx),"lx.gpkg")


#-------------------------------------------------------------------------------
# GRASS
#-------------------------------------------------------------------------------
# import clipped layers into grass
writeVECT(st_as_sf(lx), 'lx', v.in.ogr_flags = c('o','overwrite')) 
writeVECT(st_as_sf(p), 'px', v.in.ogr_flags = c('o','overwrite')) 
execGRASS("v.info", map = 'l')
execGRASS("v.info", map = 'p')

# create lines map connecting points to network (on layer 2)
execGRASS("v.net", input = 'lx', points = 'p', output = 'lxc',
          operation = 'connect', threshold = 500,flags = 'overwrite' )

# clean lines
execGRASS("v.clean",
          input = 'lx',
          output = 'l_clean',
          tool = c('break','snap'),
          threshold = c(10,10),
          flags = c('c','overwrite'))

# steiner tree
execGRASS("v.net.steiner",
          input = 'l_clean',
          output = 'st',
          node_layer = 'px',
          terminal_cats = '0-1000000',
          flags = c('overwrite','verbose'))

This reads two layers (lines and points), dissolves and cleans the lines, import into grass and perform an steiner tree.

¿Why do I do that dissolve part? Because, executing this v.net.steiner tool within QGIS it also fails, unless I do just a simple dissolve over lines.

Here is the error I get if I use just those lines and v.net.steiner:

enter image description here

...And here is the successful tool if I just do a simple dissolve over lines before:

enter image description here

The final goal is to execute this succesful v.net.steiner tree within R, by making the correct dissolve over lines or including another tool that avoids the error.

DOWNLOAD THE LAYERS

PD: I use QGIS 3.10 in Ubuntu 19.10.

  • Is it intentional that the input to the steiner algorithm is lxc instead of l_clean? – JonasV Apr 26 at 8:23
  • Sorry, It was a mistake. Corrected. – César Arquero Apr 26 at 8:31
  • And with l_clean as input it doen't work either? – JonasV Apr 26 at 8:39
  • No. I tryed, lines without dissolve (l), dissolved lines (lx) and dissolved and cleaned lines (l_clean). Always getting the same results. – César Arquero Apr 26 at 8:45
1

I foun it that, if you try to execute v.net.steiner within R, it will crush when you have some nodes connected to unconnected lines. Sometims, there are topology error and some others there are just lines not attached to the main network.

In this package, there is a function that uses grass tools to clean lines before using these in v.net.steiner --> https://github.com/cesarkero/IterativeSteinerTree

update.packages()
library(devtools)
install_github("cesarkero/IterativeSteinerTree")

library(IterativeSteinerTree)

# basic setGRASS (based on iniGRASS params but simplified)
setGRASS(gisBase = "/usr/lib/grass78", epsg= 25829)

# Windows setGRASS example: 
# setGRASS("C:/OSGeo4W64/apps/grass/grass78", home=tempdir(), override = TRUE)

# load sldf (l) and spdf (p)
data("l"); data("p")

# clean lines
lclean <- CleanLines(l)
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.