Ошибка базы данных при использовании distance () в GeoDjango - PullRequest
1 голос
/ 11 июля 2011

С учетом следующих (упрощенных) моделей:

from django.contrib.gis.db import models

class City(models.Model):
    center = models.PointField(spatial_index=True, null=True)
    objects = models.GeoManager()

class Place(models.Model):
    city = models.ForeignKey(City, null=True)
    lat = models.FloatField(null=True)
    lng = models.FloatField(null=True)
    objects = models.GeoManager()

Забыв на мгновение, что лат / лнг на месте должен быть перемещен на PointField(), я пытаюсь просмотреть все Places и найти ближайший город. В настоящее время я делаю:

from django.contrib.gis.geos import Point

places = Property.objects.filter(lat__isnull=False, lng__isnull=False)
for place in places:
    point = Point(place.lng, place.lat, srid=4326) # setting srid just to be safe
    closest_city = City.objects.distance(point).order_by('distance')[0]

Это приводит к следующей ошибке:

DatabaseError: geometry_distance_spheroid: Operation on two GEOMETRIES with different SRIDs

Предполагая, что SRID не были по умолчанию равны 4326, я включил srid=4326 в приведенный выше код и убедился, что во всех городах City.center имеет SRID 4326:

In [6]: [c['center'].srid for c in City.objects.all().values('center')]
Out[6]: [4326, 4326, 4326, ...]

Есть идеи, что может быть причиной этого?

UPDATE:

Кажется, что-то в том, как создается SQL-запрос, вызывает проблему. После того, как ошибка выдана, глядя на sql показывает:

In [9]: from django.db import connection
In [10]: print connection.queries[-1]['sql']
SELECT (ST_distance_sphere("model_city"."center", 
    ST_GeomFromEWKB(E'\\001\\001...\\267C@'::bytea))) AS "distance", 
    "model_city"."id", "model_city"."name", "listing_city"."center" 
    FROM "model_city" ORDER BY "model_city"."name" ASC LIMIT 21

Похоже, django превращает аргумент point distance() в расширенный хорошо известный бинарный файл. Если я затем изменю ST_GeomFromEWKB на ST_GeomFromText, все работает нормально. Пример:

# SELECT (ST_distance_sphere("listing_city"."center",
          ST_GeomFromText('POINT(-118 38)',4326))) AS "distance", 
          "model_city"."name", "model_city"."center" FROM "model_city" 
          ORDER BY "listing_city"."name" ASC LIMIT 5;

     distance     |    name     |                       center                       
------------------+-------------+----------------------------------------------------
 3124059.73265751 | Akron       | 0101000020E6100000795DBF60376154C01CB62DCA6C8A4440
  3742978.5514446 | Albany      | 0101000020E6100000130CE71A667052C038876BB587534540
 1063596.35270877 | Albuquerque | 0101000020E6100000CC0D863AACA95AC036E7E099D08A4140

Я не могу найти ничего в документации, которая говорит о том, как GeoQuerySet.distance() переводит в SQL. Я, конечно, могу использовать сырой SQL-запрос в запросе, чтобы заставить вещи работать, но предпочел бы, чтобы все было хорошо в среде Django.

1 Ответ

0 голосов
/ 25 февраля 2014

Я думаю, что это ошибка: «Операция на двух ГЕОМЕТРИЯХ с разными SRID»

Для таблицы "geometry_columns" в вашей базе данных задан другой srid между именем таблицы для обработки

***** вы должны изменить это сами enter image description here

...