manager.py 108 KB

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