[GRASS-SVN] r45659 - in grass-addons/gui/wxpython/psmap: . docs
gui_modules images xml
svn_grass at osgeo.org
svn_grass at osgeo.org
Mon Mar 14 03:15:14 EDT 2011
Author: annakrat
Date: 2011-03-14 00:15:14 -0700 (Mon, 14 Mar 2011)
New Revision: 45659
Added:
grass-addons/gui/wxpython/psmap/docs/
grass-addons/gui/wxpython/psmap/docs/wxGUI.PsMap.html
grass-addons/gui/wxpython/psmap/gui_modules/
grass-addons/gui/wxpython/psmap/gui_modules/psmap.py
grass-addons/gui/wxpython/psmap/gui_modules/psmap_dialogs.py
grass-addons/gui/wxpython/psmap/images/
grass-addons/gui/wxpython/psmap/images/scalebar-fancy.png
grass-addons/gui/wxpython/psmap/images/scalebar-simple.png
grass-addons/gui/wxpython/psmap/xml/
grass-addons/gui/wxpython/psmap/xml/menudata_psmap.xml
Log:
ps.map gui added
Added: grass-addons/gui/wxpython/psmap/docs/wxGUI.PsMap.html
===================================================================
--- grass-addons/gui/wxpython/psmap/docs/wxGUI.PsMap.html (rev 0)
+++ grass-addons/gui/wxpython/psmap/docs/wxGUI.PsMap.html 2011-03-14 07:15:14 UTC (rev 45659)
@@ -0,0 +1,31 @@
+<h2>DESCRIPTION</h2>
+
+<b>Note:</b> <em>wxGUI Hardcopy Map Utility is currently under
+development.</em>
+
+<p>
+<b>Hardcopy Map Utility</b> is
+a <em><a href="wxGUI.html">wxGUI</a></em> extension which allows the
+user ...
+
+<h2>SEE ALSO</h2>
+
+<em>
+ <a href="wxGUI.html">wxGUI</a>
+</em>
+
+<p>
+Other wxGUI components:<br>
+<em>
+ <a href="wxGUI.Vector_Digitizer.html">Vector Digitizer</a><br>
+ <a href="wxGUI.Attribute_Table_Manager.html">Attribute Table Manager</a><br>
+ <a href="wxGUI.Nviz.html">3D Viewer</a><br>
+ <a href="wxGUI.GCP_Manager.html">Manage Ground Control Points</a><br>
+</em>
+
+<h2>AUTHORS</h2>
+
+Anna Kratochvilova, CTU in Prague, Czech Republic (bachelor's final project 2011, mentor: Martin Landa)
+
+<p>
+<i>$Date$</i>
Added: grass-addons/gui/wxpython/psmap/gui_modules/psmap.py
===================================================================
--- grass-addons/gui/wxpython/psmap/gui_modules/psmap.py (rev 0)
+++ grass-addons/gui/wxpython/psmap/gui_modules/psmap.py 2011-03-14 07:15:14 UTC (rev 45659)
@@ -0,0 +1,1535 @@
+"""!
+ at package psmap
+
+ at brief GUI for ps.map
+
+Classes:
+ - PsMapData (to be moved - menudata.py)
+ - PsMapToolbar (to be moved - toolbars.py)
+ - PsMapFrame
+ - PsMapBufferedWindow
+
+(C) 2011 by Anna Kratochvilova, and the GRASS Development Team
+This program is free software under the GNU General Public License
+(>=v2). Read the file COPYING that comes with GRASS for details.
+
+ at author Anna Kratochvilova <anna.kratochvilova fsv.cvut.cz> (bachelor's project)
+ at author Martin Landa <landa.martin gmail.com> (mentor)
+"""
+
+import os
+import sys
+import tempfile
+import textwrap
+import Queue
+try:
+ import Image
+except ImportError:
+ sys.exit("Python Imaging Library is not available")
+from math import ceil, sin, cos, pi
+from collections import namedtuple
+
+import grass.script as grass
+if int(grass.version()['version'].split('.')[0]) > 6:
+ sys.path.append(os.path.join(os.getenv('GISBASE'), 'etc', 'gui', 'wxpython',
+ 'gui_modules'))
+else:
+ sys.path.append(os.path.join(os.getenv('GISBASE'), 'etc', 'wxpython',
+ 'gui_modules'))
+import globalvar
+import menu
+from goutput import CmdThread, EVT_CMD_DONE
+from menudata import MenuData, etcwxdir
+from gselect import Select
+from toolbars import AbstractToolbar
+from icon import Icons, MetaIcon, iconSet
+from gcmd import RunCommand, GError, GMessage
+from psmap_dialogs import *
+
+import wx
+import wx.lib.scrolledpanel as scrolled
+
+try:
+ from agw import flatnotebook as fnb
+except ImportError: # if it's not there locally, try the wxPython lib.
+ import wx.lib.agw.flatnotebook as fnb
+
+Icons['psMap'] = {
+ 'script' : MetaIcon(img = iconSet['ps-script'],
+ label = _('Generate instruction file')),
+ 'export' : MetaIcon(img = iconSet['ps-export'],
+ label = _('Generate PostScript output')),
+ 'pageSetup' : MetaIcon(img = iconSet['settings'],
+ label = _('Page setup'),
+ desc = _('Specify paper size, margins and orientation')),
+ 'fullExtent' : MetaIcon(img = iconSet['zoom-extent'],
+ label = _("Full extent"),
+ desc = _("Zoom to full extent")),
+ 'addMap' : MetaIcon(img = iconSet['layer-add'],
+ label = _("Map frame"),
+ desc = _("Click and drag to place map frame")),
+ 'addRast' : MetaIcon(img = iconSet['layer-raster-add'],
+ label = _("Raster map"),
+ desc = _("Add raster map")),
+ 'addVect' : MetaIcon(img = iconSet['layer-vector-add'],
+ label = _("Vector map"),
+ desc = _("Add vector map")),
+ 'deleteObj' : MetaIcon(img = iconSet['layer-remove'],
+ label = _("Delete selected object")),
+ 'preview' : MetaIcon(img = iconSet['execute'],
+ label = _("Show preview")),
+ 'quit' : MetaIcon(img = iconSet['quit'],
+ label = _('Quit Hardcopy Map Utility')),
+ 'addText' : MetaIcon(img = iconSet['text-add'],
+ label = _('Add text')),
+ 'addMapinfo': MetaIcon(img = iconSet['legend-add'],
+ label = _('Add map info')),
+ 'addLegend' : MetaIcon(img = iconSet['legend-add'],
+ label = _('Add legend')),
+ 'addScalebar' : MetaIcon(img = iconSet['scalebar-add'],
+ label = _('Add scale bar')),
+ }
+
+class PsMapData(MenuData):
+ def __init__(self, path = None):
+ """!Menu for Hardcopy Map Output Utility (psmap.py)
+
+ @path path to XML to be read (None for menudata_psmap.xml)
+ """
+ if not path:
+ gisbase = os.getenv('GISBASE')
+ global etcwxdir
+ path = os.path.join(etcwxdir, 'xml', 'menudata_psmap.xml')
+
+ MenuData.__init__(self, path)
+
+class PsMapToolbar(AbstractToolbar):
+ def __init__(self, parent):
+ """!Toolbar Hardcopy Map Output Utility (psmap.py)
+
+ @param parent parent window
+ """
+ AbstractToolbar.__init__(self, parent)
+
+ self.InitToolbar(self._toolbarData())
+
+ self.Realize()
+
+ self.action = { 'id' : self.pointer }
+ self.defaultAction = { 'id' : self.pointer,
+ 'bind' : self.parent.OnPointer }
+ self.OnTool(None)
+
+
+ def _toolbarData(self):
+ """!Toolbar data
+ """
+ self.quit = wx.NewId()
+ self.pagesetup = wx.NewId()
+ self.pointer = wx.NewId()
+ self.zoomIn = wx.NewId()
+ self.zoomOut = wx.NewId()
+ self.zoomAll = wx.NewId()
+ self.addMap = wx.NewId()
+ self.addRaster = wx.NewId()
+ self.addVector = wx.NewId()
+ self.dec = wx.NewId()
+ self.delete = wx.NewId()
+ self.preview = wx.NewId()
+ self.instructionFile = wx.NewId()
+ self.generatePS = wx.NewId()
+ self.pan = wx.NewId()
+
+ icons = Icons['psMap']
+ return self._getToolbarData(((self.pagesetup, 'page setup', icons['pageSetup'],
+ self.parent.OnPageSetup),
+ (None, ),
+ (self.pointer, "pointer", Icons["displayWindow"]["pointer"],
+ self.parent.OnPointer, wx.ITEM_CHECK),
+ (self.pan, 'pan', Icons["displayWindow"]['pan'],
+ self.parent.OnPan, wx.ITEM_CHECK),
+ (self.zoomIn, "zoomin", Icons["displayWindow"]["zoomIn"],
+ self.parent.OnZoomIn, wx.ITEM_CHECK),
+ (self.zoomOut, "zoomout", Icons["displayWindow"]["zoomOut"],
+ self.parent.OnZoomOut, wx.ITEM_CHECK),
+ (self.zoomAll, 'full extent', icons['fullExtent'],
+ self.parent.OnZoomAll),
+ (None, ),
+ (self.addMap, 'add map', icons['addMap'],
+ self.parent.OnAddMap, wx.ITEM_CHECK),
+ (self.addRaster, 'add raster', icons['addRast'],
+ self.parent.OnAddRaster),
+ (self.addVector, 'add vect', icons['addVect'],
+ self.parent.OnAddVect),
+ (self.dec, "overlay", Icons["displayWindow"]["overlay"],
+ self.parent.OnDecoration),
+ (self.delete, "delete", icons["deleteObj"],
+ self.parent.OnDelete),
+ (None, ),
+ (self.preview, "preview", icons["preview"],
+ self.parent.OnPreview),
+ (self.instructionFile, 'psScript', icons['script'],
+ self.parent.OnInstructionFile),
+ (self.generatePS, 'generatePS', icons['export'],
+ self.parent.OnPSFile),
+ (None, ),
+ (self.quit, 'quit', icons['quit'],
+ self.parent.OnCloseWindow))
+ )
+
+
+class PsMapFrame(wx.Frame):
+ def __init__(self, parent = None, id = wx.ID_ANY,
+ title = _("GRASS GIS Hardcopy Map Output Utility"), **kwargs):
+ """!Main window of ps.map GUI
+
+ @param parent parent window
+ @param id window id
+ @param title window title
+
+ @param kwargs wx.Frames' arguments
+ """
+ self.parent = parent
+
+ wx.Frame.__init__(self, parent = parent, id = id, title = title, name = "PsMap", **kwargs)
+ self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
+ #menubar
+ self.menubar = menu.Menu(parent = self, data = PsMapData())
+ self.SetMenuBar(self.menubar)
+ #toolbar
+
+ self.toolbar = PsMapToolbar(parent = self)
+ self.SetToolBar(self.toolbar)
+
+ self.actionOld = self.toolbar.action['id']
+ self.iconsize = (16, 16)
+ #satusbar
+ self.statusbar = self.CreateStatusBar(number = 1)
+
+ # mouse attributes -- position on the screen, begin and end of
+ # dragging, and type of drawing
+ self.mouse = {
+ 'begin': [0, 0], # screen coordinates
+ 'end' : [0, 0],
+ 'use' : "pointer",
+ }
+ # available cursors
+ self.cursors = {
+ "default" : wx.StockCursor(wx.CURSOR_ARROW),
+ "cross" : wx.StockCursor(wx.CURSOR_CROSS),
+ "hand" : wx.StockCursor(wx.CURSOR_HAND),
+ "sizenwse": wx.StockCursor(wx.CURSOR_SIZENWSE)
+ }
+ # pen and brush
+ self.pen = {
+ 'paper': wx.Pen(colour = "BLACK", width = 1),
+ 'margins': wx.Pen(colour = "GREY", width = 1),
+ 'map': wx.Pen(colour = wx.Color(86, 122, 17), width = 2),
+ 'rasterLegend': wx.Pen(colour = wx.Color(219, 216, 4), width = 2),
+ 'vectorLegend': wx.Pen(colour = wx.Color(219, 216, 4), width = 2),
+ 'mapinfo': wx.Pen(colour = wx.Color(5, 184, 249), width = 2),
+ 'scalebar': wx.Pen(colour = wx.Color(150, 150, 150), width = 2),
+ 'box': wx.Pen(colour = 'RED', width = 2, style = wx.SHORT_DASH),
+ 'select': wx.Pen(colour = 'BLACK', width = 1, style = wx.SHORT_DASH),
+ 'resize': wx.Pen(colour = 'BLACK', width = 1)
+ }
+ self.brush = {
+ 'paper': wx.WHITE_BRUSH,
+ 'margins': wx.TRANSPARENT_BRUSH,
+ 'map': wx.Brush(wx.Color(151, 214, 90)),
+ 'rasterLegend': wx.Brush(wx.Color(250, 247, 112)),
+ 'vectorLegend': wx.Brush(wx.Color(250, 247, 112)),
+ 'mapinfo': wx.Brush(wx.Color(127, 222, 252)),
+ 'scalebar': wx.Brush(wx.Color(200, 200, 200)),
+ 'box': wx.TRANSPARENT_BRUSH,
+ 'select':wx.TRANSPARENT_BRUSH,
+ 'resize': wx.BLACK_BRUSH
+ }
+
+
+ # list of objects to draw
+ self.objectId = []
+
+ # instructions
+ self.instruction = Instruction(parent = self, objectsToDraw = self.objectId)
+
+ self.pageId = wx.NewId()
+ #current page of flatnotebook
+ self.currentPage = 0
+ #canvas for draft mode
+ self.canvas = PsMapBufferedWindow(parent = self, mouse = self.mouse, pen = self.pen,
+ brush = self.brush, cursors = self.cursors,
+ instruction = self.instruction,
+ pageId = self.pageId, objectId = self.objectId,
+ preview = False)
+
+ self.canvas.SetCursor(self.cursors["default"])
+ self.getInitMap()
+
+
+ # image path
+ env = grass.gisenv()
+ self.imgName = os.path.join( env['GISDBASE'], env['LOCATION_NAME'], env['MAPSET'], '.tmp', 'tmpImage.png')
+
+ #canvas for preview
+ self.previewCanvas = PsMapBufferedWindow(parent = self, mouse = self.mouse, cursors = self.cursors,
+ pen = self.pen, brush = self.brush, preview = True)
+
+
+
+
+ # set WIND_OVERRIDE
+ grass.use_temp_region()
+
+ # create queues
+ self.requestQ = Queue.Queue()
+ self.resultQ = Queue.Queue()
+ # thread
+ self.cmdThread = CmdThread(self, self.requestQ, self.resultQ)
+
+ self._layout()
+ self.SetMinSize(wx.Size(700, 600))
+
+ self.Bind(fnb.EVT_FLATNOTEBOOK_PAGE_CHANGING, self.OnPageChanging)
+ self.Bind(fnb.EVT_FLATNOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
+ self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+ self.Bind(EVT_CMD_DONE, self.OnCmdDone)
+
+## # load instructions
+## self.readObjectId = []
+## self.readInstruction = Instruction(parent = self, objectsToDraw = self.readObjectId)
+## self.readInstruction.Read('/home/anna/Desktop/reading.txt')
+## print '%%%%%%%%%%%%%%%%%%%\n',self.readInstruction
+
+ def _layout(self):
+ """!Do layout
+ """
+ mainSizer = wx.BoxSizer(wx.VERTICAL)
+ if globalvar.hasAgw:
+ self.book = fnb.FlatNotebook(parent = self, id = wx.ID_ANY,
+ agwStyle = fnb.FNB_FANCY_TABS | fnb.FNB_BOTTOM |
+ fnb.FNB_NO_NAV_BUTTONS | fnb.FNB_NO_X_BUTTON)
+ else:
+ self.book = fnb.FlatNotebook(parent = self, id = wx.ID_ANY,
+ style = fnb.FNB_FANCY_TABS | fnb.FNB_BOTTOM |
+ fnb.FNB_NO_NAV_BUTTONS | fnb.FNB_NO_X_BUTTON)
+ #self.book = fnb.FlatNotebook(self, wx.ID_ANY, style = fnb.FNB_BOTTOM)
+ self.book.AddPage(self.canvas, "Draft mode")
+ self.book.AddPage(self.previewCanvas, "Preview")
+ self.book.SetSelection(0)
+
+ mainSizer.Add(self.book,1, wx.EXPAND)
+
+ self.SetSizer(mainSizer)
+ mainSizer.Fit(self)
+
+
+ def InstructionFile(self):
+ """!Creates mapping instructions"""
+
+ return str(self.instruction)
+
+ def OnPSFile(self, event):
+ filename = self.getFile(wildcard = "PostScript (*.ps)|*.ps|Encapsulated PostScript (*.eps)|*.eps")
+ if filename:
+ self.PSFile(filename)
+
+ def OnPreview(self, event):
+ """!Run ps.map and show result"""
+ self.PSFile()
+
+
+
+ def PSFile(self, filename = None):
+ """!Create temporary instructions file and run ps.map with output = filename"""
+ instrFile = grass.tempfile()
+ instrFileFd = open(instrFile, mode = 'w')
+ instrFileFd.write(self.InstructionFile())
+ instrFileFd.flush()
+ instrFileFd.close()
+
+ temp = False
+ if not filename:
+ temp = True
+ filename = grass.tempfile()
+
+ cmd = ['ps.map', '--overwrite']
+ if os.path.splitext(filename)[1] == '.eps':
+ cmd.append('-e')
+ if self.instruction[self.pageId]['Orientation'] == 'Landscape':
+ cmd.append('-r')
+ cmd.append('input=%s' % instrFile)
+ cmd.append('output=%s' % filename)
+ self.SetStatusText(_('Generating preview...'), 0)
+
+ self.cmdThread.RunCmd(cmd, userData = {'instrFile' : instrFile, 'filename' : filename, 'temp' : temp })
+
+ def OnCmdDone(self, event):
+ """!ps.map process finished"""
+
+ if event.returncode != 0:
+ GMessage(parent = self,
+ message = _("Ps.map exited with return code %s") % event.returncode)
+ return
+
+ try:
+ im = Image.open(event.userData['filename'])
+ if self.instruction[self.pageId]['Orientation'] == 'Landscape':
+ im = im.rotate(270)
+ im.save(self.imgName)
+
+ except IOError, e:
+ GError(parent = self,
+ message = _("Unable to generate preview. %s") % e)
+
+
+ rect = self.previewCanvas.ImageRect()
+ self.previewCanvas.image = wx.Image(self.imgName, wx.BITMAP_TYPE_PNG)
+ self.previewCanvas.DrawImage(rect = rect)
+
+ self.SetStatusText(_('Preview generated'), 0)
+ self.book.SetSelection(1)
+ self.currentPage = 1
+
+ grass.try_remove(event.userData['instrFile'])
+ if event.userData['temp']:
+ grass.try_remove(event.userData['filename'])
+
+ def getFile(self, wildcard):
+ suffix = []
+ for filter in wildcard.split('|')[1::2]:
+ s = filter.strip('*').split('.')[1]
+ if s:
+ s = '.' + s
+ suffix.append(s)
+ raster = self.instruction.FindInstructionByType('raster')
+ rasterId = raster.id if raster else None
+
+ if rasterId and self.instruction[rasterId]['raster']:
+ mapName = self.instruction[rasterId]['raster'].split('@')[0] + suffix[0]
+ else:
+ mapName = ''
+
+ filename = ''
+ dlg = wx.FileDialog(self, message = "Save file as", defaultDir = "",
+ defaultFile = mapName, wildcard = wildcard,
+ style = wx.CHANGE_DIR|wx.SAVE|wx.OVERWRITE_PROMPT)
+ if dlg.ShowModal() == wx.ID_OK:
+ filename = dlg.GetPath()
+ suffix = suffix[dlg.GetFilterIndex()]
+ if not os.path.splitext(filename)[1]:
+ filename = filename + suffix
+ elif os.path.splitext(filename)[1] != suffix and suffix != '':
+ filename = os.path.splitext(filename)[0] + suffix
+
+ dlg.Destroy()
+ return filename
+
+ def OnInstructionFile(self, event):
+ filename = self.getFile(wildcard = "All files(*.*)|*.*|Text file|*.txt")
+ if filename:
+ instrFile = open(filename, "w")
+ instrFile.write(self.InstructionFile())
+ instrFile.close()
+
+ def OnPageSetup(self, event = None):
+ """!Specify paper size, margins and orientation"""
+ id = self.instruction.FindInstructionByType('page').id
+ dlg = PageSetupDialog(self, id = id, settings = self.instruction)
+ dlg.CenterOnScreen()
+ val = dlg.ShowModal()
+ if val == wx.ID_OK:
+ self.canvas.SetPage()
+ self.canvas.RecalculatePosition(ids = self.objectId)
+ dlg.Destroy()
+
+ def OnPointer(self, event):
+ self.toolbar.OnTool(event)
+ self.mouse["use"] = "pointer"
+ self.canvas.SetCursor(self.cursors["default"])
+ self.previewCanvas.SetCursor(self.cursors["default"])
+
+ def OnPan(self, event):
+ self.toolbar.OnTool(event)
+ self.mouse["use"] = "pan"
+ self.canvas.SetCursor(self.cursors["hand"])
+ self.previewCanvas.SetCursor(self.cursors["hand"])
+
+ def OnZoomIn(self, event):
+ self.toolbar.OnTool(event)
+ self.mouse["use"] = "zoomin"
+ self.canvas.SetCursor(self.cursors["cross"])
+ self.previewCanvas.SetCursor(self.cursors["cross"])
+
+ def OnZoomOut(self, event):
+ self.toolbar.OnTool(event)
+ self.mouse["use"] = "zoomout"
+ self.canvas.SetCursor(self.cursors["cross"])
+ self.previewCanvas.SetCursor(self.cursors["cross"])
+
+ def OnZoomAll(self, event):
+ self.mouseOld = self.mouse['use']
+ self.cursorOld = self.canvas.GetCursor() if self.currentPage == 0 else self.previewCanvas.GetCursor()
+ self.mouse["use"] = "zoomin"
+ self.canvas.ZoomAll() if self.currentPage == 0 else self.previewCanvas.ZoomAll()
+ self.mouse["use"] = self.mouseOld
+ self.canvas.SetCursor(self.cursorOld) if self.currentPage == 0 else self.previewCanvas.SetCursor(self.cursorOld)
+
+
+ def OnAddMap(self, event, notebook = False):
+ if event is not None:
+ if event.GetId() != self.toolbar.action['id']:
+ self.actionOld = self.toolbar.action['id']
+ self.mouseOld = self.mouse['use']
+ self.cursorOld = self.canvas.GetCursor()
+ self.toolbar.OnTool(event)
+
+ if self.instruction.FindInstructionByType('map'):
+ mapId = self.instruction.FindInstructionByType('map').id
+ else: mapId = None
+ id = [mapId, None, None]
+ if notebook:
+ if self.instruction.FindInstructionByType('vector'):
+ vectorId = self.instruction.FindInstructionByType('vector').id
+ else: vectorId = None
+ if self.instruction.FindInstructionByType('raster'):
+ rasterId = self.instruction.FindInstructionByType('raster').id
+ else: rasterId = None
+ id[1] = rasterId
+ id[2] = vectorId
+
+
+ if mapId: # map exists
+
+ self.toolbar.ToggleTool(self.actionOld, True)
+ self.toolbar.ToggleTool(self.toolbar.action['id'], False)
+ self.toolbar.action['id'] = self.actionOld
+ self.canvas.SetCursor(self.cursorOld)
+
+ dlg = MapDialog(parent = self, id = id, settings = self.instruction,
+ notebook = notebook)
+ dlg.ShowModal()
+
+
+ else: # sofar no map
+ self.mouse["use"] = "addMap"
+ self.canvas.SetCursor(self.cursors["cross"])
+ if self.currentPage == 1:
+ self.book.SetSelection(0)
+ self.currentPage = 0
+
+ def OnAddRaster(self, event):
+ if self.instruction.FindInstructionByType('raster'):
+ id = self.instruction.FindInstructionByType('raster').id
+ else: id = None
+ if self.instruction.FindInstructionByType('map'):
+ mapId = self.instruction.FindInstructionByType('map').id
+ else: mapId = None
+
+ if not id:
+ if not mapId:
+ GMessage(message = _("Please, create map frame first."))
+ return
+
+ dlg = RasterDialog(self, id = id, settings = self.instruction)
+ dlg.ShowModal()
+
+
+
+ def OnAddVect(self, event):
+ if self.instruction.FindInstructionByType('vector'):
+ id = self.instruction.FindInstructionByType('vector').id
+ else: id = None
+ if self.instruction.FindInstructionByType('map'):
+ mapId = self.instruction.FindInstructionByType('map').id
+ else: mapId = None
+ if not id:
+ if not mapId:
+ GMessage(message = _("Please, create map frame first."))
+ return
+
+ dlg = MainVectorDialog(self, id = id, settings = self.instruction)
+ dlg.ShowModal()
+
+ def OnDecoration(self, event):
+ """!Decorations overlay menu
+ """
+ decmenu = wx.Menu()
+ # legend
+ AddLegend = wx.MenuItem(decmenu, wx.ID_ANY, Icons['psMap']["addLegend"].GetLabel())
+ AddLegend.SetBitmap(Icons['psMap']["addLegend"].GetBitmap(self.iconsize))
+ decmenu.AppendItem(AddLegend)
+ self.Bind(wx.EVT_MENU, self.OnAddLegend, AddLegend)
+ # mapinfo
+ AddMapinfo = wx.MenuItem(decmenu, wx.ID_ANY, Icons['psMap']["addMapinfo"].GetLabel())
+ AddMapinfo.SetBitmap(Icons['psMap']["addMapinfo"].GetBitmap(self.iconsize))
+ decmenu.AppendItem(AddMapinfo)
+ self.Bind(wx.EVT_MENU, self.OnAddMapinfo, AddMapinfo)
+ # scalebar
+ AddScalebar = wx.MenuItem(decmenu, wx.ID_ANY, Icons['psMap']["addScalebar"].GetLabel())
+ AddScalebar.SetBitmap(Icons['psMap']["addScalebar"].GetBitmap(self.iconsize))
+ decmenu.AppendItem(AddScalebar)
+ self.Bind(wx.EVT_MENU, self.OnAddScalebar, AddScalebar)
+ # text
+ AddText = wx.MenuItem(decmenu, wx.ID_ANY, Icons['psMap']["addText"].GetLabel())
+ AddText.SetBitmap(Icons['psMap']["addText"].GetBitmap(self.iconsize))
+ decmenu.AppendItem(AddText)
+ self.Bind(wx.EVT_MENU, self.OnAddText, AddText)
+ # Popup the menu. If an item is selected then its handler
+ # will be called before PopupMenu returns.
+ self.PopupMenu(decmenu)
+ decmenu.Destroy()
+
+ def OnAddScalebar(self, event):
+ """!Add scalebar"""
+ if projInfo()['proj'] == 'll':
+ GMessage(message = _("Scalebar is not appropriate for this projection"))
+ return
+ if self.instruction.FindInstructionByType('scalebar'):
+ id = self.instruction.FindInstructionByType('scalebar').id
+ else: id = None
+
+ dlg = ScalebarDialog(self, id = id, settings = self.instruction)
+ dlg.ShowModal()
+
+
+ def OnAddLegend(self, event, page = 0):
+ """!Add raster or vector legend"""
+ if self.instruction.FindInstructionByType('rasterLegend'):
+ idR = self.instruction.FindInstructionByType('rasterLegend').id
+ else: idR = None
+ if self.instruction.FindInstructionByType('vectorLegend'):
+ idV = self.instruction.FindInstructionByType('vectorLegend').id
+ else: idV = None
+
+ dlg = LegendDialog(self, id = [idR, idV], settings = self.instruction, page = page)
+ dlg.ShowModal()
+
+
+
+ def OnAddMapinfo(self, event):
+ if self.instruction.FindInstructionByType('mapinfo'):
+ id = self.instruction.FindInstructionByType('mapinfo').id
+ else: id = None
+
+ dlg = MapinfoDialog(self, id = id, settings = self.instruction)
+ dlg.ShowModal()
+
+
+ def OnAddText(self, event, id = None):
+ dlg = TextDialog(self, id = id, settings = self.instruction)
+ dlg.ShowModal()
+
+ def getModifiedTextBounds(self, x, y, textExtent, rotation):
+ """!computes bounding box of rotated text, not very precisely"""
+ w, h = textExtent
+ rotation = float(rotation)/180*pi
+ H = float(w) * sin(rotation)
+ W = float(w) * cos(rotation)
+ X, Y = x, y
+ if pi/2 < rotation <= 3*pi/2:
+ X = x + W
+ if 0 < rotation < pi:
+ Y = y - H
+ if rotation == 0:
+ return wx.Rect(x,y, *textExtent)
+ else:
+ return wx.Rect(X, Y, abs(W), abs(H)).Inflate(h,h)
+
+ def getTextExtent(self, textDict):
+ fontsize = str(textDict['fontsize'] * self.canvas.currScale)
+ #fontsize = str(fontsize if fontsize >= 4 else 4)
+ dc = wx.PaintDC(self) # dc created because of method GetTextExtent, which pseudoDC lacks
+ dc.SetFont(wx.FontFromNativeInfoString(textDict['font'] + " " + fontsize))
+ return dc.GetTextExtent(textDict['text'])
+
+ def getInitMap(self):
+ """!Create default map frame when no map is selected, needed for coordinates in map units"""
+ instrFile = grass.tempfile()
+ instrFileFd = open(instrFile, mode = 'w')
+ instrFileFd.write(self.InstructionFile())
+ instrFileFd.flush()
+ instrFileFd.close()
+
+ mapInitRect = GetMapBounds(instrFile)
+ grass.try_remove(instrFile)
+
+ region = grass.region()
+ units = UnitConversion(self)
+ realWidth = units.convert(value = abs(region['w'] - region['e']), fromUnit = 'meter', toUnit = 'inch')
+ scale = mapInitRect.Get()[2]/realWidth
+
+ initMap = self.instruction.FindInstructionByType('initMap')
+ id = initMap.id if initMap else None
+
+ if not id:
+ id = wx.NewId()
+ initMap = InitMap(id)
+ self.instruction.AddInstruction(initMap)
+ self.instruction[id].SetInstruction(dict(rect = mapInitRect, scale = scale))
+
+ def OnDelete(self, event):
+ if self.canvas.dragId != -1 and self.currentPage == 0:
+ if self.instruction[self.canvas.dragId].type == 'map':
+ self.deleteObject(self.canvas.dragId)
+ self.getInitMap()
+ self.canvas.RecalculateEN()
+ else:
+ self.deleteObject(self.canvas.dragId)
+
+
+ def deleteObject(self, id):
+ """!Deletes object, his id and redraws"""
+ #delete from canvas
+ self.canvas.pdcObj.RemoveId(id)
+ if id == self.canvas.dragId:
+ self.canvas.pdcTmp.RemoveAll()
+ self.canvas.dragId = -1
+ self.canvas.Refresh()
+
+ # delete from instructions
+ del self.instruction[id]
+
+
+
+
+
+
+
+ def DialogDataChanged(self, id):
+ ids = id
+ if type(id) == int:
+ ids = [id]
+ for id in ids:
+ itype = self.instruction[id].type
+ if itype in ('scalebar', 'mapinfo'):
+ drawRectangle = self.canvas.CanvasPaperCoordinates(
+ rect = self.instruction[id]['rect'], canvasToPaper = False)
+ self.canvas.Draw( pen = self.pen[itype], brush = self.brush[itype],
+ pdc = self.canvas.pdcObj, drawid = id, pdctype = 'rectText', bb = drawRectangle)
+ self.canvas.RedrawSelectBox(id)
+
+
+ if itype == 'text':
+
+ rot = float(self.instruction[id]['rotate']) if self.instruction[id]['rotate'] else 0
+
+ extent = self.getTextExtent(textDict = self.instruction[id].GetInstruction())
+ rect = wx.Rect2D(self.instruction[id]['where'][0], self.instruction[id]['where'][1], 0, 0)
+ self.instruction[id]['coords'] = list(self.canvas.CanvasPaperCoordinates(rect = rect, canvasToPaper = False)[:2])
+
+ #computes text coordinates according to reference point, not precisely
+ if self.instruction[id]['ref'].split()[0] == 'lower':
+ self.instruction[id]['coords'][1] -= extent[1]
+ elif self.instruction[id]['ref'].split()[0] == 'center':
+ self.instruction[id]['coords'][1] -= extent[1]/2
+ if self.instruction[id]['ref'].split()[1] == 'right':
+ self.instruction[id]['coords'][0] -= extent[0] * cos(rot/180*pi)
+ self.instruction[id]['coords'][1] += extent[0] * sin(rot/180*pi)
+ elif self.instruction[id]['ref'].split()[1] == 'center':
+ self.instruction[id]['coords'][0] -= extent[0]/2 * cos(rot/180*pi)
+ self.instruction[id]['coords'][1] += extent[0]/2 * sin(rot/180*pi)
+
+ self.instruction[id]['coords'][0] += self.instruction[id]['xoffset']
+ self.instruction[id]['coords'][1] += self.instruction[id]['yoffset']
+ coords = self.instruction[id]['coords']
+ self.instruction[id]['rect'] = bounds = self.getModifiedTextBounds(coords[0], coords[1], extent, rot)
+ self.canvas.DrawRotText(pdc = self.canvas.pdcObj, drawId = id,
+ textDict = self.instruction[id].GetInstruction(),
+ coords = coords, bounds = bounds)
+ self.canvas.RedrawSelectBox(id)
+
+ if itype in ('map', 'vector', 'raster'):
+
+ if itype == 'raster':#set resolution
+ resol = RunCommand('r.info', read = True, flags = 's', map = self.instruction[id]['raster'])
+ resol = grass.parse_key_val(resol, val_type = float)
+ RunCommand('g.region', nsres = resol['nsres'], ewres = resol['ewres'])
+ id = self.instruction.FindInstructionByType('map').id
+
+ rectCanvas = self.canvas.CanvasPaperCoordinates(rect = self.instruction[id]['rect'],
+ canvasToPaper = False)
+ self.canvas.RecalculateEN()
+ self.canvas.UpdateMapLabel()
+
+ self.canvas.Draw( pen = self.pen['map'], brush = self.brush['map'],
+ pdc = self.canvas.pdcObj, drawid = id, pdctype = 'rectText', bb = rectCanvas)
+ # redraw select box
+ self.canvas.RedrawSelectBox(id)
+ self.canvas.pdcTmp.RemoveId(self.canvas.idZoomBoxTmp)
+
+ if itype == 'rasterLegend':
+ if self.instruction[id]['rLegend']:
+ drawRectangle = self.canvas.CanvasPaperCoordinates(rect = self.instruction[id]['rect'], canvasToPaper = False)
+ self.canvas.Draw( pen = self.pen[itype], brush = self.brush[itype],
+ pdc = self.canvas.pdcObj, drawid = id, pdctype = 'rectText', bb = drawRectangle)
+ self.canvas.RedrawSelectBox(id)
+ else:
+ self.deleteObject(id)
+
+ if itype == 'vectorLegend':
+ if not self.instruction.FindInstructionByType('vector'):
+ self.deleteObject(id)
+ elif self.instruction[id]['vLegend']:
+ drawRectangle = self.canvas.CanvasPaperCoordinates(rect = self.instruction[id]['rect'], canvasToPaper = False)
+ self.canvas.Draw( pen = self.pen[itype], brush = self.brush[itype],
+ pdc = self.canvas.pdcObj, drawid = id, pdctype = 'rectText', bb = drawRectangle)
+ self.canvas.RedrawSelectBox(id)
+
+ else:
+ self.deleteObject(id)
+
+ def OnPageChanged(self, event):
+ """!Flatnotebook page has changed"""
+ self.currentPage = self.book.GetPageIndex(self.book.GetCurrentPage())
+
+
+ def OnPageChanging(self, event):
+ """!Flatnotebook page is changing"""
+ if self.currentPage == 0 and self.mouse['use'] == 'addMap':
+ event.Veto()
+
+ def OnHelp(self, event):
+ """!Show help"""
+ if self.parent and self.parent.GetName() == 'LayerManager':
+ log = self.parent.GetLogWindow()
+ log.RunCmd(['g.manual',
+ 'entry=wxGUI.PsMap'])
+ else:
+ RunCommand('g.manual',
+ quiet = True,
+ entry = 'wxGUI.PsMap')
+
+ def OnAbout(self, event):
+ """!Display About window"""
+ info = wx.AboutDialogInfo()
+
+ info.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
+ info.SetName(_('wxGUI Hardcopy Map Utility'))
+ info.SetWebSite('http://grass.osgeo.org')
+ info.SetDescription(_('(C) 2011 by the GRASS Development Team\n\n') +
+ '\n'.join(textwrap.wrap(_('This program is free software under the GNU General Public License'
+ '(>=v2). Read the file COPYING that comes with GRASS for details.'), 75)))
+
+ wx.AboutBox(info)
+
+ def OnCloseWindow(self, event):
+ """!Close window"""
+ try:
+ os.remove(self.imgName)
+ except OSError:
+ pass
+ self.Destroy()
+
+
+
+class PsMapBufferedWindow(wx.Window):
+ """!A buffered window class.
+
+ @param parent parent window
+ @param kwargs other wx.Window parameters
+ """
+ def __init__(self, parent, id = wx.ID_ANY,
+ style = wx.NO_FULL_REPAINT_ON_RESIZE,
+ **kwargs):
+ wx.Window.__init__(self, parent, id = id, style = style)
+ self.parent = parent
+
+ self.FitInside()
+
+ # store an off screen empty bitmap for saving to file
+ self._buffer = None
+ # indicates whether or not a resize event has taken place
+ self.resize = False
+
+ self.mouse = kwargs['mouse']
+ self.cursors = kwargs['cursors']
+ self.preview = kwargs['preview']
+ self.pen = kwargs['pen']
+ self.brush = kwargs['brush']
+
+ if kwargs.has_key('instruction'):
+ self.instruction = kwargs['instruction']
+ if kwargs.has_key('pageId'):
+ self.pageId = kwargs['pageId']
+ if kwargs.has_key('objectId'):
+ self.objectId = kwargs['objectId']
+
+
+ #labels
+ self.itemLabels = { 'map': ['MAP FRAME'],
+ 'rasterLegend': ['RASTER LEGEND'],
+ 'vectorLegend': ['VECTOR LEGEND'],
+ 'mapinfo': ['MAP INFO'],
+ 'scalebar': ['SCALE BAR']}
+
+ # define PseudoDC
+ self.pdc = wx.PseudoDC()
+ self.pdcObj = wx.PseudoDC()
+ self.pdcPaper = wx.PseudoDC()
+ self.pdcTmp = wx.PseudoDC()
+ self.pdcImage = wx.PseudoDC()
+ dc = wx.PaintDC(self)
+ self.font = dc.GetFont()
+
+ self.SetClientSize((700,510))#?
+ self._buffer = wx.EmptyBitmap(*self.GetClientSize())
+
+ self.idBoxTmp = wx.NewId()
+ self.idZoomBoxTmp = wx.NewId()
+ self.idResizeBoxTmp = wx.NewId()
+
+
+
+ self.dragId = -1
+
+ if self.preview:
+ self.image = None
+ self.imageId = 2000
+ self.imgName = self.parent.imgName
+
+
+
+ self.currScale = None
+
+ self.Clear()
+
+ self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x: None)
+
+ self.Bind(wx.EVT_PAINT, self.OnPaint)
+ self.Bind(wx.EVT_SIZE, self.OnSize)
+ self.Bind(wx.EVT_IDLE, self.OnIdle)
+ self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse)
+
+
+ def Clear(self):
+ """!Clear canvas and set paper
+ """
+ bg = wx.LIGHT_GREY_BRUSH
+ self.pdcPaper.BeginDrawing()
+ self.pdcPaper.SetBackground(bg)
+ self.pdcPaper.Clear()
+ self.pdcPaper.EndDrawing()
+ if not self.preview:
+ self.SetPage()
+
+
+
+ def CanvasPaperCoordinates(self, rect, canvasToPaper = True):
+ """!Converts canvas (pixel) -> paper (inch) coordinates and size and vice versa"""
+
+ units = UnitConversion(self)
+
+ fromU = 'pixel'
+ toU = 'inch'
+ pRect = self.pdcPaper.GetIdBounds(self.pageId)
+ pRectx, pRecty = pRect.x, pRect.y
+ scale = 1/self.currScale
+ if not canvasToPaper: # paper -> canvas
+ fromU = 'inch'
+ toU = 'pixel'
+ scale = self.currScale
+ pRectx = units.convert(value = - pRect.x, fromUnit = 'pixel', toUnit = 'inch' ) /scale #inch, real, negative
+ pRecty = units.convert(value = - pRect.y, fromUnit = 'pixel', toUnit = 'inch' ) /scale
+ Width = units.convert(value = rect.width, fromUnit = fromU, toUnit = toU) * scale
+ Height = units.convert(value = rect.height, fromUnit = fromU, toUnit = toU) * scale
+ X = units.convert(value = (rect.x - pRectx), fromUnit = fromU, toUnit = toU) * scale
+ Y = units.convert(value = (rect.y - pRecty), fromUnit = fromU, toUnit = toU) * scale
+
+ return wx.Rect2D(X, Y, Width, Height)
+
+
+
+ def SetPage(self):
+ """!Sets and changes page, redraws paper"""
+
+ page = self.instruction[self.pageId]
+ if not page:
+ page = PageSetup(id = self.pageId)
+ self.instruction.AddInstruction(page)
+
+ ppi = wx.PaintDC(self).GetPPI()
+ cW, cH = self.GetClientSize()
+ pW, pH = page['Width']*ppi[0], page['Height']*ppi[1]
+
+ if self.currScale is None:
+ self.currScale = min(cW/pW, cH/pH)
+ pW = pW * self.currScale
+ pH = pH * self.currScale
+
+ x = cW/2 - pW/2
+ y = cH/2 - pH/2
+ self.DrawPaper(wx.Rect(x, y, pW, pH))
+
+
+ def modifyRectangle(self, r):
+ """! Recalculates rectangle not to have negative size"""
+ if r.GetWidth() < 0:
+ r.SetX(r.GetX() + r.GetWidth())
+ if r.GetHeight() < 0:
+ r.SetY(r.GetY() + r.GetHeight())
+ r.SetWidth(abs(r.GetWidth()))
+ r.SetHeight(abs(r.GetHeight()))
+ return r
+
+ def RecalculateEN(self):
+ """!Recalculate east and north for texts (eps, points) after their or map's movement"""
+ try:
+ mapId = self.instruction.FindInstructionByType('map').id
+ except AttributeError:
+ mapId = self.instruction.FindInstructionByType('initMap').id
+
+ texts = self.instruction.FindInstructionByType('text', list = True)
+ for text in texts:
+ e, n = PaperMapCoordinates(self, mapId = mapId, x = self.instruction[text.id]['where'][0],
+ y = self.instruction[text.id]['where'][1], paperToMap = True)
+ self.instruction[text.id]['east'], self.instruction[text.id]['north'] = e, n
+
+ def OnPaint(self, event):
+ """!Draw pseudo DC to buffer
+ """
+ if not self._buffer:
+ return
+ dc = wx.BufferedPaintDC(self, self._buffer)
+ # use PrepareDC to set position correctly
+ self.PrepareDC(dc)
+
+ dc.SetBackground(wx.LIGHT_GREY_BRUSH)
+ dc.Clear()
+
+ # draw paper
+ if not self.preview:
+ self.pdcPaper.DrawToDC(dc)
+ # draw to the DC using the calculated clipping rect
+
+ rgn = self.GetUpdateRegion()
+
+ if not self.preview:
+ self.pdcObj.DrawToDCClipped(dc, rgn.GetBox())
+ else:
+ self.pdcImage.DrawToDCClipped(dc, rgn.GetBox())
+ self.pdcTmp.DrawToDCClipped(dc, rgn.GetBox())
+
+ def OnMouse(self, event):
+
+ if event.GetWheelRotation():
+ zoom = event.GetWheelRotation()
+ use = self.mouse['use']
+ self.mouse['begin'] = event.GetPosition()
+ if zoom > 0:
+ self.mouse['use'] = 'zoomin'
+ else:
+ self.mouse['use'] = 'zoomout'
+
+ zoomFactor, view = self.ComputeZoom(wx.Rect(0,0,0,0))
+ self.Zoom(zoomFactor, view)
+ self.mouse['use'] = use
+
+ if event.Moving():
+ if self.mouse['use'] in ('pointer', 'resize'):
+ pos = event.GetPosition()
+ foundResize = self.pdcTmp.FindObjects(pos[0], pos[1])
+ if foundResize and foundResize[0] == self.idResizeBoxTmp:
+ self.SetCursor(self.cursors["sizenwse"])
+ self.parent.SetStatusText(_('Click and drag to resize object'), 0)
+ else:
+ self.parent.SetStatusText(_(''), 0)
+ self.SetCursor(self.cursors["default"])
+ elif event.LeftDown():
+ self.mouse['begin'] = event.GetPosition()
+ self.begin = self.mouse['begin']
+ if self.mouse['use'] in ('pan', 'zoomin', 'zoomout', 'addMap'):
+ pass
+
+ #select
+ if self.mouse['use'] == 'pointer':
+ found = self.pdcObj.FindObjects(self.mouse['begin'][0], self.mouse['begin'][1])
+ foundResize = self.pdcTmp.FindObjects(self.mouse['begin'][0], self.mouse['begin'][1])
+
+ if foundResize and foundResize[0] == self.idResizeBoxTmp:
+ self.mouse['use'] = 'resize'
+ elif found:
+ self.dragId = found[0]
+ self.RedrawSelectBox(self.dragId)
+ if self.instruction[self.dragId].type != 'map':
+ self.pdcTmp.RemoveId(self.idResizeBoxTmp)
+ self.Refresh()
+
+ else:
+ self.dragId = -1
+ self.pdcTmp.RemoveId(self.idBoxTmp)
+ self.pdcTmp.RemoveId(self.idResizeBoxTmp)
+ self.Refresh()
+
+
+ elif event.Dragging() and event.LeftIsDown():
+ #draw box when zooming, creating map
+ if self.mouse['use'] in ('zoomin', 'zoomout', 'addMap'):
+ self.mouse['end'] = event.GetPosition()
+ r = wx.Rect(self.mouse['begin'][0], self.mouse['begin'][1],
+ self.mouse['end'][0]-self.mouse['begin'][0], self.mouse['end'][1]-self.mouse['begin'][1])
+ r = self.modifyRectangle(r)
+ self.Draw(pen = self.pen['box'], brush = self.brush['box'], pdc = self.pdcTmp, drawid = self.idZoomBoxTmp,
+ pdctype = 'rect', bb = r)
+
+ # panning
+ if self.mouse["use"] == 'pan':
+ self.mouse['end'] = event.GetPosition()
+ view = self.mouse['begin'][0] - self.mouse['end'][0], self.mouse['begin'][1] - self.mouse['end'][1]
+ zoomFactor = 1
+ self.Zoom(zoomFactor, view)
+ self.mouse['begin'] = event.GetPosition()
+
+ #move object
+ if self.mouse['use'] == 'pointer' and self.dragId != -1:
+
+ self.mouse['end'] = event.GetPosition()
+ dx, dy = self.mouse['end'][0] - self.begin[0], self.mouse['end'][1] - self.begin[1]
+ self.pdcObj.TranslateId(self.dragId, dx, dy)
+ self.pdcTmp.TranslateId(self.idBoxTmp, dx, dy)
+ self.pdcTmp.TranslateId(self.idResizeBoxTmp, dx, dy)
+ if self.instruction[self.dragId].type == 'text':
+ self.instruction[self.dragId]['coords'] = self.instruction[self.dragId]['coords'][0] + dx,\
+ self.instruction[self.dragId]['coords'][1] + dy
+ self.begin = event.GetPosition()
+ self.Refresh()
+
+ # resize object
+ if self.mouse['use'] == 'resize':
+ bounds = self.pdcObj.GetIdBounds(self.dragId)
+ type = self.instruction[self.dragId].type
+ self.mouse['end'] = event.GetPosition()
+ diffX = self.mouse['end'][0] - self.begin[0]
+ diffY = self.mouse['end'][1] - self.begin[1]
+ bounds.Inflate(diffX, diffY)
+
+ self.Draw(pen = self.pen[type], brush = self.brush[type], pdc = self.pdcObj, drawid = self.dragId,
+ pdctype = 'rectText', bb = bounds)
+ self.RedrawSelectBox(self.dragId)
+ self.begin = event.GetPosition()
+
+ elif event.LeftUp():
+ # zoom in, zoom out
+ if self.mouse['use'] in ('zoomin','zoomout'):
+ zoomR = self.pdcTmp.GetIdBounds(self.idZoomBoxTmp)
+ self.pdcTmp.RemoveId(self.idZoomBoxTmp)
+ self.Refresh()
+ zoomFactor, view = self.ComputeZoom(zoomR)
+ self.Zoom(zoomFactor, view)
+
+
+ # draw map frame
+ if self.mouse['use'] == 'addMap':
+ rectTmp = self.pdcTmp.GetIdBounds(self.idZoomBoxTmp)
+ rectPaper = self.CanvasPaperCoordinates(rect = rectTmp, canvasToPaper = True)
+
+ dlg = MapDialog(parent = self.parent, id = [None, None, None], settings = self.instruction,
+ rect = rectPaper)
+ dlg.ShowModal()
+ if self.instruction.FindInstructionByType('map'):
+ #redraw objects to lower map to the bottom
+ self.Zoom(zoomFactor = 1, view = (0, 0))
+
+ self.mouse['use'] = self.parent.mouseOld
+
+ self.SetCursor(self.parent.cursorOld)
+ self.parent.toolbar.ToggleTool(self.parent.actionOld, True)
+ self.parent.toolbar.ToggleTool(self.parent.toolbar.action['id'], False)
+ self.parent.toolbar.action['id'] = self.parent.actionOld
+
+ self.pdcTmp.RemoveId(self.idZoomBoxTmp)
+ self.Refresh()
+
+
+ # resize resizable objects (only map sofar)
+ if self.mouse['use'] == 'resize':
+ mapId = self.instruction.FindInstructionByType('map').id
+
+ if self.dragId == mapId:
+ # necessary to change either map frame (scaleType 0,1,2) or region (scaletype 3)
+ newRectCanvas = self.pdcObj.GetIdBounds(mapId)
+ newRectPaper = self.CanvasPaperCoordinates(rect = newRectCanvas, canvasToPaper = True)
+ self.instruction[mapId]['rect'] = newRectPaper
+
+ if self.instruction[mapId]['scaleType'] in (0, 1, 2):
+ if self.instruction[mapId]['scaleType'] == 0:
+
+ scale, foo, rect = AutoAdjust(self, scaleType = 0,
+ map = self.instruction[mapId]['map'],
+ mapType = self.instruction[mapId]['mapType'],
+ rect = self.instruction[mapId]['rect'])
+ if self.instruction[mapId]['scaleType'] == 1:
+ scale, foo, rect = AutoAdjust(self, scaleType = 1,
+ region = self.instruction[mapId]['region'],
+ rect = self.instruction[mapId]['rect'])
+ else:
+ scale, foo, rect = AutoAdjust(self, scaleType = 2,
+ rect = self.instruction[mapId]['rect'])
+ self.instruction[mapId]['rect'] = rect
+ self.instruction[mapId]['scale'] = scale
+
+ rectCanvas = self.CanvasPaperCoordinates(rect = rect, canvasToPaper = False)
+ self.Draw(pen = self.pen['map'], brush = self.brush['map'],
+ pdc = self.pdcObj, drawid = mapId, pdctype = 'rectText', bb = rectCanvas)
+
+ elif self.instruction[mapId]['scaleType'] == 3:
+ ComputeSetRegion(self, mapDict = self.instruction[mapId].GetInstruction())
+
+ self.RedrawSelectBox(mapId)
+ self.mouse['use'] = 'pointer'
+
+ # recalculate the position of objects after dragging
+ if self.mouse['use'] in ('pointer', 'resize') and self.dragId != -1:
+ if self.mouse['begin'] != event.GetPosition(): #for double click
+
+ self.RecalculatePosition(ids = [self.dragId])
+
+ # double click launches dialogs
+ elif event.LeftDClick():
+ if self.mouse['use'] == 'pointer' and self.dragId != -1:
+ itemCall = { 'text':self.parent.OnAddText, 'mapinfo': self.parent.OnAddMapinfo,
+ 'scalebar': self.parent.OnAddScalebar,
+ 'rasterLegend': self.parent.OnAddLegend, 'vectorLegend': self.parent.OnAddLegend,
+ 'map': self.parent.OnAddMap}
+ itemArg = { 'text': dict(event = None, id = self.dragId), 'mapinfo': dict(event = None),
+ 'scalebar': dict(event = None),
+ 'rasterLegend': dict(event = None), 'vectorLegend': dict(event = None, page = 1),
+ 'map': dict(event = None, notebook = True)}
+ type = self.instruction[self.dragId].type
+ itemCall[type](**itemArg[type])
+
+
+
+
+ def RecalculatePosition(self, ids):
+ for id in ids:
+ itype = self.instruction[id].type
+ if itype == 'map':
+ self.instruction[id]['rect'] = self.CanvasPaperCoordinates(rect = self.pdcObj.GetIdBounds(id),
+ canvasToPaper = True)
+ self.RecalculateEN()
+
+ elif itype in ('mapinfo' ,'rasterLegend', 'vectorLegend'):
+ self.instruction[id]['rect'] = self.CanvasPaperCoordinates(rect = self.pdcObj.GetIdBounds(id),
+ canvasToPaper = True)
+ self.instruction[id]['where'] = self.CanvasPaperCoordinates(rect = self.pdcObj.GetIdBounds(id),
+ canvasToPaper = True)[:2]
+ elif itype == 'scalebar':
+ self.instruction[id]['rect'] = self.CanvasPaperCoordinates(rect = self.pdcObj.GetIdBounds(id),
+ canvasToPaper = True)
+
+
+ self.instruction[id]['where'] = self.instruction[id]['rect'].GetCentre()
+
+ elif itype == 'text':
+ x, y = self.instruction[id]['coords'][0] - self.instruction[id]['xoffset'],\
+ self.instruction[id]['coords'][1] - self.instruction[id]['yoffset']
+ extent = self.parent.getTextExtent(textDict = self.instruction[id])
+ rot = float(self.instruction[id]['rotate'])/180*pi if self.instruction[id]['rotate'] is not None else 0
+ if self.instruction[id]['ref'].split()[0] == 'lower':
+ y += extent[1]
+ elif self.instruction[id]['ref'].split()[0] == 'center':
+ y += extent[1]/2
+ if self.instruction[id]['ref'].split()[1] == 'right':
+ x += extent[0] * cos(rot)
+ y -= extent[0] * sin(rot)
+ elif self.instruction[id]['ref'].split()[1] == 'center':
+ x += extent[0]/2 * cos(rot)
+ y -= extent[0]/2 * sin(rot)
+
+ self.instruction[id]['where'] = self.CanvasPaperCoordinates(rect = wx.Rect2D(x, y, 0, 0),
+ canvasToPaper = True)[:2]
+ self.RecalculateEN()
+
+ def ComputeZoom(self, rect):
+ """!Computes zoom factor and scroll view"""
+ zoomFactor = 1
+ cW, cH = self.GetClientSize()
+ cW = float(cW)
+ if rect.IsEmpty(): # clicked on canvas
+ zoomFactor = 1.5
+ if self.mouse['use'] == 'zoomout':
+ zoomFactor = 1./zoomFactor
+ x,y = self.mouse['begin']
+ xView = x - cW/(zoomFactor * 2)
+ yView = y - cH/(zoomFactor * 2)
+
+ else: #dragging
+ rW, rH = float(rect.GetWidth()), float(rect.GetHeight())
+ zoomFactor = 1/max(rW/cW, rH/cH)
+ # when zooming to full extent, in some cases, there was zoom 1.01..., which causes problem
+ zoomFactor = zoomFactor if abs(zoomFactor - 1) > 0.01 else 1.
+
+ if self.mouse['use'] == 'zoomout':
+ zoomFactor = min(rW/cW, rH/cH)
+ if rW/rH > cW/cH:
+ yView = rect.GetY() - (rW*(cH/cW) - rH)/2
+ xView = rect.GetX()
+
+ if self.mouse['use'] == 'zoomout':
+ x,y = rect.GetX() + (rW-(cW/cH)*rH)/2, rect.GetY()
+ xView, yView = -x, -y
+ else:
+ xView = rect.GetX() - (rH*(cW/cH) - rW)/2
+ yView = rect.GetY()
+ if self.mouse['use'] == 'zoomout':
+ x,y = rect.GetX(), rect.GetY() + (rH-(cH/cW)*rW)/2
+ xView, yView = -x, -y
+ return zoomFactor, (int(xView), int(yView))
+
+
+ def Zoom(self, zoomFactor, view):
+ """! Zoom to specified region, scroll view, redraw"""
+ if not self.currScale:
+ return
+ self.currScale = self.currScale*zoomFactor
+
+ if self.currScale > 10 or self.currScale < 0.1:
+ self.currScale = self.currScale/zoomFactor
+ return
+ if not self.preview:
+ # redraw paper
+ pRect = self.pdcPaper.GetIdBounds(self.pageId)
+ pRect.OffsetXY(-view[0], -view[1])
+ pRect = self.ScaleRect(rect = pRect, scale = zoomFactor)
+ self.DrawPaper(pRect)
+
+ #redraw objects
+ for id in self.objectId:
+ oRect = self.CanvasPaperCoordinates(
+ rect = self.instruction[id]['rect'], canvasToPaper = False)
+
+ type = self.instruction[id].type
+ if type == 'text':
+ coords = self.instruction[id]['coords']# recalculate coordinates, they are not equal to BB
+ self.instruction[id]['coords'] = coords = [(int(coord) - view[i]) * zoomFactor
+ for i, coord in enumerate(coords)]
+ self.DrawRotText(pdc = self.pdcObj, drawId = id, textDict = self.instruction[id],
+ coords = coords, bounds = oRect )
+ extent = self.parent.getTextExtent(textDict = self.instruction[id])
+ rot = float(self.instruction[id]['rotate']) if self.instruction[id]['rotate'] else 0
+ self.instruction[id]['rect'] = bounds = self.parent.getModifiedTextBounds(coords[0], coords[1], extent, rot)
+ self.pdcObj.SetIdBounds(id, bounds)
+ else:
+ self.Draw(pen = self.pen[type], brush = self.brush[type], pdc = self.pdcObj,
+ drawid = id, pdctype = 'rectText', bb = oRect)
+ #redraw tmp objects
+ if self.dragId != -1:
+ self.RedrawSelectBox(self.dragId)
+
+ #redraw preview
+ else: # preview mode
+ imageRect = self.pdcImage.GetIdBounds(self.imageId)
+ imageRect.OffsetXY(-view[0], -view[1])
+ imageRect = self.ScaleRect(rect = imageRect, scale = zoomFactor)
+ self.DrawImage(imageRect)
+
+
+
+ def ZoomAll(self):
+ """! Zoom to full extent"""
+ if not self.preview:
+ bounds = self.pdcPaper.GetIdBounds(self.pageId)
+ else:
+ bounds = self.pdcImage.GetIdBounds(self.imageId)
+ zoomP = bounds.Inflate(bounds.width/20, bounds.height/20)
+ zoomFactor, view = self.ComputeZoom(zoomP)
+ self.Zoom(zoomFactor, view)
+
+ def Draw(self, pen, brush, pdc, drawid = None, pdctype = 'rect', bb = wx.Rect(0,0,0,0)):
+ """! Draw object"""
+ if drawid is None:
+ drawid = wx.NewId()
+ bb = bb.Get()
+ pdc.BeginDrawing()
+ pdc.RemoveId(drawid)
+ pdc.SetId(drawid)
+ pdc.SetPen(pen)
+ pdc.SetBrush(brush)
+ if pdctype in ('rect', 'rectText'):
+ pdc.DrawRectangle(*bb)
+ if pdctype == 'rectText':
+ dc = wx.PaintDC(self) # dc created because of method GetTextExtent, which pseudoDC lacks
+ font = self.font
+ size = 10
+ font.SetPointSize(size)
+ font.SetStyle(wx.ITALIC)
+ dc.SetFont(font)
+ pdc.SetFont(font)
+ text = '\n'.join(self.itemLabels[self.instruction[drawid].type])
+ textExtent = dc.GetTextExtent(text)
+ textRect = wx.Rect(0, 0, *textExtent).CenterIn(bb)
+ r = map(int, bb)
+ while not wx.Rect(*r).ContainsRect(textRect) and size >= 8:
+ size -= 2
+ font.SetPointSize(size)
+ dc.SetFont(font)
+ pdc.SetFont(font)
+ textExtent = dc.GetTextExtent(text)
+ textRect = wx.Rect(0, 0, *textExtent).CenterIn(bb)
+ pdc.SetTextForeground(wx.Color(100,100,100,200))
+ pdc.SetBackgroundMode(wx.TRANSPARENT)
+
+ pdc.DrawText(text = text, x = textRect.x, y = textRect.y)
+
+ pdc.SetIdBounds(drawid, bb)
+ pdc.EndDrawing()
+ self.Refresh()
+
+ return drawid
+
+ def DrawRotText(self, pdc, drawId, textDict, coords, bounds):
+ rot = float(textDict['rotate']) if textDict['rotate'] else 0
+ fontsize = str(textDict['fontsize'] * self.currScale)
+ background = textDict['background'] if textDict['background'] != 'none' else None
+
+ dc = wx.PaintDC(self) # dc created because of method GetTextExtent, which pseudoDC lacks
+ dc.SetFont(wx.FontFromNativeInfoString(textDict['font'] + " " + fontsize))
+ textExtent = dc.GetTextExtent(textDict['text'])
+
+ pdc.RemoveId(drawId)
+ pdc.SetId(drawId)
+ pdc.BeginDrawing()
+ # doesn't work
+ if background:
+ pdc.SetBackground(wx.Brush(convertRGB(background)))
+ pdc.SetBackgroundMode(wx.SOLID)
+ else:
+ pdc.SetBackground(wx.TRANSPARENT_BRUSH)
+ pdc.SetBackgroundMode(wx.TRANSPARENT)
+ pdc.SetFont(wx.FontFromNativeInfoString(textDict['font'] + " " + fontsize))
+## pdc.SetTextForeground(convertRGB(textDict['color']))
+ pdc.SetTextForeground(textDict['color'])
+ pdc.DrawRotatedText(textDict['text'], coords[0], coords[1], rot)
+
+ pdc.SetIdBounds(drawId, wx.Rect(*bounds))
+ self.Refresh()
+ pdc.EndDrawing()
+
+ def DrawImage(self, rect):
+ """!Draw preview image to pseudoDC"""
+ self.pdcImage.ClearId(self.imageId)
+ self.pdcImage.SetId(self.imageId)
+ img = self.image
+
+
+ if img.GetWidth() != rect.width or img.GetHeight() != rect.height:
+ img = img.Scale(rect.width, rect.height)
+ bitmap = img.ConvertToBitmap()
+
+ self.pdcImage.BeginDrawing()
+ self.pdcImage.DrawBitmap(bitmap, rect.x, rect.y)
+ self.pdcImage.SetIdBounds(self.imageId, rect)
+ self.pdcImage.EndDrawing()
+ self.Refresh()
+
+ def DrawPaper(self, rect):
+ """!Draw paper and margins"""
+ page = self.instruction[self.pageId]
+ scale = page['Width'] / rect.GetWidth()
+ w = (page['Width'] - page['Right'] - page['Left']) / scale
+ h = (page['Height'] - page['Top'] - page['Bottom']) / scale
+ x = page['Left'] / scale + rect.GetX()
+ y = page['Top'] / scale + rect.GetY()
+
+ self.pdcPaper.BeginDrawing()
+ self.pdcPaper.RemoveId(self.pageId)
+ self.pdcPaper.SetId(self.pageId)
+ self.pdcPaper.SetPen(self.pen['paper'])
+ self.pdcPaper.SetBrush(self.brush['paper'])
+ self.pdcPaper.DrawRectangleRect(rect)
+
+ self.pdcPaper.SetPen(self.pen['margins'])
+ self.pdcPaper.SetBrush(self.brush['margins'])
+ self.pdcPaper.DrawRectangle(x, y, w, h)
+
+ self.pdcPaper.SetIdBounds(self.pageId, rect)
+ self.pdcPaper.EndDrawing()
+ self.Refresh()
+
+
+ def ImageRect(self):
+ """!Returns image centered in canvas, computes scale"""
+ img = wx.Image(self.imgName, wx.BITMAP_TYPE_PNG)
+ cW, cH = self.GetClientSize()
+ iW, iH = img.GetWidth(), img.GetHeight()
+
+ self.currScale = min(float(cW)/iW, float(cH)/iH)
+ iW = iW * self.currScale
+ iH = iH * self.currScale
+ x = cW/2 - iW/2
+ y = cH/2 - iH/2
+ imageRect = wx.Rect(x, y, iW, iH)
+
+ return imageRect
+
+ def RedrawSelectBox(self, id):
+ """!Redraws select box when selected object changes its size"""
+ if self.dragId == id:
+ rect = [self.pdcObj.GetIdBounds(id).Inflate(3,3)]
+ type = ['select']
+ ids = [self.idBoxTmp]
+ if self.instruction[id].type == 'map':
+ controlP = self.pdcObj.GetIdBounds(id).GetBottomRight()
+ rect.append(wx.Rect(controlP.x, controlP.y, 10,10))
+ type.append('resize')
+ ids.append(self.idResizeBoxTmp)
+ for id, type, rect in zip(ids, type, rect):
+ self.Draw(pen = self.pen[type], brush = self.brush[type], pdc = self.pdcTmp,
+ drawid = id, pdctype = 'rect', bb = rect)
+
+ def UpdateMapLabel(self):
+ """!Updates map frame label"""
+ mapId = self.instruction.FindInstructionByType('map').id
+ vector = self.instruction.FindInstructionByType('vector')
+ vectorId = vector.id if vector else None
+ raster = self.instruction.FindInstructionByType('raster')
+ rasterId = raster.id if raster else None
+ rasterName = 'None'
+ if rasterId:
+ rasterName = self.instruction[rasterId]['raster'].split('@')[0]
+
+ self.itemLabels['map'] = self.itemLabels['map'][0:1]
+ self.itemLabels['map'].append("raster: " + rasterName)
+ if vectorId:
+ for map in self.instruction[vectorId]['list']:
+ self.itemLabels['map'].append('vector: ' + map[0].split('@')[0])
+
+ def OnSize(self, event):
+ """!Init image size to match window size
+ """
+ # not zoom all when notebook page is changed
+ if self.preview and self.parent.currentPage == 1 or not self.preview and self.parent.currentPage == 0:
+ self.ZoomAll()
+ self.OnIdle(None)
+ event.Skip()
+
+ def OnIdle(self, event):
+ """!Only re-render a image during idle time instead of
+ multiple times during resizing.
+ """
+
+ width, height = self.GetClientSize()
+ # Make new off screen bitmap: this bitmap will always have the
+ # current drawing in it, so it can be used to save the image
+ # to a file, or whatever.
+ self._buffer = wx.EmptyBitmap(width, height)
+ # re-render image on idle
+ self.resize = True
+
+
+ def ScaleRect(self, rect, scale):
+ """! Scale rectangle"""
+ return wx.Rect(rect.GetLeft()*scale, rect.GetTop()*scale,
+ rect.GetSize()[0]*scale, rect.GetSize()[1]*scale)
+
+def main():
+ app = wx.PySimpleApp()
+ wx.InitAllImageHandlers()
+ frame = PsMapFrame()
+ frame.Show()
+
+ app.MainLoop()
+
+if __name__ == "__main__":
+ main()
Added: grass-addons/gui/wxpython/psmap/gui_modules/psmap_dialogs.py
===================================================================
--- grass-addons/gui/wxpython/psmap/gui_modules/psmap_dialogs.py (rev 0)
+++ grass-addons/gui/wxpython/psmap/gui_modules/psmap_dialogs.py 2011-03-14 07:15:14 UTC (rev 45659)
@@ -0,0 +1,4488 @@
+"""!
+ at package psmap_dialogs
+
+ at brief dialogs for ps.map
+
+Classes:
+ - UnitConversion
+ - PageSetupDialog
+ - MapDialog
+ - LegendDialog
+
+(C) 2011 by Anna Kratochvilova, and the GRASS Development Team
+This program is free software under the GNU General Public License
+(>=v2). Read the file COPYING that comes with GRASS for details.
+
+ at author Anna Kratochvilova <anna.kratochvilova fsv.cvut.cz> (bachelor's project)
+ at author Martin Landa <landa.martin gmail.com> (mentor)
+"""
+
+import os
+import sys
+import string
+from math import ceil, floor
+from copy import deepcopy
+
+import grass.script as grass
+if int(grass.version()['version'].split('.')[0]) > 6:
+ sys.path.append(os.path.join(os.getenv('GISBASE'), 'etc', 'gui', 'wxpython',
+ 'gui_modules'))
+else:
+ sys.path.append(os.path.join(os.getenv('GISBASE'), 'etc', 'wxpython',
+ 'gui_modules'))
+import globalvar
+import dbm_base
+from utils import CmdToTuple
+from gselect import Select
+from gcmd import RunCommand, GError, GMessage
+
+import wx
+import wx.lib.scrolledpanel as scrolled
+import wx.lib.filebrowsebutton as filebrowse
+from wx.lib.mixins.listctrl import CheckListCtrlMixin, ListCtrlAutoWidthMixin
+from wx.lib.expando import ExpandoTextCtrl, EVT_ETC_LAYOUT_NEEDED
+
+try:
+ from agw import flatnotebook as fnb
+except ImportError: # if it's not there locally, try the wxPython lib.
+ import wx.lib.agw.flatnotebook as fnb
+
+grass.set_raise_on_error(True)
+
+class UnitConversion():
+ """! Class for converting units"""
+ def __init__(self, parent):
+ self.parent = parent
+ ppi = wx.PaintDC(self.parent).GetPPI()
+ self._unitsPage = { 'inch' : 1.0,
+ 'point' : 72.0,
+ 'centimeter' : 2.54,
+ 'milimeter' : 25.4}
+ self._unitsMap = { 'meters' : 0.0254,
+ 'kilometers' : 2.54e-5,
+ 'feet' : 1./12,
+ 'miles' : 1./63360,
+ 'nautical miles' : 1/72913.44}
+
+ self._units = { 'pixel': ppi[0],
+ 'meter': 0.0254,
+ 'degrees' : 0.0254 #like 1 meter, incorrect
+ }
+ self._units.update(self._unitsPage)
+ self._units.update(self._unitsMap)
+
+ def getPageUnits(self):
+ return sorted(self._unitsPage.keys())
+
+ def getMapUnits(self):
+ return sorted(self._unitsMap.keys())
+
+ def getAllUnits(self):
+ return sorted(self._units.keys())
+
+ def convert(self, value, fromUnit = None, toUnit = None):
+ return float(value)/self._units[fromUnit]*self._units[toUnit]
+
+
+class TCValidator(wx.PyValidator):
+ """!validates input in textctrls, combobox, taken from wxpython demo"""
+ def __init__(self, flag = None):
+ wx.PyValidator.__init__(self)
+ self.flag = flag
+ self.Bind(wx.EVT_CHAR, self.OnChar)
+
+ def Clone(self):
+ return TCValidator(self.flag)
+
+ def Validate(self, win):
+
+ tc = self.GetWindow()
+ val = tc.GetValue()
+
+ if self.flag == 'DIGIT_ONLY':
+ for x in val:
+ if x not in string.digits:
+ return False
+ return True
+
+ def OnChar(self, event):
+ key = event.GetKeyCode()
+ if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255:
+ event.Skip()
+ return
+ if self.flag == 'DIGIT_ONLY' and chr(key) in string.digits + '.':
+ event.Skip()
+ return
+## if self.flag == 'SCALE' and chr(key) in string.digits + ':':
+## event.Skip()
+## return
+ if self.flag == 'ZERO_AND_ONE_ONLY' and chr(key) in '01':
+ event.Skip()
+ return
+ if not wx.Validator_IsSilent():
+ wx.Bell()
+ # Returning without calling even.Skip eats the event before it
+ # gets to the text control
+ return
+
+
+class PenStyleComboBox(wx.combo.OwnerDrawnComboBox):
+ """!Combo for selecting line style, taken from wxpython demo"""
+
+ # Overridden from OwnerDrawnComboBox, called to draw each
+ # item in the list
+ def OnDrawItem(self, dc, rect, item, flags):
+ if item == wx.NOT_FOUND:
+ # painting the control, but there is no valid item selected yet
+ return
+
+ r = wx.Rect(*rect) # make a copy
+ r.Deflate(3, 5)
+
+ penStyle = wx.SOLID
+ if item == 1:
+ penStyle = wx.LONG_DASH
+ elif item == 2:
+ penStyle = wx.DOT
+ elif item == 3:
+ penStyle = wx.DOT_DASH
+
+ pen = wx.Pen(dc.GetTextForeground(), 3, penStyle)
+ dc.SetPen(pen)
+
+ # for painting the items in the popup
+ dc.DrawText(self.GetString( item ),
+ r.x + 3,
+ (r.y + 0) + ( (r.height/2) - dc.GetCharHeight() )/2
+ )
+ dc.DrawLine( r.x+5, r.y+((r.height/4)*3)+1, r.x+r.width - 5, r.y+((r.height/4)*3)+1 )
+
+
+ def OnDrawBackground(self, dc, rect, item, flags):
+ """!Overridden from OwnerDrawnComboBox, called for drawing the
+ background area of each item."""
+ # If the item is selected, or its item # iseven, or we are painting the
+ # combo control itself, then use the default rendering.
+ if (item & 1 == 0 or flags & (wx.combo.ODCB_PAINTING_CONTROL |
+ wx.combo.ODCB_PAINTING_SELECTED)):
+ wx.combo.OwnerDrawnComboBox.OnDrawBackground(self, dc, rect, item, flags)
+ return
+
+ # Otherwise, draw every other background with different colour.
+ bgCol = wx.Colour(240,240,250)
+ dc.SetBrush(wx.Brush(bgCol))
+ dc.SetPen(wx.Pen(bgCol))
+ dc.DrawRectangleRect(rect);
+
+ def OnMeasureItem(self, item):
+ """!Overridden from OwnerDrawnComboBox, should return the height
+ needed to display an item in the popup, or -1 for default"""
+ return 30
+
+ def OnMeasureItemWidth(self, item):
+ """!Overridden from OwnerDrawnComboBox. Callback for item width, or
+ -1 for default/undetermined"""
+ return -1; # default - will be measured from text width
+
+
+class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin):
+ """!List control for managing order and labels of vector maps in legend"""
+ def __init__(self, parent):
+ wx.ListCtrl.__init__(self, parent, id = wx.ID_ANY,
+ style = wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.BORDER_SUNKEN|wx.LC_VRULES|wx.LC_HRULES)
+ CheckListCtrlMixin.__init__(self)
+ ListCtrlAutoWidthMixin.__init__(self)
+
+class Instruction:
+ """!Class which represents instruction file"""
+ def __init__(self, parent, objectsToDraw):
+
+ self.parent = parent
+ self.objectsToDraw = objectsToDraw
+ #here are kept objects like mapinfo, rasterlegend, etc.
+ self.instruction = list()
+
+ def __str__(self):
+ """!Returns text for instruction file"""
+ border = ''
+ if not self.FindInstructionByType('map'):
+ border = 'border n\n'
+ text = [str(each) for each in self.instruction]
+ return border + '\n'.join(text) + '\nend'
+
+ def __getitem__(self, id):
+ for each in self.instruction:
+ if each.id == id:
+ return each
+ return None
+
+ def __contains__(self, id):
+ """!Test if instruction is included"""
+ for each in self.instruction:
+ if each.id == id:
+ return True
+ return False
+
+ def __delitem__(self, id):
+ """!Delete instruction"""
+ for each in self.instruction:
+ if each.id == id:
+ if each.type == 'map':
+ #must remove raster, vector layers too
+ vektor = self.FindInstructionByType('vector', list = True)
+ vProperties = self.FindInstructionByType('vProperties', list = True)
+ raster = self.FindInstructionByType('raster', list = True)
+ for item in vektor + vProperties + raster:
+ if item in self.instruction:
+ self.instruction.remove(item)
+
+ self.instruction.remove(each)
+ if id in self.objectsToDraw:
+ self.objectsToDraw.remove(id)
+ return
+
+ def AddInstruction(self, instruction):
+ """!Add instruction"""
+ self.instruction.append(instruction)
+ if instruction.type not in ('page', 'raster', 'vector', 'vProperties', 'initMap'):
+ self.objectsToDraw.append(instruction.id)
+
+
+
+ def FindInstructionByType(self, type, list = False):
+ """!Find instruction(s) with the given type"""
+ inst = []
+ for each in self.instruction:
+ if each.type == type:
+ inst.append(each)
+ if len(inst) == 1 and not list:
+ return inst[0]
+ return inst
+
+ def Read(self, filename):
+ """!Reads instruction file and creates instruction objects"""
+ print 'Starts to read...'
+ # open file
+ try:
+ file = open(filename, 'r')
+ except IOError:
+ GError(message = _("Unable to open file\n{0}").format(filename))
+ return
+ # read lines
+ isBuffer = False
+ buffer = []
+ instruction = None
+ isRegionComment = False
+ for line in file:
+ line = line.strip()
+ if isBuffer:
+ buffer.append(line)
+ if line.startswith('end'):
+ isBuffer = False
+ self.SendToRead(instruction, buffer)
+ buffer = []
+ continue
+
+ if line.startswith('#'):
+ if 'g.region' in line:
+ instruction = 'gregion'
+ self.SendToRead(instruction, line)
+ isRegionComment = True
+ else:
+ continue
+
+ if line.startswith('paper'):
+ instruction = 'paper'
+ isBuffer = True
+ buffer.append(line)
+ continue
+
+ if line.startswith('border'):
+ if line == 'border n':
+ self.SendToRead('border', [line])
+ continue
+ elif line == 'border y':
+ instruction = 'border'
+ isBuffer = True
+ buffer.append(line)
+ continue
+
+ if line.startswith('scale'):
+ self.SendToRead('scale', line)
+ continue
+
+ if line.startswith('maploc'):
+ self.SendToRead(instruction = 'maploc', text = line, filename = filename)
+ continue
+
+ if line.startswith('raster'):
+ self.SendToRead(instruction = 'raster', text = line)
+ continue
+
+ if line.startswith('mapinfo'):
+ instruction = 'mapinfo'
+ isBuffer = True
+ buffer.append(line)
+ continue
+
+
+ # check at the end
+ if not isRegionComment:
+ map = self.FindInstructionByType('map')
+ if map:
+ map['scaleType'] = 2 # current region
+ if not map['rect']:
+ map['rect'] = GetMapBounds(filename)
+ if map['rect']:
+ region = grass.region()
+ units = UnitConversion(self.parent)
+ realWidth = units.convert(value = abs(region['w'] - region['e']), fromUnit = 'meter', toUnit = 'inch')
+ scale = map['rect'].Get()[2]/realWidth
+ map['scale'] = scale
+
+
+ else:
+ rect = GetMapBounds(filename)
+ if rect:
+ initMap = InitMap(wx.NewId())
+ self.instruction.AddInstruction(initMap)
+ initMap['rect'] = rect
+ region = grass.region()
+ units = UnitConversion(self.parent)
+ realWidth = units.convert(value = abs(region['w'] - region['e']), fromUnit = 'meter', toUnit = 'inch')
+ scale = rect.Get()[2]/realWidth
+ initMap['scale'] = scale
+
+ print 'end of reading'
+
+
+ def SendToRead(self, instruction, text, **kwargs):
+ #print 'send to read', instruction, text
+ psmapInstrDict = dict( paper = ['page'],
+ maploc = ['map'],
+ scale = ['map'],
+ border = ['map'],
+ raster = ['raster'],
+ mapinfo = ['mapinfo'],
+ scalebar = ['scalebar'],
+ text = ['text'],
+ vpoints = ['vector', 'vProperties'],
+ vlines = ['vector', 'vProperties'],
+ vareas = ['vector', 'vProperties'],
+ colortable = ['rasterLegend'],
+ vlegend = ['vectorLegend'],
+ # not a real instruction, just help in commentary
+ gregion = ['map']
+ )
+
+ myInstrDict = dict( page = PageSetup,
+ map = MapFrame,
+ raster = Raster,
+ mapinfo = Mapinfo,
+ scalebar = Scalebar,
+ text = Text,
+ rasterLegend = RasterLegend,
+ vectorLegend = VectorLegend,
+ vector = Vector,
+ vProperties = VProperties
+ )
+
+ myInstruction = psmapInstrDict[instruction]
+
+ for i in myInstruction:
+ instr = self.FindInstructionByType(i)
+ if i in ('text', 'vProperties') or not instr:
+ id = wx.NewId() #!vProperties expect subtype
+ newInstr = myInstrDict[i](id)
+ ok = newInstr.Read(instruction, text, **kwargs)
+ if ok:
+ self.AddInstruction(newInstr)
+ else:
+ GMessage(_("Failed to read"))
+
+ else:
+ ok = instr.Read(instruction, text, **kwargs)
+
+ if not ok:
+ GMessage(_("Failed to read"))
+
+
+
+
+class InstructionObject:
+ """!Abtract class representing single instruction"""
+ def __init__(self, id):
+ self.id = id
+
+ # default values
+ self.defaultInstruction = dict()
+ # current values
+ self.instruction = self.defaultInstruction
+
+ def __str__(self):
+ """!Returns particular part of text instruction"""
+ return ''
+
+ def __getitem__(self, key):
+ for each in self.instruction.keys():
+ if each == key:
+ return self.instruction[key]
+ return None
+
+ def __setitem__(self, key, value):
+ self.instruction[key] = value
+
+ def GetInstruction(self):
+ """!Get current values"""
+ return self.instruction
+
+ def SetInstruction(self, instruction):
+ """!Set default values"""
+ self.instruction = instruction
+
+ def Read(self, instruction, text, **kwargs):
+ """!Read instruction and save them"""
+ pass
+
+class InitMap(InstructionObject):
+ """!Class representing virtual map"""
+ def __init__(self, id):
+ InstructionObject.__init__(self, id = id)
+ self.type = 'initMap'
+
+ # default values
+ self.defaultInstruction = dict(rect = None, scale = None)
+ # current values
+ self.instruction = dict(self.defaultInstruction)
+
+
+class MapFrame(InstructionObject):
+ """!Class representing map (instructions maploc, scale, border)"""
+ def __init__(self, id):
+ InstructionObject.__init__(self, id = id)
+ self.type = 'map'
+ # default values
+ self.defaultInstruction = dict( map = None, mapType = None, region = None,
+ rect = wx.Rect2D(), scaleType = 0, scale = None, center = None,
+ border = 'y', width = 1, color = '0:0:0')
+ # current values
+ self.instruction = dict(self.defaultInstruction)
+
+ def __str__(self):
+ instr = ''
+ comment = ''
+ #region settings
+ if self.instruction['scaleType'] == 0: #match map
+ map = self.instruction['map']
+ mapType = 'rast' if self.instruction['mapType'] == 'raster' else 'vect'
+ comment = "# set region: g.region {0}={1}\n".format(mapType, map)
+ elif self.instruction['scaleType'] == 1:# saved region
+ region = self.instruction['region']
+ comment = "# set region: g.region region={0}\n".format(region)
+ elif self.instruction['scaleType'] == 3: #fixed scale
+ region = grass.region()
+ comment = "# set region: g.region n={n} s={s} e={e} w={w}\n".format(**region)
+ instr += comment
+ instr += '\n'
+ # maploc
+ maplocInstruction = "maploc {rect.x} {rect.y}".format(**self.instruction)
+ if self.instruction['scaleType'] != 3:
+ maplocInstruction += " {rect.width} {rect.height}".format(**self.instruction)
+ instr += maplocInstruction
+ instr += '\n'
+
+ # scale
+ if self.instruction['scaleType'] == 3: #fixed scale
+ scaleInstruction = "scale 1:{0:.0f}".format(1/self.instruction['scale'])
+ instr += scaleInstruction
+ instr += '\n'
+ # border
+ borderInstruction = ''
+ if self.instruction['border'] == 'n':
+ borderInstruction = "border n"
+ else:
+ borderInstruction = "border y\n"
+ borderInstruction += " width {width}\n color {color}\n".format(**self.instruction)
+ borderInstruction += "end"
+ instr += borderInstruction
+ instr += '\n'
+
+ return instr
+
+ def Read(self, instruction, text, **kwargs):
+ """!Read instruction and save information"""
+
+ instr = {}
+ if instruction == 'gregion':
+ start = text.find('g.region')
+ cmd = text[start:].split()
+ if len(cmd) == 2:
+ if cmd[1].split('=')[0] == 'rast':
+ instr['scaleType'] = 0
+ instr['mapType'] = 'raster'
+ instr['map'] = cmd[1].split('=')[1]
+ elif cmd[1].split('=')[0] == 'vect':
+ instr['scaleType'] = 0
+ instr['mapType'] = 'vector'
+ instr['map'] = cmd[1].split('=')[1]
+ elif cmd[1].split('=')[0] == 'region':
+ instr['scaleType'] = 1
+ instr['region'] = cmd[1].split('=')[1]
+
+ elif len(text[start:].split()[1:]) == 4:
+ instr['scaleType'] = 3
+ region = grass.parse_key_val(text[start:].split(' ',1)[1], val_type = float, vsep = ' ')
+ instr['center'] = (region['n'] + region['s']) / 2, (region['w'] + region['e']) / 2
+
+ cmd = CmdToTuple(cmd)
+ RunCommand(cmd[0], **cmd[1])
+
+
+ elif instruction == 'border':
+ for line in text:
+ try:
+ if line == 'border n':
+ instr['border'] = 'n'
+ break
+ elif line == 'border y':
+ instr['border'] = 'y'
+ elif line.startswith('width'):
+ instr['width'] = line.split()[1]
+ elif line.startswith('color'):
+ instr['color'] = line.split()[1]
+ except IndexError:
+ GError(_("Failed to read instruction {0}").format(instruction))
+ return False
+
+ elif instruction == 'scale':
+ try:
+ scale = text.strip('scale ').split(':')[1]
+ instr['scale'] = 1/float(scale)
+ except (ValueError, IndexError):
+ GError(_("Failed to read instruction {0}.\nUse 1:25000 notation.").format(instruction))
+ return False
+
+ elif instruction == 'maploc':
+ #TODO: run psmap -b always?
+ instr['rect'] = GetMapBounds(kwargs['filename'])
+
+
+ self.instruction.update(instr)
+ return True
+
+class PageSetup(InstructionObject):
+ """!Class representing page instruction"""
+ def __init__(self, id):
+ InstructionObject.__init__(self, id = id)
+ self.type = 'page'
+ # default values
+ self.defaultInstruction = dict(Units = 'inch', Format = 'a4', Orientation = 'Portrait',
+ Width = 8.268, Height = 11.693, Left = 0.5, Right = 0.5, Top = 1, Bottom = 1)
+ # current values
+ self.instruction = dict(self.defaultInstruction)
+
+ def __str__(self):
+ if self.instruction['Format'] == 'custom':
+ instr = "paper\n width {Width}\n height {Height}\n".format(**self.instruction)
+ else:
+ instr = "paper {Format}\n".format(**self.instruction)
+ instr += " left {Left}\n right {Right}\n" \
+ " bottom {Bottom}\n top {Top}\nend".format(**self.instruction)
+
+ return instr
+
+ def Read(self, instruction, text):
+ """!Read instruction and save information"""
+ instr = {}
+ self.cats = ['Width', 'Height', 'Left', 'Right', 'Top', 'Bottom']
+ self.subInstr = dict(zip(['width', 'height', 'left', 'right', 'top', 'bottom'], self.cats))
+
+ if instruction == 'paper': # just for sure
+ for line in text:
+ if line.startswith('paper'):
+ if len(line.split()) > 1:
+ format = line.split()[1]
+ availableFormats = self._toDict(grass.read_command('ps.map', flags = 'p'))
+ # e.g. paper a3
+ try:
+ instr['Format'] = format
+ for key, value in availableFormats[format].iteritems():
+ instr[key] = float(value)
+ break
+ except KeyError:
+ GError(_("Failed to read instruction '{0}'.\nUnknown format {1}").format(instruction, format))
+ return False
+
+ else:
+ # paper
+ # width ...
+ instr['Format'] = 'custom'
+ # read subinstructions
+ elif instr['Format'] == 'custom' and not line.startswith('end'):
+ text = line.split()
+ try:
+ instr[self.subInstr[text[0]]] = float(text[1])
+ except (IndexError, KeyError):
+ GError(_("Failed to read instruction '{0}'.").format(instruction))
+ return False
+
+ self.instruction.update(instr)
+ return True
+
+ def _toDict(self, paperStr):
+ sizeDict = dict()
+# cats = self.subInstr[ 'Width', 'Height', 'Left', 'Right', 'Top', 'Bottom']
+ for line in paperStr.strip().split('\n'):
+ d = dict(zip(self.cats, line.split()[1:]))
+ sizeDict[line.split()[0]] = d
+
+ return sizeDict
+
+class Mapinfo(InstructionObject):
+ """!Class representing mapinfo instruction"""
+ def __init__(self, id):
+ InstructionObject.__init__(self, id = id)
+ self.type = 'mapinfo'
+ # default values
+ self.defaultInstruction = dict( unit = 'inch', where = (0, 0),
+ font = 'Helvetica', fontsize = 10, color = 'black', background = 'none',
+ #font = 'Sans', fontsize = 10, color = '0:0:0', background = 'none',
+ border = 'none', rect = None)
+ # current values
+ self.instruction = dict(self.defaultInstruction)
+
+ def __str__(self):
+ instr = "mapinfo\n"
+ instr += " where {where[0]} {where[1]}\n".format(**self.instruction)
+ instr += " font {font}\n fontsize {fontsize}\n color {color}\n".format(**self.instruction)
+ instr += " background {background}\n border {border}\n".format(**self.instruction)
+ instr += "end"
+ return instr
+
+ def Read(self, instruction, text):
+ """!Read instruction and save information"""
+ instr = {}
+ try:
+ for line in text:
+ sub = line.split(' ',1)
+ if sub[0] == 'font':
+ instr['font'] = sub[1]
+ elif sub[0] == 'fontsize':
+ instr['fontsize'] = int(sub[1])
+ elif sub[0] == 'color':
+ instr['color'] = sub[1]
+ elif sub[0] == 'background':
+ instr['background'] = sub[1]
+ elif sub[0] == 'border':
+ instr['border'] = sub[1]
+ elif sub[0] == 'where':
+ instr['where'] = tuple(sub[2].split())
+ except (ValueError, IndexError):
+ GError(_("Failed to read instruction {0}").format(instruction))
+
+ self.instruction.update(instr)
+ return True
+
+class Text(InstructionObject):
+ """!Class representing text instruction"""
+ def __init__(self, id):
+ InstructionObject.__init__(self, id = id)
+ self.type = 'text'
+ # default values
+ self.defaultInstruction = dict(text = "", font = "Helvetica", fontsize = 10, color = 'black', background = 'none',
+ hcolor = 'none', hwidth = 1, border = 'none', width = '1', XY = True,
+ where = (0,0), unit = 'inch', rotate = None,
+ ref = "center center", xoffset = 0, yoffset = 0, east = None, north = None)
+ # current values
+ self.instruction = dict(self.defaultInstruction)
+
+ def __str__(self):
+ text = self.instruction['text'].replace('\n','\\n')
+ instr = "text {east} {north}".format(**self.instruction)
+ instr += " {0}\n".format(text)
+ instr += " font {font}\n fontsize {fontsize}\n color {color}\n".format(**self.instruction)
+ instr += " hcolor {hcolor}\n".format(**self.instruction)
+ if self.instruction['hcolor'] != 'none':
+ instr += " hwidth {hwidth}\n".format(**self.instruction)
+ instr += " border {border}\n".format(**self.instruction)
+ if self.instruction['border'] != 'none':
+ instr += " width {width}\n".format(**self.instruction)
+ instr += " background {background}\n".format(**self.instruction)
+ if self.instruction["ref"] != '0':
+ instr += " ref {ref}\n".format(**self.instruction)
+ if self.instruction["rotate"]:
+ instr += " rotate {rotate}\n".format(**self.instruction)
+ if float(self.instruction["xoffset"]) or float(self.instruction["yoffset"]):
+ instr += " xoffset {xoffset}\n yoffset {yoffset}\n".format(**self.instruction)
+ instr += "end"
+ return instr
+
+
+class Scalebar(InstructionObject):
+ """!Class representing scalebar instruction"""
+ def __init__(self, id):
+ InstructionObject.__init__(self, id = id)
+ self.type = 'scalebar'
+ # default values
+ self.defaultInstruction = dict( unit = 'inch', where = (0,0),
+ unitsLength = 'auto', unitsHeight = 'inch',
+ length = None, height = 0.1, rect = None,
+ fontsize = 10, background = 'y',
+ scalebar = 'f', segment = 4, numbers = 1)
+ # current values
+ self.instruction = dict(self.defaultInstruction)
+
+ def __str__(self):
+ instr = "scalebar {scalebar}\n".format(**self.instruction)
+ instr += " where {where[0]} {where[1]}\n".format(**self.instruction)
+ instr += " length {length}\n units {unitsLength}\n".format(**self.instruction)
+ instr += " height {height}\n".format(**self.instruction)
+ instr += " segment {segment}\n numbers {numbers}\n".format(**self.instruction)
+ instr += " fontsize {fontsize}\n background {background}\n".format(**self.instruction)
+ instr += "end"
+ return instr
+
+class RasterLegend(InstructionObject):
+ """!Class representing colortable instruction"""
+ def __init__(self, id):
+ InstructionObject.__init__(self, id = id)
+ self.type = 'rasterLegend'
+ # default values
+ self.defaultInstruction = dict(rLegend = False, unit = 'inch', rasterDefault = True, raster = None,
+ discrete = None, type = None,
+ where = (0, 0), defaultSize = True,
+ width = 0, height = 0, cols = 1, font = "Serif", fontsize = 10,
+ #color = '0:0:0', tickbar = False, range = False, min = 0, max = 0,
+ color = 'black', tickbar = False, range = False, min = 0, max = 0,
+ nodata = False)
+ # current values
+ self.instruction = dict(self.defaultInstruction)
+
+ def __str__(self):
+ instr = "colortable y\n"
+ instr += " raster {raster}\n".format(**self.instruction)
+ instr += " where {where[0]} {where[1]}\n".format(**self.instruction)
+ if not self.instruction['defaultSize']:
+ instr += " width {width}\n".format(**self.instruction)
+ instr += " discrete {discrete}\n".format(**self.instruction)
+ if self.instruction['discrete'] == 'n':
+ if not self.instruction['defaultSize']:
+ instr += " height {height}\n".format(**self.instruction)
+ instr += " tickbar {tickbar}\n".format(**self.instruction)
+ if self.instruction['range']:
+ instr += " range {min} {max}\n".format(**self.instruction)
+ else:
+ instr += " cols {cols}\n".format(**self.instruction)
+ instr += " nodata {nodata}\n".format(**self.instruction)
+ instr += " font {font}\n fontsize {fontsize}\n color {color}\n"\
+ .format(**self.instruction)
+ instr += "end"
+ return instr
+
+
+class VectorLegend(InstructionObject):
+ """!Class representing colortable instruction"""
+ def __init__(self, id):
+ InstructionObject.__init__(self, id = id)
+ self.type = 'vectorLegend'
+ # default values
+ self.defaultInstruction = dict(vLegend = False, unit = 'inch', where = (0, 0),
+ defaultSize = True, width = 0.4, cols = 1, span = None, font = "Serif", fontsize = 10,
+ border = 'none')
+ # current values
+ self.instruction = dict(self.defaultInstruction)
+
+ def __str__(self):
+ instr = "vlegend\n"
+ instr += " where {where[0]} {where[1]}\n".format(**self.instruction)
+ instr += " font {font}\n fontsize {fontsize}\n".format(**self.instruction)
+ instr += " width {width}\n cols {cols}\n".format(**self.instruction)
+ if self.instruction['span']:
+ instr += " span {span}\n".format(**self.instruction)
+ instr += " border {border}\n".format(**self.instruction)
+ instr += "end"
+ return instr
+
+class Raster(InstructionObject):
+ """!Class representing raster instruction"""
+ def __init__(self, id):
+ InstructionObject.__init__(self, id = id)
+ self.type = 'raster'
+ # default values
+ self.defaultInstruction = dict(isRaster = False, raster = None)
+ # current values
+ self.instruction = dict(self.defaultInstruction)
+
+ def __str__(self):
+ instr = "raster {raster}".format(**self.instruction)
+ return instr
+
+ def Read(self, instruction, text):
+ """!Read instruction and save information"""
+ instr = {}
+ instr['isRaster'] = True
+ try:
+ map = text.split()[1]
+ except IndexError:
+ GError(_("Failed to read instruction {0}").format(instruction))
+ return False
+ try:
+ info = grass.find_file(map, element = 'cell')
+ except grass.ScriptError, e:
+ GError(message = e.value)
+ return False
+ instr['raster'] = info['fullname']
+
+
+ self.instruction.update(instr)
+ return True
+
+class Vector(InstructionObject):
+ """!Class keeps vector layers"""
+ def __init__(self, id):
+ InstructionObject.__init__(self, id = id)
+ self.type = 'vector'
+ # default values
+ self.defaultInstruction = dict(list = None)
+ # current values
+ self.instruction = dict(self.defaultInstruction)
+ def __str__(self):
+ return ''
+
+class VProperties(InstructionObject):
+ """!Class represents instructions vareas, vlines, vpoints"""
+ def __init__(self, id, subType):
+ InstructionObject.__init__(self, id = id)
+ self.type = 'vProperties'
+ self.subType = subType
+ # default values
+ if self.subType == 'points':
+ dd = dict(subType = 'points', name = None, type = 'point or centroid', connection = False, layer = '1', masked = 'n', color = '0:0:0', width = 1,
+ fcolor = '255:0:0', rgbcolumn = None, symbol = os.path.join('basic', 'x'), eps = None,
+ size = 5, sizecolumn = None, scale = None,
+ rotation = False, rotate = 0, rotatecolumn = None, label = None, lpos = None)
+ elif self.subType == 'lines':
+ dd = dict(subType = 'lines', name = None, type = 'line or boundary', connection = False, layer = '1', masked = 'n', color = '0:0:0', hwidth = 1,
+ hcolor = 'none', rgbcolumn = None,
+ width = 1, cwidth = None,
+ style = 'solid', linecap = 'butt', label = None, lpos = None)
+ else: # areas
+ dd = dict(subType = 'areas', name = None, type = 'point or centroid', connection = False, layer = '1', masked = 'n', color = '0:0:0', width = 1,
+ fcolor = 'none', rgbcolumn = None,
+ pat = None, pwidth = 1, scale = 1, label = None, lpos = None)
+ self.defaultInstruction = dd
+ # current values
+ self.instruction = dict(self.defaultInstruction)
+
+ def __str__(self):
+ dic = self.instruction
+ vInstruction = "v{subType} {name}\n".format(**dic)
+ #data selection
+ if self.subType in ('points', 'lines'):
+ vInstruction += " type {type}\n".format(**dic)
+ if dic['connection']:
+ vInstruction += " layer {layer}\n".format(**dic)
+ if dic.has_key('cats'):
+ vInstruction += " cats {cats}\n".format(**dic)
+ elif dic.has_key('where'):
+ vInstruction += " where {where}\n".format(**dic)
+ vInstruction += " masked {masked}\n".format(**dic)
+ #colors
+ vInstruction += " color {color}\n".format(**dic)
+ if self.subType in ('points', 'areas'):
+ if dic['color'] != 'none':
+ vInstruction += " width {width}\n".format(**dic)
+ if dic['rgbcolumn']:
+ vInstruction += " rgbcolumn {rgbcolumn}\n".format(**dic)
+ vInstruction += " fcolor {fcolor}\n".format(**dic)
+ else:
+ if dic['rgbcolumn']:
+ vInstruction += " rgbcolumn {rgbcolumn}\n".format(**dic)
+ elif dic['hcolor'] != 'none':
+ vInstruction += " hwidth {hwidth}\n".format(**dic)
+ vInstruction += " hcolor {hcolor}\n".format(**dic)
+
+ # size and style
+ if self.subType == 'points':
+ if dic['symbol']:
+ vInstruction += " symbol {symbol}\n".format(**dic)
+ else: #eps
+ vInstruction += " eps {eps}\n".format(**dic)
+ if dic['size']:
+ vInstruction += " size {size}\n".format(**dic)
+ else: # sizecolumn
+ vInstruction += " sizecolumn {sizecolumn}\n".format(**dic)
+ vInstruction += " scale {scale}\n".format(**dic)
+ if dic['rotation']:
+ if dic['rotate'] is not None:
+ vInstruction += " rotate {rotate}\n".format(**dic)
+ else:
+ vInstruction += " rotatecolumn {rotatecolumn}\n".format(**dic)
+
+ if self.subType == 'areas':
+ if dic['pat'] is not None:
+ vInstruction += " pat {pat}\n".format(**dic)
+ vInstruction += " pwidth {pwidth}\n".format(**dic)
+ vInstruction += " scale {scale}\n".format(**dic)
+
+ if self.subType == 'lines':
+ if dic['width'] is not None:
+ vInstruction += " width {width}\n".format(**dic)
+ else:
+ vInstruction += " cwidth {cwidth}\n".format(**dic)
+ vInstruction += " style {style}\n".format(**dic)
+ vInstruction += " linecap {linecap}\n".format(**dic)
+ #position and label in vlegend
+ vInstruction += " label {label}\n lpos {lpos}\n".format(**dic)
+
+ vInstruction += "end"
+ return vInstruction
+
+class PsmapDialog(wx.Dialog):
+ def __init__(self, parent, id, title, settings, apply = True):
+ wx.Dialog.__init__(self, parent = parent, id = wx.ID_ANY,
+ title = title, size = wx.DefaultSize, style = wx.DEFAULT_DIALOG_STYLE)
+ self.apply = apply
+ self.id = id
+ self.parent = parent
+ self.instruction = settings
+
+ self.unitConv = UnitConversion(self)
+ self.spinCtrlSize = (50, -1)
+
+
+ def AddUnits(self, parent, dialogDict):
+ parent.units = dict()
+ parent.units['unitsLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Units:"))
+ choices = self.unitConv.getPageUnits()
+ parent.units['unitsCtrl'] = wx.Choice(parent, id = wx.ID_ANY, choices = choices)
+ parent.units['unitsCtrl'].SetStringSelection(dialogDict['unit'])
+
+ def AddPosition(self, parent, dialogDict):
+ parent.position = dict()
+ parent.position['comment'] = wx.StaticText(parent, id = wx.ID_ANY,\
+ label = _("Position of the top left corner\nfrom the top left edge of the paper"))
+ parent.position['xLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("X:"))
+ parent.position['yLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Y:"))
+ parent.position['xCtrl'] = wx.TextCtrl(parent, id = wx.ID_ANY, value = str(dialogDict['where'][0]), validator = TCValidator(flag = 'DIGIT_ONLY'))
+ parent.position['yCtrl'] = wx.TextCtrl(parent, id = wx.ID_ANY, value = str(dialogDict['where'][1]), validator = TCValidator(flag = 'DIGIT_ONLY'))
+ if dialogDict.has_key('unit'):
+ x = self.unitConv.convert(value = dialogDict['where'][0], fromUnit = 'inch', toUnit = dialogDict['unit'])
+ y = self.unitConv.convert(value = dialogDict['where'][1], fromUnit = 'inch', toUnit = dialogDict['unit'])
+ parent.position['xCtrl'].SetValue("{0:5.3f}".format(x))
+ parent.position['yCtrl'].SetValue("{0:5.3f}".format(y))
+
+ def AddFont(self, parent, dialogDict, color = True):
+ parent.font = dict()
+## parent.font['fontLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Choose font:"))
+## parent.font['fontCtrl'] = wx.FontPickerCtrl(parent, id = wx.ID_ANY)
+##
+## parent.font['fontCtrl'].SetSelectedFont(
+## wx.FontFromNativeInfoString(dialogDict['font'] + " " + str(dialogDict['fontsize'])))
+## parent.font['fontCtrl'].SetMaxPointSize(50)
+##
+## if color:
+## parent.font['colorLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Choose color:"))
+## parent.font['colorCtrl'] = wx.ColourPickerCtrl(parent, id = wx.ID_ANY, style=wx.FNTP_FONTDESC_AS_LABEL)
+## parent.font['colorCtrl'].SetColour(dialogDict['color'])
+
+## parent.font['colorCtrl'].SetColour(convertRGB(dialogDict['color']))
+
+ parent.font['fontLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Font:"))
+ parent.font['fontSizeLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Font size:"))
+ fontChoices = [ 'Times-Roman', 'Times-Italic', 'Times-Bold', 'Times-BoldItalic', 'Helvetica',\
+ 'Helvetica-Oblique', 'Helvetica-Bold', 'Helvetica-BoldOblique', 'Courier',\
+ 'Courier-Oblique', 'Courier-Bold', 'Courier-BoldOblique']
+ parent.font['fontCtrl'] = wx.Choice(parent, id = wx.ID_ANY, choices = fontChoices)
+ parent.font['fontCtrl'].SetStringSelection(dialogDict['font'])
+ parent.font['fontSizeCtrl']= wx.SpinCtrl(parent, id = wx.ID_ANY, min = 4, max = 50, initial = 10)
+ parent.font['fontSizeCtrl'].SetValue(dialogDict['fontsize'])
+
+ if color:
+ parent.font['colorLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Choose color:"))
+ parent.font['colorCtrl'] = wx.ColourPickerCtrl(parent, id = wx.ID_ANY, style=wx.FNTP_FONTDESC_AS_LABEL)
+ parent.font['colorCtrl'].SetColour(dialogDict['color'])
+## parent.font['colorLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Color:"))
+## colorChoices = [ 'aqua', 'black', 'blue', 'brown', 'cyan', 'gray', 'green', 'indigo', 'magenta',\
+## 'orange', 'purple', 'red', 'violet', 'white', 'yellow']
+## parent.colorCtrl = wx.Choice(parent, id = wx.ID_ANY, choices = colorChoices)
+## parent.colorCtrl.SetStringSelection(parent.rLegendDict['color'])
+## parent.font['colorCtrl'] = wx.ColourPickerCtrl(parent, id = wx.ID_ANY)
+## parent.font['colorCtrl'].SetColour(dialogDict['color'])
+ def OnApply(self, event):
+ ok = self.update()
+ if ok:
+ self.parent.DialogDataChanged(id = self.id)
+ return True
+ else:
+ return False
+
+ def OnOK(self, event):
+ ok = self.OnApply(event)
+ if ok:
+ event.Skip()
+
+ def OnCancel(self, event):
+ event.Skip()
+
+
+ def _layout(self, panel):
+ #buttons
+ btnCancel = wx.Button(self, wx.ID_CANCEL)
+ btnOK = wx.Button(self, wx.ID_OK)
+ btnOK.SetDefault()
+ if self.apply:
+ btnApply = wx.Button(self, wx.ID_APPLY)
+
+
+ # bindigs
+ btnOK.Bind(wx.EVT_BUTTON, self.OnOK)
+ btnOK.SetToolTipString(_("Close dialog and apply changes"))
+ btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
+ btnCancel.SetToolTipString(_("Close dialog and ignore changes"))
+ if self.apply:
+ btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
+ btnApply.SetToolTipString(_("Apply changes"))
+
+ # sizers
+ btnSizer = wx.StdDialogButtonSizer()
+ btnSizer.AddButton(btnCancel)
+ if self.apply:
+ btnSizer.AddButton(btnApply)
+ btnSizer.AddButton(btnOK)
+ btnSizer.Realize()
+
+ mainSizer = wx.BoxSizer(wx.VERTICAL)
+ mainSizer.Add(item = panel, proportion = 1, flag = wx.EXPAND | wx.ALL, border = 5)
+ mainSizer.Add(item = btnSizer, proportion = 0,
+ flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
+
+ self.Bind(wx.EVT_CLOSE, self.OnCancel)
+
+ self.SetSizer(mainSizer)
+ mainSizer.Layout()
+ mainSizer.Fit(self)
+
+class PageSetupDialog(PsmapDialog):
+ def __init__(self, parent, id, settings):
+ PsmapDialog.__init__(self, parent = parent, id = id, title = "Page setup", settings = settings)
+
+ self.cat = ['Units', 'Format', 'Orientation', 'Width', 'Height', 'Left', 'Right', 'Top', 'Bottom']
+ paperString = RunCommand('ps.map', flags = 'p', read = True)
+ self.paperTable = self._toList(paperString)
+ self.unitsList = self.unitConv.getPageUnits()
+ pageId = id
+ self.pageSetupDict = settings[id].GetInstruction()
+
+ self._layout()
+
+ if self.pageSetupDict:
+ for item in self.cat[:3]:
+ self.getCtrl(item).SetSelection(self.getCtrl(item).FindString(self.pageSetupDict[item]))
+ for item in self.cat[3:]:
+ self.getCtrl(item).SetValue("{0:4.3f}".format(self.pageSetupDict[item]))
+
+
+ if self.getCtrl('Format').GetString(self.getCtrl('Format').GetSelection()) != 'custom':
+ self.getCtrl('Width').Disable()
+ self.getCtrl('Height').Disable()
+ else:
+ self.getCtrl('Orientation').Disable()
+ # events
+ self.getCtrl('Units').Bind(wx.EVT_CHOICE, self.OnChoice)
+ self.getCtrl('Format').Bind(wx.EVT_CHOICE, self.OnChoice)
+ self.getCtrl('Orientation').Bind(wx.EVT_CHOICE, self.OnChoice)
+ self.btnOk.Bind(wx.EVT_BUTTON, self.OnOK)
+
+
+ def update(self):
+ self.pageSetupDict['Units'] = self.getCtrl('Units').GetString(self.getCtrl('Units').GetSelection())
+ self.pageSetupDict['Format'] = self.paperTable[self.getCtrl('Format').GetSelection()]['Format']
+ self.pageSetupDict['Orientation'] = self.getCtrl('Orientation').GetString(self.getCtrl('Orientation').GetSelection())
+ for item in self.cat[3:]:
+ self.pageSetupDict[item] = self.unitConv.convert(value = float(self.getCtrl(item).GetValue()),
+ fromUnit = self.pageSetupDict['Units'], toUnit = 'inch')
+
+
+
+ def OnOK(self, event):
+ try:
+ self.update()
+ except ValueError:
+ wx.MessageBox(message = _("Literal is not allowed!"), caption = _('Invalid input'),
+ style = wx.OK|wx.ICON_ERROR)
+ else:
+ event.Skip()
+
+ def _layout(self):
+ size = (110,-1)
+ #sizers
+ mainSizer = wx.BoxSizer(wx.VERTICAL)
+ pageBox = wx.StaticBox(self, id = wx.ID_ANY, label =" Page size ")
+ pageSizer = wx.StaticBoxSizer(pageBox, wx.VERTICAL)
+ marginBox = wx.StaticBox(self, id = wx.ID_ANY, label = " Margins ")
+ marginSizer = wx.StaticBoxSizer(marginBox, wx.VERTICAL)
+ horSizer = wx.BoxSizer(wx.HORIZONTAL)
+ #staticText + choice
+ choices = [self.unitsList, [item['Format'] for item in self.paperTable], ['Portrait', 'Landscape']]
+ propor = [0,1,1]
+ border = [5,3,3]
+ self.hBoxDict={}
+ for i, item in enumerate(self.cat[:3]):
+ hBox = wx.BoxSizer(wx.HORIZONTAL)
+ stText = wx.StaticText(self, id = wx.ID_ANY, label = item + ':')
+ choice = wx.Choice(self, id = wx.ID_ANY, choices = choices[i], size = size)
+ hBox.Add(stText, proportion = propor[i], flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = border[i])
+ hBox.Add(choice, proportion = 0, flag = wx.ALL, border = border[i])
+ if item == 'Units':
+ hBox.Add(size,1)
+ self.hBoxDict[item] = hBox
+
+ #staticText + TextCtrl
+ for item in self.cat[3:]:
+ hBox = wx.BoxSizer(wx.HORIZONTAL)
+ label = wx.StaticText(self, id = wx.ID_ANY, label = item + ':')
+ textctrl = wx.TextCtrl(self, id = wx.ID_ANY, size = size, value = '')
+ hBox.Add(label, proportion = 1, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 3)
+ hBox.Add(textctrl, proportion = 0, flag = wx.ALIGN_CENTRE|wx.ALL, border = 3)
+ self.hBoxDict[item] = hBox
+
+ sizer = list([mainSizer] + [pageSizer]*4 + [marginSizer]*4)
+ for i, item in enumerate(self.cat):
+ sizer[i].Add(self.hBoxDict[item], 0, wx.GROW|wx.RIGHT|wx.LEFT,5)
+ # OK button
+ btnSizer = wx.StdDialogButtonSizer()
+ self.btnOk = wx.Button(self, wx.ID_OK)
+ self.btnOk.SetDefault()
+ btnSizer.AddButton(self.btnOk)
+ btn = wx.Button(self, wx.ID_CANCEL)
+ btnSizer.AddButton(btn)
+ btnSizer.Realize()
+
+
+ horSizer.Add(pageSizer, proportion = 0, flag = wx.LEFT|wx.RIGHT|wx.BOTTOM, border = 10)
+ horSizer.Add(marginSizer, proportion = 0, flag = wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.EXPAND, border = 10)
+ mainSizer.Add(horSizer, proportion = 0, border = 10)
+ mainSizer.Add(btnSizer, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.ALL, border = 10)
+ self.SetSizer(mainSizer)
+ mainSizer.Fit(self)
+
+ def OnChoice(self, event):
+ currPaper = self.paperTable[self.getCtrl('Format').GetSelection()]
+ currUnit = self.getCtrl('Units').GetString(self.getCtrl('Units').GetSelection())
+ currOrient = self.getCtrl('Orientation').GetString(self.getCtrl('Orientation').GetSelection())
+ newSize = dict()
+ for item in self.cat[3:]:
+ newSize[item] = self.unitConv.convert(float(currPaper[item]), fromUnit = 'inch', toUnit = currUnit)
+
+ enable = True
+ if currPaper['Format'] != 'custom':
+ if currOrient == 'Landscape':
+ newSize['Width'], newSize['Height'] = newSize['Height'], newSize['Width']
+ for item in self.cat[3:]:
+ self.getCtrl(item).ChangeValue("{0:4.3f}".format(newSize[item]))
+ enable = False
+ self.getCtrl('Width').Enable(enable)
+ self.getCtrl('Height').Enable(enable)
+ self.getCtrl('Orientation').Enable(not enable)
+
+
+ def getCtrl(self, item):
+ return self.hBoxDict[item].GetItem(1).GetWindow()
+
+ def _toList(self, paperStr):
+
+ sizeList = list()
+ for line in paperStr.strip().split('\n'):
+ d = dict(zip([self.cat[1]]+ self.cat[3:],line.split()))
+ sizeList.append(d)
+ d = {}.fromkeys([self.cat[1]]+ self.cat[3:], 100)
+ d.update(Format = 'custom')
+ sizeList.append(d)
+ return sizeList
+
+class MapDialog(PsmapDialog):
+ """!Dialog for map frame settings and optionally raster and vector map selection"""
+ def __init__(self, parent, id, settings, rect = None, notebook = False):
+ PsmapDialog.__init__(self, parent = parent, id = id, title = "", settings = settings)
+
+ self.instruction = settings
+ self.isNotebook = notebook
+ #notebook
+ if self.isNotebook:
+ notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT)
+ self.mPanel = MapFramePanel(parent = notebook, id = self.id[0], settings = self.instruction,
+ rect = rect, notebook = True)
+ self.id[0] = self.mPanel.getId()
+ self.rPanel = RasterPanel(parent = notebook, id = self.id[1], settings = self.instruction,
+ notebook = True)
+ self.id[1] = self.rPanel.getId()
+ self.vPanel = VectorPanel(parent = notebook, id = self.id[2], settings = self.instruction,
+ notebook = True)
+ self.id[2] = self.vPanel.getId()
+ self._layout(notebook)
+ self.SetTitle(_("Map settings"))
+ else:
+ self.mPanel = MapFramePanel(parent = self, id = self.id[0], settings = self.instruction,
+ rect = rect, notebook = False)
+ self.id[0] = self.mPanel.getId()
+ self._layout(self.mPanel)
+ self.SetTitle(_("Map frame settings"))
+
+
+ def OnApply(self, event):
+ """!Apply changes"""
+ if self.isNotebook:
+ okV = self.vPanel.update()
+ okR = self.rPanel.update()
+ if okV and self.id[2] in self.instruction:
+ self.parent.DialogDataChanged(id = self.id[2])
+ if okR and self.id[1] in self.instruction:
+ self.parent.DialogDataChanged(id = self.id[1])
+ if not okR or not okV:
+ return False
+
+ ok = self.mPanel.update()
+ if ok:
+ self.parent.DialogDataChanged(id = self.id[0])
+ return True
+
+ return False
+
+class MapFramePanel(wx.Panel):
+ """!wx.Panel with map (scale, region, border) settings"""
+ def __init__(self, parent, id, settings, rect, notebook = True):
+ wx.Panel.__init__(self, parent, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
+
+ self.id = id
+ self.instruction = settings
+
+ if notebook:
+ self.book = parent
+ self.book.AddPage(page = self, text = _("Map frame"))
+ self.mapDialog = self.book.GetParent()
+ else:
+ self.mapDialog = parent
+
+ if self.id is not None:
+ self.mapFrameDict = self.instruction[self.id].GetInstruction()
+ else:
+ self.id = wx.NewId()
+ mapFrame = MapFrame(self.id)
+ self.mapFrameDict = mapFrame.GetInstruction()
+ self.mapFrameDict['rect'] = rect
+
+
+ self._layout()
+
+ self.scale = [None]*4
+ self.center = [None]*4
+
+
+
+ self.selectedMap = self.mapFrameDict['map']
+ self.selectedRegion = self.mapFrameDict['region']
+ self.scaleType = self.mapFrameDict['scaleType']
+ self.mapType = self.mapFrameDict['mapType']
+ self.scaleChoice.SetSelection(self.mapFrameDict['scaleType'])
+ if self.mapFrameDict['scaleType'] == 0 and self.mapFrameDict['map']:
+
+ self.select.SetValue(self.mapFrameDict['map'])
+ if self.mapFrameDict['mapType'] == 'raster':
+ self.rasterTypeRadio.SetValue(True)
+ self.vectorTypeRadio.SetValue(False)
+ else:
+ self.rasterTypeRadio.SetValue(False)
+ self.vectorTypeRadio.SetValue(True)
+ elif self.mapFrameDict['scaleType'] == 1 and self.mapFrameDict['region']:
+ self.select.SetValue(self.mapFrameDict['region'])
+
+
+ self.OnMap(None)
+ self.scale[self.mapFrameDict['scaleType']] = self.mapFrameDict['scale']
+ self.center[self.mapFrameDict['scaleType']] = self.mapFrameDict['center']
+ self.OnScaleChoice(None)
+ self.OnElementType(None)
+ self.OnBorder(None)
+
+
+
+ def _layout(self):
+ """!Do layout"""
+ border = wx.BoxSizer(wx.VERTICAL)
+
+ box = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " {0} ".format(_("Map frame")))
+ sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+ gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
+
+
+ #scale options
+ frameText = wx.StaticText(self, id = wx.ID_ANY, label = _("Map frame options:"))
+ scaleChoices = [_("fit frame to match selected map"),
+ _("fit frame to match saved region"),
+ _("fit frame to match current computational region"),
+ _("fixed scale and map center")]
+ self.scaleChoice = wx.Choice(self, id = wx.ID_ANY, choices = scaleChoices)
+
+
+ gridBagSizer.Add(frameText, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.scaleChoice, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+
+ #map and region selection
+ self.staticBox = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " {0} ".format(_("Map selection")))
+ sizerM = wx.StaticBoxSizer(self.staticBox, wx.HORIZONTAL)
+ self.mapSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
+
+ self.rasterTypeRadio = wx.RadioButton(self, id = wx.ID_ANY, label = " {0} ".format(_("raster")), style = wx.RB_GROUP)
+ self.vectorTypeRadio = wx.RadioButton(self, id = wx.ID_ANY, label = " {0} ".format(_("vector")))
+
+ self.mapOrRegionText = [_("Map:"), _("Region:")]
+ dc = wx.PaintDC(self)# determine size of labels
+ width = max(dc.GetTextExtent(self.mapOrRegionText[0])[0], dc.GetTextExtent(self.mapOrRegionText[1])[0])
+ self.mapText = wx.StaticText(self, id = wx.ID_ANY, label = self.mapOrRegionText[0], size = (width, -1))
+ self.select = Select(self, id = wx.ID_ANY, size = globalvar.DIALOG_GSELECT_SIZE,
+ type = 'raster', multiple = False,
+ updateOnPopup = True, onPopup = None)
+
+ self.mapSizer.Add(self.rasterTypeRadio, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.mapSizer.Add(self.vectorTypeRadio, pos = (0, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.mapSizer.Add(self.mapText, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.mapSizer.Add(self.select, pos = (1, 1), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+ sizerM.Add(self.mapSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ gridBagSizer.Add(sizerM, pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+
+
+ #map scale and center
+ boxC = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " {0} ".format(_("Map scale and center")))
+ sizerC = wx.StaticBoxSizer(boxC, wx.HORIZONTAL)
+ self.centerSizer = wx.FlexGridSizer(rows = 2, cols = 5, hgap = 5, vgap = 5)
+
+
+ centerText = wx.StaticText(self, id = wx.ID_ANY, label = _("Center:"))
+ self.eastingText = wx.StaticText(self, id = wx.ID_ANY, label = _("E:"))
+ self.northingText = wx.StaticText(self, id = wx.ID_ANY, label = _("N:"))
+ self.eastingTextCtrl = wx.TextCtrl(self, id = wx.ID_ANY, style = wx.TE_RIGHT, validator = TCValidator(flag = 'DIGIT_ONLY'))
+ self.northingTextCtrl = wx.TextCtrl(self, id = wx.ID_ANY, style = wx.TE_RIGHT, validator = TCValidator(flag = 'DIGIT_ONLY'))
+ scaleText = wx.StaticText(self, id = wx.ID_ANY, label = _("Scale:"))
+ scalePrefixText = wx.StaticText(self, id = wx.ID_ANY, label = _("1 :"))
+ self.scaleTextCtrl = wx.TextCtrl(self, id = wx.ID_ANY, value = "", style = wx.TE_RIGHT, validator = TCValidator('DIGIT_ONLY'))
+
+ self.centerSizer.Add(centerText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, border = 10)
+ self.centerSizer.Add(self.eastingText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
+ self.centerSizer.Add(self.eastingTextCtrl, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.centerSizer.Add(self.northingText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
+ self.centerSizer.Add(self.northingTextCtrl, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+ self.centerSizer.Add(scaleText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, border = 10)
+ self.centerSizer.Add(scalePrefixText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
+ self.centerSizer.Add(self.scaleTextCtrl, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+ sizerC.Add(self.centerSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ gridBagSizer.Add(sizerC, pos = (3, 0), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+
+ sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ # border
+ box = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " {0} ".format(_("Border")))
+ sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+ gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
+
+ self.borderCheck = wx.CheckBox(self, id = wx.ID_ANY, label = (_("draw border around map frame")))
+ self.borderCheck.SetValue(True if self.mapFrameDict['border'] == 'y' else False)
+
+ self.borderColorText = wx.StaticText(self, id = wx.ID_ANY, label = _("border color:"))
+ self.borderWidthText = wx.StaticText(self, id = wx.ID_ANY, label = _("border width (pts):"))
+ self.borderColourPicker = wx.ColourPickerCtrl(self, id = wx.ID_ANY)
+ self.borderWidthCtrl = wx.SpinCtrl(self, id = wx.ID_ANY, min = 1, max = 100, initial = 1)
+
+ if self.mapFrameDict['border'] == 'y':
+ self.borderWidthCtrl.SetValue(int(self.mapFrameDict['width']))
+ self.borderColourPicker.SetColour(convertRGB(self.mapFrameDict['color']))
+
+
+ gridBagSizer.Add(self.borderCheck, pos = (0, 0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+ gridBagSizer.Add(self.borderColorText, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.borderWidthText, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.borderColourPicker, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+ gridBagSizer.Add(self.borderWidthCtrl, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+
+ sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ self.SetSizer(border)
+ self.Fit()
+
+
+ if projInfo()['proj'] == 'll':
+ self.scaleChoice.SetItems(self.scaleChoice.GetItems()[0:2])
+ boxC.Hide()
+ for each in self.centerSizer.GetChildren():
+ each.GetWindow().Hide()
+
+
+ # bindings
+ self.scaleChoice.Bind(wx.EVT_CHOICE, self.OnScaleChoice)
+ self.select.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnMap)
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnElementType, self.vectorTypeRadio)
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnElementType, self.rasterTypeRadio)
+ self.Bind(wx.EVT_CHECKBOX, self.OnBorder, self.borderCheck)
+
+
+
+ def OnMap(self, event):
+ """!Selected map or region changing"""
+
+ self.selected = self.select.GetValue() if self.select.GetValue() else None
+ if self.scaleChoice.GetSelection() == 0:
+ self.selectedMap = self.selected
+ mapType = 'raster' if self.rasterTypeRadio.GetValue() else 'vector'
+ self.scale[0], self.center[0], foo = AutoAdjust(self, scaleType = 0, map = self.selected,
+ mapType = mapType, rect = self.mapFrameDict['rect'])
+ #self.center[0] = self.RegionCenter(self.RegionDict(scaleType = 0))
+
+ elif self.scaleChoice.GetSelection() == 1:
+ self.selectedRegion = self.selected
+ self.scale[1], self.center[1], foo = AutoAdjust(self, scaleType = 1, region = self.selected, rect = self.mapFrameDict['rect'])
+ #self.center[1] = self.RegionCenter(self.RegionDict(scaleType = 1))
+ elif self.scaleChoice.GetSelection() == 2:
+ self.scale[2], self.center[2], foo = AutoAdjust(self, scaleType = 2, rect = self.mapFrameDict['rect'])
+ #self.center[2] = self.RegionCenter(self.RegionDict(scaleType = 2))
+
+ else:
+ self.scale[3] = None
+ self.center[3] = None
+
+ self.OnScaleChoice(None)
+
+
+ def OnScaleChoice(self, event):
+ """!Selected scale type changing"""
+
+ scaleType = self.scaleChoice.GetSelection()
+ if self.scaleType != scaleType:
+ self.scaleType = scaleType
+ self.select.SetValue("")
+
+ if scaleType in (0, 1): # automatic - region from raster map, saved region
+ if scaleType == 0:
+ # set map selection
+ self.rasterTypeRadio.Show()
+ self.vectorTypeRadio.Show()
+ self.staticBox.SetLabel(" {0} ".format(_("Map selection")))
+ type = 'raster' if self.rasterTypeRadio.GetValue() else 'vector'
+ self.select.SetElementList(type = type)
+ self.mapText.SetLabel(self.mapOrRegionText[0])
+ self.select.SetToolTipString(_("Region is set to match this map,\nraster or vector map must be added later"))
+
+ if scaleType == 1:
+ # set region selection
+ self.rasterTypeRadio.Hide()
+ self.vectorTypeRadio.Hide()
+ self.staticBox.SetLabel(" {0} ".format(_("Region selection")))
+ type = 'region'
+ self.select.SetElementList(type = type)
+ self.mapText.SetLabel(self.mapOrRegionText[1])
+ self.select.SetToolTipString(_(""))
+
+ for each in self.mapSizer.GetChildren():
+ each.GetWindow().Enable()
+ for each in self.centerSizer.GetChildren():
+ each.GetWindow().Disable()
+
+ if self.scale[scaleType]:
+ self.scaleTextCtrl.SetValue("{0:.0f}".format(1/self.scale[scaleType]))
+ if self.center[scaleType]:
+ self.eastingTextCtrl.SetValue(str(self.center[scaleType][0]))
+ self.northingTextCtrl.SetValue(str(self.center[scaleType][1]))
+ elif scaleType == 2:
+ for each in self.mapSizer.GetChildren():
+ each.GetWindow().Disable()
+ for each in self.centerSizer.GetChildren():
+ each.GetWindow().Disable()
+
+ if self.scale[scaleType]:
+ self.scaleTextCtrl.SetValue("{0:.0f}".format(1/self.scale[scaleType]))
+ if self.center[scaleType]:
+ self.eastingTextCtrl.SetValue(str(self.center[scaleType][0]))
+ self.northingTextCtrl.SetValue(str(self.center[scaleType][1]))
+ else: # fixed
+ for each in self.mapSizer.GetChildren():
+ each.GetWindow().Disable()
+ for each in self.centerSizer.GetChildren():
+ each.GetWindow().Enable()
+
+ if self.scale[scaleType]:
+ self.scaleTextCtrl.SetValue("{0:.0f}".format(1/self.scale[scaleType]))
+ if self.center[scaleType]:
+ self.eastingTextCtrl.SetValue(str(self.center[scaleType][0]))
+ self.northingTextCtrl.SetValue(str(self.center[scaleType][1]))
+
+ def OnElementType(self, event):
+ """!Changes data in map selection tree ctrl popup"""
+ if self.rasterTypeRadio.GetValue():
+ mapType = 'raster'
+ else:
+ mapType = 'vector'
+ self.select.SetElementList(type = mapType)
+ if self.mapType != mapType and event is not None:
+ self.mapType = mapType
+ self.select.SetValue('')
+ self.mapType = mapType
+
+ def OnBorder(self, event):
+ """!Enables/disable the part relating to border of map frame"""
+ for each in (self.borderColorText, self.borderWidthText, self.borderColourPicker, self.borderWidthCtrl):
+ each.Enable(self.borderCheck.GetValue())
+
+ def getId(self):
+ """!Returns id of raster map"""
+ return self.id
+
+ def update(self):
+ """!Save changes"""
+ mapFrameDict = dict(self.mapFrameDict)
+
+ #scale
+ scaleType = self.scaleType
+ mapFrameDict['scaleType'] = scaleType
+
+ if mapFrameDict['scaleType'] == 0:
+ if self.select.GetValue():
+ mapFrameDict['map'] = self.select.GetValue()
+ mapFrameDict['mapType'] = self.mapType
+ mapFrameDict['region'] = None
+
+ self.scale[0], self.center[0], self.rectAdjusted = AutoAdjust(self, scaleType = 0, map = mapFrameDict['map'],
+ mapType = self.mapType, rect = self.mapFrameDict['rect'])
+
+ mapFrameDict['rect'] = self.rectAdjusted if self.rectAdjusted else self.mapFrameDict['rect']
+ mapFrameDict['scale'] = self.scale[0]
+
+ mapFrameDict['center'] = self.center[0]
+ # set region
+ if self.mapType == 'raster':
+ RunCommand('g.region', rast = mapFrameDict['map'])
+ if self.mapType == 'vector':
+ raster = self.instruction.FindInstructionByType('raster')
+ rasterId = raster.id if raster else None
+ if rasterId:
+
+ RunCommand('g.region', vect = mapFrameDict['map'], rast = self.instruction[rasterId]['raster'])
+ else:
+ RunCommand('g.region', vect = mapFrameDict['map'])
+ else:
+ wx.MessageBox(message = _("No map selected!"),
+ caption = _('Invalid input'), style = wx.OK|wx.ICON_ERROR)
+ return False
+
+ elif mapFrameDict['scaleType'] == 1:
+ if self.select.GetValue():
+ mapFrameDict['map'] = None
+ mapFrameDict['mapType'] = None
+ mapFrameDict['region'] = self.select.GetValue()
+ self.scale[1], self.center[1], self.rectAdjusted = AutoAdjust(self, scaleType = 1, region = mapFrameDict['region'],
+ rect = self.mapFrameDict['rect'])
+ mapFrameDict['rect'] = self.rectAdjusted if self.rectAdjusted else self.mapFrameDict['rect']
+ mapFrameDict['scale'] = self.scale[1]
+ mapFrameDict['center'] = self.center[1]
+ # set region
+ RunCommand('g.region', region = mapFrameDict['region'])
+ else:
+ wx.MessageBox(message = _("No region selected!"),
+ caption = _('Invalid input'), style = wx.OK|wx.ICON_ERROR)
+ return False
+
+ elif scaleType == 2:
+ mapFrameDict['map'] = None
+ mapFrameDict['mapType'] = None
+ mapFrameDict['region'] = None
+ self.scale[2], self.center[2], self.rectAdjusted = AutoAdjust(self, scaleType = 2, rect = self.mapFrameDict['rect'])
+ mapFrameDict['rect'] = self.rectAdjusted if self.rectAdjusted else self.mapFrameDict['rect']
+ mapFrameDict['scale'] = self.scale[2]
+ mapFrameDict['center'] = self.center[2]
+
+ env = grass.gisenv()
+ windFilePath = os.path.join(env['GISDBASE'], env['LOCATION_NAME'], env['MAPSET'], 'WIND')
+ try:
+ windFile = open(windFilePath, 'r').read()
+ region = grass.parse_key_val(windFile, sep = ':', val_type = float)
+ except IOError:
+ region = grass.region()
+
+ raster = self.instruction.FindInstructionByType('raster')
+ rasterId = raster.id if raster else None
+ if rasterId: # because of resolution
+ RunCommand('g.region', n = region['north'], s = region['south'],
+ e = region['east'], w = region['west'], rast = self.instruction[rasterId]['raster'])
+ else:
+ RunCommand('g.region', n = region['north'], s = region['south'],
+ e = region['east'], w = region['west'])
+
+ elif scaleType == 3:
+ mapFrameDict['map'] = None
+ mapFrameDict['mapType'] = None
+ mapFrameDict['region'] = None
+ mapFrameDict['rect'] = self.mapFrameDict['rect']
+ try:
+ scaleNumber = float(self.scaleTextCtrl.GetValue())
+ centerE = float(self.eastingTextCtrl.GetValue())
+ centerN = float(self.northingTextCtrl.GetValue())
+ except (ValueError, SyntaxError):
+ wx.MessageBox(message = _("Invalid scale or map center!"),
+ caption = _('Invalid input'), style = wx.OK|wx.ICON_ERROR)
+ return False
+ mapFrameDict['scale'] = 1/scaleNumber
+ mapFrameDict['center'] = centerE, centerN
+
+ ComputeSetRegion(self, mapDict = mapFrameDict)
+
+ # border
+ mapFrameDict['border'] = 'y' if self.borderCheck.GetValue() else 'n'
+ if mapFrameDict['border'] == 'y':
+ mapFrameDict['width'] = self.borderWidthCtrl.GetValue()
+ mapFrameDict['color'] = convertRGB(self.borderColourPicker.GetColour())
+
+ if self.id not in self.instruction:
+ mapFrame = MapFrame(self.id)
+ self.instruction.AddInstruction(mapFrame)
+ self.instruction[self.id].SetInstruction(mapFrameDict)
+
+ if self.id not in self.mapDialog.parent.objectId:
+ self.mapDialog.parent.objectId.insert(0, self.id)# map frame is drawn first
+ return True
+
+class RasterPanel(wx.Panel):
+ """!Panel for raster map settings"""
+ def __init__(self, parent, id, settings, notebook = True):
+ wx.Panel.__init__(self, parent, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
+ self.instruction = settings
+
+ if notebook:
+ self.book = parent
+ self.book.AddPage(page = self, text = _("Raster map"))
+ self.mainDialog = self.book.GetParent()
+ else:
+ self.mainDialog = parent
+ if id:
+ self.id = id
+ self.rasterDict = self.instruction[self.id].GetInstruction()
+ else:
+ self.id = wx.NewId()
+ raster = Raster(self.id)
+ self.rasterDict = raster.GetInstruction()
+
+
+ self._layout()
+ self.OnRaster(None)
+
+ def _layout(self):
+ """!Do layout"""
+ border = wx.BoxSizer(wx.VERTICAL)
+
+ # choose raster map
+
+ box = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " {0} ".format(_("Choose raster map")))
+ sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
+
+ self.rasterNoRadio = wx.RadioButton(self, id = wx.ID_ANY, label = _("no raster map"), style = wx.RB_GROUP)
+ self.rasterYesRadio = wx.RadioButton(self, id = wx.ID_ANY, label = _("raster:"))
+
+ self.rasterSelect = Select(self, id = wx.ID_ANY, size = globalvar.DIALOG_GSELECT_SIZE,
+ type = 'raster', multiple = False,
+ updateOnPopup = True, onPopup = None)
+ if self.rasterDict['isRaster']:
+ self.rasterYesRadio.SetValue(True)
+ self.rasterNoRadio.SetValue(False)
+ self.rasterSelect.SetValue(self.rasterDict['raster'])
+ else:
+ self.rasterYesRadio.SetValue(False)
+ self.rasterNoRadio.SetValue(True)
+ mapId = self.instruction.FindInstructionByType('map').id
+
+ if self.instruction[mapId]['map'] and self.instruction[mapId]['mapType'] == 'raster':
+ self.rasterSelect.SetValue(self.instruction[mapId]['map'])# raster map from map frame dialog if possible
+ else:
+ self.rasterSelect.SetValue('')
+ gridBagSizer.Add(self.rasterNoRadio, pos = (0, 0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.rasterYesRadio, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.rasterSelect, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+
+ sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ #self.rasterSelect.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnRaster)
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterNoRadio)
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterYesRadio)
+
+ self.SetSizer(border)
+ self.Fit()
+
+ def OnRaster(self, event):
+ """!Enable/disable raster selection"""
+ self.rasterSelect.Enable(self.rasterYesRadio.GetValue())
+
+ def update(self):
+ #draw raster
+ if self.rasterNoRadio.GetValue() or not self.rasterSelect.GetValue():
+ self.rasterDict['isRaster'] = False
+ self.rasterDict['raster'] = None
+ if self.id in self.instruction:
+ del self.instruction[self.id]
+
+ else:
+ self.rasterDict['isRaster'] = True
+ self.rasterDict['raster'] = self.rasterSelect.GetValue()
+
+ if self.id not in self.instruction:
+ raster = Raster(self.id)
+ self.instruction.AddInstruction(raster)
+ self.instruction[self.id].SetInstruction(self.rasterDict)
+
+
+ return True
+
+ def getId(self):
+ return self.id
+
+class VectorPanel(wx.Panel):
+ """!Panel for vector maps settings"""
+ def __init__(self, parent, id, settings, notebook = True):
+ wx.Panel.__init__(self, parent, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
+
+ self.parent = parent
+ self.instruction = settings
+ self.tmpDialogDict = {}
+ vectors = self.instruction.FindInstructionByType('vProperties', list = True)
+ for vector in vectors:
+ self.tmpDialogDict[vector.id] = dict(self.instruction[vector.id].GetInstruction())
+
+ if id:
+ self.id = id
+ self.vectorList = deepcopy(self.instruction[id]['list'])
+ else:
+ self.id = wx.NewId()
+ self.vectorList = []
+
+ vLegend = self.instruction.FindInstructionByType('vectorLegend')
+ self.vLegendId = vLegend.id if vLegend else None
+
+ self._layout()
+
+ if notebook:
+ self.parent.AddPage(page = self, text = _("Vector maps"))
+
+ def _layout(self):
+ """!Do layout"""
+ border = wx.BoxSizer(wx.VERTICAL)
+
+ # choose vector map
+
+ box = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " {0} ".format(_("Choose map")))
+ sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
+
+ text = wx.StaticText(self, id = wx.ID_ANY, label = _("Map:"))
+ self.select = Select(self, id = wx.ID_ANY,# size = globalvar.DIALOG_GSELECT_SIZE,
+ type = 'vector', multiple = False,
+ updateOnPopup = True, onPopup = None)
+ topologyType = [_("points"), _("lines"), _("areas")]
+ self.vectorType = wx.RadioBox(self, id = wx.ID_ANY, label = " {0} ".format(_("Data Type")), choices = topologyType,
+ majorDimension = 3, style = wx.RA_SPECIFY_COLS)
+ self.AddVector = wx.Button(self, id = wx.ID_ANY, label = _("Add"))
+
+ gridBagSizer.Add(text, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.select, pos = (0,1), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.vectorType, pos = (1,1), flag = wx.ALIGN_CENTER, border = 0)
+ gridBagSizer.Add(self.AddVector, pos = (1,2), flag = wx.ALIGN_BOTTOM|wx.ALIGN_RIGHT, border = 0)
+
+ sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ # manage vector layers
+
+ box = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " {0} ".format(_("Vector maps order")))
+ sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
+ gridBagSizer.AddGrowableCol(0,2)
+ gridBagSizer.AddGrowableCol(1,1)
+
+
+
+ text = wx.StaticText(self, id = wx.ID_ANY, label = _("The topmost vector map overlaps the others"))
+ self.listbox = wx.ListBox(self, id = wx.ID_ANY, choices = [], style = wx.LB_SINGLE|wx.LB_NEEDED_SB)
+ self.btnUp = wx.Button(self, id = wx.ID_ANY, label = _("Up"))
+ self.btnDown = wx.Button(self, id = wx.ID_ANY, label = _("Down"))
+ self.btnDel = wx.Button(self, id = wx.ID_ANY, label = _("Delete"))
+ self.btnProp = wx.Button(self, id = wx.ID_ANY, label = _("Properties"))
+
+ self.updateListBox()
+
+
+ gridBagSizer.Add(text, pos = (0,0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.listbox, pos = (1,0), span = (4, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+ gridBagSizer.Add(self.btnUp, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.btnDown, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.btnDel, pos = (3,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.btnProp, pos = (4,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+ sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ self.Bind(wx.EVT_BUTTON, self.OnAddVector, self.AddVector)
+ self.Bind(wx.EVT_BUTTON, self.OnDelete, self.btnDel)
+ self.Bind(wx.EVT_BUTTON, self.OnUp, self.btnUp)
+ self.Bind(wx.EVT_BUTTON, self.OnDown, self.btnDown)
+ self.Bind(wx.EVT_BUTTON, self.OnProperties, self.btnProp)
+ self.select.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnVector)
+
+ self.SetSizer(border)
+ self.Fit()
+
+ def OnVector(self, event):
+ """!Gets info about toplogy and enables/disables choices point/line/area"""
+ vmap = self.select.GetValue()
+ try:
+ topoInfo = grass.vector_info_topo(map = vmap)
+ except grass.ScriptError, e:
+ GError(parent = self,
+ message = e.value)
+ return
+
+ self.vectorType.EnableItem(2, bool(topoInfo['areas']))
+ self.vectorType.EnableItem(1, bool(topoInfo['boundaries']) or bool(topoInfo['lines']))
+ self.vectorType.EnableItem(0, bool(topoInfo['centroids'] or bool(topoInfo['points']) ))
+ for item in range(2,-1,-1):
+ if self.vectorType.IsItemEnabled(item):
+ self.vectorType.SetSelection(item)
+ break
+
+ self.AddVector.SetFocus()
+
+ def OnAddVector(self, event):
+ """!Adds vector map to list"""
+ vmap = self.select.GetValue()
+ if vmap:
+ mapname = vmap.split('@')[0]
+ try:
+ mapset = '(' + vmap.split('@')[1] + ')'
+ except IndexError:
+ mapset = ''
+ type = self.vectorType.GetStringSelection()
+ record = "{0} - {1}".format(vmap,type)
+ id = wx.NewId()
+ lpos = 1
+ label = mapname + mapset
+ self.vectorList.insert(0, [vmap, type, id, lpos, label])
+ self.reposition()
+ self.listbox.InsertItems([record], 0)
+
+ vector = VProperties(id, type)
+ #self.instruction.AddInstruction(vector)
+ self.tmpDialogDict[id] = vector.GetInstruction()
+ self.tmpDialogDict[id]['name'] = vmap
+
+
+ self.listbox.SetSelection(0)
+ self.listbox.EnsureVisible(0)
+ self.btnProp.SetFocus()
+
+ def OnDelete(self, event):
+ """!Deletes vector map from the list"""
+ if self.listbox.GetSelections():
+ pos = self.listbox.GetSelection()
+ id = self.vectorList[pos][2]
+ del self.vectorList[pos]
+ del self.tmpDialogDict[id]
+
+ for i in range(pos, len(self.vectorList)):
+ if self.vectorList[i][3]:# can be 0
+ self.vectorList[i][3] -= 1
+ self.updateListBox(selected = pos if pos < len(self.vectorList) -1 else len(self.vectorList) -1)
+
+
+ def OnUp(self, event):
+ """!Moves selected map to top"""
+ if self.listbox.GetSelections():
+ pos = self.listbox.GetSelection()
+ if pos:
+ self.vectorList.insert(pos - 1, self.vectorList.pop(pos))
+ if not self.vLegendId:
+ self.reposition()
+ self.updateListBox(selected = (pos - 1) if pos > 0 else 0)
+
+ def OnDown(self, event):
+ """!Moves selected map to bottom"""
+ if self.listbox.GetSelections():
+ pos = self.listbox.GetSelection()
+ if pos != len(self.vectorList) - 1:
+ self.vectorList.insert(pos + 1, self.vectorList.pop(pos))
+ if not self.vLegendId:
+ self.reposition()
+ self.updateListBox(selected = (pos + 1) if pos < len(self.vectorList) -1 else len(self.vectorList) -1)
+
+ def OnProperties(self, event):
+ """!Opens vector map properties dialog"""
+ if self.listbox.GetSelections():
+ pos = self.listbox.GetSelection()
+ id = self.vectorList[pos][2]
+
+ dlg = VPropertiesDialog(self, id = id, settings = self.instruction,
+ vectors = self.vectorList, tmpSettings = self.tmpDialogDict[id])
+ dlg.ShowModal()
+
+ self.parent.FindWindowById(wx.ID_OK).SetFocus()
+
+
+
+ def updateListBox(self, selected = None):
+ mapList = ["{0} - {1}".format(*item) for item in self.vectorList]
+ self.listbox.Set(mapList)
+ if selected is not None:
+ self.listbox.SetSelection(selected)
+ self.listbox.EnsureVisible(selected)
+
+ def reposition(self):
+ """!Update position in legend, used only if there is no vlegend yet"""
+ for i in range(len(self.vectorList)):
+ if self.vectorList[i][3]:
+ self.vectorList[i][3] = i + 1
+
+ def getId(self):
+ return self.id
+
+ def update(self):
+ vectors = self.instruction.FindInstructionByType('vProperties', list = True)
+
+ for vector in vectors:
+ del self.instruction[vector.id]
+ if self.id in self.instruction:
+ del self.instruction[self.id]
+
+ if len(self.vectorList) > 0:
+ vector = Vector(self.id)
+ self.instruction.AddInstruction(vector)
+
+ vector.SetInstruction({'list': deepcopy(self.vectorList)})
+
+
+ # save new vectors
+ for item in self.vectorList:
+ id = item[2]
+
+ vLayer = VProperties(id, item[1])
+ self.instruction.AddInstruction(vLayer)
+ vLayer.SetInstruction(self.tmpDialogDict[id])
+ vLayer['name'] = item[0]
+ vLayer['label'] = item[4]
+ vLayer['lpos'] = item[3]
+
+ else:
+ if self.id in self.instruction:
+ del self.instruction[self.id]
+
+ return True
+
+class RasterDialog(PsmapDialog):
+ def __init__(self, parent, id, settings):
+ PsmapDialog.__init__(self, parent = parent, id = id, title = "Choose raster map", settings = settings)
+ self.instruction = settings
+ self.rPanel = RasterPanel(parent = self, id = self.id, settings = self.instruction, notebook = False)
+
+ self.id = self.rPanel.getId()
+ self._layout(self.rPanel)
+
+ def update(self):
+ ok = self.rPanel.update()
+ if ok:
+ return True
+ return False
+
+ def OnApply(self, event):
+ ok = self.update()
+ if not ok:
+ return False
+
+ if self.id in self.instruction:
+ self.parent.DialogDataChanged(id = self.id)
+ else:
+ mapId = self.instruction.FindInstructionByType('map').id
+ self.parent.DialogDataChanged(id = mapId)
+ return True
+
+class MainVectorDialog(PsmapDialog):
+ def __init__(self, parent, id, settings):
+ PsmapDialog.__init__(self, parent = parent, id = id, title = "Choose vector maps", settings = settings)
+ self.instruction = settings
+ self.vPanel = VectorPanel(parent = self, id = self.id, settings = self.instruction, notebook = False)
+
+ self.id = self.vPanel.getId()
+ self._layout(self.vPanel)
+
+ def update(self):
+ self.vPanel.update()
+
+ def OnApply(self, event):
+ self.update()
+ if self.id in self.instruction:
+ self.parent.DialogDataChanged(id = self.id)
+ else:
+ mapId = self.instruction.FindInstructionByType('map').id
+ self.parent.DialogDataChanged(id = mapId)
+ return True
+
+
+class VPropertiesDialog(PsmapDialog):
+ def __init__(self, parent, id, settings, vectors, tmpSettings):
+ PsmapDialog.__init__(self, parent = parent, id = id, title = "", settings = settings, apply = False)
+
+ vectorList = vectors
+ self.vPropertiesDict = tmpSettings
+
+ # determine map and its type
+ for item in vectorList:
+ if id == item[2]:
+ self.vectorName = item[0]
+ self.type = item[1]
+ self.SetTitle(self.vectorName + " "+ _("properties"))
+
+ #vector map info
+ self.connection = True
+ try:
+ self.mapDBInfo = dbm_base.VectorDBInfo(self.vectorName)
+ self.layers = self.mapDBInfo.layers.keys()
+ except grass.ScriptError:
+ self.connection = False
+ self.layers = []
+
+
+ self.currLayer = self.vPropertiesDict['layer']
+
+ #path to symbols, patterns
+ gisbase = os.getenv("GISBASE")
+ self.symbolPath = os.path.join(gisbase, 'etc', 'symbol')
+ self.symbols = []
+ for dir in os.listdir(self.symbolPath):
+ for symbol in os.listdir(os.path.join(self.symbolPath, dir)):
+ self.symbols.append(os.path.join(dir, symbol))
+ self.patternPath = os.path.join(gisbase, 'etc', 'paint', 'patterns')
+
+ #notebook
+ notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT)
+ self.DSpanel = self._DataSelectionPanel(notebook)
+ self.EnableLayerSelection(enable = self.connection)
+ selectPanel = { 'points': [self._ColorsPointAreaPanel, self._StylePointPanel],
+ 'lines': [self._ColorsLinePanel, self._StyleLinePanel],
+ 'areas': [self._ColorsPointAreaPanel, self._StyleAreaPanel]}
+ self.ColorsPanel = selectPanel[self.type][0](notebook)
+
+ self.OnOutline(None)
+ if self.type in ('points', 'areas'):
+ self.OnFill(None)
+ self.OnColor(None)
+
+ self.StylePanel = selectPanel[self.type][1](notebook)
+ if self.type == 'points':
+ self.OnSize(None)
+ self.OnRotation(None)
+ if self.type == 'areas':
+ self.OnPattern(None)
+
+ self._layout(notebook)
+
+ def _DataSelectionPanel(self, notebook):
+ panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
+ notebook.AddPage(page = panel, text = _("Data selection"))
+
+ border = wx.BoxSizer(wx.VERTICAL)
+
+ # data type
+ self.checkType1 = self.checkType2 = None
+ if self.type in ('lines', 'points'):
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Feature type")))
+ sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+ gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
+
+ label = (_("points"), _("centroids")) if self.type == 'points' else (_("lines"), _("boundaries"))
+ name = ("point", "centroid") if self.type == 'points' else ("line", "boundary")
+ self.checkType1 = wx.CheckBox(panel, id = wx.ID_ANY, label = label[0], name = name[0])
+ self.checkType2 = wx.CheckBox(panel, id = wx.ID_ANY, label = label[1], name = name[1])
+ self.checkType1.SetValue(self.vPropertiesDict['type'].find(name[0]) >= 0)
+ self.checkType2.SetValue(self.vPropertiesDict['type'].find(name[1]) >= 0)
+
+ gridBagSizer.Add(self.checkType1, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.checkType2, pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ # layer selection
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Layer selection")))
+ sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+ self.gridBagSizerL = wx.GridBagSizer(hgap = 5, vgap = 5)
+
+
+ self.warning = wx.StaticText(panel, id = wx.ID_ANY, label = "")
+ if not self.connection:
+ self.warning = wx.StaticText(panel, id = wx.ID_ANY, label = _("Database connection is not defined in DB file."))
+ text = wx.StaticText(panel, id = wx.ID_ANY, label = _("Select layer:"))
+ self.layerChoice = wx.Choice(panel, id = wx.ID_ANY, choices = map(str, self.layers), size = self.spinCtrlSize)
+ self.layerChoice.SetStringSelection(self.currLayer)
+
+ table = self.mapDBInfo.layers[int(self.currLayer)]['table'] if self.connection else ""
+ self.radioWhere = wx.RadioButton(panel, id = wx.ID_ANY, label = "SELECT * FROM {0} WHERE".format(table), style = wx.RB_GROUP)
+ self.textCtrlWhere = wx.TextCtrl(panel, id = wx.ID_ANY, value = "")
+
+
+ cols = self.mapDBInfo.GetColumns(self.mapDBInfo.layers[int(self.currLayer)]['table']) if self.connection else []
+ self.choiceColumns = wx.Choice(panel, id = wx.ID_ANY, choices = cols)
+
+ self.radioCats = wx.RadioButton(panel, id = wx.ID_ANY, label = "Choose categories ".format(table))
+ self.textCtrlCats = wx.TextCtrl(panel, id = wx.ID_ANY, value = "")
+ self.textCtrlCats.SetToolTipString(_("list of categories (e.g. 1,3,5-7)"))
+
+ if self.vPropertiesDict.has_key('cats'):
+ self.radioCats.SetValue(True)
+ self.textCtrlCats.SetValue(self.vPropertiesDict['cats'])
+ if self.vPropertiesDict.has_key('where'):
+ self.radioWhere.SetValue(True)
+ where = self.vPropertiesDict['where'].strip().split(" ",1)
+ self.choiceColumns.SetStringSelection(where[0])
+ self.textCtrlWhere.SetValue(where[1])
+
+ row = 0
+ if not self.connection:
+ self.gridBagSizerL.Add(self.warning, pos = (0,0), span = (1,3), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ row = 1
+ self.gridBagSizerL.Add(text, pos = (0 + row,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerL.Add(self.layerChoice, pos = (0 + row,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+ self.gridBagSizerL.Add(self.radioWhere, pos = (1 + row,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerL.Add(self.choiceColumns, pos = (1 + row,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerL.Add(self.textCtrlWhere, pos = (1 + row,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerL.Add(self.radioCats, pos = (2 + row,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerL.Add(self.textCtrlCats, pos = (2 + row,1), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+
+ sizer.Add(self.gridBagSizerL, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ #mask
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Mask")))
+ sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+
+ self.mask = wx.CheckBox(panel, id = wx.ID_ANY, label = _("Use current mask"))
+ self.mask.SetValue(True if self.vPropertiesDict['masked'] == 'y' else False)
+
+ sizer.Add(self.mask, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ self.Bind(wx.EVT_CHOICE, self.OnLayer, self.layerChoice)
+
+ panel.SetSizer(border)
+ panel.Fit()
+ return panel
+
+ def _ColorsPointAreaPanel(self, notebook):
+ panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
+ notebook.AddPage(page = panel, text = _("Colors"))
+
+ border = wx.BoxSizer(wx.VERTICAL)
+
+ #colors - outline
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Outline")))
+ sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+ self.gridBagSizerO = wx.GridBagSizer(hgap = 5, vgap = 2)
+
+
+ self.outlineCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("draw outline"))
+ self.outlineCheck.SetValue(self.vPropertiesDict['color'] != 'none')
+
+ widthText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Width (pts):"))
+ self.widthSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 25, initial = 1, size = self.spinCtrlSize)
+ self.widthSpin.SetValue(self.vPropertiesDict['width'] if self.vPropertiesDict['color'] != 'none' else 1)
+
+ colorText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Color:"))
+ self.colorPicker = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
+ self.colorPicker.SetColour(convertRGB(self.vPropertiesDict['color']) if self.vPropertiesDict['color'] != 'none' else 'black')
+
+
+ self.gridBagSizerO.Add(self.outlineCheck, pos = (0, 0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerO.Add(widthText, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerO.Add(self.widthSpin, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+ self.gridBagSizerO.Add(colorText, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerO.Add(self.colorPicker, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+
+ sizer.Add(self.gridBagSizerO, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ self.Bind(wx.EVT_CHECKBOX, self.OnOutline, self.outlineCheck)
+
+ #colors - fill
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Fill")))
+ sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+ self.gridBagSizerF = wx.GridBagSizer(hgap = 5, vgap = 2)
+
+ self.fillCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("fill color"))
+ self.fillCheck.SetValue(self.vPropertiesDict['fcolor'] != 'none' or self.vPropertiesDict['rgbcolumn'] is not None)
+
+
+ self.colorPickerRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("choose color:"), style = wx.RB_GROUP)
+ #set choose color option if there is no db connection
+ if self.connection:
+ self.colorPickerRadio.SetValue(not self.vPropertiesDict['rgbcolumn'])
+ else:
+ self.colorPickerRadio.SetValue(False)
+ self.fillColorPicker = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
+ self.fillColorPicker.SetColour(convertRGB(self.vPropertiesDict['fcolor']) if self.vPropertiesDict['fcolor'] != 'none' else 'red')
+
+
+ self.colorColRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("color from map table column:"))
+ self.colorColChoice = self.getColsChoice(parent = panel)
+ if self.connection:
+ if self.vPropertiesDict['rgbcolumn']:
+ self.colorColRadio.SetValue(True)
+ self.colorColChoice.SetStringSelection(self.vPropertiesDict['rgbcolumn'])
+ else:
+ self.colorColRadio.SetValue(False)
+ self.colorColChoice.SetSelection(0)
+ self.colorColChoice.Enable(self.connection)
+ self.colorColRadio.Enable(self.connection)
+
+ self.gridBagSizerF.Add(self.fillCheck, pos = (0, 0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerF.Add(self.colorPickerRadio, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerF.Add(self.fillColorPicker, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerF.Add(self.colorColRadio, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerF.Add(self.colorColChoice, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+
+ sizer.Add(self.gridBagSizerF, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ self.Bind(wx.EVT_CHECKBOX, self.OnFill, self.fillCheck)
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorColRadio)
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorPickerRadio)
+
+ panel.SetSizer(border)
+ panel.Fit()
+ return panel
+
+ def _ColorsLinePanel(self, notebook):
+ panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
+ notebook.AddPage(page = panel, text = _("Colors"))
+
+ border = wx.BoxSizer(wx.VERTICAL)
+
+ #colors - outline
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Outline")))
+ sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+ self.gridBagSizerO = wx.GridBagSizer(hgap = 5, vgap = 2)
+
+
+ self.outlineCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("draw outline"))
+ self.outlineCheck.SetValue(self.vPropertiesDict['hcolor'] != 'none')
+ self.outlineCheck.SetToolTipString(_("No effect for fill color from table column"))
+
+ widthText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Width (pts):"))
+ self.widthSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 25, initial = 1, size = self.spinCtrlSize)
+ self.widthSpin.SetValue(self.vPropertiesDict['hwidth'] if self.vPropertiesDict['hcolor'] != 'none' else 1)
+
+ colorText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Color:"))
+ self.colorPicker = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
+ self.colorPicker.SetColour(convertRGB(self.vPropertiesDict['hcolor']) if self.vPropertiesDict['hcolor'] != 'none' else 'black')
+
+
+ self.gridBagSizerO.Add(self.outlineCheck, pos = (0, 0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerO.Add(widthText, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerO.Add(self.widthSpin, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+ self.gridBagSizerO.Add(colorText, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerO.Add(self.colorPicker, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+
+ sizer.Add(self.gridBagSizerO, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ self.Bind(wx.EVT_CHECKBOX, self.OnOutline, self.outlineCheck)
+
+ #colors - fill
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Fill")))
+ sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+ self.gridBagSizerF = wx.GridBagSizer(hgap = 5, vgap = 2)
+
+ fillText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Color of lines:"))
+
+
+ self.colorPickerRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("choose color:"), style = wx.RB_GROUP)
+ #set choose color option if there is no db connection
+ if self.connection:
+ self.colorPickerRadio.SetValue(not self.vPropertiesDict['rgbcolumn'])
+ else:
+ self.colorPickerRadio.SetValue(False)
+ self.fillColorPicker = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
+ self.fillColorPicker.SetColour(convertRGB(self.vPropertiesDict['color']) if self.vPropertiesDict['color'] != 'none' else 'black')
+
+
+ self.colorColRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("color from map table column:"))
+ self.colorColChoice = self.getColsChoice(parent = panel)
+ if self.connection:
+ if self.vPropertiesDict['rgbcolumn']:
+ self.colorColRadio.SetValue(True)
+ self.colorColChoice.SetStringSelection(self.vPropertiesDict['rgbcolumn'])
+ else:
+ self.colorColRadio.SetValue(False)
+ self.colorColChoice.SetSelection(0)
+ self.colorColChoice.Enable(self.connection)
+ self.colorColRadio.Enable(self.connection)
+
+ self.gridBagSizerF.Add(fillText, pos = (0, 0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerF.Add(self.colorPickerRadio, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerF.Add(self.fillColorPicker, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerF.Add(self.colorColRadio, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerF.Add(self.colorColChoice, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+
+ sizer.Add(self.gridBagSizerF, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorColRadio)
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorPickerRadio)
+ panel.SetSizer(border)
+ panel.Fit()
+ return panel
+
+ def _StylePointPanel(self, notebook):
+ panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
+ notebook.AddPage(page = panel, text = _("Size and style"))
+
+ border = wx.BoxSizer(wx.VERTICAL)
+
+ #symbology
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Symbology")))
+ sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+ gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
+ gridBagSizer.AddGrowableCol(1)
+
+ self.symbolRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("symbol:"), style = wx.RB_GROUP)
+ self.symbolRadio.SetValue(bool(self.vPropertiesDict['symbol']))
+
+
+ self.symbolChoice = wx.Choice(panel, id = wx.ID_ANY, choices = self.symbols)
+
+ self.epsRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("eps file:"))
+ self.epsRadio.SetValue(bool(self.vPropertiesDict['eps']))
+
+ self.epsFileCtrl = filebrowse.FileBrowseButton(panel, id = wx.ID_ANY, labelText = '',
+ buttonText = _("Browse"), toolTip = _("Type filename or click browse to choose file"),
+ dialogTitle = _("Choose a file"), startDirectory = '', initialValue = '',
+ fileMask = "Encapsulated PostScript (*.eps)|*.eps|All files (*.*)|*.*", fileMode = wx.OPEN)
+ if self.vPropertiesDict['symbol']:
+ self.symbolChoice.SetStringSelection(self.vPropertiesDict['symbol'])
+ self.epsFileCtrl.SetValue('')
+ else: #eps chosen
+ self.epsFileCtrl.SetValue(self.vPropertiesDict['eps'])
+ self.symbolChoice.SetSelection(0)
+
+ gridBagSizer.Add(self.symbolRadio, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.symbolChoice, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.epsRadio, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.epsFileCtrl, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+
+ sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ #size
+
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Size")))
+ sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+ gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
+ gridBagSizer.AddGrowableCol(0)
+
+ self.sizeRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("size:"), style = wx.RB_GROUP)
+ self.sizeSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 50, initial = 1)
+ self.sizecolumnRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("size from map table column:"))
+ self.sizeColChoice = self.getColsChoice(panel)
+ self.scaleText = wx.StaticText(panel, id = wx.ID_ANY, label = _("scale:"))
+ self.scaleSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 25, initial = 1)
+
+ self.sizeRadio.SetValue(self.vPropertiesDict['size'] is not None)
+ self.sizecolumnRadio.SetValue(bool(self.vPropertiesDict['sizecolumn']))
+ self.sizeSpin.SetValue(self.vPropertiesDict['size'] if self.vPropertiesDict['size'] else 5)
+ if self.vPropertiesDict['sizecolumn']:
+ self.scaleSpin.SetValue(self.vPropertiesDict['scale'])
+ self.sizeColChoice.SetStringSelection(self.vPropertiesDict['sizecolumn'])
+ else:
+ self.scaleSpin.SetValue(1)
+ self.sizeColChoice.SetSelection(0)
+ if not self.connection:
+ for each in (self.sizecolumnRadio, self.sizeColChoice, self.scaleSpin, self.scaleText):
+ each.Disable()
+
+ gridBagSizer.Add(self.sizeRadio, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.sizeSpin, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.sizecolumnRadio, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.sizeColChoice, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+ gridBagSizer.Add(self.scaleText, pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
+ gridBagSizer.Add(self.scaleSpin, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+ sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnSize, self.sizeRadio)
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnSize, self.sizecolumnRadio)
+
+ #rotation
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Rotation")))
+ sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+ gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
+ gridBagSizer.AddGrowableCol(1)
+
+
+ self.rotateCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("rotate symbols:"))
+ self.rotateRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("counterclockwise in degrees:"), style = wx.RB_GROUP)
+ self.rotateSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 0, max = 360, initial = 0)
+ self.rotatecolumnRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("from map table column:"))
+ self.rotateColChoice = self.getColsChoice(panel)
+
+ self.rotateCheck.SetValue(self.vPropertiesDict['rotation'])
+ self.rotateRadio.SetValue(self.vPropertiesDict['rotate'] is not None)
+ self.rotatecolumnRadio.SetValue(bool(self.vPropertiesDict['rotatecolumn']))
+ self.rotateSpin.SetValue(self.vPropertiesDict['rotate'] if self.vPropertiesDict['rotate'] else 0)
+ if self.vPropertiesDict['rotatecolumn']:
+ self.rotateColChoice.SetStringSelection(self.vPropertiesDict['rotatecolumn'])
+ else:
+ self.rotateColChoice.SetSelection(0)
+
+ gridBagSizer.Add(self.rotateCheck, pos = (0, 0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.rotateRadio, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.rotateSpin, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.rotatecolumnRadio, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.rotateColChoice, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+
+ sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ self.Bind(wx.EVT_CHECKBOX, self.OnRotation, self.rotateCheck)
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnRotationType, self.rotateRadio)
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnRotationType, self.rotatecolumnRadio)
+
+ panel.SetSizer(border)
+ panel.Fit()
+ return panel
+
+ def _StyleLinePanel(self, notebook):
+ panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
+ notebook.AddPage(page = panel, text = _("Size and style"))
+
+ border = wx.BoxSizer(wx.VERTICAL)
+
+ #width
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Width")))
+ sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+ gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
+
+ widthText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Set width (pts):"))
+ self.widthSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 25, initial = 1)
+ self.cwidthCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("multiply width by category value"))
+
+ if self.vPropertiesDict['width']:
+ self.widthSpin.SetValue(self.vPropertiesDict['width'])
+ self.cwidthCheck.SetValue(False)
+ else:
+ self.widthSpin.SetValue(self.vPropertiesDict['cwidth'])
+ self.cwidthCheck.SetValue(True)
+
+ gridBagSizer.Add(widthText, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.widthSpin, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.cwidthCheck, pos = (1, 0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+ sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ #style
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Line style")))
+ sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+ gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
+
+ styleText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Choose line style:"))
+ penStyles = ["solid", "dashed", "dotted", "dashdotted"]
+ self.styleCombo = PenStyleComboBox(panel, choices = penStyles, validator = TCValidator(flag = 'ZERO_AND_ONE_ONLY'))
+## self.styleCombo = wx.ComboBox(panel, id = wx.ID_ANY,
+## choices = ["solid", "dashed", "dotted", "dashdotted"],
+## validator = TCValidator(flag = 'ZERO_AND_ONE_ONLY'))
+## self.styleCombo.SetToolTipString(_("It's possible to enter a series of 0's and 1's too. "\
+## "The first block of repeated zeros or ones represents 'draw', "\
+## "the second block represents 'blank'. An even number of blocks "\
+## "will repeat the pattern, an odd number of blocks will alternate the pattern."))
+ linecapText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Choose linecap:"))
+ self.linecapChoice = wx.Choice(panel, id = wx.ID_ANY, choices = ["butt", "round", "extended_butt"])
+
+ self.styleCombo.SetValue(self.vPropertiesDict['style'])
+ self.linecapChoice.SetStringSelection(self.vPropertiesDict['linecap'])
+
+ gridBagSizer.Add(styleText, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.styleCombo, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+ gridBagSizer.Add(linecapText, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.linecapChoice, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+
+ sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ panel.SetSizer(border)
+ panel.Fit()
+ return panel
+
+ def _StyleAreaPanel(self, notebook):
+ panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
+ notebook.AddPage(page = panel, text = _("Size and style"))
+
+ border = wx.BoxSizer(wx.VERTICAL)
+
+ #pattern
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Pattern")))
+ sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+ gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
+ gridBagSizer.AddGrowableCol(1)
+
+ self.patternCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("use pattern:"))
+ self.patFileCtrl = filebrowse.FileBrowseButton(panel, id = wx.ID_ANY, labelText = _("Choose pattern file:"),
+ buttonText = _("Browse"), toolTip = _("Type filename or click browse to choose file"),
+ dialogTitle = _("Choose a file"), startDirectory = self.patternPath, initialValue = '',
+ fileMask = "Encapsulated PostScript (*.eps)|*.eps|All files (*.*)|*.*", fileMode = wx.OPEN)
+ self.patWidthText = wx.StaticText(panel, id = wx.ID_ANY, label = _("pattern line width (pts):"))
+ self.patWidthSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 25, initial = 1)
+ self.patScaleText = wx.StaticText(panel, id = wx.ID_ANY, label = _("pattern scale factor:"))
+ self.patScaleSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 25, initial = 1)
+
+ self.patternCheck.SetValue(bool(self.vPropertiesDict['pat']))
+ if self.patternCheck.GetValue():
+ self.patFileCtrl.SetValue(self.vPropertiesDict['pat'])
+ self.patWidthSpin.SetValue(self.vPropertiesDict['pwidth'])
+ self.patScaleSpin.SetValue(self.vPropertiesDict['scale'])
+
+ gridBagSizer.Add(self.patternCheck, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.patFileCtrl, pos = (1, 0), span = (1, 2),flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+ gridBagSizer.Add(self.patWidthText, pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.patWidthSpin, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.patScaleText, pos = (3, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.patScaleSpin, pos = (3, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+
+ sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ self.Bind(wx.EVT_CHECKBOX, self.OnPattern, self.patternCheck)
+
+ panel.SetSizer(border)
+ panel.Fit()
+ return panel
+
+
+ def OnLayer(self, event):
+ """!Change columns on layer change """
+ if self.layerChoice.GetStringSelection() == self.currLayer:
+ return
+ self.currLayer = self.layerChoice.GetStringSelection()
+ cols = self.mapDBInfo.GetColumns(self.mapDBInfo.layers[int(self.currLayer)]['table']) if self.connection else []
+ self.choiceColumns.SetItems(cols)
+
+ self.choiceColumns.SetSelection(0)
+ if self.type in ('points', 'lines'):
+ self.colorColChoice.SetItems(cols)
+ self.colorColChoice.SetSelection(0)
+
+ def OnOutline(self, event):
+ for widget in self.gridBagSizerO.GetChildren():
+ if widget.GetWindow() != self.outlineCheck:
+ widget.GetWindow().Enable(self.outlineCheck.GetValue())
+
+ def OnFill(self, event):
+ enable = self.fillCheck.GetValue()
+
+ self.colorColChoice.Enable(enable)
+ self.colorColRadio.Enable(enable)
+ self.fillColorPicker.Enable(enable)
+ self.colorPickerRadio.Enable(enable)
+ if enable:
+ self.OnColor(None)
+ if not self.connection:
+ self.colorColChoice.Disable()
+ self.colorColRadio.Disable()
+
+ def OnColor(self, event):
+ self.colorColChoice.Enable(self.colorColRadio.GetValue())
+ self.fillColorPicker.Enable(self.colorPickerRadio.GetValue())
+
+ def OnSize(self, event):
+ self.sizeSpin.Enable(self.sizeRadio.GetValue())
+ self.sizeColChoice.Enable(self.sizecolumnRadio.GetValue())
+ self.scaleText.Enable(self.sizecolumnRadio.GetValue())
+ self.scaleSpin.Enable(self.sizecolumnRadio.GetValue())
+
+ def OnRotation(self, event):
+ for each in (self.rotateRadio, self.rotatecolumnRadio, self.rotateColChoice, self.rotateSpin):
+ if self.rotateCheck.GetValue():
+ each.Enable()
+ self.OnRotationType(event = None)
+ else:
+ each.Disable()
+
+
+ def OnRotationType(self, event):
+ self.rotateSpin.Enable(self.rotateRadio.GetValue())
+ self.rotateColChoice.Enable(self.rotatecolumnRadio.GetValue())
+
+ def OnPattern(self, event):
+ for each in (self.patFileCtrl, self.patWidthText, self.patWidthSpin, self.patScaleText, self.patScaleSpin):
+ each.Enable(self.patternCheck.GetValue())
+
+ def EnableLayerSelection(self, enable = True):
+ for widget in self.gridBagSizerL.GetChildren():
+ if widget.GetWindow() != self.warning:
+ widget.GetWindow().Enable(enable)
+
+ def getColsChoice(self, parent):
+ """!Returns a wx.Choice with table columns"""
+ cols = self.mapDBInfo.GetColumns(self.mapDBInfo.layers[int(self.currLayer)]['table']) if self.connection else []
+ choice = wx.Choice(parent = parent, id = wx.ID_ANY, choices = cols)
+ return choice
+
+ def update(self):
+ #feature type
+ if self.type in ('lines', 'points'):
+ featureType = None
+ if self.checkType1.GetValue():
+ featureType = self.checkType1.GetName()
+ if self.checkType2.GetValue():
+ featureType += " or " + self.checkType2.GetName()
+ elif self.checkType2.GetValue():
+ featureType = self.checkType2.GetName()
+ if featureType:
+ self.vPropertiesDict['type'] = featureType
+
+ # is connection
+ self.vPropertiesDict['connection'] = self.connection
+ if self.connection:
+ self.vPropertiesDict['layer'] = self.layerChoice.GetStringSelection()
+ if self.radioCats.GetValue() and not self.textCtrlCats.IsEmpty():
+ self.vPropertiesDict['cats'] = self.textCtrlCats.GetValue()
+ elif self.radioWhere.GetValue() and not self.textCtrlWhere.IsEmpty():
+ self.vPropertiesDict['where'] = self.choiceColumns.GetStringSelection() + " " \
+ + self.textCtrlWhere.GetValue()
+ #mask
+ self.vPropertiesDict['masked'] = 'y' if self.mask.GetValue() else 'n'
+
+ #colors
+ if self.type in ('points', 'areas'):
+ if self.outlineCheck.GetValue():
+ self.vPropertiesDict['color'] = convertRGB(self.colorPicker.GetColour())
+ self.vPropertiesDict['width'] = self.widthSpin.GetValue()
+ else:
+ self.vPropertiesDict['color'] = 'none'
+
+ if self.fillCheck.GetValue():
+ if self.colorPickerRadio.GetValue():
+ self.vPropertiesDict['fcolor'] = convertRGB(self.fillColorPicker.GetColour())
+ self.vPropertiesDict['rgbcolumn'] = None
+ if self.colorColRadio.GetValue():
+ self.vPropertiesDict['fcolor'] = 'none'# this color is taken in case of no record in rgb column
+ self.vPropertiesDict['rgbcolumn'] = self.colorColChoice.GetStringSelection()
+ else:
+ self.vPropertiesDict['fcolor'] = 'none'
+
+ if self.type == 'lines':
+ #hcolor only when no rgbcolumn
+ if self.outlineCheck.GetValue():# and self.fillCheck.GetValue() and self.colorColRadio.GetValue():
+ self.vPropertiesDict['hcolor'] = convertRGB(self.colorPicker.GetColour())
+ self.vPropertiesDict['hwidth'] = self.widthSpin.GetValue()
+ else:
+ self.vPropertiesDict['hcolor'] = 'none'
+
+ if self.colorPickerRadio.GetValue():
+ self.vPropertiesDict['color'] = convertRGB(self.fillColorPicker.GetColour())
+ self.vPropertiesDict['rgbcolumn'] = None
+ if self.colorColRadio.GetValue():
+ self.vPropertiesDict['color'] = 'none'# this color is taken in case of no record in rgb column
+ self.vPropertiesDict['rgbcolumn'] = self.colorColChoice.GetStringSelection()
+ #
+ #size and style
+ #
+
+ if self.type == 'points':
+ #symbols
+ if self.symbolRadio.GetValue():
+ self.vPropertiesDict['symbol'] = self.symbolChoice.GetStringSelection()
+ self.vPropertiesDict['eps'] = None
+ else:
+ self.vPropertiesDict['eps'] = self.epsFileCtrl.GetValue()
+ self.vPropertiesDict['symbol'] = None
+ #size
+ if self.sizeRadio.GetValue():
+ self.vPropertiesDict['size'] = self.sizeSpin.GetValue()
+ self.vPropertiesDict['sizecolumn'] = None
+ self.vPropertiesDict['scale'] = None
+ else:
+ self.vPropertiesDict['sizecolumn'] = self.sizeColChoice.GetStringSelection()
+ self.vPropertiesDict['scale'] = self.scaleSpin.GetValue()
+ self.vPropertiesDict['size'] = None
+
+ #rotation
+ self.vPropertiesDict['rotate'] = None
+ self.vPropertiesDict['rotatecolumn'] = None
+ self.vPropertiesDict['rotation'] = False
+ if self.rotateCheck.GetValue():
+ self.vPropertiesDict['rotation'] = True
+ if self.rotateRadio.GetValue():
+ self.vPropertiesDict['rotate'] = self.rotateSpin.GetValue()
+ else:
+ self.vPropertiesDict['rotatecolumn'] = self.rotateColChoice.GetStringSelection()
+
+ if self.type == 'areas':
+ #pattern
+ self.vPropertiesDict['pat'] = None
+ if self.patternCheck.GetValue() and bool(self.patFileCtrl.GetValue()):
+ self.vPropertiesDict['pat'] = self.patFileCtrl.GetValue()
+ self.vPropertiesDict['pwidth'] = self.patWidthSpin.GetValue()
+ self.vPropertiesDict['scale'] = self.patScaleSpin.GetValue()
+
+ if self.type == 'lines':
+ #width
+ if self.cwidthCheck.GetValue():
+ self.vPropertiesDict['cwidth'] = self.widthSpin.GetValue()
+ self.vPropertiesDict['width'] = None
+ else:
+ self.vPropertiesDict['width'] = self.widthSpin.GetValue()
+ self.vPropertiesDict['cwidth'] = None
+ #line style
+ self.vPropertiesDict['style'] = self.styleCombo.GetValue() if self.styleCombo.GetValue() else 'solid'
+ self.vPropertiesDict['linecap'] = self.linecapChoice.GetStringSelection()
+
+
+ def OnOK(self, event):
+ self.update()
+ event.Skip()
+
+class LegendDialog(PsmapDialog):
+ def __init__(self, parent, id, settings, page):
+ PsmapDialog.__init__(self, parent = parent, id = id, title = "Legend settings", settings = settings)
+
+ self.instruction = settings
+ map = self.instruction.FindInstructionByType('map')
+ self.mapId = map.id if map else None
+ vector = self.instruction.FindInstructionByType('vector')
+ self.vectorId = vector.id if vector else None
+ raster = self.instruction.FindInstructionByType('raster')
+ self.rasterId = raster.id if raster else None
+
+
+ self.pageId = self.instruction.FindInstructionByType('page').id
+ currPage = self.instruction[self.pageId].GetInstruction()
+ #raster legend
+ if self.id[0] is not None:
+ self.rLegendDict = self.instruction[self.id[0]].GetInstruction()
+ else:
+ self.id[0] = wx.NewId()
+ rasterLegend = RasterLegend(self.id[0])
+ self.rLegendDict = rasterLegend.GetInstruction()
+ self.rLegendDict['where'] = currPage['Left'], currPage['Top']
+
+
+ #vector legend
+ if self.id[1] is not None:
+ self.vLegendDict = self.instruction[self.id[1]].GetInstruction()
+ else:
+ self.id[1] = wx.NewId()
+ vectorLegend = VectorLegend(self.id[1])
+ self.vLegendDict = vectorLegend.GetInstruction()
+ self.vLegendDict['where'] = currPage['Left'], currPage['Top']
+
+
+
+ self.currRaster = self.instruction[self.rasterId]['raster'] if self.rasterId else None
+
+ #notebook
+ self.notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT)
+ self.panelRaster = self._rasterLegend(self.notebook)
+ self.panelVector = self._vectorLegend(self.notebook)
+ self.OnDefaultSize(None)
+ self.OnRaster(None)
+ self.OnRange(None)
+ self.OnIsLegend(None)
+ self.OnSpan(None)
+ self.OnBorder(None)
+
+
+ self._layout(self.notebook)
+ self.notebook.ChangeSelection(page)
+
+ def _rasterLegend(self, notebook):
+ panel = scrolled.ScrolledPanel(parent = notebook, id = wx.ID_ANY, size = (-1, 500), style = wx.TAB_TRAVERSAL)
+ panel.SetupScrolling(scroll_x = False, scroll_y = True)
+ notebook.AddPage(page = panel, text = _("Raster legend"))
+
+ border = wx.BoxSizer(wx.VERTICAL)
+ # is legend
+ self.isRLegend = wx.CheckBox(panel, id = wx.ID_ANY, label = _("Show raster legend"))
+ self.isRLegend.SetValue(self.rLegendDict['rLegend'])
+ border.Add(item = self.isRLegend, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ # choose raster
+
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Source raster")))
+ sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ flexSizer = wx.FlexGridSizer (cols = 2, hgap = 5, vgap = 5)
+ flexSizer.AddGrowableCol(1)
+
+ self.rasterDefault = wx.RadioButton(panel, id = wx.ID_ANY, label = _("current raster"), style = wx.RB_GROUP)
+ self.rasterOther = wx.RadioButton(panel, id = wx.ID_ANY, label = _("select raster"))
+ self.rasterDefault.SetValue(self.rLegendDict['rasterDefault'])#
+ self.rasterOther.SetValue(not self.rLegendDict['rasterDefault'])#
+
+ rasterType = self.getRasterType(map = self.currRaster)
+
+ self.rasterCurrent = wx.StaticText(panel, id = wx.ID_ANY, label = _("{0}: type {1}").format(self.currRaster, str(rasterType)))
+ self.rasterSelect = Select( panel, id = wx.ID_ANY, size = globalvar.DIALOG_GSELECT_SIZE,
+ type = 'raster', multiple = False,
+ updateOnPopup = True, onPopup = None)
+ self.rasterSelect.SetValue(self.rLegendDict['raster'] if not self.rLegendDict['rasterDefault'] else '')
+ flexSizer.Add(self.rasterDefault, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ flexSizer.Add(self.rasterCurrent, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.LEFT, border = 10)
+ flexSizer.Add(self.rasterOther, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ flexSizer.Add(self.rasterSelect, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
+
+ sizer.Add(item = flexSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ # type of legend
+
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Type of legend")))
+ sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ vbox = wx.BoxSizer(wx.VERTICAL)
+ self.discrete = wx.RadioButton(parent = panel, id = wx.ID_ANY,
+ label = " {0} ".format(_("discrete legend (categorical maps)")), style = wx.RB_GROUP)
+ self.continuous = wx.RadioButton(parent = panel, id = wx.ID_ANY,
+ label = " {0} ".format(_("continuous color gradient legend (floating point map)")))
+
+ vbox.Add(self.discrete, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 0)
+ vbox.Add(self.continuous, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 0)
+ sizer.Add(item = vbox, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ # size, position and font
+ self.sizePositionFont(legendType = 'raster', parent = panel, mainSizer = border)
+
+ # advanced settings
+
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Advanced legend settings")))
+ sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
+ # no data
+ self.nodata = wx.CheckBox(panel, id = wx.ID_ANY, label = _('draw "no data" box'))
+ self.nodata.SetValue(True if self.rLegendDict['nodata'] == 'y' else False)
+ #tickbar
+ self.ticks = wx.CheckBox(panel, id = wx.ID_ANY, label = _("draw ticks across color table"))
+ self.ticks.SetValue(True if self.rLegendDict['tickbar'] == 'y' else False)
+ # range
+ if self.rasterId and self.instruction[self.rasterId]['raster']:
+ range = RunCommand('r.info', flags = 'r', read = True, map = self.instruction[self.rasterId]['raster']).strip().split('\n')
+ self.minim, self.maxim = range[0].split('=')[1], range[1].split('=')[1]
+ else:
+ self.minim, self.maxim = 0,0
+ self.range = wx.CheckBox(panel, id = wx.ID_ANY, label = _("range"))
+ self.range.SetValue(self.rLegendDict['range'])
+ self.minText = wx.StaticText(panel, id = wx.ID_ANY, label = "{0} ({1})".format(_("min:"),self.minim))
+ self.maxText = wx.StaticText(panel, id = wx.ID_ANY, label = "{0} ({1})".format(_("max:"),self.maxim))
+
+ self.min = wx.TextCtrl(panel, id = wx.ID_ANY, value = str(self.rLegendDict['min']))
+ self.max = wx.TextCtrl(panel, id = wx.ID_ANY, value = str(self.rLegendDict['max']))
+
+ gridBagSizer.Add(self.nodata, pos = (0,0), span = (1,5), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.ticks, pos = (1,0), span = (1,5), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.range, pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.minText, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
+ gridBagSizer.Add(self.min, pos = (2,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.maxText, pos = (2,3), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
+ gridBagSizer.Add(self.max, pos = (2,4), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+ sizer.Add(gridBagSizer, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ panel.SetSizer(border)
+ panel.Fit()
+
+ # bindings
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterDefault)
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterOther)
+ self.Bind(wx.EVT_CHECKBOX, self.OnIsLegend, self.isRLegend)
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnDiscrete, self.discrete)
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnDiscrete, self.continuous)
+ self.Bind(wx.EVT_CHECKBOX, self.OnDefaultSize, panel.defaultSize)
+ self.Bind(wx.EVT_CHECKBOX, self.OnRange, self.range)
+ self.rasterSelect.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnRaster)
+
+ return panel
+
+ def _vectorLegend(self, notebook):
+ panel = scrolled.ScrolledPanel(parent = notebook, id = wx.ID_ANY, size = (-1, 500), style = wx.TAB_TRAVERSAL)
+ panel.SetupScrolling(scroll_x = False, scroll_y = True)
+ notebook.AddPage(page = panel, text = _("Vector legend"))
+
+ border = wx.BoxSizer(wx.VERTICAL)
+ # is legend
+ self.isVLegend = wx.CheckBox(panel, id = wx.ID_ANY, label = _("Show vector legend"))
+ self.isVLegend.SetValue(self.vLegendDict['vLegend'])
+ border.Add(item = self.isVLegend, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ #vector maps, their order, labels
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Source vector maps")))
+ sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
+ gridBagSizer.AddGrowableCol(0,3)
+ gridBagSizer.AddGrowableCol(1,1)
+
+ vectorText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Choose vector maps and their order in legend"))
+
+ self.vectorListCtrl = CheckListCtrl(panel)
+
+ self.vectorListCtrl.InsertColumn(0, _("Vector map"))
+ self.vectorListCtrl.InsertColumn(1, _("Label"))
+ if self.vectorId:
+ vectors = sorted(self.instruction[self.vectorId]['list'], key = lambda x: x[3])
+ for vector in vectors:
+ index = self.vectorListCtrl.InsertStringItem(sys.maxint, vector[0].split('@')[0])
+ self.vectorListCtrl.SetStringItem(index, 1, vector[4])
+ self.vectorListCtrl.SetItemData(index, index)
+ self.vectorListCtrl.CheckItem(index, True)
+ if vector[3] == 0:
+ self.vectorListCtrl.CheckItem(index, False)
+ if not self.vectorId:
+ self.vectorListCtrl.SetColumnWidth(0, 100)
+ else:
+ self.vectorListCtrl.SetColumnWidth(0, wx.LIST_AUTOSIZE)
+ self.vectorListCtrl.SetColumnWidth(1, wx.LIST_AUTOSIZE)
+
+ self.btnUp = wx.Button(panel, id = wx.ID_ANY, label = _("Up"))
+ self.btnDown = wx.Button(panel, id = wx.ID_ANY, label = _("Down"))
+ self.btnLabel = wx.Button(panel, id = wx.ID_ANY, label = _("Edit label"))
+
+
+ gridBagSizer.Add(vectorText, pos = (0,0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.vectorListCtrl, pos = (1,0), span = (3,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+ gridBagSizer.Add(self.btnUp, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.btnDown, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.btnLabel, pos = (3,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+ sizer.Add(gridBagSizer, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ # size, position and font
+ self.sizePositionFont(legendType = 'vector', parent = panel, mainSizer = border)
+
+ # border
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Border")))
+ sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ flexGridSizer = wx.FlexGridSizer(cols = 2, hgap = 5, vgap = 5)
+
+ self.borderCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("draw border around legend"))
+ self.borderColorCtrl = wx.ColourPickerCtrl(panel, id = wx.ID_ANY, style = wx.FNTP_FONTDESC_AS_LABEL)
+ if self.vLegendDict['border'] == 'none':
+ self.borderColorCtrl.SetColour('black')
+ self.borderCheck.SetValue(False)
+ else:
+ self.borderColorCtrl.SetColour(self.vLegendDict['border'])
+ self.borderCheck.SetValue(True)
+
+ flexGridSizer.Add(self.borderCheck, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ flexGridSizer.Add(self.borderColorCtrl, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ sizer.Add(item = flexGridSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ self.Bind(wx.EVT_BUTTON, self.OnUp, self.btnUp)
+ self.Bind(wx.EVT_BUTTON, self.OnDown, self.btnDown)
+ self.Bind(wx.EVT_BUTTON, self.OnEditLabel, self.btnLabel)
+ self.Bind(wx.EVT_CHECKBOX, self.OnIsLegend, self.isVLegend)
+ self.Bind(wx.EVT_CHECKBOX, self.OnSpan, panel.spanRadio)
+ self.Bind(wx.EVT_CHECKBOX, self.OnBorder, self.borderCheck)
+ self.Bind(wx.EVT_FONTPICKER_CHANGED, self.OnFont, panel.font['fontCtrl'])
+
+ panel.SetSizer(border)
+
+ panel.Fit()
+ return panel
+
+ def sizePositionFont(self, legendType, parent, mainSizer):
+ """!Insert widgets for size, position and font control"""
+ legendDict = self.rLegendDict if legendType == 'raster' else self.vLegendDict
+ panel = parent
+ border = mainSizer
+
+ # size and position
+
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Size and position")))
+ sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ #unit
+ self.AddUnits(parent = panel, dialogDict = legendDict)
+ unitBox = wx.BoxSizer(wx.HORIZONTAL)
+ unitBox.Add(panel.units['unitsLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.LEFT, border = 10)
+ unitBox.Add(panel.units['unitsCtrl'], proportion = 1, flag = wx.ALL, border = 5)
+ sizer.Add(unitBox, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+ hBox = wx.BoxSizer(wx.HORIZONTAL)
+ posBox = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Position")))
+ posSizer = wx.StaticBoxSizer(posBox, wx.VERTICAL)
+ sizeBox = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Size")))
+ sizeSizer = wx.StaticBoxSizer(sizeBox, wx.VERTICAL)
+ posGridBagSizer = wx.GridBagSizer(hgap = 10, vgap = 5)
+ posGridBagSizer.AddGrowableRow(2)
+
+ #position
+ self.AddPosition(parent = panel, dialogDict = legendDict)
+
+ posGridBagSizer.Add(panel.position['xLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ posGridBagSizer.Add(panel.position['xCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ posGridBagSizer.Add(panel.position['yLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ posGridBagSizer.Add(panel.position['yCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ posGridBagSizer.Add(panel.position['comment'], pos = (2,0), span = (1,2), flag =wx.ALIGN_BOTTOM, border = 0)
+ posSizer.Add(posGridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+
+ #size
+ width = wx.StaticText(panel, id = wx.ID_ANY, label = _("Width:"))
+ w = self.unitConv.convert(value = float(legendDict['width']), fromUnit = 'inch', toUnit = legendDict['unit'])
+ panel.widthCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, value = str(w), validator = TCValidator("DIGIT_ONLY"))
+
+ if legendType == 'raster':
+ panel.defaultSize = wx.CheckBox(panel, id = wx.ID_ANY, label = _("Use default size"))
+ panel.defaultSize.SetValue(legendDict['defaultSize'])
+
+ panel.heightOrColumnsLabel = wx.StaticText(panel, id = wx.ID_ANY, label = _("Height:"))
+ h = self.unitConv.convert(value = float(legendDict['height']), fromUnit = 'inch', toUnit = legendDict['unit'])
+ panel.heightOrColumnsCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, value = str(h), validator = TCValidator("DIGIT_ONLY"))
+
+ self.rSizeGBSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
+ self.rSizeGBSizer.Add(panel.defaultSize, pos = (0,0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.rSizeGBSizer.Add(width, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.rSizeGBSizer.Add(panel.widthCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.rSizeGBSizer.Add(panel.heightOrColumnsLabel, pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.rSizeGBSizer.Add(panel.heightOrColumnsCtrl, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ sizeSizer.Add(self.rSizeGBSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+
+ if legendType == 'vector':
+ panel.widthCtrl.SetToolTipString(_("Width of the color symbol (for lines)\nin front of the legend text"))
+ #columns
+ minVect, maxVect = 0, 0
+ if self.vectorId:
+ minVect = 1
+ maxVect = min(10, len(self.instruction[self.vectorId]['list']))
+ cols = wx.StaticText(panel, id = wx.ID_ANY, label = _("Columns:"))
+ panel.colsCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, value = "",
+ min = minVect, max = maxVect, initial = legendDict['cols'])
+ #span
+ panel.spanRadio = wx.CheckBox(panel, id = wx.ID_ANY, label = _("column span:"))
+ panel.spanTextCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, value = '')
+ panel.spanTextCtrl.SetToolTipString(_("Column separation distance between the left edges\n"\
+ "of two columns in a multicolumn legend"))
+ if legendDict['span']:
+ panel.spanRadio.SetValue(True)
+ s = self.unitConv.convert(value = float(legendDict['span']), fromUnit = 'inch', toUnit = legendDict['unit'])
+ panel.spanTextCtrl.SetValue(str(s))
+ else:
+ panel.spanRadio.SetValue(False)
+
+ self.vSizeGBSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
+ self.vSizeGBSizer.AddGrowableCol(1)
+ self.vSizeGBSizer.Add(width, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.vSizeGBSizer.Add(panel.widthCtrl, pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.vSizeGBSizer.Add(cols, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.vSizeGBSizer.Add(panel.colsCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.vSizeGBSizer.Add(panel.spanRadio, pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.vSizeGBSizer.Add(panel.spanTextCtrl, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ sizeSizer.Add(self.vSizeGBSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+
+ hBox.Add(posSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 3)
+ hBox.Add(sizeSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 3)
+ sizer.Add(hBox, proportion = 0, flag = wx.EXPAND, border = 0)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+
+ # font
+
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Font settings")))
+ fontSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ flexSizer = wx.FlexGridSizer (cols = 2, hgap = 5, vgap = 5)
+ flexSizer.AddGrowableCol(1)
+
+ if legendType == 'raster':
+ self.AddFont(parent = panel, dialogDict = legendDict, color = True)
+ else:
+ self.AddFont(parent = panel, dialogDict = legendDict, color = False)
+ flexSizer.Add(panel.font['fontLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ flexSizer.Add(panel.font['fontCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ flexSizer.Add(panel.font['fontSizeLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ flexSizer.Add(panel.font['fontSizeCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ if legendType == 'raster':
+ flexSizer.Add(panel.font['colorLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ flexSizer.Add(panel.font['colorCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+ fontSizer.Add(item = flexSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
+ border.Add(item = fontSizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+
+
+
+ # some enable/disable methods
+
+ def OnIsLegend(self, event):
+ """!Enables and disables controls, it depends if raster or vector legend is checked"""
+ page = self.notebook.GetSelection()
+ if page == 0 or event is None:
+ children = self.panelRaster.GetChildren()
+ if self.isRLegend.GetValue():
+ for i,widget in enumerate(children):
+ widget.Enable()
+ self.OnRaster(None)
+ self.OnDefaultSize(None)
+ self.OnRange(None)
+ self.OnDiscrete(None)
+ else:
+ for i,widget in enumerate(children):
+ if i != 0:
+ widget.Disable()
+ if page == 1 or event is None:
+ children = self.panelVector.GetChildren()
+ if self.isVLegend.GetValue():
+ for i, widget in enumerate(children):
+ widget.Enable()
+ self.OnSpan(None)
+ self.OnBorder(None)
+ else:
+ for i, widget in enumerate(children):
+ if i != 0:
+ widget.Disable()
+
+ def OnRaster(self, event):
+ if self.rasterDefault.GetValue():#default
+ self.rasterSelect.Disable()
+ type = self.getRasterType(self.currRaster)
+ else:#select raster
+ self.rasterSelect.Enable()
+ map = self.rasterSelect.GetValue()
+ type = self.getRasterType(map)
+
+ if type == 'CELL':
+ self.discrete.SetValue(True)
+ elif type in ('FCELL', 'DCELL'):
+ self.continuous.SetValue(True)
+ if event is None:
+ if self.rLegendDict['discrete'] == 'y':
+ self.discrete.SetValue(True)
+ elif self.rLegendDict['discrete'] == 'n':
+ self.continuous.SetValue(True)
+ self.OnDiscrete(None)
+
+ def OnDiscrete(self, event):
+ """! Change control according to the type of legend"""
+ enabledSize = self.panelRaster.heightOrColumnsCtrl.IsEnabled()
+ self.panelRaster.heightOrColumnsCtrl.Destroy()
+ if self.discrete.GetValue():
+ self.panelRaster.heightOrColumnsLabel.SetLabel(_("Columns:"))
+ self.panelRaster.heightOrColumnsCtrl = wx.SpinCtrl(self.panelRaster, id = wx.ID_ANY, value = "", min = 1, max = 10, initial = self.rLegendDict['cols'])
+ self.panelRaster.heightOrColumnsCtrl.Enable(enabledSize)
+ self.nodata.Enable()
+ self.range.Disable()
+ self.min.Disable()
+ self.max.Disable()
+ self.minText.Disable()
+ self.maxText.Disable()
+ self.ticks.Disable()
+ else:
+ self.panelRaster.heightOrColumnsLabel.SetLabel(_("Height:"))
+ h = self.unitConv.convert(value = float(self.rLegendDict['height']), fromUnit = 'inch', toUnit = self.rLegendDict['unit'])
+ self.panelRaster.heightOrColumnsCtrl = wx.TextCtrl(self.panelRaster, id = wx.ID_ANY,
+ value = str(h), validator = TCValidator("DIGIT_ONLY"))
+ self.panelRaster.heightOrColumnsCtrl.Enable(enabledSize)
+ self.nodata.Disable()
+ self.range.Enable()
+ if self.range.GetValue():
+ self.minText.Enable()
+ self.maxText.Enable()
+ self.min.Enable()
+ self.max.Enable()
+ self.ticks.Enable()
+
+ self.rSizeGBSizer.Add(self.panelRaster.heightOrColumnsCtrl, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.panelRaster.Layout()
+ self.panelRaster.Fit()
+
+
+ def OnDefaultSize(self, event):
+ if self.panelRaster.defaultSize.GetValue():
+ self.panelRaster.widthCtrl.Disable()
+ self.panelRaster.heightOrColumnsCtrl.Disable()
+ else:
+ self.panelRaster.widthCtrl.Enable()
+ self.panelRaster.heightOrColumnsCtrl.Enable()
+
+ def OnRange(self, event):
+ if not self.range.GetValue():
+ self.min.Disable()
+ self.max.Disable()
+ self.minText.Disable()
+ self.maxText.Disable()
+ else:
+ self.min.Enable()
+ self.max.Enable()
+ self.minText.Enable()
+ self.maxText.Enable()
+
+ def OnUp(self, event):
+ """!Moves selected map up, changes order in vector legend"""
+ if self.vectorListCtrl.GetFirstSelected() != -1:
+ pos = self.vectorListCtrl.GetFirstSelected()
+ if pos:
+ idx1 = self.vectorListCtrl.GetItemData(pos) - 1
+ idx2 = self.vectorListCtrl.GetItemData(pos - 1) + 1
+ self.vectorListCtrl.SetItemData(pos, idx1)
+ self.vectorListCtrl.SetItemData(pos - 1, idx2)
+ self.vectorListCtrl.SortItems(cmp)
+ selected = (pos - 1) if pos > 0 else 0
+ self.vectorListCtrl.Select(selected)
+
+ def OnDown(self, event):
+ """!Moves selected map down, changes order in vector legend"""
+ if self.vectorListCtrl.GetFirstSelected() != -1:
+ pos = self.vectorListCtrl.GetFirstSelected()
+ if pos != self.vectorListCtrl.GetItemCount() - 1:
+ idx1 = self.vectorListCtrl.GetItemData(pos) + 1
+ idx2 = self.vectorListCtrl.GetItemData(pos + 1) - 1
+ self.vectorListCtrl.SetItemData(pos, idx1)
+ self.vectorListCtrl.SetItemData(pos + 1, idx2)
+ self.vectorListCtrl.SortItems(cmp)
+ selected = (pos + 1) if pos < self.vectorListCtrl.GetItemCount() -1 else self.vectorListCtrl.GetItemCount() -1
+ self.vectorListCtrl.Select(selected)
+
+ def OnEditLabel(self, event):
+ """!Change legend label of vector map"""
+ if self.vectorListCtrl.GetFirstSelected() != -1:
+ idx = self.vectorListCtrl.GetFirstSelected()
+ default = self.vectorListCtrl.GetItem(idx, 1).GetText()
+ dlg = wx.TextEntryDialog(self, message = _("Edit legend label:"), caption = _("Edit label"),
+ defaultValue = default, style = wx.OK|wx.CANCEL|wx.CENTRE)
+ if dlg.ShowModal() == wx.ID_OK:
+ new = dlg.GetValue()
+ self.vectorListCtrl.SetStringItem(idx, 1, new)
+ dlg.Destroy()
+
+ def OnSpan(self, event):
+ self.panelVector.spanTextCtrl.Enable(self.panelVector.spanRadio.GetValue())
+ def OnFont(self, event):
+ """!Changes default width according to fontsize, width [inch] = fontsize[pt]/24"""
+## fontsize = self.panelVector.font['fontCtrl'].GetSelectedFont().GetPointSize()
+ fontsize = self.panelVector.font['fontSizeCtrl'].GetValue()
+ unit = self.panelVector.units['unitsCtrl'].GetStringSelection()
+ w = fontsize/24.
+ width = self.unitConv.convert(value = w, fromUnit = 'inch', toUnit = unit)
+ self.panelVector.widthCtrl.SetValue("{0:3.2f}".format(width))
+
+ def OnBorder(self, event):
+ """!Enables/disables colorPickerCtrl for border"""
+ self.borderColorCtrl.Enable(self.borderCheck.GetValue())
+
+ def updateRasterLegend(self):
+ """!Save information from raster legend dialog to dictionary"""
+
+ #is raster legend
+ if not self.isRLegend.GetValue():
+ self.rLegendDict['rLegend'] = False
+ else:
+ self.rLegendDict['rLegend'] = True
+ #units
+ currUnit = self.panelRaster.units['unitsCtrl'].GetStringSelection()
+ self.rLegendDict['unit'] = currUnit
+ # raster
+ if self.rasterDefault.GetValue():
+ self.rLegendDict['rasterDefault'] = True
+ self.rLegendDict['raster'] = self.currRaster
+ else:
+ self.rLegendDict['rasterDefault'] = False
+ self.rLegendDict['raster'] = self.rasterSelect.GetValue()
+ if self.rLegendDict['rLegend'] and not self.rLegendDict['raster']:
+ wx.MessageBox(message = _("No raster map selected!"),
+ caption = _('No raster'), style = wx.OK|wx.ICON_ERROR)
+ return False
+
+ if self.rLegendDict['raster']:
+ # type and range of map
+ rasterType = self.getRasterType(self.rLegendDict['raster'])
+ self.rLegendDict['type'] = rasterType
+
+ range = RunCommand('r.info', flags = 'r', read = True, map = self.rLegendDict['raster']).strip().split('\n')
+ minim, maxim = range[0].split('=')[1], range[1].split('=')[1]
+
+ #discrete
+ if self.discrete.GetValue():
+ self.rLegendDict['discrete'] = 'y'
+ else:
+ self.rLegendDict['discrete'] = 'n'
+
+ # font
+ self.rLegendDict['font'] = self.panelRaster.font['fontCtrl'].GetStringSelection()
+ self.rLegendDict['fontsize'] = self.panelRaster.font['fontSizeCtrl'].GetValue()
+## font = self.panelRaster.font['fontCtrl'].GetSelectedFont()
+## self.rLegendDict['font'] = font.GetFaceName()
+## self.rLegendDict['fontsize'] = font.GetPointSize()
+ self.rLegendDict['color'] = self.panelRaster.font['colorCtrl'].GetColour().GetAsString(wx.C2S_NAME)
+ dc = wx.PaintDC(self)
+ font = dc.GetFont()
+ dc.SetFont(wx.Font( pointSize = self.rLegendDict['fontsize'], family = font.GetFamily(),
+ style = font.GetStyle(), weight = wx.FONTWEIGHT_NORMAL))
+ # position
+ x = self.unitConv.convert(value = float(self.panelRaster.position['xCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
+ y = self.unitConv.convert(value = float(self.panelRaster.position['yCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
+ self.rLegendDict['where'] = (x, y)
+ # estimated size
+ if not self.panelRaster.defaultSize.GetValue():
+ self.rLegendDict['defaultSize'] = False
+
+ width = self.unitConv.convert(value = float(self.panelRaster.widthCtrl.GetValue()), fromUnit = currUnit, toUnit = 'inch')
+ height = self.unitConv.convert(value = float(self.panelRaster.heightOrColumnsCtrl.GetValue()), fromUnit = currUnit, toUnit = 'inch')
+
+ if self.rLegendDict['discrete'] == 'n': #rasterType in ('FCELL', 'DCELL'):
+ self.rLegendDict['width'] = width
+ self.rLegendDict['height'] = height
+ textPart = self.unitConv.convert(value = dc.GetTextExtent(maxim)[0], fromUnit = 'pixel', toUnit = 'inch')
+ drawWidth = width + textPart
+ drawHeight = height
+ self.rLegendDict['rect'] = wx.Rect2D(x = x, y = y, w = drawWidth, h = drawHeight)
+ else: #categorical map
+ self.rLegendDict['width'] = width
+ self.rLegendDict['cols'] = self.panelRaster.heightOrColumnsCtrl.GetValue()
+ cat = RunCommand( 'r.category', read = True, map = self.rLegendDict['raster'],
+ fs = ':').strip().split('\n')
+ rows = ceil(float(len(cat))/self.rLegendDict['cols'])
+
+ drawHeight = self.unitConv.convert(value = 1.5 *rows * self.rLegendDict['fontsize'], fromUnit = 'point', toUnit = 'inch')
+ self.rLegendDict['rect'] = wx.Rect2D(x = x, y = y, w = width, h = drawHeight)
+
+ else:
+ self.rLegendDict['defaultSize'] = True
+ if self.rLegendDict['discrete'] == 'n': #rasterType in ('FCELL', 'DCELL'):
+ textPart = self.unitConv.convert(value = dc.GetTextExtent(maxim)[0], fromUnit = 'pixel', toUnit = 'inch')
+ drawWidth = self.unitConv.convert( value = self.rLegendDict['fontsize'] * 2,
+ fromUnit = 'point', toUnit = 'inch') + textPart
+
+ drawHeight = self.unitConv.convert(value = self.rLegendDict['fontsize'] * 10,
+ fromUnit = 'point', toUnit = 'inch')
+ self.rLegendDict['rect'] = wx.Rect2D(x = x, y = y, w = drawWidth, h = drawHeight)
+ else:#categorical map
+ self.rLegendDict['cols'] = self.panelRaster.heightOrColumnsCtrl.GetValue()
+ cat = RunCommand( 'r.category', read = True, map = self.rLegendDict['raster'],
+ fs = ':').strip().split('\n')
+ if len(cat) == 1:# for discrete FCELL
+ rows = float(maxim)
+ else:
+ rows = ceil(float(len(cat))/self.rLegendDict['cols'])
+ drawHeight = self.unitConv.convert(value = 1.5 *rows * self.rLegendDict['fontsize'],
+ fromUnit = 'point', toUnit = 'inch')
+ paperWidth = self.instruction[self.pageId]['Width']- self.instruction[self.pageId]['Right']\
+ - self.instruction[self.pageId]['Left']
+ drawWidth = (paperWidth / self.rLegendDict['cols']) * (self.rLegendDict['cols'] - 1) + 1
+ self.rLegendDict['rect'] = wx.Rect2D(x = x, y = y, w = drawWidth, h = drawHeight)
+
+
+
+ # no data
+ if self.rLegendDict['discrete'] == 'y':
+ if self.nodata.GetValue():
+ self.rLegendDict['nodata'] = 'y'
+ else:
+ self.rLegendDict['nodata'] = 'n'
+ # tickbar
+ elif self.rLegendDict['discrete'] == 'n':
+ if self.ticks.GetValue():
+ self.rLegendDict['tickbar'] = 'y'
+ else:
+ self.rLegendDict['tickbar'] = 'n'
+ # range
+ if self.range.GetValue():
+ self.rLegendDict['range'] = True
+ self.rLegendDict['min'] = self.min.GetValue()
+ self.rLegendDict['max'] = self.max.GetValue()
+ else:
+ self.rLegendDict['range'] = False
+
+ if not self.id[0] in self.instruction:
+ rasterLegend = RasterLegend(self.id[0])
+ self.instruction.AddInstruction(rasterLegend)
+ self.instruction[self.id[0]].SetInstruction(self.rLegendDict)
+
+ if self.id[0] not in self.parent.objectId:
+ self.parent.objectId.append(self.id[0])
+ return True
+
+ def updateVectorLegend(self):
+ """!Save information from vector legend dialog to dictionary"""
+
+ #is vector legend
+ if not self.isVLegend.GetValue():
+ self.vLegendDict['vLegend'] = False
+ else:
+ self.vLegendDict['vLegend'] = True
+ if self.vLegendDict['vLegend'] == True and self.vectorId is not None:
+ # labels
+ #reindex order
+ idx = 1
+ for item in range(self.vectorListCtrl.GetItemCount()):
+ if self.vectorListCtrl.IsChecked(item):
+ self.vectorListCtrl.SetItemData(item, idx)
+ idx += 1
+ else:
+ self.vectorListCtrl.SetItemData(item, 0)
+ if idx == 1:
+ self.vLegendDict['vLegend'] = False
+ else:
+ vList = self.instruction[self.vectorId]['list']
+ for i, vector in enumerate(vList):
+ item = self.vectorListCtrl.FindItem(start = -1, str = vector[0].split('@')[0])
+ vList[i][3] = self.vectorListCtrl.GetItemData(item)
+ vList[i][4] = self.vectorListCtrl.GetItem(item, 1).GetText()
+ vmaps = self.instruction.FindInstructionByType('vProperties', list = True)
+ for vmap, vector in zip(vmaps, vList):
+ self.instruction[vmap.id]['lpos'] = vector[3]
+ self.instruction[vmap.id]['label'] = vector[4]
+ #units
+ currUnit = self.panelVector.units['unitsCtrl'].GetStringSelection()
+ self.vLegendDict['unit'] = currUnit
+ # position
+ x = self.unitConv.convert(value = float(self.panelVector.position['xCtrl'].GetValue()),
+ fromUnit = currUnit, toUnit = 'inch')
+ y = self.unitConv.convert(value = float(self.panelVector.position['yCtrl'].GetValue()),
+ fromUnit = currUnit, toUnit = 'inch')
+ self.vLegendDict['where'] = (x, y)
+
+ # font
+ self.vLegendDict['font'] = self.panelVector.font['fontCtrl'].GetStringSelection()
+ self.vLegendDict['fontsize'] = self.panelVector.font['fontSizeCtrl'].GetValue()
+## self.vLegendDict['font'] = font.GetFaceName()
+## self.vLegendDict['fontsize'] = font.GetPointSize()
+ dc = wx.PaintDC(self)
+ font = dc.GetFont()
+ dc.SetFont(wx.Font( pointSize = self.vLegendDict['fontsize'], family = font.GetFamily(),
+ style = font.GetStyle(), weight = wx.FONTWEIGHT_NORMAL))
+ #size
+ width = self.unitConv.convert(value = float(self.panelVector.widthCtrl.GetValue()),
+ fromUnit = currUnit, toUnit = 'inch')
+ self.vLegendDict['width'] = width
+ self.vLegendDict['cols'] = self.panelVector.colsCtrl.GetValue()
+ if self.panelVector.spanRadio.GetValue() and self.panelVector.spanTextCtrl.GetValue():
+ self.vLegendDict['span'] = self.panelVector.spanTextCtrl.GetValue()
+ else:
+ self.vLegendDict['span'] = None
+
+ # size estimation
+ vectors = self.instruction[self.vectorId]['list']
+ labels = [vector[4] for vector in vectors if vector[3] != 0]
+ extent = dc.GetTextExtent(max(labels, key = len))
+ wExtent = self.unitConv.convert(value = extent[0], fromUnit = 'pixel', toUnit = 'inch')
+ hExtent = self.unitConv.convert(value = extent[1], fromUnit = 'pixel', toUnit = 'inch')
+ w = (width + wExtent) * self.vLegendDict['cols']
+ h = len(labels) * hExtent / self.vLegendDict['cols']
+ h *= 1.1
+ self.vLegendDict['rect'] = wx.Rect2D(x, y, w, h)
+
+ #border
+ if self.borderCheck.GetValue():
+ self.vLegendDict['border'] = self.borderColorCtrl.GetColour().GetAsString(flags=wx.C2S_NAME)
+ else:
+ self.vLegendDict['border'] = 'none'
+
+ if not self.id[1] in self.instruction:
+ vectorLegend = VectorLegend(self.id[1])
+ self.instruction.AddInstruction(vectorLegend)
+ self.instruction[self.id[1]].SetInstruction(self.vLegendDict)
+ if self.id[1] not in self.parent.objectId:
+ self.parent.objectId.append(self.id[1])
+ return True
+
+ def update(self):
+ okR = self.updateRasterLegend()
+ okV = self.updateVectorLegend()
+ if okR and okV:
+ return True
+ return False
+
+ def getRasterType(self, map):
+ rasterType = RunCommand('r.info', flags = 't', read = True,
+ map = map).strip().split('=')
+ return (rasterType[1] if rasterType[0] else None)
+
+
+
+class MapinfoDialog(PsmapDialog):
+ def __init__(self, parent, id, settings):
+ PsmapDialog.__init__(self, parent = parent, id = id, title = "Mapinfo settings", settings = settings)
+ self.instruction = settings
+ if self.id is not None:
+ self.mapinfoDict = self.instruction[id].GetInstruction()
+ else:
+ self.id = wx.NewId()
+ mapinfo = Mapinfo(self.id)
+
+ self.mapinfoDict = mapinfo.GetInstruction()
+ page = self.instruction.FindInstructionByType('page').GetInstruction()
+ self.mapinfoDict['where'] = page['Left'], page['Top']
+
+ self.panel = self._mapinfoPanel()
+
+ self._layout(self.panel)
+ self.OnIsBackground(None)
+ self.OnIsBorder(None)
+
+
+ def _mapinfoPanel(self):
+ panel = wx.Panel(parent = self, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
+ #panel.SetupScrolling(scroll_x = False, scroll_y = True)
+ border = wx.BoxSizer(wx.VERTICAL)
+
+
+ # position
+
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Position")))
+ sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
+ gridBagSizer.AddGrowableCol(1)
+
+ self.AddPosition(parent = panel, dialogDict = self.mapinfoDict)
+ self.AddUnits(parent = panel, dialogDict = self.mapinfoDict)
+ gridBagSizer.Add(panel.units['unitsLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(panel.units['unitsCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(panel.position['xLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(panel.position['xCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(panel.position['yLabel'], pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(panel.position['yCtrl'], pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(panel.position['comment'], pos = (3,0), span = (1,2), flag =wx.ALIGN_BOTTOM, border = 0)
+
+ sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ # font
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Font settings")))
+ sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
+ gridBagSizer.AddGrowableCol(1)
+
+ self.AddFont(parent = panel, dialogDict = self.mapinfoDict)#creates font color too, used below
+
+## gridBagSizer.Add(panel.font['fontLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+## gridBagSizer.Add(panel.font['fontCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+## gridBagSizer.Add(panel.font['colorLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+## gridBagSizer.Add(panel.font['colorCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+ gridBagSizer.Add(panel.font['fontLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(panel.font['fontCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(panel.font['fontSizeLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(panel.font['fontSizeCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(panel.font['colorLabel'], pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(panel.font['colorCtrl'], pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+ sizer.Add(item = gridBagSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ # colors
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Color settings")))
+ sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ flexSizer = wx.FlexGridSizer (cols = 2, hgap = 5, vgap = 5)
+ flexSizer.AddGrowableCol(1)
+
+ self.colors = {}
+ self.colors['borderCtrl'] = wx.CheckBox(panel, id = wx.ID_ANY, label = _("use border color:"))
+ self.colors['backgroundCtrl'] = wx.CheckBox(panel, id = wx.ID_ANY, label = _("use background color:"))
+ self.colors['borderColor'] = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
+ self.colors['backgroundColor'] = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
+
+ self.colors['borderCtrl'].SetValue(True if self.mapinfoDict['border'] != 'none' else False)
+ self.colors['backgroundCtrl'].SetValue(True if self.mapinfoDict['background'] != 'none' else False)
+ self.colors['borderColor'].SetColour(self.mapinfoDict['border']
+ if self.mapinfoDict['border'] != 'none' else 'black')
+## self.colors['borderColor'].SetColour(convertRGB(self.mapinfoDict['border'])
+## if self.mapinfoDict['border'] != 'none' else 'black')
+ self.colors['backgroundColor'].SetColour(self.mapinfoDict['background']
+ if self.mapinfoDict['background'] != 'none' else 'black')
+## self.colors['backgroundColor'].SetColour(convertRGB(self.mapinfoDict['background'])
+## if self.mapinfoDict['background'] != 'none' else 'black')
+
+ flexSizer.Add(self.colors['borderCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ flexSizer.Add(self.colors['borderColor'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ flexSizer.Add(self.colors['backgroundCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ flexSizer.Add(self.colors['backgroundColor'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+ sizer.Add(item = flexSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ panel.SetSizer(border)
+
+
+ self.Bind(wx.EVT_CHECKBOX, self.OnIsBorder, self.colors['borderCtrl'])
+ self.Bind(wx.EVT_CHECKBOX, self.OnIsBackground, self.colors['backgroundCtrl'])
+
+ return panel
+
+ def OnIsBackground(self, event):
+ if self.colors['backgroundCtrl'].GetValue():
+ self.colors['backgroundColor'].Enable()
+ else:
+ self.colors['backgroundColor'].Disable()
+
+ def OnIsBorder(self, event):
+ if self.colors['borderCtrl'].GetValue():
+ self.colors['borderColor'].Enable()
+ else:
+ self.colors['borderColor'].Disable()
+
+
+ def update(self):
+
+ #units
+ currUnit = self.panel.units['unitsCtrl'].GetStringSelection()
+ self.mapinfoDict['unit'] = currUnit
+ # position
+ x = self.panel.position['xCtrl'].GetValue() if self.panel.position['xCtrl'].GetValue() else self.mapinfoDict['where'][0]
+ y = self.panel.position['yCtrl'].GetValue() if self.panel.position['yCtrl'].GetValue() else self.mapinfoDict['where'][1]
+ x = self.unitConv.convert(value = float(self.panel.position['xCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
+ y = self.unitConv.convert(value = float(self.panel.position['yCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
+ self.mapinfoDict['where'] = (x, y)
+ # font
+ self.mapinfoDict['font'] = font = self.panel.font['fontCtrl'].GetStringSelection()
+ self.mapinfoDict['fontsize'] = self.panel.font['fontSizeCtrl'].GetValue()
+## font = self.panel.font['fontCtrl'].GetSelectedFont()
+## self.mapinfoDict['font'] = font.GetFaceName()
+## self.mapinfoDict['fontsize'] = font.GetPointSize()
+ #colors
+ self.mapinfoDict['color'] = self.panel.font['colorCtrl'].GetColour().GetAsString(flags=wx.C2S_NAME)
+ self.mapinfoDict['background'] = self.colors['backgroundColor'].GetColour().GetAsString(flags=wx.C2S_NAME)\
+ if self.colors['backgroundCtrl'].GetValue() else 'none'
+## self.mapinfoDict['background'] = (convertRGB(self.colors['backgroundColor'].GetColour())
+## if self.colors['backgroundCtrl'].GetValue() else 'none')
+ self.mapinfoDict['border'] = self.colors['borderColor'].GetColour().GetAsString(flags=wx.C2S_NAME)\
+ if self.colors['borderCtrl'].GetValue() else 'none'
+## self.mapinfoDict['border'] = (convertRGB(self.colors['borderColor'].GetColour())
+## if self.colors['borderCtrl'].GetValue() else 'none')
+
+ # estimation of size
+ w = self.mapinfoDict['fontsize'] * 20 # any better estimation?
+ h = self.mapinfoDict['fontsize'] * 7
+ width = self.unitConv.convert(value = w, fromUnit = 'point', toUnit = 'inch')
+ height = self.unitConv.convert(value = h, fromUnit = 'point', toUnit = 'inch')
+ self.mapinfoDict['rect'] = wx.Rect2D(x = x, y = y, w = width, h = height)
+
+ if self.id not in self.instruction:
+ mapinfo = Mapinfo(self.id)
+ self.instruction.AddInstruction(mapinfo)
+ self.instruction[self.id].SetInstruction(self.mapinfoDict)
+
+ if self.id not in self.parent.objectId:
+ self.parent.objectId.append(self.id)
+
+ return True
+
+
+class ScalebarDialog(PsmapDialog):
+ """!Dialog for scale bar"""
+ def __init__(self, parent, id, settings):
+ PsmapDialog.__init__(self, parent = parent, id = id, title = "Scale bar settings", settings = settings)
+ self.instruction = settings
+ if self.id is not None:
+ self.scalebarDict = self.instruction[id].GetInstruction()
+ else:
+ self.id = wx.NewId()
+ scalebar = Scalebar(self.id)
+ self.scalebarDict = scalebar.GetInstruction()
+ page = self.instruction.FindInstructionByType('page').GetInstruction()
+ self.scalebarDict['where'] = page['Left'], page['Top']
+
+
+
+ self.panel = self._scalebarPanel()
+
+ self._layout(self.panel)
+
+ self.mapUnit = projInfo()['units']
+ if projInfo()['proj'] == 'xy':
+ self.mapUnit = 'meters'
+ if self.mapUnit not in self.unitConv.getAllUnits():
+ wx.MessageBox(message = _("Units of current projection are not supported,\n meters will be used!"),
+ caption = _('Unsupported units'),
+ style = wx.OK|wx.ICON_ERROR)
+ self.mapUnit = 'meters'
+
+ def _scalebarPanel(self):
+ panel = wx.Panel(parent = self, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
+ border = wx.BoxSizer(wx.VERTICAL)
+ #
+ # position
+ #
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Position")))
+ sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
+ gridBagSizer.AddGrowableCol(1)
+
+ self.AddUnits(parent = panel, dialogDict = self.scalebarDict)
+ self.AddPosition(parent = panel, dialogDict = self.scalebarDict)
+
+ if self.scalebarDict['rect']: # set position, ref point is center and not left top corner
+
+ x = self.unitConv.convert(value = self.scalebarDict['where'][0] - self.scalebarDict['rect'].Get()[2]/2,
+ fromUnit = 'inch', toUnit = self.scalebarDict['unit'])
+ y = self.unitConv.convert(value = self.scalebarDict['where'][1] - self.scalebarDict['rect'].Get()[3]/2,
+ fromUnit = 'inch', toUnit = self.scalebarDict['unit'])
+ panel.position['xCtrl'].SetValue("{0:5.3f}".format(x))
+ panel.position['yCtrl'].SetValue("{0:5.3f}".format(y))
+
+ gridBagSizer.Add(panel.units['unitsLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(panel.units['unitsCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(panel.position['xLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(panel.position['xCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(panel.position['yLabel'], pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(panel.position['yCtrl'], pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(panel.position['comment'], pos = (3,0), span = (1,2), flag =wx.ALIGN_BOTTOM, border = 0)
+
+ sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+ #
+ # size
+ #
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Size")))
+ sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
+ gridBagSizer.AddGrowableCol(1)
+
+ lengthText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Length:"))
+ heightText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Height:"))
+
+ self.lengthTextCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, validator = TCValidator('DIGIT_ONLY'))
+ self.lengthTextCtrl.SetToolTipString(_("Scalebar length is given in map units"))
+
+ self.heightTextCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, validator = TCValidator('DIGIT_ONLY'))
+ self.heightTextCtrl.SetToolTipString(_("Scalebar height is real height on paper"))
+
+ choices = ['default'] + self.unitConv.getMapUnits()
+ self.unitsLength = wx.Choice(panel, id = wx.ID_ANY, choices = choices)
+ choices = self.unitConv.getPageUnits()
+ self.unitsHeight = wx.Choice(panel, id = wx.ID_ANY, choices = choices)
+
+ # set values
+ ok = self.unitsLength.SetStringSelection(self.scalebarDict['unitsLength'])
+ if not ok:
+ if self.scalebarDict['unitsLength'] == 'auto':
+ self.unitsLength.SetSelection(0)
+ elif self.scalebarDict['unitsLength'] == 'nautmiles':
+ self.unitsLength.SetStringSelection("nautical miles")
+ self.unitsHeight.SetStringSelection(self.scalebarDict['unitsHeight'])
+ if self.scalebarDict['length']:
+ self.lengthTextCtrl.SetValue(str(self.scalebarDict['length']))
+ else: #estimate default
+ reg = grass.region()
+ w = int((reg['e'] - reg['w'])/3)
+ w = round(w, -len(str(w)) + 2) #12345 -> 12000
+ self.lengthTextCtrl.SetValue(str(w))
+
+ h = self.unitConv.convert(value = self.scalebarDict['height'], fromUnit = 'inch',
+ toUnit = self.scalebarDict['unitsHeight'])
+ self.heightTextCtrl.SetValue(str(h))
+
+ gridBagSizer.Add(lengthText, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.lengthTextCtrl, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.unitsLength, pos = (0, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+ gridBagSizer.Add(heightText, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.heightTextCtrl, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.unitsHeight, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+
+
+ sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+ #
+ #style
+ #
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Style")))
+ sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
+
+
+ sbTypeText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Type:"))
+ self.sbCombo = wx.combo.BitmapComboBox(panel, style = wx.CB_READONLY)
+ # only temporary, images must be moved away
+ imagePath = os.path.join(globalvar.ETCIMGDIR, "scalebar-fancy.png"), os.path.join(globalvar.ETCIMGDIR, "scalebar-simple.png")
+ for item, path in zip(['fancy', 'simple'], imagePath):
+ if not os.path.exists(path):
+ bitmap = wx.EmptyBitmap(0,0)
+ else:
+ bitmap = wx.Bitmap(path)
+ self.sbCombo.Append(item = item, bitmap = bitmap, clientData = item[0])
+ #self.sbCombo.Append(item = 'simple', bitmap = wx.Bitmap("./images/scalebar-simple.png"), clientData = 's')
+ if self.scalebarDict['scalebar'] == 'f':
+ self.sbCombo.SetSelection(0)
+ elif self.scalebarDict['scalebar'] == 's':
+ self.sbCombo.SetSelection(1)
+
+ sbSegmentsText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Number of segments:"))
+ self.sbSegmentsCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 30, initial = 4)
+ self.sbSegmentsCtrl.SetValue(self.scalebarDict['segment'])
+
+ sbLabelsText1 = wx.StaticText(panel, id = wx.ID_ANY, label = _("Label every "))
+ sbLabelsText2 = wx.StaticText(panel, id = wx.ID_ANY, label = _("segments"))
+ self.sbLabelsCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 30, initial = 1)
+ self.sbLabelsCtrl.SetValue(self.scalebarDict['numbers'])
+
+ #font
+ fontsizeText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Font size:"))
+ self.fontsizeCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 4, max = 30, initial = 10)
+ self.fontsizeCtrl.SetValue(self.scalebarDict['fontsize'])
+
+ self.backgroundCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("transparent text background"))
+ self.backgroundCheck.SetValue(False if self.scalebarDict['background'] == 'y' else True)
+
+
+ gridBagSizer.Add(sbTypeText, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.sbCombo, pos = (0,1), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
+ gridBagSizer.Add(sbSegmentsText, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.sbSegmentsCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(sbLabelsText1, pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.sbLabelsCtrl, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(sbLabelsText2, pos = (2,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(fontsizeText, pos = (3,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.fontsizeCtrl, pos = (3,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.backgroundCheck, pos = (4, 0), span = (1,3), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+ sizer.Add(gridBagSizer, proportion = 1, flag = wx.ALIGN_CENTER_VERTICAL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ panel.SetSizer(border)
+
+ return panel
+
+
+
+ def update(self):
+ """!Save information from dialog"""
+
+ #units
+ currUnit = self.panel.units['unitsCtrl'].GetStringSelection()
+ self.scalebarDict['unit'] = currUnit
+ # position
+ x = self.panel.position['xCtrl'].GetValue() if self.panel.position['xCtrl'].GetValue() else self.scalebarDict['where'][0]
+ y = self.panel.position['yCtrl'].GetValue() if self.panel.position['yCtrl'].GetValue() else self.scalebarDict['where'][1]
+ x = self.unitConv.convert(value = float(self.panel.position['xCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
+ y = self.unitConv.convert(value = float(self.panel.position['yCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
+
+
+ # size
+
+ # height
+ self.scalebarDict['unitsHeight'] = self.unitsHeight.GetStringSelection()
+ try:
+ height = float(self.heightTextCtrl.GetValue())
+ height = self.unitConv.convert(value = height, fromUnit = self.scalebarDict['unitsHeight'], toUnit = 'inch')
+ except (ValueError, SyntaxError):
+ height = 0.1 #default in inch
+ self.scalebarDict['height'] = height
+
+ #length
+ selected = self.unitsLength.GetStringSelection()
+ if selected == 'default':
+ selected = 'auto'
+ elif selected == 'nautical miles':
+ selected = 'nautmiles'
+ self.scalebarDict['unitsLength'] = selected
+ try:
+ length = float(self.lengthTextCtrl.GetValue())
+ except (ValueError, SyntaxError):
+ wx.MessageBox(message = _("Length of scale bar is not defined"),
+ caption = _('Invalid input'), style = wx.OK|wx.ICON_ERROR)
+ return False
+ self.scalebarDict['length'] = length
+
+ if self.scalebarDict['unitsLength'] != 'auto':
+ length = self.unitConv.convert(value = length, fromUnit = self.unitsLength.GetStringSelection(), toUnit = 'inch')
+ else:
+ length = self.unitConv.convert(value = length, fromUnit = self.mapUnit, toUnit = 'inch')
+ # estimation of size
+ map = self.instruction.FindInstructionByType('map')
+ if not map:
+ map = self.instruction.FindInstructionByType('initMap')
+ mapId = map.id
+
+ length *= self.instruction[mapId]['scale']
+ length *= 1.1 #for numbers on the edge
+ fontsize = 10
+ height = height + 2 * self.unitConv.convert(value = fontsize, fromUnit = 'point', toUnit = 'inch')
+ self.scalebarDict['rect'] = wx.Rect2D(x, y, length, height)
+
+
+ self.scalebarDict['where'] = self.scalebarDict['rect'].GetCentre()
+
+ #style
+ self.scalebarDict['scalebar'] = self.sbCombo.GetClientData(self.sbCombo.GetSelection())
+ self.scalebarDict['segment'] = self.sbSegmentsCtrl.GetValue()
+ self.scalebarDict['numbers'] = self.sbLabelsCtrl.GetValue()
+ self.scalebarDict['fontsize'] = self.fontsizeCtrl.GetValue()
+ self.scalebarDict['background'] = 'n' if self.backgroundCheck.GetValue() else 'y'
+
+
+ if self.id not in self.instruction:
+ scalebar = Scalebar(self.id)
+ self.instruction.AddInstruction(scalebar)
+ self.instruction[self.id].SetInstruction(self.scalebarDict)
+ if self.id not in self.parent.objectId:
+ self.parent.objectId.append(self.id)
+
+ return True
+
+
+class TextDialog(PsmapDialog):
+ def __init__(self, parent, id, settings):
+ PsmapDialog.__init__(self, parent = parent, id = id, title = "Text settings", settings = settings)
+
+ if self.id is not None:
+ self.textDict = self.instruction[id].GetInstruction()
+ else:
+ self.id = wx.NewId()
+ text = Text(self.id)
+ self.textDict = text.GetInstruction()
+ page = self.instruction.FindInstructionByType('page').GetInstruction()
+ self.textDict['where'] = page['Left'], page['Top']
+
+ map = self.instruction.FindInstructionByType('map')
+ if not map:
+ map = self.instruction.FindInstructionByType('initMap')
+ self.mapId = map.id
+
+
+ self.textDict['east'], self.textDict['north'] = PaperMapCoordinates(self, mapId = self.mapId, x = self.textDict['where'][0], y = self.textDict['where'][1], paperToMap = True)
+
+ notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT)
+ self.textPanel = self._textPanel(notebook)
+ self.positionPanel = self._positionPanel(notebook)
+ self.OnBackground(None)
+ self.OnHighlight(None)
+ self.OnBorder(None)
+ self.OnPositionType(None)
+ self.OnRotation(None)
+
+ self._layout(notebook)
+
+ def _textPanel(self, notebook):
+ panel = wx.Panel(parent = notebook, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
+ notebook.AddPage(page = panel, text = _("Text"))
+
+ border = wx.BoxSizer(wx.VERTICAL)
+
+ # text entry
+
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Text")))
+ sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+
+ textLabel = wx.StaticText(panel, id = wx.ID_ANY, label = _("Enter text:"))
+ self.textCtrl = ExpandoTextCtrl(panel, id = wx.ID_ANY, value = self.textDict['text'])
+
+ sizer.Add(textLabel, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
+ sizer.Add(self.textCtrl, proportion = 1, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+
+ #font
+
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Font settings")))
+ sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ flexGridSizer = wx.FlexGridSizer (rows = 3, cols = 2, hgap = 5, vgap = 5)
+ flexGridSizer.AddGrowableCol(1)
+
+ self.AddFont(parent = panel, dialogDict = self.textDict)
+
+ flexGridSizer.Add(panel.font['fontLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ flexGridSizer.Add(panel.font['fontCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ flexGridSizer.Add(panel.font['fontSizeLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ flexGridSizer.Add(panel.font['fontSizeCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ flexGridSizer.Add(panel.font['colorLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ flexGridSizer.Add(panel.font['colorCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+ sizer.Add(item = flexGridSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ #text effects
+
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Text effects")))
+ sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
+
+ self.effect = {}
+ self.effect['backgroundCtrl'] = wx.CheckBox(panel, id = wx.ID_ANY, label = _("text background"))
+ self.effect['backgroundColor'] = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
+
+ self.effect['highlightCtrl'] = wx.CheckBox(panel, id = wx.ID_ANY, label = _("highlight"))
+ self.effect['highlightColor'] = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
+ self.effect['highlightWidth'] = wx.SpinCtrl(panel, id = wx.ID_ANY, size = self.spinCtrlSize, value = 'pts',min = 0, max = 5, initial = 1)
+ self.effect['highlightWidthLabel'] = wx.StaticText(panel, id = wx.ID_ANY, label = _("Width (pts):"))
+
+ self.effect['borderCtrl'] = wx.CheckBox(panel, id = wx.ID_ANY, label = _("text border"))
+ self.effect['borderColor'] = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
+ self.effect['borderWidth'] = wx.SpinCtrl(panel, id = wx.ID_ANY, size = self.spinCtrlSize, value = 'pts',min = 1, max = 25, initial = 1)
+ self.effect['borderWidthLabel'] = wx.StaticText(panel, id = wx.ID_ANY, label = _("Width (pts):"))
+ #set values
+ self.effect['backgroundCtrl'].SetValue(True if self.textDict['background'] != 'none' else False)
+ self.effect['backgroundColor'].SetColour(convertRGB(self.textDict['background'])
+ if self.textDict['background'] != 'none' else 'white')
+ self.effect['highlightCtrl'].SetValue(True if self.textDict['hcolor'] != 'none' else False)
+ self.effect['highlightColor'].SetColour(convertRGB(self.textDict['hcolor'])
+ if self.textDict['hcolor'] != 'none' else 'grey')
+ self.effect['highlightWidth'].SetValue(float(self.textDict['hwidth']))
+ self.effect['borderCtrl'].SetValue(True if self.textDict['border'] != 'none' else False)
+ self.effect['borderColor'].SetColour(convertRGB(self.textDict['border'])
+ if self.textDict['border'] != 'none' else 'black')
+ self.effect['borderWidth'].SetValue(float(self.textDict['width']))
+
+ gridBagSizer.Add(self.effect['backgroundCtrl'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.effect['backgroundColor'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.effect['highlightCtrl'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.effect['highlightColor'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.effect['highlightWidthLabel'], pos = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.effect['highlightWidth'], pos = (1,3), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.effect['borderCtrl'], pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.effect['borderColor'], pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.effect['borderWidthLabel'], pos = (2,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizer.Add(self.effect['borderWidth'], pos = (2,3), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+ sizer.Add(item = gridBagSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ self.Bind(EVT_ETC_LAYOUT_NEEDED, self.OnRefit, self.textCtrl)
+ self.Bind(wx.EVT_CHECKBOX, self.OnBackground, self.effect['backgroundCtrl'])
+ self.Bind(wx.EVT_CHECKBOX, self.OnHighlight, self.effect['highlightCtrl'])
+ self.Bind(wx.EVT_CHECKBOX, self.OnBorder, self.effect['borderCtrl'])
+
+ panel.SetSizer(border)
+ panel.Fit()
+ return panel
+
+ def _positionPanel(self, notebook):
+ panel = wx.Panel(parent = notebook, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
+ notebook.AddPage(page = panel, text = _("Position"))
+
+ border = wx.BoxSizer(wx.VERTICAL)
+
+ #Position
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Position")))
+ sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+ gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
+ gridBagSizer.AddGrowableCol(0)
+ gridBagSizer.AddGrowableCol(1)
+
+ self.positionLabel = wx.StaticText(panel, id = wx.ID_ANY, label = _("Position is given:"))
+ self.paperPositionCtrl = wx.RadioButton(panel, id = wx.ID_ANY, label = _("relatively to paper"), style = wx.RB_GROUP)
+ self.mapPositionCtrl = wx.RadioButton(panel, id = wx.ID_ANY, label = _("by map coordinates"))
+ self.paperPositionCtrl.SetValue(self.textDict['XY'])
+ self.mapPositionCtrl.SetValue(not self.textDict['XY'])
+
+ gridBagSizer.Add(self.positionLabel, pos = (0,0), span = (1,3), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT, border = 0)
+ gridBagSizer.Add(self.paperPositionCtrl, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT, border = 0)
+ gridBagSizer.Add(self.mapPositionCtrl, pos = (1,1),flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT, border = 0)
+
+ # first box - paper coordinates
+ box1 = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = "")
+ sizerP = wx.StaticBoxSizer(box1, wx.VERTICAL)
+ self.gridBagSizerP = wx.GridBagSizer (hgap = 5, vgap = 5)
+ self.gridBagSizerP.AddGrowableCol(1)
+ self.gridBagSizerP.AddGrowableRow(3)
+
+ self.AddPosition(parent = panel, dialogDict = self.textDict)
+ panel.position['comment'].SetLabel(_("Position from the top left\nedge of the paper"))
+ self.AddUnits(parent = panel, dialogDict = self.textDict)
+ self.gridBagSizerP.Add(panel.units['unitsLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerP.Add(panel.units['unitsCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerP.Add(panel.position['xLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerP.Add(panel.position['xCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerP.Add(panel.position['yLabel'], pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerP.Add(panel.position['yCtrl'], pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerP.Add(panel.position['comment'], pos = (3,0), span = (1,2), flag = wx.ALIGN_BOTTOM, border = 0)
+
+
+ sizerP.Add(self.gridBagSizerP, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ gridBagSizer.Add(sizerP, pos = (2,0),span = (1,1), flag = wx.ALIGN_CENTER_HORIZONTAL|wx.EXPAND, border = 0)
+
+
+ # second box - map coordinates
+ box2 = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = "")
+ sizerM = wx.StaticBoxSizer(box2, wx.VERTICAL)
+ self.gridBagSizerM = wx.GridBagSizer (hgap = 5, vgap = 5)
+ self.gridBagSizerM.AddGrowableCol(0)
+ self.gridBagSizerM.AddGrowableCol(1)
+
+ self.eastingLabel = wx.StaticText(panel, id = wx.ID_ANY, label = "E:")
+ self.northingLabel = wx.StaticText(panel, id = wx.ID_ANY, label = "N:")
+ self.eastingCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, value = "")
+ self.northingCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, value = "")
+ east, north = PaperMapCoordinates(self, mapId = self.mapId, x = self.textDict['where'][0], y = self.textDict['where'][1], paperToMap = True)
+ self.eastingCtrl.SetValue(str(east))
+ self.northingCtrl.SetValue(str(north))
+
+
+ self.gridBagSizerM.Add(self.eastingLabel, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerM.Add(self.northingLabel, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerM.Add(self.eastingCtrl, pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ self.gridBagSizerM.Add(self.northingCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+ sizerM.Add(self.gridBagSizerM, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ gridBagSizer.Add(sizerM, pos = (2,1), flag = wx.ALIGN_LEFT|wx.EXPAND, border = 0)
+
+ #offset
+ box3 = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Offset")))
+ sizerO = wx.StaticBoxSizer(box3, wx.VERTICAL)
+ gridBagSizerO = wx.GridBagSizer (hgap = 5, vgap = 5)
+ self.xoffLabel = wx.StaticText(panel, id = wx.ID_ANY, label = _("horizontal (pts):"))
+ self.yoffLabel = wx.StaticText(panel, id = wx.ID_ANY, label = _("vertical (pts):"))
+ self.xoffCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, size = (50, -1), min = -50, max = 50, initial = 0)
+ self.yoffCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, size = (50, -1), min = -50, max = 50, initial = 0)
+ self.xoffCtrl.SetValue(self.textDict['xoffset'])
+ self.yoffCtrl.SetValue(self.textDict['yoffset'])
+ gridBagSizerO.Add(self.xoffLabel, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizerO.Add(self.yoffLabel, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizerO.Add(self.xoffCtrl, pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+ gridBagSizerO.Add(self.yoffCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
+
+ sizerO.Add(gridBagSizerO, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
+ gridBagSizer.Add(sizerO, pos = (3,0), flag = wx.ALIGN_CENTER_HORIZONTAL|wx.EXPAND, border = 0)
+ # reference point
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_(" Reference point")))
+ sizerR = wx.StaticBoxSizer(box, wx.VERTICAL)
+ flexSizer = wx.FlexGridSizer(rows = 3, cols = 3, hgap = 5, vgap = 5)
+ flexSizer.AddGrowableCol(0)
+ flexSizer.AddGrowableCol(1)
+ flexSizer.AddGrowableCol(2)
+ ref = []
+ for row in ["upper", "center", "lower"]:
+ for col in ["left", "center", "right"]:
+ ref.append(row + " " + col)
+ self.radio = [wx.RadioButton(panel, id = wx.ID_ANY, label = '', style = wx.RB_GROUP, name = ref[0])]
+ self.radio[0].SetValue(False)
+ flexSizer.Add(self.radio[0], proportion = 0, flag = wx.ALIGN_CENTER, border = 0)
+ for i in range(1,9):
+ self.radio.append(wx.RadioButton(panel, id = wx.ID_ANY, label = '', name = ref[i]))
+ self.radio[-1].SetValue(False)
+ flexSizer.Add(self.radio[-1], proportion = 0, flag = wx.ALIGN_CENTER, border = 0)
+ self.FindWindowByName(self.textDict['ref']).SetValue(True)
+
+
+ sizerR.Add(flexSizer, proportion = 1, flag = wx.EXPAND, border = 0)
+ gridBagSizer.Add(sizerR, pos = (3,1), flag = wx.ALIGN_LEFT|wx.EXPAND, border = 0)
+
+ sizer.Add(gridBagSizer, proportion = 1, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ #rotation
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " {0} ".format(_("Text rotation")))
+ sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+
+ self.rotCtrl = wx.CheckBox(panel, id = wx.ID_ANY, label = _("rotate text (counterclockwise)"))
+ self.rotValue = wx.SpinCtrl(panel, wx.ID_ANY, size = (50, -1), min = 0, max = 360, initial = 0)
+ if self.textDict['rotate']:
+ self.rotValue.SetValue(int(self.textDict['rotate']))
+ self.rotCtrl.SetValue(True)
+ else:
+ self.rotValue.SetValue(0)
+ self.rotCtrl.SetValue(False)
+ sizer.Add(self.rotCtrl, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT|wx.ALL, border = 5)
+ sizer.Add(self.rotValue, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT|wx.ALL, border = 5)
+
+ border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
+
+ panel.SetSizer(border)
+ panel.Fit()
+
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnPositionType, self.paperPositionCtrl)
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnPositionType, self.mapPositionCtrl)
+ self.Bind(wx.EVT_CHECKBOX, self.OnRotation, self.rotCtrl)
+
+ return panel
+
+ def OnRefit(self, event):
+ self.Fit()
+
+ def OnRotation(self, event):
+ if self.rotCtrl.GetValue():
+ self.rotValue.Enable()
+ else:
+ self.rotValue.Disable()
+
+ def OnPositionType(self, event):
+ if self.paperPositionCtrl.GetValue():
+ for widget in self.gridBagSizerP.GetChildren():
+ widget.GetWindow().Enable()
+ for widget in self.gridBagSizerM.GetChildren():
+ widget.GetWindow().Disable()
+ else:
+ for widget in self.gridBagSizerM.GetChildren():
+ widget.GetWindow().Enable()
+ for widget in self.gridBagSizerP.GetChildren():
+ widget.GetWindow().Disable()
+ def OnBackground(self, event):
+ if self.effect['backgroundCtrl'].GetValue():
+ self.effect['backgroundColor'].Enable()
+ else:
+ self.effect['backgroundColor'].Disable()
+
+ def OnHighlight(self, event):
+ if self.effect['highlightCtrl'].GetValue():
+ self.effect['highlightColor'].Enable()
+ self.effect['highlightWidth'].Enable()
+ self.effect['highlightWidthLabel'].Enable()
+ else:
+ self.effect['highlightColor'].Disable()
+ self.effect['highlightWidth'].Disable()
+ self.effect['highlightWidthLabel'].Disable()
+
+ def OnBorder(self, event):
+ if self.effect['borderCtrl'].GetValue():
+ self.effect['borderColor'].Enable()
+ self.effect['borderWidth'].Enable()
+ self.effect['borderWidthLabel'].Enable()
+ else:
+ self.effect['borderColor'].Disable()
+ self.effect['borderWidth'].Disable()
+ self.effect['borderWidthLabel'].Disable()
+
+ def update(self):
+
+ #text
+ self.textDict['text'] = self.textCtrl.GetValue()
+ if not self.textDict['text']:
+ wx.MessageBox(_("No text entered!"), _("Error"))
+ return False
+
+ #font
+ self.textDict['font'] = font = self.textPanel.font['fontCtrl'].GetStringSelection()
+ self.textDict['fontsize'] = self.textPanel.font['fontSizeCtrl'].GetValue()
+## font = self.textPanel.font['fontCtrl'].GetSelectedFont()
+## self.textDict['font'] = font.GetFaceName()
+## self.textDict['fontsize'] = font.GetPointSize()
+ self.textDict['color'] = self.textPanel.font['colorCtrl'].GetColour().GetAsString(flags=wx.C2S_NAME)
+ #effects
+ self.textDict['background'] = (convertRGB(self.effect['backgroundColor'].GetColour())
+ if self.effect['backgroundCtrl'].GetValue() else 'none')
+ self.textDict['border'] = (convertRGB(self.effect['borderColor'].GetColour())
+ if self.effect['borderCtrl'].GetValue() else 'none')
+ self.textDict['width'] = self.effect['borderWidth'].GetValue()
+ self.textDict['hcolor'] = (convertRGB(self.effect['highlightColor'].GetColour())
+ if self.effect['highlightCtrl'].GetValue() else 'none')
+ self.textDict['hwidth'] = self.effect['highlightWidth'].GetValue()
+
+ #offset
+ self.textDict['xoffset'] = self.xoffCtrl.GetValue()
+ self.textDict['yoffset'] = self.yoffCtrl.GetValue()
+ #position
+ if self.paperPositionCtrl.GetValue():
+ self.textDict['XY'] = True
+ currUnit = self.positionPanel.units['unitsCtrl'].GetStringSelection()
+ self.textDict['unit'] = currUnit
+ x = self.positionPanel.position['xCtrl'].GetValue() if self.positionPanel.position['xCtrl'].GetValue() else self.textDict['where'][0]
+ y = self.positionPanel.position['yCtrl'].GetValue() if self.positionPanel.position['yCtrl'].GetValue() else self.textDict['where'][1]
+ x = self.unitConv.convert(value = float(x), fromUnit = currUnit, toUnit = 'inch')
+ y = self.unitConv.convert(value = float(y), fromUnit = currUnit, toUnit = 'inch')
+ self.textDict['where'] = x, y
+ self.textDict['east'], self.textDict['north'] = PaperMapCoordinates(self, self.mapId, x, y, paperToMap = True)
+ else:
+ self.textDict['XY'] = False
+ self.textDict['east'] = self.eastingCtrl.GetValue() if self.eastingCtrl.GetValue() else self.textDict['east']
+ self.textDict['north'] = self.northingCtrl.GetValue() if self.northingCtrl.GetValue() else self.textDict['north']
+ self.textDict['where'] = PaperMapCoordinates(self, mapId = self.mapId, x = float(self.textDict['east']),
+ y = float(self.textDict['north']), paperToMap = False)
+ #rotation
+ if self.rotCtrl.GetValue():
+ self.textDict['rotate'] = self.rotValue.GetValue()
+ else:
+ self.textDict['rotate'] = None
+ #reference point
+ for radio in self.radio:
+ if radio.GetValue() == True:
+ self.textDict['ref'] = radio.GetName()
+
+ if self.id not in self.instruction:
+ text = Text(self.id)
+ self.instruction.AddInstruction(text)
+ self.instruction[self.id].SetInstruction(self.textDict)
+
+ if self.id not in self.parent.objectId:
+ self.parent.objectId.append(self.id)
+
+ return True
+
+
+
+def find_key(dic, val, multiple = False):
+ """!Return the key of dictionary given the value"""
+ result = [k for k, v in dic.iteritems() if v == val]
+ if len(result) == 0 and not multiple:
+ return None
+ return sorted(result) if multiple else result[0]
+
+def convertRGB(rgb):
+ """!Converts wx.Colour(255,255,255,255) and string '255:255:255',
+ depends on input"""
+ if type(rgb) == wx.Colour:
+ return str(rgb.Red()) + ':' + str(rgb.Green()) + ':' + str(rgb.Blue())
+ elif type(rgb) == str:
+ return wx.Colour(*map(int, rgb.split(':')))
+
+
+def PaperMapCoordinates(self, mapId, x, y, paperToMap = True):
+ """!Converts paper (inch) coordinates -> map coordinates"""
+ unitConv = UnitConversion(self)
+ currRegionDict = grass.region()
+ cornerEasting, cornerNorthing = currRegionDict['w'], currRegionDict['n']
+ xMap = self.instruction[mapId]['rect'][0]
+ yMap = self.instruction[mapId]['rect'][1]
+ widthMap = self.instruction[mapId]['rect'][2] * 0.0254 # to meter
+ heightMap = self.instruction[mapId]['rect'][3] * 0.0254
+ xScale = widthMap / abs(currRegionDict['w'] - currRegionDict['e'])
+ yScale = heightMap / abs(currRegionDict['n'] - currRegionDict['s'])
+ currScale = (xScale + yScale) / 2
+
+
+ if not paperToMap:
+ textEasting, textNorthing = x, y
+ eastingDiff = textEasting - cornerEasting
+ eastingDiff = - eastingDiff if currRegionDict['w'] > currRegionDict['e'] else eastingDiff
+ northingDiff = textNorthing - cornerNorthing
+ northingDiff = - northingDiff if currRegionDict['n'] > currRegionDict['s'] else northingDiff
+ xPaper = xMap + unitConv.convert(value = eastingDiff, fromUnit = 'meter', toUnit = 'inch') * currScale
+ yPaper = yMap + unitConv.convert(value = northingDiff, fromUnit = 'meter', toUnit = 'inch') * currScale
+ return xPaper, yPaper
+ else:
+ eastingDiff = (x - xMap) if currRegionDict['w'] < currRegionDict['e'] else (xMap - x)
+ northingDiff = (y - yMap) if currRegionDict['n'] < currRegionDict['s'] else (yMap - y)
+ textEasting = cornerEasting + unitConv.convert(value = eastingDiff, fromUnit = 'inch', toUnit = 'meter') / currScale
+ textNorthing = cornerNorthing + unitConv.convert(value = northingDiff, fromUnit = 'inch', toUnit = 'meter') / currScale
+ return int(textEasting), int(textNorthing)
+
+
+def AutoAdjust(self, scaleType, rect, map = None, mapType = None, region = None):
+ """!Computes map scale, center and map frame rectangle to fit region (scale is not fixed)"""
+ currRegionDict = {}
+ if scaleType == 0 and map:# automatic, region from raster or vector
+ res = ''
+ if mapType == 'raster':
+ res = grass.read_command("g.region", flags = 'gu', rast = map)
+ elif mapType == 'vector':
+ res = grass.read_command("g.region", flags = 'gu', vect = map)
+ currRegionDict = grass.parse_key_val(res, val_type = float)
+ elif scaleType == 1 and region: # saved region
+ res = grass.read_command("g.region", flags = 'gu', region = region)
+ currRegionDict = grass.parse_key_val(res, val_type = float)
+ elif scaleType == 2: # current region
+ env = grass.gisenv()
+ windFilePath = os.path.join(env['GISDBASE'], env['LOCATION_NAME'], env['MAPSET'], 'WIND')
+ try:
+ windFile = open(windFilePath, 'r').read()
+ except IOError:
+ currRegionDict = grass.region()
+ regionDict = grass.parse_key_val(windFile, sep = ':', val_type = float)
+ region = grass.read_command("g.region", flags = 'gu', n = regionDict['north'], s = regionDict['south'],
+ e = regionDict['east'], w = regionDict['west'])
+ currRegionDict = grass.parse_key_val(region, val_type = float)
+
+ else:
+ return None, None, None
+
+ if not currRegionDict:
+ return None, None
+ rX = rect.x
+ rY = rect.y
+ rW = rect.width
+ rH = rect.height
+ if not hasattr(self, 'unitConv'):
+ self.unitConv = UnitConversion(self)
+ toM = 1
+ if projInfo()['proj'] != 'xy':
+ toM = float(projInfo()['meters'])
+
+ mW = self.unitConv.convert(value = (currRegionDict['e'] - currRegionDict['w']) * toM, fromUnit = 'meter', toUnit = 'inch')
+ mH = self.unitConv.convert(value = (currRegionDict['n'] - currRegionDict['s']) * toM, fromUnit = 'meter', toUnit = 'inch')
+ scale = min(rW/mW, rH/mH)
+
+
+ if rW/rH > mW/mH:
+ x = rX - (rH*(mW/mH) - rW)/2
+ y = rY
+ rWNew = rH*(mW/mH)
+ rHNew = rH
+ else:
+ x = rX
+ y = rY - (rW*(mH/mW) - rH)/2
+ rHNew = rW*(mH/mW)
+ rWNew = rW
+
+ # center
+ cE = (currRegionDict['w'] + currRegionDict['e'])/2
+ cN = (currRegionDict['n'] + currRegionDict['s'])/2
+ return scale, (cE, cN), wx.Rect2D(x, y, rWNew, rHNew) #inch
+
+def ComputeSetRegion(self, mapDict):
+ """!Computes and sets region from current scale, map center coordinates and map rectangle"""
+
+ if mapDict['scaleType'] == 3: # fixed scale
+ scale = mapDict['scale']
+
+ if not hasattr(self, 'unitConv'):
+ self.unitConv = UnitConversion(self)
+
+ fromM = 1
+ if projInfo()['proj'] != 'xy':
+ fromM = float(projInfo()['meters'])
+ rectHalfInch = ( mapDict['rect'].width/2, mapDict['rect'].height/2)
+ rectHalfMeter = ( self.unitConv.convert(value = rectHalfInch[0], fromUnit = 'inch', toUnit = 'meter')/ fromM /scale,
+ self.unitConv.convert(value = rectHalfInch[1], fromUnit = 'inch', toUnit = 'meter')/ fromM /scale)
+
+ centerE = mapDict['center'][0]
+ centerN = mapDict['center'][1]
+
+ raster = self.instruction.FindInstructionByType('raster')
+ rasterId = raster.id if raster else None
+
+ if rasterId:
+ RunCommand('g.region', n = ceil(centerN + rectHalfMeter[1]),
+ s = floor(centerN - rectHalfMeter[1]),
+ e = ceil(centerE + rectHalfMeter[0]),
+ w = floor(centerE - rectHalfMeter[0]),
+ rast = self.instruction[rasterId]['raster'])
+ else:
+ RunCommand('g.region', n = ceil(centerN + rectHalfMeter[1]),
+ s = floor(centerN - rectHalfMeter[1]),
+ e = ceil(centerE + rectHalfMeter[0]),
+ w = floor(centerE - rectHalfMeter[0]))
+
+def projInfo():
+ """!Return region projection and map units information,
+ taken from render.py"""
+
+ projinfo = dict()
+
+ ret = RunCommand('g.proj', read = True, flags = 'p')
+
+ if not ret:
+ return projinfo
+
+ for line in ret.splitlines():
+ if ':' in line:
+ key, val = line.split(':')
+ projinfo[key.strip()] = val.strip()
+ elif "XY location (unprojected)" in line:
+ projinfo['proj'] = 'xy'
+ projinfo['units'] = ''
+ break
+
+ return projinfo
+
+def GetMapBounds(filename):
+ """!Run ps.map -b to get information about map bounding box"""
+ try:
+ bb = map(float, RunCommand('ps.map', read = True,
+ flags = 'b',
+ input = filename).strip().split('=')[1].split(','))
+ except (grass.ScriptError, IndexError):
+ GError(message = _("Unable to run ps.map -b "))
+ return None
+ return wx.Rect2D(bb[0], bb[3], bb[2] - bb[0], bb[1] - bb[3])
Added: grass-addons/gui/wxpython/psmap/images/scalebar-fancy.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/gui/wxpython/psmap/images/scalebar-fancy.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: grass-addons/gui/wxpython/psmap/images/scalebar-simple.png
===================================================================
(Binary files differ)
Property changes on: grass-addons/gui/wxpython/psmap/images/scalebar-simple.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: grass-addons/gui/wxpython/psmap/xml/menudata_psmap.xml
===================================================================
--- grass-addons/gui/wxpython/psmap/xml/menudata_psmap.xml (rev 0)
+++ grass-addons/gui/wxpython/psmap/xml/menudata_psmap.xml 2011-03-14 07:15:14 UTC (rev 45659)
@@ -0,0 +1,104 @@
+<menudata>
+ <menubar>
+ <menu>
+ <label>&File</label>
+ <items>
+ <menuitem>
+ <label>Page setup</label>
+ <help>Specify paper size, margins and orientation</help>
+ <handler>OnPageSetup</handler>
+ <shortcut>Ctrl+P</shortcut>
+ </menuitem>
+ <menuitem>
+ <label>Export to text file</label>
+ <help>Generate text file with mapping instructions</help>
+ <handler>OnInstructionFile</handler>
+ <shortcut>Ctrl+Shift+E</shortcut>
+ </menuitem>
+ <menuitem>
+ <label>Export to PostScript</label>
+ <help>Generate PostScript file</help>
+ <handler>OnPSFile</handler>
+ <shortcut>Ctrl+E</shortcut>
+ </menuitem>
+ <separator/>
+ <menuitem>
+ <label>Quit</label>
+ <help>Close Hardcopy Map Output Utility</help>
+ <handler>OnCloseWindow</handler>
+ <shortcut>Ctrl+W</shortcut>
+ </menuitem>
+ </items>
+ </menu>
+ <menu>
+ <label>&Insert</label>
+ <items>
+ <menuitem>
+ <label>Map frame</label>
+ <help>Add or edit map frame</help>
+ <handler>OnAddMap</handler>
+ <shortcut>Ctrl+M</shortcut>
+ </menuitem>
+ <menuitem>
+ <label>Raster map</label>
+ <help>Add or edit raster map</help>
+ <handler>OnAddRaster</handler>
+ <shortcut>Ctrl+R</shortcut>
+ </menuitem>
+ <menuitem>
+ <label>Vector map</label>
+ <help>Add or edit vector map</help>
+ <handler>OnAddVect</handler>
+ <shortcut>Ctrl+V</shortcut>
+ </menuitem>
+ <menuitem>
+ <label>Map legend</label>
+ <help>Add or edit raster and vector legend</help>
+ <handler>OnAddLegend</handler>
+ <shortcut>Ctrl+L</shortcut>
+ </menuitem>
+ <menuitem>
+ <label>Map info</label>
+ <help>Add or edit map info</help>
+ <handler>OnAddMapinfo</handler>
+ <shortcut>Ctrl+I</shortcut>
+ </menuitem>
+ <menuitem>
+ <label>Scale bar</label>
+ <help>Add or edit scale bar</help>
+ <handler>OnAddScalebar</handler>
+ <shortcut>Ctrl+B</shortcut>
+ </menuitem>
+ <menuitem>
+ <label>Text</label>
+ <help>Add text</help>
+ <handler>OnAddText</handler>
+ <shortcut>Ctrl+T</shortcut>
+ </menuitem>
+ <separator/>
+ <menuitem>
+ <label>Delete</label>
+ <help>Delete selected object</help>
+ <handler>OnDelete</handler>
+ <shortcut>Delete</shortcut>
+ </menuitem>
+ </items>
+ </menu>
+ <menu>
+ <label>&Help</label>
+ <items>
+ <menuitem>
+ <label>Help</label>
+ <help>Display the HTML man pages of Hardcopy Map Output Utility</help>
+ <handler>OnHelp</handler>
+ </menuitem>
+ <separator />
+ <menuitem>
+ <label>About Hardcopy Map Output Utility</label>
+ <help>Display information about Hardcopy Map Output Utility</help>
+ <handler>OnAbout</handler>
+ </menuitem>
+ </items>
+ </menu>
+ </menubar>
+</menudata>
More information about the grass-commit
mailing list