Splitting spatial lines at self intersections (line crossings)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Splitting spatial lines at self intersections (line crossings)

Glenn Stauffer
I have a Spatial Lines object I would like to split at every point where the
line self-intersects (crosses or touches itself), or anywhere lines touch
each other, if there are multiple lines.

I've tried using spatstat to convert the SpatialLines to a psp object and
then use the selfcrossing.psp function to find the intersection points (see
example below). But that seems to identify all the nodes, not just the
points where the line crosses. Also, even if it identified only the
crossings (which is what I want), I am not sure how to perform the next step
and split the lines at those points.

So, 1) I need to identify the crossings/touches, and 2) split the lines at
those points.

 

Essentially, what I am looking for is an R equivalent to the planarize
function in ArgGIS. Is there a relatively easy way to do this in R?

 

Thanks,

Glenn

 

Here is an example of what I have tried.

 

 

pts <- cbind(c(120:123,121,125),c(100,100,104,102,99,98))

pt2 <- cbind(c(124,124,123,118,124,125),c(100,97,100,104,106,110))

projstr <- "+init=epsg:3071"         # make everything in meters

L <- SpatialLines(list(Lines(list(Line(pts),Line(pt2)),"X")),proj4string =
CRS(projstr))

plot(L)

PSP <- as.psp.SpatialLines(L)

int <- selfcrossing.psp(PSP)

plot(int,add=TRUE,col="red") # identifies more than just the crossings

                               


        [[alternative HTML version deleted]]

_______________________________________________
R-sig-Geo mailing list
[hidden email]
https://stat.ethz.ch/mailman/listinfo/r-sig-geo
Reply | Threaded
Open this post in threaded view
|

Re: Splitting spatial lines at self intersections (line crossings)

Ege Rubak
The `psp` class in spatstat consists of individual line segments and
`selfcrossing.psp` checks whether each individual line intersects one of
the other lines, which happens at all the points in your plot.

If instead you treat each of the two line sequences as a `psp` you can
check find the crossings of the two `psp` objects. I.e., continuing your
code (with `spatstat` and `maptools` loaded):

L1 <- SpatialLines(list(Lines(list(Line(pts)), "X")))
L2 <- SpatialLines(list(Lines(list(Line(pt2)), "X")))
l1 <- as.psp(L1)
l2 <- as.psp(L2)
int <- crossing.psp(l1, l2)

This gives you the four intersections between the lines. I don't know of
a simple way to do the next task in `spatstat`. A useful function if you
are going to try to write some code is `test.crossing.psp` which gives
you a logical matrix indicating which segments cross.

Cheers,
Ege

On 01/25/2018 11:26 PM, Glenn Stauffer wrote:

> I have a Spatial Lines object I would like to split at every point where the
> line self-intersects (crosses or touches itself), or anywhere lines touch
> each other, if there are multiple lines.
>
> I've tried using spatstat to convert the SpatialLines to a psp object and
> then use the selfcrossing.psp function to find the intersection points (see
> example below). But that seems to identify all the nodes, not just the
> points where the line crosses. Also, even if it identified only the
> crossings (which is what I want), I am not sure how to perform the next step
> and split the lines at those points.
>
> So, 1) I need to identify the crossings/touches, and 2) split the lines at
> those points.
>
>  
>
> Essentially, what I am looking for is an R equivalent to the planarize
> function in ArgGIS. Is there a relatively easy way to do this in R?
>
>  
>
> Thanks,
>
> Glenn
>
>  
>
> Here is an example of what I have tried.
>
>  
>
>  
>
> pts <- cbind(c(120:123,121,125),c(100,100,104,102,99,98))
>
> pt2 <- cbind(c(124,124,123,118,124,125),c(100,97,100,104,106,110))
>
> projstr <- "+init=epsg:3071"         # make everything in meters
>
> L <- SpatialLines(list(Lines(list(Line(pts),Line(pt2)),"X")),proj4string =
> CRS(projstr))
>
> plot(L)
>
> PSP <- as.psp.SpatialLines(L)
>
> int <- selfcrossing.psp(PSP)
>
> plot(int,add=TRUE,col="red") # identifies more than just the crossings
>
>                                  
>
>
> [[alternative HTML version deleted]]
>
> _______________________________________________
> R-sig-Geo mailing list
> [hidden email]
> https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>

