Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django PostGIS最近邻搜索结果出现问题?_Django_Postgresql_Postgis_Nearest Neighbor - Fatal编程技术网

Django PostGIS最近邻搜索结果出现问题?

Django PostGIS最近邻搜索结果出现问题?,django,postgresql,postgis,nearest-neighbor,Django,Postgresql,Postgis,Nearest Neighbor,我有一个Django/PostgreSQL应用程序,它显示哪些用户最接近某个特定用户。它在ORDER BY子句中使用PostGIS 2.0 KNN K Nearest NECTORIES运算符列出最靠近的用户。我发现我的初始数据集中有两个搜索结果出现问题所有距离都是从加利福尼亚州洛杉矶测量的: Member, City, State, Distance (miles) user1, North Las Vegas, NV, 239 user2, Phoenix, AZ, 365 user3,

我有一个Django/PostgreSQL应用程序,它显示哪些用户最接近某个特定用户。它在ORDER BY子句中使用PostGIS 2.0 KNN K Nearest NECTORIES运算符列出最靠近的用户。我发现我的初始数据集中有两个搜索结果出现问题所有距离都是从加利福尼亚州洛杉矶测量的:

Member, City, State, Distance (miles)

user1, North Las Vegas, NV, 239
user2, Phoenix, AZ, 365
user3, Provo, UT, 568
user4, Twin Falls, ID, 630
user5, Albuquerque, NM, 673
user6, Portland, OR, 828
user7, Bozeman, MT, 896
user8, Seattle, WA, 962
user9, Boulder, CO, 834       <- Out of order!
user10, Laramie, WY, 862      <- Out of order!
user11, Naperville, IL, 1756
以下是my Django视图中的查询:

def members(request, template):
    """View all members of the website."""
    uid = request.session['uid']   # PK from User table

    # Get the current user's lon/lat and measurement system
    try:
        ua = UserAccount.objects.get(user_id=uid)
        lon = ua.current_lon
        lat = ua.current_lat
        measurement_sys = ua.measurement_sys
    except UserAccount.DoesNotExist as e:
        return HttpResponseRedirect(reverse('unable-to-display-members'))

    # Define the proximity query.
    if measurement_sys == 'US':
        multiplier = 0.000621371  # Convert to miles
    else:
        multiplier = 0.001  # Convert to kilometers

    query = "SELECT \
                ua.user_id, \
                au.username, \
                ua.city, \
                ua.region, \
                ST_Distance( \
                    ua.current_point::geography, \
                    ST_GeographyFromText( \
                        'SRID=4326;POINT(" \
                            + str(lon) \
                            + " " \
                            + str(lat) + \
                        ")' \
                    ) \
                )*" + str(multiplier) + " AS distance \
            FROM \
                user_account ua \
                INNER JOIN \
                auth_user au \
                ON (ua.user_id = au.id) \
            WHERE ua.user_id != %s \
            ORDER BY \
                ua.current_point::geometry \
                <-> \
                'SRID=4326;POINT(" + str(lon) + " " + str(lat) + ")'::geometry \
            LIMIT 250;"

    # Run the proximity query
    raw_queryset = UserAccount.objects.raw(query, [uid])

    # Paginate results
    user_list = [user for user in raw_queryset]
    list_size = len(list(user_list))
    paginator = Paginator(user_list, 10, 4)
    paginator._count = list_size

    page = request.GET.get('page')
    try:
        users = paginator.page(page)
    except PageNotAnInteger:
        users = paginator.page(1)
    except EmptyPage:
        users = paginator.page(paginator.num_pages)
    return render(request, template, {'users': users})
我的问题有没有做错什么?KNN运算符有时会打嗝并返回一些不正常的结果吗?我这样问是因为当我尝试从表中取出两条无序记录,然后为地址更遥远的用户(即IL、LA、MI、NC、PA、NY和ME)添加额外记录时,所有结果都是按正确顺序排列的

顺便说一下,我的输入是定位的

谢谢

最新答案:

Postgis有两个kNN邻居功能的近似解决方案,因为:

使用该操作符,可以使用边界框的中心获得最近的邻居,以计算对象间距离。 使用该操作符,可以使用边界框本身获得最近的邻居来计算对象间距离。 你的问题是,两者都是近似的,所以它们不是完美的。因此,如果您想要最佳的250个结果,您可以使用其中的任何一个来检索最佳的1000个结果,然后按ST_距离对相同的结果进行排序,并限制250以从这些大约1000个结果中获得最佳的250个结果

例如:

SELECT * FROM 
    (SELECT *,ST_DISTANCE(current_point::geography, 'SRID=4326;POINT(" + str(lon) + " " + str(lat) + ")'::geography ) AS st_dist
    FROM ua
    ORDER BY current_point::geometry <-> 'SRID=4326;POINT(" + str(lon) + " " + str(lat) + ")'::geometry 
    LIMIT 1000) AS s
    ORDER BY st_dist LIMIT 250;

这很奇怪。你可以发布一些数据,这样我们就可以测试了吗?当然可以。以下是测试数据:Alexandros,谢谢你的评论,因为他们给了我一些其他的东西来思考。很遗憾,您建议的对ORDER BY子句的更改无效。KNN运算符仅接受几何体操作数。如果您尝试将两个操作数强制转换为地理类型,您将得到编程错误:运算符不存在:地理地理地理我发现的一个问题是,我需要将我的主点和当前点列声明为Django PointField类型,而不是GeometryField类型。但即使这样做了,结果仍然不正常。值得一提的是,我将CO和WY用户记录替换为CO和WY两个不同城市的地址,这两个记录再次出现故障。Alexandros,这似乎解决了问题。我真的很感谢你的帮助!我看过你提到的那篇文章,但我没有实现它的解决方案,因为它似乎说,只有在对非点对象(如直线和多边形)进行计算时,才需要这种技术。由于我的计算是针对点之间的距离,并且点的边界框与点本身相等,因此答案是准确的。“我想我还是应该试试看的。”亚历山德罗斯。引人注目的亚历山德罗斯。我完全错过了。嗨,我在看同样的问题。我想知道你是否找到了更好的解决办法?谢谢
SELECT * FROM 
    (SELECT *,ST_DISTANCE(current_point::geography, 'SRID=4326;POINT(" + str(lon) + " " + str(lat) + ")'::geography ) AS st_dist
    FROM ua
    ORDER BY current_point::geometry <-> 'SRID=4326;POINT(" + str(lon) + " " + str(lat) + ")'::geometry 
    LIMIT 1000) AS s
    ORDER BY st_dist LIMIT 250;