# Jan Tappenbeck (OSM-User: Lübeck) ######################### # Historie ######################### # 2014-04-26 JT erste Version # ######################### # ToDo ######################### package OSM::Tree::WayMerger2 ; use OSM::Tree::Helper; use strict; use warnings; use Data::Dumper; # JT Log-File-PM use Log::File; use OSM::osm_jt ; #paketbasis von jan tappenbeck # CHANGELOG: # # 2010-04-24 JT creater # # use base qw (Exporter AutoLoader); our $version='0.1'; our @EXPORT = qw (osmtree_waymerger ) ; ######################################################### # start ######################################################### #our $server='http://www.openstreetmap.org'; ######################################################################## # PRIVATE FUNCTIONS #################################################### ######################################################################## # private sub to check osm_tree_objects sub _is_osm_tree_obj { my $object=shift; # haben wir etwas return 0 if(! defined($object) || !ref($object) ); # ist es sein OSM::Tree Objekt? # ist der String kürzer als neun Zeichen? # "OSM::Tree" ist genau 9 Zeichen lang return 0 if(length(ref($object)) < 9); # ich schneide die ersten 9 Zeichen raus # und prüfe ob sie "OSM::Tree" entsprechen return 0 if(! substr(ref($object), 0, 9) eq 'OSM::Tree' ); # kennt es die Methoden "id" und "type"? return 0 if(!$object->can('id') || !$object->can('type')); return 1; } # # # search a possible area to connect to node X # sucht nach einem AREA das einen übergebenen Node besitzt - egal ob am Anfang oder Ende # Rückgabe ist das betreffende Object sub _search_area { my ($search_id , @area_objects) = @_; my $found_object = undef; #print "\n----- _search_area ----------\n"; #print "search Node-Id: ".$search_id."\n"; #print "Dumper of area_objects: \n"; #print Dumper(@area_objects); #print "\n"; for my $ele_area (@area_objects){ my $ele_area_obj = $ele_area->[0]; my @id_of_area = osmtree_get_node_list_id($ele_area_obj); # suchen nach search_id in der Liste #print "name: ".$ele_area_obj->tag('note')->value()."\n" if $ele_area_obj->has_tag('note'); if(in_array(\@id_of_area,$search_id)==1){ $found_object = $ele_area_obj; }#end-in_array }#end-for return $found_object; };#end-_search_area # # # delete found AREA-Objekt from Analyze-List sub _del_area_from_list { my ($del_id, @data) = @_; my @new_data= (); for my $data_obj (@data){ print "-- _del_area_from_list: ".$del_id." ----\n"; if ($data_obj->[0]->id() ne $del_id){ push(@new_data, $data_obj); }#endif }#end-for return @data; };#end-_del_area_from_list ######################################################################## # PUBLIC FUNCTIONS ##################################################### ######################################################################## ######################################################### # WayMerger ######################################################### =item osmtree_waymerger() XXXX request: I ... osmtree-obj I ... zoomlevel - default 16 I ... baseurl of mal - default http://www.openstreetmap.org result: html-Source or " " =cut sub osmtree_waymerger { waymerger(@_); } sub waymerger { my ($log, @data) = @_; # my $log = shift; # my @data = shift; my $superdumper = 1; if ($superdumper == 1){ print "#############################\n"; print "# osmtree_waymerger #\n"; print "#############################\n"; } #print Dumper \@data; # Liste der auszuwertenden Elemente # Wegeelemente my @ways4track = (); # Flächen und geschlossene Kreisverkehr my @areas4track = (); print "------ Elemente-Analyse-Schleife ------\n"; for my $ele_way (@data){ print "--------------------------\n" if ($superdumper == 1); #print Dumper(osmtree_get_way_id_first($ele_way)); #print Dumper(osmtree_get_way_id_first($ele_way,1)); print "WayElement: ".$ele_way->id()."\n" if ($superdumper == 1); my $way_firstnode = osmtree_get_way_id_first($ele_way,1); print "FIRST Way-Punkt: ".$way_firstnode."\n" if ($superdumper == 1); $log->doublewrite("Error find first node in way: ".$ele_way->id()) if (not defined $way_firstnode); # letzter Punkt my $way_lastnode = osmtree_get_way_id_last($ele_way,1); print "LAST Way-Punkt: ".$way_lastnode."\n" if ($superdumper == 1); # erstellen einer Liste für das Objekt my @element_data = ($ele_way, $way_firstnode, $way_lastnode); print "CLOSE?: ".osmtree_geo_check_close_way($ele_way)."\n" if ($superdumper == 1); # anhängen der Liste an die Element-Liste if (osmtree_geo_check_close_way($ele_way)==1){ print "--- area\n" if ($superdumper == 1); push(@areas4track,\@element_data); } else { print "--- way\n" if ($superdumper == 1); push(@ways4track,\@element_data); } }#end-for - ele_way print "------ der Bestand ist analysiert ------\n"; my @ways4track2analyze = @ways4track; my @areas4track2analyze = @areas4track; $log->doublewrite("-- suchen der Anschluss-Elemente ---"); #$log->doublewrite("-- suchen der Anschluss-Elemente ---"); if ($superdumper == 1){ foreach my $way_data (@ways4track2analyze){ print "0-ID... ".$way_data->[0]->id()."\n"; print "1... ".$way_data->[1]."\n"; print "2... ".$way_data->[2]."\n"; #foreach my $way_parameter (@$way_data){ # print $way_parameter."\n"; #} } }#end-superdumper my @superway_id_result = (); print "--- vor der such-schleife - anzahl durchläufe: ".scalar(@ways4track2analyze)."\n"; while (0 < scalar (@ways4track2analyze)){ # entfernen des ersten Elementes in der Liste my @first_way = @{ shift @ways4track2analyze}; my $first_obj = $first_way[0]; my $superway_start = $first_way[1]; my $superway_end = $first_way[2]; my $FirstObjType = 'way'; my $LastObjType = 'way'; my $FirstObj = undef; my $LastObj = undef; $log->doublewrite("\n\n**** hier faengt alles an fuer einen neuen Superway ****"); #$log->doublewrite("note: ".$first_obj->tag('note')->value()) if $first_obj->has_tag('note'); $log->doublewrite("---------- Anschluss-Element suche fuer ...."); $log->doublewrite("wayID: ".$first_obj->id()." - fromID ".$superway_start." toID ".$superway_end); #print "--- dumper ----\n" if ($superdumper == 1); my @superway_id = osmtree_get_node_list_id($first_obj); #print Dumper \@superway_id if ($superdumper == 1); # hier wird die Anzahl von Verknüpfungen geloggt # gleichzeitig wird darüber die innere Merge-Schleife gesteuert # wird immer noch ein Merge durchgeführt, dann folgt immer noch ein Durchlauf my $counter_of_merge = -1; print "#### jetzt wird passendes gesucht ####\n"; my @ways4track2analyze_rest; print "****************************************\n" if ($superdumper == 1); # durchlaufen der vorhandenen Ways um nach einem passenden Anschluss zu suchen #$counter_of_merge = 1; # reset while ($counter_of_merge > 0 || $counter_of_merge == -1){ $log->doublewrite("\n\n++++++++++ Durchlauf ++++++++++"); $counter_of_merge = 0; @ways4track2analyze_rest = (); foreach my $data (@ways4track2analyze){ $log->doublewrite("===== naechtes Element ====="); # Daten ermitteln my $current_obj = $data->[0]; my $current_start = $data->[1]; my $current_end = $data->[2]; print "wayID: ".$current_obj->id()." - fromID: ".$current_start." toID: ".$current_end."\n" if ($superdumper == 1); print "Superway - first: ".$superway_start." - end: ".$superway_end."\n" if ($superdumper == 1); # bevor das nächste Way-Element untersucht werden kann ist zu klären welcher Elementtype vorab steht. # ist es ein Way, dann ist alles ok # ist es ein AREA, dann ist zu prüfen, ob vom current-objekt etwas zum zuvor ermittelten Kreis passen würde # dann kann der nächste Way gesucht werden # BEDINGUNG: AREA schließen nicht aneinandern !!!!!!!!! # untersuchtes passt HINTER das aktuelle in Standardrichtung #print "aktuelle Element-Node-ID\n"; my @node_list_id = osmtree_get_node_list_id($current_obj); #print Dumper \@node_list_id; if ($superway_end == $current_start) { $log->doublewrite("action:= nur anhaengen ###"); shift @node_list_id; push @superway_id, @node_list_id; $superway_end = $current_end; $LastObjType = 'way'; $LastObj = $current_obj; $counter_of_merge++; $log->doublewrite("neuer Superway - first: ".$superway_start." - end: ".$superway_end); $log->doublewrite("--> Ergaenzung"); print Dumper \@node_list_id if ($superdumper == 1); } elsif ($superway_start == $current_end){ $log->doublewrite("action:= vorstellen ###"); pop @node_list_id; unshift @superway_id, @node_list_id; $superway_start = $current_start; $FirstObjType = 'way'; $FirstObj = $current_obj; $counter_of_merge++; $log->doublewrite("neuer Superway - first: ".$superway_start." - end: ".$superway_end); $log->doublewrite("--> Ergaenzung"); print Dumper \@node_list_id if ($superdumper == 1); print "----- vorstellen fertig ---\n" if ($superdumper == 1); # jetzt schauen, ob ggf. das current_obj reverse passen würde } elsif ($superway_end == $current_end){ $log->doublewrite("action:= reverse anhaengen ###"); @node_list_id = reverse @node_list_id; shift @node_list_id; push @superway_id, @node_list_id; $superway_end = $current_start; $LastObjType = 'way'; $LastObj = $current_obj; $log->doublewrite("neuer Superway - first: ".$superway_start." - end: ".$superway_end); $log->doublewrite("--> Ergaenzung"); print Dumper \@node_list_id if ($superdumper == 1); $counter_of_merge++; } elsif ($superway_start == $current_start){ $log->doublewrite("action:= reverse vorstellen ###"); shift @node_list_id; @node_list_id = reverse @node_list_id; unshift @superway_id, @node_list_id; $superway_start = $current_end; $FirstObjType = 'way'; $FirstObj = $current_obj; $counter_of_merge++; $log->doublewrite("neuer Superway - first: ".$superway_start." - end: ".$superway_end); $log->doublewrite("--> Ergaenzung"); print Dumper \@node_list_id if ($superdumper == 1); # nachdem keine Linie paßt werden die AREA untersucht # jetzt wird noch geprüft, ob ein AREA passen würde # das ist immer der Fall, wenn ein AREA gefunden wurde und damit der # Rückgabert ungleich -1 ist. # am Ende anknüpfend } else { print "action:= >>>> kein Way-Anschluss gefunden !\n" if ($superdumper == 1); push(@ways4track2analyze_rest, $data); # wenn jetzt kein passender Way gefunden wurde, dann wird gepüft, ob eventuell AREA passen würden # diese Werte werden ausgewertet, wenn keine Linie gefunden wurde my $obj_area_current_start = _search_area($superway_start, @areas4track2analyze); my $obj_area_current_end = _search_area($superway_end, @areas4track2analyze); print "---- mögliche areaID an den bestehenden Superway ----\n"; if !(defined($obj_area_current_start)){ print "id_area_current_start: *nicht gefunden!*\n"; } else { print "id_area_current_start: ".$obj_area_current_start->id()."\n"; } if !(defined($obj_area_current_end)){ print "id_area_current_end: *nicht gefunden!*\n"; } else { print "id_area_current_end: ".$obj_area_current_end->id()."\n"; } # am Anfang anknüpfend if (defined($obj_area_current_start)) { $log->doublewrite("action:= Area am ANFANG - id: ".$superway_start); # Todo: AREA-Element aus Liste entfernen - > $xObj zuweisen @areas4track2analyze = _del_area_from_list($obj_area_current_start->id(), @areas4track2analyze); $FirstObjType = 'area'; $FirstObj = $obj_area_current_start; # in dieser Situation wird die $superway_start nicht geändert # an das Ende stellend } elsif (defined($obj_area_current_end)) { $log->doublewrite("action:= area am ENDE - id: ".$superway_end); # Todo: AREA-Element aus Liste entfernen - > $xObj zuweisen @areas4track2analyze = _del_area_from_list($obj_area_current_end->id(), @areas4track2analyze); $LastObjType = 'area'; $LastObj = $obj_area_current_end; # in dieser Situation wird die $superway_end nicht geändert } #endif-wenn kein way gepaßt hat print "--------------------------------------------\n" if ($superdumper == 1); } print "------ aktueller Stand\n" if ($superdumper == 1); print Dumper \@superway_id if ($superdumper == 1); }#end-foreach - ways4track2analyze @ways4track2analyze = @ways4track2analyze_rest; print "counter_of_merge: ".$counter_of_merge."\n" if ($superdumper == 1); print "--- Element nach durchlauf ---\n" if ($superdumper == 1); print Dumper \@superway_id if ($superdumper == 1); }#end-while - $counter_of_merge push @superway_id_result, \@superway_id; @ways4track2analyze = @ways4track2analyze_rest; print "--- nicht zugeordnete ways ---\n" if ($superdumper == 1); #print Dumper \@ways4track2analyze_rest; if ($superdumper == 1){ print "\n\n"; foreach my $data (@ways4track2analyze_rest){ print "0-ID... ".$data->[0]->id()."\n"; print "1... ".$data->[1]."\n"; print "2... ".$data->[2]."\n"; } }#end-superdumper }#end-while - neuer Superway return @superway_id_result; } 1;