[R-sig-Geo] Using sf package to calculate line midpoints from Spatial Line data (both LINESTRING and MULTILINESTRING)

Roger Bivand Roger@B|v@nd @end|ng |rom nhh@no
Wed Feb 3 16:19:31 CET 2021


On Wed, 3 Feb 2021, abo using elrick.de wrote:

> Dear Julian,
>
> To get the midpoint of a line data just use st_centroid(). Here is a brief 
> example:

Not quite, but checking why not and in which cases would be interesting - 
please do run the code, the ouput is what is interesting:

library(maptools)
xx <- readShapeLines(system.file("shapes/fylk-val.shp",
   package="maptools")[1],
   proj4string=CRS("+proj=utm +zone=33 +datum=WGS84"))
spdf <- SpatialLinesMidPoints(xx)
oo <- sf::st_centroid(sf::st_as_sf(xx))
all.equal(sf::st_coordinates(oo), coordinates(spdf),
   check.attributes=FALSE, scale=1)
df <- sf::st_coordinates(oo) - coordinates(spdf)
df[apply(df, 1, function(x) any(abs(x) > 1)),]

geos <- rgeos::gCentroid(xx, byid=TRUE)
all.equal(sf::st_coordinates(oo), coordinates(geos),
   check.attributes=FALSE, scale=1) # same as st_centroid()

And:

lr <- t(sapply(1:length(xx), function(i)
   coordinates(rgeos::gInterpolate(xx[i,], d=0.5, normalized=TRUE))))
all.equal(coordinates(spdf), lr, check.attributes=FALSE, scale=1)

So rgeos::gInterpolate() and SpatialLinesMidPoints() appear to be 
interpolating along the line segments, that is using linear reference.

res <- gDistance(geos, xx, byid=TRUE)
summary(c(res))

res1 <- gDistance(spdf, xx, byid=TRUE)
summary(diag(res1))

So the linear reference measures give points on the lines, but centroids 
do not necessarily do so. Neither of GEOSInterpolateNormalized_r() nor 
GEOSInterpolate_r() appear in code in sf/src, so maptools or rgeos are at 
present the only alternatives; maybe one of the spatstat packages also 
provides linear reference.

Hope this clarifies,

Roger

>
> library(sf)
>
> # example with two lines
> ds <- data.frame(id = 1:2,
>            geom = c('LINESTRING(0 0, 2 2)', 'LINESTRING(3 2, 4 5)'))
> ds <- st_as_sf(ds, wkt = "geom")
> st_centroid(ds)
>
> # example with a multi line string
> ds <- data.frame(id = 1:1,
>            geom = c('MULTILINESTRING ((0 0, 2 2),(3 2, 4 5))'))
> ds <- st_as_sf(ds, wkt = "geom")
> st_centroid(ds)
>
> Hope that helps,
> Tim
>
> Zitat von Julian Parnelle <julianparnelle using outlook.com>:
>
>> Dear list,
>> 
>> My question is straightforward: how could one use the sf package to 
>> calculate the Longitude and Latitude of the line midpoints in spatial line 
>> data, in a way that works both for LINESTRING and MULTILINESTRING sf 
>> data.frames? (one per spatial line, in case the spatial line is composed of 
>> multiple line segments). After searching online for quite a bit, the only 
>> direct reference I found was this GIS Stack Exchange question from three 
>> years ago: 
>> https://gis.stackexchange.com/questions/277219/sf-equivalent-of-r-maptools-packages-spatiallinesmidpoints. 
>> However, the solution proposed there is only more or less reliable for 
>> LINESTRING data and I lack sufficient knowledge of sf objects and 
>> MULTILINESTRING representation to update that and make it more reliable.
>> 
>> I was used to doing that with the SpatialLinesMidPoints command, but I am 
>> finding it quite difficult to accomplish the same with the sf package. I do 
>> know that this task could perhaps be achieved by interpolating across the 
>> lines up to 50% of its extension, using for example 
>> ST_Line_Interpolate_Point. However, I don't see to be able to achieve 
>> exactly the same with either st_line_sample or st_segmentize.
>> 
>> Any suggestions would be very welcome.
>> 
>> Julian
>>
>>  [[alternative HTML version deleted]]
>> 
>> _______________________________________________
>> R-sig-Geo mailing list
>> R-sig-Geo using r-project.org
>> https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>
> _______________________________________________
> R-sig-Geo mailing list
> R-sig-Geo using r-project.org
> https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>

-- 
Roger Bivand
Department of Economics, Norwegian School of Economics,
Helleveien 30, N-5045 Bergen, Norway.
voice: +47 55 95 93 55; e-mail: Roger.Bivand using nhh.no
https://orcid.org/0000-0003-2392-6140
https://scholar.google.no/citations?user=AWeghB0AAAAJ&hl=en



More information about the R-sig-Geo mailing list