12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302 |
- """
- @package gcp.manager
- @brief Georectification module for GRASS GIS. Includes ground control
- point management and interactive point and click GCP creation
- Classes:
- - manager::GCPWizard
- - manager::LocationPage
- - manager::GroupPage
- - manager::DispMapPage
- - manager::GCP
- - manager::GCPList
- - manager::VectGroup
- - manager::EditGCP
- - manager::GrSettingsDialog
- (C) 2006-2017 by the GRASS Development Team
- This program is free software under the GNU General Public License
- (>=v2). Read the file COPYING that comes with GRASS for details.
- @author Original author Michael Barton
- @author Original version improved by Martin Landa <landa.martin gmail.com>
- @author Rewritten by Markus Metz redesign georectfier -> GCP Manage
- @author Support for GraphicsSet added by Stepan Turek <stepan.turek seznam.cz> (2012)
- @author port i.image.2target (v6) to version 7 in 2017 by Yann
- """
- #TODO: i.ortho.transform has 6 appearances, check each of them and configure
- #TODO: i.ortho.transform looks for REF_POINTS/CONTROL_POINTS and not POINTS
- #TODO: CHECK CONTROL_POINTS format and create it for i.ortho.transform to use.
- from __future__ import print_function
- import os
- import sys
- import six
- import shutil
- import time
- from copy import copy
- import wx
- from wx.lib.mixins.listctrl import CheckListCtrlMixin, ColumnSorterMixin, ListCtrlAutoWidthMixin
- import wx.lib.colourselect as csel
- from core import globalvar
- if globalvar.wxPythonPhoenix:
- from wx.adv import Wizard as wiz
- else:
- import wx.wizard as wiz
- import grass.script as grass
- from core import utils
- from core.render import Map
- from gui_core.gselect import Select, LocationSelect, MapsetSelect
- from gui_core.dialogs import GroupDialog
- from core.gcmd import RunCommand, GMessage, GError, GWarning, EncodeString
- from core.settings import UserSettings
- from gcp.mapdisplay import MapFrame
- from core.giface import Notification
- from gui_core.wrap import SpinCtrl, Button, StaticText, StaticBox, \
- CheckListBox, TextCtrl, Menu
- from location_wizard.wizard import TitledPage as TitledPage
- #
- # global variables
- #
- global src_map
- global tgt_map
- global maptype
- src_map = ''
- tgt_map = {'raster': '',
- 'vector': ''}
- maptype = 'raster'
- def getSmallUpArrowImage():
- stream = open(os.path.join(globalvar.IMGDIR, 'small_up_arrow.png'), 'rb')
- try:
- img = wx.ImageFromStream(stream)
- finally:
- stream.close()
- return img
- def getSmallDnArrowImage():
- stream = open(os.path.join(globalvar.IMGDIR, 'small_down_arrow.png'), 'rb')
- try:
- img = wx.ImageFromStream(stream)
- finally:
- stream.close()
- stream.close()
- return img
- class GCPWizard(object):
- """
- Start wizard here and finish wizard here
- """
- #def __init__(self, parent, giface, srcloc, srcmpt, srcgrp, srcras, tgtras, camera, order, extension):
- # global maptype
- # global src_map
- # global tgt_map
- # maptype = 'raster'
- # rendertype = 'raster'
- # self.parent = parent # GMFrame
- # self._giface = giface
- # self.srcloc = srcloc
- # self.srcmpt = srcmpt
- # self.group = srcgrp
- # self.src_map = srcras
- # self.tgt_map = tgtras
- # self.camera = camera
- # self.order = int(order)
- # self.extension = extension
- # self.src_maps = self.src_map
- # # location for xy map to georectify
- # self.newlocation = self.srcloc
- # # mapset for xy map to georectify
- # self.newmapset = self.srcmpt
- def __init__(self, parent, giface):
- self.parent = parent # GMFrame
- self._giface = giface
- #
- # get environmental variables
- #
- self.grassdatabase = grass.gisenv()['GISDBASE']
- #
- # read original environment settings
- #
- self.target_gisrc = os.environ['GISRC']
- self.gisrc_dict = {}
- try:
- f = open(self.target_gisrc, 'r')
- for line in f.readlines():
- line = line.replace('\n', '').strip()
- if len(line) < 1:
- continue
- key, value = line.split(':', 1)
- self.gisrc_dict[key.strip()] = value.strip()
- finally:
- f.close()
- self.currentlocation = self.gisrc_dict['LOCATION_NAME']
- self.currentmapset = self.gisrc_dict['MAPSET']
- # location for xy map to georectify
- self.newlocation = ''
- # mapset for xy map to georectify
- self.newmapset = ''
- global maptype
- global src_map
- global tgt_map
- #src_map = ''
- #tgt_map = ''
- maptype = 'raster'
- # GISRC file for source location/mapset of map(s) to georectify
- self.source_gisrc = ''
- self.src_maps = []
- # Raster map with camera angle relative to ground surface (i.ortho.rectify)
- self.cam_angle = ''
- #
- # define wizard pages
- #
- self.wizard = wiz.Wizard(
- parent=parent,
- id=wx.ID_ANY,
- title=_("Setup for georectification"))
- self.startpage = LocationPage(self.wizard, self)
- self.grouppage = GroupPage(self.wizard, self)
- self.mappage = DispMapPage(self.wizard, self)
- #
- # set the initial order of the pages
- #
- self.startpage.SetNext(self.grouppage)
- self.grouppage.SetPrev(self.startpage)
- self.grouppage.SetNext(self.mappage)
- self.mappage.SetPrev(self.grouppage)
- #
- # do pages layout
- #
- self.startpage.DoLayout()
- self.grouppage.DoLayout()
- self.mappage.DoLayout()
- self.wizard.FitToPage(self.startpage)
- # self.Bind(wx.EVT_CLOSE, self.Cleanup)
- # self.parent.Bind(wx.EVT_ACTIVATE, self.OnGLMFocus)
- success = False
- #
- # run wizard
- #
- if self.wizard.RunWizard(self.startpage):
- success = self.OnWizFinished()
- if success == False:
- GMessage(parent=self.parent,
- message=_("Georectifying setup canceled."))
- self.Cleanup()
- else:
- GMessage(parent=self.parent,
- message=_("Georectifying setup canceled."))
- self.Cleanup()
- #
- # start GCP display
- #
- if success != False:
- # instance of render.Map to be associated with display
- self.SwitchEnv('source')
- self.SrcMap = Map(gisrc=self.source_gisrc)
- self.SwitchEnv('target')
- self.TgtMap = Map(gisrc=self.target_gisrc)
- self.Map = self.SrcMap
- #
- # add layer to source map
- #
- if maptype == 'raster':
- rendertype = 'raster'
- cmdlist = ['d.rast', 'map=%s' % src_map]
- else: # -> vector layer
- rendertype = 'vector'
- cmdlist = ['d.vect', 'map=%s' % src_map]
- self.SwitchEnv('source')
- name, found = utils.GetLayerNameFromCmd(cmdlist)
- self.SrcMap.AddLayer(
- ltype=rendertype,
- command=cmdlist,
- active=True,
- name=name,
- hidden=False,
- opacity=1.0,
- render=False)
- self.SwitchEnv('target')
- if tgt_map['raster']:
- #
- # add raster layer to target map
- #
- rendertype = 'raster'
- cmdlist = ['d.rast', 'map=%s' % tgt_map['raster']]
- name, found = utils.GetLayerNameFromCmd(cmdlist)
- self.TgtMap.AddLayer(
- ltype=rendertype,
- command=cmdlist,
- active=True,
- name=name,
- hidden=False,
- opacity=1.0,
- render=False)
- if tgt_map['vector']:
- #
- # add raster layer to target map
- #
- rendertype = 'vector'
- cmdlist = ['d.vect', 'map=%s' % tgt_map['vector']]
- name, found = utils.GetLayerNameFromCmd(cmdlist)
- self.TgtMap.AddLayer(
- ltype=rendertype,
- command=cmdlist,
- active=True,
- name=name,
- hidden=False,
- opacity=1.0,
- render=False)
- #
- # start GCP Manager
- #
- self.gcpmgr = GCP(self.parent, giface=self._giface,
- grwiz=self, size=globalvar.MAP_WINDOW_SIZE,
- toolbars=["gcpdisp"],
- Map=self.SrcMap, lmgr=self.parent)
- # load GCPs
- self.gcpmgr.InitMapDisplay()
- self.gcpmgr.CenterOnScreen()
- self.gcpmgr.Show()
- # need to update AUI here for wingrass
- self.gcpmgr._mgr.Update()
- else:
- self.Cleanup()
- def SetSrcEnv(self, location, mapset):
- """Create environment to use for location and mapset
- that are the source of the file(s) to georectify
- :param location: source location
- :param mapset: source mapset
- :return: False on error
- :return: True on success
- """
- self.newlocation = location
- self.newmapset = mapset
- # check to see if we are georectifying map in current working
- # location/mapset
- if self.newlocation == self.currentlocation and self.newmapset == self.currentmapset:
- return False
- self.gisrc_dict['LOCATION_NAME'] = location
- self.gisrc_dict['MAPSET'] = mapset
- self.source_gisrc = EncodeString(utils.GetTempfile())
- try:
- f = open(self.source_gisrc, mode='w')
- for line in self.gisrc_dict.items():
- f.write(line[0] + ": " + line[1] + "\n")
- finally:
- f.close()
- return True
- def SwitchEnv(self, grc):
- """
- Switches between original working location/mapset and
- location/mapset that is source of file(s) to georectify
- """
- # check to see if we are georectifying map in current working
- # location/mapset
- if self.newlocation == self.currentlocation and self.newmapset == self.currentmapset:
- return False
- if grc == 'target':
- os.environ['GISRC'] = str(self.target_gisrc)
- elif grc == 'source':
- os.environ['GISRC'] = str(self.source_gisrc)
- return True
- def OnWizFinished(self):
- # self.Cleanup()
- return True
- def OnGLMFocus(self, event):
- """Layer Manager focus"""
- # self.SwitchEnv('target')
- event.Skip()
- def Cleanup(self):
- """Return to current location and mapset"""
- # here was also the cleaning of gcpmanagement from layer manager
- # which is no longer needed
- self.SwitchEnv('target')
- self.wizard.Destroy()
- class LocationPage(TitledPage):
- """
- Set map type (raster or vector) to georectify and
- select location/mapset of map(s) to georectify.
- """
- def __init__(self, wizard, parent):
- TitledPage.__init__(self, wizard, _(
- "Select map type and location/mapset"))
- self.parent = parent
- self.grassdatabase = self.parent.grassdatabase
- self.xylocation = ''
- self.xymapset = ''
- #
- # layout
- #
- # map type
- self.rb_maptype = wx.RadioBox(
- parent=self, id=wx.ID_ANY, label=' %s ' %
- _("Map type to georectify"), choices=[
- _('raster'), _('vector')], majorDimension=wx.RA_SPECIFY_COLS)
- self.sizer.Add(self.rb_maptype,
- flag=wx.ALIGN_CENTER | wx.ALL | wx.EXPAND, border=5,
- pos=(1, 1), span=(1, 2))
- # location
- self.sizer.Add(
- StaticText(
- parent=self,
- id=wx.ID_ANY,
- label=_('Select source location:')),
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5,
- pos=(
- 2,
- 1))
- self.cb_location = LocationSelect(
- parent=self, gisdbase=self.grassdatabase)
- self.sizer.Add(
- self.cb_location,
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5,
- pos=(
- 2,
- 2))
- # mapset
- self.sizer.Add(
- StaticText(
- parent=self,
- id=wx.ID_ANY,
- label=_('Select source mapset:')),
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5,
- pos=(
- 3,
- 1))
- self.cb_mapset = MapsetSelect(parent=self, gisdbase=self.grassdatabase,
- setItems=False)
- self.sizer.Add(self.cb_mapset, flag=wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5, pos=(3, 2))
- self.sizer.AddGrowableCol(2)
- #
- # bindings
- #
- self.Bind(wx.EVT_RADIOBOX, self.OnMaptype, self.rb_maptype)
- self.Bind(wx.EVT_COMBOBOX, self.OnLocation, self.cb_location)
- self.cb_mapset.Bind(wx.EVT_TEXT, self.OnMapset)
- self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
- self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnEnterPage)
- # self.Bind(wx.EVT_CLOSE, self.parent.Cleanup)
- def OnMaptype(self, event):
- """Change map type"""
- global maptype
- if event.GetInt() == 0:
- maptype = 'raster'
- else:
- maptype = 'vector'
- def OnLocation(self, event):
- """Sets source location for map(s) to georectify"""
- self.xylocation = event.GetString()
- # create a list of valid mapsets
- tmplist = os.listdir(os.path.join(self.grassdatabase, self.xylocation))
- self.mapsetList = []
- for item in tmplist:
- if os.path.isdir(os.path.join(self.grassdatabase, self.xylocation, item)) and \
- os.path.exists(os.path.join(self.grassdatabase, self.xylocation, item, 'WIND')):
- if item != 'PERMANENT':
- self.mapsetList.append(item)
- self.xymapset = 'PERMANENT'
- utils.ListSortLower(self.mapsetList)
- self.mapsetList.insert(0, 'PERMANENT')
- self.cb_mapset.SetItems(self.mapsetList)
- self.cb_mapset.SetStringSelection(self.xymapset)
- if not wx.FindWindowById(wx.ID_FORWARD).IsEnabled():
- wx.FindWindowById(wx.ID_FORWARD).Enable(True)
- def OnMapset(self, event):
- """Sets source mapset for map(s) to georectify"""
- if self.xylocation == '':
- GMessage(_('You must select a valid location '
- 'before selecting a mapset'),
- parent=self)
- return
- self.xymapset = event.GetString()
- if not wx.FindWindowById(wx.ID_FORWARD).IsEnabled():
- wx.FindWindowById(wx.ID_FORWARD).Enable(True)
- def OnPageChanging(self, event=None):
- if event.GetDirection() and \
- (self.xylocation == '' or self.xymapset == ''):
- GMessage(_('You must select a valid location '
- 'and mapset in order to continue'),
- parent=self)
- event.Veto()
- return
- self.parent.SetSrcEnv(self.xylocation, self.xymapset)
- def OnEnterPage(self, event=None):
- if self.xylocation == '' or self.xymapset == '':
- wx.FindWindowById(wx.ID_FORWARD).Enable(False)
- else:
- wx.FindWindowById(wx.ID_FORWARD).Enable(True)
- class GroupPage(TitledPage):
- """
- Set group to georectify. Create group if desired.
- """
- def __init__(self, wizard, parent):
- TitledPage.__init__(self, wizard, _(
- "Select image/map group to georectify"))
- self.parent = parent
- self.grassdatabase = self.parent.grassdatabase
- self.groupList = []
- self.xylocation = ''
- self.xymapset = ''
- self.xygroup = ''
- # default extension
- self.extension = '_georect' + str(os.getpid())
- #
- # layout
- #
- # group
- self.sizer.Add(
- StaticText(
- parent=self,
- id=wx.ID_ANY,
- label=_('Select group:')),
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5,
- pos=(
- 1,
- 1))
- self.cb_group = wx.ComboBox(parent=self, id=wx.ID_ANY,
- choices=self.groupList, size=(350, -1),
- style=wx.CB_DROPDOWN | wx.CB_READONLY)
- self.sizer.Add(self.cb_group, flag=wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5, pos=(1, 2))
- # create group
- self.sizer.Add(
- StaticText(
- parent=self,
- id=wx.ID_ANY,
- label=_('Create group if none exists')),
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5,
- pos=(
- 2,
- 1))
- btnSizer = wx.BoxSizer(wx.HORIZONTAL)
- self.btn_mkgroup = Button(
- parent=self,
- id=wx.ID_ANY,
- label=_("Create/edit group..."))
- self.btn_vgroup = Button(
- parent=self,
- id=wx.ID_ANY,
- label=_("Add vector map to group..."))
- btnSizer.Add(self.btn_mkgroup,
- flag=wx.RIGHT, border=5)
- btnSizer.Add(self.btn_vgroup,
- flag=wx.LEFT, border=5)
- self.sizer.Add(
- btnSizer,
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5,
- pos=(
- 2,
- 2))
- # extension
- self.sizer.Add(
- StaticText(
- parent=self,
- id=wx.ID_ANY,
- label=_('Extension for output maps:')),
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5,
- pos=(
- 3,
- 1))
- self.ext_txt = TextCtrl(
- parent=self, id=wx.ID_ANY, value="", size=(
- 350, -1))
- self.ext_txt.SetValue(self.extension)
- self.sizer.Add(self.ext_txt, flag=wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5, pos=(3, 2))
- self.sizer.AddGrowableCol(2)
- #
- # bindings
- #
- self.Bind(wx.EVT_COMBOBOX, self.OnGroup, self.cb_group)
- self.Bind(wx.EVT_TEXT, self.OnExtension, self.ext_txt)
- self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
- self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnEnterPage)
- self.Bind(wx.EVT_CLOSE, self.parent.Cleanup)
- # hide vector group button by default
- self.btn_vgroup.Hide()
- def OnGroup(self, event):
- self.xygroup = event.GetString()
- def OnMkGroup(self, event):
- """Create new group in source location/mapset"""
- dlg = GroupDialog(parent=self, defaultGroup=self.xygroup)
- dlg.DisableSubgroupEdit()
- dlg.ShowModal()
- gr, s = dlg.GetSelectedGroup()
- if gr in dlg.GetExistGroups():
- self.xygroup = gr
- else:
- gr = ''
- dlg.Destroy()
- self.OnEnterPage()
- self.Update()
- def OnVGroup(self, event):
- """Add vector maps to group"""
- dlg = VectGroup(parent=self,
- id=wx.ID_ANY,
- grassdb=self.grassdatabase,
- location=self.xylocation,
- mapset=self.xymapset,
- group=self.xygroup)
- if dlg.ShowModal() != wx.ID_OK:
- return
- dlg.MakeVGroup()
- self.OnEnterPage()
- def OnExtension(self, event):
- self.extension = self.ext_txt.GetValue()
- def OnPageChanging(self, event=None):
- if event.GetDirection() and self.xygroup == '':
- GMessage(_('You must select a valid image/map '
- 'group in order to continue'),
- parent=self)
- event.Veto()
- return
- if event.GetDirection() and self.extension == '':
- GMessage(_('You must enter an map name '
- 'extension in order to continue'),
- parent=self)
- event.Veto()
- return
- def OnEnterPage(self, event=None):
- global maptype
- self.groupList = []
- self.xylocation = self.parent.gisrc_dict['LOCATION_NAME']
- self.xymapset = self.parent.gisrc_dict['MAPSET']
- # create a list of groups in selected mapset
- if os.path.isdir(os.path.join(self.grassdatabase,
- self.xylocation,
- self.xymapset,
- 'group')):
- tmplist = os.listdir(os.path.join(self.grassdatabase,
- self.xylocation,
- self.xymapset,
- 'group'))
- for item in tmplist:
- if os.path.isdir(os.path.join(self.grassdatabase,
- self.xylocation,
- self.xymapset,
- 'group',
- item)):
- self.groupList.append(item)
- if maptype == 'raster':
- self.btn_vgroup.Hide()
- self.Bind(wx.EVT_BUTTON, self.OnMkGroup, self.btn_mkgroup)
- elif maptype == 'vector':
- self.btn_vgroup.Show()
- self.Bind(wx.EVT_BUTTON, self.OnMkGroup, self.btn_mkgroup)
- self.Bind(wx.EVT_BUTTON, self.OnVGroup, self.btn_vgroup)
- utils.ListSortLower(self.groupList)
- self.cb_group.SetItems(self.groupList)
- if len(self.groupList) > 0:
- if self.xygroup and self.xygroup in self.groupList:
- self.cb_group.SetStringSelection(self.xygroup)
- else:
- self.cb_group.SetSelection(0)
- self.xygroup = self.groupList[0]
- if self.xygroup == '' or \
- self.extension == '':
- wx.FindWindowById(wx.ID_FORWARD).Enable(False)
- else:
- wx.FindWindowById(wx.ID_FORWARD).Enable(True)
- # switch to source
- self.parent.SwitchEnv('source')
- class DispMapPage(TitledPage):
- """
- Select ungeoreferenced map to display for interactively
- setting ground control points (GCPs).
- """
- def __init__(self, wizard, parent):
- TitledPage.__init__(
- self, wizard,
- _("Select maps to display for ground control point (GCP) creation"))
- self.parent = parent
- global maptype
- #
- # layout
- #
- self.sizer.Add(
- StaticText(
- parent=self,
- id=wx.ID_ANY,
- label=_('Select source map to display:')),
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5,
- pos=(
- 1,
- 1))
- self.srcselection = Select(
- self,
- id=wx.ID_ANY,
- size=globalvar.DIALOG_GSELECT_SIZE,
- type=maptype,
- updateOnPopup=False)
- self.sizer.Add(
- self.srcselection,
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5,
- pos=(
- 1,
- 2))
- self.sizer.Add(
- StaticText(
- parent=self,
- id=wx.ID_ANY,
- label=_('Select target raster map to display:')),
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5,
- pos=(
- 2,
- 1))
- self.tgtrastselection = Select(
- self, id=wx.ID_ANY, size=globalvar.DIALOG_GSELECT_SIZE,
- type='raster', updateOnPopup=False)
- self.sizer.Add(
- self.tgtrastselection,
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5,
- pos=(
- 2,
- 2))
- self.sizer.Add(
- StaticText(
- parent=self,
- id=wx.ID_ANY,
- label=_('Select target vector map to display:')),
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5,
- pos=(
- 3,
- 1))
- self.tgtvectselection = Select(
- self, id=wx.ID_ANY, size=globalvar.DIALOG_GSELECT_SIZE,
- type='vector', updateOnPopup=False)
- self.sizer.Add(
- self.tgtvectselection,
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5,
- pos=(
- 3,
- 2))
- #
- # bindings
- #
- self.srcselection.Bind(wx.EVT_TEXT, self.OnSrcSelection)
- self.tgtrastselection.Bind(wx.EVT_TEXT, self.OnTgtRastSelection)
- self.tgtvectselection.Bind(wx.EVT_TEXT, self.OnTgtVectSelection)
- self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
- self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnEnterPage)
- self.Bind(wx.EVT_CLOSE, self.parent.Cleanup)
- def OnSrcSelection(self, event):
- """Source map to display selected"""
- global src_map
- global maptype
- src_map = self.srcselection.GetValue()
- if src_map == '':
- wx.FindWindowById(wx.ID_FORWARD).Enable(False)
- else:
- wx.FindWindowById(wx.ID_FORWARD).Enable(True)
- try:
- # set computational region to match selected map and zoom display
- # to region
- if maptype == 'raster':
- p = RunCommand('g.region', 'raster=src_map')
- elif maptype == 'vector':
- p = RunCommand('g.region', 'vector=src_map')
- if p.returncode == 0:
- print('returncode = ', str(p.returncode))
- self.parent.Map.region = self.parent.Map.GetRegion()
- except:
- pass
- def OnTgtRastSelection(self, event):
- """Source map to display selected"""
- global tgt_map
- tgt_map['raster'] = self.tgtrastselection.GetValue()
- def OnTgtVectSelection(self, event):
- """Source map to display selected"""
- global tgt_map
- tgt_map['vector'] = self.tgtvectselection.GetValue()
- def OnPageChanging(self, event=None):
- global src_map
- global tgt_map
- if event.GetDirection() and (src_map == ''):
- GMessage(_('You must select a source map '
- 'in order to continue'),
- parent=self)
- event.Veto()
- return
- self.parent.SwitchEnv('target')
- def OnEnterPage(self, event=None):
- global maptype
- global src_map
- global tgt_map
- self.srcselection.SetElementList(maptype)
- if maptype == 'raster':
- ret = RunCommand('i.group',
- parent=self,
- read=True,
- group=self.parent.grouppage.xygroup,
- flags='g')
- if ret:
- self.parent.src_maps = ret.splitlines()
- else:
- GError(
- parent=self, message=_(
- 'No maps in selected group <%s>.\n'
- 'Please edit group or select another group.') %
- self.parent.grouppage.xygroup)
- return
- elif maptype == 'vector':
- grassdatabase = self.parent.grassdatabase
- xylocation = self.parent.gisrc_dict['LOCATION_NAME']
- xymapset = self.parent.gisrc_dict['MAPSET']
- # make list of vectors to georectify from VREF
- vgrpfile = os.path.join(grassdatabase,
- xylocation,
- xymapset,
- 'group',
- self.parent.grouppage.xygroup,
- 'VREF')
- f = open(vgrpfile)
- try:
- for vect in f.readlines():
- vect = vect.strip('\n')
- if len(vect) < 1:
- continue
- self.parent.src_maps.append(vect)
- finally:
- f.close()
- if len(self.parent.src_maps) < 1:
- GError(
- parent=self, message=_(
- 'No maps in selected group <%s>.\n'
- 'Please edit group or select another group.') %
- self.parent.grouppage.xygroup)
- return
- # filter out all maps not in group
- self.srcselection.tcp.GetElementList(elements=self.parent.src_maps)
- src_map = self.parent.src_maps[0]
- self.srcselection.SetValue(src_map)
- self.parent.SwitchEnv('target')
- self.tgtrastselection.SetElementList('raster')
- self.tgtrastselection.GetElementList()
- self.tgtvectselection.SetElementList('vector')
- self.tgtvectselection.GetElementList()
- self.parent.SwitchEnv('source')
- if src_map == '':
- wx.FindWindowById(wx.ID_FORWARD).Enable(False)
- else:
- wx.FindWindowById(wx.ID_FORWARD).Enable(True)
- class GCP(MapFrame, ColumnSorterMixin):
- """
- Manages ground control points for georectifying. Calculates RMS statistics.
- Calls i.ortho.rectify or v.rectify to georectify map.
- """
- def __init__(self, parent, giface, grwiz=None, id=wx.ID_ANY,
- title=_("Manage Ground Control Points"),
- size=(700, 300), toolbars=["gcpdisp"], Map=None, lmgr=None):
- self.grwiz = grwiz # GR Wizard
- self._giface = giface
- if tgt_map['raster'] == '' and tgt_map['vector'] == '':
- self.show_target = False
- else:
- self.show_target = True
- #wx.Frame.__init__(self, parent, id, title, size = size, name = "GCPFrame")
- MapFrame.__init__(
- self,
- parent=parent,
- giface=self._giface,
- title=title,
- size=size,
- Map=Map,
- toolbars=toolbars,
- name='GCPMapWindow')
- # init variables
- self.parent = parent
- #
- # register data structures for drawing GCP's
- #
- self.pointsToDrawTgt = self.TgtMapWindow.RegisterGraphicsToDraw(
- graphicsType="point", setStatusFunc=self.SetGCPSatus)
- self.pointsToDrawSrc = self.SrcMapWindow.RegisterGraphicsToDraw(
- graphicsType="point", setStatusFunc=self.SetGCPSatus)
- # connect to the map windows signals
- # used to add or edit GCP
- self.SrcMapWindow.mouseLeftUpPointer.connect(
- lambda x, y:
- self._onMouseLeftUpPointer(self.SrcMapWindow, x, y))
- self.TgtMapWindow.mouseLeftUpPointer.connect(
- lambda x, y:
- self._onMouseLeftUpPointer(self.TgtMapWindow, x, y))
- # window resized
- self.resize = False
- self.grassdatabase = self.grwiz.grassdatabase
- self.currentlocation = self.grwiz.currentlocation
- self.currentmapset = self.grwiz.currentmapset
- self.newlocation = self.grwiz.newlocation
- self.newmapset = self.grwiz.newmapset
- self.xylocation = self.grwiz.gisrc_dict['LOCATION_NAME']
- self.xymapset = self.grwiz.gisrc_dict['MAPSET']
- self.xygroup = self.grwiz.grouppage.xygroup
- self.src_maps = self.grwiz.src_maps
- self.extension = self.grwiz.grouppage.extension
- self.outname = ''
- self.VectGRList = []
- self.file = {
- 'control_points': os.path.join(self.grassdatabase,
- self.xylocation,
- self.xymapset,
- 'group',
- self.xygroup,
- 'CONTROL_POINTS'),
- 'control_points_bak': os.path.join(self.grassdatabase,
- self.xylocation,
- self.xymapset,
- 'group',
- self.xygroup,
- 'CONTROL_POINTS_BAK'),
- 'rgrp': os.path.join(self.grassdatabase,
- self.xylocation,
- self.xymapset,
- 'group',
- self.xygroup,
- 'REF'),
- 'vgrp': os.path.join(self.grassdatabase,
- self.xylocation,
- self.xymapset,
- 'group',
- self.xygroup,
- 'VREF'),
- 'target': os.path.join(self.grassdatabase,
- self.xylocation,
- self.xymapset,
- 'group',
- self.xygroup,
- 'TARGET'),
- 'elevation': os.path.join(self.grassdatabase,
- self.xylocation,
- self.xymapset,
- 'group',
- self.xygroup,
- 'ELEVATION'),
- }
- # make a backup of the current points file
- if os.path.exists(self.file['control_points']):
- shutil.copy(self.file['control_points'], self.file['control_points_bak'])
- # polynomial order transformation for georectification
- self.gr_order = 1
- # interpolation method for georectification
- self.gr_method = 'nearest'
- # region clipping for georectified map
- self.clip_to_region = False
- # number of GCPs selected to be used for georectification (checked)
- self.GCPcount = 0
- # forward RMS error
- self.fwd_rmserror = 0.0
- # backward RMS error
- self.bkw_rmserror = 0.0
- # list map coords and ID of map display they came from
- self.mapcoordlist = []
- self.mapcoordlist.append([0, # GCP number
- 0.0, # source east
- 0.0, # source north
- 0.0, # source height
- 0.0, # target east
- 0.0, # target north
- 0.0, # target height
- 0.0, # forward error
- 0.0]) # backward error
- # init vars to highlight high RMS errors
- self.highest_only = True
- self.show_unused = True
- self.highest_key = -1
- self.rmsthresh = 0
- self.rmsmean = 0
- self.rmssd = 0
- self.SetTarget(self.xygroup, self.currentlocation, self.currentmapset)
- self.itemDataMap = None
- # images for column sorting
- # CheckListCtrlMixin must set an ImageList first
- self.il = self.list.GetImageList(wx.IMAGE_LIST_SMALL)
- SmallUpArrow = wx.BitmapFromImage(getSmallUpArrowImage())
- SmallDnArrow = wx.BitmapFromImage(getSmallDnArrowImage())
- self.sm_dn = self.il.Add(SmallDnArrow)
- self.sm_up = self.il.Add(SmallUpArrow)
- # set mouse characteristics
- self.mapwin = self.SrcMapWindow
- self.mapwin.mouse['box'] = 'point'
- self.mapwin.mouse["use"] == "pointer"
- self.mapwin.zoomtype = 0
- self.mapwin.pen = wx.Pen(colour='black', width=2, style=wx.SOLID)
- self.mapwin.SetNamedCursor('cross')
- self.mapwin = self.TgtMapWindow
- # set mouse characteristics
- self.mapwin.mouse['box'] = 'point'
- self.mapwin.mouse["use"] == "pointer"
- self.mapwin.zoomtype = 0
- self.mapwin.pen = wx.Pen(colour='black', width=2, style=wx.SOLID)
- self.mapwin.SetNamedCursor('cross')
- #
- # show new display & draw map
- #
- if self.show_target:
- self.MapWindow = self.TgtMapWindow
- self.Map = self.TgtMap
- self.OnZoomToMap(None)
- self.MapWindow = self.SrcMapWindow
- self.Map = self.SrcMap
- self.OnZoomToMap(None)
- #
- # bindings
- #
- self.Bind(wx.EVT_ACTIVATE, self.OnFocus)
- self.Bind(wx.EVT_SIZE, self.OnSize)
- self.Bind(wx.EVT_IDLE, self.OnIdle)
- self.Bind(wx.EVT_CLOSE, self.OnQuit)
- self.SetSettings()
- def __del__(self):
- """Disable GCP manager mode"""
- # leaving the method here but was used only to delete gcpmanagement
- # from layer manager which is now not needed
- pass
- def CreateGCPList(self):
- """Create GCP List Control"""
- return GCPList(parent=self, gcp=self)
- # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
- def GetListCtrl(self):
- return self.list
- def GetMapCoordList(self):
- return self.mapcoordlist
- # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
- def GetSortImages(self):
- return (self.sm_dn, self.sm_up)
- def GetFwdError(self):
- return self.fwd_rmserror
- def GetBkwError(self):
- return self.bkw_rmserror
- def InitMapDisplay(self):
- self.list.LoadData()
- # initialize column sorter
- self.itemDataMap = self.mapcoordlist
- ncols = self.list.GetColumnCount()
- ColumnSorterMixin.__init__(self, ncols)
- # init to ascending sort on first click
- self._colSortFlag = [1] * ncols
- def SetTarget(self, tgroup, tlocation, tmapset):
- """
- Sets rectification target to current location and mapset
- """
- # check to see if we are georectifying map in current working
- # location/mapset
- if self.newlocation == self.currentlocation and self.newmapset == self.currentmapset:
- RunCommand('i.target',
- parent=self,
- flags='c',
- group=tgroup)
- else:
- self.grwiz.SwitchEnv('source')
- RunCommand('i.target',
- parent=self,
- group=tgroup,
- location=tlocation,
- mapset=tmapset)
- self.grwiz.SwitchEnv('target')
- def AddGCP(self, event):
- """
- Appends an item to GCP list
- """
- keyval = self.list.AddGCPItem() + 1
- # source east, source north, target east, target north, forward error,
- # backward error
- self.mapcoordlist.append([keyval, # GCP number
- 0.0, # source east
- 0.0, # source north
- 0.0, # source height
- 0.0, # target east
- 0.0, # target north
- 0.0, # target height
- 0.0, # forward error
- 0.0]) # backward error
- if self.statusbarManager.GetMode() == 8: # go to
- self.StatusbarUpdate()
- def DeleteGCP(self, event):
- """
- Deletes selected item in GCP list
- """
- minNumOfItems = self.OnGROrder(None)
- if self.list.GetItemCount() <= minNumOfItems:
- GMessage(
- parent=self,
- message=_("At least %d GCPs required. Operation canceled.") %
- minNumOfItems)
- return
- key = self.list.DeleteGCPItem()
- del self.mapcoordlist[key]
- # update key and GCP number
- for newkey in range(key, len(self.mapcoordlist)):
- index = self.list.FindItemData(-1, newkey + 1)
- self.mapcoordlist[newkey][0] = newkey
- self.list.SetStringItem(index, 0, str(newkey))
- self.list.SetItemData(index, newkey)
- # update selected
- if self.list.GetItemCount() > 0:
- if self.list.selected < self.list.GetItemCount():
- self.list.selectedkey = self.list.GetItemData(
- self.list.selected)
- else:
- self.list.selected = self.list.GetItemCount() - 1
- self.list.selectedkey = self.list.GetItemData(
- self.list.selected)
- self.list.SetItemState(self.list.selected,
- wx.LIST_STATE_SELECTED,
- wx.LIST_STATE_SELECTED)
- else:
- self.list.selected = wx.NOT_FOUND
- self.list.selectedkey = -1
- self.UpdateColours()
- if self.statusbarManager.GetMode() == 8: # go to
- self.StatusbarUpdate()
- if self.list.selectedkey > 0:
- self.statusbarManager.SetProperty(
- 'gotoGCP', self.list.selectedkey)
- def ClearGCP(self, event):
- """
- Clears all values in selected item of GCP list and unchecks it
- """
- index = self.list.GetSelected()
- key = self.list.GetItemData(index)
- for i in range(1, 7):
- self.list.SetStringItem(index, i, '0.0')
- self.list.SetStringItem(index, 7, '')
- self.list.SetStringItem(index, 8, '')
- self.list.CheckItem(index, False)
- # GCP number, source E, source N, target E, target N, fwd error, bkwd
- # error
- self.mapcoordlist[key] = [key, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
- def SetSettings(self):
- """Sets settings for drawing of GCP's.
- """
- self.highest_only = UserSettings.Get(
- group='gcpman', key='rms', subkey='highestonly')
- self.show_unused = UserSettings.Get(
- group='gcpman', key='symbol', subkey='unused')
- colours = {"color": "default",
- "hcolor": "highest",
- "scolor": "selected",
- "ucolor": "unused"}
- wpx = UserSettings.Get(group='gcpman', key='symbol', subkey='width')
- for k, v in six.iteritems(colours):
- col = UserSettings.Get(group='gcpman', key='symbol', subkey=k)
- self.pointsToDrawSrc.GetPen(v).SetColour(wx.Colour(
- col[0], col[1], col[2], 255)) # TODO GetPen neni to spatne?
- self.pointsToDrawTgt.GetPen(v).SetColour(
- wx.Colour(col[0], col[1], col[2], 255))
- self.pointsToDrawSrc.GetPen(v).SetWidth(wpx)
- self.pointsToDrawTgt.GetPen(v).SetWidth(wpx)
- spx = UserSettings.Get(group='gcpman', key='symbol', subkey='size')
- self.pointsToDrawSrc.SetPropertyVal("size", int(spx))
- self.pointsToDrawTgt.SetPropertyVal("size", int(spx))
- font = self.GetFont()
- font.SetPointSize(int(spx) + 2)
- textProp = {}
- textProp['active'] = True
- textProp['font'] = font
- self.pointsToDrawSrc.SetPropertyVal("text", textProp)
- self.pointsToDrawTgt.SetPropertyVal("text", copy(textProp))
- def SetGCPSatus(self, item, itemIndex):
- """Before GCP is drawn, decides it's colour and whether it
- will be drawed.
- """
- key = self.list.GetItemData(itemIndex)
- # incremented because of itemDataMap (has one more item) - will be
- # changed
- itemIndex += 1
- if not self.list.IsChecked(key - 1):
- wxPen = "unused"
- if not self.show_unused:
- item.SetPropertyVal('hide', True)
- else:
- item.SetPropertyVal('hide', False)
- else:
- item.SetPropertyVal('hide', False)
- if self.highest_only == True:
- if itemIndex == self.highest_key:
- wxPen = "highest"
- else:
- wxPen = "default"
- else:
- if (self.mapcoordlist[key][7] > self.rmsthresh):
- wxPen = "highest"
- else:
- wxPen = "default"
- if itemIndex == self.list.selectedkey:
- wxPen = "selected"
- item.SetPropertyVal('label', str(itemIndex))
- item.SetPropertyVal('penName', wxPen)
- def SetGCPData(self, coordtype, coord, mapdisp=None, confirm=False):
- """Inserts coordinates from file, mouse click on map, or
- after editing into selected item of GCP list and checks it for
- use.
- """
- index = self.list.GetSelected()
- if index == wx.NOT_FOUND:
- return
- coord0 = coord[0]
- coord1 = coord[1]
- key = self.list.GetItemData(index)
- if confirm:
- if self.MapWindow == self.SrcMapWindow:
- currloc = _("source")
- else:
- currloc = _("target")
- ret = wx.MessageBox(
- parent=self, caption=_("Set GCP coordinates"),
- message=_(
- 'Set %(coor)s coordinates for GCP No. %(key)s? \n\n'
- 'East: %(coor0)s \n'
- 'North: %(coor1)s') %
- {'coor': currloc, 'key': str(key),
- 'coor0': str(coord0),
- 'coor1': str(coord1)},
- style=wx.ICON_QUESTION | wx.YES_NO | wx.CENTRE)
- # for wingrass
- if os.name == 'nt':
- self.MapWindow.SetFocus()
- if ret == wx.NO:
- return
- if coordtype == 'source':
- self.list.SetStringItem(index, 1, str(coord0))
- self.list.SetStringItem(index, 2, str(coord1))
- self.mapcoordlist[key][1] = coord[0]
- self.mapcoordlist[key][2] = coord[1]
- self.pointsToDrawSrc.GetItem(key - 1).SetCoords([coord0, coord1])
- elif coordtype == 'target':
- self.list.SetStringItem(index, 4, str(coord0))
- self.list.SetStringItem(index, 5, str(coord1))
- self.mapcoordlist[key][4] = coord[0]
- self.mapcoordlist[key][5] = coord[1]
- #ADD ELEVATION FROM MAP AS HEIGHT PARAMETER
- if os.path.exists(self.file['elevation']):
- #Parse the i.ortho.elev generated file
- #Get all lines from file
- lines = open(self.file['elevation']).read().splitlines()
- #Remove empty spaces in lines
- lines = [x.replace(' ','') for x in lines]
- #Extract map@mapset
- elevationmap=lines[0].split(':')[1]+'@'+lines[1].split(':')[1]
- #Make sure the region is set to the elevation map
- ret, msg = RunCommand('g.region',
- parent=self,
- getErrorMsg=True,
- quiet=True,
- raster=elevationmap,
- flags=None)
- #Get the elevation height from the map given by i.ortho.elev
- from subprocess import PIPE
- from grass.pygrass.modules import Module
- rwhat = Module('r.what',
- map=elevationmap,
- coordinates=[coord[0],coord[1]],
- stdout_=PIPE)
- self.mapcoordlist[key][6] = rwhat.outputs.stdout.split('|')[3].rstrip('\n')
- self.list.SetStringItem(index, 6, str(self.mapcoordlist[key][6]))
- self.pointsToDrawTgt.GetItem(key - 1).SetCoords([coord0, coord1])
- self.list.SetStringItem(index, 7, '0')
- self.list.SetStringItem(index, 8, '0')
- self.mapcoordlist[key][7] = 0.0
- self.mapcoordlist[key][8] = 0.0
- # self.list.ResizeColumns()
- def SaveGCPs(self, event):
- """Make a CONTROL_POINTS file or save GCP coordinates to existing
- POINTS file
- """
- self.GCPcount = 0
- try:
- f = open(self.file['control_points'], mode='w')
- # use os.linesep or '\n' here ???
- f.write('# Ground Control Points File\n')
- f.write("# \n")
- f.write("# target location: " + self.currentlocation + '\n')
- f.write("# target mapset: " + self.currentmapset + '\n')
- f.write("#\tsource\t\t\ttarget\t\t\tstatus\n")
- f.write("#\teast\tnorth\theight\teast\tnorth\theight\t(1=ok, 0=ignore)\n")
- f.write(
- "#---------------------------- --------------------------- ---------------\n")
- for index in range(self.list.GetItemCount()):
- if self.list.IsChecked(index) == True:
- check = "1"
- self.GCPcount += 1
- else:
- check = "0"
- coord0 = self.list.GetItem(index, 1).GetText()
- coord1 = self.list.GetItem(index, 2).GetText()
- coord2 = self.list.GetItem(index, 3).GetText()
- coord3 = self.list.GetItem(index, 4).GetText()
- coord4 = self.list.GetItem(index, 5).GetText()
- coord5 = self.list.GetItem(index, 6).GetText()
- f.write(
- coord0 +
- ' ' +
- coord1 +
- ' ' +
- coord2 +
- ' ' +
- coord3 +
- ' ' +
- coord4 +
- ' ' +
- coord5 +
- ' ' +
- check +
- '\n')
- except IOError as err:
- GError(
- parent=self,
- message="%s <%s>. %s%s" %
- (_("Writing CONTROL_POINTS file failed"),
- self.file['control_points'],
- os.linesep,
- err))
- return
- f.close()
- # if event != None save also to backup file
- if event:
- shutil.copy(self.file['control_points'], self.file['control_points_bak'])
- self._giface.WriteLog(
- _('CONTROL_POINTS file saved for group <%s>') %
- self.xygroup)
- #self.SetStatusText(_('POINTS file saved'))
- def ReadGCPs(self):
- """
- Reads GCPs and georectified coordinates from POINTS file
- """
- self.GCPcount = 0
- sourceMapWin = self.SrcMapWindow
- targetMapWin = self.TgtMapWindow
- if not sourceMapWin:
- GError(parent=self,
- message="%s. %s%s" % (_("source mapwin not defined"),
- os.linesep, err))
- if not targetMapWin:
- GError(parent=self,
- message="%s. %s%s" % (_("target mapwin not defined"),
- os.linesep, err))
- try:
- f = open(self.file['control_points'], 'r')
- GCPcnt = 0
- for line in f.readlines():
- if line[0] == '#' or line == '':
- continue
- line = line.replace('\n', '').strip()
- coords = map(float, line.split())
- if coords[6] == 1:
- check = True
- self.GCPcount += 1
- else:
- check = False
- self.AddGCP(event=None)
- self.SetGCPData('source', (coords[0], coords[1]), sourceMapWin)
- self.SetGCPData('target', (coords[3], coords[4]), targetMapWin)
- index = self.list.GetSelected()
- if index != wx.NOT_FOUND:
- self.list.CheckItem(index, check)
- GCPcnt += 1
- except IOError as err:
- GError(
- parent=self,
- message="%s <%s>. %s%s" %
- (_("Reading CONTROL_POINTS file failed"),
- self.file['control_points'],
- os.linesep,
- err))
- return
- f.close()
- if GCPcnt == 0:
- # 3 gcp is minimum
- for i in range(3):
- self.AddGCP(None)
- if self.CheckGCPcount():
- # calculate RMS
- self.RMSError(self.xygroup, self.gr_order)
- def ReloadGCPs(self, event):
- """Reload data from file"""
- # use backup
- shutil.copy(self.file['control_points_bak'], self.file['control_points'])
- # delete all items in mapcoordlist
- self.mapcoordlist = []
- self.mapcoordlist.append([0, # GCP number
- 0.0, # source east
- 0.0, # source north
- 0.0, # source height
- 0.0, # target east
- 0.0, # target north
- 0.0, # target height
- 0.0, # forward error
- 0.0]) # backward error
- self.list.LoadData()
- self.itemDataMap = self.mapcoordlist
- if self._col != -1:
- self.list.ClearColumnImage(self._col)
- self._colSortFlag = [1] * self.list.GetColumnCount()
- # draw GCPs (source and target)
- sourceMapWin = self.SrcMapWindow
- sourceMapWin.UpdateMap(render=False, renderVector=False)
- if self.show_target:
- targetMapWin = self.TgtMapWindow
- targetMapWin.UpdateMap(render=False, renderVector=False)
- def OnFocus(self, event):
- # TODO: it is here just to remove old or obsolate beavior of base class gcp/MapFrame?
- # self.grwiz.SwitchEnv('source')
- pass
- def _onMouseLeftUpPointer(self, mapWindow, x, y):
- if mapWindow == self.SrcMapWindow:
- coordtype = 'source'
- else:
- coordtype = 'target'
- coord = (x, y)
- self.SetGCPData(coordtype, coord, self, confirm=True)
- mapWindow.UpdateMap(render=False, renderVector=False)
- def OnRMS(self, event):
- """
- RMS button handler
- """
- self.RMSError(self.xygroup, self.gr_order)
- sourceMapWin = self.SrcMapWindow
- sourceMapWin.UpdateMap(render=False, renderVector=False)
- if self.show_target:
- targetMapWin = self.TgtMapWindow
- targetMapWin.UpdateMap(render=False, renderVector=False)
- def CheckGCPcount(self, msg=False):
- """
- Checks to make sure that the minimum number of GCPs have been defined and
- are active for the selected transformation order
- """
- if (self.GCPcount < 3 and self.gr_order == 1) or \
- (self.GCPcount < 6 and self.gr_order == 2) or \
- (self.GCPcount < 10 and self.gr_order == 3):
- if msg:
- GWarning(
- parent=self, message=_(
- 'Insufficient points defined and active (checked) '
- 'for selected rectification method (order: %d).\n'
- '3+ points needed for 1st order,\n'
- '6+ points for 2nd order, and\n'
- '10+ points for 3rd order.') %
- self.gr_order)
- return False
- else:
- return True
- def OnGeorect(self, event):
- """
- Georectifies map(s) in group using i.ortho.rectify or v.rectify
- """
- global maptype
- self.SaveGCPs(None)
- if self.CheckGCPcount(msg=True) == False:
- return
- if maptype == 'raster':
- self.grwiz.SwitchEnv('source')
- if self.clip_to_region:
- flags = "ac"
- else:
- flags = "a"
- busy = wx.BusyInfo(_("Rectifying images, please wait..."),
- parent=self)
- wx.Yield()
- ret, msg = RunCommand('i.ortho.rectify',
- parent=self,
- getErrorMsg=True,
- quiet=True,
- group=self.xygroup,
- extension=self.extension,
- method=self.gr_method,
- angle=self.grwiz.cam_angle,
- flags=flags)
- del busy
- # provide feedback on failure
- if ret != 0:
- print(msg, file=sys.stderr)
- elif maptype == 'vector':
- # loop through all vectors in VREF
- self.grwiz.SwitchEnv('source')
- # make list of vectors to georectify from VREF
- f = open(self.file['vgrp'])
- vectlist = []
- try:
- for vect in f.readlines():
- vect = vect.strip('\n')
- if len(vect) < 1:
- continue
- vectlist.append(vect)
- finally:
- f.close()
- # georectify each vector in VREF using v.rectify
- for vect in vectlist:
- self.outname = str(vect.split('@')[0]) + self.extension
- self._giface.WriteLog(text=_('Transforming <%s>...') % vect,
- notification=Notification.MAKE_VISIBLE)
- ret = msg = ''
- busy = wx.BusyInfo(
- _("Rectifying vector map <%s>, please wait...") %
- vect, parent=self)
- wx.Yield()
- ret, msg = RunCommand('v.rectify',
- parent=self,
- getErrorMsg=True,
- quiet=True,
- input=vect,
- output=self.outname,
- group=self.xygroup,
- order=self.gr_order)
- del busy
- # provide feedback on failure
- if ret != 0:
- print(msg, file=sys.stderr)
- self.grwiz.SwitchEnv('target')
- def OnGeorectDone(self, **kargs):
- """Print final message"""
- global maptype
- if maptype == 'raster':
- return
- returncode = kargs['returncode']
- if returncode == 0:
- self.VectGRList.append(self.outname)
- print('*****vector list = ' + str(self.VectGRList),
- file=sys.stderr)
- else:
- self._giface.WriteError(
- _('Georectification of vector map <%s> failed') %
- self.outname)
- def OnSettings(self, event):
- """GCP Manager settings"""
- dlg = GrSettingsDialog(parent=self, giface=self._giface,
- id=wx.ID_ANY, title=_('GCP Manager settings'))
- if dlg.ShowModal() == wx.ID_OK:
- pass
- dlg.Destroy()
- def UpdateColours(self, srcrender=False, srcrenderVector=False,
- tgtrender=False, tgtrenderVector=False):
- """update colours"""
- highest_fwd_err = 0.0
- self.highest_key = 0
- highest_idx = 0
- for index in range(self.list.GetItemCount()):
- if self.list.IsChecked(index):
- key = self.list.GetItemData(index)
- fwd_err = self.mapcoordlist[key][5]
- if self.highest_only == True:
- self.list.SetItemTextColour(index, wx.BLACK)
- if highest_fwd_err < fwd_err:
- highest_fwd_err = fwd_err
- self.highest_key = key
- highest_idx = index
- elif self.rmsthresh > 0:
- if (fwd_err > self.rmsthresh):
- self.list.SetItemTextColour(index, wx.RED)
- else:
- self.list.SetItemTextColour(index, wx.BLACK)
- else:
- self.list.SetItemTextColour(index, wx.BLACK)
- if self.highest_only and highest_fwd_err > 0.0:
- self.list.SetItemTextColour(highest_idx, wx.RED)
- sourceMapWin = self.SrcMapWindow
- sourceMapWin.UpdateMap(render=srcrender, renderVector=srcrenderVector)
- if self.show_target:
- targetMapWin = self.TgtMapWindow
- targetMapWin.UpdateMap(
- render=tgtrender,
- renderVector=tgtrenderVector)
- def OnQuit(self, event):
- """Quit georectifier"""
- ret = wx.MessageBox(
- parent=self, caption=_("Quit GCP Manager"),
- message=_('Save ground control points?'),
- style=wx.ICON_QUESTION | wx.YES_NO | wx.CANCEL | wx.CENTRE)
- if ret != wx.CANCEL:
- if ret == wx.YES:
- self.SaveGCPs(None)
- elif ret == wx.NO:
- # restore POINTS file from backup
- if os.path.exists(self.file['control_points_bak']):
- shutil.copy(self.file['control_points_bak'], self.file['control_points'])
- if os.path.exists(self.file['control_points_bak']):
- os.unlink(self.file['control_points_bak'])
- self.SrcMap.Clean()
- self.TgtMap.Clean()
- self.grwiz.Cleanup()
- self.Destroy()
- # event.Skip()
- def OnGROrder(self, event):
- """
- sets transformation order for georectifying
- """
- if event:
- self.gr_order = event.GetInt() + 1
- numOfItems = self.list.GetItemCount()
- minNumOfItems = numOfItems
- if self.gr_order == 1:
- minNumOfItems = 3
- # self.SetStatusText(_('Insufficient points, 3+ points needed for 1st order'))
- elif self.gr_order == 2:
- minNumOfItems = 6
- diff = 6 - numOfItems
- # self.SetStatusText(_('Insufficient points, 6+ points needed for 2nd order'))
- elif self.gr_order == 3:
- minNumOfItems = 10
- # self.SetStatusText(_('Insufficient points, 10+ points needed for 3rd order'))
- for i in range(minNumOfItems - numOfItems):
- self.AddGCP(None)
- return minNumOfItems
- def RMSError(self, xygroup, order):
- """
- Uses i.ortho.transform to calculate forward and backward error for each used GCP
- in CONTROL_POINTS file and insert error values into GCP list.
- Calculates total forward and backward RMS error for all used points
- """
- # save GCPs to points file to make sure that all checked GCPs are used
- self.SaveGCPs(None)
- # self.SetStatusText('')
- if self.CheckGCPcount(msg=True) == False:
- return
- # get list of forward and reverse rms error values for each point
- self.grwiz.SwitchEnv('source')
- ret = RunCommand('i.ortho.transform',
- parent=self,
- read=True,
- group=xygroup)
- self.grwiz.SwitchEnv('target')
- if ret:
- errlist = ret.splitlines()
- else:
- GError(parent=self,
- message=_('Could not calculate RMS Error.\n'
- 'Possible error with i.ortho.transform.'))
- return
- # insert error values into GCP list for checked items
- sdfactor = float(
- UserSettings.Get(
- group='gcpman',
- key='rms',
- subkey='sdfactor'))
- GCPcount = 0
- sumsq_fwd_err = 0.0
- sumsq_bkw_err = 0.0
- sum_fwd_err = 0.0
- highest_fwd_err = 0.0
- self.highest_key = 0
- highest_idx = 0
- for index in range(self.list.GetItemCount()):
- key = self.list.GetItemData(index)
- if self.list.IsChecked(index):
- fwd_err, bkw_err = errlist[GCPcount].split()
- self.list.SetStringItem(index, 7, fwd_err)
- self.list.SetStringItem(index, 8, bkw_err)
- self.mapcoordlist[key][7] = float(fwd_err)
- self.mapcoordlist[key][8] = float(bkw_err)
- self.list.SetItemTextColour(index, wx.BLACK)
- if self.highest_only:
- if highest_fwd_err < float(fwd_err):
- highest_fwd_err = float(fwd_err)
- self.highest_key = key
- highest_idx = index
- sumsq_fwd_err += float(fwd_err)**2
- sumsq_bkw_err += float(bkw_err)**2
- sum_fwd_err += float(fwd_err)
- GCPcount += 1
- else:
- self.list.SetStringItem(index, 7, '')
- self.list.SetStringItem(index, 8, '')
- self.mapcoordlist[key][7] = 0.0
- self.mapcoordlist[key][8] = 0.0
- self.list.SetItemTextColour(index, wx.BLACK)
- # SD
- if GCPcount > 0:
- self.rmsmean = sum_fwd_err / GCPcount
- self.rmssd = ((sumsq_fwd_err - self.rmsmean**2)**0.5)
- self.rmsthresh = self.rmsmean + sdfactor * self.rmssd
- else:
- self.rmsthresh = 0
- self.rmsmean = 0
- self.rmssd = 0
- if self.highest_only and highest_fwd_err > 0.0:
- self.list.SetItemTextColour(highest_idx, wx.RED)
- elif GCPcount > 0 and self.rmsthresh > 0 and not self.highest_only:
- for index in range(self.list.GetItemCount()):
- if self.list.IsChecked(index):
- key = self.list.GetItemData(index)
- if (self.mapcoordlist[key][7] > self.rmsthresh):
- self.list.SetItemTextColour(index, wx.RED)
- # calculate global RMS error (geometric mean)
- self.fwd_rmserror = round((sumsq_fwd_err / GCPcount)**0.5, 4)
- self.bkw_rmserror = round((sumsq_bkw_err / GCPcount)**0.5, 4)
- self.list.ResizeColumns()
- def GetNewExtent(self, region, map=None):
- coord_file = utils.GetTempfile()
- newreg = {'n': 0.0, 's': 0.0, 'e': 0.0, 'w': 0.0, }
- try:
- f = open(coord_file, mode='w')
- # NW corner
- f.write(str(region['e']) + " " + str(region['n']) + "\n")
- # NE corner
- f.write(str(region['e']) + " " + str(region['s']) + "\n")
- # SW corner
- f.write(str(region['w']) + " " + str(region['n']) + "\n")
- # SE corner
- f.write(str(region['w']) + " " + str(region['s']) + "\n")
- finally:
- f.close()
- # save GCPs to points file to make sure that all checked GCPs are used
- self.SaveGCPs(None)
- order = self.gr_order
- self.gr_order = 1
- if self.CheckGCPcount(msg=True) == False:
- self.gr_order = order
- return
- self.gr_order = order
- # get list of forward and reverse rms error values for each point
- self.grwiz.SwitchEnv('source')
- if map == 'source':
- ret = RunCommand('i.ortho.transform',
- parent=self,
- read=True,
- group=self.xygroup,
- format='dst',
- coords=coord_file)
- elif map == 'target':
- ret = RunCommand('i.ortho.transform',
- parent=self,
- read=True,
- group=self.xygroup,
- flags='r',
- format='src',
- coords=coord_file)
- os.unlink(coord_file)
- self.grwiz.SwitchEnv('target')
- if ret:
- errlist = ret.splitlines()
- else:
- GError(parent=self,
- message=_('Could not calculate new extends.\n'
- 'Possible error with i.ortho.transform.'))
- return
- # fist corner
- e, n = errlist[0].split()
- fe = float(e)
- fn = float(n)
- newreg['n'] = fn
- newreg['s'] = fn
- newreg['e'] = fe
- newreg['w'] = fe
- # other three corners
- for i in range(1, 4):
- e, n = errlist[i].split()
- fe = float(e)
- fn = float(n)
- if fe < newreg['w']:
- newreg['w'] = fe
- if fe > newreg['e']:
- newreg['e'] = fe
- if fn < newreg['s']:
- newreg['s'] = fn
- if fn > newreg['n']:
- newreg['n'] = fn
- return newreg
- def OnHelp(self, event):
- """Show GCP Manager manual page"""
- self._giface.Help(entry='wxGUI.gcp')
- def OnUpdateActive(self, event):
- if self.activemap.GetSelection() == 0:
- self.MapWindow = self.SrcMapWindow
- self.Map = self.SrcMap
- else:
- self.MapWindow = self.TgtMapWindow
- self.Map = self.TgtMap
- self.UpdateActive(self.MapWindow)
- # for wingrass
- if os.name == 'nt':
- self.MapWindow.SetFocus()
- def UpdateActive(self, win):
- # optionally disable tool zoomback tool
- self.GetMapToolbar().Enable('zoomback',
- enable=(len(self.MapWindow.zoomhistory) > 1))
- if self.activemap.GetSelection() != (win == self.TgtMapWindow):
- self.activemap.SetSelection(win == self.TgtMapWindow)
- self.StatusbarUpdate()
- def AdjustMap(self, newreg):
- """Adjust map window to new extents
- """
- # adjust map window
- self.Map.region['n'] = newreg['n']
- self.Map.region['s'] = newreg['s']
- self.Map.region['e'] = newreg['e']
- self.Map.region['w'] = newreg['w']
- self.MapWindow.ZoomHistory(self.Map.region['n'], self.Map.region['s'],
- self.Map.region['e'], self.Map.region['w'])
- # LL locations
- if self.Map.projinfo['proj'] == 'll':
- if newreg['n'] > 90.0:
- newreg['n'] = 90.0
- if newreg['s'] < -90.0:
- newreg['s'] = -90.0
- ce = newreg['w'] + (newreg['e'] - newreg['w']) / 2
- cn = newreg['s'] + (newreg['n'] - newreg['s']) / 2
- # calculate new center point and display resolution
- self.Map.region['center_easting'] = ce
- self.Map.region['center_northing'] = cn
- self.Map.region["ewres"] = (newreg['e'] - newreg['w']) / self.Map.width
- self.Map.region["nsres"] = (
- newreg['n'] - newreg['s']) / self.Map.height
- self.Map.AlignExtentFromDisplay()
- self.MapWindow.ZoomHistory(self.Map.region['n'], self.Map.region['s'],
- self.Map.region['e'], self.Map.region['w'])
- if self.MapWindow.redrawAll is False:
- self.MapWindow.redrawAll = True
- self.MapWindow.UpdateMap()
- self.StatusbarUpdate()
- def OnZoomToSource(self, event):
- """Set target map window to match extents of source map window
- """
- if not self.MapWindow == self.TgtMapWindow:
- self.MapWindow = self.TgtMapWindow
- self.Map = self.TgtMap
- self.UpdateActive(self.TgtMapWindow)
- # get new N, S, E, W for target
- newreg = self.GetNewExtent(self.SrcMap.region, 'source')
- if newreg:
- self.AdjustMap(newreg)
- def OnZoomToTarget(self, event):
- """Set source map window to match extents of target map window
- """
- if not self.MapWindow == self.SrcMapWindow:
- self.MapWindow = self.SrcMapWindow
- self.Map = self.SrcMap
- self.UpdateActive(self.SrcMapWindow)
- # get new N, S, E, W for target
- newreg = self.GetNewExtent(self.TgtMap.region, 'target')
- if newreg:
- self.AdjustMap(newreg)
- def OnZoomMenuGCP(self, event):
- """Popup Zoom menu
- """
- point = wx.GetMousePosition()
- zoommenu = Menu()
- # Add items to the menu
- zoomsource = wx.MenuItem(zoommenu, wx.ID_ANY, _(
- 'Adjust source display to target display'))
- zoommenu.AppendItem(zoomsource)
- self.Bind(wx.EVT_MENU, self.OnZoomToTarget, zoomsource)
- zoomtarget = wx.MenuItem(zoommenu, wx.ID_ANY, _(
- 'Adjust target display to source display'))
- zoommenu.AppendItem(zoomtarget)
- self.Bind(wx.EVT_MENU, self.OnZoomToSource, zoomtarget)
- # Popup the menu. If an item is selected then its handler
- # will be called before PopupMenu returns.
- self.PopupMenu(zoommenu)
- zoommenu.Destroy()
- def OnSize(self, event):
- """Adjust Map Windows after GCP Map Display has been resized
- """
- # re-render image on idle
- self.resize = time.clock()
- super(MapFrame, self).OnSize(event)
- def OnIdle(self, event):
- """GCP Map Display resized, adjust Map Windows
- """
- if self.GetMapToolbar():
- if self.resize and self.resize + 0.2 < time.clock():
- srcwidth, srcheight = self.SrcMapWindow.GetSize()
- tgtwidth, tgtheight = self.TgtMapWindow.GetSize()
- srcwidth = (srcwidth + tgtwidth) / 2
- if self.show_target:
- self._mgr.GetPane("target").Hide()
- self._mgr.Update()
- self._mgr.GetPane("source").BestSize((srcwidth, srcheight))
- self._mgr.GetPane("target").BestSize((srcwidth, tgtheight))
- if self.show_target:
- self._mgr.GetPane("target").Show()
- self._mgr.Update()
- self.resize = False
- elif self.resize:
- event.RequestMore()
- pass
- class GCPList(wx.ListCtrl,
- CheckListCtrlMixin,
- ListCtrlAutoWidthMixin):
- def __init__(self, parent, gcp, id=wx.ID_ANY,
- pos=wx.DefaultPosition, size=wx.DefaultSize,
- style=wx.LC_REPORT | wx.SUNKEN_BORDER | wx.LC_HRULES |
- wx.LC_SINGLE_SEL):
- wx.ListCtrl.__init__(self, parent, id, pos, size, style)
- self.gcp = gcp # GCP class
- self.render = True
- # Mixin settings
- CheckListCtrlMixin.__init__(self)
- ListCtrlAutoWidthMixin.__init__(self)
- # TextEditMixin.__init__(self)
- # tracks whether list items are checked or not
- self.CheckList = []
- self._Create()
- self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected)
- self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated)
- self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick)
- self.selected = wx.NOT_FOUND
- self.selectedkey = -1
- def _Create(self):
- if 0:
- # normal, simple columns
- idx_col = 0
- for col in (_('use'),
- _('source E'),
- _('source N'),
- _('source Z'),
- _('target E'),
- _('target N'),
- _('target Z'),
- _('Forward error'),
- _('Backward error')):
- self.InsertColumn(idx_col, col)
- idx_col += 1
- else:
- # the hard way: we want images on the column header
- info = wx.ListItem()
- info.SetMask(
- wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT)
- info.SetImage(-1)
- info.m_format = wx.LIST_FORMAT_LEFT
- idx_col = 0
- for lbl in (_('use'),
- _('source E'),
- _('source N'),
- _('source Z'),
- _('target E'),
- _('target N'),
- _('target Z'),
- _('Forward error'),
- _('Backward error')):
- info.SetText(lbl)
- self.InsertColumnInfo(idx_col, info)
- idx_col += 1
- def LoadData(self):
- """Load data into list"""
- self.DeleteAllItems()
- self.render = False
- if os.path.isfile(self.gcp.file['control_points']):
- self.gcp.ReadGCPs()
- else:
- # 3 gcp is minimum
- for i in range(3):
- self.gcp.AddGCP(None)
- # select first point by default
- self.selected = 0
- self.selectedkey = self.GetItemData(self.selected)
- self.SetItemState(self.selected,
- wx.LIST_STATE_SELECTED,
- wx.LIST_STATE_SELECTED)
- self.ResizeColumns()
- self.render = True
- self.EnsureVisible(self.selected)
- def OnCheckItem(self, index, flag):
- """Item is checked/unchecked"""
- if self.render:
- # redraw points
- sourceMapWin = self.gcp.SrcMapWindow
- sourceMapWin.UpdateMap(render=False, renderVector=False)
- if self.gcp.show_target:
- targetMapWin = self.gcp.TgtMapWindow
- targetMapWin.UpdateMap(render=False, renderVector=False)
- def AddGCPItem(self):
- """
- Appends an item to GCP list
- """
- self.selectedkey = self.GetItemCount() + 1
- self.Append([str(self.selectedkey), # GCP number
- '0.0', # source E
- '0.0', # source N
- '0.0', # source Z
- '0.0', # target E
- '0.0', # target N
- '0.0', # target Z
- '', # forward error
- '']) # backward error
- self.selected = self.GetItemCount() - 1
- self.SetItemData(self.selected, self.selectedkey)
- self.SetItemState(self.selected,
- wx.LIST_STATE_SELECTED,
- wx.LIST_STATE_SELECTED)
- self.ResizeColumns()
- self.gcp.pointsToDrawSrc.AddItem(
- coords=[0, 0], label=str(self.selectedkey))
- self.gcp.pointsToDrawTgt.AddItem(
- coords=[0, 0], label=str(self.selectedkey))
- self.EnsureVisible(self.selected)
- return self.selected
- def DeleteGCPItem(self):
- """Deletes selected item in GCP list.
- """
- if self.selected == wx.NOT_FOUND:
- return
- key = self.GetItemData(self.selected)
- self.DeleteItem(self.selected)
- if self.selected != wx.NOT_FOUND:
- item = self.gcp.pointsToDrawSrc.GetItem(key - 1)
- self.gcp.pointsToDrawSrc.DeleteItem(item)
- item = self.gcp.pointsToDrawTgt.GetItem(key - 1)
- self.gcp.pointsToDrawTgt.DeleteItem(item)
- return key
- def ResizeColumns(self):
- """Resize columns"""
- minWidth = [90, 120]
- for i in range(self.GetColumnCount()):
- self.SetColumnWidth(i, wx.LIST_AUTOSIZE)
- # first column is checkbox, don't set to minWidth
- if i > 0 and self.GetColumnWidth(i) < minWidth[i > 4]:
- self.SetColumnWidth(i, minWidth[i > 4])
- self.SendSizeEvent()
- def GetSelected(self):
- """Get index of selected item"""
- return self.selected
- def OnItemSelected(self, event):
- """Item selected
- """
- if self.render and self.selected != event.GetIndex():
- self.selected = event.GetIndex()
- self.selectedkey = self.GetItemData(self.selected)
- sourceMapWin = self.gcp.SrcMapWindow
- sourceMapWin.UpdateMap(render=False, renderVector=False)
- if self.gcp.show_target:
- targetMapWin = self.gcp.TgtMapWindow
- targetMapWin.UpdateMap(render=False, renderVector=False)
- event.Skip()
- def OnItemActivated(self, event):
- """
- When item double clicked, open editor to update coordinate values
- """
- coords = []
- index = event.GetIndex()
- key = self.GetItemData(index)
- changed = False
- for i in range(1, 7):
- coords.append(self.GetItem(index, i).GetText())
- dlg = EditGCP(parent=self, id=wx.ID_ANY, data=coords, gcpno=key)
- if dlg.ShowModal() == wx.ID_OK:
- values = dlg.GetValues() # string
- if len(values) == 0:
- GError(parent=self, message=_(
- "Invalid coordinate value. Operation canceled."))
- else:
- for i in range(len(values)):
- if values[i] != coords[i]:
- self.SetStringItem(index, i + 1, values[i])
- changed = True
- if changed:
- # reset RMS and update mapcoordlist
- self.SetStringItem(index, 7, '')
- self.SetStringItem(index, 8, '')
- key = self.GetItemData(index)
- self.gcp.mapcoordlist[key] = [key,
- float(values[0]),
- float(values[1]),
- float(values[2]),
- float(values[3]),
- float(values[4]),
- float(values[5]),
- 0.0,
- 0.0]
- self.gcp.pointsToDrawSrc.GetItem(
- key - 1).SetCoords([float(values[0]), float(values[1])])
- self.gcp.pointsToDrawTgt.GetItem(
- key - 1).SetCoords([float(values[3]), float(values[4])])
- self.gcp.UpdateColours()
- def OnColClick(self, event):
- """ListCtrl forgets selected item..."""
- self.selected = self.FindItemData(-1, self.selectedkey)
- self.SetItemState(self.selected,
- wx.LIST_STATE_SELECTED,
- wx.LIST_STATE_SELECTED)
- event.Skip()
- class VectGroup(wx.Dialog):
- """Dialog to create a vector group (VREF file) for georectifying
- .. todo::
- Replace by g.group
- """
- def __init__(self, parent, id, grassdb, location, mapset, group,
- style=wx.DEFAULT_DIALOG_STYLE):
- wx.Dialog.__init__(self, parent, id, style=style,
- title=_("Create vector map group"))
- self.grassdatabase = grassdb
- self.xylocation = location
- self.xymapset = mapset
- self.xygroup = group
- #
- # get list of valid vector directories
- #
- vectlist = os.listdir(os.path.join(self.grassdatabase,
- self.xylocation,
- self.xymapset,
- 'vector'))
- for dir in vectlist:
- if not os.path.isfile(os.path.join(self.grassdatabase,
- self.xylocation,
- self.xymapset,
- 'vector',
- dir,
- 'coor')):
- vectlist.remove(dir)
- utils.ListSortLower(vectlist)
- # path to vref file
- self.vgrpfile = os.path.join(self.grassdatabase,
- self.xylocation,
- self.xymapset,
- 'group',
- self.xygroup,
- 'VREF')
- #
- # buttons
- #
- self.btnCancel = Button(parent=self,
- id=wx.ID_CANCEL)
- self.btnOK = Button(parent=self,
- id=wx.ID_OK)
- self.btnOK.SetDefault()
- #
- # list of vector maps
- #
- self.listMap = CheckListBox(parent=self, id=wx.ID_ANY,
- choices=vectlist)
- if os.path.isfile(self.vgrpfile):
- f = open(self.vgrpfile)
- try:
- checked = []
- for line in f.readlines():
- line = line.replace('\n', '')
- if len(line) < 1:
- continue
- checked.append(line)
- self.listMap.SetCheckedStrings(checked)
- finally:
- f.close()
- line = wx.StaticLine(parent=self,
- id=wx.ID_ANY, size=(20, -1),
- style=wx.LI_HORIZONTAL)
- #
- # layout
- #
- sizer = wx.BoxSizer(wx.VERTICAL)
- box = wx.BoxSizer(wx.HORIZONTAL)
- box.Add(
- StaticText(
- parent=self,
- id=wx.ID_ANY,
- label=_('Select vector map(s) to add to group:')),
- flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT,
- border=5)
- box.Add(self.listMap,
- flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT,
- border=5)
- sizer.Add(box, flag=wx.ALIGN_RIGHT | wx.ALL,
- border=3)
- sizer.Add(line, proportion=0,
- flag=wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT,
- border=5)
- # buttons
- btnSizer = wx.StdDialogButtonSizer()
- btnSizer.AddButton(self.btnCancel)
- btnSizer.AddButton(self.btnOK)
- btnSizer.Realize()
- sizer.Add(btnSizer, proportion=0,
- flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER,
- border=5)
- self.SetSizer(sizer)
- sizer.Fit(self)
- self.Layout()
- def MakeVGroup(self):
- """Create VREF file"""
- vgrouplist = []
- for item in range(self.listMap.GetCount()):
- if not self.listMap.IsChecked(item):
- continue
- vgrouplist.append(
- self.listMap.GetString(item) +
- '@' +
- self.xymapset)
- f = open(self.vgrpfile, mode='w')
- try:
- for vect in vgrouplist:
- f.write(vect + '\n')
- finally:
- f.close()
- class EditGCP(wx.Dialog):
- def __init__(self, parent, data, gcpno, id=wx.ID_ANY,
- title=_("Edit GCP"),
- style=wx.DEFAULT_DIALOG_STYLE):
- """Dialog for editing GPC and map coordinates in list control"""
- wx.Dialog.__init__(self, parent, id, title=title, style=style)
- panel = wx.Panel(parent=self)
- sizer = wx.BoxSizer(wx.VERTICAL)
- box = StaticBox(
- parent=panel, id=wx.ID_ANY, label=" %s %s " %
- (_("Ground Control Point No."), str(gcpno)))
- boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
- # source coordinates
- gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
- self.xcoord = TextCtrl(parent=panel, id=wx.ID_ANY, size=(150, -1))
- self.ycoord = TextCtrl(parent=panel, id=wx.ID_ANY, size=(150, -1))
- self.zcoord = TextCtrl(parent=panel, id=wx.ID_ANY, size=(150, -1))
- self.ecoord = TextCtrl(parent=panel, id=wx.ID_ANY, size=(150, -1))
- self.ncoord = TextCtrl(parent=panel, id=wx.ID_ANY, size=(150, -1))
- self.hcoord = TextCtrl(parent=panel, id=wx.ID_ANY, size=(150, -1))
- # swap source N, target E
- tmp_coord = data[1]
- data[1] = data[2]
- data[2] = tmp_coord
- row = 0
- col = 0
- idx = 0
- for label, win in ((_("source E:"), self.xcoord),
- (_("target E:"), self.ecoord),
- (_("source N:"), self.ycoord),
- (_("target N:"), self.ncoord),
- (_("source Z:"), self.zcoord),
- (_("target Z:"), self.hcoord)):
- label = StaticText(parent=panel, id=wx.ID_ANY,
- label=label)
- gridSizer.Add(label,
- flag=wx.ALIGN_CENTER_VERTICAL,
- pos=(row, col))
- col += 1
- win.SetValue(str(data[idx]))
- gridSizer.Add(win,
- pos=(row, col))
- col += 1
- idx += 1
- if col > 3:
- row += 1
- col = 0
- boxSizer.Add(gridSizer, proportion=1,
- flag=wx.EXPAND | wx.ALL, border=5)
- sizer.Add(boxSizer, proportion=1,
- flag=wx.EXPAND | wx.ALL, border=5)
- #
- # buttons
- #
- self.btnCancel = Button(panel, wx.ID_CANCEL)
- self.btnOk = Button(panel, wx.ID_OK)
- self.btnOk.SetDefault()
- btnSizer = wx.StdDialogButtonSizer()
- btnSizer.AddButton(self.btnCancel)
- btnSizer.AddButton(self.btnOk)
- btnSizer.Realize()
- sizer.Add(btnSizer, proportion=0,
- flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
- panel.SetSizer(sizer)
- sizer.Fit(self)
- def GetValues(self, columns=None):
- """Return list of values (as strings).
- """
- valuelist = []
- try:
- float(self.xcoord.GetValue())
- float(self.ycoord.GetValue())
- float(self.zcoord.GetValue())
- float(self.ecoord.GetValue())
- float(self.ncoord.GetValue())
- float(self.hcoord.GetValue())
- except ValueError:
- return valuelist
- valuelist.append(self.xcoord.GetValue())
- valuelist.append(self.ycoord.GetValue())
- valuelist.append(self.zcoord.GetValue())
- valuelist.append(self.ecoord.GetValue())
- valuelist.append(self.ncoord.GetValue())
- valuelist.append(self.hcoord.GetValue())
- return valuelist
- class GrSettingsDialog(wx.Dialog):
- def __init__(
- self, parent, id, giface, title, pos=wx.DefaultPosition,
- size=wx.DefaultSize, style=wx.DEFAULT_DIALOG_STYLE):
- wx.Dialog.__init__(self, parent, id, title, pos, size, style)
- """
- Dialog to set profile text options: font, title
- and font size, axis labels and font size
- """
- #
- # initialize variables
- #
- self.parent = parent
- self.new_src_map = src_map
- self.new_tgt_map = {'raster': tgt_map['raster'],
- 'vector': tgt_map['vector']}
- self.sdfactor = 0
- self.symbol = {}
- self.methods = ["nearest",
- "linear",
- "linear_f",
- "cubic",
- "cubic_f",
- "lanczos",
- "lanczos_f"]
- # notebook
- notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
- self.__CreateSymbologyPage(notebook)
- self.__CreateRectificationPage(notebook)
- # buttons
- btnSave = Button(self, wx.ID_SAVE)
- btnApply = Button(self, wx.ID_APPLY)
- btnClose = Button(self, wx.ID_CLOSE)
- btnApply.SetDefault()
- # bindings
- btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
- btnApply.SetToolTip(_("Apply changes for the current session"))
- btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
- btnSave.SetToolTip(
- _("Apply and save changes to user settings file (default for next sessions)"))
- btnClose.Bind(wx.EVT_BUTTON, self.OnClose)
- btnClose.SetToolTip(_("Close dialog"))
- # sizers
- btnSizer = wx.BoxSizer(wx.HORIZONTAL)
- btnSizer.Add(btnApply, flag=wx.LEFT | wx.RIGHT, border=5)
- btnSizer.Add(btnSave, flag=wx.LEFT | wx.RIGHT, border=5)
- btnSizer.Add(btnClose, flag=wx.LEFT | wx.RIGHT, border=5)
- # sizers
- mainSizer = wx.BoxSizer(wx.VERTICAL)
- mainSizer.Add(
- notebook,
- proportion=1,
- flag=wx.EXPAND | wx.ALL,
- border=5)
- mainSizer.Add(btnSizer, proportion=0,
- flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
- # flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
- self.SetSizer(mainSizer)
- mainSizer.Fit(self)
- def __CreateSymbologyPage(self, notebook):
- """Create notebook page with symbology settings"""
- panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
- notebook.AddPage(page=panel, text=_("Symbology"))
- sizer = wx.BoxSizer(wx.VERTICAL)
- rmsgridSizer = wx.GridBagSizer(vgap=5, hgap=5)
- # highlight only highest forward RMS error
- self.highlighthighest = wx.CheckBox(
- parent=panel, id=wx.ID_ANY,
- label=_("Highlight highest RMS error only"))
- hh = UserSettings.Get(group='gcpman', key='rms', subkey='highestonly')
- self.highlighthighest.SetValue(hh)
- rmsgridSizer.Add(
- self.highlighthighest,
- flag=wx.ALIGN_CENTER_VERTICAL,
- pos=(
- 0,
- 0))
- # RMS forward error threshold
- rmslabel = StaticText(
- parent=panel, id=wx.ID_ANY,
- label=_("Highlight RMS error > M + SD * factor:"))
- rmslabel.SetToolTip(
- wx.ToolTip(
- _(
- "Highlight GCPs with an RMS error larger than \n"
- "mean + standard deviation * given factor. \n"
- "Recommended values for this factor are between 1 and 2.")))
- rmsgridSizer.Add(
- rmslabel,
- flag=wx.ALIGN_CENTER_VERTICAL,
- pos=(
- 1,
- 0))
- sdfactor = UserSettings.Get(
- group='gcpman', key='rms', subkey='sdfactor')
- self.rmsWin = TextCtrl(parent=panel, id=wx.ID_ANY,
- size=(70, -1), style=wx.TE_NOHIDESEL)
- self.rmsWin.SetValue("%s" % str(sdfactor))
- if (self.parent.highest_only == True):
- self.rmsWin.Disable()
- self.symbol['sdfactor'] = self.rmsWin.GetId()
- rmsgridSizer.Add(self.rmsWin, flag=wx.ALIGN_RIGHT, pos=(1, 1))
- rmsgridSizer.AddGrowableCol(1)
- sizer.Add(rmsgridSizer, flag=wx.EXPAND | wx.ALL, border=5)
- box = StaticBox(parent=panel, id=wx.ID_ANY,
- label=" %s " % _("Symbol settings"))
- boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
- gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
- #
- # general symbol color
- #
- row = 0
- label = StaticText(parent=panel, id=wx.ID_ANY, label=_("Color:"))
- gridSizer.Add(label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
- col = UserSettings.Get(group='gcpman', key='symbol', subkey='color')
- colWin = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
- colour=wx.Colour(col[0],
- col[1],
- col[2],
- 255))
- self.symbol['color'] = colWin.GetId()
- gridSizer.Add(colWin,
- flag=wx.ALIGN_RIGHT,
- pos=(row, 1))
- #
- # symbol color for high forward RMS error
- #
- row += 1
- label = StaticText(
- parent=panel,
- id=wx.ID_ANY,
- label=_("Color for high RMS error:"))
- gridSizer.Add(label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
- hcol = UserSettings.Get(group='gcpman', key='symbol', subkey='hcolor')
- hcolWin = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
- colour=wx.Colour(hcol[0],
- hcol[1],
- hcol[2],
- 255))
- self.symbol['hcolor'] = hcolWin.GetId()
- gridSizer.Add(hcolWin,
- flag=wx.ALIGN_RIGHT,
- pos=(row, 1))
- #
- # symbol color for selected GCP
- #
- row += 1
- label = StaticText(
- parent=panel,
- id=wx.ID_ANY,
- label=_("Color for selected GCP:"))
- gridSizer.Add(label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
- scol = UserSettings.Get(group='gcpman', key='symbol', subkey='scolor')
- scolWin = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
- colour=wx.Colour(scol[0],
- scol[1],
- scol[2],
- 255))
- self.symbol['scolor'] = scolWin.GetId()
- gridSizer.Add(scolWin,
- flag=wx.ALIGN_RIGHT,
- pos=(row, 1))
- #
- # symbol color for unused GCP
- #
- row += 1
- label = StaticText(
- parent=panel,
- id=wx.ID_ANY,
- label=_("Color for unused GCPs:"))
- gridSizer.Add(label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
- ucol = UserSettings.Get(group='gcpman', key='symbol', subkey='ucolor')
- ucolWin = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
- colour=wx.Colour(ucol[0],
- ucol[1],
- ucol[2],
- 255))
- self.symbol['ucolor'] = ucolWin.GetId()
- gridSizer.Add(ucolWin,
- flag=wx.ALIGN_RIGHT,
- pos=(row, 1))
- # show unused GCPs
- row += 1
- self.showunused = wx.CheckBox(parent=panel, id=wx.ID_ANY,
- label=_("Show unused GCPs"))
- shuu = UserSettings.Get(group='gcpman', key='symbol', subkey='unused')
- self.showunused.SetValue(shuu)
- gridSizer.Add(
- self.showunused,
- flag=wx.ALIGN_CENTER_VERTICAL,
- pos=(
- row,
- 0))
- #
- # symbol size
- #
- row += 1
- label = StaticText(
- parent=panel,
- id=wx.ID_ANY,
- label=_("Symbol size:"))
- gridSizer.Add(label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
- symsize = int(
- UserSettings.Get(
- group='gcpman',
- key='symbol',
- subkey='size'))
- sizeWin = SpinCtrl(parent=panel, id=wx.ID_ANY,
- min=1, max=20)
- sizeWin.SetValue(symsize)
- self.symbol['size'] = sizeWin.GetId()
- gridSizer.Add(sizeWin,
- flag=wx.ALIGN_RIGHT,
- pos=(row, 1))
- #
- # symbol width
- #
- row += 1
- label = StaticText(
- parent=panel,
- id=wx.ID_ANY,
- label=_("Line width:"))
- gridSizer.Add(label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
- width = int(
- UserSettings.Get(
- group='gcpman',
- key='symbol',
- subkey='width'))
- widWin = SpinCtrl(parent=panel, id=wx.ID_ANY,
- min=1, max=10)
- widWin.SetValue(width)
- self.symbol['width'] = widWin.GetId()
- gridSizer.Add(widWin,
- flag=wx.ALIGN_RIGHT,
- pos=(row, 1))
- gridSizer.AddGrowableCol(1)
- boxSizer.Add(gridSizer, flag=wx.EXPAND)
- sizer.Add(boxSizer, flag=wx.EXPAND | wx.ALL, border=5)
- #
- # maps to display
- #
- # source map to display
- self.srcselection = Select(
- panel,
- id=wx.ID_ANY,
- size=globalvar.DIALOG_GSELECT_SIZE,
- type='maptype',
- updateOnPopup=False)
- self.parent.grwiz.SwitchEnv('source')
- self.srcselection.SetElementList(maptype)
- # filter out all maps not in group
- self.srcselection.tcp.GetElementList(elements=self.parent.src_maps)
- # target map(s) to display
- self.parent.grwiz.SwitchEnv('target')
- self.tgtrastselection = Select(
- panel, id=wx.ID_ANY, size=globalvar.DIALOG_GSELECT_SIZE,
- type='raster', updateOnPopup=False)
- self.tgtrastselection.SetElementList('cell')
- self.tgtrastselection.GetElementList()
- self.tgtvectselection = Select(
- panel, id=wx.ID_ANY, size=globalvar.DIALOG_GSELECT_SIZE,
- type='vector', updateOnPopup=False)
- self.tgtvectselection.SetElementList('vector')
- self.tgtvectselection.GetElementList()
- sizer.Add(
- StaticText(
- parent=panel,
- id=wx.ID_ANY,
- label=_('Select source map to display:')),
- proportion=0,
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5)
- sizer.Add(
- self.srcselection,
- proportion=0,
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5)
- self.srcselection.SetValue(src_map)
- sizer.Add(
- StaticText(
- parent=panel,
- id=wx.ID_ANY,
- label=_('Select target raster map to display:')),
- proportion=0,
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5)
- sizer.Add(
- self.tgtrastselection,
- proportion=0,
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5)
- self.tgtrastselection.SetValue(tgt_map['raster'])
- sizer.Add(
- StaticText(
- parent=panel,
- id=wx.ID_ANY,
- label=_('Select target vector map to display:')),
- proportion=0,
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5)
- sizer.Add(
- self.tgtvectselection,
- proportion=0,
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5)
- self.tgtvectselection.SetValue(tgt_map['vector'])
- # bindings
- self.highlighthighest.Bind(wx.EVT_CHECKBOX, self.OnHighlight)
- self.rmsWin.Bind(wx.EVT_TEXT, self.OnSDFactor)
- self.srcselection.Bind(wx.EVT_TEXT, self.OnSrcSelection)
- self.tgtrastselection.Bind(wx.EVT_TEXT, self.OnTgtRastSelection)
- self.tgtvectselection.Bind(wx.EVT_TEXT, self.OnTgtVectSelection)
- panel.SetSizer(sizer)
- return panel
- def __CreateRectificationPage(self, notebook):
- """Create notebook page with symbology settings"""
- panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
- notebook.AddPage(page=panel, text=_("Rectification"))
- sizer = wx.BoxSizer(wx.VERTICAL)
- # transformation order
- self.rb_grorder = wx.RadioBox(
- parent=panel,
- id=wx.ID_ANY,
- label=" %s " %
- _("Select rectification order"),
- choices=[
- _('1st order'),
- _('2nd order'),
- _('3rd order')],
- majorDimension=wx.RA_SPECIFY_COLS)
- sizer.Add(self.rb_grorder, proportion=0,
- flag=wx.EXPAND | wx.ALL, border=5)
- self.rb_grorder.SetSelection(self.parent.gr_order - 1)
- # interpolation method
- gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
- gridSizer.Add(
- StaticText(
- parent=panel,
- id=wx.ID_ANY,
- label=_('Select interpolation method:')),
- pos=(
- 0,
- 0),
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5)
- self.grmethod = wx.Choice(parent=panel, id=wx.ID_ANY,
- choices=self.methods)
- gridSizer.Add(self.grmethod, pos=(0, 1),
- flag=wx.ALIGN_RIGHT, border=5)
- self.grmethod.SetStringSelection(self.parent.gr_method)
- gridSizer.AddGrowableCol(1)
- sizer.Add(gridSizer, flag=wx.EXPAND | wx.ALL, border=5)
- # clip to region
- self.check = wx.CheckBox(parent=panel, id=wx.ID_ANY, label=_(
- "clip to computational region in target location"))
- sizer.Add(self.check, proportion=0,
- flag=wx.EXPAND | wx.ALL, border=5)
- self.check.SetValue(self.parent.clip_to_region)
- # extension
- sizer.Add(
- StaticText(
- parent=panel,
- id=wx.ID_ANY,
- label=_('Extension for output maps:')),
- proportion=0,
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5)
- self.ext_txt = TextCtrl(
- parent=panel, id=wx.ID_ANY, value="", size=(
- 350, -1))
- self.ext_txt.SetValue(self.parent.extension)
- sizer.Add(
- self.ext_txt,
- proportion=0,
- flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
- border=5)
- # bindings
- self.ext_txt.Bind(wx.EVT_TEXT, self.OnExtension)
- self.Bind(wx.EVT_RADIOBOX, self.parent.OnGROrder, self.rb_grorder)
- self.Bind(wx.EVT_CHOICE, self.OnMethod, self.grmethod)
- self.Bind(wx.EVT_CHECKBOX, self.OnClipRegion, self.check)
- panel.SetSizer(sizer)
- return panel
- def OnHighlight(self, event):
- """Checkbox 'highlighthighest' checked/unchecked"""
- if self.highlighthighest.IsChecked():
- self.parent.highest_only = True
- self.rmsWin.Disable()
- else:
- self.parent.highest_only = False
- self.rmsWin.Enable()
- def OnSDFactor(self, event):
- """New factor for RMS threshold = M + SD * factor"""
- try:
- self.sdfactor = float(self.rmsWin.GetValue())
- except ValueError:
- return
- if self.sdfactor <= 0:
- GError(parent=self,
- message=_('RMS threshold factor must be > 0'))
- elif self.sdfactor < 1:
- GError(parent=self,
- message=_('RMS threshold factor is < 1\n'
- 'Too many points might be highlighted'))
- def OnSrcSelection(self, event):
- """Source map to display selected"""
- global src_map
- tmp_map = self.srcselection.GetValue()
- if not tmp_map == '' and not tmp_map == src_map:
- self.new_src_map = tmp_map
- def OnTgtRastSelection(self, event):
- """Target map to display selected"""
- global tgt_map
- self.new_tgt_map['raster'] = self.tgtrastselection.GetValue()
- def OnTgtVectSelection(self, event):
- """Target map to display selected"""
- global tgt_map
- self.new_tgt_map['vector'] = self.tgtvectselection.GetValue()
- def OnMethod(self, event):
- self.parent.gr_method = self.methods[event.GetSelection()]
- def OnClipRegion(self, event):
- self.parent.clip_to_region = event.IsChecked()
- def OnExtension(self, event):
- self.parent.extension = self.ext_txt.GetValue()
- def UpdateSettings(self):
- global src_map
- global tgt_map
- global maptype
- layers = None
- UserSettings.Set(group='gcpman', key='rms', subkey='highestonly',
- value=self.highlighthighest.GetValue())
- if self.sdfactor > 0:
- UserSettings.Set(group='gcpman', key='rms', subkey='sdfactor',
- value=self.sdfactor)
- self.parent.sdfactor = self.sdfactor
- if self.parent.rmsthresh > 0:
- self.parent.rmsthresh = self.parent.rmsmean + self.parent.sdfactor * self.parent.rmssd
- UserSettings.Set(
- group='gcpman',
- key='symbol',
- subkey='color',
- value=tuple(
- wx.FindWindowById(
- self.symbol['color']).GetColour()))
- UserSettings.Set(
- group='gcpman',
- key='symbol',
- subkey='hcolor',
- value=tuple(
- wx.FindWindowById(
- self.symbol['hcolor']).GetColour()))
- UserSettings.Set(
- group='gcpman',
- key='symbol',
- subkey='scolor',
- value=tuple(
- wx.FindWindowById(
- self.symbol['scolor']).GetColour()))
- UserSettings.Set(
- group='gcpman',
- key='symbol',
- subkey='ucolor',
- value=tuple(
- wx.FindWindowById(
- self.symbol['ucolor']).GetColour()))
- UserSettings.Set(group='gcpman', key='symbol', subkey='unused',
- value=self.showunused.GetValue())
- UserSettings.Set(
- group='gcpman',
- key='symbol',
- subkey='size',
- value=wx.FindWindowById(
- self.symbol['size']).GetValue())
- UserSettings.Set(
- group='gcpman',
- key='symbol',
- subkey='width',
- value=wx.FindWindowById(
- self.symbol['width']).GetValue())
- srcrender = False
- srcrenderVector = False
- tgtrender = False
- tgtrenderVector = False
- reload_target = False
- if self.new_src_map != src_map:
- # remove old layer
- layers = self.parent.grwiz.SrcMap.GetListOfLayers()
- self.parent.grwiz.SrcMap.DeleteLayer(layers[0])
- src_map = self.new_src_map
- if maptype == 'raster':
- cmdlist = ['d.rast', 'map=%s' % src_map]
- srcrender = True
- else:
- cmdlist = ['d.vect', 'map=%s' % src_map]
- srcrenderVector = True
- self.parent.grwiz.SwitchEnv('source')
- name, found = utils.GetLayerNameFromCmd(cmdlist)
- self.parent.grwiz.SrcMap.AddLayer(
- ltype=maptype, command=cmdlist, active=True, name=name,
- hidden=False, opacity=1.0, render=False)
- self.parent.grwiz.SwitchEnv('target')
- if self.new_tgt_map['raster'] != tgt_map['raster'] or \
- self.new_tgt_map['vector'] != tgt_map['vector']:
- # remove all layers
- layers = self.parent.grwiz.TgtMap.GetListOfLayers()
- while layers:
- self.parent.grwiz.TgtMap.DeleteLayer(layers[0])
- del layers[0]
- layers = self.parent.grwiz.TgtMap.GetListOfLayers()
- # self.parent.grwiz.TgtMap.DeleteAllLayers()
- reload_target = True
- tgt_map['raster'] = self.new_tgt_map['raster']
- tgt_map['vector'] = self.new_tgt_map['vector']
- if tgt_map['raster'] != '':
- cmdlist = ['d.rast', 'map=%s' % tgt_map['raster']]
- name, found = utils.GetLayerNameFromCmd(cmdlist)
- self.parent.grwiz.TgtMap.AddLayer(
- ltype='raster', command=cmdlist, active=True, name=name,
- hidden=False, opacity=1.0, render=False)
- tgtrender = True
- if tgt_map['vector'] != '':
- cmdlist = ['d.vect', 'map=%s' % tgt_map['vector']]
- name, found = utils.GetLayerNameFromCmd(cmdlist)
- self.parent.grwiz.TgtMap.AddLayer(
- ltype='vector', command=cmdlist, active=True, name=name,
- hidden=False, opacity=1.0, render=False)
- tgtrenderVector = True
- if tgt_map['raster'] == '' and tgt_map['vector'] == '':
- if self.parent.show_target == True:
- self.parent.show_target = False
- self.parent._mgr.GetPane("target").Hide()
- self.parent._mgr.Update()
- self.parent.activemap.SetSelection(0)
- self.parent.activemap.Enable(False)
- self.parent.GetMapToolbar().Enable('zoommenu', enable=False)
- else:
- if self.parent.show_target == False:
- self.parent.show_target = True
- self.parent._mgr.GetPane("target").Show()
- self.parent._mgr.Update()
- self.parent.activemap.SetSelection(0)
- self.parent.activemap.Enable(True)
- self.parent.GetMapToolbar().Enable('zoommenu', enable=True)
- self.parent.TgtMapWindow.ZoomToMap(
- layers=self.parent.TgtMap.GetListOfLayers())
- self.parent.UpdateColours(
- srcrender,
- srcrenderVector,
- tgtrender,
- tgtrenderVector)
- self.parent.SetSettings()
- def OnSave(self, event):
- """Button 'Save' pressed"""
- self.UpdateSettings()
- fileSettings = {}
- UserSettings.ReadSettingsFile(settings=fileSettings)
- fileSettings['gcpman'] = UserSettings.Get(group='gcpman')
- file = UserSettings.SaveToFile(fileSettings)
- self.parent._giface.WriteLog(
- _('GCP Manager settings saved to file \'%s\'.') %
- file)
- # self.Close()
- def OnApply(self, event):
- """Button 'Apply' pressed"""
- self.UpdateSettings()
- # self.Close()
- def OnClose(self, event):
- """Button 'Cancel' pressed"""
- self.Close()
|