[Django] #25498: PostGIS Distance lookups use ST_Distance_Sphere() and not ST_Distance()

31 views
Skip to first unread message

Django

unread,
Oct 3, 2015, 4:55:13 PM10/3/15
to django-...@googlegroups.com
#25498: PostGIS Distance lookups use ST_Distance_Sphere() and not ST_Distance()
-------------------------------+--------------------
Reporter: iambibhas | Owner: nobody
Type: Bug | Status: new
Component: Documentation | Version: master
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------
Currently
[https://docs.djangoproject.com/en/1.8/ref/contrib/gis/geoquerysets
/#distance-gt the doc says] that PostGIS uses `ST_Distance()` for distance
lookups like `distance_gte` etc. But actually `ST_Distance_Sphere()` is
used. We need to fix that on the doc.

The doc also says in the beginning -

{{{

... an optional third element, 'spheroid', may be included to tell
GeoDjango to use the more accurate spheroid distance calculation functions
on fields with a geodetic coordinate system (e.g., ST_Distance_Spheroid
would be used instead of ST_Distance_Sphere).

}}}

But then `ST_Distance_Sphere` is not mentioned anywhere else.

Here is what currently is happening -

{{{
current_localities = Locality.objects.filter(centroid__distance_lte=(pnt,
1000))
}}}

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_Distance_Sphere("map_locality"."centroid",
ST_GeomFromEWKB('\x0101000020e6100000865ad3bce3685340e9b7af03e7ec2940'::bytea))
<= 1000 LIMIT 21;
args=(<django.contrib.gis.db.backends.postgis.adapter.PostGISAdapter
object at 0x7fdcc9d320d0>, 1000)
}}}

Attaching a patch with the issue. I can send a PR.

--
Ticket URL: <https://code.djangoproject.com/ticket/25498>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Oct 3, 2015, 4:55:42 PM10/3/15
to django-...@googlegroups.com
#25498: PostGIS Distance lookups use ST_Distance_Sphere() and not ST_Distance()
---------------------------+----------------------------

Reporter: iambibhas | Owner: nobody
Type: Bug | Status: new
Component: Documentation | Version: master
Severity: Normal | Resolution:

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Easy pickings: 0
UI/UX: 0 |
---------------------------+----------------------------
Changes (by iambibhas):

* Attachment "doc_gis_distance.patch" added.

patch to rename st_distance to st_distance_sphere

Django

unread,
Oct 3, 2015, 4:56:12 PM10/3/15
to django-...@googlegroups.com
#25498: PostGIS Distance lookups use ST_Distance_Sphere() and not ST_Distance()
-------------------------------+--------------------------------------

Reporter: iambibhas | Owner: nobody
Type: Bug | Status: new
Component: Documentation | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by iambibhas):

* needs_better_patch: => 0
* has_patch: 0 => 1
* needs_tests: => 0
* needs_docs: => 0


--
Ticket URL: <https://code.djangoproject.com/ticket/25498#comment:1>

Django

unread,
Oct 3, 2015, 5:15:34 PM10/3/15
to django-...@googlegroups.com
#25498: PostGIS Distance lookups use ST_Distance_Sphere() and not ST_Distance()
-------------------------------+--------------------------------------

Reporter: iambibhas | Owner: nobody
Type: Bug | Status: new
Component: Documentation | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed

Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Description changed by iambibhas:

Old description:

> Currently
> [https://docs.djangoproject.com/en/1.8/ref/contrib/gis/geoquerysets
> /#distance-gt the doc says] that PostGIS uses `ST_Distance()` for
> distance lookups like `distance_gte` etc. But actually
> `ST_Distance_Sphere()` is used. We need to fix that on the doc.
>
> The doc also says in the beginning -
>
> {{{
>
> ... an optional third element, 'spheroid', may be included to tell
> GeoDjango to use the more accurate spheroid distance calculation
> functions on fields with a geodetic coordinate system (e.g.,
> ST_Distance_Spheroid would be used instead of ST_Distance_Sphere).
>
> }}}
>
> But then `ST_Distance_Sphere` is not mentioned anywhere else.
>
> Here is what currently is happening -
>
> {{{
> current_localities = Locality.objects.filter(centroid__distance_lte=(pnt,
> 1000))
> }}}
>
> 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_Distance_Sphere("map_locality"."centroid",
> ST_GeomFromEWKB('\x0101000020e6100000865ad3bce3685340e9b7af03e7ec2940'::bytea))
> <= 1000 LIMIT 21;
> args=(<django.contrib.gis.db.backends.postgis.adapter.PostGISAdapter
> object at 0x7fdcc9d320d0>, 1000)
> }}}
>
> Attaching a patch with the issue. I can send a PR.

