source: subversion/editors/osmpedit/landsat.pm @ 1044

Last change on this file since 1044 was 871, checked in by tpersson, 14 years ago

fill_cache fix from Joerg Ostertag

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