django postgis 初步使用

  之前做个项目,我们的项目中有用户添加的特定信息,这条信息包含了用户添加时的位置(经纬度),现在有个需求,就是后取当前用户30km范围内所有的这种信息。思路并不难,但是有个问题,如果我们每次都根据用户的当前位置,然后对比所有信息的经纬度坐标,计算出用户30km范围的数据,再返回给用户,我们需要很好的去优化算法和查询方式,但是依我目前的水平,还做不到很好的优化。由于项目使用的数据库是postgresql,于是就想到了postgis。

PostGIS is a spatial database extender for PostgreSQL object-relational database. 

GIS(Geographic Information System),空间地理信息系统。

django中如何使用postgis(https://docs.djangoproject.com/en/2.1/ref/contrib/gis/tutorial/

通过django 官方文档可知,Ubuntu/Debian安装postgis是非常方便的,只需要使用使用apt-get install 命令安装以下包(注意:postgis只支持postgresql9.3或以上版本https://postgis.net/docs/postgis_installation.html#install_requirements):

postgresql-x.x, postgresql-x.x-postgis, postgresql-server-dev-x.x, python-psycopg2

(2019-01-20 postgresql 10,然后直接sudo apt install libgdal-dev 环境就可以了,不用上面的那么麻烦了)

数据库不要忘记安装extension:CREATE EXTENSION postgis;

使用前配置请参考:django postgis Configure settings.py

对于之前提出的需求,我是这样做的:

model:

from django.contrib.gis.db import models as geo_models
from django.contrib.gis.db.models.manager import GeoManager
class PatrolPoint(models.Model):
    id = models.BigAutoField(primary_key=True)
    appid =  models.CharField(max_length=200, null=True, blank=True, default='')
    user = models.ForeignKey(user_info)
    river_base_info = models.ForeignKey(RiverBaseInfo, null=True)
    river_check = models.ForeignKey(RiverCheck, null=True)
    task = models.ForeignKey(tasks, null=True)
    longitude = models.CharField(max_length=50, blank=True, null=True)
    latitude = models.CharField(max_length=50, blank=True, null=True)
    symbol = models.CharField(max_length=125, blank=True, null=True)
    river_name = models.CharField(max_length=125, blank=True, null=True)
    create_time = models.DateTimeField(blank=True, auto_now_add=True, null=True)
    update_time = models.DateTimeField(blank=True, auto_now=True)
    pos = geo_models.GeometryField(srid=4326, null=True)
    usual_flag = models.BooleanField(default=True)
    report_flag = models.BooleanField(default=False)
    objects = GeoManager()
    class Meta:
        db_table = "patrol_point"

查询语句:

from django.contrib.gis.geos import GEOSGeometry
from django.contrib.gis.db.models.functions import Distance
patrol_points = PatrolPoint.objects.annotate(distance=Distance('pos', GEOSGeometry('POINT(%s %s)' % (request.GET['longitude'],request.GET['latitude']), 4326))).filter(distance__lte=radius, usual_flag=True)

  

 

  

posted @ 2018-09-16 21:32  lplucky  阅读(2063)  评论(0编辑  收藏  举报