sobota, 4 czerwca 2016

Zamiana MOV na MP4

W sobotę nagrałem na rowerze ponad 1,5 godziny filmu, który jest podzielony na 3 kawałki -- każdy po 4Gb. Teraz chciałem dodać do niego nakładki z danymi typu prędkość, dystans itp używając Garmin Virb Edit, ale ponieważ Virb Edit nie przetwarza plików większych od 4Gb, to trzeba najpierw połączyć wszystko w jeden plik, jednocześnie zmniejszając rozmiar (można też synchronizować każdy kawałek osobno w VE a potem połączyć, ale ja wolę prościej):

### zamiana na 720p, z redukcją jakości do 23 (domyślnie 20)
HandBrakeCLI -w 1280 -l 720 -q 23 -i Plik.mov -o Plik.mp4 --preset="Normal"

Pliki po konwersji jak wyżej mają circa nieco ponad 1Gb każdy.

Teraz trzeba połączyć je do kupy:

MP4Box -cat plik1.mp4 -cat plik2.mp4 -cat plik3.mp4 -new ALL.mp4

Ostatni etap to dodanie nakładek w VE, niestety w tym celu trzeba się przełączyć na MS Windows. Shame...

sobota, 28 maja 2016

Wysyłanie śladów TCX na Endomondo/Strava z poprawioną wysokością

Ciąg dlaszy wpisu Rejestrowanie wysokości przez odbiorniki GPS

Ciąg dalszy bo ,,ciąg technologiczny'' FIT →TCX →GPX →srtm.py →lepszy_GPX→Endomondo/Strava pozbawia niestety przesyłany plik GPX danych, które nie są wspierane przez format GPX (takie jak tętno dla przykładu).

Problem można rozwiązać dodając do pliku TCX poprawione wysokości z pliku lepszy_GPX:

#!/usr/bin/perl
use XML::LibXML;
use XML::LibXML::XPathContext;
use Getopt::Long;

binmode(STDOUT, ":utf8");

my $Gpx_file; my $Tcx_file;

## gpx -- plik GPX z poprawionymi wysokościami
## tcx -- oryginalny plik TCX (w którym mają być poprawione wysokości)
GetOptions( "gpx=s" => \$Gpx_file, "tcx=s" => \$Tcx_file, ) ;

my $parser = XML::LibXML->new();

for my $file2parse ("$Gpx_file") {

  my $doc = $parser->parse_file($file2parse);
  my $root = $doc->documentElement();

  my $xc = XML::LibXML::XPathContext->new( $root );
  $xc->registerNs('gpx', 'http://www.topografix.com/GPX/1/0');

  foreach my $t ($xc->findnodes('//gpx:trkpt')) {

    my $xpe = XML::LibXML::XPathContext->new( $t );
    $xpe->registerNs('gpx', 'http://www.topografix.com/GPX/1/0');
    $node++;
    $gmttime = ($xpe->findnodes('gpx:time'))[0]->textContent();
    $altitude = ($xpe->findnodes('gpx:ele'))[0]->textContent();
    $GpxPoints{"$gmttime"} = $altitude;
  }
}

## for $e (keys %GpxPoints) { print "$e => $GpxPoints{$e}\n"; }

for my $file2parse ("$Tcx_file") {
  # http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2
  my $doc = $parser->parse_file($file2parse);

  my $root = $doc->documentElement();

  my $xc = XML::LibXML::XPathContext->new( $root );
  $xc->registerNs('tcx',
      'http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2');

  foreach my $t ($xc->findnodes('//tcx:Trackpoint')) {

    my $xpe = XML::LibXML::XPathContext->new( $t );
    $xpe->registerNs('tcx',
       'http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2');

    $gmttime = ($xpe->findnodes('tcx:Time'))[0]->textContent();

    foreach my $xpa ( $xpe->findnodes('tcx:AltitudeMeters') ) {
       $oldAltitude = $xpa->textContent();
       ## jeżeli istnieje w pliku GPX punkt z tym samym stemplem 
       ## czasu zmień zawartość elementu tcx:AltitudeMeters
       if (exists $GpxPoints{$gmttime} ) {
          ## replace content of tcx:AltitudeMeters
          $xpa->removeChildNodes();
          $xpa->appendText("$GpxPoints{$gmttime}");
          $changedNodesNo++;
       } else {
          ## jeżeli nie istnieje usuń cały węzeł
          my $parent = $t->parentNode;
          $parent->removeChild( $t );
          $droppedNodes .= "$gmttime;";
          $droppedNodesNo++;
       }
    }
  }

### ###
print "<?xml version='1.0' encoding='UTF-8' standalone='no' ?>\n";
print $root->toString;
### ###
}

