Am 25.07.2010 13:32, schrieb Jan Tappenbeck:
> Das Einpassen dieser Bilder in JOSM etc gestaltet sich auf Grund der
> Auflösung relativ mühsam und schwierig.
> 
> Hat das schon einmal einer von Euch gemacht - gibt es einen Tipp oder
> gar bessere Alternativen ??

Hallo Jan,

Ja, ich hab vor einiger Zeit für Rheinland-Pfalz die Gemeindegrenzen
aus der zugehörigen SVG-Datei in ein Linien-Netz im OSM-Format
übertragen. Das zugehörige (Anfänger-) Perl-Skript habe ich mal angehängt.
Für das Eintragen der Grenzen habe ich in JOSM dann stets per Hand die
entsprechenden Linien aus dem Netz kopiert und in die bestehenden
Grenzen eingepasst. Bzw. mache ich das zur Zeit immer noch. ;)

Alternativ könnte man auch mit dem Pic-Layer-Plugin für JOSM arbeiten.

Beste Grüße,
Rainer
#!/usr/local/bin/perl -w

use strict;
use XML::Simple;
use Data::Dumper;

# Datei für die Ausgabe
my $datei;      
if ($ARGV[0] =~ /(.*)\..*/) {   # Dem Namen der Quelldatei...
        $datei = $1.".osm";}            # wird '.osm' angehängt


my $xml_file = $ARGV[0];                # übergebene Quelldatei

my $svg = XMLin($xml_file,KeyAttr => [ 'id' ]);#, ForceArray => 1 ,KeyAttr => [ 
'id' ]);        # Hash-Ref-Präsentation der Quelldatei einlesen
#print Dumper($svg);

my $counter = -1;       # Counter für IDs; neue Objekte bekommen negative ID
my %points;                     # Hash für die einzelnen Punkte
my %ways;                       # Array für die Wege
my $bound = 9;  # Toleranz-Bereich für das Zusammenfassen von einzelnen Punkten

my $Xt0 = 6.1123607;
my $Xtmax = 8.5081187;
my $Yt0 = 48.9664903;
my $Ytmax = 50.9423256;

my $op = 0.00001;
# my $xoffset = ($svg -> {'metadata'} -> {'sfw'} -> {'sliceSourceBounds'} -> 
{'height'}); 
# my $yoffset = ($svg -> {'metadata'} -> {'sfw'} -> {'sliceSourceBounds'} -> 
{'width'}); 
my $xoffset = 0;#(split(/p/,($svg -> {'height'})))[0] * 1000; 
my $yoffset = 0;#(split(/p/,($svg -> {'width'})))[0] * 1000; 
my $xmove = $Xt0;#6.0598186363180273655729182125389;
my $ymove = $Yt0;#48.96675;
my $xscale = 1;#0.22094002495090722302913205119244;
my $yscale = 1;#0.14253259328335299271675824592552;

# {Node id=323674752 version=1 V lat=50.9399869,lon=7,7863774}
# {Node id=-892413 version=0 V lat=13,84411,lon=7,7336}-1,9527
#1,9732369      -0,4135326
#{Node id=323819272 version=2 V lat=50.2192956,lon=6,166803}                    
{Node id=660910430 version=1 V lat=49.7678655,lon=8,4744133} 2,3076103
#{Node id=-1004791 version=0 V lat=8,84328,lon=0,44394}                         
{Node id=-1002671 version=0 V lat=5.62563,lon=10,88845}10,44451
# {Node id=323465585 version=1 V lat=50.9403419,lon=7.8132735}
# {Node id=-879087 version=0 V lat=13.84454,lon=7.81777}

#print $xoffset,", ",$yoffset,"\n";

#my @borders = (@{$svg -> {'switch'} -> {'g'} -> {'g'} -> {'Gemeinden_1_'} -> 
{'polygon'}});    # die Gemeindeumrisse aus der Quelldatei in Array einlesen

my @borders = (@{$svg -> {'g'} -> {'Gemeinden_1_'} -> {'polygon'}}); 
#Ortsgemeinden RLP

