0

ユーザーがデータベースエントリの特定の半径内にいる場合にのみデータを返すことになっているDjangoに位置認識サーバーがあります..オンラインでそれを行うPythonのコードスニペットを見つけました(ここまたは他の場所で、私は本当にできません覚えておいてください)そして、2つの異なる座標を設定したときではなく、0,0の座標に対してテストしたときにうまくいくように見えました. 現在の場所から 300 メートル以内のデータベース エントリがあり、半径は 10 キロメートルに設定されていますが、何らかの理由でサーバーが結果を返してくれません。このコードのどこが間違っているのでしょうか。私はそれを修正する方法についてまったく無知であり、Pythonの初心者であり、どうしようもなく失われ、プロジェクトの期限まで5日でhaversineを使用して要素から外れています。ここに、harsine ベースのクエリのコードを示します。

class StoreList(generics.ListAPIView):
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
                  IsOwnerOrReadOnly,)
serializer_class = StoreSerializer

def get_queryset(self):
    lat = self.request.query_params.get('lat', None)
    lon = self.request.query_params.get('lng', None)

    if lat and lon:
        lat = float(lat)
        lon = float(lon)

        # Haversine formula = https://en.wikipedia.org/wiki/Haversine_formula


        lat1 = math.radians(lat)  # lat in radians
        lng1 = math.radians(lon)  # lng in radians

        lat2 = math.asin(math.sin(lat1)*math.cos(distance/R) +
            math.cos(lat1)*math.sin(distance/R)*math.cos(bearing))

        lng2 = lng1 + math.atan2(math.sin(bearing)*math.sin(distance/R)*math.cos(lat1),
            math.cos(distance/R)-math.sin(lat1)*math.sin(lat2))

        lat2 = math.degrees(lat2)
        lng2 = math.degrees(lng2)

        return Store.objects.filter(latitude__gte=lat1, latitude__lte=lat2)\
            .filter(longitude__gte=lng1, longitude__lte=lng2)

この画像は、リクエストが受信され、座標が正しいことを示していますが、結果セットはまだ空です:(

サーバー出力

4

3 に答える 3

1

lat1通過しているように見えますがlng1、ラジアンですがlat2lng2度です。lat1( andをラジアンに変換しlng1ましたが、度に戻すことはありませんでした。)

于 2016-05-11T20:17:27.633 に答える
1

postgresql (postgis 拡張子付き) や mysql 5.7 のような位置認識データベースに切り替える方がはるかに簡単です。ポイントから指定された距離でオブジェクトを見る場合、そのようなデータベースの簡単なクエリであり、django によって完全にサポートされています

Dwithin ルックアップ ジオメトリからジオメトリ フィールドまでの距離が互いに指定された距離内にあるモデルを返します。対象となるジオメトリが投影されたシステムにある場合、距離オブジェクトのみを提供できることに注意してください。地理的形状の場合、形状フィールドの単位を使用する必要があります (例: WGS84 の度数) 。

例:

Zipcode.objects.filter(poly__dwithin=(geom, D(m=5)))

したがって、複雑なコードはワンライナーになります。地理空間データベースには、便利な機能がたくさんあります。

于 2016-05-11T23:09:24.313 に答える
0

だから..アルゴリズムが間違っていた場所を見つけました.. @ncole458の投稿のおかげでアンサーソース

完全に機能するサーバー コードは次のとおりです。

class StoreList(generics.ListAPIView):
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
                  IsOwnerOrReadOnly,)
serializer_class = StoreSerializer

def get_queryset(self):
    lat = self.request.query_params.get('lat', None)
    lon = self.request.query_params.get('lng', None)

    if lat and lon:
        lat = float(lat)
        lon = float(lon)

        # Haversine formula = https://en.wikipedia.org/wiki/Haversine_formula


        """
        lat1 = math.radians(lat)  # lat in radians
        lng1 = math.radians(lon)  # lng in radians

        lat2 = math.asin(math.sin(lat1)*math.cos(distance/R) +
            math.cos(lat1)*math.sin(distance/R)*math.cos(bearing))

        lng2 = lng1 + math.atan2(math.sin(bearing)*math.sin(distance/R)*math.cos(lat1),
            math.cos(distance/R)-math.sin(lat1)*math.sin(lat2))

        lat1 = math.degrees(lat1)
        lat2 = math.degrees(lat2)

        lat2 = math.degrees(lat2)
        lng2 = math.degrees(lng2)
        """
        lat1 = lat - math.degrees(distance / R)
        lat2 = lat + math.degrees(distance / R)
        lng1 = lon - math.degrees(distance / R / math.cos(math.degrees(lat)))
        lng2 = lon + math.degrees(distance / R / math.cos(math.degrees(lat)))

        return Store.objects.filter(latitude__gte=lat1, latitude__lte=lat2)\
            .filter(longitude__gte=lng1, longitude__lte=lng2)
于 2016-05-12T17:45:58.970 に答える