Pull to refresh

Как я в библиотеке реальность дополнял

Reading time 5 min
Views 5K
картинка для привлечения внимания
Картинка для привлечения внимания.
Я тот, кто первым использовал технологии навигации для построения дополненной реальности.
Технологии геолокации известны давно и хорошо документированы во всех языковых частях Интернета, включая русскую. Но, как бы это ни было удивительно, до сих пор никем не применялись толком на практике. Несколько лет назад, всё на том же habrahabr'е я читал о планах использования карт дополненной реальности. Но, насколько я могу видеть, нигде, кроме ingress это, опять же, так и не использовали.
В декабре 2011-го года Воронежская областная детская библиотека создала свой собственный краеведческий ресурс Детям о Воронежском крае и с тех пор систематически наполняла его краткими аннотациями по памятникам, памятным местам и другой информацией о Воронежском крае. Пользователи в любой момент могли получить эту информацию и отсылки к краеведческой литературе, которая имеется в библиотеке.
Всё до крайности просто. Информация уже есть на сайте. Каждая такая статья это единственная запись в базе данных в виде html кода. Чтобы отобразить её, достаточно сделать один запрос. Но нужно как-то доставить её пользователю. Тут и родилась идея «гида».
В Воронеже очень много гостей. Это и студенты из других городов, и иностранцы, приехавшие по долгу службы, и просто туристы. Все они любят осматривать наши достопримечательности и памятники. А всегда удобнее иметь под рукой что-то, с чем не нужно долго возиться и разбираться.
Поэтому я решил привязать каждую запись к определённым координатам на местности. Если это не дополненная реальность, то что?
Разберём конкретную реализацию.
Поискав недельку готовые решения и не найдя ничего подходящего, решил сделать всё по-своему. Во-первых, метод определения координат пользователя.
<body onload="getLocation();">
...
geolocationOptions: 
	{
        enableHighAccuracy: true;
    }

function getLocation() {
    if (navigator.geolocation) {
        navigator.geolocation.watchPosition(showPosition);
    } else { 
        x.innerHTML = "Геолокация не поддерживается данным браузером или устройством.";
    }

Как можно видеть отсюда, всё крайне просто. Здесь мне очень помог метод watchPosition, который срабатывает не один раз, как getCurrentPosition, но работает постоянно по мере изменения координат пользователя. Поэтому оказалось крайне удобно показывать контент в зависимости от положения.
Следующий момент, это как раз проверка координат. Я долго думал, как же лучше сделать? Сначала меня посетила мысль о достаточном огрублении точности указанного местоположения. Но этот метод оказался неподходящим, поскольку оказалось сложным подобрать такую погрешность, которая бы давала нужный радиус и я от неё отказался.
Тогда я стал думать в сторону контуров, очерчивающих площади на местности. Но это сильно усложнило и утяжелило бы код и от этой идеи я тоже отказался.
Третье решение показалось мне наиболее простым и правильным. Выражается оно в следующей строке кода:
var data = <?php echo $myArray ?>; //вывод массива полученных из БД данных

Что в итоге, очевидно, превращается в код вида:
var data = [["293","51.6569823","51.6583003","39.2145828","39.2174366"],["294","51.630048","51.630752","39.156333","39.157132"],["295","51.693474","51.693709","39.20857","39.209728"],["296","51.6704160","51.6718383","39.2093698","39.2117104"],["297","51.6644532","51.6647234","39.2065102","39.2066389"],["298","51.6640640","51.6645244","39.2074646","39.2079206"],["300","51.6664147","51.6669751","39.2019236","39.2021328"],["301","51.6624973","51.6629277","39.2063693","39.2069325"],["302","51.6610044","51.6621621","39.2011539","39.2019854"],["303","51.6735303","51.6739639","39.2071490","39.2077873"],["304","51.6644936","51.6652675","39.2038072","39.2049820"],["305","51.6715535","51.6722906","39.2086361","39.2097626"],["306","51.6615435","51.6622841","39.1990161","39.1997027"],["308","51.6554642","51.6559213","39.1859334","39.1865128"],["312","51.6735318","51.6740154","39.2113578","39.2124253"],["313","51.6758248","51.6762417","39.2107791","39.2114228"],["315","51.7115548","51.7120380","39.2272416","39.2277244"],["316","51.7564548","51.7572128","39.1742317","39.1752658"],["434","51.6659232","51.6664169","39.2051209","39.2057968"],["435","51.7064638","51.7071071","39.1711776","39.1726474"]];

Как можно видеть, это просто набор координат и id статей.
И вот тут уже делается всё самое важное:
function showPosition(position) {
			for (i = 0; i < data.length; i++) {
				if ((position.coords.latitude >= data[i][1] && position.coords.latitude <= data[i][2]) && (position.coords.longitude >= data[i][3] &&  position.coords.longitude <= data[i][4]))
				{
					showArticle(data[i][0]);
					x.innerHTML = ("<h1>Мы обновим и отобразим для Вас информацию о следующем памятнике, когда Вы будете с ним рядом.</h1>");
				}
			} 
		}

То есть, суммируя вышеизложенное, каждый раз при изменении координат мы пробегаемся по всему массиву и проводим сравнение текущих значений с теми, что есть в массиве. Таким образом, если пользователь вошёл в прямоугольник, который мы указали при создании метки, скрипт автоматически загрузит статью из базы данных. Естественно, при помощи ajax, вот таким простым способом:
function showArticle(str) {
	if (str == "") {
	   document.getElementById("txtHint").innerHTML = "";
	   return;
	} else { 
	    if (window.XMLHttpRequest) {
	     // code for IE7+, Firefox, Chrome, Opera, Safari
	       xmlhttp = new XMLHttpRequest();
	    } else {
	        // code for IE6, IE5
	        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
	    }
	    xmlhttp.onreadystatechange = function() {
	        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
	            document.getElementById("txtHint").innerHTML = xmlhttp.responseText;
	        }
	    }
        xmlhttp.open("GET","getArticle.php?q="+str,true);
	    xmlhttp.send();
	}
}

Конечно, у описанного выше метода есть и очевидные недостатки.

В выделенном прямоугольнике находится памятный знак жертвам бомбардировки в саду Пионеров. Но указать его как-то иначе, чтобы в эту площадь не попадали рядом стоящие дома, при использовании данного подхода просто невозможно. Но, к счастью, в данном случае, это не важно, потому что, как правило, плотность памятников на единицу площади крайне мала, а следовательно, это никак не помешает.
Другая сложность — это проблемы самой технологии навигации. Порою она даёт удивительно большие погрешности. Так, памятник С. Есенину находится примерно в более чем в пятистах метрах от памятника А. Кольцову. Но из-за окружающих зданий, временами, вместо С. Есенина можно увидеть информацию по А. Кольцову.
Но тем не менее «Гид» запущен и им уже пользуются жители и гости города. Работа по его улучшению будет продолжена. Буду рад конструктивной критике и предложениям.
Сам «гид» можно найти по следующей ссылке: www.okrae.odbvrn.ru/guide
На этом, я считаю, можно закончить обзор. Надеюсь, информация будет полезна сообществу.
UPD: видео с местного тв.
UPD 2: скоро выкатим новую версию. Эта уже старая.
Tags:
Hubs:
If this publication inspired you and you want to support the author, do not hesitate to click on the button
0
Comments 4
Comments Comments 4

Articles