如何根据经度和纬度过滤geodjango

时间:2014-01-16 08:23:01

标签: django geodjango

我有一个存储经度和纬度的应用程序现在我想将它与geodjango集成,应用程序看起来像这样。

class Location(models.Model):
    #other fields here
    lat = models.CharField(blank=True, max_length=100)
    lng = models.CharField(blank=True, max_length=100)

现在我想根据距离过滤位置说使用django.contrib.gis.measure导入D和GEOSGeometry来过滤距离pk = 1位置1km的所有位置或者我应该重构模型以获得点而不是经度和纬度所以我可以做这样的事情:

Location.objects.filter(point__dwithin=(D(km=5)))

任何建议和建议都可以。

2 个答案:

答案 0 :(得分:3)

使用南方...需要3次迁移才能解决这个问题。 (链接:How to install South]

1)添加名为PointField的{​​{1}}:

point

2)自动执行from django.contrib.gis.db import models <-- NEW # ... class Location(models.Model): #other fields here lat = models.CharField(blank=True, max_length=100) lng = models.CharField(blank=True, max_length=100) point = models.PointField(null=True) <-- NEW

schemamigration

3)执行自定义patrick@localhost:~$ python manage.py schemamigration my_app_name --auto ,您可以在其中为现有datamigration属性

中的每个元素创建一个点
CharField

编辑patrick@localhost:~$ python manage.py datamigration my_app_name latlng_to_point 管理命令创建的文件:

datamigration

4)如果您愿意,请从模型中删除# my_app_name/migrations/0034__latlng_to_point.py from django.contrib.gis.geos import Point # ... class Migration(DataMigration): def forwards(self, orm): "Write your forwards methods here." # Note: Remember to use orm['appname.ModelName'] rather than "from appname.models..." for location in orm['my_app_name.Location'].objects.all(): location.point = Point(float(location.lng), float(location.lat), srid=4326) location.save() def backwards(self, orm): "Write your backwards methods here." for location in orm['data.Location'].objects.all(): location.point = None location.save() 并删除CharField

null=True

5)自动创建另一个模式迁移

class Location(models.Model):
    # other fields here
    # DELETED lat = models.CharField(blank=True, max_length=100)
    # DELETED lng = models.CharField(blank=True, max_length=100)

    point = models.PointField(null=False)  <-- NEW: null=False

6)成功运行迁移!这是将更改写入您的数据库等的时候。

patrick@localhost:~$ python manage.py schemamigration my_app_name --auto

答案 1 :(得分:3)

架构迁移

2016年快进,我们已经在django内置了迁移,你不再需要南方了。您只需要两次迁移而不是三次迁移。

第1步:更改模型。

class Location(models.Model):
    #other fields here
    lat = models.CharField(blank=True, max_length=100)
    lng = models.CharField(blank=True, max_length=100)

    point = models.PointField(null=True)

第2步:创建迁移

./manage.py makemigrations

数据迁移

这是第三步,涉及编辑上面创建的迁移文件,查看操作部分并添加

migrations.RunSQL('''UPDATE myapp_location SET `point` = Point(lat,lng)''')

此查询适用于mysql。如果您使用PostGis,您的查询将是

migrations.RunSQL('''UPDATE myapp_location SET "point" = ST_MakePoint(lng,lat)''')

请注意,postgis的格式为 lng,lat 请注意,这是一个查询,应该可以合理快速地执行。使用python迭代所有行并逐个更新它们意味着如果你有一百万个记录就会有一百万个查询!

第4步:./manage.py migrate

步骤5:从模型中删除lat,lng列。

第6步:./manage.py makemigrations

第7步:./manage.py migrate