_______________________________________________
R-sig-Geo mailing list
[hidden email]
https://stat.ethz.ch/mailman/listinfo/r-sig-geo
Reply | Threaded
Open this post in threaded view
|

Re: Splitting spatial lines at self intersections (line crossings)

Michael Sumner-2
Ege: I don't believe that this code is enough to get coercion between sp
and spatstat:

pts <- cbind(c(120:123,121,125),c(100,100,104,102,99,98))
pt2 <- cbind(c(124,124,123,118,124,125),c(100,97,100,104,106,110))
library(sp)
library(spatstat)
L1 <- SpatialLines(list(Lines(list(Line(pts)), "X")))
L2 <- SpatialLines(list(Lines(list(Line(pt2)), "X")))
l1 <- as.psp(L1)
l2 <- as.psp(L2)
int <- crossing.psp(l1, l2)

Are we relying on some other code, or perhaps a specific version of
spatstat or its family?  (I know ways to convert from Spatial to psp, but I
was taken by this apparent lack of infrastructure - and I'm very keen on
seeing more bridges between these rich worlds).

Cheers, Mike


On Fri, 26 Jan 2018 at 17:48 Ege Rubak <[hidden email]> wrote:

> The `psp` class in spatstat consists of individual line segments and
> `selfcrossing.psp` checks whether each individual line intersects one of
> the other lines, which happens at all the points in your plot.
>
> If instead you treat each of the two line sequences as a `psp` you can
> check find the crossings of the two `psp` objects. I.e., continuing your
> code (with `spatstat` and `maptools` loaded):
>
> L1 <- SpatialLines(list(Lines(list(Line(pts)), "X")))
> L2 <- SpatialLines(list(Lines(list(Line(pt2)), "X")))
> l1 <- as.psp(L1)
> l2 <- as.psp(L2)
> int <- crossing.psp(l1, l2)
>
> This gives you the four intersections between the lines. I don't know of
> a simple way to do the next task in `spatstat`. A useful function if you
> are going to try to write some code is `test.crossing.psp` which gives
> you a logical matrix indicating which segments cross.
>
> Cheers,
> Ege
>
> On 01/25/2018 11:26 PM, Glenn Stauffer wrote:
> > I have a Spatial Lines object I would like to split at every point where
> the
> > line self-intersects (crosses or touches itself), or anywhere lines touch
> > each other, if there are multiple lines.
> >
> > I've tried using spatstat to convert the SpatialLines to a psp object and
> > then use the selfcrossing.psp function to find the intersection points
> (see
> > example below). But that seems to identify all the nodes, not just the
> > points where the line crosses. Also, even if it identified only the
> > crossings (which is what I want), I am not sure how to perform the next
> step
> > and split the lines at those points.
> >
> > So, 1) I need to identify the crossings/touches, and 2) split the lines
> at
> > those points.
> >
> >
> >
> > Essentially, what I am looking for is an R equivalent to the planarize
> > function in ArgGIS. Is there a relatively easy way to do this in R?
> >
> >
> >
> > Thanks,
> >
> > Glenn
> >
> >
> >
> > Here is an example of what I have tried.
> >
> >
> >
> >
> >
> > pts <- cbind(c(120:123,121,125),c(100,100,104,102,99,98))
> >
> > pt2 <- cbind(c(124,124,123,118,124,125),c(100,97,100,104,106,110))
> >
> > projstr <- "+init=epsg:3071"         # make everything in meters
> >
> > L <- SpatialLines(list(Lines(list(Line(pts),Line(pt2)),"X")),proj4string
> =
> > CRS(projstr))
> >
> > plot(L)
> >
> > PSP <- as.psp.SpatialLines(L)
> >
> > int <- selfcrossing.psp(PSP)
> >
> > plot(int,add=TRUE,col="red") # identifies more than just the crossings
> >
> >
> >
> >
> >       [[alternative HTML version deleted]]
> >
> > _______________________________________________
> > R-sig-Geo mailing list
> > [hidden email]
> > https://stat.ethz.ch/mailman/listinfo/r-sig-geo
> >
>
> _______________________________________________
> R-sig-Geo mailing list
> [hidden email]
> https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>
--
Dr. Michael Sumner
Software and Database Engineer
Australian Antarctic Division
203 Channel Highway
Kingston Tasmania 7050 Australia

        [[alternative HTML version deleted]]

