#!/usr/bin/wish -f ## ## Tk SCRIPT NAME: tkFetchOSMtiles_forLatLon_oneTileAtVariousZoomLevels.tk ## ##+####################################################################### ## PURPOSE: This Tk script provides a GUI for entering or selecting a ## latitude-longitude location on the Earth (in decimal degrees). ## The GUI also allows the user to select several OSM zoom-levels --- ## where each 'zoom-level' indicator is an integer between 0 and 19. ## (OSM = Open Street Map) ## ## Reference: ## http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Zoom_levels ## ## This script then ## ## 1) converts that latitude-longitude (in decimal degrees) ## into a pair of integers m,n that (for each specified ## zoom-level, 'z') determines an OSM tile --- a URL that ## specifies a 256x256 PNG filename, example: ## http://tile.openstreetmap.org/z/m/n.png ## ## 2) uses the 'wget' command to fetch the PNG files for ## several triplets: (z1,m,n) (z2,m,n) (z3,m,n) ... ## into a local directory, such as /tmp ## ## 3) shows all of the several fetched PNG files using ## an image viewer that the user can specify in a ## variable 'IMGviewer' set at the bottom of this script. ## ## Examples: set IMGviewer "/usr/bin/eog" ## or ## set IMGviewer "/usr/bin/eom" ## ## to specify the EyeOfGnome or EyeOfMATE ## image viewer on Linux. ## ## 4) The user can close the several image viewer windows and ## then specify another Earth location and/or set of ## zoom levels and do another fetch-and-show. ## ## The intent of this utility is to allow the user to easily ## sample some OSM tiles (256x256 PNG files) at a specific ## Earth location for several zoom levels --- with the view ## in mind of using another Tk script utility to build a ## map (a PNG file made up of rows and columns of OSM tiles) ## using a single appropriate zoom-level to fetch the tiles ## to build the larger PNG file. ## ## An 'external' Tk GUI script can be called by the user ## --- via a 'SomeLatLonSites' button on the GUI --- to allow the ## user to select a site on the Earth (city, state, country, ## national park, etc.). The external script provides the ## latitude,longitude location of the user-selected site. ## ##+###################### ## NOTES ON OTHER VIEWERS: ## Other 'simple', quick-starting image viewer programs that ## might be useful are 'feh', 'gwenview', 'gpicview', ## ImageMagick 'display' or 'animate', and quite a few others. ## ##+################# ## THE GUI WIDGETS: ## ## The options available to the user are compactly indicated ## by the following 'sketch' of the GUI: ## ## FRAME ## NAMES ## VVVVVVVVVV ## ------------------------------------------------------------------------------------ ## Fetch OSM Tiles (256x256 PNG files) - for a Latitude-Longitude - Various Zoom-Levels ## [window title] ## ------------------------------------------------------------------------------------ ## ## .fRbuttons {Exit} {Help} {SomeLatLonSites} {FetchAndShowTiles} ZoomLevels (0 to 18): 4_8_12_16______ ## ## .fRlatlon Earth Location in decimal degrees - Latitude: ____________ Longitude: __________ ## ## .fRmsg [---------- a message line goes here in a label widget -------------------------] ## ## -------------------------------------------------------- ## ## In the above sketch of the GUI: ## ## Square brackets indicate a comment (not to be placed on the GUI). ## Braces indicate a Tk 'button' widget. ## Underscores indicate a Tk 'entry' widget. ## A colon indicates that the text before the colon is on a 'label' widget. ## Capital-O indicates a Tk 'radiobutton' widget, if any. ## Capital-X indicates a Tk 'checkbutton' widget, if any. ## ##+############## ## GUI components: ## ## From the GUI 'sketch' above, it is seen that the GUI consists of ## about ## ## - 4 button widgets ## - 3 label widgets ## - 3 entry widgets ## - 0 radiobutton widgets ## - 0 checkbutton widgets ## - 0 scale widgets ## - 0 listbox widgets ## - 0 canvas widgets ## - 0 text widgets ## ##+##################################################################### ## CALLED BY: This script is inteded to be called from a 'MAPtools' ## toolchest of the FE 'tkGooies' menus/toolchests system. ##+######################################################################## ## STRUCTURE OF THIS CODE: ## ## 0) Set general window parms (win-name, win-position, win-color-scheme, ## fonts, widget-geom-parms, win-size-control, text-array-for-labels-etc). ## ## 1a) Define ALL frames (and sub-frames, if any). ## 1b) Pack the frames. ## ## 2) Define & pack all widgets in the frames, frame by frame. ## After all the widgets for a frame are defined, pack them in the frame. ## ## 3) Define keyboard and/or mouse/touchpad/touch-sensitive-screen 'event' ## BINDINGS, if needed. ## 4) Define PROCS, if needed. ## 5) Additional GUI INITIALIZATION (typically with one or more of ## the procs), if needed. ## ## In more detail: ## ## 1a) Define ALL frames -- and sub-frames: ## ## Top-level : ## 'fRbuttons' for Exit, Help, ... buttons ## 'fRlatlon' for latitude-longitude entry fields ## 'fRmsg' for messages to the user ## ## 1b) Pack ALL frames, including sub-frames (if any). ## ## 2) Define & pack all widgets in the frames -- basically going through ## frames & their interiors in left-to-right, top-to-bottom order: ## ## 3) Define bindings: See the BINDINGS section below. ## ## 4) Define procs: See the PROCS section below. ## ## 5) Additional GUI initialization: See this section at the bottom ## of this script. ##+####################################################################### ## DEVELOPED WITH: Tcl-Tk 8.5 on Ubuntu 9.10 (2009-october, 'Karmic Koala') ## ## $ wish ## % puts "$tcl_version $tk_version" ## ## showed ## 8.5 8.5 ## but this script should work in most previous 8.x versions, and probably ## even in some 7.x versions (if font handling is made 'old-style'). ##+######################################################################## ## MAINTENANCE HISTORY: ## Started by: Blaise Montandon 2016oct30 Started development, on Ubuntu 9.10, ## based on the code of some Tk scripts ## of mine that contained most of the ## widgets needed. ## Updated by: Blaise Montandon 2016 ##+####################################################################### ##+###################################################### ## Set WINDOW TITLE and POSITION. ##+###################################################### wm title . "Fetch OSM Tiles (256x256 PNG files) - for a Latitude-Longitude - Various Zoom-Levels" wm iconname . "FetchOSMtiles" wm geometry . +15+30 # wm geometry . +250+285 ##+###################################################### ## Set the COLOR SCHEME for the window and its widgets --- ## such as listbox and entry field background color. ##+###################################################### tk_setPalette "#e0e0e0" set entryBKGD "#ffffff" # set radbuttBKGD "#ffffff" # set chkbuttBKGD "#ffffff" # set scaleBKGD "#f0f0f0" # set listboxBKGD "#f0f0f0" # set textBKGD "#f0f0f0" ##+######################################################## ## DEFINE (temporary) FONT NAMES. ## ## We use a VARIABLE-WIDTH font for text on LABEL and ## BUTTON widgets. ## ## We use a FIXED-WIDTH font for LISTBOX lists, ## for text in ENTRY fields --- and often for text in ## TEXT widgets. ##+######################################################## font create fontTEMP_varwidth \ -family {comic sans ms} \ -size -14 \ -weight bold \ -slant roman font create fontTEMP_SMALL_varwidth \ -family {comic sans ms} \ -size -12 \ -weight bold \ -slant roman ## Some other possible (similar) variable width fonts: ## Arial ## Bitstream Vera Sans ## DejaVu Sans ## Droid Sans ## FreeSans ## Liberation Sans ## Nimbus Sans L ## Trebuchet MS ## Verdana font create fontTEMP_fixedwidth \ -family {liberation mono} \ -size -14 \ -weight bold \ -slant roman font create fontTEMP_SMALL_fixedwidth \ -family {liberation mono} \ -size -12 \ -weight bold \ -slant roman ## Some other possible fixed width fonts (esp. on Linux): ## Andale Mono ## Bitstream Vera Sans Mono ## Courier 10 Pitch ## DejaVu Sans Mono ## Droid Sans Mono ## FreeMono ## Nimbus Mono L ## TlwgMono ##+########################################################### ## SET GEOM VARS FOR THE VARIOUS WIDGET DEFINITIONS. ## (e.g. width and height of canvas, and padding for Buttons) ##+########################################################### ## LABEL widget geom settings: set PADXpx_label 0 set PADYpx_label 0 set BDwidthPx_label 2 ## BUTTON widget geom settings: set PADXpx_button 0 set PADYpx_button 0 set BDwidthPx_button 2 ## ENTRY widget geom settings: set BDwidthPx_entry 2 ## COMMENT some widget geom parms. if {0} { ## RADIOBUTTON widget geom settings: set PADXpx_radbutton 0 set PADYpx_radbutton 0 set BDwidthPx_radbutt 2 ## CHECKBUTTON widget geom settings: set PADXpx_chkbutton 0 set PADYpx_chkbutton 0 set BDwidthPx_chkbutton 2 ## TEXT widget geom settings: set BDwidthPx_text 2 ## SCALE widget geom parameters: # set BDwidthPx_scale 2 # set scaleThicknessPx 10 } ## END of commented geom parms ##+############################################################## ## Set a TEXT-ARRAY to hold text for buttons & labels on the GUI. ## NOTE: This can aid INTERNATIONALIZATION. This array can ## be set according to a nation/region parameter. ##+############################################################## ## if { "$VARlocale" == "en"} ## For '.fRbuttons' frame: set aRtext(buttonEXIT) "Exit" set aRtext(buttonHELP) "Help" set aRtext(buttonGETLATLON) "SomeLatLonSites" set aRtext(buttonFETCHTILES) "FetchAndShowTiles" set aRtext(labelZOOMLEVELS) " ZoomLevels (0 to 18):" ## For '.fRlatlon' frame: set aRtext(labelLATITUDE) "Earth Location in decimal degrees - Latitude:" set aRtext(labelLONGITUDE) "Longitude:" ## END OF if { "$VARlocale" == "en"} ##+###################################################################### ## Set a MIN-SIZE of the window (roughly). ## ## For WIDTH, allow for the min-width of the '.fRbuttons' frame. ## ## For HEIGHT, allow for the stacked frames: ## 1 char high for the '.fRbuttons' frame ## 1 char high for the '.fRlatlon' frame ## 1 char high for the '.fRmsg' frame ## -------- ## 3 chars high for the 3 frames ##+##################################################################### ## FOR WIDTH: (allow for widgets in the '.fRbuttons' frame) set minWidthPx [font measure fontTEMP_varwidth \ " $aRtext(buttonEXIT) $aRtext(buttonHELP) $aRtext(buttonGETLATLON) \ $aRtext(buttonFETCHTILES) $aRtext(labelZOOMLEVELS)"] ## We add some pixels to account for right-left-size of ## window-manager decoration (~8 pixels) and some pixels for ## frame/widget borders (~5 widgets x 4 pixels/widget = 20 pixels). set minWinWidthPx [expr {28 + $minWidthPx}] ## For HEIGHT --- for ## 1 char high for the '.fRbuttons' frame ## 1 char high for the '.fRlatlon' frame ## 1 char high for the '.fRmsg' frame ## -------- ## 3 chars high for the 3 frames set charHeightPx [font metrics fontTEMP_varwidth -linespace] set minWinHeightPx [expr {3 * $charHeightPx}] ## Add about 20 pixels for top-and-bottom window decoration -- ## and some pixels for top-and-bottom of frame/widget borders ## (~3 widgets x 4 pixels/widget = 12 pixels). set minWinHeightPx [expr {32 + $minWinHeightPx}] ## FOR TESTING: # puts "minWinWidthPx = $minWinWidthPx" # puts "minWinHeightPx = $minWinHeightPx" wm minsize . $minWinWidthPx $minWinHeightPx ## We may allow the window to be resizable. We pack the canvases ## (and the frames that contain them) with '-fill both -expand 1' ## so that the canvases can be enlarged by enlarging the window. ## If you want to make the window un-resizable, ## you can use the following statement. # wm resizable . 0 0 ## We fix the y-size of the window, but allow the x-size to vary. wm resizable . 1 0 ##+#################################################################### ##+#################################################################### ## DEFINE *ALL* THE FRAMES: ## ## Top-level : ## 'fRbuttons' for Exit, Help, ... buttons ## 'fRlatlon' for latitude,longitude entry fields ## 'fRmsg' for messages to the user ##+#################################################################### ##+#################################################################### ## FOR TESTING change 0 to 1: ## (Example1: To see appearance of frames when borders are drawn.) ## (Example2: To see sizes of frames for various '-fill' options.) ## (Example3: To see how frames expand as window is resized.) if {0} { set RELIEF_frame raised set BDwidthPx_frame 2 } else { set RELIEF_frame flat set BDwidthPx_frame 0 } frame .fRbuttons -relief $RELIEF_frame -bd $BDwidthPx_frame frame .fRlatlon -relief raised -bd 2 frame .fRmsg -relief raised -bd 2 ##+######################################################## ## PACK *ALL* the FRAMES. ##+######################################################## pack .fRbuttons \ -side top \ -anchor nw \ -fill x \ -expand 0 pack .fRlatlon \ -side top \ -anchor nw \ -fill x \ -expand 0 pack .fRmsg \ -side top \ -anchor nw \ -fill x \ -expand 0 ##+################################################################ ##+################################################################ ## START DEFINING & PACKING WIDGETS WITHIN THEIR FRAMES. ##+################################################################ ##+################################################################ ##+######################################################## ## IN THE '.fRbuttons' frame -- DEFINE several buttons ## --- Exit, Help, .... Then PACK them. ##+######################################################## button .fRbuttons.buttEXIT \ -text "$aRtext(buttonEXIT)" \ -font fontTEMP_varwidth \ -padx $PADXpx_button \ -pady $PADYpx_button \ -relief raised \ -bd $BDwidthPx_button \ -command {exit} button .fRbuttons.buttHELP \ -text "$aRtext(buttonHELP)" \ -font fontTEMP_varwidth \ -padx $PADXpx_button \ -pady $PADYpx_button \ -relief raised \ -bd $BDwidthPx_button \ -command {popup_msgVarWithScroll .topHelp "$HELPtext" +30+30} button .fRbuttons.buttGETLATLON \ -text "$aRtext(buttonGETLATLON)" \ -font fontTEMP_varwidth \ -padx $PADXpx_button \ -pady $PADYpx_button \ -relief raised \ -bd $BDwidthPx_button \ -command {get_lat_lon} button .fRbuttons.buttFETCHTILES \ -text "$aRtext(buttonFETCHTILES)" \ -font fontTEMP_varwidth \ -padx $PADXpx_button \ -pady $PADYpx_button \ -relief raised \ -bd $BDwidthPx_button \ -command {fetch_and_show_tiles} label .fRbuttons.labelZOOMLEVELS \ -text "$aRtext(labelZOOMLEVELS)" \ -font fontTEMP_varwidth \ -justify left \ -anchor w \ -relief flat \ -bd $BDwidthPx_label entry .fRbuttons.entryZOOMLEVELS \ -textvariable ENTRYzoomlevels \ -bg $entryBKGD \ -font fontTEMP_fixedwidth \ -relief sunken \ -bd $BDwidthPx_entry ##+######################################## ## Pack the widgets in the 'fRbuttons' frame ##+######################################## pack .fRbuttons.buttEXIT \ .fRbuttons.buttHELP \ .fRbuttons.buttGETLATLON \ .fRbuttons.buttFETCHTILES \ .fRbuttons.labelZOOMLEVELS \ -side left \ -anchor w \ -fill none \ -expand 0 pack .fRbuttons.entryZOOMLEVELS \ -side left \ -anchor w \ -fill x \ -expand 1 ##+######################################################## ## IN THE '.fRlatlon' frame -- DEFINE a pair of ## LABEL and ENTRY widgets. Then PACK them. ##+######################################################## label .fRlatlon.labelLATITUDE \ -text "$aRtext(labelLATITUDE)" \ -font fontTEMP_varwidth \ -justify left \ -anchor w \ -relief flat \ -bd $BDwidthPx_label entry .fRlatlon.entryLATITUDE \ -textvariable ENTRYlatitude \ -width 22 \ -bg $entryBKGD \ -font fontTEMP_fixedwidth \ -relief sunken \ -bd $BDwidthPx_entry ## We set an initial value for the latitude entry var ## in the 'Additional GUI Initialization' section at ## the bottom of this script. label .fRlatlon.labelLONGITUDE \ -text "$aRtext(labelLONGITUDE)" \ -font fontTEMP_varwidth \ -justify left \ -anchor w \ -relief flat \ -bd $BDwidthPx_label entry .fRlatlon.entryLONGITUDE \ -textvariable ENTRYlongitude \ -width 22 \ -bg $entryBKGD \ -font fontTEMP_fixedwidth \ -relief sunken \ -bd $BDwidthPx_entry ## We set an initial value for the latitude entry var ## in the 'Additional GUI Initialization' section at ## the bottom of this script. ##+######################################## ## PACK the widgets in the 'fRlatlon' frame. ##+######################################## pack .fRlatlon.labelLATITUDE \ -side left \ -anchor w \ -fill none \ -expand 0 pack .fRlatlon.entryLATITUDE \ -side left \ -anchor w \ -fill x \ -expand 1 pack .fRlatlon.labelLONGITUDE \ -side left \ -anchor w \ -fill none \ -expand 0 pack .fRlatlon.entryLONGITUDE \ -side left \ -anchor w \ -fill x \ -expand 1 ##+######################################################## ## IN THE '.fRmsg' frame -- DEFINE a LABEL widget. ## Then PACK it. ##+######################################################## label .fRmsg.labelMSG \ -text "" \ -font fontTEMP_varwidth \ -justify left \ -anchor w \ -relief flat \ -bd $BDwidthPx_label \ -bg #ff6600 ## PACK the widget in the 'fRmsg' frame. pack .fRmsg.labelMSG \ -side left \ -anchor w \ -fill x \ -expand 1 ##+##################################################################### ## END OF SECTION TO DEFINE AND PACK THE GUI WIDGETS. ##+##################################################################### ##+##################################################################### ##+##################################################################### ## DEFINE BINDINGS: button1-release bindings on some widgets ??? ## Return-key bindings on some entry widgets ??? ##+##################################################################### # bind .fR?????.???widget??? {??proc??} # bind .fR?????.???widget??? {??proc??} ##+##################################################################### ##+##################################################################### ## DEFINE PROCEDURES: ## ## 'get_lat_lon' - called by the 'SomeLatLonSites' button ## ## 'fetch_and_show_tiles' - called by the 'FetchAndShowTiles' button. ## ## 'z_lat_lon_TO_col_row' - called by proc 'fetch_and_show_tiles' ## ## 'advise_user' - called in the 'Additional GUI Initialization' ## section at the bottom of the script ## ## 'edit_inputs' - called by the 'fetch_and_show_tiles' proc ## ## 'decimal_check' - called by the 'edit_inputs' proc ## ## 'popup_msgVarWithScroll' - called by 'Help' button to show HELPtext var. ##+##################################################################### ##+##################################################################### ##+##################################################################### ## PROC: 'get_lat_lon' ## ## PURPOSE: Call on an external Tk GUI script to allow the user ## to select a site (city, state, country, national park, other) ## and extract the latitude and longitude (in decimal degrees) ## from the string returned by that external script. ## ## CALLED BY: the 'SomeLatLonSites' button. ##+##################################################################### proc get_lat_lon {} { global SELECTORlatlon ENTRYlatitude ENTRYlongitude ############################################# ## Get an 'image-playlist' file name. ############################################# set TEMPstring [exec "$SELECTORlatlon"] ## FOR TESTING: # puts "TEMPstring : $TEMPstring" ################################### ## Check if TEMPstring var is empty. ################################### if {"$TEMPstring" == ""} {return} ##################################################### ## Extract latitude and longitude from TEMPstring ## and put those numbers in the ENTRYlatitude and ## ENTRYlongitude variables. ##################################################### set TEMPlatlon [lindex [split "$TEMPstring" "#"] 1] set ENTRYlatitude [lindex "$TEMPlatlon" 0] set ENTRYlongitude [lindex "$TEMPlatlon" 1] } ## END OF PROC 'get_lat_lon' ##+################################################################### ## PROC: 'fetch_and_show_tiles' ##+################################################################### ## PURPOSE: For a given set of zoom-levels (integers) and ## a given latitude,longitude, ## fetch a set of tiles from an OpenStreetMap server and ## show each of the tiles in an instance of an ## image viewer. ## ## METHOD: In a loop over the user-specified zoom-levels (z1,z2,z3,...) ## for each triple (zi,lat,lon) convert that triple to ## a new triple: (zi,m,n) ## ## Using 'wget', use each triple (zi,m,n) to get the PNG file at ## http://tile.openstreetmap.org/zi/m/n.png ## to a local directory, like /tmp. ## Then use the image viewer, IMGviewer, to show each PNG file. ## ## CALLED BY: the 'FetchAndShowTiles' button ##+################################################################## proc fetch_and_show_tiles { } { global ENTRYzoomlevels ENTRYlatitude ENTRYlongitude \ WGETpgm DIRtemp IMGviewer EDITcode POPUPloc WAITmillisecs ######################################################## ## Check the latitude, longitude entry field inputs. ## Bail out if there seems to be invalid input. ######################################################## edit_inputs if {$EDITcode > 0} {return} ########################################################### ## Fetch and show a tile for each user-specified zoom level. ## METHOD: ## Uses 'wget' to get each tile from OpenStreetMap and ## uses an image viewer, like 'eog' (Eye of Gnome), to ## show each image file retrieved to a local working ## directory. ########################################################## foreach z $ENTRYzoomlevels { set TEMPcolrow [z_lat_lon_TO_col_row $z $ENTRYlatitude $ENTRYlongitude] set col [lindex $TEMPcolrow 0] set row [lindex $TEMPcolrow 1] set OUTfile "$DIRtemp/tile_${z}_${col}_${row}.png" ## FOR TESTING: if {0} { puts "" puts "From PROC 'fetch_and_show_tiles':" puts "TEMPcolrow: $TEMPcolrow" puts "z: $z ENTRYlatitude: $ENTRYlatitude ENTRYlongitude: $ENTRYlongitude" puts "col: $col row: $row" puts "OUTfile: $OUTfile" } #################################################################### ## Some error-checking with 'catch' statements on these 'exec' ## statements may be needed. See 'tkGooie' script ## tk_showImgFilesInPlaylist_FrontEnd.tk #################################################################### ## SOME SYNTAX NOTES on running 'external' programs via a Tcl 'exec': #################################################################### ## On page 105 of the 4th edition of 'Practical Programming in Tcl & Tk', ## is the following quote on the Tcl 'exec' command: ## ## "The 'exec' command runs programs from your Tcl script. For example: ## set d [exec date] ## The standard output of the program is returned as the value of ## the 'exec' command. However, if the program writes to its standard ## error channel or exits with a nonzero status code, then 'exec' ## raises an error. If you do not care about the exit status, or you ## use a program that insists on writing to standard error, then you ## can use 'catch' to mask the errors: ## ## catch {exec program arg arg} result" ## ## This is an example of running a program in 'foreground' mode. ####################################################################### ## On page 107 of the 4th edition of 'Practical Programming in Tcl & Tk', ## is the following quote on the Tcl 'exec' command and 'background' mode: ## ## "A trailing '&' causes the program to run in the background. ## In this case, the process identifier is returned by the 'exec' ## command. Otherwise, the 'exec' command blocks during execution ## of the program, and the standard output of the program is the ## return code of 'exec'." ## ## Page 83 of the same book says: ## "'catch' returns zero if there was no error caught, ## or a nonzero error code if it did catch an error." #################################################################### ## A couple of examples of using a PID (process ID) with Tcl: ## ## catch {eval exec $feREADER_text \"$FULFILname\" &} ViewerPID ## ## set RETcode [ catch {eval exec ${feDIR}/tkGUIs/shofil.tk \ ## "$FULFILname" &} ViewerPID ] ## #################################################################### ## An alternative form of trying 'exec': ## exec /bin/sh -c "$...." #################################################################### ############################################################### ## A 'foreground' run of 'wget' per page 105 of the 4th edition ## of 'Practical Programming in Tcl & Tk'. ## ## (We do not want to run 'wget' in the background --- with & --- ## because we do not want to start the image viewer until ## the PNG file is retrieved from the OSM server.) ## ## We MAY need to use 'eval' to avoid a 'not found' error if ## we append some parms (or a space) to the command. ############################################################### ## And example of message from a SUCCESSFUL 'wget' fetch: ## ## --2016-10-30 21:52:28-- http://tile.openstreetmap.org/4/7/6.png ## Resolving tile.openstreetmap.org... 140.211.167.105 ## Connecting to tile.openstreetmap.org|140.211.167.105|:80... connected. ## HTTP request sent, awaiting response... 200 OK ## Length: 12300 (12K) [image/png] ## Saving to: `/tmp/tile_4_7_6.png' ## ## 0K .......... .. 100% 103K=0.1s ## ## 2016-10-30 21:52:28 (103 KB/s) - `/tmp/tile_4_7_6.png' saved [12300/12300] ## ## The non-verbose (-nv) message: ## ## 2016-10-30 22:59:09 URL:http://tile.openstreetmap.org/16/29964/27434.png [103/103] -> "/tmp/tile_16_29964_27434.png" [1] ############################################################### ## And example of message from a SUCCESSFUL 'wget' fetch ## due to no internet connection: ## ## --2016-10-30 21:56:30-- http://tile.openstreetmap.org/4/7/6.png ## Resolving tile.openstreetmap.org... failed: Name or service not known. ## wget: unable to resolve host address `tile.openstreetmap.org' ## ## The non-verbose (-nv) message: ## wget: unable to resolve host address `tile.openstreetmap.org' ## ################################################################ set URLname "http://tile.openstreetmap.org/$z/$col/$row.png" ##################################################################### ## '-nv' is non-verbose --- not as quieting as '-q'. ##################################################################### set VARcommand "$WGETpgm -nv -O $OUTfile $URLname" catch {eval exec $VARcommand} ForegroundResult ##################################################################### ## 'string match {wget: unable to resolve host address*} str' ## returns 1 if the pattern 'wget: unable to resolve host address*' ## is in the string str. ##################################################################### set MatchIndex [string match {wget: unable to resolve host address*} "$ForegroundResult"] ## FOR TESTING: if {0} { puts "" puts "From PROC 'fetch_and_show_tiles':" puts "ForegroundResult:" puts "$ForegroundResult" puts "MatchIndex: $MatchIndex" } if {$MatchIndex == 1} { set ERRtext \ "Proc 'fetch_and_show_tiles' seems to have encountered an error in trying to 'wget' URL-file $URLname Message: $ForegroundResult Stopping processing. MAKE SURE YOUR NETWORK CONNECTION IS 'UP'." popup_msgVarWithScroll .topErr "$ERRtext" $POPUPloc return } ############################################################### ## Pause about 500 millisecs to allow time for the PNG file ## to be ready for viewing. ############################################################### after $WAITmillisecs ############################################################### ## A 'background' run of the viewer --- with & --- per page 105 ## of the 4th edition of 'Practical Programming in Tcl & Tk. ## ## (We want to run the viewer in the background --- with & --- ## because we do want to go on to fetch the next PNG file ## from the OSM server with 'wget'.) ## ## We MAY need to use 'eval' to avoid a 'not found' error if ## we append some parms (or a space) to the command. ############################################################### set VARcommand "$IMGviewer $OUTfile" # set VARcommand "$IMGviewer $OUTfile 2&>1 /dev/null" set RETcode [ catch {eval exec $VARcommand &} BackgroundResult ] if {$RETcode != 0} { set ERRtext \ "Proc 'fetch_and_show_tiles' seems to have encountered an error in trying to view local image-file $OUTfile with image-viewer $IMGviewer. RETcode: $RETcode Message/ViewerPID: $BackgroundResult Stopping processing. Make sure the named image-viewer is available." popup_msgVarWithScroll .topErr "$ERRtext" $POPUPloc return } } ## END OF 'for z' loop } ## END OF PROC 'fetch_and_show_tiles' ##+################################################################### ## PROC: 'z_lat_lon_TO_col_row' ##+################################################################### ## PURPOSE: For a given zoom-level, latitude (in decimal degrees), ## and longitude (in decimal-degrees), ## return two integers for column(longitude),row(latitude) ## of an OSM tile for that zoom-level. ## ## REFERENCE: ## http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Zoom_levels ## ## CALLED BY: the 'fetch_and_show_tiles' proc ##+################################################################### proc z_lat_lon_TO_col_row {zoomlevel lat_deg lon_deg} { global pi radsPERdeg set lat_rad [expr {$radsPERdeg * $lat_deg}] set n [expr {pow(2,$zoomlevel)}] set col [expr {int( ($lon_deg + 180.0) / 360.0 * $n)}] set row [expr {int( (1.0 - log(tan($lat_rad) + (1 / cos($lat_rad))) / $pi) / 2.0 * $n)}] ## FOR TESTING: if {0} { puts "" puts "From PROC 'z_lat_lon_TO_col_row':" puts "INPUT : zoomlevel: $zoomlevel lat_deg: $lat_deg lon_deg: $lon_deg" puts "OUTPUT: col: $col row: $row" } return [list $col $row] } ## END OF PROC 'z_lat_lon_TO_col_row' ##+##################################################################### ## PROC 'advise_user' ##+##################################################################### ## PURPOSE: Puts a message to the user on the GUI. ## ## CALLED BY: in the additional-GUI-initialization section at ## the bottom of this script ## and in some procs. ##+##################################################################### proc advise_user {text} { .fRmsg.labelMSG configure -text "$text" ## Make sure the text is displayed on the GUI. update ## Alternatively, we could put the message in the title-bar ## of the GUI window. (But it is easy for the user to ## fail to see the message there. Besides, we have more ## options in displaying the message by putting it on a ## Tk widget in the GUI.) ## # wm title . "$text" } ## END OF PROC 'advise_user' ##+#################################################################### ## PROC: 'edit_inputs' ##+##################################################################### ## PURPOSE: Checks entry widgets entries and pops up an error message ## if the data is invalid. ## ## CALLED BY: the 'rePlot' proc ##+##################################################################### proc edit_inputs {} { ## Decimal/floating-point variables. global ENTRYlatitude ENTRYlongitude ## Integer variables. global ENTRYzoomlevels ## Error indicator --- and window-location for popup error windows. global EDITcode POPUPloc ## We could do without the EDITcode variable, by using ## a code with the 'return' statement herein. But using this ## code variable is a little more self-documenting. set EDITcode 0 ####################################################### ## Remove trailing and leading blanks (if any) from the ## user entries in the 'entry' widgets. ####################################################### set ENTRYlatitude [string trim $ENTRYlatitude] set ENTRYlongitude [string trim $ENTRYlongitude] set ENTRYzoomlevels [string trim $ENTRYzoomlevels] ######################################################################### ## Check that these entry fields are NOT blank. ######################################################################### set MSGblank "is blank. Must NOT be blank." if {"$ENTRYlatitude" == ""} { popup_msgVarWithScroll .topErr "The LATITUDE entry field $MSGblank" $POPUPloc set EDITcode 1 return } if {"$ENTRYlongitude" == ""} { popup_msgVarWithScroll .topErr "The LONGITUDE entry field $MSGblank" $POPUPloc set EDITcode 1 return } if {"$ENTRYzoomlevels" == ""} { popup_msgVarWithScroll .topErr "The ZOOM-LEVELS entry field $MSGblank" $POPUPloc set EDITcode 1 return } ############################################################# ## Check that ENTRYzoomlevels contains only positive integers ## and spaces. ############################################################# set MSGnotIntegersSpaces " is NOT a POSITIVE INTEGER or a SPACE." set STRlen [string length "$ENTRYzoomlevels"] for {set idx 0} {$idx < $STRlen} {incr idx} { set char [string index "$ENTRYzoomlevels" $idx] set MATCHcode [ string match {[0-9 ]} $char ] ## FOR TESTING: if {0} { puts "" puts "PROC 'edit_inputs' :" puts " ENTRYzoomlevels: $ENTRYzoomlevels" puts " STRlen: $STRlen" puts " char: $char" puts " MATCHcode: $MATCHcode" } if {$MATCHcode == 0} { popup_msgVarWithScroll .topErr \ "A character in the ZOOM-LEVELS entry field $MSGnotIntegersSpaces" $POPUPloc set EDITcode 1 return } } ########################################################################## ## Check that each component of ENTRYzoomlevels is an integer less than 20. ########################################################################## set MSGnotSmallInteger " is NOT INTEGER less than 20." foreach z $ENTRYzoomlevels { if {$z > 19} { popup_msgVarWithScroll .topErr \ "The string '$z' of the ZOOM-LEVELS $MSGnotSmallInteger" $POPUPloc set EDITcode 1 return } } ######################################################################### ## Check that ENTRYlatitude and ENTRYlongitude ## are decimal numbers (positive or negative) ## --- such as 1.234 or -3 or -3.0 or -.4 or .5 or 7 ######################################################################### ## Implemented using the 'decimal_check' proc below. ######################################################################### set NUMERICmsg "should be a decimal number. Examples: 1.234 or 0.56 or -.789" if {![decimal_check "$ENTRYlatitude"]} { popup_msgVarWithScroll .topErr "The LATITUDE parameter $NUMERICmsg" $POPUPloc set EDITcode 1 return } if {![decimal_check "$ENTRYlongitude"]} { popup_msgVarWithScroll .topErr "The LONGITUDE parameter $NUMERICmsg" $POPUPloc set EDITcode 1 return } ####################################################################### ## Check that ENTRYnonnegnumber is not negative. ## COMMENTED, for no. ####################################################################### if {0} { set POSITIVEmsg "should be a POSITIVE number. Examples: 0.001 or 0.56" if {$ENTRYwhatever < 0.0} { popup_msgVarWithScroll .topErr "The WHATEVER value $POSITIVEmsg" $POPUPloc set EDITcode 1 return } } } ## END OF PROC 'edit_inputs' ##+######################################################################## ## PROC: 'decimal_check' ##+######################################################################## ## PURPOSE: Returns 1 or 0 if the input string looks like a decimal number ## --- positive or negative. Example numbers that are OK: ## 1.234 12.34 0.234 .234 6 ## -1.234 -12.34 -0.234 -.234 -6 ##+######################################################################## ## References (lots of one-liners): ## http://stackoverflow.com/questions/2072222/regular-expression-for-positive-and-a-negative-decimal-value-in-java ## http://stackoverflow.com/questions/308122/simple-regular-expression-for-a-decimal-with-a-precision-of-2 ## http://stackoverflow.com/questions/4246077/matching-numbers-with-regular-expressions-only-digits-and-commas/4247184#4247184 ## ## More specific to Tcl-Tk (including multi-liners): ## http://wiki.tcl.tk/989 'Regular Expression Examples' ## http://wiki.tcl.tk/768 'Entry Validation' - See "Integer forbidding leading zero:" ## http://wiki.tcl.tk/10166 'string is' ## http://wiki.tcl.tk/40710 'significant digits rounding' - uses regexp to split a number - ## Splits using: if {[regexp {^([+,-]?)([0-9]+)(\.?[0-9]*)?([eE][+-]?[0-9]+)?$} $num -> s i d e]} ## Removes leading zero with: regexp {^(0*)([1-9][0-9]*)$} $i -> NULL DIG ## http://wiki.tcl.tk/530 'Unit converter' has a regexp to parse numbers: ## set RE {(?ix) # Ignore case, extended syntax ## ([-+]?) # Optional leading sign ## ([0-9]*) # Integer part ## \.? # Optional decimal point ## ([0-9]*) # Fractional part ## (e?[0-9]*) # Optional exponent ## } ## ##+######################################################################## ## I do not mind incurring a little (minute amount of) processing ## with a multiple-line implementation. Probably easier to fix if ## a string gets through --- such as ".0.3" (two decimal points). ## ## CALLED BY: proc 'edit_inputs' ##+######################################################################## proc decimal_check {string} { set PosDecimalOK [regexp {^([0-9]*)\.?([0-9]*)$} "$string"] set NegDecimalOK [regexp {^\-([0-9]*)\.?([0-9]*)$} "$string"] set PosNakedDecimalOK [regexp {^\.?([0-9]*)$} "$string"] set NegNakedDecimalOK [regexp {^\-\.?([0-9]*)$} "$string"] set IntegerOK [string is integer $string] set retCODE [expr { \ $PosDecimalOK || $NegDecimalOK || \ $PosNakedDecimalOK || $NegNakedDecimalOK || \ $IntegerOK }] ## FOR TESTING: if {0} { puts "" puts "decimal_check:" puts "string: $string" puts "PosDecimalOK: $PosDecimalOK" puts "NegDecimalOK: $NegDecimalOK" puts "PosNakedDecimalOK: $PosNakedDecimalOK" puts "NegNakedDecimalOK: $NegNakedDecimalOK" puts "IntegerOK: $IntegerOK" puts "retCODE: $retCODE" } return $retCODE } ## END OF PROC 'decimal_check' ##+######################################################################## ## PROC: 'popup_msgVarWithScroll' ##+######################################################################## ## PURPOSE: Report help or error conditions to the user. ## ## We do not use focus,grab,tkwait in this proc, ## because we use it to show help when the GUI is idle, ## and we may want the user to be able to keep the Help ## window open while doing some other things with the GUI ## such as putting a filename in the filename entry field ## or clicking on a radiobutton. ## ## For a similar proc with focus-grab-tkwait added, ## see the proc 'popup_msgVarWithScroll_wait' in a ## 3DterrainGeneratorExaminer Tk script. ## ## REFERENCE: page 602 of 'Practical Programming in Tcl and Tk', ## 4th edition, by Welch, Jones, Hobbs. ## ## ARGUMENTS: A toplevel frame name (such as .fRhelp or .fRerrmsg) ## and a variable holding text (many lines, if needed). ## ## CALLED BY: 'help' button ##+######################################################################## ## To have more control over the formatting of the message (esp. ## words per line), we use this 'toplevel-text' method, ## rather than the 'tk_dialog' method -- like on page 574 of the book ## by Hattie Schroeder & Mike Doyel,'Interactive Web Applications ## with Tcl/Tk', Appendix A "ED, the Tcl Code Editor". ##+######################################################################## proc popup_msgVarWithScroll { toplevName VARtext ULloc} { ## global fontTEMP_varwidth #; Not needed. 'wish' makes this global. ## global env # bell # bell ################################################# ## Set VARwidth & VARheight from $VARtext. ################################################# ## To get VARheight, ## split at '\n' (newlines) and count 'lines'. ################################################# set VARlist [ split $VARtext "\n" ] ## For testing: # puts "VARlist: $VARlist" set VARheight [ llength $VARlist ] ## For testing: # puts "VARheight: $VARheight" ################################################# ## To get VARwidth, ## loop through the 'lines' getting length ## of each; save max. ################################################# set VARwidth 0 ############################################# ## LOOK AT EACH LINE IN THE LIST. ############################################# foreach line $VARlist { ############################################# ## Get the length of the line. ############################################# set LINEwidth [ string length $line ] if { $LINEwidth > $VARwidth } { set VARwidth $LINEwidth } } ## END OF foreach line $VARlist ## For testing: # puts "VARwidth: $VARwidth" ############################################################### ## NOTE: VARwidth works for a fixed-width font used for the ## text widget ... BUT the programmer may need to be ## careful that the contents of VARtext are all ## countable characters by the 'string length' command. ############################################################### ##################################### ## SETUP 'TOP LEVEL' HELP WINDOW. ##################################### catch {destroy $toplevName} toplevel $toplevName # wm geometry $toplevName 600x400+100+50 # wm geometry $toplevName +100+50 wm geometry $toplevName $ULloc wm title $toplevName "Note" # wm title $toplevName "Note to $env(USER)" wm iconname $toplevName "Note" ##################################### ## In the frame '$toplevName' - ## DEFINE THE TEXT WIDGET and ## its two scrollbars --- and ## DEFINE an OK BUTTON widget. ##################################### if {$VARheight > 10} { text $toplevName.text \ -wrap none \ -font fontTEMP_fixedwidth \ -width $VARwidth \ -height $VARheight \ -bg "#f0f0f0" \ -relief raised \ -bd 2 \ -yscrollcommand "$toplevName.scrolly set" \ -xscrollcommand "$toplevName.scrollx set" ## -font fontTEMP_varwidth scrollbar $toplevName.scrolly \ -orient vertical \ -command "$toplevName.text yview" scrollbar $toplevName.scrollx \ -orient horizontal \ -command "$toplevName.text xview" } else { text $toplevName.text \ -wrap none \ -font fontTEMP_fixedwidth \ -width $VARwidth \ -height $VARheight \ -bg "#f0f0f0" \ -relief raised \ -bd 2 ## -font fontTEMP_varwidth } button $toplevName.butt \ -text "OK" \ -font fontTEMP_varwidth \ -command "destroy $toplevName" ############################################### ## PACK *ALL* the widgets in frame '$toplevName'. ############################################### ## Pack the bottom button BEFORE the ## bottom x-scrollbar widget, pack $toplevName.butt \ -side bottom \ -anchor center \ -fill none \ -expand 0 if {$VARheight > 10} { ## Pack the scrollbars BEFORE the text widget, ## so that the text does not monopolize the space. pack $toplevName.scrolly \ -side right \ -anchor center \ -fill y \ -expand 0 ## DO NOT USE '-expand 1' HERE on the Y-scrollbar. ## THAT ALLOWS Y-SCROLLBAR TO EXPAND AND PUTS ## BLANK SPACE BETWEEN Y-SCROLLBAR & THE TEXT AREA. pack $toplevName.scrollx \ -side bottom \ -anchor center \ -fill x \ -expand 0 ## DO NOT USE '-expand 1' HERE on the X-scrollbar. ## THAT KEEPS THE TEXT AREA FROM EXPANDING. pack $toplevName.text \ -side top \ -anchor center \ -fill both \ -expand 1 } else { pack $toplevName.text \ -side top \ -anchor center \ -fill both \ -expand 1 } ################################################ ## Set some 'event' bindings to allow for ## easy scrolling through huge listings. ## is a press of the Page-Down key. ## is a press of the Page-Up key. ## is a press of the Home key ## to go to the top of the listing. ## is a press of the End key ## to go to the bottom of the listing. ## is a press of the Up-arrow key. ## is a press of the Down-arrow key. ################################################ bind $toplevName "$toplevName.text yview scroll +1 page" bind $toplevName "$toplevName.text yview scroll -1 page" bind $toplevName "$toplevName.text see 1.0" bind $toplevName "$toplevName.text see end" bind $toplevName "$toplevName.text yview scroll -1 unit" bind $toplevName "$toplevName.text yview scroll +1 unit" ##################################### ## LOAD MSG INTO TEXT WIDGET. ##################################### ## $toplevName.text delete 1.0 end $toplevName.text insert end $VARtext $toplevName.text configure -state disabled } ## END OF PROC 'popup_msgVarWithScroll' ##+######################## ## END of PROC definitions. ##+######################## ## Set HELPtext var. ##+######################## set HELPtext \ " ** HELP for this Fetch-and-Show OSM Tiles utility ** ** for a given latitude and longitude (in decimal degrees) ** ** and for a given set of OSM 'zoom-levels' ** (OSM = Open Street Map) This Tk script provides a GUI for entering or selecting a latitude-longitude location (in decimal degrees) on the Earth. The user can click on a 'SomeLatLonSites' button to start up another Tk GUI that allows the user to get a latitude,longitude for a selected site (city, state, country, national park, other). The GUI also allows the user to specify several OSM zoom-levels --- where each 'zoom-level' indicator is an integer between 0 and 18. Reference: http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Zoom_levels When the user clicks the 'FetchAndShowTiles' button, this script executes a loop over the specified zoom-levels (z1,z2,z3,...). This script 1) converts the latitude-longitude (in decimal degrees) into a pair of integers col,row --- for each specified zoom-level, 'zi'. The triplet (zi,col,row) determines an OSM tile --- a URL that specifies a 256x256 PNG filename, example: http://tile.openstreetmap.org/zi/col/row.png 2) uses the 'wget' command to fetch a PNG file for each triplet --- (zi,col,row) --- into a local directory, such as /tmp 3) shows each fetched PNG file using an image viewer that the user can specify in a variable 'IMGviewer' set at the bottom of this script. Examples: set IMGviewer \"/usr/bin/eog\" or set IMGviewer \"/usr/bin/eom\" to specify the EyeOfGnome or EyeOfMATE image viewer on Linux. The user can close the several image viewer windows and then specify another Earth location and/or set of zoom levels and do another fetch-and-show. --- The intent of this utility is to allow the user to easily sample some OSM tiles (256x256 PNG files) at a specific Earth location for several zoom levels --- with the view in mind of using another Tk script utility to build a map (a PNG file made up of rows and columns of OSM tiles) using a single appropriate zoom-level to fetch the tiles to build the larger PNG file. The larger PNG file is a rectangular image made by a merge of N columns and M rows of OSM tiles. ************************* NOTES ON OTHER VIEWERS: ************************* Other 'simple', quick-starting image viewer programs that might be useful are 'ffplay', 'feh', 'gwenview', 'gpicview', ImageMagick 'display' or 'animate', and quite a few others. OR, use a light-weight (quick-starting) image editor program such as 'mtpaint'. (These programs are available on Linux.) " ##+###################################################### ## ADDITIONAL GUI INITIALIZATION section. ##+###################################################### ##+###################################################### ## Set angle parms for use in a lat-lon-TO-OSM-integers ## conversion script. ##+###################################################### set pi [expr {4.0 * atan(1.0)}] set radsPERdeg [expr {$pi/180.0}] ##+##################################################### ## Set full-name for a Tk GUI script that is to be used ## to return latitude,longitude (in decimal degrees) ## for a user-selected site (city, state, country, ## national park, whatever). ##+##################################################### ## FOR TESTING: # puts "argv0: $argv0" set DIRthisScript "[file dirname $argv0]" ## For ease of testing in a Linux/Unix terminal and located at the ## directory containing this Tk script: Set the full directory name ## instead of 'dot'. if {"$DIRthisScript" == "."} { set DIRthisScript "[pwd]" } ## Choose one of two locations for the LatLonSelector Tk script. if {1} { ## This is the location of the LatLonSelector in the directory structure ## of the FE 'tkGooies' system. set DIRupOne "[file dirname "$DIRthisScript"]" set DIRupTwo "[file dirname "$DIRupOne"]" set SELECTORlatlon "$DIRupTwo/SELECTORtools/tkSiteLatitudeLongitudeSelector/tkSiteLatitudeLongitudeSelector.tk" } else { ## Alternatively: Put the LatLon-selector Tk script in the ## same directory as this FetchOSMtiles Tk script and use the following. set SELECTORlatlon "$DIRthisScript/tkSiteLatitudeLongitudeSelector.tk" } ##+############################################ ## Set a (temp) directory for fetched PNG files. ##+############################################ set DIRtemp "/tmp" ##+##################################################### ## Set full-name for the executable of an image viewer. ##+##################################################### # set IMGviewer "/usr/bin/ffplay" # set IMGviewer "/usr/bin/eog" # set IMGviewer "/usr/bin/eom" # set IMGviewer "/usr/bin/display" # set IMGviewer "/usr/bin/animate" set IMGviewer "/usr/bin/mtpaint -v" # set IMGviewer "/usr/bin/evince" # set IMGviewer "/usr/bin/gimp" ;# This is overkill. Slow start. # set IMGviewer "/usr/bin/xpaint" ;# This is overkill. Too many windows/menus. ##+##################################################### ## Set full-name for the 'wget' executable. ##+##################################################### set WGETpgm "/usr/bin/wget" ##+####################################################### ## Set a wait-time to pause to allow for full retrieval ## of an image from an OpenStreetMap server before trying ## to display the image in an image viewer. ## ## For a faster image viewer, you may want to use a ## lower wait value. ##+####################################################### # set WAITmillisecs 500 set WAITmillisecs 800 ##+####################################################### ## Set a variable to hold the location of the popup ## window used for error messages. ## Used in proc 'edit_inputs'. ##+####################################################### set POPUPloc "+30+30" ##+##################################################### ## Initialize the entry fields --- for latitude, longitude. ##+##################################################### ## Lat-Lon for Canary Islands, Tenerife ## according to Wikipedia: 28.1, -15.4 # set ENTRYlatitude 28.1 # set ENTRYlongitude -15.6 set ENTRYlatitude "" set ENTRYlongitude "" ##+##################################################### ## Initialize the entry fields for zoom-levels. ## ## It is best to order from most-zoomed-in to ## least-zoomed-in --- because they will popup in ## the image viewer in that order and the last window ## may appear on top of the others. It is generally ## better to see the 'grander' view first, to see if ## your desired area is 'in the ball park' --- then ## check the more-zoomed-in-tiles to see if the ## desired area is still in them. ## ## If the desired area is not in the tile of a ## desired zoom level, then the user will probably ## want to adjust the latitude/longitude and try again. ##+##################################################### ## 7 views. Difference between zoom levels: 2 set ENTRYzoomlevels "16 14 12 10 8 6 4" ## 5 views. Difference between zoom levels: 3 # set ENTRYzoomlevels "16 13 10 7 4" ## 6 views. Difference between zoom levels: 3 # set ENTRYzoomlevels "18 15 12 9 6 3" ##+##################################################### ## Give the user some advice on how to start. ##+##################################################### advise_user \ "** Supply a latitude-longitude (you can use the 'SomeLatLonSites' button), ** then click 'FetchAndShowTiles' to show tiles for the specified zoom-levels. ** If some images are not displayed with the image viewer $IMGviewer, ** check for the files in directory $DIRtemp."