manager.py 108 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208
  1. """
  2. @package gcp.manager
  3. @brief Georectification module for GRASS GIS. Includes ground control
  4. point management and interactive point and click GCP creation
  5. Classes:
  6. - manager::GCPWizard
  7. - manager::LocationPage
  8. - manager::GroupPage
  9. - manager::DispMapPage
  10. - manager::GCP
  11. - manager::GCPList
  12. - manager::VectGroup
  13. - manager::EditGCP
  14. - manager::GrSettingsDialog
  15. (C) 2006-2014 by the GRASS Development Team
  16. This program is free software under the GNU General Public License
  17. (>=v2). Read the file COPYING that comes with GRASS for details.
  18. @author Original author Michael Barton
  19. @author Original version improved by Martin Landa <landa.martin gmail.com>
  20. @author Rewritten by Markus Metz redesign georectfier -> GCP Manage
  21. @author Support for GraphicsSet added by Stepan Turek <stepan.turek seznam.cz> (2012)
  22. """
  23. import os
  24. import sys
  25. import shutil
  26. import time
  27. from copy import copy
  28. import wx
  29. from wx.lib.mixins.listctrl import CheckListCtrlMixin, ColumnSorterMixin, ListCtrlAutoWidthMixin
  30. import wx.lib.colourselect as csel
  31. import wx.wizard as wiz
  32. import grass.script as grass
  33. from core import globalvar
  34. from core import utils
  35. from core.render import Map
  36. from core.utils import _
  37. from gui_core.gselect import Select, LocationSelect, MapsetSelect
  38. from gui_core.dialogs import GroupDialog
  39. from core.gcmd import RunCommand, GMessage, GError, GWarning, EncodeString
  40. from core.settings import UserSettings
  41. from gcp.mapdisplay import MapFrame
  42. from core.giface import Notification
  43. from location_wizard.wizard import TitledPage as TitledPage
  44. #
  45. # global variables
  46. #
  47. global src_map
  48. global tgt_map
  49. global maptype
  50. src_map = ''
  51. tgt_map = {'raster': '',
  52. 'vector': ''}
  53. maptype = 'raster'
  54. def getSmallUpArrowImage():
  55. stream = open(os.path.join(globalvar.IMGDIR, 'small_up_arrow.png'), 'rb')
  56. try:
  57. img = wx.ImageFromStream(stream)
  58. finally:
  59. stream.close()
  60. return img
  61. def getSmallDnArrowImage():
  62. stream = open(os.path.join(globalvar.IMGDIR, 'small_down_arrow.png'), 'rb')
  63. try:
  64. img = wx.ImageFromStream(stream)
  65. finally:
  66. stream.close()
  67. stream.close()
  68. return img
  69. class GCPWizard(object):
  70. """
  71. Start wizard here and finish wizard here
  72. """
  73. def __init__(self, parent, giface):
  74. self.parent = parent # GMFrame
  75. self._giface = giface
  76. #
  77. # get environmental variables
  78. #
  79. self.grassdatabase = grass.gisenv()['GISDBASE']
  80. #
  81. # read original environment settings
  82. #
  83. self.target_gisrc = os.environ['GISRC']
  84. self.gisrc_dict = {}
  85. try:
  86. f = open(self.target_gisrc, 'r')
  87. for line in f.readlines():
  88. line = line.replace('\n', '').strip()
  89. if len(line) < 1:
  90. continue
  91. key, value = line.split(':', 1)
  92. self.gisrc_dict[key.strip()] = value.strip()
  93. finally:
  94. f.close()
  95. self.currentlocation = self.gisrc_dict['LOCATION_NAME']
  96. self.currentmapset = self.gisrc_dict['MAPSET']
  97. # location for xy map to georectify
  98. self.newlocation = ''
  99. # mapset for xy map to georectify
  100. self.newmapset = ''
  101. global maptype
  102. global src_map
  103. global tgt_map
  104. #src_map = ''
  105. #tgt_map = ''
  106. maptype = 'raster'
  107. # GISRC file for source location/mapset of map(s) to georectify
  108. self.source_gisrc = ''
  109. self.src_maps = []
  110. #
  111. # define wizard pages
  112. #
  113. self.wizard = wiz.Wizard(
  114. parent=parent,
  115. id=wx.ID_ANY,
  116. title=_("Setup for georectification"))
  117. self.startpage = LocationPage(self.wizard, self)
  118. self.grouppage = GroupPage(self.wizard, self)
  119. self.mappage = DispMapPage(self.wizard, self)
  120. #
  121. # set the initial order of the pages
  122. #
  123. self.startpage.SetNext(self.grouppage)
  124. self.grouppage.SetPrev(self.startpage)
  125. self.grouppage.SetNext(self.mappage)
  126. self.mappage.SetPrev(self.grouppage)
  127. #
  128. # do pages layout
  129. #
  130. self.startpage.DoLayout()
  131. self.grouppage.DoLayout()
  132. self.mappage.DoLayout()
  133. self.wizard.FitToPage(self.startpage)
  134. # self.Bind(wx.EVT_CLOSE, self.Cleanup)
  135. # self.parent.Bind(wx.EVT_ACTIVATE, self.OnGLMFocus)
  136. success = False
  137. #
  138. # run wizard
  139. #
  140. if self.wizard.RunWizard(self.startpage):
  141. success = self.OnWizFinished()
  142. if success == False:
  143. GMessage(parent=self.parent,
  144. message=_("Georectifying setup canceled."))
  145. self.Cleanup()
  146. else:
  147. GMessage(parent=self.parent,
  148. message=_("Georectifying setup canceled."))
  149. self.Cleanup()
  150. #
  151. # start GCP display
  152. #
  153. if success != False:
  154. # instance of render.Map to be associated with display
  155. self.SwitchEnv('source')
  156. self.SrcMap = Map(gisrc=self.source_gisrc)
  157. self.SwitchEnv('target')
  158. self.TgtMap = Map(gisrc=self.target_gisrc)
  159. self.Map = self.SrcMap
  160. #
  161. # add layer to source map
  162. #
  163. if maptype == 'raster':
  164. rendertype = 'raster'
  165. cmdlist = ['d.rast', 'map=%s' % src_map]
  166. else: # -> vector layer
  167. rendertype = 'vector'
  168. cmdlist = ['d.vect', 'map=%s' % src_map]
  169. self.SwitchEnv('source')
  170. name, found = utils.GetLayerNameFromCmd(cmdlist)
  171. self.SrcMap.AddLayer(
  172. ltype=rendertype,
  173. command=cmdlist,
  174. active=True,
  175. name=name,
  176. hidden=False,
  177. opacity=1.0,
  178. render=False)
  179. self.SwitchEnv('target')
  180. if tgt_map['raster']:
  181. #
  182. # add raster layer to target map
  183. #
  184. rendertype = 'raster'
  185. cmdlist = ['d.rast', 'map=%s' % tgt_map['raster']]
  186. name, found = utils.GetLayerNameFromCmd(cmdlist)
  187. self.TgtMap.AddLayer(
  188. ltype=rendertype,
  189. command=cmdlist,
  190. active=True,
  191. name=name,
  192. hidden=False,
  193. opacity=1.0,
  194. render=False)
  195. if tgt_map['vector']:
  196. #
  197. # add raster layer to target map
  198. #
  199. rendertype = 'vector'
  200. cmdlist = ['d.vect', 'map=%s' % tgt_map['vector']]
  201. name, found = utils.GetLayerNameFromCmd(cmdlist)
  202. self.TgtMap.AddLayer(
  203. ltype=rendertype,
  204. command=cmdlist,
  205. active=True,
  206. name=name,
  207. hidden=False,
  208. opacity=1.0,
  209. render=False)
  210. #
  211. # start GCP Manager
  212. #
  213. self.gcpmgr = GCP(self.parent, giface=self._giface,
  214. grwiz=self, size=globalvar.MAP_WINDOW_SIZE,
  215. toolbars=["gcpdisp"],
  216. Map=self.SrcMap, lmgr=self.parent)
  217. # load GCPs
  218. self.gcpmgr.InitMapDisplay()
  219. self.gcpmgr.CenterOnScreen()
  220. self.gcpmgr.Show()
  221. # need to update AUI here for wingrass
  222. self.gcpmgr._mgr.Update()
  223. else:
  224. self.Cleanup()
  225. def SetSrcEnv(self, location, mapset):
  226. """Create environment to use for location and mapset
  227. that are the source of the file(s) to georectify
  228. :param location: source location
  229. :param mapset: source mapset
  230. :return: False on error
  231. :return: True on success
  232. """
  233. self.newlocation = location
  234. self.newmapset = mapset
  235. # check to see if we are georectifying map in current working
  236. # location/mapset
  237. if self.newlocation == self.currentlocation and self.newmapset == self.currentmapset:
  238. return False
  239. self.gisrc_dict['LOCATION_NAME'] = location
  240. self.gisrc_dict['MAPSET'] = mapset
  241. self.source_gisrc = EncodeString(utils.GetTempfile())
  242. try:
  243. f = open(self.source_gisrc, mode='w')
  244. for line in self.gisrc_dict.items():
  245. f.write(line[0] + ": " + line[1] + "\n")
  246. finally:
  247. f.close()
  248. return True
  249. def SwitchEnv(self, grc):
  250. """
  251. Switches between original working location/mapset and
  252. location/mapset that is source of file(s) to georectify
  253. """
  254. # check to see if we are georectifying map in current working
  255. # location/mapset
  256. if self.newlocation == self.currentlocation and self.newmapset == self.currentmapset:
  257. return False
  258. if grc == 'target':
  259. os.environ['GISRC'] = str(self.target_gisrc)
  260. elif grc == 'source':
  261. os.environ['GISRC'] = str(self.source_gisrc)
  262. return True
  263. def OnWizFinished(self):
  264. # self.Cleanup()
  265. return True
  266. def OnGLMFocus(self, event):
  267. """Layer Manager focus"""
  268. # self.SwitchEnv('target')
  269. event.Skip()
  270. def Cleanup(self):
  271. """Return to current location and mapset"""
  272. # here was also the cleaning of gcpmanagement from layer manager
  273. # which is no longer needed
  274. self.SwitchEnv('target')
  275. self.wizard.Destroy()
  276. class LocationPage(TitledPage):
  277. """
  278. Set map type (raster or vector) to georectify and
  279. select location/mapset of map(s) to georectify.
  280. """
  281. def __init__(self, wizard, parent):
  282. TitledPage.__init__(self, wizard, _(
  283. "Select map type and location/mapset"))
  284. self.parent = parent
  285. self.grassdatabase = self.parent.grassdatabase
  286. self.xylocation = ''
  287. self.xymapset = ''
  288. #
  289. # layout
  290. #
  291. # map type
  292. self.rb_maptype = wx.RadioBox(
  293. parent=self, id=wx.ID_ANY, label=' %s ' %
  294. _("Map type to georectify"), choices=[
  295. _('raster'), _('vector')], majorDimension=wx.RA_SPECIFY_COLS)
  296. self.sizer.Add(item=self.rb_maptype,
  297. flag=wx.ALIGN_CENTER | wx.ALL | wx.EXPAND, border=5,
  298. pos=(1, 1), span=(1, 2))
  299. # location
  300. self.sizer.Add(
  301. item=wx.StaticText(
  302. parent=self,
  303. id=wx.ID_ANY,
  304. label=_('Select source location:')),
  305. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  306. border=5,
  307. pos=(
  308. 2,
  309. 1))
  310. self.cb_location = LocationSelect(
  311. parent=self, gisdbase=self.grassdatabase)
  312. self.sizer.Add(
  313. item=self.cb_location,
  314. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  315. border=5,
  316. pos=(
  317. 2,
  318. 2))
  319. # mapset
  320. self.sizer.Add(
  321. item=wx.StaticText(
  322. parent=self,
  323. id=wx.ID_ANY,
  324. label=_('Select source mapset:')),
  325. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  326. border=5,
  327. pos=(
  328. 3,
  329. 1))
  330. self.cb_mapset = MapsetSelect(parent=self, gisdbase=self.grassdatabase,
  331. setItems=False)
  332. self.sizer.Add(item=self.cb_mapset, flag=wx.ALIGN_LEFT |
  333. wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5, pos=(3, 2))
  334. self.sizer.AddGrowableCol(2)
  335. #
  336. # bindings
  337. #
  338. self.Bind(wx.EVT_RADIOBOX, self.OnMaptype, self.rb_maptype)
  339. self.Bind(wx.EVT_COMBOBOX, self.OnLocation, self.cb_location)
  340. self.cb_mapset.Bind(wx.EVT_TEXT, self.OnMapset)
  341. self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
  342. self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnEnterPage)
  343. # self.Bind(wx.EVT_CLOSE, self.parent.Cleanup)
  344. def OnMaptype(self, event):
  345. """Change map type"""
  346. global maptype
  347. if event.GetInt() == 0:
  348. maptype = 'raster'
  349. else:
  350. maptype = 'vector'
  351. def OnLocation(self, event):
  352. """Sets source location for map(s) to georectify"""
  353. self.xylocation = event.GetString()
  354. # create a list of valid mapsets
  355. tmplist = os.listdir(os.path.join(self.grassdatabase, self.xylocation))
  356. self.mapsetList = []
  357. for item in tmplist:
  358. if os.path.isdir(os.path.join(self.grassdatabase, self.xylocation, item)) and \
  359. os.path.exists(os.path.join(self.grassdatabase, self.xylocation, item, 'WIND')):
  360. if item != 'PERMANENT':
  361. self.mapsetList.append(item)
  362. self.xymapset = 'PERMANENT'
  363. utils.ListSortLower(self.mapsetList)
  364. self.mapsetList.insert(0, 'PERMANENT')
  365. self.cb_mapset.SetItems(self.mapsetList)
  366. self.cb_mapset.SetStringSelection(self.xymapset)
  367. if not wx.FindWindowById(wx.ID_FORWARD).IsEnabled():
  368. wx.FindWindowById(wx.ID_FORWARD).Enable(True)
  369. def OnMapset(self, event):
  370. """Sets source mapset for map(s) to georectify"""
  371. if self.xylocation == '':
  372. GMessage(_('You must select a valid location '
  373. 'before selecting a mapset'),
  374. parent=self)
  375. return
  376. self.xymapset = event.GetString()
  377. if not wx.FindWindowById(wx.ID_FORWARD).IsEnabled():
  378. wx.FindWindowById(wx.ID_FORWARD).Enable(True)
  379. def OnPageChanging(self, event=None):
  380. if event.GetDirection() and \
  381. (self.xylocation == '' or self.xymapset == ''):
  382. GMessage(_('You must select a valid location '
  383. 'and mapset in order to continue'),
  384. parent=self)
  385. event.Veto()
  386. return
  387. self.parent.SetSrcEnv(self.xylocation, self.xymapset)
  388. def OnEnterPage(self, event=None):
  389. if self.xylocation == '' or self.xymapset == '':
  390. wx.FindWindowById(wx.ID_FORWARD).Enable(False)
  391. else:
  392. wx.FindWindowById(wx.ID_FORWARD).Enable(True)
  393. class GroupPage(TitledPage):
  394. """
  395. Set group to georectify. Create group if desired.
  396. """
  397. def __init__(self, wizard, parent):
  398. TitledPage.__init__(self, wizard, _(
  399. "Select image/map group to georectify"))
  400. self.parent = parent
  401. self.grassdatabase = self.parent.grassdatabase
  402. self.groupList = []
  403. self.xylocation = ''
  404. self.xymapset = ''
  405. self.xygroup = ''
  406. # default extension
  407. self.extension = '_georect' + str(os.getpid())
  408. #
  409. # layout
  410. #
  411. # group
  412. self.sizer.Add(
  413. item=wx.StaticText(
  414. parent=self,
  415. id=wx.ID_ANY,
  416. label=_('Select group:')),
  417. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  418. border=5,
  419. pos=(
  420. 1,
  421. 1))
  422. self.cb_group = wx.ComboBox(parent=self, id=wx.ID_ANY,
  423. choices=self.groupList, size=(350, -1),
  424. style=wx.CB_DROPDOWN | wx.CB_READONLY)
  425. self.sizer.Add(item=self.cb_group, flag=wx.ALIGN_LEFT |
  426. wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5, pos=(1, 2))
  427. # create group
  428. self.sizer.Add(
  429. item=wx.StaticText(
  430. parent=self,
  431. id=wx.ID_ANY,
  432. label=_('Create group if none exists')),
  433. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  434. border=5,
  435. pos=(
  436. 2,
  437. 1))
  438. btnSizer = wx.BoxSizer(wx.HORIZONTAL)
  439. self.btn_mkgroup = wx.Button(
  440. parent=self,
  441. id=wx.ID_ANY,
  442. label=_("Create/edit group..."))
  443. self.btn_vgroup = wx.Button(
  444. parent=self,
  445. id=wx.ID_ANY,
  446. label=_("Add vector map to group..."))
  447. btnSizer.Add(item=self.btn_mkgroup,
  448. flag=wx.RIGHT, border=5)
  449. btnSizer.Add(item=self.btn_vgroup,
  450. flag=wx.LEFT, border=5)
  451. self.sizer.Add(
  452. item=btnSizer,
  453. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  454. border=5,
  455. pos=(
  456. 2,
  457. 2))
  458. # extension
  459. self.sizer.Add(
  460. item=wx.StaticText(
  461. parent=self,
  462. id=wx.ID_ANY,
  463. label=_('Extension for output maps:')),
  464. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  465. border=5,
  466. pos=(
  467. 3,
  468. 1))
  469. self.ext_txt = wx.TextCtrl(
  470. parent=self, id=wx.ID_ANY, value="", size=(
  471. 350, -1))
  472. self.ext_txt.SetValue(self.extension)
  473. self.sizer.Add(item=self.ext_txt, flag=wx.ALIGN_LEFT |
  474. wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5, pos=(3, 2))
  475. self.sizer.AddGrowableCol(2)
  476. #
  477. # bindings
  478. #
  479. self.Bind(wx.EVT_COMBOBOX, self.OnGroup, self.cb_group)
  480. self.Bind(wx.EVT_TEXT, self.OnExtension, self.ext_txt)
  481. self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
  482. self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnEnterPage)
  483. self.Bind(wx.EVT_CLOSE, self.parent.Cleanup)
  484. # hide vector group button by default
  485. self.btn_vgroup.Hide()
  486. def OnGroup(self, event):
  487. self.xygroup = event.GetString()
  488. def OnMkGroup(self, event):
  489. """Create new group in source location/mapset"""
  490. dlg = GroupDialog(parent=self, defaultGroup=self.xygroup)
  491. dlg.DisableSubgroupEdit()
  492. dlg.ShowModal()
  493. gr, s = dlg.GetSelectedGroup()
  494. if gr in dlg.GetExistGroups():
  495. self.xygroup = gr
  496. else:
  497. gr = ''
  498. dlg.Destroy()
  499. self.OnEnterPage()
  500. self.Update()
  501. def OnVGroup(self, event):
  502. """Add vector maps to group"""
  503. dlg = VectGroup(parent=self,
  504. id=wx.ID_ANY,
  505. grassdb=self.grassdatabase,
  506. location=self.xylocation,
  507. mapset=self.xymapset,
  508. group=self.xygroup)
  509. if dlg.ShowModal() != wx.ID_OK:
  510. return
  511. dlg.MakeVGroup()
  512. self.OnEnterPage()
  513. def OnExtension(self, event):
  514. self.extension = self.ext_txt.GetValue()
  515. def OnPageChanging(self, event=None):
  516. if event.GetDirection() and self.xygroup == '':
  517. GMessage(_('You must select a valid image/map '
  518. 'group in order to continue'),
  519. parent=self)
  520. event.Veto()
  521. return
  522. if event.GetDirection() and self.extension == '':
  523. GMessage(_('You must enter an map name '
  524. 'extension in order to continue'),
  525. parent=self)
  526. event.Veto()
  527. return
  528. def OnEnterPage(self, event=None):
  529. global maptype
  530. self.groupList = []
  531. self.xylocation = self.parent.gisrc_dict['LOCATION_NAME']
  532. self.xymapset = self.parent.gisrc_dict['MAPSET']
  533. # create a list of groups in selected mapset
  534. if os.path.isdir(os.path.join(self.grassdatabase,
  535. self.xylocation,
  536. self.xymapset,
  537. 'group')):
  538. tmplist = os.listdir(os.path.join(self.grassdatabase,
  539. self.xylocation,
  540. self.xymapset,
  541. 'group'))
  542. for item in tmplist:
  543. if os.path.isdir(os.path.join(self.grassdatabase,
  544. self.xylocation,
  545. self.xymapset,
  546. 'group',
  547. item)):
  548. self.groupList.append(item)
  549. if maptype == 'raster':
  550. self.btn_vgroup.Hide()
  551. self.Bind(wx.EVT_BUTTON, self.OnMkGroup, self.btn_mkgroup)
  552. elif maptype == 'vector':
  553. self.btn_vgroup.Show()
  554. self.Bind(wx.EVT_BUTTON, self.OnMkGroup, self.btn_mkgroup)
  555. self.Bind(wx.EVT_BUTTON, self.OnVGroup, self.btn_vgroup)
  556. utils.ListSortLower(self.groupList)
  557. self.cb_group.SetItems(self.groupList)
  558. if len(self.groupList) > 0:
  559. if self.xygroup and self.xygroup in self.groupList:
  560. self.cb_group.SetStringSelection(self.xygroup)
  561. else:
  562. self.cb_group.SetSelection(0)
  563. self.xygroup = self.groupList[0]
  564. if self.xygroup == '' or \
  565. self.extension == '':
  566. wx.FindWindowById(wx.ID_FORWARD).Enable(False)
  567. else:
  568. wx.FindWindowById(wx.ID_FORWARD).Enable(True)
  569. # switch to source
  570. self.parent.SwitchEnv('source')
  571. class DispMapPage(TitledPage):
  572. """
  573. Select ungeoreferenced map to display for interactively
  574. setting ground control points (GCPs).
  575. """
  576. def __init__(self, wizard, parent):
  577. TitledPage.__init__(
  578. self, wizard,
  579. _("Select maps to display for ground control point (GCP) creation"))
  580. self.parent = parent
  581. global maptype
  582. #
  583. # layout
  584. #
  585. self.sizer.Add(
  586. item=wx.StaticText(
  587. parent=self,
  588. id=wx.ID_ANY,
  589. label=_('Select source map to display:')),
  590. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  591. border=5,
  592. pos=(
  593. 1,
  594. 1))
  595. self.srcselection = Select(
  596. self,
  597. id=wx.ID_ANY,
  598. size=globalvar.DIALOG_GSELECT_SIZE,
  599. type=maptype,
  600. updateOnPopup=False)
  601. self.sizer.Add(
  602. item=self.srcselection,
  603. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  604. border=5,
  605. pos=(
  606. 1,
  607. 2))
  608. self.sizer.Add(
  609. item=wx.StaticText(
  610. parent=self,
  611. id=wx.ID_ANY,
  612. label=_('Select target raster map to display:')),
  613. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  614. border=5,
  615. pos=(
  616. 2,
  617. 1))
  618. self.tgtrastselection = Select(
  619. self, id=wx.ID_ANY, size=globalvar.DIALOG_GSELECT_SIZE,
  620. type='raster', updateOnPopup=False)
  621. self.sizer.Add(
  622. item=self.tgtrastselection,
  623. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  624. border=5,
  625. pos=(
  626. 2,
  627. 2))
  628. self.sizer.Add(
  629. item=wx.StaticText(
  630. parent=self,
  631. id=wx.ID_ANY,
  632. label=_('Select target vector map to display:')),
  633. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  634. border=5,
  635. pos=(
  636. 3,
  637. 1))
  638. self.tgtvectselection = Select(
  639. self, id=wx.ID_ANY, size=globalvar.DIALOG_GSELECT_SIZE,
  640. type='vector', updateOnPopup=False)
  641. self.sizer.Add(
  642. item=self.tgtvectselection,
  643. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  644. border=5,
  645. pos=(
  646. 3,
  647. 2))
  648. #
  649. # bindings
  650. #
  651. self.srcselection.Bind(wx.EVT_TEXT, self.OnSrcSelection)
  652. self.tgtrastselection.Bind(wx.EVT_TEXT, self.OnTgtRastSelection)
  653. self.tgtvectselection.Bind(wx.EVT_TEXT, self.OnTgtVectSelection)
  654. self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
  655. self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnEnterPage)
  656. self.Bind(wx.EVT_CLOSE, self.parent.Cleanup)
  657. def OnSrcSelection(self, event):
  658. """Source map to display selected"""
  659. global src_map
  660. global maptype
  661. src_map = self.srcselection.GetValue()
  662. if src_map == '':
  663. wx.FindWindowById(wx.ID_FORWARD).Enable(False)
  664. else:
  665. wx.FindWindowById(wx.ID_FORWARD).Enable(True)
  666. try:
  667. # set computational region to match selected map and zoom display
  668. # to region
  669. if maptype == 'raster':
  670. p = RunCommand('g.region', 'raster=src_map')
  671. elif maptype == 'vector':
  672. p = RunCommand('g.region', 'vector=src_map')
  673. if p.returncode == 0:
  674. print 'returncode = ', str(p.returncode)
  675. self.parent.Map.region = self.parent.Map.GetRegion()
  676. except:
  677. pass
  678. def OnTgtRastSelection(self, event):
  679. """Source map to display selected"""
  680. global tgt_map
  681. tgt_map['raster'] = self.tgtrastselection.GetValue()
  682. def OnTgtVectSelection(self, event):
  683. """Source map to display selected"""
  684. global tgt_map
  685. tgt_map['vector'] = self.tgtvectselection.GetValue()
  686. def OnPageChanging(self, event=None):
  687. global src_map
  688. global tgt_map
  689. if event.GetDirection() and (src_map == ''):
  690. GMessage(_('You must select a source map '
  691. 'in order to continue'),
  692. parent=self)
  693. event.Veto()
  694. return
  695. self.parent.SwitchEnv('target')
  696. def OnEnterPage(self, event=None):
  697. global maptype
  698. global src_map
  699. global tgt_map
  700. self.srcselection.SetElementList(maptype)
  701. if maptype == 'raster':
  702. ret = RunCommand('i.group',
  703. parent=self,
  704. read=True,
  705. group=self.parent.grouppage.xygroup,
  706. flags='g')
  707. if ret:
  708. self.parent.src_maps = ret.splitlines()
  709. else:
  710. GError(
  711. parent=self, message=_(
  712. 'No maps in selected group <%s>.\n'
  713. 'Please edit group or select another group.') %
  714. self.parent.grouppage.xygroup)
  715. return
  716. elif maptype == 'vector':
  717. grassdatabase = self.parent.grassdatabase
  718. xylocation = self.parent.gisrc_dict['LOCATION_NAME']
  719. xymapset = self.parent.gisrc_dict['MAPSET']
  720. # make list of vectors to georectify from VREF
  721. vgrpfile = os.path.join(grassdatabase,
  722. xylocation,
  723. xymapset,
  724. 'group',
  725. self.parent.grouppage.xygroup,
  726. 'VREF')
  727. f = open(vgrpfile)
  728. try:
  729. for vect in f.readlines():
  730. vect = vect.strip('\n')
  731. if len(vect) < 1:
  732. continue
  733. self.parent.src_maps.append(vect)
  734. finally:
  735. f.close()
  736. if len(self.parent.src_maps) < 1:
  737. GError(
  738. parent=self, message=_(
  739. 'No maps in selected group <%s>.\n'
  740. 'Please edit group or select another group.') %
  741. self.parent.grouppage.xygroup)
  742. return
  743. # filter out all maps not in group
  744. self.srcselection.tcp.GetElementList(elements=self.parent.src_maps)
  745. src_map = self.parent.src_maps[0]
  746. self.srcselection.SetValue(src_map)
  747. self.parent.SwitchEnv('target')
  748. self.tgtrastselection.SetElementList('raster')
  749. self.tgtrastselection.GetElementList()
  750. self.tgtvectselection.SetElementList('vector')
  751. self.tgtvectselection.GetElementList()
  752. self.parent.SwitchEnv('source')
  753. if src_map == '':
  754. wx.FindWindowById(wx.ID_FORWARD).Enable(False)
  755. else:
  756. wx.FindWindowById(wx.ID_FORWARD).Enable(True)
  757. class GCP(MapFrame, ColumnSorterMixin):
  758. """
  759. Manages ground control points for georectifying. Calculates RMS statistics.
  760. Calls i.rectify or v.rectify to georectify map.
  761. """
  762. def __init__(self, parent, giface, grwiz=None, id=wx.ID_ANY,
  763. title=_("Manage Ground Control Points"),
  764. size=(700, 300), toolbars=["gcpdisp"], Map=None, lmgr=None):
  765. self.grwiz = grwiz # GR Wizard
  766. self._giface = giface
  767. if tgt_map['raster'] == '' and tgt_map['vector'] == '':
  768. self.show_target = False
  769. else:
  770. self.show_target = True
  771. #wx.Frame.__init__(self, parent, id, title, size = size, name = "GCPFrame")
  772. MapFrame.__init__(
  773. self,
  774. parent=parent,
  775. giface=self._giface,
  776. title=title,
  777. size=size,
  778. Map=Map,
  779. toolbars=toolbars,
  780. name='GCPMapWindow')
  781. # init variables
  782. self.parent = parent
  783. #
  784. # register data structures for drawing GCP's
  785. #
  786. self.pointsToDrawTgt = self.TgtMapWindow.RegisterGraphicsToDraw(
  787. graphicsType="point", setStatusFunc=self.SetGCPSatus)
  788. self.pointsToDrawSrc = self.SrcMapWindow.RegisterGraphicsToDraw(
  789. graphicsType="point", setStatusFunc=self.SetGCPSatus)
  790. # connect to the map windows signals
  791. # used to add or edit GCP
  792. self.SrcMapWindow.mouseLeftUpPointer.connect(
  793. lambda x, y:
  794. self._onMouseLeftUpPointer(self.SrcMapWindow, x, y))
  795. self.TgtMapWindow.mouseLeftUpPointer.connect(
  796. lambda x, y:
  797. self._onMouseLeftUpPointer(self.TgtMapWindow, x, y))
  798. # window resized
  799. self.resize = False
  800. self.grassdatabase = self.grwiz.grassdatabase
  801. self.currentlocation = self.grwiz.currentlocation
  802. self.currentmapset = self.grwiz.currentmapset
  803. self.newlocation = self.grwiz.newlocation
  804. self.newmapset = self.grwiz.newmapset
  805. self.xylocation = self.grwiz.gisrc_dict['LOCATION_NAME']
  806. self.xymapset = self.grwiz.gisrc_dict['MAPSET']
  807. self.xygroup = self.grwiz.grouppage.xygroup
  808. self.src_maps = self.grwiz.src_maps
  809. self.extension = self.grwiz.grouppage.extension
  810. self.outname = ''
  811. self.VectGRList = []
  812. self.file = {
  813. 'points': os.path.join(self.grassdatabase,
  814. self.xylocation,
  815. self.xymapset,
  816. 'group',
  817. self.xygroup,
  818. 'POINTS'),
  819. 'points_bak': os.path.join(self.grassdatabase,
  820. self.xylocation,
  821. self.xymapset,
  822. 'group',
  823. self.xygroup,
  824. 'POINTS_BAK'),
  825. 'rgrp': os.path.join(self.grassdatabase,
  826. self.xylocation,
  827. self.xymapset,
  828. 'group',
  829. self.xygroup,
  830. 'REF'),
  831. 'vgrp': os.path.join(self.grassdatabase,
  832. self.xylocation,
  833. self.xymapset,
  834. 'group',
  835. self.xygroup,
  836. 'VREF'),
  837. 'target': os.path.join(self.grassdatabase,
  838. self.xylocation,
  839. self.xymapset,
  840. 'group',
  841. self.xygroup,
  842. 'TARGET'),
  843. }
  844. # make a backup of the current points file
  845. if os.path.exists(self.file['points']):
  846. shutil.copy(self.file['points'], self.file['points_bak'])
  847. # polynomial order transformation for georectification
  848. self.gr_order = 1
  849. # interpolation method for georectification
  850. self.gr_method = 'nearest'
  851. # region clipping for georectified map
  852. self.clip_to_region = False
  853. # number of GCPs selected to be used for georectification (checked)
  854. self.GCPcount = 0
  855. # forward RMS error
  856. self.fwd_rmserror = 0.0
  857. # backward RMS error
  858. self.bkw_rmserror = 0.0
  859. # list map coords and ID of map display they came from
  860. self.mapcoordlist = []
  861. self.mapcoordlist.append([0, # GCP number
  862. 0.0, # source east
  863. 0.0, # source north
  864. 0.0, # target east
  865. 0.0, # target north
  866. 0.0, # forward error
  867. 0.0]) # backward error
  868. # init vars to highlight high RMS errors
  869. self.highest_only = True
  870. self.show_unused = True
  871. self.highest_key = -1
  872. self.rmsthresh = 0
  873. self.rmsmean = 0
  874. self.rmssd = 0
  875. self.SetTarget(self.xygroup, self.currentlocation, self.currentmapset)
  876. self.itemDataMap = None
  877. # images for column sorting
  878. # CheckListCtrlMixin must set an ImageList first
  879. self.il = self.list.GetImageList(wx.IMAGE_LIST_SMALL)
  880. SmallUpArrow = wx.BitmapFromImage(getSmallUpArrowImage())
  881. SmallDnArrow = wx.BitmapFromImage(getSmallDnArrowImage())
  882. self.sm_dn = self.il.Add(SmallDnArrow)
  883. self.sm_up = self.il.Add(SmallUpArrow)
  884. # set mouse characteristics
  885. self.mapwin = self.SrcMapWindow
  886. self.mapwin.mouse['box'] = 'point'
  887. self.mapwin.mouse["use"] == "pointer"
  888. self.mapwin.zoomtype = 0
  889. self.mapwin.pen = wx.Pen(colour='black', width=2, style=wx.SOLID)
  890. self.mapwin.SetNamedCursor('cross')
  891. self.mapwin = self.TgtMapWindow
  892. # set mouse characteristics
  893. self.mapwin.mouse['box'] = 'point'
  894. self.mapwin.mouse["use"] == "pointer"
  895. self.mapwin.zoomtype = 0
  896. self.mapwin.pen = wx.Pen(colour='black', width=2, style=wx.SOLID)
  897. self.mapwin.SetNamedCursor('cross')
  898. #
  899. # show new display & draw map
  900. #
  901. if self.show_target:
  902. self.MapWindow = self.TgtMapWindow
  903. self.Map = self.TgtMap
  904. self.OnZoomToMap(None)
  905. self.MapWindow = self.SrcMapWindow
  906. self.Map = self.SrcMap
  907. self.OnZoomToMap(None)
  908. #
  909. # bindings
  910. #
  911. self.Bind(wx.EVT_ACTIVATE, self.OnFocus)
  912. self.Bind(wx.EVT_SIZE, self.OnSize)
  913. self.Bind(wx.EVT_IDLE, self.OnIdle)
  914. self.Bind(wx.EVT_CLOSE, self.OnQuit)
  915. self.SetSettings()
  916. def __del__(self):
  917. """Disable GCP manager mode"""
  918. # leaving the method here but was used only to delete gcpmanagement
  919. # from layer manager which is now not needed
  920. pass
  921. def CreateGCPList(self):
  922. """Create GCP List Control"""
  923. return GCPList(parent=self, gcp=self)
  924. # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
  925. def GetListCtrl(self):
  926. return self.list
  927. def GetMapCoordList(self):
  928. return self.mapcoordlist
  929. # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
  930. def GetSortImages(self):
  931. return (self.sm_dn, self.sm_up)
  932. def GetFwdError(self):
  933. return self.fwd_rmserror
  934. def GetBkwError(self):
  935. return self.bkw_rmserror
  936. def InitMapDisplay(self):
  937. self.list.LoadData()
  938. # initialize column sorter
  939. self.itemDataMap = self.mapcoordlist
  940. ncols = self.list.GetColumnCount()
  941. ColumnSorterMixin.__init__(self, ncols)
  942. # init to ascending sort on first click
  943. self._colSortFlag = [1] * ncols
  944. def SetTarget(self, tgroup, tlocation, tmapset):
  945. """
  946. Sets rectification target to current location and mapset
  947. """
  948. # check to see if we are georectifying map in current working
  949. # location/mapset
  950. if self.newlocation == self.currentlocation and self.newmapset == self.currentmapset:
  951. RunCommand('i.target',
  952. parent=self,
  953. flags='c',
  954. group=tgroup)
  955. else:
  956. self.grwiz.SwitchEnv('source')
  957. RunCommand('i.target',
  958. parent=self,
  959. group=tgroup,
  960. location=tlocation,
  961. mapset=tmapset)
  962. self.grwiz.SwitchEnv('target')
  963. def AddGCP(self, event):
  964. """
  965. Appends an item to GCP list
  966. """
  967. keyval = self.list.AddGCPItem() + 1
  968. # source east, source north, target east, target north, forward error,
  969. # backward error
  970. self.mapcoordlist.append([keyval, # GCP number
  971. 0.0, # source east
  972. 0.0, # source north
  973. 0.0, # target east
  974. 0.0, # target north
  975. 0.0, # forward error
  976. 0.0]) # backward error
  977. if self.statusbarManager.GetMode() == 8: # go to
  978. self.StatusbarUpdate()
  979. def DeleteGCP(self, event):
  980. """
  981. Deletes selected item in GCP list
  982. """
  983. minNumOfItems = self.OnGROrder(None)
  984. if self.list.GetItemCount() <= minNumOfItems:
  985. GMessage(
  986. parent=self,
  987. message=_("At least %d GCPs required. Operation canceled.") %
  988. minNumOfItems)
  989. return
  990. key = self.list.DeleteGCPItem()
  991. del self.mapcoordlist[key]
  992. # update key and GCP number
  993. for newkey in range(key, len(self.mapcoordlist)):
  994. index = self.list.FindItemData(-1, newkey + 1)
  995. self.mapcoordlist[newkey][0] = newkey
  996. self.list.SetStringItem(index, 0, str(newkey))
  997. self.list.SetItemData(index, newkey)
  998. # update selected
  999. if self.list.GetItemCount() > 0:
  1000. if self.list.selected < self.list.GetItemCount():
  1001. self.list.selectedkey = self.list.GetItemData(
  1002. self.list.selected)
  1003. else:
  1004. self.list.selected = self.list.GetItemCount() - 1
  1005. self.list.selectedkey = self.list.GetItemData(
  1006. self.list.selected)
  1007. self.list.SetItemState(self.list.selected,
  1008. wx.LIST_STATE_SELECTED,
  1009. wx.LIST_STATE_SELECTED)
  1010. else:
  1011. self.list.selected = wx.NOT_FOUND
  1012. self.list.selectedkey = -1
  1013. self.UpdateColours()
  1014. if self.statusbarManager.GetMode() == 8: # go to
  1015. self.StatusbarUpdate()
  1016. if self.list.selectedkey > 0:
  1017. self.statusbarManager.SetProperty(
  1018. 'gotoGCP', self.list.selectedkey)
  1019. def ClearGCP(self, event):
  1020. """
  1021. Clears all values in selected item of GCP list and unchecks it
  1022. """
  1023. index = self.list.GetSelected()
  1024. key = self.list.GetItemData(index)
  1025. for i in range(1, 5):
  1026. self.list.SetStringItem(index, i, '0.0')
  1027. self.list.SetStringItem(index, 5, '')
  1028. self.list.SetStringItem(index, 6, '')
  1029. self.list.CheckItem(index, False)
  1030. # GCP number, source E, source N, target E, target N, fwd error, bkwd
  1031. # error
  1032. self.mapcoordlist[key] = [key, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
  1033. def SetSettings(self):
  1034. """Sets settings for drawing of GCP's.
  1035. """
  1036. self.highest_only = UserSettings.Get(
  1037. group='gcpman', key='rms', subkey='highestonly')
  1038. self.show_unused = UserSettings.Get(
  1039. group='gcpman', key='symbol', subkey='unused')
  1040. colours = {"color": "default",
  1041. "hcolor": "highest",
  1042. "scolor": "selected",
  1043. "ucolor": "unused"}
  1044. wpx = UserSettings.Get(group='gcpman', key='symbol', subkey='width')
  1045. for k, v in colours.iteritems():
  1046. col = UserSettings.Get(group='gcpman', key='symbol', subkey=k)
  1047. self.pointsToDrawSrc.GetPen(v).SetColour(wx.Colour(
  1048. col[0], col[1], col[2], 255)) # TODO GetPen neni to spatne?
  1049. self.pointsToDrawTgt.GetPen(v).SetColour(
  1050. wx.Colour(col[0], col[1], col[2], 255))
  1051. self.pointsToDrawSrc.GetPen(v).SetWidth(wpx)
  1052. self.pointsToDrawTgt.GetPen(v).SetWidth(wpx)
  1053. spx = UserSettings.Get(group='gcpman', key='symbol', subkey='size')
  1054. self.pointsToDrawSrc.SetPropertyVal("size", int(spx))
  1055. self.pointsToDrawTgt.SetPropertyVal("size", int(spx))
  1056. font = self.GetFont()
  1057. font.SetPointSize(int(spx) + 2)
  1058. textProp = {}
  1059. textProp['active'] = True
  1060. textProp['font'] = font
  1061. self.pointsToDrawSrc.SetPropertyVal("text", textProp)
  1062. self.pointsToDrawTgt.SetPropertyVal("text", copy(textProp))
  1063. def SetGCPSatus(self, item, itemIndex):
  1064. """Before GCP is drawn, decides it's colour and whether it
  1065. will be drawed.
  1066. """
  1067. key = self.list.GetItemData(itemIndex)
  1068. # incremented because of itemDataMap (has one more item) - will be
  1069. # changed
  1070. itemIndex += 1
  1071. if not self.list.IsChecked(key - 1):
  1072. wxPen = "unused"
  1073. if not self.show_unused:
  1074. item.SetPropertyVal('hide', True)
  1075. else:
  1076. item.SetPropertyVal('hide', False)
  1077. else:
  1078. item.SetPropertyVal('hide', False)
  1079. if self.highest_only == True:
  1080. if itemIndex == self.highest_key:
  1081. wxPen = "highest"
  1082. else:
  1083. wxPen = "default"
  1084. else:
  1085. if (self.mapcoordlist[key][5] > self.rmsthresh):
  1086. wxPen = "highest"
  1087. else:
  1088. wxPen = "default"
  1089. if itemIndex == self.list.selectedkey:
  1090. wxPen = "selected"
  1091. item.SetPropertyVal('label', str(itemIndex))
  1092. item.SetPropertyVal('penName', wxPen)
  1093. def SetGCPData(self, coordtype, coord, mapdisp=None, confirm=False):
  1094. """Inserts coordinates from file, mouse click on map, or
  1095. after editing into selected item of GCP list and checks it for
  1096. use.
  1097. """
  1098. index = self.list.GetSelected()
  1099. if index == wx.NOT_FOUND:
  1100. return
  1101. coord0 = coord[0]
  1102. coord1 = coord[1]
  1103. key = self.list.GetItemData(index)
  1104. if confirm:
  1105. if self.MapWindow == self.SrcMapWindow:
  1106. currloc = _("source")
  1107. else:
  1108. currloc = _("target")
  1109. ret = wx.MessageBox(
  1110. parent=self, caption=_("Set GCP coordinates"),
  1111. message=_(
  1112. 'Set %(coor)s coordinates for GCP No. %(key)s? \n\n'
  1113. 'East: %(coor0)s \n'
  1114. 'North: %(coor1)s') %
  1115. {'coor': currloc, 'key': str(key),
  1116. 'coor0': str(coord0),
  1117. 'coor1': str(coord1)},
  1118. style=wx.ICON_QUESTION | wx.YES_NO | wx.CENTRE)
  1119. # for wingrass
  1120. if os.name == 'nt':
  1121. self.MapWindow.SetFocus()
  1122. if ret == wx.NO:
  1123. return
  1124. if coordtype == 'source':
  1125. self.list.SetStringItem(index, 1, str(coord0))
  1126. self.list.SetStringItem(index, 2, str(coord1))
  1127. self.mapcoordlist[key][1] = coord[0]
  1128. self.mapcoordlist[key][2] = coord[1]
  1129. self.pointsToDrawSrc.GetItem(key - 1).SetCoords([coord0, coord1])
  1130. elif coordtype == 'target':
  1131. self.list.SetStringItem(index, 3, str(coord0))
  1132. self.list.SetStringItem(index, 4, str(coord1))
  1133. self.mapcoordlist[key][3] = coord[0]
  1134. self.mapcoordlist[key][4] = coord[1]
  1135. self.pointsToDrawTgt.GetItem(key - 1).SetCoords([coord0, coord1])
  1136. self.list.SetStringItem(index, 5, '0')
  1137. self.list.SetStringItem(index, 6, '0')
  1138. self.mapcoordlist[key][5] = 0.0
  1139. self.mapcoordlist[key][6] = 0.0
  1140. # self.list.ResizeColumns()
  1141. def SaveGCPs(self, event):
  1142. """Make a POINTS file or save GCP coordinates to existing
  1143. POINTS file
  1144. """
  1145. self.GCPcount = 0
  1146. try:
  1147. f = open(self.file['points'], mode='w')
  1148. # use os.linesep or '\n' here ???
  1149. f.write('# Ground Control Points File\n')
  1150. f.write("# \n")
  1151. f.write("# target location: " + self.currentlocation + '\n')
  1152. f.write("# target mapset: " + self.currentmapset + '\n')
  1153. f.write("#\tsource\t\ttarget\t\tstatus\n")
  1154. f.write("#\teast\tnorth\teast\tnorth\t(1=ok, 0=ignore)\n")
  1155. f.write(
  1156. "#----------------------- ----------------------- ---------------\n")
  1157. for index in range(self.list.GetItemCount()):
  1158. if self.list.IsChecked(index) == True:
  1159. check = "1"
  1160. self.GCPcount += 1
  1161. else:
  1162. check = "0"
  1163. coord0 = self.list.GetItem(index, 1).GetText()
  1164. coord1 = self.list.GetItem(index, 2).GetText()
  1165. coord2 = self.list.GetItem(index, 3).GetText()
  1166. coord3 = self.list.GetItem(index, 4).GetText()
  1167. f.write(
  1168. coord0 +
  1169. ' ' +
  1170. coord1 +
  1171. ' ' +
  1172. coord2 +
  1173. ' ' +
  1174. coord3 +
  1175. ' ' +
  1176. check +
  1177. '\n')
  1178. except IOError as err:
  1179. GError(
  1180. parent=self,
  1181. message="%s <%s>. %s%s" %
  1182. (_("Writing POINTS file failed"),
  1183. self.file['points'],
  1184. os.linesep,
  1185. err))
  1186. return
  1187. f.close()
  1188. # if event != None save also to backup file
  1189. if event:
  1190. shutil.copy(self.file['points'], self.file['points_bak'])
  1191. self._giface.WriteLog(
  1192. _('POINTS file saved for group <%s>') %
  1193. self.xygroup)
  1194. #self.SetStatusText(_('POINTS file saved'))
  1195. def ReadGCPs(self):
  1196. """
  1197. Reads GCPs and georectified coordinates from POINTS file
  1198. """
  1199. self.GCPcount = 0
  1200. sourceMapWin = self.SrcMapWindow
  1201. targetMapWin = self.TgtMapWindow
  1202. if not sourceMapWin:
  1203. GError(parent=self,
  1204. message="%s. %s%s" % (_("source mapwin not defined"),
  1205. os.linesep, err))
  1206. if not targetMapWin:
  1207. GError(parent=self,
  1208. message="%s. %s%s" % (_("target mapwin not defined"),
  1209. os.linesep, err))
  1210. try:
  1211. f = open(self.file['points'], 'r')
  1212. GCPcnt = 0
  1213. for line in f.readlines():
  1214. if line[0] == '#' or line == '':
  1215. continue
  1216. line = line.replace('\n', '').strip()
  1217. coords = map(float, line.split())
  1218. if coords[4] == 1:
  1219. check = True
  1220. self.GCPcount += 1
  1221. else:
  1222. check = False
  1223. self.AddGCP(event=None)
  1224. self.SetGCPData('source', (coords[0], coords[1]), sourceMapWin)
  1225. self.SetGCPData('target', (coords[2], coords[3]), targetMapWin)
  1226. index = self.list.GetSelected()
  1227. if index != wx.NOT_FOUND:
  1228. self.list.CheckItem(index, check)
  1229. GCPcnt += 1
  1230. except IOError as err:
  1231. GError(
  1232. parent=self,
  1233. message="%s <%s>. %s%s" %
  1234. (_("Reading POINTS file failed"),
  1235. self.file['points'],
  1236. os.linesep,
  1237. err))
  1238. return
  1239. f.close()
  1240. if GCPcnt == 0:
  1241. # 3 gcp is minimum
  1242. for i in range(3):
  1243. self.AddGCP(None)
  1244. if self.CheckGCPcount():
  1245. # calculate RMS
  1246. self.RMSError(self.xygroup, self.gr_order)
  1247. def ReloadGCPs(self, event):
  1248. """Reload data from file"""
  1249. # use backup
  1250. shutil.copy(self.file['points_bak'], self.file['points'])
  1251. # delete all items in mapcoordlist
  1252. self.mapcoordlist = []
  1253. self.mapcoordlist.append([0, # GCP number
  1254. 0.0, # source east
  1255. 0.0, # source north
  1256. 0.0, # target east
  1257. 0.0, # target north
  1258. 0.0, # forward error
  1259. 0.0]) # backward error
  1260. self.list.LoadData()
  1261. self.itemDataMap = self.mapcoordlist
  1262. if self._col != -1:
  1263. self.list.ClearColumnImage(self._col)
  1264. self._colSortFlag = [1] * self.list.GetColumnCount()
  1265. # draw GCPs (source and target)
  1266. sourceMapWin = self.SrcMapWindow
  1267. sourceMapWin.UpdateMap(render=False, renderVector=False)
  1268. if self.show_target:
  1269. targetMapWin = self.TgtMapWindow
  1270. targetMapWin.UpdateMap(render=False, renderVector=False)
  1271. def OnFocus(self, event):
  1272. # TODO: it is here just to remove old or obsolate beavior of base class gcp/MapFrame?
  1273. # self.grwiz.SwitchEnv('source')
  1274. pass
  1275. def _onMouseLeftUpPointer(self, mapWindow, x, y):
  1276. if mapWindow == self.SrcMapWindow:
  1277. coordtype = 'source'
  1278. else:
  1279. coordtype = 'target'
  1280. coord = (x, y)
  1281. self.SetGCPData(coordtype, coord, self, confirm=True)
  1282. mapWindow.UpdateMap(render=False, renderVector=False)
  1283. def OnRMS(self, event):
  1284. """
  1285. RMS button handler
  1286. """
  1287. self.RMSError(self.xygroup, self.gr_order)
  1288. sourceMapWin = self.SrcMapWindow
  1289. sourceMapWin.UpdateMap(render=False, renderVector=False)
  1290. if self.show_target:
  1291. targetMapWin = self.TgtMapWindow
  1292. targetMapWin.UpdateMap(render=False, renderVector=False)
  1293. def CheckGCPcount(self, msg=False):
  1294. """
  1295. Checks to make sure that the minimum number of GCPs have been defined and
  1296. are active for the selected transformation order
  1297. """
  1298. if (self.GCPcount < 3 and self.gr_order == 1) or \
  1299. (self.GCPcount < 6 and self.gr_order == 2) or \
  1300. (self.GCPcount < 10 and self.gr_order == 3):
  1301. if msg:
  1302. GWarning(
  1303. parent=self, message=_(
  1304. 'Insufficient points defined and active (checked) '
  1305. 'for selected rectification method (order: %d).\n'
  1306. '3+ points needed for 1st order,\n'
  1307. '6+ points for 2nd order, and\n'
  1308. '10+ points for 3rd order.') %
  1309. self.gr_order)
  1310. return False
  1311. else:
  1312. return True
  1313. def OnGeorect(self, event):
  1314. """
  1315. Georectifies map(s) in group using i.rectify or v.transform
  1316. """
  1317. global maptype
  1318. self.SaveGCPs(None)
  1319. if self.CheckGCPcount(msg=True) == False:
  1320. return
  1321. if maptype == 'raster':
  1322. self.grwiz.SwitchEnv('source')
  1323. if self.clip_to_region:
  1324. flags = "ac"
  1325. else:
  1326. flags = "a"
  1327. busy = wx.BusyInfo(message=_("Rectifying images, please wait..."),
  1328. parent=self)
  1329. wx.Yield()
  1330. ret, msg = RunCommand('i.rectify',
  1331. parent=self,
  1332. getErrorMsg=True,
  1333. quiet=True,
  1334. group=self.xygroup,
  1335. extension=self.extension,
  1336. order=self.gr_order,
  1337. method=self.gr_method,
  1338. flags=flags)
  1339. busy.Destroy()
  1340. # provide feedback on failure
  1341. if ret != 0:
  1342. print >> sys.stderr, msg
  1343. elif maptype == 'vector':
  1344. # loop through all vectors in VREF
  1345. self.grwiz.SwitchEnv('source')
  1346. # make list of vectors to georectify from VREF
  1347. f = open(self.file['vgrp'])
  1348. vectlist = []
  1349. try:
  1350. for vect in f.readlines():
  1351. vect = vect.strip('\n')
  1352. if len(vect) < 1:
  1353. continue
  1354. vectlist.append(vect)
  1355. finally:
  1356. f.close()
  1357. # georectify each vector in VREF using v.rectify
  1358. for vect in vectlist:
  1359. self.outname = str(vect.split('@')[0]) + self.extension
  1360. self._giface.WriteLog(text=_('Transforming <%s>...') % vect,
  1361. notification=Notification.MAKE_VISIBLE)
  1362. ret = msg = ''
  1363. busy = wx.BusyInfo(
  1364. message=_("Rectifying vector map <%s>, please wait...") %
  1365. vect, parent=self)
  1366. wx.Yield()
  1367. ret, msg = RunCommand('v.rectify',
  1368. parent=self,
  1369. getErrorMsg=True,
  1370. quiet=True,
  1371. input=vect,
  1372. output=self.outname,
  1373. group=self.xygroup,
  1374. order=self.gr_order)
  1375. busy.Destroy()
  1376. # provide feedback on failure
  1377. if ret != 0:
  1378. print >> sys.stderr, msg
  1379. self.grwiz.SwitchEnv('target')
  1380. def OnGeorectDone(self, **kargs):
  1381. """Print final message"""
  1382. global maptype
  1383. if maptype == 'raster':
  1384. return
  1385. returncode = kargs['returncode']
  1386. if returncode == 0:
  1387. self.VectGRList.append(self.outname)
  1388. print '*****vector list = ' + str(self.VectGRList)
  1389. else:
  1390. self._giface.WriteError(
  1391. _('Georectification of vector map <%s> failed') %
  1392. self.outname)
  1393. def OnSettings(self, event):
  1394. """GCP Manager settings"""
  1395. dlg = GrSettingsDialog(parent=self, giface=self._giface,
  1396. id=wx.ID_ANY, title=_('GCP Manager settings'))
  1397. if dlg.ShowModal() == wx.ID_OK:
  1398. pass
  1399. dlg.Destroy()
  1400. def UpdateColours(self, srcrender=False, srcrenderVector=False,
  1401. tgtrender=False, tgtrenderVector=False):
  1402. """update colours"""
  1403. highest_fwd_err = 0.0
  1404. self.highest_key = 0
  1405. highest_idx = 0
  1406. for index in range(self.list.GetItemCount()):
  1407. if self.list.IsChecked(index):
  1408. key = self.list.GetItemData(index)
  1409. fwd_err = self.mapcoordlist[key][5]
  1410. if self.highest_only == True:
  1411. self.list.SetItemTextColour(index, wx.BLACK)
  1412. if highest_fwd_err < fwd_err:
  1413. highest_fwd_err = fwd_err
  1414. self.highest_key = key
  1415. highest_idx = index
  1416. elif self.rmsthresh > 0:
  1417. if (fwd_err > self.rmsthresh):
  1418. self.list.SetItemTextColour(index, wx.RED)
  1419. else:
  1420. self.list.SetItemTextColour(index, wx.BLACK)
  1421. else:
  1422. self.list.SetItemTextColour(index, wx.BLACK)
  1423. if self.highest_only and highest_fwd_err > 0.0:
  1424. self.list.SetItemTextColour(highest_idx, wx.RED)
  1425. sourceMapWin = self.SrcMapWindow
  1426. sourceMapWin.UpdateMap(render=srcrender, renderVector=srcrenderVector)
  1427. if self.show_target:
  1428. targetMapWin = self.TgtMapWindow
  1429. targetMapWin.UpdateMap(
  1430. render=tgtrender,
  1431. renderVector=tgtrenderVector)
  1432. def OnQuit(self, event):
  1433. """Quit georectifier"""
  1434. ret = wx.MessageBox(
  1435. parent=self, caption=_("Quit GCP Manager"),
  1436. message=_('Save ground control points?'),
  1437. style=wx.ICON_QUESTION | wx.YES_NO | wx.CANCEL | wx.CENTRE)
  1438. if ret != wx.CANCEL:
  1439. if ret == wx.YES:
  1440. self.SaveGCPs(None)
  1441. elif ret == wx.NO:
  1442. # restore POINTS file from backup
  1443. if os.path.exists(self.file['points_bak']):
  1444. shutil.copy(self.file['points_bak'], self.file['points'])
  1445. if os.path.exists(self.file['points_bak']):
  1446. os.unlink(self.file['points_bak'])
  1447. self.SrcMap.Clean()
  1448. self.TgtMap.Clean()
  1449. self.grwiz.Cleanup()
  1450. self.Destroy()
  1451. # event.Skip()
  1452. def OnGROrder(self, event):
  1453. """
  1454. sets transformation order for georectifying
  1455. """
  1456. if event:
  1457. self.gr_order = event.GetInt() + 1
  1458. numOfItems = self.list.GetItemCount()
  1459. minNumOfItems = numOfItems
  1460. if self.gr_order == 1:
  1461. minNumOfItems = 3
  1462. # self.SetStatusText(_('Insufficient points, 3+ points needed for 1st order'))
  1463. elif self.gr_order == 2:
  1464. minNumOfItems = 6
  1465. diff = 6 - numOfItems
  1466. # self.SetStatusText(_('Insufficient points, 6+ points needed for 2nd order'))
  1467. elif self.gr_order == 3:
  1468. minNumOfItems = 10
  1469. # self.SetStatusText(_('Insufficient points, 10+ points needed for 3rd order'))
  1470. for i in range(minNumOfItems - numOfItems):
  1471. self.AddGCP(None)
  1472. return minNumOfItems
  1473. def RMSError(self, xygroup, order):
  1474. """
  1475. Uses m.transform to calculate forward and backward error for each used GCP
  1476. in POINTS file and insert error values into GCP list.
  1477. Calculates total forward and backward RMS error for all used points
  1478. """
  1479. # save GCPs to points file to make sure that all checked GCPs are used
  1480. self.SaveGCPs(None)
  1481. # self.SetStatusText('')
  1482. if self.CheckGCPcount(msg=True) == False:
  1483. return
  1484. # get list of forward and reverse rms error values for each point
  1485. self.grwiz.SwitchEnv('source')
  1486. ret = RunCommand('m.transform',
  1487. parent=self,
  1488. read=True,
  1489. group=xygroup,
  1490. order=order)
  1491. self.grwiz.SwitchEnv('target')
  1492. if ret:
  1493. errlist = ret.splitlines()
  1494. else:
  1495. GError(parent=self,
  1496. message=_('Could not calculate RMS Error.\n'
  1497. 'Possible error with m.transform.'))
  1498. return
  1499. # insert error values into GCP list for checked items
  1500. sdfactor = float(
  1501. UserSettings.Get(
  1502. group='gcpman',
  1503. key='rms',
  1504. subkey='sdfactor'))
  1505. GCPcount = 0
  1506. sumsq_fwd_err = 0.0
  1507. sumsq_bkw_err = 0.0
  1508. sum_fwd_err = 0.0
  1509. highest_fwd_err = 0.0
  1510. self.highest_key = 0
  1511. highest_idx = 0
  1512. for index in range(self.list.GetItemCount()):
  1513. key = self.list.GetItemData(index)
  1514. if self.list.IsChecked(index):
  1515. fwd_err, bkw_err = errlist[GCPcount].split()
  1516. self.list.SetStringItem(index, 5, fwd_err)
  1517. self.list.SetStringItem(index, 6, bkw_err)
  1518. self.mapcoordlist[key][5] = float(fwd_err)
  1519. self.mapcoordlist[key][6] = float(bkw_err)
  1520. self.list.SetItemTextColour(index, wx.BLACK)
  1521. if self.highest_only:
  1522. if highest_fwd_err < float(fwd_err):
  1523. highest_fwd_err = float(fwd_err)
  1524. self.highest_key = key
  1525. highest_idx = index
  1526. sumsq_fwd_err += float(fwd_err)**2
  1527. sumsq_bkw_err += float(bkw_err)**2
  1528. sum_fwd_err += float(fwd_err)
  1529. GCPcount += 1
  1530. else:
  1531. self.list.SetStringItem(index, 5, '')
  1532. self.list.SetStringItem(index, 6, '')
  1533. self.mapcoordlist[key][5] = 0.0
  1534. self.mapcoordlist[key][6] = 0.0
  1535. self.list.SetItemTextColour(index, wx.BLACK)
  1536. # SD
  1537. if GCPcount > 0:
  1538. self.rmsmean = sum_fwd_err / GCPcount
  1539. self.rmssd = ((sumsq_fwd_err - self.rmsmean**2)**0.5)
  1540. self.rmsthresh = self.rmsmean + sdfactor * self.rmssd
  1541. else:
  1542. self.rmsthresh = 0
  1543. self.rmsmean = 0
  1544. self.rmssd = 0
  1545. if self.highest_only and highest_fwd_err > 0.0:
  1546. self.list.SetItemTextColour(highest_idx, wx.RED)
  1547. elif GCPcount > 0 and self.rmsthresh > 0 and not self.highest_only:
  1548. for index in range(self.list.GetItemCount()):
  1549. if self.list.IsChecked(index):
  1550. key = self.list.GetItemData(index)
  1551. if (self.mapcoordlist[key][5] > self.rmsthresh):
  1552. self.list.SetItemTextColour(index, wx.RED)
  1553. # calculate global RMS error (geometric mean)
  1554. self.fwd_rmserror = round((sumsq_fwd_err / GCPcount)**0.5, 4)
  1555. self.bkw_rmserror = round((sumsq_bkw_err / GCPcount)**0.5, 4)
  1556. self.list.ResizeColumns()
  1557. def GetNewExtent(self, region, map=None):
  1558. coord_file = utils.GetTempfile()
  1559. newreg = {'n': 0.0, 's': 0.0, 'e': 0.0, 'w': 0.0, }
  1560. try:
  1561. f = open(coord_file, mode='w')
  1562. # NW corner
  1563. f.write(str(region['e']) + " " + str(region['n']) + "\n")
  1564. # NE corner
  1565. f.write(str(region['e']) + " " + str(region['s']) + "\n")
  1566. # SW corner
  1567. f.write(str(region['w']) + " " + str(region['n']) + "\n")
  1568. # SE corner
  1569. f.write(str(region['w']) + " " + str(region['s']) + "\n")
  1570. finally:
  1571. f.close()
  1572. # save GCPs to points file to make sure that all checked GCPs are used
  1573. self.SaveGCPs(None)
  1574. order = self.gr_order
  1575. self.gr_order = 1
  1576. if self.CheckGCPcount(msg=True) == False:
  1577. self.gr_order = order
  1578. return
  1579. self.gr_order = order
  1580. # get list of forward and reverse rms error values for each point
  1581. self.grwiz.SwitchEnv('source')
  1582. if map == 'source':
  1583. ret = RunCommand('m.transform',
  1584. parent=self,
  1585. read=True,
  1586. group=self.xygroup,
  1587. order=1,
  1588. format='dst',
  1589. coords=coord_file)
  1590. elif map == 'target':
  1591. ret = RunCommand('m.transform',
  1592. parent=self,
  1593. read=True,
  1594. group=self.xygroup,
  1595. order=1,
  1596. flags='r',
  1597. format='src',
  1598. coords=coord_file)
  1599. os.unlink(coord_file)
  1600. self.grwiz.SwitchEnv('target')
  1601. if ret:
  1602. errlist = ret.splitlines()
  1603. else:
  1604. GError(parent=self,
  1605. message=_('Could not calculate new extends.\n'
  1606. 'Possible error with m.transform.'))
  1607. return
  1608. # fist corner
  1609. e, n = errlist[0].split()
  1610. fe = float(e)
  1611. fn = float(n)
  1612. newreg['n'] = fn
  1613. newreg['s'] = fn
  1614. newreg['e'] = fe
  1615. newreg['w'] = fe
  1616. # other three corners
  1617. for i in range(1, 4):
  1618. e, n = errlist[i].split()
  1619. fe = float(e)
  1620. fn = float(n)
  1621. if fe < newreg['w']:
  1622. newreg['w'] = fe
  1623. if fe > newreg['e']:
  1624. newreg['e'] = fe
  1625. if fn < newreg['s']:
  1626. newreg['s'] = fn
  1627. if fn > newreg['n']:
  1628. newreg['n'] = fn
  1629. return newreg
  1630. def OnHelp(self, event):
  1631. """Show GCP Manager manual page"""
  1632. self._giface.Help(entry='wxGUI.gcp')
  1633. def OnUpdateActive(self, event):
  1634. if self.activemap.GetSelection() == 0:
  1635. self.MapWindow = self.SrcMapWindow
  1636. self.Map = self.SrcMap
  1637. else:
  1638. self.MapWindow = self.TgtMapWindow
  1639. self.Map = self.TgtMap
  1640. self.UpdateActive(self.MapWindow)
  1641. # for wingrass
  1642. if os.name == 'nt':
  1643. self.MapWindow.SetFocus()
  1644. def UpdateActive(self, win):
  1645. # optionally disable tool zoomback tool
  1646. self.GetMapToolbar().Enable('zoomback',
  1647. enable=(len(self.MapWindow.zoomhistory) > 1))
  1648. if self.activemap.GetSelection() != (win == self.TgtMapWindow):
  1649. self.activemap.SetSelection(win == self.TgtMapWindow)
  1650. self.StatusbarUpdate()
  1651. def AdjustMap(self, newreg):
  1652. """Adjust map window to new extents
  1653. """
  1654. # adjust map window
  1655. self.Map.region['n'] = newreg['n']
  1656. self.Map.region['s'] = newreg['s']
  1657. self.Map.region['e'] = newreg['e']
  1658. self.Map.region['w'] = newreg['w']
  1659. self.MapWindow.ZoomHistory(self.Map.region['n'], self.Map.region['s'],
  1660. self.Map.region['e'], self.Map.region['w'])
  1661. # LL locations
  1662. if self.Map.projinfo['proj'] == 'll':
  1663. if newreg['n'] > 90.0:
  1664. newreg['n'] = 90.0
  1665. if newreg['s'] < -90.0:
  1666. newreg['s'] = -90.0
  1667. ce = newreg['w'] + (newreg['e'] - newreg['w']) / 2
  1668. cn = newreg['s'] + (newreg['n'] - newreg['s']) / 2
  1669. # calculate new center point and display resolution
  1670. self.Map.region['center_easting'] = ce
  1671. self.Map.region['center_northing'] = cn
  1672. self.Map.region["ewres"] = (newreg['e'] - newreg['w']) / self.Map.width
  1673. self.Map.region["nsres"] = (
  1674. newreg['n'] - newreg['s']) / self.Map.height
  1675. self.Map.AlignExtentFromDisplay()
  1676. self.MapWindow.ZoomHistory(self.Map.region['n'], self.Map.region['s'],
  1677. self.Map.region['e'], self.Map.region['w'])
  1678. if self.MapWindow.redrawAll is False:
  1679. self.MapWindow.redrawAll = True
  1680. self.MapWindow.UpdateMap()
  1681. self.StatusbarUpdate()
  1682. def OnZoomToSource(self, event):
  1683. """Set target map window to match extents of source map window
  1684. """
  1685. if not self.MapWindow == self.TgtMapWindow:
  1686. self.MapWindow = self.TgtMapWindow
  1687. self.Map = self.TgtMap
  1688. self.UpdateActive(self.TgtMapWindow)
  1689. # get new N, S, E, W for target
  1690. newreg = self.GetNewExtent(self.SrcMap.region, 'source')
  1691. if newreg:
  1692. self.AdjustMap(newreg)
  1693. def OnZoomToTarget(self, event):
  1694. """Set source map window to match extents of target map window
  1695. """
  1696. if not self.MapWindow == self.SrcMapWindow:
  1697. self.MapWindow = self.SrcMapWindow
  1698. self.Map = self.SrcMap
  1699. self.UpdateActive(self.SrcMapWindow)
  1700. # get new N, S, E, W for target
  1701. newreg = self.GetNewExtent(self.TgtMap.region, 'target')
  1702. if newreg:
  1703. self.AdjustMap(newreg)
  1704. def OnZoomMenuGCP(self, event):
  1705. """Popup Zoom menu
  1706. """
  1707. point = wx.GetMousePosition()
  1708. zoommenu = wx.Menu()
  1709. # Add items to the menu
  1710. zoomsource = wx.MenuItem(zoommenu, wx.ID_ANY, _(
  1711. 'Adjust source display to target display'))
  1712. zoommenu.AppendItem(zoomsource)
  1713. self.Bind(wx.EVT_MENU, self.OnZoomToTarget, zoomsource)
  1714. zoomtarget = wx.MenuItem(zoommenu, wx.ID_ANY, _(
  1715. 'Adjust target display to source display'))
  1716. zoommenu.AppendItem(zoomtarget)
  1717. self.Bind(wx.EVT_MENU, self.OnZoomToSource, zoomtarget)
  1718. # Popup the menu. If an item is selected then its handler
  1719. # will be called before PopupMenu returns.
  1720. self.PopupMenu(zoommenu)
  1721. zoommenu.Destroy()
  1722. def OnSize(self, event):
  1723. """Adjust Map Windows after GCP Map Display has been resized
  1724. """
  1725. # re-render image on idle
  1726. self.resize = time.clock()
  1727. super(MapFrame, self).OnSize(event)
  1728. def OnIdle(self, event):
  1729. """GCP Map Display resized, adjust Map Windows
  1730. """
  1731. if self.GetMapToolbar():
  1732. if self.resize and self.resize + 0.2 < time.clock():
  1733. srcwidth, srcheight = self.SrcMapWindow.GetSize()
  1734. tgtwidth, tgtheight = self.TgtMapWindow.GetSize()
  1735. srcwidth = (srcwidth + tgtwidth) / 2
  1736. if self.show_target:
  1737. self._mgr.GetPane("target").Hide()
  1738. self._mgr.Update()
  1739. self._mgr.GetPane("source").BestSize((srcwidth, srcheight))
  1740. self._mgr.GetPane("target").BestSize((srcwidth, tgtheight))
  1741. if self.show_target:
  1742. self._mgr.GetPane("target").Show()
  1743. self._mgr.Update()
  1744. self.resize = False
  1745. elif self.resize:
  1746. event.RequestMore()
  1747. pass
  1748. class GCPList(wx.ListCtrl,
  1749. CheckListCtrlMixin,
  1750. ListCtrlAutoWidthMixin):
  1751. def __init__(self, parent, gcp, id=wx.ID_ANY,
  1752. pos=wx.DefaultPosition, size=wx.DefaultSize,
  1753. style=wx.LC_REPORT | wx.SUNKEN_BORDER | wx.LC_HRULES |
  1754. wx.LC_SINGLE_SEL):
  1755. wx.ListCtrl.__init__(self, parent, id, pos, size, style)
  1756. self.gcp = gcp # GCP class
  1757. self.render = True
  1758. # Mixin settings
  1759. CheckListCtrlMixin.__init__(self)
  1760. ListCtrlAutoWidthMixin.__init__(self)
  1761. # TextEditMixin.__init__(self)
  1762. # tracks whether list items are checked or not
  1763. self.CheckList = []
  1764. self._Create()
  1765. self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected)
  1766. self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated)
  1767. self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick)
  1768. self.selected = wx.NOT_FOUND
  1769. self.selectedkey = -1
  1770. def _Create(self):
  1771. if 0:
  1772. # normal, simple columns
  1773. idx_col = 0
  1774. for col in (_('use'),
  1775. _('source E'),
  1776. _('source N'),
  1777. _('target E'),
  1778. _('target N'),
  1779. _('Forward error'),
  1780. _('Backward error')):
  1781. self.InsertColumn(idx_col, col)
  1782. idx_col += 1
  1783. else:
  1784. # the hard way: we want images on the column header
  1785. info = wx.ListItem()
  1786. info.SetMask(
  1787. wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT)
  1788. info.SetImage(-1)
  1789. info.m_format = wx.LIST_FORMAT_LEFT
  1790. idx_col = 0
  1791. for lbl in (_('use'),
  1792. _('source E'),
  1793. _('source N'),
  1794. _('target E'),
  1795. _('target N'),
  1796. _('Forward error'),
  1797. _('Backward error')):
  1798. info.SetText(lbl)
  1799. self.InsertColumnInfo(idx_col, info)
  1800. idx_col += 1
  1801. def LoadData(self):
  1802. """Load data into list"""
  1803. self.DeleteAllItems()
  1804. self.render = False
  1805. if os.path.isfile(self.gcp.file['points']):
  1806. self.gcp.ReadGCPs()
  1807. else:
  1808. # 3 gcp is minimum
  1809. for i in range(3):
  1810. self.gcp.AddGCP(None)
  1811. # select first point by default
  1812. self.selected = 0
  1813. self.selectedkey = self.GetItemData(self.selected)
  1814. self.SetItemState(self.selected,
  1815. wx.LIST_STATE_SELECTED,
  1816. wx.LIST_STATE_SELECTED)
  1817. self.ResizeColumns()
  1818. self.render = True
  1819. self.EnsureVisible(self.selected)
  1820. def OnCheckItem(self, index, flag):
  1821. """Item is checked/unchecked"""
  1822. if self.render:
  1823. # redraw points
  1824. sourceMapWin = self.gcp.SrcMapWindow
  1825. sourceMapWin.UpdateMap(render=False, renderVector=False)
  1826. if self.gcp.show_target:
  1827. targetMapWin = self.gcp.TgtMapWindow
  1828. targetMapWin.UpdateMap(render=False, renderVector=False)
  1829. def AddGCPItem(self):
  1830. """
  1831. Appends an item to GCP list
  1832. """
  1833. self.selectedkey = self.GetItemCount() + 1
  1834. self.Append([str(self.selectedkey), # GCP number
  1835. '0.0', # source E
  1836. '0.0', # source N
  1837. '0.0', # target E
  1838. '0.0', # target N
  1839. '', # forward error
  1840. '']) # backward error
  1841. self.selected = self.GetItemCount() - 1
  1842. self.SetItemData(self.selected, self.selectedkey)
  1843. self.SetItemState(self.selected,
  1844. wx.LIST_STATE_SELECTED,
  1845. wx.LIST_STATE_SELECTED)
  1846. self.ResizeColumns()
  1847. self.gcp.pointsToDrawSrc.AddItem(
  1848. coords=[0, 0], label=str(self.selectedkey))
  1849. self.gcp.pointsToDrawTgt.AddItem(
  1850. coords=[0, 0], label=str(self.selectedkey))
  1851. self.EnsureVisible(self.selected)
  1852. return self.selected
  1853. def DeleteGCPItem(self):
  1854. """Deletes selected item in GCP list.
  1855. """
  1856. if self.selected == wx.NOT_FOUND:
  1857. return
  1858. key = self.GetItemData(self.selected)
  1859. self.DeleteItem(self.selected)
  1860. if self.selected != wx.NOT_FOUND:
  1861. item = self.gcp.pointsToDrawSrc.GetItem(key - 1)
  1862. self.gcp.pointsToDrawSrc.DeleteItem(item)
  1863. item = self.gcp.pointsToDrawTgt.GetItem(key - 1)
  1864. self.gcp.pointsToDrawTgt.DeleteItem(item)
  1865. return key
  1866. def ResizeColumns(self):
  1867. """Resize columns"""
  1868. minWidth = [90, 120]
  1869. for i in range(self.GetColumnCount()):
  1870. self.SetColumnWidth(i, wx.LIST_AUTOSIZE)
  1871. # first column is checkbox, don't set to minWidth
  1872. if i > 0 and self.GetColumnWidth(i) < minWidth[i > 4]:
  1873. self.SetColumnWidth(i, minWidth[i > 4])
  1874. self.SendSizeEvent()
  1875. def GetSelected(self):
  1876. """Get index of selected item"""
  1877. return self.selected
  1878. def OnItemSelected(self, event):
  1879. """Item selected
  1880. """
  1881. if self.render and self.selected != event.GetIndex():
  1882. self.selected = event.GetIndex()
  1883. self.selectedkey = self.GetItemData(self.selected)
  1884. sourceMapWin = self.gcp.SrcMapWindow
  1885. sourceMapWin.UpdateMap(render=False, renderVector=False)
  1886. if self.gcp.show_target:
  1887. targetMapWin = self.gcp.TgtMapWindow
  1888. targetMapWin.UpdateMap(render=False, renderVector=False)
  1889. event.Skip()
  1890. def OnItemActivated(self, event):
  1891. """
  1892. When item double clicked, open editor to update coordinate values
  1893. """
  1894. coords = []
  1895. index = event.GetIndex()
  1896. key = self.GetItemData(index)
  1897. changed = False
  1898. for i in range(1, 5):
  1899. coords.append(self.GetItem(index, i).GetText())
  1900. dlg = EditGCP(parent=self, id=wx.ID_ANY, data=coords, gcpno=key)
  1901. if dlg.ShowModal() == wx.ID_OK:
  1902. values = dlg.GetValues() # string
  1903. if len(values) == 0:
  1904. GError(parent=self, message=_(
  1905. "Invalid coordinate value. Operation canceled."))
  1906. else:
  1907. for i in range(len(values)):
  1908. if values[i] != coords[i]:
  1909. self.SetStringItem(index, i + 1, values[i])
  1910. changed = True
  1911. if changed:
  1912. # reset RMS and update mapcoordlist
  1913. self.SetStringItem(index, 5, '')
  1914. self.SetStringItem(index, 6, '')
  1915. key = self.GetItemData(index)
  1916. self.gcp.mapcoordlist[key] = [key,
  1917. float(values[0]),
  1918. float(values[1]),
  1919. float(values[2]),
  1920. float(values[3]),
  1921. 0.0,
  1922. 0.0]
  1923. self.gcp.pointsToDrawSrc.GetItem(
  1924. key - 1).SetCoords([float(values[0]), float(values[1])])
  1925. self.gcp.pointsToDrawTgt.GetItem(
  1926. key - 1).SetCoords([float(values[2]), float(values[3])])
  1927. self.gcp.UpdateColours()
  1928. def OnColClick(self, event):
  1929. """ListCtrl forgets selected item..."""
  1930. self.selected = self.FindItemData(-1, self.selectedkey)
  1931. self.SetItemState(self.selected,
  1932. wx.LIST_STATE_SELECTED,
  1933. wx.LIST_STATE_SELECTED)
  1934. event.Skip()
  1935. class VectGroup(wx.Dialog):
  1936. """Dialog to create a vector group (VREF file) for georectifying
  1937. .. todo::
  1938. Replace by g.group
  1939. """
  1940. def __init__(self, parent, id, grassdb, location, mapset, group,
  1941. style=wx.DEFAULT_DIALOG_STYLE):
  1942. wx.Dialog.__init__(self, parent, id, style=style,
  1943. title=_("Create vector map group"))
  1944. self.grassdatabase = grassdb
  1945. self.xylocation = location
  1946. self.xymapset = mapset
  1947. self.xygroup = group
  1948. #
  1949. # get list of valid vector directories
  1950. #
  1951. vectlist = os.listdir(os.path.join(self.grassdatabase,
  1952. self.xylocation,
  1953. self.xymapset,
  1954. 'vector'))
  1955. for dir in vectlist:
  1956. if not os.path.isfile(os.path.join(self.grassdatabase,
  1957. self.xylocation,
  1958. self.xymapset,
  1959. 'vector',
  1960. dir,
  1961. 'coor')):
  1962. vectlist.remove(dir)
  1963. utils.ListSortLower(vectlist)
  1964. # path to vref file
  1965. self.vgrpfile = os.path.join(self.grassdatabase,
  1966. self.xylocation,
  1967. self.xymapset,
  1968. 'group',
  1969. self.xygroup,
  1970. 'VREF')
  1971. #
  1972. # buttons
  1973. #
  1974. self.btnCancel = wx.Button(parent=self,
  1975. id=wx.ID_CANCEL)
  1976. self.btnOK = wx.Button(parent=self,
  1977. id=wx.ID_OK)
  1978. self.btnOK.SetDefault()
  1979. #
  1980. # list of vector maps
  1981. #
  1982. self.listMap = wx.CheckListBox(parent=self, id=wx.ID_ANY,
  1983. choices=vectlist)
  1984. if os.path.isfile(self.vgrpfile):
  1985. f = open(self.vgrpfile)
  1986. try:
  1987. checked = []
  1988. for line in f.readlines():
  1989. line = line.replace('\n', '')
  1990. if len(line) < 1:
  1991. continue
  1992. checked.append(line)
  1993. self.listMap.SetCheckedStrings(checked)
  1994. finally:
  1995. f.close()
  1996. line = wx.StaticLine(parent=self,
  1997. id=wx.ID_ANY, size=(20, -1),
  1998. style=wx.LI_HORIZONTAL)
  1999. #
  2000. # layout
  2001. #
  2002. sizer = wx.BoxSizer(wx.VERTICAL)
  2003. box = wx.BoxSizer(wx.HORIZONTAL)
  2004. box.Add(
  2005. item=wx.StaticText(
  2006. parent=self,
  2007. id=wx.ID_ANY,
  2008. label=_('Select vector map(s) to add to group:')),
  2009. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT,
  2010. border=5)
  2011. box.Add(item=self.listMap,
  2012. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT,
  2013. border=5)
  2014. sizer.Add(box, flag=wx.ALIGN_RIGHT | wx.ALL,
  2015. border=3)
  2016. sizer.Add(item=line, proportion=0,
  2017. flag=wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT,
  2018. border=5)
  2019. # buttons
  2020. btnSizer = wx.StdDialogButtonSizer()
  2021. btnSizer.AddButton(self.btnCancel)
  2022. btnSizer.AddButton(self.btnOK)
  2023. btnSizer.Realize()
  2024. sizer.Add(item=btnSizer, proportion=0,
  2025. flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER,
  2026. border=5)
  2027. self.SetSizer(sizer)
  2028. sizer.Fit(self)
  2029. self.Layout()
  2030. def MakeVGroup(self):
  2031. """Create VREF file"""
  2032. vgrouplist = []
  2033. for item in range(self.listMap.GetCount()):
  2034. if not self.listMap.IsChecked(item):
  2035. continue
  2036. vgrouplist.append(
  2037. self.listMap.GetString(item) +
  2038. '@' +
  2039. self.xymapset)
  2040. f = open(self.vgrpfile, mode='w')
  2041. try:
  2042. for vect in vgrouplist:
  2043. f.write(vect + '\n')
  2044. finally:
  2045. f.close()
  2046. class EditGCP(wx.Dialog):
  2047. def __init__(self, parent, data, gcpno, id=wx.ID_ANY,
  2048. title=_("Edit GCP"),
  2049. style=wx.DEFAULT_DIALOG_STYLE):
  2050. """Dialog for editing GPC and map coordinates in list control"""
  2051. wx.Dialog.__init__(self, parent, id, title=title, style=style)
  2052. panel = wx.Panel(parent=self)
  2053. sizer = wx.BoxSizer(wx.VERTICAL)
  2054. box = wx.StaticBox(
  2055. parent=panel, id=wx.ID_ANY, label=" %s %s " %
  2056. (_("Ground Control Point No."), str(gcpno)))
  2057. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  2058. # source coordinates
  2059. gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
  2060. self.xcoord = wx.TextCtrl(parent=panel, id=wx.ID_ANY, size=(150, -1))
  2061. self.ycoord = wx.TextCtrl(parent=panel, id=wx.ID_ANY, size=(150, -1))
  2062. self.ecoord = wx.TextCtrl(parent=panel, id=wx.ID_ANY, size=(150, -1))
  2063. self.ncoord = wx.TextCtrl(parent=panel, id=wx.ID_ANY, size=(150, -1))
  2064. # swap source N, target E
  2065. tmp_coord = data[1]
  2066. data[1] = data[2]
  2067. data[2] = tmp_coord
  2068. row = 0
  2069. col = 0
  2070. idx = 0
  2071. for label, win in ((_("source E:"), self.xcoord),
  2072. (_("target E:"), self.ecoord),
  2073. (_("source N:"), self.ycoord),
  2074. (_("target N:"), self.ncoord)):
  2075. label = wx.StaticText(parent=panel, id=wx.ID_ANY,
  2076. label=label)
  2077. gridSizer.Add(item=label,
  2078. flag=wx.ALIGN_CENTER_VERTICAL,
  2079. pos=(row, col))
  2080. col += 1
  2081. win.SetValue(str(data[idx]))
  2082. gridSizer.Add(item=win,
  2083. pos=(row, col))
  2084. col += 1
  2085. idx += 1
  2086. if col > 3:
  2087. row += 1
  2088. col = 0
  2089. boxSizer.Add(item=gridSizer, proportion=1,
  2090. flag=wx.EXPAND | wx.ALL, border=5)
  2091. sizer.Add(item=boxSizer, proportion=1,
  2092. flag=wx.EXPAND | wx.ALL, border=5)
  2093. #
  2094. # buttons
  2095. #
  2096. self.btnCancel = wx.Button(panel, wx.ID_CANCEL)
  2097. self.btnOk = wx.Button(panel, wx.ID_OK)
  2098. self.btnOk.SetDefault()
  2099. btnSizer = wx.StdDialogButtonSizer()
  2100. btnSizer.AddButton(self.btnCancel)
  2101. btnSizer.AddButton(self.btnOk)
  2102. btnSizer.Realize()
  2103. sizer.Add(item=btnSizer, proportion=0,
  2104. flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
  2105. panel.SetSizer(sizer)
  2106. sizer.Fit(self)
  2107. def GetValues(self, columns=None):
  2108. """Return list of values (as strings).
  2109. """
  2110. valuelist = []
  2111. try:
  2112. float(self.xcoord.GetValue())
  2113. float(self.ycoord.GetValue())
  2114. float(self.ecoord.GetValue())
  2115. float(self.ncoord.GetValue())
  2116. except ValueError:
  2117. return valuelist
  2118. valuelist.append(self.xcoord.GetValue())
  2119. valuelist.append(self.ycoord.GetValue())
  2120. valuelist.append(self.ecoord.GetValue())
  2121. valuelist.append(self.ncoord.GetValue())
  2122. return valuelist
  2123. class GrSettingsDialog(wx.Dialog):
  2124. def __init__(
  2125. self, parent, id, giface, title, pos=wx.DefaultPosition,
  2126. size=wx.DefaultSize, style=wx.DEFAULT_DIALOG_STYLE):
  2127. wx.Dialog.__init__(self, parent, id, title, pos, size, style)
  2128. """
  2129. Dialog to set profile text options: font, title
  2130. and font size, axis labels and font size
  2131. """
  2132. #
  2133. # initialize variables
  2134. #
  2135. self.parent = parent
  2136. self.new_src_map = src_map
  2137. self.new_tgt_map = {'raster': tgt_map['raster'],
  2138. 'vector': tgt_map['vector']}
  2139. self.sdfactor = 0
  2140. self.symbol = {}
  2141. self.methods = ["nearest",
  2142. "linear",
  2143. "linear_f",
  2144. "cubic",
  2145. "cubic_f",
  2146. "lanczos",
  2147. "lanczos_f"]
  2148. # notebook
  2149. notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
  2150. self.__CreateSymbologyPage(notebook)
  2151. self.__CreateRectificationPage(notebook)
  2152. # buttons
  2153. btnSave = wx.Button(self, wx.ID_SAVE)
  2154. btnApply = wx.Button(self, wx.ID_APPLY)
  2155. btnClose = wx.Button(self, wx.ID_CLOSE)
  2156. btnApply.SetDefault()
  2157. # bindings
  2158. btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
  2159. btnApply.SetToolTipString(_("Apply changes for the current session"))
  2160. btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
  2161. btnSave.SetToolTipString(
  2162. _("Apply and save changes to user settings file (default for next sessions)"))
  2163. btnClose.Bind(wx.EVT_BUTTON, self.OnClose)
  2164. btnClose.SetToolTipString(_("Close dialog"))
  2165. # sizers
  2166. btnSizer = wx.BoxSizer(wx.HORIZONTAL)
  2167. btnSizer.Add(btnApply, flag=wx.LEFT | wx.RIGHT, border=5)
  2168. btnSizer.Add(btnSave, flag=wx.LEFT | wx.RIGHT, border=5)
  2169. btnSizer.Add(btnClose, flag=wx.LEFT | wx.RIGHT, border=5)
  2170. # sizers
  2171. mainSizer = wx.BoxSizer(wx.VERTICAL)
  2172. mainSizer.Add(
  2173. item=notebook,
  2174. proportion=1,
  2175. flag=wx.EXPAND | wx.ALL,
  2176. border=5)
  2177. mainSizer.Add(item=btnSizer, proportion=0,
  2178. flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
  2179. # flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
  2180. self.SetSizer(mainSizer)
  2181. mainSizer.Fit(self)
  2182. def __CreateSymbologyPage(self, notebook):
  2183. """Create notebook page with symbology settings"""
  2184. panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
  2185. notebook.AddPage(page=panel, text=_("Symbology"))
  2186. sizer = wx.BoxSizer(wx.VERTICAL)
  2187. rmsgridSizer = wx.GridBagSizer(vgap=5, hgap=5)
  2188. # highlight only highest forward RMS error
  2189. self.highlighthighest = wx.CheckBox(
  2190. parent=panel, id=wx.ID_ANY,
  2191. label=_("Highlight highest RMS error only"))
  2192. hh = UserSettings.Get(group='gcpman', key='rms', subkey='highestonly')
  2193. self.highlighthighest.SetValue(hh)
  2194. rmsgridSizer.Add(
  2195. item=self.highlighthighest,
  2196. flag=wx.ALIGN_CENTER_VERTICAL,
  2197. pos=(
  2198. 0,
  2199. 0))
  2200. # RMS forward error threshold
  2201. rmslabel = wx.StaticText(
  2202. parent=panel, id=wx.ID_ANY,
  2203. label=_("Highlight RMS error > M + SD * factor:"))
  2204. rmslabel.SetToolTip(
  2205. wx.ToolTip(
  2206. _(
  2207. "Highlight GCPs with an RMS error larger than \n"
  2208. "mean + standard deviation * given factor. \n"
  2209. "Recommended values for this factor are between 1 and 2.")))
  2210. rmsgridSizer.Add(
  2211. item=rmslabel,
  2212. flag=wx.ALIGN_CENTER_VERTICAL,
  2213. pos=(
  2214. 1,
  2215. 0))
  2216. sdfactor = UserSettings.Get(
  2217. group='gcpman', key='rms', subkey='sdfactor')
  2218. self.rmsWin = wx.TextCtrl(parent=panel, id=wx.ID_ANY,
  2219. size=(70, -1), style=wx.TE_NOHIDESEL)
  2220. self.rmsWin.SetValue("%s" % str(sdfactor))
  2221. if (self.parent.highest_only == True):
  2222. self.rmsWin.Disable()
  2223. self.symbol['sdfactor'] = self.rmsWin.GetId()
  2224. rmsgridSizer.Add(item=self.rmsWin, flag=wx.ALIGN_RIGHT, pos=(1, 1))
  2225. rmsgridSizer.AddGrowableCol(1)
  2226. sizer.Add(item=rmsgridSizer, flag=wx.EXPAND | wx.ALL, border=5)
  2227. box = wx.StaticBox(parent=panel, id=wx.ID_ANY,
  2228. label=" %s " % _("Symbol settings"))
  2229. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  2230. gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
  2231. #
  2232. # general symbol color
  2233. #
  2234. row = 0
  2235. label = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Color:"))
  2236. gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
  2237. col = UserSettings.Get(group='gcpman', key='symbol', subkey='color')
  2238. colWin = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
  2239. colour=wx.Colour(col[0],
  2240. col[1],
  2241. col[2],
  2242. 255))
  2243. self.symbol['color'] = colWin.GetId()
  2244. gridSizer.Add(item=colWin,
  2245. flag=wx.ALIGN_RIGHT,
  2246. pos=(row, 1))
  2247. #
  2248. # symbol color for high forward RMS error
  2249. #
  2250. row += 1
  2251. label = wx.StaticText(
  2252. parent=panel,
  2253. id=wx.ID_ANY,
  2254. label=_("Color for high RMS error:"))
  2255. gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
  2256. hcol = UserSettings.Get(group='gcpman', key='symbol', subkey='hcolor')
  2257. hcolWin = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
  2258. colour=wx.Colour(hcol[0],
  2259. hcol[1],
  2260. hcol[2],
  2261. 255))
  2262. self.symbol['hcolor'] = hcolWin.GetId()
  2263. gridSizer.Add(item=hcolWin,
  2264. flag=wx.ALIGN_RIGHT,
  2265. pos=(row, 1))
  2266. #
  2267. # symbol color for selected GCP
  2268. #
  2269. row += 1
  2270. label = wx.StaticText(
  2271. parent=panel,
  2272. id=wx.ID_ANY,
  2273. label=_("Color for selected GCP:"))
  2274. gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
  2275. scol = UserSettings.Get(group='gcpman', key='symbol', subkey='scolor')
  2276. scolWin = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
  2277. colour=wx.Colour(scol[0],
  2278. scol[1],
  2279. scol[2],
  2280. 255))
  2281. self.symbol['scolor'] = scolWin.GetId()
  2282. gridSizer.Add(item=scolWin,
  2283. flag=wx.ALIGN_RIGHT,
  2284. pos=(row, 1))
  2285. #
  2286. # symbol color for unused GCP
  2287. #
  2288. row += 1
  2289. label = wx.StaticText(
  2290. parent=panel,
  2291. id=wx.ID_ANY,
  2292. label=_("Color for unused GCPs:"))
  2293. gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
  2294. ucol = UserSettings.Get(group='gcpman', key='symbol', subkey='ucolor')
  2295. ucolWin = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
  2296. colour=wx.Colour(ucol[0],
  2297. ucol[1],
  2298. ucol[2],
  2299. 255))
  2300. self.symbol['ucolor'] = ucolWin.GetId()
  2301. gridSizer.Add(item=ucolWin,
  2302. flag=wx.ALIGN_RIGHT,
  2303. pos=(row, 1))
  2304. # show unused GCPs
  2305. row += 1
  2306. self.showunused = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  2307. label=_("Show unused GCPs"))
  2308. shuu = UserSettings.Get(group='gcpman', key='symbol', subkey='unused')
  2309. self.showunused.SetValue(shuu)
  2310. gridSizer.Add(
  2311. item=self.showunused,
  2312. flag=wx.ALIGN_CENTER_VERTICAL,
  2313. pos=(
  2314. row,
  2315. 0))
  2316. #
  2317. # symbol size
  2318. #
  2319. row += 1
  2320. label = wx.StaticText(
  2321. parent=panel,
  2322. id=wx.ID_ANY,
  2323. label=_("Symbol size:"))
  2324. gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
  2325. symsize = int(
  2326. UserSettings.Get(
  2327. group='gcpman',
  2328. key='symbol',
  2329. subkey='size'))
  2330. sizeWin = wx.SpinCtrl(parent=panel, id=wx.ID_ANY,
  2331. min=1, max=20)
  2332. sizeWin.SetValue(symsize)
  2333. self.symbol['size'] = sizeWin.GetId()
  2334. gridSizer.Add(item=sizeWin,
  2335. flag=wx.ALIGN_RIGHT,
  2336. pos=(row, 1))
  2337. #
  2338. # symbol width
  2339. #
  2340. row += 1
  2341. label = wx.StaticText(
  2342. parent=panel,
  2343. id=wx.ID_ANY,
  2344. label=_("Line width:"))
  2345. gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
  2346. width = int(
  2347. UserSettings.Get(
  2348. group='gcpman',
  2349. key='symbol',
  2350. subkey='width'))
  2351. widWin = wx.SpinCtrl(parent=panel, id=wx.ID_ANY,
  2352. min=1, max=10)
  2353. widWin.SetValue(width)
  2354. self.symbol['width'] = widWin.GetId()
  2355. gridSizer.Add(item=widWin,
  2356. flag=wx.ALIGN_RIGHT,
  2357. pos=(row, 1))
  2358. gridSizer.AddGrowableCol(1)
  2359. boxSizer.Add(item=gridSizer, flag=wx.EXPAND)
  2360. sizer.Add(item=boxSizer, flag=wx.EXPAND | wx.ALL, border=5)
  2361. #
  2362. # maps to display
  2363. #
  2364. # source map to display
  2365. self.srcselection = Select(
  2366. panel,
  2367. id=wx.ID_ANY,
  2368. size=globalvar.DIALOG_GSELECT_SIZE,
  2369. type='maptype',
  2370. updateOnPopup=False)
  2371. self.parent.grwiz.SwitchEnv('source')
  2372. self.srcselection.SetElementList(maptype)
  2373. # filter out all maps not in group
  2374. self.srcselection.tcp.GetElementList(elements=self.parent.src_maps)
  2375. # target map(s) to display
  2376. self.parent.grwiz.SwitchEnv('target')
  2377. self.tgtrastselection = Select(
  2378. panel, id=wx.ID_ANY, size=globalvar.DIALOG_GSELECT_SIZE,
  2379. type='raster', updateOnPopup=False)
  2380. self.tgtrastselection.SetElementList('cell')
  2381. self.tgtrastselection.GetElementList()
  2382. self.tgtvectselection = Select(
  2383. panel, id=wx.ID_ANY, size=globalvar.DIALOG_GSELECT_SIZE,
  2384. type='vector', updateOnPopup=False)
  2385. self.tgtvectselection.SetElementList('vector')
  2386. self.tgtvectselection.GetElementList()
  2387. sizer.Add(
  2388. item=wx.StaticText(
  2389. parent=panel,
  2390. id=wx.ID_ANY,
  2391. label=_('Select source map to display:')),
  2392. proportion=0,
  2393. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  2394. border=5)
  2395. sizer.Add(
  2396. item=self.srcselection,
  2397. proportion=0,
  2398. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  2399. border=5)
  2400. self.srcselection.SetValue(src_map)
  2401. sizer.Add(
  2402. item=wx.StaticText(
  2403. parent=panel,
  2404. id=wx.ID_ANY,
  2405. label=_('Select target raster map to display:')),
  2406. proportion=0,
  2407. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  2408. border=5)
  2409. sizer.Add(
  2410. item=self.tgtrastselection,
  2411. proportion=0,
  2412. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  2413. border=5)
  2414. self.tgtrastselection.SetValue(tgt_map['raster'])
  2415. sizer.Add(
  2416. item=wx.StaticText(
  2417. parent=panel,
  2418. id=wx.ID_ANY,
  2419. label=_('Select target vector map to display:')),
  2420. proportion=0,
  2421. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  2422. border=5)
  2423. sizer.Add(
  2424. item=self.tgtvectselection,
  2425. proportion=0,
  2426. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  2427. border=5)
  2428. self.tgtvectselection.SetValue(tgt_map['vector'])
  2429. # bindings
  2430. self.highlighthighest.Bind(wx.EVT_CHECKBOX, self.OnHighlight)
  2431. self.rmsWin.Bind(wx.EVT_TEXT, self.OnSDFactor)
  2432. self.srcselection.Bind(wx.EVT_TEXT, self.OnSrcSelection)
  2433. self.tgtrastselection.Bind(wx.EVT_TEXT, self.OnTgtRastSelection)
  2434. self.tgtvectselection.Bind(wx.EVT_TEXT, self.OnTgtVectSelection)
  2435. panel.SetSizer(sizer)
  2436. return panel
  2437. def __CreateRectificationPage(self, notebook):
  2438. """Create notebook page with symbology settings"""
  2439. panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
  2440. notebook.AddPage(page=panel, text=_("Rectification"))
  2441. sizer = wx.BoxSizer(wx.VERTICAL)
  2442. # transformation order
  2443. self.rb_grorder = wx.RadioBox(
  2444. parent=panel,
  2445. id=wx.ID_ANY,
  2446. label=" %s " %
  2447. _("Select rectification order"),
  2448. choices=[
  2449. _('1st order'),
  2450. _('2nd order'),
  2451. _('3rd order')],
  2452. majorDimension=wx.RA_SPECIFY_COLS)
  2453. sizer.Add(item=self.rb_grorder, proportion=0,
  2454. flag=wx.EXPAND | wx.ALL, border=5)
  2455. self.rb_grorder.SetSelection(self.parent.gr_order - 1)
  2456. # interpolation method
  2457. gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
  2458. gridSizer.Add(
  2459. item=wx.StaticText(
  2460. parent=panel,
  2461. id=wx.ID_ANY,
  2462. label=_('Select interpolation method:')),
  2463. pos=(
  2464. 0,
  2465. 0),
  2466. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  2467. border=5)
  2468. self.grmethod = wx.Choice(parent=panel, id=wx.ID_ANY,
  2469. choices=self.methods)
  2470. gridSizer.Add(item=self.grmethod, pos=(0, 1),
  2471. flag=wx.ALIGN_RIGHT, border=5)
  2472. self.grmethod.SetStringSelection(self.parent.gr_method)
  2473. gridSizer.AddGrowableCol(1)
  2474. sizer.Add(item=gridSizer, flag=wx.EXPAND | wx.ALL, border=5)
  2475. # clip to region
  2476. self.check = wx.CheckBox(parent=panel, id=wx.ID_ANY, label=_(
  2477. "clip to computational region in target location"))
  2478. sizer.Add(item=self.check, proportion=0,
  2479. flag=wx.EXPAND | wx.ALL, border=5)
  2480. self.check.SetValue(self.parent.clip_to_region)
  2481. # extension
  2482. sizer.Add(
  2483. item=wx.StaticText(
  2484. parent=panel,
  2485. id=wx.ID_ANY,
  2486. label=_('Extension for output maps:')),
  2487. proportion=0,
  2488. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  2489. border=5)
  2490. self.ext_txt = wx.TextCtrl(
  2491. parent=panel, id=wx.ID_ANY, value="", size=(
  2492. 350, -1))
  2493. self.ext_txt.SetValue(self.parent.extension)
  2494. sizer.Add(
  2495. item=self.ext_txt,
  2496. proportion=0,
  2497. flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  2498. border=5)
  2499. # bindings
  2500. self.ext_txt.Bind(wx.EVT_TEXT, self.OnExtension)
  2501. self.Bind(wx.EVT_RADIOBOX, self.parent.OnGROrder, self.rb_grorder)
  2502. self.Bind(wx.EVT_CHOICE, self.OnMethod, self.grmethod)
  2503. self.Bind(wx.EVT_CHECKBOX, self.OnClipRegion, self.check)
  2504. panel.SetSizer(sizer)
  2505. return panel
  2506. def OnHighlight(self, event):
  2507. """Checkbox 'highlighthighest' checked/unchecked"""
  2508. if self.highlighthighest.IsChecked():
  2509. self.parent.highest_only = True
  2510. self.rmsWin.Disable()
  2511. else:
  2512. self.parent.highest_only = False
  2513. self.rmsWin.Enable()
  2514. def OnSDFactor(self, event):
  2515. """New factor for RMS threshold = M + SD * factor"""
  2516. try:
  2517. self.sdfactor = float(self.rmsWin.GetValue())
  2518. except ValueError:
  2519. return
  2520. if self.sdfactor <= 0:
  2521. GError(parent=self,
  2522. message=_('RMS threshold factor must be > 0'))
  2523. elif self.sdfactor < 1:
  2524. GError(parent=self,
  2525. message=_('RMS threshold factor is < 1\n'
  2526. 'Too many points might be highlighted'))
  2527. def OnSrcSelection(self, event):
  2528. """Source map to display selected"""
  2529. global src_map
  2530. tmp_map = self.srcselection.GetValue()
  2531. if not tmp_map == '' and not tmp_map == src_map:
  2532. self.new_src_map = tmp_map
  2533. def OnTgtRastSelection(self, event):
  2534. """Target map to display selected"""
  2535. global tgt_map
  2536. self.new_tgt_map['raster'] = self.tgtrastselection.GetValue()
  2537. def OnTgtVectSelection(self, event):
  2538. """Target map to display selected"""
  2539. global tgt_map
  2540. self.new_tgt_map['vector'] = self.tgtvectselection.GetValue()
  2541. def OnMethod(self, event):
  2542. self.parent.gr_method = self.methods[event.GetSelection()]
  2543. def OnClipRegion(self, event):
  2544. self.parent.clip_to_region = event.IsChecked()
  2545. def OnExtension(self, event):
  2546. self.parent.extension = self.ext_txt.GetValue()
  2547. def UpdateSettings(self):
  2548. global src_map
  2549. global tgt_map
  2550. global maptype
  2551. layers = None
  2552. UserSettings.Set(group='gcpman', key='rms', subkey='highestonly',
  2553. value=self.highlighthighest.GetValue())
  2554. if self.sdfactor > 0:
  2555. UserSettings.Set(group='gcpman', key='rms', subkey='sdfactor',
  2556. value=self.sdfactor)
  2557. self.parent.sdfactor = self.sdfactor
  2558. if self.parent.rmsthresh > 0:
  2559. self.parent.rmsthresh = self.parent.rmsmean + self.parent.sdfactor * self.parent.rmssd
  2560. UserSettings.Set(
  2561. group='gcpman',
  2562. key='symbol',
  2563. subkey='color',
  2564. value=tuple(
  2565. wx.FindWindowById(
  2566. self.symbol['color']).GetColour()))
  2567. UserSettings.Set(
  2568. group='gcpman',
  2569. key='symbol',
  2570. subkey='hcolor',
  2571. value=tuple(
  2572. wx.FindWindowById(
  2573. self.symbol['hcolor']).GetColour()))
  2574. UserSettings.Set(
  2575. group='gcpman',
  2576. key='symbol',
  2577. subkey='scolor',
  2578. value=tuple(
  2579. wx.FindWindowById(
  2580. self.symbol['scolor']).GetColour()))
  2581. UserSettings.Set(
  2582. group='gcpman',
  2583. key='symbol',
  2584. subkey='ucolor',
  2585. value=tuple(
  2586. wx.FindWindowById(
  2587. self.symbol['ucolor']).GetColour()))
  2588. UserSettings.Set(group='gcpman', key='symbol', subkey='unused',
  2589. value=self.showunused.GetValue())
  2590. UserSettings.Set(
  2591. group='gcpman',
  2592. key='symbol',
  2593. subkey='size',
  2594. value=wx.FindWindowById(
  2595. self.symbol['size']).GetValue())
  2596. UserSettings.Set(
  2597. group='gcpman',
  2598. key='symbol',
  2599. subkey='width',
  2600. value=wx.FindWindowById(
  2601. self.symbol['width']).GetValue())
  2602. srcrender = False
  2603. srcrenderVector = False
  2604. tgtrender = False
  2605. tgtrenderVector = False
  2606. reload_target = False
  2607. if self.new_src_map != src_map:
  2608. # remove old layer
  2609. layers = self.parent.grwiz.SrcMap.GetListOfLayers()
  2610. self.parent.grwiz.SrcMap.DeleteLayer(layers[0])
  2611. src_map = self.new_src_map
  2612. if maptype == 'raster':
  2613. cmdlist = ['d.rast', 'map=%s' % src_map]
  2614. srcrender = True
  2615. else:
  2616. cmdlist = ['d.vect', 'map=%s' % src_map]
  2617. srcrenderVector = True
  2618. self.parent.grwiz.SwitchEnv('source')
  2619. name, found = utils.GetLayerNameFromCmd(cmdlist)
  2620. self.parent.grwiz.SrcMap.AddLayer(
  2621. ltype=maptype, command=cmdlist, active=True, name=name,
  2622. hidden=False, opacity=1.0, render=False)
  2623. self.parent.grwiz.SwitchEnv('target')
  2624. if self.new_tgt_map['raster'] != tgt_map['raster'] or \
  2625. self.new_tgt_map['vector'] != tgt_map['vector']:
  2626. # remove all layers
  2627. layers = self.parent.grwiz.TgtMap.GetListOfLayers()
  2628. while layers:
  2629. self.parent.grwiz.TgtMap.DeleteLayer(layers[0])
  2630. del layers[0]
  2631. layers = self.parent.grwiz.TgtMap.GetListOfLayers()
  2632. # self.parent.grwiz.TgtMap.DeleteAllLayers()
  2633. reload_target = True
  2634. tgt_map['raster'] = self.new_tgt_map['raster']
  2635. tgt_map['vector'] = self.new_tgt_map['vector']
  2636. if tgt_map['raster'] != '':
  2637. cmdlist = ['d.rast', 'map=%s' % tgt_map['raster']]
  2638. name, found = utils.GetLayerNameFromCmd(cmdlist)
  2639. self.parent.grwiz.TgtMap.AddLayer(
  2640. ltype='raster', command=cmdlist, active=True, name=name,
  2641. hidden=False, opacity=1.0, render=False)
  2642. tgtrender = True
  2643. if tgt_map['vector'] != '':
  2644. cmdlist = ['d.vect', 'map=%s' % tgt_map['vector']]
  2645. name, found = utils.GetLayerNameFromCmd(cmdlist)
  2646. self.parent.grwiz.TgtMap.AddLayer(
  2647. ltype='vector', command=cmdlist, active=True, name=name,
  2648. hidden=False, opacity=1.0, render=False)
  2649. tgtrenderVector = True
  2650. if tgt_map['raster'] == '' and tgt_map['vector'] == '':
  2651. if self.parent.show_target == True:
  2652. self.parent.show_target = False
  2653. self.parent._mgr.GetPane("target").Hide()
  2654. self.parent._mgr.Update()
  2655. self.parent.activemap.SetSelection(0)
  2656. self.parent.activemap.Enable(False)
  2657. self.parent.GetMapToolbar().Enable('zoommenu', enable=False)
  2658. else:
  2659. if self.parent.show_target == False:
  2660. self.parent.show_target = True
  2661. self.parent._mgr.GetPane("target").Show()
  2662. self.parent._mgr.Update()
  2663. self.parent.activemap.SetSelection(0)
  2664. self.parent.activemap.Enable(True)
  2665. self.parent.GetMapToolbar().Enable('zoommenu', enable=True)
  2666. self.parent.TgtMapWindow.ZoomToMap(
  2667. layers=self.parent.TgtMap.GetListOfLayers())
  2668. self.parent.UpdateColours(
  2669. srcrender,
  2670. srcrenderVector,
  2671. tgtrender,
  2672. tgtrenderVector)
  2673. self.parent.SetSettings()
  2674. def OnSave(self, event):
  2675. """Button 'Save' pressed"""
  2676. self.UpdateSettings()
  2677. fileSettings = {}
  2678. UserSettings.ReadSettingsFile(settings=fileSettings)
  2679. fileSettings['gcpman'] = UserSettings.Get(group='gcpman')
  2680. file = UserSettings.SaveToFile(fileSettings)
  2681. self.parent._giface.WriteLog(
  2682. _('GCP Manager settings saved to file \'%s\'.') %
  2683. file)
  2684. # self.Close()
  2685. def OnApply(self, event):
  2686. """Button 'Apply' pressed"""
  2687. self.UpdateSettings()
  2688. # self.Close()
  2689. def OnClose(self, event):
  2690. """Button 'Cancel' pressed"""
  2691. self.Close()