0

У меня есть сервер с поддержкой местоположения в Django, который должен возвращать данные только тогда, когда пользователь находится в пределах заданного радиуса ввода базы данных. Я нашел фрагмент кода в python что делает это онлайн (здесь или где-то еще, я действительно не помню), и, похоже, он работал, когда я тестировал его с координатами 0,0, а не когда я установил две разные координаты. Теперь у меня есть запись базы данных, которая находится в пределах 300 метров от моего текущего местоположения, а радиус установлен в 10 километров, но по какой-то причине сервер не возвращает результаты мне. где я ошибаюсь в этом коде, потому что я совершенно не понимаю, как это исправить, новичок на python и беспомощно потерян и вышел из моего элемента с haversine с 5 днями до моего проекта. вот мой код запроса на основе гаверсинуса:Сервер на основе 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) 

это изображение показывает, что запрос был получен и координаты правой, но ResultSet еще пуста :(

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

Это выглядит как вы проходите lat1 и lng1 в радианах, но lat2 и lng2 в градусах. (Вы преобразовали lat1 и lng1 в радианы, но никогда не меняли их обратно в градусы.)

+0

У меня есть, но ResultSet еще пуста –

+1

@CoolBeans: Трудно понять, что происходит, не зная, что находится в вашей базе данных. Еще раз взглянув на ваш код, похоже, что вы проверяете точки, широта которых больше, чем 'lat1' --- но не' lat1' латитус вашей исходной точки? Похоже, вы хотели бы использовать haversine для вычисления * двух * новых широт и долгот (для границ NSEW), а не для передачи в lat/long исходной точки. – BrenBarn

+0

Танки .. В итоге мне удалось найти обходное решение .. обновление с ответом –

1

Вам будет гораздо проще переключиться на базу данных, поддерживающую местоположение, так как postgresql (с расширением postgis) или mysql 5.7. Если смотреть на объектах с заданным расстоянием от точки, является тривиальным запросом для такой базы данных и fully supported by django

Dwithin Возвращает модель, где расстояние до поля геометрии от геометрия поиска находится в пределах заданного расстояния друг от друга. Обратите внимание, что вы можете предоставить объекты расстояний только в том случае, если целевые геометрии находятся в проецируемой системе. Для географических геометрий вы должны использовать единицы измерения геометрии (например, для WGS84).

Пример:

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

Таким образом, ваш сложный код становится один вкладыш. В базе данных геопространственных данных есть много возможностей, которые вы найдете довольно полезными.

+0

Хотелось бы, чтобы я мог, но у меня нет vcvar.bat для использования mysql, я хотел, но не мог, потому что в vcvar отсутствует ошибка –

 Смежные вопросы

  • Нет связанных вопросов^_^