0

Djangoには、ユーザーがデータベースエントリの指定された半径内にあるときにデータを返すと想定される位置認識サーバーがあります.. Pythonでコードスニペットが見つかりましたそれはちょうどオンライン(ここか他の場所では、私は本当に覚えていない)であり、私は0,0の座標に対してそれをテストしたときに動作するように見えました。私は今現在の場所から300メートル以内のデータベースエントリを持っており、半径は10キロメートルに設定されていますが、何らかの理由でサーバが結果を返すことはありません。私はこのコードで間違っているのですが、私はそれを修正する方法が全くわからないので、初心者はpythonにして、私のプロジェクトが完了するまで5日間のhaversineで私の要素から無力に失われてしまいました。ここ は、半正矢ベースのクエリのために私のコードです:Haversineベースのサーバーは、座標が完全一致の場合にのみデータを返します

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) 

この画像は、要求を受信したことを示し、座標は右ですが、結果セットが空のままである:(

Server out put

答えて

0

..だから私は、アルゴリズムが間違ってた場所.. @ ncole458のポストのおかげでここAnswer source

が完全に機能するサーバーのコードで見つけた:私が持っている

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) 
1

に見えますlat1lng1をラジアンで渡しますが、lat2lng2の度数です(lat1lng1をラジアンに変換しましたが、度に変更していない)。

+0

が、結果セットが空のままであります –

+1

@CoolBeans:データベースの内容を知らなくても何が起きているのかを知ることは難しいです。あなたのコードをもう一度見てみると、latitudeがlat1よりも大きい点をチェックしているように見えますが、元の点のlatitiudeではありません。元のポイントの緯度/経度を渡すのではなく、2つの新しい緯度と経度(NSEW境界の場合)を計算するために、haversineを使用したいと思うようです。 – BrenBarn

+0

タンク..私は最終的に回避策を見つけることができました。答えは –

1

postgresql(postgis拡張子付き)やmysql 5.7が好きな位置認識データベースに切り替える方がはるかに簡単です。あなたはポイントから所定の距離を持つオブジェクトを見れば、このようなデータベースのための些細なクエリであるとDwithinが からジオメトリフィールドまでの距離参照ジオメトリが与えられた距離内にあるモデルを返しfully supported by django

です互いに。 ターゲットの ジオメトリが投影システム内にある場合にのみ距離オブジェクトを提供できることに注意してください。ジオメトリジオメトリの場合、 はジオメトリフィールドの単位を使用する必要があります(例:WGS84の度数)。

例:

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

このように、あなたの複雑なコードは1つのライナーとなります。地理空間データベースには、多くの機能があります。

+0

で更新したいと思いますが、私はmysqlを使用するためにvcvar.batを持っていませんが、vcvarにはエラーがありません –

関連する問題