print STDERR "Zmieniono: $changedNodesNo / Usunięto: $droppedNodesNo\n";
print STDERR "($droppedNodes)\n";

Ponieważ skrypt srtm.py nie tworzy pliku GPX zawierającego wszystkie punkty z pliku TCX (z jakiś powodów niewielka część jest pomijana); warunek exists $GpxPoints{$gmttime} sprawdza czy istnieje w pliku GPX punkt z podanym stemplem czasowym. Jeżeli istnieje zmieniana jest wysokość, jeżeli nie to punkt jest usuwany.

piątek, 13 maja 2016

Porównanie frekwencji/głosów nieważnych w wyborach 2014/15

Rozkład frekwencji i odsetka głosów nieważnych (odpowiednio pierwsza i druga kolumna) w wyborach: do Sejmu 2015, do Parlamentu Europejskiego 2014 oraz słynnych wyborach do Sejmików Wojewódzkich 2014 (trzeci wiersz)

Wydaje mi się że baza protokołów z wyborów samorządowych jest niekompletna, w szczególności protokołów z wyborów do Sejmików Wojewódzkich (SW) powinno chyba być tyle ile jest obwodów czyli 27435, a jest 26495 (96,57%). Nie wiem czemu jest mniej, ale na przykład w Szczecinie przy części komisji obwodowych faktycznie nie ma protokołów z głosowania do SW.

Dane z wyborów samorządowych 2014 (na razie dotyczące tylko frekwencji) pobrane ze strony http://wybory2014.pkw.gov.pl/pl są dostępne tutaj. W poprzednich wpisach dotyczących wyborów podano odnośniki do danych z innych głosowań.

czwartek, 12 maja 2016

Rejestrowanie wysokości przez odbiorniki GPS

Rejestrowanie wysokości przez odbiorniki GPS jak wiadomo odbywa się z błędem. Do tej pory mi to wisiało, ale problem stanął, gdy zachciało mi się dodać nachylenie do danych GPS (wyświetlanych jako napisy generowane autorskimi skryptami z pliku GPX/TCX), które to nachylenie nie zgadzało się wielokrotnie ze stanem faktycznym. Szczególnie tajemnicze były różnice na plus/minus 300% i więcej...

W trakcie prób rozwiązania tego problemu dowiedziałem się tego i owego na temat rejestracji wysokości. I o tym jest ten wpis. Natomiast problem z obliczaniem nachylenia został nierozwiązany. Wartości nachylenia pokazywane w trakcie jazdy przez urządzenia, takie jak Garmin Edge 500 są wiarygodnie, co by świadczyło, że zaimplementowano w nich jakiś całkiem sprytny algorytm wygładzający. Szukałem co na ten temat wie google, ale nic nie znalazłem. Próbowałem wygładzać wysokość/nachylenie w R za pomocą funkcji loess (a także średniej ruchomej) -- rezultaty były kiepskie.

Znalazłem natomiast informacje w jaki sposób można poprawić dokładność danych o wysokości, zarejestrowaną (niedokładnie) przez urządzenie GPS. Otóż można albo skorzystać z usługi Google Elevation (GE) albo użyć danych SRTM, przy czym minusem GE jest dzienny limit 2500 zapytań.

Zaczniejmy od prostszego przypadku, tj. dodania/zmiany wysokości z modelu SRTM. W tym celu pobieramy/instalujemy pakiet srtm.py. Pakiet zawiera m.in narzędzie pn. gpxelevations:

## Dodaje dane SRTM, zapisuje do pliku PLIK_SRTMS.gpx
gpxelevations -s -o PLIK.gpx -f PLIK_SRTMS.gpx
  
## Wygładza dane i zapisuje do pliku PLIK_SRTMS.gpx
gpxelevations -o 20160511.gpx -f PLIK_SRTMS.gpx

Dane SRTM można też dodać/zamienić posługując się okienkową aplikacją pn. GPSPrune, jak ktoś lubi klikać ale nie lubi wiersza poleceń.

Zakładając, że dane są w pliku GPX pobranym z urządzenia, poniższy skrypt wygeneruje plik CSV zawierający m.in. wysokość oryginalną, wysokość z modelu SRTM oraz wysokość wygładzoną:

