~ubuntu-branches/ubuntu/precise/grass/precise

« back to all changes in this revision

Viewing changes to gui/wxpython/gui_modules/georect.py

  • Committer: Bazaar Package Importer
  • Author(s): Francesco Paolo Lovergine
  • Date: 2011-04-13 17:08:41 UTC
  • mfrom: (8.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20110413170841-ss1t9bic0d0uq0gz
Tags: 6.4.1-1
* New upstream version.
* Now build-dep on libjpeg-dev and current libreadline6-dev.
* Removed patch swig: obsolete.
* Policy bumped to 3.9.2, without changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
"""!
2
 
@package georect.py
3
 
 
4
 
@brief Georectification module for GRASS GIS. Includes ground control
5
 
point management and interactive point and click GCP creation
6
 
 
7
 
Classes:
8
 
 - GeorectWizard
9
 
 - LocationPage
10
 
 - GroupPage
11
 
 - DispMapPage
12
 
 - GCP
13
 
 - GCPList
14
 
 - VectGroup
15
 
 - EditGCP
16
 
 - GrSettingsDialog
17
 
 
18
 
(C) 2006-2010 by the GRASS Development Team
19
 
 
20
 
This program is free software under the GNU General Public License
21
 
(>=v2). Read the file COPYING that comes with GRASS for details.
22
 
 
23
 
@author Michael Barton
24
 
@author Updated by Martin Landa <landa.martin gmail.com>
25
 
"""
26
 
 
27
 
import os
28
 
import sys
29
 
import tempfile
30
 
import shutil
31
 
import time
32
 
 
33
 
import wx
34
 
from wx.lib.mixins.listctrl import CheckListCtrlMixin, ListCtrlAutoWidthMixin, TextEditMixin
35
 
import wx.lib.colourselect as  csel
36
 
import wx.wizard as wiz
37
 
 
38
 
import grass.script as grass
39
 
 
40
 
import globalvar
41
 
import mapdisp
42
 
import render
43
 
import toolbars
44
 
import menuform
45
 
import gselect
46
 
import gcmd
47
 
import utils
48
 
from debug import Debug as Debug
49
 
from icon import Icons as Icons
50
 
from location_wizard import TitledPage as TitledPage
51
 
from preferences import globalSettings as UserSettings
52
 
 
53
 
try:
54
 
    import subprocess # Not needed if GRASS commands could actually be quiet
55
 
except:
56
 
    CompatPath = globalvar.ETCWXDIR
57
 
    sys.path.append(CompatPath)
58
 
    from compat import subprocess
59
 
 
60
 
gmpath = os.path.join(globalvar.ETCWXDIR, "icons")
61
 
sys.path.append(gmpath)
62
 
 
63
 
#
64
 
# global variables
65
 
#
66
 
global xy_map
67
 
global maptype
68
 
 
69
 
xy_map = ''
70
 
maptype = 'cell'
71
 
 
72
 
class GeorectWizard(object):
73
 
    """
74
 
    Start wizard here and finish wizard here
75
 
    """
76
 
 
77
 
    def __init__(self, parent):
78
 
        self.parent = parent # GMFrame
79
 
 
80
 
        #
81
 
        # get environmental variables
82
 
        #
83
 
        p = gcmd.Command(['g.gisenv', 'get=GISDBASE'])
84
 
        self.grassdatabase = p.ReadStdOutput()[0]
85
 
 
86
 
        #
87
 
        # read original environment settings
88
 
        #
89
 
        self.orig_gisrc = os.environ['GISRC']
90
 
        self.gisrc_dict = {}
91
 
        try:
92
 
            f = open(self.orig_gisrc, 'r')
93
 
            for line in f.readlines():
94
 
                line = line.replace('\n', '').strip()
95
 
                if len(line) < 1:
96
 
                    continue
97
 
                key, value = line.split(':', 1)
98
 
                self.gisrc_dict[key.strip()] = value.strip()
99
 
        finally:
100
 
            f.close()
101
 
            
102
 
        self.currentlocation = self.gisrc_dict['LOCATION_NAME']
103
 
        self.currentmapset = self.gisrc_dict['MAPSET']
104
 
        # location for xy map to georectify
105
 
        self.newlocation = ''
106
 
        # mapset for xy map to georectify
107
 
        self.newmapset = '' 
108
 
 
109
 
        # GISRC file for source location/mapset of map(s) to georectify
110
 
        self.new_gisrc = ''
111
 
 
112
 
        #
113
 
        # define wizard pages
114
 
        #
115
 
        self.wizard = wiz.Wizard(parent=parent, id=wx.ID_ANY, title=_("Setup for georectification"))
116
 
        self.startpage = LocationPage(self.wizard, self)
117
 
        self.grouppage = GroupPage(self.wizard, self)
118
 
        self.mappage = DispMapPage(self.wizard, self)
119
 
 
120
 
        #
121
 
        # set the initial order of the pages
122
 
        #
123
 
        self.startpage.SetNext(self.grouppage)
124
 
        self.grouppage.SetPrev(self.startpage)
125
 
        self.grouppage.SetNext(self.mappage)
126
 
        self.mappage.SetPrev(self.grouppage)
127
 
 
128
 
        #
129
 
        # do pages layout
130
 
        #
131
 
        self.startpage.DoLayout()
132
 
        self.grouppage.DoLayout()
133
 
        self.mappage.DoLayout()
134
 
        self.wizard.FitToPage(self.startpage)
135
 
 
136
 
        # self.Bind(wx.EVT_CLOSE,    self.Cleanup)
137
 
        # self.parent.Bind(wx.EVT_ACTIVATE, self.OnGLMFocus)
138
 
 
139
 
        success = False
140
 
 
141
 
        #
142
 
        # run wizard
143
 
        #
144
 
        if self.wizard.RunWizard(self.startpage):
145
 
            success = self.OnWizFinished()
146
 
            if success == False:
147
 
                wx.MessageBox(parent=self.parent,
148
 
                              message=_("Georectifying setup canceled."),
149
 
                              caption=_("Georectify"),
150
 
                              style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
151
 
                self.Cleanup()
152
 
        else:
153
 
            wx.MessageBox(parent=self.parent,
154
 
                          message=_("Georectifying setup canceled."),
155
 
                          caption=_("Georectify"),
156
 
                          style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
157
 
            self.Cleanup()
158
 
 
159
 
        #
160
 
        # start display showing xymap
161
 
        #
162
 
        if success != False:
163
 
            # instance of render.Map to be associated with display
164
 
            self.Map = render.Map(gisrc=self.new_gisrc) 
165
 
            
166
 
            global maptype
167
 
            global xy_map
168
 
 
169
 
            #
170
 
            # add layer to map
171
 
            #
172
 
            if maptype == 'cell':
173
 
                rendertype = 'raster'
174
 
                cmdlist = ['d.rast', 'map=%s' % xy_map]
175
 
            else: # -> vector layer
176
 
                rendertype = 'vector'
177
 
                cmdlist = ['d.vect', 'map=%s' % xy_map]
178
 
            
179
 
            self.Map.AddLayer(type=rendertype, command=cmdlist, l_active=True,
180
 
                              name=utils.GetLayerNameFromCmd(cmdlist),
181
 
                              l_hidden=False, l_opacity=1.0, l_render=False)
182
 
            
183
 
            #
184
 
            # start GCP form
185
 
            #
186
 
            self.gcpmgr = GCP(self.parent, grwiz=self)
187
 
            self.gcpmgr.Show()
188
 
 
189
 
            #
190
 
            # start map display
191
 
            #
192
 
            self.xy_mapdisp = mapdisp.MapFrame(self.gcpmgr, title=_("Set ground control points (GCPs)"),
193
 
                                               size=globalvar.MAP_WINDOW_SIZE,
194
 
                                               toolbars=["georect"],
195
 
                                               Map=self.Map, gismgr=self.parent)
196
 
            self.xy_mapdisp.SetTitle(_("GRASS GIS Map Display: 1" +
197
 
                                       " - Location: " + self.newlocation +
198
 
                                       " (source location)"))
199
 
            self.xy_mapdisp.SetName("GRMapWindow")
200
 
 
201
 
            self.gcpmgr.SetMapDisplay(self.xy_mapdisp)
202
 
            
203
 
            self.mapwin = self.xy_mapdisp.MapWindow
204
 
            
205
 
            # set mouse characteristics
206
 
            self.mapwin.mouse['box'] = 'point'
207
 
            self.mapwin.mouse["use"] == "pointer"
208
 
            self.mapwin.zoomtype = 0
209
 
            self.mapwin.pen = wx.Pen(colour='black', width=2, style=wx.SOLID)
210
 
            self.mapwin.SetCursor(self.xy_mapdisp.cursors["cross"])
211
 
 
212
 
            #
213
 
            # show new display & draw map
214
 
            #
215
 
            self.xy_mapdisp.toolbars['georect'].OnZoomMap(None)
216
 
            self.xy_mapdisp.CenterOnScreen()
217
 
            self.xy_mapdisp.Show()
218
 
            self.gcpmgr.Centre()
219
 
            self.gcpmgr.Raise()
220
 
        else:
221
 
            self.Cleanup()
222
 
                            
223
 
    def SetSrcEnv(self, location, mapset):
224
 
        """Create environment to use for location and mapset
225
 
        that are the source of the file(s) to georectify
226
 
 
227
 
        @param location source location
228
 
        @param mapset source mapset
229
 
 
230
 
        @return False on error
231
 
        @return True on success
232
 
        """
233
 
        
234
 
        self.newlocation = location
235
 
        self.newmapset = mapset
236
 
        
237
 
        # check to see if we are georectifying map in current working location/mapset
238
 
        if self.newlocation == self.currentlocation and self.newmapset == self.currentmapset:
239
 
            return False
240
 
        
241
 
        self.gisrc_dict['LOCATION_NAME'] = location
242
 
        self.gisrc_dict['MAPSET'] = mapset
243
 
        
244
 
        self.new_gisrc = utils.GetTempfile()
245
 
 
246
 
        try:
247
 
            f = open(self.new_gisrc, mode='w')        
248
 
            for line in self.gisrc_dict.items():
249
 
                f.write(line[0] + ": " + line[1] + "\n")
250
 
        finally:
251
 
            f.close()
252
 
 
253
 
        return True
254
 
 
255
 
    def SwitchEnv(self, grc):
256
 
        """
257
 
        Switches between original working location/mapset and
258
 
        location/mapset that is source of file(s) to georectify
259
 
        """
260
 
        # check to see if we are georectifying map in current working location/mapset
261
 
        if self.newlocation == self.currentlocation and self.newmapset == self.currentmapset:
262
 
            return False
263
 
 
264
 
        if grc == 'original':
265
 
            os.environ["GISRC"] = str(self.orig_gisrc)
266
 
        elif grc == 'new':
267
 
            os.environ["GISRC"] = str(self.new_gisrc)
268
 
 
269
 
        return True
270
 
    
271
 
    def OnWizFinished(self):
272
 
        # self.Cleanup()
273
 
 
274
 
        return True
275
 
        
276
 
    def OnGLMFocus(self, event):
277
 
        """Layer Manager focus"""
278
 
        # self.SwitchEnv('original')
279
 
        
280
 
        event.Skip()
281
 
 
282
 
    def Cleanup(self):
283
 
        """Return to current location and mapset"""
284
 
        self.SwitchEnv('original')
285
 
                
286
 
        self.parent.georectifying = None
287
 
 
288
 
        if hasattr(self, "xy_mapdisp"):
289
 
            self.xy_mapdisp.Close()
290
 
            self.xy_mapdisp = None
291
 
 
292
 
        self.wizard.Destroy()
293
 
        
294
 
        # clear GCPs from target display
295
 
        self.parent.curr_page.maptree.mapdisplay.MapWindow.UpdateMap(render=False)
296
 
 
297
 
class LocationPage(TitledPage):
298
 
    """
299
 
    Set map type (raster or vector) to georectify and
300
 
    select location/mapset of map(s) to georectify.
301
 
    """
302
 
    def __init__(self, wizard, parent):
303
 
        TitledPage.__init__(self, wizard, _("Select map type and location/mapset"))
304
 
 
305
 
        self.parent = parent
306
 
        self.grassdatabase = self.parent.grassdatabase
307
 
        
308
 
        self.xylocation = ''
309
 
        self.xymapset = ''
310
 
 
311
 
        tmplist = os.listdir(self.grassdatabase)
312
 
        self.locList = []
313
 
        self.mapsetList = []
314
 
        
315
 
        #
316
 
        # create a list of valid locations
317
 
        #
318
 
        for item in tmplist:
319
 
            if os.path.isdir(os.path.join(self.grassdatabase, item)) and \
320
 
                    os.path.exists(os.path.join(self.grassdatabase, item, 'PERMANENT')):
321
 
                self.locList.append(item)
322
 
 
323
 
        utils.ListSortLower(self.locList)
324
 
        
325
 
        #
326
 
        # layout
327
 
        #
328
 
        self.sizer.AddGrowableCol(2)
329
 
        # map type
330
 
        self.rb_maptype = wx.RadioBox(parent=self, id=wx.ID_ANY,
331
 
                                      label=' %s ' % _("Map type to georectify"),
332
 
                                      choices=[_('raster'), _('vector')],
333
 
                                      majorDimension=wx.RA_SPECIFY_COLS)
334
 
        self.sizer.Add(item=self.rb_maptype,
335
 
                       flag=wx.ALIGN_CENTER | wx.ALL | wx.EXPAND, border=5,
336
 
                       pos=(1, 1), span=(1, 2))
337
 
 
338
 
        # location
339
 
        self.sizer.Add(item=wx.StaticText(parent=self, id=wx.ID_ANY, label=_('Select source location:')),
340
 
                       flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5,
341
 
                       pos=(2, 1))
342
 
        self.cb_location = wx.ComboBox(parent=self, id=wx.ID_ANY, 
343
 
                                     choices = self.locList, size=(300, -1),
344
 
                                     style=wx.CB_DROPDOWN | wx.CB_READONLY)
345
 
        self.sizer.Add(item=self.cb_location,
346
 
                       flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5,
347
 
                       pos=(2, 2))
348
 
 
349
 
        # mapset
350
 
        self.sizer.Add(item=wx.StaticText(parent=self, id=wx.ID_ANY, label=_('Select source mapset:')),
351
 
                       flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5,
352
 
                       pos=(3, 1))
353
 
        self.cb_mapset = wx.ComboBox(parent=self, id=wx.ID_ANY,
354
 
                                     choices = self.mapsetList, size=(300, -1),
355
 
                                     style=wx.CB_DROPDOWN | wx.CB_READONLY)
356
 
        self.sizer.Add(item=self.cb_mapset,
357
 
                       flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5,
358
 
                       pos=(3,2))
359
 
 
360
 
        #
361
 
        # bindings
362
 
        #
363
 
        self.Bind(wx.EVT_RADIOBOX, self.OnMaptype, self.rb_maptype)
364
 
        self.Bind(wx.EVT_COMBOBOX, self.OnLocation, self.cb_location)
365
 
        self.Bind(wx.EVT_COMBOBOX, self.OnMapset, self.cb_mapset)
366
 
        self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
367
 
        self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnEnterPage)
368
 
        # self.Bind(wx.EVT_CLOSE, self.parent.Cleanup)
369
 
 
370
 
    def OnMaptype(self,event):
371
 
        """Change map type"""
372
 
        global maptype
373
 
 
374
 
        if event.GetInt() == 0:
375
 
            maptype = 'cell'
376
 
        else:
377
 
            maptype = 'vector'
378
 
        
379
 
    def OnLocation(self, event):
380
 
        """Sets source location for map(s) to georectify"""
381
 
        self.xylocation = event.GetString()
382
 
        
383
 
        #create a list of valid mapsets
384
 
        tmplist = os.listdir(os.path.join(self.grassdatabase, self.xylocation))
385
 
        self.mapsetList = []
386
 
        for item in tmplist:
387
 
            if os.path.isdir(os.path.join(self.grassdatabase, self.xylocation, item)) and \
388
 
                os.path.exists(os.path.join(self.grassdatabase, self.xylocation, item, 'WIND')):
389
 
                if item != 'PERMANENT':
390
 
                    self.mapsetList.append(item)
391
 
 
392
 
        self.xymapset = 'PERMANENT'
393
 
        utils.ListSortLower(self.mapsetList)
394
 
        self.mapsetList.insert(0, 'PERMANENT')
395
 
        self.cb_mapset.SetItems(self.mapsetList)
396
 
        self.cb_mapset.SetStringSelection(self.xymapset)
397
 
        
398
 
        if not wx.FindWindowById(wx.ID_FORWARD).IsEnabled():
399
 
            wx.FindWindowById(wx.ID_FORWARD).Enable(True)
400
 
 
401
 
    def OnMapset(self, event):
402
 
        """Sets source mapset for map(s) to georectify"""
403
 
        if self.xylocation == '':
404
 
            wx.MessageBox(_('You must select a valid location before selecting a mapset'))
405
 
            return
406
 
 
407
 
        self.xymapset = event.GetString()
408
 
        
409
 
        if not wx.FindWindowById(wx.ID_FORWARD).IsEnabled():
410
 
            wx.FindWindowById(wx.ID_FORWARD).Enable(True)
411
 
 
412
 
    def OnPageChanging(self, event=None):
413
 
        if event.GetDirection() and \
414
 
               (self.xylocation == '' or self.xymapset == ''):
415
 
            wx.MessageBox(_('You must select a valid location and mapset in order to continue'))
416
 
            event.Veto()
417
 
            return
418
 
        
419
 
        self.parent.SetSrcEnv(self.xylocation, self.xymapset)
420
 
        
421
 
    def OnEnterPage(self, event=None):
422
 
        if self.xylocation == '' or self.xymapset == '':
423
 
            wx.FindWindowById(wx.ID_FORWARD).Enable(False)
424
 
        else:
425
 
            wx.FindWindowById(wx.ID_FORWARD).Enable(True)
426
 
 
427
 
class GroupPage(TitledPage):
428
 
    """
429
 
    Set group to georectify. Create group if desired.
430
 
    """
431
 
    def __init__(self, wizard, parent):
432
 
        TitledPage.__init__(self, wizard, _("Select image/map group to georectify"))
433
 
 
434
 
        self.parent = parent
435
 
        
436
 
        self.grassdatabase = self.parent.grassdatabase
437
 
        self.groupList = []
438
 
        
439
 
        self.xylocation = ''
440
 
        self.xymapset = ''
441
 
        self.xygroup = ''
442
 
 
443
 
        # default extension
444
 
        self.extension = 'georect' + str(os.getpid())
445
 
 
446
 
        #
447
 
        # layout
448
 
        #
449
 
        self.sizer.AddGrowableCol(2)
450
 
        # group
451
 
        self.sizer.Add(item=wx.StaticText(parent=self, id=wx.ID_ANY, label=_('Select group:')),
452
 
                       flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5,
453
 
                       pos=(1, 1))
454
 
        self.cb_group = wx.ComboBox(parent=self, id=wx.ID_ANY,
455
 
                                    choices=self.groupList, size=(350, -1),
456
 
                                    style=wx.CB_DROPDOWN | wx.CB_READONLY)
457
 
        self.sizer.Add(item=self.cb_group,
458
 
                       flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5,
459
 
                       pos=(1, 2))
460
 
        
461
 
        # create group               
462
 
        self.sizer.Add(item=wx.StaticText(parent=self, id=wx.ID_ANY, label=_('Create group if none exists')),
463
 
                       flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5,
464
 
                       pos=(2, 1))
465
 
        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
466
 
        self.btn_mkgroup = wx.Button(parent=self, id=wx.ID_ANY, label=_("Create/edit group..."))
467
 
        self.btn_vgroup = wx.Button(parent=self, id=wx.ID_ANY, label=_("Add vector map to group..."))
468
 
        self.btn_vgroup.Hide()
469
 
        btnSizer.Add(item=self.btn_mkgroup,
470
 
                     flag=wx.RIGHT, border=5)
471
 
 
472
 
        btnSizer.Add(item=self.btn_vgroup,
473
 
                     flag=wx.LEFT, border=5)
474
 
        
475
 
        self.sizer.Add(item=btnSizer,
476
 
                       flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5,
477
 
                       pos=(2, 2))
478
 
        
479
 
        # extension
480
 
        self.sizer.Add(item=wx.StaticText(parent=self, id=wx.ID_ANY, label=_('Extension for output maps:')),
481
 
                       flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5,
482
 
                       pos=(3, 1))
483
 
        self.ext_txt = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="", size=(350,-1))
484
 
        self.ext_txt.SetValue(self.extension)
485
 
        self.sizer.Add(item=self.ext_txt,
486
 
                       flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5,
487
 
                       pos=(3, 2))
488
 
 
489
 
        #
490
 
        # bindings
491
 
        #
492
 
        self.Bind(wx.EVT_COMBOBOX, self.OnGroup, self.cb_group)
493
 
        self.Bind(wx.EVT_TEXT, self.OnExtension, self.ext_txt)
494
 
        self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
495
 
        self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnEnterPage)