_______________________________________________
R-sig-Geo mailing list
[hidden email]
https://stat.ethz.ch/mailman/listinfo/r-sig-geo
Reply | Threaded
Open this post in threaded view
|

Re: Splitting spatial lines at self intersections (line crossings)

Marcelino de la Cruz Rot
You should load before library(maptools) and the coercion is done.

Cheers

Marcelino




El 26/01/2018 a las 13:12, Michael Sumner escribió:

> Ege: I don't believe that this code is enough to get coercion between sp
> and spatstat:
>
> pts <- cbind(c(120:123,121,125),c(100,100,104,102,99,98))
> pt2 <- cbind(c(124,124,123,118,124,125),c(100,97,100,104,106,110))
> library(sp)
> library(spatstat)
> L1 <- SpatialLines(list(Lines(list(Line(pts)), "X")))
> L2 <- SpatialLines(list(Lines(list(Line(pt2)), "X")))
> l1 <- as.psp(L1)
> l2 <- as.psp(L2)
> int <- crossing.psp(l1, l2)
>
> Are we relying on some other code, or perhaps a specific version of
> spatstat or its family?  (I know ways to convert from Spatial to psp, but I
> was taken by this apparent lack of infrastructure - and I'm very keen on
> seeing more bridges between these rich worlds).
>
> Cheers, Mike
>
>
> On Fri, 26 Jan 2018 at 17:48 Ege Rubak <[hidden email]> wrote:
>
>> The `psp` class in spatstat consists of individual line segments and
>> `selfcrossing.psp` checks whether each individual line intersects one of
>> the other lines, which happens at all the points in your plot.
>>
>> If instead you treat each of the two line sequences as a `psp` you can
>> check find the crossings of the two `psp` objects. I.e., continuing your
>> code (with `spatstat` and `maptools` loaded):
>>
>> L1 <- SpatialLines(list(Lines(list(Line(pts)), "X")))
>> L2 <- SpatialLines(list(Lines(list(Line(pt2)), "X")))
>> l1 <- as.psp(L1)
>> l2 <- as.psp(L2)
>> int <- crossing.psp(l1, l2)
>>
>> This gives you the four intersections between the lines. I don't know of
>> a simple way to do the next task in `spatstat`. A useful function if you
>> are going to try to write some code is `test.crossing.psp` which gives
>> you a logical matrix indicating which segments cross.
>>
>> Cheers,
>> Ege
>>
>> On 01/25/2018 11:26 PM, Glenn Stauffer wrote:
>>> I have a Spatial Lines object I would like to split at every point where
>> the
>>> line self-intersects (crosses or touches itself), or anywhere lines touch
>>> each other, if there are multiple lines.
>>>
>>> I've tried using spatstat to convert the SpatialLines to a psp object and
>>> then use the selfcrossing.psp function to find the intersection points
>> (see
>>> example below). But that seems to identify all the nodes, not just the
>>> points where the line crosses. Also, even if it identified only the
>>> crossings (which is what I want), I am not sure how to perform the next
>> step
>>> and split the lines at those points.
>>>
>>> So, 1) I need to identify the crossings/touches, and 2) split the lines
>> at
>>> those points.
>>>
>>>
>>>
>>> Essentially, what I am looking for is an R equivalent to the planarize
>>> function in ArgGIS. Is there a relatively easy way to do this in R?
>>>
>>>
>>>
>>> Thanks,
>>>
>>> Glenn
>>>
>>>
>>>
>>> Here is an example of what I have tried.
>>>
>>>
>>>
>>>
>>>
>>> pts <- cbind(c(120:123,121,125),c(100,100,104,102,99,98))
>>>
>>> pt2 <- cbind(c(124,124,123,118,124,125),c(100,97,100,104,106,110))
>>>
>>> projstr <- "+init=epsg:3071"         # make everything in meters
>>>
>>> L <- SpatialLines(list(Lines(list(Line(pts),Line(pt2)),"X")),proj4string
>> =
>>> CRS(projstr))
>>>
>>> plot(L)
>>>
>>> PSP <- as.psp.SpatialLines(L)
>>>
>>> int <- selfcrossing.psp(PSP)
>>>
>>> plot(int,add=TRUE,col="red") # identifies more than just the crossings
>>>
>>>
>>>
>>>
>>>        [[alternative HTML version deleted]]
>>>
>>> _______________________________________________
>>> R-sig-Geo mailing list
>>> [hidden email]
>>> https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>>>
>> _______________________________________________
>> R-sig-Geo mailing list
>> [hidden email]
>> https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>>

