我想使用网格对球体表面进行采样。要求是表面上的每个单元应具有相等的面积。我看到有像测地网格这样的解决方案,但有更简单的解决方案吗?
答案 0 :(得分:3)
您没有指定您是否有语言偏好。我将在R中建议一个解决方案。如果你需要一种不同的语言,其中很多都有你可以使用的R接口。此解决方案还以标准格式生成输出文件,任何语言都应该能够读取。
你是对的,测地网格很棘手。你也是对的,他们是你获得同等面积细胞的唯一方式。
幸运的是,我已经构建了一个名为dggridR的R软件包,可以轻松使用它们。
以下代码通过在地球表面均匀分布相等面积的六边形单元来完成您想要的任务。它还将这些六边形单元格的顶点保存到文件中,以便在其他上下文中使用。
#Include libraries
library(dggridR)
library(rgdal)
library(dplyr)
N <- 100 #How many cells to sample
#Distribute the points uniformly on a sphere using equations from
#http://mathworld.wolfram.com/SpherePointPicking.html
u <- runif(N)
v <- runif(N)
theta <- 2*pi*u * 180/pi
phi <- acos(2*v-1) * 180/pi
lon <- theta-180
lat <- phi-90
df <- data.frame(lat=lat,lon=lon)
#Construct a global grid in which every hexagonal cell has an area of
#100,000 km^2. You could, of course, choose a much smaller value, but these
#will show up when I map them later.
#Note: Cells can only have certain areas, the `dgconstruct()` function below
#will tell you which area is closest to the one you want. You can also round
#up or down.
#Note: 12 cells are actually pentagons with an area 5/6 that of the hexagons
#But, with millions and millions of hexes, you are unlikely to choose one
#Future versions of the package will make it easier to reject the pentagons
dggs <- dgconstruct(area=100000, metric=FALSE, resround='nearest')
#Get the corresponding grid cells for each randomly chosen lat-long
df$cell <- dgtransform(dggs,df$lat,df$lon)
#Get the hexes for each of these cells
grid <- dgcellstogrid(dggs,df$cell,frame=FALSE)
#Save the hex boundaries to a handy KML file for use in your project
writeOGR(grid, "dgg_sample_cells.kml", "cells", "KML")
此时你已经完成了!如果需要,你可以通过计算KML中的顶点来解析任何非常不可能的五边形。
对于踢球,让我们绘制选择多边形的情节。如果您有太多样本,请小心这样做。
#Get the grid in a more convenient format
grid <- dgcellstogrid(dggs,df$cell,frame=TRUE,wrapcells=TRUE)
#Get polygons for each country of the world
countries <- map_data("world")
#Plot everything on a flat map
p<- ggplot() +
geom_polygon(data=countries, aes(x=long, y=lat, group=group), fill=NA, color="black") +
geom_polygon(data=grid, aes(x=long, y=lat, group=group), fill="green", alpha=0.4) +
geom_path (data=grid, aes(x=long, y=lat, group=group), alpha=0.4, color="white")
p
请注意,此平面地图的投影会使单元格失真。但是,如果我们在球体上绘制细胞,我们会看到它们具有相同的面积,正如所承诺的那样:
#Replot on a spherical projection
p+coord_map("ortho", orientation = c(-38.49831, -179.9223, 0))+
xlab('')+ylab('')+
theme(axis.ticks.x=element_blank())+
theme(axis.ticks.y=element_blank())+
theme(axis.text.x=element_blank())+
theme(axis.text.y=element_blank())
你也可以像这样随机选择细胞:
#Choose a set of cells randomly distributed over the Earth
library(dggridR)
dggs <- dgconstruct(spacing=1000, metric=FALSE, resround='down')
N <- 100 #Number of cells
maxcell <- dgmaxcell(dggs) #Get maximum cell id
cells <- sample(1:maxcell, N, replace=FALSE) #Choose random cells
grid <- dgcellstogrid(dggs,cells,frame=TRUE,wrapcells=TRUE) #Get grid
答案 1 :(得分:1)
如果您使用圆柱坐标z
和方位角phi
来描述球体上的点,则z
和phi
中的矩形网格将具有相同的 - 区域细胞。这是因为以z
和phi
为坐标的地图会生成(Lambert) equal area projection。