source: subversion/applications/utils/opengeodb2osm/opengeodb2osm.pl @ 34621

Last change on this file since 34621 was 6465, checked in by tabacha, 12 years ago

Version of a initial import

File size: 13.4 KB
Line 
1#!/usr/bin/perl -w
2#
3# Author: Sven Anders <sven@anders-hamburg.de>
4# License GPL 2.0
5#
6my $version="0.5.2";
7my $progname="opengeodb2osm";
8my $osmApiURL="http://api.openstreetmap.org/api/0.5/node/";
9$dbversion="0.2.5a / 2007-10-04 / http://opengeodb.sourceforge.net/";
10
11use utf8;
12use DBI;
13use LWP::Simple;
14
15my %osmOGDB;
16$uselat=0;
17$minlat=53;
18$maxlat=54;
19$minlon=9;
20$maxlon=11;
21
22$mysqldb="opengeodb";
23$mysqluser="root"; 
24
25$mysqlpw="";
26
27print "<?xml version='1.0' encoding='UTF-8'?>
28<osm version='0.5' generator='$progname'>\n";
29if (-f "opengeodb2osmSettings.pm") {
30    require opengeodb2osmSettings;
31}
32
33$osmOGDB{"400100000"}="openGeoDB:is_in_loc_id";
34$osmOGDB{"400200000"}="openGeoDB:layer";
35$osmOGDB{"400300000"}="openGeoDB:type";
36$osmOGDB{"500300000"}="openGeoDB:postal_codes";
37$osmOGDB{"500600000"}="openGeoDB:community_identification_number";
38$osmOGDB{"500100002"}="openGeoDB:sort_name";
39$osmOGDB{"500500000"}="openGeoDB:license_plate_code";
40$osmOGDB{"500400000"}="openGeoDB:telephone_area_code";
41$osmOGDB{"500700000"}="openGeoDB:combination_of_public_administration";
42$osmOGDB{"500100003"}="openGeoDB:ISO-3166-2";
43
44$osmOGDB{"500100000"}="name";
45
46my %is_in;
47
48my $dbh = DBI->connect( 'dbi:mysql:'.$mysqldb, $mysqluser, $mysqlpw) ||
49     die "Kann keine Verbindung zum MySQL-Server aufbauen: $DBI::errstr\n";
50
51# Befehl fuer Ausfuehrung vorbereiten. Referenz auf Statement
52# Handle Objekt wird zurueckgeliefert
53
54my $sthRel=$dbh->prepare( 'select distinct text_val from geodb_textdata where text_type="400100000" and valid_until>NOW() ') ||
55     die "Kann Statement nicht vorbereiten: $DBI::errstr\n";
56my $sth = $dbh->prepare( 'SELECT distinct loc_id FROM geodb_textdata where loc_id>0 and loc_id!=100 and valid_until>NOW()') ||
57     die "Kann Statement nicht vorbereiten: $DBI::errstr\n";
58my $sthOSMNode =  $dbh->prepare('SELECT c.loc_id,n.id,SQRT(((c.lat-n.lat)*(c.lat-n.lat))+((c.lon-n.lon)*(c.lon-n.lon)))*100 as dist FROM geodb_coordinates c, geodb_textdata t, nodes n WHERE c.loc_id=t.loc_id and t.text_type=500100000 and n.name=t.text_val  order by c.loc_id ') or 
59     die "Kann Statement nicht vorbereiten: $DBI::errstr\n";
60my $sthOSM = $dbh->prepare('SELECT lat,lon FROM nodes WHERE id=?') ||
61     die "Kann Statement nicht vorbereiten: $DBI::errstr\n";
62
63my $where="where valid_until>NOW()";
64if ($uselat==1) {
65        $where.="and lat>=$minlat and lat<=$maxlat and lon>=$minlon and lon<=$maxlon";
66}
67
68
69
70
71
72my $sthNode = $dbh->prepare( 'SELECT distinct loc_id FROM geodb_coordinates '.$where ) ||
73     die "Kann Statement nicht vorbereiten: $DBI::errstr\n";
74
75if ($where ne "") {
76    $where.=" and loc_id=?";
77} else {
78    $where="where loc_id=?";
79}
80
81my $sthCoord = $dbh->prepare( 'SELECT lon,lat,valid_since,date_type_since,valid_until,date_type_until FROM geodb_coordinates '.$where ) ||
82     die "Kann Statement nicht vorbereiten: $DBI::errstr\n";
83
84
85my $sthText = $dbh->prepare('select text_type,text_val,text_locale,is_native_lang,is_default_name from geodb_textdata where loc_id=? and valid_until>NOW()');
86
87my $sthLoc = $dbh->prepare('select loc_type from geodb_locations where loc_id=? ');
88my $sthPop = $dbh->prepare('select int_val from geodb_intdata where loc_id=? and int_type=600700000 and valid_until>NOW()');
89
90my $sthParts = $dbh->prepare('select loc_id from geodb_textdata where text_type=400100000 and text_val=? and valid_until>NOW()');
91
92$sthOSMNode->execute ||
93     die "Kann Abfrage nicht ausfuehren: $DBI::errstr\n";
94my $oldlocid=-1;
95my $olddist;
96my $maxDist=10;
97my %OsmIdToNodeId;
98while ( my @ergebnis = $sthOSMNode->fetchrow_array() ){
99    my $locid=$ergebnis[0];
100    my $osmid=$ergebnis[1];
101    my $dist=$ergebnis[2];
102    if ($oldlocid != $locid) {
103        if ($oldlocid != -1) {
104            $OsmIdToNodeId{$oldosmid}=$oldlocid;
105        }
106        $olddist=$maxDist+2;
107    }
108    if (($dist<$maxDist) and ($dist<$olddist)) {
109        if (!(defined($OsmIdToNodeId{$osmid}))) {
110            $NodelocIdHash{$locid}=$osmid;
111        } 
112        $olddist=$dist;
113        $oldlocid=$locid;
114        $oldosmid=$osmid;
115    }
116}
117
118
119# Vorbereitetes Statement (Abfrage) ausfuehren
120$sthNode->execute ||
121     die "Kann Abfrage nicht ausfuehren: $DBI::errstr\n";
122
123$nodeid=-1;
124while ( my @ergebnis = $sthNode->fetchrow_array() ){
125    my $locid=$ergebnis[0];
126    if (!(defined($NodelocIdHash{$locid}))) {
127        $NodelocIdHash{$locid}=$nodeid;
128        $nodeid--;
129    }
130}
131$sthRel->execute ||
132     die "Kann Abfrage nicht ausfuehren: $DBI::errstr\n";
133
134while ( my @ergebnis = $sthRel->fetchrow_array() ){
135    my $locid=$ergebnis[0];
136    $RelationlocIdHash{$locid}=$nodeid;
137    $nodeid--;
138}
139
140
141
142# Vorbereitetes Statement (Abfrage) ausfuehren
143$sth->execute ||
144     die "Kann Abfrage nicht ausfuehren: $DBI::errstr\n";
145
146
147while ( my @ergebnis = $sth->fetchrow_array() ){
148   # Im Array @ergebnis steht nun ein Datensatz
149    my $locid=$ergebnis[0];
150    my $timestamp="";
151    my $lat;
152    my $lon;
153
154   
155    $tag=' <tag k="openGeoDB:loc_id" v="'.$locid.'" />'."\n";
156    $sthCoord->execute($locid);
157    while ( my @corderg = $sthCoord->fetchrow_array() ){
158        $lat=$corderg[1];
159        $lon=$corderg[0];
160    }
161    $found=0;
162
163    my %osmTag=();
164    if (defined($NodelocIdHash{$locid}) and ($NodelocIdHash{$locid} >0)) {     
165        $osmContent = get($osmApiURL.$NodelocIdHash{$locid});
166        if (defined($osmContent)) {
167            @content=split(/\n/,$osmContent);
168            foreach my $line (@content) {
169                if (($line=~/node id=\"\d*\" lat=\"(.*)\" lon="(.*)" user=".*" visible="true" timestamp="(.*)"/) or ($line=~/node id=\"\d*\" lat=\"(.*)\" lon="(.*)" visible="true" timestamp="(.*)"/)) { 
170                   
171                   
172                    $lat=$1;
173                    $lon=$2;
174                    $timestamp=" timestamp=\"$3\"";
175                    $tag.=' <tag k="opengeodb:lat" v="'.$lat.'" />'."\n";
176                    $tag.=' <tag k="opengeodb:lon" v="'.$lon.'" />'."\n";
177                    $found=1;
178
179                } elsif ($line=~/^\s*<tag k=\"(.*)\" v=\"(.*)\"\/>\s*$/) {
180                    my $k=$1;
181                    my $v=$2;
182                    $osmTag{$k}=$v;
183                    if (($k ne "created_by") and (!($k =~/^openGeoDB:/))){
184                        $tag.="$line\n";
185                    }
186                } elsif ($line=~/<?xml version=\"/) {
187                } elsif ($line=~/<osm version=\"/) {
188                } elsif ($line=~/^\s*<\/node>/) {
189                } elsif ($line=~/^\s*<\/osm>/) {
190                }else {
191                    warn("line: $line");
192                }
193            }
194        }
195
196    }
197    $sthText->execute($locid);
198    $sthLoc->execute($locid);
199    $sthPop->execute($locid);
200    my $updatePopulation=1;
201    my $updatePlace=1;
202    my $updateName=1;
203    my $updateIsIn=1;
204    my $autoUpdate="";
205    if (defined($osmTag{"openGeoDB:auto_update"})) {
206        $updatePopulation=0;
207        $updatePlace=0;
208        $updateName=0;
209        $updateIsIn=0;
210        $autoUpdate=$osmTag{"openGeoDB:auto_update"};
211        foreach my $e (split /,/,$osmTag{"openGeoDB:auto_update"}) {
212            if ($e eq "population") {
213                $updatePopulation=1;
214            } elsif ($e eq "place") {
215                $updatePlace=1;
216            } elsif ($e eq "name") {
217                $updateName=1;
218            } elsif ($e eq "is_in") {
219                $updateIsIn=1;
220            }
221        }
222    } elsif ($found==0) {
223        $updatePopulation=1;
224        $updatePlace=1;
225        $updateName=1;
226        $updateIsIn=1;
227        $autoUpdate="population,place,name,is_in";
228    } else {
229        my @arr;
230        $updateName=!(defined($osmTag{"name"}));
231        if ($updateName) {
232            push @arr,"name";
233        }
234        $updatePlace=!(defined($osmTag{"place"}));
235        if ($updatePlace) {
236            push @arr,"place";
237        }
238        $updatePopulation=!(defined($osmTag{"population"}));
239        if ($updatePopulation) {
240            push @arr,"population";
241        }
242        $updateIsIn=!(defined($osmTag{"is_in"}));
243        if ($updateIsIn) {
244            push @arr,"is_in";
245        }
246        $autoUpdate=join(",",@arr);
247    }
248    if ($found) {
249        if ($updateName) {
250            delete $osmTag{"name"};
251        }
252        if ($updatePlace) {
253            delete $osmTag{"place"};
254        }
255        if ($updatePopulation) {
256            delete $osmTag{"population"};
257        }
258        if ($updateIsIn) {
259            delete $osmTag{"is_in"};
260        }
261    }
262    my %textval;
263    while ( my @texterg = $sthText->fetchrow_array() ){
264        my $key=$texterg[0];
265        my $value=$texterg[1];
266        utf8::encode($value);
267        $value=~s/&/&amp;/g;
268        $value=~s/\"/&quot;/g;
269        my $locale=$texterg[2];
270        my $nativelang=$texterg[3];
271        my $defaultname=$texterg[4];
272        if (defined($osmOGDB{$key})) {
273            $key=$osmOGDB{$key};
274        } else {
275            $key='openGeoDB:'.$key;
276        }
277        if (defined($defaultname) and ($defaultname eq "0")) {
278            $key.=":".$locale;
279        }
280        if (defined $textval{"$key"}) {
281            $textval{$key}.=",".$value;
282        } else {
283            $textval{$key}=$value;
284        }
285
286    }
287    for my $key ( keys %textval ) {
288        my $value = $textval{$key};
289        if (($key eq "name") or ($key=~/^name:/)) {
290            if ($updateName) {
291                $tag.=' <tag k="'.$key.'" v="'.$value.'" />'."\n";
292            }
293            $tag.=' <tag k="openGeoDB:'.$key.'" v="'.$value.'" />'."\n";
294        } else {
295            $tag.=' <tag k="'.$key.'" v="'.$value.'" />'."\n";
296        }
297       
298    }
299    if (defined($textval{"openGeoDB:is_in_loc_id"})) {
300#       print "ISIN: ".$textval{"openGeoDB:is_in_loc_id"}."\n";
301        my $isinval="";
302        if (defined($is_in{$textval{"openGeoDB:is_in_loc_id"}})) {
303            $isinval=$is_in{$textval{"openGeoDB:is_in_loc_id"}};
304        } else {
305            my $bla=$textval{"openGeoDB:is_in_loc_id"};
306            my $ibla=$bla;
307            while ($bla > -1) {
308                $sthText->execute($bla);
309                $bla=-1;
310                while ( my @texterg= $sthText->fetchrow_array() ) {
311                    my $key=$texterg[0];
312                    my $value=$texterg[1];
313                    utf8::encode($value);
314                    my $locale=$texterg[2];
315                    my $nativelang=$texterg[3];
316                    my $defaultname=$texterg[4];
317                    if (defined($osmOGDB{$key})) {
318                        $key=$osmOGDB{$key};
319                    } else {
320                        $key='openGeoDB:'.$key;
321                    }
322                    if (defined($defaultname) and ($defaultname eq "0")) {
323                        $key.=":".$locale;
324                    }
325                    if ($key eq "openGeoDB:is_in_loc_id") {
326                        $bla=$value;
327                    }
328                    if ($key eq "name") {
329                        if ($isinval ne "") {
330                            $isinval="$isinval,$value";
331                        } else {
332                            $isinval=$value;
333                        }
334                    }
335                }
336            }
337            $isinval=~s/Hamburg,Freie und Hansestadt Hamburg,Hamburg/Freie und Hansestadt Hamburg/;
338            $is_in{$ibla}=$isinval;
339        }
340        if (defined($isinval)) {
341            if ($updateIsIn) {
342                $tag.=' <tag k="is_in" v="'. $isinval.'" />'."\n";
343            }
344            $tag.=' <tag k="openGeoDB:is_in" v="'. $isinval.'" />'."\n";
345        } else {
346            die($locid);
347        }
348        if (defined($textval{'name'})) {
349            $is_in{$locid}=$textval{'name'}.",".$isinval;
350            $is_in{$locid}=~s/Hamburg,Freie und Hansestadt Hamburg,Hamburg/Freie und Hansestadt Hamburg/;
351        }
352
353   
354    } else {
355        if (defined($textval{'name'})) {
356            $is_in{$locid}=$textval{'name'};
357        }
358    }
359
360    my $population="";
361    while ( my @poperg = $sthPop->fetchrow_array() ){
362        $population=$poperg[0];
363    }
364    if ($population ne "") {
365        if ($updatePopulation) {
366            $tag.=' <tag k="population" v="'.$population.'" />'."\n";
367        }
368        $tag.=' <tag k="openGeoDB:population" v="'.$population.'" />'."\n";
369    }
370
371    my $place="";
372    my $geodbPlace="";
373    if (defined($osmTag{"place"})) {
374        $place=$osmTag{"place"};
375    }
376    if ($place eq "") {
377        while ( my @locerg = $sthLoc->fetchrow_array() ){
378            my $id=$locerg[0];
379            if ($id == 100100000) {
380                $place="continent";
381                $geodbPlace="continent";
382            } elsif ($id == 100200000) {
383                $place="country";
384                $geodbPlace="country";
385            } elsif ($id == 100300000) {
386                $place="state";
387                $geodbPlace="state";
388            } elsif ($id == 100400000) {
389                $place="county";
390                $geodbPlace="county";
391            } elsif ($id == 100500000) {
392                $place="region";
393                $geodbPlace="region";
394            } elsif ($id == 100600000) {
395                $geodbPlace="political_structure";
396            } elsif ($id == 100700000) {
397                $geodbPlace="locality";
398            } elsif ($id == 100800000) {
399                $geodbPlace="postal_code_area";
400            } elsif ($id == 100900000) {
401                $geodbPlace="district";
402                $place="suburb";
403            } else {
404                $geodbPlace=$id;
405            }
406       
407        }
408    }
409    if ($geodbPlace ne "") {
410        $tag.=' <tag k="openGeoDB:location" v="'.$geodbPlace.'" />'."\n";   
411    }
412
413    if ($place eq "") {
414
415        my $typ=$textval{$osmOGDB{"400300000"}};
416        if (!defined($typ)) {
417        } elsif ($typ=~/Stadtteil/) {
418            $place="suburb";
419        } elsif ($typ=~/stadt/i) {
420            if ($population eq "") {
421                $place="town";
422            } elsif ($population>100000) {
423                $place="city";
424            } else {
425                $place="town";
426            }
427        } elsif ($typ=~/[Gg]emeinde/i) {
428            $place="village";
429        } elsif ($population eq "") {
430            # do nothing
431        } elsif ($population>100000) {
432            $place="city";
433        } elsif ($population>10000) {
434            $place="town";
435        } elsif ($population>30) {
436            $place="village";
437        } else {
438            $place="hamlet";
439        }
440    }
441    if ($updatePlace) {
442        if ($place ne "") {
443            $tag.=' <tag k="place" v="'.$place.'" />'."\n";
444        } else {
445            $tag.=' <tag k="place" v="FIXME" />'."\n";
446        }
447    }
448
449
450    $tag.=' <tag k="created_by" v="'.$progname.$version.'" />'."\n";
451    $tag.=' <tag k="openGeoDB:version" v="'.$dbversion.'" />'."\n";
452
453    if ($autoUpdate eq "") {
454        $autoUpdate="openGeoDB:NONE";
455    }
456    $tag.=' <tag k="openGeoDB:auto_update" v="'.$autoUpdate.'" />'."\n";
457   
458
459   
460    if (defined($lat)) {
461        if ($NodelocIdHash{$locid}>-1) {
462            print '<node id="'.$NodelocIdHash{$locid}.'" visible="true" lat="'."$lat\" lon=\"$lon\" action=\"modify\" $timestamp>\n$tag</node>\n";
463        } else {
464            print '<node id="'.$NodelocIdHash{$locid}.'" visible="true" lat="'."$lat\" lon=\"$lon\" >\n$tag</node>\n";
465        }
466    }
467    $found=0;
468    $sthParts->execute($locid);
469    if (defined($RelationlocIdHash{$locid})) {
470        print "<relation id=\"".$RelationlocIdHash{$locid}."\" visible='true'>\n";
471        print $tag;
472        if (defined($NodelocIdHash{$locid})) {
473            print " <member type='node' ref=\"$NodelocIdHash{$locid}\" role='this' />\n";
474        }
475        while ( my @partserg = $sthParts->fetchrow_array() ){
476            if ((defined($NodelocIdHash{$partserg[0]})) or (defined($RelationlocIdHash{$partserg[0]}))) {
477                if (defined($NodelocIdHash{$partserg[0]})) {
478                    print " <member type='node' ref=\"$NodelocIdHash{$partserg[0]}\" role='child' />\n";
479                }
480                if (defined($RelationlocIdHash{$partserg[0]})) {
481                    print " <member type='relation' ref=\"$RelationlocIdHash{$partserg[0]}\" role='child' />\n";
482                }
483            }
484        }
485
486        print "</relation>\n";
487    }
488
489}
490
491# Datenbank-Verbindung beenden
492$dbh->disconnect;
493print "</osm>\n";
Note: See TracBrowser for help on using the repository browser.