将左上角和右下角坐标给出的矩形有效地分割成较小的矩形

时间:2018-12-21 13:23:06

标签: r

我有一个由纬度和经度指定的矩形,分别代表该矩形的左上角和右下角。我想将此矩形拆分为几个较小的矩形。较小的矩形也应该由左上角和右下角的坐标给出。

到目前为止,我可以通过创建占位符列表然后运行嵌套的for循环来创建较小的矩形。

我认为这不是一个有效的解决方案,而是希望使代码更高效。

输出最好是listdata.tabledata.table的每一行可以有4列指定坐标。

到目前为止我的代码:

# the big rectangle i want to split
big_rectangle <- list(top_left = c("lat" = 50.183297, "lon" = 14.223024),
                      bottom_right = c("lat" = 49.945189, "lon" = 14.706829))

# sequence along the sides of the rectangle:
lat <- seq(from = big_rectangle[["bottom_right"]]["lat"],
           to = big_rectangle[["top_left"]]["lat"], length = 20)
lon <- seq(from = big_rectangle[["top_left"]]["lon"],
           to = big_rectangle[["bottom_right"]]["lon"], length = 20)

# create a list of small rectangles, each given by its top left and bottom right corners:
holder <- vector("list", (length(lat) - 1) * (length(lon) - 1))
iterator <- 1
for (i in 1:(length(lat) - 1))
{
  for (j in 1:(length(lon) - 1))
  {
    holder[[iterator]] <- list(top_left = c("lat" = lat[i + 1], "lon" = lon[j]), bottom_right = c("lat" = lat[i], "lon" = lon[j+1]))
    iterator = iterator + 1
  }
}

3 个答案:

答案 0 :(得分:1)

这个怎么样?制作索引的所有组合,保留上一步和上一步的索引,然后再返回到坐标?

^([^,]{5,7},)*[^,][^ ]{5,7}$

答案 1 :(得分:1)

与Halvorsen基本概念相同,但是由于感兴趣的坐标都以可预测的方式间隔开了,因此进行匹配似乎有点浪费。

width <- 5
height <- 4

brm <- do.call(cbind, big_rectangle)
lat <- seq(brm[1, 1], brm[1, 2], length.out=width+1)
lon <- seq(brm[2, 1], brm[2, 2], length.out=height+1)

eg <- expand.grid(lon=lon, lat=lat)

lr <- eg[-(1:(width+1)),]
ul <- eg[1:(nrow(eg)-(width+1)),]

corners <- cbind(upper_left=ul, lower_right=lr)
corners <- corners[1:nrow(corners) %% width != 0,]
rownames(corners) <- NULL
head(corners)

#   upper_left.lon upper_left.lat lower_right.lon lower_right.lat
# 1       14.22302       50.18330        14.34398        50.13568
# 2       14.34398       50.18330        14.46493        50.13568
# 3       14.46493       50.18330        14.58588        50.13568
# 4       14.58588       50.18330        14.70683        50.13568
# 5       14.22302       50.13568        14.34398        50.08805
# 6       14.34398       50.13568        14.46493        50.08805

可以按照需要将坐标重新排列到列表中。

corners.l <- apply(corners, 1, 
  function(x) 
    list(upper_left=c(lon=x[[1]], lat=x[[2]]), 
        lower_right=c(lon=x[[3]], lat=x[[4]])))

corners.l[1]
# [[1]]
# [[1]]$upper_left
#      lon      lat 
# 14.22302 50.18330 

# [[1]]$lower_right
#      lon      lat 
# 14.34398 50.13568 

仅仅是因为

plot(eg, cex=0, axes=FALSE)
points(corners[,1:2], pch=1, cex=2)
points(corners[,3:4], pch=16)
axis(1, unique(eg[,1]), floor(unique(eg[,1])*100)/100)
axis(2, unique(eg[,2]), floor(unique(eg[,2])*100)/100)

enter image description here

答案 2 :(得分:0)

最后,我选择了以下解决方案。它受到Svenhalvorson使用expand.grid函数的回答的启发。此外,它避免使用不必要的组合,并且输出为data.table

# load data.table library
library(data.table)
# create the large bounding box
big_rectangle <- list(top_left = c("lat" = 50.183297, "lon" = 14.223024),
                      bottom_right = c("lat" = 49.945189, "lon" = 14.706829))

# split the rectangle into smaller pieces
lat <- seq(from = big_rectangle[["bottom_right"]]["lat"], to = big_rectangle[["top_left"]]["lat"], length = 20)
lon <- seq(from = big_rectangle[["top_left"]]["lon"], to = big_rectangle[["bottom_right"]]["lon"], length = 20)

# index of the lon and lat vectors
seq_lat = 1:(length(lat)-1)
seq_lon = 1:(length(lon)-1)

# create combinanations of indices and store as data.table
rectangles = data.table(expand.grid(lat1 = seq_lat,lon1 = seq_lon))

# store the coordinates of small rectangles into data.table
rectangles[, `:=`(lat_br = lat[lat1],
                  lon_tl = lon[lon1],
                  lat_tl = lat[lat1 + 1],
                  lon_br = lon[lon1 + 1]
                  )]