source: subversion/applications/utils/gary68/mwFile.pm @ 34714

Last change on this file since 34714 was 29098, checked in by gary68, 7 years ago

shield error in mapweaver corrected

File size: 12.6 KB
Line 
1#
2# PERL mapweaver module by gary68
3#
4#
5#
6#
7# Copyright (C) 2011, Gerhard Schwanz
8#
9# 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
10# Free Software Foundation; either version 3 of the License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>
16#
17
18
19package mwFile ; 
20
21use strict ;
22use warnings ;
23
24use mwConfig ;
25use mwMap ;
26use mwLabel ;
27use LWP::Simple ;
28
29use OSM::osm ;
30
31use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
32
33require Exporter ;
34
35@ISA = qw ( Exporter AutoLoader ) ;
36
37@EXPORT = qw (  readFile
38                getNodePointers
39                getWayPointers
40                getRelationPointers
41                 ) ;
42
43my %lon ;
44my %lat ;
45my %memNodeTags ;
46
47my %memWayNodes ;
48my %memWayTags ;
49
50my %memRelationMembers ;
51my %memRelationTags ;
52
53my $overpassSource0 = "interpreter?data=node%5B%22name%22%3D%22NAME%22%5D%3Bout%20body%3B%0A" ;
54my $overpassSource1 = "interpreter?data=node%5B%22name%22%3D%22NEAR%22%5D%3Bnode%28around%3ADIST%29%5B%22name%22%3D%22NAME%22%5D%3Bout%3B" ;
55my $overpassSource3 = "interpreter?data=%28node%28BOTTOM%2CLEFT%2CTOP%2CRIGHT%29%3B%3C%3B%3E%3B%29%3Bout%20meta%3B" ;
56
57
58sub readFile {
59
60        my ($nodeId, $nodeLon, $nodeLat, $nodeUser, $aRef1, @nodeTags) ;
61        my ($wayId, $wayUser, $aRef2, @wayTags, @wayNodes) ;
62        my ($relationId, $relationUser, @relationTags, @relationMembers) ;
63        my %invalidWays ;
64
65
66        my $osmName ;
67        if (defined cv('in')) { $osmName = cv('in') ; }
68
69
70        my $clipbbox = "" ;
71        if (defined cv('clipbbox')) { $clipbbox = cv('clipbbox') ; }
72
73        if ( cv('overpass') eq "1" ) {
74                if ( cv('place') eq "" ) { die ("ERROR: option place not specified.\n") ; }
75
76                my $overpassNear = cv('near') ;
77                my $overpassDistance = cv('overpassdistance') ;
78                my $overpassName = cv('place') ;
79                my $overpassUrl1 = cv('overpassserver') . $overpassSource1 ;
80
81                if ( cv('near') eq "" ) {
82                        $overpassUrl1 = cv('overpassserver') . $overpassSource0 ;
83                }
84
85                $overpassUrl1 =~ s/NEAR/$overpassNear/ ;
86                $overpassUrl1 =~ s/DIST/$overpassDistance/ ;
87                $overpassUrl1 =~ s/NAME/$overpassName/ ;
88
89                if ( cv('debug') eq "1" ) { print "Overpass Query1: $overpassUrl1 ...\n" ; }
90                print "Send Query 1 to overpass server..\n" ;
91                my $result1 = get ( $overpassUrl1 ) ;
92                if ( ! defined $result1 ) { die ("ERROR: bad overpass result!\n") ; }
93
94                if ( cv('debug') eq "1" ) { print "\n$result1\n\n" ; }
95
96                # get lon, lat
97
98                my ($placeLon) = ( $result1 =~ /lon=\"([\d\.\-]+)/ ) ;
99                my ($placeLat) = ( $result1 =~ /lat=\"([\d\.\-]+)/ ) ;
100
101                if ((! defined $placeLon) or (! defined $placeLat)) { die ("ERROR: lon/lat could not be obtained from 1st overpass result.\n") ; }
102
103                print "place $overpassName found:\n" ;
104                print "lon= $placeLon\n" ;
105                print "lat= $placeLat\n" ;
106
107
108                # calc bbox
109
110                my $overLeft = $placeLon - cv('lonrad')/(111.11 * cos ( $placeLat / 360 * 3.14 * 2 ) ) ; 
111                my $overRight = $placeLon + cv('lonrad')/(111.11 * cos ( $placeLat / 360 * 3.14 * 2 ) ) ; 
112                my $overTop = $placeLat + cv('latrad')/111.11 ; 
113                my $overBottom = $placeLat - cv('latrad')/111.11 ;
114
115                my $overpassUrl2 = cv('overpassserver') . $overpassSource3 ;
116                $overpassUrl2 =~ s/LEFT/$overLeft/ ;
117                $overpassUrl2 =~ s/RIGHT/$overRight/ ;
118                $overpassUrl2 =~ s/TOP/$overTop/ ;
119                $overpassUrl2 =~ s/BOTTOM/$overBottom/ ;
120
121
122                if ( cv('debug') eq "1" ) { print "Overpass Query2: $overpassUrl2\n" ; }
123                print "Send Query 2 to overpass server..\n" ;
124                my $result2 = get ( $overpassUrl2 ) ;
125                if ( ! defined $result2 ) { die ("ERROR: bad overpass result!\n") ; }
126
127                # save
128
129
130                my $opFileName = "overpass.osm" ;
131                open (my $overFile, ">", $opFileName) ;
132                binmode($overFile, ":utf8") ;
133                print $overFile $result2 ;
134                close ( $overFile ) ;
135
136                setConfigValue ('in', $opFileName) ;
137                $osmName = $opFileName ;
138                # setConfigValue ('place', '') ;
139
140                $clipbbox = "$overLeft,$overBottom,$overRight,$overTop" ;
141                if ( cv('debug') eq "1" ) { print "clipbox: $clipbbox\n" ; }
142        }
143
144        if ( grep /\.pbf/, $osmName ) {
145                my $newName = $osmName ;
146                $newName =~ s/\.pbf/\.osm/i ;
147
148                # osmosis
149                print "call osmosis to convert pbf file to osm file.\n" ;
150                `osmosis --read-pbf $osmName --write-xml $newName` ;
151
152                # change config
153                $osmName = $newName ;
154                setConfigValue ("in", $newName) ;
155        }
156
157
158        # -place given? look for place and call osmosis
159
160        my $left ;
161        my $right ;
162        my $top ;
163        my $bottom ;
164
165        my $placeFound = 0 ; my $placeLon ; my $placeLat ;
166        if ( ( cv('place') ne "") and (cv('overpass') ne "1" ) ) {
167                my ($placeId) = ( cv('place') =~ /([\d]+)/);
168                if (!defined $placeId) { $placeId = -999999999 ; }
169                print "looking for place...\n" ;
170
171                my $placeFileName = "" ;
172                if ( cv('placeFile') ne "" ) { 
173                        $placeFileName = cv('placeFile') ; 
174                }
175                else {
176                        $placeFileName = cv('in') ; 
177                }
178
179                openOsmFile ($placeFileName) ;
180                ($nodeId, $nodeLon, $nodeLat, $nodeUser, $aRef1) = getNode2 () ;
181                if ($nodeId != -1) {
182                        @nodeTags = @$aRef1 ;
183                }
184                my $place = cv ('place') ;
185                while ( ($nodeId != -1) and ($placeFound == 0) ) {
186                        my $placeNode = 0 ; my $placeName = 0 ;
187                        foreach my $tag ( @nodeTags ) {
188                                if ($tag->[0] eq "place") { $placeNode = 1 ; }
189                                if ( ($tag->[0] eq "name") and (grep /$place/i, $tag->[1]) ){ $placeName = 1 ; }
190                        }
191                        if ( (($placeNode == 1) and ($placeName == 1)) or ($placeId == $nodeId) ) {
192                                $placeFound = 1 ;
193                                $placeLon = $nodeLon ;
194                                $placeLat = $nodeLat ;
195                        }
196                        ($nodeId, $nodeLon, $nodeLat, $nodeUser, $aRef1) = getNode2 () ;
197                        if ($nodeId != -1) {
198                                @nodeTags = @$aRef1 ;
199                        }
200                }
201
202                closeOsmFile() ;
203
204                if ($placeFound == 1) {
205                        print "place $place found at " ;
206                        print "lon: $placeLon " ;
207                        print "lat: $placeLat\n" ;
208                        $left = $placeLon - cv('lonrad')/(111.11 * cos ( $placeLat / 360 * 3.14 * 2 ) ) ; 
209                        $right = $placeLon + cv('lonrad')/(111.11 * cos ( $placeLat / 360 * 3.14 * 2 ) ) ; 
210                        $top = $placeLat + cv('latrad')/111.11 ; 
211                        $bottom = $placeLat - cv('latrad')/111.11 ;
212
213                        print "call osmosis...\n" ;
214
215                        if ( cv('cie') eq "0" ) {
216                                print "OSMOSIS STRING: --bounding-box completeWays=yes completeRelations=yes bottom=$bottom top=$top left=$left right=$right\n" ;
217                                `osmosis --read-xml $osmName  --bounding-box completeWays=yes completeRelations=yes bottom=$bottom top=$top left=$left right=$right --write-xml ./temp.osm` ;
218                        }
219                        else {
220                                print "OSMOSIS STRING: --bounding-box clipIncompleteEntities=yes bottom=$bottom top=$top left=$left right=$right\n" ;
221                                `osmosis --read-xml $osmName  --bounding-box clipIncompleteEntities=yes  bottom=$bottom top=$top left=$left right=$right --write-xml ./temp.osm` ;
222                        }
223
224                        print "osmosis done.\n" ;
225
226                        $osmName = "./temp.osm" ;
227                        $clipbbox = "$left,$bottom,$right,$top" ;
228                }
229                else {
230                        print "ERROR: place $place not found.\n" ;
231                        die() ;
232                }
233        }
234
235
236        my $srtmFileName = cv('srtm') ;
237        if ( $srtmFileName ne "" ) {
238
239                my $cmdX = "osmosis --read-xml $osmName --rx file=\"$srtmFileName\" --bounding-box completeWays=yes completeRelations=yes bottom=$bottom top=$top left=$left right=$right --merge --write-xml file=\"./temp2.osm\"" ;
240                my $cmdP = "osmosis --read-xml $osmName --read-pbf file=\"$srtmFileName\" --bounding-box completeWays=yes completeRelations=yes bottom=$bottom top=$top left=$left right=$right --merge --write-xml file=\"./temp2.osm\"" ;
241
242                my $cmd = "" ;
243                if (grep /\.pbf/, $srtmFileName) {
244                        $cmd = $cmdP ;
245                }
246                else {
247                        $cmd = $cmdX ;
248                }
249
250                print "call osmosis to merge SRTM data...\n$cmd\n" ;
251
252                `$cmd` ;
253
254                $osmName = "temp2.osm" ;
255        }
256
257
258        # STORE DATA
259        my $nr = 0 ; my $wr = 0 ; my $rr = 0 ;
260        print "reading osm file...\n" ;
261
262        openOsmFile ($osmName) ;
263        ($nodeId, $nodeLon, $nodeLat, $nodeUser, $aRef1) = getNode2 () ;
264        if ($nodeId != -1) {
265                @nodeTags = @$aRef1 ;
266        }
267        while ($nodeId != -1) {
268                $nr++ ;
269                $lon{$nodeId} = $nodeLon ; $lat{$nodeId} = $nodeLat ;   
270                @{$memNodeTags{$nodeId}} = @nodeTags ;
271
272                ($nodeId, $nodeLon, $nodeLat, $nodeUser, $aRef1) = getNode2 () ;
273                if ($nodeId != -1) {
274                        @nodeTags = @$aRef1 ;
275                }
276        }
277
278        ($wayId, $wayUser, $aRef1, $aRef2) = getWay2 () ;
279        if ($wayId != -1) {
280                @wayNodes = @$aRef1 ;
281                @wayTags = @$aRef2 ;
282        }
283        while ($wayId != -1) {
284                $wr++ ;
285                if (scalar (@wayNodes) > 1) {
286                        @{$memWayTags{$wayId}} = @wayTags ;
287                        @{$memWayNodes{$wayId}} = @wayNodes ;
288                        foreach my $node (@wayNodes) {
289                                if (!defined $lon{$node}) {
290                                        print "  ERROR: way $wayId references node $node, which is not present!\n" ;
291                                }
292                        }
293                }
294                else {
295                        $invalidWays{$wayId} = 1 ;
296                }
297       
298                ($wayId, $wayUser, $aRef1, $aRef2) = getWay2 () ;
299                if ($wayId != -1) {
300                        @wayNodes = @$aRef1 ;
301                        @wayTags = @$aRef2 ;
302                }
303        }
304
305
306        ($relationId, $relationUser, $aRef1, $aRef2) = getRelation () ;
307        if ($relationId != -1) {
308                @relationMembers = @$aRef1 ;
309                @relationTags = @$aRef2 ;
310        }
311
312        while ($relationId != -1) {
313                $rr++ ;
314                @{$memRelationTags{$relationId}} = @relationTags ;
315                @{$memRelationMembers{$relationId}} = @relationMembers ;
316
317                foreach my $member (@relationMembers) {
318                        if ( ($member->[0] eq "node") and (!defined $lon{$member->[1]}) ) {
319                                print "  ERROR: relation $relationId references node $member->[1] which is not present!\n" ;
320                        }
321                        if ( ($member->[0] eq "way") and (!defined $memWayNodes{$member->[1]} ) and (!defined $invalidWays{$member->[1]}) ) {
322                                print "  ERROR: relation $relationId references way $member->[1] which is not present or invalid!\n" ;
323                        }
324                }
325
326                #next
327                ($relationId, $relationUser, $aRef1, $aRef2) = getRelation () ;
328                if ($relationId != -1) {
329                        @relationMembers = @$aRef1 ;
330                        @relationTags = @$aRef2 ;
331                }
332        }
333
334        closeOsmFile () ;
335
336        print "read: $nr nodes, $wr ways and $rr relations.\n\n" ;
337
338        # calc area of pic and init graphics
339        my $lonMin = 999 ; my $lonMax = -999 ; my $latMin = 999 ; my $latMax = -999 ;
340        foreach my $key (keys %lon) {
341                if ($lon{$key} > $lonMax) { $lonMax = $lon{$key} ; }
342                if ($lon{$key} < $lonMin) { $lonMin = $lon{$key} ; }
343                if ($lat{$key} > $latMax) { $latMax = $lat{$key} ; }
344                if ($lat{$key} < $latMin) { $latMin = $lat{$key} ; }
345        }
346
347        # clip picture if desired
348        if ($clipbbox ne "") {
349                my ($bbLeft, $bbBottom, $bbRight, $bbTop) = ($clipbbox =~ /([\d\-\.]+),([\d\-\.]+),([\d\-\.]+),([\d\-\.]+)/ ) ;
350                # print "$bbLeft, $bbBottom, $bbRight, $bbTop\n" ;
351                if (($bbLeft > $lonMax) or ($bbLeft < $lonMin)) { print "WARNING -clipbox left parameter outside data.\n" ; }
352                if (($bbRight > $lonMax) or ($bbRight < $lonMin)) { print "WARNING -clipbox right parameter outside data.\n" ; }
353                if (($bbBottom > $latMax) or ($bbBottom < $latMin)) { print "WARNING -clipbox bottom parameter outside data.\n" ; }
354                if (($bbTop > $latMax) or ($bbTop < $latMin)) { print "WARNING -clipbox top parameter outside data.\n" ; }
355                $lonMin = $bbLeft ;
356                $lonMax = $bbRight ;
357                $latMin = $bbBottom ;
358                $latMax = $bbTop ;
359        }
360        else {
361                if (defined cv('clip')) {
362                        if ( (cv('clip') > 0) and (cv('clip') < 100) ) { 
363                                my $clip = cv('clip') ;
364                                $clip = $clip / 100 ;
365                                $lonMin += ($lonMax-$lonMin) * $clip ;
366                                $lonMax -= ($lonMax-$lonMin) * $clip ;
367                                $latMin += ($latMax-$latMin) * $clip ;
368                                $latMax -= ($latMax-$latMin) * $clip ;
369                        }
370                }
371        }
372
373        # pad picture if desired
374        if (defined cv('pad')) {
375                my $pad = cv('pad') ;
376                if ( ($pad > 0) and ($pad < 100) ) { 
377                        $pad = $pad / 100 ;
378                        $lonMin -= ($lonMax-$lonMin) * $pad ;
379                        $lonMax += ($lonMax-$lonMin) * $pad ;
380                        $latMin -= ($latMax-$latMin) * $pad ;
381                        $latMax += ($latMax-$latMin) * $pad ;
382                }
383        }
384
385        my $size = cv('size') ;
386
387        # calc pic size
388
389        if ( cv('scaleSet') != 0 ) {
390                my $dist = distance ($lonMin, $latMin, $lonMax, $latMin) ;
391                my $width = $dist / cv('scaleSet') * 1000 * 100 / 2.54 ; # inches
392                $size = int ($width * 300) ;
393        }
394
395        if ( cv('maxTargetSize') ne "" ) {
396                my @a = split /,/, cv('maxTargetSize') ;
397                my $targetWidth = $a[0] ;
398                my $targetHeight = $a[1] ;
399                # print "TS: $targetWidth, $targetHeight [cm]\n" ;
400                my $distLon = distance ($lonMin, $latMin, $lonMax, $latMin) ;
401                my $distLat = distance ($lonMin, $latMin, $lonMin, $latMax) ;
402                # print "TS: $distLon, $distLat [km]\n" ;
403                my $scaleLon = ($distLon * 1000 * 100) / $targetWidth ;
404                my $scaleLat = ($distLat * 1000 * 100) / $targetHeight ;
405                my $targetScale = int $scaleLon ;
406                if ( $scaleLat > $targetScale ) { $targetScale = int $scaleLat ; }
407                # print "TS: $targetScale [1:n]\n" ;
408
409                my $width = $distLon / $targetScale * 1000 * 100 / 2.54 ; # inches
410                $size = int ($width * 300) ;
411                print "Map width now $size [px] due to maxTargetSize parameter\n" ;             
412        }
413
414        mwMap::initGraph ($size, $lonMin, $latMin, $lonMax, $latMax) ;
415
416}
417
418sub getNodePointers {
419        return ( \%lon, \%lat, \%memNodeTags) ;
420}
421
422sub getWayPointers {
423        return ( \%memWayNodes, \%memWayTags) ;
424}
425
426sub getRelationPointers {
427
428        return ( \%memRelationMembers, \%memRelationTags) ;
429}
430
431
4321 ;
433
434
Note: See TracBrowser for help on using the repository browser.