profile.tcl 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  1. ##########################################################################
  2. # profile.tcl - Dialog to create profile of raster surface for GRASS GIS Manager
  3. # May 2006 Michael Barton, Arizona State University
  4. # COPYRIGHT: (C) 1999 - 2007 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 GmProfile {
  12. variable pcan
  13. variable status ""
  14. variable pmap ""
  15. variable pmainframe
  16. variable transect ""
  17. variable tottransect ""
  18. variable pcoords ""
  19. variable pcoordslist ""
  20. variable profilelist ""
  21. variable x
  22. variable y
  23. variable first 1
  24. variable firsteast 0.0
  25. variable firstnorth 0.0
  26. variable east1 0.0
  27. variable north1 0.0
  28. variable east2 0.0
  29. variable north2 0.0
  30. variable tlength 0.0
  31. variable tottlength 0.0
  32. variable linex1 0.0
  33. variable liney1 0.0
  34. variable linex2 0.0
  35. variable liney2 0.0
  36. variable array psegment len #
  37. variable elevrange 0.0
  38. variable elevmax 0.0
  39. variable elevmin 0.0
  40. variable elev 0.0
  41. variable msg
  42. }
  43. ###############################################################################
  44. # select raster map to profile
  45. # select base raster map from list and put name in layer tree node
  46. proc GmProfile::select_rast { } {
  47. variable pmap
  48. variable status
  49. set m [GSelect cell title "Raster map for profile" parent [winfo containing [winfo pointerx .] [winfo pointery .]]]
  50. if { $m != "" } {
  51. set pmap $m
  52. }
  53. set GmProfile::status [G_msg "Profile for $pmap"]
  54. }
  55. ###############################################################################
  56. # create canvas for displaying profile
  57. proc GmProfile::create { mapcan } {
  58. global gmpath
  59. global iconpath
  60. global env
  61. global bgcolor
  62. global mon
  63. variable pmap
  64. variable pcan
  65. if { [winfo exists .profile] } {return}
  66. set ptitle "Profile Window"
  67. toplevel .profile
  68. wm title .profile [G_msg $ptitle]
  69. wm withdraw .profile
  70. #wm overrideredirect $txt 1
  71. # create canvas for profile
  72. set profilemf [MainFrame .profile.mf \
  73. -textvariable GmProfile::status]
  74. set profile_frame [$profilemf getframe]
  75. set pcan [canvas $profile_frame.can -bg white\
  76. -borderwidth 0 -closeenough 1.0 \
  77. -relief ridge -selectbackground #c4c4c4 \
  78. -width 600 -height 300 ]
  79. # setting geometry
  80. place $pcan \
  81. -in $profile_frame -x 0 -y 0 -anchor nw \
  82. -bordermode ignore
  83. # profile control buttons
  84. set pcan_tb [$profilemf addtoolbar]
  85. pack $pcan_tb -side left -expand yes -fill x
  86. set pcanbb [ButtonBox $pcan_tb.bb -orient horizontal]
  87. $pcanbb add -image [image create photo -file "$iconpath/element-cell.gif"] \
  88. -command "GmProfile::select_rast" \
  89. -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 \
  90. -highlightbackground $bgcolor -activebackground $bgcolor\
  91. -helptext [G_msg "Select raster map to profile.\nCurrently selected raster is default."] -highlightbackground $bgcolor
  92. $pcanbb add -image [image create photo -file "$iconpath/gui-profiledefine.gif"] \
  93. -command "GmProfile::profilebind $mapcan" \
  94. -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 \
  95. -highlightbackground $bgcolor -activebackground $bgcolor\
  96. -helptext [G_msg "Draw profile transect in map display"] -highlightbackground $bgcolor
  97. $pcanbb add -image [image create photo -file "$iconpath/gui-profiledraw.gif"] \
  98. -command "GmProfile::pdraw" \
  99. -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 \
  100. -highlightbackground $bgcolor -activebackground $bgcolor\
  101. -helptext [G_msg "Draw profile"] -highlightbackground $bgcolor
  102. $pcanbb add -image [image create photo -file "$iconpath/gui-erase.gif"] \
  103. -command "GmProfile::perase $mapcan" \
  104. -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 \
  105. -highlightbackground $bgcolor -activebackground $bgcolor\
  106. -helptext [G_msg "Clear profile"] -highlightbackground $bgcolor
  107. $pcanbb add -image [image create photo -file "$iconpath/file-save.gif"] \
  108. -command "GmProfile::psave" \
  109. -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1 \
  110. -highlightbackground $bgcolor -activebackground $bgcolor\
  111. -helptext [G_msg "Save profile to EPS file"] -highlightbackground $bgcolor
  112. set helpbtn [Button $pcan_tb.help -text [G_msg "Help"] \
  113. -image [image create photo -file "$iconpath/gui-help.gif"] \
  114. -command "spawn g.manual --q gm_profile" \
  115. -background $bgcolor -borderwidth 1 \
  116. -helptext [G_msg "Help"]]
  117. # add a menu button to set preferences?
  118. pack $profilemf -expand yes -fill both -padx 0 -pady 0
  119. pack $pcan -fill both -expand yes
  120. pack $helpbtn -side right -anchor e
  121. pack $pcanbb -side left -anchor w
  122. set GmProfile::status [G_msg "Profile for $pmap"]
  123. $profilemf showstatusbar status
  124. pack $profilemf -fill both -expand yes
  125. BWidget::place .profile 0 0 at 500 100
  126. wm deiconify .profile
  127. # bindings for closing profile window
  128. bind .profile <Destroy> "GmProfile::cleanup %W $mapcan"
  129. }
  130. ###############################################################################
  131. proc GmProfile::setelev { pmap } {
  132. variable elevrange
  133. variable elevmax
  134. variable elevmin
  135. global devnull
  136. #calculate elevation range so all profiles with same window geometry with have
  137. # same scale. Elevation range calcuated within currently displayed region.
  138. #set input [exec r.describe -rdq map=$pmap]
  139. #regexp -nocase {^([0-9]+) thru ([0-9]+)} $input trash elevmin elevmax
  140. #set elevrange [expr $elevmax - $elevmin]
  141. if {![catch {open "|r.univar --q -g map=$pmap 2> $devnull" r} input]} {
  142. while {[gets $input line] >= 0} {
  143. regexp -nocase {^([a-z]+)=(.*)$} $line trash key value
  144. set elev($key) $value
  145. }
  146. if {[catch {close $input} error]} {
  147. GmLib::errmsg $error [G_msg "r.univar error"]
  148. }
  149. set elevmax $elev(max)
  150. set elevmin $elev(min)
  151. set elevrange $elev(range)
  152. }
  153. #vwait elevrange
  154. #set GmProfile::status [G_msg "Profile for $pmap"]
  155. }
  156. ###############################################################################
  157. # save profile to eps file
  158. proc GmProfile::psave { } {
  159. variable pcan
  160. global env
  161. set types {
  162. {{EPS} {.eps}}
  163. }
  164. if { [info exists HOME] } {
  165. set dir $env(HOME)
  166. set path [tk_getSaveFile -filetypes $types -initialdir $dir \
  167. -defaultextension ".eps" -parent .profile]
  168. } else {
  169. set path [tk_getSaveFile -filetypes $types -defaultextension ".eps" -parent .profile]
  170. }
  171. $pcan postscript -file "$path"
  172. return
  173. }
  174. ###############################################################################
  175. # procedures for marking profile location
  176. # bindings for drawing profile transect
  177. proc GmProfile::profilebind { mapcan } {
  178. variable measurement_annotation_handle
  179. variable tlength
  180. variable tottlength
  181. variable linex1
  182. variable liney1
  183. variable linex2
  184. variable liney2
  185. variable first
  186. variable msg
  187. global mon
  188. # Make the output for the measurement
  189. set measurement_annotation_handle [monitor_annotation_start $mon "Measurement" {}]
  190. if {[info exists linex1]} {unset linex1}
  191. if {[info exists liney1]} {unset liney1}
  192. if {[info exists linex2]} {unset linex2}
  193. if {[info exists liney2]} {unset liney2}
  194. bind $mapcan <1> "GmProfile::marktransect $mapcan %x %y"
  195. bind $mapcan <B1-Motion> "GmProfile::drawtransect $mapcan %x %y"
  196. bind $mapcan <ButtonRelease-1> "GmProfile::getcoords $mapcan"
  197. set GmProfile::msg "Draw profile transect with mouse"
  198. MapCanvas::setcursor $mon "pencil"
  199. set tlength 0
  200. set tottlength 0
  201. }
  202. # start profile transect
  203. proc GmProfile::marktransect {mapcan x y} {
  204. variable transect
  205. variable tlength
  206. variable tottlength
  207. variable linex1
  208. variable liney1
  209. variable linex2
  210. variable liney2
  211. variable first
  212. variable firsteast
  213. variable firstnorth
  214. variable pcoords
  215. global mon
  216. #start line
  217. if { ![info exists linex1] } {
  218. set linex1 [$mapcan canvasx $x]
  219. set liney1 [$mapcan canvasy $y]
  220. }
  221. if { $first == 1 } {
  222. set firsteast [MapCanvas::scrx2mape $mon $linex1]
  223. set firstnorth [MapCanvas::scry2mapn $mon $liney1]
  224. set pcoords "$firsteast,$firstnorth"
  225. }
  226. set first 0
  227. #check for click with no drag
  228. if { ![info exists linex2] } {
  229. set linex2 $linex1
  230. }
  231. if { ![info exists liney2] } {
  232. set liney2 $liney1
  233. }
  234. $mapcan delete transect
  235. }
  236. # draw profile transect
  237. proc GmProfile::drawtransect { mapcan x y } {
  238. variable measurement_annotation_handle
  239. variable transect
  240. variable tlength
  241. variable tottlength
  242. variable linex1
  243. variable liney1
  244. variable linex2
  245. variable liney2
  246. variable pcoords
  247. global mon
  248. set scrxmov $x
  249. set scrymov $y
  250. set eastcoord [eval MapCanvas::scrx2mape $mon $x]
  251. set northcoord [eval MapCanvas::scry2mapn $mon $y]
  252. set coords "$eastcoord,$northcoord"
  253. set xc [$mapcan canvasx $x]
  254. set yc [$mapcan canvasy $y]
  255. # draw line segment
  256. if {($linex1 != $xc) && ($liney1 != $yc)} {
  257. $mapcan delete transect
  258. $mapcan addtag transect withtag \
  259. [$mapcan create line $linex1 $liney1 $xc $yc \
  260. -fill red -arrow last -width 2]
  261. set linex2 $xc
  262. set liney2 $yc
  263. }
  264. }
  265. # get coordinates for transect nodes and endpoints
  266. proc GmProfile::getcoords { mapcan } {
  267. variable measurement_annotation_handle
  268. variable transect
  269. variable tottransect
  270. variable tlength
  271. variable tottlength
  272. variable linex1
  273. variable liney1
  274. variable linex2
  275. variable liney2
  276. variable pcoords
  277. variable firsteast
  278. variable east1
  279. variable north1
  280. variable east2
  281. variable north2
  282. variable pcoords
  283. variable pcoordslist
  284. global mon
  285. # draw cumulative line
  286. $mapcan addtag tottransect withtag \
  287. [$mapcan create line $linex1 $liney1 $linex2 $liney2 \
  288. -fill blue -arrow last -width 2]
  289. # get line endpoints in map coordinates
  290. set east1 [expr 1.0 * [MapCanvas::scrx2mape $mon $linex1]]
  291. set north1 [expr 1.0 * [MapCanvas::scry2mapn $mon $liney1]]
  292. set east2 [expr 1.0 * [MapCanvas::scrx2mape $mon $linex2]]
  293. set north2 [expr 1.0 * [MapCanvas::scry2mapn $mon $liney2]]
  294. # coordinates for use in r.profile
  295. append pcoords "," $east2 "," $north2
  296. # x distance off each transect segment
  297. # First convert map coordinates to profile screen coordinates
  298. # Then add the profile screen coordinates to the profile coordinates list.
  299. # Only add east1 and north1 the first time;
  300. # continue to add east2 and north2 until ready to draw profile
  301. # calculate line segment length and total length
  302. set tlength [expr {sqrt(pow(($east1 - $east2), 2) + pow(($north1 - $north2), 2))}]
  303. set tottlength [expr {$tottlength + $tlength}]
  304. lappend pcoordslist $tottlength
  305. monitor_annotate $measurement_annotation_handle " --segment length\t= $tlength\n"
  306. monitor_annotate $measurement_annotation_handle "cumulative length\t= $tottlength\n"
  307. set linex1 $linex2
  308. set liney1 $liney2
  309. }
  310. ###############################################################################
  311. # draw profile
  312. proc GmProfile::pdraw { } {
  313. variable pcan
  314. variable pmap
  315. variable tottlength
  316. variable elevrange
  317. variable elevmax
  318. variable elevmin
  319. variable firsteast
  320. variable firstnorth
  321. variable east1
  322. variable north1
  323. variable east2
  324. variable north2
  325. variable pcoords
  326. variable pcoordslist
  327. variable profilelist
  328. variable status
  329. global mon
  330. global devnull
  331. set cumdist 0.0
  332. if {![catch {open "|g.proj -p" r} input]} {
  333. set key ""
  334. set value ""
  335. while {[gets $input line] >= 0} {
  336. if { [string equal "XY location (unprojected)" "$line"] } {
  337. set mapunits "map units"
  338. break
  339. }
  340. regexp -nocase {^(.*):(.*)$} $line trash key value
  341. set key [string trim $key]
  342. set value [string trim $value]
  343. set prj($key) $value
  344. }
  345. if {[catch {close $input} error]} {
  346. GmLib::errmsg $error [G_msg "g.proj or projection error"]
  347. }
  348. }
  349. # r.profile always returns meters, but here profile length is calculated
  350. # from the map canvas arrows and so is measured & plotted in map units.
  351. # May already be set above if locn was XY.
  352. if { ! [ info exist mapunits ] } {
  353. set mapunits $prj(units)
  354. }
  355. if {$pmap == ""} {
  356. # get currently selected raster map as default to profile if nothing else chosen
  357. set tree($mon) $GmTree::tree($mon)
  358. set sel [ lindex [$tree($mon) selection get] 0 ]
  359. if { $sel != "" } {
  360. set type [GmTree::node_type $sel]
  361. if {$type == "raster" } {
  362. set GmProfile::pmap [GmRaster::mapname $sel]
  363. }
  364. } else {
  365. tk_messageBox -message [G_msg "You must select a raster to profile"] -type ok -icon warning \
  366. -title [G_msg "No raster map selected"] -parent .profile
  367. return
  368. }
  369. }
  370. if {$pcoords == ""} {
  371. tk_messageBox -message [G_msg "You must draw a transect to profile"] -type ok -icon warning \
  372. -title [G_msg "No transect drawn"] -parent .profile
  373. return
  374. }
  375. set GmProfile::status [G_msg "Please wait while profile elevations are calculated"]
  376. update
  377. # calculate elevation max, min, and range
  378. GmProfile::setelev $pmap
  379. if {$elevrange == 0} {
  380. tk_messageBox -message [G_msg "Elevation range for selected raster is zero.\nNo profile can be created."]\
  381. -type ok -icon warning -title [G_msg "Zero elevation range"] -parent .profile
  382. return
  383. }
  384. # put map name back in status bar
  385. set GmProfile::status [G_msg "Profile for $pmap"]
  386. $pcan delete all
  387. set profilelist ""
  388. # calculate screen length and width
  389. set w [winfo width $pcan]
  390. set h [winfo height $pcan]
  391. #calculate graph box and scale extents
  392. set top [expr 0.20 * $h]
  393. set bottom [expr 0.80 * $h]
  394. set height [expr $bottom - $top]
  395. set left [expr 0.2 * $w]
  396. set right [expr 0.9 * $w]
  397. set center [expr 0.55 * $w]
  398. set width [expr $right - $left]
  399. set yscaleright [expr $left - 10]
  400. set xscaletop [expr $bottom + 10]
  401. set titlebottom [expr 0.10 * $h]
  402. set titleleft [expr $left + 15]
  403. # create title
  404. $pcan create text $center $titlebottom \
  405. -text [G_msg "Profile for $pmap"] \
  406. -font {-size 14 -weight bold} \
  407. -anchor s \
  408. -justify center
  409. # create y axis (from 20%x20% to 20%x80% - top to bottom)
  410. $pcan create line $left $top $left [expr $bottom + 5]
  411. # format axis labels in a nice way, as a function of range
  412. if { $elevrange >= 100 } {
  413. set outfmt "%.0f"
  414. } elseif { $elevrange > 0 } {
  415. set outfmt "%.[expr {int(ceil(2 - log10($elevrange)))}]f"
  416. } else {
  417. # error: no range (nan?)
  418. set outfmt "%g"
  419. }
  420. # add scale to y axis
  421. $pcan create text $yscaleright $top \
  422. -text "[format $outfmt $elevmax]" \
  423. -anchor e \
  424. -justify right
  425. $pcan create text $yscaleright $bottom \
  426. -text "[format $outfmt $elevmin]" \
  427. -anchor e \
  428. -justify right
  429. # create x axis (from 20%x80% to 90%x80% - left to right)
  430. $pcan create line [expr $left - 5] $bottom $right $bottom
  431. # add scale to x axis
  432. $pcan create text $left $xscaletop \
  433. -text "0" \
  434. -anchor n \
  435. -justify center
  436. # add tick marks
  437. $pcan create line $right $bottom $right [expr $bottom + 5]
  438. $pcan create line [expr $left - 5] $top $left $top
  439. # run r.profile first time to calculate total transect distance (needed for lat lon regions)
  440. if {![catch {open "|r.profile input=$pmap profile=$pcoords null=nan 2> $devnull" r} input]} {
  441. while {[gets $input line] >= 0} {
  442. if { [regexp -nocase {^([0-9].*) ([[.-.]0-9na].*)$} $line trash dist elev] } {
  443. set cumdist $dist
  444. }
  445. }
  446. if {[catch {close $input} error]} {
  447. GmLib::errmsg $error [G_msg "r.profile error"]
  448. }
  449. }
  450. set divisor "1.0"
  451. if { [string equal "meters" "$mapunits"] } {
  452. if { $tottlength > 2500 } {
  453. set mapunits "km"
  454. set divisor "1000.0"
  455. }
  456. } elseif { [string first "feet" "$mapunits"] >= 0 } {
  457. # nano-bug: we match any "feet", but US Survey feet is really
  458. # 5279.9894 per statute mile, or 1.06' per 100 miles. As >100
  459. # miles the tick markers are rounded to the nearest 10th of a
  460. # mile (528'), the difference in foot flavours is ignored.
  461. if { $tottlength > 5280 } {
  462. set mapunits "miles"
  463. set divisor "5280.0"
  464. }
  465. } elseif { [string first "degree" "$mapunits"] >= 0 } {
  466. if { $tottlength < 1 } {
  467. set mapunits "minutes"
  468. set divisor [expr 1/60.0]
  469. }
  470. }
  471. # format axis labels in a nice way, as a function of range
  472. if { [expr $tottlength/$divisor ] >= 500 } {
  473. set outfmt "%.0f"
  474. } elseif { [expr $tottlength/$divisor ] >= 100 } {
  475. set outfmt "%.1f"
  476. } elseif { [expr $tottlength/$divisor ] > 0 } {
  477. set outfmt "%.[expr {int(ceil(2 - log10($tottlength/$divisor)))}]f"
  478. } else {
  479. # error: no range (nan?)
  480. set outfmt "%g"
  481. }
  482. # add axis label
  483. $pcan create text $center $xscaletop \
  484. -text [G_msg "distance along transect ($mapunits)"] \
  485. -anchor n \
  486. -justify center
  487. # add transect segment markers
  488. foreach {x} $pcoordslist {
  489. if { $tottlength > 0.0 } {
  490. set segx [expr $left + (($x * $width) / $tottlength)]
  491. $pcan create line $segx $bottom $segx $top -fill grey
  492. $pcan create text $segx $top -text "[format $outfmt [expr $x/$divisor]]" \
  493. -anchor s -justify center -fill grey
  494. }
  495. }
  496. # add label for total transect distance
  497. $pcan create text $right $xscaletop \
  498. -text "[format $outfmt [expr $tottlength/$divisor]]" \
  499. -anchor n \
  500. -justify center
  501. # run r.profile again to
  502. # convert dist elev (stdout) to xy coordinates of profile line
  503. if {![catch {open "|r.profile input=$pmap profile=$pcoords null=nan 2> $devnull" r} input]} {
  504. while {[gets $input line] >= 0} {
  505. if { [regexp -nocase {^([0-9].*) ([[.-.]0-9na].*)$} $line trash dist elev] } {
  506. if { [string equal "$elev" "nan" ] } {
  507. # draw profile line
  508. if { [ info exist profilelist ] } {
  509. if { [llength $profilelist] >= 4 } {
  510. $pcan create line $profilelist -fill blue
  511. } elseif { [llength $profilelist] == 2 } {
  512. # plot a dot
  513. $pcan create oval [concat $profilelist $profilelist] \
  514. -fill blue -outline blue -width 1
  515. }
  516. unset profilelist
  517. }
  518. } else {
  519. set pelev [expr $bottom - ($height * ($elev - $elevmin) / $elevrange)]
  520. set pdist [expr $left + (($dist * $width) / $cumdist)]
  521. lappend profilelist $pdist $pelev
  522. }
  523. }
  524. }
  525. if {[catch {close $input} error]} {
  526. GmLib::errmsg $error [G_msg "r.profile error"]
  527. }
  528. }
  529. # draw profile line
  530. if { [ info exist profilelist ] && [llength $profilelist] >= 4 } {
  531. $pcan create line $profilelist -fill blue
  532. }
  533. }
  534. ###############################################################################
  535. # erase profile and clear transects
  536. proc GmProfile::perase { mapcan } {
  537. variable pmap
  538. variable pcan
  539. variable transect
  540. variable tottransect
  541. variable tlength
  542. variable tottlength
  543. variable pcoords
  544. variable pcoordslist
  545. variable profilelist
  546. variable first
  547. variable linex1
  548. variable liney1
  549. variable elevrange
  550. variable elevmax
  551. variable elevmin
  552. $pcan delete all
  553. $mapcan delete transect
  554. $mapcan delete tottransect
  555. set tlength 0.0
  556. set tottlength 0.0
  557. set pcoords ""
  558. set pcoordslist ""
  559. set profilelist ""
  560. set first 1
  561. if { [info exists linex1] } {
  562. unset linex1
  563. }
  564. if { [info exists liney1] } {
  565. unset liney1
  566. }
  567. }
  568. ###############################################################################
  569. proc GmProfile::cleanup { destroywin mapcan } {
  570. # cleanup procedures on closing profile window
  571. variable pcan
  572. variable transect
  573. variable tottransect
  574. variable tlength
  575. variable tottlength
  576. variable pcoords
  577. variable pcoordslist
  578. variable profilelist
  579. variable first
  580. variable linex1
  581. variable liney1
  582. global mon
  583. set tlength 0.0
  584. set tottlength 0.0
  585. set pcoords ""
  586. set pcoordslist ""
  587. set profilelist ""
  588. set first 1
  589. if { [info exists linex1] } {
  590. unset linex1
  591. }
  592. if { [info exists liney1] } {
  593. unset liney1
  594. }
  595. $mapcan delete transect
  596. $mapcan delete tottransect
  597. MapCanvas::restorecursor $mon
  598. }
  599. ###############################################################################