Pull to refresh

Мониторинг на коленке

Reading time 5 min
Views 4.9K
Широко распространена задача треканья подвижного объекта. В простейшем случае надо взять телефон с android-ом, поставить туда OsmAnd и настроить live-мониторинг. Сидишь себе и смотришь на карте (OpenStreetMap конечно) перемещение аппарата. Так бы и поступил, но внезапно оказалось, что в нужный день у меня не будет интернета, не будет компьютера, не будет времени.

И я начал искать выход. Сначала состоялись непродолжительные консультации и обсуждения с чатиком, а потом, после обеда, пришло решение.

Есть мобильный телефон и есть услуга оператора email2sms. Значит в моем случае задача сводится к простому получению человекочитаемого текста не более 1000 символов длинной. Но сначала постараюсь изложить ход мыслей.
  • Предоставляемый опсос-ами сервис слежения отметаем сразу, как неточный и по причине не имения симки ни одного из означенных операторов.
  • У ОСМЪ есть неплохой поиск (не без греха, как выяснили хабрапользователи, но приемлемый). А что, если его развернуть в обратную сторону и по переданным координатам получить наименование близлежащего наземного объекта. При чем тут моя задача?.. А не при чем! Просто относительно ориентиров более человекочитаемым получиться текст должен. В общем, мысль интересная, надо на потом оставить. Автор сайта даже что-то имеет в загашнике.
  • «Наблюдаемый продвинулся с прошлого замера на север на 350 м» — вроде годится, но тогда нужно как-то сохранять все точки. Пусть даже последние две… Где взять хостинг такой?
  • Заранее расставить WPT и по достижении их пусть аппарат скидывает сообщение. Ну тут, во-первых, не известен заранее маршрут, а только место назначения. Во-вторых, такого приложения не нашлось. Об этом ниже.
  • И так не всегда отзывчивый juick_ppl и тут ничем не помог.
  • «Наблюдаемый» — «относительно» — «место назначения»… Эврика!

Итак, 100500 приложений из маркета умеют ровно тоже, что OsmAnd — собирают треки, показывают местоположение на карте, делятся координатами. Проблема в том, что делятся они только по нажатию пункта меню «поделиться», а зависимость от ручных действий не обученного андроидопользователя следует исключить. Да и то сказать — пара координат (lat, lon) годится разве что в рамку на стену вешать, но никак не подсказывать человеку куда уже добрался объект. Прочих пригодных вариантов так и не обнаружилось, возможно времени не хватило. Упомяну лишь OruxMaps — несомненно полезная и весьма функциональная программа. Настолько функциональная, что напугала меня до дрожи в коленках. Оставлю её изучение на потом...

К этому моменту четко сформировалась мысль о формате получаемого каждые 5 мин сообщения: "До точки назначения осталось ХХХ км", этого мне будет достаточно. Можно бы и реже, но 5 минут — максимум, что можно выставить. Примерное ограничение на количество сообщений email2sms — 100 в сутки. Этого хватит на целых 8 часов, годится.

Неожиданно просто удалось найти хостинг, на условиях размещения предельно простого php-скрипта, без БД и прочих плюшек. Значит пора приступать к кодингу. На сайте из закладок (ГИС-ЛАБ.инфо, чего уж скрывать) нашлось толковое описание больших кругов с готовым алгоритмом «Вычисление расстояния и начального азимута между двумя точками на сфере», нагло передираю и бессовестным образом переделываю в php:
<?php
#координаты двух точек
$slat=53.393055555556;
$slon=58.755555555556;
$flat=55.3;
$flon=61.5;

#pi - число pi, rad - радиус сферы (Земли)
$pi = pi();
$rad = 6372795;

#в радианах
$lat1 = deg2rad($slat);
$long1 = deg2rad($slon);
$lat2 = deg2rad($flat);
$long2 = deg2rad($flon);

#косинусы и синусы широт и разницы долгот
$cl1 = cos($lat1);
$cl2 = cos($lat2);
$sl1 = sin($lat1);
$sl2 = sin($lat2);
$delta = $long2 - $long1;
$cdelta = cos($delta);
$sdelta = sin($delta);

#вычисления длины большого круга
$y = sqrt(pow($cl2*$sdelta,2)+pow($cl1*$sl2-$sl1*$cl2*$cdelta,2));
$x = $sl1*$sl2+$cl1*$cl2*$cdelta;
$ad = atan2($y,$x);
$dist = $ad*$rad;

#вычисление начального азимута
$x = ($cl1*$sl2) - ($sl1*$cl2*$cdelta);
$y = $sdelta*$cl2;
$z = rad2deg(atan(-$y/$x));