496
 
        self.Bind(wx.EVT_CLOSE, self.parent.Cleanup)
497
 
 
498
 
    def OnGroup(self, event):        
499
 
        self.xygroup = event.GetString()
500
 
        
501
 
    def OnMkGroup(self, event):
502
 
        """Create new group in source location/mapset"""
503
 
        menuform.GUI().ParseCommand(['i.group'],
504
 
                                    completed=(self.GetOptData, None, ''),
505
 
                                    parentframe=self.parent.parent, modal=True)
506
 
                                    
507
 
    def OnVGroup(self, event):
508
 
        """Add vector maps to group"""
509
 
        dlg = VectGroup(parent = self,
510
 
                        id = wx.ID_ANY,
511
 
                        grassdb = self.grassdatabase,
512
 
                        location = self.xylocation,
513
 
                        mapset = self.xymapset,
514
 
                        group = self.xygroup)
515
 
 
516
 
        if dlg.ShowModal() != wx.ID_OK:
517
 
            return
518
 
 
519
 
        dlg.MakeVGroup()
520
 
        self.OnEnterPage()
521
 
        
522
 
    def GetOptData(self, dcmd, layer, params, propwin):
523
 
        """Process i.group"""
524
 
        # update the page
525
 
        if dcmd:
526
 
            gcmd.Command(dcmd)
