Spatial/GIS: find records within X distance of point?

126 views
Skip to first unread message

User

unread,
Dec 8, 2013, 8:02:06 AM12/8/13
to web...@googlegroups.com
I'm storing latitude/longitude coordinates in a geometry field (using PostgreSQL 9.1.10):

Field('point', 'geometry()')

I understand there is also the geography type but from my reading geometry is faster and is suitable for small distances (http://workshops.boundlessgeo.com/postgis-intro/geography.html#why-not-use-geography)

I want users to be able to specify a reference point and search for all records within X distance from the reference point.  Using raw SQL I would use  ST_DWithin doing something like

SELECT name, ST_AsText(point)
FROM mytable
WHERE ST_DWithin(point, ST_GeomFromText('POINT(40.47112 -76.33)',4326), 0.1)

But web2py does not seem to support ST_DWithin only st_within.  So how can I achieve a similar result in web2py?

Massimo Di Pierro

unread,
Dec 8, 2013, 9:25:35 AM12/8/13
to web...@googlegroups.com
Added ST_Dwithin support in trunk. Please check it.

User

unread,
Dec 9, 2013, 1:21:37 PM12/9/13
to web...@googlegroups.com
Thanks.  This is what I see at line 2983 in dal.py:

    def ST_DWITHIN(self, first, second):
        """
        http://postgis.org/docs/ST_Within.html
        """
        return 'ST_DWithin(%s,%s)' %(self.expand(first), self.expand(second, first.type))


The proper documentation is at http://postgis.org/docs/ST_DWithin.html (note the 'D').  Also looks like this is missing the 3rd argument to ST_DWithin:

boolean ST_DWithin(geometry g1, geometry g2, double precision distance_of_srid);

Massimo Di Pierro

unread,
Dec 9, 2013, 4:45:27 PM12/9/13
to web...@googlegroups.com
OK. This needs more work than anticipated. Looks like the Query object only supports unary and binary operators. Give me a little more time. ;-)

User

unread,
Dec 9, 2013, 5:33:09 PM12/9/13
to web...@googlegroups.com
Forgive me because I don't understand anything about the internals of web2py but doesn't REPLACE take three parameters:

def REPLACE(self, first, (second, third)):
   
return 'REPLACE(%s,%s,%s)' % (self.expand(first,'string'),
               
self.expand(second,'string'),
               
self.expand(third,'string'))



Also:

def ST_ASGEOJSON(self, first, second):
       
"""
       
http://postgis.org/docs/ST_AsGeoJSON.html
        """

       
return 'ST_AsGeoJSON(%s,%s,%s,%s)' %(second['version'],
           
self.expand(first), second['precision'], second['options'])



Or do you mean something different?

Massimo Di Pierro

unread,
Dec 9, 2013, 6:06:32 PM12/9/13
to web...@googlegroups.com
Actually you do understand a lot of about this. That's a trick. It works. We can use it in this case too, until we come up with a better design.
I used the same trick as in REPLACE, in trunk. Please give it a try.

Massimo

User

unread,
Dec 9, 2013, 6:16:17 PM12/9/13
to web...@googlegroups.com
Thanks, on line 2987 I believe the format string is missing the 3rd '%s' parameter:

        return 'ST_DWithin(%s,%s)' %(self.expand(first), self.expand(second, first.type),
                                     self.expand(third, 'double'))

Should be:

        return 'ST_DWithin(%s,%s,%s)' %(self.expand(first), self.expand(second, first.type),
                                     self.expand(third, 'double'))

Massimo Di Pierro

unread,
Dec 9, 2013, 6:54:53 PM12/9/13
to web...@googlegroups.com
You are right. Please check again.

User

unread,
Dec 10, 2013, 1:34:01 AM12/10/13
to web...@googlegroups.com
This appears to be working correctly now thank you.  One more thing: the docstring on line 2985 is referencing the wrong PostGIS function (ST_Within), it should be:

        """
        http://postgis.org/docs/ST_DWithin.html
        """
(note the D)
Reply all
Reply to author
Forward
0 new messages