6
votes

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?

3
Just to clarify, are you actually experiencing performance issues with PostGIS? If you're just worried about what might happen, resist premature optimization! People have good results with queries like yours using tables with many millions of records. More on distance queries: bostongis.com/?content_name=postgis_tut02#21tcarobruce
Well, I'm not sure I would call this premature optimization (although I haven't had performance issues yet). I simply need to know GeoDjango will be up to the challenge when necessary. I know postGIS and how to improve distance queries using && and overlap boxes, but for example does GeoDjango use this? On the other hand, I'm not really picky with precision, so I shouldn't be using geometry, because it comes at a price.maraujop

3 Answers

3
votes

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.

3
votes

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.

0
votes

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].