# my @borders = (@{$svg -> {'switch'} -> {'g'} -> {'g'}});
# foreach my $hashref (@borders){
        # if ($$hashref{'id'} eq 'Gemeinden_1_'){
                # @borders = (@{$hashref -> {'polygon'}});
                # last;
                # }
        # }
#                          @{$svg -> {'switch'} -> {'g'} -> {'g'} -> 
{'Kreise_Borders'} -> {'polygon'}});

# Gemeindegrenzen einlesen
print "Punkte & Wege einlesen\n";
my %roughpoints;
my %simpleways;
my %pointcount;
foreach my $polygon (@borders){                 # aktuelle Grenze
        my $points = $$polygon{'points'};       # String mit Grenzpunkten 
einlesen
        my @points = split(/\s+/,$points);      # Punkte an den Leerzeichen 
aufteilen
        push (@points,$points[0]);                      # ersten Eintrag 
wiederholen um Grenzeverlauf zu schließen
        
        # Punkte & Wege einlesen        
        
        for(my $i = 0;$i < @points;$i++){

                #Eng beieinander liegende Punkte zusammen fassen
                my @tp = split(/,/,$points[$i]);                                
                        # aktuellen Punkt in Koordinaten aufteilen
                                                                                
                        # temporäre Variable für Punktereferenz
                for (0,1) {$tp[$_] = $tp[$_] * 1000;}
                if ($tp[0] > $xoffset) {$xoffset = $tp[0];}
                if ($tp[1] > $yoffset) {$yoffset = $tp[1];}
                my @compare = @tp;
                push (@compare,($tp[0]  + $bound,
                                          $tp[1]  + $bound,
                                          $tp[0]  - $bound,
                                          $tp[1]  - $bound));
                foreach my $tp (@compare){chop $tp;}
                #print $points[$i],"\n";
                #print "\t",@compare,"\n";
                my $tp = undef;
                for my $k1 (0,2,4){
                        for my $k2 (1,3,5){
                                my $pkey = ($compare[$k1]).($compare[$k2]);
                                #print "\t",$pkey,"\n";
                                if (defined($roughpoints{$pkey})){
                                        $tp = $roughpoints{$pkey};
                                        last;
                                        }
                                }
                        }
                        
                if (defined($tp)){                                              
                                        # ist der Punkt vorhanden...
                        $points[$i] = $tp;                                      
                                        # ...benutzen wir diesen
                        }       
                else {                                                          
                                                # falls nicht...
                        $points{$counter} = \...@tp;                            
                                # ...legen wir neuen Punkt mit den Koordinaten 
an.
                        $points[$i] = $counter;                                 
                                # wir merken uns die Referenz
                        $roughpoints{($compare[0]).($compare[1])} = $counter;
                        $counter--;                                             
                                                # und drehen den Zähler für 
die IDs weiter
                        }
                
                # foreach my $otherpoint (keys (%points)){                      
                # Suche nach bereits erfassten Punkten im Toleranzbereich
                        # if (($tp[0] > ($points{$otherpoint}[0] - $bound)) &&
                                # ($tp[0] < ($points{$otherpoint}[0] + $bound)) 
&&
                                # ($tp[1] > ($points{$otherpoint}[1] - $bound)) 
&&
                                # ($tp[1] < ($points{$otherpoint}[1] + $bound))
                                # ){
                                # $tp = $otherpoint;                            
                                        # wurde ein passender Punkt gefunden: 
Referenz merken...
                                # last;                                         
                                                # ...und Suche beenden
                                # }
                        # }
                # if (defined($tp)){                                            
                                        # ist der Punkt vorhanden...
                        # $points[$i] = $tp;                                    
                                        # ...benutzen wir diesen
                        # }     
                # else {                                                        
                                                        # falls nicht...
                        # $points{$counter} = \...@tp;                          
                                # ...legen wir neuen Punkt mit den Koordinaten 
an.
                        # $points[$i] = $counter;                               
                                        # wir merken uns die Referenz
                        # $counter--;                                           
                                                # und drehen den Zähler für 
die IDs weiter
                        # }
                
                #Doppelte einfache Wege entfernen
                #my $twice = '';                                                
                                                # boolean ist zuächst mal false
                if ($i > 0){                                                    
                                        # Startknoten lassen wir aus 
(=Endknoten)
                        # foreach (@ways){
                                # if ((($$_[0] eq $points[$i-1])                
                                # ist der Weg vorhanden...
                                                # && ($$_[1] eq $points[$i])) 
                                        # || 
                                        # (($$_[0] eq $points[$i])              
                                # ...bzw. in entgegen gesetzter Richtung...
                                                # && ($$_[1] eq $points[$i-1])))
                                        # {$twice = '1';last;}                  
                                # ...merken wir uns das und verlassen die Suche
                                # }
                        # if ($twice){next;}                                    
                                        # Ist der Weg vorhanden, vergessen wir 
den aktuellen...
                        my $waykey1 = $points[$i-1].",".$points[$i];
                        my $waykey2 = $points[$i].",".$points[$i-1];
                        if ((defined($simpleways{$waykey1}))
                                 || (defined($simpleways{$waykey2}))){next;}
                        else{
                                $ways{$counter} = [$points[$i-1],$points[$i]];  
                # ansonsten legen wir einen neuen Weg an
                                $simpleways{$waykey1} = $counter;
                                
                                #print "Weg ",$counter,"\n";
                                for my $tp ($points[$i-1],$points[$i]){
                                        if (defined($pointcount{$tp})){
                                                
push(@{$pointcount{$tp}},$counter);
                                                }
                                        else {$pointcount{$tp} = [$counter];}
                                #       print "\t",$tp,"\n";
                                        }
                                $counter--;
                                }
                        
                        }
                }
        #push (@polygon_matrix,[...@points]);
        }



