Skip to content

Cut SpatialLines into two Lines when intersecting with SpatialPolyon

5 messages · Wouter Steenbeek, Roger Bivand

#
[My apologies if this is a double post. I wrote the first post in HTML, and I think it may not have gotten through.]

I have a SpatialLines(DataFrame) (e.g. streets) and SpatialPolygons(DataFrame) (e.g. neighborhoods). When a Line intersects with a polygon boundary, I want to split this Line into two new Lines. So: if a street begins in one neighborhood and ends in another neighborhood, I want to remove the original SpatialLine and replace that by two SpatialLines (streets): one street from the starting point until the intersection with the polygon boundary, and another street from the intersection with the polygon boundary to the original end point.

Can someone give me advice on how to do this?

Cheers,
Wouter
#
On Tue, 3 Jun 2014, Wouter Steenbeek wrote:

            
Thanks for respecting our guidelines - it is much harder to infect plain 
text, which is why HTML is not welcome.
As in most cases, you will increase your chances of a reply if you provide 
a toy example, for instance using readWKT() in rgeos to generate the 
objects. Probably all you need is in rgeos, but without a toy example, it 
is hard to give advice that isn't more like hand-waving.

Roger

  
    
#
I'm sorry I didn't provide a toy example. I figured it was a simple question and I just couldn't find some well-known function.

I am not very familiar with readWKT(), but I used the sp_intro text to generate the following example:

library(sp)

Sr1 = Polygon(cbind(c(2,4,4,1,2),c(2,3,5,4,2)))
Sr2 = Polygon(cbind(c(5,4,2,5),c(2,3,2,2)))
Sr3 = Polygon(cbind(c(4,4,5,6,6,4),c(5,3,2,2,5,5)))
Sr4 = Polygon(cbind(c(6,6,8,8,6),c(5,2,2,5,5)))
Srs1 = Polygons(list(Sr1), "s1")
Srs2 = Polygons(list(Sr2), "s2")
Srs3 = Polygons(list(Sr3), "s3")
Srs4 = Polygons(list(Sr4), "s4")
SpP = SpatialPolygons(list(Srs1,Srs2,Srs3, Srs4), 1:4)
plot(SpP, col = 5:8) # these are three example neighborhoods

l1 = cbind(c(2,5),c(4,4))
l2 = cbind(c(5,7),c(3,3))
Sl1 = Line(l1)
Sl2 = Line(l2)
S1 = Lines(list(Sl1), ID="a")
S2 = Lines(list(Sl2), ID="b")
Sl = SpatialLines(list(S1,S2))
plot(Sl, add=TRUE) # two streets, which cross neighborhood boundaries

I am looking for a way to recode the lines into separate lines, when they cross a polygon boundary. So the resulting SpatialLines object should, for SpatialLine #1, have two new lines: one from (2,4) to (4,4), and another line from (4,4) to (5,4). For SpatialLine #2 there should also be two new lines created: one from (5,3) to (6,3) and another one from (6,3) to (7,3). Ideally these new lines should rename the IDs of the original SpatialLines in a convenient way.

Outcome would be a new SpatialLines object:

l1_1 = cbind(c(2,4),c(4,4))
l1_2 = cbind(c(4,5),c(4,4))
l2_1 = cbind(c(5,6),c(3,3))
l2_2 = cbind(c(6,7),c(3,3))
Sl1_1 = Line(l1_1)
Sl1_2 = Line(l1_2)
Sl2_1 = Line(l2_1)
Sl2_2 = Line(l2_2)
S1_1 = Lines(list(Sl1_1), ID="a_1")
S1_2 = Lines(list(Sl1_2), ID="a_2")
S2_1 = Lines(list(Sl2_1), ID="b_1")
S2_2 = Lines(list(Sl2_2), ID="b_2")
Sl2 = SpatialLines(list(S1_1,S1_2,S2_1,S2_2))
plot(Sl2, add=TRUE, col=1:4)

So I would like to convert Sl into Sl2 in some automatic manner. I'm thinking I should use "over" (from sp) to get the intersections of lines and polygons and go from there. But I don't quite see how to proceed from there (ie how to automatically "cut" a line into two lines).

By the way, if this is important to know: I'm actually working with SpatialPolygonsDataFrame and SpatialLinesDataFrame. So it would be nice if the two new lines (for example, S1_1 and S1_2) simply inherit the entire dataframe of the parent (in this example, the df attached to S1). My apologies that I don't provide that in the toy example, but I thought I'd keep the example as simple as possible.

Cheers,
Wouter



-----Original Message-----
From: Roger Bivand [mailto:Roger.Bivand at nhh.no] 
Sent: Tuesday, June 03, 2014 11:23 AM
To: Wouter Steenbeek
Cc: 'r-sig-geo at r-project.org'
Subject: Re: [R-sig-Geo] Cut SpatialLines into two Lines when intersecting with SpatialPolyon
On Tue, 3 Jun 2014, Wouter Steenbeek wrote:

            
Thanks for respecting our guidelines - it is much harder to infect plain text, which is why HTML is not welcome.
As in most cases, you will increase your chances of a reply if you provide a toy example, for instance using readWKT() in rgeos to generate the objects. Probably all you need is in rgeos, but without a toy example, it is hard to give advice that isn't more like hand-waving.

Roger
--
Roger Bivand
Department of Economics, Norwegian School of Economics, Helleveien 30, N-5045 Bergen, Norway.
voice: +47 55 95 93 55; fax +47 55 95 91 00
e-mail: Roger.Bivand at nhh.no
#
On Tue, 3 Jun 2014, Wouter Steenbeek wrote:

            
gI <- gIntersection(SpP, Sl, byid=c(TRUE, TRUE))
plot(gI, col=1:4, lwd=2, add=TRUE)
row.names(gI)

The row.names() of the output are predictable, and can be modified by 
modifying the row.names of the input objects.
No, you have to figure this out youself, using the components of the 
row.names of the output object, and ensure that the names of the variables 
in the new data.frame object are unique.

Hope this helps,

Roger