This post describes in detail how to add GPS data to video file using `visual correlation' (see also: Video geocoding with gpsbabel).
There is an easy way to augment video files with GPS data using GPSbabel. Since version 1.4 of GPSBabel is able to create a subtitle file from a GPS tracklog. The subtitle contains latitude/longitude/altitude as well as the time. With a simple Perl scripts I have added current speed (not particularly accurate however).
To convert GPX file to subtitles one have to execute:
gpsbabel -i gpx -f FILE.gpx -o subrip,video_time=hhmmss,gps_time=hhmmss,gps_date=YYYYMMDD -F FILE.srt
Where: video_time
--
video position (relative to beginning of video) for which exact corresponding GPS timestamp
is known. gps_time
-- the time part
of the GPS timestamp which corresponds to a known position in the video.
gps_date
-- the date part of
the GPS timestamp which corresponds to a known position in the video.
On a video (see below) you can see that in 34 second I passed the zebra crossing. The zebra's crossing coordinates can be easily identified at Google Maps (cf. picture Crossing at Osowa). Now one have to search the GPX track for the point which is nearest to 54.429591/18.477973. I developed a simple Perl script for that purpose:
$ perl My_GPX_nearest_timestamp.pl -c 54.429591:18.477973 20130420.gpx *** USAGE: My_GPX_nearest_timestamp.pl -c latitude:longitude GPX-file *** Looking for 20 points near: 54.429591:18.477973 (lat/lon) *** > 15.3758195746663 2013-04-20T10:27:09Z 54.429509640:18.477780819 > 22.0617273294607 2013-04-20T09:05:15Z 54.429701502:18.478256240 > 32.6458959467509 2013-04-20T10:27:15Z 54.429787332:18.478348190 > 43.3771684316959 2013-04-20T09:05:24Z 54.429531014:18.477310427 > 47.7727043140018 2013-04-20T09:05:11Z 54.429905936:18.478475260 > 63.903936892351 2013-04-20T10:27:00Z 54.429627573:18.476987137 > 70.171200323179 2013-04-20T09:05:28Z 54.429655485:18.476893930
One can stipulate from the above output that I passed a point 15,4 meters away
from 54.429591/18.477973 at 10:27:09 GMT as well as I passed onother point which is 22 meters away from 54.429591/18.477973
at 09:05:15. As I cycled back and forth along the same route the second point is valid, the first
is accidentally closer but as the
time is almost one and half hours later it is clear that I was there on returning home.
So gpsbabel should be executed as follows (20130420.gpx
contains GPX track):
gpsbabel -i gpx -f 20130420.gpx -o subrip,video_time=000034,gps_time=090515,gps_date=20130420 -F 20130420_1.srt
Speed is added with another very simple Perl script:
perl add_speed_2_srt.pl 20130420_1.srt > 20130420_1_S.srt
Just to remind: internally all GPS units record time/date using Coordinated Universal Time aka Greenwich Mean Time vel Zulu time (for army enthusiasts). What the unit displays is another matter (usually it displays local time).
Some time ago I bought a Contour HD camera on Ebay and the seller claimed he was selling it as he want to upgrade to GPS enabled model. That inspired me to investigate how I can do the same with the camera lacking build-in GPS receiver. For example to geotag photos one can use GPS enabled still cameras, but usually it is a costly luxury and it suffice to synchronize GPS log with a photo timestamp. Using this approach I have developed a simple bash scripts which works neatly with all my cameras. So I can geotag my photographs without wasting a lot of time.
In case of video images the approach is similar: one has to synchronize video and GPS data. The best approach is to film the display of the GPS unit showing the GPS time. In case when the camera is unable to get a good quality image (because the digits are too small for example as in case of my Garmin Legend) a simple trick can be used: just one has to write down time on a sheet of paper (using 15-30 seconds time-ahead) and in a appropriate moment film it. Or one can says out loudly the time displayed if the microphone is able to record it. Looks silly and old fashioned but works. Instead of the above two methods one have to establish initial video geolocation with `visual correlation' method (described in the next paragraph).
The camera Pause button should not be used as it breaks out the GPS-camera synchronization. Namely after every pause one has to establish correct initial geolocation which can be difficult but not impossible (`visual correlation' can be used ie. inspecting video for distinguishable objects which geo-position can be established). I think the advantage of GPS-equipped camcorder boils down to that aspect (one can use Pause w/o worrying that his/her video will be out of sync.) but I suspect to take this extra advantage some extra software is needed which almost for sure runs on MS Windows. For a Linux users it can be usless or at least troublesome.
The only method I tried to augment video files with GPS data is to convert them to video subtitles. Since version 1.4 of GPSBabel is able to create a subtitle file from a GPS tracklog. The subtitle contains latitude/longitude/altitude as well as the time and current speed.
To convert GPX file to subtitles one have to execute:
gpsbabel -i gpx -f FILE.gpx -o subrip,video_time=hhmmss,gps_time=hhmmss,gps_date=YYYYMMDD -F FILE.srt
Where: video_time
--
video position (relative to beginning of video) for which exact corresponding GPS timestamp
is known. gps_time
-- the time part
of the GPS timestamp which corresponds to a known position in the video.
gps_date
-- the date part of
the GPS timestamp which corresponds to a known position in the video.
Let's assume that the recorded image of GPS display appears in 15 second of the captured image.
One has to look for (inside GPX file) the timestamp containing
the exact time displayed (element <time> inside element <trkpt>).
Let's assume
this timestamp is <time>2013-02-07T09:58:29Z</time>
.
To convert GPX to subtitles one has to run:
gpsbabel -i gpx -f FILE.gpx -o subrip,video_time=000015,gps_time=095829,gps_date=20130207 -F FILE.srt
Just to remind: internally all GPS units record time/date using Coordinated Universal Time aka Greenwich Mean Time vel Zulu time (for army enthusiasts). What the unit displays is another matter (usually it displays local time).
My first geotagged video obtained using method described above can be seen here.
Added 21 April 2013: This post is (partially) obsolete as I prefer `visual correlation' method now (see my newer post.)
The nuisance of GoogleMaps is that it does not know GPX and only KML/GeoRSS files can be uploaded. Fortunately it is easy to convert GPX to KML with gpsbabel:
gpsbabel -i gpx -f file.gpx -x simplify,count=333 -o kml -F file.kml
If there are several files they have to be convert one-by-one and then upload to Google. It would be more comfortable to merge them first and upload it in one go rather than uploading each individually.
As I could not find how to merge serveral GPX files into one using gpsbabel (merge option in gpsbabel puts all track points from all tracks into a single track and sorts them by time stamp. Points with identical time stamps will be dropped) I worked out the following simple Perl script:
#!/usr/bin/perl # # Combine GPX files into one # usage: gpxmerge file1 file2 file3 .... # use XML::DOM; binmode(STDOUT, ":utf8"); my $parser = new XML::DOM::Parser; for my $file2parse (@ARGV) { my $doc = $parser->parsefile ($file2parse); for my $w ( $doc->getElementsByTagName ("wpt") ) { $waypoints .= $w->toString() . "\n"; } for my $r ( $doc->getElementsByTagName ("rte") ) { $routes .= $r->toString() . "\n"; } for my $t ( $doc->getElementsByTagName ("trk") ) { $tracks .= $t->toString() . "\n"; } } print "<?xml version='1.0' encoding='UTF-8' ?> <gpx version='1.1' creator='GPXmerger' xmlns='http://www.topografix.com/GPX/1/1' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd'>\n <author>tomasz przechlewski </author> <email>tprzechlewski[at]acm.org</email> <url>http://pinkaccordions.homelinux.org/Geo/gpx/</url>"; print "$waypoints\n$routes\n$tracks\n"; print "</gpx>\n";
The resulting file structure is as follows: first all waypoints, then all routes and finally all tracks. This is perfectly legal GPX file.
Now I convert GPX to KML using gpsbabel:
gpsbabel -i gpx -f file.gpx -x simplify,count=333 -o kml -F file.kml
Since gpsbabel generates pretty verbose KML files I simplify them using XSLT stylesheet (perhaps this step is superfluous):
xsltproc -o simplified.kml kml2kml.xsl file.kml
and the stylesheet looks like:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:kml="http://www.opengis.net/kml/2.2" > <xsl:output method="xml" indent='yes' /> <xsl:template match="/"> <!-- ;; http://www.jonmiles.co.uk/2007/07/using-xpaths-text-function/ ;; --> <kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2"> <Document> <Folder> <name>Waypoints</name> <xsl:for-each select="//kml:Folder[kml:name/text()='Waypoints']/kml:Placemark//kml:Point"> <Placemark> <!-- <name><xsl:value-of select='../kml:name'/></name> --><!-- niepotrzebne --> <Point> <coordinates> <xsl:value-of select="kml:coordinates"/> </coordinates> </Point> </Placemark> </xsl:for-each> </Folder> <Folder> <name>Tracks</name> <xsl:for-each select="//kml:Placemark//kml:LineString"> <Placemark> <name>Path</name> <LineString> <tessellate>1</tessellate> <coordinates> <xsl:value-of select="kml:coordinates"/> </coordinates> </LineString> </Placemark> </xsl:for-each> </Folder> </Document> </kml> </xsl:template> </xsl:stylesheet>
Now KML file is ready to be imported to Google maps via Maps → My Places → Create map.
The result of example conversion can be be found here.
Having fixed Garmin-babel communication some time ago I have encountered similar problem with another GPSdevice, namely MTK's BT747 logger. This time fixing the problem was simple.
I added the
following to the /etc/udev/rules.d/51-garmin.rules
:
SYSFS{idVendor}=="10c4", SYSFS{idProduct}=="ea60", MODE="0666"
Vendor ID and product ID can
be figured out inspecting dmesg
log:
# connect the device first dmesg | less
So my /etc/udev/rules.d/51-garmin.rules
file
looks like in the following listing:
SYSFS{idVendor}=="091e", SYSFS{idProduct}=="0003", MODE="0666" SYSFS{idVendor}=="10c4", SYSFS{idProduct}=="ea60", MODE="0666"
One
has to remember to stop/remove gps demon (gpsd
).
Gpsbabel
does not work at all in brand new fedora 15.
I have followed
suggestions from
https://bugzilla.redhat.com/show_bug.cgi?id=713483
and rebuild it from the source .rpm
. I have also
fixed udev
rules, as described
here:
## /etc/udev/rules.d/51-garmin.rules SYSFS{idVendor}=="091e", SYSFS{idProduct}=="0003", MODE="0666"
Now (sometimes) I was able to fetch GPX trace but only as a root.
Inspecting /var/log/messages
I noticed suspicious
messages from
gpsd daemon, ie:
Aug 14 16:50:09 darkstar gpsd.hotplug: gpsd_control(action=add,arg=/dev/ttyUSB0)
Moreover the deamon starts/stops in some tricky way as it is down
if one looks in Programs →Administration→Services, but
ps uax | grep gpsd
indicates something contrary:
nobody 2530 0.0 0.0 12652 1412 ? S<s 13:31 0:00 gpsd -n -F /var/run/gpsd.sock
As gpsbabel
works flawlessly
in my fc11 w/o gpsd I have decided to remove it:
yum erase gpsd ## removes also following dependencies: kdeutils-libs-4.6.5-2.fc15.i686 kdeutils-4.6.5-2.fc15.i686 kde-settings-kdm-4.6-10.fc15.noarch kdm-4.6.5-2.fc15.i686 digikam-1.9.0-2.fc15.i686 digikam-libs-1.9.0-2.fc15.i686 kdeedu-marble-4.6.5-1.fc15.i686 kdeedu-marble-libs-4.6.5-1.fc15.i686 kdeplasma-addons-4.6.5-1.fc15.i686 kdeplasma-addons-libs-4.6.5-1.fc15.i686 ktorrent-4.1.1-1.fc15.i686 ktorrent-libs-4.1.1-1.fc15.i686 kpackagekit-0.6.3.3-2.fc15.i686 kde-plasma-networkmanagement-vpnc-0.9-0.53.20110616git.nm09.fc15.i686 kde-plasma-networkmanagement-openvpn-0.9-0.53.20110616git.nm09.fc15.i686 plasma-scriptengine-python-4.6.5-2.fc15.i686 kdenetwork-4.6.5-1.fc15.i686 kdenetwork-libs-4.6.5-1.fc15.i686 kde-plasma-networkmanagement-pptp-0.9-0.53.20110616git.nm09.fc15.i686 kde-plasma-networkmanagement-0.9-0.53.20110616git.nm09.fc15.i686 kde-plasma-networkmanagement-libs-0.9-0.53.20110616git.nm09.fc15.i686 kdebase-workspace-4.6.5-2.fc15.i686 kdebase-workspace-libs-4.6.5-2.fc15.i686 gpsd-2.95-6.fc15.i686 ## and disables the following udev rules: ostrzeżenie: /etc/udev/rules.d/99-gpsd.rules zapisano jako /etc/udev/rules.d/99-gpsd.rules.rpmsave
Pretty surprising that so many KDE packages depends on gpsd!
Now I have access to gpsbabel
as normal user.
(It needs 10--20 second to plug
the device in fc15 while in fc11 it was instantaneously.)
Moreover my Gnome3 desktop once unusable looks much better (I still intend to use Xfce however). It seems KDE in FC15 interfere in a nasty way...
Added 24 august 2011:
Xine error while playing .avi
file resolved.
$ rpm -qa '*ffmpeg*' ffmpeg-devel-0.7-0.3.20110612git.fc15.i686 ffmpeg-libs-0.7-0.3.20110612git.fc15.i686 $ rpm remove ffmpeg-devel $ yum downgrade ffmpeg-libs Removed: ffmpeg-libs.i686 0:0.7-0.3.20110612git.fc15 Installed: ffmpeg-libs.i686 0:0.6.90-0.2.rc0.fc15
xine
now works with .avi
. Btw:
$ rpm -qa '*git*' emacs-git-el-1.7.6-1.fc15.noarch emacs-git-1.7.6-1.fc15.noarch git-1.7.6-1.fc15.i686
It appears ffmpeg-libs-0.7-0.3.20110612git
and ffmpeg-devel-0.7-0.3.20110612git
were the only compiled from git
shapshots
packages installed in my system
(providing gip snapshots are always marked
by adding git
to package name).
It is convenient to add exclude=ffmpeg-libs
to /etc/yum.conf
to prevent
yum
to update
ffmpeg
libs with yum update
command.
Added 31 august 2011:
According to man xine
one can specify
``additional command line arguments'' using ~/.xine/xinerc
where
each line specifies an additional command line argument. However
--geometry 990x650
does not work, as well as
-G 990x650
.
By trial and error I have figure out the only(?) working
syntax:
##vi ~/.xine/xinerc -G990x650
Note no space after -G
.
No maps or advanced features are supported but thanks to 1 inch display screen it can shows direction (electronic compass) and distance to up to 5 different targets. Targets (POIs) can be marked, manually entered or uploaded with appropriate software. (IMHO manual entry of POI requires at least Kristian Zimerman's fingers---for mere human it is simply impossible to remember and perform all key clicks in appropriate sequence...)
The producer recommends
ntrip
Travel Management Shareware.
Two main features of ntrip
are:
-- importing logged GPS data,
-- setting up to 5 locations by clicking them on the Google map.
Ntrip
is Windows only (perhaps it works with wine---I didn't try)
shareware and the license fee is 20 USD.
Brand new minihomer has logging capability disabled. On first
connection to ntrip
it is enabled.
One can stop/start logging manually with mark key.
As I do not use MSW (MS Windows) and don't like shareware applications
I have been searching for some free replacement for ntrip
starting
with an obvious one, namely gpsbabel.
Latest version of Gpsbabel (1.4.2) supports skytraq venus based loggers (Venus 5 and 6; for 130 PLN at allegro.pl) but the support for minihomer is limited to dowloading the GPS tracks only:
gpsbabel -i skytraq -f /dev/ttyUSB0 -o gpx -F out.gpx ## if the above do not works thy add baud=0 ; erase clears all device's memory gpsbabel -i skytraq,erase,baud=0 -f /dev/ttyUSB0 -o gpx -F out.gpx
Alternatively one can use skytraq-datalogger:
## get information about software version and configuration skytraq-datalogger --info --device /dev/ttyS0 ## change configuration of the data logger (do not works with miniHomer): skytraq-datalogger --enable-log --set-config ## dumping memory in GPX (works): skytraq-datalogger --dump > out.gpx
Finally a guy called Josef Reisinger adds Minihomer support to gpsbabel but it has not been integrated (yet?) to official distribution. However the `hacked' gpsbabel can be dowloaded from www.ohloh.net:
cvs -d :pserver:anonymous:@gpsbabel.cvs.sourceforge.net:/cvsroot/gpsbabel co gpsbabel cd gpsbabel ./configure make ## change gpsbabel to something else: mv gpsbabel gpsbabel_minihomer
To set location for ``Home'' icon one can issue a command similar to the following example:
## =55.44:18.55:45 is latitute:longitude:altitude ; altitude is optional ## -o gpx -F out.haha is suprefluous, perhaps -F - will suffice: gpsbabel_minihomer -i minihomer,Home=55.44:18.55:45 -f /dev/ttyUSB0 -o gpx -F out.haha
Other icons include ``Car'', ``Boat'', ``Heart'' and ``Bar''. The track can be dowloaded
as with ordinary version of gpsbabel of course.
It seems to be impossible to configure the
device however (disabling/enabling logging, setting logging period etc...) so enabling logging
can be done---as far as I know---with ntrip
only.
Dopisane 24 marca 2011: Się okazało, że połączenie gpsbabel/minihomer jest straszliwie zależne od użytego kabla USB. Kto by pomyślał. Mi działa z kablem oznaczonym jako Belkin Pro Series USB 2.0 [...] E237114 CSA 219561 Z innymi nie działa... Trudno powiedzieć czy to jest oryginalny dołączony do urządzenia, bo różnych kabelków USB mam już z kilkanaście...
Dopisane 28 marca 2011: Ponieważ ciągle nie działa poprawnie wykonałem następujące testy:
## działa: gpsbabel -i skytraq,baud=0 -f /dev/ttyUSB0 -o gpx -F 20110326.gpx ## nie działa: gpsbabel -i skytraq,erase,baud=0 -f /dev/ttyUSB0 -o gpx -F 20110326-e.gpx skytraq: Can't find skytraq device on '/dev/ttyUSB0' ## jeszcze raz polecenie nr1 teraz też nie działa: gpsbabel -i skytraq,baud=0 -f /dev/ttyUSB0 -o gpx -F 20110326p.gpx skytraq: Can't find skytraq device on '/dev/ttyUSB0' ## wyjęcie USB/wsadzenie, powtórka, działa: gpsbabel -i skytraq,baud=0 -f /dev/ttyUSB0 -o gpx -F 20110326p.gpx ## i jeszcze raz, działa: gpsbabel -i skytraq,baud=0 -f /dev/ttyUSB0 -o gpx -F 20110326pp.gpx ## teraz próba zmodyfikowanym babelem: miniHomer_gpsbabel -i minihomer,baud=0 -f /dev/ttyUSB0 -o gpx -F 20110324m.gpx skytraq: Can't find skytraq device on '/dev/ttyUSB0' ## wyjęcie USB/wsadzenie: miniHomer_gpsbabel -i minihomer,baud=0 -f /dev/ttyUSB0 -o gpx -F 20110324m.gpx Naruszenie ochrony pamięci ## ## działa natomiast: miniHomer_gpsbabel -i minihomer,Bar=55.44:18.55:45 -f /dev/ttyUSB0 -o gpx -F -
Reasumując ślad można zgrywać ,,klasycznym'' babelem. Zmodyfikowany ma coś
spieprzone, ale działa w trybie ustawiania POI, czego nie potrafi ,,klasyczny'' z kolei.
Żaden nie obsługuje polecenia erase
.
To nie jest wszakże aż tak wielki problem bo pamięć po zapełnieniu jest nadpisywana (chyba:-).
Poza tym w komputerze kol. B. nie działało w ogóle.
Pomogło wpisanie w google frazy:
gpsbabel+hangs
.
Należy wykonać przed uruchomieniem
gpsbabela [ale po podłączeniu urządzenia] następujące tajemnicze polecenie:
stty -F /dev/ttyUSB0 clocal
co jest opisane tutaj albo tutaj. Z opisu zaś wynika, że błąd dotyczy nowych wersji Ubuntu lub nawet kernela per se (nie chciało mi się czytać, bo ja mam ciągle Fedorę acht i jest OK!).
Poprawne działanie mojego skryptu My-get-GPX.sh
, który
służy do pobierania danych w formacie GPX z urządzeń GPS wymaga
w systemie Fedora 11 ręcznego zainstalowania pakietu perla
Geo::Distance
oraz
dopasowanie systemu według zaleceń
z wiki.openstreetmap.org.
Mianowicie w pliku /etc/modprobe.d/blacklist.conf
umieszczamy
[Nb. z mojego
opisu instalacji MapSource
pod wine, wynika że może się to gryźć z MapSource. Na razie się nie
gryzie bo ww. MS mam na komputerze ze starszą wersją Fedory....]:
blacklist garmin_gps
oraz zmieniamy uprawnienia do urządzenia (bez tego ściągać dane
może tylko root
), dodając do katalogu
/etc/udev/rules.d/
plik 51-garmin.rules
zawierający:
SYSFS{idVendor}=="091e", SYSFS{idProduct}=="0003", MODE="0666"
Teraz należy nowe reguły załadować:
sudo udevadm control --reload-rules
Uwaga: gpsbabel widzi urządzenie jako usb:0
a nie jak poprzednio,
w starszej wersji Fedory /dev/ttyUSB0
. W nowej fedorze
przestał też działać -- zapewne z uwagi na havoc
z urządzeniami -- bt747.
Szukając zamiennika doczytałem, że gpsbabel
też potrafi
ściągnąć dane z i-Blue 747:
gpsbabel -t -w -i mtk,erase -f /dev/ttyUSB0 -o gpx -F out.gpx
Opcja erase
powoduje wyczyszczenie zawartości pamięci...
Oprócz pliku .gpx
dane są ściągane w formacie binarnym i zapisywane
do pliku data.bin
. Gpsbabel
nie umie m.in. manipulować ustawieniami loggera, ale nie jest to dla mnie aż tak wielka strata,
bo nigdy nic nie ustawiałem...
Ciekawostką jest, że dla i-Blue 747
działa /dev/ttyUSB0
a w przypadku Legenda wspomniane usb:0
.
Trochę to dziwne, albo znowu czegoś nie doczytałem...
Anyway, skrypt
My-get-GPX.sh
obsługuje teraz zarówno Garmin Legend
jak i Blue 747. Dodałem też opcję -publish
,
działającą w ten sposób, że po pobraniu pliku GPX jest wycinany ślad ,,z dziś''
(tj. od 6.00 do 23.00 dla bieżącej daty),
który to ślad jest następnie wysyłany
w odpowiednie miejsce na serwerze (np. tutaj).
Reasumując: po przyjechaniu z wycieczki rowerowej wystarczy
wsadzić kabel USB, włączyć urządzenie i wpisać:
My-get-GPX.sh
A reszta zrobi się sama...
W tym roku w tzw. długi weekend pojechaliśmy na wycieczkę (samochodem) na Litwę, a konkretnie w zamiarze zwiedzania Wilna i Troków.
Ślady GPX z wycieczki są tutaj: 20100430 | 20100501 | 20100502 | 20100503. Więcej zdjęć jest na flickr.com. Ślady w formacie KML są tutaj: 20100430 | 20100501 | 20100502 | 20100503.
W opisie tzw. waypointa (punkt nawigacyjny),
w formacie GPX jest m.in. znacznik <sym>
, którego
zawartością jest napis określający symbol punktu. Do tej pory zawsze wstawiałem tam Flag,
a Legend oznaczał taki punkt ikoną niebieskiej flagi.
Wprawdzie teoretycznie to (chyba) może być dowolny napis, ale lepiej ograniczyć się do
tych kilkanastu--kilkudziesięciu, które Garmin zna i ,,reaguje'' na nie
podstawiając odpowiednią ikonę.
Zestaw tychże znalazłem
tutaj. Na stronach
Garmina zaś trudno się doszukać stosownej informacji.
Przykładowo pierwszy z punktów (poniżej) to cmentarz a drugi Miejsce Polowania wybrany na oznaczanie ,,grzybowych miejscówek'' -- ponieważ w zestawie symboli nie ma takiego, który by się lepiej nadawał na oznaczenie miejsca ,,gdzie rosną grzyby''
<wpt lat="54.0704694444" lon="18.9803833333"> <name>Stogi k/M Cment</name> <cmt>Stogi k/M Cment</cmt> <desc>Stogi k/Malborka Cmentarz Mennonitów</desc> <sym>Cemetery</sym> </wpt> <wpt lat='54.84425261' lon='18.000581109'> <name>Boczniak1</name> <cmt>Boczniak Ostrygowaty</cmt> <desc>Boczniak Ostrygowaty na pniu buka</desc> <sym>Hunting Area</sym> </wpt>
Jak już opisałem kiedyś
bazę moich punktów trzymam w pliku (konkretnie w ~/.gps/local.wpts
) co ułatwia jej modyfikowanie.
Jeżeli baza się zmieni, to przesyłam plik (synchronizuję) do urządzenia wykorzystując
program gpsbabel
.
Mniej znana atrakcja Gdańska położona w dolinie Radości. Dojście wygląda następująco: Kierujemy się na hotel Oliwski Dwór. Jak już do tego hotelu dojdziemy to należy iść w górę, wzdłuż doliny ścieżką na skraju lasu (mając ogródki działkowe po lewej ręce). Mijamy małe jeziorko i wychodzimy na łąkę. Teraz trzeba zachować czujność i skręcić w prawo do lasu (miejsce skrętu ma współrzędne (54.399598/18.529976, cf. górne zdjęcie zamieszczone obok). Idziemy według znaków czarnego szlaku. Po przejściu 20--30 metrów droga się rozwidla. Idziemy w lewo (wzdłuż szlaku, tyle że niekoniecznie jest to oczywiste, bo znaczek może być słabo widoczny). Po 100--200 metrach będzie widać skocznię na lewym zboczu doliny (a raczej to co ze skoczni zostało). Dokładnie naprzeciwko skoczni znajduje się kamień--płyta pamiątkowa.
Płyty z dołu nie widać. Trzeba wejść na prawe zbocze--dokładnie naprzeciw zeskoku skoczni (współrzędne 54.40047/18.52563). Informacje nt. płyty są także tutaj oraz tutaj.
Przy okazji jak załadować plik GPX do Garmina (za wiki.gpsbabel.org):
gpsbabel -w -i gpx -f ~/.gps/local.wpts -o garmin -F /dev/ttyUSB0
Nota bene stojąc na rozbiegu skoczni płytę widać doskonale.... Dziwny pomysł na zmotywowanie zawodników:-)
Dopisane 6 maja 2009: Informacja z Panoramy Gdańskiej zamieszczona na youtube.com
Wziąłem aparat na dzisiejsze jeżdżenie rowerowe i popstrykałem trochę zdjęć w czasie jazdy. Rowerzyści są na nich od strony rewersu widoczni w większości (por. rysunek obok), ale to tylko podnosi autentyczność--tak to wygląda w środku peletonu:-)
No i GPS złośliwie się wyłączył w okolicach Kielna czyli
tak w 2/3 trasy. Akurat zdjęcia, na których kol. Rysiu mnie sfotografował
nie mogą być geokodowane (aka geotagowane), bo ślad się urwał. Pech...
Ale, ale...
Już kiedyś tą trasą jechałem i ślad mam tyle, że nie do końca tą, pewnie
z trochę inną prędokością dziś dziś ale lepsze to niż nic.
Tyle, że stempel czasu dla każdego punktu na śladzie jest zły.
Pomyślałem, że można by oszukać
gpsphoto
,,uzupełniając'' dzisiejszy ślad kawałkiem starego. Okazało się to całkiem
proste dzięki gpsbabel:
gpsbabel -t -i gpx -f plik-we.gpx -x track,move=spec-czasu -o gpx -F plik-wy.gpx
Gdzie spec-czasu ma postać znak99d99h99m99s (99 oznacza stosowną liczbę, a poszczególne składniki są opcjonalne.) Przykładowo +2h przesunie czas o dwie godziny do przodu. Podobnie +32d0h1m42s przesunie o 13 dni, minutę i 42 sekundy ,,do przodu''.
Teraz w Google maps ustaliłem gdzie się kończy dzisiejszy ślad a następnie znalazłem
punkt na śladzie z 23 sierpnia z grubsza odpowiadający tej pozycji. Zrobiłem to zupełnie
na piechotę metodą ,,kilku przybliżeń'' (tj. wstawiałem do pliku GPX element wpt
odpowiadający punktowi ze śladu,
który był ,,w okolicy'' szukanego miejsca.
Oczywiście
pierwszy strzał był niezbyt celny, ale po kilku podstawieniach znalazłem szukany punkt).
Od tego punktu wyciąłem
do końca (bo akurat do końca trasy się pokrywały)
i zapisałem jako plik tmp.gpx
.
Teraz ustaliłem różnicę czasu między obu punktami. Do tego ostatniego zadania użyłem Perla:
#!/usr/bin/perl # Uruchom np.: delta_days.pl -w 2008:8:24:10:2:9 -p 2008:9:6:10:3:51 use Date::Calc qw/Delta_DHMS/; use Getopt::Long; GetOptions("w=s" => \$wszesniej, "p=s" => \$pozniej); @wczesniej = ex ($wszesniej); @pozniej = ex ($pozniej); my ($d, $h, $m, $s) = Delta_DHMS(@wczesniej, @pozniej); print "Różnica: d: $d, h: $h, m: $m, s: $s\n"; sub ex { my $w = shift ; return ( split /[:;-]/, $w ) }
Różnica wyniosła 13 dni, minutę i 42 sekundy. Teraz uruchomiłem gpsbabela:
gpsbabel -t -i gpx -f tmp.gpx -x track,move=+13d0h1m42s -o gpx -F tmp-out.gpx
Śladem z plik tmp-out.gpx
uzupełniłem dzisiejszy, niekompletny ślad.
Skrypt gpsphoto
(uruchomiony via My-photo-sync.sh
) zsynchronizował
wszystkie fotki. Oczywiście jest błąd (np. wynikający z tego, że wtedy i dziś
poruszałem się z różną prędkością), ale imho jest to błąd akceptowalny...
Całość jest tutaj. No i niech ktoś się teraz nie upiera, że Windowsem i Excelem to on wszystko obliczy....:-)
Jak już jestem przy tematyce rowerowej, to szukając butów SPD dla młodego usiłowałem obejrzeć stronę WWW jednego z większych trójmiejskich sklepów. Nie udało się... nur für Windows. I to tak dramatycznie: nic nie widać, w nic nie można kliknąć...
W tzw. długi weekend pojechaliśmy na wycieczkę (samochodem) do północnych Niemiec: Kilonia, Lubeka, wyspa Rugia. Pod Kilonią w miejscowości Laboe jest Das Technische Museum, pod którą to nazwą kryje się U-Boot udostępniony do zwiedzania. Jest to okręt typu VIIC o numerze 995, czyli trzeba wpisać U-995 do Google jakby ktoś chciał poszukać w Internecie więcej informacji na ten temat. Obok jest coś w rodzaju mauzoleum (Marine-Ehrenmal) i wieża. Nic ciekawego--jakaś ekspozycja nt. Bundesmarine + modele okrętów + coś tam jeszcze. Opisy wyłącznie po niemiecku... Można sobie śmiało darować. Z wieży oczywiście lepiej widać okolicę, więc jak ktoś jest ciekaw to może sobie wjechać windą.
Obok Laboe, bliżej Kilonii, w miejscowości Möltenort jest jeszcze jedno mauzoleum. Upamiętnia ono załogi okrętów podwodnych Kriegsmarine (U-boot Ehrenmal). Dla niezorientowanych: 80% U-Bootów, tj. około 840 z 1100, które weszły do służby zostało zatopionych. Wiele łodzi zostało zniszczonych w pierwszym rejsie, często pierwszy kontakt z wrogiem był dla załogi kontaktem śmiertelnym i ostatnim. Z tego co pamiętam około 40% łodzi nie zatopiło żadnego statku. Zginęło ok. 28000 spośród ok. 40000 marynarzy. Do tego cała sprawa była z góry przegrana (wojny o Atlantyk Ubootwaffe nie mogła wygrać), a poświęcenie tych ludzi z góry skazane na niepowodzenie i bezsensowne.
Zwiedzanie U-boota było w czwartek, w piątek pojechaliśmy do Lubeki i cały dzień zwiedzaliśmy stare miasto, szczególnie zwracając uwagę na kościół St Marien Kirche w którym Orgelmeisterem był Dietrich Buxtehude, (cf. Buxtehude -- zapomniany geniusz z Lubeki). BTW organów mistrza już nie ma bo się spaliły w 1942 roku w czasie nalotu RAF.
Wreszcie w sobotę jeździliśmy po Rugii. Byliśmy w Narodowym Parku Jasmund i oglądaliśmy Königsstuhl. Okazało się, że w Sassnitz stoi przycumowany jeszcze jeden okręt podwodny: HMS Otus. Dużo większy od U-995, bo to powojenna konstrukcja--nie zwiedzaliśmy. Potem zamek myśliwski Jagdschloss Granitz i powrót do domu z noclegiem u znajomych w Świnoujściu.
Zrobiłem dużo zdjęć ale wyszły tak sobie. Specjalnie na U-boota kupiłem lampę (FL-36, używaną na Allego), którą zresztą mało nie rozbiłem przez nieuwagę. Ostatecznie straciłem tam tylko jeden akumulator AA, który wtoczył się pod pokrywy podłogi i przepadł w czeluściach okrętu.
Ślad GPX z wycieczki jest tutaj. Więcej zdjęć jest na flickr.com. Ślad w formacie KML w przygotowaniu...
Dopisane 8 maja 2008:
Przebytą trasę rejestrowałem moim bt747 (aka Iblue 747); teoretycznie
logger powinien zmieścić zapis 20 godzinny ale dla pewności zgrywałem
ślad codziennie. Po przyjeździe zagregowałem całość używając
gpsbabela
:
#!/bin/bash gpsbabel -t -i gpx -f 20080501.gpx -i gpx -f 20080502.gpx \ -i gpx -f 20080503.gpx -i gpx -f 20080504.gpx \ -x track,merge,title="Trip to Laboe 30/4--4/5 2008" \ -x simplify,count=2000 -o gpx -F sopot-laboe-sopot.gpx && \ grep -v '<course>0.000000</course>\|<fix>2d</fix>\|<ele>0.000000</ele>' \ sopot-laboe-sopot.gpx > sopot-laboe-sopot_s.gpx
Teraz używając opisanych na innych stronach tego bloga skryptu
gpsPhoto.pl
dodałem współrzędne geograficzne do zdjęć.
Kilkanaście zdjęć nie zostało oznakowanych -- wszystkie
nieoznakowane były robione wewnątrz U-boota. Nic dziwnego zresztą bo
toto ma podwójny stalowy kadłub w tym wewnętrzny dość gruby. Nie
pamiętam ile konkretnie milimetrów, ale U-booty potrafiły się zanurzać
na ponad 250 metrów, szacun!
Oczywistym rozwiązaniem jest dodanie współrzędnych ze zdjęć
zrobionych w tym samym miejscu w momencie gdy GPS logger
,,widział'' niebo. Używając exiftool
jest to banalnie
proste:
#!/bin/bash exiftool -TagsFromFile plik-bez-wsp -GPSLatitude -GPSLongitude -GPSLatitudeRef -GPSLongitudeRef plik-z-wsp
Dodałem też możliwość uruchomienia ww. skryptu moim w trybie Emacsa służącym do ładowania zdjęć na flickr.com. Działa to w ten sposób, że kopiowane są współrzędne GPS z pliku podanego w wierszu minibufora do pliku, którego nazwa znajduje się w wierszu bieżącym (tj. wierszu, w którym jest kursor).
Na ,,odcinku'' ładowania zdjęć też się popsuło. Mój skrypt
przestał obracać zdjęcia zrobione w układzie portretowym. Przestała
działać metoda flickr.photos.transform.rotate
i to w dość
dziwny sposób: zwracany komunikat jest OK, ale obrazek nie jest
obracany. Do tego wykonanie
flickr.photos.transform.rotate
oddzielnym skryptem
działa. Podejrzewam braci Flickr, że coś zmienili na serwerze
i namieszali. Ostatecznie zmieniłem strategię: zdjęcia są obracane
,,fizycznie'', z użyciem jpegtran
wywołanym z ,,wnętrza''
skryptu perlowego za pomocą system()
.
Po załadowaniu zdjęć na flickr.com.
Poprawiłem plik KML używając do tego skryptów
kml-adjust-urls
/kml-skip-deadlinks
.
Googleearth wersja na linuksa nie działa `out of the box'. Bardzo wolno startuje, a na ekranie pojawia się komunikat:
do_wait: drmWaitVBlank returned -1, IRQs don't seem to be working correctly. Try running with LIBGL_THROTTLE_REFRESH and LIBL_SYNC_REFRESH unset.
Sądząc z liczby stron w Google jest to problem wielu użytkowników.
Rozwiązanie znalazłem
tutaj
(pomocne mogą być też uwagi
z tej strony).
Na wszelki wypadek zniknięcia oryginału w czeluściach
Internetu poniżej kopiuję co trzeba zrobić. Otóż do pliku
drm_nowaitVblank.c
wpisujemy:
#include <sys/time.h> #include <unistd.h> #include <string.h> #define DELAY 33333 int drmWaitVBlank(void) { static struct timeval last = { 0, 0 }; static struct timeval now = { 0, 0 }; int udiff; gettimeofday(&now, NULL); udiff = (int)now.tv_usec - (int)last.tv_usec; if (udiff < 0) udiff += 1000000; udiff -= DELAY; if (udiff < 0) usleep(-udiff); memcpy(&last, &now, sizeof(struct timeval)); return 0; }
Plik należy skompilować, uruchamiając gcc
w następujący
sposób:
gcc -o drm_nowaitVblank.so -shared -fPIC -ldl drm_nowaitVblank.c
Plik należy umieścić tam gdzie znajduje się plik
googleearth-bin
, u mnie jest to
/opt/google-earth/
.
Teraz trzeba zmienić skrypt googleearth
w wierszu zwierającym
exec "./googleearth-bin" "$@"
(jest tylko jeden wiersz
z exec
w skrypcie googleearth
) na:
LD_PRELOAD="./drm_nowaitVblank.so" exec "./googleearth-bin" $*
Googleearth wyświetla też komunikat o brakujących fontach. To akurat jest łatwe do poprawienia:
yum -y install bitstream-vera-fonts
Teraz mogę w komfortowy sposób oglądać swoje zdjęcia z samodzielnie
wygenerowanych, przy pomocy GPSbabela
plików KML (sposób
jaki w jaki to robię opisałem
wcześniej).
Tutaj są próbki a jednocześnie propozycje ciekawych do zwiedzania
miejsc w okolicach Sopotu (więcej wkrótce):
Oliwa, Dolina Radości
| Rezerwat Kacze Łęgi, Witomino
| Elekrownia Rutki, Jar Raduni
| Z Gdyni do Sopotu wzdłuż plaży
| wzdłuż Potoku Oliwskiego, potem Sopot.
Więcej jest tutaj.
GPS logger to odbiornik GPS wyposażony w pamięć pozwalającą na rejestrację przebytej drogi (śladu). Ślad z GPSa jest mi potrzebny do dodania współrzędnych geograficznych do zdjęć. Do tej pory do tego celu wykorzystywałem odbiornik Geko 301 firmy Garmin. Geko jednakże jest urządzeniem starszego typu i generalnie nie działa jeżeli nie widzi ,,czystego nieba''. Nie działa w lesie, często są duże problemy w terenie mocno zabudowanym, itp.
Postanowiłem kupić lepszy odbiornik. Czytając fora i blogi poświęcone GPS najpierw dowiedziałem się, że jest coś takiego jak SIRF. Już chciałem takiego SIRFa kupić ale doczytałem o chipsecie MTK. Według niektórych doniesień jest on lepszy niż SIRF 3 (są też tacy co twierdzą, że tak nie jest; głosów w stylu X to syf a ja jestem wielkim znafcom nie biorę pod uwagę).
Ceny loggerów na allegro zaczynają się od 300 zł (styczeń 2008) a ja znalazłem coś chwalonego, podobno działającego z Linuksem co jest dla mnie bardzo ważne i (okazało się) tańszego pn. i-Blue 747 Dziwne, ale w Polsce nikt tego nie sprzedaje, przynajmniej w Internecie. Znalazłem i-Blue na ebay za mniej niż 200 zł przy czym 30% tej kwoty stanowiły koszty wysyłki.
BTW opis na e-bay był w języku włoskim, sklep w Niemczech, sklepowy (sądząc po imieniu i nazwisku, Turek) po angielsku słabo pisał, ale się dogadaliśmy i paczka doszła.
Do obsługi loggera jest dołączony CDrom z programem. Program jest
of course na system MSW,
ale podobno działa z wine. Dokładnie postępując według instrukcji
stąd dało się go uruchomić:
należy zainstalować wine
, uruchomić winecfg
,
a następnie:
cd ~/.wine/dosdevices ln -s /dev/ttyUSB0 com1
Teraz należy skopiować
plik instalacyjny
i uruchomić wine DataLog.exe
.
Program zostanie zaistalowany tyle, że u mnie nie działa.
Ściąga ślad całkiem dziarsko
ale nie do końca bo zwisa.
Próbowałem dwa razy raz zawisł gdy wskaźnik był na 49%
drugi raz na 89%.
W google znalazłem opinie użytkowników
Ubuntu utrzymujących, że w ich systemie wszystko
działa (like a charm).
BTW w MS Windows też były problemy, zarówno z instalacją,
jak i z uruchomieniem, ale jak w końcu poszło, ale
co z tego przecież nie będę go używał w systemie W.
Uwaga: Aby ściągnąć ślad albo zmienić konfigurację urządzenia przełącznik musi być w pozycji LOG. Po uruchomieniu programu pierwsze co trzeba zrobić to zatrzymać zapis śladu (można to zrobić tylko programowo), bo inaczej logger cały czas zapisuje dane.
Zainstalowałem też w bólach bt747 (aplikacja Javy).
Zresztą autor ostrzega, że dokumentacja jest niedoskonała. Po
rozpakowaniu zipa, zainstalowałem zawartość katalogu
rxtx-2.1-7-bins-r2
,
zgodnie z tym co jest napisane
w pliku INSTALL
, umieszczonym w tym katalogu. Następnie
uruchomiłem skrypt run_rxtx.sh
, zmieniając wartość
zmiennej MYROOTPATH=/usr/local/bt747
.
Żby użytkownik
miał dostęp do /dev/ttyUSB0
musi być w grupie
uucp
, to już ustaliłem wcześniej. Dalej jednak nie
działało (check_group_uucp(): error testing lock file creation
Error details: Permission denied check_lock_status:
No permission to create lock file.).
Kluczowa okazała się zmiana praw dostępu do
/var/log
:
chmod 777 /var/lock
Aplikacja, jak widać obok, wygląda okropnie, ale funkcjonalnie jest OK: ściąga
dane i kasuje LOG. Więcej nie potrzebuję. Żeby skrypt run_rxtx.sh
działał uruchamiany z dowolnego katalogu musiałem jeszcze zmienić wartości
zmiennej CLASSPATH
(albo wstawić zawartość CLASSPATH
jako wartość opcji -cp
przy uruchamianiu javy):
CLASSPATH=${RXTXJAR}:$MYROOTPATH/webstart/Waba_only.jar:\ $MYROOTPATH/dist/BT747_rxtx.jar:.:$CLASSPATH
Wreszcie jest też aplikacja pn. MTKbabel (skrypt Perla), działająca podobnie do programu GPSbabel, czyli z wiersza poleceń. Do działania wymaga zainstalowania modułu Device::SerialPort. Ten sposób działania podoba mi się najbardziej. Pobranie danych sprowadza się do wydania następującego polecenia:
mtkbabel -f nazwa-pliku-bez-rozszerzenia -t
Powstaną dwa pliki (dlatego nie podaje się rozszerzenia): jeden w formacie binarnym, drugi w fomacie GPX. Jedno wielkie ale -- transmisja jest bardzo wolna: plik binarny o wielkości ca 650 kB (czyli ca 30% pamięci) był ściągany z loggera 9 minut 47 sekund. Czyli cała pamięć byłaby ściągana 30 min. Hmm... Dla porównania obie wcześniej wymienione aplikacje ściągały te 650 kB w circa 2 minuty. Różnica jest.
Wykonałem już dwa eksperymenty porównujące iblue z moim Garminem 301. Pierwsza trasa to las, w wielu miejscach gęsty i wysoki. Do tego też w wielu miejscach jary o stromych zboczach. Trasa zapisana przez geko oraz trasa zapisana przez iblue. Nie ma porównania, bo geko w zasadzie w lesie nie działał.
Druga trasa to teren zabudowany, a konkretnie Sopot. Zabudowa w większości 3--4 kondygnacyjna. Dwa razy wszedłem do sklepu (Geko zgubił w pierwszym ślad, ale poczekałem po wyjściu aż znajdzie, a za drugim razem sam szybko się odnalazł). Oba ślady wyglądają nieźle (cf. geko iblue). Iblue pogubił się w okolicach skrzyżowania 1-go Maja z Aleją Niepodległości, gdzie wszedłem do sklepu (na dłużej). Nie zgubił satelity, tak jak geko, ale trasa w tym miejscu jest nieprawidłowa (wielki `tik' od 1-go Maja wzdłuż Al. Niepodległości w stronę Gdańska. Na mapie od szpilki oznaczonej jako `sklep' do szpilki `tik'. W rzeczywistości od sklepu poszedłem do szpilki oznaczonej `tunel' i dalej wzdłuż ul. Bohaterów Monte Cassino, co zresztą też jest zaznaczone). Nie ma różnicy pomiędzy śladami zredukowanymi do 500 punktów i dużo większym -- 2500 punktów.
Reasumując: wszystkie zdjęcia zrobione na obu trasach zostały (z zadowalającą precyzją) oznakowane współrzędnymi geograficznymi na podstawie śladu z Iblue, a po to go kupiłem.
Ślad iblue zredukowałem za pomocą gpsbabela, bo oryginalny ślad
składa się z tysięcy punktów. Iblue zapisuje ślad co sekundę, Garmin
w trybie auto (Iblue nie ma czegoś takiego jak auto).
Kiedyś eksperymentowałem z Garminem i też go przestawiłem
na zapis sekundowy, ale nie zaobserwowałem różnicy pomiędzy takim trybem
a trybem auto. Polecenie uproszczenia śladu wygląda
następująco (Log.nma
zawiera dane zapisane jako
NMEA):
gpsbabel -i nmea -f Log.nma -x simplify,count=450 \ -o gpx -F 2008-01-23BT_x.gpx
Poniżej bardziej zaawansowane polecenie: zapisz jako GPX, ślad od 2008-01-24T13:40
od 2008-01-24T14:50, następnie upraszczając go do 500 punktów.
Uwaga: opcje
-x
nie są przemienne, tj. ich zamiana skutkowałaby najpierw
uproszczeniem do 500 punktów, a potem wycięciem od-do, dając w rezultacie
ślad dużo bardziej uproszczony:
gpsbabel -i nmea -f GPSDATA-20080123.nmea \ -x track,start=200801241340,stop=200801241450 -x simplify,count=2500 \ -o gpx -F 20080124BT_x.gpx
Kończąc, trochę mnie zastanawia/niepokoi trwałość tego urządzenia, bo jakość wykonania jest taka sobie (100% chińszczyzna). Jakby mi, np. wypadł z ręki, to chyba byłby to jego ostatni lot. Nawet nie próbuję tego sprawdzać. Poza tym logger wydaje się całkiem, całkiem...
Dopisane 16 marca 2008: Dioda GPS: pomarańczowa -- szuka satelitów; pomarańczowa/miga -- nawiguje; niebieska/miga -- mało pamięci (mniej niż 20%); niebieska -- pamięć jest zapełniona, stop (cokolwiek to znaczy); trzykrotny błysk -- zarejestrowanie POI. Dioda baterii: czerwona -- bateria prawie wyczerpana; zielona -- ładowanie; zielona/miga -- naładowana. Dioda BT: niebieska -- BT włączone, ale nie połączony; wolno miga -- połączony w sleeping mode; szybko miga -- połączony i gotowy.
Dopisane 16 marca 2008: projekt formularzy
w aplikacji bt747
jest daleki od ergonomicznego, stąd
poniżej krótka rekapitulacja.
Aby usunąć plik: Fmt/Erase (albo Fmr/Set&erase).
Pobranie pliku i zapis na dysk: Log/Get Log i inne przyciski z tej karty.
Karta File: konfiguracja. Karta Con: połączenie z urządzeniem.
Innych kart w zasadzie nie używam.
Dopisane 19 marca 2008:
Poniżej skrypt do zamiany pliku NMEA pobranego z bt747
na
plik GPX. Skrypt upraszcza uruchomienie gpsbabela. Ponadto
uruchomiony z opcją -U
wycina niepotrzebne znaczniki (np. <ele>
, czyli
wysokość, która w moim przypadku zawsze wynosi zero. Dodatkowo
liczy długość wyciętego śladu. Pełny skrypt jest
tutaj.
# !/bin/bash # # Skrypt ułatwiający uruchomienie programu gpsbabel # Wycina fragment ścieżki + upraszcza ślad do zadanej liczby punktów # Na koniec plik podaje długość wyciętego śladu. # OUT='' FORMAT=nmea ROK=`date +"%Y"` XREDUCE="NO" while test $# -gt 0; do case "$1" in -help|--help) echo "$USAGE"; exit 0;; -od) shift; START="$1";; -od*) START="`echo :$1 | sed 's/^:-od//'`";; -do) shift; STOP="$1";; -do*) STOP="`echo :$1 | sed 's/^:-do//'`";; -max) shift; COUNT="$1";; -max*) COUNT="`echo :$1 | sed 's/^:-max//'`";; -rok) shift; ROK="$1";; -rok*) ROK="`echo :$1 | sed 's/^:-rok//'`";; -format) shift; FORMAT="$1";; -format*) FORMAT="`echo :$1 | sed 's/^:-format//'`";; -U) XREDUCE="YES";; -out) shift; OUT="$1";; -out*) OUT="`echo :$1 | sed 's/^:-out//'`";; -h) echo usage; exit;; -h*) echo usage; exit;; *) FILE="$1";; esac shift done if [ "$XREDUCE" = "YES" ] ; then echo "** Tracks will be simplified! (Option -U)" ; fi EXTENSION=${FILE##*.} BASE=`basename $FILE .$EXTENSION` if [ "$OUT" = "" ] ; then OUTFILE="$BASE.gpx" ; else OUTFILE="$OUT" ; fi if [ "$START" != "" -a "$STOP" != "" ] ; then PERIOD="-x track,start=$ROK$START,stop=$ROK$STOP" ; elif [ "$START" != "" ] ; then PERIOD="-x track,start=$ROK$START" ; elif [ "$STOP" != "" ] ; then PERIOD="-x track,stop=$ROK$STOP" ; fi if [ "$COUNT" != "" ] ; then SIMPLIFY="-x simplify,count=$COUNT" ; fi if [ -f "$BASE.$EXTENSION" ] ; then gpsbabel -i $FORMAT -f $BASE.$EXTENSION $PERIOD $SIMPLIFY -o gpx -F $OUTFILE if [ -f "$OUTFILE" -a "$XREDUCE" = "YES" ] ; then extension=${OUTFILE##*.} simname="`basename $OUTFILE .$extension`_s.$extension" echo "** File $OUTFILE simplified to $simname" ; # perl -e 'while ( <> ) { unless(/<ele|fix|course|speed>/) ... to błąd !! perl -e 'while ( <> ) { unless(/<(ele|fix|course|speed)>/) { print $_ }} ' $OUTFILE > $simname OUTFILE=$simname fi else echo "File $BASE.$EXTENSION found!" ; echo "$USAGE" fi if [ -f "$OUTFILE" ] ; then ## Oblicz dystans: echo "** Counting distance covered in: $OUTFILE " perl -e 'use Geo::Distance; my $geo = new Geo::Distance; my $qchars = "\042\047"; # znaki cytowania pojedynczy i podwojny while (<>) { if (/<trkpt\s+lat\s*=\s*([$qchars])([^$qchars]+)\1\s+lon\s*=\s*([$qchars])([^$qchars]+)\3/) { $lat=$2; $lon=$4; unless ($trkpt < 1) { $dist += $geo->distance( "meter", $plon, $plat => $lon, $lat ); } $trkpt++; $plat=$lat; $plon=$lon; } } print "** Distance covered (meters): $dist\n"; ' $OUTFILE fi
W okresie świątecznym i na przełomie roku wykonałem kilka eksperymentów weryfikujących jakość dodawania współrzędnych za pomocą synchronizacji czasu odbiornika GPS i aparatu. Dokładnie siedem prób (odpowiednio data: zdjęcia ogółem/zdjęcia oznaczone): 20071226: 61/61, 20071228: 11/11, 20071229: 29/29, 20071230: 71/71, 20071230: 48/48, 20080101: 30/30, 20080102: 8/22. Łącznie zdjęć było zatem 260 z czego 16 (6,1%) nie zostało zsynchronizowanych. Większość zdjęć została oznakowana z zadowalającą albo nawet dobrą dokładnością. Niektóre trasy były łatwe: płaski teren. Ale trasa z 31.12 prowadziła w sporej części przez gęsty las a GPS się nie pogubił. Dziś poszedłem jeszcze dalej do lasu, no i GPS tym razem odmówił kooperacji. A GPSa -- zgodnie z zaleceniem, żeby był jak najwyżej -- noszę pod czapką!
Przerobiłem swoje skrypty, oraz bibliotekę dla Emacsa. Aby odróżnić zdjęcia zawierające zdefiniowane tagi EXIF ze współrzędnymi geograficznymi od tych, które tej informacji nie zawierają, generowana miniatura zdjęcia zawiera czerwony prostokąt w lewym górnym rogu (jeżeli zdjęcie jest już geotagowane). No tak to sobie wymyśliłem.
Niektóre ślady GPS na mojej stronie zawierają teraz miniatury zdjęć. Publikuję też dane w formacie KML. Uaktualniony opis jest tutaj. Detaliczna instrukcja jak używać GPSphoto. jest zaś tutaj.
Dopisane 8 maja 2008/Zmodyfikowane 27 sierpnia 2008: Podsumowanie procedury pobrania śladu z urządzenia GPS i ich zamiany na ślad w formacie GPX/KML:
Ślad z urządzenia jest pobierany albo za pomocą gpsbabela albo programu bt747.
Skrypt nmea2gpx
zamienia dane w formacie NMEA na GPS w razie potrzeby
wycinając fragment śladu i upraszczając go (opcja -max liczba-punktów
).
Skrypt akceptuje także inne formaty danych wejściowych (opcja -format
):
nmea2gpx -od czas -do czas -max liczba [-format format ] [-U ] [-out plik.gpx] plik
Skrypt My-photo-sync.sh
(wykorzystujący gpsPhoto.pl
)
,,synchronizuje'' ślad ze zdjęciami i generuje plik w formacie KML:
My-photo-sync.sh -d katalog-zdjęć -f plik.gpx -t różnica-czasów
różnica czasów jest obliczana za pomocą skryptu exif_datetime.pl
exif_datetime -b czas_z_GPSa -f zdjęcie -o GMT_offset_in_seconds
gdzie: zdjęcie, to nazwa pliku ze zdjęciem ekranu GPSa;
czas_z_GPS, to czas wyświetlany przez GPSa na ww. zdjęciu;
GMT_offset_in_seconds, różnica między czasem lokalnym a GMT (niektóry GPSy to wyświetlają,
a jak nie to łatwo jest to obliczyć).
Ponieważ uruchamianie exif_datetime
w ww. sposób dla każdej sesji zdjęciowej
jest pracochłonne można też napisać:
exif_datetime
Powyższe wyświetli przesunięcia czasowe zapisywane w pliku ~/.time_offset
. Ponieważ
czas w aparatach rozsynchronizowuje się w miarę
wolno, wystarczy co kilka tygodni aktualizować ~/.time_offset
.
Można też napisać:
My-photo-sync.sh -d katalog-zdjęć -f plik.gpx -a
Przesunięcie zostanie pobrane automatycznie z pliku ~/.time_offset
. [Nie trzeba
uruchamiać exif_datetime
.]
W wyniku wykonania My-photo-sync.sh
powstaje także plik .kml
.
Skrypt perlowy kml-adjust-urls
zamienia linki do zdjęć
w pliku KML, tak aby wskazywały na zdjęcia umieszczone w serwisie
flickr.com (skrypt My-photo-sync.sh
oryginalnie wstawia linki lokalne). Przed wykonaniem kml-adjust-urls
należy wykonać flickr_update_kb
bo kml-adjust-urls
pobiera
informacje nt. zdjęć lokalnie z bazy utworzonej przez flickr_update_kb
.
kml-adjust-urls plik.kml
Ubocznym efektem działania kml-adjust-urls
jest plik plik.wpts
zawierający elementy <wpt>
określające linki do zdjęć umieszczonych na flickr.com.
Zawartość tego pliku można dodać do pliku plik.gpx
uzskanego w kroku #2.
Ślad -- wyświetlony w googlemaps
-- będzie wtedy zawierał ,,pinezki'' z minaturami zdjęć.
Niektóre zdjęcia z lokalnego katalogu nie są umieszczone na
flickr.com. Skrypt kml-skip-deadlinks
usuwa takie
zdjęcia z pliku KML. Mało eleganckie rozwiązanie -- jeden skrypt by wystarczył, ale
nie mam czasu w tej chwili poprawiać skryptu kml-adjust-urls
:
Skrypt kml-adjust-urls
usuwa takie zdjęcia z pliku .kml
.
Wprawdzie jestem/byłem sceptyczny co do rezultatów, ale postanowiłem sprawdzić empirycznie ile warte jest dodanie współrzędnych geograficznych przy wykorzystaniu techniki zsynchronizowania czasów GPSa i aparatu. Ustawiłem czas Geko na Paryż. To co odbiornik wyświetlał z grubsza się zgadzało z czasem na zegarku. No akurat wiem, że GPS z definicji może ,,robić'' za ultra dokładny zegarek. Z aparatem było gorzej--wyświetla tylko godziny i minuty. Ustawiłem czas na tyle dokładnie na ile się dało.
Po zapisaniu śladu do pliku GPX okazało się, że czas zapisany przez Geko jest circa godzinę do tyłu w porównaniu do tego co jest wyświetlane. Wyświetla czas lokalny a zapisuje UTC? Chyba tak, bo w dokumentacji skryptu GPSphoto jest o czymś takim wspomniane. Zdjęcie z kolei jest oznaczone czasem lokalnym i taki czas jest zapisywany. No i dodatkowo jest pewna różnica wynikająca z niezbyt precyzyjnego zgrania obu urządzeń. Prosty pomysł jak je zgrać dokładnie podano w dokumentacji GPSphoto: po prostu trzeba zrobić zdjęcie Geko z wyświetlonym na ekranie czasem. Faktycznie, prościej chyba się nie da:-) Ale nie do zastosowania w urządzeniach GPS bez ekranu (por. komentarz z tego bloga.)
Żeby sobie
ułatwić skrypt
zrobiłem wykorzystujący Image::ExifTool
.
Na wejściu pobiera nazwę pliku ze zdjęciem, a wypisuje zawartość
pola DateTimeOriginal
. Jeżeli podam -- jako drugi
parametr -- czas w notacji gg:mm:ss, to skrypt wypisze
też różnicę w sekundach:
exif_datetime.pl -f dscf2451.jpg -b 15:49:20
Wyszło 44 sekundy. Dodałem 3600 sekund jako różnicę między czasem aparatu a czasem garmina, wpisując z wiersza poleceń:
perl gpsPhoto.pl --dir=jpgs --gpsfile=20071228.gpx --timeoffset=-3644 \ --kml 20071228.kml
Szczerze mówiąc za pierwszym razem nie dodałem znaku minus przed wartością 3644. W rezultacie większość zdjęć została pominięta. Ale kilka zostało oznaczonych. Uruchomiłem gpsPhoto drugi raz, tym razem poszło lepiej. Powstały plik wyświetliłem w googleearth i konsternacja: część zdjęć jest oznaczona prawidłowo, ale kilka ma współrzędne kompletnie do kitu. Do tego ślad jak zwykle jest przerwany i ma jeden gigatyczny ,,odlot'' od prawdziwego przebiegu trasy. Najbardziej zdumiewało mnie jednak to, że zdjęcia na śladzie nie były wstawione chronologicznie, tylko przemieszane. Niechybnie oznaczało to, że coś namieszałem.
Straciłem sporo czasu kombinując czemu tak się stało. Wreszcie
wróciłem do źródeł, czyli zacząłem studiować
dokumentację
gpsPhoto.pl. Dodałem opcję --overwrite-geotagged
, słusznie
mniemając, że skoro jest taka opcja, to geo-oznakowane pliki nie są
domyślnie brane pod uwagę.
Ostatecznie zatem uruchomiłem gpsPhoto
w następujący sposób:
perl gpsPhoto.pl --dir=jpgs --gpsfile=20071228.gpx --timeoffset=-3644 \ --overwrite-geotagged --kml 20071228.kml
Wynikowy plik 20071228.kml
pokazuje, że
współrzędne geograficze poszczególnych zdjęć są całkiem precyzyje. Tak się
jednak stało, że w wszystkich miejscach gdzie robiłem zdjęcia garmin
nie miał problemów z rejestrowaniem śladu.
Zobaczymy jak będzie
np. w lesie, albo w mieście, przy wysokich budowlach.
Reasumując, muszę odszczekać to co napisałem wcześniej no i być mniej sarkastyczny. Ślad z mojego pierwszego eksperymentu jest tutaj. Na razie nie ma na nim zaznaczonych zdjęć; są dostępne na flickr.com. Muszę też doczytać na temat formatu KML.
Zrezygnowałem wreszcie z używania do komunikacji z GPSem programu GPSman na rzecz GPSBabela. Ten pierwszy jest programem interaktywnym a przez to niezbyt wygodnym bo trzeba się trochę naklikać żeby przegrać zawartość pamięci Geko na PC. GPSBabel działa w trybie wsadowym, dzięki czemu można oszczędzić dużo (cennego) czasu:
#!/bin/bash TODAY=`date +"%Y%m%d"` # zapisz do pliku yyyymmdd.gpx gpsbabel -t -r -w -i garmin -f /dev/ttyS0 -o gpx -F "$TODAY.gpx"
Przyznać muszę, że podchodziłem do tego GPSBabela jak do jeża bo przy poprzednich próbach coś mi tam nie działało. A niesłusznie -- wystarczyło przeczytać dokumentację.
Najwięcej czasu straciłem zresztą na podłączeniu Garmina do komputera.
Mój Geko 301
jest podpięty do PC standardowym ,,fabrycznym'' kablem
pn. RS232 serial port connector
(part number: 010-10310-00). Port szeregowy, tj. /dev/ttyS0
w nomenklaturze Linuksa, w FC5 jest dostępny tylko dla superużytkownika.
BTW mam poczucie, że wcześniej był dostępny dla wszystkich.
Kłopot ten rozwiązałem w sposób przedstawiony
tutaj:
ls -l /dev/ttyS0 crw-rw---- 1 root uucp 4, 64 gru 18 2007 /dev/ttyS0 /usr/sbin/usermod -G uucp tomek # dodanie tomka do grupy uucp
Uwaga: program usermod
działa tak, że jeżeli
użytkownik jest obecnie członkiem grupy, której nie podano na
liście--wartości opcji -G
, to zostanie z niej usunięty.
Lepiej więc zwyczajnie uruchomić vi
i dopisać co trzeba
do /etc/groups
.
Mając już zgrany ślad (track) i punkty (waypoints)
zacząłem kombinować co dalej z tym robić. Sposób w jaki publikuję
moje ślady korzysta
z biblioteki
gpx-viewer
Kaza Okudy. Każdy punkt z pliku GPX jest przedstawiony w postaci
standardowej ,,pinezki'' znanej z google maps. Pinezka po
kliknięciu zamienia się w okienko zawierające zawartość
elementów-dzieci elementu wpt
(tj. ele
,
name
, cmt
, desc
oraz sym
)
oraz atrybuty tego elementu (lat
i lon
), np.:
<wpt lat="54.443087485" lon="18.540491704"> <ele>69.340332</ele> <name>168</name> <cmt>168</cmt> <desc>168</desc> <sym>Flag</sym> </wpt>
Gdyby ww. element zawierał element extension
, to
pokazana by była tylko zawartość extension
.
W przykładach ze strony Okudy extension
zawiera
element img
zawierający z kolei zdjęcie
zrobione w tym właśnie miejscu:
<wpt lat="49.237919" lon="-122.760106"> <ele>4.0</ele> <name>Photo 2</name> <extensions><html><![CDATA[ <a href="http://okuda.blogspot.com/2005/07/traboulay-poco-trail.html" target="_blank"> <img src="blog/2005-07/IMG_2370-01.jpg" /> </a> ]]></html></extensions>
Teraz mała dygresja: odsyłacze do zdjęć na flickr.com są tworzone według pewnego schematu.
Strona główna zdjęcia ma adres http://www.flickr.com/tprzechlewski/<photo_id>/
, gdzie
<photo_id>
oznacza identyfikator zdjęcia.
Plik ze zdjęciem ma zaś następujący URL:
http://static.flickr.com/<server>/<photo_id>_<secret>_<size>.jpg
Wartości <server>
oraz <secret>
można ustalić
np. poprzez wykonanie metody flickr.people.getPublicPhotos
.
Wartościami size
są s
(square), t
(thumbnail), m
(small), b
(large), o
(original). Oznaczają one odpowiednio pliki o wielkościach
75, 100, 200, 1024 pikseli i wielkość oryginalną. Rysunek typu
square to kwadrat, pozostałe to prostokąty o dłuższym boku
równym podanej licznie pikseli. Prostokąt o dłuższym boku równym 500 pikseli
to wielkość zdjęcia, która jest wyświetlana na stronie głównej zdjęcia.
Ta wielkość
jest wybierana jeżeli URL nie zawiera części _<size>
.
Ja chciałem żeby element img
wewnątrz extension
w pliku GPX
wskazywał na zdjęcie w rozmiarze thumbnail
na flickr.com a element a
odsyłał na stronę główną tego zdjęcia. Żeby nie wpisywać
kodu ręcznie wymyśliłem to następująco.
Za pomocą skryptu
flickr_getphotolist.pl
pobieram informacje nt. wszystkich zdjęć (publicznych, ale to ograniczenie
akurat jest OK). Skrypt zapisuje informacje w postaci następującej listy haszy:
@photos = ( {'owner' => '20425995@N00','isfriend' => '0','ispublic' => '1','secret' => '95826dcd42',\ 'farm' => '3','title' => 'dscf1209','server' => '2343','id' => '1747402167','isfamily' => '0'}, ...
do pliku ~/.flickr/hr.icio.ph
. Prosty skrypt zwraca kompletne
adresy URL po podaniu tytułu zdjęcia (działa przy założeniu, że tytuły są unikatowe):
#!/usr/bin/perl require "$ENV{HOME}/.flickr/hr.icio.ph" ; $photo_title = shift; for (@photos) { if ($photo_title eq $_->{title} ) { print "<extensions><html><![CDATA[ <a href=\"http://www.flickr.com/tprzechlewski/$_->{id}/\" target=\"_blank\"> <img src=\"http://static.flickr.com/$_->{server}/$_->{id}_$_->{secret}_t.jpg\" /> </a> ]]></html></extensions> \n"; } }
Teraz wystarczy dopisać w .emacs
funkcję, która w miejscu wywołania albo zapyta
o tytuł zdjęcia, albo pobierze go sama z wiersza gdzie jest kursor po czym wstawi to co
wypluje ww. skrypt do Emacsowego bufora. Genialne:-)
Na próbę dodałem zdjęcia do śladu
wygenerowanego 16. 12. 2007 r.
BTW patrząc na ten dziwny ślad nie mogę się powstrzymać od sarkazmu, mając w pamięci opinię niejakiej squishy z forum flickr.com: ... it's smaller than many cell phones and I think it's fabulous. I just turn it on and toss it in a backpack, then download the track log later to sync with photos... Gdzie ona mieszka? Na pustyni Gobi? Albo pracuje w Garminie... Albo to sync with photos jest plus/minus 10 kilometers. Bo mój geko 301 prawie zawsze zgubi ślad w trudnym terenie typu las, duże budynki, głębokie doliny itp...
Okazało się, że w sobotę (28 lipca) mój Garmin Geko 301 nie tylko przestawił magicznie
częstotliwość zapisu śladu, ale także cofnął się w czasie. W rezultacie kilka wpisów ,,zachodzi''
chronologicznie na siebie. Wyszło to dzisiaj, gdy usiłując wyciąć
kawałek śladu przy pomocy programu gpsbabel
uruchomionego
w następujący sposób (por.
Data Filters):
gpsbabel -t -i gpx -f plik-we.gpx -x track,start=2007081907,stop=2007081915 -o gpx -F plik-wy.gpx
otrzymałem:
trackfilter-init: Track points badly ordered (timestamp)!
Nie wiem czemu tak się stało. Mniejsza z tym. Zamiast ręcznie poprawiać błędne
wpisy można spróbować dodać opcję merge
,
która łączy wszystkie ślady w jeden usuwając
,,części wspólne'' (jeżeli ślady nie zachodzą na siebie można zamiast merge
,
użyć pack
)
gpsbabel -t -i gpx -f plik-we.gpx -x track,merge,start=2007081907,stop=2007081915 \ -o gpx -F plik-wy.gpx
Powyższe wytnie ślad utworzony od siódmej do piętnastej, 19 sierpnia 2007 r. BTW: do ściągnięcia zawartości Geko na dysk użyłem następującego skryptu:
#!/bin/bash # http://wiki.openstreetmap.org/index.php/How_to_get_data_from_a_Geko_201 filename="`date +%y%m%d-%H%M`" echo "creating $filename-waypoints.gpx" gpsbabel -i garmin -f /dev/ttyS0 -o gpx -F $filename-waypoints.gpx sleep 2 echo "creating $filename-tracklog.gpx" gpsbabel -t -i garmin -f /dev/ttyS0 -o gpx -F $filename-tracklog.gpx
Do tej pory używałem okienkowego programu gpsman
;
gpsbabel
jest wygodniejszy bo nie trzeba klikać, tyle że
gpsman
potrafi wyświetlić ślad, co czasami się może
przydać, więc nie skreślam go ostatecznie.
W sobotę (28 lipca) mój Garmin Geko 301 na chwilę się przestawił magicznie i rejestrował --przez dłuższy czas--położenie co sekundę. Powstały w rezultacie ślad (trace) miał ca 0,5Mb, znacząco więcej niż normalnie. Ponieważ stało się to po raz pierwszy byłem nieco zaskoczony, co z tym fantem począć. Wysyłanie tego do mojego repozytorium tras rowerowych nie miało sensu. Po krótkiej interakcji z Google znalazłem sposób na rozwiązanie mojego problemu na stronie wiki.openstreetmap.org:
gpsbabel -i gpx -f plik-we.gpx -x simplify,count=500 -o gpx -F plik-wy.gpx