# Links auf Knoten zählen für das Zusammenfassen von Wegen
# print "Links auf Knoten zählen\n";
# my %pointcount;

# foreach my $way (@ways){ #jeden Weg betrachten
        # foreach my $node (@$way){
                # if (defined($pointcount{$node})){$pointcount{$node} = 
$pointcount{$node} + 1;}        # vorhandenen Zähler erhöhen oder...
                # else {$pointcount{$node} = 1;}                                
                                                                        # 
...Zähler anlegen
                # }
        # }

# my $onecount = 0;
# foreach my $point (keys (%pointcount)){
        # if (@{$pointcount{$point}} == 1){$onecount++}
        # #print $point," : ",@{$pointcount{$point}},"\n";
        # }
# print $onecount,"\n"; 
# Wege zusammenfassen zu Einzelgrenzen zwischen zwei Gemeinden
print "Wege zusammenfassen\n";


foreach my $point (keys (%pointcount)){
        my $begin;
        if (@{$pointcount{$point}} < 3){
                #print $point,"\n";
                my $w1 = (@{$pointcount{$point}}[0]);
                #print "\t",@{$ways{$w1}},",";
                my $w2 = (@{$pointcount{$point}}[1]);
                #print @{$ways{$w2}},"\n";
                if (@{$ways{$w1}}[0] eq $point){
                        splice (@{$ways{$w1}},0,1);
                        $begin='1';
                        }
                else{#elsif (@{$ways{$w1...@{$ways{$w1}}-1] eq $point){
                        pop(@{$ways{$w1}});
                        $begin='';
                        }
                if (@{$ways{$w2}}[0] eq $point){
                        if ($begin){
                                unshift(@{$ways{$w2}},reverse(@{$ways{$w1}}));
                                }
                        else{
                                unshift(@{$ways{$w2}},@{$ways{$w1}});
                                }
                        }
                else{#elsif (@{$ways{$w2...@{$ways{$w1}}-1] eq $point){
                        if ($begin){
                                push (@{$ways{$w2}},@{$ways{$w1}});
                                }
                        else{
                                push (@{$ways{$w2}},reverse(@{$ways{$w1}}));
                                }
                        }
                #print "\t",@{$ways{$w1}},",";
                #print @{$ways{$w2}},"\n";
                #print "\t";
                # foreach (@{$ways{$w1}})
                        # {print $_,",";}
                # print "\n";   
                
                my $pc;
                if ($begin){$pc = pop(@{$ways{$w1}});}
                else {$pc = @{$ways{$w1}}[0];}
                for my $tway (@{$pointcount{$pc}}){
                        #print @{$pointcount{$pc}},"\t",$tway,"\n";
                        #if 
(!defined(@{$pointcount{$pc}}[$tway])){print"ARRGH!tway\n";}
                        if ($tway eq $w1)
                                {$tway = $w2;}
                        }
                        
                delete $ways{$w1};
                # for (my $i = 0; $i < @ways; $i++){
                        # if (!defined($ways[$i])){next;}
                        # for my $h (0,@{$ways[$i]}-1){
                                # if (($ways[$i][$h]) == $point){
                                        # for (my $f = $i+1; $f < @ways; $f++){
                                                # if 
(!defined($ways[$f])){next;}
                                                # for my $g (0,@{$ways[$f]}-1){
                                                        # if ($ways[$f][$g] == 
$point){
                                                                # splice 
(@{$ways[$i]},$h,1);
                                                                # if ($g == 0){
                                                                        # if 
($h == 0) {unshift(@{$ways[$f]},reverse(@{$ways[$i]}));}
                                                                        # else 
{unshift(@{$ways[$f]},@{$ways[$i]});}
                                                                        # } 
                                                                # else {
                                                                        # if 
($h == 0){push (@{$ways[$f]},@{$ways[$i]});}
                                                                        # else 
{push (@{$ways[$f]},reverse(@{$ways[$i]}));}
                                                                        # }
                                                                # splice 
(@ways,$i,1);
                                                                # #$ways[$i] = 
undef; #Element löschen
                                                                # $i--; 
#Zähler verringern, da Array kleiner
                                                                # $gefunden = 
'1';
                                                                # last;
                                                                # }
                                                        # }
                                                # if ($gefunden){last;}
                                                # }
                                        # }
                                # if ($gefunden){last;}
                                # }
                        # if ($gefunden){last;}
                        # }
                }
}