527
 
 
528
 
        self.OnEnterPage()
529
 
        self.Update()
530
 
        
531
 
    def OnExtension(self, event):
532
 
        self.extension = event.GetString()
533
 
 
534
 
    def OnPageChanging(self, event=None):
535
 
        if event.GetDirection() and self.xygroup == '':
536
 
            wx.MessageBox(_('You must select a valid image/map group in order to continue'))
537
 
            event.Veto()
538
 
            return
539
 
 
540
 
        if event.GetDirection() and self.extension == '':
541
 
            wx.MessageBox(_('You must enter an map name extension in order to continue'))
542
 
            event.Veto()
543
 
            return
544
 
 
545
 
    def OnEnterPage(self, event=None):
546
 
        global maptype
547
 
        
548
 
        self.groupList = []
549
 
 
550
 
        self.xylocation = self.parent.gisrc_dict['LOCATION_NAME']
551
 
        self.xymapset = self.parent.gisrc_dict['MAPSET']
552
 
 
553
 
        # create a list of groups in selected mapset
554
 
        if os.path.isdir(os.path.join(self.grassdatabase,
555
 
                                      self.xylocation,
556
 
                                      self.xymapset,
557
 
                                      'group')):
558
 
            tmplist = os.listdir(os.path.join(self.grassdatabase,
559
 
                                              self.xylocation,
560
 
                                              self.xymapset,
561
 
                                              'group'))
562
 
            for item in tmplist:
563
 
                if os.path.isdir(os.path.join(self.grassdatabase,
564
 
                                              self.xylocation,
565
 
                                              self.xymapset,
566
 
                                              'group',
567
 
                                              item)):
568
 
                    self.groupList.append(item)
569
 
        
570
 
        if maptype == 'cell':
571
 
            self.btn_vgroup.Hide()
572
 
            self.Bind(wx.EVT_BUTTON, self.OnMkGroup, self.btn_mkgroup)
573
 
 
574
 
        elif maptype == 'vector':
575
 
            self.btn_vgroup.Show()
576
 
            self.Bind(wx.EVT_BUTTON, self.OnMkGroup, self.btn_mkgroup)
577
 
            self.Bind(wx.EVT_BUTTON, self.OnVGroup, self.btn_vgroup)
578
 
        
579
 
        utils.ListSortLower(self.groupList)
580
 
        self.cb_group.SetItems(self.groupList)
581
 
        
582
 
        if len(self.groupList) > 0 and \
583
 
                self.xygroup == '':
584
 
            self.cb_group.SetSelection(0)
585
 
            self.xygroup = self.groupList[0]
586
 
        
587
 
        if self.xygroup == '' or \
588
 
                self.extension == '':
589
 
            wx.FindWindowById(wx.ID_FORWARD).Enable(False)
590
 
        else:
591
 
            wx.FindWindowById(wx.ID_FORWARD).Enable(True)
592
 
        
593
 
        # switch to source
594
 
        self.parent.SwitchEnv('new')
595
 
    
596
 
class DispMapPage(TitledPage):
597
 
    """
598
 
    Select ungeoreferenced map to display for interactively
599
 
    setting ground control points (GCPs).
600
 
    """
601
 
    def __init__(self, wizard, parent):
602
 
        TitledPage.__init__(self, wizard,
603
 
                            _("Select image/map to display for ground control point (GCP) creation"))
604
 
 
605
 
        self.parent = parent
606
 
        global maptype
607
 
 
608
 
        #
609
 
        # layout
610
 
        #
611
 
        self.sizer.Add(item=wx.StaticText(parent=self, id=wx.ID_ANY, label=_('Select display image/map:')),
612
 
                       flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5,
613
 
                       pos=(1, 1))
614
 
        
615
 
        self.selection = gselect.Select(self, id=wx.ID_ANY,
616
 
                                        size=globalvar.DIALOG_GSELECT_SIZE)
617
 
        
618
 
        self.sizer.Add(item=self.selection,
619
 
                       flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5,
620
 
                       pos=(1, 2))
621
 
 
622
 
        #
623
 
        # bindings
624
 
        #
625
 
        self.selection.Bind(wx.EVT_TEXT, self.OnSelection)
626
 
        self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
627
 
        self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnEnterPage)
628
 
        self.Bind(wx.EVT_CLOSE, self.parent.Cleanup)
629
 
 
630
 
    def OnSelection(self,event):
631
 
        """Map to display selected"""
632
 
        global xy_map
633
 
        global maptype
634
 
 
635
 
        xy_map = event.GetString()
636
 
 
637
 
        if xy_map == '':
638
 
            wx.FindWindowById(wx.ID_FORWARD).Enable(False)
639
 
        else:
640
 
            wx.FindWindowById(wx.ID_FORWARD).Enable(True)
641
 
 
642
 
        try:
643
 
        # set computational region to match selected map and zoom display to region
644
 
            if maptype == 'cell':
645
 
                p = gcmd.RunCommand('g.region', rast = xy_map)
646
 
            elif maptype == 'vector':
647
 
                p = gcmd.RunCommand('g.region', vect = xy_map)       
648
 
        except:
649
 
            pass
650
 
 
651
 
    def OnPageChanging(self, event=None):
652
 
        global xy_map
653
 
 
654
 
        if event.GetDirection() and xy_map == '':
655
 
            wx.MessageBox(_('You must select a valid image/map in order to continue'))
656
 
            event.Veto()
657
 
            return
658
 
        self.parent.SwitchEnv('original')
659
 
        
660
 
    def OnEnterPage(self, event=None):
661
 
        global maptype
662
 
        global xy_map
663
 
        
664
 
        self.selection.SetElementList(maptype,
665
 
                                      mapsets = [self.parent.newmapset, ])
666
 
 
667
 
        if xy_map == '':
668
 
            wx.FindWindowById(wx.ID_FORWARD).Enable(False)
669
 
        else:
670
 
            wx.FindWindowById(wx.ID_FORWARD).Enable(True)
671
 
 
672
 
class GCP(wx.Frame):
673
 
    """
674
 
    Manages ground control points for georectifying. Calculates RMS statics.
675
 
    Calls i.rectify or v.transform to georectify map.
676
 
    """
677
 
 
678
 
    def __init__(self, parent, grwiz, mapdisp=None, id=wx.ID_ANY,
679
 
                 title=_("Define/manage ground control points"),
680
 
                 size=wx.DefaultSize):
681
 
 
682
 
        wx.Frame.__init__(self, parent, id, title, size=(625, 300))
683
 
 
684
 
        self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass_map.ico'), wx.BITMAP_TYPE_ICO))
685
 
        
686
 
        #
687
 
        # init variables
688
 
        #
689
 
        self.parent = parent # GMFrame
690
 
        self.parent.georectifying = self
691
 
        
692
 
        self.mapdisp = mapdisp # XY-location Map Display
693
 
        self.grwiz = grwiz # GR Wizard
694
 
 
695
 
        self.grassdatabase = self.grwiz.grassdatabase