#!/bin/bash

FILE=`basename $1 .gpx`

if [ -f "$FILE.gpx" ] ; then
  ## Dodanie lepszych wysokości
  gpxelevations -o $FILE.gpx -f ${FILE}_SRTM.gpx
  gpxelevations -s -o $FILE.gpx -f ${FILE}_SRTMS.gpx

  ## Zamiana na CSV (skrypt gpx2csv.pl zamieszczono dalej)
  gpx2csv.pl ${FILE}.gpx > ${FILE}.csv && \
  gpx2csv.pl ${FILE}_SRTM.gpx > ${FILE}_SRTM.csv && \
  gpx2csv.pl ${FILE}_SRTMS.gpx > ${FILE}_SRTMS.csv

  ## Scalenie w jeden plik CSV
  paste -d ';' ${FILE}.csv ${FILE}_SRTM.csv ${FILE}_SRTMS.csv | \
  awk -F';' ' BEGIN{ print "daytime;lat;long;ele;srtm;srtms"; };\
     {print $1 ";" $2 ";" $3 ";" $4 ";" $8 ";" $12}' > ${FILE}_ALLE.csv

else
  echo "*** USAGE: $0 PLIK.gpx ***"
fi

Teraz można porównać wysokość oryginalną, wysokość SRTM oraz wygładzoną na wykresie:

library(reshape)
require(ggplot2)

args = commandArgs(trailingOnly = TRUE);

if (length(args)==0) { stop("Podaj nazwę pliku CSV", call.=FALSE) }

fileBase <- gsub(".csv", "", args[1]);
outFile <- paste (fileBase, ".pdf", sep = "");

d <- read.csv(args[1], sep = ';',  header=T, na.string="NA");

ggplot(d, aes(x = as.POSIXct(daytime, format="%Y-%m-%dT%H:%M:%SZ"))) +
  geom_line(aes(y = ele, colour = 'zarejestrowana', group = 1), size=.5) +
  geom_line(aes(y = srtm, colour = 'srtm', group = 1), size=.5) +
  geom_line(aes(y = srtms, colour = "srtm (wygładzona)", group = 1), size=.5) +
  ylab(label="Wysokość [mnpm]") +
  xlab(label="czas") +
  labs(colour = paste("Plik:", fileBase )) +
  theme(legend.position="top") +
  theme(legend.text=element_text(size=12));

ggsave(file=outFile, width=12, height=5)

## Uruchomienie:
## Rscript gps_vs_srtm.R PLIK.csv

Oryginalne dane z urządzenia są systematycznie zaniżone.

Dodanie danych z Google Elevation jest równie proste. Poniższy skrypt -- jako przykład -- pobiera wysokość dla punktu o współrzędnych podanych jako argumenty wywołania (szerokość/długość):

use LWP::Simple; 
use JSON qw( decode_json );

my $geocodeapi =
 "https://maps.googleapis.com/maps/api/elevation/json?locations";

 ## szerokość = $ARGV[0] ; długość = $ARGV[1]
 my $url = $geocodeapi . "=$ARGV[0],$ARGV[1]";
 my $json = get($url);

 my $d_json = decode_json( $json );

 if ( $d_json->{status} eq 'OK' ) {
   $elevationG = $d_json->{results}->[0]->{elevation};
   $resolutionG = $d_json->{results}->[0]->{resolution};
   $latG = $d_json->{results}->[0]->{location}->{lat};
   $lngG = $d_json->{results}->[0]->{location}->{lng};
 }

 print "$elevationG\n";

Drugi z wykresów zawiera dane pobrane z Google Elevation Service.

Na zakończenie jeszcze skrypt zamieniający gpx na csv:

#!/usr/bin/perl
# Wykorzystanie gpx2csv.pl PLIK.gpx > PLIK.csv
#
use XML::DOM;
my $parser = new XML::DOM::Parser;

for my $file2parse (@ARGV) {
  my $doc = $parser->parsefile ($file2parse);
  for my $t ( $doc->getElementsByTagName ("trk") ) {

    for my $p ( $t->getElementsByTagName ("trkpt") ) {  $node++;
        my $latitude = $p->getAttributeNode ("lat")->getValue() ;
        my $longitude = $p->getAttributeNode ("lon")->getValue() ;

	$gmttime = $p->getElementsByTagName ("time")->
	   item(0)->getFirstChild->getNodeValue();
	
	 $altitude = $p->getElementsByTagName ("ele")->
	   item(0)->getFirstChild->getNodeValue();
	printf "%s;%s;%s;%s\n", $gmttime, $latitude, $longitude, $altitude;
       }
   }
}

