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

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

opengeodb2osm: Get Data directly from OSM api, first try, but not finished yet

File size: 11.0 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.4.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";
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
42$osmOGDB{"500100000"}="name";
43
44my %is_in;
45
46my $dbh = DBI->connect( 'dbi:mysql:'.$mysqldb, $mysqluser, $mysqlpw) ||
47     die "Kann keine Verbindung zum MySQL-Server aufbauen: $DBI::errstr\n";
48
49# Befehl fuer Ausfuehrung vorbereiten. Referenz auf Statement
50# Handle Objekt wird zurueckgeliefert
51
52my $sthRel=$dbh->prepare( 'select distinct text_val from geodb_textdata where text_type="400100000" ') ||
53     die "Kann Statement nicht vorbereiten: $DBI::errstr\n";
54my $sth = $dbh->prepare( 'SELECT distinct loc_id FROM geodb_textdata where loc_id>0 and loc_id!=100') ||
55     die "Kann Statement nicht vorbereiten: $DBI::errstr\n";
56my $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 
57     die "Kann Statement nicht vorbereiten: $DBI::errstr\n";
58my $sthOSM = $dbh->prepare('SELECT lat,lon FROM nodes WHERE id=?') ||
59     die "Kann Statement nicht vorbereiten: $DBI::errstr\n";
60
61my $where="";
62if ($uselat==1) {
63        $where.="where lat>=$minlat and lat<=$maxlat and lon>=$minlon and lon<=$maxlon";
64}
65
66
67
68
69
70my $sthNode = $dbh->prepare( 'SELECT distinct loc_id FROM geodb_coordinates '.$where ) ||
71     die "Kann Statement nicht vorbereiten: $DBI::errstr\n";
72
73if ($where ne "") {
74    $where.=" and loc_id=?";
75} else {
76    $where="where loc_id=?";
77}
78
79my $sthCoord = $dbh->prepare( 'SELECT lon,lat,valid_since,date_type_since,valid_until,date_type_until FROM geodb_coordinates '.$where ) ||
80     die "Kann Statement nicht vorbereiten: $DBI::errstr\n";
81
82
83my $sthText = $dbh->prepare('select text_type,text_val,text_locale,is_native_lang,is_default_name from geodb_textdata where loc_id=?');
84
85my $sthLoc = $dbh->prepare('select loc_type from geodb_locations where loc_id=?');
86my $sthPop = $dbh->prepare('select int_val from geodb_intdata where loc_id=? and int_type=600700000');
87
88my $sthParts = $dbh->prepare('select loc_id from geodb_textdata where text_type=400100000 and text_val=?');
89
90$sthOSMNode->execute ||
91     die "Kann Abfrage nicht ausfuehren: $DBI::errstr\n";
92my $oldlocid=-1;
93my $olddist;
94my $maxDist=10;
95my %OsmIdToNodeId;
96while ( my @ergebnis = $sthOSMNode->fetchrow_array() ){
97    my $locid=$ergebnis[0];
98    my $osmid=$ergebnis[1];
99    my $dist=$ergebnis[2];
100    if ($oldlocid != $locid) {
101        if ($oldlocid != -1) {
102            $OsmIdToNodeId{$oldosmid}=$oldlocid;
103        }
104        $olddist=$maxDist+2;
105    }
106    if (($dist<$maxDist) and ($dist<$olddist)) {
107        if (!(defined($OsmIdToNodeId{$osmid}))) {
108            $NodelocIdHash{$locid}=$osmid;
109        } 
110        $olddist=$dist;
111        $oldlocid=$locid;
112        $oldosmid=$osmid;
113    }
114}
115
116
117# Vorbereitetes Statement (Abfrage) ausfuehren
118$sthNode->execute ||
119     die "Kann Abfrage nicht ausfuehren: $DBI::errstr\n";
120
121$nodeid=-1;
122while ( my @ergebnis = $sthNode->fetchrow_array() ){
123    my $locid=$ergebnis[0];
124    if (!(defined($NodelocIdHash{$locid}))) {
125        $NodelocIdHash{$locid}=$nodeid;
126        $nodeid--;
127    }
128}
129$sthRel->execute ||
130     die "Kann Abfrage nicht ausfuehren: $DBI::errstr\n";
131
132while ( my @ergebnis = $sthRel->fetchrow_array() ){
133    my $locid=$ergebnis[0];
134    $RelationlocIdHash{$locid}=$nodeid;
135    $nodeid--;
136}
137
138
139
140# Vorbereitetes Statement (Abfrage) ausfuehren
141$sth->execute ||
142     die "Kann Abfrage nicht ausfuehren: $DBI::errstr\n";
143
144
145while ( my @ergebnis = $sth->fetchrow_array() ){
146   # Im Array @ergebnis steht nun ein Datensatz
147    my $locid=$ergebnis[0];
148
149    my $lat;
150    my $lon;
151
152   
153    $tag=' <tag k="openGeoDB:loc_id" v="'.$locid.'" />'."\n";
154    $sthCoord->execute($locid);
155    while ( my @corderg = $sthCoord->fetchrow_array() ){
156        $lat=$corderg[1];
157        $lon=$corderg[0];
158    }
159    $found=0;
160
161    my %osmTag=();
162    if (defined($NodelocIdHash{$locid}) and ($NodelocIdHash{$locid} >0)) {     
163        $osmContent = get($osmApiURL.$NodelocIdHash{$locid});
164        if (defined($osmContent)) {
165            @content=split(/\n/,$osmContent);
166            foreach my $line (@content) {
167                if (($line=~/node id=\"\d*\" lat=\"(.*)\" lon="(.*)" user="(.*)" visible="true"/) or ($line=~/node id=\"\d*\" lat=\"(.*)\" lon="(.*)" visible="true"/)) { 
168                   
169                   
170                    $lat=$1;
171                    $lon=$2;
172                    $tag.=' <tag k="opengeodb:lat" v="'.$lat.'" />'."\n";
173                    $tag.=' <tag k="opengeodb:lon" v="'.$lon.'" />'."\n";
174                    $found=1;
175
176                } elsif ($line=~/^\s*<tag k=\"(.*)\" v=\"(.*)\"\/>\s*$/) {
177                    my $k=$1;
178                    my $v=$2;
179                    $osmTag{$k}=$v;
180                    if (($k ne "created_by") and (!($k =~/^openGeoDB:/))){
181                        $tag.="$line\n";
182                    }
183                } elsif ($line=~/<?xml version=\"/) {
184                } elsif ($line=~/<osm version=\"/) {
185                } elsif ($line=~/^\s*<\/node>/) {
186                } elsif ($line=~/^\s*<\/osm>/) {
187                }else {
188                    warn("line: $line");
189                }
190            }
191        }
192
193    }
194    $sthText->execute($locid);
195    $sthLoc->execute($locid);
196    $sthPop->execute($locid);
197
198    my %textval;
199    while ( my @texterg = $sthText->fetchrow_array() ){
200        my $key=$texterg[0];
201        my $value=$texterg[1];
202        utf8::encode($value);
203        $value=~s/&/&amp;/g;
204        $value=~s/\"/&quot;/g;
205        my $locale=$texterg[2];
206        my $nativelang=$texterg[3];
207        my $defaultname=$texterg[4];
208        if (defined($osmOGDB{$key})) {
209            $key=$osmOGDB{$key};
210        } else {
211            $key='openGeoDB:'.$key;
212        }
213        if (defined($defaultname) and ($defaultname eq "0")) {
214            $key.=":".$locale;
215        }
216        if (defined $textval{"$key"}) {
217            $textval{$key}.=",".$value;
218        } else {
219            $textval{$key}=$value;
220        }
221
222    }
223    for my $key ( keys %textval ) {
224        my $value = $textval{$key};
225        $tag.=' <tag k="'.$key.'" v="'.$value.'" />'."\n";
226       
227    }
228    if (defined($textval{"openGeoDB:is_in"})) {
229#       print "ISIN: ".$textval{"openGeoDB:is_in"}."\n";
230        my $isinval="";
231        if (defined($is_in{$textval{"openGeoDB:is_in"}})) {
232            $isinval=$is_in{$textval{"openGeoDB:is_in"}};
233        } else {
234            my $bla=$textval{"openGeoDB:is_in"};
235            my $ibla=$bla;
236            while ($bla > -1) {
237                $sthText->execute($bla);
238                $bla=-1;
239                while ( my @texterg= $sthText->fetchrow_array() ) {
240                    my $key=$texterg[0];
241                    my $value=$texterg[1];
242                    utf8::encode($value);
243                    my $locale=$texterg[2];
244                    my $nativelang=$texterg[3];
245                    my $defaultname=$texterg[4];
246                    if (defined($osmOGDB{$key})) {
247                        $key=$osmOGDB{$key};
248                    } else {
249                        $key='openGeoDB:'.$key;
250                    }
251                    if (defined($defaultname) and ($defaultname eq "0")) {
252                        $key.=":".$locale;
253                    }
254                    if ($key eq "openGeoDB:is_in") {
255                        $bla=$value;
256                    }
257                    if ($key eq "name") {
258                        if ($isinval ne "") {
259                            $isinval="$value,$isinval";
260                        } else {
261                            $isinval=$value;
262                        }
263                    }
264                }
265            }
266            $is_in{$ibla}=$isinval;
267        }
268        if (defined($isinval)) {
269            $tag.=' <tag k="is_in" v="'. $isinval.'" />'."\n";
270        } else {
271            die($locid);
272        }
273        if (defined($textval{'name'})) {
274            $is_in{$locid}=$isinval.",".$textval{'name'};
275        }
276
277   
278    } else {
279        if (defined($textval{'name'})) {
280            $is_in{$locid}=$textval{'name'};
281        }
282    }
283
284    my $population="";
285    while ( my @poperg = $sthPop->fetchrow_array() ){
286        $population=$poperg[0];
287    }
288    if ($population ne "") {
289        $tag.=' <tag k="population" v="'.$population.'" />'."\n";
290        $tag.=' <tag k="openGeoDB:population" v="'.$population.'" />'."\n";
291    }
292
293    my $place="";
294    my $geodbPlace="";
295    if (defined($osmTag{"place"})) {
296        $place=$osmTag{"place"};
297    }
298    if ($place eq "") {
299        while ( my @locerg = $sthLoc->fetchrow_array() ){
300            my $id=$locerg[0];
301            if ($id == 100100000) {
302                $place="continent";
303                $geodbPlace="continent";
304            } elsif ($id == 100200000) {
305                $place="country";
306                $geodbPlace="country";
307            } elsif ($id == 100300000) {
308                $place="state";
309                $geodbPlace="state";
310            } elsif ($id == 100400000) {
311                $place="county";
312                $geodbPlace="county";
313            } elsif ($id == 100500000) {
314                $place="region";
315                $geodbPlace="region";
316            } elsif ($id == 100600000) {
317                $geodbPlace="political_structure";
318            } elsif ($id == 100700000) {
319                $geodbPlace="locality";
320            } elsif ($id == 100800000) {
321                $geodbPlace="postal_code_area";
322            } elsif ($id == 100900000) {
323                $geodbPlace="district";
324                $place="suburb";
325            } else {
326                $geodbPlace=$id;
327            }
328       
329        }
330    }
331    if ($geodbPlace ne "") {
332        $tag.=' <tag k="openGeoDB:location" v="'.$geodbPlace.'" />'."\n";   
333    }
334
335    if ($place eq "") {
336
337        my $typ=$textval{$osmOGDB{"400300000"}};
338        if (!defined($typ)) {
339        } elsif ($typ=~/Stadtteil/) {
340            $place="suburb";
341        } elsif ($typ=~/stadt/i) {
342            if ($population eq "") {
343                $place="town";
344            } elsif ($population>100000) {
345                $place="city";
346            } else {
347                $place="town";
348            }
349        } elsif ($typ=~/[Gg]emeinde/i) {
350            $place="village";
351        } elsif ($population eq "") {
352            # do nothing
353        } elsif ($population>100000) {
354            $place="city";
355        } elsif ($population>10000) {
356            $place="town";
357        } elsif ($population>30) {
358            $place="village";
359        } else {
360            $place="hamlet";
361        }
362    }
363    if ($place ne "") {
364        $tag.=' <tag k="place" v="'.$place.'" />'."\n";
365    } else {
366        $tag.=' <tag k="place" v="FIXME" />'."\n";
367    }
368
369
370    $tag.=' <tag k="created_by" v="'.$progname.$version.'" />'."\n";
371    $tag.=' <tag k="openGeoDB:version" v="'.$dbversion.'" />'."\n";
372
373    $tag.=' <tag k="openGeoDB:auto_update" v="population,is_in" />'."\n";
374   
375    $found=0;
376   
377    if (defined($lat)) {
378        print '<node id="'.$NodelocIdHash{$locid}.'" visible="true" lat="'."$lat\" lon=\"$lon\" >\n$tag</node>\n";
379    }
380    $found=0;
381    $sthParts->execute($locid);
382
383    while ( my @partserg = $sthParts->fetchrow_array() ){
384        if ((defined($NodelocIdHash{$partserg[0]})) or (defined($RelationlocIdHash{$partserg[0]}))) {
385            if ($found==0) {
386                defined($RelationlocIdHash{$locid}) or die("RelationLocId $locid");
387                print "<relation id=\"".$RelationlocIdHash{$locid}."\" visible='true'>\n";
388                $found++;
389                print $tag;
390                if (defined($NodelocIdHash{$locid})) {
391                    print " <member type='node' ref=\"$NodelocIdHash{$locid}\" role='this' />\n";
392                }
393
394            }
395            if (defined($NodelocIdHash{$partserg[0]})) {
396                print " <member type='node' ref=\"$NodelocIdHash{$partserg[0]}\" role='child' />\n";
397            }
398            if (defined($RelationlocIdHash{$partserg[0]})) {
399                print " <member type='relation' ref=\"$RelationlocIdHash{$partserg[0]}\" role='child' />\n";
400            }
401        }
402    }
403    if ($found>0) {
404        print "</relation>\n";
405    }
406}
407
408# Datenbank-Verbindung beenden
409$dbh->disconnect;
410print "</osm>\n";
Note: See TracBrowser for help on using the repository browser.