696
 
 
697
 
        self.currentlocation = self.grwiz.currentlocation
698
 
        self.currentmapset = self.grwiz.currentmapset
699
 
 
700
 
        self.newlocation = self.grwiz.newlocation
701
 
        self.newmapset = self.grwiz.newmapset
702
 
 
703
 
        self.xylocation = self.grwiz.gisrc_dict['LOCATION_NAME']
704
 
        self.xymapset = self.grwiz.gisrc_dict['MAPSET']
705
 
        self.xygroup = self.grwiz.grouppage.xygroup
706
 
        self.extension = self.grwiz.grouppage.extension
707
 
        self.VectGRList = []
708
 
 
709
 
        self.file = {
710
 
            'points' : os.path.join(self.grassdatabase,
711
 
                                    self.xylocation,
712
 
                                    self.xymapset,
713
 
                                    'group',
714
 
                                    self.xygroup,
715
 
                                    'POINTS'),
716
 
            'rgrp' : os.path.join(self.grassdatabase,
717
 
                                  self.xylocation,
718
 
                                  self.xymapset,
719
 
                                  'group',
720
 
                                  self.xygroup,
721
 
                                  'REF'),
722
 
            'vgrp' : os.path.join(self.grassdatabase,
723
 
                                  self.xylocation,
724
 
                                  self.xymapset,
725
 
                                  'group',
726
 
                                  self.xygroup,
727
 
                                  'VREF'),
728
 
            'target' : os.path.join(self.grassdatabase,
729
 
                                    self.xylocation,
730
 
                                    self.xymapset,
731
 
                                    'group',
732
 
                                    self.xygroup,
733
 
                                    'TARGET'),
734
 
            }
735
 
        
736
 
        # polynomial order transformation for georectification
737
 
        self.gr_order = 1 
738
 
        # number of GCPs selected to be used for georectification (checked)
739
 
        self.GCPcount = 0
740
 
        # forward RMS error
741
 
        self.fwd_rmserror = 0.0
742
 
        # backward RMS error
743
 
        self.bkw_rmserror = 0.0
744
 
        # list map coords and ID of map display they came from
745
 
        self.mapcoordlist = [] 
746
 
        # region clipping for georectified map
747
 
        self.clip_to_region = False
748
 
 
749
 
        self.SetTarget(self.xygroup, self.currentlocation, self.currentmapset)
750
 
 
751
 
        #
752
 
        # toolbar and display for xy map
753
 
        #
754
 
        self.toolbar = toolbars.GCPToolbar(parent=self, tbframe=self).GetToolbar()
755
 
        self.SetToolBar(self.toolbar)
756
 
        
757
 
        self.SetMapDisplay(self.mapdisp)
758
 
 
759
 
        #
760
 
        # statusbar 
761
 
        #
762
 
        self.CreateStatusBar(number=1)
763
 
        
764
 
        # can put guage into custom statusbar for progress if can figure out how to get progress text from i.rectify
765
 
        # self.gr_gauge = wx.Gauge(self, -1, 100, (-1,-1), (100, 25))
766
 
        # self.gr_guage.Pulse()
767
 
 
768
 
        panel = wx.Panel(parent=self)
769
 
 
770
 
        #
771
 
        # do layout
772
 
        #
773
 
        sizer = wx.BoxSizer(wx.VERTICAL)
774
 
 
775
 
        self.rb_grmethod = wx.RadioBox(parent=panel, id=wx.ID_ANY,
776
 
                                       label=" %s " % _("Select rectification method for rasters"),
777
 
                                       choices=[_('1st order'), _('2nd order'), _('3rd order')],
778
 
                                       majorDimension=wx.RA_SPECIFY_COLS)
779
 
        sizer.Add(item=self.rb_grmethod, proportion=0,
780
 
                       flag=wx.EXPAND | wx.ALL, border=5)
781
 
        
782
 
        self.check = wx.CheckBox(parent=panel, id=wx.ID_ANY,
783
 
                                label=_("clip to computational region in target location"))
784
 
        sizer.Add(item=self.check, proportion=0,
785
 
                       flag=wx.EXPAND | wx.ALL, border=5)
786
 
 
787
 
        box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
788
 
                            label=" %s " % _("Ground Control Points"))
789
 
        boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
790
 
 
791
 
        # initialize list control for GCP management
792
 
        self.list = GCPList(parent=panel, gcp=self)
793
 
 
794
 
        boxSizer.Add(item=self.list, proportion=1,
795
 
                     flag=wx.EXPAND | wx.ALL, border=3)
796
 
 
797
 
        sizer.Add(item=boxSizer, proportion=1,
798
 
                  flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border=5)
799
 
 
800
 
        #
801
 
        # bindigs
802
 
        #
803
 
        self.Bind(wx.EVT_RADIOBOX, self.OnGRMethod, self.rb_grmethod)
804
 
        self.Bind(wx.EVT_ACTIVATE, self.OnFocus)
805
 
        self.Bind(wx.EVT_CLOSE, self.OnQuit)
806
 
        self.Bind(wx.EVT_CHECKBOX, self.ClipRegion, self.check)
807
 
 
808
 
        panel.SetSizer(sizer)
809
 
        # sizer.Fit(self)
810
 
 
811
 
    def __del__(self):
812
 
        """Disable georectification mode"""
813
 
        self.parent.georectifying = None
814
 
        
815
 
    def ClipRegion(self, event):
816
 
        self.clip_to_region = event.IsChecked()
817
 
        
818
 
    def SetMapDisplay(self, win):
819
 
        self.mapdisp = win
820
 
        if self.mapdisp:
821
 
             self.list.LoadData()
822
 
 
823
 
    def SetTarget(self, tgroup, tlocation, tmapset):
824
 
        """
825
 
        Sets rectification target to current location and mapset
826
 
        """
827
 
        # check to see if we are georectifying map in current working location/mapset
828
 
        if self.newlocation == self.currentlocation and self.newmapset == self.currentmapset:
829
 
            cmdlist = ['i.target',
830
 
                       '-c',
831
 
                       'group=%s' % tgroup]
832
 
        else:
833
 
            self.grwiz.SwitchEnv('new')
834
 
            cmdlist = ['i.target',
835
 
                       'group=%s' % tgroup,
836
 
                       'location=%s' % tlocation,
837
 
                       'mapset=%s' % tmapset]
838
 
        gcmd.Command(cmd=cmdlist, stderr=None)
839
 
 
840
 
        self.grwiz.SwitchEnv('original')
841
 
 
842
 
    def AddGCP(self, event):
843
 
        """
844
 
        Appends an item to GCP list
845
 
        """
846
 
        self.list.AddGCPItem()
847
 
        # x, y, MapWindow instance
848
 
        self.mapcoordlist.append({ 'gcpcoord' : (0.0, 0.0, None),
849
 
                                   'mapcoord' : (0.0, 0.0, None) })
850
 
 
851
 
    def DeleteGCP(self, event):
852
 
        """
853
 
        Deletes selected item in GCP list
854
 
        """
855
 
        minNumOfItems = self.OnGRMethod(None)
856
 
 
857
 
        if self.list.GetItemCount() <= minNumOfItems:
858
 
            wx.MessageBox(parent=self, message=_("At least %d GCPs required. Operation cancelled.") % minNumOfItems,
859
 
                          caption=_("Delete GCP"), style=wx.OK | wx.ICON_INFORMATION)
860
 
            return
861
 
 
862
 
        item = self.list.DeleteGCPItem()
863
 
        del self.mapcoordlist[item]
864
 
 
865
 
    def ClearGCP(self, event):
866
 
        """
867
 
        Clears all values in selected item of GCP list and unchecks it
868
 
        """
869
 
        index = self.list.GetSelected()
870
 
 
871
 
        for i in range(4):
872
 
            self.list.SetStringItem(index, i, '0.0')
873
 
        self.list.SetStringItem(index, 4, '')
874
 
        self.list.SetStringItem(index, 5, '')
875
 
        self.list.CheckItem(index, False)
876
 
 
877
 
        self.mapcoordlist[index] = { 'gcpcoord' : (0.0, 0.0, None),
878
 
                                     'mapcoord' : (0.0, 0.0, None) }
879
 
 
880
 
    def DrawGCP(self, coordtype):
881
 
        """
882
 
        Updates GCP and map coord maps and redraws
883
 
        active (checked) GCP markers
884
 
        """
885
 
        col = UserSettings.Get(group='georect', key='symbol', subkey='color')
886
 
        wxCol = wx.Colour(col[0], col[1], col[2], 255)
887
 
        wpx = UserSettings.Get(group='georect', key='symbol', subkey='width')
888
 
        font = self.GetFont()
889
 
        
890
 
        penOrig = polypenOrig = None
891
 
        
892
 
        idx = 0
893
 
        for gcp in self.mapcoordlist:
894
 
            mapWin = gcp[coordtype][2]
895
 
            if not self.list.IsChecked(idx) or not mapWin:
896
 
                idx += 1
897
 
                continue
898
 
            
899
 
            if not penOrig:
900
 
                penOrig = mapWin.pen
901
 
                polypenOrig = mapWin.polypen
902
 
                mapWin.pen = wx.Pen(colour=wxCol, width=wpx, style=wx.SOLID)
903
 
                mapWin.polypen = wx.Pen(colour=wxCol, width=wpx, style=wx.SOLID) # ?
904
 
            
905
 
            coord = mapWin.Cell2Pixel((gcp[coordtype][0], gcp[coordtype][1]))
906
 
            mapWin.DrawCross(pdc=mapWin.pdcTmp, coords=coord,
907
 
                             size=5, text={ 'text' : '%s' % str(idx + 1),
908
 
                                            'active' : True,
909
 
                                            'font' : font,
910
 
                                            'color': wxCol,
911
 
                                            'coords': [coord[0] + 5,
912
 
                                                       coord[1] + 5,
913
 
                                                       5,
914
 
                                                       5]})
