Pod tym adresem umieściłem moje ślady GPS (głównie rowerowe) z lat 2010--2012. W formacie KML bo to jedyny -- z tego co mi się wydaje -- obsługiwany przez Google Fusion Tables (GFT).
Moja procedura skopiowania danych z urządzenia GPS (zwykle jest to Garmin Legend) do GFT jest następująca:
Skryptem obsługującym program
gpsbabel
pobieram dane z urządzenia GPS do pliku w formacie GPX.Skryptem
kml2kml.sh
zamieniam plik GPX otrzymany w pierwszym kroku na plik w formacie KML. Ponieważ plik ten jest ogromy (przykładowo z 60 kilowego pliku GPX gpsbabel wygenerował plik o wielkości ponad 500 kb) zostaje on za pomocą trywialnego arkusza XSLT zamieniony na znacznie mniejszą wersję uproszczoną:
#!/bin/bash
#
KMLSTYLE=~/share/xml/kml2kml.xsl
#
# Domyslna liczba punktow na sladzie
COUNT=99
## Domyslna nazwa Placemarka
NAME=`date +%Y%m%d_%H`;
while test $# -gt 0; do
case "$1" in
-name) shift; NAME="$1";;
-name*) NAME="`echo :$1 | sed 's/^:-name//'`";;
-max) shift; COUNT="$1";;
-max*) COUNT="`echo :$1 | sed 's/^:-max//'`";;
*) FILE="$1";;
esac
shift
done
## Usun rozszerzenie z nazwy pliku wejsciowego
OUT_FILE="${FILE%.*}"
TMP_FILE=/tmp/${OUT_FILE}.kml.tmp
echo "Converting $FILE to ${TMP_FILE}..."
if [ -f $FILE ] ; then
## Konwersja GPX->KML
gpsbabel -i gpx -f $FILE -x simplify,count=$COUNT -o kml -F $TMP_FILE
else
echo "*** ERROR *** File $FILE not found.... ***" ; exit
fi
## Konwersja do uproszczonego KMLa (KML->KML)
echo "Converting $TMP_FILE to ${OUT_FILE}.kml with maximum $COUNT points..."
echo "KML' Placemark name is: $NAME..."
xsltproc --stringparam FileName "$NAME" -o ${OUT_FILE}.kml $KMLSTYLE $TMP_FILE
echo "Done..."Zawartość arkusza XSLT zamieszczono na końcu tej notki.
-
Do interakcji z Fusion Tables wykorzystam zmodyfikowany skrypt (nazwany
ftquery.sh
) znaleziony na stronach code.google.com:
#!/bin/bash
#
# Copyright 2011 Google Inc. All Rights Reserved.
# Author: arl@google.com (Anno Langen)
# http://code.google.com/intl/pl/apis/fusiontables/docs/samples/curl.html
# -- Modified by TP --
MY_QUERY=$*
function ClientLogin() {
password='?1234567890?'
email='looseheadprop1@gmail.com'
local service=$1
curl -s -d Email=$email -d Passwd=$password -d \
service=$service https://www.google.com/accounts/ClientLogin | tr ' ' \n | grep Auth= | sed -e 's/Auth=//'
}
function FusionTableQuery() {
local sql=$1
curl -L -s -H "Authorization: GoogleLogin auth=$(ClientLogin fusiontables)" \
--data-urlencode sql="$sql" https://www.google.com/fusiontables/api/query
}
FusionTableQuery "$MY_QUERY" Teraz tworzę nową tabelę (wyklikowując co trzeba w przeglądarce)
MyTracks
o następującej strukturze:
## Korzystamy z skryptu ftquery.sh
./ftquery.sh SHOW TABLES
table id,name
2590817,MyTracks
## Tabela MyTracks ma zatem id=2590817
./ftquery.sh DESCRIBE 2590817
column id,name,type
col4,Date,string
col0,Start,string
col1,Stop,string
col2,Location,location
col3,Description,stringKolumny zawierają odpowiednio: datę (
Date
), czas pierwszego wpisu na śladzie GPX (Start
), czas ostatniego wpisu na śladzie GPX (Stop
), ślad (Location
) oraz opis (Description
).Kolumny Tabeli w Google Fusin Tables mogą być albo napisami (
STRING
), liczbami (NUMBER
), zawierać dane przestrzenne (LOCATION
) albo czas (DATETIME
). Wstępne eksperymenty z typemDATETIME
wskazują, że jest z nim jakiś problem. Primo format czasu jest dość dziwaczny (np. gpsbabelowy zapis:2012-01-07T09:19:47Z
nie jest rozpoznawany). Także późniejsze filtrowanie w oparciu o kolumnęDATETIME
też jakoś nie wychodzi, nawet jak zapisałem datę w formacieYYY.MM.DD
, który wg. dokumentacji powinien być rozpoznawany. Nie badając sprawy dogłębnie, zmieniłem po prostu typ kolumnDate
,Start
,Stop
naSTRING
.-
Cytując za dokumentacją GFT: In a column of type LOCATION, the value can be a string containing an address, city name, country name, or latitude/longitude pair. The string can also use KML code to specify a point, line, or polygon... (cf. SQL API: Reference ). Zatem żeby wstawić linię śladu wystarczy przesłać napis zawierający współrzędne opakowane w następujący sposób:
<lineString><coordinates>lng,lat[,alt] lng,lat[,alt]...<coordinates></lineString>Do tego służy następujący skrypt:
#!/bin/bash
#
STYLE=~/share/xml/gpxtimestamp.xsl
MYTRACKS_TABLE_ID="2590817"
GPX_FILE=$1
KML_FILE="${GPX_FILE%.*}".kml
## Ustal czas od--do sladu
STARTTIME=`xsltproc --param Position '"First"' $STYLE $GPX_FILE`
STOPTIME=`xsltproc --param Position '"Last"' $STYLE $GPX_FILE`
DATE=`xsltproc --param Position '"First"' --param Mode '"Date"' $STYLE $GPX_FILE`
if [ ! -f $GPX_FILE ] ; then echo "*** Error *** No GPX file: $GPX_FILE" ; exit ; fi
if [ ! -f $KML_FILE ] ; then echo "*** Error *** No KML file: $KML_FILE" ; exit ; fi
## ## Wycinamy nastepujacym skryptem z uproszczonego pliku KML:
TRACK=`perl -e 'undef $/; $t = <>; $t =~ m/(<coordinates>.*<\/coordinates>)/s; \
$t = $1; $t =~ s/[ \t\n]+/ /gm; print $t;' $KML_FILE`
TRACK="<LineString>$TRACK</LineString>"
ftquery.sh "INSERT INTO $MYTRACKS_TABLE_ID (Date, Start, Stop, Location, Description)
VALUES ('$DATE', '$STARTTIME', '$STOPTIME', '$TRACK', '') "I działa, tj. przesyła co trzeba na moje konto Google.
Google się chwali, że GFT radzi sobie z ogromnymi zbiorami danych. Mój ma -- na tem chwilem -- ponad 150 wierszy, a w każdym 99 punktów na śladzie, co daje łącznie approx 15,000 punktów do wykreślenia. Firefox/Opera coś tam wyświetla ale niewiele widać. Chrome radzi sobie najlepiej -- faktycznie da się to obejrzeć, przesuwać, powiększać... Wprawdzie nic z tych danych nie wynika, ale to już nie jest pytanie do Google.
Także filtr w połączeniu z mapą działa w Firefoksie i Operze tak sobie. Wybieram zbiór tras, np. za pomocą warunku Date < 20100901
(na tem chwilem jest to 7 wierszy) następnie klikam Visualise Map i guzik -- nic nie widać. Ale znowu w Chrome jest znacznie lepiej. Dowód w postaci zrzutu ekranu obok. Także wklejony poniżej link do mapy (pobrany przez kliknięcie w guzik Get embeddable link) daje pozytywny wynik:
Przynajmniej w mojej wersji FF (8.0).
Arkusze XSLT wykorzystane w skryptach
Zamiana pliku KML na uproszczony plik KML:
<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"/>
<xsl:param name='FileName' select="'??????'"/>
<xsl:template match="/">
<kml xmlns="http://www.opengis.net/kml/2.2"
xmlns:gx="http://www.google.com/kml/ext/2.2">
<Document>
<Placemark>
<name><xsl:value-of select="$FileName"/></name>
<MultiGeometry><LineString>
<tessellate>1</tessellate>
<coordinates>
<xsl:for-each select="//kml:Placemark//kml:LineString">
<xsl:value-of select="kml:coordinates"/>
</xsl:for-each>
</coordinates></LineString></MultiGeometry></Placemark>
</Document></kml>
</xsl:template>
</xsl:stylesheet>
Wydrukowanie daty/czasu z pliku w formacie GPX:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:gpx="http://www.topografix.com/GPX/1/0">
<xsl:output method="text"/>
<xsl:param name='Position' select="'First'"/>
<xsl:param name='Mode' select="'Time'"/>
<xsl:template match="/" >
<xsl:for-each select='//*[local-name()="trkpt"]'>
<xsl:choose>
<xsl:when test="position()=1 and $Position='First' and $Mode='Time'">
<xsl:value-of select='substring(*[local-name()="time"], 12, 8)'/>
<xsl:text> </xsl:text>
</xsl:when>
<xsl:when test="position()=1 and $Position='First' and $Mode='Date'">
<xsl:value-of select='translate(substring(*[local-name()="time"], 1, 10), "-", "")'/>
<xsl:text> </xsl:text>
</xsl:when>
<xsl:when test="position()=last() and $Position='Last'">
<xsl:value-of select='substring(*[local-name()="time"], 12, 8)'/>
<xsl:text> </xsl:text>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Brak komentarzy:
Prześlij komentarz