środa, 11 maja 2016

Garmin Virb Edit

Według producenta program: łączy nagrania wideo z kamery sportowej VIRB z danymi GPS i innymi informacjami pochodzącymi ze zgodnych urządzeń firmy Garmin. Faktycznie łączy dane zapisane w formacie FIT/GPX z dowolnym plikiem wideo zapisanym w formacie MP4.

VIRB Edit można ściągnąć za darmo ze strony Garmina (dostępne są wersje dla systemów MS Windows/Mac).

Moja niegarminowska kamera zapisuje obraz w formacie MOV (Dane GPS są faktycznie z urządzenia firmy Garmin, ale równie dobrze mogłyby być ze smartfonu albo chińskiego loggera.) Zamieniam plik MOV do formatu MP4 za pomocą aplikacji HandBrakeCLI. Poniższe polecenie wykonuje konwersję, a wynikowy plik.mp4 będzie około 50% mniejszy niż plik MOV:

time HandBrakeCLI -i PLIK.MOV -o PLIK.mp4 -w 1280 -l 720 --preset="Normal"

Trzydziestominutowy plik MOV, zamieniany jest przez około pół godziny (Linux IntelNuc/i5/8Gb pamięci).

Uparłem się zainstalować HandBrakeCLI w systemie Fedora21, a ponieważ nie ma stosownych pakietów .rpm musiałem go skompilować:

yum install yasm zlib-devel bzip2-devel libogg-devel libtheora-devel \
libvorbis-devel libsamplerate-devel libxml2-devel fribidi-devel \
freetype-devel fontconfig-devel libass-devel dbus-glib-devel \
libgudev1-devel webkitgtk-devel libnotify-devel \
gstreamer-devel gstreamer-plugins-base-devel

sudo yum groupinstall "Development Tools" "Development Libraries" \
"X Software Development" "GNOME Software Development"

yum install lame-libs lame-devel x264-devel intltool

tar -xvzf HandBrake-0.10.3.tar.bz2
cd HandBrake-0.10.3
./configure
cd build
make
make install

W sumie mogłem sobie darować powyższe, bo i tak w końcu muszę używać MS Windows, no ale może ten HandBrake przyda się do czegoś innego.

Na mojej stronie na youtube można obejrzeć wygenerowane za pomocą VIRB filmiki z dodanymi danymi GPS.

czwartek, 21 kwietnia 2016

Wybory do PE2014/Sejmu2015: komisje obwodowe z wysokim odsetkiem głosów nieważnych

W nawiązaniu do poprzedniego wpisu.

861 komisji obwodowych z ze znaczącym odsetkiem głosów nieważnych (przyjąłem 6% jako wartość progową):


duże mapy/dane

Na pierwszy ogląd, to nie wydaje się żeby w jakimś regionie mieszkali szczególnie niekumaci wyborcy, chociaż Dolny Śląsk/Podlaskie wydają się prezentować najkorzystniej:-)

środa, 20 kwietnia 2016

Web scrapping protokołów z wyborów do Parlamentu Europejskiego w 2014 r.


Rozkład komisji wg. liczby głosów

Frekwencja

Głosy nieważne

Ze strony pe2014.pkw.gov.pl ściągnąłem szczegółowe wyniki wyborów do parlamentu europejskiego z 2014 r. Pobrałem protokoły ze wszystkich 27664 komisji obwodowych. Takie protokoły są dostępne pod adresem:

http://pe2014.pkw.gov.pl/pl/wyniki/protokoly/<idGminy><idOkręgu>

Rozkład komisji obwodowych według liczby oddanych głosów:

komisje <- read.csv("komisje-frekwencja.csv", sep = ';',  header=T, na.string="NA");
str(komisje);

fivenum(komisje$lkw);

hist(komisje$lkw, breaks=seq(0, 1250, by=10),
       freq=TRUE,col="orange",main="Wybory2014: komisje wg liczby oddanych głosów ważnych",
       xlab="# głosów",ylab="# komisji (N = 27664)",yaxs="i",xaxs="i")

Zależność pomiędzy frekwencją w wyborach do PE a frekwencją w wyborach do Sejmu 2015:

require(ggplot2)

d <- read.csv("komisje-frekwencja14_15.csv", sep = ';',  header=T, na.string="NA");
# Usuń zagraniczne (jako nietypowe):
d <- subset (d, ( teryt != 149901 ));

ggplot(d, aes(x = freq)) +
  geom_point(aes(y = freq15), colour = 'blue') +
  xlab(label="freq 2014") +
  ylab(label="freq 2015")

## tylko obwody z liczbą głosów > 20 oraz
## frekwencją większą od 60  
d <- subset (d, ( lkw > 20 & lkw15 > 20 & freq > 60 & freq15 > 60))
str(d)
'data.frame':   76 obs. of  19 variables:

Komisji z nietypowo dużą frekwencją (arbitralnie przyjąłem 60%), w których głosowało co najmniej 21 wyborców (też arbitralnie) było 76 (0,2% wszystkich komisji). Okazało się, że praktycznie wszystkie te komisje są zlokalizowane w obwodach ,,specjalnych'' (szpitale, domy pomocy społecznej, areszty itp...)

Zależność pomiędzy odsetkiem głosów nieważnych w wyborach do PE a frekwencją w wyborach do Sejmu 2015:

 ggplot(d, aes(x = pgnw)) +
  geom_point(aes(y = pgnw15), colour = 'blue') +
  xlab(label="nonvalid 2014 (%)") +
  ylab(label="nonvalid 2015 (%)") 

Zwraca uwagę pewna liczba komisji o bardzo dużej liczbie głosów nieważnych:

d <- read.csv("komisje-frekwencja14_15.csv", sep = ';',  header=T, na.string="NA");
# Usuń zagraniczne (nietypowe):
d <- subset (d, ( teryt != 149901 ));

# Usuń krajowe nietypowe tj.areszty/domy pomocy itp:
d <- subset (d, !grepl("Dom pomocy|Domu Pomocy|Areszt|Zakład karny", adres, ignore.case = TRUE));

# Tylko komisje gdzie odsetek gł. nieważnych > 6%
d <- subset (d, ( pgnw > 6 & pgnw15 > 6 ));

str(d);
'data.frame':   861 obs. of  19 variables:

Komisji z ze znacznym odsetkiem głosów nieważnych (przyjąłem 6% jako wartość progową) było zatem 861 (3%). Trzy procent to nie jest aż tak mało, więc warto by się przyjrzeć im bliżej, ale to nie teraz.

Dane pobrane ze strony http://pe2014.pkw.gov.pl/pl/ są dostępne tutaj. Natomiast tutaj znajdują się pobrane ze strony PKW protokoły wyborcze: 1) z wyborów do parlamentu europejskiego 2014r. 2) z wyborów prezydenckich 2015r. 3) z wyborów parlamentarnych 2015r. oraz 4) z wyborów samorządowych 2014r.

Wszelkie komentarze/uwagi/poprawki mile widziane:-)

piątek, 26 lutego 2016

Jak często powtarzają się nazwy miejscowości w Polsce

W pewnym hobbystycznym projekcie geokoduję nazwy miejscowości używając do tego celu usługi Google. Potencjalnym źródłem błędnych wyników mogą być miejscowości, które mają identyczne nazwy. Jaka jest skala zjawiska?

Według obwieszczenie Ministra Administracji i Cyfryzacji z dnia 4 sierpnia 2015 r. w wykazie urzędowych nazw miejscowości i ich części (Dziennik Ustaw 19 10. 2015 r., poz. 1636) znajduje się: 103086 nazw, w tym 915 nazw miast, 6710 nazw części miast, 43068 nazw wsi, 36263 nazwy części wsi, 5132 nazwy osad. Z czego wynika, że wsi + miast jest 43068 + 915 = 43,983 nazw. (Na podstawie KSNG/Urzędowe nazwy miejscowości)

Po ściągnięciu arkusza z powyższej strony, zamieniam go na format CSV używając jako separatora pola średnika (bo lubię). Następnie za pomocą poniższego skryptu agregują dane:

#!/usr/bin/perl
# zamiana listy nazw na listę:
#   nazwa;województwo;liczba-wystąpień-w-województwie
while (<>) { chomp();
  @tmp = split /;/, $_;
  if ($tmp[1] eq 'wieś' || $tmp[1] eq 'miasto' ) {
     $NW{"$tmp[4]"}{"$tmp[0]"}++;  }
}