915
 
            idx += 1
916
 
            
917
 
        if penOrig:
918
 
            mapWin.pen = penOrig
919
 
            mapWin.polypen = polypenOrig
920
 
        
921
 
    def SetGCPData(self, coordtype, coord, mapdisp=None, check=True):
922
 
        """
923
 
        Inserts coordinates from mouse click on map
924
 
        into selected item of GCP list and checks it for use
925
 
        """
926
 
        
927
 
        index = self.list.GetSelected()
928
 
        if index == wx.NOT_FOUND:
929
 
            return
930
 
 
931
 
        coord0 = str(coord[0])
932
 
        coord1 = str(coord[1])
933
 
 
934
 
        if coordtype == 'gcpcoord':
935
 
            self.list.SetStringItem(index, 0, coord0)
936
 
            self.list.SetStringItem(index, 1, coord1)
937
 
            self.mapcoordlist[index]['gcpcoord'] = (coord[0], coord[1], mapdisp)
938
 
        elif coordtype == 'mapcoord':
939
 
            self.list.SetStringItem(index, 2, coord0)
940
 
            self.list.SetStringItem(index, 3, coord1)
941
 
            
942
 
        self.mapcoordlist[index][coordtype] = (coord[0], coord[1], mapdisp)
943
 
 
944
 
        self.list.CheckItem(index, check)
945
 
 
946
 
        # self.list.ResizeColumns()
947
 
 
948
 
    def SaveGCPs(self, event):
949
 
        """
950
 
        Make a POINTS file or save GCP coordinates to existing POINTS file
951
 
        """
952
 
        
953
 
        self.GCPcount = 0
954
 
        try:
955
 
            f = open(self.file['points'], mode='w')
956
 
            # use os.linesep or '\n' here ???
957
 
            f.write('# Ground Control Points File\n')
958
 
            f.write("# \n")
959
 
            f.write("# target location: " + self.currentlocation + '\n')
960
 
            f.write("# target mapset: " + self.currentmapset + '\n')
961
 
            f.write("#unrectified xy     georectified east north     1=use gcp point\n")
962
 
            f.write("#--------------     -----------------------     ---------------\n")
963
 
 
964
 
            for index in range(self.list.GetItemCount()):
965
 
                if self.list.IsChecked(index) == True:
966
 
                    check = "1"
967
 
                    self.GCPcount += 1
968
 
                else:
969
 
                    check = "0"
970
 
                coord0 = self.list.GetItem(index, 0).GetText()
971
 
                coord1 = self.list.GetItem(index, 1).GetText()
972
 
                coord2 = self.list.GetItem(index, 2).GetText()
973
 
                coord3 = self.list.GetItem(index, 3).GetText()
974
 
                f.write(coord0 + ' ' + coord1 + '     ' + coord2 + ' ' + coord3 + '     ' + check + '\n')
975
 
 
976
 
            self.parent.goutput.WriteLog(_('POINTS file <%s> saved') % self.file['points'])
977
 
            self.SetStatusText(_('POINTS file saved'))
978
 
        except IOError, err:
