Вычислить радиус вокруг точки GPS широты и долготы в PHP

Я пытаюсь создать сценарий PHP, который может что-то делать, когда устройство GPS (трекер) входит в «геозону» с предопределенным положением. В большинстве найденных мной подсказок используется формула гаверсинуса, но большинство из них пытается определить ближайшее местоположение из точки. Мне в значительной степени нужно обратное.
Координаты устройства и "местоположения забора" находятся в базе данных MySQL, я могу извлечь их успешно. Теперь мне нужно установить радиус вокруг центра расположения забора, который должен составлять 10 метров в любом направлении от этой точки.
Всякий раз, когда устройство входит в этот радиус 10 метров, PHP что-то делает.
Итак, точка A (широта, lon) имеет радиус 10 м вокруг него, устройство B отправляет свои широты и долготы в базу данных SQL, и всякий раз, когда точки A и B находятся в пределах 10 м друг от друга, что-то происходит. С чего мне начать? Пригоден ли гаверсин в моей ситуации? Я думаю, что PHP может вычислить разницу расстояний между A и B, и если это расстояние меньше 10 м, PHP что-то делает.

Я думаю, это может сработать.

function haversineGreatCircleDistance(
  $latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo, $earthRadius = 6371000)
{
  // convert from degrees to radians
  $latFrom = deg2rad($latitudeFrom);
  $lonFrom = deg2rad($longitudeFrom);
  $latTo = deg2rad($latitudeTo);
  $lonTo = deg2rad($longitudeTo);

  $latDelta = $latTo - $latFrom;
  $lonDelta = $lonTo - $lonFrom;

  $angle = 2 * asin(sqrt(pow(sin($latDelta / 2), 2) +
    cos($latFrom) * cos($latTo) * pow(sin($lonDelta / 2), 2)));
  return $angle * $earthRadius;
}

person Fid    schedule 13.11.2015    source источник
comment
php работает на сервере. как именно он узнает, где это устройство GPS и что оно делает?   -  person Marc B    schedule 13.11.2015
comment
Координаты A и B хранятся в базе данных SQL. A всегда имеет одну и ту же координату (он не перемещается), B перемещается и обновляет свое местоположение в базе данных каждые X секунд, поэтому самая новая запись в базе данных - это последняя позиция B. У меня все это уже работает.   -  person Fid    schedule 13.11.2015
comment
поэтому, когда php обновляет базу данных, он выбирает для расчета расстояния между A&B, например. if (dist($A, $B) < 10) { do_something(); }   -  person Marc B    schedule 13.11.2015
comment
чтобы у вас были координаты центра и устройства, используйте эту функцию для расчета расстояния и проверки быть меньше 10, тогда делай то, что хочешь   -  person Danil Gudz    schedule 13.11.2015
comment
Правильный. Я нашел этот код и попробую. Обновленный вопрос.   -  person Fid    schedule 13.11.2015
comment
@MarcB Этот код прекрасно работает, спасибо! Как я могу отметить ваш ответ как правильный?   -  person Fid    schedule 13.11.2015
comment
не может принимать комментарии (очевидно, это не ответы). И не беспокойтесь, поскольку это был всего лишь псевдокод, это тоже не ответ.   -  person Marc B    schedule 13.11.2015


Ответы (1)


Итак, чтобы выразить все это в полном ответе:

Используйте функцию, аналогичную той, которую использует @Gudz Daniel, чтобы вычислить фактическое расстояние от любой точки givien: https://www.geodatasource.com/developers/php. Это рисует вокруг этой точки эффективный круг "геозоны", так как вы можете измерить расстояние под любым входящим углом.

function distance($lat1, $lon1, $lat2, $lon2, $unit) {

  $theta = $lon1 - $lon2;
  $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
  $dist = acos($dist);
  $dist = rad2deg($dist);
  $miles = $dist * 60 * 1.1515;
  $unit = strtoupper($unit);

  if ($unit == "K") {
    return ($miles * 1.609344);
  } else {
    return $miles;
  }
}

Затем вы просто сравниваете любое расстояние, на котором устройство должно отмечать ваш следующий процесс, как указано в @Mark B:

$distance = distance($lat1, $lon1, $lat2, $lon2, "M");

if ($distance <= 1) {
    // Now you know your truck/device is
    // within 1 mile of the center-point.

    send_alert("You've arrived!");
}
person ryebread    schedule 16.08.2016