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";
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Talk-de mailing list [email protected] http://lists.openstreetmap.org/listinfo/talk-de