for $w (sort keys %NW ) {
   for $m (sort { $NW{$w}{$b} <=> $NW{$w}{$a} } keys %{$NW{$w} }) {
      print "$m;$w;$NW{$w}{$m}\n";
    }
}

Teraz z kolei używając R grupuję dane w podziale na następujące cztery klasy: 1 wystąpienie, 2 wystąpienia 3--4 oraz 5 i więcej wystąpień. Rezultaty zestawiono w poniższej tabeli (kolumny 2--5 to liczebności a 6--10 udziały; przykładowo zapis [1,2) oznacza, że klasa zawiera 1 a nie zawiera 2):

Województwo        [1,2) [2,3) [3,5) [5,30) [1,2)  [2,3) [3,5) [5,30)
---------------------------------------------------------------------
dolnośląskie       2082   117   37    3     92,99  5,23  1,65  0,13 
kuj.-pomorskie     2257   183   52   10     90,20  7,30  2,10  0,40
lubelskie          2698   154   65   26     91,68  5,23  2,21  0,88 
lubuskie            965    57    5    0     93,96  5,55  0,49  0,00 
łódzkie            3276   275   99   45     88,70  7,40  2,70  1,20 
małopolskie        1594   105   21    4     92,46  6,09  1,22  0,23 
mazowieckie        5780   466  177   79     88,90  7,20  2,70  1,20 
opolskie            941    39    9    1     95,05  3,94  0,91  0,10 
podkarpackie       1429    49   17    2     95,46  3,27  1,14  0,13 
podlaskie          2852   136   42    9     93,80  4,50  1,40  0,30 
pomorskie          1579    58   13    2     95,58  3,51  0,79  0,12 
śląskie            1033    48    7    2     94,77  4,40  0,64  0,18 
świętokrzyskie     1844   111   51   12     91,38  5,50  2,53  0,59 
war.-mazurskie     2060   128   34    3     92,58  5,75  1,53  0,13 
wielkopolskie      3378   310   99   19     88,80  8,10  2,60  0,50 
zachodniopomorskie 1504   117   19    1     91,65  7,13  1,15  0,06

Lista najczęściej powtarzających się (więcej niż 4 powtórzenia) nazw w poszczególnych województwach:

dolnośląskie: Księginice (5) Nowy Dwór (5) Piotrowice (5)

kujawsko-pomorskie: Nowa Wieś (14) Dąbrówka (9) Nowy Dwór (8) Janowo (7) Zalesie (7) Ostrowo (6) Zakrzewo (6) Józefowo (6) Białe Błota (5) Brzeźno (5)

lubelskie: Marysin (9) Brzeziny (8) Zalesie (8) Dąbrowa (7) Stara Wieś (7) Władysławów (6) Antoniówka (6) Nowiny (6) Józefów (6) Ludwinów (6) Dębina (6) Natalin (5) Zastawie (5) Nowosiółki (5) Stanisławów (5) Ruda (5) Kąty (5) Michałówka (5) Janówka (5) Ostrów (5) Zabłocie (5) Huta (5) Wysokie (5) Nowa Wieś (5) Wojciechów (5) Siedliska (5)

mazowieckie: Nowa Wieś (28) Zalesie (23) Dąbrowa (21) Helenów (16) Władysławów (16) Józefów (15) Aleksandrów (15) Dąbrówka (14) Zawady (14) Stanisławów (13) Ruda (11) Marianów (11) Janów (11) Ludwików (10) Kamionka (10) Górki (10) Borki (9) Ostrówek (9) Lipiny (9) Grabina (9) Janówek (9) Marysin (8) Józefowo (8) Stara Wieś (8) Majdan (8) Łazy (8) Michałów (8) Wygoda (7) Bronisławów (7) Julianów (7) Sewerynów (7) Adamowo (7) Grądy (7) Trzcianka (7) Osiny (7) Adamów (7) Kąty (7) Emilianów (6) Żuków (6) Wymysłów (6) Pieńki (6) Lipniki (6) Grabowo (6) Franciszków (6) Mościska (6) Dębówka (6) Mała Wieś (6) Natolin (6) Piaski (6) Anielin (6) Bieliny (6) Lipa (6) Wincentów (6) Kazimierzów (6) Pogorzel (5) Aleksandrówka (5) Józefin (5) Laski (5) Huta (5) Kałęczyn (5) Łaziska (5) Marianka (5) Pawłowice (5) Karolew (5) Osiek (5) Zakrzew (5) Zamość (5) Chmielewo (5) Ostrów (5) Rososz (5) Białobrzegi (5) Romanów (5) Pawłowo (5) Wyczółki (5) Kozłów (5) Podgórze (5) Dąbrówki (5) Ignaców (5) Jakubów (5)

