2009-11-01 97 views
1

我试图找出接近以下方法的最佳方法:根据经度和纬度设计网格叠加层

说我有一个地球的平面表示形式。我想创建一个网格覆盖这与网格上的每个广场相当于约3平方公里。每个广场都有一个唯一的区域ID。这个网格只会存储在一个数据库表中,该数据库表中有一个区域id,然后可能是该区域四个角的长/纬度坐标,对吧?有关如何轻松生成此表的任何建议?我知道我首先需要找出这个“扁平地球”的宽度和高度,以千米为单位,计算区域的数量,然后以某种方式将长/拉特赋予每条垂直/水平线的交点;然而,这听起来像很多手动工作。其次,一旦我创建了网格表,我需要设计一个fxn,它需要一个长/拉对,然后确定它所在的逻辑“区域”。我不知道如何去做这件事。

任何帮助,将不胜感激。

谢谢。

+0

你必须意识到的第一件事是球面上没有像方形那样的东西。 – 2009-11-01 20:14:07

回答

3

假定地球是一个半径为R = 6371 km的球体。

从(lat,long)=(0,0)deg开始。绕地球赤道,3公里相当于变化的

dlong = 3/(2 * pi * R) * 360 
     = 0.0269796482 degrees 

经度如果我们走在赤道附近,把一个标记每3公里,就会有他们的约(2 * pi * R)/3 = 13343.3912。 “关于”,因为这是你决定如何处理额外的0.3912。从(0,0)起,我们步行3公里到(拉特,长)(0.0269796482,0)。我们将再次走上与地球平行于我们走过的第一条道路的路径。因为它离N极更近一点,这个圆的半径比我们走的第一个圆的半径要小一些。让我们用小写字母r代表这个半径

r = R * cos(lat) 
    = 6371 * cos(0.0269796482) 
    = 6 368.68141 km 

我们再次使用较小的半径计算dlong

dlong = 3/(2 * pi * r) * 360 
     = 0.0269894704 deg 

我们放下第二组标志。这次他们有大约(2 * pi * r)/3 = 13 338.5352。之前有13343人,但现在有13338人。那是什么?少了五个。

顶线中有五个角较少时,我们如何绘制正方形的条纹?事实上,当我们在地球周围走动时,我们会发现我们的起点非常好,但区域的形状被剪切成非常极端的平行四边形。

我们需要一种不同的策略,给予我们相同数量的上下角。如果下边界(SW-SE)长3公里,那么顶端应该稍短一些,以制造梯形带。

有许多方法可以制定出接近您理想的方形网格的折衷方案。 This wikipedia article关于保存度量属性的地图投影,链接到几十个这样的策略。

你的应用程序的细节可能会让你大大简化事情,特别是如果你不需要映射整个地球。

+0

这太好了。谢谢。会给我足够的开始。 – cakeforcerberus 2009-11-02 03:16:52

+0

要记住的主要问题是E-W距离上的cos(纬度)调节。另见http://stackoverflow.com/questions/1624574/calculate-lat-lng-of-corners-of-ground-overlay-from-kml-file/1624732#1624732。 – 2009-11-02 12:02:44

1

你的确认识到,因为地球是一个“3平方公里”的球体在极点附近的数量要比靠近赤道的球体的数量更多,对吗?而在地图的顶部和底部,您的网格广场将实际上代表世界的馅饼形状的部分,对吧?

我已经做了类似于我的数据库的东西 - 我已经把它分成四个单元格。所以我所做的就是将地球分成四个季度(-180,-90) - (0,0),(-180,0) - (0,90)等等。当我将点实体添加到我的数据库中时,如果“单元格”的数量超过了X条目,我将该单元格分割为4个。这意味着在世界上有很多点实体的区域中,我有很多四元单元格,但在世界其他地方,我很少。

我对四叉树数据库的样子:

\d areaids; 
       Table "public.areaids" 
    Column |   Type    | Modifiers 
--------------+-----------------------------+----------- 
areaid  | integer      | not null 
supercededon | timestamp without time zone | 
supercedes | integer      | 
numpoints | integer      | not null 
rectangle | geometry     | 
Indexes: 
    "areaids_pk" PRIMARY KEY, btree (areaid) 
    "areaids_rect_idx" gist (rectangle) 
Check constraints: 
    "enforce_dims_rectangle" CHECK (ndims(rectangle) = 2) 
    "enforce_geotype_rectangle" CHECK (geometrytype(rectangle) = 'POLYGON'::text OR rectangle IS NULL) 
    "enforce_srid_rectangle" CHECK (srid(rectangle) = 4326) 

我使用的PostGIS帮助寻找在细胞分。如果我看一个单元格,我可以判断它是否被拆分,因为supercededon不为null。我可以通过寻找与其身份相同的代名词来找到自己的孩子。而且我可以从上到下挖掘,直到找到覆盖我关心的区域的那些区域,找到具有supercedeson null并且矩形与我感兴趣区域重叠的区域(使用PostGIS'&'运算符)。

2

微软一直在SQL Server 2008产品中投资空间数据类型。它可以帮助你在这里。因为它具有数据类型来表示您的展平地球区域,操作员可以确定一组坐标是否位于几何图形内,等等。即使您选择不使用它,也可以考虑查看以下链接。第二个特别有关于这个问题的很好的背景信息,以及关于空间数据的一些行业标准数据格式的讨论。

http://www.microsoft.com/sqlserver/2008/en/us/spatial-data.aspx

http://jasonfollas.com/blog/archive/2008/03/14/sql-server-2008-spatial-data-part-1.aspx

1

首先,保罗是正确的。不幸的是,地球是圆的,这真的让这件事变得复杂。

许多年前,我为地形绘图服务器创建了一个类似于此的网格。我只是记录了每个区域左上角编码器的坐标。我也用UTM坐标代替lat/long。如果您知道每个区域覆盖3平方公里,并且由于UTM基于米,因此直接进行范围查询以发现正确的区域。

0

你不可能用矩形单元做到这一点,但我刚刚完成了一个R包dggridR,这将使得使用六角形网格的网格变得容易。但是,3公里的电池需求可能会产生太多的电池,导致您的机器过载。

您可以用R生成网格:

install.packages('devtools') 
install.packages('rgdal') 
library(devtools) 
devools.install_github('r-barnes/dggridR') 
library(dggridR) 
library(rgdal) 

#Construct a discrete global grid (geodesic) with cells of ~3 km^2 
dggs <- dgconstruct(area=100000, metric=FALSE, resround='nearest') 

#Get a hexagonal grid for the whole earth based on this dggs 
grid <- dgearthgrid(dggs,frame=FALSE) 

#Save the grid 
writeOGR(grid, "grid_3km_cells.kml", "cells", "KML") 

KML文件则包含了ID和每一个细胞的边缘顶点坐标。

网格看上去有点像这样:

Discrete Global Grid

我的包是基于凯文·萨赫尔的DGGRID可以直接生成同样的网格,以KML,但你需要弄清楚如何编译它自己。