manager.py 108 KB

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