views:

152

answers:

3

This is the first time I'm using GeoDjango with postGIS. After installation and some tests with everything running fine I am concerned about query performance when table rows will grow.

I'm saving in a geometry point longitudes and latitudes that I get from Google geocoding (WGS84, or SRID 4326). My problem is that distance operations are very common in my application. I often need to get near spots from a landmark. Geometry maths are very complex, so even if I have an spatial index, it will probably take too long in the future having more than 1000 spots in a nearby area.

So is there any way to project this geometry type to do distance operations faster? does anyone know a Django library that can render a Google map containing some of these points?

Any advices on how to speed up spatial queries on GeoDjango?

Thanks

A: 

Generally, GeoDjango will create and use spatial indexes on geometry columns where appropriate.

For an application dealing primarily with distances between points, the Geography type (introduced in PostGIS 1.5, and supported by GeoDjango) may be a good fit. GeoDjango says it gives "much better performance on WGS84 distance queries" [link].

tcarobruce
That is true, as you can read in http://docs.djangoproject.com/en/1.2/ref/contrib/gis/model-api/#spatial-indexGeometryField.spatial_index --> Defaults to True. Creates a spatial index for the given geometry field.Django supports geography type since last stable version 1.2.1 so it's pretty new. In the docs you can also read: Because geography calculations involve more mathematics: http://docs.djangoproject.com/en/dev/ref/contrib/gis/model-api/#selecting-an-sridSo what I'm asking is geography really a good fit? will it scale properly?
maraujop
A: 

If you can fit your working area into a map projection, that will always be faster, as there are fewer math calls necessary for things like distance calculations. However, if you have truly global data, suck it up: use geography. If you only have continental USA data, use something like EPSG:2163 http://spatialreference.org/ref/epsg/2163/

The more constrained your working area, the more accurate results you can get in a map projection. See the state plane projections for highly constrained, accurate projections for regional areas in the USA. Or UTM projections for larger sub-national regions.

Paul Ramsey
I understand projecting is faster, but I'm managing Spanish geodata and not sure how to transform, store and process it in GeoDjango. At the same time, not sure if points given by Google are in SRID 4326 or EPSG 900913
maraujop
The Google API returns and consumes coordinates in EPSG:4326. For a projected system in Spain, try EPSG:25831.
Paul Ramsey
A: 

I'm researching on this topic. As far as I have found, coordinates that you get from geopy library are in SRID 4326 format, so you can store them in a geometry field type without problems. This would be an example of a GeoDjango model using geometry:

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

   objects = models.GeoManager()

By the way, be very careful to pass longitude / latitude to the PointField, in that exact order. geopy returns latitude / longitude coordinates, so you will need to reverse them.

For transforming points in one coordinate system to another we can use GEOS with GeoDjango. In the example I will transform a point in 4326 to the famous Google projection 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)'

This way we can store coordinates in projection systems, which will have better performance maths. For showing points in a Google map in the admin site interface. We can use this great article.

I have decided to go on with geography types, and I will convert them in the future, in case I need to improve performance.

maraujop