--
Marcelino de la Cruz Rot
Depto. de Biología y Geología
Física y Química Inorgánica
Universidad Rey Juan Carlos
Móstoles España

_______________________________________________
R-sig-Geo mailing list
[hidden email]
https://stat.ethz.ch/mailman/listinfo/r-sig-geo
Reply | Threaded
Open this post in threaded view
|

Re: Splitting spatial lines at self intersections (line crossings)

Glenn Stauffer
In reply to this post by Ege Rubak
I think I have a solution now.
To recap, I wanted to planarize a line feature (split every line at every
line crossing), and I wanted an R solution so I could iterate over many
feature objects. My solution obviously does not strictly use R, but it is
carried out completely from within R. I used the v.clean algorithm from
GRASS, passed as an argument to the run_qgis function from the RQGIS
package. Seems to do exactly what I want.
My initial problem with v.clean was that I was passing a SpatialLines
feature instead of a SpatialLinesDataFrame feature to the algorithm.

Glenn

-----Original Message-----
From: Glenn Stauffer [mailto:[hidden email]]
Sent: Friday, January 26, 2018 12:29 PM
To: 'Ege Rubak' <[hidden email]>
Subject: RE: [R-sig-Geo] Splitting spatial lines at self intersections (line
crossings)

I think I am really close to a solution using the RQGIS package and the
GRASS function v.clean. The v.clean function should do exactly what I want,
but I have not been able to get it to work yet from R, although I could get
another GRASS functions to work (see example from Jannes Muenchow at
http://r-sig-geo.2731867.n2.nabble.com/v-split-length-GRASS-in-R-td7590611.h
tml ). When I try v.clean, I keep getting an error " Error in
file.exists(params[[i]]) : invalid 'file' argument", and have not been able
to ferret out the cause. I am going to start a new thread about this, and
report back here if I can get resolution.

Glenn

-----Original Message-----
From: R-sig-Geo [mailto:[hidden email]] On Behalf Of Ege
Rubak
Sent: Friday, January 26, 2018 12:49 AM
To: [hidden email]
Subject: Re: [R-sig-Geo] Splitting spatial lines at self intersections (line
crossings)

The `psp` class in spatstat consists of individual line segments and
`selfcrossing.psp` checks whether each individual line intersects one of the
other lines, which happens at all the points in your plot.

If instead you treat each of the two line sequences as a `psp` you can check
find the crossings of the two `psp` objects. I.e., continuing your code
(with `spatstat` and `maptools` loaded):

L1 <- SpatialLines(list(Lines(list(Line(pts)), "X")))
L2 <- SpatialLines(list(Lines(list(Line(pt2)), "X")))
l1 <- as.psp(L1)
l2 <- as.psp(L2)
int <- crossing.psp(l1, l2)

