Dziś znalazłem pierwsze tegoroczne lejkowce. W Lasach Oliwskich wokół Sopotu.
Dopisane 4 września 2008: W lesie naokoło Sopotu jest wysyp borowików jakiego najstarsi ludzie nie pamiętają... I do tego pełno lejkowców, które mało kto zbiera.
Wymieniony w tytule Apache Velocity DocBook Framework (AVDF) to
sterowany antem zbiór narzędzi do zamiany dokumentów DocBook na
HTML/PDF. Konkretnie tymi narzędziami są Fop (w wersji 0.20.5), Saxon i szablony XSL
N. Walsha.
Po ściągnięciu archiwum .zip
lub
.tgz
ze strony projektu
i rozpakowaniu, na dysku pojawi się następująca struktura katalogów:
<korzeń instalacji AVDF> | +---- build-docbook.xml +---- project.properties +-- src +-- styles +-- docs +-- build.xml +-- project.properties +-- src +--css +--docbook | +--<projekt> +-- images +-- target +-- lib
Katalog lib
zawiera fopa i saxona plus niezbędne
dodatkowe aplikacje. Katalog src/styles
zawiera szablony
,,startowe'', uruchamiane przy zamianie plików XML na HTML i PDF. [Tu
trzeba dłubnąć żeby dokonać polonizacji.] Wreszcie dokument
,,źródłowy'' ma być obowiązkowo umieszczony w katalogu
docs/src/docbook/<projekt>
. Pliki z rysunkami zaś
muszą być umieszczone w docs/src/images
. Wynik
transformacji będzie się znajdował
w docs/target/<projekt>
. Dodatkowo
w docs/src/css
znajduje się szablon CSS wykorzystywany
przez wygenerowane pliki HTML.
Polonizacja wymaga: 1) ściągnięcia następującego archiwum
.zip
i rozpakowania
jego zawartości w tak sposób aby została dodana do oryginalnej dystrybucji AVDF
(kilka plików zostanie nadpisanych); 2) wykonania polecenia
ant -f build-docbook.xml dbf.init
z poziomu
korzenia instalacji AVDF. Tyle -- powinno działać. Reszta tego wpisu
dotyczy szczegółów: co, jak i dlaczego. Można nie czytać...
Pliki build-docbook.xml
zmieniłem tak, że
dodałem do wywołania
fopa argument -c plik.cnf
, tj.:
<java classname="org.apache.fop.apps.Fop" fork="true" maxmemory="256m" dir="${basedir}" classpathref="dbf.classpath"> <arg value="${pdf.target.file}.xml"/> <arg value="${target.dir}/${docbook.dir}/pdf/${docbook.file}.pdf"/> <arg value="-c"/> <arg value="${dbf.basedir}/conf/userconfig.xml"/> </java>
Parametr ${dbf.basedir}
to katalog główny, w którym znajduje
się cały framework. Dodany katalog conf/
zawiera
plik konfiguracyjny fopa + pliki metryczne fontów.
Same fonty (pliki .ttf
) są w katalogu fonts/
.
Dodanie do AVDC fontów powoduje, że całość jest gotowa
do użycia w każdym systemie.
[Można oczywiście tak skonfigurować AVDF żeby
używał fontów systemowych]. Z kilku zestawów
rozpowszechnianych bezpłatnie
fontów truetype
(Core fonts for the Web (Nie najwyższej jakości i do tego ich
rozpowszechnianie podlega pewnym ograniczeniom),
TeX Gyre,
Quasi,
STIX (tylko jedna odmiana -- brak kroju
bezszeryfowego i kroju typu monospace),
DejaVue)
zdecydowałem się na fonty Quasi.
Wprawdzie są one już obsolete ale działają z fopem a fonty TeX Gyre,
które są lepszą wersją Quasi -- nie bardzo.
[Są problemy nawet po konwersji OTF->TTF.]
Położenie fontów w systemie jest określone w pliku conf/userconfig.conf
. Ponieważ
ścieżka do fontu nie może być zaszyta na zicher, plik conf/userconfig.conf
rozpoczyna się od następującej deklaracji
DOCTYPE
:
<!DOCTYPE configuration SYSTEM "config.dtd" [ <!ENTITY fop.home "@dbf.basedir@"> <!ENTITY ttf.dir "@dbf.basedir@/fonts">
Napisy @dbf.basedir@
są zamieniane na to co trzeba po uruchomieniu
ant -f build-docbook.xml dbf.init
(trzeba to zrobić dokładnie raz).
Cel (target) dbf.init
wygląda zaś następująco:
<target name='dbf.init' description='Adjust some system specific files'> <copy file="${basedir}/conf/userconfig.conf" tofile='${basedir}/conf/userconfig.xml' overwrite="true" failonerror="false" filtering="on" > <filterset> <filter token="dbf.basedir" value="${basedir}"/> </filterset> </copy> </target>
Jak widać plik conf/userconfig.conf
jest kopiowany do conf/userconfig.xml
a dodatkowo napisy @dbf.basedir@
są zamieniane na bieżącą wartość ${basedir}
.
To się nazywa token substitution (cf. Using
Ant as a Text Substitution Preprocessor).
Ostatni etap polonizacji AVDF to poprawienie plików html.xsl
, htmlsingle.xsl
z katalogu src/styles
. Dodałem do plików html.xsl
oraz htmlsingle.xsl
:
<xsl:output method="html" encoding="utf-8" indent="no" saxon:character-representation="native;decimal" xmlns:saxon="http://icl.com/saxon" /> <!-- zapisuje znaki `natywnie' a nie jako encje (domyślnie) --> <xsl:param name="chunker.output.encoding" select="'utf-8'"/> <xsl:param name="saxon.character.representation" select="'native;decimal'"/>
A do pliku pdf.xsl
(z tego samego katalogu):
<!-- przełącza się na fonty Quasi, domyślnym fontem szeryfowym jest QuasiPalatinoTTF, zmień na QuasiTimesTTF jeżeli ma być Times New Roman --> <xsl:param name="sans.font.family" select="'QuasiSwissTTF'"/> <xsl:param name="title.font.family" select="'QuasiSwissTTF'"/> <xsl:param name="body.font.family" select="'QuasiPalatinoTTF'"/> <xsl:param name="monospace.font.family" select="'QuasiCourierTTF'"/>
Powyższe to minimum: polskie znaki są prawidłowo wyświetlane na ekranie oraz -- co ważne --
zapisywane w pliku jako sekwencje UTF a nie w postaci encji (tj. ó
).
Jeżeli układ graficzny dokumenty komuś nie odpowiada,
no to musi jeszcze bardziej zmodyfikować pliki .xsl
i/lub CSS (oczywiście szablony CSS dotyczą wyłącznie dokumentów HTML).
W numerach 7--8 Communications of the ACM jest wywiad z Knuthem (ściśle mówiąc: vol. 51 nos 7--8, 2008). Pierwsza część jest teraz nawet dostępna on-line. Fragment: Then a startup company came to me and said, [...] ``Name your price.'' I said ``Oh, okay, $100,000,'' assuming that this was [outrageous]. The guy didn't blink. He agreed. I didn't blink either. I said, ``I'm not going to do it. I just thought that was an impossible number.'' At that point I made the decision in my life that, I wasn't going to optimize my income.
Poniżej skrypt zamieniający font w formacie OpenType na TrueType.
#!/usr/local/bin/fontforge # Quick and dirty hack: converts a font to truetype (.ttf) # cf. http://www.stuermer.ch/blog/convert-otf-to-ttf-font-on-ubuntu.html Print("Opening "+$1); Open($1); Print("Saving "+$1:r+".ttf"); Generate($1:r+".ttf"); Quit(0);
Czy konwersja jest w 100% OK nie jest do końca pewne bo podobno gubiona jest informacja na temat par kernowych.
Etrex mimo, że nie ma barometru dość sensownie podaje wysokość npm. Jakoś do tej pory umknęło to mojej uwadze.
Poniżej skrypt wyznaczający długość trasy, łączną sumę wysokości
podjazdów (przewyższenie, aka
cumulative elevation gain)
oraz
rysujący profil w postaci pliku PNG. To ostatnie niekoniecznie jest
sensowne, bo GD::Graph::lines
traktuje dane z osi OX jako napisy
a nie liczby i w związku
z tym odstępy między poszczególnymi punktami na tej osi są równe.
Zamiast GD::Graph::lines
trzeba użyć czegoś innego,
np. Chart::Graph::Gnuplot.
#!/usr/bin/perl # # Tworzy plik PNG przedstawiający profil śladu (wysokość mnpm) # z danych podanych (jako argument skryptu) w pliku GPX # tprzechlewski[_at_]gmail.com sierpień/2008 # use XML::LibXML; use Geo::Distance; use Getopt::Long; GetOptions( 'log' => \$print_log, 'pic' => \$print_pic, ); $usage = "Usage: $0 [-p | -l] plik.gpx ;; -p generate PNG file ; -l show log.\n"; my $geo = new Geo::Distance; my $file = shift || die "$usage"; my $parser = XML::LibXML->new; open my $fh, $file || die "problems..."; $doc = $parser->parse_fh($fh); my @tracks = $doc->getElementsByTagName('trk'); my $ptnum=0; for $tx (@tracks) { @segments = $tx->getChildrenByTagName('trkseg'); if ( $name = $tx->getChildrenByTagName('name')->[0] ) { # pierwszy element to nazwa śladu if ($print_log) { print "<!-- track:: ", $name->textContent(), " -->\n"; } } for $sx (@segments) { @points = $sx->getChildrenByTagName('trkpt'); for $px (@points) { @data = $px->getChildrenByTagName('*'); @attrs = $px->attributes(); if ($print_log) { print "-> " ; } for $dx (@data) { if ($print_log) { print $dx->nodeName, " = ", $dx->textContent(), " ; " ; } if ($dx->nodeName eq 'ele') { $ele = $dx->textContent(); push @Elevations, $ele; } } for $ax (@attrs) { if ($print_log) { print " ", $ax->nodeName, " = ", $ax->getValue() ; } if ($ax->nodeName eq 'lon') { $lon = $ax->textContent() } elsif ($ax->nodeName eq 'lat') { $lat = $ax->textContent() } } if ($print_log) { print " ;;\n"; } if ( $ptnum > 0 ) { $curr_dist = $geo->distance( "meter", $plon, $plat => $lon, $lat ); $dist += $curr_dist ; push @Distances, $curr_dist; if (($ele_diff = $ele - $pele ) > 0) { $totalEleGain += $ele_diff ; } } else { push @Distances, 0; } $plon = $lon; $plat = $lat ; $pele = $ele ; $ptnum++; } } } # http://en.wikipedia.org/wiki/Cumulative_elevation_gain (przewyższenie): printf "*** Dist: %.1f meters *** EleGain: $totalEleGain ***\n", $dist; ## Drukowanie profilu trasy unless ( $print_pic ) { exit 0 } use GD::Graph::lines; use POSIX; # floor my $img_file = "${file}.png" ; my @data = (\@Distances, \@Elevations, ); my $mygraph = GD::Graph::lines->new(400, 300); # skip some dates to avoid label overlapping on X-axis: my $x_factor = floor (($#Distances + 1) / 10 ) + 2; print "$#Distances observations. X-axis labels printed evey ${x_factor}th one!\n"; $mygraph->set_text_clr('black'); $mygraph->set( x_label => 'Dist', y_label => '#', title => "# Elev", # Draw datasets in 'solid', 'dashed' and 'dotted-dashed' lines line_types => [1, 1, ], # Set the thickness of line line_width => 2, # Set colors for datasets dclrs => ['blue', 'red', 'cyan'], #x_tick_number => 'auto', x_label_skip => $x_factor, transparent => 0, ## non-transparent bgclr => 'white', fgclr => 'black', borderclrs => 'black', boxclr => '#ede7e7', labelclr => 'black', #axislabelclr, legendclr => 'black', ) or warn $mygraph->error; $mygraph->set_legend_font(GD::gdMediumBoldFont); $mygraph->set_legend('ele', 'ele2', '???'); my $myimage = $mygraph->plot(\@data) or die $mygraph->error; ## for cgi script uncomment: ##print "Content-type: image/png\n\n"; open ( IMG, ">$img_file") or die " *** Problems opening: $img_file ***" ; print IMG $myimage->png; close (IMG); ##print "@Distances\n"; ## debug ##
Wykorzystuję od jakiegoś czasu XML::LibXML
.
W skryptach do obsługi flickr.com korzystałem z XML::Simple
ale do parsowania plików GPX ten pakiet
się nie nadaje -- nie zachowuje porządku elementów (bo je czyta do hasza).
W oczywisty sposób porządek punktów na śladzie nie może być dowolny.
A tutaj ktoś zrobił coś podobnego tyle, że używając Pythona.
To była ciekawa wycieczka. Zwiedzaliśmy okolice Świdnicy oraz byliśmy na Śnieżce i w Górach Stołowych (Szczeliniec/Teplice). Wracając z Teplic zwiedziliśmy klasztor w Broumovie.
Doszło do niewielkiego bałaganu w zbiorze zdjęć przywiezionych
z tygodniowego pobytu w Świdnicy. Zdjęcia z kilku dni przegrałem do
jednego katalogu i hop, bez zbędnego myślenia uruchomiłem skrypt
gpsPhoto.pl
aby dodać współrzędne geograficzne. Po tej
operacji czas modyfikacji każdego pliku ze zdjęciem się zmienił no
i był mały kłopot z szybkim ustaleniem w którym dniu dane zdjęcie było
zrobione. Oczywiście ta informacja nie została utracona, bo jest
wartością pola DateTimeOriginal
, tyle że ,,z poziomu''
wiersza poleceń tego nie widać.
Już chciałem jakiś skrypt klecić żeby pobierał
DateTimeOriginal
a następnie zmieniał czas modyfikacji
pliku, ale w dokumentacji
exiftool
znalazłem gotowy przykład dokładnie robiący to, co chciałem osiągnąć:
exiftool "-Directory<DateTimeOriginal" -d "%Y-%m-%d" KATALOG
Powyższe przeniesie wszystkie pliki .jpeg
z katalogu KATALOG do katalogów o nazwach
postaci rok-miesiąc-dzień.
Daty modyfikacji pliku to nie zmienia, ale samo uporządkowanie
w odpowiednich katalogach w zupełności mi wystarczy.
Mój GPS Logger (używam Iblue 747) dwa razy zarejestrował ślad zawierający kolosalne odchylenie (biegun północny, tj. lat="90.000000000" lon="0.000000000"). Wcześniej nie obserwowałem tego fenomenu, tj. mówiąc dokładnie Etrex H nagminnie oszukuje podając np. średnią/maksymalną prędkość, ale zwykle zgrany ślad jest OK. Próbowałem poszukać jakiś automatycznych sposobów usunięcia takich anomalii ale nie znalazłem. Ostatecznie problem jest źle zdefiniowany więc automatem się nie da. Potrzebny jest edytor i wizualna inspekcja (np. MapSource ale to wyłącznie windziana aplikacja). Z braku takowego ślad wyświetlam na Google Maps a rażące odchylenia usuwam patrząc na współrzędne. Na moje potrzeby super korekta śladu nie jest potrzebna. Tak nawiasem mówiąc wspólnym mianownikiem Loggera i Etrexa jest chip firmy MTK. Ciekawe czy wszystkie czułe GPSy typu Sirf3/MTK robią takie błędy czy tylko MTK?
Ślady w formacie KML ze zdjęciami umieściłem tutaj: świdnica--książ | wlk.sowa--ludwikowice | szczeliniec--wambierzyce | karpacz--śnieżka | kompleks--osówka+zamek grodno | teplice--broumov | ślęża--tąpadła--sulistrowiczki
Pakiet Net::Flickr::Backup, o którym pisałem niedawno nie działa prawidłowo. Dziś ustaliłem co jest nie tak i szczegółowo opisałem w tamtym wpisie.
Jak nie zapiszę, to zapomnę. Już kiedyś znalazłem serwis pozwalający on-line na tworzenie tras (routes) w formacie GPX za pomocą klikania w GoogleMaps. Nie zapisałem i oczywiście nie mogłem go znaleźć przez dłuższą chwilę. W końcu jest: http://www.gmap-pedometer.com/. Moja przykładowa trasa: Brodnica-BachotekUMK. IMHO czasami może się okazać przydatne...