13
19
my $newids = -3000000; # we give new objects ids starting here
17
#my $current_parent_way; # when we split the way, keep track of where they came from
20
# we need to store all the ways after the first pass because we dont want to have to cut a way twice.
24
# just store the last node seen an used that.
26
my %rels; # the relationships
27
#mapping of old ways onto new
30
##### we look for two in a row.. cannot have that
32
my $QUOTE="[\\'\\\"]";
33
my %seen; # what have we emitted
36
38
$current_way = $id;
39
warn "setting current way:$current_way" if $debug;
45
warn "closing current way:$current_way" if $debug;
46
warn "Way $current_way contains" . join (",",@{$ways{$current_way}->{nodes}}) . "\n" if $debug;
42
48
$current_way=undef;
50
57
return int($checksum);
53
sub postprocess_node_in_way
56
# my $coords=$nodeids{$id};
57
# warn Dumper($coords);
58
# die "no coords for $id" unless $coords;
61
# my ($lat,$lon) =@{$coords};
62
# my $checksum = checksum($lat,$lon);
63
# $current_way->{checksum} += $checksum;
64
# $current_way->{checksum} +=
73
# my $id=shift; # the splitting node
76
# $current_parent_way=$current_way;
77
# $current_way = $newids;
80
# push (@{$ways{$current_way}->{nodes}},$id);# add to way
82
# $ways{$current_way}{parent}=$current_parent_way; # store the parent
83
# push @{$ways{$current_parent_way}{children}},$current_way; # push the children
84
# # we need to apply all relationships to the children as well. and tags if needed.
88
# sub re_process_waynd
92
# ## now we look if we have to cut this way into new bits
93
# if ($nodesways{$id}) # we have seen this node before
95
# # we need to split the way here.
96
# split_way($current_way); # create a new way now starting at this point.
99
# # do we have to add the connection
100
# push (@{$ways{$current_way}->{nodes}},$id);# add to way
102
# # store the current way in the array, first one is
103
# push @{$nodesways{$id}},$current_way;
110
60
sub post_process_way
113
my $wayid =shift || carp "No way";
63
my $wayid =shift || die carp "No way";
116
64
if ($ways{$wayid}->{relationship})
118
66
die "way $wayid already in rel";
141
84
if ($seenfilter{"${first}|${second}"}++)
86
warn "seen pair: first:${first} second:${second} skipping" if $debug;
143
87
# we have seen pair in reverse, bail
158
foreach my $nd (@way)
162
if (!checkpair($nd,$last))
164
# we have seen pair in reverse, bail
175
#mapping of old ways onto new
179
95
finish_way (way_id, [@runlist])
181
96
this is called when we have a finished set of nodes in a run (contigious) along a way
182
that all have the same set of attributes, they dont need any more cutting.
97
that all have the same set of attributes, they dont need any more cutting.
184
98
returns the newid, so we can append the trailing bits
194
105
#remove duplicates from the ways
195
106
my @newlist = @{$runlist};
107
$last_node_seen=0; #reset
197
108
my $runstring= join (",",sort {$a <=> $b} @newlist);
198
# print "Last Run was connected to " . join (",",@last) . "\n";
109
warn "Run for $wayid with tag $tag contains " . join (",",@newlist) . "\n" if $debug;
200
111
if ( $#newlist == 0)
202
113
# warn "only 1 object";
206
116
if ($waystring{$runstring})
208
118
# we have done this one.
214
124
$newids--; # allocate a new id.
215
125
push @{$waymapping{$wayid}},$newids; # map the old id onto the new
216
126
$waystring{$runstring}=$newids; # give this new way an id
217
warn "Run Finished (" . $runstring . ")\n" if $debug;
127
warn "Run in way $wayid Finished (" . $runstring . ")\n" if $debug;
219
128
# now put the nodes on the new way....
220
129
push @{$ways{$newids}->{nodes}},@newlist;
268
168
$tag = "segment $segment";
269
169
#######################################
270
170
### new run starting
171
warn "node $nd is connected to ways: " . join (",",@others) . "\n" if $debug;
271
172
warn "Last Run:connected to " . join (",",@last) . "\n" if $debug;
272
173
warn "Starting new run\n" if $debug;
273
174
# get the last from the old run
274
175
my $last = pop @run; #
177
warn "adding into way:$wayid node:$last\n" if $debug;
278
180
if ($#others > 0)
300
202
# same as before, add to the run
203
warn "duplicate in way:$wayid node:$nd\n" if $debug;
304
206
# print "NODE $nd is connected to " . join (",",@others) . "\n";
309
209
#########################
310
210
warn "Finish up run\n" if $debug;
311
211
finish_way ($wayid,\@run, "last");
313
213
warn "way done $wayid\n" if $debug;
315
214
#####################################################################
316
215
# emit the last element in the loop
317
############################################################
216
############################################################
224
foreach my $chk (@{$nodesways{$id}})
321
234
sub process_waynd
237
warn "process_waynd $id in way $current_way\n" if $debug;
325
238
if ($replace{$id})
327
240
my $new=$replace{$id};
241
warn "adding replacing $id with $new in way $current_way\n" if $debug;
331
244
# dont add duplicates in array
332
245
# look if the nodesways(what ways are in this node)
333
if (!(grep {/$current_way/} @{$nodesways{$id}}))
246
if (!way_in_node($current_way,$id))
335
248
# what whays is this node in
249
warn "adding node:$id to way:$current_way\n" if $debug;
336
250
push @{$nodesways{$id}},$current_way; # store the way in the node
339
252
my $count = $#{$ways{$current_way}->{nodes}};
343
warn "Got count $count";
255
warn "Got count $count of nodes in $current_way\n" if $debug;
346
257
# done add duplicates to end of way
347
258
if ($ways{$current_way}) # look up the current way
350
my $lastinway=$skip || $ways{$current_way}->{nodes}[-1] || 0;
260
# my $lastinway=$last_node_seen;
261
#my $lastinway=$ways{$current_way}->{nodes}[-1] || 0;
262
# the first is missing
263
my $lastitem = $ways{$current_way}->{nodes}[-1]; # the last item in the way
264
my $lastinway=$lastitem;
269
if ($lastitem != $lastinway)
271
warn "in way $current_way inconsistent data $lastitem != $lastinway and count $count \n" if $debug;
274
$lastinway =$lastitem;
277
warn "last in way node :$lastinway in way:$current_way\n" if $debug;
352
278
if ($lastinway ne $id) # not the last in the way
356
if (checkpair($lastinway, $id)) # remove all duplicate ways
281
# if (checkpair($lastinway, $id)) # remove all duplicate ways
358
# the first is missing
363
warn "adding first $lastinway";
364
push (@{$ways{$current_way}->{nodes}},$lastinway);# store the first
368
warn "adding pair $lastinway, $id\n" if $debug;
369
my $lastitem = $ways{$current_way}->{nodes}[-1];
370
carp "inconsistent data $lastitem and count $count " unless $ways{$current_way}->{nodes}[-1]==$lastinway;
283
warn "in way $current_way adding pair lastinway :$lastinway | lastitem:$lastitem, node:$id\n" if $debug;
371
285
push (@{$ways{$current_way}->{nodes}},$id);# store the node
376
warn "going to skip $id\n" if $debug;
378
$skip=$id; # save this for usage.
288
# only store the last node seen if it is not a duplicate
294
# # now we use this for checking duplicates.
295
# #$last_node_seen=$id;
297
# warn "skipping this pair" if $debug;
479
390
if (/<\?xml version=${QUOTE}1.0${QUOTE}/) #encoding=${QUOTE}UTF-8${QUOTE}\?
482
elsif (/<osm version=${QUOTE}0.\d${QUOTE} /) #generator=${QUOTE}[\w\s]+${QUOTE}>
487
next unless consumeattrs;
488
if (s/lon=${QUOTE}($coordpattern)${QUOTE} //)
393
elsif (/<osm version=${QUOTE}0.\d${QUOTE}/) #generator=${QUOTE}[\w\s]+${QUOTE}>
398
next unless consumeattrs;
399
if (s/lon=${QUOTE}($coordpattern)${QUOTE} //)
495
die "no lon $coordpattern $_";
498
if (s/lat=${QUOTE}($coordpattern)${QUOTE} //)
406
die "no lon $coordpattern $_";
409
if (s/lat=${QUOTE}($coordpattern)${QUOTE} //)
508
if (/<node id=${QUOTE}(-?\d+)${QUOTE}\s*\/?>/)
419
if (/<node id=${QUOTE}(-?\d+)${QUOTE}\s*\/?>/)
526
next unless consumeattrs;
528
if (/\s*<way id=${QUOTE}(\-?\d+)${QUOTE}\s*>/)
534
die "missing way $_";
538
elsif(/<nd ref=${QUOTE}(-?\d+)${QUOTE}\s*\/>/)
435
next unless consumeattrs;
436
if (/\s*<way id=${QUOTE}(\-?\d+)${QUOTE}\s*>/)
442
die "missing way $_";
445
elsif(/<nd ref=${QUOTE}(-?\d+)${QUOTE}\s*\/>/)
546
453
# <way id=${QUOTE}-572620${QUOTE} action=${QUOTE}modify${QUOTE} timestamp=${QUOTE}2010-12-05T01:31:40Z${QUOTE} visible=${QUOTE}true${QUOTE}>
547
elsif (/<nd ref=${QUOTE}(-_\d)${QUOTE} \/>/){}
454
elsif (/<nd ref=${QUOTE}(-_\d)${QUOTE} \/>/){}
548
455
elsif (/<relation/){
551
458
next unless consumeattrs;
553
if (/<relation id=${QUOTE}(\-?\d+)${QUOTE}\s*/)
559
die "Bad Relation $_";
460
if (/<relation id=${QUOTE}(\-?\d+)${QUOTE}\s*/)
466
die "Bad Relation $_";
562
468
# all on one line?
563
469
while (s/<member type=${QUOTE}way${QUOTE} ref=${QUOTE}(-?\d+)${QUOTE} role=${QUOTE}outer${QUOTE}\s?\/>//){
568
474
# warn "member $_";
569
475
post_process_way($current_rel,$1);
574
479
elsif (/<\/relation>/){
577
482
elsif (/<member type=${QUOTE}way${QUOTE} ref=${QUOTE}(-?\d+)${QUOTE} role=${QUOTE}outer${QUOTE}\s?\/>/){
579
# now we want to post process this way
580
# cut the way on all the intersections with all other relations
581
# remove other ways that are duplicate, match it 100%
483
# now we want to post process this way
484
# cut the way on all the intersections with all other relations
485
# remove other ways that are duplicate, match it 100%
582
486
# warn "member $_";
583
post_process_way($current_rel,$1);
585
elsif (/<member type=${QUOTE}node${QUOTE} ref=${QUOTE}(-?\d+)${QUOTE} role=${QUOTE}admin_centre${QUOTE}\s?\/>/){}
586
elsif (/<tag k=${QUOTE}(.+)${QUOTE} v=${QUOTE}(.+)${QUOTE}\s*\/>/)
588
while (s/<tag k=${QUOTE}([^\/\${QUOTE}]+)${QUOTE} v=${QUOTE}([^\/\${QUOTE}]+)${QUOTE}\s*\/>//)
487
post_process_way($current_rel,$1);
489
elsif (/<member type=${QUOTE}node${QUOTE} ref=${QUOTE}(-?\d+)${QUOTE} role=${QUOTE}admin_centre${QUOTE}\s?\/>/){}
490
elsif (/<tag k=${QUOTE}(.+)${QUOTE} v=${QUOTE}(.+)${QUOTE}\s*\/>/)
492
while (s/<tag k=${QUOTE}([^\/\${QUOTE}]+)${QUOTE} v=${QUOTE}([^\/\${QUOTE}]+)${QUOTE}\s*\/>//)
593
$tags{$current_rel}{$1}=$2;
597
$tags{$current_way}{$1}=$2;
609
die "Missing anything $_";
615
my %rels; # the relationships
497
$tags{$current_rel}{$1}=$2;
501
$tags{$current_way}{$1}=$2;
513
die "Missing anything $_";
520
duplicate way algorithm
522
1. each node has a pointer to a set of arc, the next node.
523
2. if the next node points back to this node, it is duplicate, we remove it.
617
526
sub post_process_ways
619
528
foreach my $wayid (sort keys %ways)
621
530
my $rel =$ways{$wayid}->{relationship};
622
post_process_way_end $rel, $wayid;
531
#post_process_way_end $rel, $wayid; # for each way, lets process it.
532
push @{$waymapping{$wayid}},$wayid; # map onto self for now
537
##################### MAIN ROUTINE TO CLEAN
627
539
foreach my $file (@ARGV)
632
543
post_process_ways;
634
544
foreach my $wayid (sort keys %ways)
636
546
my $rel =$ways{$wayid}->{relationship};
648
558
#warn Dumper(\%waymapping); # dump out the ways
649
559
# now we can emit the relationships with the new ways instead of the old ones.
651
my %seen; # what have we emitted
652
560
#####################################################
653
561
### now output the doc
654
562
print "<osm version='0.6'>\n";
656
563
foreach my $rel (keys %{rels})
658
565
# warn "emit $rel\n";
659
566
# warn Dumper($tags{$rel});
660
# warn Dumper($rels{$rel});
567
# warn Dumper($rels{$rel});
662
569
foreach my $oldway ( @{$rels{$rel}})
664
571
warn "found old way $oldway" if $debug;
573
here we map all old ways onto new ways.
574
the old ways are not used, only the new ones, recreated from the old
575
the waymapping hash manages that
666
577
foreach my $newway (@{$waymapping{$oldway}} )
668
579
# add the new ways
669
580
push @ways,$newway;
671
581
if (!$seen{$newway}++)
673
warn "found new way $newway" if $debug;
583
warn "found new way $newway from old way $oldway" if $debug;
677
foreach my $nd (@{$ways{$newway}->{nodes}})
679
# have we emitted the node yet?
680
print "$nd in $newway\n" if $debug;
684
# emitnode($nd, @{$nodeids{$nd}});
685
my ($lat,$lon)=@{$nodeids{$nd}};
686
print "<node id=\'$nd\' lat='$lat' lon='$lon'>\n";
687
print "<tag k='_ID' v='$nd' />\n";
692
# emit new way------------------------
693
print "<way id='$newway'>\n";
694
foreach my $nd (@{$ways{$newway}->{nodes}})
696
print "<nd ref='$nd'/>\t";
698
print "<tag k='is_in:country' v='Colombia'/>\n";
699
print "<tag k='_ID' v='$newway' />\n";
586
foreach my $nd (@{$ways{$newway}->{nodes}})
588
# have we emitted the node yet?
589
warn "$nd in $newway\n" if $debug;
593
my ($lat,$lon)=@{$nodeids{$nd}};
594
print "<node id=\'$nd\' lat='$lat' lon='$lon'>\n";
595
print "<tag k='_ID' v='$nd' />\n";
600
# emit new way------------------------
601
print "<way id='$newway'>\n";
602
foreach my $nd (@{$ways{$newway}->{nodes}})
604
print "<nd ref='$nd'/>\t";
606
print "<tag k='is_in:country' v='Colombia'/>\n";
607
print "<tag k='_ID' v='$newway' />\n";