2016-06-02 7 views
1

Angenommen, ich habe ein SpatialLines (DataFrame) -Objekt in R mit einem hohen Grad an geografischen Details. Ich möchte dieses Objekt vereinfachen (reduzieren Sie die Anzahl der Koordinatenpunkte, die zum Erstellen des Objekts benötigt werden, einige Detailverluste sind in Ordnung) und wandeln es dann in ein igraph-Objekt um.Vereinfachen spatialLines-Objekt und Konvertieren in das Objekt iigraph

Jeder Koordinatenpunkt sollte ein Knoten im Diagramm sein. Die Attribute des Diagrammknotens sollten die geografischen Koordinaten enthalten und die Kantenattribute sollten die geografische Entfernung zwischen den Knoten enthalten. Die Kanten sollten auch die Attribute erben, die im Dataframe-Teil des SpatialLines-Objekts gespeichert sind. Hier

ist das, was ich bisher getan:

readShapeFile <- function(path, filename, crs){ 
    shapefile <- readOGR(path.expand(path), filename) 
    if(is.na(is.projected(shapefile))){ 
     projection(shapefile) <- CRS(crs) 
    } else{ 
     shapefile <- spTransform(shapefile, CRS(crs)) 
    } 
    return(shapefile) 
} 

canal_shapefile <- readShapeFile(PATH, FILENAME, "+init=epsg:4326") 

lines <- canal_shapefile 
length(coordinates(lines)[[1]][[1]][, 1]) ### To indicate how 'complex' the object is. 
lines <- gSimplify(lines, tol = .001) 
length(coordinates(lines)[[1]][[1]][, 1]) 

nodes <- NULL 
edges <- NULL 
for(i in 1:length(coordinates(lines))){ 
    nodes <- rbind(nodes, coordinates(lines)[[i]][[1]]) 
    for (j in 2:length(coordinates(lines)[[i]][[1]][, 1])){ 
    node1 <- coordinates(lines)[[i]][[1]][j - 1, ] 
    node2 <- coordinates(lines)[[i]][[1]][j, ] 
    dist <- distance(node1[2], node1[1], node2[2], node2[1])$distance 
    edges <- rbind(edges, c(node1, node2, dist)) 
    } 
} 
colnames(edges) <- c("node1_long", "node1_lat", "node2_long", "node2_lat", "dist") 

NODE1 <- match(sprintf("%s:%s", edges[, "node1_long"], edges[, "node1_lat"]), 
      sprintf("%s:%s", nodes[, 1], nodes[, 2])) 
NODE2 <- match(sprintf("%s:%s", edges[, "node2_long"], edges[, "node2_lat"]), 
      sprintf("%s:%s", nodes[, 1], nodes[, 2])) 
EDGES <- cbind(NODE1, NODE2, edges[, "dist"]) 
NODES <- cbind(1:length(nodes[, 1]), nodes) 

g <- graph.data.frame(EDGES, FALSE, NODES) 

jedoch der gSimplify Befehl die Datenrahmen entfernt. Ich muss noch überprüfen, ob das richtig ist.

Daten sind die Shapefiles der Kanäle, die als SpatialLinesDataFrame von https://my.vanderbilt.edu/jeremyatack/data-downloads/ geladen werden.

+2

Bitte geben Sie den reproduzierbaren Code und die Daten für das, was Sie bisher versucht haben, an. http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-beispiel –

+0

@ Hack-R, fügte ich die Datenquelle und teilweise Lösung. Vielen Dank. – LJB

Antwort

0

Ohne in Details Ihres Objekts spatialLines zu gelangen, verwenden Sie am wahrscheinlichsten graph.data.frame mit Argument vertices nicht NULL.

Basierend auf Ihrer knappen Beschreibung könnte es so aussehen:

g = graph.data.frame(edge_list_with_distances, FALSE, points_with_coordinates) 

wo:

points_with_coordinates einen Datenrahmen enthält alle Punkte mit ihren Attributen (erste Spalte ist ein Punktname oder eindeutige ID , die zu symbolischen Eckpunktnamen im resultierenden Graphen werden)

edge_list_with_distancesedge_list_with_distances ist ein Datenrahmen mit den Abständen zwischen diesen Punkten: die ersten beiden Spalten müssen den symbolischen Eckpunktnamen ausentsprechen).