$xoffset = $xoffset * $op;
$yoffset = $yoffset * $op;


my $At = $Xtmax - $Xt0;
my $Ct = $Ytmax - $Yt0;
my $Bt = 90 - $Yt0;

my $Et = $At - $At*$Ct/$Bt;

my $As = $xoffset;
my $Es = $As*$Et/$At;

$xscale = ($At/$xoffset);
$yscale = ($Ct/$yoffset);

# Ausgabe als OSM/XML-Datei

open(SCHREIBEN,"> $datei")                                                      
                        # Datei öffnen
  or die "Fehler beim Öffnen von Datei: $!\n";

# Schreiben
print "Schreiben\n";
print SCHREIBEN "<?xml version='1.0' encoding='UTF-8'?>";               # 
Header schreiben
print SCHREIBEN "<osm version='0.6' generator='perl script'>";  # Root-Element 
öffnen

foreach (keys (%points)){                                                       
                        # Punkte schreiben
        my @tp = split(/,/,$_);
        my $x = ($points{$_}[0]) * $op;
        my $y = $yoffset - ($points{$_}[1]) * $op;
        #$x = ($As/2) * (2*$x/$As - 1) * ($Es/2 + ($As/2 - $Es/2) * (1 - 
$y/$yoffset));

        print SCHREIBEN "<node id='".$_."' visible='true' lat='".($y * $yscale 
+ $ymove)."' lon='".($x * $xscale + $xmove)."' />";
        }
        
foreach (keys (%ways)){                                                         
                                # Wege schreiben
        print SCHREIBEN "<way id='".$_."' visible='true'>";
    foreach my $point (@{$ways{$_}}){
                print SCHREIBEN "<nd ref='".$point."' />";
                }
        print SCHREIBEN "</way>";
        #$counter--;
        }
print SCHREIBEN "</osm>";                                                       
                        # Root-Element schließen

close(SCHREIBEN)                                                                
                                # Datei schließen
  or die "Fehler beim Schließen von Datei: $! \n";

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Talk-de mailing list
Talk-de@openstreetmap.org
http://lists.openstreetmap.org/listinfo/talk-de

Antwort per Email an