if ($x < 0) $z = $z+180;

$z2 = ($z+180.) % 360. - 180.;
$z2 = - deg2rad($z2);
$anglerad2 = $z2 - ((2*$pi)*floor(($z2/(2*$pi))) );
$angledeg = rad2deg($anglerad2);

echo 'Distance >> ' . $dist . ' [meters]';
echo '<br/>Initial bearing >> ' . $angledeg . ' [degrees]';
?>

Distance >> 276805.84112453 [meters]
Initial bearing >> 39 [degrees]


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

Distance between MQF and CEK
The distance has been calculated as being: 277 kilometres (173 miles)


Отлично, работает! Оформляем в функцию, начальный азимут выкидывается за ненадобностью и для упрощения. Навешиваем недостающий функционал, не забывая запостить данные в ту сторону, ради которой изначально и появился Live Tracking в OsmAnd 0.7.1.




<?php
function distance($llat1,$llong1,$llat2,$llong2) #координаты двух точек
{
	//[...поскипано...]
	return $dist;
}

import_request_variables('G', 'hhsb_');
//проверка переменных на наличие и их заполненность - для слабых духом. не наш случай!
# c - current; f - final; s - start
$d1 = distance($hhsb_clat,$hhsb_clon,$hhsb_flat,$hhsb_flon);
$d2 = distance($hhsb_clat,$hhsb_clon,$hhsb_slat,$hhsb_slon);

# письмо
$emailfrom = $hhsb_rpl;
$replyemail = $emailfrom;
$emailto = $hhsb_eml;
$headers = "MIME-Version: 1.0\r\n";
$headers .= "From: ".$emailfrom."\r\n";
$headers .= "Reply-To: ".$replyemail."\r\n";
$headers .= "X-Priority: 3 (Normal)\r\n";
$headers .= "X-Mailer: yourhoster.com\r\n";
$headers .= "Content-Type: text/plain; charset=Windows-1251\r\n";
$headers .= "Content-Transfer-Encoding: 8bit";
$message = "Distance >> ".$d1." to final destination and ".$d2." from start (meters)\r\n";
$message .= "Speed >> ".round($hhsb_speed,2)." (m/s)";
$subject = "distance";
mail($emailto, $subject, $message, $headers);

# сохранить в ОсМо для просмотра на карте
$esya = 'http://воизбежаниехабраэффектапутьвидентольковархиве/?'.$hhsb_clat.':'.$hhsb_clon.':'.$hhsb_hdop.':'.$hhsb_alt.':'.$hhsb_speed.':'.$hhsb_usr.':'.$hhsb_n;
$ch = curl_init($esya);
$res=curl_exec($ch);
curl_close($ch);
$ans=json_decode($res);
echo $ans->response; //{"s":1} по-любому, можно не проверять
?>


Очень важный этап — в OsmAnd прописать строку Web адрес Live слежения вида:

h͇t͇t͇p͇://hosting_does_not_advertise/fd.php?clat={0}&clon={1}&hdop={3}&alt={4}&speed={5}&slat=53.393&slon=58.756&flat=55.3&flon=61.5&eml=emailto@gmail.com&rpl=emailfrom@mail.ru&usr=[osmohash]&n=[num]



Можно грабить корованы в эту же концепцию добавить путевые точки, а при наличии мало-мальской БД вообще развернуться по-полной. Однако мой наколеночный минимум уже выполнен...
...В добрый путь! Осталось обязательно зарядить андроид. Ведь если не дунутьзарядить, то фокус не получится.

Из выявленных недостатков:
  • Максимальный интервал 5 минут, хотелось бы побольше. В идеале вообще иметь возможность вводить числом, а не выбирать из списка.
  • К исходу второго часа сдохло приложение, не понятно кто постарался. Подозреваю, что андроид сумничал, т.к. пользователь не проявлял активность всё это время — как только состоялась первая передача данных аппарат сразу оказался в сумке и исправно подавал сигналы. Пришлось наводить панику и просить реанимировать OsmAnd. Справились, ОК.
  • Таки есть зависимость от не обученного пользователя — удаленно же не отключить. Инструкции не помогли, сложно видите ли… Проще оказалось попросить выключить питание «трекера» по прибытии.

Но довольно перемывать косточки такого сферически-идеального, продуманного и логически завершенного лайфхака, ведь уже приехали на место.
Distance >> 29 to final destination and 247194 from start (meters)
Speed >> 0.0 (m/s)
Tags:
Hubs:
+17
Comments 7
Comments Comments 7

Articles