Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need performance on postGIS with GeoDjango

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?

like image 829
maraujop Avatar asked Aug 23 '10 12:08

maraujop


2 Answers

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.

like image 59
Paul Ramsey Avatar answered Nov 20 '22 17:11

Paul Ramsey


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.

like image 3
maraujop Avatar answered Nov 20 '22 16:11

maraujop