manager.py 108 KB

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