user3471881
user3471881

Reputation: 2724

Find neighbouring polygons R

I have one table containing +500k rows with coordinates x, y grouped by shapeid (289 ids in total) and forming a polygon.

shapeid      x           y
1            679400.3   6600354
1            679367.9   6600348
1            679313.3   6600340
1            679259.5   6600331
1            679087.5   6600201
0            661116.3   6606615
0            661171.5   6606604
0            661182.7   6606605
0            661198.9   6606606
0            661205.9   6606605
...          ...        ...

I want to find the coordinates which intersects or lies closest to each other, in essence finding the physical neighbours for each shapeid.

The results should look something like:

shapeid shapeid_neighbour1   shapeid_neighbour2

So I tried using sp and rgeos like so:

library(sp)
library(rgeos)

mydata <- read.delim('d:/temp/testfile.txt', header=T, sep=",")

sp.mydata <- mydata
coordinates(sp.mydata) <- ~x+y

When I run class, everything looks fine:

class(sp.mydata)
[1] "SpatialPointsDataFrame"
attr(,"package")
[1] "sp"

I now try calculating the distance by each point:

d <- gDistance(sp.mydata, byid=T)

R Studio encounters fatal error. Any ideas? My plan is then to use:

min.d <- apply(d, 1, function(x) order(x, decreasing=F)[2])

To find the second shortest distance, i.e. the closest point. But maybe this isn't the best approach to do what I want - finding the physical neighbours for each shapeid?

Upvotes: 0

Views: 1011

Answers (1)

nicola
nicola

Reputation: 24490

Assuming that each shapeid of your dataframe identifies the vertices of a polygon, you need first to create a SpatialPolygons object from the coordinates and then apply the function gDistance to know the distance between any pair of polygons (assuming that is what you are looking for). In order to create a SpatialPolygons you need a Polygons and in turn a Polygon object. You can find details in the help page of the sp package under Polygon.

You might find soon a problem: the coordinates of each polygons must close, i.e. the last vertex must be the same as the first for each shapeid. As far as I can see from your data, that seems not to be the case for you. So you should "manually" add a row for each subset of your data.

You can try this (assuming that df is your starting dataframe):

    require(rgeos)
    #split the dataframe for each shapeid and coerce to matrix
    coordlist<-lapply(split(df[,2:3],df$shapeid),as.matrix)
    #apply the following command only if the polygons don't close
    #coordlist<-lapply(coordilist, function(x) rbind(x,x[1,]))
    #create a SpatialPolygons for each shapeid
    SPList<-lapply(coordlist,function(x) SpatialPolygons(list(Polygons(list(Polygon(x)),1))))
    #initialize a matrix of distances
    distances<-matrix(0,ncol=length(SPList),nrow=length(SPList))
    #calculate the distances
    for (i in 1:(length(SPList)-1))
      for (j in (i+1):length(SPList))
        distances[i,j]<-gDistance(SPList[[i]],SPList[[j]])

This may require some time, since you are calculating 289*288/2 polygons distances. Eventually, you'll obtain a matrix of distances.

Upvotes: 1

Related Questions