hallo und guten Abend,
ich habe bisher immer meine Daten von planet-files abgeleitet und dann in CSV-Dateien hinterlegt. Dabei war ich der Frage nachgegangen - ob ich in postgresql anfangen soll oder noch mit Mysql arbeiten kann. GGF ist dann ansonsten das Thema etwas zu groß für das was ich mache.
Deshalb hatte ich eine andere Überlegung und nun wollte ich Euch fragen, ob es gewisse Grundlagen dafür gibt mittels Perl an die overpass-Api zu kommen. Was mache ich in der Regel. In der Regel frage ich in den OSM-Daten nur bestimmte POI ab und mache daraus eine thematische Karte. In der einfachsten Anwendung wären das nur Nodes und bei Flächen wird ein Punkt generiert der dann die Daten bekommt - quasi eine Flächen->Node-Konvertierung.
Meine Überlegungen gehen nun dahin diese Daten nicht mehr in einer CSV vorzuhalten sondern in einer mySQL-Datenbank:
Gearbeitet hab ich mit dem folgenden Toolset: hier eine detailliere Übersicht über meine Ideen, Ansätze u.d Versuche mit den o.g. Techniken: https://wiki.openstreetmap.org/wiki/User:Tagtheworld
- osmfilter - osmconvert
ein Bspl:
./osmconvert ein file aus deutschland ....osm --all-to-nodes --csv="@id @lon @lat amenity name" --out-csv -o=outfile.csv
und dann:
grep cafe outfile.csv > cafes.csv
grep restaurant outfile.csv > restaurants.csv
cat cafes.csv restaurants.csv > cafes_and_restaurants.csv
b. auf der anderern Hand koennte ich das ggf. auch so machen: mit der overpass-api:
untenstehend die beiden skripte:
die datei osm_to_db.pl ferner die datei create_db.pl
eine Ausgabe von overpass-api;
mysql.txt
<node id="2064639440" lat="49.4873181" lon="8.4710548">
<tag k="amenity" v="restaurant"/>
<tag k="cuisine" v="turkish"/>
<tag k="email" v="info@lynso.de"/>
<tag k="name" v="Kilim - Café und Bar Restaurant"/>
<tag k="opening_hours" v="Su-Th 17:00-1:00; Fr, Sa 17:00-3:00"/>
<tag k="operator" v="Cengiz Kaya"/>
<tag k="phone" v="06 21 - 43 755 371"/>
<tag k="website" v="http://www.kilim-mannheim.de/"/>
</node>
<node id="2126473801" lat="49.4851170" lon="8.4756295">
<tag k="amenity" v="restaurant"/>
<tag k="cuisine" v="italian"/>
<tag k="email" v="mannheim1@vapiano.de"/>
<tag k="fax" v="+49 621 1259 779"/>
<tag k="name" v="Vapiano"/>
<tag k="opening_hours" v="Su-Th 10:00-24:00; Fr-Sa 10:00-01:00"/>
<tag k="operator" v="Vapiano"/>
<tag k="phone" v="+49 621 1259 777"/>
<tag k="website" v="http://www.vapiano.de/newsroom/?store=29"/>
<tag k="wheelchair" v="yes"/>
</node>
<node id="667927886" lat="49.4909673" lon="8.4764904">
<tag k="addr:city" v="Mannheim"/>
<tag k="addr:country" v="DE"/>
<tag k="addr:housenumber" v="5"/>
<tag k="addr:postcode" v="68161"/>
<tag k="addr:street" v="Collinistraße"/>
<tag k="amenity" v="restaurant"/>
<tag k="name" v="Churrascaria Brasil Tropical"/>
<tag k="phone" v="+496211225596"/>
<tag k="wheelchair" v="limited"/>
</node>
und dann hier der Code
#!/usr/bin/perl
use strict ;
use DBI;
use XML::Twig;
# prepare database
my $dbh=dbh(); # connect
init();
$dbh->do('USE db123');
#$dbh->do('DELETE FROM pois');
# sql
my $sql = 'REPLACE INTO pois VALUES (?,?,?,?,?,?)';
my $sth = $dbh->prepare($sql);
# set up handler
my $t = XML::Twig->new(
twig_handlers => { 'node' => \&node }
);
# parse xml
my $xml = do { local $/; <DATA> };
$t->parse($xml);
#$t->parsefile('.osm');
sub node {
my ($t,$elt) = @_;
my %data=(
'id' => $elt->att('id'),
'lat' => $elt->att('lat'),
'lon' => $elt->att('lon'),
);
for my $tag ( $elt->children() ){
$data{$tag->att('k')} = $tag->att('v');
#print $tag->att('k').' = '.$tag->att('v')."\n";
}
# update database
my @f = map{ $data{$_} }('id','lat','lon','name','amenity','operator');
if ($f[3] ne '' && $f[4] ne '' && $f[5] ne ''){
print "-- INSERT --\n".
(join "\n",@f).
"\n\n";
$sth->execute(@f);
}
}
sub init {
$dbh-> do('CREATE DATABASE IF NOT EXISTS db123
DEFAULT CHARACTER SET latin1
COLLATE latin1_german2_ci');
$dbh->do('USE db123');
$dbh->do('CREATE TABLE IF NOT EXISTS pois (
id BIGINT(20) UNSIGNED NOT NULL,
lat FLOAT(10,7) NOT NULL,
lon FLOAT(10,7) NOT NULL,
name VARCHAR(255) COLLATE utf8_bin NOT NULL,
amenity VARCHAR(255) COLLATE utf8_bin NOT NULL,
operator VARCHAR(255) COLLATE utf8_bin NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT
CHARSET=utf8
COLLATE=utf8_bin');
}
sub dbh {
my $dsn = "DBI:mysql:database=;host=localhost";
my $dbh = DBI->connect($dsn, 'user', 'pwd',
{RaiseError => 1, PrintError => 1})
or die (Error connecting " $DBI::errstr");
}
Zusatzüberlegungen :Den pois.osm file kann ich auch in die create_db.pl packen. Aber in der frühen Testphase ann ich auch ein Datei anlegen - etwa so /home/perl/OSM und die osm.pm dort hinlegen.
By the way: es sieht irgendwie danauch aus, als koennte ich osmDB.pm auch gut gebrauchen. Auserdem koennte ich noch Compress::Bzip2 installieren.
Meine neue Wiki-Page auf der ich mal die Moeglichen Lösungen zusammengestellt hab: https://wiki.openstreetmap.org/wiki/User:Tagtheworld