This gives you the four intersections between the lines. I don't know of a
simple way to do the next task in `spatstat`. A useful function if you are
going to try to write some code is `test.crossing.psp` which gives you a
logical matrix indicating which segments cross.

Cheers,
Ege

On 01/25/2018 11:26 PM, Glenn Stauffer wrote:

> I have a Spatial Lines object I would like to split at every point
> where the line self-intersects (crosses or touches itself), or
> anywhere lines touch each other, if there are multiple lines.
>
> I've tried using spatstat to convert the SpatialLines to a psp object
> and then use the selfcrossing.psp function to find the intersection
> points (see example below). But that seems to identify all the nodes,
> not just the points where the line crosses. Also, even if it
> identified only the crossings (which is what I want), I am not sure
> how to perform the next step and split the lines at those points.
>
> So, 1) I need to identify the crossings/touches, and 2) split the
> lines at those points.
>
>  
>
> Essentially, what I am looking for is an R equivalent to the planarize
> function in ArgGIS. Is there a relatively easy way to do this in R?
>
>  
>
> Thanks,
>
> Glenn
>
>  
>
> Here is an example of what I have tried.
>
>  
>
>  
>
> pts <- cbind(c(120:123,121,125),c(100,100,104,102,99,98))
>
> pt2 <- cbind(c(124,124,123,118,124,125),c(100,97,100,104,106,110))
>
> projstr <- "+init=epsg:3071"         # make everything in meters
>
> L <-
> SpatialLines(list(Lines(list(Line(pts),Line(pt2)),"X")),proj4string =
> CRS(projstr))
>
> plot(L)
>
> PSP <- as.psp.SpatialLines(L)
>
> int <- selfcrossing.psp(PSP)
>
> plot(int,add=TRUE,col="red") # identifies more than just the crossings
>
>                                  
>
>
> [[alternative HTML version deleted]]
>
> _______________________________________________
> R-sig-Geo mailing list
> [hidden email]
> https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>

_______________________________________________
R-sig-Geo mailing list
[hidden email]
https://stat.ethz.ch/mailman/listinfo/r-sig-geo

_______________________________________________
R-sig-Geo mailing list
[hidden email]
https://stat.ethz.ch/mailman/listinfo/r-sig-geo
Reply | Threaded
Open this post in threaded view
|

Re: Splitting spatial lines at self intersections (line crossings)

Michael Sumner-2
I think rgeos::gNode will do it,  prior to decomposition, and perhaps
requiring a union beforehand -  there are other options, but I got side
tracked exploring them :)

On Sat, 27 Jan 2018, 09:05 Glenn Stauffer, <[hidden email]> wrote:

