次の (単純化された) モデルが与えられた場合:
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, ...]
これを引き起こしている可能性のあるアイデアはありますか?
アップデート:
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()
を Extended Well-Known Binary に変換しているようです。 その後、すべてに変更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 フレームワークですべてを適切に保持することを好みます。