在多边形中生成规则间隔的点 [英] Generate regularly spaced points in polygon

查看:92
本文介绍了在多边形中生成规则间隔的点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否存在一种使用R生成多边形内规则间隔(例如相隔500米)的点的方法?我一直在尝试使用sp包,但似乎无法定义一组彼此隔开一定距离的点.我的目的是生成点,然后将其经/纬度坐标提取到新的数据框中.任何帮助将非常感激!谢谢

Is there a way to generate regularly spaced (e.g., 500 meters apart) points within a polygon using R? I have been trying to use the sp package but can't seem to define a set of points that are spaced a certain distance apart from one another. My aim is to generate the points, then extract their lat/long coordinates into a new dataframe. Any help would be much appreciated! Thanks

推荐答案

非常直接,并且几乎开箱即用.

Quite straight forward and almost out-of-the-box.

由于OP没有共享数据,请系好安全带,将您的座位垂直放置,然后让我们飞往巴黎.在那里,我们将适应geosphere函数,并在其帮助下将巴黎的形状划分为lon/lat坐标,每个坐标相距500米(垂直和水平).

As OP did not share data, buckle up, put your seats in a vertical position and let us fly to Paris. There, we will adapt a geosphere function, and with its help we will divide up Paris' shape into lon / lat coordinates that are 500 meters apart each (vertically and horizontally).

# Load necessary libraries.
library(raster)
library(geosphere)
library(tidyverse)
library(sp)

# This is an adapted version of geosphere's destPoint() function that works with
# changing d (distance).
destPoint_v <- function (x, y, b, d, a = 6378137, f = 1/298.257223563, ...) 
{
    r <- list(...)$r
    if (!is.null(r)) {
        return(.old_destPoint(x, y, b, d, r = r))
    }
    b <- as.vector(b)
    d <- as.vector(d)
    x <- as.vector(x)
    y <- as.vector(y)
    p <- cbind(x, y, b, d)
    r <- .Call("_geodesic", as.double(p[, 1]), as.double(p[, 2]), 
               as.double(p[, 3]), as.double(p[, 4]), 
               as.double(a), as.double(f), 
               PACKAGE = "geosphere")
    r <- matrix(r, ncol = 3, byrow = TRUE)
    colnames(r) <- c("lon", "lat", "finalbearing")
    return(r[, 1:2, drop = FALSE])
}

# Data can be downloaded from 
# http://osm13.openstreetmap.fr/~cquest/openfla/export/communes-20190101-shp.zip
# or 
# https://www.data.gouv.fr/en/datasets/decoupage-administratif-communal-francais-issu-d-openstreetmap/
# ("Export simple de janvier 2019 (225Mo)")

# Load shapefile.
# shp <- raster::shapefile("Dropbox/work/crema/communes-20190101-shp/communes-20190101.shp")
# Extract Paris.
paris <- shp[shp$nom == "Paris", ]

# Set distance of points in meters.
dist <- 500

# Extract bounding box from Paris' SpatialPolygonDataFrame. 
bbox <- raster::extent(paris)

# Calculate number of points on the vertical axis.
ny <- ceiling(geosphere::distGeo(p1 = c(bbox@xmin, bbox@ymin), 
                               p2 = c(bbox@xmin, bbox@ymax)) / dist)
# Calculate maximum number of points on the horizontal axis. 
# This needs to be calculated for the lowermost and uppermost horizontal lines
# as the distance between latitudinal lines varies when the longitude changes. 
nx <- ceiling(max(geosphere::distGeo(p1 = c(bbox@xmin, bbox@ymin), 
                                   p2 = c(bbox@xmax, bbox@ymin)) / dist,
                geosphere::distGeo(p1 = c(bbox@xmin, bbox@ymax), 
                                   p2 = c(bbox@xmax, bbox@ymax)) / dist))

# Create result data frame with number of points on vertical axis.
df <- data.frame(ny = 1:ny)

# Calculate coordinates along the vertical axis.
pts <- geosphere::destPoint(p = c(bbox@xmin, bbox@ymin), 
                            b = 0, d = dist * (1:ny - 1))
df$x <- pts[, 1]
df$y <- pts[, 2]

# Add points on horizontal axis.
df <- tidyr::crossing(nx = 1:nx, df)

# Calculate coordinates.
pts <- destPoint_v(df$x, df$y, b = 90, 500 * (df$nx - 1))

# Turn coordinates into SpatialPoints.
pts <- SpatialPoints(cbind(pts[, 1], pts[, 2]), proj4string = CRS(proj4string(paris)))

# Cut to boundaries of Paris.
result <- raster::intersect(pts, paris)

# Plot result.
plot(result)
title("Paris in Points")

这篇关于在多边形中生成规则间隔的点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