New description:

Currently
[https://docs.djangoproject.com/en/1.8/ref/contrib/gis/geoquerysets
/#distance-gt the doc says] that PostGIS uses `ST_Distance()` for distance
lookups like `distance_gte` etc. But actually `ST_Distance_Sphere()` is
used. We need to fix that on the doc.

The doc also says in the beginning -

... an optional third element, 'spheroid', may be included to tell
GeoDjango to use the more accurate spheroid distance calculation functions
on fields with a geodetic coordinate system (e.g., `ST_Distance_Spheroid`

would be used instead of `ST_Distance_Sphere`).

But then `ST_Distance_Sphere` is not mentioned anywhere else.

Here is what currently is happening -

{{{
current_localities = Locality.objects.filter(centroid__distance_lte=(pnt,
1000))
}}}

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_Distance_Sphere("map_locality"."centroid",
ST_GeomFromEWKB('\x0101000020e6100000865ad3bce3685340e9b7af03e7ec2940'::bytea))
<= 1000 LIMIT 21;
args=(<django.contrib.gis.db.backends.postgis.adapter.PostGISAdapter
object at 0x7fdcc9d320d0>, 1000)
}}}

Attaching a patch with the issue. I can send a PR.

--

--
Ticket URL: <https://code.djangoproject.com/ticket/25498#comment:2>

Django

unread,
Oct 3, 2015, 6:34:51 PM10/3/15
to django-...@googlegroups.com
#25498: PostGIS Distance lookups use ST_Distance_Sphere() and not ST_Distance()
-------------------------------+------------------------------------

Reporter: iambibhas | Owner: nobody
Type: Bug | Status: new
Component: Documentation | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted

Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------
Changes (by claudep):

* needs_better_patch: 0 => 1
* stage: Unreviewed => Accepted


Comment:

You are right in that the documentation is not up-to-date. However, it's a
bit more complicated than that. The real function used depends on the type
of the geometry field in the database. You can see the logic here:
https://github.com/django/django/blob/master/django/contrib/gis/db/backends/postgis/operations.py#L39

If the field is geodetic (latitude/longitude), `ST_Distance_Sphere` is
used by default (with spheroid as an option). If the field has projected
coordinates, `ST_Distance` is used by default.

--
Ticket URL: <https://code.djangoproject.com/ticket/25498#comment:3>

Django

unread,
Oct 4, 2015, 2:53:54 PM10/4/15
to django-...@googlegroups.com
#25498: PostGIS Distance lookups use ST_Distance_Sphere() and not ST_Distance()
-------------------------------+------------------------------------

Reporter: iambibhas | Owner: nobody
Type: Bug | Status: new
Component: Documentation | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------

Comment (by iambibhas):

Replying to [comment:3 claudep]:


> If the field is geodetic (latitude/longitude), `ST_Distance_Sphere` is
used by default (with spheroid as an option). If the field has projected
coordinates, `ST_Distance` is used by default.

By `geodetic` do you mean a Point type geometry field using SRID 4326? In
my example above, `centroid` is of type `geometry(Point,4326)`.

Just trying to get a clear idea about it.

--
Ticket URL: <https://code.djangoproject.com/ticket/25498#comment:4>

Django

unread,
Oct 4, 2015, 3:03:05 PM10/4/15
to django-...@googlegroups.com
#25498: PostGIS Distance lookups use ST_Distance_Sphere() and not ST_Distance()
-------------------------------+------------------------------------

Reporter: iambibhas | Owner: nobody
Type: Bug | Status: new
Component: Documentation | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------