> I think I have a solution now.
> To recap, I wanted to planarize a line feature (split every line at every
> line crossing), and I wanted an R solution so I could iterate over many
> feature objects. My solution obviously does not strictly use R, but it is
> carried out completely from within R. I used the v.clean algorithm from
> GRASS, passed as an argument to the run_qgis function from the RQGIS
> package. Seems to do exactly what I want.
> My initial problem with v.clean was that I was passing a SpatialLines
> feature instead of a SpatialLinesDataFrame feature to the algorithm.
>
> Glenn
>
> -----Original Message-----
> From: Glenn Stauffer [mailto:[hidden email]]
> Sent: Friday, January 26, 2018 12:29 PM
> To: 'Ege Rubak' <[hidden email]>
> Subject: RE: [R-sig-Geo] Splitting spatial lines at self intersections
> (line
> crossings)
>
> I think I am really close to a solution using the RQGIS package and the
> GRASS function v.clean. The v.clean function should do exactly what I want,
> but I have not been able to get it to work yet from R, although I could get
> another GRASS functions to work (see example from Jannes Muenchow at
>
> http://r-sig-geo.2731867.n2.nabble.com/v-split-length-GRASS-in-R-td7590611.h
> tml
> <http://r-sig-geo.2731867.n2.nabble.com/v-split-length-GRASS-in-R-td7590611.html>
> ). When I try v.clean, I keep getting an error " Error in
> file.exists(params[[i]]) : invalid 'file' argument", and have not been able
> to ferret out the cause. I am going to start a new thread about this, and
> report back here if I can get resolution.
>
> Glenn
>
> -----Original Message-----
> From: R-sig-Geo [mailto:[hidden email]] On Behalf Of Ege
> Rubak
> Sent: Friday, January 26, 2018 12:49 AM
> To: [hidden email]
> Subject: Re: [R-sig-Geo] Splitting spatial lines at self intersections
> (line
> crossings)
>
> The `psp` class in spatstat consists of individual line segments and
> `selfcrossing.psp` checks whether each individual line intersects one of
> the
> other lines, which happens at all the points in your plot.
>
> If instead you treat each of the two line sequences as a `psp` you can
> check
> find the crossings of the two `psp` objects. I.e., continuing your code
> (with `spatstat` and `maptools` loaded):
>
> L1 <- SpatialLines(list(Lines(list(Line(pts)), "X")))
> L2 <- SpatialLines(list(Lines(list(Line(pt2)), "X")))
> l1 <- as.psp(L1)
> l2 <- as.psp(L2)
> int <- crossing.psp(l1, l2)
>
> This gives you the four intersections between the lines. I don't know of a
> simple way to do the next task in `spatstat`. A useful function if you are
> going to try to write some code is `test.crossing.psp` which gives you a
> logical matrix indicating which segments cross.
>
> Cheers,
> Ege
>
> On 01/25/2018 11:26 PM, Glenn Stauffer wrote:
> > I have a Spatial Lines object I would like to split at every point
> > where the line self-intersects (crosses or touches itself), or
> > anywhere lines touch each other, if there are multiple lines.
> >
> > I've tried using spatstat to convert the SpatialLines to a psp object
> > and then use the selfcrossing.psp function to find the intersection
> > points (see example below). But that seems to identify all the nodes,
> > not just the points where the line crosses. Also, even if it
> > identified only the crossings (which is what I want), I am not sure
> > how to perform the next step and split the lines at those points.
> >
> > So, 1) I need to identify the crossings/touches, and 2) split the
> > lines at those points.
> >
> >
> >
> > Essentially, what I am looking for is an R equivalent to the planarize
> > function in ArgGIS. Is there a relatively easy way to do this in R?
> >
> >
> >
> > Thanks,
> >
> > Glenn
> >
> >
> >
> > Here is an example of what I have tried.
> >
> >
> >
> >
> >
> > pts <- cbind(c(120:123,121,125),c(100,100,104,102,99,98))
> >
> > pt2 <- cbind(c(124,124,123,118,124,125),c(100,97,100,104,106,110))
> >
> > projstr <- "+init=epsg:3071"         # make everything in meters
> >
> > L <-
> > SpatialLines(list(Lines(list(Line(pts),Line(pt2)),"X")),proj4string =
> > CRS(projstr))
> >
> > plot(L)
> >
> > PSP <- as.psp.SpatialLines(L)
> >
> > int <- selfcrossing.psp(PSP)
> >
> > plot(int,add=TRUE,col="red") # identifies more than just the crossings
> >
> >
> >
> >
> >       [[alternative HTML version deleted]]
> >
> > _______________________________________________
> > R-sig-Geo mailing list
> > [hidden email]
> > https://stat.ethz.ch/mailman/listinfo/r-sig-geo
> >
>
> _______________________________________________
> R-sig-Geo mailing list
> [hidden email]
> https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>
> _______________________________________________
> R-sig-Geo mailing list
> [hidden email]
> https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>


--
Dr. Michael Sumner
Software and Database Engineer
Australian Antarctic Division
203 Channel Highway
Kingston Tasmania 7050 Australia

        [[alternative HTML version deleted]]

_______________________________________________
R-sig-Geo mailing list
[hidden email]
https://stat.ethz.ch/mailman/listinfo/r-sig-geo