source: subversion/applications/editors/osmpedit/landsat.pm @ 34348

Last change on this file since 34348 was 1108, checked in by tpersson, 13 years ago

More support for ways added

File size: 12.3 KB
Line 
1#    Copyright (C) 2005 Tommy Persson, tpe@ida.liu.se
2#
3#    This program is free software; you can redistribute it and/or modify
4#    it under the terms of the GNU General Public License as published by
5#    the Free Software Foundation; either version 2 of the License, or
6#    (at your option) any later version.
7#
8#    This program is distributed in the hope that it will be useful,
9#    but WITHOUT ANY WARRANTY; without even the implied warranty of
10#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11#    GNU General Public License for more details.
12#
13#    You should have received a copy of the GNU General Public License
14#    along with this program; if not, write to the Free Software
15#    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
16
17package landsat;
18
19use FindBin qw($RealBin);
20use lib "$RealBin/../perl";
21
22use landsattile;
23
24use strict;
25
26
27sub new {
28    my $this = shift;
29    my $class = ref($this) || $this;
30    bless {
31        PIXELWIDTH => 600,
32        PIXELHEIGHT => 500,
33        CENTERLAT => 0,
34        CENTERLON => 0,
35        TRACKSHIDDEN => 0,
36        NODESSHIDDEN => 0,
37        SEGMENTSHIDDEN => 0,
38        WAYSHIDDEN => 0,
39        TRACKCOLLECTION => 0,
40        FRAME => 0,
41        CANVAS => 0,
42        CURRENTTILE => 0,
43        SCALE => 100,
44        DELTALAT => 0.0005,
45        DELTALON => 0.001,   # Gives ratio 1.2 in meter
46        CLASSBUTTONMAP => {},
47        NAMETOTILEMAP => {},
48        @_
49        }, $class;
50}
51
52
53sub set_center {
54   my $self = shift;
55   my $lat = shift;
56   my $lon = shift;
57   $self->{CENTERLAT} = $lat;
58   $self->{CENTERLON} = $lon;
59   my $dlat = $self->{DELTALAT};
60   my $dlon = $self->{DELTALON};
61   my $scale = $self->get_scale ();
62   $self->set_area ($lon-$dlon*$scale/2, 
63                    $lat-$dlat*$scale/2, $lon+$dlon*$scale/2, 
64                    $lat+$dlat*$scale/2);
65}
66
67sub add_to_center {
68   my $self = shift;
69   my $lat = shift;
70   my $lon = shift;
71   $self->{CENTERLAT} += $lat;
72   $self->{CENTERLON} += $lon;
73   $self->{NORTH} += $lat;
74   $self->{SOUTH} += $lat;
75   $self->{WEST} += $lon;
76   $self->{EAST} += $lon;
77}
78
79sub get_deltalat {
80    my $self = shift;
81    return $self->{DELTALAT};;
82}
83
84sub get_deltalon {
85    my $self = shift;
86    return $self->{DELTALON};;
87}
88
89sub get_lat {
90    my $self = shift;
91    return $self->{CENTERLAT};;
92}
93
94sub get_lon {
95    my $self = shift;
96    return $self->{CENTERLON};;
97}
98
99sub set_osm {
100    my $self = shift;
101    my $val = shift;
102    $self->{OSM} = $val;
103}
104
105sub get_osm {
106    my $self = shift;
107    return $self->{OSM};
108}
109
110sub set_track_collection {
111    my $self = shift;
112    my $val = shift;
113    $self->{TRACKCOLLECTION} = $val;
114}
115
116sub get_track_collection {
117    my $self = shift;
118    return $self->{TRACKCOLLECTION};
119}
120
121sub set_scale {
122    my $self = shift;
123    my $val = shift;
124    $self->{SCALE} = $val;
125    my $lat = $self->get_lat ();
126    my $lon = $self->get_lon ();
127    $self->set_center ($lat, $lon);
128}
129
130sub get_scale {
131    my $self = shift;
132    return $self->{SCALE};
133}
134
135sub set_frame {
136    my $self = shift;
137    my $val = shift;
138    $self->{FRAME} = $val;
139}
140
141sub get_frame {
142    my $self = shift;
143    return $self->{FRAME};;
144}
145
146sub set_canvas {
147    my $self = shift;
148    my $val = shift;
149    $self->{CANVAS} = $val;
150}
151
152sub get_canvas {
153    my $self = shift;
154    return $self->{CANVAS};;
155}
156
157sub get_tile {
158    my $self = shift;
159    my $lat = shift;
160    my $lon = shift;
161    my $scale = shift;
162
163    my $filename = "landsat-$scale";
164    if ($lat > 0) {
165        $filename .= "+";
166    }
167    $filename .= "$lat";
168    if ($lon > 0) {
169        $filename .= "+";
170    }
171    $filename .= "$lon";
172
173    my $tile = $self->{NAMETOTILEMAP}->{$filename};
174    if (not $tile) {
175        $tile = new landsattile ();
176        $tile->set_scale ($scale);  ### Hum, must be before set_center...
177        $tile->set_center ($lat, $lon);
178        $tile->set_frame ($self->get_frame ());
179        $tile->set_canvas ($self->get_canvas ());
180        $tile->load ();
181        $self->{NAMETOTILEMAP}->{$filename} = $tile;
182    }
183    return $tile;
184}
185
186
187sub display {
188    my $self = shift;
189
190    my $lat = $self->{CENTERLAT};
191    my $lon = $self->{CENTERLON};
192    my $scale = $self->get_scale ();
193
194    my ($clat, $clon) = $self->clamp_to_center_of_tile ($lat, $lon, $scale);
195
196##    $self->get_canvas ()->lower ("markeritem", "image");
197
198    my $tile = $self->get_tile ($clat, $clon, $scale);
199    $tile->display ($lat, $lon);
200
201
202    my $dlat = $self->get_deltalat ();  # 0.005
203    my $dlon = $self->get_deltalon ();  # 0.001
204    $dlat *= $scale;
205    $dlon *= $scale;
206
207    # eight tiles around
208    $tile = $self->get_tile ($clat+$dlat, $clon, $scale);   
209    $tile->display ($lat, $lon);
210    $tile = $self->get_tile ($clat+$dlat, $clon+$dlon, $scale);   
211    $tile->display ($lat, $lon);
212    $tile = $self->get_tile ($clat, $clon+$dlon, $scale);   
213    $tile->display ($lat, $lon);
214    $tile = $self->get_tile ($clat-$dlat, $clon+$dlon, $scale);   
215    $tile->display ($lat, $lon);
216    $tile = $self->get_tile ($clat-$dlat, $clon, $scale);   
217    $tile->display ($lat, $lon);
218    $tile = $self->get_tile ($clat-$dlat, $clon-$dlon, $scale);   
219    $tile->display ($lat, $lon);
220    $tile = $self->get_tile ($clat, $clon-$dlon, $scale);   
221    $tile->display ($lat, $lon);
222    $tile = $self->get_tile ($clat+$dlat, $clon-$dlon, $scale);   
223    $tile->display ($lat, $lon);
224}
225
226sub update_tracks {
227    my $self = shift;
228    $self->get_track_collection ()->draw ($self);
229}
230
231sub update_osm {
232    my $self = shift;
233    $self->get_osm ()->draw ($self);
234}
235
236sub display_tile {
237    my $self = shift;
238    my $lat = shift;
239    my $lon = shift;
240    my $scale = shift;
241
242    #
243    # Non landsat stuff, should be in another place
244    #
245
246
247}
248
249sub load_osm {
250    my $self = shift;
251    my $osm = $self->get_osm ();
252    $osm->fetch ($self);
253    $osm->parse ($self);
254    $self->update_osm ();
255}
256
257
258#sub display () {
259#    my $self = shift;
260#    my $tile = $self->get_tile ();
261#    my $scale = $self->get_scale ();
262#    my $lat = $tile->get_lat ();
263#    my $lon = $tile->get_lon ();
264#    $self->display_tile ($lat, $lon, $scale);
265#}
266
267sub north () {
268    my $self = shift;
269    my $scale = $self->get_scale ();
270    my $deltalat = $self->get_deltalat ();
271    my $lat = $self->get_lat ();
272    my $lon = $self->get_lon ();
273    $lat += ($deltalat*$scale);
274    $self->set_center ($lat, $lon);
275    $self->display ();
276}
277
278sub south () {
279    my $self = shift;
280    my $scale = $self->get_scale ();
281    my $deltalat = $self->get_deltalat ();
282    my $lat = $self->get_lat ();
283    my $lon = $self->get_lon ();
284    $lat -= ($deltalat*$scale);
285    $self->set_center ($lat, $lon);
286    $self->display ();
287}
288
289sub west () {
290    my $self = shift;
291    my $scale = $self->get_scale ();
292    my $deltalon = $self->get_deltalon ();
293    my $lat = $self->get_lat ();
294    my $lon = $self->get_lon ();
295    $lon -= ($deltalon*$scale);
296    $self->set_center ($lat, $lon);
297    $self->display ();
298}
299
300sub east () {
301    my $self = shift;
302    my $scale = $self->get_scale ();
303    my $deltalon = $self->get_deltalon ();
304    my $lat = $self->get_lat ();
305    my $lon = $self->get_lon ();
306    $lon += ($deltalon*$scale);
307    $self->set_center ($lat, $lon);
308    $self->display ();
309}
310
311sub zoomin () {
312    my $self = shift;
313    my $scale = $self->get_scale ();
314    if ($scale > 25) {
315        $scale /= 2;
316    } else {
317        if ($scale > 10) {
318            $scale = 10;
319        }
320    }
321    print STDERR "Set scale to $scale\n";
322    $self->set_scale ($scale);
323    $self->display ();
324}
325
326sub zoomout () {
327    my $self = shift;
328    my $scale = $self->get_scale ();
329    if ($scale < 11) {
330        $scale = 25;
331    } else {
332        $scale *= 2;
333    }
334    print STDERR "Set scale to $scale\n";
335    $self->set_scale ($scale);
336    $self->display ();
337}
338
339sub fix_order {
340    my $self = shift;
341    my $can = $self->get_canvas ();
342    my $top = "all";
343    if ($can->find ("withtag", "image")) {
344        $can->raise ("image", $top);
345        my $top = "image";
346    }
347    if (not $self->{WAYSHIDDEN}) {
348        if ($can->find ("withtag", "osmway")) {
349            $self->get_canvas ()->raise ("osmway", $top);
350            $top = "osmway";
351        }
352    } 
353    if (not $self->{TRACKSHIDDEN}) {
354        if ($can->find ("withtag", "track")) {
355            $self->get_canvas ()->raise ("track", $top);
356            $top = "track";
357        }
358    } 
359    if (not $self->{SEGMENTSHIDDEN}) {
360        if ($can->find ("withtag", "osmsegment")) {
361            $self->get_canvas ()->raise ("osmsegment", $top);
362            $top = "osmsegment";
363        }
364    } 
365    if (not $self->{NODESHIDDEN}) {
366        if ($can->find ("withtag", "osmnode")) {
367            $self->get_canvas ()->raise ("osmnode", $top);
368            $top = "osmnodes";
369        }
370    } 
371}
372
373
374sub toggle_tracks {
375    my $self = shift;
376    if ($self->{TRACKSHIDDEN}) {
377        $self->{TRACKSHIDDEN}  = 0;
378    } else {
379        $self->{TRACKSHIDDEN} = 1;
380    }
381    $self->fix_order ();
382}
383
384sub toggle_nodes {
385    my $self = shift;
386    if ($self->{NODESHIDDEN}) {
387        $self->{NODESHIDDEN}  = 0;
388    } else {
389        $self->{NODESHIDDEN} = 1;
390    }
391    $self->fix_order ();
392}
393
394sub toggle_segments {
395    my $self = shift;
396    if ($self->{SEGMENTSHIDDEN}) {
397        $self->{SEGMENTSHIDDEN}  = 0;
398    } else {
399        $self->{SEGMENTSHIDDEN} = 1;
400    }
401    $self->fix_order ();
402}
403
404sub toggle_ways {
405    my $self = shift;
406    if ($self->{WAYSHIDDEN}) {
407        $self->{WAYSHIDDEN}  = 0;
408    } else {
409        $self->{WAYSHIDDEN} = 1;
410    }
411    $self->fix_order ();
412}
413
414sub ctowgs84 {
415    my $self = shift;
416    my $x = shift;
417    my $y = shift;
418
419    my $w = $self->get_pixel_width ();
420    my $h = $self->get_pixel_height ();
421    my ($west, $south, $east, $north) = $self->get_area ();
422    my $dx = $east-$west;
423    my $dy = $north-$south;
424
425    my $lat = $south + ($h-$y)/$h*$dy;
426    my $lon = $west + $x/$w*$dx;
427
428    return ($lat, $lon);
429}
430
431sub clamp_to_center_of_tile {
432    my $self = shift;
433    my $lat = shift;
434    my $lon = shift;
435    my $scale = shift; # 10 25 50 100 200 400 800 ...
436    my $dlat = $self->get_deltalat ();  # 0.005
437    my $dlon = $self->get_deltalon ();  # 0.001
438    $dlat *= $scale;
439    $dlon *= $scale;
440#    my $flat = int (1/$dlat);
441#    my $flon = int (1/$dlon);
442    my $flat = (1/$dlat);
443    my $flon = (1/$dlon);
444    $lat = int ($lat*$flat+0.5)/$flat;
445    if ($lon >= 0) {
446        $lon = int ($lon*$flon+0.5)/$flon;
447    } else {
448        $lon = int ($lon*$flon-0.5)/$flon;
449    }
450    return ($lat, $lon);
451}
452
453sub get_pixel_width {
454    my $self = shift;
455    return $self->{PIXELWIDTH};
456}
457
458sub get_pixel_height {
459    my $self = shift;
460    return $self->{PIXELHEIGHT};
461}
462
463
464sub get_area {
465    my $self = shift;
466    my $west = $self->{WEST};
467    my $south = $self->{SOUTH};
468    my $east = $self->{EAST};
469    my $north = $self->{NORTH};
470    return ($west, $south, $east, $north);
471}
472
473sub set_area {
474    my $self = shift;
475    my $west = shift;
476    my $south = shift;
477    my $east = shift;
478    my $north = shift;
479    $self->{WEST} = $west;
480    $self->{SOUTH} = $south;
481    $self->{EAST} = $east;
482    $self->{NORTH} = $north;
483}
484
485sub fill_cache ($$$) {
486    my $self = shift;
487    my $max_new = shift || 1;
488    my $can_frame = shift;
489
490    my $scale = $self->get_scale ();
491    my $deltalat = $self->get_deltalat ();
492    my $deltalon = $self->get_deltalon ();
493    my $lat = $self->get_lat ();
494    my $lon = $self->get_lon ();
495    my $size = 10;
496    my $anz_seen=0;
497    my $anz_new=0;
498
499    print STDERR "Fill Cache for: $scale ($lat,$lon) +- $size tiles, max_new_tiles: $max_new\n";
500
501    for my $scale_fac ( qw( 1 2 4 8 16 32 )){
502        for my $test_scale ( ( $scale / $scale_fac, 
503                               $scale * $scale_fac )
504                             ) {
505            for my $dist ( 0..$size ) { # Start from actual position and get larger area in each loop
506                for my $la ( (-$dist..$dist) ) {
507                    for my $lo ( (-$dist..$dist) ) {
508                        #( 10,25,50,100,200,400,800,
509                        # 1600,3200,6400,12800,25600,51200 )
510                        last if $anz_new >= $max_new;
511                        $test_scale=10 if $test_scale<25;
512                        my ($la1, $lo1) = $self->clamp_to_center_of_tile
513                            (
514                             $lat+($deltalat*$test_scale*$la),
515                             $lon+($deltalon*$test_scale*$lo),
516                             $scale);
517                        $la1 = "+$la1" if $la1>0;
518                        $lo1 = "+$lo1" if $lo1>0;
519                        my $filename = 
520                        sprintf( "$ENV{HOME}/.osmpedit/cache/landsat-%d%s%s.jpg",
521                                 $test_scale,$la1,$lo1);
522                        #print STDERR "Check File:  $filename\n";
523                        if ( -s $filename ) {
524                            $anz_seen++; # This number is wrong since the inner
525                            # tiles are looked at multiple times
526                            next;
527                        }
528                        print STDERR "Fill Cache(new:$anz_new,seen:$anz_seen,max_new:$max_new)(dist:$dist): scale:$test_scale ($la1,$lo1)\n";
529                        my $tile = $self->get_tile ($la1+0.0, $lo1+0.0, $test_scale);
530                        $anz_new++;
531                        $anz_seen++;
532                    }
533                }
534            }
535        }
536    }
537    $self->set_scale ($scale);
538    $self->set_center ($lat, $lon);
539    $self->display ();
540    print STDERR "Fill Cache: existing: $anz_seen\n";
541    $can_frame->after( 100000, 
542                  sub{ 
543                      printf "Timer %s\n",''.localtime(time());
544                      $self->fill_cache(4,$can_frame);
545                  });
546}
547
548
549return 1;
Note: See TracBrowser for help on using the repository browser.