【问题标题】:Advice on how to structure a Location model with Django and PostgreSQL (postGIS)关于如何使用 Django 和 PostgreSQL (postGIS) 构建位置模型的建议
【发布时间】:2014-02-14 14:51:51
【问题描述】:

stack 在我最需要的时候帮助了我,我将再次测试我的运气。这是场景。目前我有以下型号:

class Location(models.Model):
    name = models.CharField(max_length=200, blank=True)
    address = models.CharField(max_length=255, blank=True)
    city = models.CharField(max_length=140, null=True, blank=True)
    province_state = models.CharField(max_length = 140, null=True, blank=True)
    country = models.CharField(max_length=2, null=True, blank=True)
    postal_code = models.CharField(max_length=32, null=True, blank=True)
    foursquare_id = models.CharField(max_length=100, blank=True, unique=True)
    lat = models.DecimalField(max_digits=18, decimal_places=15, null=True, blank=True)
    lon = models.DecimalField(max_digits=18, decimal_places=15, null=True, blank=True)

看起来相当直截了当,对吧?现在我要做的是返回用户当前位置 100 公里范围内的所有位置。每个度数约为 100 KM。例如,在纬度 10 度和 11 度之间,大约有 100 公里的距离。经度也一样。 1 度约为 100 公里。这是我的 WhatsNearBy 视图:

@csrf_exempt
def WhatsNearBy(request):
    if request.META.has_key('HTTP_AUTHORIZATION') and request.method == 'GET':
        authmeth, auth = request.META['HTTP_AUTHORIZATION'].split(' ', 1)
        if authmeth.lower() == 'basic':
            auth = auth.strip().decode('base64')
            username, password = auth.split(':', 1)
            authuser = authenticate(username=username, password=password)
            if authuser: 
                if authuser.is_active:
                client_lat = int(request.GET.get('lat'))
                client_lon = int(request.GET.get('lon'))

                queryset = Location.objects.filter(__lat__gte = (client_lat - 1), 
                                lat__lte = (client_lat + 1), 
                                lon__gte = (client_lon - 1), 
                                lon__lte = (client_lon + 1))
                return queryset

上述查询集返回大约 100 公里外的所有位置。这很好用,而且非常可靠。但是,我担心的是,随着数据库变大,过滤迟早会变慢。

我听说过 postGIS,但我不确定它是否会比我现在做的更有效。我是否必须将 Location 模型迁移到 postGIS?这一切将如何运作?一旦我这样做了,我能找到一定距离内的所有位置吗?

期待看到您的解决方案!

【问题讨论】:

    标签: django postgresql postgis


    【解决方案1】:

    我最近处理了一个类似的问题。我发现 PostGIS 和其他空间解决方案对于查找近似半径内的所有点来说太过分了。

    我最终在数据库中使用了 SAS 距离算法。用正方形过滤后,我使用 raw 命令让数据库为我处理数字。 Postgres 和除 SQLite 之外的大多数其他数据库都支持三角函数,因此您可以过滤数据库的计算距离。这是以英里为单位的公式,但您可以更改常数。

    Dist = 3949.99 * arcos(sin(Y1) * sin(Y2) + cos(Y1) * cos(Y2) * cos(X1 - X2));
    

    http://support.sas.com/kb/3/973.html

    编辑:为了扩展,我查询了半径内美国的所有邮政编码 (~44K)。事实证明,我可以在不到一秒的时间内查询 500 英里内的所有邮政编码,这对于我的目的来说是可以接受的。地理空间库让您可以更快地找到复杂多边形内的所有点,但我不认为您的应用程序会看到明显的性能改进。

    【讨论】:

    • 感谢您的回复!
    猜你喜欢
    • 1970-01-01
    • 2017-09-01
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    • 2011-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多