Dont know specifically about sql lite. I have used django orm with postgres spatial db to find points within a 'convex hull' bounding box shape:
from django.contrib.gis.geos import GEOSGeometry, Polygon, LineString, Point, LinearRing from django.contrib.gis.measure import D coords_in = simplejson.loads(request.POST['coords']) #add the first point to the end to form a loop coords_in.append(coords_in[0]) #construct linear ring lin_ring = LinearRing([ Point(float(item['b']), float(item['c'])) for item in coords_in ]) #create convex hull boundaries = lin_ring.convex_hull #data list to return, calculate airfields in convex hull data_list = [] for airf in Airfield.objects.filter(point__intersects=boundaries.wkt): data_list.append([airf.airfield_name, airf.point.x, airf.point.y, airf.ycode]) Dont take the code as gospel however for performance reasons i found it fair to specify a segmented convex hull approximating a sphere. Set the radius from the centre to be x units and find points within this area. Return the queryset and order by distance from the centre with a spheroid-arc distance formula eg: Vincenty formula. Either way i found using forums less django-specific and more math+map specific was a good approach On Fri, Aug 12, 2011 at 5:51 PM, Thomas Weholt <thomas.weh...@gmail.com> wrote: > Thanks for your detailed reply :-) I'll try to figure it out. So far I > got a few candidates for a solution but the math functions seem to be > somewhat different on the different database platforms so I need to > experiment some more to find one that works on the three major ones ( > sqlite, postgres and mysql - I often use sqlite for development and > postgres for production myself, but still want to support mysql ). > > About the accuracy; my app is suppose to show photos take nearby some > location so it doesn't have to be dead on. But this should really be a > reusable app or widget. Seems like more than just me needs this > functionality. If I get something going I'll look into making it > generic and reusable. Anybody interesting in helping out making this > happen please let me know. My experience using math functions in SQL > like this is close to zero. > > Thanks alot for all the replies and interest :-) > > Regards, > Thomas > > On Thu, Aug 11, 2011 at 7:51 PM, Bill Freeman <ke1g...@gmail.com> wrote: >> I've done this sort of thing in the past without the aid of geo-django, >> using a >> reasonably ordinary model. >> >> I did it as a two step process, first calculating a bounding box, which is a >> rectangle in lat/long space. It is calculated once per search, based on >> the distance and the coordinates of the distance circle's center (the point >> from which you are measuring distance). >> >> A pair of latitudes that are tangent to the distance circle are easy to come >> by because the point of tangency is at the same longitude as the circle's >> center, and because distance in linear with latitude along such a line. >> >> Bounding longitudes are harder because their points of tangency are >> closer to the pole than the circle's center (unless it's on the equator), >> as well as distance not being linear with longitude change. But since >> a distance circle radius through the point of tangency will necessarily >> intersect the bounding line of longitude at a right angle, you can use >> one of the spherical right triangle formulas. I like: >> sin(a) = sin(A) * sin(c) >> where the triangle includes the pole, the point of tangency, and the center >> of the distance circle; "a" is the angle, measured as seen from the center >> of the earth, subtended by the side not involving the pole, that is of the >> distance radius (2*PI*distance/earth_radius); "c", the hypontenuse, is >> the same thing for the distance between the distance circle's center and >> the pole, that is, the compliment of the latitude of the distance circle's >> center; and A is the surface angle subtended at the pole, that is, the >> difference in longitude (what we're looking for). Because it would be >> convenient to work in latitude, rather than compliment of latitude, change >> the formula to: >> sin(a) = sin(A) * cos(lat) >> therefore: >> A = asin(sin(a)/cos(lat)) >> The desired bounding longitudes are then +/- A from the longitude of >> the distance circle's center's longitude. It doesn't hurt that the use >> of cos(lat) has even symmetry, making it clear that you don't have to >> choose a pole. >> >> Now you select candidate database rows satisfying the bounding limits, >> and only have to calculate actual distance for them, discarding the >> relatively few that are too far, but within the corners of the bounding box. >> Some databases support a "BETWEEN" operator, or something like it, >> but the ORM's range lookup will work. Be careful, though, if your circle >> can include 180 degrees of longitude, since then you want longitude to >> be outside the range, rather than within it, because the sign of longitude >> changes there. >> >> Note that if a pole is closer than your distance limit that there are no >> bounding longitudes, and only that bounding latitude that's further from >> that pole applies. >> >> In the interests of performance, note that the distance formula: >> d = 2*PI*earth_radius*acos(sin(lat1)*sin(lat2) + >> cos(lat1)*cos(lat2)*cos(long1 - long2)) >> only needs the sin and cos of the latitudes, not the latitudes themselves. >> So that's what I stored in the database avoiding those trig operations >> on each distance calculation. (Actually, I wound up also storing the >> latitude so that the user saw the latitude he had entered, whereas, >> given the non-infinite precision of float, or even double, doing >> asin(sin_lat) leads to some differences in less significant digits.) Then >> we get: >> d = 2*PI*earth_radius*acos(sin_lat1*sin_lat2 + >> cos_lat1*cos_lat2*cos(long1 - long2)) >> and we're down to just two trig functions per distance calculation, a cos >> and an acos. >> >> Further, notice that for distance less than or equal to half way around the >> globe (which is as far as you can get on the globe), acos(x) is, while not >> linear, monotonic(ly decreasing) with x. So throwing out the candidates >> that are in the corners of the bounding box can be done using the >> the expression inside the acos, by comparing it to: >> a = cos(d/(2*PI*earth_radius)) >> and discarding points where: >> a < sin_lat1*sin_lat2 + cos_lat1*cos_lat2*cos(long1 - long2) >> taking us down to one trig operation for those. (Yes, I have the inequality >> correct: cos == 1 implies 0 distance, and cos gets smaller as you get >> further until you are as far away as possible, on the other side of the >> globe.) >> >> Note that you can even sort by the cos of the distance angle (the thing >> >> And, yes, "a" is the "a" from the bounding box calculation, so you only have >> to calculate it once per look up. In fact, if you only offer a limited set >> of >> distances, you can calculate "a" for each of them once, at startup. >> being compared to "a"), largest first to get smallest distance first. >> >> Most databases will support such expressions, so if you are willing to >> execute SQL directly (https://docs.djangoproject.com/en/1.3/topics/db/sql/) >> you can get the database to calculate the cos of the distance angle, do the >> compare on it, and also sort by it. The trick is to avoid doing the >> calculation >> for points outside the bounding box, and you will have to know your database >> well to do that (a stored procedure may be in order). You also don't want >> to sort before you've winnowed, so there may be a sub-query (or so) involved. >> >> You might even be able to do it using the "raw" model manager method, though >> having calculated the cos of the distance angle, and assuming that you will >> want to display the distance to each candidate, you would like to have it >> returned, and it's not a model field. >> >> Python should be just as fast as the database on the trig, but decreasing the >> number of items that get passed over the database connection, and that then >> must be instantiated as model instances in django, is a performace benefit. >> >> Good luck. >> >> On Thu, Aug 11, 2011 at 11:09 AM, Thomas Weholt <thomas.weh...@gmail.com> >> wrote: >>> I got a model with longitude and latitude and want to be able to find >>> other objects nearby a selected object. Can this be done using the >>> django orm? What is the best approach to do this in a django project? >>> >>> I found a answer on Stackoverflow, but doesn't work with sqlite. Doing >>> it in SQL is ok and probably the best solution performance wise, but >>> if it has to be done in python I'll do that too. >>> >>> Ref question on stackoverflow: >>> http://stackoverflow.com/questions/4610717/django-determining-if-geographic-coordinates-are-inside-of-an-circle >>> >>> -- >>> Mvh/Best regards, >>> Thomas Weholt >>> http://www.weholt.org >>> >>> -- >>> You received this message because you are subscribed to the Google Groups >>> "Django users" group. >>> To post to this group, send email to django-users@googlegroups.com. >>> To unsubscribe from this group, send email to >>> django-users+unsubscr...@googlegroups.com. >>> For more options, visit this group at >>> http://groups.google.com/group/django-users?hl=en. >>> >>> >> > > > > -- > Mvh/Best regards, > Thomas Weholt > http://www.weholt.org > > -- > You received this message because you are subscribed to the Google Groups > "Django users" group. > To post to this group, send email to django-users@googlegroups.com. > To unsubscribe from this group, send email to > django-users+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/django-users?hl=en. > > -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.