source: subversion/applications/utils/gary68/hikingbook.pl @ 34714

Last change on this file since 34714 was 26778, checked in by gary68, 8 years ago

gpl added to some files

  • Property svn:executable set to *
File size: 62.9 KB
Line 
1# PERL by gary68
2#
3#
4#
5#
6# Copyright (C) 2011, Gerhard Schwanz
7#
8# This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the
9# Free Software Foundation; either version 3 of the License, or (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>
15#
16
17
18
19
20
21# todo
22#
23# LATER
24# - negative ids for steps
25# - print parameters
26#
27
28# history
29# 0.91 autorotate corrected
30# 0.92 bigger overview and detail maps; added names to pois in description; less steps
31# 0.93 variable discs, taginfo -> pdf
32# 0.94 role selection; title and outName defaults
33# 0.95 sanitize
34# 0.96 contour data
35# 0.97 street directory
36# 0.98 street atlas
37#
38
39use strict ;
40use warnings ;
41use Getopt::Long ;
42use OSM::osm ;
43use OSM::QuadTree ;
44
45
46my $programName = "hikingbook.pl" ;
47my $version = "0.98" ;
48
49my $inFileName = "hessen.osm" ;
50my $outFileName = "hikingbook.pdf" ;
51my $overviewStyleFileName = "hikingRules.csv" ;
52my $detailStyleFileName = "hikingRules.csv" ;
53my $poiFileName = "hikingbook.poi" ;
54my $relationId = 0 ;
55my $relationName = "" ;
56my $relationRef = "" ;
57my @relationTags ;
58my $scale = 10000 ; # default detail scale
59my %pageHeight = () ;
60$pageHeight{"A4"} = 27.7 ;
61$pageHeight{"A5"} = 19 ;
62my %pageWidth = () ;
63$pageWidth{"A4"} = 19 ;
64$pageWidth{"A5"} = 13.8 ;
65my @overviewScales = (10000,25000,50000,75000,100000,200000,500000,1000000) ; # best fit will be taken
66my $title = "Hiking book" ;
67my $workDir = "" ;
68my $logFileName = "hikingbooklog.txt" ;
69my @tempFiles = () ; # to be deleted later
70
71my %lon ; my %lat ;
72my @ways ;
73my @nodes ;
74my %nodeDirCount ; 
75my %wayNodesHash = () ;
76my %wayNameHash = () ;
77my $mapNumber = 0 ; # counts detail maps
78my $scaleOverview = 0 ;
79my $rectangles = "" ; # collect data for overview map
80
81my $languageOpt = "EN" ;
82my $noOutputOpt = 0 ;
83my $verboseOpt = 0 ;
84my $dirNumberOpt = 8 ; # number of different directions used (N,S,SW...)
85my $pageSizeOpt = "A4" ;
86my $overlapOpt = 5 ; # in percent
87my $landscapeOpt = 0 ;
88my $reverseOpt = 0 ;
89my $roundtripOpt = 0 ;
90my $noDeleteOpt = 0 ;
91my $pnSizeOverview = 48 ;
92my $pnSizeDetail = 64 ;
93my $descName = "" ;
94my $stepDescName = "" ;
95my $autorotateOpt = 0 ;
96my $lessStepsOpt = 0 ;
97my $stepSizeOpt = 15 ;
98my $stepColorOpt = "black" ;
99my $stepFontSizeOpt = 35 ;
100my $atlasOpt = "" ;
101
102my $poiOpt = 0 ;
103my $gridNumber = 5 ;
104my %pois = () ;
105my $streetOpt = 0 ;
106my %streets = () ;
107
108my $extraMapData1 = 0.1 ; # overlap for osm temp file 1 in degrees
109my $extraMapData2 = 0.005 ; # for temp file 2s
110
111my $mapgenCommandOverview = "perl mapgen.pl -pdf -declutter -legend=0 -scale -allowiconmove -pagenumbers=$pnSizeOverview,black,0" ;
112my $mapgenCommandDetail = "perl mapgen.pl -pdf -declutter -legend=0 -scale -allowiconmove" ;
113
114# relation bounding box. all data.
115my $relLonMax = -999 ;
116my $relLonMin = 999 ;
117my $relLatMax = -999 ;
118my $relLatMin = 999 ;
119
120# detail boxes outer bounds 0.92
121my $detailLonMax = -999 ;
122my $detailLonMin = 999 ;
123my $detailLatMax = -999 ;
124my $detailLatMin = 999 ;
125
126# initial file
127my $fileLonMax = -999 ;
128my $fileLonMin = 999 ;
129my $fileLatMax = -999 ;
130my $fileLatMin = 999 ;
131
132# temp osm file 1 data
133my $file1LonMax = -999 ;
134my $file1LonMin = 999 ;
135my $file1LatMax = -999 ;
136my $file1LatMin = 999 ;
137
138my $temp1FileName = "temp1.osm" ;
139my $temp2FileName = "temp2.osm" ;
140
141my %nodeName = () ;
142my %nodeElevation = () ;
143my %nodeInfo = () ;
144my $segmentLength = 0 ;
145my %stepInformation = () ;
146my %contourData = () ;
147my %contourWays = () ;
148my $qt ;
149
150my @poiList ;   # POIs actually found
151my @pois = () ; # POIs to be used
152
153my %translations = () ;
154$translations{"DE"}{"station"} = "Bahnhof" ;
155$translations{"DE"}{"bus_stop"} = "Bushaltestelle" ;
156$translations{"DE"}{"viewpoint"} = "Aussichtspunkt" ;
157$translations{"DE"}{"restaurant"} = "Restaurant" ;
158$translations{"DE"}{"pharmacy"} = "Apotheke" ;
159$translations{"DE"}{"hospital"} = "Krankenhaus" ;
160$translations{"DE"}{"peak"} = "Gipfel" ;
161$translations{"DE"}{"fuel"} = "Tankstelle" ;
162$translations{"DE"}{"place_of_worship"} = "Kirche" ;
163$translations{"DE"}{"bar"} = "Bar" ;
164$translations{"DE"}{"hotel"} = "Hotel" ;
165$translations{"DE"}{"attraction"} = "Attraktion" ;
166$translations{"DE"}{"supermarket"} = "Supermarkt" ;
167$translations{"DE"}{"fast food"} = "Fast Food" ;
168$translations{"DE"}{"suburb"} = "Vorort" ;
169$translations{"DE"}{"hamlet"} = "Weiler" ;
170$translations{"DE"}{"city"} = "Großstadt" ;
171$translations{"DE"}{"town"} = "Stadt" ;
172$translations{"DE"}{"information"} = "Information" ;
173$translations{"DE"}{"spring"} = "Quelle" ;
174$translations{"DE"}{"parking"} = "Parkplatz" ;
175$translations{"DE"}{"pub"} = "Kneipe" ;
176$translations{"DE"}{"bank"} = "Bank" ;
177$translations{"DE"}{"castle"} = "Burg" ;
178$translations{"DE"}{"village"} = "Dorf" ;
179$translations{"DE"}{"hostel"} = "Herberge" ;
180# $translations{"DE"}{""} = "" ;
181
182my %validLatex = () ;
183my %replaceLatex = () ;
184
185initializeLatex() ;
186getProgramOptions () ;
187
188if ($atlasOpt eq "") {
189        print "HIKING/ROUTE MODE\n" ;
190        getPoiFiledata () ;
191        getRelationData() ;
192        getStepInformation() ;
193        createTemp1 () ;
194        buildCompleteWay() ;
195        compileElevationData () ;
196        addPois() ;
197        createDirections() ;
198        createDetailMaps() ;
199}
200else {
201        print "ATLAS MODE\n" ;
202
203        if ($title eq "Hiking book") { $title = "Atlas" ; }
204
205        # print "opt = $atlasOpt\n" ;
206        ($relLonMin, $relLatMin, $relLonMax, $relLatMax) = ( $atlasOpt =~ /([\-\d\.]+)\,([\-\d\.]+)\,([\-\d\.]+)\,([\-\d\.]+)/ ) ;
207        # print "$relLonMin, $relLatMin, $relLonMax, $relLatMax\n" ;
208        if ((! defined $relLonMin) or (! defined $relLatMin) or (! defined $relLonMax) or (! defined $relLatMax)) {
209                die "ERROR in atlas coordinates: $atlasOpt\n" ;
210        }
211
212        openOsmFile ($inFileName) ;
213        print "reading nodes of input file...\n" ;
214
215        my $propRef ; my $tagsRef ;     
216        ($propRef, $tagsRef) = getNode3() ;
217        while (defined $propRef) {
218                # collect data of big file
219                if ( $$propRef{"lon"} > $fileLonMax ) { $fileLonMax = $$propRef{"lon"} ; }
220                if ( $$propRef{"lon"} < $fileLonMin ) { $fileLonMin = $$propRef{"lon"} ; }
221                if ( $$propRef{"lat"} > $fileLatMax ) { $fileLatMax = $$propRef{"lat"} ; }
222                if ( $$propRef{"lat"} < $fileLatMin ) { $fileLatMin = $$propRef{"lat"} ; }
223
224                ($propRef, $tagsRef) = getNode3() ;
225        }
226        closeOsmFile() ;
227        print "done.\n" ;
228
229        createTemp1 () ;
230        createDetailMapsAtlas() ;
231}
232
233createOverviewMap() ;
234createTitlePage () ;
235createDirectory () ;
236mergeAllFiles() ;
237
238print "\ndeleting temp files (disable with -nodelete)...\n" ;
239if ($noDeleteOpt == 0) {
240        push @tempFiles, $temp2FileName ;
241        foreach my $f (@tempFiles) {
242                `rm $f` ;
243        }
244}
245print "done.\n\n" ;
246
247
248sub getRelationData {
249        my %neededWays = () ;
250        my %neededNodes = () ;
251        my @relationMembers = () ;
252        # my @relationTags = () ; # now GLOBAL
253
254        # get relation data
255
256        print "\nget data from file...\n" ;
257        print "parsing relations...\n" ;
258        openOsmFile ($inFileName) ;
259        skipNodes() ;
260        skipWays() ;
261
262        my $propRef ; my $membersRef ; my $tagsRef ;
263        ($propRef, $membersRef, $tagsRef) = getRelation3() ;
264
265        my $found = 0 ;
266        my $name = "" ; my $ref = "" ;
267        while ( (defined $propRef) and (! $found) ) {
268                if ($$propRef{"id"} == $relationId) {
269                        $found = 1 ;
270                        @relationMembers = @$membersRef ;
271                        @relationTags = @$tagsRef ;
272                }
273
274                foreach my $t (@$tagsRef) {
275                        if ($t->[0] eq "name") { $name = $t->[1] ; }
276                        if ($t->[0] eq "ref") { $ref = $t->[1] ; }
277                }
278
279                if ( ($relationName ne "") and (grep /^$relationName$/i, $name) ) {
280                        $found = 1 ;
281                        $relationId = $$propRef{'id'} ;
282                        @relationMembers = @$membersRef ;
283                        @relationTags = @$tagsRef ;
284                }
285                if ( ($relationRef ne "") and (grep /^$relationRef$/i, $ref) ) {
286                        $found = 1 ;
287                        $relationId = $$propRef{'id'} ;
288                        @relationMembers = @$membersRef ;
289                        @relationTags = @$tagsRef ;
290                }
291
292                if ($found) {
293                        print "\nRelation $$propRef{'id'} found.\n" ;
294                        print "Name: $name\n" ;
295                        print "Ref: $ref\n\n" ;
296
297                }
298
299                ($propRef, $membersRef, $tagsRef) = getRelation3() ;
300        }
301        closeOsmFile() ;
302
303        if ( ($name ne "") and ($title eq "Hiking book") ) { $title = $name ; } # 0.94
304        if ( ($name ne "") and ($outFileName eq "hikingbook.pdf") ) { $outFileName = $name . ".pdf" ; }
305
306        if ($found == 0) {
307                die ("relation not found!\n") ;
308        }
309
310        @ways = () ;
311
312        my $wc = 0 ;
313        my %types = () ;
314        foreach my $m (@relationMembers) {
315                if ($m->[0] eq "way") {
316                        $types{$m->[2]} = 1 ;
317                        my $validRole = 0 ; # 0.94
318                        foreach my $r (qw (none forward route) ) { 
319                                if ( $m->[2] eq $r ) { $validRole = 1 ; }
320                        }
321                        if ($validRole) {
322                                $wc++ ;
323                                $neededWays{$m->[1]} = 1 ;
324                                push @ways, $m->[1] ;
325                        }
326                        else {
327                                my $role = $m->[2] ;
328                                print "WARNING: invalid role $role detected.\n" ;
329                        }
330                }
331        }
332        if ($verboseOpt eq "1") {
333                print "relation contains $wc ways.\n" ;
334                my @nw = keys %neededWays ;
335                print "NEEDED WAYS: @nw\n" ;
336        }
337
338        if ($verboseOpt eq "1") {
339                print "ROLES: " ;
340                foreach my $r (keys %types) { print $r, " " ; }
341                print "\n" ;
342        }
343
344        # get way data
345
346        print "parsing ways...\n" ;
347        openOsmFile ($inFileName) ;
348        skipNodes() ;
349
350        my $nodesRef ; 
351        ($propRef, $nodesRef, $tagsRef) = getWay3() ;
352        while (defined $propRef) {
353                if (defined $neededWays{$$propRef{"id"}}) {
354
355                        delete $neededWays{$$propRef{"id"}} ;
356
357                        if (scalar @$nodesRef < 2) { print "ERROR: needed way $$propRef{'id'} has less than 2 nodes!\n" ; } 
358
359                        foreach my $n (@$nodesRef) {
360                                $neededNodes{$n} = 1 ;
361                        }
362                        @{$wayNodesHash{ $$propRef{"id"}} } = @$nodesRef ;
363
364                        my $n = "" ; 
365                        my $r = "" ;
366                        foreach my $t (@$tagsRef) {
367                                if ($t->[0] eq "name") { $n = $t->[1] ; }
368                                if ($t->[0] eq "ref") { $r = $t->[1] ; }
369                        }
370
371                        my $name = "" ;
372                        if ($n ne "") { $name = $n ; }
373                        if ($r ne "") { $name = $r . " " . $name ; }
374                        $wayNameHash{$$propRef{"id"}} = $name ;
375                        # print "name: $name\n" ;
376
377                }
378
379
380                ($propRef, $nodesRef, $tagsRef) = getWay3() ;
381        }
382        closeOsmFile() ;
383
384        if (scalar keys %neededWays > 0) {
385                foreach my $w (keys %neededWays) {
386                        print "ERROR: needed way $w missing.\n" ;
387                }
388                die ("ERROR: ways missing.\n") ;
389        }
390
391        # get node data
392
393        openOsmFile ($inFileName) ;
394        print "reading nodes...\n" ;
395
396        ($propRef, $tagsRef) = getNode3() ;
397        while (defined $propRef) {
398                if (defined $neededNodes{$$propRef{"id"}}) {
399                        delete $neededNodes{$$propRef{"id"}} ;
400
401                        $lon{ $$propRef{"id"} } = $$propRef{"lon"} ; 
402                        $lat{ $$propRef{"id"} } = $$propRef{"lat"} ; 
403
404                        if ( $$propRef{"lon"} > $relLonMax ) { $relLonMax = $$propRef{"lon"} ; }
405                        if ( $$propRef{"lon"} < $relLonMin ) { $relLonMin = $$propRef{"lon"} ; }
406                        if ( $$propRef{"lat"} > $relLatMax ) { $relLatMax = $$propRef{"lat"} ; }
407                        if ( $$propRef{"lat"} < $relLatMin ) { $relLatMin = $$propRef{"lat"} ; }
408
409                        my $ele = "" ;
410                        foreach my $t (@$tagsRef) {
411                                if ($t->[0] eq "ele") { $ele = $t->[1] ; }
412                        }
413                        $nodeElevation{$$propRef{"id"}} = $ele ;
414       
415                }
416
417                my $extra = 0.000 ;
418                $relLonMin = $relLonMin - $extra ;
419                $relLonMax = $relLonMax + $extra ;
420                $relLatMin = $relLatMin - $extra ;
421                $relLatMax = $relLatMax + $extra ;
422
423
424                # also collect data of big file
425                if ( $$propRef{"lon"} > $fileLonMax ) { $fileLonMax = $$propRef{"lon"} ; }
426                if ( $$propRef{"lon"} < $fileLonMin ) { $fileLonMin = $$propRef{"lon"} ; }
427                if ( $$propRef{"lat"} > $fileLatMax ) { $fileLatMax = $$propRef{"lat"} ; }
428                if ( $$propRef{"lat"} < $fileLatMin ) { $fileLatMin = $$propRef{"lat"} ; }
429
430                ($propRef, $tagsRef) = getNode3() ;
431        }
432        closeOsmFile() ;
433        print "done.\n" ;
434
435        if (scalar keys %neededNodes > 0) {
436                foreach my $n (keys %neededNodes) {
437                        print "ERROR: needed node $n missing.\n" ;
438                }
439                die ("ERROR: nodes missing.\n") ;
440        }
441
442
443        if ($verboseOpt eq "1") {
444                print "relation bounding box: $relLonMin, $relLatMin, $relLonMax, $relLatMax\n" ;
445        }
446
447
448
449}
450
451
452sub createTemp1 {
453        # this file is used to draw the overview and further osm files for details are generated from this one to save time.
454        print "\ncreate temp file 1...\n" ;
455
456
457        if ($noOutputOpt eq "0") {
458                shrinkFile ($inFileName, $temp1FileName, $fileLonMin, $fileLatMin, $fileLonMax, $fileLatMax, $relLonMin, $relLatMin, $relLonMax, $relLatMax, $extraMapData1) ;
459
460                push @tempFiles, $temp1FileName ;
461
462                print "reading temp file...\n" ;
463
464                my $contourCount = 0 ;
465                my %neededNodes = () ;
466
467                my $nodesRef ; my $propRef ; my $tagsRef ;
468
469                if ($atlasOpt eq "") {
470
471                        # openOsmFile ($inFileName) ;
472                        openOsmFile ($temp1FileName) ; # 0.92
473                        skipNodes() ;
474
475                        ($propRef, $nodesRef, $tagsRef) = getWay3() ;
476                        while (defined $propRef) {
477                                my $needed = 0 ;
478                                my $contourNeeded = 0 ;
479                                my $ele = -999 ;
480                                foreach my $t (@$tagsRef) {
481                                        if ($t->[0] eq "highway") { $needed = 1 ; }
482                                        if ($t->[0] eq "contour_ext") { $contourNeeded = 1 ; }
483                                        if ($t->[0] eq "ele") { $ele = $t->[1] ; }
484                                }
485
486                                if ($needed) {
487                                        @nodes = @$nodesRef ;
488                                        for (my $i=0 ; $i <= $#nodes; $i++) {
489                                                my $n = $nodes[$i] ;
490                                                if ( ($i == 0) or ($i ==$#nodes) ) {
491                                                        $nodeDirCount{$n} += 1 ;
492                                                }
493                                                else {
494                                                        $nodeDirCount{$n} += 2 ;
495                                                }
496                                        }
497                                }
498
499                                if ( ($contourNeeded) and ($ele != -999) and (scalar @$nodesRef > 1) ) {
500                                        $contourCount++ ;
501                                        @{ $wayNodesHash{ $$propRef{"id"} } } = @$nodesRef ;
502                                        $contourWays { $$propRef{"id"} } = $ele ;
503                                        foreach my $n ( @$nodesRef ) {
504                                                $neededNodes{$n} = 1 ;
505                                        }
506                                }
507
508                                ($propRef, $nodesRef, $tagsRef) = getWay3() ;
509                        }
510                        closeOsmFile() ;
511                        print "$contourCount contour ways found.\n" ;
512
513                }
514
515                # store min / max of temp file
516
517
518                openOsmFile ($temp1FileName) ;
519                ($propRef, $tagsRef) = getNode3() ;
520                while (defined $propRef) {
521
522                        if (defined $neededNodes { $$propRef{"id"} }) {
523                                $lon { $$propRef{"id"} } = $$propRef{"lon"} ;
524                                $lat { $$propRef{"id"} } = $$propRef{"lat"} ;
525                        }
526
527                        if ( $$propRef{"lon"} > $file1LonMax ) { $file1LonMax = $$propRef{"lon"} ; }
528                        if ( $$propRef{"lon"} < $file1LonMin ) { $file1LonMin = $$propRef{"lon"} ; }
529                        if ( $$propRef{"lat"} > $file1LatMax ) { $file1LatMax = $$propRef{"lat"} ; }
530                        if ( $$propRef{"lat"} < $file1LatMin ) { $file1LatMin = $$propRef{"lat"} ; }
531
532                        if ($atlasOpt eq "") {
533
534                                # poi check and data collection
535                                foreach my $t (@$tagsRef) {
536                                        foreach my $p (@pois) {
537                                                if ( ($t->[0] eq $p->[0]) and ($t->[1] eq $p->[1]) ) {
538                                                        my $name = "" ;
539                                                        foreach my $t1 (@$tagsRef) {
540                                                                if ($t1->[0] eq "name") { $name = $t1->[1] ; }
541                                                        }
542                                                        my $info ;
543                                                        if ($languageOpt eq "EN") { $info = $p->[3] ; }
544                                                        if ($languageOpt eq "DE") { $info = $p->[4] ; }
545                                                        $name = sanitizeLatexString ($name) ;
546                                                        push @poiList, [ $info, $name, $$propRef{"id"}, $p->[2] ] ;
547                                                        $lon{ $$propRef{"id"} } = $$propRef{"lon"} ;
548                                                        $lat{ $$propRef{"id"} } = $$propRef{"lat"} ;
549                                                }
550                                        }
551                                }
552
553                        }
554
555                        ($propRef, $tagsRef) = getNode3() ;
556                }
557                closeOsmFile() ;
558
559                # print "temp1: $file1LonMin, $file1LatMin, $file1LonMax, $file1LatMax\n" ;
560
561                $qt = OSM::QuadTree->new (      -xmin => $file1LonMin, 
562                                                -xmax => $file1LonMax, 
563                                                -ymin => $file1LatMin, 
564                                                -ymax => $file1LatMax, 
565                                                -depth => 6) ;
566
567
568        }
569}
570
571sub createOverviewMap {
572        print "\ncreate overview map...\n" ;
573
574        my $scale ;
575        # my $distLon = distance ($relLonMin, $relLatMin, $relLonMax, $relLatMin) ; # in km
576        # my $distLat = distance ($relLonMin, $relLatMin, $relLonMin, $relLatMax) ; # in km
577        # 0.92
578        my $distLon = distance ($detailLonMin, $detailLatMin, $detailLonMax, $detailLatMin) ; # in km
579        my $distLat = distance ($detailLonMin, $detailLatMin, $detailLonMin, $detailLatMax) ; # in km
580
581        $distLon = int ($distLon * 1000) / 1000 ;
582        $distLat = int ($distLat * 1000) / 1000 ;
583
584        if ($verboseOpt eq "1") {
585                print "overview distances lon / lat in km: $distLon $distLat\n" ;
586        }
587
588        my $distWidth = $pageWidth{$pageSizeOpt} / 100 / 1000 ;
589        my $distHeight = $pageHeight{$pageSizeOpt} / 100 / 1000 ;
590        my $scaleWidth =  int ($distLon / $distWidth) ;
591        my $scaleHeight =  int ($distLat / $distHeight) ;
592
593        if ($verboseOpt eq "1") {
594                print "overview scales W/H: $scaleWidth / $scaleHeight\n" ;
595        }
596
597        # select min scale
598        $scale = $scaleWidth ;
599        if ($scaleHeight > $scale) { $scale = $scaleHeight ; }
600
601        # select fitting scale
602        foreach my $s (@overviewScales) {
603                if ($s > $scale) {
604                        $scale = $s ;
605                        last ;
606                }
607        }
608
609        $scaleOverview = $scale ;
610
611        if ($verboseOpt eq "1") {
612                print "selected overview scale: $scale\n" ;
613        }
614
615
616        my $outName = $workDir . "overview.svg" ;
617        if ($noOutputOpt eq "0") {
618
619                my $pdfName = $outName ; $pdfName =~ s/\.svg/\.pdf/ ;
620                my $ndlName = $outName ; $ndlName =~ s/\.svg/\_NotDrawnLabels\.txt/ ;
621                push @tempFiles, $outName ;
622                push @tempFiles, $pdfName ;
623                push @tempFiles, $ndlName ;
624
625                # allow for some more data than just the relation 0.92
626                my $more = 0.005 ;
627                my $ovLonMin = $detailLonMin - $more ;
628                my $ovLonMax = $detailLonMax + $more ;
629                my $ovLatMin = $detailLatMin - $more ;
630                my $ovLatMax = $detailLatMax + $more ;
631
632                # but check if data is present
633                if ($ovLonMin < $file1LonMin) { $ovLonMin = $file1LonMin ; }
634                if ($ovLonMax > $file1LonMax) { $ovLonMax = $file1LonMax ; }
635                if ($ovLatMin < $file1LatMin) { $ovLatMin = $file1LatMin ; }
636                if ($ovLatMax > $file1LatMax) { $ovLatMax = $file1LatMax ; }
637
638
639                print "call mapgen and log to $logFileName...\n" ;
640
641                `$mapgenCommandOverview -in=$temp1FileName -out=$outName -style=$overviewStyleFileName -scaleset=$scaleOverview -clipbbox=$ovLonMin,$ovLatMin,$ovLonMax,$ovLatMax -relid=$relationId $rectangles >> $logFileName 2>&1` ;
642
643                print "done.\n" ;
644        }
645}
646
647
648
649sub buildCompleteWay {
650#
651# this function tries to make sense of all the ways collected from the relation
652#
653        my %leftWays = () ;
654
655        my @orderedWays ;
656
657        print "\nbuilding complete way for relation...\n" ;
658
659        my $firstWay = shift @ways ;
660        @orderedWays = ($firstWay) ;
661
662        if ($roundtripOpt eq "1") {
663                # assure that first way can be expanded at the end
664                my @n = @{$wayNodesHash{ $firstWay }} ;
665                my $end = $n[-1] ;
666                my $found = 0 ;
667                foreach my $w (@ways) {
668                        my @tn = @{$wayNodesHash{ $w }} ;
669                        if ( ($tn[0] == $end) or ($tn[-1] == $end) ) { $found = 1 ; }
670                }
671                if ($found == 0) {
672                        @{$wayNodesHash{ $firstWay }} = reverse @{$wayNodesHash{ $firstWay }} ;
673                }
674        }
675
676
677        @nodes = @{$wayNodesHash{ $firstWay }} ;
678
679        foreach my $w (@ways) { $leftWays{ $w } = 1 ; }
680
681        my $success = 1 ;
682        while ( $success and ( scalar (keys %leftWays) > 0 ) ) {
683                $success = 0 ;
684
685                foreach my $w (keys %leftWays) {
686                        my @wayNodes = @{$wayNodesHash{$w}} ;
687
688                        if ( ( $nodes[0] == $wayNodes[0] ) and ($roundtripOpt == 0) ) {
689                        # if ( ( $nodes[0] == $wayNodes[0] ) ) {
690                                # reverse unshift
691                                @wayNodes = reverse @wayNodes ;
692                                pop @wayNodes ; # remove last element
693                                unshift @nodes, @wayNodes ;
694                                unshift @orderedWays, $w ;
695                                $success = 1 ;
696                                delete $leftWays{ $w } ;
697                                last ;
698                        }
699
700                        if ( ( $nodes[0] == $wayNodes[-1] ) and ($roundtripOpt == 0) ) {
701                        # if ( ( $nodes[0] == $wayNodes[-1] ) ) {
702                                # unshift
703                                pop @wayNodes ; # remove last element
704                                unshift @nodes, @wayNodes ;
705                                unshift @orderedWays, $w ;
706                                $success = 1 ;
707                                delete $leftWays{ $w } ;
708                                last ;
709                        }
710
711                        if ( $nodes[-1] == $wayNodes[0] ) {
712                                # push
713                                shift @wayNodes ; # remove first element
714                                push @nodes, @wayNodes ;
715                                push @orderedWays, $w ;
716                                $success = 1 ;
717                                delete $leftWays{ $w } ;
718                                last ;
719                        }
720
721                        if ( $nodes[-1] == $wayNodes[-1] ) {
722                                # push reverse
723                                @wayNodes = reverse @wayNodes ;
724                                shift @wayNodes ; # remove first element
725                                push @nodes, @wayNodes ;
726                                push @orderedWays, $w ;
727                                $success = 1 ;
728                                delete $leftWays{ $w } ;
729                                last ;
730                        }
731
732                }
733        }
734
735        if ( $nodes[0] == $nodes[-1]) { print "found segment is closed.\n" ; }
736        if ( scalar (keys %leftWays) > 0) { print "WARNING: relation consists of more than one segment. using only first one.\n" ; }
737
738        my $nc = scalar @nodes ;
739
740        if ($verboseOpt eq "1") {
741                print "used segment consists of $nc nodes.\n" ;
742        }
743
744        @ways = @orderedWays ;
745
746        if ( $lon{ $nodes[0] } > $lon{ $nodes[-1] } ) { 
747                @nodes = reverse @nodes ; 
748                @ways = reverse @ways ;
749        } 
750
751        if ($reverseOpt eq "1") {
752                print "reversing ways and nodes.\n" ;
753                @nodes = reverse @nodes ; 
754                @ways = reverse @ways ;
755        }
756       
757        # get names of ways to nodes for directions
758        foreach my $w (@ways) {
759                foreach my $n (@{$wayNodesHash{$w}}) {
760                        $nodeName{$n} = $wayNameHash{$w} ;
761                }
762        }
763
764        # calc distances // nodeinfo is indexed by node number, not ID!
765        my $dist = 0 ;
766        $nodeInfo{0}{"distance"} = 0 ;
767        for (my $i = 1;  $i<=$#nodes; $i++) {
768                $dist += distance ($lon{$nodes[$i-1]}, $lat{$nodes[$i-1]}, $lon{$nodes[$i]}, $lat{$nodes[$i]}) ;
769                $nodeInfo{$i}{"distance"} = int ($dist * 100) / 100 ;
770        }
771        $segmentLength = $dist ;
772        $dist = int ($dist * 1000) / 1000 ;
773        print "used route segment is $dist km long.\n" ;
774
775        # nodeinfo is indexed by nodeNumber, NOT id!
776        for (my $i = 0;  $i<$#nodes; $i++) {
777                $nodeInfo{$i}{"direction"} = direction ($nodes[$i], $nodes[$i+1]) ;             
778                $nodeInfo{$i}{"angle"} = angle ($lon{$nodes[$i]}, $lat{$nodes[$i]}, $lon{$nodes[$i+1]}, $lat{$nodes[$i+1]}) ;
779                $nodeInfo{$i}{"name"} = sanitizeLatexString ( $nodeName{ $nodes[$i] } ) ;               
780                $nodeInfo{$i}{"ele"} = $nodeElevation{ $nodes[$i] } ;           
781                $nodeInfo{$i}{"dirs"} = $nodeDirCount{ $nodes[$i] } ;           
782        }
783
784        $nodeInfo{$#nodes}{"ele"} = $nodeElevation{ $nodes[ -1 ] } ;
785        $nodeInfo{$#nodes}{"dirs"} = $nodeDirCount{ $nodes[ -1 ] } ;
786        $nodeInfo{$#nodes}{"direction"} = "" ;
787        $nodeInfo{$#nodes}{"angle"} = 0 ;
788        $nodeInfo{$#nodes}{"name"} = "" ;
789
790        my %info = () ;
791        $info{"EN"}{"start"} = "Start" ;
792        $info{"EN"}{"end"} = "End" ;
793        $info{"DE"}{"start"} = "Start" ;
794        $info{"DE"}{"end"} = "Ende" ;
795        @{$nodeInfo{0}{"information"}} = ( $info{$languageOpt}{"start"} ) ;
796        @{$nodeInfo{$#nodes}{"information"}} = ( $info{$languageOpt}{"end"} ) ;
797
798       
799
800        if ($verboseOpt eq "1") {
801                print "ordered ways: @ways\n" ;
802                print "\nordered nodes: @nodes\n\n" ;
803        }
804}
805
806
807
808sub createDetailMaps {
809
810        print "\ncreate detail maps...\n" ;
811
812        my $first = 1 ;
813
814        my $maxDistLon = $pageWidth{$pageSizeOpt} / 100 / 1000 * $scale ; # in km
815        my $maxDistLat = $pageHeight{$pageSizeOpt} / 100 / 1000 * $scale ; # in km
816
817        my $maxDistLonOverlap = $maxDistLon * ( 1 - 2 * $overlapOpt / 100) ;
818        my $maxDistLatOverlap  = $maxDistLat * ( 1 - 2 * $overlapOpt / 100) ;
819
820        # print "DETAIL:  page max dists $maxDistLon / $maxDistLat\n" ;
821
822        my $mapName = "detail" ;
823        my $start = 0 ;
824        my $finished = 0 ;
825
826        while ( ! $finished ) {
827               
828                my $actual = $start ;
829                my $rotated = 0 ;
830                my $lonMin = $lon{$nodes[$start]} ;
831                my $lonMax = $lon{$nodes[$start]} ;
832                my $latMin = $lat{$nodes[$start]} ;
833                my $latMax = $lat{$nodes[$start]} ;
834               
835                my $busted = 0 ;
836                while ( ( ! $busted ) and ($actual < $#nodes) ) {
837
838                        # print " $actual\n" ;
839                        my $tempLonMax = $lonMax ;
840                        my $tempLonMin = $lonMin ;
841                        my $tempLatMax = $latMax ;
842                        my $tempLatMin = $latMin ;
843
844                        # add point
845                        $actual++ ;
846                        if ( $lon{ $nodes[ $actual ] } > $lonMax) { $lonMax = $lon{ $nodes[ $actual ] } ; }
847                        if ( $lon{ $nodes[ $actual ] } < $lonMin) { $lonMin = $lon{ $nodes[ $actual ] } ; }
848                        if ( $lat{ $nodes[ $actual ] } > $latMax) { $latMax = $lat{ $nodes[ $actual ] } ; }
849                        if ( $lat{ $nodes[ $actual ] } < $latMin) { $latMin = $lat{ $nodes[ $actual ] } ; }
850
851                        my $distLon = distance ($lonMin, $latMin, $lonMax, $latMin) ;
852                        my $distLat = distance ($lonMin, $latMin, $lonMin, $latMax) ;
853
854                        # print "$actual:  $distLon / $distLat\n" ;
855
856                        # autorotate
857                        if ( ($autorotateOpt eq "1") and ( ! $rotated) ) {
858                                if      ( ( ($distLon > $maxDistLonOverlap) and ( $distLat < $maxDistLonOverlap) and ($maxDistLatOverlap > $maxDistLonOverlap) )
859                                        or ( ($distLat > $maxDistLatOverlap) and ( $distLon < $maxDistLatOverlap)  and ($maxDistLatOverlap < $maxDistLonOverlap) )
860                                        ) { 
861                                        if ($verboseOpt eq "1") { print "actual page automatically rotated.\n" ; }
862
863                                        # print "rotated\n" ;
864
865                                        $rotated = 1 ;
866                                        $maxDistLon = $pageHeight{$pageSizeOpt} / 100 / 1000 * $scale ; # in km
867                                        $maxDistLat = $pageWidth{$pageSizeOpt} / 100 / 1000 * $scale ; # in km
868
869                                        $maxDistLonOverlap = $maxDistLon * ( 1 - 2 * $overlapOpt / 100) ;
870                                        $maxDistLatOverlap  = $maxDistLat * ( 1 - 2 * $overlapOpt / 100) ;
871                                }
872                        }       
873
874                        if ( ($distLon > $maxDistLonOverlap) or ($distLat > $maxDistLatOverlap) ) { 
875                                # print "BUSTED\n" ;
876                                $busted = 1 ; 
877                                $actual-- ;
878                                # restore max and min
879                                $lonMax = $tempLonMax ;
880                                $lonMin = $tempLonMin ;
881                                $latMax = $tempLatMax ;
882                                $latMin = $tempLatMin;
883                        }
884                }
885
886                if ($actual == $#nodes) { $finished = 1 ; }
887
888                # create map
889                my $percent = int ($actual / $#nodes * 100) ;
890                print "\ncreate map for nodes $start to $actual ($percent \%).\n" ;
891
892                # print "DETAIL: initial bbox = $lonMin,$latMin,$lonMax,$latMax\n" ;
893                # print "DETAIL: max dists = $maxDistLon $maxDistLat\n" ;
894
895                my $distLon = distance ($lonMin, $latMin, $lonMax, $latMin) ;
896                my $distLat = distance ($lonMin, $latMin, $lonMin, $latMax) ;
897                # print "DETAIL: actual dists: $distLon, $distLat\n" ;
898
899
900                my $missingLat = $maxDistLat - $distLat ;
901                my $missingLatFactor = $missingLat / $distLat ;
902                my $additionalLat = ($latMax-$latMin) * $missingLatFactor / 2 ;
903                # print "DETAIL: LAT: $missingLat $missingLatFactor $additionalLat\n" ;
904               
905                $latMin = $latMin - $additionalLat ;
906                $latMax = $latMax + $additionalLat ;
907
908                my $missingLon = $maxDistLon - $distLon ;
909                my $missingLonFactor = $missingLon / $distLon ;
910                my $additionalLon = ($lonMax-$lonMin) * $missingLonFactor / 2 ;
911                # print "DETAIL: LON: $missingLon $missingLonFactor $additionalLon\n" ;
912
913                $lonMin = $lonMin - $additionalLon ;
914                $lonMax = $lonMax + $additionalLon ;
915
916                # print "DETAIL: bbox after factor = $lonMin,$latMin,$lonMax,$latMax\n" ;
917
918
919
920                $mapNumber++ ;
921                my $outName = $workDir . $mapName . $mapNumber . ".svg" ;
922                my $actualScale = $scale ;
923                if ($noOutputOpt eq "0") {
924
925
926                        shrinkFile ($temp1FileName, $temp2FileName, $file1LonMin, $file1LatMin, $file1LonMax, $file1LatMax, $lonMin, $latMin, $lonMax, $latMax, $extraMapData2) ;
927
928                        my ($file2LonMin, $file2LatMin, $file2LonMax, $file2LatMax) = getMinMax ($temp2FileName)  ;
929
930                        if ($lonMin < $file2LonMin) { $lonMin = $file2LonMin ; }
931                        if ($lonMax > $file2LonMax) { $lonMax = $file2LonMax ; }
932                        if ($latMin < $file2LatMin) { $latMin = $file2LatMin ; }
933                        if ($latMax > $file2LatMax) { $latMax = $file2LatMax ; }
934
935                        # maintain details outer box 0.92
936                        if ($lonMin < $detailLonMin) { $detailLonMin = $lonMin ; }
937                        if ($lonMax > $detailLonMax) { $detailLonMax = $lonMax ; }
938                        if ($latMin < $detailLatMin) { $detailLatMin = $latMin ; }
939                        if ($latMax > $detailLatMax) { $detailLatMax = $latMax ; }
940
941                        # print "DETAIL: bbox before mapgen = $lonMin,$latMin,$lonMax,$latMax\n" ;
942
943                        if ($first) {
944                                $first = 0 ;
945                                $rectangles = "-rectangles=" ;
946                        }
947                        else {
948                                $rectangles .= "#" ;
949                        }
950                        $rectangles .= "$lonMin,$latMin,$lonMax,$latMax" ;
951
952                        my $pdfName = $outName ; $pdfName =~ s/\.svg/\.pdf/ ;
953                        my $ndlName = $outName ; $ndlName =~ s/\.svg/\_NotDrawnLabels\.txt/ ;
954                        push @tempFiles, $outName ;
955                        push @tempFiles, $pdfName ;
956                        push @tempFiles, $ndlName ;
957
958                        my $poiParams = "" ;
959                        if ($poiOpt > 0) {
960                                $poiParams = "-poi -grid=$gridNumber" ;
961                        }
962
963                        my $streetParams = "" ;
964                        if ($streetOpt > 0) {
965                                $streetParams = "-dir -grid=$gridNumber" ;
966                        }
967
968                        print "call mapgen and log to $logFileName...\n" ;
969                        `$mapgenCommandDetail -in=$temp2FileName -out=$outName -style=$detailStyleFileName -scaleset=$actualScale -clipbbox=$lonMin,$latMin,$lonMax,$latMax -poifile=step.txt -relid=$relationId -pagenumbers=$pnSizeDetail,black,$mapNumber $poiParams $streetParams >> $logFileName 2>&1` ;
970                        print "done.\n" ;
971
972                        loadExternalFiles($outName) ;
973
974                }
975
976                # next
977                $start = $actual ;
978
979                # restore sizes (after rotate)
980                $maxDistLon = $pageWidth{$pageSizeOpt} / 100 / 1000 * $scale ; # in km
981                $maxDistLat = $pageHeight{$pageSizeOpt} / 100 / 1000 * $scale ; # in km
982
983                $maxDistLonOverlap = $maxDistLon * ( 1 - 2 * $overlapOpt / 100) ;
984                $maxDistLatOverlap  = $maxDistLat * ( 1 - 2 * $overlapOpt / 100) ;
985
986
987        }
988
989}
990
991sub createDetailMapsAtlas {
992        my $mapName = "detail" ;
993        my $first = 1 ;
994
995        # calc dists
996
997        my $maxDistLon = $pageWidth{$pageSizeOpt} / 100 / 1000 * $scale ; # in km
998        my $maxDistLat = $pageHeight{$pageSizeOpt} / 100 / 1000 * $scale ; # in km
999        my $sizeX = $maxDistLon / (111.11 * cos ($relLatMin / 360 * 3.14 * 2) ) ;
1000        my $sizeY = $maxDistLat / 111.11 ;
1001        if ($verboseOpt eq "1") {
1002                print "MAX dists: $maxDistLon, $maxDistLat (km)   $sizeX, $sizeY (degrees)\n" ; 
1003        }
1004
1005
1006        my @hor = () ;
1007        my @ver = () ;
1008
1009        my $x = $relLonMin ; 
1010        my $x2 = $x + $sizeX ;
1011        push @hor, [$x, $x2] ;
1012        # print "$x $x2\n" ;
1013        while ($x2 < $relLonMax) {
1014                $x = $x2 - $sizeX * ($overlapOpt/100) ;
1015                $x2 = $x + $sizeX ;
1016                if ($x2 > $relLonMax) { $x2 = $relLonMax ; }
1017                push @hor, [$x, $x2] ;
1018                # print "$x $x2\n" ;
1019        }
1020
1021        my $y = $relLatMax ; 
1022        my $y2 = $y - $sizeY ;
1023        push @ver, [$y2, $y] ;
1024        # print "$y $y2\n" ;
1025        while ($y2 > $relLatMin) {
1026                $y = $y2 + $sizeY * ($overlapOpt/100) ;
1027                $y2 = $y - $sizeY ;
1028                if ($y2 < $relLatMin) { $y2 = $relLatMin ; }
1029                push @ver, [$y2, $y] ;
1030                # print "$y $y2\n" ;
1031        }
1032        my $nx = scalar @hor ;
1033        my $ny = scalar @ver ;
1034        print "Dimensions: $nx * $ny (width * height)\n" ;
1035        my $ntot = $nx * $ny ;
1036
1037        my $page ; my $py = 1 ; my $tot ;
1038        foreach my $v (@ver) {
1039                my $px = 1 ; 
1040                foreach my $h (@hor) {
1041                        $tot = ($py-1) * (scalar @hor) + $px ;
1042                        print "\n\ndetail maps progress: y=$py, x=$px  -  $h->[0] $v->[0] $h->[1] $v->[1]  -   page: $tot/$ntot\n" ;
1043
1044                        my $left ; my $right ; my $top ; my $bottom ;
1045                        if ($px > 1) { $left = $px - 1 + ($py - 1) * (scalar @hor) ; } else { $left = 0 ; }
1046                        if ($px < scalar @hor) { $right = $px + 1 + ($py - 1) * scalar @hor ; } else { $right = 0 ; }
1047                        # print "TEST ", ($py - 2) * (scalar @hor) + $px, "\n" ;
1048                        if ($py > 1) { $top = ($py - 2) * (scalar @hor) + $px ; } else { $top = 0 ; }
1049                        if ($py < scalar @ver) { $bottom = ($py) * (scalar @hor) + $px ; } else { $bottom = 0 ; }
1050                        if ($verboseOpt eq "1") {
1051                                print "neighbour pages: $bottom $top // $left $right\n\n" ;
1052                        }
1053
1054                        my $lonMin = $h->[0] ;
1055                        my $lonMax = $h->[1] ;
1056                        my $latMin = $v->[0] ;
1057                        my $latMax = $v->[1] ;
1058       
1059                        #
1060                        # create map
1061                        #
1062
1063                        $mapNumber++ ;
1064                        my $outName = $workDir . $mapName . $mapNumber . ".svg" ;
1065
1066                        shrinkFile ($temp1FileName, $temp2FileName, $file1LonMin, $file1LatMin, $file1LonMax, $file1LatMax, $lonMin, $latMin, $lonMax, $latMax, $extraMapData2) ;
1067
1068                        my ($file2LonMin, $file2LatMin, $file2LonMax, $file2LatMax) = getMinMax ($temp2FileName)  ;
1069
1070                        if ($lonMin < $file2LonMin) { $lonMin = $file2LonMin ; }
1071                        if ($lonMax > $file2LonMax) { $lonMax = $file2LonMax ; }
1072                        if ($latMin < $file2LatMin) { $latMin = $file2LatMin ; }
1073                        if ($latMax > $file2LatMax) { $latMax = $file2LatMax ; }
1074
1075                        # maintain details outer box
1076                        if ($lonMin < $detailLonMin) { $detailLonMin = $lonMin ; }
1077                        if ($lonMax > $detailLonMax) { $detailLonMax = $lonMax ; }
1078                        if ($latMin < $detailLatMin) { $detailLatMin = $latMin ; }
1079                        if ($latMax > $detailLatMax) { $detailLatMax = $latMax ; }
1080
1081                        # print "DETAIL: bbox before mapgen = $lonMin,$latMin,$lonMax,$latMax\n" ;
1082
1083                        if ($first) {
1084                                $first = 0 ;
1085                                $rectangles = "-rectangles=" ;
1086                        }
1087                        else {
1088                                $rectangles .= "#" ;
1089                        }
1090                        $rectangles .= "$lonMin,$latMin,$lonMax,$latMax" ;
1091
1092                        my $pdfName = $outName ; $pdfName =~ s/\.svg/\.pdf/ ;
1093                        my $ndlName = $outName ; $ndlName =~ s/\.svg/\_NotDrawnLabels\.txt/ ;
1094                        push @tempFiles, $outName ;
1095                        push @tempFiles, $pdfName ;
1096                        push @tempFiles, $ndlName ;
1097
1098                        my $poiParams = "" ;
1099                        if ($poiOpt > 0) {
1100                                $poiParams = "-poi -grid=$gridNumber" ;
1101                        }
1102
1103                        my $streetParams = "" ;
1104                        if ($streetOpt > 0) {
1105                                $streetParams = "-dir -grid=$gridNumber" ;
1106                        }
1107
1108                        my $pageNumbers = "$pnSizeDetail,black,$mapNumber,$left,$bottom,$right,$top" ;
1109
1110                        print "call mapgen and log to $logFileName...\n" ;
1111                        `$mapgenCommandDetail -in=$temp2FileName -out=$outName -style=$detailStyleFileName -scaleset=$scale -clipbbox=$lonMin,$latMin,$lonMax,$latMax -pagenumbers=$pageNumbers $poiParams $streetParams >> $logFileName 2>&1` ;
1112                        print "done.\n" ;
1113
1114                        loadExternalFiles($outName) ;
1115
1116
1117
1118                        $px ++ ;
1119                }
1120                $py ++ ;
1121        }
1122}
1123
1124
1125sub shrinkFile {
1126        my ($inFileName, $outFileName, $inLonMin, $inLatMin, $inLonMax, $inLatMax, $outLonMin, $outLatMin, $outLonMax, $outLatMax, $pad) = @_ ;
1127
1128        # print "SHRINK:\n" ;
1129        # print "$inFileName, $outFileName, $inLonMin, $inLatMin, $inLonMax, $inLatMax, $outLonMin, $outLatMin, $outLonMax, $outLatMax, $percentPad\n" ;
1130
1131        # calc new bbox
1132        $outLonMax += $pad ; # 0.92
1133        $outLonMin -= $pad ;
1134        $outLatMax += $pad ;
1135        $outLatMin -= $pad ;
1136       
1137        # check against source bbox
1138        if ($outLonMin < $inLonMin) { $outLonMin = $inLonMin ; }
1139        if ($outLonMax > $inLonMax) { $outLonMax = $inLonMax ; }
1140        if ($outLatMin < $inLatMin) { $outLatMin = $inLatMin ; }
1141        if ($outLatMax > $inLatMax) { $outLatMax = $inLatMax ; }
1142
1143        # print "bottom=$outLatMin top=$outLatMax left=$outLonMin right=$outLonMax\n" ;
1144        # print "SHRINK END\n" ;
1145
1146
1147        # call osmosis
1148        print "call osmosis and log to $logFileName...\n" ;
1149
1150        # `osmosis --read-xml $inFileName  --bounding-box clipIncompleteEntities=true bottom=$outLatMin top=$outLatMax left=$outLonMin right=$outLonMax --write-xml $outFileName >> $logFileName 2>&1` ;
1151
1152        `osmosis --read-xml $inFileName  --bounding-box completeWays=yes completeRelations=yes bottom=$outLatMin top=$outLatMax left=$outLonMin right=$outLonMax --write-xml $outFileName >> $logFileName 2>&1` ;
1153
1154        print "osmosis done.\n" ;
1155
1156}
1157
1158sub direction {
1159        my ($node1, $node2) = @_ ;
1160
1161        my %direction = () ;
1162        $direction{"EN"}{"N"} = "North" ;
1163        $direction{"EN"}{"S"} = "South" ;
1164        $direction{"EN"}{"W"} = "West" ;
1165        $direction{"EN"}{"E"} = "East" ;
1166        $direction{"EN"}{"NE"} = "North-East" ;
1167        $direction{"EN"}{"NW"} = "North-West" ;
1168        $direction{"EN"}{"SE"} = "South-East" ;
1169        $direction{"EN"}{"SW"} = "South-West" ;
1170
1171        $direction{"DE"}{"N"} = "Nord" ;
1172        $direction{"DE"}{"S"} = "Süd" ;
1173        $direction{"DE"}{"W"} = "West" ;
1174        $direction{"DE"}{"E"} = "Ost" ;
1175        $direction{"DE"}{"NE"} = "Nordost" ;
1176        $direction{"DE"}{"NW"} = "Nordwest" ;
1177        $direction{"DE"}{"SE"} = "Südost" ;
1178        $direction{"DE"}{"SW"} = "Südwest" ;
1179
1180        my $a = angle ($lon{$node1}, $lat{$node1}, $lon{$node2}, $lat{$node2}) ;       
1181
1182        my $dir = "" ;
1183
1184        if ($dirNumberOpt eq "8") {
1185                if ( ($a < 22.5) or ($a >= 337.5) ) { $dir = $direction {$languageOpt}{"N"} ; }
1186                if ( ($a >= 22.5) and ($a < 67.5) ) { $dir = $direction {$languageOpt}{"NE"} ; }
1187                if ( ($a >= 67.5) and ($a < 112.5) ) { $dir = $direction {$languageOpt}{"E"} ; }
1188                if ( ($a >= 112.5) and ($a < 167.5) ) { $dir = $direction {$languageOpt}{"SE"} ; }
1189                if ( ($a >= 167.5) and ($a < 202.5) ) { $dir = $direction {$languageOpt}{"S"} ; }
1190                if ( ($a >= 202.5) and ($a < 247.5) ) { $dir = $direction {$languageOpt}{"SW"} ; }
1191                if ( ($a >= 247.5) and ($a < 292.5) ) { $dir = $direction {$languageOpt}{"W"} ; }
1192                if ( ($a >= 292.5) and ($a < 337.5) ) { $dir = $direction {$languageOpt}{"NW"} ; }
1193        }
1194        else {
1195                if ( ($a < 45) or ($a >= 315) ) { $dir = $direction {$languageOpt}{"N"} ; }
1196                if ( ($a >= 45) and ($a < 135) ) { $dir = $direction {$languageOpt}{"E"} ; }
1197                if ( ($a >= 135) and ($a < 225) ) { $dir = $direction {$languageOpt}{"S"} ; }
1198                if ( ($a >= 225) and ($a < 315) ) { $dir = $direction {$languageOpt}{"W"} ; }
1199        }
1200
1201        return $dir ;
1202}
1203
1204
1205sub mergeAllFiles {
1206        my $files ;
1207
1208        $files .= $workDir . "title.pdf" ;
1209        $files .= " " . $workDir . "overview.pdf" ;
1210
1211        if ($atlasOpt eq "") {
1212                $files .= " " . $workDir . "directions.pdf" ;
1213        }
1214
1215        for (my $i = 1; $i <= $mapNumber; $i++) {
1216                my $name ;
1217                $name = " " . $workDir . "detail" . $i . ".pdf" ; 
1218                $files .= $name ;
1219        }
1220
1221        if ( ($poiOpt > 0) or ($streetOpt > 0) ) {
1222                $files .= " " . $workDir . "directory.pdf" ; 
1223        }
1224
1225        print "\nmerge pdfs ($files) into $outFileName and log to $logFileName\n" ;
1226
1227        `pdfjoin --outfile \"$outFileName\" $files >> $logFileName 2>&1` ;
1228
1229}
1230
1231
1232sub createDirections {
1233        print "\ncreating directions...\n" ;
1234
1235        my $stepFileName = "step.txt" ;
1236        open (my $stepFile, ">", $stepFileName) or die ("can't open step output file") ;
1237
1238        my $texFileName ; 
1239        my $ltxFileName ; 
1240        $texFileName = "directions.tex" ;
1241        $ltxFileName = "directionsltx.tex" ;
1242        push @tempFiles, $texFileName ;
1243        push @tempFiles, $stepFileName ;
1244        push @tempFiles, $ltxFileName ;
1245        my %label = () ;
1246        $label{"EN"}{"directions"} = "Directions" ;
1247        $label{"DE"}{"directions"} = "Wegbeschreibung" ;
1248        $label{"EN"}{"number"} = "Nr" ;
1249        $label{"DE"}{"number"} = "Nr" ;
1250        $label{"EN"}{"distance"} = "Distance" ;
1251        $label{"DE"}{"distance"} = "Entfernung" ;
1252        $label{"EN"}{"name"} = "Name" ;
1253        $label{"DE"}{"name"} = "Name" ;
1254        $label{"EN"}{"direction"} = "Direction" ;
1255        $label{"DE"}{"direction"} = "Richtung" ;
1256        $label{"EN"}{"elevation"} = "Elevation" ;
1257        $label{"DE"}{"elevation"} = "Höhe" ;
1258        $label{"EN"}{"info"} = "Information" ;
1259        $label{"DE"}{"info"} = "Informationen" ;
1260        $label{"EN"}{"eleprofile"} = "Elevation profile" ;
1261        $label{"DE"}{"eleprofile"} = "Höhenprofil" ;
1262
1263        open (my $texFile, ">", $texFileName) or die ("can't open tex output file") ;
1264        open (my $ltxFile, ">", $ltxFileName) or die ("can't open tex ltx output file") ;
1265        if ($pageSizeOpt eq "A5") {
1266                print $texFile "\\documentclass[a5paper,12pt]{book}\n" ;
1267        }
1268        else {
1269                print $texFile "\\documentclass[a4paper,12pt]{book}\n" ;
1270        }
1271        print $texFile "\\usepackage[utf8]{inputenc}\n" ;
1272        print $texFile "\\usepackage{longtable}\n" ;
1273        print $texFile "\\usepackage{ltxtable}\n" ;
1274        print $texFile "\\columnsep7mm\n" ;
1275        print $texFile "\\begin{document}\n" ;
1276        print $texFile "\\section*{" .  $label{$languageOpt}{"directions"} . "}\n" ;
1277        print $texFile "\\LTXtable{\\textwidth}{directionsltx}\n" ;
1278
1279        my $elevationDataPresent = 0 ;
1280        for (my $i=0; $i <= $#nodes; $i++) {
1281                if ($nodeInfo{$i}{'ele'} ne "") { $elevationDataPresent = 1 ; }
1282        }
1283
1284        print $ltxFile "\\tiny\n" ;
1285
1286        if ($elevationDataPresent) {
1287                print $ltxFile "\\begin{longtable}{|p{1cm}|p{2cm}|p{1.5cm}|p{3cm}|p{2cm}|p{3cm}|}\n" ;
1288        }
1289        else {
1290                print $ltxFile "\\begin{longtable}{|p{1cm}|p{2cm}|p{3cm}|p{2cm}|p{4.5cm}|}\n" ;
1291        }
1292
1293        print $ltxFile "\\hline\n" ;
1294
1295        if ($elevationDataPresent) {
1296                print $ltxFile "$label{$languageOpt}{'number'} & $label{$languageOpt}{'distance'} & $label{$languageOpt}{'elevation'} & $label{$languageOpt}{'name'} & $label{$languageOpt}{'direction'} & $label{$languageOpt}{'info'} \\\\ \n" ;
1297        }
1298        else {
1299                print $ltxFile "$label{$languageOpt}{'number'} & $label{$languageOpt}{'distance'} & $label{$languageOpt}{'name'} & $label{$languageOpt}{'direction'} & $label{$languageOpt}{'info'} \\\\ \n" ;
1300        }
1301        print $ltxFile "\\hline\n" ;
1302
1303
1304        my %toPrint = () ;
1305        $toPrint{0} = 1 ; 
1306        $toPrint{ $#nodes } = 1 ; 
1307        for (my $i=1; $i<$#nodes; $i++) {
1308                # if ($nodeInfo{$i-1}{"direction"} ne $nodeInfo{$i}{"direction"}) { $toPrint{$i} = 1 ; }
1309
1310                # if ($nodeInfo{$i}{"dirs"} > 2) { $toPrint{$i} = 1 ; } #0.92
1311                if ( ($nodeInfo{$i}{"dirs"} > 2) and ( dirChange ($nodeInfo{$i-1}{"angle"}, $nodeInfo{$i}{"angle"}) > $lessStepsOpt) ) { $toPrint{$i} = 1 ; } #0.92
1312
1313                if ($nodeInfo{$i-1}{"name"} ne $nodeInfo{$i}{"name"}) { $toPrint{$i} = 1 ; }
1314                if ($nodeInfo{$i}{"ele"} ne "") { $toPrint{$i} = 1 ; }
1315                if ( defined $nodeInfo{$i}{"information"} ) { $toPrint{$i} = 1 ; }
1316        }
1317
1318        # prepare information
1319        my %info = () ;
1320        for (my $i=0; $i <= $#nodes; $i++) {
1321                $info{$i} = "" ;
1322                if (defined $nodeInfo{$i}{'information'} ) {
1323                        my @a = () ; 
1324                        @a = @{$nodeInfo{$i}{'information'}} ;
1325                        my $t ; 
1326                        my $first = 1 ;
1327                        foreach my $e (@a) {
1328                                if ($first) { $first = 0 ; } else { $t .= " * " ; }
1329                                $t .= $e  ;
1330                        }
1331                        $info{$i} = $t ;
1332                }
1333        }
1334
1335        my $lastDist = 0 ;
1336        my $line = 0 ;
1337        for (my $i=0; $i <= $#nodes; $i++) {
1338                if (defined $toPrint{$i}) {
1339                        $line++ ;
1340                        my $stepDist = $nodeInfo{$i}{"distance"} - $lastDist ;
1341                        $stepDist = int ($stepDist * 100) / 100 ;
1342
1343                        if (defined $stepInformation{$line}) {
1344                                if ($info{$i} eq "") {
1345                                        $info{$i} = $stepInformation{$line} ;
1346                                }
1347                                else {
1348                                        $info{$i} .= " * " . $stepInformation{$line} ;
1349                                } 
1350                        }
1351
1352
1353                        if ($elevationDataPresent) {
1354                                print $ltxFile "$line & " . $nodeInfo{$i}{"distance"} . " ($stepDist)" . " & " . $nodeInfo{$i}{"ele"} . " & " . $nodeInfo{$i}{"name"} . " & " . $nodeInfo{$i}{"direction"} . " & " . $info{$i} . "\\\\\n" ;
1355                        }
1356                        else {
1357                                print $ltxFile "$line & " . $nodeInfo{$i}{"distance"} . " ($stepDist)" . " & " . $nodeInfo{$i}{"name"} . " & " . $nodeInfo{$i}{"direction"} . " & " . $info{$i} . "\\\\\n" ;
1358                        }
1359
1360                        print $ltxFile "\\hline\n" ;
1361                        $lastDist = $nodeInfo{$i}{"distance"} ;
1362
1363                        if ($stepSizeOpt > 0) {
1364                                print $stepFile $lon{ $nodes[$i] } . " " ;
1365                                print $stepFile $lat{ $nodes[$i] } . " " ;
1366                                print $stepFile "$stepSizeOpt " ;
1367                                print $stepFile "\"$stepColorOpt\" " ;
1368                                print $stepFile "\"$line\" " ;
1369                                print $stepFile "$stepFontSizeOpt" ;
1370                                print $stepFile "\n" ;
1371                        }
1372                }               
1373        }
1374
1375        print $ltxFile "\\end{longtable}\n" ;
1376
1377
1378        my $countEle = 0 ; my $eleMin = 999 ; my $eleMax = -999 ;
1379        for (my $i=0; $i<=$#nodes; $i++) {
1380                if ($nodeInfo{$i}{'ele'} ne "") { 
1381                        $countEle++ ; 
1382                        if ($nodeInfo{$i}{'ele'} > $eleMax) { $eleMax = $nodeInfo{$i}{'ele'} ; }
1383                        if ($nodeInfo{$i}{'ele'} < $eleMin) { $eleMin = $nodeInfo{$i}{'ele'} ; }
1384                }
1385        }
1386
1387        foreach my $d (keys %contourData) {
1388                $countEle++ ; 
1389                if ($contourData{$d} > $eleMax) { $eleMax = $contourData{$d} ; }
1390                if ($contourData{$d} < $eleMin) { $eleMin = $contourData{$d} ; }
1391
1392        }
1393
1394        if ($countEle >= 2) {
1395
1396                my $picWidth = 110 ;
1397                my $xOffset = 10 ;
1398                my $yOffset = 10 ;
1399               
1400                print $texFile "\\section*{" .  $label{$languageOpt}{"eleprofile"} . "}\n" ;
1401                print $texFile "\\setlength{\\unitlength}{1mm}\n" ;
1402                my $height = int ( ($eleMax - $eleMin) / 10 ) ;
1403                my $lh = $height + 10 ;
1404                print $texFile "\\begin{picture} ($picWidth,$lh)\n" ;
1405
1406                my $width = 0 ;
1407                foreach my $d (1, 2, 3, 5, 7, 10, 15, 20, 25, 30, 35, 40, 45, 50, 75, 100, 150, 200, 300, 500, 750, 1000) {
1408                        if ($d > $segmentLength) {
1409                                $width = $d ;
1410                                last ;
1411                        } 
1412                }
1413                my $tx = $picWidth-$xOffset ;
1414
1415                print $texFile "\\put($xOffset,$yOffset){\\line($picWidth,0){$tx}}\n" ;
1416                print $texFile "\\put($xOffset,$lh){\\line($picWidth,0){$tx}}\n" ;
1417
1418                print $texFile "\\put($xOffset,$yOffset){\\line(0,$height){$height}}\n" ;
1419                print $texFile "\\put($picWidth,$yOffset){\\line(0,$height){$height}}\n" ;
1420
1421                my $h1 = int ($eleMin) ;
1422                my $h2 = int ($eleMax) ;
1423                my $pos2 = $height + $yOffset ;
1424                my $ty = $yOffset + 2 ;
1425                print $texFile "\\put(0,$ty){\\tiny $h1 m}\n" ;
1426                print $texFile "\\put(0,$pos2){\\tiny $h2 m}\n" ;
1427                $tx = $picWidth-$xOffset ;
1428                print $texFile "\\put($tx,2){\\tiny $width km}\n" ;
1429
1430
1431                for (my $i=0; $i<=$#nodes; $i++) {
1432                        if ($nodeInfo{$i}{"ele"} ne "") {
1433                                my $x = int ($nodeInfo{$i}{"distance"} / $width * ($picWidth - $xOffset)) + $xOffset ;
1434                                my $y = ($nodeInfo{$i}{"ele"} - $eleMin) / 10 + $yOffset ;
1435                                print $texFile "\\put($x,$y){\\circle*{1}}\n" ;
1436                        }
1437                }
1438
1439                foreach my $d (keys %contourData) {
1440                        my $x = int ($d / $width * ($picWidth - $xOffset)) + $xOffset ;
1441                        my $y = ($contourData{$d} - $eleMin) / 10 + $yOffset ;
1442                        print $texFile "\\put($x,$y){\\circle*{1}}\n" ;
1443                }
1444
1445                print $texFile "\\end{picture}\n" ;
1446        }
1447
1448
1449        print $texFile "\\end{document}\n" ;
1450        close ($texFile) ;
1451        close ($ltxFile) ;
1452
1453        close ($stepFile) ;
1454
1455        my $dviFileName = $texFileName ;
1456        $dviFileName =~ s/.tex/.dvi/ ;
1457        my $psFileName = $texFileName ;
1458        $psFileName =~ s/.tex/.ps/ ;
1459        my $pdfFileName = "directions.pdf" ;
1460
1461        push @tempFiles, $pdfFileName ;
1462
1463        print "call latex, dvips and ps2pdf and log to $logFileName\n" ;
1464        `latex $texFileName >> $logFileName 2>&1` ;
1465        `latex $texFileName >> $logFileName 2>&1` ;
1466        `dvips -D600 $dviFileName -o >> $logFileName 2>&1` ;
1467        `ps2pdf $psFileName $pdfFileName >> $logFileName 2>&1` ;
1468        `rm *.dvi` ;
1469        # `rm *.tex` ;
1470        `rm *.ps` ;
1471        `rm *.aux` ;
1472        `rm *.log` ;
1473        my $target = $workDir . "directions.pdf" ;
1474        # `mv directions.pdf $target` ;
1475        print "done\n" ;
1476}
1477
1478sub createTitlePage {
1479
1480        my %heading = () ;
1481        $heading{"EN"} = "Disclaimer" ;
1482        $heading{"DE"} = "Haftungsauschluss" ;
1483        my %heading2 = () ;
1484        $heading2{"EN"} = "Tour description" ;
1485        $heading2{"DE"} = "Tourenbeschreibung" ;
1486        my %heading3 = () ;
1487        $heading3{"EN"} = "Basic route data" ;
1488        $heading3{"DE"} = "Basisroutendaten" ;
1489        my %disclaimer = () ;
1490        $disclaimer{"EN"} = << "END1" ;
1491The user of this book is always responsible for all his steps and actions.
1492The authors of this documentation are not responsible for the correctness and completeness of the data.
1493Data is derived from openstreetmap and is licensed by CC-BY-SA.
1494END1
1495        $disclaimer{"DE"} = << "END2" ;
1496Der Nutzer dieses Werkes ist stets selbst für seine Schritte und Aktionen ver\\-antwortlich.
1497Die Ersteller dieser Dokumentation übernehmen keine Garantie für Richtigkeit und Vollständigkeit selbiger.
1498Die Daten stammen von openstreetmap und stehen unter der CC-BY-SA Lizenz.
1499END2
1500
1501       
1502        print "create title page...\n" ;
1503        my $texFileName ; 
1504        $texFileName = "title.tex" ;
1505
1506        push @tempFiles, $texFileName ;
1507
1508        open (my $texFile, ">", $texFileName) or die ("can't open tex output file") ;
1509
1510        if ($pageSizeOpt eq "A5") {
1511                print $texFile "\\documentclass[a5paper,12pt]{book}\n" ;
1512        }
1513        else {
1514                print $texFile "\\documentclass[a4paper,12pt]{book}\n" ;
1515        }
1516
1517        print $texFile "\\usepackage[utf8]{inputenc}\n" ;
1518        print $texFile "\\begin{document}\n" ;
1519
1520
1521        #
1522        # title
1523        #
1524
1525        print $texFile "\\thispagestyle{empty}\n" ;
1526        print $texFile "\\vspace*{8cm}\n" ;
1527        print $texFile "\\Huge\n" ;
1528        $title = sanitizeLatexString ($title) ;
1529        print $texFile "$title \\par\n" ;
1530        # print $texFile "\\newline\n" ;
1531        print $texFile "\\vspace*{2cm}\n" ;
1532        print $texFile "\\normalsize\n" ;
1533        my %created = () ;
1534        $created{"EN"} = "created with hikingbook.pl" ;
1535        $created{"DE"} = "erstellt mit hikingbook.pl" ;
1536        print $texFile "$created{$languageOpt}\n" ;
1537
1538
1539        #
1540        # description
1541        #
1542
1543        if ($descName ne "") {
1544                print $texFile "\\newpage\n" ;
1545                print "\nreading description file...\n" ;
1546                open (my $file, "<", $descName) or die ("ERROR: could not open description file $descName\n") ;
1547                        print $texFile "\\section*{$heading2{$languageOpt}}\n" ;
1548                        my $line = "" ; my $c = 0 ;
1549                        while ($line = <$file>) {
1550                                print $texFile $line ;
1551                                $c++ ;
1552                        }
1553                close ($file) ; 
1554                print "done. $c lines read.\n" ;
1555        }
1556
1557
1558
1559        #
1560        # basic relation data
1561        #
1562
1563        print $texFile "\\newpage\n" ;
1564        print $texFile "\\thispagestyle{empty}\n" ;
1565
1566        if ($atlasOpt eq "") {
1567                print $texFile "\\section*{$heading3{$languageOpt}}\n" ;
1568                my %tags = () ;
1569                foreach my $t (@relationTags) {
1570                        my $temp = $t->[1] ;
1571                        $temp = sanitizeLatexString ($temp) ;
1572                        $temp = convertHTML ($temp) ; 
1573                        $tags{ $t->[0] } = $temp ; 
1574                }
1575                print $texFile "\\begin{tabular}{|p{4cm}|p{10cm}|}\n" ;
1576                print $texFile "\\hline\n" ;
1577                print $texFile "Key & Value \\\\ \n" ;
1578                print $texFile "\\hline\n" ;
1579                foreach my $t (sort keys %tags) {
1580                        print $texFile "$t & $tags{$t} \\\\ \n" ;
1581                        print $texFile "\\hline\n" ;
1582                }
1583                print $texFile "\\end{tabular}\n" ;
1584        }
1585
1586
1587        #
1588        # disclaimer
1589        #
1590
1591        print $texFile "\\section*{$heading{$languageOpt}}\n" ;
1592        print $texFile "$disclaimer{$languageOpt}\n" ;
1593       
1594
1595        print $texFile "\\end{document}\n" ;
1596        close ($texFile) ;
1597
1598        my $dviFileName = $texFileName ;
1599        $dviFileName =~ s/.tex/.dvi/ ;
1600        my $psFileName = $texFileName ;
1601        $psFileName =~ s/.tex/.ps/ ;
1602        my $pdfFileName = "title.pdf" ;
1603
1604        push @tempFiles, $pdfFileName ;
1605
1606        print "call latex, dvips and ps2pdf and log to $logFileName\n" ;
1607        `latex $texFileName >> $logFileName 2>&1` ;
1608        `latex $texFileName >> $logFileName 2>&1` ;
1609        `dvips -D600 $dviFileName -o >> $logFileName 2>&1` ;
1610        `ps2pdf $psFileName $pdfFileName >> $logFileName 2>&1` ;
1611        `rm *.dvi` ;
1612        # `rm *.tex` ;
1613        `rm *.ps` ;
1614        `rm *.aux` ;
1615        `rm *.log` ;
1616        my $target = $workDir . "title.pdf" ;
1617        print "done.\n" ;
1618}
1619
1620
1621sub getProgramOptions {
1622        my $helpOpt = 0 ;
1623        my $optResult = GetOptions (    "in=s"          => \$inFileName,
1624                                        "out=s"         => \$outFileName,               # output file
1625                                        "detailstyle=s" => \$detailStyleFileName,
1626                                        "overviewstyle=s"       => \$overviewStyleFileName,
1627                                        "title=s"       => \$title,
1628                                        "language=s"    => \$languageOpt,
1629                                        "pagesize=s"    => \$pageSizeOpt,
1630                                        "relation=i"    => \$relationId,
1631                                        "atlas=s"       => \$atlasOpt,
1632                                        "name=s"        => \$relationName,
1633                                        "desc=s"        => \$descName,
1634                                        "steps=s"       => \$stepDescName,
1635                                        "ref=s" => \$relationRef,
1636                                        "overlap=i"     => \$overlapOpt,
1637                                        "dirnumber=i"   => \$dirNumberOpt,
1638                                        "lesssteps=i"   => \$lessStepsOpt,
1639                                        "poi=i"         => \$poiOpt,
1640                                        "street=i"              => \$streetOpt,
1641                                        "scale=i"       => \$scale,
1642                                        "stepsize=i"            => \$stepSizeOpt,
1643                                        "stepcolor=s"           => \$stepColorOpt,
1644                                        "stepfontsize=i"        => \$stepFontSizeOpt,
1645                                        "pnsizeoverview=i"      => \$pnSizeOverview,
1646                                        "pnsizedetail=i"        => \$pnSizeDetail,
1647                                        "landscape"     => \$landscapeOpt,
1648                                        "reverse"       => \$reverseOpt,
1649                                        "autorotate"    => \$autorotateOpt,
1650                                        "nodelete"      => \$noDeleteOpt,
1651                                        "roundtrip"     => \$roundtripOpt,
1652                                        "help"          => \$helpOpt,
1653                                        "verbose"       => \$verboseOpt ) ;
1654
1655        if ( (uc $languageOpt) eq "DE") { 
1656                $languageOpt = "DE" ;
1657        }
1658        else {
1659                $languageOpt = "EN" ;
1660        }
1661        if ( (uc $pageSizeOpt) eq "A5") { 
1662                $pageSizeOpt = "A5" ;
1663        }
1664        else {
1665                $pageSizeOpt = "A4" ;
1666        }
1667
1668        if ($landscapeOpt eq "1") {
1669                foreach my $f (keys %pageHeight) {
1670                        my $temp = $pageHeight{$f} ;
1671                        $pageHeight{$f} = $pageWidth{$f} ;
1672                        $pageWidth{$f} = $temp ;
1673                }
1674        }
1675
1676        if ($helpOpt eq "1") {
1677                usage() ;
1678                die() ;
1679        }
1680}
1681
1682sub usage {
1683        print "$programName version $version\n" ;
1684        print "-in=<infile.osm>\n" ;
1685        print "-out=<outfile.pdf>\n" ;
1686        print "-relation=<relation id>\n" ;
1687        print "-name=<relation name>\n" ;
1688        print "-ref=<relation ref>\n" ;
1689        print "-atlas=FLOAT,FLOAT,FLOAT,FLOAT (create street atlas for bounding box)\n" ;
1690        print "-detailstyle=<mapgen rules file for detail maps>\n" ;
1691        print "-overviewstyle=<mapgen rules file for overview maps>\n" ;
1692        print "-scale=<integer> (scale for detail maps); default = 10000\n\n" ;
1693
1694        print "-language=EN|DE\n" ;
1695        print "-title=\"title text\" (for title page)\n" ;
1696        print "-desc=<tex file> (for long text after title page; tex format, max heading subsection\n" ;
1697        print "-steps=<step description file> (for descriptions of single steps or nodes; format: stepNr<space>TEXT)\n" ;
1698        print "-poi=<integer> (add poi directory to description, specify column number like 1,2,3)\n" ;
1699        print "-street=<integer> (add street directory to description, specify column number like 1,2,3)\n" ;
1700        print "-dirnumber=4|8 (4 or 8 different directions like N, S, E, W...); default=8\n" ;
1701        print "-lesssteps=INTEGER (reduce number of steps in description, step only if direction change > integer degrees)\n" ;
1702        print "-stepsize=INTEGER (size of step disc in map; 0 will suppress discs and labels)\n" ;
1703        print "-stepcolor=TEXT (color of step disc in map)\n" ;
1704        print "-stepfontsize=INTEGER (size of label for step disc in map)\n" ;
1705        print "\n" ;
1706
1707        print "-pagesize=A4|A5\n" ;
1708        print "-overlap=<percent> (10 for 10\% overlap on each side; default=5)\n" ;
1709        print "-pnsizeoverview=INTEGER (size of page numbers in overview map)\n" ;
1710        print "-pnsizedetail=INTEGER (size of page numbers in detail maps)\n" ;
1711        print "-landscape\n" ;
1712        print "-autorotate (rotate paper format automatically)\n" ;
1713        print "\n" ;
1714
1715        print "-reverse (reverse direction of relation/route)\n" ;
1716        print "-roundtrip (force route to begin/end with first way in relation)\n" ;
1717        print "\n" ;
1718
1719        print "-verbose\n" ;
1720        print "-nodelete (temp files will not be deleted)\n" ;
1721        print "-help\n" ;
1722}
1723
1724
1725sub addPois {
1726        print "\nadding POIs to description...\n" ;
1727        foreach my $p (@poiList) {
1728                my $minDist = 999 ;
1729                my $nodeNumber = -1 ;
1730                my $dir = "" ;
1731                for (my $i = 0; $i <= $#nodes; $i++) {
1732                        my $dist = distance ( $lon {$p->[2]}, $lat {$p->[2]}, $lon{ $nodes[$i] }, $lat{ $nodes[$i] }) ;
1733                        if ($dist < $minDist) {
1734                                $minDist = $dist ;
1735                                $nodeNumber = $i ;
1736                                $dir = direction ( $nodes[$i], $p->[2] ) ;
1737                        }
1738                }
1739                if ($minDist < $p->[3]) {
1740                        my $info = $p->[0] ; my $name = $p->[1] ;
1741                        $minDist = int ($minDist * 100) / 100 ;
1742                        push @{$nodeInfo{$nodeNumber}{"information"}}, "$info $name ($dir $minDist)" ;
1743                }
1744        }
1745}
1746
1747sub getPoiFiledata {
1748        print "\nreading poi file...\n" ;
1749        my $result = open (my $file, "<", $poiFileName) ;
1750        if ($result) {
1751                my $line = "" ;
1752                my $count = 0 ;
1753                while ($line = <$file>) {
1754                        my ($k, $v, $d, $en, $de) = ( $line =~ /(.+),(.+),(.+),(.+),(.+)/ ) ;
1755                        if ( (defined $k) and (defined $v) and (defined $d) and (defined $en) and (defined $de) ) {
1756                                $count++ ;
1757                                push @pois, [$k, $v, $d, $en, $de] ;
1758                                if ($verboseOpt eq "1") { print "POI $k=$v read from file.\n" ; }
1759                        }
1760                }
1761                close ($file) ;
1762                print "$count pois read.\n" ;
1763        }
1764        else {
1765                print "WARNING: poi file $poiFileName could not be opened!\n" ;
1766        }
1767}
1768
1769sub getStepInformation {
1770        if ($stepDescName ne "") {
1771                print "\nreading step information file...\n" ;
1772                open (my $file, "<", $stepDescName) or die ("ERROR: step information file $stepDescName could not be opened!\n") ;
1773                my $line = "" ; my $c = 0 ;
1774                while ($line = <$file>) {
1775                        my ($nr, $text) = ($line =~ /([\d\-]+)\s(.+)/ ) ;
1776                        if ( (defined $nr) and (defined $text) ) {
1777                                $c++ ;
1778                                $stepInformation{$nr} = $text ;
1779                                if ($verboseOpt eq "1") {
1780                                        print "$nr $text\n" ;
1781                                }
1782                        }
1783                        else {
1784                                print "problem reading line from step information file:\n$line\n" ;
1785                        }
1786                }
1787                close ($file) ;
1788                print "done. $c lines read.\n" ;
1789        }
1790}
1791
1792
1793
1794
1795sub createDirectory {
1796
1797        if ( ($poiOpt > 0) or ($streetOpt > 0) ) {
1798
1799                if ($poiOpt < 1) { $poiOpt = 1 ; } 
1800                if ($poiOpt > 3) { $poiOpt = 3 ; } 
1801                if ($streetOpt < 1) { $streetOpt = 1 ; } 
1802                if ($streetOpt > 3) { $streetOpt = 3 ; } 
1803                $poiOpt = int $poiOpt ;
1804                $streetOpt = int $streetOpt ;
1805
1806                print "create directory...\n" ;
1807                my $texFileName ; 
1808                $texFileName = "directory.tex" ;
1809
1810                push @tempFiles, $texFileName ;
1811
1812                open (my $texFile, ">", $texFileName) or die ("can't open tex output file") ;
1813
1814                if ($pageSizeOpt eq "A5") {
1815                        print $texFile "\\documentclass[a5paper,12pt]{book}\n" ;
1816                }
1817                else {
1818                        print $texFile "\\documentclass[a4paper,12pt]{book}\n" ;
1819                }
1820
1821                print $texFile "\\usepackage[utf8]{inputenc}\n" ;
1822                print $texFile "\\usepackage{multicol}\n" ;
1823                print $texFile "\\begin{document}\n" ;
1824
1825                if ($poiOpt > 0) {
1826                        print $texFile "\\thispagestyle{empty}\n" ;
1827
1828                        my %heading3 = () ;
1829                        $heading3{"EN"} = "Points of interest" ;
1830                        $heading3{"DE"} = "Interessante Punkte" ;
1831
1832                        if ($poiOpt > 1) {
1833                                print $texFile "\\begin{multicols}{$poiOpt}[\\section*{$heading3{$languageOpt}}]\n" ;
1834                        }
1835                        else {
1836                                print $texFile "\\section*{$heading3{$languageOpt}}\n" ;
1837                        }
1838                        print $texFile "\\tiny\n" ;
1839
1840                        foreach my $poi (sort keys %pois) {
1841                                my $sqText = "" ; my $first = 1 ;
1842                                foreach my $sq ( @{$pois{$poi}} ) {
1843                                        if ($first) {
1844                                                $first = 0 ;
1845                                                $sqText .= $sq ;
1846                                        }
1847                                        else {
1848                                                $sqText .= " " ;
1849                                                $sqText .= $sq ;
1850                                        }
1851                                }
1852                                $poi = sanitizeLatexString ($poi) ;
1853                                print $texFile $poi ;
1854                                print $texFile " \\dotfill " ;
1855                                print $texFile $sqText, "\\\\\n" ;
1856                        }
1857
1858                        if ($poiOpt > 1) {
1859                                print $texFile "\\end{multicols}\n" ;
1860                        }
1861                        print $texFile "\\normalsize\n" ;
1862                } # poiOpt > 0
1863       
1864                if ($streetOpt > 0) {
1865                        print $texFile "\\thispagestyle{empty}\n" ;
1866
1867                        my %heading4 = () ;
1868                        $heading4{"EN"} = "Street Directory" ;
1869                        $heading4{"DE"} = "Straßenverzeichnis" ; 
1870
1871                        if ($streetOpt > 1) {
1872                                print $texFile "\\begin{multicols}{$streetOpt}[\\section*{$heading4{$languageOpt}}]\n" ;
1873                        }
1874                        else {
1875                                print $texFile "\\section*{$heading4{$languageOpt}}\n" ;
1876                        }
1877                        print $texFile "\\tiny\n" ;
1878
1879                        foreach my $street (sort keys %streets) {
1880                                my $sqText = "" ; my $first = 1 ;
1881                                foreach my $sq ( @{$streets{$street}} ) {
1882                                        if ($first) {
1883                                                $first = 0 ;
1884                                                $sqText .= $sq ;
1885                                        }
1886                                        else {
1887                                                $sqText .= " " ;
1888                                                $sqText .= $sq ;
1889                                        }
1890                                }
1891                                $street = sanitizeLatexString ($street) ;
1892                                print $texFile $street ;
1893                                print $texFile " \\dotfill " ;
1894                                print $texFile $sqText, "\\\\\n" ;
1895                        }
1896
1897                        if ($streetOpt > 1) {
1898                                print $texFile "\\end{multicols}\n" ;
1899                        }
1900                        print $texFile "\\normalsize\n" ;
1901                } # streetOpt > 0
1902       
1903
1904                print $texFile "\\end{document}\n" ;
1905                close ($texFile) ;
1906
1907                my $dviFileName = $texFileName ;
1908                $dviFileName =~ s/.tex/.dvi/ ;
1909                my $psFileName = $texFileName ;
1910                $psFileName =~ s/.tex/.ps/ ;
1911                my $pdfFileName = "directory.pdf" ;
1912
1913                push @tempFiles, $pdfFileName ;
1914
1915                print "call latex, dvips and ps2pdf and log to $logFileName\n" ;
1916                `latex $texFileName >> $logFileName 2>&1` ;
1917                `latex $texFileName >> $logFileName 2>&1` ;
1918                `dvips -D600 $dviFileName -o >> $logFileName 2>&1` ;
1919                `ps2pdf $psFileName $pdfFileName >> $logFileName 2>&1` ;
1920                `rm *.dvi` ;
1921                `rm *.ps` ;
1922                `rm *.aux` ;
1923                `rm *.log` ;
1924                print "done.\n" ;
1925
1926        }
1927}
1928
1929
1930sub convertHTML {
1931        my $line = shift ;
1932
1933        ($line) = ($line =~ /^(.*)$/ ) ;
1934
1935        $line =~ s/\&apos;/\'/g ;
1936        $line =~ s/\&quot;/\'/g ;
1937
1938        return $line ;
1939}
1940
1941sub dirChange {
1942        my ($a, $b) = @_ ;
1943
1944        my $c1 = abs ($a - $b) ;
1945        my $c2 = 360 - max ($a, $b) + min ($a, $b) ;
1946
1947        my $c3 = min ($c1, $c2) ;
1948        return $c3 ;
1949}
1950
1951
1952sub min {
1953        my ($a, $b) = @_ ;
1954        if ($a < $b) {
1955                return $a ;
1956        }
1957        else {
1958                return $b ;
1959        }
1960}
1961
1962sub max {
1963        my ($a, $b) = @_ ;
1964        if ($a > $b) {
1965                return $a ;
1966        }
1967        else {
1968                return $b ;
1969        }
1970}
1971
1972sub initializeLatex {
1973
1974        $replaceLatex{'_'} = '\\_' ;   
1975        $replaceLatex{'&'} = '\\&' ;   
1976        $replaceLatex{'$'} = '\\$' ;   
1977        $replaceLatex{'%'} = '\\%' ;   
1978        $replaceLatex{'{'} = '\\{' ;   
1979        $replaceLatex{'}'} = '\\}' ;   
1980        $replaceLatex{'#'} = '\\#' ;   
1981
1982        foreach my $c (0..9) {
1983                $validLatex{$c} = 1 ;
1984        }
1985        foreach my $c ("a".."z") {
1986                $validLatex{$c} = 1 ;
1987        }
1988        foreach my $c ("A".."Z") {
1989                $validLatex{$c} = 1 ;
1990        }
1991        foreach my $c ( qw (! + * - : . ; § / = ?) ) {
1992                $validLatex{$c} = 1 ;
1993        }
1994        foreach my $c ( ' ', '"', "\'", '(', ')', '[', ']', ',' ) {
1995                $validLatex{$c} = 1 ;
1996        }
1997}
1998
1999sub sanitizeLatexString {
2000        my $text = shift ;
2001
2002        my $out = "" ;
2003        my @chars ;
2004        @chars = split //, $text ;
2005
2006        for (my $i=0; $i<=$#chars; $i++) {
2007                my $c = $chars[$i] ;
2008                # print "$c ", ord ($c), "\n" ;
2009                if (defined $validLatex{$c}) {
2010                        $out .= $c ;
2011                }
2012                elsif (defined $replaceLatex{$c}) {
2013                        $out .= $replaceLatex{$c} ;
2014                }
2015                else {
2016                        if ( ($i < $#chars) and ($c eq chr (195)) ) {
2017                                my $found = 0 ;
2018                                foreach my $c2 (164, 182, 188, 132, 150, 156, 159) {
2019                                        if ($chars[$i+1] eq chr($c2)) {
2020                                                $found = 1 ;
2021                                        }
2022                                }
2023                                if ($found) {
2024                                        $out .= $c . $chars[$i+1] ;
2025                                        $i++ ;
2026                                }
2027                        }
2028                }
2029        } 
2030        return $out ;
2031}
2032
2033
2034sub compileElevationData {
2035        print "evaluating contour data...\n" ;
2036
2037        foreach my $wayId (keys %contourWays) {
2038
2039                my ($x1, $x2, $y1, $y2) = getArea ( @{$wayNodesHash{$wayId}} );
2040
2041                $qt->add ($wayId, $x1, $y1, $x2, $y2) ;
2042        }
2043
2044
2045        my $count = 0 ;
2046        for (my $a = 0; $a < $#nodes; $a++) { #way 1
2047                # print "a = $a\n" ;
2048
2049                my $ref = $qt->getEnclosedObjects (     min( $lon{$nodes[$a]}, $lon{$nodes[$a+1]}),
2050                                                        min( $lat{$nodes[$a]}, $lat{$nodes[$a+1]}),
2051                                                        max( $lon{$nodes[$a]}, $lon{$nodes[$a+1]}),
2052                                                        max( $lat{$nodes[$a]}, $lat{$nodes[$a+1]}) ) ;
2053                my @temp = @$ref ;
2054
2055                foreach my $cw ( @temp ) { #way 2
2056                # foreach my $cw (keys %contourWays) { #way 2
2057                        for ($b=0; $b<$#{$wayNodesHash{$cw}}; $b++) {
2058                                # print "cw= $cw\n" ;
2059                                # print "b = $b\n" ;
2060                                my ($x, $y) = crossing ($lon{ $nodes[$a] }, 
2061                                                $lat{ $nodes[$a] }, 
2062                                                $lon{ $nodes[$a+1] }, 
2063                                                $lat{ $nodes[$a+1] }, 
2064                                                $lon{$wayNodesHash{$cw}[$b]}, 
2065                                                $lat{$wayNodesHash{$cw}[$b]}, 
2066                                                $lon{$wayNodesHash{$cw}[$b+1]}, 
2067                                                $lat{$wayNodesHash{$cw}[$b+1]}) ;
2068                                if (($x != 0) and ($y != 0)) {
2069                                        $count ++ ;
2070                                        my $dist = $nodeInfo{$a}{"distance"} + distance ($lon{$nodes[$a]}, $lat{$nodes[$a]}, $x, $y) ;
2071                                        $contourData{$dist} = $contourWays { $cw } ;
2072                                        if ($verboseOpt eq "1") {
2073                                                print "contour intersection found: ($x, $y), $dist, $contourWays{$cw}\n" ;
2074                                        }
2075                                }
2076                        }
2077                }
2078        }
2079        print "done. $count intersections found.\n" ;
2080}
2081
2082
2083sub getArea {
2084        my @nodes = @_ ;
2085
2086        my $minLon = 999 ;
2087        my $maxLon = -999 ;
2088        my $minLat = 999 ;
2089        my $maxLat = -999 ;
2090
2091
2092        foreach my $node (@nodes) {
2093                if ($lon{$node} > $maxLon) { $maxLon = $lon{$node} ; }
2094                if ($lon{$node} < $minLon) { $minLon = $lon{$node} ; }
2095                if ($lat{$node} > $maxLat) { $maxLat = $lat{$node} ; }
2096                if ($lat{$node} < $minLat) { $minLat = $lat{$node} ; }
2097        }       
2098        return ($minLon, $maxLon, $minLat, $maxLat) ;
2099}
2100
2101
2102sub getMinMax {
2103        my $fileName = shift ;
2104        # store min / max of temp file
2105        openOsmFile ($fileName) ;
2106        print "reading temp file nodes...\n" ;
2107
2108        my $file2LonMax = -999 ;
2109        my $file2LonMin = 999 ;
2110        my $file2LatMax = -999 ;
2111        my $file2LatMin = 999 ;
2112        my $propRef ; my $tagsRef ;
2113        ($propRef, $tagsRef) = getNode3() ;
2114        while (defined $propRef) {
2115                if ( $$propRef{"lon"} > $file2LonMax ) { $file2LonMax = $$propRef{"lon"} ; }
2116
2117                if ( $$propRef{"lon"} < $file2LonMin ) { $file2LonMin = $$propRef{"lon"} ; }
2118                if ( $$propRef{"lat"} > $file2LatMax ) { $file2LatMax = $$propRef{"lat"} ; }
2119                if ( $$propRef{"lat"} < $file2LatMin ) { $file2LatMin = $$propRef{"lat"} ; }
2120
2121                ($propRef, $tagsRef) = getNode3() ;
2122        }
2123        closeOsmFile() ;
2124        print "done.\n" ;
2125        return ($file2LonMin, $file2LatMin, $file2LonMax, $file2LatMax) ;
2126}
2127
2128
2129sub loadExternalFiles {
2130        my $outName = shift ;
2131        my $poiName = $outName ;
2132        if ($poiOpt > 0) {
2133                $poiName =~ s/\.svg/\_pois\.txt/ ;
2134                open (my $file, "<", $poiName) or die ("ERRROR: could not open poi file name $poiName\n") ;
2135
2136                my $line = "" ;
2137                while ($line = <$file>) {
2138                        # print "POI line read : $line" ;
2139                        my ($poi, $fields) = ( $line =~ /(.+)\t(.*)/ ) ;
2140                        if ( (defined $poi) and (defined $fields) ) {
2141                                my @f = split / /, $fields ;
2142                                foreach my $sq (@f) {
2143                                        $poi = convertHTML ($poi) ;
2144
2145                                        # translation German
2146                                        if ($languageOpt ne "EN") {
2147                                                foreach my $k (keys %{ $translations{$languageOpt} } ) {
2148                                                        my $v = $translations{$languageOpt}{$k} ;
2149                                                        $poi =~ s/\($k\)/\($v\)/gi ;
2150                                                }
2151                                        }
2152
2153                                        $poi =~ s/\_/ /g ;
2154                                        push @{$pois{$poi}}, $mapNumber . "-" . $sq ;
2155                                }
2156                        }
2157                }
2158                close ($file) ;
2159                push @tempFiles, $poiName ;
2160        }
2161
2162        my $streetName = $outName ;
2163        if ($streetOpt > 0) {
2164                $streetName =~ s/\.svg/\_streets\.txt/ ;
2165                open (my $file, "<", $streetName) or die ("ERRROR: could not open street file name $streetName\n") ;
2166                my $line = "" ;
2167                while ($line = <$file>) {
2168                        # print "STREET line read : $line" ;
2169                        my ($street, $fields) = ( $line =~ /(.+)\t(.*)/ ) ;
2170                        if ( (defined $street) and (defined $fields) ) {
2171                                my @f = split / /, $fields ;
2172                                foreach my $sq (@f) {
2173                                        $street = convertHTML ($street) ;
2174                                        push @{$streets{$street}}, $mapNumber . "-" . $sq ;
2175                                }
2176                        }
2177                }
2178                close ($file) ;
2179                push @tempFiles, $streetName ;
2180        }
2181
2182}
Note: See TracBrowser for help on using the repository browser.