thematic.tcl 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828
  1. ##########################################################################
  2. # thematic.tcl - thematic vector mapping layer options file for GRASS GIS Manager
  3. # March 2006 Michael Barton, Arizona State University
  4. # COPYRIGHT: (C) 1999 - 2006 by the GRASS Development Team
  5. #
  6. # This program is free software under the GNU General Public
  7. # License (>=v2). Read the file COPYING that comes with GRASS
  8. # for details.
  9. #
  10. ##########################################################################
  11. namespace eval GmThematic {
  12. variable array opt # thematic current options
  13. variable array tlegend # mon id
  14. variable array tlegcan # mon id
  15. variable count 1
  16. variable array lfile # raster
  17. variable array lfilemask # raster
  18. variable optlist
  19. variable array dup # vector
  20. }
  21. ###############################################################################
  22. # create new thematic layer
  23. proc GmThematic::create { tree parent } {
  24. variable opt
  25. variable count
  26. variable dup
  27. variable lfile
  28. variable lfilemask
  29. variable optlist
  30. global iconpath
  31. set node "thematic:$count"
  32. set frm [ frame .thematicicon$count]
  33. set check [checkbutton $frm.check \
  34. -variable GmThematic::opt($count,1,_check) \
  35. -height 1 -padx 0 -width 0]
  36. image create photo thematicico -file "$iconpath/module-d.vect.thematic.gif"
  37. set ico [label $frm.ico -image thematicico -bd 1 -relief raised]
  38. bind $ico <ButtonPress-1> "GmTree::selectn $tree $node"
  39. pack $check $ico -side left
  40. #insert new layer
  41. if {[$tree selection get] != "" } {
  42. set sellayer [$tree index [$tree selection get]]
  43. } else {
  44. set sellayer "end"
  45. }
  46. $tree insert $sellayer $parent $node \
  47. -text "thematic $count"\
  48. -window $frm \
  49. -drawcross auto
  50. set opt($count,1,_check) 1
  51. set dup($count) 0
  52. set opt($count,1,map) ""
  53. set opt($count,1,opacity) 1.0
  54. set opt($count,1,type) "area"
  55. set opt($count,1,column) ""
  56. set opt($count,1,themetype) "graduated_colors"
  57. set opt($count,1,themecalc) "interval"
  58. set opt($count,1,breakpoints) ""
  59. set opt($count,1,where) ""
  60. set opt($count,1,layer) 1
  61. set opt($count,1,icon) "basic/circle"
  62. set opt($count,1,ptsize) 5
  63. set opt($count,1,maxsize) 20
  64. set opt($count,1,nint) 4
  65. set opt($count,1,colorscheme) "blue-red"
  66. set opt($count,1,pointcolor) \#FF0000
  67. set opt($count,1,linecolor) \#000000
  68. set opt($count,1,startcolor) \#FF0000
  69. set opt($count,1,endcolor) \#0000FF
  70. set opt($count,1,update_rgb) 0
  71. set opt($count,1,math) 0
  72. set opt($count,1,psmap) ""
  73. set opt($count,1,border) 1
  74. # keep font names here to make sure that all fonts used are in proper TclTk format
  75. set opt($count,1,titlefont) "{times} 14 bold"
  76. set opt($count,1,subtitlefont) "{times} 12 bold"
  77. set opt($count,1,labelfont) "{times} 12"
  78. set opt($count,1,tfontcolor) \#000000
  79. set opt($count,1,lfontcolor) \#000000
  80. set opt($count,1,mod) 1
  81. set optlist { _check map opacity type column themetype themecalc breakpoints where \
  82. layer icon ptsize maxsize nint colorscheme pointcolor linecolor\
  83. startcolor endcolor border update_rgb math psmap \
  84. titlefont tfontcolor subtitlefont labelfont lfontcolor}
  85. foreach key $optlist {
  86. set opt($count,0,$key) $opt($count,1,$key)
  87. }
  88. # create files in tmp diretory for layer output
  89. set mappid [pid]
  90. if {[catch {set lfile($count) [exec g.tempfile pid=$mappid]} error]} {
  91. GmLib::errmsg $error [G_msg "Error creating tempfile"]
  92. }
  93. set lfilemask($count) $lfile($count)
  94. append lfile($count) ".ppm"
  95. append lfilemask($count) ".pgm"
  96. incr count
  97. return $node
  98. }
  99. ###############################################################################
  100. proc GmThematic::set_option { node key value } {
  101. variable opt
  102. set id [GmTree::node_id $node]
  103. set opt($id,1,$key) $value
  104. }
  105. proc GmThematic::select_map { id } {
  106. variable tree
  107. variable node
  108. set m [GSelect vector title [G_msg "Vector map"] parent "."]
  109. if { $m != "" } {
  110. set GmThematic::opt($id,1,map) $m
  111. GmTree::autonamel [format [G_msg "thematic map for %s"] $m]
  112. }
  113. }
  114. ###############################################################################
  115. # select fonts for legend
  116. proc GmThematic::select_tfont { id frm} {
  117. variable opt
  118. set fon [SelectFont $frm.font -type dialog -sampletext [G_msg "This is font sample text."] -title [G_msg "Select font"]]
  119. if { $fon != "" } {set opt($id,1,titlefont) $fon}
  120. }
  121. proc GmThematic::select_stfont { id frm} {
  122. variable opt
  123. set fon [SelectFont $frm.font -type dialog -sampletext [G_msg "This is font sample text."] -title [G_msg "Select font"]]
  124. if { $fon != "" } {set opt($id,1,subtitlefont) $fon}
  125. }
  126. proc GmThematic::select_lfont { id frm} {
  127. variable opt
  128. set fon [SelectFont $frm.font -type dialog -sampletext [G_msg "This is font sample text."] -title [G_msg "Select font"]]
  129. if { $fon != "" } {set opt($id,1,labelfont) $fon}
  130. }
  131. ###############################################################################
  132. # show attribute columns and attribute values
  133. proc GmThematic::show_columns { id } {
  134. variable opt
  135. global bgcolor
  136. set mapname $opt($id,1,map)
  137. set layernum $opt($id,1,layer)
  138. set cmd "v.info -c map=$mapname layer=$layernum"
  139. run_panel $cmd
  140. }
  141. proc GmThematic::show_data { id } {
  142. variable opt
  143. global bgcolor
  144. set mapname $opt($id,1,map)
  145. set layer $opt($id,1,layer)
  146. if {![catch {open "|v.db.connect map=$mapname layer=$layer -g" r} vdb]} {
  147. set vectdb [read $vdb]
  148. if {[catch {close $vdb} error]} {
  149. GmLib::errmsg $error
  150. }
  151. set vdblist [split $vectdb " "]
  152. set tbl [lindex $vdblist 1]
  153. set db [lindex $vdblist 3]
  154. set drv [lindex $vdblist 4]
  155. set cmd "db.select table=$tbl database=$db driver=$drv"
  156. run_panel $cmd
  157. }
  158. }
  159. ###############################################################################
  160. # select symbols from directories
  161. proc GmThematic::select_symbol { id } {
  162. variable opt
  163. set i [GSelect symbol title [G_msg "Vector point symbol"] parent "."]
  164. if { $i != "" } {
  165. set GmThematic::opt($id,1,icon) $i
  166. }
  167. }
  168. ###############################################################################
  169. # set thematic options
  170. proc GmThematic::options { id frm } {
  171. variable opt
  172. global iconpath
  173. global bgcolor
  174. # Panel heading
  175. set row [ frame $frm.heading1 ]
  176. Label $row.a -text [G_msg "Display vector maps thematically by graduate colors (all types)"] \
  177. -fg MediumBlue
  178. pack $row.a -side left
  179. pack $row -side top -fill both -expand yes
  180. set row [ frame $frm.heading2 ]
  181. Label $row.a -text [G_msg " or by graduated sizes (points and lines)"] \
  182. -fg MediumBlue
  183. pack $row.a -side left
  184. pack $row -side top -fill both -expand yes
  185. #opacity
  186. set row [ frame $frm.opc]
  187. Label $row.a -text [G_msg "Opaque "]
  188. scale $row.b -from 1.0 -to 0.0 -showvalue 1 \
  189. -orient horizontal -length 300 -resolution 0.01 -fg "#656565"\
  190. -variable GmThematic::opt($id,1,opacity)
  191. Label $row.c -text [G_msg " Transparent"]
  192. pack $row.a $row.b $row.c -side left
  193. pack $row -side top -fill both -expand yes
  194. # vector name
  195. set row [ frame $frm.map ]
  196. Label $row.a -text [G_msg "Vector map:"]
  197. Button $row.b -image [image create photo -file "$iconpath/element-vector.gif"] \
  198. -highlightthickness 0 -takefocus 0 -relief raised -borderwidth 1 \
  199. -helptext [G_msg "vector for thematic mapping"] \
  200. -command "GmThematic::select_map $id"
  201. Entry $row.c -width 35 -text " $opt($id,1,map)" \
  202. -textvariable GmThematic::opt($id,1,map)
  203. Label $row.d -text " "
  204. Button $row.e -text [G_msg "Help"] \
  205. -image [image create photo -file "$iconpath/gui-help.gif"] \
  206. -command "spawn g.manual --q d.vect.thematic" \
  207. -background $bgcolor \
  208. -helptext [G_msg "Help"]
  209. pack $row.a $row.b $row.c $row.d $row.e -side left
  210. pack $row -side top -fill both -expand yes
  211. # vector type and layer
  212. set row [ frame $frm.vtype ]
  213. Label $row.a -text [G_msg " vector type"]
  214. ComboBox $row.b -padx 2 -width 10 -textvariable GmThematic::opt($id,1,type) \
  215. -values {"area" "point" "centroid" "line" "boundary"}
  216. Label $row.c -text [G_msg " attribute layer"]
  217. LabelEntry $row.d -textvariable GmThematic::opt($id,1,layer) -width 3
  218. pack $row.a $row.b $row.c $row.d -side left
  219. pack $row -side top -fill both -expand yes
  220. # vector column
  221. set row [ frame $frm.column ]
  222. Label $row.a -text [G_msg " NUMERIC attribute column to use for thematic map"]
  223. LabelEntry $row.b -textvariable GmThematic::opt($id,1,column) -width 15
  224. pack $row.a $row.b -side left
  225. pack $row -side top -fill both -expand yes
  226. #show columns and data
  227. set row [ frame $frm.columns ]
  228. Label $row.a -text [G_msg " show attribute columns"]
  229. Button $row.b -text [G_msg "columns"] \
  230. -image [image create photo -file "$iconpath/db-columns.gif"] \
  231. -command "GmThematic::show_columns $id" \
  232. -background $bgcolor \
  233. -helptext [G_msg "Show columns"]
  234. Label $row.c -text [G_msg " show data"]
  235. Button $row.d -text [G_msg "data"] \
  236. -image [image create photo -file "$iconpath/db-values.gif"] \
  237. -command "GmThematic::show_data $id" \
  238. -background $bgcolor \
  239. -helptext [G_msg "Show data"]
  240. pack $row.a $row.b $row.c $row.d -side left
  241. pack $row -side top -fill both -expand yes
  242. # Thematic type
  243. set row [ frame $frm.ttype ]
  244. Label $row.a -text [G_msg "Thematic map: type"]
  245. ComboBox $row.b -padx 2 -width 16 -textvariable GmThematic::opt($id,1,themetype) \
  246. -values {"graduated_colors" "graduated_points" "graduated_lines"}
  247. Label $row.c -text [G_msg " map by"]
  248. ComboBox $row.d -padx 2 -width 15 -textvariable GmThematic::opt($id,1,themecalc) \
  249. -values {"interval" "std_deviation" "quartiles" \
  250. "custom_breaks"}
  251. pack $row.a $row.b $row.c $row.d -side left
  252. pack $row -side top -fill both -expand yes
  253. # intervals
  254. set row [ frame $frm.int ]
  255. Label $row.a -text [G_msg " number of intervals to map (interval themes):"]
  256. SpinBox $row.b -range {1 99 1} -textvariable GmThematic::opt($id,1,nint) \
  257. -width 3
  258. pack $row.a $row.b -side left
  259. pack $row -side top -fill both -expand yes
  260. # breakpoints
  261. set row [ frame $frm.break ]
  262. Label $row.a -text [G_msg " custom breakpoints (val val ...) "]
  263. LabelEntry $row.b -textvariable GmThematic::opt($id,1,breakpoints) -width 32
  264. pack $row.a $row.b -side left
  265. pack $row -side top -fill both -expand yes
  266. # where
  267. set row [ frame $frm.where ]
  268. Label $row.a -text [G_msg " query with SQL where clause "]
  269. LabelEntry $row.b -textvariable GmThematic::opt($id,1,where) -width 32
  270. pack $row.a $row.b -side left
  271. pack $row -side top -fill both -expand yes
  272. # point options1
  273. set row [ frame $frm.pts1 ]
  274. Label $row.a -text [G_msg "Graduated points & lines: "]
  275. Button $row.b -text [G_msg "icon"] \
  276. -command "GmThematic::select_symbol $id"
  277. Entry $row.c -width 10 -text "$opt($id,1,icon)" \
  278. -textvariable GmThematic::opt($id,1,icon)
  279. Label $row.d -text [G_msg "point color"]
  280. SelectColor $row.e -type menubutton -variable GmThematic::opt($id,1,pointcolor)
  281. Label $row.f -text [G_msg "line color"]
  282. SelectColor $row.g -type menubutton -variable GmThematic::opt($id,1,linecolor)
  283. pack $row.a $row.b $row.c $row.d $row.e $row.f $row.g -side left
  284. pack $row -side top -fill both -expand yes
  285. # point options2
  286. set row [ frame $frm.pts2 ]
  287. Label $row.a -text [G_msg " size/min size (graduated pts/lines)"]
  288. SpinBox $row.b -range {1 50 1} -textvariable GmThematic::opt($id,1,ptsize) \
  289. -width 2 -helptext [G_msg "icon size/min size (graduated pts/lines)"]
  290. Label $row.c -text [G_msg "max size (graduated pts)"]
  291. SpinBox $row.d -range {1 50 1} -textvariable GmThematic::opt($id,1,maxsize) \
  292. -width 2 -helptext [G_msg " max size (graduated pts/lines)"]
  293. pack $row.a $row.b $row.c $row.d -side left
  294. pack $row -side top -fill both -expand yes
  295. # color options1
  296. set row [ frame $frm.color1 ]
  297. Label $row.a -text [G_msg "Graduated colors: preset color schemes"]
  298. ComboBox $row.b -padx 2 -width 18 -textvariable GmThematic::opt($id,1,colorscheme) \
  299. -values {"blue-red" "red-blue" "green-red" "red-green" \
  300. "blue-green" "green-blue" "cyan-yellow" "yellow-cyan" "custom_gradient" \
  301. "single_color" }
  302. pack $row.a $row.b -side left
  303. pack $row -side top -fill both -expand yes
  304. # color options2
  305. set row [ frame $frm.color2 ]
  306. Label $row.a -text [G_msg " custom color scheme - start color"]
  307. SelectColor $row.b -type menubutton -variable GmThematic::opt($id,1,startcolor)
  308. Label $row.c -text [G_msg " end color"]
  309. SelectColor $row.d -type menubutton -variable GmThematic::opt($id,1,endcolor)
  310. checkbutton $row.e -text [G_msg "draw border"] -variable GmThematic::opt($id,1,border)
  311. pack $row.a $row.b $row.c $row.d $row.e -side left
  312. pack $row -side top -fill both -expand yes
  313. # color options3
  314. set row [ frame $frm.color3 ]
  315. Label $row.a -text " "
  316. checkbutton $row.b -text [G_msg "save thematic colors to GRASSRGB column of vector file"] -variable \
  317. GmThematic::opt($id,1,update_rgb)
  318. pack $row.a $row.b -side left
  319. pack $row -side top -fill both -expand yes
  320. # legend 1
  321. set row [ frame $frm.legend1 ]
  322. Label $row.a -text [G_msg "Legend: title font "]
  323. Button $row.b -image [image create photo -file "$iconpath/gui-font.gif"] \
  324. -highlightthickness 0 -takefocus 0 -relief raised -borderwidth 1 \
  325. -helptext [G_msg "title font for legend"] \
  326. -command "GmThematic::select_tfont $id $frm"
  327. Entry $row.c -width 15 -text "$opt($id,1,titlefont)" \
  328. -textvariable GmThematic::opt($id,1,titlefont)
  329. Label $row.d -text [G_msg " font color"]
  330. SelectColor $row.e -type menubutton -variable GmThematic::opt($id,1,tfontcolor)
  331. pack $row.a $row.b $row.c $row.d $row.e -side left
  332. pack $row -side top -fill both -expand yes
  333. # legend 2
  334. set row [ frame $frm.legend2 ]
  335. Label $row.a -text [G_msg " subtitle font "]
  336. Button $row.b -image [image create photo -file "$iconpath/gui-font.gif"] \
  337. -highlightthickness 0 -takefocus 0 -relief raised -borderwidth 1 \
  338. -helptext [G_msg "subtitle font for legend"] \
  339. -command "GmThematic::select_stfont $id $frm"
  340. Entry $row.c -width 15 -text "$opt($id,1,subtitlefont)" \
  341. -textvariable GmThematic::opt($id,1,subtitlefont)
  342. pack $row.a $row.b $row.c -side left
  343. pack $row -side top -fill both -expand yes
  344. # legend 3
  345. set row [ frame $frm.legend3 ]
  346. Label $row.a -text [G_msg " label font "]
  347. Button $row.b -image [image create photo -file "$iconpath/gui-font.gif"] \
  348. -highlightthickness 0 -takefocus 0 -relief raised -borderwidth 1 \
  349. -helptext [G_msg "label font for legend"] \
  350. -command "GmThematic::select_lfont $id $frm"
  351. Entry $row.c -width 15 -text "$opt($id,1,labelfont)" \
  352. -textvariable GmThematic::opt($id,1,labelfont)
  353. Label $row.d -text [G_msg " font color"]
  354. SelectColor $row.e -type menubutton -variable GmThematic::opt($id,1,lfontcolor)
  355. pack $row.a $row.b $row.c $row.d $row.e -side left
  356. pack $row -side top -fill both -expand yes
  357. # legend 4
  358. set row [ frame $frm.legend4 ]
  359. Label $row.a -text " "
  360. checkbutton $row.b -text [G_msg "use math notation in legend"] -variable \
  361. GmThematic::opt($id,1,math)
  362. pack $row.a $row.b -side left
  363. pack $row -side top -fill both -expand yes
  364. # psmap
  365. set row [ frame $frm.psmap ]
  366. Label $row.a -text [G_msg "Name for ps.map instruction files"]
  367. LabelEntry $row.b -textvariable GmThematic::opt($id,1,psmap) -width 34
  368. pack $row.a $row.b -side left
  369. pack $row -side top -fill both -expand yes
  370. }
  371. ###############################################################################
  372. # save to grc file
  373. proc GmThematic::save { tree depth node } {
  374. variable opt
  375. variable optlist
  376. set id [GmTree::node_id $node]
  377. foreach key $optlist {
  378. GmTree::rc_write $depth "$key $opt($id,1,$key)"
  379. }
  380. }
  381. ###############################################################################
  382. # get selected vector map
  383. proc GmThematic::mapname { node } {
  384. variable opt
  385. variable tree
  386. global mon
  387. set tree($mon) $GmTree::tree($mon)
  388. set id [GmTree::node_id $node]
  389. if { $opt($id,1,map) == "" } { return ""}
  390. set mapname $opt($id,1,map)
  391. return $mapname
  392. }
  393. ###############################################################################
  394. # render and composite thematic layer
  395. proc GmThematic::display { node mod } {
  396. global mon
  397. variable optlist
  398. variable lfile
  399. variable lfilemask
  400. variable opt
  401. variable tree
  402. variable dup
  403. variable count
  404. set line ""
  405. set input ""
  406. set cmd ""
  407. set tree($mon) $GmTree::tree($mon)
  408. set id [GmTree::node_id $node]
  409. # If we are told dirty (for zoom) force dirty
  410. # Don't remove a dirty from a previous unrendered zoom
  411. if {$mod} {set opt($id,1,mod) 1}
  412. if { $opt($id,1,map) == "" } { return }
  413. if { $opt($id,1,column) == "" } { return }
  414. # set hex colors to rgb
  415. set pointcolor [GmLib::color $opt($id,1,pointcolor)]
  416. set linecolor [GmLib::color $opt($id,1,linecolor)]
  417. set startcolor [GmLib::color $opt($id,1,startcolor)]
  418. set endcolor [GmLib::color $opt($id,1,endcolor)]
  419. # turn off x11 display
  420. set monitor "none"
  421. #create d.vect.thematic command
  422. set cmd "d.vect.thematic -s map=$opt($id,1,map) type=$opt($id,1,type) column=$opt($id,1,column) \
  423. layer=$opt($id,1,layer) icon=$opt($id,1,icon) size=$opt($id,1,ptsize) \
  424. maxsize=$opt($id,1,maxsize) nint=$opt($id,1,nint) pointcolor=$pointcolor \
  425. linecolor=$linecolor startcolor=$startcolor endcolor=$endcolor \
  426. themetype=$opt($id,1,themetype) monitor=$monitor \
  427. themecalc=$opt($id,1,themecalc) colorscheme=$opt($id,1,colorscheme)"
  428. # breakpoints
  429. if { $opt($id,1,breakpoints) != "" } {
  430. append cmd " {breakpoints=$opt($id,1,breakpoints)}"
  431. }
  432. # where query
  433. if { $opt($id,1,where) != "" } {
  434. append cmd " {where=$opt($id,1,where)}"
  435. }
  436. # psmap file
  437. if { $opt($id,1,psmap) != "" } {
  438. append cmd " psmap=$opt($id,1,psmap)"
  439. }
  440. # hide border
  441. if { $opt($id,1,border) == 0 } {
  442. append cmd " -f"
  443. }
  444. # update_rgb
  445. if { $opt($id,1,update_rgb) == 1 } {
  446. append cmd " -u"
  447. }
  448. # math notation
  449. if { $opt($id,1,math) == 1 } {
  450. append cmd " -m"
  451. }
  452. # Decide whether to run, run command, and copy files to temp
  453. GmCommonLayer::display_command [namespace current] $id $cmd
  454. # Legend
  455. if { $opt($id,1,_check) } {
  456. GmThematic::tlegend $mon $id
  457. GmThematic::tleg_item $mon $id
  458. }
  459. }
  460. ###############################################################################
  461. # duplicate thematic layer
  462. proc GmThematic::duplicate { tree parent node id } {
  463. variable optlist
  464. variable lfile
  465. variable lfilemask
  466. variable opt
  467. variable count
  468. variable dup
  469. global iconpath
  470. set node "thematic:$count"
  471. set dup($count) 1
  472. set frm [ frame .thematicicon$count]
  473. set check [checkbutton $frm.check \
  474. -variable GmThematic::opt($count,1,_check) \
  475. -height 1 -padx 0 -width 0]
  476. image create photo thematicico -file "$iconpath/module-d.vect.thematic.gif"
  477. set ico [label $frm.ico -image thematicico -bd 1 -relief raised]
  478. bind $ico <ButtonPress-1> "GmTree::selectn $tree $node"
  479. pack $check $ico -side left
  480. #insert new layer
  481. if {[$tree selection get] != "" } {
  482. set sellayer [$tree index [$tree selection get]]
  483. } else {
  484. set sellayer "end"
  485. }
  486. if { $opt($id,1,map) == ""} {
  487. $tree insert $sellayer $parent $node \
  488. -text "thematic $count" \
  489. -window $frm \
  490. -drawcross auto
  491. } else {
  492. $tree insert $sellayer $parent $node \
  493. -text "thematic map for $opt($id,1,map)" \
  494. -window $frm \
  495. -drawcross auto
  496. }
  497. set opt($count,1,opacity) $opt($id,1,opacity)
  498. set optlist { _check map type column themetype themecalc breakpoints where \
  499. layer icon ptsize maxsize nint colorscheme pointcolor linecolor\
  500. startcolor endcolor border update_rgb math psmap \
  501. titlefont tfontcolor subtitlefont labelfont lfontcolor}
  502. foreach key $optlist {
  503. set opt($count,1,$key) $opt($id,1,$key)
  504. set opt($count,0,$key) $opt($count,1,$key)
  505. }
  506. set id $count
  507. # create files in tmp directory for layer output
  508. set mappid [pid]
  509. if {[catch {set lfile($count) [exec g.tempfile pid=$mappid]} error]} {
  510. GmLib::errmsg $error [G_msg "Error creating tempfile"]
  511. }
  512. set lfilemask($count) $lfile($count)
  513. append lfile($count) ".ppm"
  514. append lfilemask($count) ".pgm"
  515. incr count
  516. return $node
  517. }
  518. ###############################################################################
  519. # create graphic legend in separate display canvas
  520. proc GmThematic::tlegend { mon id } {
  521. global bgcolor
  522. global iconpath
  523. global env
  524. variable opt
  525. variable tlegend
  526. variable tlegcan
  527. if { [winfo exists .tlegend($mon,$id)] } {return}
  528. set legendtitle [format [G_msg "Legend for Map %d, %s"] $mon $opt($id,1,map)]
  529. toplevel .tlegend($mon,$id)
  530. wm title .tlegend($mon,$id) $legendtitle
  531. wm withdraw .tlegend($mon,$id)
  532. #wm overrideredirect $txt 1
  533. # create canvas for legend
  534. set tlegmf [MainFrame .tlegend($mon,$id).mf ]
  535. set tlegcan($mon,$id) [canvas $tlegmf.can -bg white\
  536. -borderwidth 0 -closeenough 1.0 \
  537. -relief ridge -selectbackground #c4c4c4 \
  538. -width 300 -height 300 ]
  539. # setting geometry
  540. place $tlegcan($mon,$id) \
  541. -in $tlegmf -x 0 -y 0 -anchor nw \
  542. -bordermode ignore
  543. # control buttons
  544. set tleg_tb [$tlegmf addtoolbar]
  545. set tlbb [ButtonBox $tleg_tb.bb -orient horizontal]
  546. $tlbb add -text [G_msg "clear"] -command "GmThematic::tleg_erase $mon $id" -bg #dddddd \
  547. -highlightthickness 0 -takefocus 0 -relief raised -borderwidth 1 \
  548. -helptext [G_msg "Clear legend"] -highlightbackground $bgcolor
  549. $tlbb add -text [G_msg "save"] -command "GmThematic::tleg_save $mon $id" -bg #dddddd \
  550. -highlightthickness 0 -takefocus 0 -relief raised -borderwidth 1 \
  551. -helptext [G_msg "Save legend to EPS file"] -highlightbackground $bgcolor
  552. pack $tlegmf -expand yes -fill both -padx 0 -pady 0
  553. pack $tlegcan($mon,$id) -fill both -expand yes
  554. pack $tlbb -side left -anchor w
  555. BWidget::place .tlegend($mon,$id) 0 0 at 500 100
  556. wm deiconify .tlegend($mon,$id)
  557. }
  558. # read legend file and create legend items
  559. proc GmThematic::tleg_item { mon id } {
  560. variable tlegend
  561. variable tlegcan
  562. variable opt
  563. global legfile
  564. GmThematic::tleg_erase $mon $id
  565. # get legend file created by d.vect.thematic in GRASS tmp diretory
  566. set mappid [pid]
  567. if {[catch {set tmpdir [file dirname [exec g.tempfile pid=$mappid]]} error]} {
  568. GmLib::errmsg $error [G_msg "Error creating tempfile"]
  569. }
  570. set legfile "$tmpdir/gismlegend.txt"
  571. if {![file exists $legfile]} {return}
  572. catch {set ltxt [open $legfile r]}
  573. set x1 30
  574. set y1 40
  575. set txtx 60
  576. set font $opt($id,1,labelfont)
  577. regexp {.*\s(\d*)} $font string lineht
  578. set yinc [expr {$lineht * 2}]
  579. set titlefont $opt($id,1,titlefont)
  580. set tfontcolor $opt($id,1,tfontcolor)
  581. set subtitlefont $opt($id,1,subtitlefont)
  582. set labelfont $opt($id,1,labelfont)
  583. set lfontcolor $opt($id,1,lfontcolor)
  584. while {![eof $ltxt]} {
  585. gets $ltxt line
  586. set type [lindex $line 0]
  587. set fcolor [lindex $line 1]
  588. set lcolor [lindex $line 2]
  589. set size [lindex $line 3]
  590. set label [lindex $line 4]
  591. if { $fcolor != "-" } { set xfcolor [GmThematic::rgb2hex $fcolor] }
  592. if { $lcolor != "-" } { set xlcolor [GmThematic::rgb2hex $lcolor] }
  593. switch $type {
  594. title {
  595. regexp {.*\s(\d*)\s.*} $titlefont string lineht
  596. set yinc [expr {$lineht * 2}]
  597. set x2 [expr {$x1 + 15}]
  598. set y2 [expr {$y1 + 15}]
  599. $tlegcan($mon,$id) create text $x1 $y2 -anchor sw -width 250 \
  600. -fill $tfontcolor -font $titlefont -text "$label"
  601. }
  602. subtitle {
  603. regexp {.*\s(\d*)\s.*} $subtitlefont string lineht
  604. set yinc [expr {$lineht * 2}]
  605. set x2 [expr {$x1 + 15}]
  606. set y2 [expr {$y1 + 15}]
  607. $tlegcan($mon,$id) create text $x1 $y2 -anchor sw -width 250 \
  608. -fill $tfontcolor -font $subtitlefont -text "$label"
  609. incr y2 10
  610. $tlegcan($mon,$id) create line $x1 $y2 [expr {$x1 + 250}] $y2 \
  611. -width 1 -fill #000000
  612. incr y1 10
  613. }
  614. text {
  615. regexp {.*\s(\d*)\s.*} $labelfont string lineht
  616. set yinc [expr {$lineht * 2}]
  617. set x2 [expr {$x1 + 15}]
  618. set y2 [expr {$y1 + 15}]
  619. $tlegcan($mon,$id) create text $x1 $y2 -anchor sw -width 250 \
  620. -fill $lfontcolor -font $labelfont -text "$label"
  621. }
  622. area {
  623. regexp {.*\s(\d*)\s.*} $labelfont string lineht
  624. set yinc [expr {$lineht * 2}]
  625. set x2 [expr {$x1 + 15}]
  626. set y2 [expr {$y1 + 15}]
  627. $tlegcan($mon,$id) create rectangle $x1 $y1 $x2 $y2 -fill $xfcolor \
  628. -outline $xlcolor
  629. $tlegcan($mon,$id) create text [expr {$x2 + 15}] [expr {(($y2-$y1)/2) + $y1}] \
  630. -fill $lfontcolor -anchor w -font $labelfont -text "$label"
  631. }
  632. point {
  633. regexp {.*\s(\d*)\s.*} $labelfont string lineht
  634. set yinc [expr {$lineht * 2}]
  635. if { $size > [expr {$yinc + 2}] } {
  636. incr y1 [expr {int(($size/5) + 2)}]
  637. }
  638. if { $txtx <= [expr {$x1 + $size + 15}] } {
  639. set txtx [expr {$x1 + $size + 15}]
  640. }
  641. set x2 [expr {$x1 + $size}]
  642. set y2 [expr {$y1 + $size}]
  643. $tlegcan($mon,$id) create oval $x1 $y1 $x2 $y2 -fill $xfcolor \
  644. -outline $xlcolor
  645. $tlegcan($mon,$id) create text $txtx [expr (($y2-$y1)/2) + $y1] \
  646. -fill $lfontcolor -anchor w -font $labelfont -text "$label"
  647. }
  648. line {
  649. regexp {.*\s(\d*)\s.*} $labelfont string lineht
  650. set yinc [expr {$lineht * 2}]
  651. set x2 [expr {$x1 + 15}]
  652. set y2 [expr {$y1 + 15}]
  653. $tlegcan($mon,$id) create line $x1 $y1 $x2 $y2 -width $size \
  654. -fill $xlcolor
  655. $tlegcan($mon,$id) create text [expr $x2 + 15] [expr (($y2-$y1)/2) + $y1] \
  656. -fill $lfontcolor -anchor w -font $labelfont -text "$label"
  657. }
  658. default { break }
  659. }
  660. if { $size > $yinc } {
  661. incr y1 [expr {int($size + 2)}]
  662. } else {
  663. incr y1 $yinc
  664. }
  665. }
  666. if {[catch {close $ltxt} error]} {
  667. GmLib::errmsg $error
  668. }
  669. return
  670. }
  671. # rgb to hex color convertor
  672. proc GmThematic::rgb2hex { clr } {
  673. set rgb [split $clr :]
  674. set r [lindex $rgb 0]
  675. set g [lindex $rgb 1]
  676. set b [lindex $rgb 2]
  677. if {$r == "" || $g == "" || $b == ""} {return}
  678. set xclr [format "#%02x%02x%02x" $r $g $b]
  679. return $xclr
  680. }
  681. # erase legend canvas
  682. proc GmThematic::tleg_erase { mon id} {
  683. variable tlegcan
  684. $tlegcan($mon,$id) delete all
  685. return
  686. }
  687. #save legend canvas (might use maptool procedures)
  688. proc GmThematic::tleg_save { mon id} {
  689. global env
  690. variable tlegcan
  691. set types {
  692. {{EPS} {.eps}}
  693. }
  694. if { [info exists HOME] } {
  695. set dir $env(HOME)
  696. set path [tk_getSaveFile -filetypes $types -initialdir $dir \
  697. -defaultextension ".eps"]
  698. } else {
  699. set path [tk_getSaveFile -filetypes $types -defaultextension ".eps"]
  700. }
  701. $tlegcan($mon,$id) postscript -file "$path"
  702. return
  703. }