LXF158:Карта ваших прогулок
|
|
|
КАРТА ВАШИХ ПРОГУЛОК
Прогулки — это хорошо. И весело. А если вы хотите поделиться своими маршрутами, используя GPS? Иэн Бартон покажет, как это делается.
Будучи знтузиастом альпинизма и велоспорта, я использую GPS-навигатор для записи своих маршрутов, а цифровую камеру – чтобы запечатлеть виды. Желая поделиться маршрутами, мне надо показать свои перемещения на карте в web-браузере. Как и в Google Maps, мне надо было привязать мои фотографии к Point of Interest (POI, интересное место) на карте и сделать так, чтобы фотографии всплывали, когда пользователь щелкает на POI. Весь процесс задействует огромную подборку инструментов с открытым кодом – от извлечения маршрутов из навигатора и снабжения фотографий геотэгами по данным GPS до отображения и маршрутов, и фото на карте при помощи библиотеки JavaScript, OpenLayers.
Содержание |
Загрузка данных
Первый шаг – извлечение данных с GPS-навигатора. У меня Garmin eTrex с последовательным портом. Однако многие более новые устройства снабжены портами USB. Если ваше устройство GPS имеет последовательный порт, вам, вероятно, понадобится стыковать его с USB через кабель. Найти такой кабель можно на eBay.
Для загрузки маршрутов и точек следования из GPS мы применим GPSBabel. Эта программа – настоящий швейцарский нож в мире GPS. Она умеет конвертировать пункты маршрута и пути следования в самые разные форматы. Если вы используете конвертор из последовательного порта в USB, то при подключении его к вашему компьютеру и запуске dmesg вы должны получить нечто вроде
[ 5753.489759] usb 5-1: pl2303 converter now attached to ttyUSB0
[ 5753.489786] usbcore: registered new interface driver pl2303
[ 5753.489789] pl2303: Prolific PL2303 USB to serial adaptor driver
Используя GPS от Garmin, вы получите наилучший результат при загрузке необработанного журнала трассы [tracklog]. Сохраненные журналы теряют изрядную долю информации, в том числе отметки времени. Но если вы хотите сделать геотэги для своих фотографий, отметки времени вам понадобятся!
Лучше всего сохранять данные в формате GPX: это наиболее широко поддерживаемый формат данных GPS. GPSBabel имеет оболочку GUI, написанную на Qt. GUI строит командную строку, а та передается GPSBabel. Команда отображается в GUI; освоив программу, вы сможете использовать командную строку для загрузки маршрутов.
Многие современные устройства GPS имеют порты USB и опознаются как устройства массового хранения данных, так что вы сможете загрузить журнал с помощью файлового менеджера.
Определим допуски
Я опорожняю журнал из своего GPS-навигатора, только когда он заполнится. Однако я не хочу загружать весь журнал целиком после каждой пешей или велосипедной прогулки. GPSBabel позволяет выбрать различные фильтры, в том числе интервала времени, чтобы уточнить, какие данные загрузятся из вашего навигатора. Следующая команда загружает журнал для указанной даты и сохраняет его в виде файла GPX:
gpsbabel -t -i garmin -f /dev/ttyUSB0 -x track,start=20120212000001,stop=20120212235959 -o gpx track.gpx
Вы – настоящий профи, и показания часов на вашем фотоаппарате совпадают с показаниями часов в устройстве GPS? Кхе... терпеть не могу в этом сознаваться, но у меня почему-то так не получается.
Часы в вашем навигаторе синхронизируются со спутником GPS, и время на них всегда точное. Почти все цифровые камеры хранят информацию о том, когда была создана фотография, в тэгах EXIF. Соответствующие тэги – ‘DateTimeOriginal’, ‘CreateDate’ и ‘TimeCreated’. И все, что вам нужно сделать – это обновить эти тэги, используя разницу во времени на камере и устройстве GPS.
Для уточнения информации EXIF мы воспользуемся инструментом exiftool от Фила Харви [Phil Harvey] (www.sno.phy.queensu.ca/~phil/exiftool). В моем случае часы на камере на 1 час 21 минуту опережали часы GPS, так что в тэгах EXIF мне надо было отнять 1 час 21 минуту от указанного там времени. С exiftool, команда такова:
exiftool “-DateTimeOriginal-=0:00:00 01:21:0” \
“-CreateDate-=0:00:00 01:21:0” \
“-TimeCreated-=0:00:00 01:21:0” *.JPG
Обратите внимание на – перед знаком равенства: он уменьшает значение времени. Перед обновлением тэгов EXIF создайте резервную копию фотографий, на случай ошибки.
Можно также создать копию данных EXIF в текстовом файле для всех фотографий в текущей директории, командой
exiftool -s *.JPG > exif_backup.txt
Если все получится криво, вы сможете использовать их для восстановления исходных данных.
Геотэги
Следующеий этап – применить отметки времени EXIF в фотографиях для их корреляции с журналом навигатора. Затем мы запишем данные положения GPS в соответствующие тэги EXIF в фотографиях. Этот процесс известен как создание геотэгов.
Для создания геотэгов фотографий воспользуемся GPSPrune. Если вы уже ликвидировали разницу во времени между вашими записями GPS и фотографиями, первым шагом будет загрузка маршрута GPS в GPSPrune.
В меню Photo выберите Add Photos [добавить фото] и выберите директорию, где хранятся ваши фотографии. В меню Photo выберите Correlate Photos [скоррелировать фото]. Множество опций в этом диалоговом окне позволят вам настроить Correlation Limits [допуски], поскольку есть вероятность, что данные в вашем журнале GPS и у фотографии в точности соответствуют друг другу. Две самых полезных опции –
» Time Limit [допуск по времени]
» Distance Limit [допуск по расстоянию]
Если время или расстояние в поле EXIF и на трассе лежат в установленных вами допусках, то GPSPrune будет считать, что фотография и точка в журнале совпадают.
Затем GPSPrune отметит флажками все фото, где можно привести в соответствие время EXIF со временем GPS. Когда вы нажмете на OK, GPSPrune отметит точки, соответствующие каждой фотографии, на вашей трассе. По нажатии на точку появится привязанная к ней фотография. После этого можно вписать широту и долготу в соответствующие поля EXIF каждой фотографии. Выберите Save to EXIF в меню Photo. Отобразится список фотографий, в которые запишутся данные EXIF.
В порядке меры безопасности, можете выбрать режим неперезаписи исходных фотографий – в этом случае они скопируются в файл с расширением _original.
Теперь GPSPrune будет присоединять новые точки следования к концу вашего GPS-файла, с местоположением каждой фотографии, отметкой времени и полным путем и именем файла фотографии. Пример приведен ниже:
<trkpt lat=”53.06943558”
lon=”-4.18059098”><ele>749</ ele><time>2011-02-20T09:53:57Z</time>
<link href=”/home/ian/Pictures/Holidays/North_Wales/2011-02-North_Wales/20022011085.jpg”>
<text>20022011085.jpg</text> </link></trkpt>
234096.pngСоздание миниатюр
Вам, естественно, захочется создать миниатюры для каждого изображения, которое вы намерены показывать на карте. Есть десятки способов сделать это, но мы воспользуемся простым скриптом оболочки, который вызывает программу конвертирования imagemagick для создания миниатюр шириной 75px. Миниатюры будут названы именем исходного файла, к которому припишется расширение .thumb.
Поместите следующий скрипт, который находится на DVD, в директорию с вашими фотографиями:
FILES=”$@”
for i in $FILES
do
echo “Обработка изображения $i ...”
/usr/bin/convert -thumbnail 75 $i thumb.$i done
и запустите
./thumbnail.sh *.JPG
Из всех файлов с расширением .JPG в этой директории создадутся миниатюры.
Интересные места
Чтобы показать место, где были сделаны фотографии на вашей карте, вы создаете точку Point of Interest (POI), соответствующую каждой из них. К счастью, OpenLayers загрузит данные для отображения POI из файла, так что вам не придется добавлять все POI вручную. Поля записи данных показаны ниже. Учтите, что поля разделяются знаками табуляции, а записи – переводом строки.
lat lon title description icon iconSize iconOffset.
[Широта Долгота Название Описание РазмерЗначка СмещениеЗначка]
В текстовом поле можно разместить URL’ы. Мы будем использовать это для отображения миниатюры фотографии, ссылки на полноразмерную фотографию и текста описания.
Точки следования, содержащие данные о фото, извлекаются из файла GPX, который вы создали в процессе создания геотэгов фотографий с помощью GPSPrune.
GPSPrune весьма удобно прилагает эти данные к концу вашего журнала, и мы легко сможем их добыть с помощью текстового редактора. Скопируйте данные XML, не забыв включить все необходимые тэги, и вставьте их в шаблон, приведенный ниже. Обратите внимание, что шаблон содержит единственную точку следования, помещенную для демонстрации, каким должен быть правильный синтаксис. Сохраните данные в файл, например, photos.gpx.
<?xml version=”1.0” encoding=”UTF-8”?>
<gpx version=”1.0” creator=”GpsPrune v13 activityworkshop.net”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xmlns=”http://www.topografix.com/GPX/1/0”
xsi:schemaLocation=”http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd”>
<name>Your Walk Name</name>
<desc>Export from GPSPrune</desc><trk><name>Your Walk Description</name><number>1</number>
<trkseg>
<trkpt lat=”53.13602777777778” lon=
”-3.9945555555555554”><ele>575</ele><link href=”./images/DSCF1869.JPG”><text>DSCF1869.JPG</text></link></trkpt>
</trkseg>
</trk>
</gpx>
Теперь конвертируем фотоданные XML из созданного вами файла photos.gpx в разделенные знаками табуляции данные, используемые для отображения POI в OpenLayers. Поскольку данные – это просто XML, для конвертирования воспользуемся скриптом Python. Полностью его код приведен на нашем DVD. Запустите скрипт с DVD и перенаправьте выходные данные в файл: ./generate_poi.py > poi.txt. Заметьте, что в конце файла должна быть пустая строка, иначе последний POI не будет отображаться. Поместите полученный файл (poi.txt) в ту самую директорию, где находится страница HTML, которая создает карту.
Отображение на карте
Теперь у вас есть фотографии с геотэгами, миниатюры и текстовый файл, содержащий информацию для отображения фотографий в виде POI на карте. Конечная стадия – создание страницы HTML, содержащей всю информацию, необходимую для загрузки данных карты и отображения маршрута и фотографий. Вы можете использовать практически любой web-сервер, поскольку работа ведется в браузере.
Для отображения карты и сопутствующей информации мы будем использовать OpenLayers, библиотеку JavaScript с открытым кодом для отображения картографических данных. Она работает с большинством современных браузеров, и она полностью клиентская, не требующая никаких специальных программ на сервере.
Используя OpenLayers, вы можете отображать ваши данные с помощью одного и того же JavaScript, используя карты от всех провайдеров, включая Google, Ordnance Survey и OpenStreetMap.
Однако если вы хотите использовать Google Maps или Ordnance Survey, вам нужно будет подписаться, чтобы получить ключ API. Внимательно прочитайте их условия соглашения, поскольку там есть ряд ограничений на использование данных. В противоположность им, OpenStreetMaps совершенно не имеет ограничений.
Выбор используемого сервиса зависит от ваших требований. В Великобритании я установил, что Ordnance Survey лучше всего подходит для отображения пешеходных маршрутов, а OpenStreetMap – для велосипедных.
Впрочем, используя LayerSwitcher, виджет OpenLayers, вы сможете переключать свою карту между разными картографическими системами, и при желании использовать все три на одной и той же web-странице.
Библиотека OpenLayers весьма обширна, и на первый взгляд кажется просто ошеломляющей. К счастью, в ней масса примеров, помогающих вам приступить к делу. Мы будем использовать созданный вами ранее файл GPX, чтобы отобразить маршрут на OpenStreetMap.
Карта также будет отображать POI, которые вы создали по тем местам, где снимали фотографии. При щелчке по POI отобразится всплывающее окно с подписью и миниатюрой фотографии. Если щелкнуть по миниатюре, во всплывающем окне отобразится полноразмерная фотография.
LayerSwitcher
Первый шаг – создать страницу, которая отображает карту интересующей вас местности. Будем использовать OpenLayers LayerSwitcher, который позволит переключаться между разными слоями OpenStreetMap. Вы также можете использовать ее для переключения между разными картами, например, Google и OpenStreetMap.
Полный код для web-страницы слишком велик, чтобы мы показывали его здесь, но он имеется на DVD. Вот несколько приемов и советов:
- Обеспечьте, чтобы на вашей странице был действующий DOCTYPE, иначе начнутся странности.
- Храните все файлы JavaScript на своем сервере.
- Однако у вас будут все самые свежие заплатки (и новые ошибки тоже), если вы обратитесь к библиотеке на удаленном сайте.
- Используя Google Maps или Ordnance Survey, убедитесь, что у вас действующий ключ API. Ключ привязан к вашему доменному имени, и на другом сайте работать не будет.
- Слой Cycle Map [велосипедный] в OpenStreetMaps также отлично подходит для отображения данных по пешеходным маршрутам, поскольку отображает контурные линии.
Код, отображающий слой карты, находится в одном блоке JavaScript. Сначала вы объявляете несколько переменных, которые сообщат карте нужную широту и долготу. Прочие атрибуты, например, отображение панелей LayerSwitcher и Pan [панорама] and Zoom [масштабирование], также должны быть определены.
Теперь добавьте слой, который отображает ваш маршрут GPX на карте в собственном слое. ‘Carneddau’ – название маршрута, который отображается в LayerSwitcher.
Если вы хотите отобразить более одного маршрута, просто скопируйте этот раздел и затем соответствующим образом измените параметры.
// Добавим слой с трассой GPX
var lgpx = new OpenLayers.Layer.GML(“Carneddau”, “carneddau.gpx”, {
format: OpenLayers.Format.GPX,
style: {strokeColor: “green”, strokeWidth: 5, strokeOpacity: 0.5},
projection: map.displayProjection});
map.addLayer(lgpx);
Далее, определите слой, который будет отображать ваши POI:
// Load our Points of Interest
var pois = new OpenLayers.Layer.Text( “POI”,{ location:”poi.txt”,
projection: map.
displayProjection });
map.addLayer(pois);
И, наконец, можно добавить маркер, чтобы показать, где вы начали и где завершили маршрут.
// Добавим маркет начального пункта.
var size = new OpenLayers.Size(21, 25);
var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
var icon = new OpenLayers.Icon(‘http://www.openstreetmap.org/openlayers/img/marker.png’,size,offset);
layerMarkers.addMarker(new OpenLayers.Marker(lonLat,icon));
Вы должны определить div в теле страницы, на которой хотите отображать карту. Помните, что имя div то же, что и у слоя, использованного для определения карты – проявив недюжинную изобретательность, я назвал его ‘map’:
После загрузки страницы функция body.onloaded() вызовет функцию JavaScript init(), которая загружает данные карты. При щелчке на миниатюре, отображенной в POI, полномерная фотография отображается во всплывающем окне.
Всплывающее окно создается с помощью JavaScript, который использует URL, заключенный в текстовом файле с данными для POI.
Графики восхождения
Мне часто хочется изобразить свой маршрут GPX в виде графика восхождения, который отображает высоту на всей протяженности маршрута. Если, как мы сказали, GPSBabel – это швейцарский нож для данных GPS, то для графиков этого звания достоин Gnuplot. Вы можете создать график с помощью GPSPrune (который вызывает GnuPlot), но работа непосредственно с GnuPlot будет более гибкой.
Мы воспользуемся скриптом Python gpxplot от Сергея Астанина [Sergey Astanin], но автор сделал свое ответвление, добавив функциональности. Эта версия имеется на Github по адресу https://github.com/geekinthesticks/GPX-Tools. Скрипт считывает данные из файла GPX и умеет давать на выходе графики в разных форматах. Запустите ./gpxplot.py –help, чтобы познакомиться с опциями. Вам также нужно будет установить gnuplot.py, который имеется в большинстве дистрибутивов. Если у вас не установлен gnuplot.py, использование опции --gprint option сгенерирует скрипт GnuPlot, который можно передать напрямую GnuPlot из командной строки.
Вот каким образом на экране создается график маршрута с указанием высот:
./gpxplot.py –output-format gnuplot --y-axis elevation \ --x-axis distance --tzname ‘Europe/
London’ \
--imperial –file
arneddau.gpx
По умолчанию данные выводятся в метрической системе (высота – в метрах, расстояние – в километрах); опция --imperial отобразит высоты в футах, а расстояние в милях.
Если вы хотите вывести график в файл изображения, а не на экран, используйте опцию --image, за которой должно следовать имя файла. Формат изображения определяется расширением имени файла: так, --imagetrack.png создаст файл PNG. Другие поддерживаемые форматы вывода – GoogleChart, Gprint, table (колонки, разделенные пробелом) и orgtable (таблицы в формате org-mode Emacs).
Время в файлах GPX обычно отображается в формате UTC. Желая отображать ваши данные по местному времени, используйте опцию --tzname и задайте часовой пояс в формате ‘Europe/London’.
В GnuPlot масса опций для настройки цветов, заголовков и прочих параметров. Если вы решите подправить выходные данные, создайте файл Gprint и отредактируйте его, чтобы получить желаемый формат. Файл Gprint можно затем использовать в качестве исходной информации для GnuPlot при создании графика.
Заключение
На нашем уроке мы рассмотрели только основы – вы можете сделать намного больше, например, добавить слои карт для Ordnance Survey и Google Maps, чтобы ваши пользователи могли переключаться между разными картами.
Помимо всего кода из этой статьи с DVD, вы также можете получать обновления из репозитория автора на Github по адресу: https://github.com/geekinthesticks/Plotting-gpx-Data-and-Showing-Geotagged-Photos-Using-OpenLayers. |