假设我在R中有一个具有高级地理细节的spatialLines(DataFrame)对象。我想简化这个对象(减少创建对象所需的坐标点的数量,一些细节的丢失是可以的),然后将其转换为igraph对象。
每个坐标点应该是图中的一个节点。图节点属性应包含地理坐标,边属性应包含节点之间的地理距离。边还应该继承存储在SpatialLines对象的DataFrame部分中的属性。
这是我到目前为止所做的:
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)
但是,gSimplify命令会删除DataFrame。我仍然需要仔细检查这是对的。
数据是从https://my.vanderbilt.edu/jeremyatack/data-downloads/加载为SpatialLinesDataFrame的运河shapefile。
答案 0 :(得分:0)
在不详细了解spatialLines
对象的情况下,您最有可能使用graph.data.frame
参数vertices
而不是NULL
。
根据您的稀缺描述,它可能是这样的:
g = graph.data.frame(edge_list_with_distances, FALSE, points_with_coordinates)
其中:
points_with_coordinates
是一个包含所有点及其属性的数据框(第一列是点名或唯一ID,在结果图中成为符号顶点名称)
edge_list_with_distances
是一个数据框,其中包含这些点之间的距离:前两列必须与points_with_distances
)中的顶点符号名称相对应。