source: subversion/applications/utils/gary68/mapgen.pl @ 19634

Last change on this file since 19634 was 19634, checked in by gary68, 10 years ago
  • Property svn:executable set to *
File size: 11.8 KB
Line 
1
2# 0.03 enhanced legend, center label in areas
3
4
5# TODO
6# LAYERS, bridges and tunnels (collect objects in separate hashes...)
7# wiki page
8
9# waybegrenzungen, farbe, dicke
10# relations (scan, then convert to ways, preserve layers!)
11# sub key/value for rules
12# bg color
13
14use strict ;
15use warnings ;
16
17use OSM::osm ;
18use OSM::osmgraph 2.4 ;
19
20my $programName = "mapgen.pl" ;
21my $usage = "mapgen.pl file.osm style.csv out.png size" ; # svg name is automatic
22my $version = "0.03" ;
23
24my @legend = () ;
25
26# AREAS
27my $areaIndexKey = 0 ;
28my $areaIndexValue = 1 ;
29my $areaIndexColor = 2 ;
30my $areaIndexLegend = 3 ;
31my @areas = () ;
32# tag value color
33
34# NODES
35my $nodeIndexTag = 0 ;
36my $nodeIndexValue = 1 ;
37my $nodeIndexColor = 2 ;
38my $nodeIndexThickness = 3 ;
39my $nodeIndexLabel = 4 ;
40my $nodeIndexLabelColor = 5 ;
41my $nodeIndexLabelSize = 6 ;
42my $nodeIndexLabelOffset = 7 ;
43my $nodeIndexLegend = 8 ;
44my @nodes = () ;
45# tag value color thickness label label-color label-size label-offset
46
47
48# WAYS and small AREAS
49my $wayIndexTag = 0 ;
50my $wayIndexValue = 1 ;
51my $wayIndexColor = 2 ;
52my $wayIndexThickness = 3 ;
53my $wayIndexFilled = 4 ;
54my $wayIndexLabel = 5 ;
55my $wayIndexLabelColor = 6 ;
56my $wayIndexLegend = 7 ;
57my @ways = () ;
58# key value color thickness fill label label-color
59
60
61my $labelMinLength = 0.1 ; # min length of street so that it will be labled / needs adjustment according to picture size
62
63my $wayId ;
64my $wayUser ;
65my @wayNodes ;
66my @wayTags ;
67my $nodeId ;
68my $nodeUser ;
69my $nodeLat ;
70my $nodeLon ;
71my @nodeTags ;
72my $aRef1 ;
73my $aRef2 ;
74
75my %memNodeTags ;
76my %memWayTags ;
77my %memWayNodes ;
78my %memRelationTags ;
79my %memRelationMembers ;
80
81my $osmName ; 
82my $pngName ;
83my $csvName ;
84
85my %lon ; my %lat ;
86
87my $size ;
88my $lonMin ; my $latMin ; my $lonMax ; my $latMax ;
89
90my $time0 ; my $time1 ;
91
92# get parameter
93
94$osmName = shift||'';
95if (!$osmName)
96{
97        die (print $usage, "\n");
98}
99
100$csvName = shift||'';
101if (!$csvName)
102{
103        die (print $usage, "\n");
104}
105
106$pngName = shift||'';
107if (!$pngName)
108{
109        die (print $usage, "\n");
110}
111
112$size = shift||'';
113if (!$size)
114{
115        $size = 1024 ; # default size
116}
117
118# READ STYLE File
119open (my $csvFile, "<", $csvName) or die ("ERROR: style file not found.") ;
120my $line = <$csvFile> ;
121
122#$line = <$csvFile> ;
123#while (! grep /^\"SECTION/, $line) {
124#       my ($color, $text) = ($line =~ /\"(.+)\" \"(.+)\"/ ) ;
125#       # print "L $color $text\n" ;
126#       push @legend, $text ; push @legend, $color ;
127#       $line = <$csvFile> ;
128#}
129
130$line = <$csvFile> ;
131while (! grep /^\"SECTION/, $line) {
132        my ($key, $value, $color, $legend) = ($line =~ /\"(.+)\" \"(.+)\" \"(.+)\" (\d)/ ) ;
133        # print "A $key, $value, $color, $legend\n" ;
134        push @areas, [$key, $value, $color, $legend] ;
135        $line = <$csvFile> ;
136}
137# tag value color thickness label label-color label-size label-offset
138$line = <$csvFile> ;
139while (! grep /^\"SECTION/, $line) {
140        my ($key, $value, $color, $thickness, $label, $labelColor, $labelSize, $labelOffset, $legend) = 
141                ($line =~ /\"(.+)\" \"(.+)\" \"(.+)\" (\d+) \"(.+)\" \"(.+)\" (\d+) (\d+) (\d)/ ) ;
142        # print "N $key, $value, $color, $thickness, $label, $labelColor, $labelSize, $labelOffset, $legend\n" ;
143        push @nodes, [$key, $value, $color, $thickness, $label, $labelColor, $labelSize, $labelOffset, $legend] ;
144        $line = <$csvFile> ;
145}
146# key value color thickness fill label label-color
147$line = <$csvFile> ;
148while ( (! grep /^\"SECTION/, $line) and (defined $line) ) {
149        my ($key, $value, $color, $thickness, $fill, $label, $labelColor, $legend) = 
150                ($line =~ /\"(.+)\" \"(.+)\" \"(.+)\" (\d+) (\d+) \"(.+)\" \"(.+)\" (\d)/ ) ;
151        # print "W $key, $value, $color, $thickness, $fill, $label, $labelColor, $legend\n" ;
152        push @ways, [$key, $value, $color, $thickness, $fill, $label, $labelColor, $legend] ;
153        $line = <$csvFile> ;
154}
155
156close ($csvFile) ;
157
158
159print "\n$programName $version for file $osmName\n" ;
160print "AREAS\n" ;
161foreach my $area (@areas) {
162        printf "%-15s %-15s %-10s\n", $area->[0], $area->[1], $area->[2] ;
163}
164print "\n" ;
165print "WAYS\n" ;
166foreach my $way (@ways) {
167        printf "%-20s %-20s %-10s %-10s %-10s %-10s %-10s\n", $way->[0], $way->[1], $way->[2], $way->[3], $way->[4], $way->[5], $way->[6] ;
168}
169print "\n" ;
170print "NODES\n" ;
171foreach my $node (@nodes) {
172        printf "%-20s %-20s %-10s %-10s %-10s %-10s %-10s %-10s\n", $node->[0], $node->[1], $node->[2], $node->[3], $node->[4], $node->[5], $node->[6], $node->[7] ;
173}
174print "\n" ;
175
176$time0 = time() ;
177
178
179# STORE DATA
180print "reading osm file...\n" ;
181
182openOsmFile ($osmName) ;
183($nodeId, $nodeLon, $nodeLat, $nodeUser, $aRef1) = getNode2 () ;
184if ($nodeId != -1) {
185        @nodeTags = @$aRef1 ;
186}
187while ($nodeId != -1) {
188
189        $lon{$nodeId} = $nodeLon ;     
190        $lat{$nodeId} = $nodeLat ;     
191        @{$memNodeTags{$nodeId}} = @nodeTags ;
192
193        ($nodeId, $nodeLon, $nodeLat, $nodeUser, $aRef1) = getNode2 () ;
194        if ($nodeId != -1) {
195                @nodeTags = @$aRef1 ;
196        }
197}
198
199($wayId, $wayUser, $aRef1, $aRef2) = getWay2 () ;
200if ($wayId != -1) {
201        @wayNodes = @$aRef1 ;
202        @wayTags = @$aRef2 ;
203}
204while ($wayId != -1) {
205
206        if (scalar (@wayNodes) > 1) {
207                @{$memWayTags{$wayId}} = @wayTags ;
208                @{$memWayNodes{$wayId}} = @wayNodes ;
209        }
210       
211        ($wayId, $wayUser, $aRef1, $aRef2) = getWay2 () ;
212        if ($wayId != -1) {
213                @wayNodes = @$aRef1 ;
214                @wayTags = @$aRef2 ;
215        }
216}
217
218closeOsmFile () ;
219
220
221
222# calc area of pic and init
223
224$lonMin = 999 ; $lonMax = -999 ; $latMin = 999 ; $latMax = -999 ;
225my $key ;
226foreach $key (keys %lon) {
227        if ($lon{$key} > $lonMax) { $lonMax = $lon{$key} ; }
228        if ($lon{$key} < $lonMin) { $lonMin = $lon{$key} ; }
229        if ($lat{$key} > $latMax) { $latMax = $lat{$key} ; }
230        if ($lat{$key} < $latMin) { $latMin = $lat{$key} ; }
231}
232initGraph ($size, $lonMin, $latMin, $lonMax, $latMax) ;
233enableSVG () ;
234
235
236# BG AREAS
237
238print "draw areas...\n" ;
239foreach my $wayId (keys %memWayTags) {
240        foreach $key (@{$memWayTags{$wayId}}) {
241                foreach my $test (@areas) {
242                        if ( ($key->[0] eq $test->[$areaIndexKey]) and ($key->[1] eq $test->[$areaIndexValue]) ) {
243                                drawArea ($test->[$areaIndexColor], nodes2Coordinates( @{$memWayNodes{$wayId}} ) ) ;
244                        }
245                }
246        }
247}
248
249
250# NODES
251
252print "draw nodes...\n" ;
253foreach my $nodeId (keys %memNodeTags) {
254        foreach my $tag (@{$memNodeTags{$nodeId}} ) {
255                foreach my $test (@nodes) {
256                        if ( ($tag->[0] eq $test->[$nodeIndexTag]) and ($tag->[1] eq $test->[$nodeIndexValue]) ) {
257                                if ($test->[$nodeIndexThickness] > 0) {
258                                        drawNodeDot ($lon{$nodeId}, $lat{$nodeId}, $test->[$nodeIndexColor], $test->[$nodeIndexThickness]) ;
259                                }
260
261                                if ($test->[$nodeIndexLabel] ne "none") {
262                                        my $name = "" ;
263                                        # get name
264                                        foreach my $tag2 (@{$memNodeTags{$nodeId}}) {
265                                                if ($tag2->[0] eq $test->[$nodeIndexLabel]) {
266                                                        $name = $tag2->[1] ;
267                                                }
268                                        }
269                                        if ($name ne "") {
270                                                drawTextPos ($lon{$nodeId}, $lat{$nodeId}, 0, -$test->[$nodeIndexLabelOffset], 
271                                                        $name, $test->[$nodeIndexLabelColor], $test->[$nodeIndexLabelSize]) ;
272                                        }
273                                } # draw label
274                        } # tag found
275                } # test
276        } # tags
277} # nodes
278
279
280# WAYS
281
282print "draw ways...\n" ;
283foreach my $wayId (keys %memWayTags) {
284        #print "wayid: $wayId\n" ;
285        my $text = "" ; 
286        my $length = 0 ;
287
288        for (my $i = 0; $i < scalar (@{$memWayNodes{$wayId}})-1   ; $i++) {
289                $length += distance ($lon{ $memWayNodes{$wayId}[$i] }, $lat{ $memWayNodes{$wayId}[$i] }, 
290                        $lon{ $memWayNodes{$wayId}[$i+1] }, $lat{ $memWayNodes{$wayId}[$i+1] }) ;
291        }
292
293        foreach my $tag (@{$memWayTags{$wayId}}) {
294                #print "  $tag->[0] $tag->[1]\n" ;
295                foreach my $test (@ways) {
296                        if ( ($tag->[0] eq $test->[$wayIndexTag]) and ($tag->[1] eq $test->[$wayIndexValue]) ) {
297                                #print "    tag match\n" ;
298                                if ($test->[$wayIndexFilled] eq "0") {
299                                        #print "      drawing way $test->[$wayIndexColor], $test->[$wayIndexThickness] ...\n" ;
300                                        drawWay ($test->[$wayIndexColor], $test->[$wayIndexThickness], nodes2Coordinates(@{$memWayNodes{$wayId}})) ;
301                                        if ($test->[$wayIndexLabel] ne "none") {
302                                                foreach my $tag2 (@{$memWayTags{$wayId}}) {
303                                                        if ( ($tag2->[0] eq $test->[$wayIndexLabel]) and ($length >= $labelMinLength) ) {
304                                                                labelWay ($test->[$wayIndexLabelColor], 0, "", $tag2->[1], -2, nodes2Coordinates(@{$memWayNodes{$wayId}})) ;
305                                                        }
306                                                }
307                                        }
308                                } # not filled
309                                else {
310                                        if (${$memWayNodes{$wayId}}[0] == ${$memWayNodes{$wayId}}[-1]) {
311                                                drawArea ($test->[$wayIndexColor], nodes2Coordinates( @{$memWayNodes{$wayId}} ) ) ;
312                                                if ($test->[$wayIndexLabel] ne "none") {
313                                                        foreach my $tag2 (@{$memWayTags{$wayId}}) {
314                                                                if ($tag2->[0] eq $test->[$wayIndexLabel]) {
315                                                                        my ($x, $y) = (0, 0) ; my $count = 0 ;
316                                                                        foreach my $node (@{$memWayNodes{$wayId}}) {
317                                                                                $x += $lon{$node} ; $y += $lat{$node} ; $count++ ;
318                                                                        }
319                                                                        $x = $x / $count ; $y = $y / $count ;
320                                                                        # drawTextPos ($lon{${$memWayNodes{$wayId}}[0]}, $lat{${$memWayNodes{$wayId}}[0]}, 0, 0, $tag2->[1], $test->[$wayIndexLabelColor], 2) ;
321                                                                        drawTextPos ($x, $y, 0, 0, $tag2->[1], $test->[$wayIndexLabelColor], 2) ;
322                                                                }
323                                                        }
324                                                } # draw label
325                                        } #closed
326                                } # filled
327                        } # tag found
328                } # $test
329        } # $tag
330} # ways
331
332
333
334# draw other information
335
336print "draw legend etc. and write files...\n" ;
337
338# drawLegend (2, @legend) ;
339createLegend() ;
340
341drawRuler ("darkgray") ;
342drawHead ("gary68's $programName $version", "black", 2) ;
343drawFoot ("data by www.openstreetmap.org", "gray", 2) ;
344
345writeGraph ($pngName) ;
346
347my $svgName = $pngName ; $svgName =~ s/.png/.svg/ ;
348writeSVG ($svgName) ;
349
350$time1 = time() ;
351print "\n$programName finished after ", stringTimeSpent ($time1-$time0), "\n\n" ;
352
353
354sub nodes2Coordinates {
355#
356# transform list of nodeIds to list of lons/lats
357#
358        my @nodes = @_ ;
359        my $i ;
360        my @result = () ;
361
362        #print "in @nodes\n" ;
363
364        for ($i=0; $i<=$#nodes; $i++) {
365                push @result, $lon{$nodes[$i]} ;
366                push @result, $lat{$nodes[$i]} ;
367        }
368        return @result ;
369}
370
371sub createLegend {
372        my $currentY = 50 ;
373        my $step = 20 ;
374        my $textX = 70 ;
375        my $textOffset = -5 ;
376        my $dotX = 40 ;
377        my $areaSize = 8 ;
378        my $wayStartX = 20 ;
379        my $wayEndX = 60 ;
380        my $areaStartX = 33 ;
381        my $areaEndX = 47 ;
382        my $count = 0 ;
383        my $sizeLegend = 2 ;
384       
385        foreach (@areas) { if ($_->[$areaIndexLegend] == 1) { $count++ ; }  }
386        foreach (@nodes) { if ($_->[$nodeIndexLegend] == 1) { $count++ ; }  }
387        foreach (@ways) { if ($_->[$wayIndexLegend] == 1) { $count++ ; }  }
388
389        # erase background
390        drawAreaPix ("white", 0, 30,
391                        180,30,
392                        180, 30 + $count*20 + 10,
393                        0, 30 + $count*20 + 10,
394                        0, 30) ;
395       
396        foreach my $node (@nodes) { 
397                if ($node->[$nodeIndexLegend] == 1) { 
398                        drawNodeDotPix ($dotX, $currentY, $node->[$nodeIndexColor], $node->[$nodeIndexThickness]) ;
399                        drawTextPix2 ($textX, $currentY+$textOffset, $node->[$nodeIndexValue], "black", $sizeLegend) ;
400                        $currentY += $step ;
401                } 
402        }
403
404        foreach my $way (@ways) { 
405                if ($way->[$wayIndexLegend] == 1) { 
406                        if ($way->[$wayIndexFilled] == 0) {
407                                drawWayPix ($way->[$wayIndexColor], $way->[$wayIndexThickness], $wayStartX, $currentY, $wayEndX, $currentY) ;
408                        } 
409                        else {
410                                drawAreaPix ($way->[$wayIndexColor], $areaStartX, $currentY-$areaSize, 
411                                        $areaEndX, $currentY-$areaSize,
412                                        $areaEndX, $currentY+$areaSize,
413                                        $areaStartX, $currentY+$areaSize,
414                                        $areaStartX, $currentY-$areaSize) ;
415                        }
416                        drawTextPix2 ($textX, $currentY+$textOffset, $way->[$wayIndexValue], "black", $sizeLegend) ;
417                        $currentY += $step ;
418                } 
419        }
420
421        foreach my $area (@areas) { 
422                if ($area->[$areaIndexLegend] == 1) { 
423                        drawAreaPix ($area->[$areaIndexColor], $areaStartX, $currentY-$areaSize, 
424                                $areaEndX, $currentY-$areaSize,
425                                $areaEndX, $currentY+$areaSize,
426                                $areaStartX, $currentY+$areaSize,
427                                $areaStartX, $currentY-$areaSize) ;
428                        drawTextPix2 ($textX, $currentY+$textOffset, $area->[$areaIndexValue], "black", $sizeLegend) ;
429                        $currentY += $step ;
430                } 
431        }
432
433}
Note: See TracBrowser for help on using the repository browser.