małopolskie: Przybysławice (6) Zawadka (5) Siedliska (5) Biskupice (5)

opolskie: Jakubowice (5)

podkarpackie: Nowa Wieś (7) Zalesie (5)

podlaskie: Zalesie (9) Olszanka (8) Ogrodniki (8) Wólka (7) Janowo (5) Rybaki (5) Nowinka (5) Nowosady (5) Jałówka (5)

pomorskie: Dąbrówka (8) Ostrowite (5)

warmińsko-mazurskie: Zalesie (7) Nowa Wieś (5) Olszewo (5)

wielkopolskie: Dąbrowa (15) Nowa Wieś (13) Bielawy (9) Zalesie (8) Biskupice (7) Zakrzewo (7) Marianowo (6) Józefowo (6) Józefów (6) Ruda (5) Zawady (5) Piaski (5) Brzezie (5) Chrustowo (5) Góra (5) Drzewce (5) Kamień (5) Nowy Dwór (5) Kamionka (5)

zachodniopomorskie: Grabowo (5)

łódzkie: Józefów (20) Dąbrowa (17) Janów (17) Dąbrówka (14) Stanisławów (14) Nowa Wieś (11) Zalesie (11) Piaski (11) Adamów (11) Zawady (10) Marianów (10) Ostrów (9) Władysławów (9) Stefanów (9) Helenów (8) Dębina (8) Aleksandrów (8) Julianów (7) Bronisławów (7) Marianka (7) Borki (7) Stara Wieś (7) Brzeziny (7) Gaj (7) Michałów (7) Ludwików (6) Witów (6) Wygoda (6) Kazimierzów (6) Kuźnica (6) Anielin (6) Karolew (6) Ruda (6) Antoniew (5) Jeziorko (5) Konstantynów (5) Zakrzew (5) Emilianów (5) Osiny (5) Poręby (5) Feliksów (5) Borowa (5) Zagórze (5) Teodorów (5) Wymysłów (5)

śląskie: Zawada (6) Nowa Wieś (6)

świętokrzyskie: Wolica (9) Wymysłów (8) Podlesie (8) Hucisko (6) Zagórze (5) Nowa Wieś (5) Brzeście (5) Zakrzów (5) Janów (5) Bugaj (5) Ludwinów (5) Górki (5)

W skali całego kraju jest 5080 miejscowości, których nazwa nie jest unikatowa, w tym, w przypadku 868 miejscowości nazwy powtarzają się 5 i więcej razy. Pierwsza dziesiątka wygląda następująco: Nowa Wieś (113 powtórzeń), Dąbrowa (92), Zalesie (86), Dąbrówka (65), Józefów (49), Kamionka (41), Ruda (39), Janów (39), Zawady (39) Stanisławów (38).

W pierwszym akapicie napisałem, że problem może być potencjalny ponieważ wydaje się, że geokoder Google działa całkiem sprytnie. Przykładowo

Nowa Wieś
 -> 07-416 Nowa Wieś (powiat oświęcim)
Nowa Wieś, ul. Dworcowa
 -> 64-234 Nowa Wieś (Powiat wolsztyński)

Po wpisaniu po prostu Nowa Wieś geocoder, z jakiś powodów, decyduje się na Nową Wieś w powiecie oświęcimskim, ale już podanie dodatkowo ul. Dworcowa zmienia wynik na Nową Wieś w powiecie wolsztyńskim; faktycznie w tej wsi jest ul. Dworcowa (pytanie czy tylko w tej). Można uściślić o co nam chodzi podając też:

Nowa Wieś, powiat wolsztyński
Nowa Wieś, województwo wielkopolskie

Podanie powiatu powinno rozwiązać problem duplikatów, zaś drugi sposób wydaje jednak mniej pewny biorąc pod uwagę liczbę powtórzeń nazw na poziomie województwa...

Skrypty i dane są tutaj.

poniedziałek, 22 lutego 2016

Asus X205TA


Asus X205TA

Kupiłem to cudo w celu używania na wyjazdach. W domu działam na PCie (bezwiatrakowy Intel NUC, opisany tutaj).