979
 
            wx.MessageBox(parent=self,
980
 
                          message="%s <%s>. %s%s" % (_("Writing POINTS file failed"),
981
 
                                                     self.file['points'], os.linesep, err),
982
 
                          caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
983
 
            return
984
 
 
985
 
        f.close()
986
 
 
987
 
    def ReadGCPs(self):
988
 
        """
989
 
        Reads GCPs and georectified coordinates from POINTS file
990
 
        """
991
 
        
992
 
        self.GCPcount = 0
993
 
 
994
 
        sourceMapWin = self.mapdisp.MapWindow
995
 
        targetMapWin = self.parent.curr_page.maptree.mapdisplay.MapWindow
996
 
            
997
 
        try:
998
 
            f = open(self.file['points'], 'r')
999
 
            GCPcnt = 0
1000
 
            
1001
 
            for line in f.readlines():
1002
 
                if line[0] == '#' or line =='':
1003
 
                    continue
1004
 
                line = line.replace('\n', '').strip()
1005
 
                coords = map(float, line.split())
1006
 
                if coords[4] == 1:
1007
 
                    check = True
1008
 
                    self.GCPcount +=1
1009
 
                else:
1010
 
                    check = False
1011
 
                index = self.AddGCP(event=None)
1012
 
                self.SetGCPData('gcpcoord', (coords[0], coords[1]), sourceMapWin, check)
1013
 
                self.SetGCPData('mapcoord', (coords[2], coords[3]), targetMapWin, check)
1014
 
 
1015
 
        except IOError, err:
1016
 
            wx.MessageBox(parent=self,
1017
 
                          message="%s <%s>. %s%s" % (_("Reading POINTS file failed"),
1018
 
                                                     self.file['points'], os.linesep, err),
1019
 
                          caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
1020
 
            return
1021
 
 
1022
 
        f.close()
1023
 
 
1024
 
        #
1025
 
        # draw GCPs (source and target)
1026
 
        #
1027
 
        sourceMapWin.UpdateMap(render=False, renderVector=False)
1028
 
        if targetMapWin:
1029
 
            targetMapWin.UpdateMap(render=False, renderVector=False)
1030
 
 
1031
 
        #
1032
 
        # calculate RMS
1033
 
        #
1034
 
        # FIXME auto calculation on load is not working
1035
 
        #if self.CheckGCPcount():
1036
 
        #    self.RMSError(self.xygroup, self.gr_order)
1037
 
 
1038
 
    def ReloadGCPs(self, event):
1039
 
        """Reload data from file"""
1040
 
        self.list.LoadData()
1041
 
    
1042
 
    def OnFocus(self, event):
1043
 
        # self.grwiz.SwitchEnv('new')
1044
 
        pass
1045
 
        
1046
 
    def OnRMS(self, event):
1047
 
        """
1048
 
        RMS button handler
1049
 
        """
1050
 
        self.RMSError(self.xygroup,self.gr_order)
1051
 
        
1052
 
    def CheckGCPcount(self, msg=False):
1053
 
        """
1054
 
        Checks to make sure that the minimum number of GCPs have been defined and
1055
 
        are active for the selected transformation order
1056
 
        """
1057
 
        if (self.GCPcount < 3 and self.gr_order == 1) or \
1058
 
            (self.GCPcount < 6 and self.gr_order == 2) or \
1059
 
            (self.GCPcount < 10 and self.gr_order == 3):
1060
 
            if msg:
1061
 
                wx.MessageBox(parent=self,
1062
 
                              caption=_("RMS Error"),
1063
 
                              message=_('Insufficient points defined and active (checked) '
1064
 
                                        'for selected rectification method.\n'
1065
 
                                        '3+ points needed for 1st order,\n'
1066
 
                                        '6+ points for 2nd order, and\n'
1067
 
                                        '10+ points for 3rd order.'),
1068
 
                              style=wx.ICON_INFORMATION | wx.ID_OK | wx.CENTRE)
1069
 
                return False
1070
 
        else:
1071
 
            return True
1072
 
 
1073
 
    def OnGeorect(self, event):
1074
 
        """
1075
 
        Georectifies map(s) in group using i.rectify or v.transform
1076
 
        """
1077
 
        global maptype
1078
 
        self.SaveGCPs(None)
1079
 
        
1080
 
        if self.CheckGCPcount(msg=True) == False:
1081
 
            return
1082
 
 
1083
 
        if maptype == 'cell':
1084
 
            self.grwiz.SwitchEnv('new')
1085
 
            cmdlist = ['i.rectify','-a','group=%s' % self.xygroup,
1086
 
                       'extension=%s' % self.extension,'order=%s' % self.gr_order]
1087
 
            if self.clip_to_region:
1088
 
                cmdlist.append('-c')
1089
 
                
1090
 
            p = gcmd.Command(cmdlist)
1091
 
            
1092
 
            output = p.ReadStdOutput()
1093
 
            error = p.ReadErrOutput()
1094
 
            
1095
 
            # printing to console
1096
 
            for i in error: 
1097
 
                try:
1098
 
                    msgtype, msg = i.split(':')
1099
 
                    if msgtype != 'GRASS_INFO_PERCENT':
1100
 
                        self.parent.goutput.WriteLog(text = _(msg), switchPage = True)
1101
 
                except:
1102
 
                    continue
1103
 
            for i in output: 
1104
 
                self.parent.goutput.WriteLog(text = _(msg), switchPage = True)
1105
 
            
1106
 
            if p.returncode == 0:
1107
 
                wx.MessageBox('Maps in group %s georectified successfully' % self.xygroup)
1108
 
            else:
1109
 
                wx.MessageBox('ERROR...',error)
1110
 
 
1111
 
            time.sleep(.1)
1112
 
            self.grwiz.SwitchEnv('original')
1113
 
 
1114
 
        elif maptype == 'vector':
1115
 
            outmsg = ''
1116
 
            # loop through all vectors in VREF
1117
 
            # and move resulting vector to target location
1118
 
            
1119
 
            # make sure current mapset has a vector folder
1120
 
            if not os.path.isdir(os.path.join(self.grassdatabase,
1121
 
                                              self.currentlocation,
1122
 
                                              self.currentmapset,
1123
 
                                              'vector')):
1124
 
                os.mkdir(os.path.join(self.grassdatabase,
1125
 
                                      self.currentlocation,
1126
 
                                      self.currentmapset,
1127
 
                                      'vector'))
1128
 
 
1129
 
            self.grwiz.SwitchEnv('new')
1130
 
            
1131
 
            # make list of vectors to georectify from VREF
1132
 
            f = open(self.file['vgrp'])
1133
 
            vectlist = []
1134
 
            try:
1135
 
                for vect in f.readlines():
1136
 
                    vect = vect.strip('\n')
1137
 
                    if len(vect) < 1:
1138
 
                        continue
1139
 
                    vectlist.append(vect)
1140
 
            finally:
1141
 
                f.close()
1142
 
                               
1143
 
            # georectify each vector in VREF using v.transform
1144
 
            for vect in vectlist:
1145
 
                self.outname = vect + '_' + self.extension
1146
 
                self.parent.goutput.WriteLog(text = _('Transforming <%s>...') % vect,
1147
 
                                             switchPage = True)
1148
 
                                             
1149
 
                p = gcmd.Command(['v.transform', 
1150
 
                                 '--o', 
1151
 
                                 'input=%s' % vect, 
1152
 
                                 'output=%s' % self.outname,
1153
 
                                 'points=%s' % self.file['points']])
1154
 
 
1155
 
                output = p.ReadStdOutput()
1156
 
                error = p.ReadErrOutput()
1157
 
                                
1158
 
                # printing to console
1159
 
                for i in error: 
1160
 
                    try:
1161
 
                        msgtype, msg = i.split(':')
1162
 
                        if msgtype != 'GRASS_INFO_PERCENT':
1163
 
                            self.parent.goutput.WriteLog(text = _(msg), switchPage = True)
1164
 
                    except:
1165
 
                        continue
1166
 
                for i in output: 
1167
 
                    self.parent.goutput.WriteLog(text = _(i), switchPage = True)
1168
 
                        
1169
 
                if p.returncode == 0:
1170
 
                    self.VectGRList.append(self.outname)
1171
 
                else:
1172
 
                    self.parent.goutput.WriteError(_('Georectification of vector map <%s> failed') %
1173
 
                                                           self.outname)
1174
 
 
1175
 
                # FIXME
1176
 
                # Copying database information not working. 
1177
 
                # Does not copy from xy location to current location
1178
 
#                xyLayer = []
1179
 
#                for layer in grass.vector_db(map = vect).itervalues():
1180
 
#                    xyLayer.append((layer['driver'],
1181
 
#                                    layer['database'],
1182
 
#                                    layer['table']))
1183
 
 
1184
 
                        
1185
 
#                dbConnect = grass.db_connection()
1186
 
#                print 'db connection =', dbConnect
1187
 
#                for layer in xyLayer:     
1188
 
#                    self.parent.goutput.RunCmd(['db.copy',
1189
 
#                                                '--q',
1190
 
#                                                '--o',
1191
 
#                                                'from_driver=%s' % layer[0],
1192
 
#                                                'from_database=%s' % layer[1],
1193
 
#                                                'from_table=%s' % layer[2],
1194
 
#                                                'to_driver=%s' % dbConnect['driver'],
1195
 
#                                                'to_database=%s' % dbConnect['database'],
1196
 
#                                                'to_table=%s' % layer[2] + '_' + self.extension])
1197
 
 
1198
 
            # copy all georectified vectors from source location to current location
1199
 
            for name in self.VectGRList:
1200
 
                xyvpath = os.path.join(self.grassdatabase,
1201
 
                                       self.xylocation,
1202
 
                                       self.xymapset,
1203
 
                                       'vector',
1204
 
                                       name)
1205
 
                vpath = os.path.join(self.grassdatabase,
1206
 
                                     self.currentlocation,
1207
 
                                     self.currentmapset,
1208
 
                                     'vector',
1209
 
                                     name)
1210
 
                                    
1211
 
                if os.path.isdir(vpath):
1212
 
                    self.parent.goutput.WriteWarning(_('Vector map <%s> already exists. '
1213
 
                                                       'Change extension name and '
1214
 
                                                       'georectify again.') % self.outname)
1215
 
                    break
1216
 
                else:
1217
 
                    shutil.move(xyvpath, vpath)
1218
 
                                                   
1219
 
        wx.MessageBox('For all vector maps georectified successfully, ' + '\n' +
1220
 
                      'you will need to copy any associated attribute tables' + '\n' +
1221
 
                      'and reconnect them to the georectified vectors')
1222
 
            
1223
 
        self.grwiz.SwitchEnv('original')
1224
 
        
1225
 
    def OnSettings(self, event):
1226
 
        """Georectifier settings"""
1227
 
        dlg = GrSettingsDialog(parent=self, id=wx.ID_ANY, title=_('Georectifier settings'))
1228
 
        
1229
 
        if dlg.ShowModal() == wx.ID_OK:
1230
 
            pass
1231
 
        
1232
 
        dlg.Destroy()
1233
 
 
1234
 
    def OnQuit(self, event):
1235
 
        """Quit georectifier"""
1236
 
        self.grwiz.Cleanup()
1237
 
 
1238
 
        self.Destroy()
1239
 
 
1240
 
        event.Skip()
1241
 
 
1242
 
    def OnGRMethod(self, event):
1243
 
        """
1244
 
        sets transformation order for georectifying
1245
 
        """
1246
 
        if event:
1247
 
            self.gr_order = event.GetInt() + 1
1248
 
 
1249
 
        numOfItems = self.list.GetItemCount()
1250
 
        minNumOfItems = numOfItems
1251
 
        
1252
 
        if self.gr_order == 1:
1253
 
            minNumOfItems = 3
1254
 
            # self.SetStatusText(_('Insufficient points, 3+ points needed for 1st order'))
1255
 
 
1256
 
        elif self.gr_order == 2:
1257
 
            minNumOfItems = 6
1258
 
            diff = 6 - numOfItems
1259
 
            # self.SetStatusText(_('Insufficient points, 6+ points needed for 2nd order'))
1260
 
 
1261
 
        elif self.gr_order == 3:
1262
 
            minNumOfItems = 10
1263
 
            # self.SetStatusText(_('Insufficient points, 10+ points needed for 3rd order'))
1264
 
 
1265
 
        for i in range(minNumOfItems - numOfItems):
1266
 
            self.AddGCP(None)
1267
 
 
1268
 
        return minNumOfItems
1269
 
    
1270
 
    def RMSError(self, xygroup, order):
1271
 
        """
1272
 
        Uses g.transform to calculate forward and backward error for each used GCP
1273
 
        in POINTS file and insert error values into GCP list.
1274
 
        Calculates total forward and backward RMS error for all used points
1275
 
        """
1276
 
        # save GCPs to points file to make sure that all checked GCPs are used
1277
 
        self.SaveGCPs(None)
1278
 
        
1279
 
        if self.CheckGCPcount(msg=True) == False:
1280
 
            return
1281
 
        
1282
 
        # get list of forward and reverse rms error values for each point
1283
 
        self.grwiz.SwitchEnv('new')
1284
 
        
1285
 
        p = gcmd.Command(['g.transform',
1286
 
                          'group=%s' % xygroup,
1287
 
                          'order=%s' % order])
1288
 
        
1289
 
        self.grwiz.SwitchEnv('original')
1290
 
 
1291
 
        errlist = p.ReadStdOutput()
1292
 
        if errlist == []:
1293
 
            return
1294
 
        
1295
 
        # insert error values into GCP list for checked items
1296
 
        i = 0
1297
 
        sumsq_fwd_err = 0.0
1298
 
        sumsq_bkw_err = 0.0
1299
 
        
1300
 
        for index in range(self.list.GetItemCount()):
1301
 
            if self.list.IsChecked(index):
1302
 
                fwd_err, bkw_err = errlist[i].split()
1303
 
                self.list.SetStringItem(index, 4, fwd_err)
1304
 
                self.list.SetStringItem(index, 5, bkw_err)
1305
 
                sumsq_fwd_err += float(fwd_err)**2
1306
 
                sumsq_bkw_err += float(bkw_err)**2
1307
 
                i += 1
1308
 
            else:
1309
 
                self.list.SetStringItem(index, 4, '')
1310
 
                self.list.SetStringItem(index, 5, '')
1311
 
        
1312
 
        # calculate RMS error
1313
 
        self.fwd_rmserror = round((sumsq_fwd_err/i)**0.5,4)
1314
 
        self.bkw_rmserror = round((sumsq_bkw_err/i)**0.5,4)
1315
 
        self.list.ResizeColumns()
1316
 
 
1317
 
        self.SetStatusText(_('RMS error for selected points forward: %(fwd)s backward: %(bkw)s') % \
1318
 
                           { 'fwd' : self.fwd_rmserror, 'bkw' : self.bkw_rmserror })
1319
 
        
1320
 
class GCPList(wx.ListCtrl,
1321
 
              CheckListCtrlMixin,
1322
 
              ListCtrlAutoWidthMixin):
1323
 
              
1324
 
    def __init__(self, parent, gcp, id=wx.ID_ANY,
1325
 
                 pos=wx.DefaultPosition, size=wx.DefaultSize,
1326
 
                 style=wx.LC_REPORT | wx.SUNKEN_BORDER | wx.LC_HRULES |
1327
 
                 wx.LC_SINGLE_SEL):
1328
 
 
1329
 
        wx.ListCtrl.__init__(self, parent, id, pos, size, style)
1330
 
 
1331
 
        # Mixin settings
1332
 
        CheckListCtrlMixin.__init__(self)
1333
 
        ListCtrlAutoWidthMixin.__init__(self)
1334
 
        # TextEditMixin.__init__(self)
1335
 
 
1336
 
        self.gcp = gcp # GCP class
1337
 
 
1338
 
        # tracks whether list items are checked or not
1339
 
        self.CheckList = [] 
1340
 
 
1341
 
        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected)
1342
 
        self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated)
1343
 
 
1344
 
        self._Create()
1345
 
 
1346
 
        self.selected = wx.NOT_FOUND
1347
 
 
1348
 
    def _Create(self):
1349
 
        idx_col = 0
1350
 
        for col in (_('use| X coord'),
1351
 
                    _('Y coord'),
1352
 
                    _('E coord'),
1353
 
                    _('N coord'),
1354
 
                    _('Forward error'),
1355
 
                    _('Backward error')):
1356
 
            self.InsertColumn(idx_col, col)
