GRASS Programmer's Manual  6.4.2(2012)
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
psmap_dialogs.py
Go to the documentation of this file.
1 """!
2 @package psmap_dialogs.py
3 
4 @brief Map feature objects and dialogs for ps.map
5 
6 Classes:
7  - UnitConversion
8  - TCValidator
9  - PenStyleComboBox
10  - CheckListCtrl
11  - Instruction
12  - InstructionObject
13  - InitMap
14  - MapFrame
15  - PageSetup
16  - Mapinfo
17  - Text
18  - Scalebar
19  - RasterLegend
20  - VectorLegend
21  - Raster
22  - Vector
23  - VProperties
24  - PsmapDialog
25  - PageSetupDialog
26  - MapDialog
27  - MapFramePanel
28  - RasterPanel
29  - VectorPanel
30  - RasterDialog
31  - MainVectorDialog
32  - VPropertiesDialog
33  - LegendDialog
34  - MapinfoDialog
35  - ScalebarDialog
36  - TextDialog
37 
38 (C) 2011 by Anna Kratochvilova, and the GRASS Development Team
39 This program is free software under the GNU General Public License
40 (>=v2). Read the file COPYING that comes with GRASS for details.
41 
42 @author Anna Kratochvilova <anna.kratochvilova fsv.cvut.cz> (bachelor's project)
43 @author Martin Landa <landa.martin gmail.com> (mentor)
44 """
45 
46 
47 import os
48 import sys
49 import string
50 from math import ceil, floor
51 from copy import deepcopy
52 from time import strftime, localtime
53 
54 import grass.script as grass
55 if int(grass.version()['version'].split('.')[0]) > 6:
56  sys.path.append(os.path.join(os.getenv('GISBASE'), 'etc', 'gui', 'wxpython',
57  'gui_modules'))
58 else:
59  sys.path.append(os.path.join(os.getenv('GISBASE'), 'etc', 'wxpython',
60  'gui_modules'))
61 import globalvar
62 import dbm_base
63 from utils import CmdToTuple, GetCmdString
64 from gselect import Select
65 from gcmd import RunCommand, GError, GMessage, GWarning
66 
67 import wx
68 import wx.lib.scrolledpanel as scrolled
69 import wx.lib.filebrowsebutton as filebrowse
70 from wx.lib.mixins.listctrl import CheckListCtrlMixin, ListCtrlAutoWidthMixin
71 from wx.lib.expando import ExpandoTextCtrl, EVT_ETC_LAYOUT_NEEDED
72 try:
73  import wx.lib.agw.floatspin as fs
74 except ImportError:
75  fs = None
76 
77 grass.set_raise_on_error(True)
78 
79 PSMAP_COLORS = ['aqua', 'black', 'blue', 'brown', 'cyan', 'gray', 'grey', 'green', 'indigo',
80  'magenta','orange', 'purple', 'red', 'violet', 'white', 'yellow']
82  """! Class for converting units"""
83  def __init__(self, parent = None):
84  self.parent = parent
85  if self.parent:
86  ppi = wx.ClientDC(self.parent).GetPPI()
87  else:
88  ppi = (72, 72)
89  self._unitsPage = { 'inch' : {'val': 1.0, 'tr' : _("inch")},
90  'point' : {'val': 72.0, 'tr' : _("point")},
91  'centimeter' : {'val': 2.54, 'tr' : _("centimeter")},
92  'millimeter' : {'val': 25.4, 'tr' : _("millimeter")}}
93  self._unitsMap = { 'meters' : {'val': 0.0254, 'tr' : _("meters")},
94  'kilometers' : {'val': 2.54e-5, 'tr' : _("kilometers")},
95  'feet' : {'val': 1./12, 'tr' : _("feet")},
96  'miles' : {'val': 1./63360, 'tr' : _("miles")},
97  'nautical miles': {'val': 1/72913.386, 'tr' : _("nautical miles")}}
98 
99  self._units = { 'pixel' : {'val': ppi[0], 'tr' : _("pixel")},
100  'meter' : {'val': 0.0254, 'tr' : _("meter")},
101  'nautmiles' : {'val': 1/72913.386, 'tr' :_("nautical miles")},
102  'degrees' : {'val': 0.0254 , 'tr' : _("degree")} #like 1 meter, incorrect
103  }
104  self._units.update(self._unitsPage)
105  self._units.update(self._unitsMap)
106 
107  def getPageUnitsNames(self):
108  return sorted(self._unitsPage[unit]['tr'] for unit in self._unitsPage.keys())
109 
110  def getMapUnitsNames(self):
111  return sorted(self._unitsMap[unit]['tr'] for unit in self._unitsMap.keys())
112 
113  def getAllUnits(self):
114  return sorted(self._units.keys())
115 
116  def findUnit(self, name):
117  """!Returns unit by its tr. string"""
118  for unit in self._units.keys():
119  if self._units[unit]['tr'] == name:
120  return unit
121  return None
122 
123  def findName(self, unit):
124  """!Returns tr. string of a unit"""
125  try:
126  return self._units[unit]['tr']
127  except KeyError:
128  return None
129 
130  def convert(self, value, fromUnit = None, toUnit = None):
131  return float(value)/self._units[fromUnit]['val']*self._units[toUnit]['val']
132 
133 
134 class TCValidator(wx.PyValidator):
135  """!validates input in textctrls, combobox, taken from wxpython demo"""
136  def __init__(self, flag = None):
137  wx.PyValidator.__init__(self)
138  self.flag = flag
139  self.Bind(wx.EVT_CHAR, self.OnChar)
140 
141  def Clone(self):
142  return TCValidator(self.flag)
143 
144  def Validate(self, win):
145 
146  tc = self.GetWindow()
147  val = tc.GetValue()
148 
149  if self.flag == 'DIGIT_ONLY':
150  for x in val:
151  if x not in string.digits:
152  return False
153  return True
154 
155  def OnChar(self, event):
156  key = event.GetKeyCode()
157  if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255:
158  event.Skip()
159  return
160  if self.flag == 'DIGIT_ONLY' and chr(key) in string.digits + '.':
161  event.Skip()
162  return
163 ## if self.flag == 'SCALE' and chr(key) in string.digits + ':':
164 ## event.Skip()
165 ## return
166  if self.flag == 'ZERO_AND_ONE_ONLY' and chr(key) in '01':
167  event.Skip()
168  return
169  if not wx.Validator_IsSilent():
170  wx.Bell()
171  # Returning without calling even.Skip eats the event before it
172  # gets to the text control
173  return
174 
175 
176 class PenStyleComboBox(wx.combo.OwnerDrawnComboBox):
177  """!Combo for selecting line style, taken from wxpython demo"""
178 
179  # Overridden from OwnerDrawnComboBox, called to draw each
180  # item in the list
181  def OnDrawItem(self, dc, rect, item, flags):
182  if item == wx.NOT_FOUND:
183  # painting the control, but there is no valid item selected yet
184  return
185 
186  r = wx.Rect(*rect) # make a copy
187  r.Deflate(3, 5)
188 
189  penStyle = wx.SOLID
190  if item == 1:
191  penStyle = wx.LONG_DASH
192  elif item == 2:
193  penStyle = wx.DOT
194  elif item == 3:
195  penStyle = wx.DOT_DASH
196 
197  pen = wx.Pen(dc.GetTextForeground(), 3, penStyle)
198  dc.SetPen(pen)
199 
200  # for painting the items in the popup
201  dc.DrawText(self.GetString(item ),
202  r.x + 3,
203  (r.y + 0) + ((r.height/2) - dc.GetCharHeight() )/2
204  )
205  dc.DrawLine(r.x+5, r.y+((r.height/4)*3)+1, r.x+r.width - 5, r.y+((r.height/4)*3)+1 )
206 
207 
208  def OnDrawBackground(self, dc, rect, item, flags):
209  """!Overridden from OwnerDrawnComboBox, called for drawing the
210  background area of each item."""
211  # If the item is selected, or its item # iseven, or we are painting the
212  # combo control itself, then use the default rendering.
213  if (item & 1 == 0 or flags & (wx.combo.ODCB_PAINTING_CONTROL |
214  wx.combo.ODCB_PAINTING_SELECTED)):
215  wx.combo.OwnerDrawnComboBox.OnDrawBackground(self, dc, rect, item, flags)
216  return
217 
218  # Otherwise, draw every other background with different colour.
219  bgCol = wx.Colour(240,240,250)
220  dc.SetBrush(wx.Brush(bgCol))
221  dc.SetPen(wx.Pen(bgCol))
222  dc.DrawRectangleRect(rect);
223 
224  def OnMeasureItem(self, item):
225  """!Overridden from OwnerDrawnComboBox, should return the height
226  needed to display an item in the popup, or -1 for default"""
227  return 30
228 
229  def OnMeasureItemWidth(self, item):
230  """!Overridden from OwnerDrawnComboBox. Callback for item width, or
231  -1 for default/undetermined"""
232  return -1; # default - will be measured from text width
233 
234 
235 class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin):
236  """!List control for managing order and labels of vector maps in legend"""
237  def __init__(self, parent):
238  wx.ListCtrl.__init__(self, parent, id = wx.ID_ANY,
239  style = wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.BORDER_SUNKEN|wx.LC_VRULES|wx.LC_HRULES)
240  CheckListCtrlMixin.__init__(self)
241  ListCtrlAutoWidthMixin.__init__(self)
242 
244  """!Class which represents instruction file"""
245  def __init__(self, parent, objectsToDraw):
246 
247  self.parent = parent
248  self.objectsToDraw = objectsToDraw
249  #here are kept objects like mapinfo, rasterlegend, etc.
250  self.instruction = list()
251 
252  def __str__(self):
253  """!Returns text for instruction file"""
254  comment = "# timestamp: " + strftime("%Y-%m-%d %H:%M", localtime()) + '\n'
255  env = grass.gisenv()
256  comment += "# location: %s\n" % env['LOCATION_NAME']
257  comment += "# mapset: %s\n" % env['MAPSET']
258  comment += "# page orientation: %s\n" % self.FindInstructionByType('page')['Orientation']
259  border = ''
260  if not self.FindInstructionByType('map'):
261  border = 'border n\n'
262  text = [str(each) for each in self.instruction]
263  return comment + border + '\n'.join(text) + '\nend'
264 
265  def __getitem__(self, id):
266  for each in self.instruction:
267  if each.id == id:
268  return each
269  return None
270 
271  def __contains__(self, id):
272  """!Test if instruction is included"""
273  for each in self.instruction:
274  if each.id == id:
275  return True
276  return False
277 
278  def __delitem__(self, id):
279  """!Delete instruction"""
280  for each in self.instruction:
281  if each.id == id:
282  if each.type == 'map':
283  #must remove raster, vector layers too
284  vektor = self.FindInstructionByType('vector', list = True)
285  vProperties = self.FindInstructionByType('vProperties', list = True)
286  raster = self.FindInstructionByType('raster', list = True)
287  for item in vektor + vProperties + raster:
288  if item in self.instruction:
289  self.instruction.remove(item)
290 
291  self.instruction.remove(each)
292  if id in self.objectsToDraw:
293  self.objectsToDraw.remove(id)
294  return
295 
296  def AddInstruction(self, instruction):
297  """!Add instruction"""
298  # add to instructions
299  if instruction.type == 'map':
300  self.instruction.insert(0, instruction)
301  else:
302  self.instruction.append(instruction)
303  # add to drawable objects
304  if instruction.type not in ('page', 'raster', 'vector', 'vProperties', 'initMap'):
305  if instruction.type == 'map':
306  self.objectsToDraw.insert(0, instruction.id)
307  else:
308  self.objectsToDraw.append(instruction.id)
309 
310 
311  def FindInstructionByType(self, type, list = False):
312  """!Find instruction(s) with the given type"""
313  inst = []
314  for each in self.instruction:
315  if each.type == type:
316  inst.append(each)
317  if len(inst) == 1 and not list:
318  return inst[0]
319  return inst
320 
321  def Read(self, filename):
322  """!Reads instruction file and creates instruction objects"""
323  self.filename = filename
324  # open file
325  try:
326  file = open(filename, 'r')
327  except IOError:
328  GError(message = _("Unable to open file\n%s") % filename)
329  return
330  # first read file to get information about region and scaletype
331  isRegionComment = False
332  orientation = 'Portrait'
333  for line in file:
334  if '# g.region' in line:
335  self.SetRegion(regionInstruction = line)
336  isRegionComment = True
337  break
338  if '# page orientation' in line:
339  orientation = line.split(':')[-1].strip()
340 
341  if not isRegionComment:
342  self.SetRegion(regionInstruction = None)
343  # then run ps.map -b to get information for maploc
344  # compute scale and center
345  map = self.FindInstructionByType('map')
346  region = grass.region()
347  map['center'] = (region['n'] + region['s']) / 2, (region['w'] + region['e']) / 2
348  mapRect = GetMapBounds(self.filename, portrait = (orientation == 'Portrait'))
349  map['rect'] = mapRect
350  proj = projInfo()
351  toM = 1.0
352  if proj['units']:
353  toM = float(proj['meters'])
354  units = UnitConversion(self.parent)
355  w = units.convert(value = mapRect.Get()[2], fromUnit = 'inch', toUnit = 'meter') / toM
356  map['scale'] = w / abs((region['w'] - region['e']))
357 
358  SetResolution(dpi = 300, width = map['rect'].width, height = map['rect'].height)
359 
360  # read file again, now with information about map bounds
361  isBuffer = False
362  buffer = []
363  instruction = None
364  vectorMapNumber = 1
365  file.seek(0)
366  for line in file:
367  if not line.strip():
368  continue
369  line = line.strip()
370  if isBuffer:
371  buffer.append(line)
372  if 'end' in line:
373  isBuffer = False
374  kwargs = {}
375  if instruction == 'scalebar':
376  kwargs['scale'] = map['scale']
377  elif instruction == 'text':
378  kwargs['mapInstruction'] = map
379  elif instruction in ('vpoints', 'vlines', 'vareas'):
380  kwargs['id'] = wx.NewId()
381  kwargs['vectorMapNumber'] = vectorMapNumber
382  vectorMapNumber += 1
383  elif instruction == 'paper':
384  kwargs['Orientation'] = orientation
385 
386  ok = self.SendToRead(instruction, buffer, **kwargs)
387  if not ok: return False
388  buffer = []
389  continue
390 
391  elif line.startswith('paper'):
392  instruction = 'paper'
393  isBuffer = True
394  buffer.append(line)
395 
396  elif line.startswith('border'):
397  if line.split()[1].lower() in ('n', 'no', 'none'):
398  ok = self.SendToRead('border', [line])
399  if not ok: return False
400  elif line.split()[1].lower() in ('y', 'yes'):
401  instruction = 'border'
402  isBuffer = True
403  buffer.append(line)
404 
405  elif line.startswith('scale '):
406  ok = self.SendToRead('scale', line, isRegionComment = isRegionComment)
407  if not ok: return False
408 
409  elif line.startswith('maploc'):
410  ok = self.SendToRead(instruction = 'maploc', text = line)
411  if not ok: return False
412 
413  elif line.startswith('raster'):
414  ok = self.SendToRead(instruction = 'raster', text = line)
415  if not ok: return False
416 
417  elif line.startswith('mapinfo'):
418  instruction = 'mapinfo'
419  isBuffer = True
420  buffer.append(line)
421 
422 
423  elif line.startswith('scalebar'):
424  instruction = 'scalebar'
425  isBuffer = True
426  buffer.append(line)
427 
428  elif line.startswith('text'):
429  instruction = 'text'
430  isBuffer = True
431  buffer.append(line)
432 
433  elif line.startswith('colortable'):
434  if len(line.split()) == 2 and line.split()[1].lower() in ('n', 'no', 'none'):
435  break
436  instruction = 'colortable'
437  isBuffer = True
438  buffer.append(line)
439 
440  elif line.startswith('vlegend'):
441  instruction = 'vlegend'
442  isBuffer = True
443  buffer.append(line)
444 
445  elif line.startswith('vpoints'):
446  instruction = 'vpoints'
447  isBuffer = True
448  buffer.append(line)
449 
450  elif line.startswith('vlines'):
451  instruction = 'vlines'
452  isBuffer = True
453  buffer.append(line)
454 
455  elif line.startswith('vareas'):
456  instruction = 'vareas'
457  isBuffer = True
458  buffer.append(line)
459 
460 
461 
462  rasterLegend = self.FindInstructionByType('rasterLegend')
463  raster = self.FindInstructionByType('raster')
464  page = self.FindInstructionByType('page')
465  vector = self.FindInstructionByType('vector')
466  vectorLegend = self.FindInstructionByType('vectorLegend')
467  vectorMaps = self.FindInstructionByType('vProperties', list = True)
468 
469  # check (in case of scaletype 0) if map is drawn also
470  map['drawMap'] = False
471  if map['scaleType'] == 0:
472  mapForRegion = map['map']
473  if map['mapType'] == 'raster' and raster:
474  if mapForRegion == raster['raster']:
475  map['drawMap'] = True
476  elif map['mapType'] == 'vector' and vector:
477  for vmap in vector['list']:
478  if mapForRegion == vmap[0]:
479  map['drawMap'] = True
480 
481  # rasterLegend
482  if rasterLegend:
483  if rasterLegend['rasterDefault'] and raster:
484  rasterLegend['raster'] = raster['raster']
485  if not rasterLegend['discrete']:
486  rasterType = getRasterType(map = rasterLegend['raster'])
487  if rasterType == 'CELL':
488  rasterLegend['discrete'] = 'y'
489  else:
490  rasterLegend['discrete'] = 'n'
491 
492  #estimate size
493  height = rasterLegend.EstimateHeight(raster = rasterLegend['raster'], discrete = rasterLegend['discrete'],
494  fontsize = rasterLegend['fontsize'],
495  cols = rasterLegend['cols'],
496  height = rasterLegend['height'])
497  width = rasterLegend.EstimateWidth(raster = rasterLegend['raster'], discrete = rasterLegend['discrete'],
498  fontsize = rasterLegend['fontsize'],
499  cols = rasterLegend['cols'] ,
500  width = rasterLegend['width'],
501  paperInstr = page)
502  rasterLegend['rect'] = wx.Rect2D(x = float(rasterLegend['where'][0]), y = float(rasterLegend['where'][1]),
503  w = width, h = height)
504 
505  # vectors, vlegend
506 
507  if vector:
508  for vmap in vectorMaps:
509  for i, each in enumerate(vector['list']):
510  if each[2] == vmap.id:
511 
512  vector['list'][i][4] = vmap['label']
513  vector['list'][i][3] = vmap['lpos']
514  if vectorLegend:
515  size = vectorLegend.EstimateSize(vectorInstr = vector, fontsize = vectorLegend['fontsize'],
516  width = vectorLegend['width'], cols = vectorLegend['cols'])
517  vectorLegend['rect'] = wx.Rect2D(x = float(vectorLegend['where'][0]), y = float(vectorLegend['where'][1]),
518  w = size[0], h = size[1])
519 
520 
521  page = self.FindInstructionByType('page')
522  if not page:
523  page = PageSetup(wx.NewId())
524  self.AddInstruction(page)
525  else:
526  page['Orientation'] = orientation
527 
528 
529  #
530  return True
531 
532  def SendToRead(self, instruction, text, **kwargs):
533  psmapInstrDict = dict(paper = ['page'],
534  maploc = ['map'],
535  scale = ['map'],
536  border = ['map'],
537  raster = ['raster'],
538  mapinfo = ['mapinfo'],
539  scalebar = ['scalebar'],
540  text = ['text'],
541  vpoints = ['vector', 'vProperties'],
542  vlines = ['vector', 'vProperties'],
543  vareas = ['vector', 'vProperties'],
544  colortable = ['rasterLegend'],
545  vlegend = ['vectorLegend']
546  )
547 
548  myInstrDict = dict(page = PageSetup,
549  map = MapFrame,
550  raster = Raster,
551  mapinfo = Mapinfo,
552  scalebar = Scalebar,
553  text = Text,
554  rasterLegend = RasterLegend,
555  vectorLegend = VectorLegend,
556  vector = Vector,
557  vProperties = VProperties
558  )
559 
560  myInstruction = psmapInstrDict[instruction]
561 
562  for i in myInstruction:
563  instr = self.FindInstructionByType(i)
564  if i in ('text', 'vProperties') or not instr:
565 
566  id = wx.NewId() #!vProperties expect subtype
567  if i == 'vProperties':
568  id = kwargs['id']
569  newInstr = myInstrDict[i](id, subType = instruction[1:])
570  else:
571  newInstr = myInstrDict[i](id)
572  ok = newInstr.Read(instruction, text, **kwargs)
573  if ok:
574  self.AddInstruction(newInstr)
575  else:
576  return False
577 
578  else:
579  ok = instr.Read(instruction, text, **kwargs)
580 
581  if not ok:
582  return False
583  return True
584 
585  def SetRegion(self, regionInstruction):
586  """!Sets region from file comment or sets current region in case of no comment"""
587  map = MapFrame(wx.NewId())
588  self.AddInstruction(map)
589  if regionInstruction:
590  cmd = CmdToTuple(regionInstruction.strip('# ').split())
591 
592  # define scaleType
593  if len(cmd[1]) <= 3:
594  if 'rast' in cmd[1]:
595  map['scaleType'] = 0
596  map['mapType'] = 'raster'
597  map['map'] = cmd[1]['rast']
598  elif 'vect' in cmd[1]:
599  map['scaleType'] = 0
600  map['mapType'] = 'vector'
601  map['map'] = cmd[1]['vect']
602  elif 'region' in cmd[1]:
603  map['scaleType'] = 1
604  map['region'] = cmd[1]['region']
605 
606  else:
607  map['scaleType'] = 2
608  else:
609  map['scaleType'] = 2
610  grass.del_temp_region()
611  region = grass.region()
612  grass.use_temp_region()
613  cmd = ['g.region', region]
614  cmdString = GetCmdString(cmd).replace('g.region', '')
615  GMessage(_("Instruction file will be loaded with following region: %s\n") % cmdString)
616  try:
617  RunCommand(cmd[0], **cmd[1])
618 
619  except grass.ScriptError, e:
620  GError(_("Region cannot be set\n%s") % e)
621  return False
622 
623 
625  """!Abtract class representing single instruction"""
626  def __init__(self, id):
627  self.id = id
628 
629  # default values
630  self.defaultInstruction = dict()
631  # current values
633  # converting units
635 
636  def __str__(self):
637  """!Returns particular part of text instruction"""
638  return ''
639 
640  def __getitem__(self, key):
641  for each in self.instruction.keys():
642  if each == key:
643  return self.instruction[key]
644  return None
645 
646  def __setitem__(self, key, value):
647  self.instruction[key] = value
648 
649  def GetInstruction(self):
650  """!Get current values"""
651  return self.instruction
652 
653  def SetInstruction(self, instruction):
654  """!Set default values"""
655  self.instruction = instruction
656 
657  def Read(self, instruction, text, **kwargs):
658  """!Read instruction and save them"""
659  pass
660 
661 class InitMap(InstructionObject):
662  """!Class representing virtual map"""
663  def __init__(self, id):
664  InstructionObject.__init__(self, id = id)
665  self.type = 'initMap'
666 
667  # default values
668  self.defaultInstruction = dict(rect = None, scale = None)
669  # current values
670  self.instruction = dict(self.defaultInstruction)
671 
672 
674  """!Class representing map (instructions maploc, scale, border)"""
675  def __init__(self, id):
676  InstructionObject.__init__(self, id = id)
677  self.type = 'map'
678  # default values
679  self.defaultInstruction = dict(map = None, mapType = None, drawMap = True, region = None,
680  rect = wx.Rect2D(), scaleType = 0, scale = None, center = None,
681  resolution = 300, border = 'y', width = 1, color = '0:0:0')
682  # current values
683  self.instruction = dict(self.defaultInstruction)
684 
685  def __str__(self):
686  instr = ''
687  comment = ''
688 
689  #region settings
690  region = grass.region()
691  if self.instruction['scaleType'] == 0: #match map
692  map = self.instruction['map']
693  if self.instruction['mapType'] == 'raster':
694  comment = "# g.region rast=%s nsres=%s ewres=%s\n" % (map, region['nsres'], region['ewres'])
695  else:
696  comment = "# g.region vect=%s\n" % (map)
697  elif self.instruction['scaleType'] == 1:# saved region
698  region = self.instruction['region']
699  comment = "# g.region region=%s\n" % region
700  elif self.instruction['scaleType'] in (2, 3): #current region, fixed scale
701  comment = string.Template("# g.region n=$n s=$s e=$e w=$w rows=$rows cols=$cols \n").substitute(**region)
702 
703  instr += comment
704  instr += '\n'
705  # maploc
706  maplocInstruction = "maploc %.3f %.3f" % (self.instruction['rect'].x, self.instruction['rect'].y)
707  if self.instruction['scaleType'] != 3:
708  maplocInstruction += " %.3f %.3f"% (self.instruction['rect'].width, self.instruction['rect'].height)
709  instr += maplocInstruction
710  instr += '\n'
711 
712  # scale
713  if self.instruction['scaleType'] == 3: #fixed scale
714  scaleInstruction = "scale 1:%.0f" % (1/self.instruction['scale'])
715  instr += scaleInstruction
716  instr += '\n'
717  # border
718  borderInstruction = ''
719  if self.instruction['border'] == 'n':
720  borderInstruction = "border n"
721  else:
722  borderInstruction = "border y\n"
723  borderInstruction += string.Template(" width $width\n color $color\n").substitute(self.instruction)
724  borderInstruction += " end"
725  instr += borderInstruction
726  instr += '\n'
727 
728  return instr
729 
730  def Read(self, instruction, text, **kwargs):
731  """!Read instruction and save information"""
732  if 'isRegionComment' in kwargs:
733  isRegionComment = kwargs['isRegionComment']
734  instr = {}
735 
736  if instruction == 'border':
737  for line in text:
738  if line.startswith('end'):
739  break
740  try:
741  if line.split()[1].lower() in ('n', 'no', 'none'):
742  instr['border'] = 'n'
743  break
744  elif line.split()[1].lower() in ('y', 'yes'):
745  instr['border'] = 'y'
746  elif line.startswith('width'):
747  instr['width'] = line.split()[1]
748  elif line.startswith('color'):
749  instr['color'] = line.split()[1]
750  except IndexError:
751  GError(_("Failed to read instruction %s") % instruction)
752  return False
753 
754  elif instruction == 'scale':
755  try:
756  scaleText = text.strip('scale ').split(':')[1]
757  # when scale instruction given and region comment also, then scaletype is fixed scale
758  if not isRegionComment:
759  instr['scaleType'] = 2
760  else:
761  instr['scaleType'] = 3
762 
763  scale = 1/float(scaleText)
764  if abs(scale - self.instruction['scale']) > (0.01 * scale):
765  GWarning(_("Scale has changed, old value: %(old)s\nnew value: %(new)s") % \
766  { 'old' : scale, 'new' : self.instruction['scale'] })
767  except (ValueError, IndexError):
768  GError(_("Failed to read instruction %s.\nUse 1:25000 notation.") % instruction)
769  return False
770 
771  elif instruction == 'maploc':
772  maploc = text.strip('maploc ').split()
773  if len(maploc) >= 2:
774  if abs(self.instruction['rect'].Get()[0] - float(maploc[0])) > 0.5 or \
775  abs(self.instruction['rect'].Get()[1] - float(maploc[1])) > 0.5:
776  GWarning(_("Map frame position changed, old value: %(old1)s %(old2)s\nnew value: %(new1)s %(new2)s") % \
777  { 'old1' : maploc[0], 'old2' : maploc[1],
778  'new1' : self.instruction['rect'].Get()[0], 'new2' : self.instruction['rect'].Get()[1] })
779 
780  #instr['rect'] = wx.Rect2D(float(maploc[0]), float(maploc[1]), self.instruction['rect'][2], self.instruction['rect'][3])
781  if len(maploc) == 4:
782  if abs(self.instruction['rect'].Get()[2] - float(maploc[2])) > 0.5 or \
783  abs(self.instruction['rect'].Get()[3] - float(maploc[3])) > 0.5:
784  GWarning(_("Map frame size changed, old value: %(old1)s %(old2)s\nnew value: %(new1)s %(new2)s") % \
785  { 'old1' : maploc[2], 'old2' : maploc[3],
786  'new1' : self.instruction['rect'].Get()[2], 'new2' : self.instruction['rect'].Get()[3] })
787  #instr['rect'] = wx.Rect2D(*map(float, maploc))
788  self.instruction.update(instr)
789  return True
790 
792  """!Class representing page instruction"""
793  def __init__(self, id):
794  InstructionObject.__init__(self, id = id)
795  self.type = 'page'
796  # default values
797  self.defaultInstruction = dict(Units = 'inch', Format = 'a4', Orientation = 'Portrait',
798  Width = 8.268, Height = 11.693, Left = 0.5, Right = 0.5, Top = 1, Bottom = 1)
799  # current values
800  self.instruction = dict(self.defaultInstruction)
801 
802  def __str__(self):
803  if self.instruction['Format'] == 'custom':
804  instr = string.Template("paper\n width $Width\n height $Height\n").substitute(self.instruction)
805  else:
806  instr = string.Template("paper $Format\n").substitute(self.instruction)
807  instr += string.Template(" left $Left\n right $Right\n bottom $Bottom\n top $Top\n end").substitute(self.instruction)
808 
809  return instr
810 
811  def Read(self, instruction, text, **kwargs):
812  """!Read instruction and save information"""
813  instr = {}
814  self.cats = ['Width', 'Height', 'Left', 'Right', 'Top', 'Bottom']
815  self.subInstr = dict(zip(['width', 'height', 'left', 'right', 'top', 'bottom'], self.cats))
816 
817  if instruction == 'paper': # just for sure
818  for line in text:
819  if line.startswith('paper'):
820  if len(line.split()) > 1:
821  pformat = line.split()[1]
822  availableFormats = self._toDict(grass.read_command('ps.map', flags = 'p',
823  quiet = True))
824  # e.g. paper a3
825  try:
826  instr['Format'] = pformat
827  for key, value in availableFormats[pformat].iteritems():
828  instr[key] = float(value)
829  break
830  except KeyError:
831  GError(_("Failed to read instruction %(file)s.\nUnknown format %(for)s") % \
832  { 'file' : instruction, 'for' : format })
833  return False
834  else:
835  # paper
836  # width ...
837  instr['Format'] = 'custom'
838  # read subinstructions
839  elif instr['Format'] == 'custom' and not line.startswith('end'):
840  text = line.split()
841  try:
842  instr[self.subInstr[text[0]]] = float(text[1])
843  except (IndexError, KeyError):
844  GError(_("Failed to read instruction %s.") % instruction)
845  return False
846 
847  if 'Orientation' in kwargs and kwargs['Orientation'] == 'Landscape':
848  instr['Width'], instr['Height'] = instr['Height'], instr['Width']
849 
850  self.instruction.update(instr)
851  return True
852 
853  def _toDict(self, paperStr):
854  sizeDict = dict()
855 # cats = self.subInstr[ 'Width', 'Height', 'Left', 'Right', 'Top', 'Bottom']
856  for line in paperStr.strip().split('\n'):
857  d = dict(zip(self.cats, line.split()[1:]))
858  sizeDict[line.split()[0]] = d
859 
860  return sizeDict
861 
863  """!Class representing mapinfo instruction"""
864  def __init__(self, id):
865  InstructionObject.__init__(self, id = id)
866  self.type = 'mapinfo'
867  # default values
868  self.defaultInstruction = dict(unit = 'inch', where = (0, 0),
869  font = 'Helvetica', fontsize = 10, color = '0:0:0', background = 'none',
870  border = 'none', rect = None)
871  # current values
872  self.instruction = dict(self.defaultInstruction)
873 
874  def __str__(self):
875  instr = "mapinfo\n"
876  instr += " where %.3f %.3f\n" % (self.instruction['where'][0], self.instruction['where'][1])
877  instr += string.Template(" font $font\n fontsize $fontsize\n color $color\n").substitute(self.instruction)
878  instr += string.Template(" background $background\n border $border\n").substitute(self.instruction)
879  instr += " end"
880  return instr
881 
882  def Read(self, instruction, text):
883  """!Read instruction and save information"""
884  instr = {}
885  try:
886  for line in text:
887  sub = line.split(None,1)
888  if sub[0] == 'font':
889  instr['font'] = sub[1]
890  elif sub[0] == 'fontsize':
891  instr['fontsize'] = int(sub[1])
892  elif sub[0] == 'color':
893  instr['color'] = sub[1]
894  elif sub[0] == 'background':
895  instr['background'] = sub[1]
896  elif sub[0] == 'border':
897  instr['border'] = sub[1]
898  elif sub[0] == 'where':
899  instr['where'] = float(sub[1].split()[0]), float(sub[1].split()[1])
900  except (ValueError, IndexError):
901  GError(_("Failed to read instruction %s") % instruction)
902  return False
903  self.instruction.update(instr)
904  self.instruction['rect'] = self.EstimateRect(mapinfoDict = self.instruction)
905  return True
906 
907  def EstimateRect(self, mapinfoDict):
908  """!Estimate size to draw mapinfo"""
909  w = mapinfoDict['fontsize'] * 20 # any better estimation?
910  h = mapinfoDict['fontsize'] * 7
911  width = self.unitConv.convert(value = w, fromUnit = 'point', toUnit = 'inch')
912  height = self.unitConv.convert(value = h, fromUnit = 'point', toUnit = 'inch')
913  return wx.Rect2D(x = float(mapinfoDict['where'][0]), y = float(mapinfoDict['where'][1]), w = width, h = height)
914 
916  """!Class representing text instruction"""
917  def __init__(self, id):
918  InstructionObject.__init__(self, id = id)
919  self.type = 'text'
920  # default values
921  self.defaultInstruction = dict(text = "", font = "Helvetica", fontsize = 10, color = 'black', background = 'none',
922  hcolor = 'none', hwidth = 1, border = 'none', width = '1', XY = True,
923  where = (0,0), unit = 'inch', rotate = None,
924  ref = "center center", xoffset = 0, yoffset = 0, east = None, north = None)
925  # current values
926  self.instruction = dict(self.defaultInstruction)
927 
928  def __str__(self):
929  text = self.instruction['text'].replace('\n','\\n')
930  instr = "text %s %s" % (self.instruction['east'], self.instruction['north'])
931  try:
932  instr += " %s\n" % text.encode('latin_1')
933  except UnicodeEncodeError, err:
934  try:
935  pos = str(err).split('position')[1].split(':')[0].strip()
936  except IndexError:
937  pos = ''
938  if pos:
939  message = _("Characters on position %s are not supported "
940  "by ISO-8859-1 (Latin 1) encoding "
941  "which is required by module ps.map.") % pos
942  else:
943  message = _("Not all characters are supported "
944  "by ISO-8859-1 (Latin 1) encoding "
945  "which is required by module ps.map.")
946  GMessage(message = message)
947  return ''
948  instr += (string.Template(" font $font\n fontsize $fontsize\n color $color\n").
949  substitute(self.instruction).
950  encode('latin_1'))
951  instr += string.Template(" hcolor $hcolor\n").substitute(self.instruction).encode('latin_1')
952  if self.instruction['hcolor'] != 'none':
953  instr += string.Template(" hwidth $hwidth\n").substitute(self.instruction).encode('latin_1')
954  instr += string.Template(" border $border\n").substitute(self.instruction).encode('latin_1')
955  if self.instruction['border'] != 'none':
956  instr += string.Template(" width $width\n").substitute(self.instruction).encode('latin_1')
957  instr += string.Template(" background $background\n").substitute(self.instruction).encode('latin_1')
958  if self.instruction["ref"] != '0':
959  instr += string.Template(" ref $ref\n").substitute(self.instruction).encode('latin_1')
960  if self.instruction["rotate"]:
961  instr += string.Template(" rotate $rotate\n").substitute(self.instruction).encode('latin_1')
962  if float(self.instruction["xoffset"]) or float(self.instruction["yoffset"]):
963  instr += (string.Template(" xoffset $xoffset\n yoffset $yoffset\n").
964  substitute(self.instruction).encode('latin_1'))
965  instr += " end"
966  return instr
967 
968  def Read(self, instruction, text, **kwargs):
969  """!Read instruction and save information"""
970  map = kwargs['mapInstruction']
971  instr = {}
972  for line in text:
973  try:
974  sub = line.split(None, 1)[0]
975  if sub == 'text':
976  e, n = line.split(None, 3)[1:3]
977  if '%' in e and '%' in n:
978  instr['XY'] = True
979  instr['east'], instr['north'] = self.PercentToReal(e, n)
980  else:
981  instr['XY'] = False
982  instr['east'], instr['north'] = float(e), float(n)
983 
984  instr['text'] = line.split(None, 3)[3]
985 
986  elif sub == 'font':
987  instr['font'] = line.split(None, 1)[1]
988  elif sub == 'fontsize':
989  instr['fontsize'] = float(line.split(None, 1)[1])
990  elif sub == 'color':
991  instr['color'] = line.split(None, 1)[1]
992  elif sub == 'width':
993  instr['width'] = line.split(None, 1)[1]
994  elif sub == 'hcolor':
995  instr['hcolor'] = line.split(None, 1)[1]
996  elif sub == 'hwidth':
997  instr['hwidth'] = line.split(None, 1)[1]
998  elif sub == 'background':
999  instr['background'] = line.split(None, 1)[1]
1000  elif sub == 'border':
1001  instr['border'] = line.split(None, 1)[1]
1002  elif sub == 'ref':
1003  instr['ref'] = line.split(None, 1)[1]
1004  elif sub == 'rotate':
1005  instr['rotate'] = float(line.split(None, 1)[1])
1006  elif sub == 'xoffset':
1007  instr['xoffset'] = int(line.split(None, 1)[1])
1008  elif sub == 'yoffset':
1009  instr['yoffset'] = int(line.split(None, 1)[1])
1010  elif sub == 'opaque':
1011  if line.split(None, 1)[1].lower() in ('n', 'none'):
1012  instr['background'] = 'none'
1013 
1014  except(IndexError, ValueError):
1015  GError(_("Failed to read instruction %s") % instruction)
1016  return False
1017  instr['where'] = PaperMapCoordinates(map = map, x = instr['east'], y = instr['north'], paperToMap = False)
1018  self.instruction.update(instr)
1019 
1020  return True
1021 
1022  def PercentToReal(self, e, n):
1023  """!Converts text coordinates from percent of region to map coordinates"""
1024  e, n = float(e.strip('%')), float(n.strip('%'))
1025  region = grass.region()
1026  N = region['s'] + (region['n'] - region['s']) / 100 * n
1027  E = region['w'] + (region['e'] - region['w']) / 100 * e
1028  return E, N
1029 
1031  """!Class representing scalebar instruction"""
1032  def __init__(self, id):
1033  InstructionObject.__init__(self, id = id)
1034  self.type = 'scalebar'
1035  # default values
1036  self.defaultInstruction = dict(unit = 'inch', where = (1,1),
1037  unitsLength = 'auto', unitsHeight = 'inch',
1038  length = None, height = 0.1, rect = None,
1039  fontsize = 10, background = 'y',
1040  scalebar = 'f', segment = 4, numbers = 1)
1041  # current values
1043 
1044  def __str__(self):
1045  instr = string.Template("scalebar $scalebar\n").substitute(self.instruction)
1046  instr += " where %.3f %.3f\n" % (self.instruction['where'][0], self.instruction['where'][1])
1047  instr += string.Template(" length $length\n units $unitsLength\n").substitute(self.instruction)
1048  instr += string.Template(" height $height\n").substitute(self.instruction)
1049  instr += string.Template(" segment $segment\n numbers $numbers\n").substitute(self.instruction)
1050  instr += string.Template(" fontsize $fontsize\n background $background\n").substitute(self.instruction)
1051  instr += " end"
1052  return instr
1053 
1054  def Read(self, instruction, text, **kwargs):
1055  """!Read instruction and save information"""
1056  scale = kwargs['scale']
1057  instr = {}
1058  for line in text:
1059  try:
1060  if line.startswith('scalebar'):
1061  if 'scalebar s' in line:
1062  instr['scalebar'] = 's'
1063  else:
1064  instr['scalebar'] = 'f'
1065  elif line.startswith('where'):
1066  instr['where'] = map(float, line.split()[1:3])
1067  elif line.startswith('length'):
1068  instr['length'] = float(line.split()[1])
1069  elif line.startswith('units'):
1070  if line.split()[1] in ['auto', 'meters', 'kilometers', 'feet', 'miles', 'nautmiles']:
1071  instr['unitsLength'] = line.split()[1]
1072  elif line.startswith('height'):
1073  instr['height'] = float(line.split()[1])
1074  elif line.startswith('fontsize'):
1075  instr['fontsize'] = float(line.split()[1])
1076  elif line.startswith('numbers'):
1077  instr['numbers'] = int(line.split()[1])
1078  elif line.startswith('segment'):
1079  instr['segment'] = int(line.split()[1])
1080  elif line.startswith('background'):
1081  if line.split()[1].strip().lower() in ('y','yes'):
1082  instr['background'] = 'y'
1083  elif line.split()[1].strip().lower() in ('n','no', 'none'):
1084  instr['background'] = 'n'
1085  except(IndexError, ValueError):
1086  GError(_("Failed to read instruction %s") % instruction)
1087  return False
1088 
1089  self.instruction.update(instr)
1090  w, h = self.EstimateSize(scalebarDict = self.instruction, scale = scale)
1091  x = self.instruction['where'][0] - w / 2
1092  y = self.instruction['where'][1] - h / 2
1093  self.instruction['rect'] = wx.Rect2D(x, y, w, h)
1094  return True
1095 
1096  def EstimateSize(self, scalebarDict, scale):
1097  """!Estimate size to draw scalebar"""
1098  units = projInfo()['units']
1099  if not units or units not in self.unitConv.getAllUnits():
1100  units = 'meters'
1101  if scalebarDict['unitsLength'] != 'auto':
1102  length = self.unitConv.convert(value = scalebarDict['length'], fromUnit = scalebarDict['unitsLength'], toUnit = 'inch')
1103  else:
1104  length = self.unitConv.convert(value = scalebarDict['length'], fromUnit = units, toUnit = 'inch')
1105 
1106  length *= scale
1107  length *= 1.1 #for numbers on the edge
1108  height = scalebarDict['height'] + 2 * self.unitConv.convert(value = scalebarDict['fontsize'], fromUnit = 'point', toUnit = 'inch')
1109  return (length, height)
1110 
1112  """!Class representing colortable instruction"""
1113  def __init__(self, id):
1114  InstructionObject.__init__(self, id = id)
1115  self.type = 'rasterLegend'
1116  # default values
1117  self.defaultInstruction = dict(rLegend = False, unit = 'inch', rasterDefault = True, raster = None,
1118  discrete = None, type = None,
1119  where = (0, 0),
1120  width = None, height = None, cols = 1, font = "Helvetica", fontsize = 10,
1121  #color = '0:0:0', tickbar = False, range = False, min = 0, max = 0,
1122  color = 'black', tickbar = 'n', range = False, min = 0, max = 0,
1123  nodata = 'n')
1124  # current values
1126 
1127  def __str__(self):
1128  instr = "colortable y\n"
1129  instr += string.Template(" raster $raster\n").substitute(self.instruction)
1130  instr += " where %.3f %.3f\n" % (self.instruction['where'][0], self.instruction['where'][1])
1131  if self.instruction['width']:
1132  instr += string.Template(" width $width\n").substitute(self.instruction)
1133  instr += string.Template(" discrete $discrete\n").substitute(self.instruction)
1134  if self.instruction['discrete'] == 'n':
1135  if self.instruction['height']:
1136  instr += string.Template(" height $height\n").substitute(self.instruction)
1137  instr += string.Template(" tickbar $tickbar\n").substitute(self.instruction)
1138  if self.instruction['range']:
1139  instr += string.Template(" range $min $max\n").substitute(self.instruction)
1140  else:
1141  instr += string.Template(" cols $cols\n").substitute(self.instruction)
1142  instr += string.Template(" nodata $nodata\n").substitute(self.instruction)
1143  instr += string.Template(" font $font\n fontsize $fontsize\n color $color\n")\
1144  .substitute(self.instruction)
1145  instr += " end"
1146  return instr
1147 
1148 
1149  def Read(self, instruction, text, **kwargs):
1150  """!Read instruction and save information"""
1151  instr = {}
1152  instr['rLegend'] = True
1153  for line in text:
1154  try:
1155  if line.startswith('where'):
1156  instr['where'] = map(float, line.split()[1:3])
1157  elif line.startswith('font '):
1158  instr['font'] = line.split()[1]
1159  elif line.startswith('fontsize'):
1160  instr['fontsize'] = float(line.split()[1])
1161  elif line.startswith('color '):
1162  instr['color'] = line.split()[1]
1163  elif line.startswith('raster'):
1164  instr['raster'] = line.split()[1]
1165  elif line.startswith('width'):
1166  instr['width'] = float(line.split()[1])
1167  elif line.startswith('height'):
1168  instr['height'] = float(line.split()[1])
1169  elif line.startswith('cols'):
1170  instr['cols'] = int(line.split()[1])
1171  elif line.startswith('range'):
1172  instr['range'] = True
1173  instr['min'] = float(line.split()[1])
1174  instr['max'] = float(line.split()[2])
1175  elif line.startswith('nodata'):
1176  if line.split()[1].strip().lower() in ('y','yes'):
1177  instr['nodata'] = 'y'
1178  elif line.split()[1].strip().lower() in ('n','no', 'none'):
1179  instr['nodata'] = 'n'
1180  elif line.startswith('tickbar'):
1181  if line.split()[1].strip().lower() in ('y','yes'):
1182  instr['tickbar'] = 'y'
1183  elif line.split()[1].strip().lower() in ('n','no', 'none'):
1184  instr['tickbar'] = 'n'
1185  elif line.startswith('discrete'):
1186  if line.split()[1].strip().lower() in ('y','yes'):
1187  instr['discrete'] = 'y'
1188  elif line.split()[1].strip().lower() in ('n','no', 'none'):
1189  instr['discrete'] = 'n'
1190 
1191  except(IndexError, ValueError):
1192  GError(_("Failed to read instruction %s") % instruction)
1193  return False
1194 
1195  if 'raster' in instr:
1196  instr['rasterDefault'] = False
1197  if 'discrete' not in instr:
1198  rasterType = getRasterType(map = instr['raster'])
1199  instr['type'] = rasterType
1200  if rasterType == 'CELL':
1201  instr['discrete'] = 'y'
1202  else:
1203  instr['discrete'] = 'n'
1204 
1205  else:
1206  instr['rasterDefault'] = True
1207  self.instruction.update(instr)
1208  # add 'rect' in the end
1209 
1210  return True
1211 
1212  def EstimateHeight(self, raster, discrete, fontsize, cols = None, height = None):
1213  """!Estimate height to draw raster legend"""
1214  if discrete == 'n':
1215  if height:
1216  height = height
1217  else:
1218  height = self.unitConv.convert(value = fontsize * 10,
1219  fromUnit = 'point', toUnit = 'inch')
1220 
1221  if discrete == 'y':
1222  if cols:
1223  cols = cols
1224  else:
1225  cols = 1
1226 
1227  rinfo = grass.raster_info(raster)
1228  if rinfo['datatype'] in ('DCELL', 'FCELL'):
1229  minim, maxim = rinfo['min'], rinfo['max']
1230  rows = ceil(maxim / cols )
1231  else:
1232  cat = grass.read_command('r.category', map = raster,
1233  fs = ':').strip().split('\n')
1234  rows = ceil(float(len(cat)) / cols )
1235 
1236 
1237  height = self.unitConv.convert(value = 1.5 * rows * fontsize, fromUnit = 'point', toUnit = 'inch')
1238 
1239  return height
1240 
1241  def EstimateWidth(self, raster, discrete, fontsize, cols = None, width = None, paperInstr = None):
1242  """!Estimate size to draw raster legend"""
1243 
1244  if discrete == 'n':
1245  rinfo = grass.raster_info(raster)
1246  minim, maxim = rinfo['min'], rinfo['max']
1247  if width:
1248  width = width
1249  else:
1250  width = self.unitConv.convert(value = fontsize * 2,
1251  fromUnit = 'point', toUnit = 'inch')
1252  text = len(max(str(minim), str(maxim), key = len))
1253  textPart = self.unitConv.convert(value = text * fontsize / 2,
1254  fromUnit = 'point', toUnit = 'inch')
1255  width += textPart
1256 
1257  elif discrete == 'y':
1258  if cols:
1259  cols = cols
1260  else:
1261  cols = 1
1262 
1263  if width:
1264  width = width
1265  else:
1266  paperWidth = paperInstr['Width'] - paperInstr['Right'] - paperInstr['Left']
1267  width = (paperWidth / cols) * (cols - 1) + 1
1268 
1269  return width
1270 
1272  """!Class representing colortable instruction"""
1273  def __init__(self, id):
1274  InstructionObject.__init__(self, id = id)
1275  self.type = 'vectorLegend'
1276  # default values
1277  self.defaultInstruction = dict(vLegend = False, unit = 'inch', where = (0, 0),
1278  defaultSize = True, width = 0.4, cols = 1, span = None,
1279  font = "Helvetica", fontsize = 10,
1280  border = 'none')
1281  # current values
1283 
1284  def __str__(self):
1285  instr = "vlegend\n"
1286  instr += " where %.3f %.3f\n" % (self.instruction['where'][0], self.instruction['where'][1])
1287  instr += string.Template(" font $font\n fontsize $fontsize\n").substitute(self.instruction)
1288  instr += string.Template(" width $width\n cols $cols\n").substitute(self.instruction)
1289  if self.instruction['span']:
1290  instr += string.Template(" span $span\n").substitute(self.instruction)
1291  instr += string.Template(" border $border\n").substitute(self.instruction)
1292  instr += " end"
1293  return instr
1294 
1295  def Read(self, instruction, text, **kwargs):
1296  """!Read instruction and save information"""
1297  instr = {}
1298  instr['vLegend'] = True
1299  for line in text:
1300  try:
1301  if line.startswith('where'):
1302  instr['where'] = map(float, line.split()[1:3])
1303  elif line.startswith('font '):
1304  instr['font'] = line.split()[1]
1305  elif line.startswith('fontsize'):
1306  instr['fontsize'] = float(line.split()[1])
1307  elif line.startswith('width'):
1308  instr['width'] = float(line.split()[1])
1309  elif line.startswith('cols'):
1310  instr['cols'] = int(line.split()[1])
1311  elif line.startswith('span'):
1312  instr['span'] = float(line.split()[1])
1313  elif line.startswith('border'):
1314  instr['border'] = line.split()[1]
1315 
1316  except(IndexError, ValueError):
1317  GError(_("Failed to read instruction %s") % instruction)
1318  return False
1319 
1320  self.instruction.update(instr)
1321 
1322  return True
1323 
1324  def EstimateSize(self, vectorInstr, fontsize, width = None, cols = None):
1325  """!Estimate size to draw vector legend"""
1326  if width:
1327  width = width
1328  else:
1329  width = fontsize/24.0
1330 
1331  if cols:
1332  cols = cols
1333  else:
1334  cols = 1
1335 
1336  vectors = vectorInstr['list']
1337  labels = [vector[4] for vector in vectors if vector[3] != 0]
1338  extent = (len(max(labels, key = len)) * fontsize / 2, fontsize)
1339  wExtent = self.unitConv.convert(value = extent[0], fromUnit = 'point', toUnit = 'inch')
1340  hExtent = self.unitConv.convert(value = extent[1], fromUnit = 'point', toUnit = 'inch')
1341  w = (width + wExtent) * cols
1342  h = len(labels) * hExtent / cols
1343  h *= 1.1
1344  return (w, h)
1345 
1346 
1348  """!Class representing raster instruction"""
1349  def __init__(self, id):
1350  InstructionObject.__init__(self, id = id)
1351  self.type = 'raster'
1352  # default values
1353  self.defaultInstruction = dict(isRaster = False, raster = None)
1354  # current values
1356 
1357  def __str__(self):
1358  instr = string.Template("raster $raster").substitute(self.instruction)
1359  return instr
1360 
1361  def Read(self, instruction, text):
1362  """!Read instruction and save information"""
1363  instr = {}
1364  instr['isRaster'] = True
1365  try:
1366  map = text.split()[1]
1367  except IndexError:
1368  GError(_("Failed to read instruction %s") % instruction)
1369  return False
1370  try:
1371  info = grass.find_file(map, element = 'cell')
1372  except grass.ScriptError, e:
1373  GError(message = e.value)
1374  return False
1375  instr['raster'] = info['fullname']
1376 
1377 
1378  self.instruction.update(instr)
1379  return True
1380 
1382  """!Class keeps vector layers"""
1383  def __init__(self, id):
1384  InstructionObject.__init__(self, id = id)
1385  self.type = 'vector'
1386  # default values
1387  self.defaultInstruction = dict(list = None)# [vmap, type, id, lpos, label]
1388  # current values
1390  def __str__(self):
1391  return ''
1392 
1393  def Read(self, instruction, text, **kwargs):
1394  """!Read instruction and save information"""
1395  instr = {}
1396 
1397  for line in text:
1398  if line.startswith('vpoints') or line.startswith('vlines') or line.startswith('vareas'):
1399  # subtype
1400  if line.startswith('vpoints'):
1401  subType = 'points'
1402  elif line.startswith('vlines'):
1403  subType = 'lines'
1404  elif line.startswith('vareas'):
1405  subType = 'areas'
1406  # name of vector map
1407  vmap = line.split()[1]
1408  try:
1409  info = grass.find_file(vmap, element = 'vector')
1410  except grass.ScriptError, e:
1411  GError(message = e.value)
1412  return False
1413  vmap = info['fullname']
1414  # id
1415  id = kwargs['id']
1416  # lpos
1417  lpos = kwargs['vectorMapNumber']
1418  #label
1419  label = '('.join(vmap.split('@')) + ')'
1420  break
1421  instr = [vmap, subType, id, lpos, label]
1422  if not self.instruction['list']:
1423  self.instruction['list'] = []
1424  self.instruction['list'].append(instr)
1425 
1426  return True
1427 
1429  """!Class represents instructions vareas, vlines, vpoints"""
1430  def __init__(self, id, subType):
1431  InstructionObject.__init__(self, id = id)
1432  self.type = 'vProperties'
1433  self.subType = subType
1434  # default values
1435  if self.subType == 'points':
1436  dd = dict(subType = 'points', name = None, type = 'point or centroid', connection = False, layer = '1',
1437  masked = 'n', color = '0:0:0', width = 1,
1438  fcolor = '255:0:0', rgbcolumn = None, symbol = os.path.join('basic', 'x'), eps = None,
1439  size = 5, sizecolumn = None, scale = None,
1440  rotation = False, rotate = 0, rotatecolumn = None, label = None, lpos = None)
1441  elif self.subType == 'lines':
1442  dd = dict(subType = 'lines', name = None, type = 'line or boundary', connection = False, layer = '1',
1443  masked = 'n', color = '0:0:0', hwidth = 1,
1444  hcolor = 'none', rgbcolumn = None,
1445  width = 1, cwidth = None,
1446  style = 'solid', linecap = 'butt', label = None, lpos = None)
1447  else: # areas
1448  dd = dict(subType = 'areas', name = None, connection = False, layer = '1',
1449  masked = 'n', color = '0:0:0', width = 1,
1450  fcolor = 'none', rgbcolumn = None,
1451  pat = None, pwidth = 1, scale = 1, label = None, lpos = None)
1453  # current values
1455 
1456  def __str__(self):
1457  dic = self.instruction
1458  vInstruction = string.Template("v$subType $name\n").substitute(dic)
1459  #data selection
1460  if self.subType in ('points', 'lines'):
1461  vInstruction += string.Template(" type $type\n").substitute(dic)
1462  if dic['connection']:
1463  vInstruction += string.Template(" layer $layer\n").substitute(dic)
1464  if dic.has_key('cats'):
1465  vInstruction += string.Template(" cats $cats\n").substitute(dic)
1466  elif dic.has_key('where'):
1467  vInstruction += string.Template(" where $where\n").substitute(dic)
1468  vInstruction += string.Template(" masked $masked\n").substitute(dic)
1469  #colors
1470  vInstruction += string.Template(" color $color\n").substitute(dic)
1471  if self.subType in ('points', 'areas'):
1472  if dic['color'] != 'none':
1473  vInstruction += string.Template(" width $width\n").substitute(dic)
1474  if dic['rgbcolumn']:
1475  vInstruction += string.Template(" rgbcolumn $rgbcolumn\n").substitute(dic)
1476  vInstruction += string.Template(" fcolor $fcolor\n").substitute(dic)
1477  else:
1478  if dic['rgbcolumn']:
1479  vInstruction += string.Template(" rgbcolumn $rgbcolumn\n").substitute(dic)
1480  elif dic['hcolor'] != 'none':
1481  vInstruction += string.Template(" hwidth $hwidth\n").substitute(dic)
1482  vInstruction += string.Template(" hcolor $hcolor\n").substitute(dic)
1483 
1484  # size and style
1485  if self.subType == 'points':
1486  if dic['symbol']:
1487  vInstruction += string.Template(" symbol $symbol\n").substitute(dic)
1488  else: #eps
1489  vInstruction += string.Template(" eps $eps\n").substitute(dic)
1490  if dic['size']:
1491  vInstruction += string.Template(" size $size\n").substitute(dic)
1492  else: # sizecolumn
1493  vInstruction += string.Template(" sizecolumn $sizecolumn\n").substitute(dic)
1494  vInstruction += string.Template(" scale $scale\n").substitute(dic)
1495  if dic['rotation']:
1496  if dic['rotate'] is not None:
1497  vInstruction += string.Template(" rotate $rotate\n").substitute(dic)
1498  else:
1499  vInstruction += string.Template(" rotatecolumn $rotatecolumn\n").substitute(dic)
1500 
1501  if self.subType == 'areas':
1502  if dic['pat'] is not None:
1503  vInstruction += string.Template(" pat $pat\n").substitute(dic)
1504  vInstruction += string.Template(" pwidth $pwidth\n").substitute(dic)
1505  vInstruction += string.Template(" scale $scale\n").substitute(dic)
1506 
1507  if self.subType == 'lines':
1508  if dic['width'] is not None:
1509  vInstruction += string.Template(" width $width\n").substitute(dic)
1510  else:
1511  vInstruction += string.Template(" cwidth $cwidth\n").substitute(dic)
1512  vInstruction += string.Template(" style $style\n").substitute(dic)
1513  vInstruction += string.Template(" linecap $linecap\n").substitute(dic)
1514  #position and label in vlegend
1515  vInstruction += string.Template(" label $label\n lpos $lpos\n").substitute(dic)
1516 
1517  vInstruction += " end"
1518  return vInstruction
1519 
1520  def Read(self, instruction, text, **kwargs):
1521  """!Read instruction and save information"""
1522  instr = {}
1523  try:
1524  info = grass.find_file(name = text[0].split()[1], element = 'vector')
1525  except grass.ScriptError, e:
1526  GError(message = e.value)
1527  return False
1528  instr['name'] = info['fullname']
1529  #connection
1530  instr['connection'] = True
1531  self.mapDBInfo = dbm_base.VectorDBInfo(instr['name'])
1532  self.layers = self.mapDBInfo.layers.keys()
1533  if not self.layers:
1534  instr['connection'] = False
1535 
1536  # points
1537  if text[0].startswith('vpoints'):
1538  for line in text[1:]:
1539  if line.startswith('type'):
1540  tp = []
1541  if line.find('point') != -1:
1542  tp.append('point')
1543  if line.find('centroid') != -1:
1544  tp.append('centroid')
1545  instr['type'] = ' or '.join(tp)
1546  elif line.startswith('fcolor'):
1547  instr['fcolor'] = line.split()[1]
1548  elif line.startswith('rgbcolumn'):
1549  instr['rgbcolumn'] = line.split()[1]
1550  elif line.startswith('symbol'):
1551  instr['symbol'] = line.split()[1]
1552  elif line.startswith('eps'):
1553  instr['eps'] = line.split()[1]
1554  elif line.startswith('size '):
1555  instr['size'] = line.split()[1]
1556  elif line.startswith('sizecolumn'):
1557  instr['size'] = None
1558  instr['sizecolumn'] = line.split()[1]
1559  elif line.startswith('scale '):
1560  instr['scale'] = float(line.split()[1])
1561  elif line.startswith('rotate '):
1562  instr['rotation'] = True
1563  instr['rotate'] = line.split()[1]
1564  elif line.startswith('rotatecolumn'):
1565  instr['rotatecolumn'] = line.split()[1]
1566  instr['rotation'] = True
1567  instr['rotate'] = None
1568 
1569  # lines
1570  elif text[0].startswith('vlines'):
1571  for line in text[1:]:
1572  if line.startswith('type'):
1573  tp = []
1574  if line.find('line') != -1:
1575  tp.append('line')
1576  if line.find('boundary') != -1:
1577  tp.append('boundary')
1578  instr['type'] = ' or '.join(tp)
1579  elif line.startswith('hwidth'):
1580  instr['hwidth'] = float(line.split()[1])
1581  elif line.startswith('hcolor'):
1582  instr['hcolor'] = line.split()[1]
1583  elif line.startswith('rgbcolumn'):
1584  instr['rgbcolumn'] = line.split()[1]
1585  elif line.startswith('cwidth'):
1586  instr['cwidth'] = float(line.split()[1])
1587  instr['width'] = None
1588  elif line.startswith('style'):
1589  instr['style'] = line.split()[1]
1590  elif line.startswith('linecap'):
1591  instr['linecap'] = line.split()[1]
1592 
1593  elif text[0].startswith('vareas'):
1594  for line in text[1:]:
1595  if line.startswith('fcolor'):
1596  instr['fcolor'] = line.split()[1]
1597  elif line.startswith('pat'):
1598  instr['pat'] = line.split()[1]
1599  elif line.startswith('pwidth'):
1600  instr['pwidth'] = float(line.split()[1])
1601  elif line.startswith('scale'):
1602  instr['scale'] = float(line.split()[1])
1603 
1604 
1605  # same properties for all
1606  for line in text[1:]:
1607  if line.startswith('lpos'):
1608  instr['lpos'] = int(line.split()[1])
1609  elif line.startswith('label'):
1610  instr['label'] = line.split(None, 1)[1]
1611  elif line.startswith('layer'):
1612  instr['layer'] = line.split()[1]
1613  elif line.startswith('masked'):
1614  if line.split()[1].lower() in ('y', 'yes'):
1615  instr['masked'] = 'y'
1616  else:
1617  instr['masked'] = 'n'
1618  elif line.startswith('color'):
1619  instr['color'] = line.split()[1]
1620  elif line.startswith('rgbcolumn'):
1621  instr['rgbcolumn'] = line.split()[1]
1622  elif line.startswith('width'):
1623  instr['width'] = float(line.split()[1])
1624 
1625  if 'label' not in instr:
1626  instr['label'] = '('.join(instr['name'].split('@')) + ')'
1627  if 'lpos' not in instr:
1628  instr['lpos'] = kwargs['vectorMapNumber']
1629  self.instruction.update(instr)
1630 
1631  return True
1632 
1633 class PsmapDialog(wx.Dialog):
1634  def __init__(self, parent, id, title, settings, apply = True):
1635  wx.Dialog.__init__(self, parent = parent, id = wx.ID_ANY,
1636  title = title, size = wx.DefaultSize,
1637  style = wx.CAPTION|wx.MINIMIZE_BOX|wx.CLOSE_BOX)
1638  self.apply = apply
1639  self.id = id
1640  self.parent = parent
1641  self.instruction = settings
1642  self.objectType = None
1644  self.spinCtrlSize = (50, -1)
1645 
1646  self.Bind(wx.EVT_CLOSE, self.OnClose)
1647 
1648 
1649 
1650  def AddUnits(self, parent, dialogDict):
1651  parent.units = dict()
1652  parent.units['unitsLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Units:"))
1653  choices = self.unitConv.getPageUnitsNames()
1654  parent.units['unitsCtrl'] = wx.Choice(parent, id = wx.ID_ANY, choices = choices)
1655  parent.units['unitsCtrl'].SetStringSelection(self.unitConv.findName(dialogDict['unit']))
1656 
1657  def AddPosition(self, parent, dialogDict):
1658  parent.position = dict()
1659  parent.position['comment'] = wx.StaticText(parent, id = wx.ID_ANY,\
1660  label = _("Position of the top left corner\nfrom the top left edge of the paper"))
1661  parent.position['xLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("X:"))
1662  parent.position['yLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Y:"))
1663  parent.position['xCtrl'] = wx.TextCtrl(parent, id = wx.ID_ANY, value = str(dialogDict['where'][0]), validator = TCValidator(flag = 'DIGIT_ONLY'))
1664  parent.position['yCtrl'] = wx.TextCtrl(parent, id = wx.ID_ANY, value = str(dialogDict['where'][1]), validator = TCValidator(flag = 'DIGIT_ONLY'))
1665  if dialogDict.has_key('unit'):
1666  x = self.unitConv.convert(value = dialogDict['where'][0], fromUnit = 'inch', toUnit = dialogDict['unit'])
1667  y = self.unitConv.convert(value = dialogDict['where'][1], fromUnit = 'inch', toUnit = dialogDict['unit'])
1668  parent.position['xCtrl'].SetValue("%5.3f" % x)
1669  parent.position['yCtrl'].SetValue("%5.3f" % y)
1670 
1671  def AddFont(self, parent, dialogDict, color = True):
1672  parent.font = dict()
1673 ## parent.font['fontLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Choose font:"))
1674 ## parent.font['fontCtrl'] = wx.FontPickerCtrl(parent, id = wx.ID_ANY)
1675 ##
1676 ## parent.font['fontCtrl'].SetSelectedFont(
1677 ## wx.FontFromNativeInfoString(dialogDict['font'] + " " + str(dialogDict['fontsize'])))
1678 ## parent.font['fontCtrl'].SetMaxPointSize(50)
1679 ##
1680 ## if color:
1681 ## parent.font['colorLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Choose color:"))
1682 ## parent.font['colorCtrl'] = wx.ColourPickerCtrl(parent, id = wx.ID_ANY, style=wx.FNTP_FONTDESC_AS_LABEL)
1683 ## parent.font['colorCtrl'].SetColour(dialogDict['color'])
1684 
1685 ## parent.font['colorCtrl'].SetColour(convertRGB(dialogDict['color']))
1686 
1687  parent.font['fontLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Font:"))
1688  parent.font['fontSizeLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Font size:"))
1689  fontChoices = [ 'Times-Roman', 'Times-Italic', 'Times-Bold', 'Times-BoldItalic', 'Helvetica',\
1690  'Helvetica-Oblique', 'Helvetica-Bold', 'Helvetica-BoldOblique', 'Courier',\
1691  'Courier-Oblique', 'Courier-Bold', 'Courier-BoldOblique']
1692  parent.font['fontCtrl'] = wx.Choice(parent, id = wx.ID_ANY, choices = fontChoices)
1693  if dialogDict['font'] in fontChoices:
1694  parent.font['fontCtrl'].SetStringSelection(dialogDict['font'])
1695  else:
1696  parent.font['fontCtrl'].SetStringSelection('Helvetica')
1697  parent.font['fontSizeCtrl'] = wx.SpinCtrl(parent, id = wx.ID_ANY, min = 4, max = 50, initial = 10)
1698  parent.font['fontSizeCtrl'].SetValue(dialogDict['fontsize'])
1699 
1700  if color:
1701  parent.font['colorLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Choose color:"))
1702  parent.font['colorCtrl'] = wx.ColourPickerCtrl(parent, id = wx.ID_ANY)
1703  parent.font['colorCtrl'].SetColour(convertRGB(dialogDict['color']))
1704 ## parent.font['colorLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Color:"))
1705 ## colorChoices = [ 'aqua', 'black', 'blue', 'brown', 'cyan', 'gray', 'green', 'indigo', 'magenta',\
1706 ## 'orange', 'purple', 'red', 'violet', 'white', 'yellow']
1707 ## parent.colorCtrl = wx.Choice(parent, id = wx.ID_ANY, choices = colorChoices)
1708 ## parent.colorCtrl.SetStringSelection(parent.rLegendDict['color'])
1709 ## parent.font['colorCtrl'] = wx.ColourPickerCtrl(parent, id = wx.ID_ANY)
1710 ## parent.font['colorCtrl'].SetColour(dialogDict['color'])
1711  def OnApply(self, event):
1712  ok = self.update()
1713  if ok:
1714  self.parent.DialogDataChanged(id = self.id)
1715  return True
1716  else:
1717  return False
1718 
1719  def OnOK(self, event):
1720  """!Apply changes, close dialog"""
1721  ok = self.OnApply(event)
1722  if ok:
1723  self.Close()
1724 
1725  def OnCancel(self, event):
1726  """!Close dialog"""
1727  self.Close()
1728 
1729  def OnClose(self, event):
1730  """!Destroy dialog and delete it from open dialogs"""
1731  if self.objectType:
1732  for each in self.objectType:
1733  if each in self.parent.openDialogs:
1734  del self.parent.openDialogs[each]
1735  event.Skip()
1736  self.Destroy()
1737 
1738  def _layout(self, panel):
1739  #buttons
1740  btnCancel = wx.Button(self, wx.ID_CANCEL)
1741  btnOK = wx.Button(self, wx.ID_OK)
1742  btnOK.SetDefault()
1743  if self.apply:
1744  btnApply = wx.Button(self, wx.ID_APPLY)
1745 
1746 
1747  # bindigs
1748  btnOK.Bind(wx.EVT_BUTTON, self.OnOK)
1749  btnOK.SetToolTipString(_("Close dialog and apply changes"))
1750  #btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
1751  btnCancel.SetToolTipString(_("Close dialog and ignore changes"))
1752  btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
1753  if self.apply:
1754  btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
1755  btnApply.SetToolTipString(_("Apply changes"))
1756 
1757  # sizers
1758  btnSizer = wx.StdDialogButtonSizer()
1759  btnSizer.AddButton(btnCancel)
1760  if self.apply:
1761  btnSizer.AddButton(btnApply)
1762  btnSizer.AddButton(btnOK)
1763  btnSizer.Realize()
1764 
1765  mainSizer = wx.BoxSizer(wx.VERTICAL)
1766  mainSizer.Add(item = panel, proportion = 1, flag = wx.EXPAND | wx.ALL, border = 5)
1767  mainSizer.Add(item = btnSizer, proportion = 0,
1768  flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
1769 
1770 
1771  self.SetSizer(mainSizer)
1772  mainSizer.Layout()
1773  mainSizer.Fit(self)
1774 
1776  def __init__(self, parent, id, settings):
1777  PsmapDialog.__init__(self, parent = parent, id = id, title = "Page setup", settings = settings)
1778 
1779  self.cat = ['Units', 'Format', 'Orientation', 'Width', 'Height', 'Left', 'Right', 'Top', 'Bottom']
1780  labels = [_('Units'), _('Format'), _('Orientation'), _('Width'), _('Height'),
1781  _('Left'), _('Right'), _('Top'), _('Bottom')]
1782  self.catsLabels = dict(zip(self.cat, labels))
1783  paperString = RunCommand('ps.map', flags = 'p', read = True, quiet = True)
1784  self.paperTable = self._toList(paperString)
1785  self.unitsList = self.unitConv.getPageUnitsNames()
1786  self.pageSetupDict = settings[id].GetInstruction()
1787 
1788  self._layout()
1789 
1790  if self.pageSetupDict:
1791  self.getCtrl('Units').SetStringSelection(self.unitConv.findName(self.pageSetupDict['Units']))
1792  if self.pageSetupDict['Format'] == 'custom':
1793  self.getCtrl('Format').SetSelection(self.getCtrl('Format').GetCount() - 1)
1794  else:
1795  self.getCtrl('Format').SetStringSelection(self.pageSetupDict['Format'])
1796  if self.pageSetupDict['Orientation'] == 'Portrait':
1797  self.getCtrl('Orientation').SetSelection(0)
1798  else:
1799  self.getCtrl('Orientation').SetSelection(1)
1800 
1801  for item in self.cat[3:]:
1802  val = self.unitConv.convert(value = self.pageSetupDict[item],
1803  fromUnit = 'inch', toUnit = self.pageSetupDict['Units'])
1804  self.getCtrl(item).SetValue("%4.3f" % val)
1805 
1806 
1807  if self.getCtrl('Format').GetSelection() != self.getCtrl('Format').GetCount() - 1: # custom
1808  self.getCtrl('Width').Disable()
1809  self.getCtrl('Height').Disable()
1810  else:
1811  self.getCtrl('Orientation').Disable()
1812  # events
1813  self.getCtrl('Units').Bind(wx.EVT_CHOICE, self.OnChoice)
1814  self.getCtrl('Format').Bind(wx.EVT_CHOICE, self.OnChoice)
1815  self.getCtrl('Orientation').Bind(wx.EVT_CHOICE, self.OnChoice)
1816  self.btnOk.Bind(wx.EVT_BUTTON, self.OnOK)
1817 
1818 
1819  def update(self):
1820  self.pageSetupDict['Units'] = self.unitConv.findUnit(self.getCtrl('Units').GetStringSelection())
1821  self.pageSetupDict['Format'] = self.paperTable[self.getCtrl('Format').GetSelection()]['Format']
1822  if self.getCtrl('Orientation').GetSelection() == 0:
1823  self.pageSetupDict['Orientation'] = 'Portrait'
1824  else:
1825  self.pageSetupDict['Orientation'] = 'Landscape'
1826  for item in self.cat[3:]:
1827  self.pageSetupDict[item] = self.unitConv.convert(value = float(self.getCtrl(item).GetValue()),
1828  fromUnit = self.pageSetupDict['Units'], toUnit = 'inch')
1829 
1830 
1831 
1832  def OnOK(self, event):
1833  try:
1834  self.update()
1835  except ValueError:
1836  wx.MessageBox(message = _("Literal is not allowed!"), caption = _('Invalid input'),
1837  style = wx.OK|wx.ICON_ERROR)
1838  else:
1839  event.Skip()
1840 
1841  def _layout(self):
1842  size = (110,-1)
1843  #sizers
1844  mainSizer = wx.BoxSizer(wx.VERTICAL)
1845  pageBox = wx.StaticBox(self, id = wx.ID_ANY, label = " %s " % _("Page size"))
1846  pageSizer = wx.StaticBoxSizer(pageBox, wx.VERTICAL)
1847  marginBox = wx.StaticBox(self, id = wx.ID_ANY, label = " %s " % _("Margins"))
1848  marginSizer = wx.StaticBoxSizer(marginBox, wx.VERTICAL)
1849  horSizer = wx.BoxSizer(wx.HORIZONTAL)
1850  #staticText + choice
1851  choices = [self.unitsList, [item['Format'] for item in self.paperTable], [_('Portrait'), _('Landscape')]]
1852  propor = [0,1,1]
1853  border = [5,3,3]
1854  self.hBoxDict={}
1855  for i, item in enumerate(self.cat[:3]):
1856  hBox = wx.BoxSizer(wx.HORIZONTAL)
1857  stText = wx.StaticText(self, id = wx.ID_ANY, label = self.catsLabels[item] + ':')
1858  choice = wx.Choice(self, id = wx.ID_ANY, choices = choices[i], size = size)
1859  hBox.Add(stText, proportion = propor[i], flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = border[i])
1860  hBox.Add(choice, proportion = 0, flag = wx.ALL, border = border[i])
1861  if item == 'Units':
1862  hBox.Add(size,1)
1863  self.hBoxDict[item] = hBox
1864 
1865  #staticText + TextCtrl
1866  for item in self.cat[3:]:
1867  hBox = wx.BoxSizer(wx.HORIZONTAL)
1868  label = wx.StaticText(self, id = wx.ID_ANY, label = self.catsLabels[item] + ':')
1869  textctrl = wx.TextCtrl(self, id = wx.ID_ANY, size = size, value = '')
1870  hBox.Add(label, proportion = 1, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 3)
1871  hBox.Add(textctrl, proportion = 0, flag = wx.ALIGN_CENTRE|wx.ALL, border = 3)
1872  self.hBoxDict[item] = hBox
1873 
1874  sizer = list([mainSizer] + [pageSizer]*4 + [marginSizer]*4)
1875  for i, item in enumerate(self.cat):
1876  sizer[i].Add(self.hBoxDict[item], 0, wx.GROW|wx.RIGHT|wx.LEFT,5)
1877  # OK button
1878  btnSizer = wx.StdDialogButtonSizer()
1879  self.btnOk = wx.Button(self, wx.ID_OK)
1880  self.btnOk.SetDefault()
1881  btnSizer.AddButton(self.btnOk)
1882  btn = wx.Button(self, wx.ID_CANCEL)
1883  btnSizer.AddButton(btn)
1884  btnSizer.Realize()
1885 
1886 
1887  horSizer.Add(pageSizer, proportion = 0, flag = wx.LEFT|wx.RIGHT|wx.BOTTOM, border = 10)
1888  horSizer.Add(marginSizer, proportion = 0, flag = wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.EXPAND, border = 10)
1889  mainSizer.Add(horSizer, proportion = 0, border = 10)
1890  mainSizer.Add(btnSizer, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.ALL, border = 10)
1891  self.SetSizer(mainSizer)
1892  mainSizer.Fit(self)
1893 
1894  def OnChoice(self, event):
1895  currPaper = self.paperTable[self.getCtrl('Format').GetSelection()]
1896  currUnit = self.unitConv.findUnit(self.getCtrl('Units').GetStringSelection())
1897  currOrientIdx = self.getCtrl('Orientation').GetSelection()
1898  newSize = dict()
1899  for item in self.cat[3:]:
1900  newSize[item] = self.unitConv.convert(float(currPaper[item]), fromUnit = 'inch', toUnit = currUnit)
1901 
1902  enable = True
1903  if currPaper['Format'] != _('custom'):
1904  if currOrientIdx == 1: # portrait
1905  newSize['Width'], newSize['Height'] = newSize['Height'], newSize['Width']
1906  for item in self.cat[3:]:
1907  self.getCtrl(item).ChangeValue("%4.3f" % newSize[item])
1908  enable = False
1909  self.getCtrl('Width').Enable(enable)
1910  self.getCtrl('Height').Enable(enable)
1911  self.getCtrl('Orientation').Enable(not enable)
1912 
1913 
1914  def getCtrl(self, item):
1915  return self.hBoxDict[item].GetItem(1).GetWindow()
1916 
1917  def _toList(self, paperStr):
1918 
1919  sizeList = list()
1920  for line in paperStr.strip().split('\n'):
1921  d = dict(zip([self.cat[1]]+ self.cat[3:],line.split()))
1922  sizeList.append(d)
1923  d = {}.fromkeys([self.cat[1]]+ self.cat[3:], 100)
1924  d.update(Format = _('custom'))
1925  sizeList.append(d)
1926  return sizeList
1927 
1929  """!Dialog for map frame settings and optionally raster and vector map selection"""
1930  def __init__(self, parent, id, settings, rect = None, notebook = False):
1931  PsmapDialog.__init__(self, parent = parent, id = id, title = "", settings = settings)
1932 
1933  self.isNotebook = notebook
1934  if self.isNotebook:
1935  self.objectType = ('mapNotebook',)
1936  else:
1937  self.objectType = ('map',)
1938 
1939 
1940  #notebook
1941  if self.isNotebook:
1942  self.notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT)
1943  self.mPanel = MapFramePanel(parent = self.notebook, id = self.id[0], settings = self.instruction,
1944  rect = rect, notebook = True)
1945  self.id[0] = self.mPanel.getId()
1946  self.rPanel = RasterPanel(parent = self.notebook, id = self.id[1], settings = self.instruction,
1947  notebook = True)
1948  self.id[1] = self.rPanel.getId()
1949  self.vPanel = VectorPanel(parent = self.notebook, id = self.id[2], settings = self.instruction,
1950  notebook = True)
1951  self.id[2] = self.vPanel.getId()
1952  self._layout(self.notebook)
1953  self.SetTitle(_("Map settings"))
1954  else:
1955  self.mPanel = MapFramePanel(parent = self, id = self.id[0], settings = self.instruction,
1956  rect = rect, notebook = False)
1957  self.id[0] = self.mPanel.getId()
1958  self._layout(self.mPanel)
1959  self.SetTitle(_("Map frame settings"))
1960 
1961 
1962  def OnApply(self, event):
1963  """!Apply changes"""
1964  if self.isNotebook:
1965  okV = self.vPanel.update()
1966  okR = self.rPanel.update()
1967  if okV and self.id[2] in self.instruction:
1968  self.parent.DialogDataChanged(id = self.id[2])
1969  if okR and self.id[1] in self.instruction:
1970  self.parent.DialogDataChanged(id = self.id[1])
1971  if not okR or not okV:
1972  return False
1973 
1974  ok = self.mPanel.update()
1975  if ok:
1976  self.parent.DialogDataChanged(id = self.id[0])
1977  return True
1978 
1979  return False
1980 
1981  def OnCancel(self, event):
1982  """!Close dialog and remove tmp red box"""
1983  self.parent.canvas.pdcTmp.RemoveId(self.parent.canvas.idZoomBoxTmp)
1984  self.parent.canvas.Refresh()
1985  self.Close()
1986 
1987  def updateDialog(self):
1988  """!Update raster and vector information"""
1989  if self.mPanel.scaleChoice.GetSelection() == 0:
1990  if self.mPanel.rasterTypeRadio.GetValue():
1991  if 'raster' in self.parent.openDialogs:
1992  if self.parent.openDialogs['raster'].rPanel.rasterYesRadio.GetValue() and \
1993  self.parent.openDialogs['raster'].rPanel.rasterSelect.GetValue() == self.mPanel.select.GetValue():
1994  self.mPanel.drawMap.SetValue(True)
1995  else:
1996  self.mPanel.drawMap.SetValue(False)
1997  else:
1998  if 'vector' in self.parent.openDialogs:
1999  found = False
2000  for each in self.parent.openDialogs['vector'].vPanel.vectorList:
2001  if each[0] == self.mPanel.select.GetValue():
2002  found = True
2003  self.mPanel.drawMap.SetValue(found)
2004 
2005 class MapFramePanel(wx.Panel):
2006  """!wx.Panel with map (scale, region, border) settings"""
2007  def __init__(self, parent, id, settings, rect, notebook = True):
2008  wx.Panel.__init__(self, parent, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
2009 
2010  self.id = id
2011  self.instruction = settings
2012 
2013  if notebook:
2014  self.book = parent
2015  self.book.AddPage(page = self, text = _("Map frame"))
2016  self.mapDialog = self.book.GetParent()
2017  else:
2018  self.mapDialog = parent
2019 
2020  if self.id is not None:
2021  self.mapFrameDict = self.instruction[self.id].GetInstruction()
2022  else:
2023  self.id = wx.NewId()
2024  mapFrame = MapFrame(self.id)
2025  self.mapFrameDict = mapFrame.GetInstruction()
2026  self.mapFrameDict['rect'] = rect
2027 
2028 
2029  self._layout()
2030 
2031  self.scale = [None]*4
2032  self.center = [None]*4
2033 
2034 
2035 
2036  self.selectedMap = self.mapFrameDict['map']
2037  self.selectedRegion = self.mapFrameDict['region']
2038  self.scaleType = self.mapFrameDict['scaleType']
2039  self.mapType = self.mapFrameDict['mapType']
2040  self.scaleChoice.SetSelection(self.mapFrameDict['scaleType'])
2041  if self.instruction[self.id]:
2042  self.drawMap.SetValue(self.mapFrameDict['drawMap'])
2043  else:
2044  self.drawMap.SetValue(True)
2045  if self.mapFrameDict['scaleType'] == 0 and self.mapFrameDict['map']:
2046  self.select.SetValue(self.mapFrameDict['map'])
2047  if self.mapFrameDict['mapType'] == 'raster':
2048  self.rasterTypeRadio.SetValue(True)
2049  self.vectorTypeRadio.SetValue(False)
2050  else:
2051  self.rasterTypeRadio.SetValue(False)
2052  self.vectorTypeRadio.SetValue(True)
2053  elif self.mapFrameDict['scaleType'] == 1 and self.mapFrameDict['region']:
2054  self.select.SetValue(self.mapFrameDict['region'])
2055 
2056 
2057  self.OnMap(None)
2058  self.scale[self.mapFrameDict['scaleType']] = self.mapFrameDict['scale']
2059  self.center[self.mapFrameDict['scaleType']] = self.mapFrameDict['center']
2060  self.OnScaleChoice(None)
2061  self.OnElementType(None)
2062  self.OnBorder(None)
2063 
2064 
2065 
2066  def _layout(self):
2067  """!Do layout"""
2068  border = wx.BoxSizer(wx.VERTICAL)
2069 
2070  box = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Map frame"))
2071  sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
2072  gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
2073 
2074 
2075  #scale options
2076  frameText = wx.StaticText(self, id = wx.ID_ANY, label = _("Map frame options:"))
2077  scaleChoices = [_("fit frame to match selected map"),
2078  _("fit frame to match saved region"),
2079  _("fit frame to match current computational region"),
2080  _("fixed scale and map center")]
2081  self.scaleChoice = wx.Choice(self, id = wx.ID_ANY, choices = scaleChoices)
2082 
2083 
2084  gridBagSizer.Add(frameText, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
2085  gridBagSizer.Add(self.scaleChoice, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
2086 
2087  #map and region selection
2088  self.staticBox = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Map selection"))
2089  sizerM = wx.StaticBoxSizer(self.staticBox, wx.HORIZONTAL)
2090  self.mapSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
2091 
2092  self.rasterTypeRadio = wx.RadioButton(self, id = wx.ID_ANY, label = " %s " % _("raster"), style = wx.RB_GROUP)
2093  self.vectorTypeRadio = wx.RadioButton(self, id = wx.ID_ANY, label = " %s " % _("vector"))
2094  self.drawMap = wx.CheckBox(self, id = wx.ID_ANY, label = "add selected map")
2095 
2096  self.mapOrRegionText = [_("Map:"), _("Region:")]
2097  dc = wx.ClientDC(self)# determine size of labels
2098  width = max(dc.GetTextExtent(self.mapOrRegionText[0])[0], dc.GetTextExtent(self.mapOrRegionText[1])[0])
2099  self.mapText = wx.StaticText(self, id = wx.ID_ANY, label = self.mapOrRegionText[0], size = (width, -1))
2100  self.select = Select(self, id = wx.ID_ANY, size = globalvar.DIALOG_GSELECT_SIZE,
2101  type = 'raster', multiple = False,
2102  updateOnPopup = True, onPopup = None)
2103 
2104  self.mapSizer.Add(self.rasterTypeRadio, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
2105  self.mapSizer.Add(self.vectorTypeRadio, pos = (0, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
2106  self.mapSizer.Add(self.drawMap, pos = (0, 3), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
2107  self.mapSizer.Add(self.mapText, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
2108  self.mapSizer.Add(self.select, pos = (1, 1), span = (1, 3), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
2109 
2110  sizerM.Add(self.mapSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
2111  gridBagSizer.Add(sizerM, pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
2112 
2113 
2114  #map scale and center
2115  boxC = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Map scale and center"))
2116  sizerC = wx.StaticBoxSizer(boxC, wx.HORIZONTAL)
2117  self.centerSizer = wx.FlexGridSizer(rows = 2, cols = 5, hgap = 5, vgap = 5)
2118 
2119 
2120  centerText = wx.StaticText(self, id = wx.ID_ANY, label = _("Center:"))
2121  self.eastingText = wx.StaticText(self, id = wx.ID_ANY, label = _("E:"))
2122  self.northingText = wx.StaticText(self, id = wx.ID_ANY, label = _("N:"))
2123  self.eastingTextCtrl = wx.TextCtrl(self, id = wx.ID_ANY, style = wx.TE_RIGHT, validator = TCValidator(flag = 'DIGIT_ONLY'))
2124  self.northingTextCtrl = wx.TextCtrl(self, id = wx.ID_ANY, style = wx.TE_RIGHT, validator = TCValidator(flag = 'DIGIT_ONLY'))
2125  scaleText = wx.StaticText(self, id = wx.ID_ANY, label = _("Scale:"))
2126  scalePrefixText = wx.StaticText(self, id = wx.ID_ANY, label = _("1 :"))
2127  self.scaleTextCtrl = wx.TextCtrl(self, id = wx.ID_ANY, value = "", style = wx.TE_RIGHT, validator = TCValidator('DIGIT_ONLY'))
2128 
2129  self.centerSizer.Add(centerText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, border = 10)
2130  self.centerSizer.Add(self.eastingText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
2131  self.centerSizer.Add(self.eastingTextCtrl, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
2132  self.centerSizer.Add(self.northingText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
2133  self.centerSizer.Add(self.northingTextCtrl, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
2134 
2135  self.centerSizer.Add(scaleText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, border = 10)
2136  self.centerSizer.Add(scalePrefixText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
2137  self.centerSizer.Add(self.scaleTextCtrl, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
2138 
2139  sizerC.Add(self.centerSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
2140  gridBagSizer.Add(sizerC, pos = (3, 0), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
2141 
2142 
2143  #resolution
2144  flexSizer = wx.FlexGridSizer(rows = 1, cols = 2, hgap = 5, vgap = 5)
2145 
2146  resolutionText = wx.StaticText(self, id = wx.ID_ANY, label = _("Map max resolution (dpi):"))
2147  self.resolutionSpin = wx.SpinCtrl(self, id = wx.ID_ANY, min = 1, max = 1000, initial = 300)
2148 
2149  flexSizer.Add(resolutionText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
2150  flexSizer.Add(self.resolutionSpin, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
2151  self.resolutionSpin.SetValue(self.mapFrameDict['resolution'])
2152 
2153  gridBagSizer.Add(flexSizer, pos = (4, 0), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
2154 
2155  sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
2156  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
2157 
2158  # border
2159  box = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Border"))
2160  sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
2161  gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
2162 
2163  self.borderCheck = wx.CheckBox(self, id = wx.ID_ANY, label = (_("draw border around map frame")))
2164  if self.mapFrameDict['border'] == 'y':
2165  self.borderCheck.SetValue(True)
2166  else:
2167  self.borderCheck.SetValue(False)
2168 
2169  self.borderColorText = wx.StaticText(self, id = wx.ID_ANY, label = _("border color:"))
2170  self.borderWidthText = wx.StaticText(self, id = wx.ID_ANY, label = _("border width (pts):"))
2171  self.borderColourPicker = wx.ColourPickerCtrl(self, id = wx.ID_ANY)
2172  self.borderWidthCtrl = wx.SpinCtrl(self, id = wx.ID_ANY, min = 1, max = 100, initial = 1)
2173 
2174  if self.mapFrameDict['border'] == 'y':
2175  self.borderWidthCtrl.SetValue(int(self.mapFrameDict['width']))
2176  self.borderColourPicker.SetColour(convertRGB(self.mapFrameDict['color']))
2177 
2178 
2179  gridBagSizer.Add(self.borderCheck, pos = (0, 0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
2180  gridBagSizer.Add(self.borderColorText, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
2181  gridBagSizer.Add(self.borderWidthText, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
2182  gridBagSizer.Add(self.borderColourPicker, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
2183  gridBagSizer.Add(self.borderWidthCtrl, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
2184 
2185  sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
2186  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
2187 
2188  self.SetSizer(border)
2189  self.Fit()
2190 
2191 
2192  if projInfo()['proj'] == 'll':
2193  self.scaleChoice.SetItems(self.scaleChoice.GetItems()[0:3])
2194  boxC.Hide()
2195  for each in self.centerSizer.GetChildren():
2196  each.GetWindow().Hide()
2197 
2198 
2199  # bindings
2200  self.scaleChoice.Bind(wx.EVT_CHOICE, self.OnScaleChoice)
2201  self.select.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnMap)
2202  self.Bind(wx.EVT_RADIOBUTTON, self.OnElementType, self.vectorTypeRadio)
2203  self.Bind(wx.EVT_RADIOBUTTON, self.OnElementType, self.rasterTypeRadio)
2204  self.Bind(wx.EVT_CHECKBOX, self.OnBorder, self.borderCheck)
2205 
2206 
2207 
2208  def OnMap(self, event):
2209  """!Selected map or region changing"""
2210 
2211  if self.select.GetValue():
2212  self.selected = self.select.GetValue()
2213  else:
2214  self.selected = None
2215 
2216  if self.scaleChoice.GetSelection() == 0:
2217  self.selectedMap = self.selected
2218  if self.rasterTypeRadio.GetValue():
2219  mapType = 'raster'
2220  else:
2221  mapType = 'vector'
2222 
2223  self.scale[0], self.center[0], foo = AutoAdjust(self, scaleType = 0, map = self.selected,
2224  mapType = mapType, rect = self.mapFrameDict['rect'])
2225  #self.center[0] = self.RegionCenter(self.RegionDict(scaleType = 0))
2226 
2227  elif self.scaleChoice.GetSelection() == 1:
2228  self.selectedRegion = self.selected
2229  self.scale[1], self.center[1], foo = AutoAdjust(self, scaleType = 1, region = self.selected, rect = self.mapFrameDict['rect'])
2230  #self.center[1] = self.RegionCenter(self.RegionDict(scaleType = 1))
2231  elif self.scaleChoice.GetSelection() == 2:
2232  self.scale[2], self.center[2], foo = AutoAdjust(self, scaleType = 2, rect = self.mapFrameDict['rect'])
2233  #self.center[2] = self.RegionCenter(self.RegionDict(scaleType = 2))
2234 
2235  else:
2236  self.scale[3] = None
2237  self.center[3] = None
2238 
2239  self.OnScaleChoice(None)
2240 
2241 
2242  def OnScaleChoice(self, event):
2243  """!Selected scale type changing"""
2244 
2245  scaleType = self.scaleChoice.GetSelection()
2246  if self.scaleType != scaleType:
2247  self.scaleType = scaleType
2248  self.select.SetValue("")
2249 
2250  if scaleType in (0, 1): # automatic - region from raster map, saved region
2251  if scaleType == 0:
2252  # set map selection
2253  self.rasterTypeRadio.Show()
2254  self.vectorTypeRadio.Show()
2255  self.drawMap.Show()
2256  self.staticBox.SetLabel(" %s " % _("Map selection"))
2257  if self.rasterTypeRadio.GetValue():
2258  stype = 'raster'
2259  else:
2260  stype = 'vector'
2261 
2262  self.select.SetElementList(type = stype)
2263  self.mapText.SetLabel(self.mapOrRegionText[0])
2264  self.select.SetToolTipString(_("Region is set to match this map,\nraster or vector map must be added later"))
2265 
2266  if scaleType == 1:
2267  # set region selection
2268  self.rasterTypeRadio.Hide()
2269  self.vectorTypeRadio.Hide()
2270  self.drawMap.Hide()
2271  self.staticBox.SetLabel(" %s " % _("Region selection"))
2272  stype = 'region'
2273  self.select.SetElementList(type = stype)
2274  self.mapText.SetLabel(self.mapOrRegionText[1])
2275  self.select.SetToolTipString("")
2276 
2277  for each in self.mapSizer.GetChildren():
2278  each.GetWindow().Enable()
2279  for each in self.centerSizer.GetChildren():
2280  each.GetWindow().Disable()
2281 
2282  if self.scale[scaleType]:
2283 
2284  self.scaleTextCtrl.SetValue("%.0f" % (1/self.scale[scaleType]))
2285  if self.center[scaleType]:
2286  self.eastingTextCtrl.SetValue(str(self.center[scaleType][0]))
2287  self.northingTextCtrl.SetValue(str(self.center[scaleType][1]))
2288  elif scaleType == 2:
2289  for each in self.mapSizer.GetChildren():
2290  each.GetWindow().Disable()
2291  for each in self.centerSizer.GetChildren():
2292  each.GetWindow().Disable()
2293 
2294  if self.scale[scaleType]:
2295  self.scaleTextCtrl.SetValue("%.0f" % (1/self.scale[scaleType]))
2296  if self.center[scaleType]:
2297  self.eastingTextCtrl.SetValue(str(self.center[scaleType][0]))
2298  self.northingTextCtrl.SetValue(str(self.center[scaleType][1]))
2299  else: # fixed
2300  for each in self.mapSizer.GetChildren():
2301  each.GetWindow().Disable()
2302  for each in self.centerSizer.GetChildren():
2303  each.GetWindow().Enable()
2304 
2305  if self.scale[scaleType]:
2306  self.scaleTextCtrl.SetValue("%.0f" % (1/self.scale[scaleType]))
2307  if self.center[scaleType]:
2308  self.eastingTextCtrl.SetValue(str(self.center[scaleType][0]))
2309  self.northingTextCtrl.SetValue(str(self.center[scaleType][1]))
2310 
2311  def OnElementType(self, event):
2312  """!Changes data in map selection tree ctrl popup"""
2313  if self.rasterTypeRadio.GetValue():
2314  mapType = 'raster'
2315  else:
2316  mapType = 'vector'
2317  self.select.SetElementList(type = mapType)
2318  if self.mapType != mapType and event is not None:
2319  self.mapType = mapType
2320  self.select.SetValue('')
2321  self.mapType = mapType
2322 
2323  def OnBorder(self, event):
2324  """!Enables/disable the part relating to border of map frame"""
2325  for each in (self.borderColorText, self.borderWidthText, self.borderColourPicker, self.borderWidthCtrl):
2326  each.Enable(self.borderCheck.GetValue())
2327 
2328  def getId(self):
2329  """!Returns id of raster map"""
2330  return self.id
2331 
2332  def update(self):
2333  """!Save changes"""
2334  mapFrameDict = dict(self.mapFrameDict)
2335  # resolution
2336  mapFrameDict['resolution'] = self.resolutionSpin.GetValue()
2337  #scale
2338  scaleType = self.scaleType
2339  mapFrameDict['scaleType'] = scaleType
2340 
2341  if mapFrameDict['scaleType'] == 0:
2342  if self.select.GetValue():
2343  mapFrameDict['drawMap'] = self.drawMap.GetValue()
2344  mapFrameDict['map'] = self.select.GetValue()
2345  mapFrameDict['mapType'] = self.mapType
2346  mapFrameDict['region'] = None
2347 
2348  if mapFrameDict['drawMap']:
2349 
2350  if mapFrameDict['mapType'] == 'raster':
2351  mapFile = grass.find_file(mapFrameDict['map'], element = 'cell')
2352  if mapFile['file'] == '':
2353  GMessage("Raster %s not found" % mapFrameDict['map'])
2354  return False
2355  raster = self.instruction.FindInstructionByType('raster')
2356  if raster:
2357  raster['raster'] = mapFrameDict['map']
2358  else:
2359  raster = Raster(wx.NewId())
2360  raster['raster'] = mapFrameDict['map']
2361  raster['isRaster'] = True
2362  self.instruction.AddInstruction(raster)
2363 
2364  elif mapFrameDict['mapType'] == 'vector':
2365 
2366  mapFile = grass.find_file(mapFrameDict['map'], element = 'vector')
2367  if mapFile['file'] == '':
2368  GMessage("Vector %s not found" % mapFrameDict['map'])
2369  return False
2370 
2371  vector = self.instruction.FindInstructionByType('vector')
2372  isAdded = False
2373  if vector:
2374  for each in vector['list']:
2375  if each[0] == mapFrameDict['map']:
2376  isAdded = True
2377  if not isAdded:
2378  topoInfo = grass.vector_info_topo(map = mapFrameDict['map'])
2379  if topoInfo:
2380  if bool(topoInfo['areas']):
2381  topoType = 'areas'
2382  elif bool(topoInfo['lines']):
2383  topoType = 'lines'
2384  else:
2385  topoType = 'points'
2386  label = '('.join(mapFrameDict['map'].split('@')) + ')'
2387 
2388  if not vector:
2389  vector = Vector(wx.NewId())
2390  vector['list'] = []
2391  self.instruction.AddInstruction(vector)
2392  id = wx.NewId()
2393  vector['list'].insert(0, [mapFrameDict['map'], topoType, id, 1, label])
2394  vProp = VProperties(id, topoType)
2395  vProp['name'], vProp['label'], vProp['lpos'] = mapFrameDict['map'], label, 1
2396  self.instruction.AddInstruction(vProp)
2397  else:
2398  return False
2399 
2400  self.scale[0], self.center[0], self.rectAdjusted = AutoAdjust(self, scaleType = 0, map = mapFrameDict['map'],
2401  mapType = self.mapType, rect = self.mapFrameDict['rect'])
2402 
2403  if self.rectAdjusted:
2404  mapFrameDict['rect'] = self.rectAdjusted
2405  else:
2406  mapFrameDict['rect'] = self.mapFrameDict['rect']
2407 
2408  mapFrameDict['scale'] = self.scale[0]
2409 
2410  mapFrameDict['center'] = self.center[0]
2411  # set region
2412  if self.mapType == 'raster':
2413  RunCommand('g.region', rast = mapFrameDict['map'])
2414  if self.mapType == 'vector':
2415  raster = self.instruction.FindInstructionByType('raster')
2416  if raster:
2417  rasterId = raster.id
2418  else:
2419  rasterId = None
2420 
2421  if rasterId:
2422 
2423  RunCommand('g.region', vect = mapFrameDict['map'], rast = self.instruction[rasterId]['raster'])
2424  else:
2425  RunCommand('g.region', vect = mapFrameDict['map'])
2426 
2427 
2428 
2429  else:
2430  wx.MessageBox(message = _("No map selected!"),
2431  caption = _('Invalid input'), style = wx.OK|wx.ICON_ERROR)
2432  return False
2433 
2434  elif mapFrameDict['scaleType'] == 1:
2435  if self.select.GetValue():
2436  mapFrameDict['drawMap'] = False
2437  mapFrameDict['map'] = None
2438  mapFrameDict['mapType'] = None
2439  mapFrameDict['region'] = self.select.GetValue()
2440  self.scale[1], self.center[1], self.rectAdjusted = AutoAdjust(self, scaleType = 1, region = mapFrameDict['region'],
2441  rect = self.mapFrameDict['rect'])
2442  if self.rectAdjusted:
2443  mapFrameDict['rect'] = self.rectAdjusted
2444  else:
2445  mapFrameDict['rect'] = self.mapFrameDict['rect']
2446 
2447  mapFrameDict['scale'] = self.scale[1]
2448  mapFrameDict['center'] = self.center[1]
2449  # set region
2450  RunCommand('g.region', region = mapFrameDict['region'])
2451  else:
2452  wx.MessageBox(message = _("No region selected!"),
2453  caption = _('Invalid input'), style = wx.OK|wx.ICON_ERROR)
2454  return False
2455 
2456  elif scaleType == 2:
2457  mapFrameDict['drawMap'] = False
2458  mapFrameDict['map'] = None
2459  mapFrameDict['mapType'] = None
2460  mapFrameDict['region'] = None
2461  self.scale[2], self.center[2], self.rectAdjusted = AutoAdjust(self, scaleType = 2, rect = self.mapFrameDict['rect'])
2462  if self.rectAdjusted:
2463  mapFrameDict['rect'] = self.rectAdjusted
2464  else:
2465  mapFrameDict['rect'] = self.mapFrameDict['rect']
2466 
2467  mapFrameDict['scale'] = self.scale[2]
2468  mapFrameDict['center'] = self.center[2]
2469 
2470  env = grass.gisenv()
2471  windFilePath = os.path.join(env['GISDBASE'], env['LOCATION_NAME'], env['MAPSET'], 'WIND')
2472  try:
2473  windFile = open(windFilePath, 'r').read()
2474  region = grass.parse_key_val(windFile, sep = ':', val_type = float)
2475  except IOError:
2476  region = grass.region()
2477 
2478  raster = self.instruction.FindInstructionByType('raster')
2479  if raster:
2480  rasterId = raster.id
2481  else:
2482  rasterId = None
2483 
2484  if rasterId: # because of resolution
2485  RunCommand('g.region', n = region['north'], s = region['south'],
2486  e = region['east'], w = region['west'], rast = self.instruction[rasterId]['raster'])
2487  else:
2488  RunCommand('g.region', n = region['north'], s = region['south'],
2489  e = region['east'], w = region['west'])
2490 
2491  elif scaleType == 3:
2492  mapFrameDict['drawMap'] = False
2493  mapFrameDict['map'] = None
2494  mapFrameDict['mapType'] = None
2495  mapFrameDict['region'] = None
2496  mapFrameDict['rect'] = self.mapFrameDict['rect']
2497  try:
2498  scaleNumber = float(self.scaleTextCtrl.GetValue())
2499  centerE = float(self.eastingTextCtrl.GetValue())
2500  centerN = float(self.northingTextCtrl.GetValue())
2501  except (ValueError, SyntaxError):
2502  wx.MessageBox(message = _("Invalid scale or map center!"),
2503  caption = _('Invalid input'), style = wx.OK|wx.ICON_ERROR)
2504  return False
2505  mapFrameDict['scale'] = 1/scaleNumber
2506  mapFrameDict['center'] = centerE, centerN
2507 
2508  ComputeSetRegion(self, mapDict = mapFrameDict)
2509 
2510  # check resolution
2511  SetResolution(dpi = mapFrameDict['resolution'], width = mapFrameDict['rect'].width,
2512  height = mapFrameDict['rect'].height)
2513  # border
2514  if self.borderCheck.GetValue():
2515  mapFrameDict['border'] = 'y'
2516  else:
2517  mapFrameDict['border'] = 'n'
2518 
2519  if mapFrameDict['border'] == 'y':
2520  mapFrameDict['width'] = self.borderWidthCtrl.GetValue()
2521  mapFrameDict['color'] = convertRGB(self.borderColourPicker.GetColour())
2522 
2523  if self.id not in self.instruction:
2524  mapFrame = MapFrame(self.id)
2525  self.instruction.AddInstruction(mapFrame)
2526  self.instruction[self.id].SetInstruction(mapFrameDict)
2527 
2528  if self.id not in self.mapDialog.parent.objectId:
2529  self.mapDialog.parent.objectId.insert(0, self.id)# map frame is drawn first
2530  return True
2531 
2532 class RasterPanel(wx.Panel):
2533  """!Panel for raster map settings"""
2534  def __init__(self, parent, id, settings, notebook = True):
2535  wx.Panel.__init__(self, parent, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
2536  self.instruction = settings
2537 
2538  if notebook:
2539  self.book = parent
2540  self.book.AddPage(page = self, text = _("Raster map"))
2541  self.mainDialog = self.book.GetParent()
2542  else:
2543  self.mainDialog = parent
2544  if id:
2545  self.id = id
2546  self.rasterDict = self.instruction[self.id].GetInstruction()
2547  else:
2548  self.id = wx.NewId()
2549  raster = Raster(self.id)
2550  self.rasterDict = raster.GetInstruction()
2551 
2552 
2553  self._layout()
2554  self.OnRaster(None)
2555 
2556  def _layout(self):
2557  """!Do layout"""
2558  border = wx.BoxSizer(wx.VERTICAL)
2559 
2560  # choose raster map
2561 
2562  box = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Choose raster map"))
2563  sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
2564  gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
2565 
2566  self.rasterNoRadio = wx.RadioButton(self, id = wx.ID_ANY, label = _("no raster map"), style = wx.RB_GROUP)
2567  self.rasterYesRadio = wx.RadioButton(self, id = wx.ID_ANY, label = _("raster:"))
2568 
2569  self.rasterSelect = Select(self, id = wx.ID_ANY, size = globalvar.DIALOG_GSELECT_SIZE,
2570  type = 'raster', multiple = False,
2571  updateOnPopup = True, onPopup = None)
2572  if self.rasterDict['isRaster']:
2573  self.rasterYesRadio.SetValue(True)
2574  self.rasterNoRadio.SetValue(False)
2575  self.rasterSelect.SetValue(self.rasterDict['raster'])
2576  else:
2577  self.rasterYesRadio.SetValue(False)
2578  self.rasterNoRadio.SetValue(True)
2579  mapId = self.instruction.FindInstructionByType('map').id
2580 
2581  if self.instruction[mapId]['map'] and self.instruction[mapId]['mapType'] == 'raster':
2582  self.rasterSelect.SetValue(self.instruction[mapId]['map'])# raster map from map frame dialog if possible
2583  else:
2584  self.rasterSelect.SetValue('')
2585  gridBagSizer.Add(self.rasterNoRadio, pos = (0, 0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
2586  gridBagSizer.Add(self.rasterYesRadio, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
2587  gridBagSizer.Add(self.rasterSelect, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
2588 
2589  sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
2590  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
2591 
2592  #self.rasterSelect.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnRaster)
2593  self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterNoRadio)
2594  self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterYesRadio)
2595 
2596  self.SetSizer(border)
2597  self.Fit()
2598 
2599  def OnRaster(self, event):
2600  """!Enable/disable raster selection"""
2601  self.rasterSelect.Enable(self.rasterYesRadio.GetValue())
2602 
2603  def update(self):
2604  #draw raster
2605  map = self.instruction.FindInstructionByType('map')
2606  if self.rasterNoRadio.GetValue() or not self.rasterSelect.GetValue():
2607  self.rasterDict['isRaster'] = False
2608  self.rasterDict['raster'] = None
2609  map['drawMap'] = False
2610  if self.id in self.instruction:
2611  del self.instruction[self.id]
2612 
2613  else:
2614  self.rasterDict['isRaster'] = True
2615  self.rasterDict['raster'] = self.rasterSelect.GetValue()
2616  if self.rasterDict['raster'] != map['drawMap']:
2617  map['drawMap'] = False
2618 
2619  if self.id not in self.instruction:
2620  raster = Raster(self.id)
2621  self.instruction.AddInstruction(raster)
2622  self.instruction[self.id].SetInstruction(self.rasterDict)
2623 
2624  if 'map' in self.mainDialog.parent.openDialogs:
2625  self.mainDialog.parent.openDialogs['map'].updateDialog()
2626  return True
2627 
2628  def getId(self):
2629  return self.id
2630 
2631 class VectorPanel(wx.Panel):
2632  """!Panel for vector maps settings"""
2633  def __init__(self, parent, id, settings, notebook = True):
2634  wx.Panel.__init__(self, parent, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
2635 
2636  self.parent = parent
2637  self.instruction = settings
2638  self.tmpDialogDict = {}
2639  vectors = self.instruction.FindInstructionByType('vProperties', list = True)
2640  for vector in vectors:
2641  self.tmpDialogDict[vector.id] = dict(self.instruction[vector.id].GetInstruction())
2642 
2643  if id:
2644  self.id = id
2645  self.vectorList = deepcopy(self.instruction[id]['list'])
2646  else:
2647  self.id = wx.NewId()
2648  self.vectorList = []
2649 
2650  vLegend = self.instruction.FindInstructionByType('vectorLegend')
2651  if vLegend:
2652  self.vLegendId = vLegend.id
2653  else:
2654  self.vLegendId = None
2655 
2656 
2657  self._layout()
2658 
2659  if notebook:
2660  self.parent.AddPage(page = self, text = _("Vector maps"))
2661  self.parent = self.parent.GetParent()
2662 
2663  def _layout(self):
2664  """!Do layout"""
2665  border = wx.BoxSizer(wx.VERTICAL)
2666 
2667  # choose vector map
2668 
2669  box = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Add map"))
2670  sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
2671  gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
2672 
2673  text = wx.StaticText(self, id = wx.ID_ANY, label = _("Map:"))
2674  self.select = Select(self, id = wx.ID_ANY,# size = globalvar.DIALOG_GSELECT_SIZE,
2675  type = 'vector', multiple = False,
2676  updateOnPopup = True, onPopup = None)
2677  topologyTypeTr = [_("points"), _("lines"), _("areas")]
2678  self.topologyTypeList = ["points", "lines", "areas"]
2679  self.vectorType = wx.RadioBox(self, id = wx.ID_ANY, label = " %s " % _("Data Type"), choices = topologyTypeTr,
2680  majorDimension = 3, style = wx.RA_SPECIFY_COLS)
2681 
2682  self.AddVector = wx.Button(self, id = wx.ID_ANY, label = _("Add"))
2683 
2684  gridBagSizer.Add(text, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
2685  gridBagSizer.Add(self.select, pos = (0,1), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
2686  gridBagSizer.Add(self.vectorType, pos = (1,1), flag = wx.ALIGN_CENTER, border = 0)
2687  gridBagSizer.Add(self.AddVector, pos = (1,2), flag = wx.ALIGN_BOTTOM|wx.ALIGN_RIGHT, border = 0)
2688 
2689  sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
2690  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
2691 
2692  # manage vector layers
2693 
2694  box = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Manage vector maps"))
2695  sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
2696  gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
2697  gridBagSizer.AddGrowableCol(0,2)
2698  gridBagSizer.AddGrowableCol(1,1)
2699 
2700 
2701 
2702  text = wx.StaticText(self, id = wx.ID_ANY, label = _("The topmost vector map overlaps the others"))
2703  self.listbox = wx.ListBox(self, id = wx.ID_ANY, choices = [], style = wx.LB_SINGLE|wx.LB_NEEDED_SB)
2704  self.btnUp = wx.Button(self, id = wx.ID_ANY, label = _("Up"))
2705  self.btnDown = wx.Button(self, id = wx.ID_ANY, label = _("Down"))
2706  self.btnDel = wx.Button(self, id = wx.ID_ANY, label = _("Delete"))
2707  self.btnProp = wx.Button(self, id = wx.ID_ANY, label = _("Properties..."))
2708 
2709  self.updateListBox(selected=0)
2710 
2711 
2712  gridBagSizer.Add(text, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
2713  gridBagSizer.Add(self.listbox, pos = (1,0), span = (4, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
2714  gridBagSizer.Add(self.btnUp, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
2715  gridBagSizer.Add(self.btnDown, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
2716  gridBagSizer.Add(self.btnDel, pos = (3,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
2717  gridBagSizer.Add(self.btnProp, pos = (4,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
2718 
2719  sizer.Add(gridBagSizer, proportion = 0, flag = wx.ALL, border = 5)
2720  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
2721 
2722  self.Bind(wx.EVT_BUTTON, self.OnAddVector, self.AddVector)
2723  self.Bind(wx.EVT_BUTTON, self.OnDelete, self.btnDel)
2724  self.Bind(wx.EVT_BUTTON, self.OnUp, self.btnUp)
2725  self.Bind(wx.EVT_BUTTON, self.OnDown, self.btnDown)
2726  self.Bind(wx.EVT_BUTTON, self.OnProperties, self.btnProp)
2727  self.select.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnVector)
2728 
2729  self.SetSizer(border)
2730  self.Fit()
2731 
2732  self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnProperties, self.listbox)
2733 
2734  def OnVector(self, event):
2735  """!Gets info about toplogy and enables/disables choices point/line/area"""
2736  vmap = self.select.GetValue()
2737  try:
2738  topoInfo = grass.vector_info_topo(map = vmap)
2739  except grass.ScriptError:
2740  return
2741 
2742  if topoInfo:
2743  self.vectorType.EnableItem(2, bool(topoInfo['areas']))
2744  self.vectorType.EnableItem(1, bool(topoInfo['boundaries']) or bool(topoInfo['lines']))
2745  self.vectorType.EnableItem(0, bool(topoInfo['centroids'] or bool(topoInfo['points']) ))
2746  for item in range(2,-1,-1):
2747  if self.vectorType.IsItemEnabled(item):
2748  self.vectorType.SetSelection(item)
2749  break
2750 
2751  self.AddVector.SetFocus()
2752 
2753  def OnAddVector(self, event):
2754  """!Adds vector map to list"""
2755  vmap = self.select.GetValue()
2756  if vmap:
2757  mapname = vmap.split('@')[0]
2758  try:
2759  mapset = '(' + vmap.split('@')[1] + ')'
2760  except IndexError:
2761  mapset = ''
2762  idx = self.vectorType.GetSelection()
2763  ttype = self.topologyTypeList[idx]
2764  record = "%s - %s" % (vmap, ttype)
2765  id = wx.NewId()
2766  lpos = 1
2767  label = mapname + mapset
2768  self.vectorList.insert(0, [vmap, ttype, id, lpos, label])
2769  self.reposition()
2770  self.listbox.InsertItems([record], 0)
2771 
2772  vector = VProperties(id, ttype)
2773  self.tmpDialogDict[id] = vector.GetInstruction()
2774  self.tmpDialogDict[id]['name'] = vmap
2775 
2776 
2777  self.listbox.SetSelection(0)
2778  self.listbox.EnsureVisible(0)
2779  self.btnProp.SetFocus()
2780  self.enableButtons()
2781 
2782  def OnDelete(self, event):
2783  """!Deletes vector map from the list"""
2784  if self.listbox.GetSelections():
2785  pos = self.listbox.GetSelection()
2786  id = self.vectorList[pos][2]
2787  del self.vectorList[pos]
2788  del self.tmpDialogDict[id]
2789 
2790  for i in range(pos, len(self.vectorList)):
2791  if self.vectorList[i][3]:# can be 0
2792  self.vectorList[i][3] -= 1
2793 
2794  if pos < len(self.vectorList) -1:
2795  selected = pos
2796  else:
2797  selected = len(self.vectorList) -1
2798  self.updateListBox(selected = selected)
2799  if self.listbox.IsEmpty():
2800  self.enableButtons(False)
2801 
2802 
2803  def OnUp(self, event):
2804  """!Moves selected map to top"""
2805  if self.listbox.GetSelections():
2806  pos = self.listbox.GetSelection()
2807  if pos:
2808  self.vectorList.insert(pos - 1, self.vectorList.pop(pos))
2809  if not self.vLegendId:
2810  self.reposition()
2811 
2812  if pos > 0:
2813  self.updateListBox(selected = (pos - 1))
2814  else:
2815  self.updateListBox(selected = 0)
2816 
2817 
2818  def OnDown(self, event):
2819  """!Moves selected map to bottom"""
2820  if self.listbox.GetSelections():
2821  pos = self.listbox.GetSelection()
2822  if pos != len(self.vectorList) - 1:
2823  self.vectorList.insert(pos + 1, self.vectorList.pop(pos))
2824  if not self.vLegendId:
2825  self.reposition()
2826  if pos < len(self.vectorList) -1:
2827  self.updateListBox(selected = (pos + 1))
2828  else:
2829  self.updateListBox(selected = len(self.vectorList) -1)
2830 
2831 
2832  def OnProperties(self, event):
2833  """!Opens vector map properties dialog"""
2834  if self.listbox.GetSelections():
2835  pos = self.listbox.GetSelection()
2836  id = self.vectorList[pos][2]
2837 
2838  dlg = VPropertiesDialog(self, id = id, settings = self.instruction,
2839  vectors = self.vectorList, tmpSettings = self.tmpDialogDict[id])
2840  dlg.ShowModal()
2841 
2842  self.parent.FindWindowById(wx.ID_OK).SetFocus()
2843 
2844  def enableButtons(self, enable = True):
2845  """!Enable/disable up, down, properties, delete buttons"""
2846  self.btnUp.Enable(enable)
2847  self.btnDown.Enable(enable)
2848  self.btnProp.Enable(enable)
2849  self.btnDel.Enable(enable)
2850 
2851  def updateListBox(self, selected = None):
2852  mapList = ["%s - %s" % (item[0], item[1]) for item in self.vectorList]
2853  self.listbox.Set(mapList)
2854  if self.listbox.IsEmpty():
2855  self.enableButtons(False)
2856  else:
2857  self.enableButtons(True)
2858  if selected is not None:
2859  self.listbox.SetSelection(selected)
2860  self.listbox.EnsureVisible(selected)
2861 
2862  def reposition(self):
2863  """!Update position in legend, used only if there is no vlegend yet"""
2864  for i in range(len(self.vectorList)):
2865  if self.vectorList[i][3]:
2866  self.vectorList[i][3] = i + 1
2867 
2868  def getId(self):
2869  return self.id
2870 
2871  def update(self):
2872  vectors = self.instruction.FindInstructionByType('vProperties', list = True)
2873 
2874  for vector in vectors:
2875  del self.instruction[vector.id]
2876  if self.id in self.instruction:
2877  del self.instruction[self.id]
2878 
2879  if len(self.vectorList) > 0:
2880  vector = Vector(self.id)
2881  self.instruction.AddInstruction(vector)
2882 
2883  vector.SetInstruction({'list': deepcopy(self.vectorList)})
2884 
2885  # save new vectors
2886  for item in self.vectorList:
2887  id = item[2]
2888 
2889  vLayer = VProperties(id, item[1])
2890  self.instruction.AddInstruction(vLayer)
2891  vLayer.SetInstruction(self.tmpDialogDict[id])
2892  vLayer['name'] = item[0]
2893  vLayer['label'] = item[4]
2894  vLayer['lpos'] = item[3]
2895 
2896  else:
2897  if self.id in self.instruction:
2898  del self.instruction[self.id]
2899 
2900  if 'map' in self.parent.parent.openDialogs:
2901  self.parent.parent.openDialogs['map'].updateDialog()
2902 
2903  return True
2904 
2906  def __init__(self, parent, id, settings):
2907  PsmapDialog.__init__(self, parent = parent, id = id, title = _("Raster map settings"), settings = settings)
2908  self.objectType = ('raster',)
2909 
2910  self.rPanel = RasterPanel(parent = self, id = self.id, settings = self.instruction, notebook = False)
2911 
2912  self.id = self.rPanel.getId()
2913  self._layout(self.rPanel)
2914 
2915  def update(self):
2916  ok = self.rPanel.update()
2917  if ok:
2918  return True
2919  return False
2920 
2921  def OnApply(self, event):
2922  ok = self.update()
2923  if not ok:
2924  return False
2925 
2926  if self.id in self.instruction:
2927  self.parent.DialogDataChanged(id = self.id)
2928  else:
2929  mapId = self.instruction.FindInstructionByType('map').id
2930  self.parent.DialogDataChanged(id = mapId)
2931  return True
2932 
2933  def updateDialog(self):
2934  """!Update information (not used)"""
2935  pass
2936 ## if 'map' in self.parent.openDialogs:
2937 ## if self.parent.openDialogs['map'].mPanel.rasterTypeRadio.GetValue()\
2938 ## and self.parent.openDialogs['map'].mPanel.select.GetValue():
2939 ## if self.parent.openDialogs['map'].mPanel.drawMap.IsChecked():
2940 ## self.rPanel.rasterSelect.SetValue(self.parent.openDialogs['map'].mPanel.select.GetValue())
2941 
2942 class MainVectorDialog(PsmapDialog):
2943  def __init__(self, parent, id, settings):
2944  PsmapDialog.__init__(self, parent = parent, id = id, title = _("Vector maps settings"), settings = settings)
2945  self.objectType = ('vector',)
2946  self.vPanel = VectorPanel(parent = self, id = self.id, settings = self.instruction, notebook = False)
2947 
2948  self.id = self.vPanel.getId()
2949  self._layout(self.vPanel)
2950 
2951  def update(self):
2952  self.vPanel.update()
2953 
2954  def OnApply(self, event):
2955  self.update()
2956  if self.id in self.instruction:
2957  self.parent.DialogDataChanged(id = self.id)
2958  else:
2959  mapId = self.instruction.FindInstructionByType('map').id
2960  self.parent.DialogDataChanged(id = mapId)
2961  return True
2962 
2963  def updateDialog(self):
2964  """!Update information (not used)"""
2965  pass
2966 
2967 class VPropertiesDialog(PsmapDialog):
2968  def __init__(self, parent, id, settings, vectors, tmpSettings):
2969  PsmapDialog.__init__(self, parent = parent, id = id, title = "", settings = settings, apply = False)
2970 
2971  vectorList = vectors
2972  self.vPropertiesDict = tmpSettings
2973 
2974  # determine map and its type
2975  for item in vectorList:
2976  if id == item[2]:
2977  self.vectorName = item[0]
2978  self.type = item[1]
2979  self.SetTitle(_("%s properties") % self.vectorName)
2980 
2981  #vector map info
2982  self.connection = True
2983  try:
2985  self.layers = self.mapDBInfo.layers.keys()
2986  except grass.ScriptError:
2987  self.connection = False
2988  self.layers = []
2989  if not self.layers:
2990  self.connection = False
2991  self.layers = []
2992 
2993  self.currLayer = self.vPropertiesDict['layer']
2994 
2995  #path to symbols, patterns
2996  gisbase = os.getenv("GISBASE")
2997  self.symbolPath = os.path.join(gisbase, 'etc', 'symbol')
2998  self.symbols = []
2999  for dir in os.listdir(self.symbolPath):
3000  for symbol in os.listdir(os.path.join(self.symbolPath, dir)):
3001  self.symbols.append(os.path.join(dir, symbol))
3002  self.patternPath = os.path.join(gisbase, 'etc', 'paint', 'patterns')
3003 
3004  #notebook
3005  notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT)
3006  self.DSpanel = self._DataSelectionPanel(notebook)
3007  self.EnableLayerSelection(enable = self.connection)
3008  selectPanel = { 'points': [self._ColorsPointAreaPanel, self._StylePointPanel],
3009  'lines': [self._ColorsLinePanel, self._StyleLinePanel],
3010  'areas': [self._ColorsPointAreaPanel, self._StyleAreaPanel]}
3011  self.ColorsPanel = selectPanel[self.type][0](notebook)
3012 
3013  self.OnOutline(None)
3014  if self.type in ('points', 'areas'):
3015  self.OnFill(None)
3016  self.OnColor(None)
3017 
3018  self.StylePanel = selectPanel[self.type][1](notebook)
3019  if self.type == 'points':
3020  self.OnSize(None)
3021  self.OnRotation(None)
3022  if self.type == 'areas':
3023  self.OnPattern(None)
3024 
3025  self._layout(notebook)
3026 
3027  def _DataSelectionPanel(self, notebook):
3028  panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
3029  notebook.AddPage(page = panel, text = _("Data selection"))
3030 
3031  border = wx.BoxSizer(wx.VERTICAL)
3032 
3033  # data type
3034  self.checkType1 = self.checkType2 = None
3035  if self.type in ('lines', 'points'):
3036  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Feature type"))
3037  sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
3038  gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
3039  if self.type == 'points':
3040  label = (_("points"), _("centroids"))
3041  else:
3042  label = (_("lines"), _("boundaries"))
3043  if self.type == 'points':
3044  name = ("point", "centroid")
3045  else:
3046  name = ("line", "boundary")
3047  self.checkType1 = wx.CheckBox(panel, id = wx.ID_ANY, label = label[0], name = name[0])
3048  self.checkType2 = wx.CheckBox(panel, id = wx.ID_ANY, label = label[1], name = name[1])
3049  self.checkType1.SetValue(self.vPropertiesDict['type'].find(name[0]) >= 0)
3050  self.checkType2.SetValue(self.vPropertiesDict['type'].find(name[1]) >= 0)
3051 
3052  gridBagSizer.Add(self.checkType1, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3053  gridBagSizer.Add(self.checkType2, pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3054  sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
3055  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
3056 
3057  # layer selection
3058  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Layer selection"))
3059  sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
3060  self.gridBagSizerL = wx.GridBagSizer(hgap = 5, vgap = 5)
3061 
3062  self.warning = wx.StaticText(panel, id = wx.ID_ANY, label = "")
3063  if not self.connection:
3064  self.warning = wx.StaticText(panel, id = wx.ID_ANY, label = _("Database connection is not defined in DB file."))
3065  text = wx.StaticText(panel, id = wx.ID_ANY, label = _("Select layer:"))
3066  self.layerChoice = wx.Choice(panel, id = wx.ID_ANY, choices = map(str, self.layers), size = self.spinCtrlSize)
3067 
3068  self.layerChoice.SetStringSelection(self.currLayer)
3069 
3070  if self.connection:
3071  table = self.mapDBInfo.layers[int(self.currLayer)]['table']
3072  else:
3073  table = ""
3074 
3075  self.radioWhere = wx.RadioButton(panel, id = wx.ID_ANY, label = "SELECT * FROM %s WHERE" % table, style = wx.RB_GROUP)
3076  self.textCtrlWhere = wx.TextCtrl(panel, id = wx.ID_ANY, value = "")
3077 
3078 
3079  if self.connection:
3080  cols = self.mapDBInfo.GetColumns(self.mapDBInfo.layers[int(self.currLayer)]['table'])
3081  else:
3082  cols = []
3083 
3084  self.choiceColumns = wx.Choice(panel, id = wx.ID_ANY, choices = cols)
3085 
3086  self.radioCats = wx.RadioButton(panel, id = wx.ID_ANY, label = "Choose categories ")
3087  self.textCtrlCats = wx.TextCtrl(panel, id = wx.ID_ANY, value = "")
3088  self.textCtrlCats.SetToolTipString(_("list of categories (e.g. 1,3,5-7)"))
3089 
3090  if self.vPropertiesDict.has_key('cats'):
3091  self.radioCats.SetValue(True)
3092  self.textCtrlCats.SetValue(self.vPropertiesDict['cats'])
3093  if self.vPropertiesDict.has_key('where'):
3094  self.radioWhere.SetValue(True)
3095  where = self.vPropertiesDict['where'].strip().split(" ",1)
3096  self.choiceColumns.SetStringSelection(where[0])
3097  self.textCtrlWhere.SetValue(where[1])
3098 
3099  row = 0
3100  if not self.connection:
3101  self.gridBagSizerL.Add(self.warning, pos = (0,0), span = (1,3), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3102  row = 1
3103  self.gridBagSizerL.Add(text, pos = (0 + row,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3104  self.gridBagSizerL.Add(self.layerChoice, pos = (0 + row,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
3105  self.gridBagSizerL.Add(self.radioWhere, pos = (1 + row,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3106  self.gridBagSizerL.Add(self.choiceColumns, pos = (1 + row,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3107  self.gridBagSizerL.Add(self.textCtrlWhere, pos = (1 + row,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3108  self.gridBagSizerL.Add(self.radioCats, pos = (2 + row,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3109  self.gridBagSizerL.Add(self.textCtrlCats, pos = (2 + row,1), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
3110 
3111  sizer.Add(self.gridBagSizerL, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
3112  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
3113 
3114  #mask
3115  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Mask"))
3116  sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
3117 
3118  self.mask = wx.CheckBox(panel, id = wx.ID_ANY, label = _("Use current mask"))
3119  if self.vPropertiesDict['masked'] == 'y':
3120  self.mask.SetValue(True)
3121  else:
3122  self.mask.SetValue(False)
3123 
3124  sizer.Add(self.mask, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
3125  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
3126 
3127  self.Bind(wx.EVT_CHOICE, self.OnLayer, self.layerChoice)
3128 
3129  panel.SetSizer(border)
3130  panel.Fit()
3131  return panel
3132 
3133  def _ColorsPointAreaPanel(self, notebook):
3134  panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
3135  notebook.AddPage(page = panel, text = _("Colors"))
3136 
3137  border = wx.BoxSizer(wx.VERTICAL)
3138 
3139  #colors - outline
3140  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Outline"))
3141  sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
3142  self.gridBagSizerO = wx.GridBagSizer(hgap = 5, vgap = 2)
3143 
3144  self.outlineCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("draw outline"))
3145  self.outlineCheck.SetValue(self.vPropertiesDict['color'] != 'none')
3146 
3147  widthText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Width (pts):"))
3148  if fs:
3149  self.widthSpin = fs.FloatSpin(panel, id = wx.ID_ANY, min_val = 0, max_val = 30,
3150  increment = 0.5, value = 1, style = fs.FS_RIGHT)
3151  self.widthSpin.SetFormat("%f")
3152  self.widthSpin.SetDigits(2)
3153  else:
3154  self.widthSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 25, initial = 1,
3155  size = self.spinCtrlSize)
3156 
3157  if self.vPropertiesDict['color'] == None:
3158  self.vPropertiesDict['color'] = 'none'
3159 
3160  if self.vPropertiesDict['color'] != 'none':
3161  self.widthSpin.SetValue(self.vPropertiesDict['width'] )
3162  else:
3163  self.widthSpin.SetValue(1)
3164 
3165  colorText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Color:"))
3166  self.colorPicker = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
3167  if self.vPropertiesDict['color'] != 'none':
3168  self.colorPicker.SetColour(convertRGB(self.vPropertiesDict['color']))
3169  else:
3170  self.colorPicker.SetColour(convertRGB('black'))
3171 
3172  self.gridBagSizerO.Add(self.outlineCheck, pos = (0, 0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3173  self.gridBagSizerO.Add(widthText, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3174  self.gridBagSizerO.Add(self.widthSpin, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
3175  self.gridBagSizerO.Add(colorText, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3176  self.gridBagSizerO.Add(self.colorPicker, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3177 
3178  sizer.Add(self.gridBagSizerO, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
3179  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
3180 
3181  self.Bind(wx.EVT_CHECKBOX, self.OnOutline, self.outlineCheck)
3182 
3183  #colors - fill
3184  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Fill"))
3185  sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
3186  self.gridBagSizerF = wx.GridBagSizer(hgap = 5, vgap = 2)
3187 
3188  self.fillCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("fill color"))
3189  self.fillCheck.SetValue(self.vPropertiesDict['fcolor'] != 'none' or self.vPropertiesDict['rgbcolumn'] is not None)
3190 
3191  self.colorPickerRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("choose color:"), style = wx.RB_GROUP)
3192  #set choose color option if there is no db connection
3193  if self.connection:
3194  self.colorPickerRadio.SetValue(not self.vPropertiesDict['rgbcolumn'])
3195  else:
3196  self.colorPickerRadio.SetValue(False)
3197  self.fillColorPicker = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
3198  if self.vPropertiesDict['fcolor'] != 'none':
3199  self.fillColorPicker.SetColour(convertRGB(self.vPropertiesDict['fcolor']))
3200  else:
3201  self.fillColorPicker.SetColour(convertRGB('red'))
3202 
3203  self.colorColRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("color from map table column:"))
3204  self.colorColChoice = self.getColsChoice(parent = panel)
3205  if self.connection:
3206  if self.vPropertiesDict['rgbcolumn']:
3207  self.colorColRadio.SetValue(True)
3208  self.colorColChoice.SetStringSelection(self.vPropertiesDict['rgbcolumn'])
3209  else:
3210  self.colorColRadio.SetValue(False)
3211  self.colorColChoice.SetSelection(0)
3212  self.colorColChoice.Enable(self.connection)
3213  self.colorColRadio.Enable(self.connection)
3214 
3215  self.gridBagSizerF.Add(self.fillCheck, pos = (0, 0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3216  self.gridBagSizerF.Add(self.colorPickerRadio, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3217  self.gridBagSizerF.Add(self.fillColorPicker, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3218  self.gridBagSizerF.Add(self.colorColRadio, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3219  self.gridBagSizerF.Add(self.colorColChoice, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
3220 
3221  sizer.Add(self.gridBagSizerF, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
3222  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
3223 
3224  self.Bind(wx.EVT_CHECKBOX, self.OnFill, self.fillCheck)
3225  self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorColRadio)
3226  self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorPickerRadio)
3227 
3228  panel.SetSizer(border)
3229  panel.Fit()
3230  return panel
3231 
3232  def _ColorsLinePanel(self, notebook):
3233  panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
3234  notebook.AddPage(page = panel, text = _("Colors"))
3235 
3236  border = wx.BoxSizer(wx.VERTICAL)
3237 
3238  #colors - outline
3239  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Outline"))
3240  sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
3241  self.gridBagSizerO = wx.GridBagSizer(hgap = 5, vgap = 2)
3242 
3243  if self.vPropertiesDict['hcolor'] == None:
3244  self.vPropertiesDict['hcolor'] = 'none'
3245  if self.vPropertiesDict['color'] == None:
3246  self.vPropertiesDict['color'] = 'none'
3247 
3248  self.outlineCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("draw outline"))
3249  self.outlineCheck.SetValue(self.vPropertiesDict['hcolor'] != 'none')
3250  self.outlineCheck.SetToolTipString(_("No effect for fill color from table column"))
3251 
3252  widthText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Width (pts):"))
3253 
3254  if fs:
3255  self.outWidthSpin = fs.FloatSpin(panel, id = wx.ID_ANY, min_val = 0, max_val = 30,
3256  increment = 0.5, value = 1, style = fs.FS_RIGHT)
3257  self.outWidthSpin.SetFormat("%f")
3258  self.outWidthSpin.SetDigits(1)
3259  else:
3260  self.outWidthSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 30, initial = 1,
3261  size = self.spinCtrlSize)
3262 
3263  if self.vPropertiesDict['hcolor'] != 'none':
3264  self.outWidthSpin.SetValue(self.vPropertiesDict['hwidth'] )
3265  else:
3266  self.outWidthSpin.SetValue(1)
3267 
3268  colorText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Color:"))
3269  self.colorPicker = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
3270  if self.vPropertiesDict['hcolor'] != 'none':
3271  self.colorPicker.SetColour(convertRGB(self.vPropertiesDict['hcolor']) )
3272  else:
3273  self.colorPicker.SetColour(convertRGB('black'))
3274 
3275 
3276  self.gridBagSizerO.Add(self.outlineCheck, pos = (0, 0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3277  self.gridBagSizerO.Add(widthText, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3278  self.gridBagSizerO.Add(self.outWidthSpin, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
3279  self.gridBagSizerO.Add(colorText, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3280  self.gridBagSizerO.Add(self.colorPicker, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3281 
3282  sizer.Add(self.gridBagSizerO, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
3283  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
3284 
3285  self.Bind(wx.EVT_CHECKBOX, self.OnOutline, self.outlineCheck)
3286 
3287  #colors - fill
3288  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Fill"))
3289  sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
3290  self.gridBagSizerF = wx.GridBagSizer(hgap = 5, vgap = 2)
3291 
3292  fillText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Color of lines:"))
3293 
3294  self.colorPickerRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("choose color:"), style = wx.RB_GROUP)
3295 
3296  #set choose color option if there is no db connection
3297  if self.connection:
3298  self.colorPickerRadio.SetValue(not self.vPropertiesDict['rgbcolumn'])
3299  else:
3300  self.colorPickerRadio.SetValue(False)
3301  self.fillColorPicker = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
3302  if self.vPropertiesDict['color'] != 'none':
3303  self.fillColorPicker.SetColour(convertRGB(self.vPropertiesDict['color']) )
3304  else:
3305  self.fillColorPicker.SetColour(convertRGB('black'))
3306 
3307  self.colorColRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("color from map table column:"))
3308  self.colorColChoice = self.getColsChoice(parent = panel)
3309  if self.connection:
3310  if self.vPropertiesDict['rgbcolumn']:
3311  self.colorColRadio.SetValue(True)
3312  self.colorColChoice.SetStringSelection(self.vPropertiesDict['rgbcolumn'])
3313  else:
3314  self.colorColRadio.SetValue(False)
3315  self.colorColChoice.SetSelection(0)
3316  self.colorColChoice.Enable(self.connection)
3317  self.colorColRadio.Enable(self.connection)
3318 
3319  self.gridBagSizerF.Add(fillText, pos = (0, 0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3320  self.gridBagSizerF.Add(self.colorPickerRadio, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3321  self.gridBagSizerF.Add(self.fillColorPicker, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3322  self.gridBagSizerF.Add(self.colorColRadio, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3323  self.gridBagSizerF.Add(self.colorColChoice, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
3324 
3325  sizer.Add(self.gridBagSizerF, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
3326  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
3327 
3328  self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorColRadio)
3329  self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorPickerRadio)
3330 
3331  panel.SetSizer(border)
3332  panel.Fit()
3333  return panel
3334 
3335  def _StylePointPanel(self, notebook):
3336  panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
3337  notebook.AddPage(page = panel, text = _("Size and style"))
3338 
3339  border = wx.BoxSizer(wx.VERTICAL)
3340 
3341  #symbology
3342  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Symbology"))
3343  sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
3344  gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
3345  gridBagSizer.AddGrowableCol(1)
3346 
3347  self.symbolRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("symbol:"), style = wx.RB_GROUP)
3348  self.symbolRadio.SetValue(bool(self.vPropertiesDict['symbol']))
3349 
3350 
3351  self.symbolChoice = wx.Choice(panel, id = wx.ID_ANY, choices = self.symbols)
3352 
3353  self.epsRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("eps file:"))
3354  self.epsRadio.SetValue(bool(self.vPropertiesDict['eps']))
3355 
3356  self.epsFileCtrl = filebrowse.FileBrowseButton(panel, id = wx.ID_ANY, labelText = '',
3357  buttonText = _("Browse"), toolTip = _("Type filename or click browse to choose file"),
3358  dialogTitle = _("Choose a file"), startDirectory = '', initialValue = '',
3359  fileMask = "Encapsulated PostScript (*.eps)|*.eps|All files (*.*)|*.*", fileMode = wx.OPEN)
3360  if self.vPropertiesDict['symbol']:
3361  self.symbolChoice.SetStringSelection(self.vPropertiesDict['symbol'])
3362  self.epsFileCtrl.SetValue('')
3363  else: #eps chosen
3364  self.epsFileCtrl.SetValue(self.vPropertiesDict['eps'])
3365  self.symbolChoice.SetSelection(0)
3366 
3367  gridBagSizer.Add(self.symbolRadio, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3368  gridBagSizer.Add(self.symbolChoice, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3369  gridBagSizer.Add(self.epsRadio, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3370  gridBagSizer.Add(self.epsFileCtrl, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
3371 
3372  sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
3373  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
3374 
3375  #size
3376 
3377  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Size"))
3378  sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
3379  gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
3380  gridBagSizer.AddGrowableCol(0)
3381 
3382  self.sizeRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("size:"), style = wx.RB_GROUP)
3383  self.sizeSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 50, initial = 1)
3384  self.sizecolumnRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("size from map table column:"))
3385  self.sizeColChoice = self.getColsChoice(panel)
3386  self.scaleText = wx.StaticText(panel, id = wx.ID_ANY, label = _("scale:"))
3387  self.scaleSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 25, initial = 1)
3388 
3389  self.sizeRadio.SetValue(self.vPropertiesDict['size'] is not None)
3390  self.sizecolumnRadio.SetValue(bool(self.vPropertiesDict['sizecolumn']))
3391  if self.vPropertiesDict['size']:
3392  self.sizeSpin.SetValue(self.vPropertiesDict['size'])
3393  else: self.sizeSpin.SetValue(5)
3394  if self.vPropertiesDict['sizecolumn']:
3395  self.scaleSpin.SetValue(self.vPropertiesDict['scale'])
3396  self.sizeColChoice.SetStringSelection(self.vPropertiesDict['sizecolumn'])
3397  else:
3398  self.scaleSpin.SetValue(1)
3399  self.sizeColChoice.SetSelection(0)
3400  if not self.connection:
3401  for each in (self.sizecolumnRadio, self.sizeColChoice, self.scaleSpin, self.scaleText):
3402  each.Disable()
3403 
3404  gridBagSizer.Add(self.sizeRadio, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3405  gridBagSizer.Add(self.sizeSpin, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3406  gridBagSizer.Add(self.sizecolumnRadio, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3407  gridBagSizer.Add(self.sizeColChoice, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
3408  gridBagSizer.Add(self.scaleText, pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
3409  gridBagSizer.Add(self.scaleSpin, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3410 
3411  sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
3412  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
3413 
3414  self.Bind(wx.EVT_RADIOBUTTON, self.OnSize, self.sizeRadio)
3415  self.Bind(wx.EVT_RADIOBUTTON, self.OnSize, self.sizecolumnRadio)
3416 
3417  #rotation
3418  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Rotation"))
3419  sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
3420  gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
3421  gridBagSizer.AddGrowableCol(1)
3422 
3423 
3424  self.rotateCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("rotate symbols:"))
3425  self.rotateRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("counterclockwise in degrees:"), style = wx.RB_GROUP)
3426  self.rotateSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 0, max = 360, initial = 0)
3427  self.rotatecolumnRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("from map table column:"))
3428  self.rotateColChoice = self.getColsChoice(panel)
3429 
3430  self.rotateCheck.SetValue(self.vPropertiesDict['rotation'])
3431  self.rotateRadio.SetValue(self.vPropertiesDict['rotate'] is not None)
3432  self.rotatecolumnRadio.SetValue(bool(self.vPropertiesDict['rotatecolumn']))
3433  if self.vPropertiesDict['rotate']:
3434  self.rotateSpin.SetValue(self.vPropertiesDict['rotate'])
3435  else:
3436  self.rotateSpin.SetValue(0)
3437  if self.vPropertiesDict['rotatecolumn']:
3438  self.rotateColChoice.SetStringSelection(self.vPropertiesDict['rotatecolumn'])
3439  else:
3440  self.rotateColChoice.SetSelection(0)
3441 
3442  gridBagSizer.Add(self.rotateCheck, pos = (0, 0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3443  gridBagSizer.Add(self.rotateRadio, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3444  gridBagSizer.Add(self.rotateSpin, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3445  gridBagSizer.Add(self.rotatecolumnRadio, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3446  gridBagSizer.Add(self.rotateColChoice, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
3447 
3448  sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
3449  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
3450 
3451  self.Bind(wx.EVT_CHECKBOX, self.OnRotation, self.rotateCheck)
3452  self.Bind(wx.EVT_RADIOBUTTON, self.OnRotationType, self.rotateRadio)
3453  self.Bind(wx.EVT_RADIOBUTTON, self.OnRotationType, self.rotatecolumnRadio)
3454 
3455  panel.SetSizer(border)
3456  panel.Fit()
3457  return panel
3458 
3459  def _StyleLinePanel(self, notebook):
3460  panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
3461  notebook.AddPage(page = panel, text = _("Size and style"))
3462 
3463  border = wx.BoxSizer(wx.VERTICAL)
3464 
3465  #width
3466  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Width"))
3467  sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
3468  gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
3469 
3470  widthText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Set width (pts):"))
3471  if fs:
3472  self.widthSpin = fs.FloatSpin(panel, id = wx.ID_ANY, min_val = 0, max_val = 30,
3473  increment = 0.5, value = 1, style = fs.FS_RIGHT)
3474  self.widthSpin.SetFormat("%f")
3475  self.widthSpin.SetDigits(1)
3476  else:
3477  self.widthSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 30, initial = 1)
3478 
3479  self.cwidthCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("multiply width by category value"))
3480 
3481  if self.vPropertiesDict['width']:
3482  self.widthSpin.SetValue(self.vPropertiesDict['width'])
3483  self.cwidthCheck.SetValue(False)
3484  else:
3485  self.widthSpin.SetValue(self.vPropertiesDict['cwidth'])
3486  self.cwidthCheck.SetValue(True)
3487 
3488  gridBagSizer.Add(widthText, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3489  gridBagSizer.Add(self.widthSpin, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3490  gridBagSizer.Add(self.cwidthCheck, pos = (1, 0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3491 
3492  sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
3493  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
3494 
3495  #style
3496  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Line style"))
3497  sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
3498  gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
3499 
3500  styleText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Choose line style:"))
3501  penStyles = ["solid", "dashed", "dotted", "dashdotted"]
3502  self.styleCombo = PenStyleComboBox(panel, choices = penStyles, validator = TCValidator(flag = 'ZERO_AND_ONE_ONLY'))
3503 ## self.styleCombo = wx.ComboBox(panel, id = wx.ID_ANY,
3504 ## choices = ["solid", "dashed", "dotted", "dashdotted"],
3505 ## validator = TCValidator(flag = 'ZERO_AND_ONE_ONLY'))
3506 ## self.styleCombo.SetToolTipString(_("It's possible to enter a series of 0's and 1's too. "\
3507 ## "The first block of repeated zeros or ones represents 'draw', "\
3508 ## "the second block represents 'blank'. An even number of blocks "\
3509 ## "will repeat the pattern, an odd number of blocks will alternate the pattern."))
3510  linecapText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Choose linecap:"))
3511  self.linecapChoice = wx.Choice(panel, id = wx.ID_ANY, choices = ["butt", "round", "extended_butt"])
3512 
3513  self.styleCombo.SetValue(self.vPropertiesDict['style'])
3514  self.linecapChoice.SetStringSelection(self.vPropertiesDict['linecap'])
3515 
3516  gridBagSizer.Add(styleText, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3517  gridBagSizer.Add(self.styleCombo, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
3518  gridBagSizer.Add(linecapText, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3519  gridBagSizer.Add(self.linecapChoice, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
3520 
3521  sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
3522  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
3523 
3524  panel.SetSizer(border)
3525  panel.Fit()
3526  return panel
3527 
3528  def _StyleAreaPanel(self, notebook):
3529  panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
3530  notebook.AddPage(page = panel, text = _("Size and style"))
3531 
3532  border = wx.BoxSizer(wx.VERTICAL)
3533 
3534  #pattern
3535  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Pattern"))
3536  sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
3537  gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
3538  gridBagSizer.AddGrowableCol(1)
3539 
3540  self.patternCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("use pattern:"))
3541  self.patFileCtrl = filebrowse.FileBrowseButton(panel, id = wx.ID_ANY, labelText = _("Choose pattern file:"),
3542  buttonText = _("Browse"), toolTip = _("Type filename or click browse to choose file"),
3543  dialogTitle = _("Choose a file"), startDirectory = self.patternPath, initialValue = '',
3544  fileMask = "Encapsulated PostScript (*.eps)|*.eps|All files (*.*)|*.*", fileMode = wx.OPEN)
3545  self.patWidthText = wx.StaticText(panel, id = wx.ID_ANY, label = _("pattern line width (pts):"))
3546  self.patWidthSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 25, initial = 1)
3547  self.patScaleText = wx.StaticText(panel, id = wx.ID_ANY, label = _("pattern scale factor:"))
3548  self.patScaleSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 25, initial = 1)
3549 
3550  self.patternCheck.SetValue(bool(self.vPropertiesDict['pat']))
3551  if self.patternCheck.GetValue():
3552  self.patFileCtrl.SetValue(self.vPropertiesDict['pat'])
3553  self.patWidthSpin.SetValue(self.vPropertiesDict['pwidth'])
3554  self.patScaleSpin.SetValue(self.vPropertiesDict['scale'])
3555 
3556  gridBagSizer.Add(self.patternCheck, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3557  gridBagSizer.Add(self.patFileCtrl, pos = (1, 0), span = (1, 2),flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
3558  gridBagSizer.Add(self.patWidthText, pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3559  gridBagSizer.Add(self.patWidthSpin, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3560  gridBagSizer.Add(self.patScaleText, pos = (3, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3561  gridBagSizer.Add(self.patScaleSpin, pos = (3, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3562 
3563 
3564  sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
3565  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
3566 
3567  self.Bind(wx.EVT_CHECKBOX, self.OnPattern, self.patternCheck)
3568 
3569  panel.SetSizer(border)
3570  panel.Fit()
3571  return panel
3572 
3573  def OnLayer(self, event):
3574  """!Change columns on layer change """
3575  if self.layerChoice.GetStringSelection() == self.currLayer:
3576  return
3577  self.currLayer = self.layerChoice.GetStringSelection()
3578  if self.connection:
3579  cols = self.mapDBInfo.GetColumns(self.mapDBInfo.layers[int(self.currLayer)]['table'])
3580  else:
3581  cols = []
3582 
3583  self.choiceColumns.SetItems(cols)
3584 
3585  self.choiceColumns.SetSelection(0)
3586  if self.type in ('points', 'lines'):
3587  self.colorColChoice.SetItems(cols)
3588  self.colorColChoice.SetSelection(0)
3589 
3590  def OnOutline(self, event):
3591  for widget in self.gridBagSizerO.GetChildren():
3592  if widget.GetWindow() != self.outlineCheck:
3593  widget.GetWindow().Enable(self.outlineCheck.GetValue())
3594 
3595  def OnFill(self, event):
3596  enable = self.fillCheck.GetValue()
3597 
3598  self.colorColChoice.Enable(enable)
3599  self.colorColRadio.Enable(enable)
3600  self.fillColorPicker.Enable(enable)
3601  self.colorPickerRadio.Enable(enable)
3602  if enable:
3603  self.OnColor(None)
3604  if not self.connection:
3605  self.colorColChoice.Disable()
3606  self.colorColRadio.Disable()
3607 
3608  def OnColor(self, event):
3609  self.colorColChoice.Enable(self.colorColRadio.GetValue())
3610  self.fillColorPicker.Enable(self.colorPickerRadio.GetValue())
3611 
3612  def OnSize(self, event):
3613  self.sizeSpin.Enable(self.sizeRadio.GetValue())
3614  self.sizeColChoice.Enable(self.sizecolumnRadio.GetValue())
3615  self.scaleText.Enable(self.sizecolumnRadio.GetValue())
3616  self.scaleSpin.Enable(self.sizecolumnRadio.GetValue())
3617 
3618  def OnRotation(self, event):
3619  for each in (self.rotateRadio, self.rotatecolumnRadio, self.rotateColChoice, self.rotateSpin):
3620  if self.rotateCheck.GetValue():
3621  each.Enable()
3622  self.OnRotationType(event = None)
3623  else:
3624  each.Disable()
3625 
3626  def OnRotationType(self, event):
3627  self.rotateSpin.Enable(self.rotateRadio.GetValue())
3628  self.rotateColChoice.Enable(self.rotatecolumnRadio.GetValue())
3629 
3630  def OnPattern(self, event):
3631  for each in (self.patFileCtrl, self.patWidthText, self.patWidthSpin, self.patScaleText, self.patScaleSpin):
3632  each.Enable(self.patternCheck.GetValue())
3633 
3634  def EnableLayerSelection(self, enable = True):
3635  for widget in self.gridBagSizerL.GetChildren():
3636  if widget.GetWindow() != self.warning:
3637  widget.GetWindow().Enable(enable)
3638 
3639  def getColsChoice(self, parent):
3640  """!Returns a wx.Choice with table columns"""
3641  if self.connection:
3642  cols = self.mapDBInfo.GetColumns(self.mapDBInfo.layers[int(self.currLayer)]['table'])
3643  else:
3644  cols = []
3645 
3646  choice = wx.Choice(parent = parent, id = wx.ID_ANY, choices = cols)
3647  return choice
3648 
3649  def update(self):
3650  #feature type
3651  if self.type in ('lines', 'points'):
3652  featureType = None
3653  if self.checkType1.GetValue():
3654  featureType = self.checkType1.GetName()
3655  if self.checkType2.GetValue():
3656  featureType += " or " + self.checkType2.GetName()
3657  elif self.checkType2.GetValue():
3658  featureType = self.checkType2.GetName()
3659  if featureType:
3660  self.vPropertiesDict['type'] = featureType
3661 
3662  # is connection
3663  self.vPropertiesDict['connection'] = self.connection
3664  if self.connection:
3665  self.vPropertiesDict['layer'] = self.layerChoice.GetStringSelection()
3666  if self.radioCats.GetValue() and not self.textCtrlCats.IsEmpty():
3667  self.vPropertiesDict['cats'] = self.textCtrlCats.GetValue()
3668  elif self.radioWhere.GetValue() and not self.textCtrlWhere.IsEmpty():
3669  self.vPropertiesDict['where'] = self.choiceColumns.GetStringSelection() + " " \
3670  + self.textCtrlWhere.GetValue()
3671  #mask
3672  if self.mask.GetValue():
3673  self.vPropertiesDict['masked'] = 'y'
3674  else:
3675  self.vPropertiesDict['masked'] = 'n'
3676 
3677  #colors
3678  if self.type in ('points', 'areas'):
3679  if self.outlineCheck.GetValue():
3680  self.vPropertiesDict['color'] = convertRGB(self.colorPicker.GetColour())
3681  self.vPropertiesDict['width'] = self.widthSpin.GetValue()
3682  else:
3683  self.vPropertiesDict['color'] = 'none'
3684 
3685  if self.fillCheck.GetValue():
3686  if self.colorPickerRadio.GetValue():
3687  self.vPropertiesDict['fcolor'] = convertRGB(self.fillColorPicker.GetColour())
3688  self.vPropertiesDict['rgbcolumn'] = None
3689  if self.colorColRadio.GetValue():
3690  self.vPropertiesDict['fcolor'] = 'none'# this color is taken in case of no record in rgb column
3691  self.vPropertiesDict['rgbcolumn'] = self.colorColChoice.GetStringSelection()
3692  else:
3693  self.vPropertiesDict['fcolor'] = 'none'
3694 
3695  if self.type == 'lines':
3696  #hcolor only when no rgbcolumn
3697  if self.outlineCheck.GetValue():# and self.fillCheck.GetValue() and self.colorColRadio.GetValue():
3698  self.vPropertiesDict['hcolor'] = convertRGB(self.colorPicker.GetColour())
3699  self.vPropertiesDict['hwidth'] = self.outWidthSpin.GetValue()
3700 
3701  else:
3702  self.vPropertiesDict['hcolor'] = 'none'
3703 
3704  if self.colorPickerRadio.GetValue():
3705  self.vPropertiesDict['color'] = convertRGB(self.fillColorPicker.GetColour())
3706  self.vPropertiesDict['rgbcolumn'] = None
3707  if self.colorColRadio.GetValue():
3708  self.vPropertiesDict['color'] = 'none'# this color is taken in case of no record in rgb column
3709  self.vPropertiesDict['rgbcolumn'] = self.colorColChoice.GetStringSelection()
3710  #
3711  #size and style
3712  #
3713 
3714  if self.type == 'points':
3715  #symbols
3716  if self.symbolRadio.GetValue():
3717  self.vPropertiesDict['symbol'] = self.symbolChoice.GetStringSelection()
3718  self.vPropertiesDict['eps'] = None
3719  else:
3720  self.vPropertiesDict['eps'] = self.epsFileCtrl.GetValue()
3721  self.vPropertiesDict['symbol'] = None
3722  #size
3723  if self.sizeRadio.GetValue():
3724  self.vPropertiesDict['size'] = self.sizeSpin.GetValue()
3725  self.vPropertiesDict['sizecolumn'] = None
3726  self.vPropertiesDict['scale'] = None
3727  else:
3728  self.vPropertiesDict['sizecolumn'] = self.sizeColChoice.GetStringSelection()
3729  self.vPropertiesDict['scale'] = self.scaleSpin.GetValue()
3730  self.vPropertiesDict['size'] = None
3731 
3732  #rotation
3733  self.vPropertiesDict['rotate'] = None
3734  self.vPropertiesDict['rotatecolumn'] = None
3735  self.vPropertiesDict['rotation'] = False
3736  if self.rotateCheck.GetValue():
3737  self.vPropertiesDict['rotation'] = True
3738  if self.rotateRadio.GetValue():
3739  self.vPropertiesDict['rotate'] = self.rotateSpin.GetValue()
3740  else:
3741  self.vPropertiesDict['rotatecolumn'] = self.rotateColChoice.GetStringSelection()
3742 
3743  if self.type == 'areas':
3744  #pattern
3745  self.vPropertiesDict['pat'] = None
3746  if self.patternCheck.GetValue() and bool(self.patFileCtrl.GetValue()):
3747  self.vPropertiesDict['pat'] = self.patFileCtrl.GetValue()
3748  self.vPropertiesDict['pwidth'] = self.patWidthSpin.GetValue()
3749  self.vPropertiesDict['scale'] = self.patScaleSpin.GetValue()
3750 
3751  if self.type == 'lines':
3752  #width
3753  if self.cwidthCheck.GetValue():
3754  self.vPropertiesDict['cwidth'] = self.widthSpin.GetValue()
3755  self.vPropertiesDict['width'] = None
3756  else:
3757  self.vPropertiesDict['width'] = self.widthSpin.GetValue()
3758  self.vPropertiesDict['cwidth'] = None
3759  #line style
3760  if self.styleCombo.GetValue():
3761  self.vPropertiesDict['style'] = self.styleCombo.GetValue()
3762  else:
3763  self.vPropertiesDict['style'] = 'solid'
3764 
3765  self.vPropertiesDict['linecap'] = self.linecapChoice.GetStringSelection()
3766 
3767  def OnOK(self, event):
3768  self.update()
3769  event.Skip()
3770 
3772  def __init__(self, parent, id, settings, page):
3773  PsmapDialog.__init__(self, parent = parent, id = id, title = "Legend settings", settings = settings)
3774  self.objectType = ('rasterLegend', 'vectorLegend')
3775  self.instruction = settings
3776  map = self.instruction.FindInstructionByType('map')
3777  if map:
3778  self.mapId = map.id
3779  else:
3780  self.mapId = None
3781 
3782  vector = self.instruction.FindInstructionByType('vector')
3783  if vector:
3784  self.vectorId = vector.id
3785  else:
3786  self.vectorId = None
3787 
3788  raster = self.instruction.FindInstructionByType('raster')
3789  if raster:
3790  self.rasterId = raster.id
3791  else:
3792  self.rasterId = None
3793 
3794  self.pageId = self.instruction.FindInstructionByType('page').id
3795  currPage = self.instruction[self.pageId].GetInstruction()
3796  #raster legend
3797  if self.id[0] is not None:
3798  self.rasterLegend = self.instruction[self.id[0]]
3799  self.rLegendDict = self.rasterLegend.GetInstruction()
3800  else:
3801  self.id[0] = wx.NewId()
3802  self.rasterLegend = RasterLegend(self.id[0])
3803  self.rLegendDict = self.rasterLegend.GetInstruction()
3804  self.rLegendDict['where'] = currPage['Left'], currPage['Top']
3805 
3806 
3807  #vector legend
3808  if self.id[1] is not None:
3809  self.vLegendDict = self.instruction[self.id[1]].GetInstruction()
3810  else:
3811  self.id[1] = wx.NewId()
3812  vectorLegend = VectorLegend(self.id[1])
3813  self.vLegendDict = vectorLegend.GetInstruction()
3814  self.vLegendDict['where'] = currPage['Left'], currPage['Top']
3815 
3816  if self.rasterId:
3817  self.currRaster = self.instruction[self.rasterId]['raster']
3818  else:
3819  self.currRaster = None
3820 
3821  #notebook
3822  self.notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT)
3824  self.panelVector = self._vectorLegend(self.notebook)
3825  self.OnRaster(None)
3826  self.OnRange(None)
3827  self.OnIsLegend(None)
3828  self.OnSpan(None)
3829  self.OnBorder(None)
3830 
3831  self._layout(self.notebook)
3832  self.notebook.ChangeSelection(page)
3833  self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGING, self.OnPageChanging)
3834 
3835  def OnPageChanging(self, event):
3836  """!Workaround to scroll up to see the checkbox"""
3837  wx.CallAfter(self.FindWindowByName('rasterPanel').ScrollChildIntoView,
3838  self.FindWindowByName('showRLegend'))
3839  wx.CallAfter(self.FindWindowByName('vectorPanel').ScrollChildIntoView,
3840  self.FindWindowByName('showVLegend'))
3841 
3842  def _rasterLegend(self, notebook):
3843  panel = scrolled.ScrolledPanel(parent = notebook, id = wx.ID_ANY, size = (-1, 500), style = wx.TAB_TRAVERSAL)
3844  panel.SetupScrolling(scroll_x = False, scroll_y = True)
3845  panel.SetName('rasterPanel')
3846  notebook.AddPage(page = panel, text = _("Raster legend"))
3847 
3848  border = wx.BoxSizer(wx.VERTICAL)
3849  # is legend
3850  self.isRLegend = wx.CheckBox(panel, id = wx.ID_ANY, label = _("Show raster legend"))
3851  self.isRLegend.SetValue(self.rLegendDict['rLegend'])
3852  self.isRLegend.SetName("showRLegend")
3853  border.Add(item = self.isRLegend, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
3854 
3855  # choose raster
3856  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Source raster"))
3857  sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
3858  flexSizer = wx.FlexGridSizer (cols = 2, hgap = 5, vgap = 5)
3859  flexSizer.AddGrowableCol(1)
3860 
3861  self.rasterDefault = wx.RadioButton(panel, id = wx.ID_ANY, label = _("current raster"), style = wx.RB_GROUP)
3862  self.rasterOther = wx.RadioButton(panel, id = wx.ID_ANY, label = _("select raster"))
3863  self.rasterDefault.SetValue(self.rLegendDict['rasterDefault'])#
3864  self.rasterOther.SetValue(not self.rLegendDict['rasterDefault'])#
3865 
3866  rasterType = getRasterType(map = self.currRaster)
3867 
3868  self.rasterCurrent = wx.StaticText(panel, id = wx.ID_ANY,
3869  label = _("%(rast)s: type %(type)s") % { 'rast' : self.currRaster,
3870  'type' : rasterType })
3871  self.rasterSelect = Select(panel, id = wx.ID_ANY, size = globalvar.DIALOG_GSELECT_SIZE,
3872  type = 'raster', multiple = False,
3873  updateOnPopup = True, onPopup = None)
3874  if not self.rLegendDict['rasterDefault']:
3875  self.rasterSelect.SetValue(self.rLegendDict['raster'])
3876  else:
3877  self.rasterSelect.SetValue('')
3878  flexSizer.Add(self.rasterDefault, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3879  flexSizer.Add(self.rasterCurrent, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.LEFT, border = 10)
3880  flexSizer.Add(self.rasterOther, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3881  flexSizer.Add(self.rasterSelect, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
3882 
3883  sizer.Add(item = flexSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
3884  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
3885 
3886  # type of legend
3887 
3888  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Type of legend"))
3889  sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
3890  vbox = wx.BoxSizer(wx.VERTICAL)
3891  self.discrete = wx.RadioButton(parent = panel, id = wx.ID_ANY,
3892  label = " %s " % _("discrete legend (categorical maps)"), style = wx.RB_GROUP)
3893  self.continuous = wx.RadioButton(parent = panel, id = wx.ID_ANY,
3894  label = " %s " % _("continuous color gradient legend (floating point map)"))
3895 
3896  vbox.Add(self.discrete, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 0)
3897  vbox.Add(self.continuous, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 0)
3898  sizer.Add(item = vbox, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
3899  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
3900 
3901  # size, position and font
3902  self.sizePositionFont(legendType = 'raster', parent = panel, mainSizer = border)
3903 
3904  # advanced settings
3905  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Advanced legend settings"))
3906  sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
3907  gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
3908  # no data
3909  self.nodata = wx.CheckBox(panel, id = wx.ID_ANY, label = _('draw "no data" box'))
3910  if self.rLegendDict['nodata'] == 'y':
3911  self.nodata.SetValue(True)
3912  else:
3913  self.nodata.SetValue(False)
3914  #tickbar
3915  self.ticks = wx.CheckBox(panel, id = wx.ID_ANY, label = _("draw ticks across color table"))
3916  if self.rLegendDict['tickbar'] == 'y':
3917  self.ticks.SetValue(True)
3918  else:
3919  self.ticks.SetValue(False)
3920  # range
3921  if self.rasterId and self.instruction[self.rasterId]['raster']:
3922  rinfo = grass.raster_info(self.instruction[self.rasterId]['raster'])
3923  self.minim, self.maxim = rinfo['min'], rinfo['max']
3924  else:
3925  self.minim, self.maxim = 0,0
3926  self.range = wx.CheckBox(panel, id = wx.ID_ANY, label = _("range"))
3927  self.range.SetValue(self.rLegendDict['range'])
3928  self.minText = wx.StaticText(panel, id = wx.ID_ANY, label = "min (%s)" % self.minim)
3929  self.maxText = wx.StaticText(panel, id = wx.ID_ANY, label = "max (%s)" % self.maxim)
3930  self.min = wx.TextCtrl(panel, id = wx.ID_ANY, value = str(self.rLegendDict['min']))
3931  self.max = wx.TextCtrl(panel, id = wx.ID_ANY, value = str(self.rLegendDict['max']))
3932 
3933  gridBagSizer.Add(self.nodata, pos = (0,0), span = (1,5), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3934  gridBagSizer.Add(self.ticks, pos = (1,0), span = (1,5), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3935  gridBagSizer.Add(self.range, pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3936  gridBagSizer.Add(self.minText, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
3937  gridBagSizer.Add(self.min, pos = (2,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3938  gridBagSizer.Add(self.maxText, pos = (2,3), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
3939  gridBagSizer.Add(self.max, pos = (2,4), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3940 
3941  sizer.Add(gridBagSizer, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
3942  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
3943 
3944  panel.SetSizer(border)
3945  panel.Fit()
3946 
3947  # bindings
3948  self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterDefault)
3949  self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterOther)
3950  self.Bind(wx.EVT_CHECKBOX, self.OnIsLegend, self.isRLegend)
3951  self.Bind(wx.EVT_RADIOBUTTON, self.OnDiscrete, self.discrete)
3952  self.Bind(wx.EVT_RADIOBUTTON, self.OnDiscrete, self.continuous)
3953 ## self.Bind(wx.EVT_CHECKBOX, self.OnDefaultSize, panel.defaultSize)
3954  self.Bind(wx.EVT_CHECKBOX, self.OnRange, self.range)
3955  self.rasterSelect.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnRaster)
3956 
3957  return panel
3958 
3959  def _vectorLegend(self, notebook):
3960  panel = scrolled.ScrolledPanel(parent = notebook, id = wx.ID_ANY, size = (-1, 500), style = wx.TAB_TRAVERSAL)
3961  panel.SetupScrolling(scroll_x = False, scroll_y = True)
3962  panel.SetName('vectorPanel')
3963  notebook.AddPage(page = panel, text = _("Vector legend"))
3964 
3965  border = wx.BoxSizer(wx.VERTICAL)
3966  # is legend
3967  self.isVLegend = wx.CheckBox(panel, id = wx.ID_ANY, label = _("Show vector legend"))
3968  self.isVLegend.SetValue(self.vLegendDict['vLegend'])
3969  self.isVLegend.SetName("showVLegend")
3970  border.Add(item = self.isVLegend, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
3971 
3972  #vector maps, their order, labels
3973  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Source vector maps"))
3974  sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
3975  gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
3976  gridBagSizer.AddGrowableCol(0,3)
3977  gridBagSizer.AddGrowableCol(1,1)
3978 
3979  vectorText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Choose vector maps and their order in legend"))
3980 
3981  self.vectorListCtrl = CheckListCtrl(panel)
3982 
3983  self.vectorListCtrl.InsertColumn(0, _("Vector map"))
3984  self.vectorListCtrl.InsertColumn(1, _("Label"))
3985  if self.vectorId:
3986  vectors = sorted(self.instruction[self.vectorId]['list'], key = lambda x: x[3])
3987 
3988  for vector in vectors:
3989  index = self.vectorListCtrl.InsertStringItem(sys.maxint, vector[0].split('@')[0])
3990  self.vectorListCtrl.SetStringItem(index, 1, vector[4])
3991  self.vectorListCtrl.SetItemData(index, index)
3992  self.vectorListCtrl.CheckItem(index, True)
3993  if vector[3] == 0:
3994  self.vectorListCtrl.CheckItem(index, False)
3995  if not self.vectorId:
3996  self.vectorListCtrl.SetColumnWidth(0, 100)
3997  else:
3998  self.vectorListCtrl.SetColumnWidth(0, wx.LIST_AUTOSIZE)
3999  self.vectorListCtrl.SetColumnWidth(1, wx.LIST_AUTOSIZE)
4000 
4001  self.btnUp = wx.Button(panel, id = wx.ID_ANY, label = _("Up"))
4002  self.btnDown = wx.Button(panel, id = wx.ID_ANY, label = _("Down"))
4003  self.btnLabel = wx.Button(panel, id = wx.ID_ANY, label = _("Edit label"))
4004 
4005  gridBagSizer.Add(vectorText, pos = (0,0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4006  gridBagSizer.Add(self.vectorListCtrl, pos = (1,0), span = (3,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
4007  gridBagSizer.Add(self.btnUp, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4008  gridBagSizer.Add(self.btnDown, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4009  gridBagSizer.Add(self.btnLabel, pos = (3,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4010 
4011  sizer.Add(gridBagSizer, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
4012  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
4013 
4014  # size, position and font
4015  self.sizePositionFont(legendType = 'vector', parent = panel, mainSizer = border)
4016 
4017  # border
4018  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Border"))
4019  sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
4020  flexGridSizer = wx.FlexGridSizer(cols = 2, hgap = 5, vgap = 5)
4021 
4022  self.borderCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("draw border around legend"))
4023  self.borderColorCtrl = wx.ColourPickerCtrl(panel, id = wx.ID_ANY, style = wx.FNTP_FONTDESC_AS_LABEL)
4024  if self.vLegendDict['border'] == 'none':
4025  self.borderColorCtrl.SetColour(wx.BLACK)
4026  self.borderCheck.SetValue(False)
4027  else:
4028  self.borderColorCtrl.SetColour(convertRGB(self.vLegendDict['border']))
4029  self.borderCheck.SetValue(True)
4030 
4031  flexGridSizer.Add(self.borderCheck, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4032  flexGridSizer.Add(self.borderColorCtrl, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4033  sizer.Add(item = flexGridSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
4034  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
4035 
4036  self.Bind(wx.EVT_BUTTON, self.OnUp, self.btnUp)
4037  self.Bind(wx.EVT_BUTTON, self.OnDown, self.btnDown)
4038  self.Bind(wx.EVT_BUTTON, self.OnEditLabel, self.btnLabel)
4039  self.Bind(wx.EVT_CHECKBOX, self.OnIsLegend, self.isVLegend)
4040  self.Bind(wx.EVT_CHECKBOX, self.OnSpan, panel.spanRadio)
4041  self.Bind(wx.EVT_CHECKBOX, self.OnBorder, self.borderCheck)
4042  self.Bind(wx.EVT_FONTPICKER_CHANGED, self.OnFont, panel.font['fontCtrl'])
4043 
4044  panel.SetSizer(border)
4045 
4046  panel.Fit()
4047  return panel
4048 
4049  def sizePositionFont(self, legendType, parent, mainSizer):
4050  """!Insert widgets for size, position and font control"""
4051  if legendType == 'raster':
4052  legendDict = self.rLegendDict
4053  else:
4054  legendDict = self.vLegendDict
4055  panel = parent
4056  border = mainSizer
4057 
4058  # size and position
4059  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Size and position"))
4060  sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
4061  #unit
4062  self.AddUnits(parent = panel, dialogDict = legendDict)
4063  unitBox = wx.BoxSizer(wx.HORIZONTAL)
4064  unitBox.Add(panel.units['unitsLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.LEFT, border = 10)
4065  unitBox.Add(panel.units['unitsCtrl'], proportion = 1, flag = wx.ALL, border = 5)
4066  sizer.Add(unitBox, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4067 
4068  hBox = wx.BoxSizer(wx.HORIZONTAL)
4069  posBox = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " %_("Position"))
4070  posSizer = wx.StaticBoxSizer(posBox, wx.VERTICAL)
4071  sizeBox = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Size"))
4072  sizeSizer = wx.StaticBoxSizer(sizeBox, wx.VERTICAL)
4073  posGridBagSizer = wx.GridBagSizer(hgap = 10, vgap = 5)
4074  posGridBagSizer.AddGrowableRow(2)
4075 
4076  #position
4077  self.AddPosition(parent = panel, dialogDict = legendDict)
4078 
4079  posGridBagSizer.Add(panel.position['xLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4080  posGridBagSizer.Add(panel.position['xCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4081  posGridBagSizer.Add(panel.position['yLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4082  posGridBagSizer.Add(panel.position['yCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4083  posGridBagSizer.Add(panel.position['comment'], pos = (2,0), span = (1,2), flag =wx.ALIGN_BOTTOM, border = 0)
4084  posSizer.Add(posGridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
4085 
4086  #size
4087  width = wx.StaticText(panel, id = wx.ID_ANY, label = _("Width:"))
4088  if legendDict['width']:
4089  w = self.unitConv.convert(value = float(legendDict['width']), fromUnit = 'inch', toUnit = legendDict['unit'])
4090  else:
4091  w = ''
4092  panel.widthCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, value = str(w), validator = TCValidator("DIGIT_ONLY"))
4093  panel.widthCtrl.SetToolTipString(_("Leave the edit field empty, to use default values."))
4094 
4095  if legendType == 'raster':
4096 ## panel.defaultSize = wx.CheckBox(panel, id = wx.ID_ANY, label = _("Use default size"))
4097 ## panel.defaultSize.SetValue(legendDict['defaultSize'])
4098 
4099  panel.heightOrColumnsLabel = wx.StaticText(panel, id = wx.ID_ANY, label = _("Height:"))
4100  if legendDict['height']:
4101  h = self.unitConv.convert(value = float(legendDict['height']), fromUnit = 'inch', toUnit = legendDict['unit'])
4102  else:
4103  h = ''
4104  panel.heightOrColumnsCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, value = str(h), validator = TCValidator("DIGIT_ONLY"))
4105 
4106  self.rSizeGBSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
4107 ## self.rSizeGBSizer.Add(panel.defaultSize, pos = (0,0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4108  self.rSizeGBSizer.Add(width, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4109  self.rSizeGBSizer.Add(panel.widthCtrl, pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4110  self.rSizeGBSizer.Add(panel.heightOrColumnsLabel, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4111  self.rSizeGBSizer.Add(panel.heightOrColumnsCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4112  sizeSizer.Add(self.rSizeGBSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
4113 
4114  if legendType == 'vector':
4115  panel.widthCtrl.SetToolTipString(_("Width of the color symbol (for lines)\nin front of the legend text"))
4116  #columns
4117  minVect, maxVect = 0, 0
4118  if self.vectorId:
4119  minVect = 1
4120  maxVect = min(10, len(self.instruction[self.vectorId]['list']))
4121  cols = wx.StaticText(panel, id = wx.ID_ANY, label = _("Columns:"))
4122  panel.colsCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, value = "",
4123  min = minVect, max = maxVect, initial = legendDict['cols'])
4124  #span
4125  panel.spanRadio = wx.CheckBox(panel, id = wx.ID_ANY, label = _("column span:"))
4126  panel.spanTextCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, value = '')
4127  panel.spanTextCtrl.SetToolTipString(_("Column separation distance between the left edges\n"\
4128  "of two columns in a multicolumn legend"))
4129  if legendDict['span']:
4130  panel.spanRadio.SetValue(True)
4131  s = self.unitConv.convert(value = float(legendDict['span']), fromUnit = 'inch', toUnit = legendDict['unit'])
4132  panel.spanTextCtrl.SetValue(str(s))
4133  else:
4134  panel.spanRadio.SetValue(False)
4135 
4136  self.vSizeGBSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
4137  self.vSizeGBSizer.AddGrowableCol(1)
4138  self.vSizeGBSizer.Add(width, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4139  self.vSizeGBSizer.Add(panel.widthCtrl, pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4140  self.vSizeGBSizer.Add(cols, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4141  self.vSizeGBSizer.Add(panel.colsCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4142  self.vSizeGBSizer.Add(panel.spanRadio, pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4143  self.vSizeGBSizer.Add(panel.spanTextCtrl, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4144  sizeSizer.Add(self.vSizeGBSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
4145 
4146  hBox.Add(posSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 3)
4147  hBox.Add(sizeSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 3)
4148  sizer.Add(hBox, proportion = 0, flag = wx.EXPAND, border = 0)
4149  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
4150 
4151  # font
4152  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Font settings"))
4153  fontSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
4154  flexSizer = wx.FlexGridSizer (cols = 2, hgap = 5, vgap = 5)
4155  flexSizer.AddGrowableCol(1)
4156 
4157  if legendType == 'raster':
4158  self.AddFont(parent = panel, dialogDict = legendDict, color = True)
4159  else:
4160  self.AddFont(parent = panel, dialogDict = legendDict, color = False)
4161  flexSizer.Add(panel.font['fontLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4162  flexSizer.Add(panel.font['fontCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4163  flexSizer.Add(panel.font['fontSizeLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4164  flexSizer.Add(panel.font['fontSizeCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4165  if legendType == 'raster':
4166  flexSizer.Add(panel.font['colorLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4167  flexSizer.Add(panel.font['colorCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4168 
4169  fontSizer.Add(item = flexSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
4170  border.Add(item = fontSizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
4171 
4172  # some enable/disable methods
4173 
4174  def OnIsLegend(self, event):
4175  """!Enables and disables controls, it depends if raster or vector legend is checked"""
4176  page = self.notebook.GetSelection()
4177  if page == 0 or event is None:
4178  children = self.panelRaster.GetChildren()
4179  if self.isRLegend.GetValue():
4180  for i,widget in enumerate(children):
4181  widget.Enable()
4182  self.OnRaster(None)
4183  self.OnRange(None)
4184  self.OnDiscrete(None)
4185  else:
4186  for widget in children:
4187  if widget.GetName() != 'showRLegend':
4188  widget.Disable()
4189  if page == 1 or event is None:
4190  children = self.panelVector.GetChildren()
4191  if self.isVLegend.GetValue():
4192  for i, widget in enumerate(children):
4193  widget.Enable()
4194  self.OnSpan(None)
4195  self.OnBorder(None)
4196  else:
4197  for widget in children:
4198  if widget.GetName() != 'showVLegend':
4199  widget.Disable()
4200 
4201  def OnRaster(self, event):
4202  if self.rasterDefault.GetValue():#default
4203  self.rasterSelect.Disable()
4204  type = getRasterType(self.currRaster)
4205  else:#select raster
4206  self.rasterSelect.Enable()
4207  map = self.rasterSelect.GetValue()
4208  type = getRasterType(map)
4209 
4210  if type == 'CELL':
4211  self.discrete.SetValue(True)
4212  elif type in ('FCELL', 'DCELL'):
4213  self.continuous.SetValue(True)
4214  if event is None:
4215  if self.rLegendDict['discrete'] == 'y':
4216  self.discrete.SetValue(True)
4217  elif self.rLegendDict['discrete'] == 'n':
4218  self.continuous.SetValue(True)
4219  self.OnDiscrete(None)
4220 
4221  def OnDiscrete(self, event):
4222  """! Change control according to the type of legend"""
4223  enabledSize = self.panelRaster.heightOrColumnsCtrl.IsEnabled()
4224  self.panelRaster.heightOrColumnsCtrl.Destroy()
4225  if self.discrete.GetValue():
4226  self.panelRaster.heightOrColumnsLabel.SetLabel(_("Columns:"))
4227  self.panelRaster.heightOrColumnsCtrl = wx.SpinCtrl(self.panelRaster, id = wx.ID_ANY, value = "", min = 1, max = 10, initial = self.rLegendDict['cols'])
4228  self.panelRaster.heightOrColumnsCtrl.Enable(enabledSize)
4229  self.nodata.Enable()
4230  self.range.Disable()
4231  self.min.Disable()
4232  self.max.Disable()
4233  self.minText.Disable()
4234  self.maxText.Disable()
4235  self.ticks.Disable()
4236  else:
4237  self.panelRaster.heightOrColumnsLabel.SetLabel(_("Height:"))
4238  if self.rLegendDict['height']:
4239  h = self.unitConv.convert(value = float(self.rLegendDict['height']), fromUnit = 'inch', toUnit = self.rLegendDict['unit'])
4240  else:
4241  h = ''
4242  self.panelRaster.heightOrColumnsCtrl = wx.TextCtrl(self.panelRaster, id = wx.ID_ANY,
4243  value = str(h), validator = TCValidator("DIGIT_ONLY"))
4244  self.panelRaster.heightOrColumnsCtrl.Enable(enabledSize)
4245  self.nodata.Disable()
4246  self.range.Enable()
4247  if self.range.GetValue():
4248  self.minText.Enable()
4249  self.maxText.Enable()
4250  self.min.Enable()
4251  self.max.Enable()
4252  self.ticks.Enable()
4253 
4254  self.rSizeGBSizer.Add(self.panelRaster.heightOrColumnsCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4255  self.panelRaster.Layout()
4256  self.panelRaster.Fit()
4257 
4258  def OnRange(self, event):
4259  if not self.range.GetValue():
4260  self.min.Disable()
4261  self.max.Disable()
4262  self.minText.Disable()
4263  self.maxText.Disable()
4264  else:
4265  self.min.Enable()
4266  self.max.Enable()
4267  self.minText.Enable()
4268  self.maxText.Enable()
4269 
4270  def OnUp(self, event):
4271  """!Moves selected map up, changes order in vector legend"""
4272  if self.vectorListCtrl.GetFirstSelected() != -1:
4273  pos = self.vectorListCtrl.GetFirstSelected()
4274  if pos:
4275  idx1 = self.vectorListCtrl.GetItemData(pos) - 1
4276  idx2 = self.vectorListCtrl.GetItemData(pos - 1) + 1
4277  self.vectorListCtrl.SetItemData(pos, idx1)
4278  self.vectorListCtrl.SetItemData(pos - 1, idx2)
4279  self.vectorListCtrl.SortItems(cmp)
4280  if pos > 0:
4281  selected = (pos - 1)
4282  else:
4283  selected = 0
4284 
4285  self.vectorListCtrl.Select(selected)
4286 
4287  def OnDown(self, event):
4288  """!Moves selected map down, changes order in vector legend"""
4289  if self.vectorListCtrl.GetFirstSelected() != -1:
4290  pos = self.vectorListCtrl.GetFirstSelected()
4291  if pos != self.vectorListCtrl.GetItemCount() - 1:
4292  idx1 = self.vectorListCtrl.GetItemData(pos) + 1
4293  idx2 = self.vectorListCtrl.GetItemData(pos + 1) - 1
4294  self.vectorListCtrl.SetItemData(pos, idx1)
4295  self.vectorListCtrl.SetItemData(pos + 1, idx2)
4296  self.vectorListCtrl.SortItems(cmp)
4297  if pos < self.vectorListCtrl.GetItemCount() -1:
4298  selected = (pos + 1)
4299  else:
4300  selected = self.vectorListCtrl.GetItemCount() -1
4301 
4302  self.vectorListCtrl.Select(selected)
4303 
4304  def OnEditLabel(self, event):
4305  """!Change legend label of vector map"""
4306  if self.vectorListCtrl.GetFirstSelected() != -1:
4307  idx = self.vectorListCtrl.GetFirstSelected()
4308  default = self.vectorListCtrl.GetItem(idx, 1).GetText()
4309  dlg = wx.TextEntryDialog(self, message = _("Edit legend label:"), caption = _("Edit label"),
4310  defaultValue = default, style = wx.OK|wx.CANCEL|wx.CENTRE)
4311  if dlg.ShowModal() == wx.ID_OK:
4312  new = dlg.GetValue()
4313  self.vectorListCtrl.SetStringItem(idx, 1, new)
4314  dlg.Destroy()
4315 
4316  def OnSpan(self, event):
4317  self.panelVector.spanTextCtrl.Enable(self.panelVector.spanRadio.GetValue())
4318  def OnFont(self, event):
4319  """!Changes default width according to fontsize, width [inch] = fontsize[pt]/24"""
4320 ## fontsize = self.panelVector.font['fontCtrl'].GetSelectedFont().GetPointSize()
4321  fontsize = self.panelVector.font['fontSizeCtrl'].GetValue()
4322  unit = self.unitConv.findUnit(self.panelVector.units['unitsCtrl'].GetStringSelection())
4323  w = fontsize/24.
4324  width = self.unitConv.convert(value = w, fromUnit = 'inch', toUnit = unit)
4325  self.panelVector.widthCtrl.SetValue("%3.2f" % width)
4326 
4327  def OnBorder(self, event):
4328  """!Enables/disables colorPickerCtrl for border"""
4329  self.borderColorCtrl.Enable(self.borderCheck.GetValue())
4330 
4332  """!Save information from raster legend dialog to dictionary"""
4333 
4334  #is raster legend
4335  if not self.isRLegend.GetValue():
4336  self.rLegendDict['rLegend'] = False
4337  else:
4338  self.rLegendDict['rLegend'] = True
4339  #units
4340  currUnit = self.unitConv.findUnit(self.panelRaster.units['unitsCtrl'].GetStringSelection())
4341  self.rLegendDict['unit'] = currUnit
4342  # raster
4343  if self.rasterDefault.GetValue():
4344  self.rLegendDict['rasterDefault'] = True
4345  self.rLegendDict['raster'] = self.currRaster
4346  else:
4347  self.rLegendDict['rasterDefault'] = False
4348  self.rLegendDict['raster'] = self.rasterSelect.GetValue()
4349  if self.rLegendDict['rLegend'] and not self.rLegendDict['raster']:
4350  wx.MessageBox(message = _("No raster map selected!"),
4351  caption = _('No raster'), style = wx.OK|wx.ICON_ERROR)
4352  return False
4353 
4354  if self.rLegendDict['raster']:
4355  # type and range of map
4356  rasterType = getRasterType(self.rLegendDict['raster'])
4357  if rasterType is None:
4358  return False
4359  self.rLegendDict['type'] = rasterType
4360 
4361 
4362  #discrete
4363  if self.discrete.GetValue():
4364  self.rLegendDict['discrete'] = 'y'
4365  else:
4366  self.rLegendDict['discrete'] = 'n'
4367 
4368  # font
4369  self.rLegendDict['font'] = self.panelRaster.font['fontCtrl'].GetStringSelection()
4370  self.rLegendDict['fontsize'] = self.panelRaster.font['fontSizeCtrl'].GetValue()
4371  color = self.panelRaster.font['colorCtrl'].GetColour()
4372  self.rLegendDict['color'] = convertRGB(color)
4373 
4374  # position
4375  x = self.unitConv.convert(value = float(self.panelRaster.position['xCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
4376  y = self.unitConv.convert(value = float(self.panelRaster.position['yCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
4377  self.rLegendDict['where'] = (x, y)
4378  # estimated size
4379  width = self.panelRaster.widthCtrl.GetValue()
4380  try:
4381  width = float(width)
4382  width = self.unitConv.convert(value = width, fromUnit = currUnit, toUnit = 'inch')
4383  except ValueError:
4384  width = None
4385  self.rLegendDict['width'] = width
4386  if self.rLegendDict['discrete'] == 'n':
4387  height = self.panelRaster.heightOrColumnsCtrl.GetValue()
4388  try:
4389  height = float(height)
4390  height = self.unitConv.convert(value = height, fromUnit = currUnit, toUnit = 'inch')
4391  except ValueError:
4392  height = None
4393  self.rLegendDict['height'] = height
4394  else:
4395  cols = self.panelRaster.heightOrColumnsCtrl.GetValue()
4396  self.rLegendDict['cols'] = cols
4397  drawHeight = self.rasterLegend.EstimateHeight(raster = self.rLegendDict['raster'], discrete = self.rLegendDict['discrete'],
4398  fontsize = self.rLegendDict['fontsize'], cols = self.rLegendDict['cols'],
4399  height = self.rLegendDict['height'])
4400  drawWidth = self.rasterLegend.EstimateWidth(raster = self.rLegendDict['raster'], discrete = self.rLegendDict['discrete'],
4401  fontsize = self.rLegendDict['fontsize'], cols = self.rLegendDict['cols'],
4402  width = self.rLegendDict['width'], paperInstr = self.instruction[self.pageId])
4403  self.rLegendDict['rect'] = wx.Rect2D(x = x, y = y, w = drawWidth, h = drawHeight)
4404 
4405  # no data
4406  if self.rLegendDict['discrete'] == 'y':
4407  if self.nodata.GetValue():
4408  self.rLegendDict['nodata'] = 'y'
4409  else:
4410  self.rLegendDict['nodata'] = 'n'
4411  # tickbar
4412  elif self.rLegendDict['discrete'] == 'n':
4413  if self.ticks.GetValue():
4414  self.rLegendDict['tickbar'] = 'y'
4415  else:
4416  self.rLegendDict['tickbar'] = 'n'
4417  # range
4418  if self.range.GetValue():
4419  self.rLegendDict['range'] = True
4420  self.rLegendDict['min'] = self.min.GetValue()
4421  self.rLegendDict['max'] = self.max.GetValue()
4422  else:
4423  self.rLegendDict['range'] = False
4424 
4425  if not self.id[0] in self.instruction:
4426  rasterLegend = RasterLegend(self.id[0])
4427  self.instruction.AddInstruction(rasterLegend)
4428  self.instruction[self.id[0]].SetInstruction(self.rLegendDict)
4429 
4430  if self.id[0] not in self.parent.objectId:
4431  self.parent.objectId.append(self.id[0])
4432  return True
4433 
4435  """!Save information from vector legend dialog to dictionary"""
4436 
4437  vector = self.instruction.FindInstructionByType('vector')
4438  if vector:
4439  self.vectorId = vector.id
4440  else:
4441  self.vectorId = None
4442 
4443  #is vector legend
4444  if not self.isVLegend.GetValue():
4445  self.vLegendDict['vLegend'] = False
4446  else:
4447  self.vLegendDict['vLegend'] = True
4448  if self.vLegendDict['vLegend'] == True and self.vectorId is not None:
4449  # labels
4450  #reindex order
4451  idx = 1
4452  for item in range(self.vectorListCtrl.GetItemCount()):
4453  if self.vectorListCtrl.IsChecked(item):
4454  self.vectorListCtrl.SetItemData(item, idx)
4455  idx += 1
4456  else:
4457  self.vectorListCtrl.SetItemData(item, 0)
4458  if idx == 1:
4459  self.vLegendDict['vLegend'] = False
4460  else:
4461  vList = self.instruction[self.vectorId]['list']
4462  for i, vector in enumerate(vList):
4463  item = self.vectorListCtrl.FindItem(start = -1, str = vector[0].split('@')[0])
4464  vList[i][3] = self.vectorListCtrl.GetItemData(item)
4465  vList[i][4] = self.vectorListCtrl.GetItem(item, 1).GetText()
4466  vmaps = self.instruction.FindInstructionByType('vProperties', list = True)
4467  for vmap, vector in zip(vmaps, vList):
4468  self.instruction[vmap.id]['lpos'] = vector[3]
4469  self.instruction[vmap.id]['label'] = vector[4]
4470  #units
4471  currUnit = self.unitConv.findUnit(self.panelVector.units['unitsCtrl'].GetStringSelection())
4472  self.vLegendDict['unit'] = currUnit
4473  # position
4474  x = self.unitConv.convert(value = float(self.panelVector.position['xCtrl'].GetValue()),
4475  fromUnit = currUnit, toUnit = 'inch')
4476  y = self.unitConv.convert(value = float(self.panelVector.position['yCtrl'].GetValue()),
4477  fromUnit = currUnit, toUnit = 'inch')
4478  self.vLegendDict['where'] = (x, y)
4479 
4480  # font
4481  self.vLegendDict['font'] = self.panelVector.font['fontCtrl'].GetStringSelection()
4482  self.vLegendDict['fontsize'] = self.panelVector.font['fontSizeCtrl'].GetValue()
4483  dc = wx.ClientDC(self)
4484  font = dc.GetFont()
4485  dc.SetFont(wx.Font(pointSize = self.vLegendDict['fontsize'], family = font.GetFamily(),
4486  style = font.GetStyle(), weight = wx.FONTWEIGHT_NORMAL))
4487  #size
4488  width = self.unitConv.convert(value = float(self.panelVector.widthCtrl.GetValue()),
4489  fromUnit = currUnit, toUnit = 'inch')
4490  self.vLegendDict['width'] = width
4491  self.vLegendDict['cols'] = self.panelVector.colsCtrl.GetValue()
4492  if self.panelVector.spanRadio.GetValue() and self.panelVector.spanTextCtrl.GetValue():
4493  self.vLegendDict['span'] = self.panelVector.spanTextCtrl.GetValue()
4494  else:
4495  self.vLegendDict['span'] = None
4496 
4497  # size estimation
4498  vectors = self.instruction[self.vectorId]['list']
4499  labels = [vector[4] for vector in vectors if vector[3] != 0]
4500  extent = dc.GetTextExtent(max(labels, key = len))
4501  wExtent = self.unitConv.convert(value = extent[0], fromUnit = 'pixel', toUnit = 'inch')
4502  hExtent = self.unitConv.convert(value = extent[1], fromUnit = 'pixel', toUnit = 'inch')
4503  w = (width + wExtent) * self.vLegendDict['cols']
4504  h = len(labels) * hExtent / self.vLegendDict['cols']
4505  h *= 1.1
4506  self.vLegendDict['rect'] = wx.Rect2D(x, y, w, h)
4507 
4508  #border
4509  if self.borderCheck.GetValue():
4510  color = self.borderColorCtrl.GetColour()
4511  self.vLegendDict['border'] = convertRGB(color)
4512 
4513  else:
4514  self.vLegendDict['border'] = 'none'
4515 
4516  if not self.id[1] in self.instruction:
4517  vectorLegend = VectorLegend(self.id[1])
4518  self.instruction.AddInstruction(vectorLegend)
4519  self.instruction[self.id[1]].SetInstruction(self.vLegendDict)
4520  if self.id[1] not in self.parent.objectId:
4521  self.parent.objectId.append(self.id[1])
4522  return True
4523 
4524  def update(self):
4525  okR = self.updateRasterLegend()
4526  okV = self.updateVectorLegend()
4527  if okR and okV:
4528  return True
4529  return False
4530 
4531  def updateDialog(self):
4532  """!Update legend coordinates after moving"""
4533 
4534  # raster legend
4535  if 'rect' in self.rLegendDict:
4536  x, y = self.rLegendDict['rect'][:2]
4537  currUnit = self.unitConv.findUnit(self.panelRaster.units['unitsCtrl'].GetStringSelection())
4538  x = self.unitConv.convert(value = x, fromUnit = 'inch', toUnit = currUnit)
4539  y = self.unitConv.convert(value = y, fromUnit = 'inch', toUnit = currUnit)
4540  self.panelRaster.position['xCtrl'].SetValue("%5.3f" % x)
4541  self.panelRaster.position['yCtrl'].SetValue("%5.3f" % y)
4542  #update name and type of raster
4543  raster = self.instruction.FindInstructionByType('raster')
4544  if raster:
4545  self.rasterId = raster.id
4546  else:
4547  self.rasterId = None
4548 
4549  if raster:
4550  currRaster = raster['raster']
4551  else:
4552  currRaster = None
4553 
4554  rasterType = getRasterType(map = currRaster)
4555  self.rasterCurrent.SetLabel(_("%(rast)s: type %(type)s") % \
4556  { 'rast' : currRaster, 'type' : str(rasterType) })
4557 
4558  # vector legend
4559  if 'rect' in self.vLegendDict:
4560  x, y = self.vLegendDict['rect'][:2]
4561  currUnit = self.unitConv.findUnit(self.panelVector.units['unitsCtrl'].GetStringSelection())
4562  x = self.unitConv.convert(value = x, fromUnit = 'inch', toUnit = currUnit)
4563  y = self.unitConv.convert(value = y, fromUnit = 'inch', toUnit = currUnit)
4564  self.panelVector.position['xCtrl'].SetValue("%5.3f" % x)
4565  self.panelVector.position['yCtrl'].SetValue("%5.3f" % y)
4566  # update vector maps
4567  if self.instruction.FindInstructionByType('vector'):
4568  vectors = sorted(self.instruction.FindInstructionByType('vector')['list'], key = lambda x: x[3])
4569  self.vectorListCtrl.DeleteAllItems()
4570  for vector in vectors:
4571  index = self.vectorListCtrl.InsertStringItem(sys.maxint, vector[0].split('@')[0])
4572  self.vectorListCtrl.SetStringItem(index, 1, vector[4])
4573  self.vectorListCtrl.SetItemData(index, index)
4574  self.vectorListCtrl.CheckItem(index, True)
4575  if vector[3] == 0:
4576  self.vectorListCtrl.CheckItem(index, False)
4577  self.panelVector.colsCtrl.SetRange(1, min(10, len(self.instruction.FindInstructionByType('vector')['list'])))
4578  self.panelVector.colsCtrl.SetValue(1)
4579  else:
4580  self.vectorListCtrl.DeleteAllItems()
4581  self.panelVector.colsCtrl.SetRange(0,0)
4582  self.panelVector.colsCtrl.SetValue(0)
4583 
4585  def __init__(self, parent, id, settings):
4586  PsmapDialog.__init__(self, parent = parent, id = id, title = "Mapinfo settings", settings = settings)
4587 
4588  self.objectType = ('mapinfo',)
4589  if self.id is not None:
4590  self.mapinfo = self.instruction[self.id]
4591  self.mapinfoDict = self.mapinfo.GetInstruction()
4592  else:
4593  self.id = wx.NewId()
4594  self.mapinfo = Mapinfo(self.id)
4595  self.mapinfoDict = self.mapinfo.GetInstruction()
4596  page = self.instruction.FindInstructionByType('page').GetInstruction()
4597  self.mapinfoDict['where'] = page['Left'], page['Top']
4598 
4599  self.panel = self._mapinfoPanel()
4600 
4601  self._layout(self.panel)
4602  self.OnIsBackground(None)
4603  self.OnIsBorder(None)
4604 
4605  def _mapinfoPanel(self):
4606  panel = wx.Panel(parent = self, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
4607  #panel.SetupScrolling(scroll_x = False, scroll_y = True)
4608  border = wx.BoxSizer(wx.VERTICAL)
4609 
4610  # position
4611  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Position"))
4612  sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
4613  gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
4614  gridBagSizer.AddGrowableCol(1)
4615 
4616  self.AddPosition(parent = panel, dialogDict = self.mapinfoDict)
4617  self.AddUnits(parent = panel, dialogDict = self.mapinfoDict)
4618  gridBagSizer.Add(panel.units['unitsLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4619  gridBagSizer.Add(panel.units['unitsCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4620  gridBagSizer.Add(panel.position['xLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4621  gridBagSizer.Add(panel.position['xCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4622  gridBagSizer.Add(panel.position['yLabel'], pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4623  gridBagSizer.Add(panel.position['yCtrl'], pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4624  gridBagSizer.Add(panel.position['comment'], pos = (3,0), span = (1,2), flag =wx.ALIGN_BOTTOM, border = 0)
4625 
4626  sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
4627  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
4628 
4629  # font
4630  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Font settings"))
4631  sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
4632  gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
4633  gridBagSizer.AddGrowableCol(1)
4634 
4635  self.AddFont(parent = panel, dialogDict = self.mapinfoDict)#creates font color too, used below
4636 
4637  gridBagSizer.Add(panel.font['fontLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4638  gridBagSizer.Add(panel.font['fontCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4639  gridBagSizer.Add(panel.font['fontSizeLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4640  gridBagSizer.Add(panel.font['fontSizeCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4641  gridBagSizer.Add(panel.font['colorLabel'], pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4642  gridBagSizer.Add(panel.font['colorCtrl'], pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4643 
4644  sizer.Add(item = gridBagSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
4645  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
4646 
4647  # colors
4648  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " %_("Color settings"))
4649  sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
4650  flexSizer = wx.FlexGridSizer (cols = 2, hgap = 5, vgap = 5)
4651  flexSizer.AddGrowableCol(1)
4652 
4653  self.colors = {}
4654  self.colors['borderCtrl'] = wx.CheckBox(panel, id = wx.ID_ANY, label = _("use border color:"))
4655  self.colors['backgroundCtrl'] = wx.CheckBox(panel, id = wx.ID_ANY, label = _("use background color:"))
4656  self.colors['borderColor'] = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
4657  self.colors['backgroundColor'] = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
4658 
4659  if self.mapinfoDict['border'] == None:
4660  self.mapinfoDict['border'] = 'none'
4661  if self.mapinfoDict['border'] != 'none':
4662  self.colors['borderCtrl'].SetValue(True)
4663  self.colors['borderColor'].SetColour(convertRGB(self.mapinfoDict['border']))
4664  else:
4665  self.colors['borderCtrl'].SetValue(False)
4666  self.colors['borderColor'].SetColour(convertRGB('black'))
4667 
4668  if self.mapinfoDict['background'] == None:
4669  self.mapinfoDict['background'] == 'none'
4670  if self.mapinfoDict['background'] != 'none':
4671  self.colors['backgroundCtrl'].SetValue(True)
4672  self.colors['backgroundColor'].SetColour(convertRGB(self.mapinfoDict['background']))
4673  else:
4674  self.colors['backgroundCtrl'].SetValue(False)
4675  self.colors['backgroundColor'].SetColour(convertRGB('white'))
4676 
4677  flexSizer.Add(self.colors['borderCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4678  flexSizer.Add(self.colors['borderColor'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4679  flexSizer.Add(self.colors['backgroundCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4680  flexSizer.Add(self.colors['backgroundColor'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4681 
4682  sizer.Add(item = flexSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
4683  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
4684 
4685  panel.SetSizer(border)
4686 
4687  self.Bind(wx.EVT_CHECKBOX, self.OnIsBorder, self.colors['borderCtrl'])
4688  self.Bind(wx.EVT_CHECKBOX, self.OnIsBackground, self.colors['backgroundCtrl'])
4689 
4690  return panel
4691 
4692  def OnIsBackground(self, event):
4693  if self.colors['backgroundCtrl'].GetValue():
4694  self.colors['backgroundColor'].Enable()
4695  self.update()
4696  else:
4697  self.colors['backgroundColor'].Disable()
4698 
4699  def OnIsBorder(self, event):
4700  if self.colors['borderCtrl'].GetValue():
4701  self.colors['borderColor'].Enable()
4702  self.update()
4703  else:
4704  self.colors['borderColor'].Disable()
4705 
4706  def update(self):
4707 
4708  #units
4709  currUnit = self.unitConv.findUnit(self.panel.units['unitsCtrl'].GetStringSelection())
4710  self.mapinfoDict['unit'] = currUnit
4711 
4712  # position
4713  if self.panel.position['xCtrl'].GetValue():
4714  x = self.panel.position['xCtrl'].GetValue()
4715  else:
4716  x = self.mapinfoDict['where'][0]
4717 
4718  if self.panel.position['yCtrl'].GetValue():
4719  y = self.panel.position['yCtrl'].GetValue()
4720  else:
4721  y = self.mapinfoDict['where'][1]
4722 
4723  x = self.unitConv.convert(value = float(self.panel.position['xCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
4724  y = self.unitConv.convert(value = float(self.panel.position['yCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
4725  self.mapinfoDict['where'] = (x, y)
4726 
4727  # font
4728  self.mapinfoDict['font'] = self.panel.font['fontCtrl'].GetStringSelection()
4729  self.mapinfoDict['fontsize'] = self.panel.font['fontSizeCtrl'].GetValue()
4730 
4731  #colors
4732  color = self.panel.font['colorCtrl'].GetColour()
4733  self.mapinfoDict['color'] = convertRGB(color)
4734 
4735  if self.colors['backgroundCtrl'].GetValue():
4736  background = self.colors['backgroundColor'].GetColour()
4737  self.mapinfoDict['background'] = convertRGB(background)
4738  else:
4739  self.mapinfoDict['background'] = 'none'
4740 
4741  if self.colors['borderCtrl'].GetValue():
4742  border = self.colors['borderColor'].GetColour()
4743  self.mapinfoDict['border'] = convertRGB(border)
4744  else:
4745  self.mapinfoDict['border'] = 'none'
4746 
4747  # estimation of size
4748  self.mapinfoDict['rect'] = self.mapinfo.EstimateRect(self.mapinfoDict)
4749 
4750  if self.id not in self.instruction:
4751  mapinfo = Mapinfo(self.id)
4752  self.instruction.AddInstruction(mapinfo)
4753 
4754  self.instruction[self.id].SetInstruction(self.mapinfoDict)
4755 
4756  if self.id not in self.parent.objectId:
4757  self.parent.objectId.append(self.id)
4758 
4759  self.updateDialog()
4760 
4761  return True
4762 
4763  def updateDialog(self):
4764  """!Update mapinfo coordinates, after moving"""
4765  x, y = self.mapinfoDict['where']
4766  currUnit = self.unitConv.findUnit(self.panel.units['unitsCtrl'].GetStringSelection())
4767  x = self.unitConv.convert(value = x, fromUnit = 'inch', toUnit = currUnit)
4768  y = self.unitConv.convert(value = y, fromUnit = 'inch', toUnit = currUnit)
4769  self.panel.position['xCtrl'].SetValue("%5.3f" % x)
4770  self.panel.position['yCtrl'].SetValue("%5.3f" % y)
4771 
4773  """!Dialog for scale bar"""
4774  def __init__(self, parent, id, settings):
4775  PsmapDialog.__init__(self, parent = parent, id = id, title = "Scale bar settings", settings = settings)
4776  self.objectType = ('scalebar',)
4777  if self.id is not None:
4778  self.scalebar = self.instruction[id]
4779  self.scalebarDict = self.scalebar.GetInstruction()
4780  else:
4781  self.id = wx.NewId()
4782  self.scalebar = Scalebar(self.id)
4783  self.scalebarDict = self.scalebar.GetInstruction()
4784  page = self.instruction.FindInstructionByType('page').GetInstruction()
4785  self.scalebarDict['where'] = page['Left'], page['Top']
4786 
4787  self.panel = self._scalebarPanel()
4788 
4789  self._layout(self.panel)
4790 
4791  self.mapUnit = projInfo()['units'].lower()
4792  if projInfo()['proj'] == 'xy':
4793  self.mapUnit = 'meters'
4794  if self.mapUnit not in self.unitConv.getAllUnits():
4795  wx.MessageBox(message = _("Units of current projection are not supported,\n meters will be used!"),
4796  caption = _('Unsupported units'),
4797  style = wx.OK|wx.ICON_ERROR)
4798  self.mapUnit = 'meters'
4799 
4800  def _scalebarPanel(self):
4801  panel = wx.Panel(parent = self, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
4802  border = wx.BoxSizer(wx.VERTICAL)
4803  #
4804  # position
4805  #
4806  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Position"))
4807  sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
4808  gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
4809  gridBagSizer.AddGrowableCol(1)
4810 
4811  self.AddUnits(parent = panel, dialogDict = self.scalebarDict)
4812  self.AddPosition(parent = panel, dialogDict = self.scalebarDict)
4813 
4814  if self.scalebarDict['rect']: # set position, ref point is center and not left top corner
4815 
4816  x = self.unitConv.convert(value = self.scalebarDict['where'][0] - self.scalebarDict['rect'].Get()[2]/2,
4817  fromUnit = 'inch', toUnit = self.scalebarDict['unit'])
4818  y = self.unitConv.convert(value = self.scalebarDict['where'][1] - self.scalebarDict['rect'].Get()[3]/2,
4819  fromUnit = 'inch', toUnit = self.scalebarDict['unit'])
4820  panel.position['xCtrl'].SetValue("%5.3f" % x)
4821  panel.position['yCtrl'].SetValue("%5.3f" % y)
4822 
4823  gridBagSizer.Add(panel.units['unitsLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4824  gridBagSizer.Add(panel.units['unitsCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4825  gridBagSizer.Add(panel.position['xLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4826  gridBagSizer.Add(panel.position['xCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4827  gridBagSizer.Add(panel.position['yLabel'], pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4828  gridBagSizer.Add(panel.position['yCtrl'], pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4829  gridBagSizer.Add(panel.position['comment'], pos = (3,0), span = (1,2), flag =wx.ALIGN_BOTTOM, border = 0)
4830 
4831  sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
4832  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
4833  #
4834  # size
4835  #
4836  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Size"))
4837  sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
4838  gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
4839  gridBagSizer.AddGrowableCol(1)
4840 
4841  lengthText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Length:"))
4842  heightText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Height:"))
4843 
4844  self.lengthTextCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, validator = TCValidator('DIGIT_ONLY'))
4845  self.lengthTextCtrl.SetToolTipString(_("Scalebar length is given in map units"))
4846 
4847  self.heightTextCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, validator = TCValidator('DIGIT_ONLY'))
4848  self.heightTextCtrl.SetToolTipString(_("Scalebar height is real height on paper"))
4849 
4850  choices = [_('default')] + self.unitConv.getMapUnitsNames()
4851  self.unitsLength = wx.Choice(panel, id = wx.ID_ANY, choices = choices)
4852  choices = self.unitConv.getPageUnitsNames()
4853  self.unitsHeight = wx.Choice(panel, id = wx.ID_ANY, choices = choices)
4854 
4855  # set values
4856  unitName = self.unitConv.findName(self.scalebarDict['unitsLength'])
4857  if unitName:
4858  self.unitsLength.SetStringSelection(unitName)
4859  else:
4860  if self.scalebarDict['unitsLength'] == 'auto':
4861  self.unitsLength.SetSelection(0)
4862  elif self.scalebarDict['unitsLength'] == 'nautmiles':
4863  self.unitsLength.SetStringSelection(self.unitConv.findName("nautical miles"))
4864  self.unitsHeight.SetStringSelection(self.unitConv.findName(self.scalebarDict['unitsHeight']))
4865  if self.scalebarDict['length']:
4866  self.lengthTextCtrl.SetValue(str(self.scalebarDict['length']))
4867  else: #estimate default
4868  reg = grass.region()
4869  w = int((reg['e'] - reg['w'])/3)
4870  w = round(w, -len(str(w)) + 2) #12345 -> 12000
4871  self.lengthTextCtrl.SetValue(str(w))
4872 
4873  h = self.unitConv.convert(value = self.scalebarDict['height'], fromUnit = 'inch',
4874  toUnit = self.scalebarDict['unitsHeight'])
4875  self.heightTextCtrl.SetValue(str(h))
4876 
4877  gridBagSizer.Add(lengthText, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4878  gridBagSizer.Add(self.lengthTextCtrl, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4879  gridBagSizer.Add(self.unitsLength, pos = (0, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
4880  gridBagSizer.Add(heightText, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4881  gridBagSizer.Add(self.heightTextCtrl, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4882  gridBagSizer.Add(self.unitsHeight, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
4883 
4884  sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
4885  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
4886  #
4887  #style
4888  #
4889  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Style"))
4890  sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
4891  gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
4892 
4893 
4894  sbTypeText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Type:"))
4895  self.sbCombo = wx.combo.BitmapComboBox(panel, style = wx.CB_READONLY)
4896  # only temporary, images must be moved away
4897  imagePath = os.path.join(globalvar.ETCIMGDIR, "scalebar-fancy.png"), os.path.join(globalvar.ETCIMGDIR, "scalebar-simple.png")
4898  for item, path in zip(['fancy', 'simple'], imagePath):
4899  if not os.path.exists(path):
4900  bitmap = wx.EmptyBitmap(0,0)
4901  else:
4902  bitmap = wx.Bitmap(path)
4903  self.sbCombo.Append(item = '', bitmap = bitmap, clientData = item[0])
4904  #self.sbCombo.Append(item = 'simple', bitmap = wx.Bitmap("./images/scalebar-simple.png"), clientData = 's')
4905  if self.scalebarDict['scalebar'] == 'f':
4906  self.sbCombo.SetSelection(0)
4907  elif self.scalebarDict['scalebar'] == 's':
4908  self.sbCombo.SetSelection(1)
4909 
4910  sbSegmentsText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Number of segments:"))
4911  self.sbSegmentsCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 30, initial = 4)
4912  self.sbSegmentsCtrl.SetValue(self.scalebarDict['segment'])
4913 
4914  sbLabelsText1 = wx.StaticText(panel, id = wx.ID_ANY, label = _("Label every "))
4915  sbLabelsText2 = wx.StaticText(panel, id = wx.ID_ANY, label = _("segments"))
4916  self.sbLabelsCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 30, initial = 1)
4917  self.sbLabelsCtrl.SetValue(self.scalebarDict['numbers'])
4918 
4919  #font
4920  fontsizeText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Font size:"))
4921  self.fontsizeCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 4, max = 30, initial = 10)
4922  self.fontsizeCtrl.SetValue(self.scalebarDict['fontsize'])
4923 
4924  self.backgroundCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("transparent text background"))
4925  if self.scalebarDict['background'] == 'y':
4926  self.backgroundCheck.SetValue(False)
4927  else:
4928  self.backgroundCheck.SetValue(True)
4929 
4930  gridBagSizer.Add(sbTypeText, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4931  gridBagSizer.Add(self.sbCombo, pos = (0,1), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
4932  gridBagSizer.Add(sbSegmentsText, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4933  gridBagSizer.Add(self.sbSegmentsCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4934  gridBagSizer.Add(sbLabelsText1, pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4935  gridBagSizer.Add(self.sbLabelsCtrl, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4936  gridBagSizer.Add(sbLabelsText2, pos = (2,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4937  gridBagSizer.Add(fontsizeText, pos = (3,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4938  gridBagSizer.Add(self.fontsizeCtrl, pos = (3,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4939  gridBagSizer.Add(self.backgroundCheck, pos = (4, 0), span = (1,3), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
4940 
4941  sizer.Add(gridBagSizer, proportion = 1, flag = wx.ALIGN_CENTER_VERTICAL, border = 5)
4942  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
4943 
4944  panel.SetSizer(border)
4945 
4946  return panel
4947 
4948  def update(self):
4949  """!Save information from dialog"""
4950 
4951  #units
4952  currUnit = self.unitConv.findUnit(self.panel.units['unitsCtrl'].GetStringSelection())
4953  self.scalebarDict['unit'] = currUnit
4954  # position
4955  if self.panel.position['xCtrl'].GetValue():
4956  x = self.panel.position['xCtrl'].GetValue()
4957  else:
4958  x = self.scalebarDict['where'][0]
4959 
4960  if self.panel.position['yCtrl'].GetValue():
4961  y = self.panel.position['yCtrl'].GetValue()
4962  else:
4963  y = self.scalebarDict['where'][1]
4964 
4965  x = self.unitConv.convert(value = float(self.panel.position['xCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
4966  y = self.unitConv.convert(value = float(self.panel.position['yCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
4967 
4968  #style
4969  self.scalebarDict['scalebar'] = self.sbCombo.GetClientData(self.sbCombo.GetSelection())
4970  self.scalebarDict['segment'] = self.sbSegmentsCtrl.GetValue()
4971  self.scalebarDict['numbers'] = self.sbLabelsCtrl.GetValue()
4972  self.scalebarDict['fontsize'] = self.fontsizeCtrl.GetValue()
4973  if self.backgroundCheck.GetValue():
4974  self.scalebarDict['background'] = 'n'
4975  else:
4976  self.scalebarDict['background'] = 'y'
4977 
4978 
4979  # size
4980 
4981  # height
4982  self.scalebarDict['unitsHeight'] = self.unitConv.findUnit(self.unitsHeight.GetStringSelection())
4983  try:
4984  height = float(self.heightTextCtrl.GetValue())
4985  height = self.unitConv.convert(value = height, fromUnit = self.scalebarDict['unitsHeight'], toUnit = 'inch')
4986  except (ValueError, SyntaxError):
4987  height = 0.1 #default in inch
4988  self.scalebarDict['height'] = height
4989 
4990  #length
4991  if self.unitsLength.GetSelection() == 0:
4992  selected = 'auto'
4993  else:
4994  selected = self.unitConv.findUnit(self.unitsLength.GetStringSelection())
4995  if selected == 'nautical miles':
4996  selected = 'nautmiles'
4997  self.scalebarDict['unitsLength'] = selected
4998  try:
4999  length = float(self.lengthTextCtrl.GetValue())
5000  except (ValueError, SyntaxError):
5001  wx.MessageBox(message = _("Length of scale bar is not defined"),
5002  caption = _('Invalid input'), style = wx.OK|wx.ICON_ERROR)
5003  return False
5004  self.scalebarDict['length'] = length
5005 
5006  # estimation of size
5007  map = self.instruction.FindInstructionByType('map')
5008  if not map:
5009  map = self.instruction.FindInstructionByType('initMap')
5010  mapId = map.id
5011 
5012  rectSize = self.scalebar.EstimateSize(scalebarDict = self.scalebarDict,
5013  scale = self.instruction[mapId]['scale'])
5014  self.scalebarDict['rect'] = wx.Rect2D(x = x, y = y, w = rectSize[0], h = rectSize[1])
5015  self.scalebarDict['where'] = self.scalebarDict['rect'].GetCentre()
5016 
5017  if self.id not in self.instruction:
5018  scalebar = Scalebar(self.id)
5019  self.instruction.AddInstruction(scalebar)
5020  self.instruction[self.id].SetInstruction(self.scalebarDict)
5021  if self.id not in self.parent.objectId:
5022  self.parent.objectId.append(self.id)
5023 
5024  return True
5025 
5026  def updateDialog(self):
5027  """!Update scalebar coordinates, after moving"""
5028  x, y = self.scalebarDict['rect'][:2]
5029  currUnit = self.unitConv.findUnit(self.panel.units['unitsCtrl'].GetStringSelection())
5030  x = self.unitConv.convert(value = x, fromUnit = 'inch', toUnit = currUnit)
5031  y = self.unitConv.convert(value = y, fromUnit = 'inch', toUnit = currUnit)
5032  self.panel.position['xCtrl'].SetValue("%5.3f" % x)
5033  self.panel.position['yCtrl'].SetValue("%5.3f" % y)
5034 
5035 
5036 
5038  def __init__(self, parent, id, settings):
5039  PsmapDialog.__init__(self, parent = parent, id = id, title = "Text settings", settings = settings)
5040  self.objectType = ('text',)
5041  if self.id is not None:
5042  self.textDict = self.instruction[id].GetInstruction()
5043  else:
5044  self.id = wx.NewId()
5045  text = Text(self.id)
5046  self.textDict = text.GetInstruction()
5047  page = self.instruction.FindInstructionByType('page').GetInstruction()
5048  self.textDict['where'] = page['Left'], page['Top']
5049 
5050  map = self.instruction.FindInstructionByType('map')
5051  if not map:
5052  map = self.instruction.FindInstructionByType('initMap')
5053  self.mapId = map.id
5054 
5055  self.textDict['east'], self.textDict['north'] = PaperMapCoordinates(map = map, x = self.textDict['where'][0], y = self.textDict['where'][1], paperToMap = True)
5056 
5057  notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT)
5058  self.textPanel = self._textPanel(notebook)
5059  self.positionPanel = self._positionPanel(notebook)
5060  self.OnBackground(None)
5061  self.OnHighlight(None)
5062  self.OnBorder(None)
5063  self.OnPositionType(None)
5064  self.OnRotation(None)
5065 
5066  self._layout(notebook)
5067 
5068  def _textPanel(self, notebook):
5069  panel = wx.Panel(parent = notebook, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
5070  notebook.AddPage(page = panel, text = _("Text"))
5071 
5072  border = wx.BoxSizer(wx.VERTICAL)
5073 
5074  # text entry
5075  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Text"))
5076  sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
5077 
5078  textLabel = wx.StaticText(panel, id = wx.ID_ANY, label = _("Enter text:"))
5079  self.textCtrl = ExpandoTextCtrl(panel, id = wx.ID_ANY, value = self.textDict['text'])
5080 
5081  sizer.Add(textLabel, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
5082  sizer.Add(self.textCtrl, proportion = 1, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
5083  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
5084 
5085  #font
5086  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Font settings"))
5087  sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
5088  flexGridSizer = wx.FlexGridSizer (rows = 3, cols = 2, hgap = 5, vgap = 5)
5089  flexGridSizer.AddGrowableCol(1)
5090 
5091  self.AddFont(parent = panel, dialogDict = self.textDict)
5092 
5093  flexGridSizer.Add(panel.font['fontLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5094  flexGridSizer.Add(panel.font['fontCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5095  flexGridSizer.Add(panel.font['fontSizeLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5096  flexGridSizer.Add(panel.font['fontSizeCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5097  flexGridSizer.Add(panel.font['colorLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5098  flexGridSizer.Add(panel.font['colorCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5099 
5100  sizer.Add(item = flexGridSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
5101  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
5102 
5103  #text effects
5104  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Text effects"))
5105  sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
5106  gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
5107 
5108  self.effect = {}
5109  self.effect['backgroundCtrl'] = wx.CheckBox(panel, id = wx.ID_ANY, label = _("text background"))
5110  self.effect['backgroundColor'] = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
5111 
5112  self.effect['highlightCtrl'] = wx.CheckBox(panel, id = wx.ID_ANY, label = _("highlight"))
5113  self.effect['highlightColor'] = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
5114  self.effect['highlightWidth'] = wx.SpinCtrl(panel, id = wx.ID_ANY, size = self.spinCtrlSize, min = 0, max = 5, initial = 1)
5115  self.effect['highlightWidthLabel'] = wx.StaticText(panel, id = wx.ID_ANY, label = _("Width (pts):"))
5116 
5117  self.effect['borderCtrl'] = wx.CheckBox(panel, id = wx.ID_ANY, label = _("text border"))
5118  self.effect['borderColor'] = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
5119  self.effect['borderWidth'] = wx.SpinCtrl(panel, id = wx.ID_ANY, size = self.spinCtrlSize, min = 1, max = 25, initial = 1)
5120  self.effect['borderWidthLabel'] = wx.StaticText(panel, id = wx.ID_ANY, label = _("Width (pts):"))
5121 
5122  #set values
5123  if self.textDict['background'] == None:
5124  self.textDict['background'] = 'none'
5125  if self.textDict['background'] != 'none':
5126  self.effect['backgroundCtrl'].SetValue(True)
5127  self.effect['backgroundColor'].SetColour(convertRGB(self.textDict['background']))
5128  else:
5129  self.effect['backgroundCtrl'].SetValue(False)
5130  self.effect['backgroundColor'].SetColour(convertRGB('white'))
5131 
5132  if self.textDict['hcolor'] == None:
5133  self.textDict['hcolor'] = 'none'
5134  if self.textDict['hcolor'] != 'none':
5135  self.effect['highlightCtrl'].SetValue(True)
5136  self.effect['highlightColor'].SetColour(convertRGB(self.textDict['hcolor']))
5137  else:
5138  self.effect['highlightCtrl'].SetValue(False)
5139  self.effect['highlightColor'].SetColour(convertRGB('grey'))
5140 
5141  self.effect['highlightWidth'].SetValue(float(self.textDict['hwidth']))
5142 
5143  if self.textDict['border'] == None:
5144  self.textDict['border'] = 'none'
5145  if self.textDict['border'] != 'none':
5146  self.effect['borderCtrl'].SetValue(True)
5147  self.effect['borderColor'].SetColour(convertRGB(self.textDict['border']))
5148  else:
5149  self.effect['borderCtrl'].SetValue(False)
5150  self.effect['borderColor'].SetColour(convertRGB('black'))
5151 
5152  self.effect['borderWidth'].SetValue(float(self.textDict['width']))
5153 
5154  gridBagSizer.Add(self.effect['backgroundCtrl'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5155  gridBagSizer.Add(self.effect['backgroundColor'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5156  gridBagSizer.Add(self.effect['highlightCtrl'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5157  gridBagSizer.Add(self.effect['highlightColor'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5158  gridBagSizer.Add(self.effect['highlightWidthLabel'], pos = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5159  gridBagSizer.Add(self.effect['highlightWidth'], pos = (1,3), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5160  gridBagSizer.Add(self.effect['borderCtrl'], pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5161  gridBagSizer.Add(self.effect['borderColor'], pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5162  gridBagSizer.Add(self.effect['borderWidthLabel'], pos = (2,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5163  gridBagSizer.Add(self.effect['borderWidth'], pos = (2,3), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5164 
5165  sizer.Add(item = gridBagSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
5166  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
5167 
5168  self.Bind(EVT_ETC_LAYOUT_NEEDED, self.OnRefit, self.textCtrl)
5169  self.Bind(wx.EVT_CHECKBOX, self.OnBackground, self.effect['backgroundCtrl'])
5170  self.Bind(wx.EVT_CHECKBOX, self.OnHighlight, self.effect['highlightCtrl'])
5171  self.Bind(wx.EVT_CHECKBOX, self.OnBorder, self.effect['borderCtrl'])
5172 
5173  panel.SetSizer(border)
5174  panel.Fit()
5175 
5176  return panel
5177 
5178  def _positionPanel(self, notebook):
5179  panel = wx.Panel(parent = notebook, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
5180  notebook.AddPage(page = panel, text = _("Position"))
5181 
5182  border = wx.BoxSizer(wx.VERTICAL)
5183 
5184  #Position
5185  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Position"))
5186  sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
5187  gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
5188  gridBagSizer.AddGrowableCol(0)
5189  gridBagSizer.AddGrowableCol(1)
5190 
5191  self.positionLabel = wx.StaticText(panel, id = wx.ID_ANY, label = _("Position is given:"))
5192  self.paperPositionCtrl = wx.RadioButton(panel, id = wx.ID_ANY, label = _("relatively to paper"), style = wx.RB_GROUP)
5193  self.mapPositionCtrl = wx.RadioButton(panel, id = wx.ID_ANY, label = _("by map coordinates"))
5194  self.paperPositionCtrl.SetValue(self.textDict['XY'])
5195  self.mapPositionCtrl.SetValue(not self.textDict['XY'])
5196 
5197  gridBagSizer.Add(self.positionLabel, pos = (0,0), span = (1,3), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT, border = 0)
5198  gridBagSizer.Add(self.paperPositionCtrl, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT, border = 0)
5199  gridBagSizer.Add(self.mapPositionCtrl, pos = (1,1),flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT, border = 0)
5200 
5201  # first box - paper coordinates
5202  box1 = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = "")
5203  sizerP = wx.StaticBoxSizer(box1, wx.VERTICAL)
5204  self.gridBagSizerP = wx.GridBagSizer (hgap = 5, vgap = 5)
5205  self.gridBagSizerP.AddGrowableCol(1)
5206  self.gridBagSizerP.AddGrowableRow(3)
5207 
5208  self.AddPosition(parent = panel, dialogDict = self.textDict)
5209  panel.position['comment'].SetLabel(_("Position from the top left\nedge of the paper"))
5210  self.AddUnits(parent = panel, dialogDict = self.textDict)
5211  self.gridBagSizerP.Add(panel.units['unitsLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5212  self.gridBagSizerP.Add(panel.units['unitsCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5213  self.gridBagSizerP.Add(panel.position['xLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5214  self.gridBagSizerP.Add(panel.position['xCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5215  self.gridBagSizerP.Add(panel.position['yLabel'], pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5216  self.gridBagSizerP.Add(panel.position['yCtrl'], pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5217  self.gridBagSizerP.Add(panel.position['comment'], pos = (3,0), span = (1,2), flag = wx.ALIGN_BOTTOM, border = 0)
5218 
5219  sizerP.Add(self.gridBagSizerP, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
5220  gridBagSizer.Add(sizerP, pos = (2,0),span = (1,1), flag = wx.ALIGN_CENTER_HORIZONTAL|wx.EXPAND, border = 0)
5221 
5222  # second box - map coordinates
5223  box2 = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = "")
5224  sizerM = wx.StaticBoxSizer(box2, wx.VERTICAL)
5225  self.gridBagSizerM = wx.GridBagSizer (hgap = 5, vgap = 5)
5226  self.gridBagSizerM.AddGrowableCol(0)
5227  self.gridBagSizerM.AddGrowableCol(1)
5228 
5229  self.eastingLabel = wx.StaticText(panel, id = wx.ID_ANY, label = "E:")
5230  self.northingLabel = wx.StaticText(panel, id = wx.ID_ANY, label = "N:")
5231  self.eastingCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, value = "")
5232  self.northingCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, value = "")
5233  east, north = PaperMapCoordinates(map = self.instruction[self.mapId], x = self.textDict['where'][0], y = self.textDict['where'][1], paperToMap = True)
5234  self.eastingCtrl.SetValue(str(east))
5235  self.northingCtrl.SetValue(str(north))
5236 
5237  self.gridBagSizerM.Add(self.eastingLabel, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5238  self.gridBagSizerM.Add(self.northingLabel, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5239  self.gridBagSizerM.Add(self.eastingCtrl, pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5240  self.gridBagSizerM.Add(self.northingCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5241 
5242  sizerM.Add(self.gridBagSizerM, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
5243  gridBagSizer.Add(sizerM, pos = (2,1), flag = wx.ALIGN_LEFT|wx.EXPAND, border = 0)
5244 
5245  #offset
5246  box3 = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " %_("Offset"))
5247  sizerO = wx.StaticBoxSizer(box3, wx.VERTICAL)
5248  gridBagSizerO = wx.GridBagSizer (hgap = 5, vgap = 5)
5249  self.xoffLabel = wx.StaticText(panel, id = wx.ID_ANY, label = _("horizontal (pts):"))
5250  self.yoffLabel = wx.StaticText(panel, id = wx.ID_ANY, label = _("vertical (pts):"))
5251  self.xoffCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, size = (50, -1), min = -50, max = 50, initial = 0)
5252  self.yoffCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, size = (50, -1), min = -50, max = 50, initial = 0)
5253  self.xoffCtrl.SetValue(self.textDict['xoffset'])
5254  self.yoffCtrl.SetValue(self.textDict['yoffset'])
5255  gridBagSizerO.Add(self.xoffLabel, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5256  gridBagSizerO.Add(self.yoffLabel, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5257  gridBagSizerO.Add(self.xoffCtrl, pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5258  gridBagSizerO.Add(self.yoffCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
5259 
5260  sizerO.Add(gridBagSizerO, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
5261  gridBagSizer.Add(sizerO, pos = (3,0), flag = wx.ALIGN_CENTER_HORIZONTAL|wx.EXPAND, border = 0)
5262  # reference point
5263  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " %_(" Reference point"))
5264  sizerR = wx.StaticBoxSizer(box, wx.VERTICAL)
5265  flexSizer = wx.FlexGridSizer(rows = 3, cols = 3, hgap = 5, vgap = 5)
5266  flexSizer.AddGrowableCol(0)
5267  flexSizer.AddGrowableCol(1)
5268  flexSizer.AddGrowableCol(2)
5269  ref = []
5270  for row in ["upper", "center", "lower"]:
5271  for col in ["left", "center", "right"]:
5272  ref.append(row + " " + col)
5273  self.radio = [wx.RadioButton(panel, id = wx.ID_ANY, label = '', style = wx.RB_GROUP, name = ref[0])]
5274  self.radio[0].SetValue(False)
5275  flexSizer.Add(self.radio[0], proportion = 0, flag = wx.ALIGN_CENTER, border = 0)
5276  for i in range(1,9):
5277  self.radio.append(wx.RadioButton(panel, id = wx.ID_ANY, label = '', name = ref[i]))
5278  self.radio[-1].SetValue(False)
5279  flexSizer.Add(self.radio[-1], proportion = 0, flag = wx.ALIGN_CENTER, border = 0)
5280  self.FindWindowByName(self.textDict['ref']).SetValue(True)
5281 
5282  sizerR.Add(flexSizer, proportion = 1, flag = wx.EXPAND, border = 0)
5283  gridBagSizer.Add(sizerR, pos = (3,1), flag = wx.ALIGN_LEFT|wx.EXPAND, border = 0)
5284 
5285  sizer.Add(gridBagSizer, proportion = 1, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
5286  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
5287 
5288  #rotation
5289  box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Text rotation"))
5290  sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
5291 
5292  self.rotCtrl = wx.CheckBox(panel, id = wx.ID_ANY, label = _("rotate text (counterclockwise)"))
5293  self.rotValue = wx.SpinCtrl(panel, wx.ID_ANY, size = (50, -1), min = 0, max = 360, initial = 0)
5294  if self.textDict['rotate']:
5295  self.rotValue.SetValue(int(self.textDict['rotate']))
5296  self.rotCtrl.SetValue(True)
5297  else:
5298  self.rotValue.SetValue(0)
5299  self.rotCtrl.SetValue(False)
5300  sizer.Add(self.rotCtrl, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT|wx.ALL, border = 5)
5301  sizer.Add(self.rotValue, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT|wx.ALL, border = 5)
5302 
5303  border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
5304 
5305  panel.SetSizer(border)
5306  panel.Fit()
5307 
5308  self.Bind(wx.EVT_RADIOBUTTON, self.OnPositionType, self.paperPositionCtrl)
5309  self.Bind(wx.EVT_RADIOBUTTON, self.OnPositionType, self.mapPositionCtrl)
5310  self.Bind(wx.EVT_CHECKBOX, self.OnRotation, self.rotCtrl)
5311 
5312  return panel
5313 
5314  def OnRefit(self, event):
5315  self.Fit()
5316 
5317  def OnRotation(self, event):
5318  if self.rotCtrl.GetValue():
5319  self.rotValue.Enable()
5320  else:
5321  self.rotValue.Disable()
5322 
5323  def OnPositionType(self, event):
5324  if self.paperPositionCtrl.GetValue():
5325  for widget in self.gridBagSizerP.GetChildren():
5326  widget.GetWindow().Enable()
5327  for widget in self.gridBagSizerM.GetChildren():
5328  widget.GetWindow().Disable()
5329  else:
5330  for widget in self.gridBagSizerM.GetChildren():
5331  widget.GetWindow().Enable()
5332  for widget in self.gridBagSizerP.GetChildren():
5333  widget.GetWindow().Disable()
5334 
5335  def OnBackground(self, event):
5336  if self.effect['backgroundCtrl'].GetValue():
5337  self.effect['backgroundColor'].Enable()
5338  self.update()
5339  else:
5340  self.effect['backgroundColor'].Disable()
5341 
5342  def OnHighlight(self, event):
5343  if self.effect['highlightCtrl'].GetValue():
5344  self.effect['highlightColor'].Enable()
5345  self.effect['highlightWidth'].Enable()
5346  self.effect['highlightWidthLabel'].Enable()
5347  self.update()
5348  else:
5349  self.effect['highlightColor'].Disable()
5350  self.effect['highlightWidth'].Disable()
5351  self.effect['highlightWidthLabel'].Disable()
5352 
5353  def OnBorder(self, event):
5354  if self.effect['borderCtrl'].GetValue():
5355  self.effect['borderColor'].Enable()
5356  self.effect['borderWidth'].Enable()
5357  self.effect['borderWidthLabel'].Enable()
5358  self.update()
5359  else:
5360  self.effect['borderColor'].Disable()
5361  self.effect['borderWidth'].Disable()
5362  self.effect['borderWidthLabel'].Disable()
5363 
5364  def update(self):
5365  #text
5366  self.textDict['text'] = self.textCtrl.GetValue()
5367  if not self.textDict['text']:
5368  wx.MessageBox(_("No text entered!"), _("Error"))
5369  return False
5370 
5371  #font
5372  self.textDict['font'] = self.textPanel.font['fontCtrl'].GetStringSelection()
5373  self.textDict['fontsize'] = self.textPanel.font['fontSizeCtrl'].GetValue()
5374  color = self.textPanel.font['colorCtrl'].GetColour()
5375  self.textDict['color'] = convertRGB(color)
5376 
5377  #effects
5378  if self.effect['backgroundCtrl'].GetValue():
5379  background = self.effect['backgroundColor'].GetColour()
5380  self.textDict['background'] = convertRGB(background)
5381  else:
5382  self.textDict['background'] = 'none'
5383 
5384  if self.effect['borderCtrl'].GetValue():
5385  border = self.effect['borderColor'].GetColour()
5386  self.textDict['border'] = convertRGB(border)
5387  else:
5388  self.textDict['border'] = 'none'
5389 
5390  self.textDict['width'] = self.effect['borderWidth'].GetValue()
5391 
5392  if self.effect['highlightCtrl'].GetValue():
5393  highlight = self.effect['highlightColor'].GetColour()
5394  self.textDict['hcolor'] = convertRGB(highlight)
5395  else:
5396  self.textDict['hcolor'] = 'none'
5397 
5398  self.textDict['hwidth'] = self.effect['highlightWidth'].GetValue()
5399 
5400  #offset
5401  self.textDict['xoffset'] = self.xoffCtrl.GetValue()
5402  self.textDict['yoffset'] = self.yoffCtrl.GetValue()
5403 
5404  #position
5405  if self.paperPositionCtrl.GetValue():
5406  self.textDict['XY'] = True
5407  currUnit = self.unitConv.findUnit(self.positionPanel.units['unitsCtrl'].GetStringSelection())
5408  self.textDict['unit'] = currUnit
5409  if self.positionPanel.position['xCtrl'].GetValue():
5410  x = self.positionPanel.position['xCtrl'].GetValue()
5411  else:
5412  x = self.textDict['where'][0]
5413 
5414  if self.positionPanel.position['yCtrl'].GetValue():
5415  y = self.positionPanel.position['yCtrl'].GetValue()
5416  else:
5417  y = self.textDict['where'][1]
5418 
5419  x = self.unitConv.convert(value = float(x), fromUnit = currUnit, toUnit = 'inch')
5420  y = self.unitConv.convert(value = float(y), fromUnit = currUnit, toUnit = 'inch')
5421  self.textDict['where'] = x, y
5422  self.textDict['east'], self.textDict['north'] = PaperMapCoordinates(self.instruction[self.mapId], x, y, paperToMap = True)
5423  else:
5424  self.textDict['XY'] = False
5425  if self.eastingCtrl.GetValue():
5426  self.textDict['east'] = self.eastingCtrl.GetValue()
5427  else:
5428  self.textDict['east'] = self.textDict['east']
5429 
5430  if self.northingCtrl.GetValue():
5431  self.textDict['north'] = self.northingCtrl.GetValue()
5432  else:
5433  self.textDict['north'] = self.textDict['north']
5434 
5435  self.textDict['where'] = PaperMapCoordinates(map = self.instruction[self.mapId], x = float(self.textDict['east']),
5436  y = float(self.textDict['north']), paperToMap = False)
5437  #rotation
5438  if self.rotCtrl.GetValue():
5439  self.textDict['rotate'] = self.rotValue.GetValue()
5440  else:
5441  self.textDict['rotate'] = None
5442  #reference point
5443  for radio in self.radio:
5444  if radio.GetValue() == True:
5445  self.textDict['ref'] = radio.GetName()
5446 
5447  if self.id not in self.instruction:
5448  text = Text(self.id)
5449  self.instruction.AddInstruction(text)
5450  self.instruction[self.id].SetInstruction(self.textDict)
5451 
5452  if self.id not in self.parent.objectId:
5453  self.parent.objectId.append(self.id)
5454 
5455 # self.updateDialog()
5456 
5457  return True
5458 
5459  def updateDialog(self):
5460  """!Update text coordinates, after moving"""
5461  # XY coordinates
5462  x, y = self.textDict['where'][:2]
5463  currUnit = self.unitConv.findUnit(self.positionPanel.units['unitsCtrl'].GetStringSelection())
5464  x = self.unitConv.convert(value = x, fromUnit = 'inch', toUnit = currUnit)
5465  y = self.unitConv.convert(value = y, fromUnit = 'inch', toUnit = currUnit)
5466  self.positionPanel.position['xCtrl'].SetValue("%5.3f" % x)
5467  self.positionPanel.position['yCtrl'].SetValue("%5.3f" % y)
5468  # EN coordinates
5469  e, n = self.textDict['east'], self.textDict['north']
5470  self.eastingCtrl.SetValue(str(self.textDict['east']))
5471  self.northingCtrl.SetValue(str(self.textDict['north']))
5472 
5473 def convertRGB(rgb):
5474  """!Converts wx.Colour(r,g,b,a) to string 'r:g:b' or named color,
5475  or named color/r:g:b string to wx.Colour, depending on input"""
5476  # transform a wx.Colour tuple into an r:g:b string
5477  if type(rgb) == wx.Colour:
5478  for name, color in grass.named_colors.items():
5479  if rgb.Red() == int(color[0] * 255) and\
5480  rgb.Green() == int(color[1] * 255) and\
5481  rgb.Blue() == int(color[2] * 255):
5482  return name
5483  return str(rgb.Red()) + ':' + str(rgb.Green()) + ':' + str(rgb.Blue())
5484  # transform a GRASS named color or an r:g:b string into a wx.Colour tuple
5485  else:
5486  color = (grass.parse_color(rgb)[0]*255,
5487  grass.parse_color(rgb)[1]*255,
5488  grass.parse_color(rgb)[2]*255)
5489  color = wx.Color(*color)
5490  if color.IsOk():
5491  return color
5492  else:
5493  return None
5494 
5495 def PaperMapCoordinates(map, x, y, paperToMap = True):
5496  """!Converts paper (inch) coordinates -> map coordinates"""
5497  unitConv = UnitConversion()
5498  currRegionDict = grass.region()
5499  cornerEasting, cornerNorthing = currRegionDict['w'], currRegionDict['n']
5500  xMap = map['rect'][0]
5501  yMap = map['rect'][1]
5502  widthMap = map['rect'][2] * 0.0254 # to meter
5503  heightMap = map['rect'][3] * 0.0254
5504  xScale = widthMap / abs(currRegionDict['w'] - currRegionDict['e'])
5505  yScale = heightMap / abs(currRegionDict['n'] - currRegionDict['s'])
5506  currScale = (xScale + yScale) / 2
5507 
5508  if not paperToMap:
5509  textEasting, textNorthing = x, y
5510  eastingDiff = textEasting - cornerEasting
5511  if currRegionDict['w'] > currRegionDict['e']:
5512  eastingDiff = - eastingDiff
5513  else:
5514  eastingDiff = eastingDiff
5515 
5516  northingDiff = textNorthing - cornerNorthing
5517  if currRegionDict['n'] > currRegionDict['s']:
5518  northingDiff = - northingDiff
5519  else:
5520  northingDiff = northingDiff
5521 
5522  xPaper = xMap + unitConv.convert(value = eastingDiff, fromUnit = 'meter', toUnit = 'inch') * currScale
5523  yPaper = yMap + unitConv.convert(value = northingDiff, fromUnit = 'meter', toUnit = 'inch') * currScale
5524  return xPaper, yPaper
5525  else:
5526  if currRegionDict['w'] < currRegionDict['e']:
5527  eastingDiff = (x - xMap)
5528  else:
5529  eastingDiff = (xMap - x)
5530  if currRegionDict['n'] < currRegionDict['s']:
5531  northingDiff = (y - yMap)
5532  else:
5533  northingDiff = (yMap - y)
5534 
5535  textEasting = cornerEasting + unitConv.convert(value = eastingDiff, fromUnit = 'inch', toUnit = 'meter') / currScale
5536  textNorthing = cornerNorthing + unitConv.convert(value = northingDiff, fromUnit = 'inch', toUnit = 'meter') / currScale
5537  return int(textEasting), int(textNorthing)
5538 
5539 def AutoAdjust(self, scaleType, rect, map = None, mapType = None, region = None):
5540  """!Computes map scale, center and map frame rectangle to fit region (scale is not fixed)"""
5541  currRegionDict = {}
5542  if scaleType == 0 and map:# automatic, region from raster or vector
5543  res = ''
5544  if mapType == 'raster':
5545  try:
5546  res = grass.read_command("g.region", flags = 'gu', rast = map)
5547  except grass.ScriptError:
5548  pass
5549  elif mapType == 'vector':
5550  res = grass.read_command("g.region", flags = 'gu', vect = map)
5551  currRegionDict = grass.parse_key_val(res, val_type = float)
5552  elif scaleType == 1 and region: # saved region
5553  res = grass.read_command("g.region", flags = 'gu', region = region)
5554  currRegionDict = grass.parse_key_val(res, val_type = float)
5555  elif scaleType == 2: # current region
5556  env = grass.gisenv()
5557  windFilePath = os.path.join(env['GISDBASE'], env['LOCATION_NAME'], env['MAPSET'], 'WIND')
5558  try:
5559  windFile = open(windFilePath, 'r').read()
5560  except IOError:
5561  currRegionDict = grass.region()
5562  regionDict = grass.parse_key_val(windFile, sep = ':', val_type = float)
5563  region = grass.read_command("g.region", flags = 'gu', n = regionDict['north'], s = regionDict['south'],
5564  e = regionDict['east'], w = regionDict['west'])
5565  currRegionDict = grass.parse_key_val(region, val_type = float)
5566 
5567  else:
5568  return None, None, None
5569 
5570  if not currRegionDict:
5571  return None, None, None
5572  rX = rect.x
5573  rY = rect.y
5574  rW = rect.width
5575  rH = rect.height
5576  if not hasattr(self, 'unitConv'):
5577  self.unitConv = UnitConversion(self)
5578  toM = 1
5579  if projInfo()['proj'] != 'xy':
5580  toM = float(projInfo()['meters'])
5581 
5582  mW = self.unitConv.convert(value = (currRegionDict['e'] - currRegionDict['w']) * toM, fromUnit = 'meter', toUnit = 'inch')
5583  mH = self.unitConv.convert(value = (currRegionDict['n'] - currRegionDict['s']) * toM, fromUnit = 'meter', toUnit = 'inch')
5584  scale = min(rW/mW, rH/mH)
5585 
5586  if rW/rH > mW/mH:
5587  x = rX - (rH*(mW/mH) - rW)/2
5588  y = rY
5589  rWNew = rH*(mW/mH)
5590  rHNew = rH
5591  else:
5592  x = rX
5593  y = rY - (rW*(mH/mW) - rH)/2
5594  rHNew = rW*(mH/mW)
5595  rWNew = rW
5596 
5597  # center
5598  cE = (currRegionDict['w'] + currRegionDict['e'])/2
5599  cN = (currRegionDict['n'] + currRegionDict['s'])/2
5600  return scale, (cE, cN), wx.Rect2D(x, y, rWNew, rHNew) #inch
5601 
5602 def SetResolution(dpi, width, height):
5603  """!If resolution is too high, lower it
5604 
5605  @param dpi max DPI
5606  @param width map frame width
5607  @param height map frame height
5608  """
5609  region = grass.region()
5610  if region['cols'] > width * dpi or region['rows'] > height * dpi:
5611  rows = height * dpi
5612  cols = width * dpi
5613  RunCommand('g.region', rows = rows, cols = cols)
5614 
5615 def ComputeSetRegion(self, mapDict):
5616  """!Computes and sets region from current scale, map center coordinates and map rectangle"""
5617 
5618  if mapDict['scaleType'] == 3: # fixed scale
5619  scale = mapDict['scale']
5620 
5621  if not hasattr(self, 'unitConv'):
5622  self.unitConv = UnitConversion(self)
5623 
5624  fromM = 1
5625  if projInfo()['proj'] != 'xy':
5626  fromM = float(projInfo()['meters'])
5627  rectHalfInch = (mapDict['rect'].width/2, mapDict['rect'].height/2)
5628  rectHalfMeter = (self.unitConv.convert(value = rectHalfInch[0], fromUnit = 'inch', toUnit = 'meter')/ fromM /scale,
5629  self.unitConv.convert(value = rectHalfInch[1], fromUnit = 'inch', toUnit = 'meter')/ fromM /scale)
5630 
5631  centerE = mapDict['center'][0]
5632  centerN = mapDict['center'][1]
5633 
5634  raster = self.instruction.FindInstructionByType('raster')
5635  if raster:
5636  rasterId = raster.id
5637  else:
5638  rasterId = None
5639 
5640  if rasterId:
5641  RunCommand('g.region', n = ceil(centerN + rectHalfMeter[1]),
5642  s = floor(centerN - rectHalfMeter[1]),
5643  e = ceil(centerE + rectHalfMeter[0]),
5644  w = floor(centerE - rectHalfMeter[0]),
5645  rast = self.instruction[rasterId]['raster'])
5646  else:
5647  RunCommand('g.region', n = ceil(centerN + rectHalfMeter[1]),
5648  s = floor(centerN - rectHalfMeter[1]),
5649  e = ceil(centerE + rectHalfMeter[0]),
5650  w = floor(centerE - rectHalfMeter[0]))
5651 
5652 def projInfo():
5653  """!Return region projection and map units information,
5654  taken from render.py"""
5655 
5656  projinfo = dict()
5657 
5658  ret = RunCommand('g.proj', read = True, flags = 'p')
5659 
5660  if not ret:
5661  return projinfo
5662 
5663  for line in ret.splitlines():
5664  if ':' in line:
5665  key, val = line.split(':')
5666  projinfo[key.strip()] = val.strip()
5667  elif "XY location (unprojected)" in line:
5668  projinfo['proj'] = 'xy'
5669  projinfo['units'] = ''
5670  break
5671 
5672  return projinfo
5673 
5674 def GetMapBounds(filename, portrait = True):
5675  """!Run ps.map -b to get information about map bounding box
5676 
5677  @param filename psmap input file
5678  @param portrait page orientation"""
5679  orient = ''
5680  if not portrait:
5681  orient = 'r'
5682  try:
5683  bb = map(float, grass.read_command('ps.map',
5684  flags = 'b' + orient,
5685  quiet = True,
5686  input = filename).strip().split('=')[1].split(','))
5687  except (grass.ScriptError, IndexError):
5688  GError(message = _("Unable to run `ps.map -b`"))
5689  return None
5690  return wx.Rect2D(bb[0], bb[3], bb[2] - bb[0], bb[1] - bb[3])
5691 
5692 def getRasterType(map):
5693  """!Returns type of raster map (CELL, FCELL, DCELL)"""
5694  if map is None:
5695  map = ''
5696  file = grass.find_file(name = map, element = 'cell')
5697  if file['file']:
5698  rasterType = grass.raster_info(map)['datatype']
5699  return rasterType
5700  else:
5701  return None
5702