Z tego co piszą w Internetach Linuksa nie da się zainstalować (przed zakupem wydawało mi się, że się da, ale okazuje się, że są tylko jakieś alfa wersje, nie do końca działające). Z 32Gb dostępnej pamięci, 10Gb zajęte jest przez recovery partition, której nie da się usunąć/przenieść na przykład na pamięć USB. Po zainstalowaniu kilku aplikacji zostało 10Gb wolnego miejsca.

Teraz plusy

Na plus tego komputera bez wątpienia należy zaliczyć: 1. waży tylko 0,9kg (1,1kg z ładowarką); 2. potrafi ponad 10 godzin pracować na baterii; 3. jest całkiem szybki i wygodny (klawiatura).

Pewnie airBook byłby lepszy ale nie za 780 PLN no i trochę byłby cięższy (ten airBook).

Problem z pamięcią rozwiązałem (mam nadzieję -- na ile skutecznie, to wyjdzie w praniu) w taki sposób, że kupiłem kartę mikroSD 32Gb z przeznaczeniem na dane. Wsadziłem ją ,,na stałe'' do czytnika po sformatowaniu do NTFS. Gdzieś coś wyczytałem, że Windows10 pozwala na przeniesienie recovery partition, ale ja się boję tego Win10 i zostaję na razie z Win8.1 (być może niesłusznie). Zresztą przy instalowaniu byłem brutalnie zachęcany do zmiany domyślnego Win8.1 na Win10, co tylko pogłębiło moje obawy czy warto...

wtorek, 16 lutego 2016

Wyświetlanie plików KML na umap.fr

W nawiązaniu do narzekań z poprzedniego wpisu spróbowałem alternatywy pn. umap.fr.

Na umap.fr można wyświetlać zawartość plików KML równie prosto jak na mymaps google. Jedyne co trzeba zmienić, to zawartość elementu description, który ma zawierać zamiast HTMLa podzbiór/wariant markdowna. Konkretnie ma być:

<description>
{{URL-do-miniatury-zdjęcia}}
[[URL-do-strony-zdjęcia|enlarge/powiększ]]
</description>

zamiast:

<description><![CDATA[
    <a href='URL-do-strony-zdjęcia' target='_blank'>
     <img src='URL-do-miniatury-zdjęcia' />enlarge/powiększ
     </a>]]>
  </description>

Tak zmieniony plik importujemy, zapisujemy, a osiągnięty rezultat jest do obejrzenia w ramce obok.

niedziela, 14 lutego 2016

Importowanie i wyświetlanie plików KML w Google Maps


Wycieczka do Mediolanu/Bergamo

Wkurzające są ciągłe udoskonalenia usług Google, których obocznym skutkiem jest niekompatybilność i/lub konieczność zmiany narzędzi, które działały kiedyś i nagle przestały działać. Taka przykrość spotkała mnie wczoraj i dotyczyła importu plików KML do myMaps/Mojemapy google.

Otóż kiedyś działało coś takiego (opisującego miejsce zrobienia zdjęcia):

<Placemark><name>epl316_2135207.jpg</name>
  <description><![CDATA[
    <a href='https://www.flickr.com/photos/tprzechlewski/24967425626/' target='_blank'>
     <img src='https://farm2.staticflickr.com/1508/24967425626_2166aceb85_m.jpg' />epl316_2135207.jpg
     </a>]]>
  </description>
  <Point><coordinates>9.20398056,45.48436667</coordinates>
  </Point>
</Placemark>

dziś przestało. Po kliknięciu w pinezkę, otwiera się okienko z informacją o zdjęciu, ale miniaturka zdjęcia nie jest wyświetlana.

Za pomocą reverse-engineering ustaliłem (być może nie jest to rozwiązanie optymalne), że działa poniższe:

  ... jak poprzednio ...
</description>
<ExtendedData><Data name='gx_media_links'>
<value>https://farm2.staticflickr.com/1508/24967425626_2166aceb85_m.jpg</value>
</Data></ExtendedData>
<Point> ...itd...

tzn po elemencie description trzeba wstawić ExtendedData, z zawartością jak wyżej.

Por także: Importowanie i wyświetlanie plików KML w Google Maps oraz Keyhole Markup Language/Adding Custom Data.

W promocji (w ramce po prawej) mapka wycieczki do Mediolanu/Bergamo zaimportowana w opisany wyżej sposób.