~ubuntu-branches/ubuntu/vivid/grass/vivid-proposed

« back to all changes in this revision

Viewing changes to gui/tcltk/gis.m/georect.tcl

  • Committer: Package Import Robot
  • Author(s): Bas Couwenberg
  • Date: 2015-02-20 23:12:08 UTC
  • mfrom: (8.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20150220231208-1u6qvqm84v430b10
Tags: 7.0.0-1~exp1
* New upstream release.
* Update python-ctypes-ternary.patch to use if/else instead of and/or.
* Drop check4dev patch, rely on upstream check.
* Add build dependency on libpq-dev to grass-dev for libpq-fe.h.
* Drop patches applied upstream, refresh remaining patches.
* Update symlinks for images switched from jpg to png.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
##########################################################################
2
 
#
3
 
# georect.tcl -TclTk canvas georectify display and controls
4
 
#    for GIS Manager: GUI for GRASS 6
5
 
#
6
 
# Author: Michael Barton (Arizona State University).
7
 
#
8
 
# July 2006
9
 
#
10
 
# COPYRIGHT:    (C) 1999 - 2006 by the GRASS Development Team
11
 
#
12
 
#               This program is free software under the GNU General Public
13
 
#               License (>=v2). Read the file COPYING that comes with GRASS
14
 
#               for details.
15
 
#
16
 
##########################################################################
17
 
 
18
 
 
19
 
# All of these must be sourced before using georect.tcl:
20
 
# source $env(GISBASE)/etc/gtcltk/gmsg.tcl
21
 
# source $env(GISBASE)/etc/gtcltk/select.tcl
22
 
# source $env(GISBASE)/etc/gui.tcl
23
 
# This one is going to be handled by pkgIndex:
24
 
# georecttool.tcl
25
 
 
26
 
namespace eval GRMap {
27
 
    variable displayrequest # true if it wants to get displayed.
28
 
 
29
 
    # Something's modified the canvas or view
30
 
    # Degree of modification 0 - none, 1 - zoom, 2 - canvas
31
 
    variable array grcanmodified
32
 
    # The canvas widget of the georectify monitor
33
 
    variable grcan 
34
 
    # Frame widget
35
 
    variable grmapframe
36
 
    # Width and height of canvas
37
 
    variable grcanvas_w 
38
 
    variable grcanvas_h
39
 
    # Actual width and height used while drawing / compositing
40
 
    variable driver_w 
41
 
    # Actual width and height used while drawing / compositing
42
 
    variable driver_h
43
 
    # Indicator widgets
44
 
    variable map_ind 
45
 
    variable initwd
46
 
    variable initht
47
 
    variable grcursor
48
 
    # TMP directory for raster display images used in canvas
49
 
    variable tmpdir
50
 
    # status bar message
51
 
    variable msg 
52
 
 
53
 
    # variables for coordinate conversions and zooming
54
 
    variable linex1
55
 
    variable liney1
56
 
    variable linex2
57
 
    variable liney2
58
 
    variable map_n
59
 
    variable map_s
60
 
    variable map_e
61
 
    variable map_w
62
 
    variable map_ew
63
 
    variable map_ns
64
 
    variable scr_n
65
 
    variable scr_s
66
 
    variable scr_e
67
 
    variable scr_w
68
 
    variable scr_ew
69
 
    variable scr_ns
70
 
    variable map2scrx_conv
71
 
    variable map2scry_conv
72
 
    variable areaX1 
73
 
    variable areaY1 
74
 
    variable areaX2 
75
 
    variable areaY2
76
 
 
77
 
    #variable grcoords # geographic coordinates from mouse click
78
 
    # geographic coordinates from mouse movement to display in indicator widget
79
 
    variable grcoords_mov
80
 
    # Driver output file (.ppm)
81
 
    variable grfile 
82
 
    #process id to use for temp files
83
 
    variable mappid 
84
 
 
85
 
    # Current region and region historys
86
 
    # Indexed by history (1 (current) - zoomhistories), part (n, s, e, w, nsres, ewres).
87
 
    variable array monitor_zooms
88
 
    # Depth of zoom history to keep
89
 
    variable zoomhistories
90
 
    set zoomhistories 7
91
 
 
92
 
    # Regular order for region values in a list representing a region or zoom
93
 
    variable zoom_attrs
94
 
    set zoom_attrs {n s e w nsres ewres}
95
 
 
96
 
    # string with region information to show in status bar
97
 
    variable regionstr
98
 
 
99
 
    # This variable keeps track of which monitor set the gism driver settings last.
100
 
    # They must always be redone if the monitor was different
101
 
    variable previous_monitor
102
 
    set previous_monitor {none}
103
 
 
104
 
    # Current projection and zone for dynamic region setting for displays
105
 
    variable gregionproj
106
 
 
107
 
    variable redrawrequest 0
108
 
 
109
 
    #variables for panning
110
 
    variable start_x
111
 
    variable start_y
112
 
    variable from_x
113
 
    variable from_y
114
 
    variable to_x
115
 
    variable to_y
116
 
 
117
 
    # gcp variables
118
 
    # use GCP in RMS calculations and rectification indexed by gcpnum
119
 
    variable array usegcp
120
 
    # entry widget for GCP xy coordinates indexed by gcpnum
121
 
    variable array xy
122
 
    # entry widget for GCP forward rms error indexed by gcpnum
123
 
    variable array fwd
124
 
    # entry widget for GCP reverse rms error indexed by gcpnum
125
 
    variable array rev
126
 
    # gcp form has been created and can be accessed
127
 
    variable drawform
128
 
    # entry widget for GCP georectified coordinates indexed by gcpnum
129
 
    variable array geoc
130
 
    # checkbutton widget for GCP use indexed by gcpnum
131
 
    variable array chk
132
 
    # forward projected error value for each GCP indexed by gcpnum
133
 
    variable array fwd_error
134
 
    # backward projected error value for each GCP indexed by gcpnum
135
 
    variable array rev_error
136
 
    # forward and backward projected error
137
 
    variable errorlist
138
 
    # clip or not clip image to target region
139
 
    variable clipregion
140
 
 
141
 
    variable gcpnum
142
 
    #forward projected rms error for GCP's, displayed in gcp manager status bar
143
 
    variable fwd_rmserror
144
 
    #backward projected rms error for GCP's, displayed in gcp manager status bar
145
 
    variable rev_rmserror
146
 
 
147
 
    #variables to keep track of location and mapset
148
 
    # current gisdbase
149
 
    variable currgdb
150
 
    # current location
151
 
    variable currloc
152
 
    # current mapset
153
 
    variable currmset
154
 
    # gisdbase of xy raster
155
 
    variable xygdb
156
 
    # location of xy raster
157
 
    variable xyloc
158
 
    # mapset of xy raster
159
 
    variable xymset
160
 
    # raster group to georectify
161
 
    variable xygroup
162
 
    # raster or vector map to display as refernce for setting ground control points
163
 
    variable xymap
164
 
    # vector map to add or delete from vector group
165
 
    variable xyvect
166
 
    # georectify raster or vector map
167
 
    variable maptype
168
 
    # is target mapset same as current mapset
169
 
    variable selftarget
170
 
    # vector map for vector group file
171
 
    variable xyvect
172
 
    # rectification method (1,2,3)
173
 
    variable rectorder
174
 
 
175
 
        # initialize variables
176
 
        set gcpnum 1
177
 
        set chk($gcpnum) ""
178
 
        set currgdb $env(GISDBASE)
179
 
        set currloc $env(LOCATION_NAME)
180
 
        set currmset $env(MAPSET)
181
 
        set east 0.0
182
 
        set errorlist ""
183
 
        set fwd_error($gcpnum) ""
184
 
        set fwd_rmserror 0.0
185
 
        set geoc($gcpnum) ""
186
 
        set gregion ""
187
 
        set gregionproj ""
188
 
        set initht 480.0
189
 
        set initwd 640.0
190
 
        set maptype ""
191
 
        set north 0.0
192
 
        set rectorder 1
193
 
        set regionstr ""
194
 
        set rev_error($gcpnum) ""
195
 
        set rev_rmserror 0.0
196
 
        set selftarget 0
197
 
        set usegcp($gcpnum) 1
198
 
        set xy($gcpnum) ""
199
 
        set fwd($gcpnum) ""
200
 
        set rev($gcpnum) ""
201
 
        set xygdb ""
202
 
        set xygroup ""
203
 
        set xyloc ""
204
 
        set xymap ""
205
 
        set xymset ""
206
 
        set xyvect ""
207
 
        set drawform 0
208
 
        set clipregion 1
209
 
 
210
 
 
211
 
}
212
 
 
213
 
 
214
 
###############################################################################
215
 
# Set location and mapset to selected xy
216
 
proc GRMap::setxyenv { mset loc } {
217
 
    variable selftarget
218
 
    global env
219
 
 
220
 
    if { $selftarget == 1 } { return }
221
 
 
222
 
    if { $mset != "" && $loc != "" } {
223
 
        runcmd "g.gisenv set=LOCATION_NAME=$loc"
224
 
        runcmd "g.gisenv set=MAPSET=$mset"
225
 
 
226
 
        set env(LOCATION_NAME) $loc
227
 
        set env(MAPSET) $mset
228
 
    }
229
 
}
230
 
 
231
 
 
232
 
###############################################################################
233
 
# set location and mapset back to georectified
234
 
proc GRMap::resetenv { } {
235
 
    variable currloc
236
 
    variable currmset
237
 
    variable selftarget
238
 
    global env
239
 
 
240
 
    if { $selftarget == 1 } { return }
241
 
 
242
 
    runcmd "g.gisenv set=LOCATION_NAME=$currloc"
243
 
    runcmd "g.gisenv set=MAPSET=$currmset"
244
 
 
245
 
    set env(LOCATION_NAME) $currloc
246
 
    set env(MAPSET) $currmset
247
 
 
248
 
}
249
 
 
250
 
 
251
 
###############################################################################
252
 
# get xy group to georectify; set target to current location and mapset
253
 
proc GRMap::getxygroup { vgcreate } {
254
 
    variable xygdb
255
 
    variable xyloc
256
 
    variable xymset
257
 
    variable xygroup
258
 
    variable currloc
259
 
    variable currmset
260
 
    variable selftarget
261
 
    variable maptype
262
 
 
263
 
    # First, switch to xy mapset
264
 
    GRMap::setxyenv $xymset $xyloc
265
 
    set m [GSelect group]
266
 
    set mname [lindex [split $m "@"] 0]
267
 
    # Return to georectified mapset
268
 
    GRMap::resetenv
269
 
 
270
 
    if { $mname != "" } {
271
 
            set GRMap::xygroup $mname
272
 
    }
273
 
 
274
 
    # are we creating a vector group?
275
 
    if { $vgcreate == 1 } {
276
 
        GRMap::read_vgroup $xygroup
277
 
        return
278
 
    }
279
 
 
280
 
    if { $maptype == "rast" } {
281
 
        # check to see if a raster group exists
282
 
        set groupfile "$xygdb/$xyloc/$xymset/group/$xygroup/REF"
283
 
        if {![file exists $groupfile] } {
284
 
            set GRMap::xygroup ""
285
 
            set msg [G_msg "There is no raster group file (REF). You must select\
286
 
                    the 'create/edit group' option to create a group file."]
287
 
            tk_messageBox -message $msg -parent .grstart -type ok
288
 
            return
289
 
        }
290
 
        # set i.rectify target
291
 
        if { $selftarget == 1 } {
292
 
            set cmd "i.target -c group=$GRMap::xygroup"
293
 
        } else {
294
 
            set cmd "i.target group=$GRMap::xygroup location=$currloc mapset=$currmset"
295
 
        }
296
 
        # First, switch to xy mapset
297
 
        GRMap::setxyenv $xymset $xyloc
298
 
        runcmd $cmd
299
 
        # Return to georectified mapset
300
 
        GRMap::resetenv
301
 
    } elseif { $maptype == "vect" } {
302
 
        # check to see if a vector group exists
303
 
        set groupfile "$xygdb/$xyloc/$xymset/group/$xygroup/VREF"
304
 
        puts "groupfile = $groupfile"
305
 
        if {![file exists $groupfile] } {
306
 
            set GRMap::xygroup ""
307
 
            set msg [G_msg "There is no vector group file (VREF). You must select\
308
 
                    the 'create/edit group' option to create a group file."]
309
 
            tk_messageBox -message $msg -parent .grstart -type ok
310
 
            return
311
 
        }
312
 
    } else {
313
 
            return
314
 
    }
315
 
 
316
 
}
317
 
 
318
 
###############################################################################
319
 
# get raster to display for georectification
320
 
proc GRMap::getxymap { type } {
321
 
    variable xyloc
322
 
    variable xymset
323
 
    variable xymap
324
 
 
325
 
    # First, switch to xy mapset
326
 
    GRMap::setxyenv $xymset $xyloc
327
 
 
328
 
    if { $type == "rast" } {
329
 
        set m [GSelect cell]
330
 
        set mname [lindex [split $m "@"] 0]
331
 
        if { $mname != "" } {
332
 
            set GRMap::xymap $mname
333
 
        }
334
 
    } elseif {$type == "vect" } {
335
 
        set m [GSelect vector]
336
 
        set mname [lindex [split $m "@"] 0]
337
 
        if { $mname != "" } {
338
 
            set GRMap::xymap $mname
339
 
        }
340
 
    }
341
 
 
342
 
    # Return to georectified mapset
343
 
    GRMap::resetenv
344
 
 
345
 
}
346
 
 
347
 
###############################################################################
348
 
# create or edit raster group to georectify
349
 
proc GRMap::group { } {
350
 
    variable xyloc
351
 
    variable xymset
352
 
    variable maptype
353
 
 
354
 
 
355
 
    if { $maptype == "rast" } {
356
 
        # First, switch to xy mapset
357
 
        GRMap::setxyenv $xymset $xyloc
358
 
                set cmd "i.group"
359
 
        if {[catch {exec -- $cmd --ui } error]} {
360
 
                GmLib::errmsg $error
361
 
        }
362
 
 
363
 
        # Return to georectified mapset
364
 
        GRMap::resetenv
365
 
    } elseif { $maptype == "vect" } {
366
 
            GRMap::vgroup
367
 
    } else {
368
 
            return
369
 
    }
370
 
 
371
 
}
372
 
 
373
 
###############################################################################
374
 
# get mapset of raster to georectify; automatically set location and gisdbase
375
 
proc GRMap::getmset { } {
376
 
    variable xygdb
377
 
    variable xyloc
378
 
    variable xymset
379
 
    variable currgdb
380
 
    variable currloc
381
 
    variable currmset
382
 
    variable mappid
383
 
    variable grfile
384
 
    variable tmpdir
385
 
    variable selftarget
386
 
 
387
 
    set path [tk_chooseDirectory -initialdir $currgdb \
388
 
            -title [G_msg "Select mapset of raster to georectify"] \
389
 
            -mustexist true ]
390
 
    # try to make sure that a valid mapset has been picked
391
 
    if { $path == "" || $path == $currgdb || [file dirname $path] == $currgdb } { return }
392
 
 
393
 
    set xymset [file tail $path]
394
 
    set xylocdir [file dirname $path]
395
 
    set xyloc [file tail $xylocdir]
396
 
    set xygdb [file dirname $xylocdir]
397
 
 
398
 
    # check to see if the target location and mapset is the current one
399
 
    if { $xyloc == $currloc && $xymset == $currmset } {set selftarget 1 }
400
 
 
401
 
    set GRMap::xymset [file tail $path]
402
 
 
403
 
    # create files in tmp diretory for layer output
404
 
    # First, switch to xy mapset
405
 
    GRMap::setxyenv $xymset $xyloc
406
 
 
407
 
    set mappid [pid]
408
 
        if {[catch {set grfile [exec g.tempfile pid=$mappid]} error]} {
409
 
                GmLib::errmsg $error [G_msg "Error creating tempfile"]
410
 
        }
411
 
 
412
 
    append grfile ".ppm"
413
 
    set tmpdir [file dirname $grfile]
414
 
 
415
 
    # Return to georectified mapset
416
 
    GRMap::resetenv
417
 
}
418
 
 
419
 
 
420
 
###############################################################################
421
 
# dialog to create or edit vector group to georectify
422
 
proc GRMap::vgroup { } {
423
 
    variable xygdb
424
 
    variable xyloc
425
 
    variable xymset
426
 
    variable xygroup
427
 
    variable xyvect
428
 
    global iconpath
429
 
    global bgcolor
430
 
 
431
 
    toplevel .vgwin
432
 
 
433
 
    set vg_mf [MainFrame .vgwin.mf \
434
 
            -textvariable GRMap::vgmsg]
435
 
 
436
 
    set GRMap::vgmsg [G_msg "Create a group REF file and directory for vectors"]
437
 
 
438
 
    set vg_frame [$vg_mf getframe]
439
 
 
440
 
    # toolbar creation
441
 
    set vg_tb  [$vg_mf addtoolbar]
442
 
 
443
 
    set bbox [ButtonBox $vg_tb.bbox1 -spacing 0 -homogeneous 1 ]
444
 
 
445
 
    # create or replace vector group
446
 
    $bbox add -image [image create photo -file "$iconpath/file-save.gif"] \
447
 
        -command {GRMap::write_vgroup $GRMap::xygroup $GRMap::xyvect} \
448
 
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1  \
449
 
        -helptext [G_msg "Create/replace vector group"]
450
 
 
451
 
    pack $bbox -side left -anchor w -expand no -fill y
452
 
 
453
 
    #create dialog
454
 
    set vg_sw [ScrolledWindow $vg_frame.sw -relief flat \
455
 
        -borderwidth 1 ]
456
 
    set vg_sf [ScrollableFrame $vg_sw.sf -height 50 -width 400]
457
 
    $vg_sw setwidget $vg_sf
458
 
 
459
 
    set vgframe [$vg_sf getframe]
460
 
 
461
 
    pack $vg_sw -fill both -expand yes
462
 
 
463
 
    set vg [frame $vgframe.fr]
464
 
    pack $vg -fill both -expand yes
465
 
 
466
 
 
467
 
    pack $vg_mf -side top -expand yes -fill both -anchor n
468
 
 
469
 
 
470
 
    # Scroll the options window with the mouse
471
 
    bind_scroll $vg_sf
472
 
 
473
 
    # Select or set group name
474
 
    set row [ frame $vg.groupname ]
475
 
    Button $row.a -text [G_msg "group name"] \
476
 
        -highlightthickness 0 -takefocus 0 -relief raised -borderwidth 1  \
477
 
        -helptext [G_msg "Select existing vector group or name new group"] \
478
 
        -width 16 -anchor w \
479
 
                -command {GRMap::getxygroup 1}
480
 
    Entry $row.b -width 35 -text "$GRMap::xygroup" \
481
 
          -textvariable GRMap::xygroup
482
 
    pack $row.a $row.b -side left
483
 
    pack $row -side top -fill both -expand yes
484
 
 
485
 
    # select xy vector for group
486
 
    set row [ frame $vg.vect ]
487
 
    Button $row.a -text [G_msg "vector"] \
488
 
        -highlightthickness 0 -takefocus 0 -relief raised -borderwidth 1  \
489
 
        -helptext [G_msg "Select xy vector(s) for group"]\
490
 
        -width 16 -anchor w \
491
 
                -command {GRMap::getxyvect }
492
 
    Entry $row.b -width 35 -text "$GRMap::xyvect" \
493
 
          -textvariable GRMap::xyvect
494
 
    pack $row.a $row.b -side left
495
 
    pack $row -side top -fill both -expand yes
496
 
 
497
 
    GRMap::read_vgroup $GRMap::xygroup
498
 
 
499
 
    wm title .vgwin [G_msg "Vector group"]
500
 
    wm withdraw .vgwin
501
 
    wm deiconify .vgwin
502
 
 
503
 
    #cleanup for window closing
504
 
    bind .vgwin <Destroy>  {
505
 
        set winname %W
506
 
        if {$winname == ".vgwin"} {GRMap::cleanup}
507
 
    }
508
 
}
509
 
 
510
 
 
511
 
# get vector for vector group
512
 
proc GRMap::getxyvect { } {
513
 
    variable xyloc
514
 
    variable xymset
515
 
    variable xyvect
516
 
 
517
 
 
518
 
    # First, switch to xy mapset
519
 
    GRMap::setxyenv $xymset $xyloc
520
 
 
521
 
    set m [GSelect vector]
522
 
    set mname [lindex [split $m "@"] 0]
523
 
    if { $mname != "" } {
524
 
        if { $GRMap::xyvect == "" } {
525
 
            set GRMap::xyvect $mname
526
 
        } else {
527
 
            append xyvect ",$mname"
528
 
        }
529
 
    }
530
 
 
531
 
    # Return to georectified mapset
532
 
    GRMap::resetenv
533
 
 
534
 
}
535
 
 
536
 
proc GRMap::read_vgroup { xygroup } {
537
 
    variable xygdb
538
 
    variable xyloc
539
 
    variable xymset
540
 
    variable xyvect
541
 
    #get vector list from existing vector group REF file
542
 
 
543
 
    set vgfile "$xygdb/$xyloc/$xymset/group/$xygroup/VREF"
544
 
    if {![file exists $vgfile] } { return }
545
 
 
546
 
    # do the import
547
 
    set xyvect ""
548
 
    catch {set vlist [open $vgfile]}
549
 
    set vectnames [read $vlist]
550
 
        if {[catch {close $vlist} error]} {
551
 
                GmLib::errmsg $error
552
 
        }
553
 
   
554
 
    set vlines [split $vectnames "\n"]
555
 
    foreach vect $vlines {
556
 
        if { $xyvect == "" } {
557
 
            set GRMap::xyvect $vect
558
 
        } else {
559
 
            append GRMap::xyvect "," $vect
560
 
            set GRMap::xyvect [string trim $GRMap::xyvect ","]
561
 
        }
562
 
    }
563
 
}
564
 
 
565
 
proc GRMap::write_vgroup {xygroup xyvect} {
566
 
    #write vector list to vector group REF file
567
 
 
568
 
    variable xygdb
569
 
    variable xyloc
570
 
    variable xymset
571
 
 
572
 
    set vgfile "$xygdb/$xyloc/$xymset/group/$xygroup/VREF"
573
 
 
574
 
    # if group directory doesn't exist, create it
575
 
 
576
 
    if {![file isdirectory [file dirname $vgfile]] } {
577
 
            file mkdir [file dirname $vgfile]
578
 
    }
579
 
 
580
 
    if { $xyvect == "" } { return }
581
 
 
582
 
    # write out vector group file
583
 
    set vlist [split $xyvect ,]
584
 
    catch {set output [open $vgfile w ]}
585
 
                foreach vect $vlist {
586
 
                        puts $output $vect
587
 
                }
588
 
        if {[catch {close $output} error]} {
589
 
                GmLib::errmsg $error
590
 
        }
591
 
 
592
 
}
593
 
 
594
 
 
595
 
 
596
 
###############################################################################
597
 
# create dialog to select mapset (and location) and raster map to profile,
598
 
# and start georectifying canvas
599
 
 
600
 
proc GRMap::startup { } {
601
 
    variable currgdb
602
 
    variable currloc
603
 
    variable currmset
604
 
    variable xygdb
605
 
    variable xyloc
606
 
    variable xymset
607
 
    variable xygroup
608
 
    variable xymap
609
 
    variable maptype
610
 
    variable initwd
611
 
    variable initht
612
 
    global env
613
 
    global bgcolor
614
 
    global iconpath
615
 
    
616
 
    set grstarttitle [G_msg "GRASS Georectifier"]
617
 
    toplevel .grstart
618
 
 
619
 
    wm title .grstart [G_msg $grstarttitle]
620
 
    wm withdraw .grstart
621
 
 
622
 
    # create frames for georectify startup
623
 
 
624
 
    set grstart_mf [MainFrame .grstart.mf \
625
 
            -textvariable GRMap::grstartmsg]
626
 
 
627
 
    set GRMap::grstartmsg [G_msg "Set up environment for georectifying rasters or vectors"]
628
 
 
629
 
    set grstartup [$grstart_mf getframe ]
630
 
 
631
 
    # toolbar creation
632
 
    set grstart_tb  [$grstart_mf addtoolbar]
633
 
 
634
 
    # select raster or vector
635
 
    set selrast [radiobutton $grstart_tb.rast -variable GRMap::maptype -value "rast" \
636
 
        -text [G_msg "Georeference raster"] -highlightthickness 0 \
637
 
        -activebackground $bgcolor -highlightbackground $bgcolor -bg $bgcolor]
638
 
        $selrast select
639
 
    set selvect [radiobutton $grstart_tb.vect -variable GRMap::maptype -value "vect" \
640
 
        -text [G_msg "Georeference vector"] -highlightthickness 0 \
641
 
        -activebackground $bgcolor -highlightbackground $bgcolor  -bg $bgcolor]
642
 
    pack $selrast $selvect -side left
643
 
    pack $grstart_tb -side left -fill both -expand no -padx 5 -pady 3
644
 
 
645
 
    # set xy mapset
646
 
    set row [ frame $grstartup.mset -bg $bgcolor]
647
 
    Button $row.a -text [G_msg "1. Select mapset"] \
648
 
        -highlightthickness 0 -takefocus 0 -relief raised -borderwidth 1  \
649
 
        -helptext [G_msg "Mapset of xy raster group"]\
650
 
        -width 16 -anchor w \
651
 
        -command {GRMap::getmset}
652
 
    Entry $row.b -width 35 -text "$GRMap::xymset" \
653
 
          -textvariable GRMap::xymset
654
 
    pack $row.a $row.b -side left
655
 
    pack $row -side top -fill both -expand yes -padx 5 -pady 1
656
 
 
657
 
    # Create raster or vector group
658
 
    set row [ frame $grstartup.group -bg $bgcolor]
659
 
    Button $row.a -text [G_msg "2. Create/edit group"] \
660
 
        -highlightthickness 0 -takefocus 0 -relief raised -borderwidth 1  \
661
 
        -helptext [G_msg "Create/edit group (rasters or vectors to georectify)"] \
662
 
        -width 16 -anchor w \
663
 
        -command {GRMap::group}
664
 
    pack $row.a -side left
665
 
    pack $row -side top -fill both -expand yes -padx 5 -pady 1
666
 
 
667
 
    # set xy group
668
 
    set row [ frame $grstartup.selgroup -bg $bgcolor]
669
 
    Button $row.a -text [G_msg "3. Select group"] \
670
 
        -highlightthickness 0 -takefocus 0 -relief raised -borderwidth 1  \
671
 
        -helptext [G_msg "Select existing group to georectify"]\
672
 
        -width 16 -anchor w \
673
 
                -command {GRMap::getxygroup 0}
674
 
    Entry $row.b -width 35 -text "$GRMap::xygroup" \
675
 
          -textvariable GRMap::xygroup
676
 
    pack $row.a $row.b -side left
677
 
    pack $row -side top -fill both -expand yes -padx 5 -pady 1
678
 
 
679
 
    # set xy raster or vector
680
 
    set row [ frame $grstartup.map -bg $bgcolor]
681
 
    Button $row.a -text [G_msg "4. Select map"] \
682
 
        -highlightthickness 0 -takefocus 0 -relief raised -borderwidth 1  \
683
 
        -helptext [G_msg "Select non-georectified raster or vector to display for marking ground control points"]\
684
 
        -width 16 -anchor w \
685
 
        -command {GRMap::getxymap $GRMap::maptype}
686
 
    Entry $row.b -width 35 -text "$GRMap::xymap" \
687
 
          -textvariable GRMap::xymap
688
 
    pack $row.a $row.b -side left
689
 
    pack $row -side top -fill both -expand yes -padx 5 -pady 1
690
 
 
691
 
    # Start georectify canvas
692
 
    set row [ frame $grstartup.start -bg $bgcolor]
693
 
    Button $row.a -text [G_msg "5. Start georectifying"] \
694
 
        -highlightthickness 0 -takefocus 0 -relief raised -borderwidth 1  \
695
 
        -helptext [G_msg "Start georectifying"]\
696
 
        -width 16 -anchor w -highlightthickness 0 \
697
 
                -command "GRMap::refmap"
698
 
    pack $row.a -side left
699
 
    pack $row -side top -fill both -expand yes -padx 5 -pady 1
700
 
 
701
 
    # quit
702
 
    set row [ frame $grstartup.quit -bg $bgcolor]
703
 
    Button $row.a -text [G_msg "Cancel"] \
704
 
        -highlightthickness 0 -takefocus 0 -relief raised -borderwidth 1  \
705
 
        -helptext [G_msg "Cancel georectification"]\
706
 
        -width 16 -anchor w -highlightthickness 0 \
707
 
        -command "destroy .grstart"
708
 
        Button $row.b -text [G_msg "Help"] \
709
 
                -image [image create photo -file "$iconpath/gui-help.gif"] \
710
 
                -command "spawn g.manual --q gm_georect" \
711
 
                -background $bgcolor \
712
 
                -helptext [G_msg "Help"]
713
 
    pack $row.a -side left
714
 
    pack $row.b -side right
715
 
    pack $row -side top -fill both -expand yes -padx 5 -pady 1
716
 
 
717
 
 
718
 
    pack $grstart_mf
719
 
    pack $grstartup -side top -fill both -expand yes
720
 
 
721
 
    wm deiconify .grstart
722
 
    raise .grstart
723
 
    focus -force .grstart
724
 
 
725
 
    #cleanup for window closing
726
 
    #bind .grstart <Destroy> "GRMap::cleanup %W"
727
 
    bind .grstart <Destroy> {
728
 
        if { "%W" == ".grstart" } { GRMap::cleanup }
729
 
    }
730
 
 
731
 
 
732
 
}
733
 
 
734
 
 
735
 
###############################################################################
736
 
 
737
 
# Create window and canvas for displaying xy raster or vector as reference map for
738
 
# selecting ground control points in the xy system
739
 
 
740
 
proc GRMap::refmap { } {
741
 
    variable initwd
742
 
    variable initht
743
 
    variable grcursor
744
 
    variable grcanvas_w
745
 
    variable grcanvas_h
746
 
    variable mappid
747
 
    variable grmapframe
748
 
    variable grcan
749
 
    variable map_ind
750
 
    variable grfile
751
 
    variable coords
752
 
    variable tmpdir
753
 
    variable xyloc
754
 
    variable xymset
755
 
    variable xygroup
756
 
    variable xymap
757
 
    variable maptype
758
 
    variable msg
759
 
    variable grcoords_mov
760
 
    global env
761
 
    global drawprog
762
 
    global grcoords
763
 
 
764
 
    if { $xymset=="" || $xygroup=="" || $xymap=="" } {
765
 
            return
766
 
            }
767
 
 
768
 
    # close dialog to select mapset and raster
769
 
    destroy .grstart
770
 
    
771
 
    #start gcp window
772
 
    GRMap::gcpwin
773
 
 
774
 
    # set environment to xy location
775
 
    GRMap::setxyenv $xymset $xyloc
776
 
 
777
 
    # need to turn off wind_override here
778
 
 
779
 
    # Initialize window and map geometry
780
 
    set grcanvas_w $initwd
781
 
    set grcanvas_h $initht
782
 
    set env(GRASS_WIDTH) $initwd
783
 
    set env(GRASS_HEIGHT) $initht
784
 
    set drawprog 0
785
 
 
786
 
    # Make sure that we are using the WIND file for everything except displays
787
 
    if {[info exists env(WIND_OVERRIDE)]} {unset env(WIND_OVERRIDE)}
788
 
 
789
 
    # Set display geometry to the current region settings (from WIND file)
790
 
    GRMap::zoom_gregion
791
 
 
792
 
 
793
 
    # Zoom to map to georectify
794
 
    if { $maptype == "rast" } {
795
 
        GRMap::zoom_gregion [list "rast=$xymap"]
796
 
    } elseif { $maptype == "vect" } {
797
 
        GRMap::zoom_gregion [list "vect=$xymap"]
798
 
    }
799
 
 
800
 
    # Create canvas monitor as top level mainframe
801
 
    toplevel .mapgrcan
802
 
    wm title .mapgrcan [G_msg "Displaying xy map to be georectified"]
803
 
 
804
 
    set grmapframe [MainFrame .mapgrcan.mf \
805
 
            -textvariable GRMap::msg \
806
 
            -progressvar drawprog -progressmax 100 -progresstype incremental]
807
 
 
808
 
    set mf_frame [$grmapframe getframe]
809
 
 
810
 
    # toolbar creation
811
 
    set map_tb  [$grmapframe addtoolbar]
812
 
    GRToolBar::create $map_tb
813
 
 
814
 
    # canvas creation
815
 
    set grcan [canvas $mf_frame.grcanvas \
816
 
        -borderwidth 0 -closeenough 10.0 -relief groove \
817
 
        -width $grcanvas_w -height $grcanvas_h ]
818
 
 
819
 
    # setting geometry
820
 
    place $grcan -in $mf_frame -x 0 -y 0 -anchor nw
821
 
 
822
 
    pack $grcan -fill both -expand yes
823
 
 
824
 
    # indicator creation
825
 
    set map_ind [$grmapframe addindicator -textvariable grcoords_mov \
826
 
        -width 33 -justify left -padx 5 -bg white]
827
 
 
828
 
    pack $grmapframe -fill both -expand yes
829
 
 
830
 
    set grcursor [$grcan cget -cursor]
831
 
 
832
 
    GRMap::coordconv
833
 
 
834
 
    # bindings for display canvas
835
 
 
836
 
    # mouse handlers
837
 
    # The coordinate transforms should be done per monitor.
838
 
    bind $grcan <ButtonPress-1> {
839
 
            set eastcoord [eval GRMap::scrx2mape %x]
840
 
            set northcoord [eval GRMap::scry2mapn %y]
841
 
            set grcoords "$eastcoord $northcoord"
842
 
    }
843
 
 
844
 
    # Displays geographic coordinates in indicator window when cursor moved across canvas
845
 
    bind $grcan <Motion> {
846
 
            set scrxmov %x
847
 
            set scrymov %y
848
 
            set eastcoord [eval GRMap::scrx2mape %x]
849
 
            set northcoord [eval GRMap::scry2mapn %y]
850
 
            set grcoords_mov "$eastcoord $northcoord"
851
 
    }
852
 
 
853
 
 
854
 
    # TSW - inserting key command ability into gis.m
855
 
    # 9 May 2006
856
 
    # set some key commands to speed use
857
 
 
858
 
    # Return to previous zoom
859
 
    bind .mapgrcan <KeyPress-r> {
860
 
        GRMap::zoom_back
861
 
    }
862
 
 
863
 
    # set key strokes to change between tools
864
 
    # I've provided strokes for both right and left handed
865
 
    # mouse users
866
 
 
867
 
    # Right handed
868
 
    # x - pointer
869
 
    # Zoom in - zoom in
870
 
    # zoom ouT - zoom out
871
 
    # pAn - pan
872
 
    # Query - query
873
 
 
874
 
    bind .mapgrcan <KeyPress-x> {
875
 
            GRToolBar::changebutton pointer
876
 
            GRMap::stoptool
877
 
    }
878
 
    bind .mapgrcan <KeyPress-z> {
879
 
            GRMap::stoptool
880
 
            GRToolBar::changebutton zoomin
881
 
            GRMap::zoombind 1
882
 
    }
883
 
    bind .mapgrcan <KeyPress-t> {
884
 
            GRMap::stoptool
885
 
            GRToolBar::changebutton zoomout
886
 
            GRMap::zoombind -1
887
 
    }
888
 
    bind .mapgrcan <KeyPress-a> {
889
 
            GRMap::stoptool
890
 
            GRToolBar::changebutton pan
891
 
            GRMap::panbind
892
 
    }
893
 
 
894
 
    # Left handed
895
 
    # poiNter - pointer
896
 
    # zoom In - zoom in
897
 
    # zoom Out - zoom out
898
 
    # Pan - pan
899
 
    # ? - query
900
 
 
901
 
    bind .mapgrcan <KeyPress-n> {
902
 
            GRToolBar::changebutton pointer
903
 
            GRMap::stoptool
904
 
    }
905
 
    bind .mapgrcan <KeyPress-i> {
906
 
            GRMap::stoptool
907
 
            GRToolBar::changebutton zoomin
908
 
            GRMap::zoombind 1
909
 
    }
910
 
    bind .mapgrcan <KeyPress-o> {
911
 
            GRMap::stoptool
912
 
            GRToolBar::changebutton zoomout
913
 
            GRMap::zoombind -1
914
 
    }
915
 
    bind .mapgrcan <KeyPress-p> {
916
 
            GRMap::stoptool
917
 
            GRToolBar::changebutton pan
918
 
            GRMap::panbind
919
 
    }
920
 
 
921
 
 
922
 
    # window configuration change handler for resizing
923
 
    bind $grcan <Configure> "GRMap::do_resize"
924
 
 
925
 
    #return to georectified location
926
 
    GRMap::resetenv
927
 
 
928
 
    #default selector tool
929
 
    GRMap::selector
930
 
 
931
 
    # bindings for closing windows
932
 
    bind .mapgrcan <Destroy> {
933
 
        if { "%W" == ".mapgrcan" } { GRMap::cleanup }
934
 
    }
935
 
 
936
 
}
937
 
 
938
 
###############################################################################
939
 
# create form for gcp management
940
 
proc GRMap::gcpwin {} {
941
 
    variable xygdb
942
 
    variable xyloc
943
 
    variable xymset
944
 
    variable xygroup
945
 
    variable gcpnum
946
 
    variable usegcp
947
 
    variable maptype
948
 
    variable xy
949
 
    variable geoc
950
 
    variable chk
951
 
    variable fwd
952
 
    variable rev
953
 
    variable rectorder
954
 
    variable fwd_error
955
 
    variable rev_error
956
 
    variable fwd_rmserror
957
 
    variable rev_rmserror
958
 
    variable drawform
959
 
    variable clipregion
960
 
    global xyentry
961
 
    global geoentry
962
 
    global b1coords
963
 
    
964
 
    set fwd_rmssumsq 0.0
965
 
    set fwd_rmserror 0.0
966
 
    set rev_rmssumsq 0.0
967
 
    set rev_rmserror 0.0
968
 
 
969
 
 
970
 
    toplevel .gcpwin
971
 
 
972
 
    set gcp_mf [MainFrame .gcpwin.mf \
973
 
        -textvariable GRMap::gcpmsg]
974
 
 
975
 
    set gcp_frame [$gcp_mf getframe]
976
 
 
977
 
    # toolbar creation
978
 
    set gcp_tb  [$gcp_mf addtoolbar]
979
 
    GRMap::gcptb $gcp_tb
980
 
 
981
 
    # gcp form creation
982
 
    set gcp_sw [ScrolledWindow $gcp_frame.sw -relief flat \
983
 
        -borderwidth 1 ]
984
 
    set gcp_sf [ScrollableFrame $gcp_sw.sf -height 200 -width 750]
985
 
    $gcp_sw setwidget $gcp_sf
986
 
 
987
 
    set gcpframe [$gcp_sf getframe]
988
 
 
989
 
    pack $gcp_sw -fill both -expand yes
990
 
 
991
 
    set gcp [frame $gcpframe.fr]
992
 
    pack $gcp -fill both -expand yes
993
 
 
994
 
 
995
 
    pack $gcp_mf -side top -expand yes -fill both -anchor n
996
 
    pack $gcp_tb -side left -expand yes -fill x
997
 
 
998
 
 
999
 
    # Scroll the options window with the mouse
1000
 
    bind_scroll $gcp_sf
1001
 
 
1002
 
    if { $maptype == "vect" } {
1003
 
        set rbstate "disabled"
1004
 
    } else {
1005
 
        set rbstate "normal"
1006
 
    }
1007
 
 
1008
 
    # setting rectification method
1009
 
    set row [ frame $gcp.method ]
1010
 
    Label $row.a -text [G_msg "Select rectification method for rasters"] \
1011
 
        -fg MediumBlue
1012
 
    set first [radiobutton $row.b -variable GRMap::rectorder -value 1 \
1013
 
        -text [G_msg "1st order"] -highlightthickness 0]
1014
 
        DynamicHelp::register $first balloon [G_msg "affine transformation \
1015
 
            (rasters & vectors). Requires 3+ GCPs."]
1016
 
        $first select
1017
 
 
1018
 
    set second [radiobutton $row.c -variable GRMap::rectorder -value 2 \
1019
 
        -text [G_msg "2nd order"] -highlightthickness 0 -state $rbstate]
1020
 
        DynamicHelp::register $second balloon [G_msg "polynomial transformation \
1021
 
                (rasters only). Requires 6+ GCPs."]
1022
 
 
1023
 
    set third [radiobutton $row.d -variable GRMap::rectorder -value 3 \
1024
 
        -text [G_msg "3rd order"] -highlightthickness 0 -state $rbstate]
1025
 
        DynamicHelp::register $third balloon [G_msg "polynomial transformation \
1026
 
                (rasters only). Requires 10+ GCPs."]
1027
 
        
1028
 
    Label $row.e -text [G_msg "Clip map/image to target region"] \
1029
 
        -fg MediumBlue
1030
 
        
1031
 
    set clip [checkbutton $row.f -takefocus 0 -variable GRMap::clipregion]
1032
 
 
1033
 
    pack $row.a $row.b $row.c $row.d -side left
1034
 
    pack $row.f $row.e -side right
1035
 
    pack $row -side top -fill both -expand yes
1036
 
 
1037
 
    set row [ frame $gcp.header ]
1038
 
    Label $row.a -text [G_msg "Use"] \
1039
 
        -fg MediumBlue -width 3
1040
 
    Label $row.b -text [G_msg "xy coordinates"] \
1041
 
        -fg MediumBlue -width 34
1042
 
    Label $row.c -text [G_msg "geographic coordinates"] \
1043
 
        -fg MediumBlue -width 35
1044
 
    Label $row.d -text [G_msg "forward error"] \
1045
 
        -fg MediumBlue -width 15
1046
 
    Label $row.e -text [G_msg "backward error"] \
1047
 
        -fg MediumBlue -width 15
1048
 
    pack $row.a $row.b $row.c $row.d $row.e -side left
1049
 
    pack $row -side top -fill both -expand yes
1050
 
 
1051
 
    for {set gcpnum 1} {$gcpnum < 51 } { incr gcpnum } {
1052
 
        if {$gcpnum == 51} {break}
1053
 
        set GRMap::usegcp($gcpnum) 1
1054
 
        set row [ frame $gcp.row$gcpnum -bd 0]
1055
 
        set chk($gcpnum) [checkbutton $row.a \
1056
 
                -takefocus 0 \
1057
 
                -variable GRMap::usegcp($gcpnum)]
1058
 
        set fwd_error($gcpnum) 0.0
1059
 
        set rev_error($gcpnum) 0.0
1060
 
 
1061
 
        set xy($gcpnum) [entry $row.b -width 35  -bd 0 ]
1062
 
        bind $xy($gcpnum) <FocusIn> "set xyentry %W"
1063
 
 
1064
 
        set geoc($gcpnum) [entry $row.c -width 35 -bd 0]
1065
 
        bind $geoc($gcpnum) <FocusIn> "set geoentry %W"
1066
 
 
1067
 
        set fwd($gcpnum) [entry $row.d -width 15 -text GRMap::fwd_error($gcpnum) \
1068
 
                 -bd 0 -takefocus 0 -textvariable GRMap::fwd_error($gcpnum)]
1069
 
 
1070
 
        set rev($gcpnum) [entry $row.e -width 15 -text GRMap::rev_error($gcpnum) \
1071
 
                 -bd 0 -takefocus 0 -textvariable GRMap::rev_error($gcpnum) ]
1072
 
 
1073
 
        pack $chk($gcpnum) $xy($gcpnum) $geoc($gcpnum) $fwd($gcpnum) $rev($gcpnum) -side left
1074
 
        pack $row -side top -fill both -expand yes
1075
 
    }
1076
 
 
1077
 
    GRMap::get_gcp
1078
 
    if {$gcpnum >2} {
1079
 
            GRMap::gcp_error
1080
 
        }
1081
 
 
1082
 
    set GRMap::gcpmsg "Forward RMS error = $fwd_rmserror, backward RMS error = $rev_rmserror"
1083
 
 
1084
 
    # set the focus to the first entry
1085
 
    focus -force $xy(1)
1086
 
 
1087
 
    wm title .gcpwin [G_msg "Manage ground control points (GCPs)"]
1088
 
    wm withdraw .gcpwin
1089
 
    wm deiconify .gcpwin
1090
 
 
1091
 
    # cleanup for window closing
1092
 
    bind .gcpwin <Destroy> {
1093
 
        if { "%W" == ".gcpwin" } { GRMap::cleanup }
1094
 
    }
1095
 
 
1096
 
}
1097
 
 
1098
 
 
1099
 
# toolbar for gcp manager window
1100
 
proc GRMap::gcptb { gcptb } {
1101
 
    global bgcolor
1102
 
    global iconpath
1103
 
 
1104
 
    # gcp management buttons
1105
 
    set bbox [ButtonBox $gcptb.bbox1 -spacing 0 -homogeneous 1 ]
1106
 
 
1107
 
    # save
1108
 
    $bbox add -image [image create photo -file "$iconpath/file-save.gif"] \
1109
 
        -command "GRMap::savegcp" \
1110
 
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1  \
1111
 
        -highlightbackground $bgcolor  -activebackground $bgcolor\
1112
 
        -helptext [G_msg "Save GCPs to POINTS file"]
1113
 
 
1114
 
    # clear
1115
 
    $bbox add -image [image create photo -file "$iconpath/gui-gcperase.gif"] \
1116
 
        -command "GRMap::cleargcp" \
1117
 
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1  \
1118
 
        -highlightbackground $bgcolor  -activebackground $bgcolor\
1119
 
        -helptext [G_msg "Clear all unchecked GCP entries"]
1120
 
 
1121
 
    # rms
1122
 
    $bbox add -image [image create photo -file "$iconpath/gui-rms.gif"] \
1123
 
        -command "GRMap::gcp_error" \
1124
 
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1  \
1125
 
        -highlightbackground $bgcolor  -activebackground $bgcolor\
1126
 
        -helptext [G_msg "Calculate RMS error"]
1127
 
 
1128
 
    # rectify
1129
 
    $bbox add -image [image create photo -file "$iconpath/gui-georect.gif"] \
1130
 
        -command "GRMap::rectify" \
1131
 
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1  \
1132
 
        -highlightbackground $bgcolor  -activebackground $bgcolor\
1133
 
        -helptext [G_msg "Rectify maps in group"]
1134
 
 
1135
 
    # quit
1136
 
    $bbox add -text [G_msg "Quit"] \
1137
 
        -command {destroy .gcpwin .mapgrcan} \
1138
 
        -highlightthickness 0 -takefocus 0 -relief link -borderwidth 1  \
1139
 
        -highlightbackground $bgcolor  -activebackground $bgcolor\
1140
 
        -helptext [G_msg "Exit georectifier"]
1141
 
        
1142
 
        set helpbtn [Button $gcptb.help -text [G_msg "Help"] \
1143
 
                -image [image create photo -file "$iconpath/gui-help.gif"] \
1144
 
                -command "spawn g.manual --q gm_georect" \
1145
 
                -background $bgcolor -borderwidth 1 \
1146
 
                -helptext [G_msg "Help"]]
1147
 
                
1148
 
            pack $helpbtn -side right -anchor e
1149
 
        pack $bbox -side left -anchor w -expand no -fill y
1150
 
        
1151
 
}
1152
 
 
1153
 
 
1154
 
proc GRMap::get_gcp { } {
1155
 
    # import any existing points file for raster or gcp file for raster or vector
1156
 
 
1157
 
    variable xygdb
1158
 
    variable xyloc
1159
 
    variable xymset
1160
 
    variable xygroup
1161
 
    variable gcpnum
1162
 
    variable usegcp
1163
 
    variable xy
1164
 
    variable geoc
1165
 
    variable chk
1166
 
    variable rectorder
1167
 
    variable fwd_error
1168
 
    variable rev_error
1169
 
 
1170
 
    set gcpfile "$xygdb/$xyloc/$xymset/group/$xygroup/POINTS"
1171
 
    if {[file exists $gcpfile] } {
1172
 
        # do the import
1173
 
        set gcpnum 1
1174
 
        catch {set pfile [open $gcpfile]}
1175
 
        set points [read $pfile]
1176
 
                if {[catch {close $pfile} error]} {
1177
 
                        GmLib::errmsg $error
1178
 
                }
1179
 
        regsub -all {[ ]+} $points " " points
1180
 
        set plines [split $points "\n"]
1181
 
        foreach gcpline $plines {
1182
 
            if {[string match {\#*} $gcpline]} continue
1183
 
            if {$gcpline == "" } continue
1184
 
            set gcpline [string trim $gcpline " "]
1185
 
            set fields [split $gcpline { }]
1186
 
            # assign variables
1187
 
            $xy($gcpnum) insert     0 "[lindex $fields 0] [lindex $fields 1]"
1188
 
            $geoc($gcpnum) insert 0 "[lindex $fields 2] [lindex $fields 3]"
1189
 
            set usegcp($gcpnum)     "[lindex $fields 4]"
1190
 
            incr gcpnum
1191
 
        }
1192
 
    }
1193
 
}
1194
 
 
1195
 
 
1196
 
# save GCP's to POINTS file in xy location and mapset
1197
 
proc GRMap::savegcp {} {
1198
 
    variable xygdb
1199
 
    variable xyloc
1200
 
    variable xymset
1201
 
    variable xygroup
1202
 
    variable currloc
1203
 
    variable currmset
1204
 
    variable gcpnum
1205
 
    variable maptype
1206
 
    variable xy
1207
 
    variable geoc
1208
 
    variable usegcp
1209
 
    variable array gcpline #array to store gcp coordinates as text for output
1210
 
 
1211
 
    set gcpfile "$xygdb/$xyloc/$xymset/group/$xygroup/POINTS"
1212
 
    catch {set output [open $gcpfile w ]}
1213
 
    puts $output "# Ground Control Points File"
1214
 
    puts $output "# "
1215
 
    puts $output "# target location: $currloc"
1216
 
    puts $output "# target mapset: $currmset"
1217
 
    puts $output "#unrectified xy     georectified east north     1=use gcp point"
1218
 
    puts $output "#--------------     -----------------------     ---------------"
1219
 
    set rowcount 0
1220
 
 
1221
 
    for {set gcpnum 1} {$gcpnum < 51 } { incr gcpnum } {
1222
 
        if { $maptype == "rast" } {
1223
 
            if { [$xy($gcpnum) get] != "" && [$geoc($gcpnum) get] != ""} {
1224
 
                set gcpline($gcpnum) "[$xy($gcpnum) get]"
1225
 
                append gcpline($gcpnum) "     [$geoc($gcpnum) get]"
1226
 
                append gcpline($gcpnum) "     $usegcp($gcpnum)"
1227
 
                puts $output $gcpline($gcpnum)
1228
 
                incr rowcount
1229
 
            }
1230
 
        } elseif { $maptype == "vect" } {
1231
 
            if { [$xy($gcpnum) get] != "" && [$geoc($gcpnum) get] != "" && $usegcp($gcpnum) == 1} {
1232
 
                set gcpline($gcpnum) "[$xy($gcpnum) get]"
1233
 
                append gcpline($gcpnum) "     [$geoc($gcpnum) get]"
1234
 
                append gcpline($gcpnum) "     $usegcp($gcpnum)"
1235
 
                puts $output $gcpline($gcpnum)
1236
 
                incr rowcount
1237
 
            }
1238
 
        }
1239
 
    }
1240
 
    
1241
 
        if {[catch {close $output} error]} {
1242
 
                GmLib::errmsg $error
1243
 
        }
1244
 
 
1245
 
}
1246
 
 
1247
 
 
1248
 
proc GRMap::gcp_error { } {
1249
 
    # calculate error for each gcp and total RMS error - projected forward and reverse
1250
 
 
1251
 
    variable xygdb
1252
 
    variable xyloc
1253
 
    variable xymset
1254
 
    variable xygroup
1255
 
    variable rectorder
1256
 
    variable fwd_error
1257
 
    variable rev_error
1258
 
    variable errorlist
1259
 
    variable gcpnum
1260
 
    variable fwd_rmserror
1261
 
    variable rev_rmserror
1262
 
 
1263
 
    set fwd_rmssumsq 0.0
1264
 
    set fwd_rmserror 0.0
1265
 
    set rev_rmssumsq 0.0
1266
 
    set rev_rmserror 0.0
1267
 
 
1268
 
    set errorlist ""
1269
 
 
1270
 
    # save current GCP values to POINTS file to use in error calculations
1271
 
    GRMap::savegcp
1272
 
 
1273
 
    set gcpfile "$xygdb/$xyloc/$xymset/group/$xygroup/POINTS"
1274
 
    if {![file exists $gcpfile] } { return }
1275
 
 
1276
 
    # First, switch to xy mapset
1277
 
    GRMap::setxyenv $xymset $xyloc
1278
 
    # calculate diagonal distance error for each GCP
1279
 
    catch {set input [open "|g.transform group=$xygroup order=$rectorder"]}
1280
 
    set errorlist [read $input]
1281
 
        if {[catch {close $input} error]} {
1282
 
                GmLib::errmsg $error
1283
 
        }
1284
 
 
1285
 
    # Return to georectified mapset
1286
 
    GRMap::resetenv
1287
 
 
1288
 
    set gcpnum 1
1289
 
    foreach {fwd rev} $errorlist {
1290
 
        set GRMap::fwd_error($gcpnum) $fwd
1291
 
        set GRMap::rev_error($gcpnum) $rev
1292
 
        set fwd_rmssumsq [expr $fwd_rmssumsq + pow($fwd,2)]
1293
 
        set rev_rmssumsq [expr $rev_rmssumsq + pow($rev,2)]
1294
 
        incr gcpnum
1295
 
    }
1296
 
 
1297
 
    # calculate total rms error for all points
1298
 
    set GRMap::fwd_rmserror [expr sqrt($fwd_rmssumsq/$gcpnum)]
1299
 
    set GRMap::rev_rmserror [expr sqrt($rev_rmssumsq/$gcpnum)]
1300
 
 
1301
 
    # update value in status bar
1302
 
    set GRMap::gcpmsg "Forward RMS error = $fwd_rmserror, backward RMS error = $rev_rmserror"
1303
 
}
1304
 
 
1305
 
 
1306
 
# run i.rectify to rectify raster group or v.transform to rectify vector
1307
 
proc GRMap::rectify { } {
1308
 
    variable xygdb
1309
 
    variable xyloc
1310
 
    variable currloc
1311
 
    variable xymset
1312
 
    variable currmset
1313
 
    variable xygroup
1314
 
    variable xyvect
1315
 
    variable maptype
1316
 
    variable mappid
1317
 
    variable selftarget
1318
 
    variable rectorder
1319
 
 
1320
 
 
1321
 
    set gcpfile "$xygdb/$xyloc/$xymset/group/$xygroup/POINTS"
1322
 
    if {![file exists $gcpfile] } {
1323
 
            set msg [G_msg "There is no POINTS file of ground control points for group.\
1324
 
                    You must create ground control points before georectifying map."]
1325
 
            tk_messageBox -message $msg -parent .gcpwin -type ok
1326
 
            return
1327
 
    }
1328
 
 
1329
 
    # count useable GCP's in points file
1330
 
    set gcpcnt 0
1331
 
    catch {set pfile [open $gcpfile]}
1332
 
    set points [read $pfile]
1333
 
        if {[catch {close $pfile} error]} {
1334
 
                GmLib::errmsg $error
1335
 
        }
1336
 
 
1337
 
    regsub -all {[ ]+} $points " " points
1338
 
    set plines [split $points "\n"]
1339
 
    foreach gcpline $plines {
1340
 
        if {[string match {\#*} $gcpline]} continue
1341
 
        if {$gcpline == "" } continue
1342
 
        set gcpline [string trim $gcpline " "]
1343
 
        set fields [split $gcpline { }]
1344
 
        # count gcps
1345
 
        if {[lindex $fields 0]!="" && [lindex $fields 1]!="" && [lindex $fields 2]!=""
1346
 
            && [lindex $fields 3]!="" && [lindex $fields 4]==1} {
1347
 
            incr gcpcnt
1348
 
        }
1349
 
    }
1350
 
 
1351
 
    if { $maptype == "rast" } {
1352
 
        if { $gcpcnt<3 || ($gcpcnt<6 && $rectorder==2) || ($gcpcnt<10 && $rectorder==3) } {
1353
 
            set msg [G_msg "Insufficient ground control points for georectification method.\
1354
 
                    You need at least 3 points for 1st order, 6 points for 2nd order and 10 points for 3rd order."]
1355
 
            tk_messageBox -message $msg -parent .gcpwin -type ok
1356
 
            return
1357
 
        }
1358
 
        # run i.rectify on raster group
1359
 
        # First, switch to xy mapset
1360
 
        GRMap::setxyenv $xymset $xyloc
1361
 
        
1362
 
#         set message_env [exec g.gisenv get=GRASS_MESSAGE_FORMAT]
1363
 
#         set env(GRASS_MESSAGE_FORMAT) gui
1364
 
#               if {![catch {open [concat "|i.rectify" "-ca" "group=$xygroup" "extension=$mappid" "order=$rectorder"] r} fh]} {
1365
 
#                       while {[gets $fh line] >= 0} {
1366
 
#                               puts "line = $line"
1367
 
#                       }
1368
 
#               }
1369
 
1370
 
#         set env(GRASS_MESSAGE_FORMAT) $message_env
1371
 
#         
1372
 
#               if {[catch {close $fh} error]} {
1373
 
#                       puts $error
1374
 
#               }
1375
 
 
1376
 
        set cmd "i.rectify -a group=$xygroup extension=$mappid order=$rectorder"
1377
 
        if { $GRMap::clipregion == 1 } { append cmd " -c"}
1378
 
        
1379
 
        run_panel $cmd
1380
 
        # Return to georectified mapset
1381
 
        GRMap::resetenv
1382
 
    } elseif { $maptype == "vect" } {
1383
 
        if { $gcpcnt < 1 } {
1384
 
            set msg [G_msg "No valid ground control points in GCP file.\
1385
 
            You must create valid ground control points before georectifying map."]
1386
 
            tk_messageBox -message $msg -parent .gcpwin -type ok
1387
 
            return
1388
 
        }
1389
 
 
1390
 
        # loop to rectify all vectors in VREF file using v.transform
1391
 
        GRMap::read_vgroup $xygroup
1392
 
        set vlist [split $xyvect ,]
1393
 
        set outcount 1
1394
 
        foreach vect $vlist {
1395
 
            set outname "$vect"
1396
 
            append outname "_$mappid"
1397
 
            # First, switch to xy mapset
1398
 
            GRMap::setxyenv $xymset $xyloc
1399
 
            set cmd "v.transform --q input=$vect output=$outname pointsfile=$gcpfile"
1400
 
            runcmd $cmd
1401
 
            # Return to georectified mapset
1402
 
            GRMap::resetenv
1403
 
            # copy vector file from source to target location and mapset
1404
 
            if { $selftarget == 0 } {
1405
 
                set xysource "$xygdb/$xyloc/$xymset/vector/$outname"
1406
 
                set xytarget "$xygdb/$currloc/$currmset/vector/$outname"
1407
 
                set xyfile "$xysource"
1408
 
                append xyfile "/coor"
1409
 
                set counter 1
1410
 
                # wait to make sure georectified file is written
1411
 
                while { $counter < 100 } {
1412
 
                    if { [file exists $xyfile] } {
1413
 
                        catch {file copy -force $xysource $xytarget}
1414
 
                        catch {file delete -force $xysource}
1415
 
                        set counter 101
1416
 
                    }
1417
 
                    after 100
1418
 
                    incr counter
1419
 
                }
1420
 
            }
1421
 
        }
1422
 
    } else {
1423
 
        GRMap::resetenv
1424
 
        return
1425
 
    }
1426
 
}
1427
 
 
1428
 
 
1429
 
# clear all GCP entries
1430
 
proc GRMap::cleargcp {} {
1431
 
    variable xy
1432
 
    variable geoc
1433
 
    variable usegcp
1434
 
    variable fwd
1435
 
    variable rev
1436
 
    variable gcpnum
1437
 
    variable grcan
1438
 
 
1439
 
    for {set gcpnum 1} {$gcpnum < 51 } { incr gcpnum } {
1440
 
        if {$usegcp($gcpnum) == 0} {
1441
 
                $xy($gcpnum) delete 0 end
1442
 
            $geoc($gcpnum) delete 0 end
1443
 
                $fwd($gcpnum) delete 0 end
1444
 
                $rev($gcpnum) delete 0 end
1445
 
                }
1446
 
    }
1447
 
    $grcan delete gcpvert gcphoriz
1448
 
}
1449
 
 
1450
 
###############################################################################
1451
 
 
1452
 
# Calculate boxes with a given aspect ratio.
1453
 
 
1454
 
# Sense - 0 means largest no larger, 1 means smallest no smaller
1455
 
# We will change box 1
1456
 
proc GRMap::shrinkwrap {sense nsew1 ar2 } {
1457
 
    foreach {n1 s1 e1 w1} $nsew1 {break}
1458
 
 
1459
 
    set ns1 [expr {$n1 - $s1}]
1460
 
    set ew1 [expr {$e1 - $w1}]
1461
 
 
1462
 
    # Width / height
1463
 
    # Big aspect ratio is wide, small aspect ratio is tall
1464
 
    set ar1 [expr { 1.0 * $ew1 / $ns1 }]
1465
 
 
1466
 
    # If box one is wider than box 2.
1467
 
    # (or box one isn't wider than box 2 and the sense is inverted)
1468
 
    if {($ar1 > $ar2) ^ $sense} {
1469
 
        # n1 and s1 are unchanged
1470
 
        # e1 and w1 must be scaled by ar2
1471
 
        set rn1 $n1
1472
 
        set rs1 $s1
1473
 
        set goal [expr {$ns1 * $ar2}]
1474
 
        set midpoint [expr {$w1 + $ew1 / 2}]
1475
 
        set re1 [expr {$midpoint + $goal / 2}]
1476
 
        set rw1 [expr {$midpoint - $goal / 2}]
1477
 
    } else {
1478
 
        # e1 and w1 are unchanged
1479
 
        # n1 and s1 must be scaled by 1/ar2
1480
 
        set re1 $e1
1481
 
        set rw1 $w1
1482
 
        set goal [expr {$ew1 / $ar2}]
1483
 
        set midpoint [expr {$s1 + $ns1 / 2}]
1484
 
        set rn1 [expr {$midpoint + $goal / 2}]
1485
 
        set rs1 [expr {$midpoint - $goal / 2}]
1486
 
    }
1487
 
 
1488
 
    set result [list $rn1 $rs1 $re1 $rw1]
1489
 
 
1490
 
    return $result
1491
 
}
1492
 
 
1493
 
###############################################################################
1494
 
# map display procedures
1495
 
 
1496
 
# draw map using png driver and open in canvas
1497
 
proc GRMap::drawmap { } {
1498
 
    variable grcanvas_h
1499
 
    variable grcanvas_w
1500
 
    variable grcan
1501
 
    variable grcanmodified
1502
 
    variable monitor_zooms
1503
 
    variable previous_monitor
1504
 
    variable xyloc
1505
 
    variable xymset
1506
 
 
1507
 
    set w [winfo width $grcan]
1508
 
    set h [winfo height $grcan]
1509
 
 
1510
 
    # Get whether or not the canvas was modified or zoomed
1511
 
    # grcanmodified has levels: 0  is none, 1 is zoom, 2 is geometry.
1512
 
    # 1 doesn't require new setting in explore mode
1513
 
    set mymodified $grcanmodified
1514
 
 
1515
 
    # Make sure grcanvas_h and grcanvas_w are correct
1516
 
    if { $grcanvas_w != $w || $grcanvas_h != $h } {
1517
 
        # Flag this as a modified canvas
1518
 
        # Modified canvas is level 2!
1519
 
        set mymodified 2
1520
 
        set grcanvas_w $w
1521
 
        set grcanvas_h $h
1522
 
    }
1523
 
 
1524
 
    # Redo the driver settings if the geometry has changed or
1525
 
    # if we weren't the previous monitor.
1526
 
    if {$mymodified != 0 } {
1527
 
        set grcanmodified 0
1528
 
        set previous_monitor "none"
1529
 
        # The canvas or view has been modified
1530
 
        # Redo the map settings to match the canvas
1531
 
        GRMap::driversettings
1532
 
    }
1533
 
 
1534
 
    # Render all the layers
1535
 
    GRMap::runprograms [expr {$mymodified != 0}]
1536
 
}
1537
 
 
1538
 
# Run the programs to clear the map and draw all of the layers
1539
 
proc GRMap::runprograms { mod } {
1540
 
    variable grcan
1541
 
    variable grcanvas_w
1542
 
    variable grcanvas_h
1543
 
    variable grmapframe
1544
 
    variable grfile
1545
 
    variable tmpdir
1546
 
    variable xygroup
1547
 
    variable xygdb
1548
 
    variable xyloc
1549
 
    variable xymset
1550
 
    variable xymap
1551
 
    variable maptype
1552
 
    variable xygroup
1553
 
    variable gregionproj
1554
 
    variable msg
1555
 
    variable zoom_attrs
1556
 
    variable gcpnum
1557
 
        variable xy
1558
 
 
1559
 
    global env
1560
 
    global drawprog
1561
 
    global devnull
1562
 
 
1563
 
    # First, switch to xy mapset
1564
 
    GRMap::setxyenv $xymset $xyloc
1565
 
 
1566
 
    set drawprog 0
1567
 
 
1568
 
        set gregion ""
1569
 
 
1570
 
        # Create a settings string to use with GRASS_WIND. 
1571
 
        # First get the current region values in normal number form (including decimal degrees)
1572
 
        set values [GRMap::currentzoom]
1573
 
        set options {}
1574
 
        foreach attr $zoom_attrs value $values {
1575
 
                lappend options "$attr=$value"
1576
 
        }
1577
 
 
1578
 
        # Now use the region values to get the region printed back out in -p format
1579
 
        # including lat long now as dd:mm:ss
1580
 
        if {![catch {open [concat "|g.region" "-up" $options "2> $devnull"] r} input]} {
1581
 
                while {[gets $input line] >= 0} {
1582
 
                        if { [regexp -nocase {^([a-z]+)\:[ ]+(.*)$} $line trash key value] } {
1583
 
                                set parts($key) $value
1584
 
                        }
1585
 
                }
1586
 
                if {[catch {close $input} error]} {
1587
 
                        GmLib::errmsg $error [G_msg "Error setting region"]
1588
 
                }
1589
 
                # Finally put this into wind file format to use with GRASS_REGION
1590
 
                regexp -nocase {^.* (\(.*\))} $parts(projection) trash end
1591
 
                set parts(projection) [string trim $parts(projection) $end]
1592
 
 
1593
 
                set gregion "projection:$parts(projection); zone:$parts(zone); north:$parts(north); south:$parts(south); east:$parts(east); west:$parts(west); e-w resol:$parts(ewres);  n-s resol:$parts(nsres)"
1594
 
        }
1595
 
 
1596
 
    set GRMap::msg [G_msg "Please wait..."]
1597
 
    $grmapframe showstatusbar progression
1598
 
 
1599
 
    incr drawprog
1600
 
    # only use dynamic region for display geometry; use WIND for computational geometry
1601
 
    set env(GRASS_REGION) $gregion
1602
 
 
1603
 
    # Setting the font really only needs to be done once per display start
1604
 
    incr drawprog
1605
 
    # display map for georectification
1606
 
    if { $maptype == "rast" } {
1607
 
            set cmd "d.rast map=$xymap"
1608
 
    } elseif { $maptype == "vect" } {
1609
 
            set cmd "d.vect map=$xymap"
1610
 
    }
1611
 
    runcmd $cmd
1612
 
 
1613
 
    unset env(GRASS_REGION)
1614
 
 
1615
 
    incr drawprog
1616
 
 
1617
 
    $grcan delete all
1618
 
    set currdir [pwd]
1619
 
    cd $tmpdir
1620
 
    incr drawprog
1621
 
 
1622
 
    image create photo grimg -file "$grfile"
1623
 
    incr drawprog
1624
 
    $grcan create image 0 0 -anchor nw \
1625
 
            -image "grimg" \
1626
 
            -tag gr
1627
 
    cd $currdir
1628
 
 
1629
 
    GRMap::coordconv
1630
 
 
1631
 
        #draw gcp marks
1632
 
        set gcpnum 1
1633
 
        if {$xy(1) != ""} {
1634
 
                #draw GCP marks from GCP form
1635
 
                for {set gcpnum 1} {$gcpnum < 51 } { incr gcpnum } {
1636
 
                        if {[$xy($gcpnum) get] != "" } {
1637
 
                                set xyfields [split [$xy($gcpnum) get] { }]
1638
 
                                set mapx [lindex $xyfields 0]
1639
 
                                set mapy [lindex $xyfields 1]
1640
 
                                set x [eval GRMap::mape2scrx $mapx]
1641
 
                                set y [eval GRMap::mapn2scry $mapy]
1642
 
                                GRMap::markgcp $x $y
1643
 
                        }
1644
 
        }
1645
 
        } else {
1646
 
                #draw GCP marks from any existing POINTS file
1647
 
                set gcpfile "$xygdb/$xyloc/$xymset/group/$xygroup/POINTS"
1648
 
                if {[file exists $gcpfile] } {
1649
 
                        # do the import
1650
 
                        set gcpnum 1
1651
 
                        catch {set pfile [open $gcpfile]}
1652
 
                        set points [read $pfile]
1653
 
                        if {[catch {close $pfile} error]} {
1654
 
                                GmLib::errmsg $error
1655
 
                        }
1656
 
 
1657
 
                        regsub -all {[ ]+} $points " " points
1658
 
                        set plines [split $points "\n"]
1659
 
                        foreach gcpline $plines {
1660
 
                                if {[string match {\#*} $gcpline]} continue
1661
 
                                if {$gcpline == "" } continue
1662
 
                                set gcpline [string trim $gcpline " "]
1663
 
                                set fields [split $gcpline { }]
1664
 
                                # assign variables            
1665
 
                                set mapx [lindex $fields 0]      
1666
 
                                set mapy  [lindex $fields 1]
1667
 
                                set x [eval GRMap::mape2scrx $mapx]
1668
 
                                set y [eval GRMap::mapn2scry $mapy]
1669
 
                                GRMap::markgcp $x $y
1670
 
                        }
1671
 
                }
1672
 
        }
1673
 
        
1674
 
    set drawprog 100
1675
 
 
1676
 
    set drawprog 0
1677
 
    set GRMap::msg [G_msg "Georectifying maps in $xygroup group"]
1678
 
 
1679
 
    $grmapframe showstatusbar status
1680
 
 
1681
 
    # Return to georectified mapset
1682
 
    GRMap::resetenv
1683
 
    return
1684
 
 
1685
 
}
1686
 
 
1687
 
# set up driver geometry and settings
1688
 
proc GRMap::driversettings { } {
1689
 
    variable grcanvas_h
1690
 
    variable grcanvas_w
1691
 
    variable driver_w
1692
 
    variable driver_h
1693
 
    variable grfile
1694
 
    variable xyloc
1695
 
    variable xymset
1696
 
    variable monitor_zooms
1697
 
    global env
1698
 
 
1699
 
    set driver_h $grcanvas_h
1700
 
    set driver_w $grcanvas_w
1701
 
 
1702
 
    #set display environment
1703
 
    # First, switch to xy mapset
1704
 
    GRMap::setxyenv $xymset $xyloc
1705
 
 
1706
 
    set env(GRASS_WIDTH) "$driver_w"
1707
 
    set env(GRASS_HEIGHT) "$driver_h"
1708
 
    set env(GRASS_PNGFILE) "$grfile"
1709
 
    set env(GRASS_BACKGROUNDCOLOR) "ffffff"
1710
 
    set env(GRASS_TRANSPARENT) "FALSE"
1711
 
    set env(GRASS_PNG_AUTO_WRITE) "TRUE"
1712
 
    set env(GRASS_TRUECOLOR) "TRUE"
1713
 
 
1714
 
    # Return to georectified mapset
1715
 
    GRMap::resetenv
1716
 
}
1717
 
 
1718
 
 
1719
 
###############################################################################
1720
 
# map display server
1721
 
# The job of these procedures is to make sure that:
1722
 
# 1: we are never running more than one update at once.
1723
 
# 2: we don't do exactly the same update multiple times.
1724
 
 
1725
 
proc GRMap::display_server {} {
1726
 
    variable redrawrequest
1727
 
    variable gcpnum
1728
 
    variable xy
1729
 
    variable drawform
1730
 
    
1731
 
    set gcpcnt 0
1732
 
 
1733
 
    if {$redrawrequest} {
1734
 
        # Mark that this monitor no longer wants to be redrawn
1735
 
        set redrawrequest 0
1736
 
        # Redraw the monitor canvas
1737
 
        GRMap::drawmap
1738
 
    }
1739
 
 
1740
 
    # Do me again in a short period of time.
1741
 
    # vwait might be appropriate here
1742
 
    after 100 GRMap::display_server
1743
 
}
1744
 
 
1745
 
# Request a redraw on a monitor
1746
 
proc GRMap::request_redraw {modified} {
1747
 
    variable redrawrequest
1748
 
    variable grcanmodified
1749
 
 
1750
 
    set redrawrequest 1
1751
 
 
1752
 
    set grcanmodified $modified
1753
 
}
1754
 
 
1755
 
# Start the server
1756
 
after idle GRMap::display_server
1757
 
 
1758
 
###############################################################################
1759
 
 
1760
 
proc GRMap::do_resize {} {
1761
 
    variable grcanvas_w
1762
 
    variable grcanvas_h
1763
 
    variable grcan
1764
 
 
1765
 
 
1766
 
    # Get the actual width and height of the canvas
1767
 
    set w [winfo width $grcan]
1768
 
    set h [winfo height $grcan]
1769
 
 
1770
 
    # Only actually resize and redraw if the size is different
1771
 
    if { $grcanvas_w != $w || $grcanvas_h != $h } {
1772
 
        $grcan delete gr
1773
 
        GRMap::request_redraw 1
1774
 
    }
1775
 
}
1776
 
 
1777
 
 
1778
 
###############################################################################
1779
 
 
1780
 
# erase to white
1781
 
proc GRMap::erase { } {
1782
 
    variable grcan
1783
 
 
1784
 
    $grcan delete gr
1785
 
    $grcan delete all
1786
 
}
1787
 
 
1788
 
 
1789
 
###############################################################################
1790
 
 
1791
 
# stop display management tools
1792
 
proc GRMap::stoptool { } {
1793
 
    variable msg
1794
 
    variable grcan
1795
 
    variable maptype
1796
 
    variable xygroup
1797
 
 
1798
 
    # release bindings
1799
 
    bind $grcan <1> ""
1800
 
    bind $grcan <2> ""
1801
 
    bind $grcan <3> ""
1802
 
    bind $grcan <B1-Motion> ""
1803
 
    bind $grcan <ButtonRelease-1> ""
1804
 
 
1805
 
    # reset status display to normal
1806
 
    set GRMap::msg [G_msg "Georectifying maps in $xygroup group"]
1807
 
 
1808
 
    GRMap::restorecursor
1809
 
}
1810
 
 
1811
 
###############################################################################
1812
 
# set bindings for GCP selection tool
1813
 
proc GRMap::selector { } {
1814
 
    variable grcan
1815
 
    variable grcoords_mov
1816
 
    global grcoords
1817
 
    global xyentry
1818
 
 
1819
 
    GRMap::setcursor "crosshair"
1820
 
 
1821
 
    bind $grcan <ButtonPress-1> {
1822
 
        set eastcoord [eval GRMap::scrx2mape %x]
1823
 
        set northcoord [eval GRMap::scry2mapn %y]
1824
 
        set grcoords "$eastcoord $northcoord"
1825
 
        GRMap::markgcp %x %y
1826
 
        $xyentry delete 0 end
1827
 
        $xyentry insert 0 $grcoords
1828
 
        focus -force [tk_focusNext $xyentry]
1829
 
    }
1830
 
 
1831
 
    # Displays geographic coordinates in indicator window when cursor moved across canvas
1832
 
    bind $grcan <Motion> {
1833
 
        set scrxmov %x
1834
 
        set scrymov %y
1835
 
        set eastcoord [eval GRMap::scrx2mape %x]
1836
 
        set northcoord [eval GRMap::scry2mapn %y]
1837
 
        set grcoords_mov "$eastcoord $northcoord"
1838
 
    }
1839
 
}
1840
 
 
1841
 
###############################################################################
1842
 
# mark ground control point
1843
 
proc GRMap::markgcp { x y } {
1844
 
 
1845
 
    # create gcp point on georectify canvas for each mouse click
1846
 
 
1847
 
    variable grcan
1848
 
    $grcan create line $x [expr $y-5] $x [expr $y+5] -tag gcpv \
1849
 
            -fill DarkGreen -width 2 -tag "gcpvert"
1850
 
    $grcan create line [expr $x-5] $y [expr $x+5] $y -tag gcph \
1851
 
            -fill red -width 2 -tag "gcphoriz"
1852
 
}
1853
 
 
1854
 
 
1855
 
###############################################################################
1856
 
# procedures for zooming and setting region
1857
 
 
1858
 
# Get the current zoom region
1859
 
# Returns a list in zoom_attrs order (n s e w nsres ewres)
1860
 
proc GRMap::currentzoom { } {
1861
 
    variable zoom_attrs
1862
 
    variable monitor_zooms
1863
 
    variable grcanvas_w
1864
 
    variable grcanvas_h
1865
 
    variable xyloc
1866
 
    variable xymset
1867
 
 
1868
 
    # Fetch the current zoom settings
1869
 
    set region {}
1870
 
    foreach attr $zoom_attrs {
1871
 
        lappend region $monitor_zooms(1,$attr)
1872
 
    }
1873
 
 
1874
 
    # Set the region to the smallest region no smaller than the canvas
1875
 
    set grcanvas_ar [expr {1.0 * $grcanvas_w / $grcanvas_h}]
1876
 
    set expanded_nsew [GRMap::shrinkwrap 1 [lrange $region 0 3] $grcanvas_ar]
1877
 
    foreach {n s e w} $expanded_nsew {break}
1878
 
    # Calculate the resolutions
1879
 
    lappend expanded_nsew [expr {1.0 * ($n - $s) / $grcanvas_h}]
1880
 
    lappend expanded_nsew [expr {1.0 * ($e - $w) / $grcanvas_w}]
1881
 
    set region $expanded_nsew
1882
 
 
1883
 
    # region contains values for n s e w ewres nsres
1884
 
    return $region
1885
 
}
1886
 
 
1887
 
# Zoom or pan to new bounds in the zoom history
1888
 
# Arguments are either n s e w or n s e w nsres ewres
1889
 
proc GRMap::zoom_new { args} {
1890
 
    variable monitor_zooms
1891
 
    variable zoomhistories
1892
 
    variable zoom_attrs
1893
 
    variable xyloc
1894
 
    variable xymset
1895
 
 
1896
 
    # Demote all of the zoom history
1897
 
    for {set i $zoomhistories} {$i > 1} {incr i -1} {
1898
 
        set iminus [expr {$i - 1}]
1899
 
        foreach attr $zoom_attrs {
1900
 
            catch {set monitor_zooms($i,$attr) $monitor_zooms($iminus,$attr)}
1901
 
        }
1902
 
    }
1903
 
 
1904
 
    # If cols and rows aren't present we just use what was already here.
1905
 
    set present_attrs [lrange $zoom_attrs 0 [expr {[llength $args] - 1}]]
1906
 
 
1907
 
    foreach value $args attr $present_attrs {
1908
 
        set monitor_zooms(1,$attr) $value
1909
 
    }
1910
 
 
1911
 
}
1912
 
 
1913
 
# Zoom to the previous thing in the zoom history
1914
 
proc GRMap::zoom_previous {} {
1915
 
    variable monitor_zooms
1916
 
    variable zoomhistories
1917
 
    variable zoom_attrs
1918
 
    variable xyloc
1919
 
    variable xymset
1920
 
 
1921
 
    # Remember the first monitor
1922
 
    set old1 {}
1923
 
    foreach attr $zoom_attrs {
1924
 
        lappend old1 $monitor_zooms(1,$attr)
1925
 
    }
1926
 
 
1927
 
    # Promote all of the zoom history
1928
 
    for {set i 1} {$i < $zoomhistories } {incr i} {
1929
 
        set iplus [expr {$i + 1}]
1930
 
        foreach attr $zoom_attrs {
1931
 
            catch {set monitor_zooms($i,$attr) $monitor_zooms($iplus,$attr)}
1932
 
        }
1933
 
    }
1934
 
 
1935
 
    # Set the oldest thing in the history to where we just were
1936
 
    foreach value $old1 attr $zoom_attrs {
1937
 
        set monitor_zooms($zoomhistories,$attr) $value
1938
 
    }
1939
 
 
1940
 
}
1941
 
 
1942
 
 
1943
 
# Zoom to something loaded from a g.region command
1944
 
proc GRMap::zoom_gregion { args} {
1945
 
    variable xyloc
1946
 
    variable xymset
1947
 
    variable gregionproj
1948
 
    global env
1949
 
    global devnull
1950
 
 
1951
 
    # First, switch to xy mapset
1952
 
    GRMap::setxyenv $xymset $xyloc
1953
 
 
1954
 
    if {![catch {open [concat "|g.region" "-up" $args "2> $devnull"] r} input]} {
1955
 
        while {[gets $input line] >= 0} {
1956
 
                        set key [string trim [lindex [split $line ":"] 0]]
1957
 
                        set value [string trim [lindex [split $line ":"] 1]]
1958
 
            set value [string trim $value "(UTM)"]
1959
 
            set value [string trim $value "(x,y)"]
1960
 
            set value [string trim $value]
1961
 
            set parts($key) $value
1962
 
        }
1963
 
                if {[catch {close $input} error]} {
1964
 
                        GmLib::errmsg $error ["Error setting region"]
1965
 
                }
1966
 
 
1967
 
        GRMap::zoom_new $parts(north) $parts(south) $parts(east) $parts(west) $parts(nsres) $parts(ewres)
1968
 
        set gregionproj "proj: $parts(projection); zone: $parts(zone); "
1969
 
    }
1970
 
 
1971
 
    # Return to georectified mapset
1972
 
    GRMap::resetenv
1973
 
}
1974
 
 
1975
 
 
1976
 
# zoom to extents and resolution of displayed map for georectifying
1977
 
proc GRMap::zoom_map { } {
1978
 
    variable xymap
1979
 
    variable xymset
1980
 
    variable xyloc
1981
 
    variable maptype
1982
 
    variable grcan
1983
 
 
1984
 
    # set region to match map to georectify
1985
 
    if { $maptype == "rast" } {
1986
 
        GRMap::zoom_gregion [list "rast=$xymap"]
1987
 
    } elseif { $maptype == "vect" } {
1988
 
        GRMap::zoom_gregion [list "vect=$xymap"]
1989
 
    }
1990
 
 
1991
 
    $grcan delete gr
1992
 
    GRMap::request_redraw 1
1993
 
 
1994
 
}
1995
 
 
1996
 
 
1997
 
# zoom back
1998
 
proc GRMap::zoom_back { } {
1999
 
    variable grcan
2000
 
 
2001
 
    GRMap::zoom_previous
2002
 
    $grcan delete gr
2003
 
    GRMap::request_redraw 1
2004
 
}
2005
 
 
2006
 
 
2007
 
###############################################################################
2008
 
# interactive zooming procedures
2009
 
# zoom bindings
2010
 
proc GRMap::zoombind { zoom } {
2011
 
    variable grcan
2012
 
    variable msg
2013
 
        variable areaX1 
2014
 
        variable areaY1 
2015
 
        variable areaX2 
2016
 
        variable areaY2
2017
 
        variable grcoords_mov
2018
 
 
2019
 
    # initialize zoom rectangle corners
2020
 
 
2021
 
    set areaX1 0
2022
 
    set areaY1 0
2023
 
    set areaX2 0
2024
 
    set areaY2 0
2025
 
 
2026
 
    GRMap::setcursor "plus"
2027
 
 
2028
 
    if {$zoom == 1} {
2029
 
        set GRMap::msg [G_msg "Drag or click mouse to zoom"]
2030
 
    } elseif {$zoom == -1} {
2031
 
        set GRMap::msg [G_msg "Drag or click mouse to unzoom"]
2032
 
    }
2033
 
 
2034
 
    bind $grcan <1> {
2035
 
        GRMap::markzoom %x %y
2036
 
        }
2037
 
    bind $grcan <B1-Motion> {
2038
 
        set scrxmov %x
2039
 
        set scrymov %y
2040
 
        set eastcoord [eval GRMap::scrx2mape %x]
2041
 
        set northcoord [eval GRMap::scry2mapn %y]
2042
 
        set grcoords_mov "$eastcoord $northcoord"
2043
 
        GRMap::drawzoom %x %y
2044
 
        }
2045
 
    bind $grcan <ButtonRelease-1> "GRMap::zoomregion $zoom"
2046
 
 
2047
 
}
2048
 
 
2049
 
# start zoom rectangle
2050
 
proc GRMap::markzoom { x y} {
2051
 
        variable areaX1 
2052
 
        variable areaY1 
2053
 
        variable areaX2 
2054
 
        variable areaY2
2055
 
    variable grcan
2056
 
 
2057
 
    # initialize corners
2058
 
    set areaX1 0
2059
 
    set areaY1 0
2060
 
    set areaX2 0
2061
 
    set areaY2 0
2062
 
    set areaX1 [$grcan canvasx $x]
2063
 
    set areaY1 [$grcan canvasy $y]
2064
 
    $grcan delete area
2065
 
}
2066
 
 
2067
 
# draw zoom rectangle
2068
 
proc GRMap::drawzoom { x y } {
2069
 
    variable grcan
2070
 
        variable areaX1 
2071
 
        variable areaY1 
2072
 
        variable areaX2 
2073
 
        variable areaY2
2074
 
 
2075
 
    set xc [$grcan canvasx $x]
2076
 
    set yc [$grcan canvasy $y]
2077
 
 
2078
 
    if {($areaX1 != $xc) && ($areaY1 != $yc)} {
2079
 
        $grcan delete area
2080
 
        $grcan addtag area withtag \
2081
 
            [$grcan create rect $areaX1 $areaY1 $xc $yc \
2082
 
            -outline yellow -width 2]
2083
 
        set areaX2 $xc
2084
 
        set areaY2 $yc
2085
 
    }
2086
 
}
2087
 
 
2088
 
 
2089
 
# zoom region
2090
 
proc GRMap::zoomregion { zoom } {
2091
 
    variable grcan
2092
 
    variable grcanvas_h
2093
 
    variable grcanvas_w
2094
 
    variable monitor_zooms
2095
 
        variable areaX1 
2096
 
        variable areaY1 
2097
 
        variable areaX2 
2098
 
        variable areaY2
2099
 
 
2100
 
    variable map_n
2101
 
    variable map_s
2102
 
    variable map_e
2103
 
    variable map_w
2104
 
    variable map_ew
2105
 
    variable map_ns
2106
 
 
2107
 
        set clickzoom 0
2108
 
 
2109
 
        # get display extents in geographic coordinates
2110
 
        set dispnorth [scry2mapn 0]
2111
 
        set dispsouth [scry2mapn $grcanvas_h]
2112
 
        set dispeast  [scrx2mape $grcanvas_w]
2113
 
        set dispwest  [scrx2mape 0]
2114
 
 
2115
 
        # get zoom rectangle extents in geographic coordinates
2116
 
        if { $areaX2 < $areaX1 } {
2117
 
                        set cright $areaX1
2118
 
                        set cleft $areaX2
2119
 
        } else {
2120
 
                        set cleft $areaX1
2121
 
                        set cright $areaX2
2122
 
        }
2123
 
 
2124
 
        if { $areaY2 < $areaY1 } {
2125
 
                        set cbottom $areaY1
2126
 
                        set ctop $areaY2
2127
 
        } else {
2128
 
                        set ctop $areaY1
2129
 
                        set cbottom $areaY2
2130
 
        }
2131
 
 
2132
 
        set north [scry2mapn $ctop]
2133
 
        set south [scry2mapn $cbottom]
2134
 
        set east  [scrx2mape $cright]
2135
 
        set west  [scrx2mape $cleft]
2136
 
        # (this is all you need to zoom in with box)
2137
 
 
2138
 
 
2139
 
        # if click and no drag, zoom in or out by fraction of original area and center on the click spot
2140
 
        if {($areaX2 == 0) && ($areaY2 == 0)} {set clickzoom 1}
2141
 
        # get first click location in map coordinates for recentering with 1-click zooming
2142
 
        set newcenter_n [scry2mapn $areaY1]
2143
 
        set newcenter_e [scrx2mape $areaX1]     
2144
 
 
2145
 
        # get current region extents for box zooming out and recentering        
2146
 
        foreach {map_n map_s map_e map_w nsres ewres} [GRMap::currentzoom] {break}
2147
 
 
2148
 
        # get original map center for recentering after 1-click zooming
2149
 
        set oldcenter_n [expr $map_s + ($map_n - $map_s)/2]
2150
 
        set oldcenter_e [expr $map_w + ($map_e - $map_w)/2]
2151
 
 
2152
 
        # set shift for recentering after 1-click zooming
2153
 
        set shift_n [expr $newcenter_n - $oldcenter_n]
2154
 
        set shift_e [expr $newcenter_e - $oldcenter_e]
2155
 
 
2156
 
        # 1-click zooming--zooms in or out by function of square root of 2 and 
2157
 
        # recenters region in display window at spot clicked
2158
 
        if {$clickzoom == 1} {
2159
 
                # calculate amount to zoom in or out in geographic distance
2160
 
                set nsscale [expr (($dispnorth - $dispsouth) - ($dispnorth - $dispsouth)/sqrt(2))/2]
2161
 
                set ewscale [expr (($dispeast - $dispwest) - ($dispeast - $dispwest)/sqrt(2))/2]
2162
 
                if {$zoom == 1} {
2163
 
                        # zoom in
2164
 
                        set north [expr {$dispnorth - $nsscale + $shift_n}]
2165
 
                        set south [expr {$dispsouth + $nsscale + $shift_n}]
2166
 
                        set east [expr {$dispeast - $ewscale + $shift_e}]
2167
 
                        set west [expr {$dispwest + $ewscale + $shift_e}]
2168
 
                } elseif {$zoom == -1} {
2169
 
                        # zoom out
2170
 
                        set north [expr {$dispnorth + $nsscale + $shift_n}]
2171
 
                        set south [expr {$dispsouth - $nsscale + $shift_n}]
2172
 
                        set east [expr {$dispeast + $ewscale + $shift_e}]
2173
 
                        set west [expr {$dispwest - $ewscale + $shift_e}]
2174
 
                }
2175
 
        }
2176
 
 
2177
 
        # zoom out with box
2178
 
        # box determines zoom out proportion, longest box dimension determines zoom,
2179
 
        # and box center becomes region center. Zoom out relative to the geographic
2180
 
        # extents of the display rather than the current region to deal with mismatches
2181
 
        # between geometry of region and display window.
2182
 
        if { $zoom == -1 && $clickzoom == 0} {
2183
 
                # Calculate the box geometry--to be used for new region geometry
2184
 
                set box_ns [expr $north-$south]
2185
 
                set box_ew [expr $east-$west]
2186
 
                # calcuate aspect ratio for zoom box
2187
 
                set box_aspect [expr $box_ns/$box_ew]
2188
 
                # calculate zoomout ratio for longest box dimension
2189
 
                if { $box_ns > $box_ew } {
2190
 
                        set zoomratio [expr ($dispnorth - $dispsouth)/$box_ns]
2191
 
                        set new_ns [expr ($dispnorth - $dispsouth) * $zoomratio]
2192
 
                        set new_ew [expr $new_ns / $box_aspect]
2193
 
                } else {
2194
 
                        set zoomratio [expr ($dispeast - $dispwest)/$box_ew]
2195
 
                        set new_ew [expr ($dispeast - $dispwest) * $zoomratio]
2196
 
                        set new_ns [expr $new_ew * $box_aspect]
2197
 
                }
2198
 
 
2199
 
                # get zoom-out box center
2200
 
                set boxcenter_n [expr $south + (($north - $south)/2)]
2201
 
                set boxcenter_e [expr $west + (($east - $west)/2)]
2202
 
                
2203
 
                # zoom out to new extents
2204
 
                set north [expr $boxcenter_n + ($new_ns/2)]
2205
 
                set south [expr $boxcenter_n - ($new_ns/2)]
2206
 
                set east [expr $boxcenter_e + ($new_ew/2)]
2207
 
                set west [expr $boxcenter_e - ($new_ew/2)]
2208
 
        }
2209
 
 
2210
 
        GRMap::zoom_new $north $south $east $west $nsres $ewres
2211
 
 
2212
 
    # redraw map
2213
 
    $grcan delete gr
2214
 
    $grcan delete area
2215
 
    GRMap::request_redraw  1
2216
 
}
2217
 
 
2218
 
 
2219
 
 
2220
 
###############################################################################
2221
 
#procedures for panning
2222
 
 
2223
 
# pan bindings
2224
 
proc GRMap::panbind { } {
2225
 
    variable grcan
2226
 
    variable msg
2227
 
    variable grcoords_mov
2228
 
 
2229
 
    set GRMap::msg [G_msg "Drag with mouse to pan"]
2230
 
 
2231
 
    GRMap::setcursor "hand2"
2232
 
 
2233
 
    bind $grcan <1> {GRMap::startpan %x %y}
2234
 
    bind $grcan <B1-Motion> {
2235
 
        set scrxmov %x
2236
 
        set scrymov %y
2237
 
        set eastcoord [eval GRMap::scrx2mape %x]
2238
 
        set northcoord [eval GRMap::scry2mapn %y]
2239
 
        set grcoords_mov "$eastcoord $northcoord"
2240
 
        GRMap::dragpan %x %y
2241
 
        }
2242
 
    bind $grcan <ButtonRelease-1> {
2243
 
        GRMap::pan
2244
 
        }
2245
 
}
2246
 
 
2247
 
 
2248
 
proc GRMap::startpan { x y} {
2249
 
    variable start_x
2250
 
    variable start_y
2251
 
    variable from_x
2252
 
    variable from_y
2253
 
    variable to_x
2254
 
    variable to_y
2255
 
    variable grcan
2256
 
 
2257
 
    set start_x [$grcan canvasx $x]
2258
 
    set start_y [$grcan canvasy $y]
2259
 
    set from_x $start_x
2260
 
    set from_y $start_y
2261
 
    set to_x $start_x
2262
 
    set to_y $start_y
2263
 
 
2264
 
}
2265
 
 
2266
 
proc GRMap::dragpan { x y} {
2267
 
    variable start_x
2268
 
    variable start_y
2269
 
    variable from_x
2270
 
    variable from_y
2271
 
    variable to_x
2272
 
    variable to_y
2273
 
    variable grcan
2274
 
 
2275
 
    set to_x [$grcan canvasx $x]
2276
 
    set to_y [$grcan canvasy $y]
2277
 
    $grcan move current [expr {$to_x-$start_x}] [expr {$to_y-$start_y}]
2278
 
 
2279
 
    set start_y $to_y
2280
 
    set start_x $to_x
2281
 
}
2282
 
 
2283
 
proc GRMap::pan { } {
2284
 
    variable start_x
2285
 
    variable start_y
2286
 
    variable from_x
2287
 
    variable from_y
2288
 
    variable to_x
2289
 
    variable to_y
2290
 
    variable grcan
2291
 
    variable monitor_zooms
2292
 
    variable map_n
2293
 
    variable map_s
2294
 
    variable map_e
2295
 
    variable map_w
2296
 
    variable map_ew
2297
 
    variable map_ns
2298
 
 
2299
 
    # get map coordinate shift
2300
 
    set from_e [scrx2mape $from_x]
2301
 
    set from_n [scry2mapn $from_y]
2302
 
    set to_e   [scrx2mape $to_x]
2303
 
    set to_n   [scry2mapn $to_y]
2304
 
 
2305
 
    # get region extents
2306
 
    foreach {map_n map_s map_e map_w} [GRMap::currentzoom] {break}
2307
 
 
2308
 
    # set new region extents
2309
 
    set north [expr {$map_n - ($to_n - $from_n)}]
2310
 
    set south [expr {$map_s - ($to_n - $from_n)}]
2311
 
    set east  [expr {$map_e - ($to_e - $from_e)}]
2312
 
    set west  [expr {$map_w - ($to_e - $from_e)}]
2313
 
 
2314
 
    # reset region and redraw map
2315
 
    GRMap::zoom_new $north $south $east $west
2316
 
 
2317
 
    $grcan delete gr
2318
 
    GRMap::request_redraw 1
2319
 
}
2320
 
 
2321
 
###############################################################################
2322
 
 
2323
 
proc GRMap::setcursor {  ctype } {
2324
 
    variable grcan
2325
 
 
2326
 
    $grcan configure -cursor $ctype
2327
 
    return
2328
 
}
2329
 
 
2330
 
proc GRMap::restorecursor {} {
2331
 
    variable grcursor
2332
 
    variable grcan
2333
 
 
2334
 
    $grcan configure -cursor $grcursor
2335
 
    return
2336
 
}
2337
 
 
2338
 
###############################################################################
2339
 
 
2340
 
# Set up initial variables for screen to map conversion
2341
 
proc GRMap::coordconv { } {
2342
 
 
2343
 
    variable map_n
2344
 
    variable map_s
2345
 
    variable map_e
2346
 
    variable map_w
2347
 
    variable map_ew
2348
 
    variable map_ns
2349
 
    variable scr_n
2350
 
    variable scr_s
2351
 
    variable scr_e
2352
 
    variable scr_w
2353
 
    variable scr_ew
2354
 
    variable scr_ns
2355
 
    variable map2scrx_conv
2356
 
    variable map2scry_conv
2357
 
    variable grcanvas_w
2358
 
    variable grcanvas_h
2359
 
    variable monitor_zooms
2360
 
 
2361
 
    # get region extents
2362
 
    foreach {map_n map_s map_e map_w} [GRMap::currentzoom] {break}
2363
 
 
2364
 
    # calculate dimensions
2365
 
 
2366
 
    set map_n [expr {1.0*($map_n)}]
2367
 
    set map_s [expr {1.0*($map_s)}]
2368
 
    set map_e [expr {1.0*($map_e)}]
2369
 
    set map_w [expr {1.0*($map_w)}]
2370
 
 
2371
 
    set map_ew [expr {$map_e - $map_w}]
2372
 
    set map_ns [expr {$map_n - $map_s}]
2373
 
 
2374
 
 
2375
 
    # get current screen geometry
2376
 
    if { [info exists "grimg"] } {
2377
 
        set scr_ew [image width "grimg"]
2378
 
        set scr_ns [image height "grimg"]
2379
 
        set scr_e [image width "grimg"]
2380
 
        set scr_s [image height "grimg"]
2381
 
    } else {
2382
 
        set scr_ew $grcanvas_w
2383
 
        set scr_ns $grcanvas_h
2384
 
        set scr_e $grcanvas_w
2385
 
        set scr_s $grcanvas_h
2386
 
    }
2387
 
    set scr_n 0.0
2388
 
    set scr_w 0.0
2389
 
 
2390
 
 
2391
 
    # calculate conversion factors. Note screen is from L->R, T->B but map
2392
 
    # is from L->R, B->T
2393
 
 
2394
 
    set map2scrx_conv [expr {$scr_ew / $map_ew}]
2395
 
    set map2scry_conv [expr {$scr_ns / $map_ns}]
2396
 
 
2397
 
    # calculate screen dimensions and offsets
2398
 
 
2399
 
    if { $map2scrx_conv > $map2scry_conv } {
2400
 
        set map2scrx_conv $map2scry_conv
2401
 
    } else {
2402
 
        set map2scry_conv $map2scrx_conv
2403
 
    }
2404
 
 
2405
 
}
2406
 
 
2407
 
###############################################################################
2408
 
 
2409
 
 
2410
 
# screen to map and map to screen conversion procedures
2411
 
 
2412
 
# map north to screen y
2413
 
proc GRMap::mapn2scry { north } {
2414
 
    variable map_n
2415
 
    variable scr_n
2416
 
    variable map2scry_conv
2417
 
 
2418
 
    return [expr {$scr_n + (($map_n - $north) * $map2scry_conv)}]
2419
 
}
2420
 
 
2421
 
# map east to screen x
2422
 
proc GRMap::mape2scrx { east } {
2423
 
    variable map_w
2424
 
    variable scr_w
2425
 
    variable map2scrx_conv
2426
 
 
2427
 
    return [expr {$scr_w + (($east - $map_w) * $map2scrx_conv)}]
2428
 
 
2429
 
}
2430
 
 
2431
 
# screen y to map north
2432
 
proc GRMap::scry2mapn { y } {
2433
 
    variable map_n
2434
 
    variable scr_n
2435
 
    variable map2scry_conv
2436
 
 
2437
 
    return [expr {$map_n - (($y - $scr_n) / $map2scry_conv)}]
2438
 
}
2439
 
 
2440
 
# screen x to map east
2441
 
proc GRMap::scrx2mape { x } {
2442
 
    variable map_w
2443
 
    variable scr_w
2444
 
    variable map2scrx_conv
2445
 
 
2446
 
    return [expr {$map_w + (($x - $scr_w) / $map2scrx_conv)}]
2447
 
 
2448
 
}
2449
 
 
2450
 
###############################################################################
2451
 
# cleanup procedure on closing window
2452
 
proc GRMap::cleanup { } {
2453
 
        variable xy
2454
 
        
2455
 
    if { [winfo exists .gcpwin] } { destroy .gcpwin }
2456
 
    if { [winfo exists .mapgrcan] } { destroy .mapgrcan }
2457
 
 
2458
 
        for {set gcpnum 1} {$gcpnum < 51 } { incr gcpnum } {
2459
 
                if {[info exists xy($gcpnum)]} {
2460
 
                        unset xy($gcpnum)
2461
 
                }
2462
 
        }
2463
 
 
2464
 
    # reset to original location and mapset
2465
 
    GRMap::resetenv
2466
 
 
2467
 
}
2468
 
 
2469
 
###############################################################################