Comment (by claudep):

Yes, 4326 is geodetic in the sense that coordinates (latitude/longitude)
are measured in angles based on an ellispoid representation of the earth.
On the other hand, projected systems are measured in meters or miles based
on a projected plane of the earth (generally only accurate on limited
areas).

--
Ticket URL: <https://code.djangoproject.com/ticket/25498#comment:5>

Django

unread,
Oct 5, 2015, 12:52:00 AM10/5/15
to django-...@googlegroups.com
#25498: PostGIS Distance lookups use ST_Distance_Sphere() and not ST_Distance()
-------------------------------+------------------------------------

Reporter: iambibhas | Owner: nobody
Type: Bug | Status: new
Component: Documentation | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------

Comment (by iambibhas):

So maybe we can say something like -

PostGIS: `ST_Distance_Sphere(poly, geom) <= 5` when SRID 4326 is
used
PostGIS: `ST_Distance(poly, geom) <= 5` when any other projected
projected coordinates are used

in 2 different rows. Or use a single row to say both of them.

--
Ticket URL: <https://code.djangoproject.com/ticket/25498#comment:6>

Django

unread,
Oct 9, 2015, 11:17:01 AM10/9/15
to django-...@googlegroups.com
#25498: PostGIS Distance lookups use ST_Distance_Sphere() and not ST_Distance()
-------------------------------+------------------------------------

Reporter: iambibhas | Owner: nobody
Type: Bug | Status: new
Component: Documentation | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------

Comment (by claudep):

What about that ?
https://github.com/django/django/pull/5418

--
Ticket URL: <https://code.djangoproject.com/ticket/25498#comment:7>

Django

unread,
Oct 9, 2015, 2:45:25 PM10/9/15
to django-...@googlegroups.com
#25498: PostGIS Distance lookups use ST_Distance_Sphere() and not ST_Distance()
-------------------------------------+-------------------------------------
Reporter: iambibhas | Owner: nobody
Type: | Status: new
Cleanup/optimization |
Component: Documentation | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Ready for
| checkin

Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):

* needs_better_patch: 1 => 0
* type: Bug => Cleanup/optimization
* stage: Accepted => Ready for checkin


--
Ticket URL: <https://code.djangoproject.com/ticket/25498#comment:8>

Django

unread,
Oct 11, 2015, 6:25:32 AM10/11/15
to django-...@googlegroups.com
#25498: PostGIS Distance lookups use ST_Distance_Sphere() and not ST_Distance()
-------------------------------------+-------------------------------------
Reporter: iambibhas | Owner: nobody
Type: | Status: closed
Cleanup/optimization |
Component: Documentation | Version: master
Severity: Normal | Resolution: fixed

Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Claude Paroz <claude@…>):

* status: new => closed
* resolution: => fixed


Comment:

In [changeset:"617b1a21f5a661ef44030c1662440cc5be158ec0" 617b1a2]:
{{{
#!CommitTicketReference repository=""
revision="617b1a21f5a661ef44030c1662440cc5be158ec0"
Fixed #25498 -- Documented ST_Distance/ST_Distance_Sphere difference

Thanks Bibhas Debnath for the report and Tim Graham for the review.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/25498#comment:9>

Django

unread,
Oct 11, 2015, 6:26:29 AM10/11/15
to django-...@googlegroups.com
#25498: PostGIS Distance lookups use ST_Distance_Sphere() and not ST_Distance()
-------------------------------------+-------------------------------------
Reporter: iambibhas | Owner: nobody
Type: | Status: closed
Cleanup/optimization |
Component: Documentation | Version: master

Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Claude Paroz <claude@…>):

In [changeset:"66319cc59724ae28917eea62643d07cc9606897d" 66319cc5]:
{{{
#!CommitTicketReference repository=""
revision="66319cc59724ae28917eea62643d07cc9606897d"
[1.9.x] Fixed #25498 -- Documented ST_Distance/ST_Distance_Sphere
difference

Thanks Bibhas Debnath for the report and Tim Graham for the review.

Backport of 617b1a21f from master.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/25498#comment:10>

Reply all
Reply to author
Forward
0 new messages