#25499 closed New feature (fixed)
Distance lookup not possible with a column value as distance
| Reported by: | Bibhas C Debnath | Owned by: | Claude Paroz |
|---|---|---|---|
| Component: | GIS | Version: | dev |
| Severity: | Normal | Keywords: | 1.10 |
| Cc: | Jani Tiainen | Triage Stage: | Accepted |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Right now this is possible -
current_localities = Locality.objects.filter(centroid__distance_lte=(pnt, 1000))
which results in -
(0.005) SELECT "map_locality"."id", "map_locality"."name", "map_locality"."slug", "map_locality"."centroid", "map_locality"."radius" FROM "map_locality" WHERE ST_Distan
ce_Sphere("map_locality"."centroid", ST_GeomFromEWKB('\x0101000020e6100000865ad3bce3685340e9b7af03e7ec2940'::bytea)) <= 1000 LIMIT 21;
But if I have a column named radius which has the radius for each Locality and centroid has the center point and I want to find all the localities that my current location falls in, I want to do something like this -
current_localities = Locality.objects.filter(centroid__distance_lte=(pnt, F('radius')))
But it's not possible right now. It generates the error -
ProgrammingError at /api/services/
can't adapt type 'F'
But in reality, this is possible -
SELECT "map_locality"."id", "map_locality"."name", "map_locality"."slug", "map_locality"."centroid", "map_locality"."radius" FROM "map_locality" WHERE ST_Distance_Sphere("map_locality"."centroid", ST_GeomFromEWKB('\x0101000020e6100000865ad3bce3685340e9b7af03e7ec2940'::bytea)) <= radius*1000 LIMIT 21;
Here I'm using radius*1000 as the result of ST_Distance_Sphere() is in meter and my radius value is in km. I'm looking for suggestions on how to handle cases like this in the ORM, but I do think that the support for using a column value using F() would be *really* helpful.
Change History (10)
comment:1 by , 10 years ago
| Component: | contrib.postgres → GIS |
|---|---|
| Owner: | set to |
| Triage Stage: | Unreviewed → Accepted |
comment:2 by , 10 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
comment:3 by , 10 years ago
| Has patch: | set |
|---|
comment:4 by , 10 years ago
| Triage Stage: | Accepted → Ready for checkin |
|---|
comment:6 by , 10 years ago
| Cc: | added |
|---|---|
| Has patch: | unset |
| Keywords: | 1.10 added |
| Resolution: | fixed |
| Status: | closed → new |
| Triage Stage: | Ready for checkin → Accepted |
This needs to be addressed on Oracle GIS. gis_tests.distapp.tests.DistanceTest.test_distance_lookups_with_expression_rhs fails like so:
Traceback (most recent call last):
File "/mnt/jenkinsdata/workspace/pull-requests-oracle/database/oragis11/python/python3.5/django/test/testcases.py", line 1068, in skip_wrapper
return test_func(*args, **kwargs)
File "/mnt/jenkinsdata/workspace/pull-requests-oracle/database/oragis11/python/python3.5/tests/gis_tests/distapp/tests.py", line 332, in test_distance_lookups_with_expression_rhs
self.get_names(qs),
File "/mnt/jenkinsdata/workspace/pull-requests-oracle/database/oragis11/python/python3.5/tests/gis_tests/distapp/tests.py", line 34, in get_names
cities = [c.name for c in qs]
File "/mnt/jenkinsdata/workspace/pull-requests-oracle/database/oragis11/python/python3.5/django/db/models/query.py", line 258, in __iter__
self._fetch_all()
File "/mnt/jenkinsdata/workspace/pull-requests-oracle/database/oragis11/python/python3.5/django/db/models/query.py", line 1074, in _fetch_all
self._result_cache = list(self.iterator())
File "/mnt/jenkinsdata/workspace/pull-requests-oracle/database/oragis11/python/python3.5/django/db/models/query.py", line 52, in __iter__
results = compiler.execute_sql()
File "/mnt/jenkinsdata/workspace/pull-requests-oracle/database/oragis11/python/python3.5/django/db/models/sql/compiler.py", line 839, in execute_sql
cursor.execute(sql, params)
File "/mnt/jenkinsdata/workspace/pull-requests-oracle/database/oragis11/python/python3.5/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/mnt/jenkinsdata/workspace/pull-requests-oracle/database/oragis11/python/python3.5/django/db/backends/oracle/base.py", line 477, in execute
query, params = self._fix_for_params(query, params)
File "/mnt/jenkinsdata/workspace/pull-requests-oracle/database/oragis11/python/python3.5/django/db/backends/oracle/base.py", line 473, in _fix_for_params
query = convert_unicode(query % tuple(args), self.charset)
TypeError: not enough arguments for format string
comment:7 by , 10 years ago
Someone can try:
-
django/contrib/gis/db/backends/oracle/operations.py
diff --git a/django/contrib/gis/db/backends/oracle/operations.py b/django/contrib/gis/db/backends/oracle/operations.py index b443ae0..bb98846 100644
a b class SDOOperator(SpatialOperator): 28 28 29 29 30 30 class SDODistance(SpatialOperator): 31 sql_template = "SDO_GEOM.SDO_DISTANCE(%%(lhs)s, %%(rhs)s, %s) %%(op)s %% %%s" % DEFAULT_TOLERANCE31 sql_template = "SDO_GEOM.SDO_DISTANCE(%%(lhs)s, %%(rhs)s, %s) %%(op)s %%(value)s" % DEFAULT_TOLERANCE 32 32 33 33 34 34 class SDODWithin(SpatialOperator):
comment:9 by , 10 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
Thanks Claude, that test now passes locally for me on Oracle.
I didn't investigate yet, but supporting this use case does make sense.