[Richard Suchenwirth] 2002-05-15 - The following code gets maps of predicted precipitation (for North Atlantic, Europe, and parts of adjacent continents) for the next 15 days, in 12 hour steps, from a German weather station via HTTP and displays them in a canvas. [DKF]: '''UPDATE 2003-06-27''' - This code no longer works because the site no longer provides the data (or at least not in the same way...?) - [RS] fixed, runs again :) proc cycle listName { upvar 1 $listName list set res [lindex $list 0] set list [concat [lrange $list 1 end] [list $res]] } proc every {ms body} {eval $body; after $ms [info level 0]} package require http # http::config -proxyhost proxy -proxyport 80 set prefix http://129.13.102.67/pics/Rtavn ;# fixed set suffix 4.gif pack [canvas .c -width 800 -height 680] -expand 1 -fill both wm title . "Loading..." for {set i 12} {$i<=504} {incr i 12} { set gif [http::data [http::geturl $prefix$i$suffix]] if ![catch {lappend ims [image create photo im$i -data $gif]}] { .c create image 0 0 -anchor nw -image im$i -tag im$i } } wm title . "Film" bind . q exit bind . exit every 1000 {.c raise [lindex [cycle ::ims] 0]} ---- [KBK] I found that the above caused my Windows desktop to, uhhhm, "become unresponsive." Apparently, the Windows implementation, at least on my machine, can't cope with 32 images of that size inside a canvas at once. Changing so that the canvas has only two image objects and loading them in alternation helps a lot. (It also allows the animation to start while the images are still downloading, if done right.) Here's an alternative implementation: ---- proc every {ms body} {eval $body; after $ms [info level 0]} proc cycleImages { } { variable ims variable imsIndex variable buffer if { [llength $ims] > 0 } { .c raise buffer$buffer wm title . "image $imsIndex" set buffer [expr { 2 - $buffer }] incr imsIndex if { $imsIndex >= [llength $ims] } { set imsIndex 0 } .c itemconfig buffer$buffer -image [lindex $ims $imsIndex] } } proc loadImage { i } { variable prefix variable suffix if { $i > 504 } return http::geturl $prefix$i$suffix -command [list loadFinished $i] } proc loadFinished { i token } { variable ims lappend ims [image create photo -data [http::data $token]] http::cleanup $token after 0 [list loadImage [expr { $i + 12 }]] } package require http # http::config -proxyhost webcache -proxyport 8080 set prefix http://129.13.102.67/pics/Rvtmrf set suffix 4.gif pack [canvas .c -width 800 -height 680 -bg white] -expand 1 -fill both .c create image 10 10 -anchor nw -tag buffer1 .c create image 10 10 -anchor nw -tag buffer2 set ims {} set imsIndex 0 set buffer 1 bind . q exit bind . exit every 1000 cycleImages loadImage 12 ---- ''[Donal Fellows] -'' Now, I'm lucky enough to have a machine big enough to take all the images, but I don't like the way that they load; I'd like to issue a bunch of HTTP requests at once and get things back ASAP (I'm on quite a big network pipe here) so I do something like this ('''min. Tcl version 8.4'''): package require http # http::config -proxyhost proxy -proxyport 80 proc every {ms body} {eval $body; after $ms [info level 0]} set prefix http://129.13.102.67/pics/Rvtmrf set suffix 4.gif set ims {} pack [canvas .c -width 800 -height 680] -expand 1 -fill both wm title . "Loading..." update set throttle 6 set cmds {} proc loadImage {i step limit} { global prefix suffix if { $i > $limit } return loadImageCore $prefix$i$suffix after 150 loadImage [expr {$i + $step}] $step $limit } proc loadImageCore {url} { global ims cmds throttle set l [llength $ims] lappend ims {} if {$throttle < 1} { lappend cmds [list \ http::geturl $url -command [list loadFinished $l]] } else { incr throttle -1 http::geturl $url -command [list loadFinished $l] } } proc loadFinished { l token } { global ims throttle incr throttle set image [image create photo -data [http::data $token]] lset ims $l [.c create image 0 0 -anchor nw -image $image] http::cleanup $token after 1000 anotherCommand } proc anotherCommand {} { global cmds if {[llength $cmds]} { set cmd [lindex $cmds 0] set cmds [lrange $cmds 1 end] uplevel #0 $cmd } } set idx 0 proc cycleImage {} { global ims idx set item [lindex $ims $idx] if {$item ne ""} { .c raise $item } if {[incr idx] >= [llength $ims]} { set idx 0 } } every [expr {1000/15}] {cycleImage} loadImage 12 12 504 wm title . "Film" bind . q exit bind . exit Alas, asynchronous HTTP has quite a hefty synchronous start-up phase on this system. :^( ---- Multiply your possibilities by changing the trailing digit in the URL ("4.gif" above): * 1: Temperature and ground pressure * 2: 850 hPa Geopot. (gpdm) and Temperature (C) * 3: Ground pressure, clouds in %, ReTop 500/1000 (gpdam) * 4: 12 h precipitation in mm until date * 5: 2 m temperature (C) * 6: 700 hPa Geopot. (gpdm) and vertical movement (hPa/h) * 7: Ground pressure (hPa) and 850hPa eq.pot.termperature (C) * 8: 2 m dewing point ---- 'Nother massive source of weather data is METAR [http://205.156.54.206/oso/oso1/oso12/metar.htm]. Not predictive but reporting current conditions (hourly, I think). Using a well-defined textual dataset with lines such as: KCPC 190751Z AUTO 00000KT 10SM SCT015 OVC110 21/19 A3016 RMK AO2 705 That's an airport code, timecode, and then al sorts of weather info. There are several sources of collected data, e.g. [http://weather.noaa.gov/weather/metar.shtml]. Hmm.... are there any [contour plot] solutions for Tcl? -[jcw] [RS]: Iain Findleton reported that he is using the turtle graphics code from [Turtleshell], which was intended more as demo for kids, to plot weather maps which he receives in relative coordinates... [AM] Believe it or not: [Vince Darley] maintains [Plplot] ("Plplotter" widget) at [http://www.santafe.edu/~vince/Pltk.html], a package that does that sort of plots. ''(Now at [http://plplot.sourceforge.net/] -[jcw])'' --- [Vince] adds that the 'plplot' sourceforge project has the Plplotter code partially integrated into the main branch of plplot, but the TEA configure/build stuff is in a 'tea' branch off the main project branch. Unfortunately [TEA] was such a disaster that everyone's patience was exhausted before the code could get incorporated into the main tree. It is a very nice plotting widget, however! (I've used it both for my thesis work and in a commercial product). A binary release of plplot for Windows is available [ftp://ftp.ucsd.edu/pub/alpha/tcl/extensions/plplot5.1a.zip]. ''As for parsing METAR data files - turns out that it has already been done, see [Jason Tang]'s [TclWeather]. Good. -[jcw]'' [MPJ]: I have been using [TclWeather] for a couple of months now (even works behind a proxy). You may also want to see his stock ticker, [TclStock], application. The 4-letter "ICAO identifiers" define each airport, there's a list with some 6000 entries along with names and longitude/latitude at [http://205.156.54.206/pub/stninfo/nsd_cccc.txt] (about 500 Kb ascii, field description at [http://www.nws.noaa.gov/tg/site.shtml]). ''One could take [TclWorld], fetch current temperatures on there, and then draw a contour plot... hmm, that could be fun -[jcw]'' [Jason Tang]: Indeed, I have written an applet that downloads and parses the METAR data for nearly any place on the planet. I haven't finished cleaning up and documenting ''TclWeather'' yet; it'll be ready Real Soon Now(tm). It uses my lexical scanner, ''(insert plug here)'' [fickle] to break down a METAR report into its individual parts. '''Update:''' Go to [TclWeather]. ---- Also see "[Tcl and the weather]". ---- !!!!!! [Arts and crafts of Tcl-Tk programming] %| [Category Geography] |% !!!!!!