[R-sig-Geo] gIntersection error in rgeos package
Roger Bivand
Roger.Bivand at nhh.no
Mon Sep 24 10:21:38 CEST 2012
On Mon, 24 Sep 2012, maogui.hu wrote:
> Hi all, I found a problem when using the "gIntersection" in rgeos for
> two lines. The expected result is a long line shared by two lines.
> However, the result I obtained is a short line (a part of the afore
> mentioned long line). I have tried to change the setScale() value for
> different operation precision. But the result is almost the same. I
> think may be it is a bug of the function. Attached are the data, r code
> and results. Can anybody help me to solve it? thanks very much.
Hi,
I think that this is a noding problem. sline1 has a long line along its
northern boundary, which visually overlaps the segment in sline2 on the
northern edge of the "bay" extending from the west. However, there is no
node in sline1 matching the node where sline2 turns north-west, then
north. The C interface that rgeos uses does not seem to offer noding;
it is deeper in the C++ code.
What you are trying to do is to approximate the results you might get from
a topological GIS, that is boundary line lengths between contiguous
polygons. Usually, topological GIS will node line segments before
cleaning. Curiously, your shapefiles contain LEFT_FID RIGHT_FID
attributes, so somewhere the data have been in a topological GIS.
I did try:
row.names(sline2) <- "1"
slines12 <- rbind.SpatialLinesDataFrame(sline1, sline2)
spoly12 <- gPolygonize(slines12)
slines12a <- as(spoly12, "SpatialLines")
gI1 <- gIntersection(slines12a[1], slines12a[2])
but the result is unchanged, not surprisingly, as ?gPolygonize says that
"Linestrings are expected to be fully noded, as such they must not cross
and must touch only at endpoints."
On reading:
writeOGR(SpatialPolygonsDataFrame(spoly12, data=as(slines12,
"data.frame")), ".", "spoly12", driver="ESRI Shapefile")
into GRASS, I see:
v.in.ogr dsn=/home/rsb/tmp/bigshape/rgeos/spoly12.shp layer=spoly12
output=spoly12
Layer: spoly12
Counting polygons for 2 features...
Importing map 2 features...
...
-----------------------------------------------------
Cleaning polygons, result is not guaranteed!
-----------------------------------------------------
...
Building topology for vector map <spoly12_tmp>...
Building areas...
3 areas built
1 isles built
Attaching islands...
Number of nodes: 4
Number of primitives: 12
Number of points: 0
Number of lines: 0
Number of boundaries: 12
Number of centroids: 0
Number of areas: 3
Number of isles: 1
Number of areas without centroid: 3
-----------------------------------------------------
Find centroids for layer: spoly12
-----------------------------------------------------
Write centroids:
1 areas represent more (overlapping) features, because polygons overlap in
input layer(s). Such areas are linked to more than 1 row in attribute
table. The number of features for those areas is stored as category in
layer 2
-----------------------------------------------------
2 input polygons
Total area: 1.84677E+08 (3 areas)
Overlapping area: 183.124 (1 areas)
Area without category: 0 (0 areas)
-----------------------------------------------------
Building topology for vector map <spoly12>...
Registering primitives...
8 primitives registered
177 vertices registered
Building areas...
3 areas built
1 isles built
Attaching islands...
Attaching centroids...
Number of nodes: 6
Number of primitives: 8
Number of points: 0
Number of lines: 0
Number of boundaries: 5
Number of centroids: 3
Number of areas: 3
Number of isles: 1
So rgeos/GEOS are being confused by the input topologies, in which lines
that appear to coincide actually do not, and in which the line segments do
not share the same end points. Reading the polygons back into R from
GRASS, I get the same intersection length. So I'm afraid that the issue is
in the input data, which contains a tiny overlap between the polygons,
leading to a mismatch between the lines. The overlap is only 183 square
metres, so is not visible on plots.
I think that the only way to repair the data is to add extra nodes, and
snap them using a digitizer in a GIS, or possibly to edit the coordinates
of sline1 manually to ensure that they match those of that part of sline2
as closely as possible.
Hope this clarifies,
Roger
>
> require(maptools)
> require(rgeos)
>
> ws <- "E:/testdata/"
> sline1 <- readShapeLines(file.path(ws, "Line01.shp"))
> sline2 <- readShapeLines(file.path(ws, "Line02.shp"))
>
> Intersection <- function(line1, line2)
> {
> gL <- c()
> nLength <- 0
> for(s in 10^c(-2:8))
> {
> setScale(s)
> gL0 <- gIntersection(line1, line2)
> if(gLength(gL0) > nLength)
> {
> gL <- gL0
> nLength <- gLength(gL)
> }
> }
> setScale()
> return(gL)
> }
>
> par(mfrow=c(2,2))
> plot(sline1, col="red")
> plot(sline2, col="blue")
> plot(rbind.SpatialLines(sline1, sline2, makeUniqueIDs=TRUE), col=c("red","blue"))
> rslt <- Intersection(sline1, sline2)
> plot(rslt, col="green")
>
>
>
>
> maogui.hu
--
Roger Bivand
Department of Economics, NHH Norwegian School of Economics,
Helleveien 30, N-5045 Bergen, Norway.
voice: +47 55 95 93 55; fax +47 55 95 95 43
e-mail: Roger.Bivand at nhh.no
More information about the R-sig-Geo
mailing list