manager.py 108 KB

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