Используйте скрипт для сравнения координат из клиентского API с DB

#javascript #node.js #express #mongoose

Вопрос:

Я пытаюсь сравнить координаты из события в моей базе данных с координатами, отправленными пользователем из их клиентского API (после утверждения), но не могу понять, как правильно настроить сравнение. Прямо сейчас координаты пользователя просто регистрируются в терминале:

Вот мой скрипт под guestValidate.js:

 if(confirm('Compare wants to use your current location to briefly checkin. Do you approve?')) {
    navigator.geolocation.getCurrentPosition(function (position) {
        console.log(position.coords.latitude)
        console.log(position.coords.longitude)
    }) 
} else { 
console.log("The Locator was denied.");
}

console.log(eventCoords)
 

Вот страница, на которой я запускаю ejs:

 <% layout('layouts/boilerplate') %> 

<h1>Prompt</h1>

<script>
    const eventCoords = '<%- event.geometry.coordinates %>'
    const eventID = '<%- event.id %>';
</script>


<script src="/javascripts/guestValidate.js"></script>
 

Я прикрепил вывод из терминала ниже. Оба работают, мне просто нужно структурировать их как объекты и сравнить, я думаю? Может ли кто-нибудь помочь мне сравнить два набора координат, пожалуйста?

Если они равны, я хочу отправить «true» обратно в маршрут базы данных.

введите описание изображения здесь

Комментарии:

1. из какого API вы хотите получить предыдущее местоположение пользователя и в какой API вы хотите отправить после их сравнения?

2. Он извлекает if else из моего guestValidate.js сценарий. Прямо сейчас он регистрирует position.coordinates. широта и долгота. Мне нужно как-то сравнить эти данные с eventCoords. Есть идеи?

Ответ №1:

Один из способов сделать это, если место проведения либо относительно небольшое, либо не имеет странной формы, — просто выбрать широту / длину в центре местоположения и разрешить радиус, который вы считаете разумным с этой точки. Вероятно, вам потребуется некоторое пространство для неточностей в определении местоположения, поскольку пользовательские службы определения местоположения иногда могут быть ненадежными. Это особенно часто встречается в закрытых помещениях в бетонных зданиях.

Вы могли бы просто использовать формулу Haversine, но поскольку земля на самом деле не является сферой, и вы пытаетесь проверить, что я предполагаю, в относительно небольших местах, потенциальные ошибки haversine со сферой делают ее использование плохой идеей. (Ошибка может составлять до 0,3%, что звучит неплохо, но земля довольно большая, так что это означает ошибку до 20 км).

Вместо этого я бы порекомендовал классную библиотеку, предложенную Крисом Венессом на https://github.com/chrisveness/geodesy

Если вам интересно, здесь есть полное объяснение математики, лежащей в основе этой библиотеки, для вашего использования: https://www.movable-type.co.uk/scripts/latlong-vincenty.html .

В вашем случае, если бы вы хотели провести это сравнение в браузере, использование выглядело бы примерно так:

 <script src="https://cdn.jsdelivr.net/npm/geodesy@2.2.1/latlon-ellipsoidal-vincenty.js"></script>
<script type="module">
  import LatLon from 'https://cdn.jsdelivr.net/npm/geodesy@2.2.1/latlon-ellipsoidal-vincenty.js';

  function getDistanceBetweenPoints(user, venue) {
    const p1 = new LatLon(user.lat, user.lon);
    const p2 = new LatLon(venue.lat, venue.lon);
    return p1.distanceTo(p2);
  }

  let user = { lat: 30.2696082, lon: -97.7521805 };
  let venue = { lat: 30.2699360, lon: -97.7485410 };

  console.log(`Distance between user and venue is ${getDistanceBetweenPoints(user, venue)} meters`);
</script> 

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

Еще одна вещь, пользователи могут технически подделывать свои местоположения, поэтому я бы не рекомендовал использовать это для чего-либо, связанного с безопасностью.