1357
 
            idx_col += 1
1358
 
        
1359
 
    def LoadData(self):
1360
 
        """Load data into list"""
1361
 
        self.DeleteAllItems()
1362
 
 
1363
 
        if os.path.isfile(self.gcp.file['points']):
1364
 
            self.gcp.ReadGCPs()
1365
 
        else:
1366
 
            # 3 gcp is minimum
1367
 
            for i in range(3):
1368
 
                self.gcp.AddGCP(None)
1369
 
 
1370
 
        # select first point by default
1371
 
        self.selected = 0
1372
 
        self.SetItemState(self.selected,
1373
 
                          wx.LIST_STATE_SELECTED,
1374
 
                          wx.LIST_STATE_SELECTED)
1375
 
 
1376
 
        self.ResizeColumns()
1377
 
 
1378
 
    def OnCheckItem(self, index, flag):
1379
 
        """Item is checked/unchecked"""
1380
 
        pass
1381
 
    
1382
 
    def AddGCPItem(self):
1383
 
        """
1384
 
        Appends an item to GCP list
1385
 
        """
1386
 
        self.Append(['0.0',
1387
 
                     '0.0',
1388
 
                     '0.0',
1389
 
                     '0.0',
1390
 
                     '',
1391
 
                     ''])
1392
 
 
1393
 
        self.selected = self.GetItemCount() - 1
1394
 
 
1395
 
        self.SetItemState(self.selected,
1396
 
                          wx.LIST_STATE_SELECTED,
1397
 
                          wx.LIST_STATE_SELECTED)
1398
 
 
1399
 
        self.ResizeColumns()
1400
 
 
1401
 
        return self.selected
1402
 
 
1403
 
    def DeleteGCPItem(self):
1404
 
        """
1405
 
        Deletes selected item in GCP list
1406
 
        """
1407
 
        if self.selected == wx.NOT_FOUND:
1408
 
            return
1409
 
 
1410
 
        self.DeleteItem(self.selected)
1411
 
 
1412
 
        if self.GetItemCount() > 0:
1413
 
            self.selected = self.GetItemCount() - 1
1414
 
            self.SetItemState(self.selected,
1415
 
                              wx.LIST_STATE_SELECTED,
1416
 
                              wx.LIST_STATE_SELECTED)
1417
 
        else:
1418
 
            self.selected = wx.NOT_FOUND
1419
 
 
1420
 
        return self.selected
1421
 
        
1422
 
    def ResizeColumns(self):
1423
 
        """Resize columns"""
1424
 
        minWidth = 90
1425
 
        for i in range(self.GetColumnCount()):
1426
 
            self.SetColumnWidth(i, wx.LIST_AUTOSIZE)
1427
 
            if self.GetColumnWidth(i) < minWidth:
1428
 
                self.SetColumnWidth(i, minWidth)
1429
 
 
1430
 
        self.SendSizeEvent()
1431
 
 
1432
 
    def GetSelected(self):
1433
 
        """Get index of selected item"""
1434
 
        return self.selected
1435
 
 
1436
 
    def OnItemSelected(self, event):
1437
 
        self.selected = event.GetIndex()
1438
 
        
1439
 
    def OnItemActivated(self, event):
1440
 
        """
1441
 
        When item double clicked, open editor to update coordinate values
1442
 
        """
1443
 
        coords = []
1444
 
        index = event.GetIndex()
1445
 
 
1446
 
        for i in range(4):
1447
 
            coords.append(self.GetItem(index, i).GetText())
1448
 
        
1449
 
        dlg = EditGPC(parent=self, id=wx.ID_ANY, data=coords)
1450
 
 
1451
 
        if dlg.ShowModal() == wx.ID_OK:
1452
 
            values = dlg.GetValues() # string
1453
 
            
1454
 
            if len(values) == 0:
1455
 
                wx.MessageBox(parent=self,
1456
 
                              caption=_("Edit GCP"),
1457
 
                              message=_("Invalid coordinate value. Operation cancelled."),
1458
 
                              style=wx.CENTRE | wx.ICON_ERROR | wx.ID_OK)
1459
 
            else:
1460
 
                for i in range(len(values)):
1461
 
                    if values[i] != coords[i]:
1462
 
                        self.SetStringItem(index, i, values[i])
1463
 
                mapdisp = self.gcp.mapcoordlist[index]['gcpcoord'][2]
1464
 
                self.gcp.mapcoordlist[index]['gcpcoord'] = (float(values[0]), float(values[1]), mapdisp)
1465
 
                mapdisp = self.gcp.mapcoordlist[index]['mapcoord'][2]
1466
 
                self.gcp.mapcoordlist[index]['mapcoord'] = (float(values[0]), float(values[1]), mapdisp)
1467
 
        
1468
 
class VectGroup(wx.Dialog):
1469
 
    """
1470
 
    Dialog to create a vector group (VREF file) for georectifying
1471
 
 
1472
 
    @todo Replace by g.group
1473
 
    """
1474
 
    def __init__(self, parent, id, grassdb, location, mapset, group,
1475
 
                 style=wx.DEFAULT_DIALOG_STYLE):
1476
 
        
1477
 
        wx.Dialog.__init__(self, parent, id, style=style,
1478
 
                           title = _("Create vector map group"))
1479
 
        
1480
 
        self.grassdatabase = grassdb
1481
 
        self.xylocation = location
1482
 
        self.xymapset = mapset
1483
 
        self.xygroup = group
1484
 
        
1485
 
        #
1486
 
        # get list of valid vector directories
1487
 
        #
1488
 
        vectlist = os.listdir(os.path.join(self.grassdatabase,
1489
 
                                           self.xylocation,
1490
 
                                           self.xymapset,
1491
 
                                           'vector'))
1492
 
        for dir in vectlist:
1493
 
            if not os.path.isfile(os.path.join(self.grassdatabase,
1494
 
                                           self.xylocation,
1495
 
                                           self.xymapset,
1496
 
                                           'vector',
1497
 
                                           dir,
1498
 
                                           'coor')):
1499
 
                vectlist.remove(dir)
1500
 
        
1501
 
        utils.ListSortLower(vectlist)
1502
 
        
1503
 
        # path to vref file
1504
 
        self.vgrpfile = os.path.join(self.grassdatabase,
1505
 
                                     self.xylocation,
1506
 
                                     self.xymapset,
1507
 
                                     'group',
1508
 
                                     self.xygroup,
1509
 
                                     'VREF')
1510
 
        
1511
 
        #
1512
 
        # buttons
1513
 
        #
1514
 
        self.btnCancel = wx.Button(parent = self,
1515
 
                                   id = wx.ID_CANCEL)
1516
 
        self.btnOK = wx.Button(parent = self,
1517
 
                                   id = wx.ID_OK)
1518
 
        self.btnOK.SetDefault()
1519
 
 
1520
 
 
1521
 
        #
1522
 
        # list of vector maps
1523
 
        #
1524
 
        self.listMap = wx.CheckListBox(parent = self, id = wx.ID_ANY,
1525
 
                                      choices = vectlist)
1526
 
        
1527
 
        if os.path.isfile(self.vgrpfile):
1528
 
            f = open(self.vgrpfile)
1529
 
            try:
1530
 
                checked = []
1531
 
                for line in f.readlines():
1532
 
                    line = line.replace('\n', '')
1533
 
                    if len(line) < 1:
1534
 
                        continue
1535
 
                    checked.append(line)
1536
 
                self.listMap.SetCheckedStrings(checked)
1537
 
            finally:
1538
 
                f.close()
1539
 
                
1540
 
        line = wx.StaticLine(parent = self,
1541
 
                             id = wx.ID_ANY, size = (20, -1),
1542
 
                             style = wx.LI_HORIZONTAL)
1543
 
 
1544
 
        #
1545
 
        # layout
1546
 
        #
1547
 
        sizer = wx.BoxSizer(wx.VERTICAL)
1548
 
        
1549
 
        box = wx.BoxSizer(wx.HORIZONTAL)
1550
 
        box.Add(item = wx.StaticText(parent = self, id = wx.ID_ANY,
1551
 
                                     label = _('Select vector map(s) to add to group:')),
1552
 
                flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT,
1553
 
                border = 5)
1554
 
 
1555
 
        box.Add(item = self.listMap,
1556
 
                flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT,
1557
 
                border = 5)
1558
 
 
1559
 
        
1560
 
        sizer.Add(box, flag = wx.ALIGN_RIGHT | wx.ALL,
1561
 
                  border = 3)
1562
 
        
1563
 
        sizer.Add(item = line, proportion = 0,
1564
 
                  flag = wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT,
1565
 
                  border = 5)
1566
 
        
1567
 
        # buttons
1568
 
        btnSizer = wx.StdDialogButtonSizer()
1569
 
        btnSizer.AddButton(self.btnCancel)
1570
 
        btnSizer.AddButton(self.btnOK)
1571
 
        btnSizer.Realize()
1572
 
 
1573
 
        sizer.Add(item = btnSizer, proportion = 0,
1574
 
                  flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER,
1575
 
                  border = 5)
1576
 
        
1577
 
        self.SetSizer(sizer)
1578
 
        sizer.Fit(self)
1579
 
        self.Layout()
1580
 
        
1581
 
    def MakeVGroup(self):
1582
 
        """Create VREF file"""
1583
 
        vgrouplist = []
1584
 
        for item in range(self.listMap.GetCount()):
1585
 
            if not self.listMap.IsChecked(item):
1586
 
                continue
1587
 
            vgrouplist.append(self.listMap.GetString(item))
1588
 
        
1589
 
        f = open(self.vgrpfile, mode='w')
1590
 
        try:
1591
 
            for vect in vgrouplist:
1592
 
                f.write(vect + '\n')
1593
 
        finally:
1594
 
            f.close()
1595
 
        
1596
 
