ii2t_manager.py 112 KB

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