2010-08-23 77 views
6

这是我第一次使用GeoDjango和postGIS。在安装和一切正常运行的测试之后,我担心表格行增长时的查询性能。使用GeoDjango需要postGIS的性能

我正在保存从Google地理编码(WGS84或SRID 4326)获得的几何点经度和纬度。我的问题是距离操作在我的应用程序中很常见。我经常需要靠近地标附近的景点。几何数学是非常复杂的,所以即使我有一个空间索引,未来可能需要很长的时间,在附近地区有超过1000个点。

那么有什么方法可以投影这个几何类型来更快地进行距离操作吗?有没有人知道一个Django库可以渲染包含这些点的Google地图?

关于如何加快GeoDjango空间查询的任何建议?

+1

只是为了澄清,你实际上是否遇到PostGIS的性能问题?如果您只是担心会发生什么,请拒绝过早优化!使用含有数百万条记录的表格的查询,人们可以获得良好的结果。更多关于距离查询:http://www.bostongis.com/?content_name = postgis_tut02#21 – tcarobruce 2010-08-23 17:53:53

+0

嗯,我不确定我会称这种过早的优化(虽然我还没有性能问题)。我只需要知道GeoDjango将在必要时接受挑战。 我知道postGIS以及如何使用&&和重叠框改善距离查询,但是例如GeoDjango是否使用它?另一方面,我对精度并不是很挑剔,所以我不应该使用几何图形,因为它是有代价的。 – maraujop 2010-08-23 18:19:51

回答

0

通常,GeoDjango将在适当的位置创建和使用几何列的空间索引。

对于主要处理点之间距离的应用程序,Geography type(在PostGIS 1.5中引入,并且由GeoDjango支持)可能非常适合。 GeoDjango表示它在“WGS84距离查询”上提供了“更好的性能”[link]

+1

这是真的,你可以阅读http://docs.djangoproject.com/en/1.2/ref/contrib/gis/model-api/#spatial-index GeometryField.spatial_index - >默认为True。为给定的几何字段创建空间索引。 Django支持自上一个稳定版本1.2.1以来的地理类型,因此它非常新颖。在文档中,您还可以阅读: 由于地理计算涉及更多数学:http://docs.djangoproject.com/en/dev/ref/contrib/gis/model-api/#selecting-an-srid 因此我问的是地理学真的很合适?它会适当扩展吗? – maraujop 2010-08-23 20:21:50

3

如果您可以将您的工作区域放入地图投影中,速度总是更快,因为距离计算等工作所需的数学调用较少。但是,如果您拥有真正的全球数据,请吸取它:使用地理。如果您只有美国大陆的数据,请使用类似EPSG的数据:2163 http://spatialreference.org/ref/epsg/2163/

工作区域越受限制,您可以在地图投影中获得更准确的结果。参见美国国家平面预测,对美国区域地区进行高度约束,准确的预测。或对更大的次国家地区进行UTM预测。

+0

我的理解是投射速度更快,但我正在管理西班牙地理数据,不确定如何在GeoDjango中转换,存储和处理它。同时,不确定Google提供的点数是否在SRID 4326或EPSG 900913 – maraujop 2010-08-26 14:36:26

+1

中Google API返回并使用EPSG中的坐标:4326。对于西班牙的投影系统,请尝试EPSG:25831。 – 2010-08-27 21:10:39

2

我正在研究这个主题。据我发现,从geopy库获得的坐标是SRID 4326格式,因此您可以将它们存储在几何字段类型中,而不会出现任何问题。这将是一个GeoDjango内置模型运用几何学的一个例子:

class Landmark(models.Model): 
    point = models.PointField(spatial_index = True, 
          srid = 4326, 
          geography = True) 

    objects = models.GeoManager() 

顺便说一句,非常小心地经度/纬度传递给PointField,在正确的顺序。 geopy会返回纬度/经度坐标,因此您需要将其反转。

为了将一个坐标系中的点转换为另一个坐标系,我们可以使用GEOS和GeoDjango。在这个例子中,我将在4326变换点到著名的谷歌投影900913:

from django.contrib.gis.geos import Point 
punto = Point(40,-3) 
punto.set_srid(900913) 
punto.transform(4326) 
punto.wkt 
Out[5]: 'POINT (0.0003593261136478 -0.0000269494585230)' 

这样我们就可以存储在投影系统,这将有更好的表现数学坐标。 用于在管理站点界面中显示Google地图中的点。我们可以使用this great article

我决定继续使用地理类型,未来我会转换它们,以防我需要提高性能。