如何从 R 中未定义但已知的空间点序列创建 SpatialLines 对象?

How to make a SpatialLines object from undefined - but known - spatial sequence of points in R?

我有一个 SpatialPoints 对象,它可以定义一个 SpatialLines 对象。问题是我没有关于创建线的点序列的任何信息属性。因此,按照 的顺序从点制作 Lines 我得到的线不符合我想要的标准。我想我必须根据 maybe:

定义一些规则
  1. 最近点
  2. 方向
  3. 或两者兼而有之

我怎样才能做到这一点?

# Load packages
library('sp')

# Load data
x <- c(788722.0, 788764.6, 788784.1, 788774.2, 788796.7, 788755.5, 788805.7, 788745.6, 788731.0, 788815.1, 788711.8, 788708.6, 788824.9, 788699.7, 788833.6, 788690.3, 788677.9, 788842.4, 788671.9, 788665.9)
y <- c(6193202, 6193217, 6193212, 6193212, 6193197, 6193217, 6193207, 6193216, 6193202, 6193211, 6193207, 6193230, 6193217, 6193235, 6193224, 6193235, 6193236, 6193230, 6193244, 6193252)

# Define projection
epsg.32721 <- "+proj=utm +zone=21 +south +datum=WGS84 +units=m +no_defs"

# Create SpatialPoints object
spatialPointsObject <- SpatialPoints(coords = cbind(x,y), proj4string = CRS(epsg.32721))

# Plot SpatialPoints
plot(spatialPointsObject, pch = 19, xlab = "Longitude", ylab = "Latitude", main = "SpatialPoints")
box()

SpatialPoints plot with order of points I want to achieve

# Create SpatialLines objects from SpatialPoints
line <- Line(coords = spatialPointsObject@coords)
lines <- Lines(slinelist = line, ID = "X")
spatialLinesObject <- SpatialLines(LinesList = list(lines), proj4string = CRS(epsg.32721))

# Plot SpatialLines + SpatialPoints
plot(spatialLinesObject, xlab = "Longitude", ylab = "Latitude", main = "SpatialLines + SpatialPoints")
points(spatialPointsObject, pch = 19)
box()

SpatialLines plot without the desired order of points I want to achieve

第二个例子

将点 6 移动到最右边以排除按 x 坐标 属性排序的点作为问题的解决方案

# Load packages
library('sp')

# Load data
x <- c(788722, 788764, 788784, 788774, 788796, 788755, 788805, 788745, 788731, 788815, 788711, 788720, 788824, 788699, 788833, 788690, 788677, 788842, 788671, 788665)
y <- c(6193202, 6193217, 6193212, 6193212, 6193197, 6193217, 6193207, 6193216, 6193202, 6193211, 6193207, 6193230, 6193217, 6193235, 6193224, 6193235, 6193236, 6193230, 6193244, 6193252)

# Define projection
epsg.32721 <- "+proj=utm +zone=21 +south +datum=WGS84 +units=m +no_defs"

# Create SpatialPoints object
spatialPointsObject <- SpatialPoints(coords = cbind(x,y), proj4string = CRS(epsg.32721))

# Plot SpatialPoints
plot(spatialPointsObject, pch = 19, xlab = "Longitude", ylab = "Latitude", main = "SpatialPoints")
box()

SpatialPoints plot with order of points I want to achieve

希望对您有所帮助:

# Load packages
library('sp')

# Load data
x <- c(788722.0, 788764.6, 788784.1, 788774.2, 788796.7, 788755.5, 788805.7, 788745.6, 788731.0, 788815.1, 788711.8, 788708.6, 788824.9, 788699.7, 788833.6, 788690.3, 788677.9, 788842.4, 788671.9, 788665.9)
y <- c(6193202, 6193217, 6193212, 6193212, 6193197, 6193217, 6193207, 6193216, 6193202, 6193211, 6193207, 6193230, 6193217, 6193235, 6193224, 6193235, 6193236, 6193230, 6193244, 6193252)

# Define projection
epsg.32721 <- "+proj=utm +zone=21 +south +datum=WGS84 +units=m +no_defs"

# Create SpatialPoints object
spatialPointsObject <- SpatialPoints(coords = cbind(x,y), proj4string = CRS(epsg.32721))

# Plot SpatialPoints
plot(spatialPointsObject, pch = 19, xlab = "Longitude", ylab = "Latitude", main = "SpatialPoints")
box()

# Create SpatialLines objects from SpatialPoints
tmp <- spatialPointsObject@coords
tmp <- as.data.frame(tmp)
tmp <- tmp[order(tmp$x),]

spatialPointsObject@coords <- as.matrix(tmp)
line  <- Line(coords = spatialPointsObject@coords)
lines <- Lines(slinelist = line, ID = "X")
spatialLinesObject <- SpatialLines(LinesList = list(lines), proj4string = CRS(epsg.32721))