class EditGPC(wx.Dialog):
1597
 
    def __init__(self, parent, data, id=wx.ID_ANY,
1598
 
                 title=_("Edit GCP"),
1599
 
                 style=wx.DEFAULT_DIALOG_STYLE):
1600
 
        """Dialog for editing GPC and map coordinates in list control"""
1601
 
 
1602
 
        wx.Dialog.__init__(self, parent, id, title=title, style=style)
1603
 
 
1604
 
        panel = wx.Panel(parent=self)
1605
 
 
1606
 
        sizer = wx.BoxSizer(wx.VERTICAL)
1607
 
 
1608
 
        box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
1609
 
                            label=" %s " % _("Ground Control Point"))
1610
 
        boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
1611
 
 
1612
 
        # source coordinates
1613
 
        gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
1614
 
       
1615
 
        self.xcoord = wx.TextCtrl(parent=panel, id=wx.ID_ANY, size=(150, -1))
1616
 
        self.ycoord = wx.TextCtrl(parent=panel, id=wx.ID_ANY, size=(150, -1))
1617
 
        self.ncoord = wx.TextCtrl(parent=panel, id=wx.ID_ANY, size=(150, -1))
1618
 
        self.ecoord = wx.TextCtrl(parent=panel, id=wx.ID_ANY, size=(150, -1))
1619
 
 
1620
 
        row = 0
1621
 
        col = 0
1622
 
        idx = 0
1623
 
        for label, win in ((_("X:"), self.xcoord),
1624
 
                           (_("Y:"), self.ycoord),
1625
 
                           (_("E:"), self.ecoord),
1626
 
                           (_("N:"), self.ncoord)):
1627
 
            label = wx.StaticText(parent=panel, id=wx.ID_ANY,
1628
 
                                  label=label)
1629
 
            gridSizer.Add(item=label,
1630
 
                          flag=wx.ALIGN_CENTER_VERTICAL,
1631
 
                          pos=(row, col))
1632
 
 
1633
 
            col += 1
1634
 
            win.SetValue(str(data[idx]))
1635
 
 
1636
 
            gridSizer.Add(item=win,
1637
 
                          pos=(row, col))
1638
 
 
1639
 
            col += 1
1640
 
            idx += 1
1641
 
 
1642
 
            if col > 3:
1643
 
                row += 1
1644
 
                col = 0
1645
 
 
1646
 
        boxSizer.Add(item=gridSizer, proportion=1,
1647
 
                  flag=wx.EXPAND | wx.ALL, border=5)
1648
 
 
1649
 
        sizer.Add(item=boxSizer, proportion=1,
1650
 
                  flag=wx.EXPAND | wx.ALL, border=5)
1651
 
 
1652
 
        #
1653
 
        # buttons
1654
 
        #
1655
 
        self.btnCancel = wx.Button(panel, wx.ID_CANCEL)
1656
 
        self.btnOk = wx.Button(panel, wx.ID_OK)
1657
 
        self.btnOk.SetDefault()
1658
 
 
1659
 
        btnSizer = wx.StdDialogButtonSizer()
1660
 
        btnSizer.AddButton(self.btnCancel)
1661
 
        btnSizer.AddButton(self.btnOk)
1662
 
        btnSizer.Realize()
1663
 
 
1664
 
        sizer.Add(item=btnSizer, proportion=0,
1665
 
                  flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
1666
 
 
1667
 
        panel.SetSizer(sizer)
1668
 
        sizer.Fit(self)
1669
 
 
1670
 
    def GetValues(self, columns=None):
1671
 
        """Return list of values (as strings).
1672
 
        """
1673
 
        valuelist = []
1674
 
        try:
1675
 
            float(self.xcoord.GetValue())
1676
 
            float(self.ycoord.GetValue())
1677
 
            float(self.ecoord.GetValue())
1678
 
            float(self.ncoord.GetValue())
1679
 
        except ValueError:
1680
 
            return valuelist
1681
 
 
1682
 
        valuelist.append(self.xcoord.GetValue())
1683
 
        valuelist.append(self.ycoord.GetValue())
1684
 
        valuelist.append(self.ecoord.GetValue())
1685
 
        valuelist.append(self.ncoord.GetValue())
1686
 
 
1687
 
        return valuelist
1688
 
 
1689
 
class GrSettingsDialog(wx.Dialog):
1690
 
    def __init__(self, parent, id, title, pos=wx.DefaultPosition, size=wx.DefaultSize,
1691
 
                 style=wx.DEFAULT_DIALOG_STYLE):
1692
 
        wx.Dialog.__init__(self, parent, id, title, pos, size, style)
1693
 
        """
1694
 
        Dialog to set profile text options: font, title
1695
 
        and font size, axis labels and font size
1696
 
        """
1697
 
        #
1698
 
        # initialize variables
1699
 
        #
1700
 
        self.parent = parent
1701
 
 
1702
 
        self.symbol = {}
1703
 
 
1704
 
        self._do_layout()
1705
 
        
1706
 
    def _do_layout(self):
1707
 
        """Do layout"""
1708
 
        # dialog layout
1709
 
        sizer = wx.BoxSizer(wx.VERTICAL)
1710
 
 
1711
 
        box = wx.StaticBox(parent=self, id=wx.ID_ANY,
1712
 
                           label=" %s " % _("Symbol settings"))
1713
 
        boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
1714
 
        gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
1715
 
        gridSizer.AddGrowableCol(1)
1716
 
 
1717
 
        #
1718
 
        # symbol color
1719
 
        #
1720
 
        row = 0
1721
 
        label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Color:"))
1722
 
        gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
1723
 
        col = UserSettings.Get(group='georect', key='symbol', subkey='color')
1724
 
        colWin = csel.ColourSelect(parent=self, id=wx.ID_ANY,
1725
 
                                   colour=wx.Colour(col[0],
1726
 
                                                    col[1],
1727
 
                                                    col[2],
1728
 
                                                    255))
1729
 
        self.symbol['color'] = colWin.GetId()
1730
 
        gridSizer.Add(item=colWin,
1731
 
                      flag=wx.ALIGN_RIGHT,
1732
 
                      pos=(row, 1))
1733
 
 
1734
 
        #
1735
 
        # symbol width
1736
 
        #
1737
 
        row += 1
1738
 
        label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Width:"))
1739
 
        gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
1740
 
        width = int(UserSettings.Get(group='georect', key='symbol', subkey='width'))
1741
 
        widWin = wx.SpinCtrl(parent=self, id=wx.ID_ANY,
1742
 
                             min=1, max=10)
1743
 
        widWin.SetValue(width)
1744
 
        self.symbol['width'] = widWin.GetId()
1745
 
        gridSizer.Add(item=widWin,
1746
 
                      flag=wx.ALIGN_RIGHT,
1747
 
                      pos=(row, 1))
1748
 
        
1749
 
        boxSizer.Add(item=gridSizer, flag=wx.EXPAND)
1750
 
        sizer.Add(item=boxSizer, flag=wx.EXPAND | wx.ALL, border=5)
1751
 
 
1752
 
        line = wx.StaticLine(parent=self, id=wx.ID_ANY, size=(20, -1), style=wx.LI_HORIZONTAL)
1753
 
        sizer.Add(item=line, proportion=0,
1754
 
                  flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, border=3)
1755
 
 
1756
 
        #
1757
 
        # buttons
1758
 
        #
1759
 
        btnSave = wx.Button(self, wx.ID_SAVE)
1760
 
        btnApply = wx.Button(self, wx.ID_APPLY)
1761
 
        btnCancel = wx.Button(self, wx.ID_CANCEL)
1762
 
        btnSave.SetDefault()
1763
 
 
1764
 
        # bindigs
1765
 
        btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
1766
 
        btnApply.SetToolTipString(_("Apply changes for the current session"))
1767
 
        btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
1768
 
        btnSave.SetToolTipString(_("Apply and save changes to user settings file (default for next sessions)"))
1769
 
        btnSave.SetDefault()
1770
 
        btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
1771
 
        btnCancel.SetToolTipString(_("Close dialog and ignore changes"))
1772
 
 
1773
 
        # sizers
1774
 
        btnStdSizer = wx.StdDialogButtonSizer()
1775
 
        btnStdSizer.AddButton(btnCancel)
1776
 
        btnStdSizer.AddButton(btnSave)
1777
 
        btnStdSizer.AddButton(btnApply)
1778
 
        btnStdSizer.Realize()
1779
 
        
1780
 
        sizer.Add(item=btnStdSizer, proportion=0, flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
1781
 
 
1782
 
        self.SetSizer(sizer)
1783
 
        sizer.Fit(self)
1784
 
 
1785
 
    def UpdateSettings(self):
1786
 
        UserSettings.Set(group='georect', key='symbol', subkey='color',
1787
 
                         value=wx.FindWindowById(self.symbol['color']).GetColour())
1788
 
        UserSettings.Set(group='georect', key='symbol', subkey='width',
1789
 
                         value=wx.FindWindowById(self.symbol['width']).GetValue())
1790
 
 
1791
 
    def OnSave(self, event):
1792
 
        """Button 'Save' pressed"""
1793
 
        self.UpdateSettings()
1794
 
        fileSettings = {}
1795
 
        UserSettings.ReadSettingsFile(settings=fileSettings)
1796
 
        fileSettings['georect'] = UserSettings.Get(group='georect')
1797
 
        file = UserSettings.SaveToFile(fileSettings)
1798
 
        self.parent.parent.goutput.WriteLog(_('Georectifier settings saved to file \'%s\'.') % file)
1799
 
        self.Close()
1800
 
 
1801
 
    def OnApply(self, event):
1802
 
        """Button 'Apply' pressed"""
1803
 
        self.UpdateSettings()
1804
 
        self.Close()
1805
 
 
1806
 
    def OnCancel(self, event):
1807
 
        """Button 'Cancel' pressed"""
1808
 
        self.Close()