123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556 |
- if {[array get env GISBASE] == ""} {
- puts stderr "You must be in GRASS GIS to run this program."
- exit 1
- }
- if {$tcl_platform(platform) == "windows"} {
- set stderr NUL:
- } else {
- set stderr @stderr
- }
- set outmap $env(GIS_OPT_OUTPUT)
- set inmap $env(GIS_OPT_INPUT)
- set aspect $env(GIS_OPT_ASPECT)
- set width $env(GIS_OPT_WIDTH)
- set height $env(GIS_OPT_HEIGHT)
- set size $env(GIS_OPT_SIZE)
- set rows $env(GIS_OPT_ROWS)
- set cols $env(GIS_OPT_COLS)
- set status(row) ""
- set status(col) ""
- set status(x) ""
- set status(y) ""
- set status(value) ""
- set status(aspect) ""
- set brush "*"
- set origin(x) 0
- set origin(y) 0
- set finalized false
- proc initialize {} {
- global tempbase tempfile tempreg tempmap env stderr
- global inmap outmap
- set tempbase [exec g.tempfile pid=[pid]]
- file delete $tempbase
- set tempfile $tempbase.ppm
- set tempreg tmp.d.rast.edit
- set tempmap tmp.d.rast.edit
- exec g.region --q --o save=$tempreg 2>$stderr
- set env(WIND_OVERRIDE) $tempreg
- exec g.copy --q --o rast=$inmap,$outmap 2>$stderr
- exec r.colors --q map=$outmap rast=$inmap 2>$stderr
- }
- proc finalize {} {
- global tempfile tempreg tempmap stderr finalized
- if {$finalized} return
- save_map
- file delete $tempfile
- exec g.remove --q rast=$tempmap region=$tempreg 2>$stderr
- set finalized true
- exit 0
- }
- proc force_window {} {
- global origin rows cols total
- if {$origin(x) < 0} {set origin(x) 0}
- if {$origin(x) > $total(cols) - $cols} {set origin(x) [expr $total(cols) - $cols]}
- if {$origin(y) < 0} {set origin(y) 0}
- if {$origin(y) > $total(rows) - $rows} {set origin(y) [expr $total(rows) - $rows]}
- }
- proc set_window {x y} {
- global origin rows cols
- set origin(x) [expr [.overview.canvas canvasx $x] - $cols / 2]
- set origin(y) [expr [.overview.canvas canvasy $y] - $rows / 2]
- force_window
- set x0 $origin(x)
- set y0 $origin(y)
- set x1 [expr $x0 + $cols]
- set y1 [expr $y0 + $rows]
- .overview.canvas delete window
- .overview.canvas create rectangle $x0 $y0 $x1 $y1 -dash {4 4} -tags window
- }
- proc update_window {} {
- global wind total origin rows cols
- set x0 $origin(x)
- set y0 $origin(y)
- set x1 [expr $x0 + $cols]
- set y1 [expr $y0 + $rows]
- set wind(n) [expr $total(n) - $y0 * $total(nsres)]
- set wind(s) [expr $total(n) - $y1 * $total(nsres)]
- set wind(w) [expr $total(w) + $x0 * $total(ewres)]
- set wind(e) [expr $total(w) + $x1 * $total(ewres)]
- set wind(rows) $rows
- set wind(cols) $cols
- }
- proc change_window {} {
- save_map
- update_window
- load_map
- load_aspect
- refresh_canvas
- }
- proc create_overview {} {
- global inmap outmap stderr env total rows cols tempfile
- exec g.region --q rast=$inmap 2>$stderr
- exec r.out.ppm --q $inmap out=$tempfile 2>$stderr
- set reg [exec g.region --q -g 2>$stderr]
- set reg [regsub -all {[\r\n]+} $reg { }]
- set reg [regsub -all {=} $reg { }]
- array set total $reg
- image create photo overview -file $tempfile
- file delete $tempfile
- toplevel .overview
- wm title .overview "d.rast.edit overview ($inmap)"
- set w $total(cols)
- set h $total(rows)
- canvas .overview.canvas -width $w -height $h -scrollregion [list 0 0 $w $h] \
- -xscrollcommand {.overview.xscroll set} -yscrollcommand {.overview.yscroll set}
- scrollbar .overview.xscroll -orient horizontal -command {.overview.canvas xview}
- scrollbar .overview.yscroll -orient vertical -command {.overview.canvas yview}
- if {$cols > $total(cols)} {set cols $total(cols)}
- if {$rows > $total(rows)} {set rows $total(rows)}
- force_window
- .overview.canvas create image 0 0 -anchor nw -image overview -tags image
- .overview.canvas create rectangle 0 0 $cols $rows -dash {4 4} -tags window
- grid .overview.canvas .overview.yscroll -sticky nsew
- grid .overview.xscroll -sticky nsew
- grid rowconfigure .overview 0 -weight 1
- grid columnconfigure .overview 0 -weight 1
- bind .overview.canvas <ButtonPress-1> { set_window %x %y }
- bind .overview.canvas <B1-Motion> { set_window %x %y }
- bind .overview.canvas <ButtonRelease-1> { set_window %x %y ; change_window }
- bind .overview <Destroy> { finalize }
- }
- proc read_header {infile window} {
- upvar \#0 $window wind
- regexp {^north: *([0-9]+)$} [gets $infile] dummy wind(n)
- regexp {^south: *([0-9]+)$} [gets $infile] dummy wind(s)
- regexp {^east: *([0-9]+)$} [gets $infile] dummy wind(e)
- regexp {^west: *([0-9]+)$} [gets $infile] dummy wind(w)
- regexp {^rows: *([0-9]+)$} [gets $infile] dummy wind(rows)
- regexp {^cols: *([0-9]+)$} [gets $infile] dummy wind(cols)
- }
- proc read_data {infile array} {
- global wind
- upvar \#0 $array values
- for {set row 0} {$row < $wind(rows)} {incr row} {
- gets $infile line
- set col 0
- foreach elem $line {
- set values($row,$col) $elem
- incr col
- }
- }
- }
- proc clear_changes {} {
- global wind changed
- for {set row 0} {$row < $wind(rows)} {incr row} {
- for {set col 0} {$col < $wind(cols)} {incr col} {
- set changed($row,$col) 0
- }
- }
- }
- proc load_map {} {
- global tempfile wind values changed colors inmap stderr
- exec g.region --q n=$wind(n) s=$wind(s) e=$wind(e) w=$wind(w) \
- rows=$wind(rows) cols=$wind(cols) 2>$stderr
- set infile [open "|r.out.ascii --q input=$inmap 2>$stderr" r]
- read_header $infile wind
- read_data $infile values
- close $infile
- clear_changes
- exec r.out.ppm --q input=$inmap output=$tempfile 2>$stderr
- image create photo colorimg -file $tempfile
- file delete $tempfile
- for {set row 0} {$row < $wind(rows)} {incr row} {
- for {set col 0} {$col < $wind(cols)} {incr col} {
- set val $values($row,$col)
- if {[array get colors $val] != ""} continue
- set pix [colorimg get $col $row]
- set r [lindex $pix 0]
- set g [lindex $pix 1]
- set b [lindex $pix 2]
- set color [format "#%02x%02x%02x" $r $g $b]
- set colors($val) $color
- }
- }
- image delete colorimg
- }
- proc load_aspect {} {
- global wind angles aspect stderr
- if {$aspect == ""} return
- set infile [open "|r.out.ascii --q input=$aspect 2>$stderr" r]
- read_header $infile dummy
- read_data $infile angles
- close $infile
- }
- proc save_map {} {
- global inmap outmap tempmap stderr
- global wind values changed
- set outfile [open "|r.in.ascii --q --o input=- output=$tempmap 2>$stderr" w]
- puts $outfile "north: $wind(n)"
- puts $outfile "south: $wind(s)"
- puts $outfile "east: $wind(e)"
- puts $outfile "west: $wind(w)"
- puts $outfile "rows: $wind(rows)"
- puts $outfile "cols: $wind(cols)"
- for {set row 0} {$row < $wind(rows)} {incr row} {
- for {set col 0} {$col < $wind(cols)} {incr col} {
- if {$col > 0} {
- puts -nonewline $outfile " "
- }
- if {$changed($row,$col)} {
- puts -nonewline $outfile "$values($row,$col)"
- } else {
- puts -nonewline $outfile "*"
- }
- }
- puts $outfile ""
- }
- close $outfile
- exec g.region --q rast=$inmap 2>$stderr
- exec r.patch --q --o input=$tempmap,$outmap output=$outmap 2>$stderr
- exec r.colors --q map=$outmap rast=$inmap 2>$stderr
- exec g.remove --q rast=$tempmap 2>$stderr
- }
- proc force_color {val} {
- global tempfile tempreg tempmap colors inmap stderr env
- exec g.region --q rows=1 cols=1 2>$stderr
- exec r.mapcalc "$tempmap = $val" 2>$stderr
- exec r.colors --q map=$tempmap rast=$inmap 2>$stderr
- exec r.out.ppm --q $tempmap out=$tempfile 2>$stderr
- exec g.remove --q rast=$tempmap 2>$stderr
- image create photo tempimg -file $tempfile
- file delete $tempfile
- set pix [tempimg get 0 0]
- set r [lindex $pix 0]
- set g [lindex $pix 1]
- set b [lindex $pix 2]
- set color [format "#%02x%02x%02x" $r $g $b]
- set colors($val) $color
- image delete tempimg
- }
- proc get_color {val} {
- global colors
- if {[array get colors $val] == ""} {
- if {[catch {force_color $val}]} {
- set colors($val) "#ffffff"
- }
- }
- return $colors($val)
- }
- proc brush_update {} {
- global brush colors
- if {$brush == "*"} {
- .tools.color configure -bitmap gray12 -foreground black
- } else {
- .tools.color configure -bitmap gray75 -foreground [get_color $brush]
- }
- }
- proc current_cell {} {
- global canvas
- set row ""
- set col ""
- set tags [.canvas itemcget current -tags]
- foreach tag $tags {
- if {[regexp {row-([0-9]+)} $tag dummy r]} {set row $r}
- if {[regexp {col-([0-9]+)} $tag dummy c]} {set col $c}
- }
- return [list $row $col]
- }
- proc cell_enter {} {
- global status
- global wind values angles
- set pos [current_cell]
- set row [lindex $pos 0]
- set col [lindex $pos 1]
- if {$row == "" || $col == ""} return
- set status(row) $row
- set status(col) $col
- set status(x) [expr {$wind(e) + ($col + 0.5) * ($wind(e) - $wind(w)) / $wind(cols)}]
- set status(y) [expr {$wind(n) - ($row + 0.5) * ($wind(n) - $wind(s)) / $wind(rows)}]
- set status(value) $values($row,$col)
- if {[array exists angles]} {
- set status(aspect) $angles($row,$col)
- }
- }
- proc cell_leave {} {
- global status
- set status(row) ""
- set status(col) ""
- set status(x) ""
- set status(y) ""
- set status(value) ""
- set status(aspect) ""
- }
- proc cell_get {} {
- global brush values colors
- set pos [current_cell]
- set row [lindex $pos 0]
- set col [lindex $pos 1]
- set brush $values($row,$col)
- brush_update
- }
- proc cell_set {} {
- global canvas brush values changed colors
- set pos [current_cell]
- set row [lindex $pos 0]
- set col [lindex $pos 1]
- set val $brush
- set values($row,$col) $val
- set changed($row,$col) 1
- set cell [.canvas find withtag "(cell&&row-$row&&col-$col)"]
- if {$val == "*"} {
- set fill black
- set stipple gray12
- } else {
- set fill [get_color $val]
- set stipple ""
- }
- .canvas itemconfigure $cell -outline white -fill $fill -stipple $stipple
- }
- proc refresh_canvas {} {
- global wind size values colors angles
- .canvas delete all
- set aspect [array exists angles]
- set pi [expr 2 * acos(0)]
- for {set row 0} {$row < $wind(rows)} {incr row} {
- for {set col 0} {$col < $wind(cols)} {incr col} {
- set x0 [expr $col * $size + 1]
- set x1 [expr $x0 + $size - 1]
- set y0 [expr $row * $size + 1]
- set y1 [expr $y0 + $size - 1]
- if {$values($row,$col) == "*"} {
- set color black
- set stipple gray12
- } else {
- set color $colors($values($row,$col))
- set stipple ""
- }
- .canvas create polygon $x0 $y0 $x1 $y0 $x1 $y1 $x0 $y1 \
- -fill $color -stipple $stipple \
- -outline black -activeoutline red \
- -tags [list cell row-$row col-$col]
- if {! $aspect} continue
- if {$angles($row,$col) == "*"} continue
- set cx [expr ($x0 + $x1) / 2]
- set cy [expr ($y0 + $y1) / 2]
- set a [expr $angles($row,$col) * $pi / 180]
- set dx [expr cos($a) * $size / 2]
- set dy [expr - sin($a) * $size / 2]
- set x0 [expr $cx - $dx]
- set y0 [expr $cy - $dy]
- set x1 [expr $cx + $dx]
- set y1 [expr $cy + $dy]
- .canvas create line $x0 $y0 $x1 $y1 \
- -arrow last \
- -disabledfill white -state disabled \
- -tags [list arrow row-$row col-$col]
- }
- }
- }
- proc make_canvas {} {
- global canvas values colors angles rows cols
- global size width height
- set cx [expr $width / $cols]
- set cy [expr $height / $rows]
- set sz [expr ($cx > $cy) ? $cx : $cy]
- if {$size < $sz} {set size $sz}
- set w [expr $cols * $size]
- set h [expr $rows * $size]
- canvas .canvas -width $width -height $height -scrollregion [list 0 0 $w $h] \
- -xscrollcommand {.xscroll set} -yscrollcommand {.yscroll set}
- scrollbar .xscroll -orient horizontal -command {.canvas xview}
- scrollbar .yscroll -orient vertical -command {.canvas yview}
- .canvas bind cell <Any-Enter> { cell_enter }
- .canvas bind cell <Any-Leave> { cell_leave }
- .canvas bind cell <Button-1> { cell_set }
- .canvas bind cell <Button-3> { cell_get }
- bind .canvas <Any-Leave> { cell_leave }
- }
- proc make_ui {} {
- global canvas inmap
- wm title . "d.rast.edit ($inmap)"
- bind . <Destroy> { finalize }
- menu .menu -tearoff 0
- menu .menu.file -tearoff 0
- .menu add cascade -label "File" -menu .menu.file -underline 0
- .menu.file add command -label "Save" -underline 0 -command {save_map}
- .menu.file add command -label "Exit" -underline 1 -command {destroy .}
- . configure -menu .menu
- frame .status
- label .status.row_l -text "Row:"
- entry .status.row -textvariable status(row) -width 6
- label .status.col_l -text "Col:"
- entry .status.col -textvariable status(col) -width 6
- label .status.x_l -text "X:"
- entry .status.x -textvariable status(x) -width 10
- label .status.y_l -text "Y:"
- entry .status.y -textvariable status(y) -width 10
- label .status.value_l -text "Value:"
- entry .status.value -textvariable status(value) -width 10
- label .status.aspect_l -text "Aspect:"
- entry .status.aspect -textvariable status(aspect) -width 10
- pack \
- .status.row_l .status.row \
- .status.col_l .status.col \
- .status.x_l .status.x \
- .status.y_l .status.y \
- .status.value_l .status.value \
- .status.aspect_l .status.aspect \
- -side left
- frame .tools
- label .tools.value_l -text "New value:"
- entry .tools.value -textvariable brush
- label .tools.color_l -text "Color:"
- label .tools.color -bitmap gray12 -foreground black
- pack \
- .tools.value_l .tools.value \
- .tools.color_l .tools.color \
- -side left
- bind .tools.value <KeyPress-Return> brush_update
- grid .canvas .yscroll -sticky nsew
- grid .xscroll -sticky nsew
- grid .status -sticky nsew
- grid .tools -sticky nsew
- grid rowconfigure . 0 -weight 1
- grid columnconfigure . 0 -weight 1
- }
- initialize
- create_overview
- make_canvas
- make_ui
- update_window
- load_map
- load_aspect
- refresh_canvas
|