# Plot SpatialLines + SpatialPoints
plot(spatialLinesObject, xlab = "Longitude", ylab = "Latitude", main = "SpatialLines + SpatialPoints")
points(spatialPointsObject, pch = 19)
box()

我可以解决我自己的问题:

选项 1

使用函数 (MakeSpatialLineFromUnsortedSpatialPoints) 将 起点 定义为 Point 1所需的线,然后找到最近的点作为 Point 2。在我得到 Point 2 之后,找到距离 Point 2 最近的点但排除 Point 1 得到 点3等等。要找到 Point n 我必须找到离 Point n-1[=60= 最近的点]n-1中排除所有之前的点。

我还在函数中包含了一些检查以验证 1) 输入 spatialPointsObject 是否是 SpatialPoints class 对象和 2) 如果存在重复点时发出警告。

选项 2

使用旅行商问题TSP

输入:

# Load packages
library('sp')
library('rgeos')

# Define projection
epsg.32721 <- "+proj=utm +zone=21 +south +datum=WGS84 +units=m +no_defs"

# Load data
x <- c(788722, 788764, 788784, 788774, 788796, 788755, 788805, 788745, 788731, 788815, 788711, 788720, 788824, 788699, 788833, 788690, 788677, 788842, 788671, 788665)
y <- c(6193202, 6193217, 6193212, 6193212, 6193197, 6193217, 6193207, 6193216, 6193202, 6193211, 6193207, 6193230, 6193217, 6193235, 6193224, 6193235, 6193236, 6193230, 6193244, 6193252)

# Create SpatialPoints object
spatialPointsObject <- SpatialPoints(coords = cbind(x,y), proj4string = CRS(epsg.32721))

# Plot SpatialPoints
plot(spatialPointsObject, pch = 19, xlab = "Longitude", ylab = "Latitude", main = "SpatialPoints")
box()

选项 1:

# Function
MakeSpatialLineFromUnsortedSpatialPoints <- function(spatialPointsObject, startPointCell, projection) {

# Check if spatialPointsObject is a SpatialPoints object
  isSP = class(spatialPointsObject) == "SpatialPoints"

  if(!isSP) {

return(print("Warning: the spatialPointsObject argument is not a SpatialPoints object"))

}

# Remove duplicate points
  n = length(spatialPointsObject)
spatialPointsObject = remove.duplicates(obj = spatialPointsObject,   remove.second = TRUE)

# Warn if there are duplicate points in data
if(n > length(spatialPointsObject)) {

 print("Warning: you have duplicate points in your SpatialPoints object. The duplicated points were removed.")

}

 seqCell = integer()
 seqCell[1] = startPointCell

# Now calculate pairwise distances between points excluding previous points

for(i in 2:length(spatialPointsObject)) {

distancesFromPoint = gDistance(spgeom1 =  spatialPointsObject[seqCell[i-1]], spgeom2 = spatialPointsObject, byid=TRUE)
minDist = min(distancesFromPoint[-seqCell,])
minDistCell = as.numeric(names(which(distancesFromPoint[,][-seqCell] == minDist)))

seqCell[i] = minDistCell

}

SL = SpatialLines(LinesList = list(Lines(slinelist = Line(spatialPointsObject[seqCell]@coords), ID = "1")), proj4string = CRS(projection))

return(SL)

}

spatialLinesObject <-   MakeSpatialLineFromUnsortedSpatialPoints(spatialPointsObject = spatialPointsObject, startPointCell = 20, projection = epsg.32721)

# Plots

# Plot SpatialPoints object
plot(spatialPointsObject, pch = 19, xlab = "Longitude", ylab = "Latitude", main = "")

# Plot starting point
plot(spatialPointsObject[20], pch = 19, col = 'blue', add = TRUE)

# Plot SpatialLines
plot(spatialLinesObject, col = 'green', add = TRUE)
box()

Plot: SpatialPoints and desired SpatialLine

更新

选项 2:

# Load packages
library('sp')
library('TSP')

# TSP
tsp <- TSP(dist(spatialPointsObject@coords))
tsp <- insert_dummy(tsp, label = "cut")
tour <- solve_TSP(tsp, method="nn", two_opt=TRUE, rep=10, start=20)
path.tsp <- unname(cut_tour(tour, "cut"))

spatialLinesObject <- SpatialLines(LinesList = list(Lines(slinelist = Line(spatialPointsObject[path.tsp,]@coords), ID = "1")), proj4string = CRS(epsg.32721))

# Plots

# Plot SpatialPoints object
plot(spatialPointsObject, pch = 19, xlab = "Longitude", ylab = "Latitude", main = "")

# Plot starting point
plot(spatialPointsObject[20], pch = 19, col = 'blue', add = TRUE)

# Plot SpatialLines
plot(spatialLinesObject, col = 'green', add = TRUE)
box()