tools.py 228 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132
  1. """!
  2. @package nviz.tools
  3. @brief Nviz (3D view) tools window
  4. Classes:
  5. - tools::NvizToolWindow
  6. - tools::PositionWindow
  7. - tools::ViewPositionWindow
  8. - tools::LightPositionWindow
  9. (C) 2008-2011 by the GRASS Development Team
  10. This program is free software under the GNU General Public License
  11. (>=v2). Read the file COPYING that comes with GRASS for details.
  12. @author Martin Landa <landa.martin gmail.com> (Google SoC 2008/2010)
  13. @author Enhancements by Michael Barton <michael.barton asu.edu>
  14. @author Anna Kratochvilova <kratochanna gmail.com> (Google SoC 2011)
  15. """
  16. import os
  17. import copy
  18. import types
  19. import wx
  20. import wx.lib.colourselect as csel
  21. import wx.lib.scrolledpanel as SP
  22. import wx.lib.filebrowsebutton as filebrowse
  23. try:
  24. import wx.lib.agw.flatnotebook as FN
  25. except ImportError:
  26. import wx.lib.flatnotebook as FN
  27. try:
  28. from agw import foldpanelbar as fpb
  29. except ImportError: # if it's not there locally, try the wxPython lib.
  30. try:
  31. import wx.lib.agw.foldpanelbar as fpb
  32. except ImportError:
  33. import wx.lib.foldpanelbar as fpb # versions <=2.5.5.1
  34. import grass.script as grass
  35. from core import globalvar
  36. from gui_core.gselect import VectorDBInfo
  37. from core.gcmd import GMessage, RunCommand
  38. from modules.colorrules import ThematicVectorTable
  39. from core.settings import UserSettings
  40. from nviz.animation import EVT_ANIM_FIN, EVT_ANIM_UPDATE_IDX
  41. from gui_core.widgets import ScrolledPanel, NumTextCtrl, FloatSlider, SymbolButton
  42. from gui_core.gselect import Select
  43. from core.debug import Debug
  44. try:
  45. from nviz.mapwindow import wxUpdateProperties, wxUpdateView,\
  46. wxUpdateLight, wxUpdateCPlane
  47. import wxnviz
  48. except ImportError:
  49. pass
  50. class NvizToolWindow(FN.FlatNotebook):
  51. """!Nviz (3D view) tools panel
  52. """
  53. def __init__(self, parent, display, id = wx.ID_ANY,
  54. style = globalvar.FNPageStyle|FN.FNB_NO_X_BUTTON,
  55. **kwargs):
  56. Debug.msg(5, "NvizToolWindow.__init__()")
  57. self.parent = parent # GMFrame
  58. self.mapDisplay = display
  59. self.mapWindow = display.GetWindow()
  60. self._display = self.mapWindow.GetDisplay()
  61. if globalvar.hasAgw:
  62. kwargs['agwStyle'] = style
  63. else:
  64. kwargs['style'] = style
  65. FN.FlatNotebook.__init__(self, parent, id, **kwargs)
  66. self.SetTabAreaColour(globalvar.FNPageColor)
  67. self.win = {} # window ids
  68. self.page = {} # page ids
  69. # view page
  70. self.AddPage(page = self._createViewPage(),
  71. text = " %s " % _("View"))
  72. # data page
  73. self.AddPage(page = self._createDataPage(),
  74. text = " %s " % _("Data"))
  75. # appearance page
  76. self.AddPage(page = self._createAppearancePage(),
  77. text = " %s " % _("Appearance"))
  78. # analysis page
  79. self.AddPage(page = self._createAnalysisPage(),
  80. text = " %s " % _("Analysis"))
  81. # view page
  82. self.AddPage(page = self._createAnimationPage(),
  83. text = " %s " % _("Animation"))
  84. self.UpdateSettings()
  85. self.mapWindow.SetToolWin(self)
  86. self.pageChanging = False
  87. self.vetoGSelectEvt = False #when setting map, event is invoked
  88. self.mapWindow.render['quick'] = False
  89. self.mapWindow.Refresh(False)
  90. # bindings
  91. self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
  92. self.Bind(wx.EVT_SIZE, self.OnSize)
  93. self.Bind(EVT_ANIM_FIN, self.OnAnimationFinished)
  94. self.Bind(EVT_ANIM_UPDATE_IDX, self.OnAnimationUpdateIndex)
  95. Debug.msg(3, "NvizToolWindow.__init__()")
  96. self.Update()
  97. wx.CallAfter(self.SetPage, 'view')
  98. wx.CallAfter(self.UpdateScrolling, (self.foldpanelData, self.foldpanelAppear,
  99. self.foldpanelAnalysis))
  100. wx.CallAfter(self.SetInitialMaps)
  101. def SetInitialMaps(self):
  102. """!Set initial raster and vector map"""
  103. for l_type in ('raster', 'vector', '3d-raster'):
  104. selectedLayer = self.mapWindow.GetSelectedLayer()
  105. layers = self.mapWindow.Map.GetListOfLayers(l_type = l_type, l_active = True)
  106. if selectedLayer in layers:
  107. selection = selectedLayer.GetName()
  108. else:
  109. try:
  110. selection = layers[0].GetName()
  111. except:
  112. continue
  113. if l_type == 'raster':
  114. self.FindWindowById(self.win['surface']['map']).SetValue(selection)
  115. self.FindWindowById(self.win['fringe']['map']).SetValue(selection)
  116. elif l_type == 'vector':
  117. self.FindWindowById(self.win['vector']['map']).SetValue(selection)
  118. elif l_type == '3d-raster':
  119. self.FindWindowById(self.win['volume']['map']).SetValue(selection)
  120. def UpdateState(self, **kwargs):
  121. if 'view' in kwargs:
  122. self.mapWindow.view = kwargs['view']
  123. self.FindWindowById(self.win['view']['position']).data = kwargs['view']
  124. self.FindWindowById(self.win['view']['position']).PostDraw()
  125. if 'iview' in kwargs:
  126. self.mapWindow.iview = kwargs['iview']
  127. if 'light' in kwargs:
  128. self.mapWindow.light = kwargs['light']
  129. self.FindWindowById(self.win['light']['position']).data = kwargs['light']
  130. self.FindWindowById(self.win['light']['position']).PostDraw()
  131. if 'fly' in kwargs:
  132. self.mapWindow.fly['exag'] = kwargs['fly']['exag']
  133. def LoadSettings(self):
  134. """!Load Nviz settings and apply to current session"""
  135. view = copy.deepcopy(UserSettings.Get(group = 'nviz', key = 'view')) # copy
  136. light = copy.deepcopy(UserSettings.Get(group = 'nviz', key = 'light')) # copy
  137. fly = copy.deepcopy(UserSettings.Get(group = 'nviz', key = 'fly')) # copy
  138. self.UpdateState(view = view, light = light, fly = fly)
  139. self.PostViewEvent(zExag = True)
  140. self.PostLightEvent()
  141. self.UpdatePage('view')
  142. self.UpdatePage('light')
  143. self.mapWindow.ReloadLayersData()
  144. self.UpdatePage('surface')
  145. self.UpdatePage('vector')
  146. self.UpdateSettings()
  147. def OnPageChanged(self, event):
  148. new = event.GetSelection()
  149. # self.ChangeSelection(new)
  150. def PostViewEvent(self, zExag = False):
  151. """!Change view settings"""
  152. event = wxUpdateView(zExag = zExag)
  153. wx.PostEvent(self.mapWindow, event)
  154. def PostLightEvent(self, refresh = False):
  155. """!Change light settings"""
  156. event = wxUpdateLight(refresh = refresh)
  157. wx.PostEvent(self.mapWindow, event)
  158. def OnSize(self, event):
  159. """!After window is resized, update scrolling"""
  160. # workaround to resize captionbars of foldpanelbar
  161. wx.CallAfter(self.UpdateScrolling, (self.foldpanelData, self.foldpanelAppear,
  162. self.foldpanelAnalysis))
  163. event.Skip()
  164. def OnPressCaption(self, event):
  165. """!When foldpanel item collapsed/expanded, update scrollbars"""
  166. foldpanel = event.GetBar().GetGrandParent().GetParent()
  167. wx.CallAfter(self.UpdateScrolling, (foldpanel,))
  168. event.Skip()
  169. def UpdateScrolling(self, foldpanels):
  170. """!Update scrollbars in foldpanel"""
  171. for foldpanel in foldpanels:
  172. length = foldpanel.GetPanelsLength(collapsed = 0, expanded = 0)
  173. # virtual width is set to fixed value to suppress GTK warning
  174. foldpanel.GetParent().SetVirtualSize((100, length[2]))
  175. foldpanel.GetParent().Layout()
  176. def _createViewPage(self):
  177. """!Create view settings page"""
  178. panel = SP.ScrolledPanel(parent = self, id = wx.ID_ANY)
  179. panel.SetupScrolling(scroll_x = False)
  180. self.page['view'] = { 'id' : 0,
  181. 'notebook' : self.GetId()}
  182. pageSizer = wx.BoxSizer(wx.VERTICAL)
  183. box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  184. label = " %s " % (_("Control View")))
  185. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  186. gridSizer = wx.GridBagSizer(vgap = 5, hgap = 10)
  187. self.win['view'] = {}
  188. # position
  189. posSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
  190. self._createCompass(panel = panel, sizer = posSizer, type = 'view')
  191. view = ViewPositionWindow(panel, size = (175, 175),
  192. mapwindow = self.mapWindow)
  193. self.win['view']['position'] = view.GetId()
  194. posSizer.Add(item = view,
  195. pos = (1, 1), flag = wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL)
  196. gridSizer.Add(item = posSizer, pos = (0, 0))
  197. # perspective
  198. # set initial defaults here (or perhaps in a default values file), not in user settings
  199. #todo: consider setting an absolute max at 360 instead of undefined. (leave the default max value at pi)
  200. tooltip = _("Adjusts the viewer's angle of view")
  201. self._createControl(panel, data = self.win['view'], name = 'persp',
  202. tooltip = tooltip, range = (1, 120),
  203. bind = (self.OnViewChange, self.OnViewChanged, self.OnViewChangedText))
  204. gridSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Perspective:")),
  205. pos = (1, 0), flag = wx.ALIGN_CENTER)
  206. gridSizer.Add(item = self.FindWindowById(self.win['view']['persp']['slider']), pos = (2, 0),
  207. flag = wx.ALIGN_CENTER)
  208. gridSizer.Add(item = self.FindWindowById(self.win['view']['persp']['text']), pos = (3, 0),
  209. flag = wx.ALIGN_CENTER)
  210. # twist
  211. tooltip = _("Rotates the scene about the horizontal axis."
  212. " An angle of 0 is flat. The scene rotates between -90 and 90 degrees.")
  213. self._createControl(panel, data = self.win['view'], name = 'twist',
  214. tooltip = tooltip, range = (-180,180),
  215. bind = (self.OnViewChange, self.OnViewChanged, self.OnViewChangedText))
  216. gridSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Twist:")),
  217. pos = (1, 1), flag = wx.ALIGN_CENTER)
  218. gridSizer.Add(item = self.FindWindowById(self.win['view']['twist']['slider']), pos = (2, 1))
  219. gridSizer.Add(item = self.FindWindowById(self.win['view']['twist']['text']), pos = (3, 1),
  220. flag = wx.ALIGN_CENTER)
  221. # height + z-exag
  222. tooltip = _("Adjusts the viewer's height above the scene")
  223. self._createControl(panel, data = self.win['view'], name = 'height', sliderHor = False,
  224. tooltip = tooltip, range = (0, 1),
  225. bind = (self.OnViewChange, self.OnViewChanged, self.OnViewChangedText))
  226. tooltip = _("Adjusts the vertical exaggeration of the surface. "
  227. "As an example, if the easting and northing are in meters and the elevation in feet, "
  228. "a vertical exaggeration of .305 would produce a true (unexaggerated) surface. ")
  229. self._createControl(panel, data = self.win['view'], name = 'z-exag', sliderHor = False,
  230. tooltip = tooltip, range = (0, 10), floatSlider = True,
  231. bind = (self.OnViewChange, self.OnViewChanged, self.OnViewChangedText))
  232. self.FindWindowById(self.win['view']['z-exag']['slider']).SetValue(1)
  233. self.FindWindowById(self.win['view']['z-exag']['text']).SetValue(1)
  234. heightSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
  235. heightSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Height:")),
  236. pos = (0, 0), flag = wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL, span = (1, 2))
  237. heightSizer.Add(item = self.FindWindowById(self.win['view']['height']['slider']),
  238. flag = wx.ALIGN_RIGHT, pos = (1, 0))
  239. heightSizer.Add(item = self.FindWindowById(self.win['view']['height']['text']),
  240. flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT, pos = (1, 1))
  241. heightSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Z-exag:")),
  242. pos = (0, 2), flag = wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL, span = (1, 2))
  243. heightSizer.Add(item = self.FindWindowById(self.win['view']['z-exag']['slider']),
  244. flag = wx.ALIGN_RIGHT, pos = (1, 2))
  245. heightSizer.Add(item = self.FindWindowById(self.win['view']['z-exag']['text']),
  246. flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.TOP |
  247. wx.BOTTOM | wx.RIGHT, pos = (1, 3))
  248. gridSizer.Add(item = heightSizer, pos = (0, 1), flag = wx.ALIGN_CENTER)
  249. # view setup + reset
  250. viewSizer = wx.BoxSizer(wx.HORIZONTAL)
  251. viewSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY,
  252. label = _("Look:")),
  253. flag = wx.ALL | wx.ALIGN_CENTER_VERTICAL,
  254. border = 5)
  255. here = wx.ToggleButton(panel, id = wx.ID_ANY, label = _("here"))
  256. here.Bind(wx.EVT_TOGGLEBUTTON, self.OnLookAt)
  257. here.SetName('here')
  258. here.SetToolTipString(_("Allows you to select a point on the surface "
  259. "that becomes the new center of view. "
  260. "Click on the button and then on the surface."))
  261. viewSizer.Add(item = here, flag = wx.TOP|wx.BOTTOM|wx.LEFT|wx.ALIGN_CENTER_VERTICAL,
  262. border = 5)
  263. center = wx.Button(panel, id = wx.ID_ANY, label = _("center"))
  264. center.Bind(wx.EVT_BUTTON, self.OnLookAt)
  265. center.SetName('center')
  266. center.SetToolTipString(_("Resets the view to the original default center of view"))
  267. viewSizer.Add(item = center, flag = wx.TOP|wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL,
  268. border = 5)
  269. top = wx.Button(panel, id = wx.ID_ANY, label = _("top"))
  270. top.Bind(wx.EVT_BUTTON, self.OnLookAt)
  271. top.SetName('top')
  272. top.SetToolTipString(_("Sets the viewer directly over the scene's center position. This top view orients approximately north south."))
  273. viewSizer.Add(item = top, flag = wx.TOP|wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL,
  274. border = 5)
  275. reset = wx.Button(panel, id = wx.ID_ANY, label = _("reset"))
  276. reset.SetToolTipString(_("Reset to default view"))
  277. reset.Bind(wx.EVT_BUTTON, self.OnResetView)
  278. viewSizer.Add(item = reset, proportion = 0,
  279. flag = wx.TOP|wx.BOTTOM|wx.RIGHT| wx.ALIGN_RIGHT,
  280. border = 5)
  281. gridSizer.AddGrowableCol(2)
  282. gridSizer.Add(item = viewSizer, pos = (4, 0), span = (1, 3),
  283. flag = wx.EXPAND)
  284. # body
  285. boxSizer.Add(item = gridSizer, proportion = 1,
  286. flag = wx.ALL | wx.EXPAND, border = 2)
  287. pageSizer.Add(item = boxSizer, proportion = 0,
  288. flag = wx.EXPAND | wx.ALL,
  289. border = 3)
  290. box = wx.StaticBox(parent = panel, id = wx.ID_ANY,
  291. label = " %s " % (_("Image Appearance")))
  292. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  293. gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
  294. gridSizer.AddGrowableCol(0)
  295. # background color
  296. self.win['view']['background'] = {}
  297. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  298. label = _("Background color:")),
  299. pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
  300. color = csel.ColourSelect(panel, id = wx.ID_ANY,
  301. colour = UserSettings.Get(group = 'nviz', key = 'view',
  302. subkey = ['background', 'color']),
  303. size = globalvar.DIALOG_COLOR_SIZE)
  304. self.win['view']['background']['color'] = color.GetId()
  305. color.Bind(csel.EVT_COLOURSELECT, self.OnBgColor)
  306. gridSizer.Add(item = color, pos = (0, 1))
  307. boxSizer.Add(item = gridSizer, proportion = 1,
  308. flag = wx.ALL | wx.EXPAND, border = 3)
  309. pageSizer.Add(item = boxSizer, proportion = 0,
  310. flag = wx.EXPAND | wx.LEFT | wx.RIGHT,
  311. border = 3)
  312. panel.SetSizer(pageSizer)
  313. return panel
  314. def _createAnimationPage(self):
  315. """!Create view settings page"""
  316. panel = SP.ScrolledPanel(parent = self, id = wx.ID_ANY)
  317. panel.SetupScrolling(scroll_x = False)
  318. self.page['animation'] = { 'id' : 0,
  319. 'notebook' : self.GetId()}
  320. pageSizer = wx.BoxSizer(wx.VERTICAL)
  321. box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  322. label = " %s " % (_("Animation")))
  323. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  324. hSizer = wx.BoxSizer(wx.HORIZONTAL)
  325. self.win['anim'] = {}
  326. # animation help text
  327. help = wx.StaticText(parent = panel, id = wx.ID_ANY,
  328. label = _("Press 'Record' button and start changing the view. "
  329. "It is recommended to use fly-through mode "
  330. "(Map Display toolbar) to achieve smooth motion."))
  331. self.win['anim']['help'] = help.GetId()
  332. hSizer.Add(item = help, proportion = 0)
  333. boxSizer.Add(item = hSizer, proportion = 1,
  334. flag = wx.ALL | wx.EXPAND, border = 5)
  335. # animation controls
  336. hSizer = wx.BoxSizer(wx.HORIZONTAL)
  337. record = SymbolButton(parent = panel, id = wx.ID_ANY,
  338. usage = "record", label = _("Record"))
  339. play = SymbolButton(parent = panel, id = wx.ID_ANY,
  340. usage = "play", label = _("Play"))
  341. pause = SymbolButton(parent = panel, id = wx.ID_ANY,
  342. usage = "pause", label = _("Pause"))
  343. stop = SymbolButton(parent = panel, id = wx.ID_ANY,
  344. usage = "stop", label = _("Stop"))
  345. self.win['anim']['record'] = record.GetId()
  346. self.win['anim']['play'] = play.GetId()
  347. self.win['anim']['pause'] = pause.GetId()
  348. self.win['anim']['stop'] = stop.GetId()
  349. self._createControl(panel, data = self.win['anim'], name = 'frameIndex',
  350. range = (0, 1), floatSlider = False,
  351. bind = (self.OnFrameIndex, None, self.OnFrameIndexText))
  352. frameSlider = self.FindWindowById(self.win['anim']['frameIndex']['slider'])
  353. frameText = self.FindWindowById(self.win['anim']['frameIndex']['text'])
  354. infoLabel = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("Total number of frames :"))
  355. info = wx.StaticText(parent = panel, id = wx.ID_ANY)
  356. self.win['anim']['info'] = info.GetId()
  357. fpsLabel = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("Frame rate (FPS):"))
  358. fps = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
  359. initial = UserSettings.Get(group = 'nviz', key = 'animation', subkey = 'fps'),
  360. min = 1,
  361. max = 50)
  362. self.win['anim']['fps'] = fps.GetId()
  363. fps.SetToolTipString(_("Frames are recorded with given frequency (FPS). "))
  364. record.Bind(wx.EVT_BUTTON, self.OnRecord)
  365. play.Bind(wx.EVT_BUTTON, self.OnPlay)
  366. stop.Bind(wx.EVT_BUTTON, self.OnStop)
  367. pause.Bind(wx.EVT_BUTTON, self.OnPause)
  368. fps.Bind(wx.EVT_SPINCTRL, self.OnFPS)
  369. hSizer.Add(item = record, proportion = 0)
  370. hSizer.Add(item = play, proportion = 0)
  371. hSizer.Add(item = pause, proportion = 0)
  372. hSizer.Add(item = stop, proportion = 0)
  373. boxSizer.Add(item = hSizer, proportion = 0,
  374. flag = wx.ALL | wx.EXPAND, border = 3)
  375. sliderBox = wx.BoxSizer(wx.HORIZONTAL)
  376. sliderBox.Add(item = frameSlider, proportion = 1, border = 5, flag = wx.EXPAND | wx.RIGHT)
  377. sliderBox.Add(item = frameText, proportion = 0, border = 5, flag = wx.EXPAND| wx.RIGHT | wx.LEFT)
  378. boxSizer.Add(item = sliderBox, proportion = 0, flag = wx.EXPAND)
  379. # total number of frames
  380. hSizer = wx.BoxSizer(wx.HORIZONTAL)
  381. hSizer.Add(item = infoLabel, proportion = 0, flag = wx.RIGHT, border = 5)
  382. hSizer.Add(item = info, proportion = 0, flag = wx.LEFT, border = 5)
  383. boxSizer.Add(item = hSizer, proportion = 0,
  384. flag = wx.ALL | wx.EXPAND, border = 5)
  385. # frames per second
  386. hSizer = wx.BoxSizer(wx.HORIZONTAL)
  387. hSizer.Add(item = fpsLabel, proportion = 0, flag = wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, border = 5)
  388. hSizer.Add(item = fps, proportion = 0, flag = wx.LEFT | wx.ALIGN_CENTER_VERTICAL, border = 5)
  389. boxSizer.Add(item = hSizer, proportion = 0,
  390. flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 5)
  391. pageSizer.Add(item = boxSizer, proportion = 0,
  392. flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  393. border = 3)
  394. # save animation
  395. self.win['anim']['save'] = {}
  396. self.win['anim']['save']['image'] = {}
  397. box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  398. label = " %s " % (_("Save image sequence")))
  399. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  400. vSizer = wx.BoxSizer(wx.VERTICAL)
  401. gridSizer = wx.GridBagSizer(vgap = 5, hgap = 10)
  402. pwd = os.getcwd()
  403. dir = filebrowse.DirBrowseButton(parent = panel, id = wx.ID_ANY,
  404. labelText = _("Choose a directory:"),
  405. dialogTitle = _("Choose a directory for images"),
  406. buttonText = _('Browse'),
  407. startDirectory = pwd)
  408. dir.SetValue(pwd)
  409. prefixLabel = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("File prefix:"))
  410. prefixCtrl = wx.TextCtrl(parent = panel, id = wx.ID_ANY, size = (100, -1),
  411. value = UserSettings.Get(group = 'nviz',
  412. key = 'animation', subkey = 'prefix'))
  413. prefixCtrl.SetToolTipString(_("Generated files names will look like this: prefix_1.ppm, prefix_2.ppm, ..."))
  414. fileTypeLabel = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("File format:"))
  415. fileTypeCtrl = wx.Choice(parent = panel, id = wx.ID_ANY, choices = ["PPM", "TIF"])
  416. save = wx.Button(parent = panel, id = wx.ID_ANY,
  417. label = "Save")
  418. self.win['anim']['save']['image']['dir'] = dir.GetId()
  419. self.win['anim']['save']['image']['prefix'] = prefixCtrl.GetId()
  420. self.win['anim']['save']['image']['format'] = fileTypeCtrl.GetId()
  421. self.win['anim']['save']['image']['confirm'] = save.GetId()
  422. boxSizer.Add(item = dir, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 3)
  423. gridSizer.Add(item = prefixLabel, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
  424. gridSizer.Add(item = prefixCtrl, pos = (0, 1), flag = wx.EXPAND )
  425. gridSizer.Add(item = fileTypeLabel, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
  426. gridSizer.Add(item = fileTypeCtrl, pos = (1, 1), flag = wx.EXPAND )
  427. boxSizer.Add(item = gridSizer, proportion = 1,
  428. flag = wx.ALL | wx.EXPAND, border = 5)
  429. boxSizer.Add(item = save, proportion = 0, flag = wx.ALL | wx.ALIGN_RIGHT, border = 5)
  430. save.Bind(wx.EVT_BUTTON, self.OnSaveAnimation)
  431. pageSizer.Add(item = boxSizer, proportion = 0,
  432. flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  433. border = 3)
  434. panel.SetSizer(pageSizer)
  435. return panel
  436. def _createDataPage(self):
  437. """!Create data (surface, vector, volume) settings page"""
  438. self.mainPanelData = ScrolledPanel(parent = self)
  439. self.mainPanelData.SetupScrolling(scroll_x = False)
  440. try:# wxpython <= 2.8.10
  441. self.foldpanelData = fpb.FoldPanelBar(parent = self.mainPanelData, id = wx.ID_ANY,
  442. style = fpb.FPB_DEFAULT_STYLE,
  443. extraStyle = fpb.FPB_SINGLE_FOLD)
  444. except:
  445. try:# wxpython >= 2.8.11
  446. self.foldpanelData = fpb.FoldPanelBar(parent = self.mainPanelData, id = wx.ID_ANY,
  447. agwStyle = fpb.FPB_SINGLE_FOLD)
  448. except: # to be sure
  449. self.foldpanelData = fpb.FoldPanelBar(parent = self.mainPanelData, id = wx.ID_ANY,
  450. style = fpb.FPB_SINGLE_FOLD)
  451. self.foldpanelData.Bind(fpb.EVT_CAPTIONBAR, self.OnPressCaption)
  452. # surface page
  453. self.surfacePanel = self.foldpanelData.AddFoldPanel(_("Surface"), collapsed = False)
  454. self.foldpanelData.AddFoldPanelWindow(self.surfacePanel,
  455. window = self._createSurfacePage(parent = self.surfacePanel), flags = fpb.FPB_ALIGN_WIDTH)
  456. self.EnablePage("surface", enabled = False)
  457. # constant page
  458. constantPanel = self.foldpanelData.AddFoldPanel(_("Constant surface"), collapsed = True)
  459. self.foldpanelData.AddFoldPanelWindow(constantPanel,
  460. window = self._createConstantPage(parent = constantPanel), flags = fpb.FPB_ALIGN_WIDTH)
  461. self.EnablePage("constant", enabled = False)
  462. # vector page
  463. vectorPanel = self.foldpanelData.AddFoldPanel(_("Vector"), collapsed = True)
  464. self.foldpanelData.AddFoldPanelWindow(vectorPanel,
  465. window = self._createVectorPage(parent = vectorPanel), flags = fpb.FPB_ALIGN_WIDTH)
  466. self.EnablePage("vector", enabled = False)
  467. # volume page
  468. volumePanel = self.foldpanelData.AddFoldPanel(_("Volume"), collapsed = True)
  469. self.foldpanelData.AddFoldPanelWindow(volumePanel,
  470. window = self._createVolumePage(parent = volumePanel), flags = fpb.FPB_ALIGN_WIDTH)
  471. self.EnablePage("volume", enabled = False)
  472. ## self.foldpanelData.ApplyCaptionStyleAll(style)
  473. sizer = wx.BoxSizer(wx.VERTICAL)
  474. sizer.Add(self.foldpanelData, proportion = 1, flag = wx.EXPAND)
  475. self.mainPanelData.SetSizer(sizer)
  476. self.mainPanelData.Layout()
  477. self.mainPanelData.Fit()
  478. return self.mainPanelData
  479. def _createAppearancePage(self):
  480. """!Create data (surface, vector, volume) settings page"""
  481. self.mainPanelAppear = ScrolledPanel(parent = self)
  482. self.mainPanelAppear.SetupScrolling(scroll_x = False)
  483. try:# wxpython <= 2.8.10
  484. self.foldpanelAppear = fpb.FoldPanelBar(parent = self.mainPanelAppear, id = wx.ID_ANY,
  485. style = fpb.FPB_DEFAULT_STYLE,
  486. extraStyle = fpb.FPB_SINGLE_FOLD)
  487. except:
  488. try:# wxpython >= 2.8.11
  489. self.foldpanelAppear = fpb.FoldPanelBar(parent = self.mainPanelAppear, id = wx.ID_ANY,
  490. agwStyle = fpb.FPB_SINGLE_FOLD)
  491. except: # to be sure
  492. self.foldpanelAppear = fpb.FoldPanelBar(parent = self.mainPanelAppear, id = wx.ID_ANY,
  493. style = fpb.FPB_SINGLE_FOLD)
  494. self.foldpanelAppear.Bind(fpb.EVT_CAPTIONBAR, self.OnPressCaption)
  495. # light page
  496. lightPanel = self.foldpanelAppear.AddFoldPanel(_("Lighting"), collapsed = False)
  497. self.foldpanelAppear.AddFoldPanelWindow(lightPanel,
  498. window = self._createLightPage(parent = lightPanel), flags = fpb.FPB_ALIGN_WIDTH)
  499. # fringe page
  500. fringePanel = self.foldpanelAppear.AddFoldPanel(_("Fringe"), collapsed = True)
  501. self.foldpanelAppear.AddFoldPanelWindow(fringePanel,
  502. window = self._createFringePage(parent = fringePanel), flags = fpb.FPB_ALIGN_WIDTH)
  503. self.EnablePage('fringe', False)
  504. # decoration page
  505. decorationPanel = self.foldpanelAppear.AddFoldPanel(_("Decorations"), collapsed = True)
  506. self.foldpanelAppear.AddFoldPanelWindow(decorationPanel,
  507. window = self._createDecorationPage(parent = decorationPanel), flags = fpb.FPB_ALIGN_WIDTH)
  508. sizer = wx.BoxSizer(wx.VERTICAL)
  509. sizer.Add(self.foldpanelAppear, proportion = 1, flag = wx.EXPAND)
  510. self.mainPanelAppear.SetSizer(sizer)
  511. self.mainPanelAppear.Layout()
  512. self.mainPanelAppear.Fit()
  513. return self.mainPanelAppear
  514. def _createAnalysisPage(self):
  515. """!Create data analysis (cutting planes, ...) page"""
  516. self.mainPanelAnalysis = ScrolledPanel(parent = self)
  517. self.mainPanelAnalysis.SetupScrolling(scroll_x = False)
  518. self.foldpanelAnalysis = fpb.FoldPanelBar(parent = self.mainPanelAnalysis, id = wx.ID_ANY,
  519. style = fpb.FPB_SINGLE_FOLD)
  520. self.foldpanelAnalysis.Bind(fpb.EVT_CAPTIONBAR, self.OnPressCaption)
  521. # cutting planes page
  522. cplanePanel = self.foldpanelAnalysis.AddFoldPanel(_("Cutting planes"), collapsed = False)
  523. self.foldpanelAnalysis.AddFoldPanelWindow(cplanePanel,
  524. window = self._createCPlanePage(parent = cplanePanel), flags = fpb.FPB_ALIGN_WIDTH)
  525. sizer = wx.BoxSizer(wx.VERTICAL)
  526. sizer.Add(self.foldpanelAnalysis, proportion = 1, flag = wx.EXPAND)
  527. self.mainPanelAnalysis.SetSizer(sizer)
  528. self.mainPanelAnalysis.Layout()
  529. self.mainPanelAnalysis.Fit()
  530. return self.mainPanelAnalysis
  531. def _createSurfacePage(self, parent):
  532. """!Create view settings page"""
  533. panel = wx.Panel(parent = parent, id = wx.ID_ANY)
  534. self.page['surface'] = { 'id' : 0,
  535. 'notebook' : self.foldpanelData.GetId() }
  536. pageSizer = wx.BoxSizer(wx.VERTICAL)
  537. self.win['surface'] = {}
  538. # selection
  539. box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  540. label = " %s " % (_("Raster map")))
  541. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  542. rmaps = Select(parent = panel, type = 'raster',
  543. onPopup = self.GselectOnPopup)
  544. rmaps.GetChildren()[0].Bind(wx.EVT_TEXT, self.OnSetRaster)
  545. self.win['surface']['map'] = rmaps.GetId()
  546. desc = wx.StaticText(parent = panel, id = wx.ID_ANY)
  547. self.win['surface']['desc'] = desc.GetId()
  548. boxSizer.Add(item = rmaps, proportion = 0,
  549. flag = wx.ALL,
  550. border = 3)
  551. boxSizer.Add(item = desc, proportion = 0,
  552. flag = wx.ALL,
  553. border = 3)
  554. pageSizer.Add(item = boxSizer, proportion = 0,
  555. flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  556. border = 3)
  557. #
  558. # draw
  559. #
  560. self.win['surface']['draw'] = {}
  561. box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  562. label = " %s " % (_("Draw")))
  563. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  564. gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
  565. gridSizer.AddGrowableCol(3)
  566. # mode
  567. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  568. label = _("Mode:")),
  569. pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
  570. mode = wx.Choice (parent = panel, id = wx.ID_ANY, size = (-1, -1),
  571. choices = [_("coarse"),
  572. _("fine"),
  573. _("both")])
  574. mode.SetName("selection")
  575. mode.Bind(wx.EVT_CHOICE, self.OnSurfaceMode)
  576. self.win['surface']['draw']['mode'] = mode.GetId()
  577. gridSizer.Add(item = mode, flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND,
  578. pos = (0, 1),span = (1, 2))
  579. # shading
  580. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  581. label = _("Shading:")),
  582. pos = (0, 3), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT)
  583. shade = wx.Choice (parent = panel, id = wx.ID_ANY, size = (-1, -1),
  584. choices = [_("flat"),
  585. _("gouraud")])
  586. shade.SetName("selection")
  587. self.win['surface']['draw']['shading'] = shade.GetId()
  588. shade.Bind(wx.EVT_CHOICE, self.OnSurfaceMode)
  589. gridSizer.Add(item = shade, flag = wx.ALIGN_CENTER_VERTICAL,
  590. pos = (0, 4))
  591. # set to all
  592. all = wx.Button(panel, id = wx.ID_ANY, label = _("Set to all"))
  593. all.SetToolTipString(_("Use draw settings for all loaded surfaces"))
  594. all.Bind(wx.EVT_BUTTON, self.OnSurfaceModeAll)
  595. gridSizer.Add(item = all, flag = wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  596. pos = (3, 4))
  597. self.win['surface']['all'] = all.GetId()
  598. # resolution coarse
  599. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  600. label = _("Coarse mode:")),
  601. pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL)
  602. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  603. label = _("resolution:")),
  604. pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL)
  605. resC = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
  606. initial = 6,
  607. min = 1,
  608. max = 100)
  609. resC.SetName("value")
  610. self.win['surface']['draw']['res-coarse'] = resC.GetId()
  611. resC.Bind(wx.EVT_SPINCTRL, self.OnSurfaceResolution)
  612. gridSizer.Add(item = resC, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT)
  613. # Coarse style
  614. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  615. label = _("style:")),
  616. pos = (3, 1), flag = wx.ALIGN_CENTER_VERTICAL)
  617. style = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
  618. choices = [_("wire"),
  619. _("surface")])
  620. style.SetName("selection")
  621. self.win['surface']['draw']['style'] = style.GetId()
  622. style.Bind(wx.EVT_CHOICE, self.OnSurfaceMode)
  623. gridSizer.Add(item = style, flag = wx.ALIGN_CENTER_VERTICAL,
  624. pos = (3, 2))
  625. # color
  626. color = csel.ColourSelect(panel, id = wx.ID_ANY,
  627. size = globalvar.DIALOG_COLOR_SIZE)
  628. color.SetName("colour")
  629. color.Bind(csel.EVT_COLOURSELECT, self.OnSurfaceWireColor)
  630. color.SetToolTipString(_("Change wire color"))
  631. self.win['surface']['draw']['wire-color'] = color.GetId()
  632. gridSizer.Add(item = color, flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
  633. pos = (3, 3))
  634. # resolution fine
  635. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  636. label = _("Fine mode:")),
  637. pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL)
  638. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  639. label = _("resolution:")),
  640. pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL)
  641. resF = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
  642. initial = 3,
  643. min = 1,
  644. max = 100)
  645. resF.SetName("value")
  646. self.win['surface']['draw']['res-fine'] = resF.GetId()
  647. resF.Bind(wx.EVT_SPINCTRL, self.OnSurfaceResolution)
  648. gridSizer.Add(item = resF, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT)
  649. boxSizer.Add(item = gridSizer, proportion = 1,
  650. flag = wx.ALL | wx.EXPAND, border = 3)
  651. pageSizer.Add(item = boxSizer, proportion = 0,
  652. flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  653. border = 3)
  654. #
  655. # surface attributes
  656. #
  657. box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  658. label = " %s " % (_("Surface attributes")))
  659. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  660. gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
  661. gridSizer.AddGrowableCol(2)
  662. # type
  663. self.win['surface']['attr'] = {}
  664. row = 0
  665. for code, attrb in (('color', _("Color")),
  666. ('mask', _("Mask")),
  667. ('transp', _("Transparency")),
  668. ('shine', _("Shininess"))):
  669. self.win['surface'][code] = {}
  670. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  671. label = attrb + ':'),
  672. pos = (row, 0), flag = wx.ALIGN_CENTER_VERTICAL)
  673. use = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
  674. choices = [_("map")])
  675. if code not in ('color', 'shine'):
  676. use.Insert(item = _("unset"), pos = 0)
  677. self.win['surface'][code]['required'] = False
  678. else:
  679. self.win['surface'][code]['required'] = True
  680. if code != 'mask':
  681. use.Append(item = _('constant'))
  682. self.win['surface'][code]['use'] = use.GetId()
  683. use.Bind(wx.EVT_CHOICE, self.OnMapObjUse)
  684. gridSizer.Add(item = use, flag = wx.ALIGN_CENTER_VERTICAL,
  685. pos = (row, 1))
  686. map = Select(parent = panel, id = wx.ID_ANY,
  687. # size = globalvar.DIALOG_GSELECT_SIZE,
  688. size = (-1, -1),
  689. type = "raster")
  690. self.win['surface'][code]['map'] = map.GetId() - 1 # FIXME
  691. map.Bind(wx.EVT_TEXT, self.OnSurfaceMap)
  692. gridSizer.Add(item = map, flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND,
  693. pos = (row, 2))
  694. if code == 'color':
  695. color = UserSettings.Get(group = 'nviz', key = 'surface', subkey = ['color', 'value'])
  696. value = csel.ColourSelect(panel, id = wx.ID_ANY,
  697. colour = color,
  698. size = globalvar.DIALOG_COLOR_SIZE)
  699. value.Bind(csel.EVT_COLOURSELECT, self.OnSurfaceMap)
  700. elif code == 'mask':
  701. value = None
  702. else:
  703. value = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
  704. initial = 0)
  705. value.SetRange(minVal = 0, maxVal = 100)
  706. value.Bind(wx.EVT_TEXT, self.OnSurfaceMap)
  707. if value:
  708. self.win['surface'][code]['const'] = value.GetId()
  709. value.Enable(False)
  710. gridSizer.Add(item = value, flag = wx.ALIGN_CENTER_VERTICAL,
  711. pos = (row, 3))
  712. else:
  713. self.win['surface'][code]['const'] = None
  714. self.SetMapObjUseMap(nvizType = 'surface',
  715. attrb = code) # -> enable map / disable constant
  716. row += 1
  717. boxSizer.Add(item = gridSizer, proportion = 0,
  718. flag = wx.ALL | wx.EXPAND, border = 3)
  719. pageSizer.Add(item = boxSizer, proportion = 0,
  720. flag = wx.EXPAND | wx.ALL,
  721. border = 3)
  722. #
  723. # position
  724. #
  725. self.win['surface']['position'] = {}
  726. box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  727. label = " %s " % (_("Position")))
  728. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  729. gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
  730. gridSizer.AddGrowableCol(3)
  731. # position
  732. tooltip = _("Changes the x, y, and z position of the current surface")
  733. self._createControl(panel, data = self.win['surface'], name = 'position',
  734. tooltip = tooltip, range = (-10000, 10000), floatSlider = True,
  735. bind = (self.OnSurfacePosition, self.OnSurfacePositionChanged, self.OnSurfacePositionText))
  736. axis = wx.Choice (parent = panel, id = wx.ID_ANY, size = (75, -1),
  737. choices = ["X",
  738. "Y",
  739. "Z"])
  740. reset = wx.Button(panel, id = wx.ID_ANY, label = _("Reset"))
  741. reset.SetToolTipString(_("Reset to default position"))
  742. reset.Bind(wx.EVT_BUTTON, self.OnResetSurfacePosition)
  743. self.win['surface']['position']['reset'] = reset.GetId()
  744. self.win['surface']['position']['axis'] = axis.GetId()
  745. axis.SetSelection(0)
  746. axis.Bind(wx.EVT_CHOICE, self.OnSurfaceAxis)
  747. pslide = self.FindWindowById(self.win['surface']['position']['slider'])
  748. ptext = self.FindWindowById(self.win['surface']['position']['text'])
  749. ptext.SetValue('0')
  750. gridSizer.Add(item = axis, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 0))
  751. gridSizer.Add(item = pslide, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 1))
  752. gridSizer.Add(item = ptext, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 2))
  753. gridSizer.Add(item = reset, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, pos = (0, 3))
  754. boxSizer.Add(item = gridSizer, proportion = 1,
  755. flag = wx.ALL | wx.EXPAND, border = 3)
  756. box.SetSizer(boxSizer)
  757. box.Layout()
  758. pageSizer.Add(item = boxSizer, proportion = 1,
  759. flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  760. border = 3)
  761. #
  762. # mask
  763. #
  764. ## box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  765. ## label = " %s " % (_("Mask")))
  766. ## boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  767. ## gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  768. ##
  769. ## gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  770. ## label = _("Mask zeros:")),
  771. ## pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
  772. ##
  773. ## elev = wx.CheckBox(parent = panel, id = wx.ID_ANY,
  774. ## label = _("by elevation"))
  775. ## elev.Enable(False) # TODO: not implemented yet
  776. ## gridSizer.Add(item = elev, pos = (0, 1))
  777. ##
  778. ## color = wx.CheckBox(parent = panel, id = wx.ID_ANY,
  779. ## label = _("by color"))
  780. ## color.Enable(False) # TODO: not implemented yet
  781. ## gridSizer.Add(item = color, pos = (0, 2))
  782. ##
  783. ## boxSizer.Add(item = gridSizer, proportion = 1,
  784. ## flag = wx.ALL | wx.EXPAND, border = 3)
  785. ## pageSizer.Add(item = boxSizer, proportion = 0,
  786. ## flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  787. ## border = 3)
  788. panel.SetSizer(pageSizer)
  789. panel.Layout()
  790. panel.Fit()
  791. return panel
  792. def _createCPlanePage(self, parent):
  793. """!Create cutting planes page"""
  794. panel = wx.Panel(parent = parent, id = wx.ID_ANY)
  795. self.page['cplane'] = { 'id' : 4,
  796. 'notebook' : self.foldpanelData.GetId() }
  797. self.win['cplane'] = {}
  798. pageSizer = wx.BoxSizer(wx.VERTICAL)
  799. box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  800. label = " %s " % (_("Cutting planes")))
  801. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  802. horSizer = wx.BoxSizer(wx.HORIZONTAL)
  803. # planes
  804. horSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  805. label = _("Active cutting plane:")),
  806. flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
  807. choice = wx.Choice(parent = panel, id = wx.ID_ANY, choices = [])
  808. self.win['cplane']['planes'] = choice.GetId()
  809. choice.Bind(wx.EVT_CHOICE, self.OnCPlaneSelection)
  810. horSizer.Add(item = choice, flag = wx.ALL, border = 5)
  811. # shading
  812. horSizer.Add(item = wx.Size(-1, -1), proportion = 1)
  813. horSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  814. label = _("Shading:")),
  815. flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
  816. choices = [_("clear"),
  817. _("top color"),
  818. _("bottom color"),
  819. _("blend"),
  820. _("shaded")]
  821. choice = wx.Choice(parent = panel, id = wx.ID_ANY, choices = choices)
  822. self.win['cplane']['shading'] = choice.GetId()
  823. choice.Bind(wx.EVT_CHOICE, self.OnCPlaneShading)
  824. horSizer.Add(item = choice, flag = wx.ALL, border = 5)
  825. boxSizer.Add(item = horSizer, flag = wx.EXPAND)
  826. gridSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
  827. # cutting plane horizontal x position
  828. self.win['cplane']['position'] = {}
  829. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  830. label = _("Horizontal X:")),
  831. pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
  832. tooltip = _("Sets the X coordinate of the current cutting plane")
  833. self._createControl(panel, data = self.win['cplane']['position'], name = 'x', size = 250,
  834. range = (-1000, 1000), sliderHor = True, floatSlider = True, tooltip = tooltip,
  835. bind = (self.OnCPlaneChanging, self.OnCPlaneChangeDone, self.OnCPlaneChangeText))
  836. self.FindWindowById(self.win['cplane']['position']['x']['slider']).SetValue(0)
  837. self.FindWindowById(self.win['cplane']['position']['x']['text']).SetValue(0)
  838. gridSizer.Add(item = self.FindWindowById(self.win['cplane']['position']['x']['slider']),
  839. pos = (0, 1), flag = wx.EXPAND|wx.ALIGN_RIGHT)
  840. gridSizer.Add(item = self.FindWindowById(self.win['cplane']['position']['x']['text']),
  841. pos = (0, 2),
  842. flag = wx.ALIGN_CENTER)
  843. # cutting plane horizontal y position
  844. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  845. label = _("Horizontal Y:")),
  846. pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL)
  847. tooltip = _("Sets the Y coordinate of the current cutting plane")
  848. self._createControl(panel, data = self.win['cplane']['position'], name = 'y', size = 250,
  849. range = (-1000, 1000), sliderHor = True, floatSlider = True, tooltip = tooltip,
  850. bind = (self.OnCPlaneChanging, self.OnCPlaneChangeDone, self.OnCPlaneChangeText))
  851. self.FindWindowById(self.win['cplane']['position']['y']['slider']).SetValue(0)
  852. self.FindWindowById(self.win['cplane']['position']['y']['text']).SetValue(0)
  853. gridSizer.Add(item = self.FindWindowById(self.win['cplane']['position']['y']['slider']),
  854. pos = (1, 1), flag = wx.EXPAND|wx.ALIGN_RIGHT)
  855. gridSizer.Add(item = self.FindWindowById(self.win['cplane']['position']['y']['text']),
  856. pos = (1, 2),
  857. flag = wx.ALIGN_CENTER)
  858. # cutting plane rotation
  859. self.win['cplane']['rotation'] = {}
  860. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  861. label = _("Rotation:")),
  862. pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL)
  863. tooltip = _("Rotates the current cutting plane about vertical axis")
  864. self._createControl(panel, data = self.win['cplane']['rotation'], name = 'rot', size = 250,
  865. range = (0, 360), sliderHor = True, tooltip = tooltip,
  866. bind = (self.OnCPlaneChanging, self.OnCPlaneChangeDone, self.OnCPlaneChangeText))
  867. self.FindWindowById(self.win['cplane']['rotation']['rot']['slider']).SetValue(0)
  868. self.FindWindowById(self.win['cplane']['rotation']['rot']['text']).SetValue(0)
  869. gridSizer.Add(item = self.FindWindowById(self.win['cplane']['rotation']['rot']['slider']),
  870. pos = (2, 1), flag = wx.EXPAND|wx.ALIGN_RIGHT)
  871. gridSizer.Add(item = self.FindWindowById(self.win['cplane']['rotation']['rot']['text']),
  872. pos = (2, 2),
  873. flag = wx.ALIGN_CENTER)
  874. # cutting plane tilt
  875. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  876. label = _("Tilt:")),
  877. pos = (3, 0), flag = wx.ALIGN_CENTER_VERTICAL)
  878. tooltip = _("Rotates the current cutting plane about horizontal axis")
  879. self._createControl(panel, data = self.win['cplane']['rotation'], name = 'tilt', size = 250,
  880. range = (0, 360), sliderHor = True, tooltip = tooltip,
  881. bind = (self.OnCPlaneChanging, self.OnCPlaneChangeDone, self.OnCPlaneChangeText))
  882. self.FindWindowById(self.win['cplane']['rotation']['tilt']['slider']).SetValue(0)
  883. self.FindWindowById(self.win['cplane']['rotation']['tilt']['text']).SetValue(0)
  884. gridSizer.Add(item = self.FindWindowById(self.win['cplane']['rotation']['tilt']['slider']),
  885. pos = (3, 1), flag = wx.EXPAND|wx.ALIGN_RIGHT)
  886. gridSizer.Add(item = self.FindWindowById(self.win['cplane']['rotation']['tilt']['text']),
  887. pos = (3, 2),
  888. flag = wx.ALIGN_CENTER)
  889. # cutting pland height
  890. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  891. label = _("Height:")),
  892. pos = (4, 0), flag = wx.ALIGN_CENTER_VERTICAL)
  893. tooltip = _("Sets the Z coordinate of the current cutting plane (only meaningful when tilt is not 0)")
  894. self._createControl(panel, data = self.win['cplane']['position'], name = 'z', size = 250,
  895. range = (-1000, 1000), sliderHor = True, tooltip = tooltip,
  896. bind = (self.OnCPlaneChanging, self.OnCPlaneChangeDone, self.OnCPlaneChangeText))
  897. self.FindWindowById(self.win['cplane']['position']['z']['slider']).SetValue(0)
  898. self.FindWindowById(self.win['cplane']['position']['z']['text']).SetValue(0)
  899. gridSizer.Add(item = self.FindWindowById(self.win['cplane']['position']['z']['slider']),
  900. pos = (4, 1), flag = wx.EXPAND|wx.ALIGN_RIGHT)
  901. gridSizer.Add(item = self.FindWindowById(self.win['cplane']['position']['z']['text']),
  902. pos = (4, 2),
  903. flag = wx.ALIGN_CENTER)
  904. boxSizer.Add(gridSizer, proportion = 0, flag = wx.EXPAND|wx.ALL, border = 5)
  905. horSizer = wx.BoxSizer(wx.HORIZONTAL)
  906. horSizer.Add(item = wx.Size(-1, -1), proportion = 1, flag = wx.ALL, border = 5)
  907. # reset
  908. reset = wx.Button(parent = panel, id = wx.ID_ANY, label = _("Reset"))
  909. self.win['cplane']['reset'] = reset.GetId()
  910. reset.Bind(wx.EVT_BUTTON, self.OnCPlaneReset)
  911. horSizer.Add(item = reset, flag = wx.ALL, border = 5)
  912. boxSizer.Add(horSizer, proportion = 0, flag = wx.EXPAND)
  913. pageSizer.Add(boxSizer, proportion = 0, flag = wx.EXPAND)
  914. panel.SetSizer(pageSizer)
  915. panel.Fit()
  916. return panel
  917. def _createConstantPage(self, parent):
  918. """!Create constant page"""
  919. panel = wx.Panel(parent = parent, id = wx.ID_ANY)
  920. self.page['constant'] = { 'id' : 1,
  921. 'notebook' : self.foldpanelData.GetId() }
  922. self.win['constant'] = {}
  923. pageSizer = wx.BoxSizer(wx.VERTICAL)
  924. box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  925. label = " %s " % (_("Constant surface")))
  926. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  927. horsizer = wx.BoxSizer(wx.HORIZONTAL)
  928. surface = wx.ComboBox(parent = panel, id = wx.ID_ANY,
  929. style = wx.CB_SIMPLE | wx.CB_READONLY,
  930. choices = [])
  931. self.win['constant']['surface'] = surface.GetId()
  932. surface.Bind(wx.EVT_COMBOBOX, self.OnConstantSelection)
  933. horsizer.Add(surface, proportion = 1, flag = wx.EXPAND|wx.RIGHT, border = 20)
  934. addNew = wx.Button(panel, id = wx.ID_ANY, label = _("New"))
  935. addNew.Bind(wx.EVT_BUTTON, self.OnNewConstant)
  936. self.win['constant']['new'] = addNew.GetId()
  937. delete = wx.Button(panel, id = wx.ID_ANY, label = _("Delete"))
  938. delete.Bind(wx.EVT_BUTTON, self.OnDeleteConstant)
  939. self.win['constant']['delete'] = delete.GetId()
  940. horsizer.Add(item = addNew, proportion = 0, flag = wx.RIGHT|wx.LEFT, border = 3)
  941. horsizer.Add(item = delete, proportion = 0, flag = wx.RIGHT|wx.LEFT, border = 3)
  942. boxSizer.Add(item = horsizer, proportion = 0, flag = wx.ALL|wx.EXPAND,
  943. border = 5)
  944. gridSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
  945. # fine resolution
  946. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  947. label = _("Fine resolution:")),
  948. pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
  949. resF = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
  950. initial = 3,
  951. min = 1,
  952. max = 100)
  953. resF.SetName("value")
  954. self.win['constant']['resolution'] = resF.GetId()
  955. resF.Bind(wx.EVT_SPINCTRL, self.OnSetConstantProp)
  956. gridSizer.Add(item = resF, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT)
  957. # value
  958. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  959. label = _("Value:")), pos = (1, 0),
  960. flag = wx.ALIGN_CENTER_VERTICAL)
  961. value = wx.SpinCtrl(panel, id = wx.ID_ANY,
  962. min = -1e9, max = 1e9,
  963. size = (65, -1))
  964. self.win['constant']['value'] = value.GetId()
  965. value.Bind(wx.EVT_SPINCTRL, self.OnSetConstantProp)
  966. gridSizer.Add(item = value, pos = (1, 1))
  967. # transparency
  968. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  969. label = _("Transparency:")), pos = (2, 0),
  970. flag = wx.ALIGN_CENTER_VERTICAL)
  971. transp = wx.SpinCtrl(panel, id = wx.ID_ANY,
  972. min = 0, max = 100,
  973. size = (65, -1))
  974. self.win['constant']['transp'] = transp.GetId()
  975. transp.Bind(wx.EVT_SPINCTRL, self.OnSetConstantProp)
  976. gridSizer.Add(item = transp, pos = (2, 1))
  977. # color
  978. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  979. label = _("Color:")), pos = (3, 0),
  980. flag = wx.ALIGN_CENTER_VERTICAL)
  981. color = csel.ColourSelect(panel, id = wx.ID_ANY,
  982. colour = (0,0,0),
  983. size = globalvar.DIALOG_COLOR_SIZE)
  984. self.win['constant']['color'] = color.GetId()
  985. color.Bind(csel.EVT_COLOURSELECT, self.OnSetConstantProp)
  986. gridSizer.Add(item = color, pos = (3, 1))
  987. boxSizer.Add(item = gridSizer, proportion = 0, flag = wx.ALL,
  988. border = 5)
  989. pageSizer.Add(item = boxSizer, proportion = 0,
  990. flag = wx.EXPAND | wx.ALL,
  991. border = 3)
  992. panel.SetSizer(pageSizer)
  993. panel.Fit()
  994. return panel
  995. def _createVectorPage(self, parent):
  996. """!Create view settings page"""
  997. panel = wx.Panel(parent = parent, id = wx.ID_ANY)
  998. self.page['vector'] = { 'id' : 2,
  999. 'notebook' : self.foldpanelData.GetId() }
  1000. pageSizer = wx.BoxSizer(wx.VERTICAL)
  1001. self.win['vector'] = {}
  1002. # selection
  1003. box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  1004. label = " %s " % (_("Vector map")))
  1005. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1006. vmaps = Select(parent = panel, type = 'vector',
  1007. onPopup = self.GselectOnPopup)
  1008. vmaps.GetChildren()[0].Bind(wx.EVT_TEXT, self.OnSetVector)
  1009. self.win['vector']['map'] = vmaps.GetId()
  1010. desc = wx.StaticText(parent = panel, id = wx.ID_ANY)
  1011. self.win['vector']['desc'] = desc.GetId()
  1012. boxSizer.Add(item = vmaps, proportion = 0,
  1013. flag = wx.ALL,
  1014. border = 3)
  1015. boxSizer.Add(item = desc, proportion = 0,
  1016. flag = wx.ALL,
  1017. border = 3)
  1018. pageSizer.Add(item = boxSizer, proportion = 0,
  1019. flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1020. border = 3)
  1021. #
  1022. # vector lines
  1023. #
  1024. self.win['vector']['lines'] = {}
  1025. showLines = wx.CheckBox(parent = panel, id = wx.ID_ANY,
  1026. label = _("Show vector lines"))
  1027. showLines.SetValue(True)
  1028. self.win['vector']['lines']['show'] = showLines.GetId()
  1029. showLines.Bind(wx.EVT_CHECKBOX, self.OnVectorShow)
  1030. pageSizer.Add(item = showLines, proportion = 0,
  1031. flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 5)
  1032. box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  1033. label = " %s " % (_("Vector lines")))
  1034. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1035. gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  1036. gridSizer.AddGrowableCol(5)
  1037. # width
  1038. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1039. label = _("Line:")),
  1040. pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
  1041. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1042. label = _("width:")),
  1043. pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL |
  1044. wx.ALIGN_RIGHT)
  1045. width = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
  1046. initial = 1,
  1047. min = 0,
  1048. max = 100)
  1049. width.SetValue(1)
  1050. self.win['vector']['lines']['width'] = width.GetId()
  1051. width.Bind(wx.EVT_SPINCTRL, self.OnVectorLines)
  1052. gridSizer.Add(item = width, pos = (0, 2),
  1053. flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
  1054. # color
  1055. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1056. label = _("color:")),
  1057. pos = (0, 3), flag = wx.ALIGN_CENTER_VERTICAL |
  1058. wx.ALIGN_RIGHT)
  1059. color = csel.ColourSelect(panel, id = wx.ID_ANY,
  1060. colour = (0,0,0),
  1061. size = globalvar.DIALOG_COLOR_SIZE)
  1062. self.win['vector']['lines']['color'] = color.GetId()
  1063. color.Bind(csel.EVT_COLOURSELECT, self.OnVectorLines)
  1064. gridSizer.Add(item = color, pos = (0, 4), flag = wx.ALIGN_CENTER_VERTICAL |
  1065. wx.ALIGN_LEFT)
  1066. # thematic mapping
  1067. self.win['vector']['lines']['thematic'] = {}
  1068. checkThematicColor = wx.CheckBox(parent = panel, id = wx.ID_ANY,
  1069. label = _("use color for thematic mapping"))
  1070. checkThematicWidth = wx.CheckBox(parent = panel, id = wx.ID_ANY,
  1071. label = _("use width for thematic mapping"))
  1072. self.win['vector']['lines']['thematic']['checkcolor'] = checkThematicColor.GetId()
  1073. self.win['vector']['lines']['thematic']['checkwidth'] = checkThematicWidth.GetId()
  1074. checkThematicColor.Bind(wx.EVT_CHECKBOX, self.OnCheckThematic)
  1075. checkThematicWidth.Bind(wx.EVT_CHECKBOX, self.OnCheckThematic)
  1076. checkThematicColor.SetValue(False)
  1077. checkThematicWidth.SetValue(False)
  1078. vSizer = wx.BoxSizer(wx.VERTICAL)
  1079. hSizer = wx.BoxSizer(wx.HORIZONTAL)
  1080. hSizer.Add(item = checkThematicColor, flag = wx.ALIGN_CENTER_VERTICAL,
  1081. border = 5)
  1082. setThematic = wx.Button(parent = panel, id = wx.ID_ANY,
  1083. label = _("Set options..."))
  1084. self.win['vector']['lines']['thematic']['buttoncolor'] = setThematic.GetId()
  1085. setThematic.Bind(wx.EVT_BUTTON, self.OnSetThematic)
  1086. hSizer.Add(item = wx.Size(-1, -1), proportion = 1)
  1087. hSizer.Add(item = setThematic, flag = wx.ALIGN_CENTER_VERTICAL|wx.LEFT,
  1088. border = 5, proportion = 0)
  1089. vSizer.Add(hSizer, flag = wx.EXPAND)
  1090. hSizer = wx.BoxSizer(wx.HORIZONTAL)
  1091. hSizer.Add(item = checkThematicWidth, flag = wx.ALIGN_CENTER_VERTICAL,
  1092. border = 5)
  1093. setThematic = wx.Button(parent = panel, id = wx.ID_ANY,
  1094. label = _("Set options..."))
  1095. self.win['vector']['lines']['thematic']['buttonwidth'] = setThematic.GetId()
  1096. setThematic.Bind(wx.EVT_BUTTON, self.OnSetThematic)
  1097. hSizer.Add(item = wx.Size(-1, -1), proportion = 1)
  1098. hSizer.Add(item = setThematic, flag = wx.ALIGN_CENTER_VERTICAL|wx.LEFT,
  1099. border = 5, proportion = 0)
  1100. vSizer.Add(hSizer, flag = wx.EXPAND)
  1101. gridSizer.Add(item = vSizer, flag = wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  1102. pos = (1, 1), span = (1, 5))
  1103. # display
  1104. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1105. label = _("Display")),
  1106. pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL |
  1107. wx.ALIGN_LEFT)
  1108. display = wx.Choice (parent = panel, id = wx.ID_ANY, size = (-1, -1),
  1109. choices = [_("on surface(s):"),
  1110. _("flat")])
  1111. self.win['vector']['lines']['flat'] = display.GetId()
  1112. display.Bind(wx.EVT_CHOICE, self.OnVectorDisplay)
  1113. gridSizer.Add(item = display, flag = wx.ALIGN_CENTER_VERTICAL |
  1114. wx.ALIGN_LEFT|wx.EXPAND, pos = (2, 1), span = (1,4))
  1115. # height
  1116. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1117. label = _("Height above surface:")),
  1118. pos = (3, 5), flag = wx.ALIGN_BOTTOM|wx.EXPAND)
  1119. surface = wx.CheckListBox(parent = panel, id = wx.ID_ANY, size = (-1, 60),
  1120. choices = [], style = wx.LB_NEEDED_SB)
  1121. surface.Bind(wx.EVT_CHECKLISTBOX, self.OnVectorSurface)
  1122. self.win['vector']['lines']['surface'] = surface.GetId()
  1123. gridSizer.Add(item = surface,
  1124. pos = (3, 0), span = (3, 5),
  1125. flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
  1126. self._createControl(panel, data = self.win['vector']['lines'], name = 'height', size = -1,
  1127. range = (0, 500), sliderHor = True,
  1128. bind = (self.OnVectorHeight, self.OnVectorHeightFull, self.OnVectorHeightText))
  1129. self.FindWindowById(self.win['vector']['lines']['height']['slider']).SetValue(0)
  1130. self.FindWindowById(self.win['vector']['lines']['height']['text']).SetValue(0)
  1131. gridSizer.Add(item = self.FindWindowById(self.win['vector']['lines']['height']['slider']),
  1132. pos = (4, 5), flag = wx.EXPAND|wx.ALIGN_RIGHT)
  1133. gridSizer.Add(item = self.FindWindowById(self.win['vector']['lines']['height']['text']),
  1134. pos = (5, 5),
  1135. flag = wx.ALIGN_CENTER)
  1136. boxSizer.Add(item = gridSizer, proportion = 1,
  1137. flag = wx.ALL | wx.EXPAND, border = 3)
  1138. pageSizer.Add(item = boxSizer, proportion = 0,
  1139. flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1140. border = 3)
  1141. #
  1142. # vector points
  1143. #
  1144. self.win['vector']['points'] = {}
  1145. showPoints = wx.CheckBox(parent = panel, id = wx.ID_ANY,
  1146. label = _("Show vector points"))
  1147. showPoints.SetValue(True)
  1148. self.win['vector']['points']['show'] = showPoints.GetId()
  1149. showPoints.Bind(wx.EVT_CHECKBOX, self.OnVectorShow)
  1150. pageSizer.Add(item = showPoints, proportion = 0,
  1151. flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 5)
  1152. box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  1153. label = " %s " % (_("Vector points")))
  1154. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1155. vertSizer = wx.BoxSizer(wx.VERTICAL)
  1156. gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  1157. gridSizer.AddGrowableCol(0)
  1158. gridSizer.AddGrowableCol(2)
  1159. gridSizer.AddGrowableCol(4)
  1160. gridSizer.AddGrowableCol(6)
  1161. # icon size
  1162. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1163. label = _("Icon:")),
  1164. pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
  1165. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1166. label = _("size:")),
  1167. pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL |
  1168. wx.ALIGN_RIGHT)
  1169. isize = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
  1170. initial = 1,
  1171. min = 1,
  1172. max = 1e6)
  1173. isize.SetName('value')
  1174. isize.SetValue(100)
  1175. self.win['vector']['points']['size'] = isize.GetId()
  1176. isize.Bind(wx.EVT_SPINCTRL, self.OnVectorPoints)
  1177. isize.Bind(wx.EVT_TEXT, self.OnVectorPoints)
  1178. gridSizer.Add(item = isize, pos = (0, 2),
  1179. flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
  1180. # icon color
  1181. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1182. label = _("color:")),
  1183. pos = (0, 3), flag = wx.ALIGN_CENTER_VERTICAL |
  1184. wx.ALIGN_RIGHT)
  1185. icolor = csel.ColourSelect(panel, id = wx.ID_ANY,
  1186. size = globalvar.DIALOG_COLOR_SIZE)
  1187. icolor.SetName("color")
  1188. icolor.SetColour((0,0,255))
  1189. self.win['vector']['points']['color'] = icolor.GetId()
  1190. icolor.Bind(csel.EVT_COLOURSELECT, self.OnVectorPoints)
  1191. gridSizer.Add(item = icolor, flag = wx.ALIGN_CENTER_VERTICAL |
  1192. wx.ALIGN_LEFT,
  1193. pos = (0, 4))
  1194. # icon width - seems to do nothing
  1195. ## gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1196. ## label = _("width")),
  1197. ## pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL |
  1198. ## wx.ALIGN_RIGHT)
  1199. ##
  1200. ## iwidth = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
  1201. ## initial = 1,
  1202. ## min = 1,
  1203. ## max = 1e6)
  1204. ## iwidth.SetName('value')
  1205. ## iwidth.SetValue(100)
  1206. ## self.win['vector']['points']['width'] = iwidth.GetId()
  1207. ## iwidth.Bind(wx.EVT_SPINCTRL, self.OnVectorPoints)
  1208. ## iwidth.Bind(wx.EVT_TEXT, self.OnVectorPoints)
  1209. ## gridSizer.Add(item = iwidth, pos = (1, 2),
  1210. ## flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
  1211. # icon symbol
  1212. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1213. label = _("symbol:")),
  1214. pos = (0, 5), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
  1215. isym = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
  1216. choices = UserSettings.Get(group = 'nviz', key = 'vector',
  1217. subkey = ['points', 'marker'], internal = True))
  1218. isym.SetName("selection")
  1219. self.win['vector']['points']['marker'] = isym.GetId()
  1220. isym.Bind(wx.EVT_CHOICE, self.OnVectorPoints)
  1221. gridSizer.Add(item = isym, flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
  1222. pos = (0, 6))
  1223. # thematic mapping
  1224. self.win['vector']['points']['thematic'] = {}
  1225. checkThematicColor = wx.CheckBox(parent = panel, id = wx.ID_ANY,
  1226. label = _("use color for thematic mapping"))
  1227. checkThematicSize = wx.CheckBox(parent = panel, id = wx.ID_ANY,
  1228. label = _("use size for thematic mapping"))
  1229. self.win['vector']['points']['thematic']['checkcolor'] = checkThematicColor.GetId()
  1230. self.win['vector']['points']['thematic']['checksize'] = checkThematicSize.GetId()
  1231. checkThematicColor.Bind(wx.EVT_CHECKBOX, self.OnCheckThematic)
  1232. checkThematicSize.Bind(wx.EVT_CHECKBOX, self.OnCheckThematic)
  1233. checkThematicColor.SetValue(False)
  1234. checkThematicSize.SetValue(False)
  1235. gridSizer.Add(item = checkThematicColor, flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
  1236. pos = (1, 1), span = (1, 5))
  1237. setThematic = wx.Button(parent = panel, id = wx.ID_ANY,
  1238. label = _("Set options..."))
  1239. self.win['vector']['points']['thematic']['buttoncolor'] = setThematic.GetId()
  1240. setThematic.Bind(wx.EVT_BUTTON, self.OnSetThematic)
  1241. gridSizer.Add(item = setThematic, flag = wx.ALIGN_CENTER_VERTICAL,
  1242. pos = (1, 6))
  1243. gridSizer.Add(item = checkThematicSize, flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
  1244. pos = (2, 1), span = (1, 5))
  1245. setThematic = wx.Button(parent = panel, id = wx.ID_ANY,
  1246. label = _("Set options..."))
  1247. self.win['vector']['points']['thematic']['buttonsize'] = setThematic.GetId()
  1248. setThematic.Bind(wx.EVT_BUTTON, self.OnSetThematic)
  1249. gridSizer.Add(item = setThematic, flag = wx.ALIGN_CENTER_VERTICAL,
  1250. pos = (2, 6))
  1251. vertSizer.Add(gridSizer, proportion = 0, flag = wx.EXPAND, border = 0)
  1252. # high
  1253. gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  1254. gridSizer.AddGrowableCol(1)
  1255. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1256. label = _("Display on surface(s):")),
  1257. pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
  1258. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1259. label = _("Height above surface:")),
  1260. pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL)
  1261. surface = wx.CheckListBox(parent = panel, id = wx.ID_ANY, size = (-1, 60),
  1262. choices = [], style = wx.LB_NEEDED_SB)
  1263. surface.Bind(wx.EVT_CHECKLISTBOX, self.OnVectorSurface)
  1264. self.win['vector']['points']['surface'] = surface.GetId()
  1265. gridSizer.Add(item = surface,
  1266. pos = (1, 0), span = (3, 1),
  1267. flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
  1268. self._createControl(panel, data = self.win['vector']['points'], name = 'height', size = -1,
  1269. range = (0, 500),
  1270. bind = (self.OnVectorHeight, self.OnVectorHeightFull, self.OnVectorHeightText))
  1271. self.FindWindowById(self.win['vector']['points']['height']['slider']).SetValue(0)
  1272. self.FindWindowById(self.win['vector']['points']['height']['text']).SetValue(0)
  1273. gridSizer.Add(item = self.FindWindowById(self.win['vector']['points']['height']['slider']),
  1274. pos = (2, 1),flag = wx.EXPAND|wx.ALIGN_CENTER_VERTICAL)
  1275. gridSizer.Add(item = self.FindWindowById(self.win['vector']['points']['height']['text']),
  1276. pos = (3, 1),
  1277. flag = wx.ALIGN_CENTER)
  1278. vertSizer.Add(gridSizer, proportion = 0, flag = wx.EXPAND, border = 0)
  1279. boxSizer.Add(item = vertSizer, proportion = 1,
  1280. flag = wx.ALL | wx.EXPAND, border = 3)
  1281. pageSizer.Add(item = boxSizer, proportion = 0,
  1282. flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1283. border = 3)
  1284. panel.SetSizer(pageSizer)
  1285. panel.Fit()
  1286. return panel
  1287. def GselectOnPopup(self, ltype, exclude = False):
  1288. """Update gselect.Select() items"""
  1289. maps = list()
  1290. for layer in self.mapWindow.Map.GetListOfLayers(l_type = ltype, l_active = True):
  1291. maps.append(layer.GetName())
  1292. return maps, exclude
  1293. def _createVolumePage(self, parent):
  1294. """!Create view settings page"""
  1295. panel = wx.Panel(parent = parent, id = wx.ID_ANY)
  1296. self.page['volume'] = { 'id' : 3,
  1297. 'notebook' : self.foldpanelData.GetId() }
  1298. pageSizer = wx.BoxSizer(wx.VERTICAL)
  1299. self.win['volume'] = {}
  1300. # selection
  1301. box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  1302. label = " %s " % (_("3D raster map")))
  1303. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1304. rmaps = Select(parent = panel, type = '3d-raster',
  1305. onPopup = self.GselectOnPopup)
  1306. rmaps.GetChildren()[0].Bind(wx.EVT_TEXT, self.OnSetRaster3D)
  1307. self.win['volume']['map'] = rmaps.GetId()
  1308. desc = wx.StaticText(parent = panel, id = wx.ID_ANY)
  1309. self.win['volume']['desc'] = desc.GetId()
  1310. boxSizer.Add(item = rmaps, proportion = 0,
  1311. flag = wx.ALL,
  1312. border = 3)
  1313. boxSizer.Add(item = desc, proportion = 0,
  1314. flag = wx.ALL,
  1315. border = 3)
  1316. pageSizer.Add(item = boxSizer, proportion = 0,
  1317. flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1318. border = 3)
  1319. #
  1320. # draw
  1321. #
  1322. self.win['volume']['draw'] = {}
  1323. box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  1324. label = " %s " % (_("Draw")))
  1325. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1326. gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  1327. ## gridSizer.AddGrowableCol(4)
  1328. # mode
  1329. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1330. label = _("Mode:")),
  1331. pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
  1332. mode = wx.Choice (parent = panel, id = wx.ID_ANY, size = (-1, -1),
  1333. choices = [_("isosurfaces"),
  1334. _("slices")])
  1335. mode.SetSelection(0)
  1336. mode.SetName("selection")
  1337. mode.Bind(wx.EVT_CHOICE, self.OnVolumeMode)
  1338. self.win['volume']['draw']['mode'] = mode.GetId()
  1339. gridSizer.Add(item = mode, flag = wx.ALIGN_CENTER_VERTICAL,
  1340. pos = (0, 1))
  1341. # shading
  1342. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1343. label = _("Shading:")),
  1344. pos = (0, 2), flag = wx.ALIGN_CENTER_VERTICAL)
  1345. shade = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
  1346. choices = [_("flat"),
  1347. _("gouraud")])
  1348. shade.SetName("selection")
  1349. self.win['volume']['draw']['shading'] = shade.GetId()
  1350. shade.Bind(wx.EVT_CHOICE, self.OnVolumeDrawMode)
  1351. gridSizer.Add(item = shade, flag = wx.ALIGN_CENTER_VERTICAL,
  1352. pos = (0, 3))
  1353. # resolution (mode)
  1354. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1355. label = _("Resolution:")),
  1356. pos = (0, 4), flag = wx.ALIGN_CENTER_VERTICAL)
  1357. resol = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
  1358. initial = 1,
  1359. min = 1,
  1360. max = 100)
  1361. resol.SetName("value")
  1362. self.win['volume']['draw']['resolution'] = resol.GetId()
  1363. resol.Bind(wx.EVT_SPINCTRL, self.OnVolumeResolution)
  1364. resol.Bind(wx.EVT_TEXT, self.OnVolumeResolution)
  1365. gridSizer.Add(item = resol, pos = (0, 5))
  1366. # draw wire box
  1367. box = wx.CheckBox(parent = panel, id = wx.ID_ANY,
  1368. label = _("Draw wire box"))
  1369. box.SetName("value")
  1370. self.win['volume']['draw']['box'] = box.GetId()
  1371. box.Bind(wx.EVT_CHECKBOX, self.OnVolumeDrawBox)
  1372. gridSizer.Add(item = box, pos = (1, 0), span = (1, 6))
  1373. boxSizer.Add(item = gridSizer, proportion = 0,
  1374. flag = wx.ALL | wx.EXPAND, border = 3)
  1375. pageSizer.Add(item = boxSizer, proportion = 0,
  1376. flag = wx.EXPAND | wx.ALL,
  1377. border = 3)
  1378. #
  1379. # manage isosurfaces
  1380. #
  1381. box = wx.StaticBox(parent = panel, id = wx.ID_ANY,
  1382. label = " %s " % (_("List of isosurfaces")))
  1383. box.SetName('listStaticBox')
  1384. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1385. gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
  1386. # list
  1387. isolevel = wx.CheckListBox(parent = panel, id = wx.ID_ANY,
  1388. size = (300, 150))
  1389. self.Bind(wx.EVT_CHECKLISTBOX, self.OnVolumeCheck, isolevel)
  1390. self.Bind(wx.EVT_LISTBOX, self.OnVolumeSelect, isolevel)
  1391. self.win['volume']['isosurfs'] = isolevel.GetId()
  1392. self.win['volume']['slices'] = isolevel.GetId()
  1393. gridSizer.Add(item = isolevel, pos = (0, 0), span = (4, 1))
  1394. # buttons (add, delete, move up, move down)
  1395. btnAdd = wx.Button(parent = panel, id = wx.ID_ADD)
  1396. self.win['volume']['btnAdd'] = btnAdd.GetId()
  1397. btnAdd.Bind(wx.EVT_BUTTON, self.OnVolumeAdd)
  1398. gridSizer.Add(item = btnAdd,
  1399. pos = (0, 1))
  1400. btnDelete = wx.Button(parent = panel, id = wx.ID_DELETE)
  1401. self.win['volume']['btnDelete'] = btnDelete.GetId()
  1402. btnDelete.Bind(wx.EVT_BUTTON, self.OnVolumeDelete)
  1403. btnDelete.Enable(False)
  1404. gridSizer.Add(item = btnDelete,
  1405. pos = (1, 1))
  1406. btnMoveUp = wx.Button(parent = panel, id = wx.ID_UP)
  1407. self.win['volume']['btnMoveUp'] = btnMoveUp.GetId()
  1408. btnMoveUp.Bind(wx.EVT_BUTTON, self.OnVolumeMoveUp)
  1409. btnMoveUp.Enable(False)
  1410. gridSizer.Add(item = btnMoveUp,
  1411. pos = (2, 1))
  1412. btnMoveDown = wx.Button(parent = panel, id = wx.ID_DOWN)
  1413. self.win['volume']['btnMoveDown'] = btnMoveDown.GetId()
  1414. btnMoveDown.Bind(wx.EVT_BUTTON, self.OnVolumeMoveDown)
  1415. btnMoveDown.Enable(False)
  1416. gridSizer.Add(item = btnMoveDown,
  1417. pos = (3, 1))
  1418. boxSizer.Add(item = gridSizer, proportion = 1,
  1419. flag = wx.ALL | wx.EXPAND, border = 3)
  1420. pageSizer.Add(item = boxSizer, proportion = 0,
  1421. flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1422. border = 3)
  1423. # isosurface/slice
  1424. sizer = wx.BoxSizer()
  1425. self.isoPanel = self._createIsosurfacePanel(panel)
  1426. self.slicePanel = self._createSlicePanel(panel)
  1427. sizer.Add(self.isoPanel, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 0)
  1428. sizer.Add(self.slicePanel, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 0)
  1429. sizer.Hide(self.slicePanel)
  1430. pageSizer.Add(item = sizer, proportion = 0,
  1431. flag = wx.EXPAND | wx.ALL,
  1432. border = 3)
  1433. #
  1434. # position
  1435. #
  1436. self.win['volume']['position'] = {}
  1437. box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  1438. label = " %s " % (_("Position")))
  1439. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1440. gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
  1441. gridSizer.AddGrowableCol(3)
  1442. # position
  1443. self._createControl(panel, data = self.win['volume'], name = 'position',
  1444. range = (-10000, 10000), floatSlider = True,
  1445. bind = (self.OnVolumePosition, self.OnVolumePositionChanged, self.OnVolumePositionText))
  1446. axis = wx.Choice (parent = panel, id = wx.ID_ANY, size = (75, -1),
  1447. choices = ["X",
  1448. "Y",
  1449. "Z"])
  1450. reset = wx.Button(panel, id = wx.ID_ANY, label = _("Reset"))
  1451. reset.SetToolTipString(_("Reset to default position"))
  1452. reset.Bind(wx.EVT_BUTTON, self.OnResetVolumePosition)
  1453. self.win['volume']['position']['reset'] = reset.GetId()
  1454. self.win['volume']['position']['axis'] = axis.GetId()
  1455. axis.SetSelection(0)
  1456. axis.Bind(wx.EVT_CHOICE, self.OnVolumeAxis)
  1457. pslide = self.FindWindowById(self.win['volume']['position']['slider'])
  1458. ptext = self.FindWindowById(self.win['volume']['position']['text'])
  1459. ptext.SetValue('0')
  1460. gridSizer.Add(item = axis, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 0))
  1461. gridSizer.Add(item = pslide, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 1))
  1462. gridSizer.Add(item = ptext, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 2))
  1463. gridSizer.Add(item = reset, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, pos = (0, 3))
  1464. boxSizer.Add(item = gridSizer, proportion = 1,
  1465. flag = wx.ALL | wx.EXPAND, border = 3)
  1466. pageSizer.Add(item = boxSizer, proportion = 0,
  1467. flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1468. border = 3)
  1469. panel.SetSizer(pageSizer)
  1470. panel.Fit()
  1471. return panel
  1472. def _createLightPage(self, parent):
  1473. """!Create light page"""
  1474. panel = wx.Panel(parent = parent, id = wx.ID_ANY)
  1475. self.page['light'] = { 'id' : 0,
  1476. 'notebook' : self.foldpanelAppear.GetId() }
  1477. self.win['light'] = {}
  1478. pageSizer = wx.BoxSizer(wx.VERTICAL)
  1479. show = wx.CheckBox(parent = panel, id = wx.ID_ANY,
  1480. label = _("Show light model"))
  1481. show.Bind(wx.EVT_CHECKBOX, self.OnShowLightModel)
  1482. show.SetValue(True)
  1483. self._display.showLight = True
  1484. pageSizer.Add(item = show, proportion = 0,
  1485. flag = wx.ALL, border = 3)
  1486. ## surface = wx.CheckBox(parent = panel, id = wx.ID_ANY,
  1487. ## label = _("Follow source viewpoint"))
  1488. ## pageSizer.Add(item = surface, proportion = 0,
  1489. ## flag = wx.ALL, border = 3)
  1490. # position
  1491. box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  1492. label = " %s " % (_("Light source position")))
  1493. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1494. gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
  1495. posSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
  1496. self._createCompass(panel = panel, sizer = posSizer, type = 'light')
  1497. pos = LightPositionWindow(panel, id = wx.ID_ANY, size = (175, 175),
  1498. mapwindow = self.mapWindow)
  1499. self.win['light']['position'] = pos.GetId()
  1500. posSizer.Add(item = pos,
  1501. pos = (1, 1), flag = wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL)
  1502. gridSizer.Add(item = posSizer, pos = (0, 0))
  1503. # height
  1504. tooltip = _("Adjusts the light height")
  1505. self._createControl(panel, data = self.win['light'], name = 'z', sliderHor = False,
  1506. range = (0, 100), tooltip = tooltip,
  1507. bind = (self.OnLightChange, self.OnLightChanged, self.OnLightChange))
  1508. heightSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
  1509. heightSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Height:")),
  1510. pos = (0, 0), flag = wx.ALIGN_LEFT, span = (1, 2))
  1511. heightSizer.Add(item = self.FindWindowById(self.win['light']['z']['slider']),
  1512. flag = wx.ALIGN_RIGHT, pos = (1, 0))
  1513. heightSizer.Add(item = self.FindWindowById(self.win['light']['z']['text']),
  1514. flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.TOP |
  1515. wx.BOTTOM | wx.RIGHT, pos = (1, 1))
  1516. gridSizer.Add(item = heightSizer, pos = (0, 2), flag = wx.ALIGN_RIGHT)
  1517. boxSizer.Add(item = gridSizer, proportion = 1,
  1518. flag = wx.ALL | wx.EXPAND, border = 2)
  1519. pageSizer.Add(item = boxSizer, proportion = 0,
  1520. flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1521. border = 3)
  1522. # position
  1523. box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  1524. label = " %s " % (_("Light color and intensity")))
  1525. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1526. gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
  1527. gridSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Color:")),
  1528. pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
  1529. color = csel.ColourSelect(panel, id = wx.ID_ANY,
  1530. colour = UserSettings.Get(group = 'nviz', key = 'light',
  1531. subkey = 'color'),
  1532. size = globalvar.DIALOG_COLOR_SIZE)
  1533. self.win['light']['color'] = color.GetId()
  1534. color.Bind(csel.EVT_COLOURSELECT, self.OnLightColor)
  1535. gridSizer.Add(item = color, pos = (0, 2))
  1536. gridSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Brightness:")),
  1537. pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL)
  1538. tooltip = _("Adjusts the brightness of the light")
  1539. self._createControl(panel, data = self.win['light'], name = 'bright', size = 300,
  1540. range = (0, 100), tooltip = tooltip,
  1541. bind = (self.OnLightValue, self.OnLightChanged, self.OnLightValue))
  1542. gridSizer.Add(item = self.FindWindowById(self.win['light']['bright']['slider']),
  1543. pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL)
  1544. gridSizer.Add(item = self.FindWindowById(self.win['light']['bright']['text']),
  1545. pos = (1, 2),
  1546. flag = wx.ALIGN_CENTER)
  1547. gridSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Ambient:")),
  1548. pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL)
  1549. tooltip = _("Adjusts the ambient light")
  1550. self._createControl(panel, data = self.win['light'], name = 'ambient', size = 300,
  1551. range = (0, 100), tooltip = tooltip,
  1552. bind = (self.OnLightValue, self.OnLightChanged, self.OnLightValue))
  1553. gridSizer.Add(item = self.FindWindowById(self.win['light']['ambient']['slider']),
  1554. pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL)
  1555. gridSizer.Add(item = self.FindWindowById(self.win['light']['ambient']['text']),
  1556. pos = (2, 2),
  1557. flag = wx.ALIGN_CENTER)
  1558. boxSizer.Add(item = gridSizer, proportion = 1,
  1559. flag = wx.ALL | wx.EXPAND, border = 2)
  1560. pageSizer.Add(item = boxSizer, proportion = 0,
  1561. flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1562. border = 3)
  1563. # reset = wx.Button(panel, id = wx.ID_ANY, label = _("Reset"))
  1564. # reset.SetToolTipString(_("Reset to default view"))
  1565. # # self.win['reset'] = reset.GetId()
  1566. # reset.Bind(wx.EVT_BUTTON, self.OnResetView)
  1567. # viewSizer.Add(item = reset, proportion = 1,
  1568. # flag = wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT,
  1569. # border = 5)
  1570. # gridSizer.AddGrowableCol(3)
  1571. # gridSizer.Add(item = viewSizer, pos = (4, 0), span = (1, 2),
  1572. # flag = wx.EXPAND)
  1573. panel.SetSizer(pageSizer)
  1574. panel.Layout()
  1575. panel.Fit()
  1576. return panel
  1577. def _createFringePage(self, parent):
  1578. """!Create fringe page"""
  1579. panel = wx.Panel(parent = parent, id = wx.ID_ANY)
  1580. self.page['fringe'] = { 'id' : 1,
  1581. 'notebook' : self.foldpanelAppear.GetId() }
  1582. self.win['fringe'] = {}
  1583. pageSizer = wx.BoxSizer(wx.VERTICAL)
  1584. # selection
  1585. rbox = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  1586. label = " %s " % (_("Surface")))
  1587. rboxSizer = wx.StaticBoxSizer(rbox, wx.VERTICAL)
  1588. rmaps = Select(parent = panel, type = 'raster',
  1589. onPopup = self.GselectOnPopup)
  1590. rmaps.GetChildren()[0].Bind(wx.EVT_TEXT, self.OnSetSurface)
  1591. self.win['fringe']['map'] = rmaps.GetId()
  1592. rboxSizer.Add(item = rmaps, proportion = 0,
  1593. flag = wx.ALL,
  1594. border = 3)
  1595. pageSizer.Add(item = rboxSizer, proportion = 0,
  1596. flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1597. border = 3)
  1598. ebox = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  1599. label = " %s " % (_("Edges with fringe")))
  1600. eboxSizer = wx.StaticBoxSizer(ebox, wx.HORIZONTAL)
  1601. for edge in [(_("N && W"), "nw"),
  1602. (_("N && E"), "ne"),
  1603. (_("S && W"), "sw"),
  1604. (_("S && E"), "se")]:
  1605. chkbox = wx.CheckBox(parent = panel,
  1606. label = edge[0],
  1607. name = edge[1])
  1608. self.win['fringe'][edge[1]] = chkbox.GetId()
  1609. eboxSizer.Add(item = chkbox, proportion = 0,
  1610. flag = wx.ADJUST_MINSIZE | wx.LEFT | wx.RIGHT, border = 5)
  1611. chkbox.Bind(wx.EVT_CHECKBOX, self.OnFringe)
  1612. pageSizer.Add(item = eboxSizer, proportion = 0,
  1613. flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1614. border = 3)
  1615. sbox = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  1616. label = " %s " % (_("Settings")))
  1617. sboxSizer = wx.StaticBoxSizer(sbox, wx.HORIZONTAL)
  1618. gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  1619. # elevation
  1620. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1621. label = _("Elevation of fringe from bottom:")),
  1622. pos = (0, 0),
  1623. flag = wx.ALIGN_CENTER_VERTICAL)
  1624. spin = wx.SpinCtrl(parent = panel, id = wx.ID_ANY,
  1625. size = (65, -1), min = -1e6, max = 1e6)
  1626. spin.SetValue(UserSettings.Get(group = 'nviz', key = 'fringe', subkey = 'elev'))
  1627. spin.Bind(wx.EVT_SPINCTRL, self.OnFringe)
  1628. self.win['fringe']['elev'] = spin.GetId()
  1629. gridSizer.Add(item = spin, pos = (0, 1))
  1630. # color
  1631. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1632. label = _("Color:")),
  1633. pos = (1, 0),
  1634. flag = wx.ALIGN_CENTER_VERTICAL)
  1635. color = csel.ColourSelect(parent = panel, id = wx.ID_ANY,
  1636. size = globalvar.DIALOG_COLOR_SIZE)
  1637. color.SetColour(UserSettings.Get(group = 'nviz', key = 'fringe',
  1638. subkey = 'color'))
  1639. color.Bind(csel.EVT_COLOURSELECT, self.OnFringe)
  1640. self.win['fringe']['color'] = color.GetId()
  1641. gridSizer.Add(item = color, pos = (1, 1))
  1642. sboxSizer.Add(item = gridSizer, proportion = 1,
  1643. flag = wx.ALL | wx.EXPAND, border = 3)
  1644. pageSizer.Add(item = sboxSizer, proportion = 0,
  1645. flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1646. border = 3)
  1647. panel.SetSizer(pageSizer)
  1648. panel.Layout()
  1649. panel.Fit()
  1650. return panel
  1651. def _createDecorationPage(self, parent):
  1652. """!Create decoration (north arrow, scalebar, legend) page"""
  1653. panel = wx.Panel(parent = parent, id = wx.ID_ANY)
  1654. self.page['decoration'] = { 'id' : 2,
  1655. 'notebook' : self.foldpanelAppear.GetId()}
  1656. self.win['decoration'] = {}
  1657. pageSizer = wx.BoxSizer(wx.VERTICAL)
  1658. # north arrow
  1659. self.win['decoration']['arrow'] = {}
  1660. nabox = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  1661. label = " %s " % (_("North Arrow")))
  1662. naboxSizer = wx.StaticBoxSizer(nabox, wx.VERTICAL)
  1663. gridSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
  1664. # size
  1665. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1666. label = _("Arrow length (in map units):")),
  1667. pos = (0,0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL)
  1668. sizeCtrl = NumTextCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1), style = wx.TE_PROCESS_ENTER)
  1669. gridSizer.Add(sizeCtrl, pos = (0, 2))
  1670. self.win['decoration']['arrow']['size'] = sizeCtrl.GetId()
  1671. sizeCtrl.Bind(wx.EVT_TEXT_ENTER, self.OnDecorationProp)
  1672. sizeCtrl.Bind(wx.EVT_KILL_FOCUS, self.OnDecorationProp)
  1673. # color
  1674. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1675. label = _("Arrow color:")),
  1676. pos = (1,0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL)
  1677. color = csel.ColourSelect(parent = panel, id = wx.ID_ANY,
  1678. size = globalvar.DIALOG_COLOR_SIZE)
  1679. gridSizer.Add(color, pos = (1, 2))
  1680. self.win['decoration']['arrow']['color'] = color.GetId()
  1681. color.Bind(csel.EVT_COLOURSELECT, self.OnDecorationProp)
  1682. # control
  1683. toggle = wx.ToggleButton(parent = panel, id = wx.ID_ANY, label = _("Place arrow"))
  1684. gridSizer.Add(item = toggle, pos = (2, 0))
  1685. toggle.Bind(wx.EVT_TOGGLEBUTTON, self.OnDecorationPlacement)
  1686. self.win['decoration']['arrow']['place'] = toggle.GetId()
  1687. toggle.SetName('placeArrow')
  1688. delete = wx.Button(parent = panel, id = wx.ID_ANY, label = _("Delete"))
  1689. self.win['decoration']['arrow']['delete'] = delete.GetId()
  1690. gridSizer.Add(item = delete, pos = (2, 1))
  1691. delete.Bind(wx.EVT_BUTTON, self.OnArrowDelete)
  1692. shown = self.mapWindow.decoration['arrow']['show']
  1693. delete.Enable(shown)
  1694. naboxSizer.Add(item = gridSizer, proportion = 0, flag = wx.EXPAND, border = 3)
  1695. pageSizer.Add(item = naboxSizer, proportion = 0,
  1696. flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1697. border = 3)
  1698. # scale bars
  1699. self.win['decoration']['scalebar'] = {}
  1700. nabox = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  1701. label = " %s " % (_("Scale bar")))
  1702. naboxSizer = wx.StaticBoxSizer(nabox, wx.VERTICAL)
  1703. gridSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
  1704. # size
  1705. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1706. label = _("Scale bar length (in map units):")),
  1707. pos = (0,0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL)
  1708. sizeCtrl = NumTextCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1), style = wx.TE_PROCESS_ENTER)
  1709. gridSizer.Add(sizeCtrl, pos = (0, 2))
  1710. self.win['decoration']['scalebar']['size'] = sizeCtrl.GetId()
  1711. sizeCtrl.Bind(wx.EVT_TEXT_ENTER, self.OnDecorationProp)
  1712. sizeCtrl.Bind(wx.EVT_KILL_FOCUS, self.OnDecorationProp)
  1713. # color
  1714. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  1715. label = _("Scale bar color:")),
  1716. pos = (1,0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL)
  1717. color = csel.ColourSelect(parent = panel, id = wx.ID_ANY,
  1718. size = globalvar.DIALOG_COLOR_SIZE)
  1719. gridSizer.Add(color, pos = (1, 2))
  1720. self.win['decoration']['scalebar']['color'] = color.GetId()
  1721. color.Bind(csel.EVT_COLOURSELECT, self.OnDecorationProp)
  1722. # control
  1723. toggle = wx.ToggleButton(parent = panel, id = wx.ID_ANY, label = _("Place new scale bar"))
  1724. gridSizer.Add(item = toggle, pos = (2, 0))
  1725. toggle.Bind(wx.EVT_TOGGLEBUTTON, self.OnDecorationPlacement)
  1726. self.win['decoration']['scalebar']['place'] = toggle.GetId()
  1727. toggle.SetName('placeScalebar')
  1728. scalebarChoice = wx.Choice(parent = panel, id = wx.ID_ANY, choices = [])
  1729. self.win['decoration']['scalebar']['choice'] = scalebarChoice.GetId()
  1730. gridSizer.Add(item = scalebarChoice, pos = (3, 0), flag = wx.EXPAND)
  1731. delete = wx.Button(parent = panel, id = wx.ID_ANY, label = _("Delete"))
  1732. self.win['decoration']['scalebar']['delete'] = delete.GetId()
  1733. gridSizer.Add(item = delete, pos = (3, 1))
  1734. delete.Bind(wx.EVT_BUTTON, self.OnScalebarDelete)
  1735. naboxSizer.Add(item = gridSizer, proportion = 0, flag = wx.EXPAND, border = 3)
  1736. pageSizer.Add(item = naboxSizer, proportion = 0,
  1737. flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1738. border = 3)
  1739. self.DisableScalebarControls()
  1740. panel.SetSizer(pageSizer)
  1741. panel.Layout()
  1742. panel.Fit()
  1743. return panel
  1744. def GetLayerData(self, nvizType, nameOnly = False):
  1745. """!Get nviz data"""
  1746. name = self.FindWindowById(self.win[nvizType]['map']).GetValue()
  1747. if nameOnly:
  1748. return name
  1749. if nvizType == 'surface' or nvizType == 'fringe':
  1750. return self.mapWindow.GetLayerByName(name, mapType = 'raster', dataType = 'nviz')
  1751. elif nvizType == 'vector':
  1752. return self.mapWindow.GetLayerByName(name, mapType = 'vector', dataType = 'nviz')
  1753. elif nvizType == 'volume':
  1754. return self.mapWindow.GetLayerByName(name, mapType = '3d-raster', dataType = 'nviz')
  1755. return None
  1756. def OnRecord(self, event):
  1757. """!Animation: start recording"""
  1758. anim = self.mapWindow.GetAnimation()
  1759. if not anim.IsPaused():
  1760. if anim.Exists() and not anim.IsSaved():
  1761. msg = _("Do you want to record new animation without saving the previous one?")
  1762. dlg = wx.MessageDialog(parent = self,
  1763. message = msg,
  1764. caption =_("Animation already axists"),
  1765. style = wx.YES_NO | wx.CENTRE)
  1766. if dlg.ShowModal() == wx.ID_NO:
  1767. dlg.Destroy()
  1768. return
  1769. anim.Clear()
  1770. self.UpdateFrameIndex(0)
  1771. self.UpdateFrameCount()
  1772. anim.SetPause(False)
  1773. anim.SetMode(mode = 'record')
  1774. anim.Start()
  1775. self.FindWindowById(self.win['anim']['play']).Disable()
  1776. self.FindWindowById(self.win['anim']['record']).Disable()
  1777. self.FindWindowById(self.win['anim']['pause']).Enable()
  1778. self.FindWindowById(self.win['anim']['stop']).Enable()
  1779. self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
  1780. self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
  1781. def OnPlay(self, event):
  1782. """!Animation: replay"""
  1783. anim = self.mapWindow.GetAnimation()
  1784. anim.SetPause(False)
  1785. anim.SetMode(mode = 'play')
  1786. anim.Start()
  1787. self.FindWindowById(self.win['anim']['play']).Disable()
  1788. self.FindWindowById(self.win['anim']['record']).Disable()
  1789. self.FindWindowById(self.win['anim']['pause']).Enable()
  1790. self.FindWindowById(self.win['anim']['stop']).Enable()
  1791. self.FindWindowById(self.win['anim']['frameIndex']['slider']).Enable()
  1792. self.FindWindowById(self.win['anim']['frameIndex']['text']).Enable()
  1793. def OnStop(self, event):
  1794. """!Animation: stop recording/replaying"""
  1795. anim = self.mapWindow.GetAnimation()
  1796. anim.SetPause(False)
  1797. if anim.GetMode() == 'save':
  1798. anim.StopSaving()
  1799. if anim.IsRunning():
  1800. anim.Stop()
  1801. self.UpdateFrameIndex(0)
  1802. self.FindWindowById(self.win['anim']['play']).Enable()
  1803. self.FindWindowById(self.win['anim']['record']).Enable()
  1804. self.FindWindowById(self.win['anim']['pause']).Disable()
  1805. self.FindWindowById(self.win['anim']['stop']).Disable()
  1806. self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
  1807. self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
  1808. def OnPause(self, event):
  1809. """!Pause animation"""
  1810. anim = self.mapWindow.GetAnimation()
  1811. anim.SetPause(True)
  1812. mode = anim.GetMode()
  1813. if anim.IsRunning():
  1814. anim.Pause()
  1815. if mode == "record":
  1816. self.FindWindowById(self.win['anim']['play']).Disable()
  1817. self.FindWindowById(self.win['anim']['record']).Enable()
  1818. self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
  1819. self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
  1820. elif mode == 'play':
  1821. self.FindWindowById(self.win['anim']['record']).Disable()
  1822. self.FindWindowById(self.win['anim']['play']).Enable()
  1823. self.FindWindowById(self.win['anim']['frameIndex']['slider']).Enable()
  1824. self.FindWindowById(self.win['anim']['frameIndex']['text']).Enable()
  1825. self.FindWindowById(self.win['anim']['pause']).Disable()
  1826. self.FindWindowById(self.win['anim']['stop']).Enable()
  1827. def OnFrameIndex(self, event):
  1828. """!Frame index changed (by slider)"""
  1829. index = event.GetInt()
  1830. self.UpdateFrameIndex(index = index, sliderWidget = False)
  1831. def OnFrameIndexText(self, event):
  1832. """!Frame index changed by (textCtrl)"""
  1833. index = event.GetValue()
  1834. self.UpdateFrameIndex(index = index, textWidget = False)
  1835. def OnFPS(self, event):
  1836. """!Frames per second changed"""
  1837. anim = self.mapWindow.GetAnimation()
  1838. anim.SetFPS(event.GetInt())
  1839. def UpdateFrameIndex(self, index, sliderWidget = True, textWidget = True, goToFrame = True):
  1840. """!Update frame index"""
  1841. anim = self.mapWindow.GetAnimation()
  1842. # check index
  1843. frameCount = anim.GetFrameCount()
  1844. if index >= frameCount:
  1845. index = frameCount - 1
  1846. if index < 0:
  1847. index = 0
  1848. if sliderWidget:
  1849. slider = self.FindWindowById(self.win['anim']['frameIndex']['slider'])
  1850. slider.SetValue(index)
  1851. if textWidget:
  1852. text = self.FindWindowById(self.win['anim']['frameIndex']['text'])
  1853. text.SetValue(int(index))
  1854. # if called from tool window, update frame
  1855. if goToFrame:
  1856. anim.GoToFrame(int(index))
  1857. def UpdateFrameCount(self):
  1858. """!Update frame count label"""
  1859. anim = self.mapWindow.GetAnimation()
  1860. count = anim.GetFrameCount()
  1861. self.FindWindowById(self.win['anim']['info']).SetLabel(str(count))
  1862. def OnAnimationFinished(self, event):
  1863. """!Animation finished"""
  1864. anim = self.mapWindow.GetAnimation()
  1865. self.UpdateFrameIndex(index = 0)
  1866. slider = self.FindWindowById(self.win['anim']['frameIndex']['slider'])
  1867. text = self.FindWindowById(self.win['anim']['frameIndex']['text'])
  1868. if event.mode == 'record':
  1869. count = anim.GetFrameCount()
  1870. slider.SetMax(count)
  1871. self.UpdateFrameCount()
  1872. self.FindWindowById(self.win['anim']['pause']).Disable()
  1873. self.FindWindowById(self.win['anim']['stop']).Disable()
  1874. self.FindWindowById(self.win['anim']['record']).Enable()
  1875. self.FindWindowById(self.win['anim']['play']).Enable()
  1876. self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
  1877. self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
  1878. self.FindWindowById(self.win['anim']['save']['image']['confirm']).Enable()
  1879. self.mapWindow.render['quick'] = False
  1880. self.mapWindow.Refresh(False)
  1881. def OnAnimationUpdateIndex(self, event):
  1882. """!Animation: frame index changed"""
  1883. if event.mode == 'record':
  1884. self.UpdateFrameCount()
  1885. elif event.mode == 'play':
  1886. self.UpdateFrameIndex(index = event.index, goToFrame = False)
  1887. def OnSaveAnimation(self, event):
  1888. """!Save animation as a sequence of images"""
  1889. anim = self.mapWindow.GetAnimation()
  1890. prefix = self.FindWindowById(self.win['anim']['save']['image']['prefix']).GetValue()
  1891. format = self.FindWindowById(self.win['anim']['save']['image']['format']).GetSelection()
  1892. dir = self.FindWindowById(self.win['anim']['save']['image']['dir']).GetValue()
  1893. if not prefix:
  1894. GMessage(parent = self,
  1895. message = _("No file prefix given."))
  1896. return
  1897. elif not os.path.exists(dir):
  1898. GMessage(parent = self,
  1899. message = _("Directory %s does not exist.") % dir)
  1900. return
  1901. self.FindWindowById(self.win['anim']['pause']).Disable()
  1902. self.FindWindowById(self.win['anim']['stop']).Enable()
  1903. self.FindWindowById(self.win['anim']['record']).Disable()
  1904. self.FindWindowById(self.win['anim']['play']).Disable()
  1905. self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
  1906. self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
  1907. self.FindWindowById(self.win['anim']['save']['image']['confirm']).Disable()
  1908. anim.SaveAnimationFile(path = dir, prefix = prefix, format = format)
  1909. def OnNewConstant(self, event):
  1910. """!Create new surface with constant value"""
  1911. #TODO settings
  1912. name = self.mapWindow.NewConstant()
  1913. win = self.FindWindowById(self.win['constant']['surface'])
  1914. name = _("constant#") + str(name)
  1915. win.Append(name)
  1916. win.SetStringSelection(name)
  1917. self.OnConstantSelection(None)
  1918. self.EnablePage(name = 'constant', enabled = True)
  1919. self.mapWindow.Refresh(eraseBackground = False)
  1920. # need to update list of surfaces in vector page
  1921. for vtype in ('points', 'lines'):
  1922. checklist = self.FindWindowById(self.win['vector'][vtype]['surface'])
  1923. checklist.Append(name)
  1924. win = self.FindWindowById(self.win['vector']['map'])
  1925. win.SetValue(win.GetValue())
  1926. def OnDeleteConstant(self, event):
  1927. """!Delete selected constant surface"""
  1928. layerIdx = self.FindWindowById(self.win['constant']['surface']).GetSelection()
  1929. if layerIdx == wx.NOT_FOUND:
  1930. return
  1931. name = self.FindWindowById(self.win['constant']['surface']).GetStringSelection()
  1932. self.mapWindow.DeleteConstant(layerIdx)
  1933. win = self.FindWindowById(self.win['constant']['surface'])
  1934. win.Delete(layerIdx)
  1935. if win.IsEmpty():
  1936. win.SetValue("")
  1937. self.EnablePage(name = 'constant', enabled = False)
  1938. else:
  1939. win.SetSelection(0)
  1940. self.OnConstantSelection(None)
  1941. # need to update list of surfaces in vector page
  1942. for vtype in ('points', 'lines'):
  1943. checklist = self.FindWindowById(self.win['vector'][vtype]['surface'])
  1944. checklist.Delete(checklist.FindString(name))
  1945. if self.mapDisplay.IsAutoRendered():
  1946. self.mapWindow.Refresh(False)
  1947. def OnConstantSelection(self, event):
  1948. """!Constant selected"""
  1949. layerIdx = self.FindWindowById(self.win['constant']['surface']).GetSelection()
  1950. if layerIdx == wx.NOT_FOUND:
  1951. return
  1952. name = _("constant#") + str(layerIdx + 1)
  1953. data = self.mapWindow.constants[layerIdx]
  1954. for attr, value in data['constant'].iteritems():
  1955. if attr == 'color':
  1956. value = self._getColorFromString(value)
  1957. if attr in ('color', 'value', 'resolution', 'transp'):
  1958. if attr == 'transp':
  1959. self.FindWindowById(self.win['constant'][attr]).SetValue(self._getPercent(value))
  1960. self.FindWindowById(self.win['constant'][attr]).SetValue(value)
  1961. def OnSetConstantProp(self, event):
  1962. """!Change properties (color, value, resolution)
  1963. of currently selected constant surface"""
  1964. layerIdx = self.FindWindowById(self.win['constant']['surface']).GetSelection()
  1965. if layerIdx == wx.NOT_FOUND:
  1966. return
  1967. data = self.mapWindow.constants[layerIdx]
  1968. for attr in ('resolution', 'value', 'transp'):
  1969. data['constant'][attr] = self.FindWindowById(self.win['constant'][attr]).GetValue()
  1970. data['constant']['color'] = self._getColorString(
  1971. self.FindWindowById(self.win['constant']['color']).GetValue())
  1972. data['constant']['transp'] = self._getPercent(data['constant']['transp'], toPercent = False)
  1973. # update properties
  1974. event = wxUpdateProperties(data = data)
  1975. wx.PostEvent(self.mapWindow, event)
  1976. if self.mapDisplay.IsAutoRendered():
  1977. self.mapWindow.Refresh(False)
  1978. def OnFringe(self, event):
  1979. """!Show/hide fringe"""
  1980. data = self.GetLayerData('fringe')['surface']
  1981. sid = data['object']['id']
  1982. elev = self.FindWindowById(self.win['fringe']['elev']).GetValue()
  1983. color = self.FindWindowById(self.win['fringe']['color']).GetValue()
  1984. self._display.SetFringe(sid, color, elev,
  1985. self.FindWindowById(self.win['fringe']['nw']).IsChecked(),
  1986. self.FindWindowById(self.win['fringe']['ne']).IsChecked(),
  1987. self.FindWindowById(self.win['fringe']['sw']).IsChecked(),
  1988. self.FindWindowById(self.win['fringe']['se']).IsChecked())
  1989. self.mapWindow.Refresh(False)
  1990. def OnScroll(self, event, win, data):
  1991. """!Generic scrolling handler"""
  1992. winName = self.__GetWindowName(win, event.GetId())
  1993. if not winName:
  1994. return
  1995. data[winName] = self.FindWindowById(event.GetId()).GetValue()
  1996. for w in win[winName].itervalues():
  1997. self.FindWindowById(w).SetValue(data[winName])
  1998. event.Skip()
  1999. def AdjustSliderRange(self, slider, value):
  2000. minim, maxim = slider.GetRange()
  2001. if not (minim <= value <= maxim):
  2002. slider.SetRange(min(minim, value), max(maxim, value))
  2003. def _createIsosurfacePanel(self, parent):
  2004. panel = wx.Panel(parent = parent, id = wx.ID_ANY)
  2005. vSizer = wx.BoxSizer(wx.HORIZONTAL)
  2006. box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  2007. label = " %s " % (_("Isosurface attributes")))
  2008. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  2009. gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
  2010. self.win['volume']['attr'] = {}
  2011. inout = wx.CheckBox(parent = panel, id = wx.ID_ANY,
  2012. label = _("toggle normal direction"))
  2013. gridSizer.Add(item = inout, pos = (0,0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL)
  2014. inout.Bind(wx.EVT_CHECKBOX, self.OnInOutMode)
  2015. self.win['volume']['inout'] = inout.GetId()
  2016. row = 1
  2017. for code, attrb in (('topo', _("Isosurface value")),
  2018. ('color', _("Color")),
  2019. ('mask', _("Mask")),
  2020. ('transp', _("Transparency")),
  2021. ('shine', _("Shininess"))):
  2022. self.win['volume'][code] = {}
  2023. # label
  2024. colspan = 1
  2025. if code == 'topo':
  2026. colspan = 2
  2027. gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  2028. label = attrb + ':'),
  2029. pos = (row, 0), span = (1, colspan),flag = wx.ALIGN_CENTER_VERTICAL)
  2030. if code != 'topo':
  2031. use = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
  2032. choices = [_("map")])
  2033. else:
  2034. use = None
  2035. # check for required properties
  2036. if code not in ('topo', 'color', 'shine'):
  2037. use.Insert(item = _("unset"), pos = 0)
  2038. self.win['volume'][code]['required'] = False
  2039. else:
  2040. self.win['volume'][code]['required'] = True
  2041. if use and code != 'mask':
  2042. use.Append(item = _('constant'))
  2043. if use:
  2044. self.win['volume'][code]['use'] = use.GetId()
  2045. use.Bind(wx.EVT_CHOICE, self.OnMapObjUse)
  2046. gridSizer.Add(item = use, flag = wx.ALIGN_CENTER_VERTICAL,
  2047. pos = (row, 1))
  2048. if code != 'topo':
  2049. map = Select(parent = panel, id = wx.ID_ANY,
  2050. # size = globalvar.DIALOG_GSELECT_SIZE,
  2051. size = (200, -1),
  2052. type = "grid3")
  2053. self.win['volume'][code]['map'] = map.GetId() - 1 # FIXME
  2054. map.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
  2055. gridSizer.Add(item = map, flag = wx.ALIGN_CENTER_VERTICAL,
  2056. pos = (row, 2))
  2057. else:
  2058. map = None
  2059. if code == 'color':
  2060. color = UserSettings.Get(group = 'nviz', key = 'volume', subkey = ['color', 'value'])
  2061. value = csel.ColourSelect(panel, id = wx.ID_ANY,
  2062. colour = color,
  2063. size = globalvar.DIALOG_COLOR_SIZE)
  2064. value.Bind(csel.EVT_COLOURSELECT, self.OnVolumeIsosurfMap)
  2065. value.SetName('color')
  2066. elif code == 'mask':
  2067. value = None
  2068. elif code == 'topo':
  2069. value = NumTextCtrl(parent = panel, id = wx.ID_ANY, size = (200, -1),
  2070. style = wx.TE_PROCESS_ENTER)
  2071. value.Bind(wx.EVT_TEXT_ENTER, self.OnVolumeIsosurfMap)
  2072. value.Bind(wx.EVT_KILL_FOCUS, self.OnVolumeIsosurfMap)
  2073. ## value.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
  2074. else:
  2075. size = (65, -1)
  2076. value = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = size,
  2077. initial = 0)
  2078. if code == 'topo':
  2079. value.SetRange(minVal = -1e9, maxVal = 1e9)
  2080. elif code in ('shine', 'transp'):
  2081. value.SetRange(minVal = 0, maxVal = 100)
  2082. value.Bind(wx.EVT_SPINCTRL, self.OnVolumeIsosurfMap)
  2083. value.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
  2084. if value:
  2085. self.win['volume'][code]['const'] = value.GetId()
  2086. if code == 'topo':
  2087. gridSizer.Add(item = value, flag = wx.ALIGN_CENTER_VERTICAL,
  2088. pos = (row, 2))
  2089. else:
  2090. value.Enable(False)
  2091. gridSizer.Add(item = value, flag = wx.ALIGN_CENTER_VERTICAL,
  2092. pos = (row, 3))
  2093. else:
  2094. self.win['volume'][code]['const'] = None
  2095. if code != 'topo':
  2096. self.SetMapObjUseMap(nvizType = 'volume',
  2097. attrb = code) # -> enable map / disable constant
  2098. row += 1
  2099. boxSizer.Add(item = gridSizer, proportion = 1,
  2100. flag = wx.ALL | wx.EXPAND, border = 3)
  2101. vSizer.Add(item = boxSizer, proportion = 1,
  2102. flag = wx.EXPAND, border = 0)
  2103. panel.SetSizer(vSizer)
  2104. return panel
  2105. def _createSlicePanel(self, parent):
  2106. panel = wx.Panel(parent = parent, id = wx.ID_ANY)
  2107. vSizer = wx.BoxSizer(wx.HORIZONTAL)
  2108. box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
  2109. label = " %s " % (_("Slice attributes")))
  2110. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  2111. hSizer = wx.BoxSizer()
  2112. self.win['volume']['slice'] = {}
  2113. hSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  2114. label = _("Slice parallel to axis:")), proportion = 0,
  2115. flag = wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, border = 3)
  2116. axes = wx.Choice(parent = panel, id = wx.ID_ANY, size = (65, -1), choices = ("X", "Y", "Z"))
  2117. hSizer.Add(axes, proportion = 0, flag = wx.ALIGN_LEFT|wx.LEFT, border = 3)
  2118. self.win['volume']['slice']['axes'] = axes.GetId()
  2119. axes.Bind(wx.EVT_CHOICE, self.OnVolumeSliceAxes)
  2120. boxSizer.Add(hSizer, proportion = 0, flag = wx.ALL|wx.EXPAND, border = 3)
  2121. gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
  2122. gridSizer.AddGrowableCol(0,1)
  2123. gridSizer.AddGrowableCol(1,2)
  2124. gridSizer.AddGrowableCol(2,2)
  2125. # text labels
  2126. for i in range(2):
  2127. label = wx.StaticText(parent = panel, id = wx.ID_ANY)
  2128. label.SetName('label_edge_' + str(i))
  2129. gridSizer.Add(item = label, pos = (0, i + 1),
  2130. flag = wx.ALIGN_CENTER)
  2131. for i in range(2,4):
  2132. label = wx.StaticText(parent = panel, id = wx.ID_ANY)
  2133. label.SetName('label_edge_' + str(i))
  2134. gridSizer.Add(item = label, pos = (3, i -1),
  2135. flag = wx.ALIGN_CENTER)
  2136. for i in range(2):
  2137. label = wx.StaticText(parent = panel, id = wx.ID_ANY)
  2138. label.SetName('label_coord_' + str(i))
  2139. gridSizer.Add(item = label, pos = (i + 1, 0),
  2140. flag = wx.ALIGN_CENTER_VERTICAL)
  2141. label = wx.StaticText(parent = panel, id = wx.ID_ANY)
  2142. label.SetName('label_coord_2')
  2143. gridSizer.Add(item = label, pos = (4, 0),
  2144. flag = wx.ALIGN_CENTER_VERTICAL)
  2145. # sliders
  2146. for i, coord in enumerate(('x1', 'x2')):
  2147. slider = wx.Slider(parent = panel, id = wx.ID_ANY, minValue = 0, maxValue = 100, value = 0)
  2148. self.win['volume']['slice']['slider_' + coord] = slider.GetId()
  2149. slider.Bind(wx.EVT_SPIN, self.OnSlicePositionChange)
  2150. slider.Bind(wx.EVT_SCROLL_THUMBRELEASE, self.OnSlicePositionChanged)
  2151. gridSizer.Add(item = slider, pos = (1, i + 1),
  2152. flag = wx.ALIGN_CENTER|wx.EXPAND)
  2153. for i, coord in enumerate(('y1', 'y2')):
  2154. slider = wx.Slider(parent = panel, id = wx.ID_ANY, minValue = 0, maxValue = 100, value = 0)
  2155. self.win['volume']['slice']['slider_' + coord] = slider.GetId()
  2156. slider.Bind(wx.EVT_SPIN, self.OnSlicePositionChange)
  2157. slider.Bind(wx.EVT_SCROLL_THUMBRELEASE, self.OnSlicePositionChanged)
  2158. gridSizer.Add(item = slider, pos = (2, i + 1),
  2159. flag = wx.ALIGN_CENTER|wx.EXPAND)
  2160. for i, coord in enumerate(('z1', 'z2')):
  2161. slider = wx.Slider(parent = panel, id = wx.ID_ANY, minValue = 0, maxValue = 100, value = 0)
  2162. self.win['volume']['slice']['slider_' + coord] = slider.GetId()
  2163. slider.Bind(wx.EVT_SPIN, self.OnSlicePositionChange)
  2164. slider.Bind(wx.EVT_SCROLL_THUMBRELEASE, self.OnSlicePositionChanged)
  2165. gridSizer.Add(item = slider, pos = (4,i+1),
  2166. flag = wx.ALIGN_CENTER|wx.EXPAND)
  2167. boxSizer.Add(item = gridSizer, proportion = 1,
  2168. flag = wx.ALL | wx.EXPAND, border = 3)
  2169. # transparency, reset
  2170. hSizer = wx.BoxSizer()
  2171. hSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  2172. label = _("Transparency:")), proportion = 0,
  2173. flag = wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, border = 7)
  2174. spin = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
  2175. min = 0, max = 100, initial = 0)
  2176. spin.Bind(wx.EVT_SPINCTRL, self.OnSliceTransparency)
  2177. self.win['volume']['slice']['transp'] = spin.GetId()
  2178. hSizer.Add(item = spin, proportion = 0,
  2179. flag = wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.TOP, border = 7)
  2180. hSizer.Add(item = wx.Size(-1, -1), proportion = 1,
  2181. flag = wx.EXPAND)
  2182. reset = wx.Button(parent = panel, id = wx.ID_ANY, label = _("Reset"))
  2183. reset.Bind(wx.EVT_BUTTON, self.OnSliceReset)
  2184. self.win['volume']['slice']['reset'] = reset.GetId()
  2185. hSizer.Add(item = reset, proportion = 0,
  2186. flag = wx.ALIGN_CENTER_VERTICAL|wx.TOP, border = 7)
  2187. boxSizer.Add(hSizer, proportion = 0, flag = wx.ALL|wx.EXPAND, border = 3)
  2188. panel.SetSizer(boxSizer)
  2189. return panel
  2190. def _createControl(self, parent, data, name, range, tooltip = None, bind = (None, None, None),
  2191. sliderHor = True, size = 200, floatSlider = False):
  2192. """!Add control (Slider + TextCtrl)"""
  2193. data[name] = dict()
  2194. if sliderHor:
  2195. style = wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | \
  2196. wx.SL_BOTTOM
  2197. sizeW = (size, -1)
  2198. else:
  2199. style = wx.SL_VERTICAL | wx.SL_AUTOTICKS | \
  2200. wx.SL_INVERSE
  2201. sizeW = (-1, size)
  2202. kwargs = dict(parent = parent, id = wx.ID_ANY,
  2203. minValue = range[0],
  2204. maxValue = range[1],
  2205. style = style,
  2206. size = sizeW)
  2207. if floatSlider:
  2208. slider = FloatSlider(**kwargs)
  2209. else:
  2210. slider = wx.Slider(**kwargs)
  2211. slider.SetName('slider')
  2212. if bind[0]:
  2213. #EVT_SCROLL emits event after slider is released, EVT_SPIN not
  2214. slider.Bind(wx.EVT_SPIN, bind[0])
  2215. if bind[1]:
  2216. slider.Bind(wx.EVT_SCROLL_THUMBRELEASE, bind[1])
  2217. data[name]['slider'] = slider.GetId()
  2218. text = NumTextCtrl(parent = parent, id = wx.ID_ANY, size = (65, -1),
  2219. style = wx.TE_PROCESS_ENTER)
  2220. text.SetName('text')
  2221. if tooltip:
  2222. text.SetToolTipString(tooltip)
  2223. if bind[2]:
  2224. text.Bind(wx.EVT_TEXT_ENTER, bind[2])
  2225. text.Bind(wx.EVT_KILL_FOCUS, bind[2])
  2226. data[name]['text'] = text.GetId()
  2227. def _createCompass(self, panel, sizer, type):
  2228. """!Create 'compass' widget for light and view page"""
  2229. w = wx.Button(panel, id = wx.ID_ANY, label = _("W"))
  2230. n = wx.Button(panel, id = wx.ID_ANY, label = _("N"))
  2231. s = wx.Button(panel, id = wx.ID_ANY, label = _("S"))
  2232. e = wx.Button(panel, id = wx.ID_ANY, label = _("E"))
  2233. nw = wx.Button(panel, id = wx.ID_ANY, label = _("NW"))
  2234. ne = wx.Button(panel, id = wx.ID_ANY, label = _("NE"))
  2235. se = wx.Button(panel, id = wx.ID_ANY, label = _("SE"))
  2236. sw = wx.Button(panel, id = wx.ID_ANY, label = _("SW"))
  2237. minWidth = sw.GetTextExtent(sw.GetLabel())[0] + 15
  2238. for win, name in zip((w, n, s, e, nw, ne, se, sw),
  2239. ('w', 'n', 's', 'e', 'nw', 'ne', 'se', 'sw')):
  2240. win.SetMinSize((minWidth, -1))
  2241. win.Bind(wx.EVT_BUTTON, self.OnLookFrom)
  2242. win.SetName(type + '_' + name)
  2243. sizer.Add(item = nw, pos = (0, 0), flag = wx.ALIGN_CENTER)
  2244. sizer.Add(item = n, pos = (0, 1), flag = wx.ALIGN_CENTER)
  2245. sizer.Add(item = ne, pos = (0, 2), flag = wx.ALIGN_CENTER)
  2246. sizer.Add(item = e, pos = (1, 2), flag = wx.ALIGN_CENTER)
  2247. sizer.Add(item = se, pos = (2, 2), flag = wx.ALIGN_CENTER)
  2248. sizer.Add(item = s, pos = (2, 1), flag = wx.ALIGN_CENTER)
  2249. sizer.Add(item = sw, pos = (2, 0), flag = wx.ALIGN_CENTER)
  2250. sizer.Add(item = w, pos = (1, 0), flag = wx.ALIGN_CENTER)
  2251. def __GetWindowName(self, data, id):
  2252. for name in data.iterkeys():
  2253. if type(data[name]) is type({}):
  2254. for win in data[name].itervalues():
  2255. if win == id:
  2256. return name
  2257. else:
  2258. if data[name] == id:
  2259. return name
  2260. return None
  2261. def UpdateSettings(self):
  2262. """!Update view from settings values
  2263. stored in self.mapWindow.view dictionary"""
  2264. for control in ('height',
  2265. 'persp',
  2266. 'twist',
  2267. 'z-exag'):
  2268. for win in self.win['view'][control].itervalues():
  2269. try:
  2270. if control == 'height':
  2271. value = int(self.mapWindow.iview[control]['value'])
  2272. else:
  2273. value = self.mapWindow.view[control]['value']
  2274. except KeyError:
  2275. value = -1
  2276. self.FindWindowById(win).SetValue(value)
  2277. viewWin = self.FindWindowById(self.win['view']['position'])
  2278. x, y = viewWin.UpdatePos(self.mapWindow.view['position']['x'],
  2279. self.mapWindow.view['position']['y'])
  2280. viewWin.Draw(pos = (x, y), scale = True)
  2281. viewWin.Refresh(False)
  2282. color = self._getColorString(self.mapWindow.view['background']['color'])
  2283. self._display.SetBgColor(str(color))
  2284. self.Update()
  2285. self.mapWindow.Refresh(eraseBackground = False)
  2286. self.mapWindow.render['quick'] = False
  2287. self.mapWindow.Refresh(True)
  2288. def OnShowLightModel(self, event):
  2289. """!Show light model"""
  2290. self._display.showLight = event.IsChecked()
  2291. self._display.DrawLightingModel()
  2292. def OnLightChange(self, event):
  2293. """!Position of the light changing"""
  2294. winName = self.__GetWindowName(self.win['light'], event.GetId())
  2295. if not winName:
  2296. return
  2297. value = self.FindWindowById(event.GetId()).GetValue()
  2298. self.mapWindow.light['position']['z'] = value
  2299. for win in self.win['light'][winName].itervalues():
  2300. self.FindWindowById(win).SetValue(value)
  2301. self.PostLightEvent()
  2302. event.Skip()
  2303. def OnLightChanged(self, event):
  2304. """!Light changed"""
  2305. self.PostLightEvent(refresh = True)
  2306. def OnLightColor(self, event):
  2307. """!Color of the light changed"""
  2308. self.mapWindow.light['color'] = tuple(event.GetValue())
  2309. self.PostLightEvent(refresh = True)
  2310. event.Skip()
  2311. def OnLightValue(self, event):
  2312. """!Light brightness/ambient changing"""
  2313. data = self.mapWindow.light
  2314. self.OnScroll(event, self.win['light'], data)
  2315. self.PostLightEvent()
  2316. event.Skip()
  2317. def OnBgColor(self, event):
  2318. """!Background color changed"""
  2319. color = event.GetValue()
  2320. self.mapWindow.view['background']['color'] = tuple(color)
  2321. color = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
  2322. self._display.SetBgColor(str(color))
  2323. if self.mapDisplay.IsAutoRendered():
  2324. self.mapWindow.Refresh(False)
  2325. def OnSetSurface(self, event):
  2326. """!Surface selected, currently used for fringes"""
  2327. name = event.GetString()
  2328. try:
  2329. data = self.mapWindow.GetLayerByName(name, mapType = 'raster', dataType = 'nviz')['surface']
  2330. except:
  2331. self.EnablePage('fringe', False)
  2332. return
  2333. layer = self.mapWindow.GetLayerByName(name, mapType = 'raster')
  2334. self.EnablePage('fringe', True)
  2335. def OnSetRaster(self, event):
  2336. """!Raster map selected, update surface page"""
  2337. name = event.GetString()
  2338. try:
  2339. data = self.mapWindow.GetLayerByName(name, mapType = 'raster', dataType = 'nviz')['surface']
  2340. except:
  2341. self.EnablePage('surface', False)
  2342. return
  2343. layer = self.mapWindow.GetLayerByName(name, mapType = 'raster')
  2344. self.EnablePage('surface', True)
  2345. self.UpdateSurfacePage(layer, data, updateName = False)
  2346. def OnSetVector(self, event):
  2347. """!Vector map selected, update properties page"""
  2348. name = event.GetString()
  2349. try:
  2350. data = self.mapWindow.GetLayerByName(name, mapType = 'vector', dataType = 'nviz')['vector']
  2351. except:
  2352. self.EnablePage('vector', False)
  2353. return
  2354. layer = self.mapWindow.GetLayerByName(name, mapType = 'vector')
  2355. self.EnablePage('vector', True)
  2356. self.UpdateVectorPage(layer, data, updateName = False)
  2357. def OnSetRaster3D(self, event):
  2358. """!3D Raster map selected, update surface page"""
  2359. name = event.GetString()
  2360. try:
  2361. data = self.mapWindow.GetLayerByName(name, mapType = '3d-raster', dataType = 'nviz')['volume']
  2362. except:
  2363. self.EnablePage('volume', False)
  2364. return
  2365. layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
  2366. self.EnablePage('volume', True)
  2367. self.UpdateVolumePage(layer, data, updateName = False)
  2368. def OnViewChange(self, event):
  2369. """!Change view, render in quick mode"""
  2370. # find control
  2371. winName = self.__GetWindowName(self.win['view'], event.GetId())
  2372. if not winName:
  2373. return
  2374. value = self.FindWindowById(event.GetId()).GetValue()
  2375. slider = self.FindWindowById(self.win['view'][winName]['slider'])
  2376. self.AdjustSliderRange(slider = slider, value = value)
  2377. if winName == 'height':
  2378. view = self.mapWindow.iview # internal
  2379. else:
  2380. view = self.mapWindow.view
  2381. if winName == 'z-exag' and value >= 0:
  2382. self.PostViewEvent(zExag = True)
  2383. else:
  2384. self.PostViewEvent(zExag = False)
  2385. if winName in ('persp', 'twist'):
  2386. convert = int
  2387. else:
  2388. convert = float
  2389. view[winName]['value'] = convert(value)
  2390. for win in self.win['view'][winName].itervalues():
  2391. self.FindWindowById(win).SetValue(value)
  2392. self.mapWindow.iview['dir']['use'] = False
  2393. self.mapWindow.render['quick'] = True
  2394. if self.mapDisplay.IsAutoRendered():
  2395. self.mapWindow.Refresh(False)
  2396. event.Skip()
  2397. def OnViewChanged(self, event):
  2398. """!View changed, render in full resolution"""
  2399. self.mapWindow.render['quick'] = False
  2400. self.mapWindow.Refresh(False)
  2401. self.UpdateSettings()
  2402. try:# when calling event = None
  2403. event.Skip()
  2404. except AttributeError:
  2405. pass
  2406. def OnViewChangedText(self, event):
  2407. """!View changed, render in full resolution"""
  2408. self.mapWindow.render['quick'] = False
  2409. self.OnViewChange(event)
  2410. self.OnViewChanged(None)
  2411. self.Update()
  2412. event.Skip()
  2413. def OnLookAt(self, event):
  2414. """!Look here/center"""
  2415. name = self.FindWindowById(event.GetId()).GetName()
  2416. if name == 'center':
  2417. self._display.LookAtCenter()
  2418. focus = self.mapWindow.iview['focus']
  2419. focus['x'], focus['y'], focus['z'] = self._display.GetFocus()
  2420. self.mapWindow.saveHistory = True
  2421. self.mapWindow.Refresh(False)
  2422. elif name == 'top':
  2423. self.mapWindow.view['position']['x'] = 0.5
  2424. self.mapWindow.view['position']['y'] = 0.5
  2425. self.PostViewEvent(zExag = True)
  2426. self.UpdateSettings()
  2427. self.mapWindow.Refresh(False)
  2428. else: # here
  2429. if self.FindWindowById(event.GetId()).GetValue():
  2430. self.mapDisplay.Raise()
  2431. self.mapWindow.mouse['use'] = 'lookHere'
  2432. self.mapWindow.SetCursor(self.mapWindow.cursors["cross"])
  2433. else:
  2434. self.mapWindow.mouse['use'] = 'default'
  2435. self.mapWindow.SetCursor(self.mapWindow.cursors['default'])
  2436. def OnResetView(self, event):
  2437. """!Reset to default view (view page)"""
  2438. self.mapWindow.ResetView()
  2439. self.UpdateSettings()
  2440. self.mapWindow.Refresh(False)
  2441. def OnResetSurfacePosition(self, event):
  2442. """!Reset position of surface"""
  2443. for win in self.win['surface']['position'].itervalues():
  2444. if win == self.win['surface']['position']['axis']:
  2445. self.FindWindowById(win).SetSelection(0)
  2446. elif win == self.win['surface']['position']['reset']:
  2447. continue
  2448. else:
  2449. self.FindWindowById(win).SetValue(0)
  2450. data = self.GetLayerData('surface')
  2451. data['surface']['position']['x'] = 0
  2452. data['surface']['position']['y'] = 0
  2453. data['surface']['position']['z'] = 0
  2454. data['surface']['position']['update'] = None
  2455. # update properties
  2456. event = wxUpdateProperties(data = data)
  2457. wx.PostEvent(self.mapWindow, event)
  2458. if self.mapDisplay.IsAutoRendered():
  2459. self.mapWindow.Refresh(False)
  2460. def OnLookFrom(self, event):
  2461. """!Position of view/light changed by buttons"""
  2462. name = self.FindWindowById(event.GetId()).GetName()
  2463. buttonName = name.split('_')[1]
  2464. if name.split('_')[0] == 'view':
  2465. type = 'view'
  2466. data = self.mapWindow.view
  2467. else:
  2468. type = 'light'
  2469. data = self.mapWindow.light
  2470. if buttonName == 'n': # north
  2471. data['position']['x'] = 0.5
  2472. data['position']['y'] = 0.0
  2473. elif buttonName == 's': # south
  2474. data['position']['x'] = 0.5
  2475. data['position']['y'] = 1.0
  2476. elif buttonName == 'e': # east
  2477. data['position']['x'] = 1.0
  2478. data['position']['y'] = 0.5
  2479. elif buttonName =='w': # west
  2480. data['position']['x'] = 0.0
  2481. data['position']['y'] = 0.5
  2482. elif buttonName == 'nw': # north-west
  2483. data['position']['x'] = 0.0
  2484. data['position']['y'] = 0.0
  2485. elif buttonName == 'ne': # north-east
  2486. data['position']['x'] = 1.0
  2487. data['position']['y'] = 0.0
  2488. elif buttonName == 'se': # south-east
  2489. data['position']['x'] = 1.0
  2490. data['position']['y'] = 1.0
  2491. elif buttonName == 'sw': # south-west
  2492. data['position']['x'] = 0.0
  2493. data['position']['y'] = 1.0
  2494. if type == 'view':
  2495. self.PostViewEvent(zExag = True)
  2496. self.UpdateSettings()
  2497. else:
  2498. self.PostLightEvent()
  2499. lightWin = self.FindWindowById(self.win['light']['position'])
  2500. x, y = lightWin.UpdatePos(self.mapWindow.light['position']['x'],
  2501. self.mapWindow.light['position']['y'])
  2502. lightWin.Draw(pos = (x, y), scale = True)
  2503. lightWin.Refresh(False)
  2504. self.mapWindow.render['quick'] = False
  2505. self.mapWindow.Refresh(False)
  2506. def OnMapObjUse(self, event):
  2507. """!Set surface attribute -- use -- map/constant"""
  2508. if not self.mapWindow.init:
  2509. return
  2510. wx.Yield()
  2511. # find attribute row
  2512. attrb = self.__GetWindowName(self.win['surface'], event.GetId())
  2513. if not attrb:
  2514. attrb = self.__GetWindowName(self.win['volume'], event.GetId())
  2515. nvizType = 'volume'
  2516. else:
  2517. nvizType = 'surface'
  2518. selection = event.GetSelection()
  2519. if self.win[nvizType][attrb]['required']: # no 'unset'
  2520. selection += 1
  2521. if selection == 0: # unset
  2522. useMap = None
  2523. value = ''
  2524. elif selection == 1: # map
  2525. useMap = True
  2526. value = self.FindWindowById(self.win[nvizType][attrb]['map']).GetValue()
  2527. elif selection == 2: # constant
  2528. useMap = False
  2529. if attrb == 'color':
  2530. value = self.FindWindowById(self.win[nvizType][attrb]['const']).GetColour()
  2531. value = self._getColorString(value)
  2532. else:
  2533. value = self._getPercent(self.FindWindowById(self.win[nvizType][attrb]['const']).GetValue(), toPercent = False)
  2534. self.SetMapObjUseMap(nvizType = nvizType,
  2535. attrb = attrb, map = useMap)
  2536. name = self.FindWindowById(self.win[nvizType]['map']).GetValue()
  2537. if nvizType == 'surface':
  2538. data = self.mapWindow.GetLayerByName(name, mapType = 'raster', dataType = 'nviz')
  2539. data[nvizType]['attribute'][attrb] = { 'map' : useMap,
  2540. 'value' : str(value),
  2541. 'update' : None }
  2542. else: # volume / isosurface
  2543. data = self.mapWindow.GetLayerByName(name, mapType = '3d-raster', dataType = 'nviz')
  2544. list = self.FindWindowById(self.win['volume']['isosurfs'])
  2545. id = list.GetSelection()
  2546. if id != -1:
  2547. data[nvizType]['isosurface'][id][attrb] = { 'map' : useMap,
  2548. 'value' : str(value),
  2549. 'update' : None }
  2550. # update properties
  2551. event = wxUpdateProperties(data = data)
  2552. wx.PostEvent(self.mapWindow, event)
  2553. if self.mapDisplay.IsAutoRendered():
  2554. self.mapWindow.Refresh(False)
  2555. def EnablePage(self, name, enabled = True):
  2556. """!Enable/disable all widgets on page"""
  2557. for key, item in self.win[name].iteritems():
  2558. if key in ('map', 'surface', 'new','planes'):
  2559. continue
  2560. if type(item) == types.DictType:
  2561. for skey, sitem in self.win[name][key].iteritems():
  2562. if type(sitem) == types.DictType:
  2563. for ssitem in self.win[name][key][skey].itervalues():
  2564. if type(ssitem) == types.IntType:
  2565. self.FindWindowById(ssitem).Enable(enabled)
  2566. else:
  2567. if type(sitem) == types.IntType:
  2568. self.FindWindowById(sitem).Enable(enabled)
  2569. else:
  2570. if type(item) == types.IntType:
  2571. self.FindWindowById(item).Enable(enabled)
  2572. def SetMapObjUseMap(self, nvizType, attrb, map = None):
  2573. """!Update dialog widgets when attribute type changed"""
  2574. if attrb in ('topo', 'color', 'shine'):
  2575. incSel = -1 # decrement selection (no 'unset')
  2576. else:
  2577. incSel = 0
  2578. if nvizType == 'volume' and attrb == 'topo':
  2579. return
  2580. if map is True: # map
  2581. if attrb != 'topo': # changing map topography not allowed
  2582. # not sure why, but here must be disabled both ids, should be fixed!
  2583. self.FindWindowById(self.win[nvizType][attrb]['map'] + 1).Enable(True)
  2584. if self.win[nvizType][attrb]['const']:
  2585. self.FindWindowById(self.win[nvizType][attrb]['const']).Enable(False)
  2586. self.FindWindowById(self.win[nvizType][attrb]['use']).SetSelection(1 + incSel)
  2587. elif map is False: # const
  2588. self.FindWindowById(self.win[nvizType][attrb]['map'] + 1).Enable(False)
  2589. if self.win[nvizType][attrb]['const']:
  2590. self.FindWindowById(self.win[nvizType][attrb]['const']).Enable(True)
  2591. self.FindWindowById(self.win[nvizType][attrb]['use']).SetSelection(2 + incSel)
  2592. else: # unset
  2593. self.FindWindowById(self.win[nvizType][attrb]['use']).SetSelection(0)
  2594. self.FindWindowById(self.win[nvizType][attrb]['map'] + 1).Enable(False)
  2595. if self.win[nvizType][attrb]['const']:
  2596. self.FindWindowById(self.win[nvizType][attrb]['const']).Enable(False)
  2597. def OnSurfaceMap(self, event):
  2598. """!Set surface attribute"""
  2599. if self.vetoGSelectEvt:
  2600. self.vetoGSelectEvt = False
  2601. return
  2602. self.SetMapObjAttrb(nvizType = 'surface', winId = event.GetId())
  2603. def SetMapObjAttrb(self, nvizType, winId):
  2604. """!Set map object (surface/isosurface) attribute (map/constant)"""
  2605. if not self.mapWindow.init:
  2606. return
  2607. attrb = self.__GetWindowName(self.win[nvizType], winId)
  2608. if not attrb:
  2609. return
  2610. if not (nvizType == 'volume' and attrb == 'topo'):
  2611. selection = self.FindWindowById(self.win[nvizType][attrb]['use']).GetSelection()
  2612. if self.win[nvizType][attrb]['required']:
  2613. selection += 1
  2614. if selection == 0: # unset
  2615. useMap = None
  2616. value = ''
  2617. elif selection == 1: # map
  2618. value = self.FindWindowById(self.win[nvizType][attrb]['map']).GetValue()
  2619. useMap = True
  2620. else: # constant
  2621. if attrb == 'color':
  2622. value = self.FindWindowById(self.win[nvizType][attrb]['const']).GetColour()
  2623. # tuple to string
  2624. value = self._getColorString(value)
  2625. else:
  2626. value = self._getPercent(
  2627. self.FindWindowById(self.win[nvizType][attrb]['const']).GetValue(), toPercent = False)
  2628. useMap = False
  2629. else:
  2630. useMap = None
  2631. value = self.FindWindowById(self.win[nvizType][attrb]['const']).GetValue()
  2632. if not self.pageChanging:
  2633. name = self.FindWindowById(self.win[nvizType]['map']).GetValue()
  2634. if nvizType == 'surface':
  2635. data = self.mapWindow.GetLayerByName(name, mapType = 'raster', dataType = 'nviz')
  2636. data[nvizType]['attribute'][attrb] = { 'map' : useMap,
  2637. 'value' : str(value),
  2638. 'update' : None }
  2639. else:
  2640. data = self.mapWindow.GetLayerByName(name, mapType = '3d-raster', dataType = 'nviz')
  2641. list = self.FindWindowById(self.win['volume']['isosurfs'])
  2642. id = list.GetSelection()
  2643. if id > -1:
  2644. data[nvizType]['isosurface'][id][attrb] = { 'map' : useMap,
  2645. 'value' : str(value),
  2646. 'update' : None }
  2647. if attrb == 'topo':
  2648. list = self.FindWindowById(self.win['volume']['isosurfs'])
  2649. sel = list.GetSelection()
  2650. list.SetString(sel, "%s %s" % (_("Level"), str(value)))
  2651. list.Check(sel)
  2652. # update properties
  2653. event = wxUpdateProperties(data = data)
  2654. wx.PostEvent(self.mapWindow, event)
  2655. if self.mapDisplay.IsAutoRendered():
  2656. self.mapWindow.Refresh(False)
  2657. def OnSurfaceResolution(self, event):
  2658. """!Draw resolution changed"""
  2659. self.SetSurfaceResolution()
  2660. if self.mapDisplay.IsAutoRendered():
  2661. self.mapWindow.Refresh(False)
  2662. def SetSurfaceResolution(self):
  2663. """!Set draw resolution"""
  2664. coarse = self.FindWindowById(self.win['surface']['draw']['res-coarse']).GetValue()
  2665. fine = self.FindWindowById(self.win['surface']['draw']['res-fine']).GetValue()
  2666. data = self.GetLayerData('surface')
  2667. data['surface']['draw']['resolution'] = { 'coarse' : coarse,
  2668. 'fine' : fine,
  2669. 'update' : None }
  2670. # update properties
  2671. event = wxUpdateProperties(data = data)
  2672. wx.PostEvent(self.mapWindow, event)
  2673. def SetSurfaceMode(self):
  2674. """!Set draw mode"""
  2675. mode = self.FindWindowById(self.win['surface']['draw']['mode']).GetSelection()
  2676. style = self.FindWindowById(self.win['surface']['draw']['style']).GetSelection()
  2677. if style == 0: # wire
  2678. self.FindWindowById(self.win['surface']['draw']['wire-color']).Enable(True)
  2679. elif style == 1: # surface
  2680. self.FindWindowById(self.win['surface']['draw']['wire-color']).Enable(False)
  2681. shade = self.FindWindowById(self.win['surface']['draw']['shading']).GetSelection()
  2682. value, desc = self.mapWindow.nvizDefault.GetDrawMode(mode, style, shade)
  2683. return value, desc
  2684. def OnSurfaceMode(self, event):
  2685. """!Set draw mode"""
  2686. value, desc = self.SetSurfaceMode()
  2687. data = self.GetLayerData('surface')
  2688. data['surface']['draw']['mode'] = { 'value' : value,
  2689. 'desc' : desc,
  2690. 'update' : None }
  2691. # update properties
  2692. event = wxUpdateProperties(data = data)
  2693. wx.PostEvent(self.mapWindow, event)
  2694. if self.mapDisplay.IsAutoRendered():
  2695. self.mapWindow.Refresh(False)
  2696. def OnSurfaceModeAll(self, event):
  2697. """!Set draw mode (including wire color) for all loaded surfaces"""
  2698. value, desc = self.SetSurfaceMode()
  2699. coarse = self.FindWindowById(self.win['surface']['draw']['res-coarse']).GetValue()
  2700. fine = self.FindWindowById(self.win['surface']['draw']['res-fine']).GetValue()
  2701. color = self.FindWindowById(self.win['surface']['draw']['wire-color']).GetColour()
  2702. cvalue = self._getColorString(color)
  2703. for name in self.mapWindow.GetLayerNames(type = 'raster'):
  2704. data = self.mapWindow.GetLayerByName(name, mapType = 'raster', dataType = 'nviz')
  2705. if not data:
  2706. continue # shouldy no happen
  2707. data['surface']['draw']['all'] = True
  2708. data['surface']['draw']['mode'] = { 'value' : value,
  2709. 'desc' : desc,
  2710. 'update' : None }
  2711. data['surface']['draw']['resolution'] = { 'coarse' : coarse,
  2712. 'fine' : fine,
  2713. 'update' : None }
  2714. data['surface']['draw']['wire-color'] = { 'value' : cvalue,
  2715. 'update' : None }
  2716. # update properties
  2717. event = wxUpdateProperties(data = data)
  2718. wx.PostEvent(self.mapWindow, event)
  2719. if self.mapDisplay.IsAutoRendered():
  2720. self.mapWindow.Refresh(False)
  2721. def _getColorString(self, color):
  2722. """!Convert color tuple to R:G:B format
  2723. @param color tuple
  2724. @return string R:G:B
  2725. """
  2726. return str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
  2727. def _getColorFromString(self, color, delim = ':'):
  2728. """!Convert color string (R:G:B) to wx.Color
  2729. @param color string
  2730. @param delim delimiter
  2731. @return wx.Color instance
  2732. """
  2733. return wx.Color(*map(int, color.split(delim)))
  2734. def _get3dRange(self, name):
  2735. """!Gelper func for getting range of 3d map"""
  2736. ret = RunCommand('r3.info', read = True, flags = 'r', map = name)
  2737. if ret:
  2738. range = []
  2739. for value in ret.strip('\n').split('\n'):
  2740. range.append(float(value.split('=')[1]))
  2741. return range
  2742. return -1e6, 1e6
  2743. def _getPercent(self, value, toPercent = True):
  2744. """!Convert values 0 - 255 to percents and vice versa"""
  2745. value = int(value)
  2746. if toPercent:
  2747. value = int(value/255. * 100)
  2748. else:
  2749. value = int(value/100. * 255)
  2750. return value
  2751. def OnSurfaceWireColor(self, event):
  2752. """!Set wire color"""
  2753. data = self.GetLayerData('surface')
  2754. value = self._getColorString(event.GetValue())
  2755. data['surface']['draw']['wire-color'] = { 'value' : value,
  2756. 'update' : None }
  2757. # update properties
  2758. event = wxUpdateProperties(data = data)
  2759. wx.PostEvent(self.mapWindow, event)
  2760. if self.mapDisplay.IsAutoRendered():
  2761. self.mapWindow.Refresh(False)
  2762. def OnSurfaceAxis(self, event):
  2763. """!Surface position, axis changed"""
  2764. data = self.GetLayerData('surface')
  2765. id = data['surface']['object']['id']
  2766. axis = self.FindWindowById(self.win['surface']['position']['axis']).GetSelection()
  2767. slider = self.FindWindowById(self.win['surface']['position']['slider'])
  2768. text = self.FindWindowById(self.win['surface']['position']['text'])
  2769. xydim = self._display.GetLongDim()
  2770. zdim = self._display.GetZRange()
  2771. zdim = zdim[1] - zdim[0]
  2772. x, y, z = self._display.GetSurfacePosition(id)
  2773. if axis == 0: # x
  2774. slider.SetRange(-3 * xydim, 3 * xydim)
  2775. slider.SetValue(x)
  2776. text.SetValue(x)
  2777. elif axis == 1: # y
  2778. slider.SetRange(-3 * xydim, 3 * xydim)
  2779. slider.SetValue(y)
  2780. text.SetValue(y)
  2781. else: # z
  2782. slider.SetRange(-3 * zdim, 3 * zdim)
  2783. slider.SetValue(z)
  2784. text.SetValue(z)
  2785. def OnSurfacePosition(self, event):
  2786. """!Surface position"""
  2787. winName = self.__GetWindowName(self.win['surface'], event.GetId())
  2788. if not winName:
  2789. return
  2790. axis = self.FindWindowById(self.win['surface']['position']['axis']).GetSelection()
  2791. value = self.FindWindowById(event.GetId()).GetValue()
  2792. slider = self.FindWindowById(self.win['surface'][winName]['slider'])
  2793. self.AdjustSliderRange(slider = slider, value = value)
  2794. for win in self.win['surface']['position'].itervalues():
  2795. if win in (self.win['surface']['position']['axis'],
  2796. self.win['surface']['position']['reset']):
  2797. continue
  2798. else:
  2799. self.FindWindowById(win).SetValue(value)
  2800. data = self.GetLayerData('surface')
  2801. id = data['surface']['object']['id']
  2802. x, y, z = self._display.GetSurfacePosition(id)
  2803. if axis == 0: # x
  2804. x = value
  2805. elif axis == 1: # y
  2806. y = value
  2807. else: # z
  2808. z = value
  2809. data['surface']['position']['x'] = x
  2810. data['surface']['position']['y'] = y
  2811. data['surface']['position']['z'] = z
  2812. data['surface']['position']['update'] = None
  2813. # update properties
  2814. event = wxUpdateProperties(data = data)
  2815. wx.PostEvent(self.mapWindow, event)
  2816. self.mapWindow.render['quick'] = True
  2817. if self.mapDisplay.IsAutoRendered():
  2818. self.mapWindow.Refresh(False)
  2819. # self.UpdatePage('surface')
  2820. def OnSurfacePositionChanged(self, event):
  2821. """!Surface position changed"""
  2822. self.mapWindow.render['quick'] = False
  2823. self.mapWindow.Refresh(False)
  2824. def OnSurfacePositionText(self, event):
  2825. """!Surface position changed by textctrl"""
  2826. self.OnSurfacePosition(event)
  2827. self.OnSurfacePositionChanged(None)
  2828. def UpdateVectorShow(self, vecType, enabled):
  2829. """!Enable/disable lines/points widgets
  2830. @param vecType vector type (lines, points)
  2831. """
  2832. if vecType != 'lines' and vecType != 'points':
  2833. return False
  2834. for win in self.win['vector'][vecType].keys():
  2835. if win == 'show':
  2836. continue
  2837. if type(self.win['vector'][vecType][win]) == type({}):
  2838. for swin in self.win['vector'][vecType][win].keys():
  2839. if enabled:
  2840. self.FindWindowById(self.win['vector'][vecType][win][swin]).Enable(True)
  2841. else:
  2842. self.FindWindowById(self.win['vector'][vecType][win][swin]).Enable(False)
  2843. else:
  2844. if enabled:
  2845. self.FindWindowById(self.win['vector'][vecType][win]).Enable(True)
  2846. else:
  2847. self.FindWindowById(self.win['vector'][vecType][win]).Enable(False)
  2848. return True
  2849. def OnVectorShow(self, event):
  2850. """!Show vector lines/points"""
  2851. winId = event.GetId()
  2852. if winId == self.win['vector']['lines']['show']:
  2853. vecType = 'lines'
  2854. points = False
  2855. else: # points
  2856. vecType = 'points'
  2857. points = True
  2858. checked = event.IsChecked()
  2859. name = self.FindWindowById(self.win['vector']['map']).GetValue()
  2860. item = self.mapWindow.GetLayerByName(name, mapType = 'vector', dataType = 'item')
  2861. data = self.GetLayerData('vector')['vector']
  2862. if checked:
  2863. self.mapWindow.LoadVector(item, points = points, append = False)
  2864. else:
  2865. self.mapWindow.UnloadVector(item, points = points, remove = False)
  2866. self.UpdateVectorShow(vecType, checked)
  2867. if checked:
  2868. try:
  2869. id = data[vecType]['object']['id']
  2870. except KeyError:
  2871. id = -1
  2872. if id > 0:
  2873. self.mapWindow.SetMapObjProperties(item, id, vecType)
  2874. # update properties
  2875. event = wxUpdateProperties(data = data)
  2876. wx.PostEvent(self.mapWindow, event)
  2877. if self.mapDisplay.IsAutoRendered():
  2878. self.mapWindow.Refresh(False)
  2879. event.Skip()
  2880. def OnVectorDisplay(self, event):
  2881. """!Display vector lines on surface/flat"""
  2882. rasters = self.mapWindow.GetLayerNames('raster')
  2883. if event.GetSelection() == 0: # surface
  2884. if len(rasters) < 1:
  2885. self.FindWindowById(self.win['vector']['lines']['surface']).Enable(False)
  2886. self.FindWindowById(self.win['vector']['lines']['flat']).SetSelection(1)
  2887. return
  2888. self.FindWindowById(self.win['vector']['lines']['surface']).Enable(True)
  2889. # set first found surface
  2890. data = self.GetLayerData('vector')
  2891. data['vector']['lines']['mode']['surface'] = rasters[0]
  2892. self.FindWindowById(self.win['vector']['lines']['surface']).SetStringSelection( \
  2893. rasters[0])
  2894. else: # flat
  2895. self.FindWindowById(self.win['vector']['lines']['surface']).Enable(False)
  2896. self.OnVectorLines(event)
  2897. event.Skip()
  2898. def OnVectorLines(self, event):
  2899. """!Set vector lines mode, apply changes if auto-rendering is enabled"""
  2900. data = self.GetLayerData('vector')
  2901. width = self.FindWindowById(self.win['vector']['lines']['width']).GetValue()
  2902. mode = {}
  2903. if self.FindWindowById(self.win['vector']['lines']['flat']).GetSelection() == 0:
  2904. mode['type'] = 'surface'
  2905. mode['surface'] = {}
  2906. checklist = self.FindWindowById(self.win['vector']['lines']['surface'])
  2907. value = list()
  2908. checked = list()
  2909. for surface in range(checklist.GetCount()):
  2910. value.append(checklist.GetString(surface))
  2911. checked.append(checklist.IsChecked(surface))
  2912. mode['surface']['value'] = value
  2913. mode['surface']['show'] = checked
  2914. else:
  2915. mode['type'] = 'flat'
  2916. for attrb in ('width', 'mode'):
  2917. data['vector']['lines'][attrb]['update'] = None
  2918. data['vector']['lines']['width']['value'] = width
  2919. data['vector']['lines']['mode'] = mode
  2920. color = self.FindWindowById(self.win['vector']['lines']['color']).GetColour()
  2921. if isinstance(color, csel.ColourSelect):
  2922. pass #color picker not yet instantiated
  2923. else:
  2924. color = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
  2925. data['vector']['lines']['color']['update'] = None
  2926. data['vector']['lines']['color']['value'] = color
  2927. # update properties
  2928. event = wxUpdateProperties(data = data)
  2929. wx.PostEvent(self.mapWindow, event)
  2930. if self.mapDisplay.IsAutoRendered():
  2931. self.mapWindow.Refresh(False)
  2932. def OnVectorHeight(self, event):
  2933. id = event.GetId()
  2934. if id in self.win['vector']['lines']['height'].values():
  2935. vtype = 'lines'
  2936. else:
  2937. vtype = 'points'
  2938. value = self.FindWindowById(id).GetValue()
  2939. slider = self.FindWindowById(self.win['vector'][vtype]['height']['slider'])
  2940. self.AdjustSliderRange(slider = slider, value = value)
  2941. for win in self.win['vector'][vtype]['height'].itervalues():
  2942. self.FindWindowById(win).SetValue(value)
  2943. data = self.GetLayerData('vector')
  2944. data['vector'][vtype]['height'] = { 'value' : value,
  2945. 'update' : None }
  2946. # update properties
  2947. event = wxUpdateProperties(data = data)
  2948. wx.PostEvent(self.mapWindow, event)
  2949. self.mapWindow.render['quick'] = True
  2950. self.mapWindow.render['v' + vtype] = True
  2951. self.mapWindow.Refresh(False)
  2952. event.Skip()
  2953. def OnVectorHeightFull(self, event):
  2954. """!Vector height changed, render in full resolution"""
  2955. self.OnVectorHeight(event)
  2956. ## self.OnVectorSurface(event)
  2957. id = event.GetId()
  2958. if id in self.win['vector']['lines']['height'].values():
  2959. vtype = 'lines'
  2960. else:
  2961. vtype = 'points'
  2962. self.mapWindow.render['quick'] = False
  2963. self.mapWindow.render['v' + vtype] = False
  2964. self.mapWindow.Refresh(False)
  2965. def OnVectorHeightText(self, event):
  2966. """!Vector height changed, render in full resolution"""
  2967. # self.OnVectorHeight(event)
  2968. self.OnVectorHeightFull(event)
  2969. def OnVectorSurface(self, event):
  2970. """!Reference surface for vector map (lines/points)"""
  2971. id = event.GetId()
  2972. if id == self.win['vector']['lines']['surface']:
  2973. vtype = 'lines'
  2974. else:
  2975. vtype = 'points'
  2976. checkList = self.FindWindowById(self.win['vector'][vtype]['surface'])
  2977. checked = []
  2978. surfaces = []
  2979. for items in range(checkList.GetCount()):
  2980. checked.append(checkList.IsChecked(items))
  2981. surfaces.append(checkList.GetString(items))
  2982. data = self.GetLayerData('vector')
  2983. data['vector'][vtype]['mode']['surface'] = { 'value' : surfaces,
  2984. 'show' : checked}
  2985. data['vector'][vtype]['mode']['update'] = None
  2986. # update properties
  2987. event = wxUpdateProperties(data = data)
  2988. wx.PostEvent(self.mapWindow, event)
  2989. if self.mapDisplay.IsAutoRendered():
  2990. self.mapWindow.Refresh(False)
  2991. def OnVectorPoints(self, event):
  2992. """!Set vector points mode, apply changes if auto-rendering is enabled"""
  2993. data = self.GetLayerData('vector')
  2994. size = self.FindWindowById(self.win['vector']['points']['size']).GetValue()
  2995. marker = self.FindWindowById(self.win['vector']['points']['marker']).GetSelection()
  2996. # width = self.FindWindowById(self.win['vector']['points']['width']).GetValue()
  2997. for attrb in ('size', 'marker'):
  2998. data['vector']['points'][attrb]['update'] = None
  2999. data['vector']['points']['size']['value'] = size
  3000. # data['vector']['points']['width']['value'] = width
  3001. data['vector']['points']['marker']['value'] = marker
  3002. color = self.FindWindowById(self.win['vector']['points']['color']).GetColour()
  3003. if isinstance(color, csel.ColourSelect):
  3004. pass #color picker not yet instantiated
  3005. else:
  3006. color = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
  3007. data['vector']['points']['color']['update'] = None
  3008. data['vector']['points']['color']['value'] = color
  3009. # update properties
  3010. event = wxUpdateProperties(data = data)
  3011. wx.PostEvent(self.mapWindow, event)
  3012. if self.mapDisplay.IsAutoRendered():
  3013. self.mapWindow.Refresh(False)
  3014. def OnCheckThematic(self, event):
  3015. """!Switch on/off thematic mapping"""
  3016. # can be called with no event to enable/disable button
  3017. if not event:
  3018. ids = (self.win['vector']['points']['thematic']['checkcolor'],
  3019. self.win['vector']['lines']['thematic']['checkcolor'],
  3020. self.win['vector']['points']['thematic']['checksize'],
  3021. self.win['vector']['lines']['thematic']['checkwidth'])
  3022. else:
  3023. ids = (event.GetId(),)
  3024. for id in ids:
  3025. if id in self.win['vector']['points']['thematic'].values():
  3026. vtype = 'points'
  3027. if id == self.win['vector'][vtype]['thematic']['checkcolor']:
  3028. attrType = 'color'
  3029. else:
  3030. attrType = 'size'
  3031. else:
  3032. vtype = 'lines'
  3033. if id == self.win['vector'][vtype]['thematic']['checkcolor']:
  3034. attrType = 'color'
  3035. else:
  3036. attrType = 'width'
  3037. check = self.win['vector'][vtype]['thematic']['check' + attrType]
  3038. button = self.win['vector'][vtype]['thematic']['button' + attrType]
  3039. if self.FindWindowById(check).GetValue():
  3040. checked = True
  3041. else:
  3042. checked = False
  3043. self.FindWindowById(button).Enable(checked)
  3044. data = self.GetLayerData('vector')
  3045. # decide if use GRASSRGB column
  3046. if attrType == 'color':
  3047. name = self.FindWindowById(self.win['vector']['map']).GetValue()
  3048. if not data['vector'][vtype]['thematic']['rgbcolumn']:
  3049. try:
  3050. id = data['vector'][vtype]['object']['id']
  3051. # if GRASSRGB exists and color table doesn't, use GRGB
  3052. if self.HasGRASSRGB(name) and \
  3053. not self._display.CheckColorTable(id = id, type = vtype):
  3054. data['vector'][vtype]['thematic']['rgbcolumn'] = 'GRASSRGB'
  3055. except KeyError:
  3056. pass
  3057. data['vector'][vtype]['thematic']['use' + attrType] = checked
  3058. data['vector'][vtype]['thematic']['update'] = None
  3059. # update properties
  3060. event = wxUpdateProperties(data = data)
  3061. wx.PostEvent(self.mapWindow, event)
  3062. if self.mapDisplay.IsAutoRendered():
  3063. self.mapWindow.Refresh(False)
  3064. def HasGRASSRGB(self, name):
  3065. """!Check if GRASSRGB column exist."""
  3066. column = False
  3067. dbInfo = VectorDBInfo(name)
  3068. if len(dbInfo.layers):
  3069. table = dbInfo.layers[1]['table']
  3070. if 'GRASSRGB' in dbInfo.GetTableDesc(table):
  3071. column = True
  3072. return column
  3073. def OnSetThematic(self, event):
  3074. """!Set options for thematic points"""
  3075. if event.GetId() in self.win['vector']['points']['thematic'].values():
  3076. vtype = 'points'
  3077. else:
  3078. vtype = 'lines'
  3079. if event.GetId() == self.win['vector'][vtype]['thematic']['buttoncolor']:
  3080. attrType = 'color'
  3081. elif vtype == 'points':
  3082. attrType = 'size'
  3083. else:
  3084. attrType = 'width'
  3085. ctable = ThematicVectorTable(self, vtype, attributeType = attrType)
  3086. ctable.CentreOnScreen()
  3087. ctable.Show()
  3088. def UpdateIsosurfButtons(self, list):
  3089. """!Enable/disable buttons 'add', 'delete',
  3090. 'move up', 'move down'"""
  3091. nitems = list.GetCount()
  3092. add = self.parent.FindWindowById(self.win['volume']['btnAdd'])
  3093. delete = self.parent.FindWindowById(self.win['volume']['btnDelete'])
  3094. moveDown = self.parent.FindWindowById(self.win['volume']['btnMoveDown'])
  3095. moveUp = self.parent.FindWindowById(self.win['volume']['btnMoveUp'])
  3096. if nitems >= wxnviz.MAX_ISOSURFS:
  3097. # disable add button on max
  3098. add.Enable(False)
  3099. else:
  3100. add.Enable(True)
  3101. if nitems < 1:
  3102. # disable 'delete' if only one item in the lis
  3103. delete.Enable(False)
  3104. else:
  3105. delete.Enable(True)
  3106. if list.GetSelection() >= nitems - 1:
  3107. # disable 'move-down' if last
  3108. moveDown.Enable(False)
  3109. else:
  3110. moveDown.Enable(True)
  3111. if list.GetSelection() < 1:
  3112. # disable 'move-up' if first
  3113. moveUp.Enable(False)
  3114. else:
  3115. moveUp.Enable(True)
  3116. def OnVolumeMode(self, event):
  3117. """!Change mode isosurfaces/slices"""
  3118. mode = self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection()
  3119. data = self.GetLayerData('volume')['volume']
  3120. sizer = self.isoPanel.GetContainingSizer()
  3121. sizer = self.slicePanel.GetContainingSizer()
  3122. listBox = self.FindWindowByName('listStaticBox')
  3123. if mode == 0:
  3124. sizer.Show(self.isoPanel)
  3125. sizer.Hide(self.slicePanel)
  3126. listBox.SetLabel(" %s " % _("List of isosurfaces"))
  3127. data['draw']['mode']['value'] = 0
  3128. data['draw']['mode']['desc'] = 'isosurface'
  3129. else:
  3130. sizer.Hide(self.isoPanel)
  3131. sizer.Show(self.slicePanel)
  3132. listBox.SetLabel(" %s " % _("List of slices"))
  3133. data['draw']['mode']['value'] = 1
  3134. data['draw']['mode']['desc'] = 'slice'
  3135. if event:
  3136. name = self.FindWindowById(self.win['volume']['map']).GetValue()
  3137. layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
  3138. self.UpdateVolumePage(layer, data, updateName = False)
  3139. sizer.Layout()
  3140. listBox.GetParent().Fit()
  3141. def OnVolumeDrawMode(self, event):
  3142. """!Set isosurface/slice draw mode"""
  3143. self.SetVolumeDrawMode(event.GetSelection())
  3144. def OnVolumeDrawBox(self, event):
  3145. """!Set wire box drawing"""
  3146. data = self.GetLayerData('volume')['volume']
  3147. vid = data['object']['id']
  3148. checked = self.FindWindowById(self.win['volume']['draw']['box']).GetValue()
  3149. self._display.SetVolumeDrawBox(vid, checked)
  3150. data['draw']['box']['enabled'] = checked
  3151. if self.mapDisplay.IsAutoRendered():
  3152. self.mapWindow.Refresh(False)
  3153. def SetVolumeDrawMode(self, selection):
  3154. """!Set isosurface draw mode"""
  3155. data = self.GetLayerData('volume')['volume']
  3156. id = data['object']['id']
  3157. mode = 0
  3158. if selection == 0:
  3159. mode |= wxnviz.DM_FLAT
  3160. else:
  3161. mode |= wxnviz.DM_GOURAUD
  3162. if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
  3163. self._display.SetIsosurfaceMode(id, mode)
  3164. data['draw']['shading']['isosurface']['desc'] = 'gouraud'
  3165. data['draw']['shading']['isosurface']['value'] = mode
  3166. else:
  3167. self._display.SetSliceMode(id, mode)
  3168. data['draw']['shading']['slice']['desc'] = 'flat'
  3169. data['draw']['shading']['slice']['value'] = mode
  3170. if self.mapDisplay.IsAutoRendered():
  3171. self.mapWindow.Refresh(False)
  3172. def OnVolumeResolution(self, event):
  3173. """!Set isosurface/slice draw resolution"""
  3174. self.SetVolumeResolution(event.GetInt())
  3175. def SetVolumeResolution(self, res):
  3176. """!Set isosurface draw resolution"""
  3177. data = self.GetLayerData('volume')['volume']
  3178. id = data['object']['id']
  3179. if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
  3180. self._display.SetIsosurfaceRes(id, res)
  3181. data['draw']['resolution']['isosurface']['value'] = res
  3182. else:
  3183. self._display.SetSliceRes(id, res)
  3184. data['draw']['resolution']['slice']['value'] = res
  3185. if self.mapDisplay.IsAutoRendered():
  3186. self.mapWindow.Refresh(False)
  3187. def OnInOutMode(self, event):
  3188. """!Change isosurfaces mode inout"""
  3189. data = self.GetLayerData('volume')['volume']
  3190. id = data['object']['id']
  3191. isosurfId = self.FindWindowById(self.win['volume']['isosurfs']).GetSelection()
  3192. ret = self._display.SetIsosurfaceInOut(id, isosurfId, event.GetInt())
  3193. if ret == 1:
  3194. data['isosurface'][isosurfId]['inout'] = event.GetInt()
  3195. if self.mapDisplay.IsAutoRendered():
  3196. self.mapWindow.Refresh(False)
  3197. def OnVolumeIsosurfMap(self, event):
  3198. """!Set surface attribute"""
  3199. if self.vetoGSelectEvt:
  3200. self.vetoGSelectEvt = False
  3201. return
  3202. self.SetMapObjAttrb(nvizType = 'volume', winId = event.GetId())
  3203. def OnVolumeCheck(self, event):
  3204. """!Isosurface/slice checked (->load) or unchecked (->unload)"""
  3205. if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
  3206. mode = 'isosurf'
  3207. else:
  3208. mode = 'slice'
  3209. index = event.GetSelection()
  3210. list = self.FindWindowById(self.win['volume'][mode + 's'])
  3211. data = self.GetLayerData('volume')['volume']
  3212. vid = data['object']['id']
  3213. id = event.GetSelection()
  3214. if mode == 'isosurf':
  3215. if list.IsChecked(index):
  3216. if 'transp' in data['isosurface'][id] and\
  3217. data['isosurface'][id]['transp']['map'] is not None:
  3218. if data['isosurface'][id]['transp']['map']:
  3219. map = True
  3220. value = data['isosurface'][id]['transp']['value']
  3221. elif data['isosurface'][id]['transp']['map'] is not None:
  3222. map = False
  3223. value = data['isosurface'][id]['transp']['value']
  3224. self._display.SetIsosurfaceTransp(vid, id, map, value)
  3225. else:
  3226. self._display.SetIsosurfaceTransp(vid, id, False, "0")
  3227. else:
  3228. # disable -> make transparent
  3229. self._display.SetIsosurfaceTransp(vid, id, False, "255")
  3230. else:
  3231. if list.IsChecked(index):
  3232. value = data['slice'][id]['transp']['value']
  3233. self._display.SetSliceTransp(vid, id, value)
  3234. else:
  3235. # disable -> make transparent
  3236. self._display.SetSliceTransp(vid, id, 255)
  3237. if self.mapDisplay.IsAutoRendered():
  3238. self.mapWindow.Refresh(False)
  3239. def OnVolumeSelect(self, event):
  3240. """!Isosurface/Slice item selected"""
  3241. if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
  3242. mode = 'isosurf'
  3243. else:
  3244. mode = 'slice'
  3245. winUp = self.FindWindowById(self.win['volume']['btnMoveUp'])
  3246. winDown = self.FindWindowById(self.win['volume']['btnMoveDown'])
  3247. selection = event.GetSelection()
  3248. if selection == -1:
  3249. return
  3250. elif selection == 0:
  3251. winUp.Enable(False)
  3252. if not winDown.IsEnabled():
  3253. winDown.Enable()
  3254. elif selection == self.FindWindowById(event.GetId()).GetCount() - 1:
  3255. winDown.Enable(False)
  3256. if not winUp.IsEnabled():
  3257. winUp.Enable()
  3258. else:
  3259. if not winDown.IsEnabled():
  3260. winDown.Enable()
  3261. if not winUp.IsEnabled():
  3262. winUp.Enable()
  3263. # update dialog
  3264. name = self.FindWindowById(self.win['volume']['map']).GetValue()
  3265. layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
  3266. if mode == 'isosurf':
  3267. data = self.GetLayerData('volume')['volume']['isosurface'][selection]
  3268. self.UpdateVolumeIsosurfPage(data)
  3269. else:
  3270. data = self.GetLayerData('volume')['volume']['slice'][selection]
  3271. self.UpdateVolumeSlicePage(data)
  3272. def OnVolumeAdd(self, event):
  3273. """!Add new isosurface/slice to the list"""
  3274. if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
  3275. mode = 'isosurf'
  3276. else:
  3277. mode = 'slice'
  3278. list = self.FindWindowById(self.win['volume'][mode + 's'])
  3279. name = self.FindWindowById(self.win['volume']['map']).GetValue()
  3280. layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
  3281. data = self.GetLayerData('volume')['volume']
  3282. id = data['object']['id']
  3283. sel = list.GetSelection()
  3284. if mode == 'isosurf':
  3285. isosurfData = self.mapWindow.nvizDefault.SetIsosurfaceDefaultProp()
  3286. if isosurfData['color']['map']:
  3287. isosurfData['color']['value'] = layer.name
  3288. level = isosurfData['topo']['value'] = round(self._get3dRange(name = layer.name)[0], 2)
  3289. if sel < 0 or sel >= list.GetCount() - 1:
  3290. item = list.Append(item = "%s %s" % (_("Level"), str(level)))
  3291. else:
  3292. list.Insert(item = "%s %s" % (_("Level"), str(level)),
  3293. pos = sel+1) # append
  3294. item = sel + 1
  3295. else:
  3296. sliceData = self.mapWindow.nvizDefault.SetSliceDefaultProp()
  3297. axis = ("X", "Y", "Z")[sliceData['position']['axis']]
  3298. if sel < 0 or sel >= list.GetCount() - 1:
  3299. item = list.Append(item = "%s %s" % (_("Slice parallel to"), axis))
  3300. else:
  3301. list.Insert(item = "%s" % (_("Slice parallel to"), axis),
  3302. pos = sel+1) # append
  3303. item = sel + 1
  3304. list.Check(item)
  3305. list.SetSelection(item)
  3306. if mode == 'isosurf':
  3307. data['isosurface'].insert(item, isosurfData)
  3308. # add isosurface
  3309. self._display.AddIsosurface(id, float(level))
  3310. else:
  3311. data['slice'].insert(item, sliceData)
  3312. # add isosurface
  3313. nslice = self._display.AddSlice(id)
  3314. self._display.SetSlicePosition(id, nslice -1, sliceData['position']['x1'], sliceData['position']['x2'],
  3315. sliceData['position']['y1'], sliceData['position']['y2'],
  3316. sliceData['position']['z1'], sliceData['position']['z2'],
  3317. sliceData['position']['axis'])
  3318. # update properties
  3319. event = wxUpdateProperties(data = data)
  3320. wx.PostEvent(self.mapWindow, event)
  3321. # update buttons
  3322. self.UpdateIsosurfButtons(list)
  3323. if mode == 'isosurf':
  3324. self.UpdateVolumeIsosurfPage(isosurfData)
  3325. else:
  3326. self.UpdateVolumeSlicePage(sliceData)
  3327. if self.mapDisplay.IsAutoRendered():
  3328. self.mapWindow.Refresh(False)
  3329. event.Skip()
  3330. def OnVolumeDelete(self, event):
  3331. """!Remove isosurface/slice from list"""
  3332. if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
  3333. mode = 'isosurf'
  3334. else:
  3335. mode = 'slice'
  3336. list = self.FindWindowById(self.win['volume'][mode + 's'])
  3337. # remove item from list
  3338. id = list.GetSelection()
  3339. list.Delete(id)
  3340. # select last item
  3341. if list.GetCount() > 0:
  3342. list.SetSelection(list.GetCount()-1)
  3343. name = self.FindWindowById(self.win['volume']['map']).GetValue()
  3344. layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
  3345. data = self.GetLayerData('volume')['volume']
  3346. vid = data['object']['id']
  3347. # delete isosurface
  3348. if mode == 'isosurf':
  3349. del data['isosurface'][id]
  3350. self._display.DeleteIsosurface(vid, id)
  3351. else:
  3352. del data['slice'][id]
  3353. self._display.DeleteSlice(vid, id)
  3354. # update buttons
  3355. if list.GetCount() > 0:
  3356. if mode == 'isosurf':
  3357. self.UpdateVolumeIsosurfPage(data['isosurface'][list.GetSelection()])
  3358. else:
  3359. self.UpdateVolumeSlicePage(data['slice'][list.GetSelection()])
  3360. else:
  3361. if mode == 'isosurf':
  3362. self.UpdateVolumeIsosurfPage(data['attribute'])
  3363. else:
  3364. self.UpdateVolumeSlicePage(None)
  3365. self.UpdateIsosurfButtons(list)
  3366. if self.mapDisplay.IsAutoRendered():
  3367. self.mapWindow.Refresh(False)
  3368. event.Skip()
  3369. def OnVolumeMoveUp(self, event):
  3370. """!Move isosurface/slice up in the list"""
  3371. if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
  3372. mode = 'isosurf'
  3373. else:
  3374. mode = 'slice'
  3375. list = self.FindWindowById(self.win['volume'][mode + 's'])
  3376. sel = list.GetSelection()
  3377. if sel < 1:
  3378. return # this should not happen
  3379. name = self.FindWindowById(self.win['volume']['map']).GetValue()
  3380. layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
  3381. data = self.GetLayerData('volume')['volume']
  3382. id = data['object']['id']
  3383. # move item up
  3384. text = list.GetStringSelection()
  3385. list.Insert(item = text, pos = sel-1)
  3386. list.Check(sel-1)
  3387. list.SetSelection(sel-1)
  3388. list.Delete(sel+1)
  3389. if mode == 'isosurf':
  3390. data['isosurface'].insert(sel-1, data['isosurface'][sel])
  3391. del data['isosurface'][sel+1]
  3392. self._display.MoveIsosurface(id, sel, True)
  3393. else:
  3394. data['slice'].insert(sel-1, data['slice'][sel])
  3395. del data['slice'][sel+1]
  3396. self._display.MoveSlice(id, sel, True)
  3397. # update buttons
  3398. self.UpdateIsosurfButtons(list)
  3399. if self.mapDisplay.IsAutoRendered():
  3400. self.mapWindow.Refresh(False)
  3401. event.Skip()
  3402. def OnVolumeMoveDown(self, event):
  3403. """!Move isosurface/slice down in the list"""
  3404. if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
  3405. mode = 'isosurf'
  3406. else:
  3407. mode = 'slice'
  3408. list = self.FindWindowById(self.win['volume'][mode + 's'])
  3409. sel = list.GetSelection()
  3410. if sel >= list.GetCount() - 1:
  3411. return # this should not happen
  3412. name = self.FindWindowById(self.win['volume']['map']).GetValue()
  3413. layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
  3414. data = self.GetLayerData('volume')['volume']
  3415. id = data['object']['id']
  3416. # move item up
  3417. text = list.GetStringSelection()
  3418. list.Insert(item = text, pos = sel+2)
  3419. list.Check(sel+2)
  3420. list.SetSelection(sel+2)
  3421. list.Delete(sel)
  3422. if mode == 'isosurf':
  3423. data['isosurface'].insert(sel+2, data['isosurface'][sel])
  3424. del data['isosurface'][sel]
  3425. self._display.MoveIsosurface(id, sel, False)
  3426. else:
  3427. data['slice'].insert(sel+2, data['slice'][sel])
  3428. del data['slice'][sel]
  3429. self._display.MoveSlice(id, sel, False)
  3430. # update buttons
  3431. self.UpdateIsosurfButtons(list)
  3432. if self.mapDisplay.IsAutoRendered():
  3433. self.mapWindow.Refresh(False)
  3434. event.Skip()
  3435. def OnVolumePositionChanged(self, event):
  3436. """!Volume position changed"""
  3437. self.mapWindow.render['quick'] = False
  3438. self.mapWindow.Refresh(False)
  3439. def OnVolumePosition(self, event):
  3440. """!Volume position"""
  3441. winName = self.__GetWindowName(self.win['volume'], event.GetId())
  3442. if not winName:
  3443. return
  3444. axis = self.FindWindowById(self.win['volume']['position']['axis']).GetSelection()
  3445. value = self.FindWindowById(event.GetId()).GetValue()
  3446. slider = self.FindWindowById(self.win['volume'][winName]['slider'])
  3447. self.AdjustSliderRange(slider = slider, value = value)
  3448. for win in self.win['volume']['position'].itervalues():
  3449. if win in (self.win['volume']['position']['axis'],
  3450. self.win['volume']['position']['reset']):
  3451. continue
  3452. else:
  3453. self.FindWindowById(win).SetValue(value)
  3454. data = self.GetLayerData('volume')
  3455. id = data['volume']['object']['id']
  3456. x, y, z = self._display.GetVolumePosition(id)
  3457. if axis == 0: # x
  3458. x = value
  3459. elif axis == 1: # y
  3460. y = value
  3461. else: # z
  3462. z = value
  3463. data['volume']['position']['x'] = x
  3464. data['volume']['position']['y'] = y
  3465. data['volume']['position']['z'] = z
  3466. data['volume']['position']['update'] = None
  3467. # update properties
  3468. event = wxUpdateProperties(data = data)
  3469. wx.PostEvent(self.mapWindow, event)
  3470. self.mapWindow.render['quick'] = True
  3471. if self.mapDisplay.IsAutoRendered():
  3472. self.mapWindow.Refresh(False)
  3473. def OnVolumeAxis(self, event):
  3474. """!Volume position, axis changed"""
  3475. data = self.GetLayerData('volume')
  3476. id = data['volume']['object']['id']
  3477. axis = self.FindWindowById(self.win['volume']['position']['axis']).GetSelection()
  3478. slider = self.FindWindowById(self.win['volume']['position']['slider'])
  3479. text = self.FindWindowById(self.win['volume']['position']['text'])
  3480. xydim = self._display.GetLongDim()
  3481. zdim = self._display.GetZRange()
  3482. zdim = zdim[1] - zdim[0]
  3483. x, y, z = self._display.GetVolumePosition(id)
  3484. if axis == 0: # x
  3485. slider.SetRange(-3 * xydim, 3 * xydim)
  3486. slider.SetValue(x)
  3487. text.SetValue(x)
  3488. elif axis == 1: # y
  3489. slider.SetRange(-3 * xydim, 3 * xydim)
  3490. slider.SetValue(y)
  3491. text.SetValue(y)
  3492. else: # z
  3493. slider.SetRange(-3 * zdim, 3 * zdim)
  3494. slider.SetValue(z)
  3495. text.SetValue(z)
  3496. def OnVolumePositionText(self, event):
  3497. """!Volume position changed by textctrl"""
  3498. self.OnVolumePosition(event)
  3499. self.OnVolumePositionChanged(None)
  3500. def OnResetVolumePosition(self, event):
  3501. """!Reset position of volume"""
  3502. for win in self.win['volume']['position'].itervalues():
  3503. if win == self.win['volume']['position']['axis']:
  3504. self.FindWindowById(win).SetSelection(0)
  3505. elif win == self.win['volume']['position']['reset']:
  3506. continue
  3507. else:
  3508. self.FindWindowById(win).SetValue(0)
  3509. data = self.GetLayerData('volume')
  3510. data['volume']['position']['x'] = 0
  3511. data['volume']['position']['y'] = 0
  3512. data['volume']['position']['z'] = 0
  3513. data['volume']['position']['update'] = None
  3514. # update properties
  3515. event = wxUpdateProperties(data = data)
  3516. wx.PostEvent(self.mapWindow, event)
  3517. if self.mapDisplay.IsAutoRendered():
  3518. self.mapWindow.Refresh(False)
  3519. def OnVolumeSliceAxes(self, event):
  3520. """!Slice axis changed"""
  3521. self.UpdateSliceLabels()
  3522. data = self.GetLayerData('volume')
  3523. list = self.FindWindowById(self.win['volume']['slices'])
  3524. sel = list.GetSelection()
  3525. if sel < 0:
  3526. return
  3527. axis = self.FindWindowById(self.win['volume']['slice']['axes']).GetSelection()
  3528. data['volume']['slice'][sel]['position']['axis'] = axis
  3529. data['volume']['slice'][sel]['position']['update'] = None
  3530. axis = ("X", "Y", "Z")[axis]
  3531. list.SetString(sel, "%s %s" % (_("Slice parallel to"), axis))
  3532. list.Check(sel)
  3533. # update properties
  3534. event = wxUpdateProperties(data = data)
  3535. wx.PostEvent(self.mapWindow, event)
  3536. if self.mapDisplay.IsAutoRendered():
  3537. self.mapWindow.Refresh(False)
  3538. def OnSliceTransparency(self, event):
  3539. """!Slice transparency changed"""
  3540. data = self.GetLayerData('volume')
  3541. list = self.FindWindowById(self.win['volume']['slices'])
  3542. sel = list.GetSelection()
  3543. if sel < 0:
  3544. return
  3545. val = self.FindWindowById(self.win['volume']['slice']['transp']).GetValue()
  3546. data['volume']['slice'][sel]['transp']['value'] = self._getPercent(val, toPercent = False)
  3547. data['volume']['slice'][sel]['transp']['update'] = None
  3548. # update properties
  3549. event = wxUpdateProperties(data = data)
  3550. wx.PostEvent(self.mapWindow, event)
  3551. if self.mapDisplay.IsAutoRendered():
  3552. self.mapWindow.Refresh(False)
  3553. def OnSliceReset(self, event):
  3554. """!Slice position reset"""
  3555. data = self.GetLayerData('volume')
  3556. list = self.FindWindowById(self.win['volume']['slices'])
  3557. sel = list.GetSelection()
  3558. if sel < 0:
  3559. return
  3560. for coord, val in zip(('x1', 'x2', 'y1', 'y2', 'z1', 'z2'),(0, 1, 0, 1, 0, 1, 0)):
  3561. data['volume']['slice'][sel]['position'][coord] = val
  3562. data['volume']['slice'][sel]['position']['update'] = None
  3563. self.UpdateVolumeSlicePage(data['volume']['slice'][sel])
  3564. # update properties
  3565. event = wxUpdateProperties(data = data)
  3566. wx.PostEvent(self.mapWindow, event)
  3567. if self.mapDisplay.IsAutoRendered():
  3568. self.mapWindow.Refresh(False)
  3569. def OnSlicePositionChange(self, event):
  3570. """!Slice position is changing"""
  3571. data = self.GetLayerData('volume')
  3572. list = self.FindWindowById(self.win['volume']['slices'])
  3573. sel = list.GetSelection()
  3574. if sel < 0:
  3575. return
  3576. win = self.win['volume']['slice']
  3577. winId = event.GetId()
  3578. value = event.GetInt()/100.
  3579. for coord in ('x1', 'x2', 'y1', 'y2', 'z1', 'z2'):
  3580. if win['slider_' + coord] == winId:
  3581. data['volume']['slice'][sel]['position'][coord] = value
  3582. data['volume']['slice'][sel]['position']['update'] = None
  3583. break
  3584. self.mapWindow.render['quick'] = True
  3585. # update properties
  3586. event = wxUpdateProperties(data = data)
  3587. wx.PostEvent(self.mapWindow, event)
  3588. if self.mapDisplay.IsAutoRendered():
  3589. self.mapWindow.Refresh(False)
  3590. def OnSlicePositionChanged(self, event):
  3591. """!Slice position is changed"""
  3592. self.mapWindow.render['quick'] = False
  3593. if self.mapDisplay.IsAutoRendered():
  3594. self.mapWindow.Refresh(False)
  3595. def OnCPlaneSelection(self, event):
  3596. """!Cutting plane selected"""
  3597. plane = self.FindWindowById(self.win['cplane']['planes']).GetStringSelection()
  3598. try:
  3599. planeIndex = int(plane.split()[-1]) - 1
  3600. self.EnablePage("cplane", enabled = True)
  3601. except:
  3602. planeIndex = -1
  3603. self.EnablePage("cplane", enabled = False)
  3604. self.mapWindow.SelectCPlane(planeIndex)
  3605. if self.mapDisplay.IsAutoRendered():
  3606. self.mapWindow.Refresh(False)
  3607. self.UpdateCPlanePage(planeIndex)
  3608. def OnCPlaneChanging(self, event):
  3609. """!Cutting plane is changing"""
  3610. plane = self.FindWindowById(self.win['cplane']['planes']).GetStringSelection()
  3611. try:
  3612. planeIndex = int(plane.split()[-1]) - 1
  3613. except:#TODO disabled page
  3614. planeIndex = -1
  3615. if event.GetId() in (self.win['cplane']['rotation']['rot'].values() +
  3616. self.win['cplane']['rotation']['tilt'].values()):
  3617. action = 'rotation'
  3618. else:
  3619. action = 'position'
  3620. data = self.mapWindow.cplanes[planeIndex][action]
  3621. self.OnScroll(event, self.win['cplane'][action], data)
  3622. self.mapWindow.render['quick'] = True
  3623. event = wxUpdateCPlane(update = (action,), current = planeIndex)
  3624. wx.PostEvent(self.mapWindow, event)
  3625. if self.mapDisplay.IsAutoRendered():
  3626. self.mapWindow.Refresh(False)
  3627. def OnCPlaneChangeDone(self, event):
  3628. """!Cutting plane change done"""
  3629. self.mapWindow.render['quick'] = False
  3630. if self.mapDisplay.IsAutoRendered():
  3631. self.mapWindow.Refresh(False)
  3632. def OnCPlaneChangeText(self, event):
  3633. """!Cutting plane changed by textctrl"""
  3634. for axis in ('x', 'y', 'z'):
  3635. if event.GetId() == self.win['cplane']['position'][axis]['text']:
  3636. value = self.FindWindowById(event.GetId()).GetValue()
  3637. slider = self.FindWindowById(self.win['cplane']['position'][axis]['slider'])
  3638. self.AdjustSliderRange(slider = slider, value = value)
  3639. self.OnCPlaneChanging(event = event)
  3640. self.OnCPlaneChangeDone(None)
  3641. def OnCPlaneShading(self, event):
  3642. """!Cutting plane shading changed"""
  3643. shading = self.FindWindowById(self.win['cplane']['shading']).GetSelection()
  3644. plane = self.FindWindowById(self.win['cplane']['planes']).GetStringSelection()
  3645. try:
  3646. planeIndex = int(plane.split()[-1]) - 1
  3647. except:#TODO disabled page
  3648. planeIndex = -1
  3649. self.mapWindow.cplanes[planeIndex]['shading'] = shading
  3650. event = wxUpdateCPlane(update = ('shading',), current = planeIndex)
  3651. wx.PostEvent(self.mapWindow, event)
  3652. self.OnCPlaneChangeDone(None)
  3653. def OnCPlaneReset(self, event):
  3654. """!Reset current cutting plane"""
  3655. plane = self.FindWindowById(self.win['cplane']['planes']).GetStringSelection()
  3656. try:
  3657. planeIndex = int(plane.split()[-1]) - 1
  3658. except:#TODO disabled page
  3659. planeIndex = -1
  3660. self.mapWindow.cplanes[planeIndex] = copy.deepcopy(UserSettings.Get(group = 'nviz',
  3661. key = 'cplane'))
  3662. event = wxUpdateCPlane(update = ('position','rotation','shading'), current = planeIndex)
  3663. wx.PostEvent(self.mapWindow, event)
  3664. self.OnCPlaneChangeDone(None)
  3665. self.UpdateCPlanePage(planeIndex)
  3666. def OnDecorationPlacement(self, event):
  3667. """!Place an arrow/scalebar by clicking on display"""
  3668. if event.GetId() == self.win['decoration']['arrow']['place']:
  3669. type = 'arrow'
  3670. elif event.GetId() == self.win['decoration']['scalebar']['place']:
  3671. type = 'scalebar'
  3672. else: return
  3673. if event.GetInt():
  3674. self.mapDisplay.Raise()
  3675. self.mapWindow.mouse['use'] = type
  3676. self.mapWindow.SetCursor(self.mapWindow.cursors["cross"])
  3677. else:
  3678. self.mapWindow.mouse['use'] = 'default'
  3679. self.mapWindow.SetCursor(self.mapWindow.cursors["default"])
  3680. def OnArrowDelete(self, event):
  3681. """!Delete arrow"""
  3682. self._display.DeleteArrow()
  3683. self.mapWindow.decoration['arrow']['show'] = False
  3684. self.FindWindowById( self.win['decoration']['arrow']['delete']).Disable()
  3685. self.mapWindow.Refresh(False)
  3686. def OnScalebarDelete(self, event):
  3687. """!Delete scalebar"""
  3688. choice = self.FindWindowById(self.win['decoration']['scalebar']['choice'])
  3689. choiceIndex = choice.GetSelection()
  3690. index = choice.GetClientData(choiceIndex)
  3691. if index == wx.NOT_FOUND:
  3692. return
  3693. self._display.DeleteScalebar(id = index)
  3694. self.FindWindowById(self.win['decoration']['scalebar']['choice']).Delete(choiceIndex)
  3695. if not choice.IsEmpty():
  3696. choice.SetSelection(choice.GetCount() - 1)
  3697. self.DisableScalebarControls()
  3698. self.mapWindow.Refresh(False)
  3699. def AddScalebar(self, scalebarNum):
  3700. choice = self.FindWindowById(self.win['decoration']['scalebar']['choice'])
  3701. choice.Append(_("Scalebar %d") % (scalebarNum + 1), scalebarNum)
  3702. choice.SetSelection(choice.GetCount() - 1)
  3703. self.DisableScalebarControls()
  3704. def AddArrow(self):
  3705. self.FindWindowById( self.win['decoration']['arrow']['delete']).Enable()
  3706. def DisableScalebarControls(self):
  3707. choice = self.FindWindowById(self.win['decoration']['scalebar']['choice'])
  3708. self.FindWindowById(self.win['decoration']['scalebar']['delete']).Enable(not choice.IsEmpty())
  3709. self.FindWindowById(self.win['decoration']['scalebar']['choice']).Enable(not choice.IsEmpty())
  3710. def OnDecorationProp(self, event):
  3711. """!Set arrow/scalebar properties"""
  3712. if event.GetId() in self.win['decoration']['arrow'].values():
  3713. type = 'arrow'
  3714. elif event.GetId() in self.win['decoration']['scalebar'].values():
  3715. type = 'scalebar'
  3716. else: return
  3717. color = self.FindWindowById(self.win['decoration'][type]['color']).GetValue()
  3718. size = self.FindWindowById(self.win['decoration'][type]['size']).GetValue()
  3719. if type == 'arrow':
  3720. self.mapWindow.decoration[type]['color'] = self._getColorString(color)
  3721. self.mapWindow.decoration[type]['size'] = size
  3722. elif type == 'scalebar'and self.mapWindow.decoration['scalebar']:
  3723. for scalebar in self.mapWindow.decoration[type]:
  3724. scalebar['color'] = self._getColorString(color)
  3725. scalebar['size'] = size
  3726. if type == 'arrow' and self.mapWindow.decoration['arrow']['show']:
  3727. self._display.SetArrow(self.mapWindow.decoration['arrow']['position']['x'],
  3728. self.mapWindow.decoration['arrow']['position']['y'],
  3729. self.mapWindow.decoration['arrow']['size'],
  3730. self.mapWindow.decoration['arrow']['color'])
  3731. self._display.DrawArrow()
  3732. elif type == 'scalebar' and self.mapWindow.decoration['scalebar']:
  3733. ids = []
  3734. choice = self.FindWindowById(self.win['decoration']['scalebar']['choice'])
  3735. for index in range(choice.GetCount()):
  3736. ids.append(choice.GetClientData(index))
  3737. for scalebar in self.mapWindow.decoration[type]:
  3738. if scalebar['id'] in ids:
  3739. self._display.SetScalebar(scalebar['id'],
  3740. scalebar['position']['x'],
  3741. scalebar['position']['y'],
  3742. scalebar['size'],
  3743. scalebar['color'])
  3744. self._display.DrawScalebar()
  3745. self.mapWindow.Refresh(False)
  3746. def UpdatePage(self, pageId):
  3747. """!Update dialog (selected page)"""
  3748. self.pageChanging = True
  3749. Debug.msg(1, "NvizToolWindow.UpdatePage(): %s", pageId)
  3750. if pageId == 'view':
  3751. self.SetPage('view')
  3752. hmin = self.mapWindow.iview['height']['min']
  3753. hmax = self.mapWindow.iview['height']['max']
  3754. hval = self.mapWindow.iview['height']['value']
  3755. zmin = self.mapWindow.view['z-exag']['min']
  3756. zmax = self.mapWindow.view['z-exag']['max']
  3757. zval = self.mapWindow.view['z-exag']['value']
  3758. for control in ('slider','text'):
  3759. self.FindWindowById(self.win['view']['height'][control]).SetRange(
  3760. hmin,hmax)
  3761. self.FindWindowById(self.win['view']['z-exag'][control]).SetRange(
  3762. zmin, zmax)
  3763. self.FindWindowById(self.win['view']['height'][control]).SetValue(hval)
  3764. self.FindWindowById(self.win['view']['z-exag'][control]).SetValue(zval)
  3765. self.FindWindowById(self.win['view']['background']['color']).SetColour(\
  3766. self.mapWindow.view['background']['color'])
  3767. tval = self.mapWindow.view['twist']['value']
  3768. pval = self.mapWindow.view['persp']['value']
  3769. for control in ('slider','text'):
  3770. self.FindWindowById(self.win['view']['twist'][control]).SetValue(tval)
  3771. self.FindWindowById(self.win['view']['persp'][control]).SetValue(pval)
  3772. elif pageId in ('surface', 'vector', 'volume'):
  3773. name = self.FindWindowById(self.win[pageId]['map']).GetValue()
  3774. data = self.GetLayerData(pageId)
  3775. if data:
  3776. if pageId == 'surface':
  3777. layer = self.mapWindow.GetLayerByName(name, mapType = 'raster')
  3778. self.UpdateSurfacePage(layer, data['surface'])
  3779. elif pageId == 'vector':
  3780. layer = self.mapWindow.GetLayerByName(name, mapType = 'vector')
  3781. self.UpdateVectorPage(layer, data['vector'])
  3782. elif pageId == 'volume':
  3783. layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
  3784. self.UpdateVolumePage(layer, data['volume'])
  3785. elif pageId == 'light':
  3786. zval = self.mapWindow.light['position']['z']
  3787. bval = self.mapWindow.light['bright']
  3788. aval = self.mapWindow.light['ambient']
  3789. for control in ('slider','text'):
  3790. self.FindWindowById(self.win['light']['z'][control]).SetValue(zval)
  3791. self.FindWindowById(self.win['light']['bright'][control]).SetValue(bval)
  3792. self.FindWindowById(self.win['light']['ambient'][control]).SetValue(aval)
  3793. self.FindWindowById(self.win['light']['color']).SetColour(self.mapWindow.light['color'])
  3794. self.FindWindowById(self.win['light']['position']).PostDraw()
  3795. elif pageId == 'fringe':
  3796. win = self.FindWindowById(self.win['fringe']['map'])
  3797. win.SetValue(self.FindWindowById(self.win['surface']['map']).GetValue())
  3798. elif pageId == 'decoration':
  3799. win = self.FindWindowById(self.win['decoration']['arrow']['size'])
  3800. win.SetValue(self.mapWindow.decoration['arrow']['size'])
  3801. win = self.FindWindowById(self.win['decoration']['scalebar']['size'])
  3802. win.SetValue(self.mapWindow._getDecorationSize())
  3803. elif pageId == 'constant':
  3804. if self.mapWindow.constants:
  3805. surface = self.FindWindowById(self.win['constant']['surface'])
  3806. for item in self.mapWindow.constants:
  3807. surface.Append(_("constant#") + str(item['constant']['object']['name']))
  3808. surface.SetSelection(0)
  3809. self.OnConstantSelection(None)
  3810. self.EnablePage('constant', True)
  3811. elif pageId == 'cplane':
  3812. count = self._display.GetCPlanesCount()
  3813. choices = [_("None"),]
  3814. for plane in range(count):
  3815. choices.append("%s %i" % (_("Plane"), plane+1))
  3816. self.FindWindowById(self.win['cplane']['planes']).SetItems(choices)
  3817. current = 0
  3818. for i, cplane in enumerate(self.mapWindow.cplanes):
  3819. if cplane['on']:
  3820. current = i + 1
  3821. self.FindWindowById(self.win['cplane']['planes']).SetSelection(current)
  3822. xyRange, zRange = self._display.GetXYRange(), self._display.GetZRange()
  3823. if xyRange > 0: # GTK warning
  3824. self.FindWindowById(self.win['cplane']['position']['x']['slider']).SetRange(
  3825. -xyRange/2., xyRange/2.)
  3826. self.FindWindowById(self.win['cplane']['position']['y']['slider']).SetRange(
  3827. -xyRange/2., xyRange/2.)
  3828. if zRange[0] - zRange[1] > 0:
  3829. self.FindWindowById(self.win['cplane']['position']['z']['slider']).SetRange(zRange[0], zRange[1])
  3830. self.FindWindowById(self.win['cplane']['position']['z']['slider']).SetValue(zRange[0])
  3831. self.FindWindowById(self.win['cplane']['position']['z']['text']).SetValue(zRange[0])
  3832. self.OnCPlaneSelection(None)
  3833. elif pageId == 'animation':
  3834. self.UpdateAnimationPage()
  3835. self.Update()
  3836. self.pageChanging = False
  3837. def UpdateAnimationPage(self):
  3838. """!Update animation page"""
  3839. # wrap help text according to tool window
  3840. help = self.FindWindowById(self.win['anim']['help'])
  3841. width = help.GetGrandParent().GetSizeTuple()[0]
  3842. help.Wrap(width - 15)
  3843. anim = self.mapWindow.GetAnimation()
  3844. if anim.Exists():
  3845. self.FindWindowById(self.win['anim']['play']).Enable()
  3846. else:
  3847. self.UpdateFrameIndex(index = 0)
  3848. self.UpdateFrameCount()
  3849. self.FindWindowById(self.win['anim']['play']).Disable()
  3850. self.FindWindowById(self.win['anim']['record']).Enable()
  3851. self.FindWindowById(self.win['anim']['pause']).Disable()
  3852. self.FindWindowById(self.win['anim']['stop']).Disable()
  3853. self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
  3854. self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
  3855. def UpdateCPlanePage(self, index):
  3856. """!Update widgets according to selected clip plane"""
  3857. if index == -1:
  3858. return
  3859. data = self.mapWindow.cplanes[index]
  3860. for widget in ('text', 'slider'):
  3861. for axes in ('x', 'y', 'z'):
  3862. self.FindWindowById(self.win['cplane']['position'][axes][widget]).SetValue(data['position'][axes])
  3863. for each in ('tilt', 'rot'):
  3864. self.FindWindowById(self.win['cplane']['rotation'][each][widget]).SetValue(data['rotation'][each])
  3865. self.FindWindowById(self.win['cplane']['shading']).SetSelection(data['shading'])
  3866. def UpdateSurfacePage(self, layer, data, updateName = True):
  3867. """!Update surface page"""
  3868. desc = grass.raster_info(layer.name)['title']
  3869. if updateName:
  3870. self.FindWindowById(self.win['surface']['map']).SetValue(layer.name)
  3871. self.FindWindowById(self.win['surface']['desc']).SetLabel(desc)
  3872. # attributes
  3873. if layer and layer.type == 'raster':
  3874. self.vetoGSelectEvt = True
  3875. self.FindWindowById(self.win['surface']['color']['map']).SetValue(layer.name)
  3876. else:
  3877. self.FindWindowById(self.win['surface']['color']['map']).SetValue('')
  3878. self.SetMapObjUseMap(nvizType = 'surface',
  3879. attrb = 'color', map = True) # -> map
  3880. if 'color' in data['attribute']:
  3881. value = data['attribute']['color']['value']
  3882. if data['attribute']['color']['map']:
  3883. self.FindWindowById(self.win['surface']['color']['map']).SetValue(value)
  3884. else: # constant
  3885. color = map(int, value.split(':'))
  3886. self.FindWindowById(self.win['surface']['color']['const']).SetColour(color)
  3887. self.SetMapObjUseMap(nvizType = 'surface',
  3888. attrb = 'color', map = data['attribute']['color']['map'])
  3889. self.SetMapObjUseMap(nvizType = 'surface',
  3890. attrb = 'shine', map = data['attribute']['shine']['map'])
  3891. value = data['attribute']['shine']['value']
  3892. if data['attribute']['shine']['map']:
  3893. self.FindWindowById(self.win['surface']['shine']['map']).SetValue(value)
  3894. else:
  3895. self.FindWindowById(self.win['surface']['shine']['const']).SetValue(self._getPercent(value))
  3896. if 'transp' in data['attribute']:
  3897. value = data['attribute']['transp']['value']
  3898. if data['attribute']['transp']['map']:
  3899. self.FindWindowById(self.win['surface']['color']['map']).SetValue(value)
  3900. else:
  3901. self.FindWindowById(self.win['surface']['transp']['const']).SetValue(self._getPercent(value))
  3902. self.SetMapObjUseMap(nvizType = 'surface', attrb = 'transp', map = data['attribute']['transp']['map'])
  3903. else:
  3904. self.SetMapObjUseMap(nvizType = 'surface', attrb = 'transp', map = None)
  3905. #
  3906. # draw
  3907. #
  3908. for control, drawData in data['draw'].iteritems():
  3909. if control == 'all': # skip 'all' property
  3910. continue
  3911. if control == 'resolution':
  3912. self.FindWindowById(self.win['surface']['draw']['res-coarse']).SetValue(drawData['coarse'])
  3913. self.FindWindowById(self.win['surface']['draw']['res-fine']).SetValue(drawData['fine'])
  3914. continue
  3915. if control == 'mode':
  3916. if drawData['desc']['mode'] == 'coarse':
  3917. self.FindWindowById(self.win['surface']['draw']['mode']).SetSelection(0)
  3918. elif drawData['desc']['mode'] == 'fine':
  3919. self.FindWindowById(self.win['surface']['draw']['mode']).SetSelection(1)
  3920. else: # both
  3921. self.FindWindowById(self.win['surface']['draw']['mode']).SetSelection(2)
  3922. if drawData['desc']['style'] == 'wire':
  3923. self.FindWindowById(self.win['surface']['draw']['style']).SetSelection(0)
  3924. else: # surface
  3925. self.FindWindowById(self.win['surface']['draw']['style']).SetSelection(1)
  3926. if drawData['desc']['shading'] == 'flat':
  3927. self.FindWindowById(self.win['surface']['draw']['shading']).SetSelection(0)
  3928. else: # gouraud
  3929. self.FindWindowById(self.win['surface']['draw']['shading']).SetSelection(1)
  3930. continue
  3931. value = drawData['value']
  3932. win = self.FindWindowById(self.win['surface']['draw'][control])
  3933. name = win.GetName()
  3934. if name == "selection":
  3935. win.SetSelection(value)
  3936. elif name == "colour":
  3937. color = map(int, value.split(':'))
  3938. win.SetColour(color)
  3939. else:
  3940. win.SetValue(value)
  3941. #
  3942. # position
  3943. #
  3944. dim = self._display.GetLongDim()
  3945. self.FindWindowById(self.win['surface']['position']['slider']).SetRange(-2 * dim, 2 * dim)
  3946. if 'x' in data['position']:
  3947. xval = data['position']['x']
  3948. self.FindWindowById(self.win['surface']['position']['axis']).SetSelection(0)
  3949. for control in ('slider','text'):
  3950. self.FindWindowById(self.win['surface']['position'][control]).SetValue(xval)
  3951. # enable/disable res widget + set draw mode
  3952. self.OnSurfaceMode(event = None)
  3953. def VectorInfo(self, layer):
  3954. """!Get number of points/lines
  3955. @param layer MapLayer instance
  3956. @return num of points/features (expect of points)
  3957. @return None
  3958. """
  3959. vInfo = grass.vector_info_topo(layer.GetName())
  3960. if not vInfo:
  3961. return None
  3962. nprimitives = 0
  3963. for key, value in vInfo.iteritems():
  3964. if key in ('points',
  3965. 'lines',
  3966. 'boundaries',
  3967. 'centroids',
  3968. 'faces',
  3969. 'kernels'):
  3970. nprimitives += value
  3971. return (vInfo['points'], vInfo['lines'], nprimitives, vInfo['map3d'])
  3972. def UpdateVectorPage(self, layer, data, updateName = True):
  3973. """!Update vector page"""
  3974. npoints, nlines, nfeatures, mapIs3D = self.VectorInfo(layer)
  3975. if mapIs3D:
  3976. desc = _("Vector map is 3D")
  3977. enable = False
  3978. else:
  3979. desc = _("Vector map is 2D")
  3980. enable = True
  3981. desc += " - " + _("%(features)d features (%(points)d points)") % \
  3982. { 'features' : nfeatures, 'points' : npoints }
  3983. if updateName:
  3984. self.FindWindowById(self.win['vector']['map']).SetValue(layer.name)
  3985. self.FindWindowById(self.win['vector']['desc']).SetLabel(desc)
  3986. self.FindWindowById(self.win['vector']['lines']['flat']).Enable(enable)
  3987. for v in ('lines', 'points'):
  3988. self.FindWindowById(self.win['vector'][v]['surface']).Enable(enable)
  3989. self.FindWindowById(self.win['vector'][v]['height']['slider']).Enable(enable)
  3990. self.FindWindowById(self.win['vector'][v]['height']['text']).Enable(enable)
  3991. if data[v]['thematic']['usecolor']:
  3992. check = self.FindWindowById(self.win['vector'][v]['thematic']['checkcolor'])
  3993. check.SetValue(data[v]['thematic']['usecolor'])
  3994. if 'usesize' in data[v]['thematic'] and data[v]['thematic']['usesize']:
  3995. check = self.FindWindowById(self.win['vector'][v]['thematic']['checksize'])
  3996. check.SetValue(data[v]['thematic']['usesize'])
  3997. elif 'usewidth' in data[v]['thematic'] and data[v]['thematic']['usewidth']:
  3998. check = self.FindWindowById(self.win['vector'][v]['thematic']['checkwidth'])
  3999. check.SetValue(data[v]['thematic']['usewidth'])
  4000. self.OnCheckThematic(None)
  4001. #
  4002. # lines
  4003. #
  4004. showLines = self.FindWindowById(self.win['vector']['lines']['show'])
  4005. if 'object' in data['lines']:
  4006. showLines.SetValue(True)
  4007. else:
  4008. showLines.SetValue(False)
  4009. if nlines > 0:
  4010. showLines.Enable(True)
  4011. else:
  4012. showLines.Enable(False)
  4013. self.UpdateVectorShow('lines',
  4014. showLines.IsChecked())
  4015. width = self.FindWindowById(self.win['vector']['lines']['width'])
  4016. width.SetValue(data['lines']['width']['value'])
  4017. color = self.FindWindowById(self.win['vector']['lines']['color'])
  4018. color.SetValue(map(int, data['lines']['color']['value'].split(':')))
  4019. for vtype in ('lines', 'points'):
  4020. if vtype == 'lines':
  4021. display = self.FindWindowById(self.win['vector']['lines']['flat'])
  4022. if data[vtype]['mode']['type'] == 'flat':
  4023. display.SetSelection(1)
  4024. else:
  4025. display.SetSelection(0)
  4026. if data[vtype]['mode']['type'] == 'surface':
  4027. rasters = self.mapWindow.GetLayerNames('raster')
  4028. constants = self.mapWindow.GetLayerNames('constant')
  4029. surfaces = rasters + constants
  4030. surfaceWin = self.FindWindowById(self.win['vector'][vtype]['surface'])
  4031. surfaceWin.SetItems(surfaces)
  4032. for idx, surface in enumerate(surfaces):
  4033. try:# TODO fix this mess
  4034. selected = data[vtype]['mode']['surface']['show'][idx]
  4035. except (TypeError, IndexError, KeyError):
  4036. selected = False
  4037. surfaceWin.Check(idx, selected)
  4038. for type in ('slider', 'text'):
  4039. win = self.FindWindowById(self.win['vector']['lines']['height'][type])
  4040. win.SetValue(data['lines']['height']['value'])
  4041. #
  4042. # points
  4043. #
  4044. showPoints = self.FindWindowById(self.win['vector']['points']['show'])
  4045. if 'object' in data['points']:
  4046. showPoints.SetValue(True)
  4047. else:
  4048. showPoints.SetValue(False)
  4049. if npoints > 0:
  4050. showPoints.Enable(True)
  4051. else:
  4052. showPoints.Enable(False)
  4053. self.UpdateVectorShow('points',
  4054. showPoints.IsChecked())
  4055. # size, width, marker, color
  4056. for prop in ('size', 'marker', 'color'):
  4057. win = self.FindWindowById(self.win['vector']['points'][prop])
  4058. name = win.GetName()
  4059. if name == 'selection':
  4060. win.SetSelection(data['points'][prop]['value'])
  4061. elif name == 'color':
  4062. color = map(int, data['points'][prop]['value'].split(':'))
  4063. win.SetValue(color)
  4064. else:
  4065. win.SetValue(data['points'][prop]['value'])
  4066. ## self.OnCheckThematic(None)
  4067. # height
  4068. for type in ('slider', 'text'):
  4069. win = self.FindWindowById(self.win['vector']['points']['height'][type])
  4070. win.SetValue(data['points']['height']['value'])
  4071. def UpdateVolumePage(self, layer, data, updateName = True):
  4072. """!Update volume page"""
  4073. if updateName:
  4074. self.FindWindowById(self.win['volume']['map']).SetValue(layer.name)
  4075. # draw
  4076. for control, idata in data['draw'].iteritems():
  4077. if control == 'all': # skip 'all' property
  4078. continue
  4079. win = self.FindWindowById(self.win['volume']['draw'][control])
  4080. if control == 'mode':
  4081. value = data['draw']['mode']['value']
  4082. if control == 'shading':
  4083. if data['draw']['shading'][data['draw']['mode']['desc']]['desc'] == 'flat':
  4084. value = 0
  4085. else:
  4086. value = 1
  4087. if control == 'resolution':
  4088. value = idata[data['draw']['mode']['desc']]['value']
  4089. if control == 'box':
  4090. value = idata['enabled']
  4091. if win.GetName() == "selection":
  4092. win.SetSelection(value)
  4093. else:
  4094. win.SetValue(value)
  4095. self.OnVolumeMode(None)
  4096. id = data['object']['id']
  4097. if data['draw']['mode']['desc'] == 'isosurface':
  4098. self._display.SetIsosurfaceMode(id, data['draw']['shading']['isosurface']['value'])
  4099. self._display.SetIsosurfaceRes(id, data['draw']['resolution']['isosurface']['value'])
  4100. else:
  4101. self._display.SetSliceMode(id, data['draw']['shading']['slice']['value'])
  4102. self._display.SetSliceRes(id, data['draw']['resolution']['slice']['value'])
  4103. box = self.FindWindowById(self.win['volume']['isosurfs'])
  4104. if data['draw']['mode']['desc'] == 'isosurface':
  4105. isosurfaces = []
  4106. for iso in data['isosurface']:
  4107. level = iso['topo']['value']
  4108. isosurfaces.append("%s %s" % (_("Level"), level))
  4109. box.Set(isosurfaces)
  4110. for i in range(len(isosurfaces)):
  4111. box.Check(i)
  4112. if data['isosurface']:
  4113. box.SetSelection(0)
  4114. self.UpdateVolumeIsosurfPage(data['isosurface'][0])
  4115. else:
  4116. self.UpdateVolumeIsosurfPage(data['attribute'])
  4117. else:
  4118. slices = []
  4119. for slice in data['slice']:
  4120. axis = ("X", "Y", "Z")[slice['position']['axis']]
  4121. slices.append("%s %s" % (_("Slice parallel to"), axis))
  4122. box.Set(slices)
  4123. for i in range(len(slices)):
  4124. box.Check(i)
  4125. if data['slice']:
  4126. box.SetSelection(0)
  4127. self.UpdateVolumeSlicePage(data['slice'][0])
  4128. else:
  4129. self.UpdateVolumeSlicePage(None)
  4130. #
  4131. # position
  4132. #
  4133. if 'x' in data['position']:
  4134. xval = data['position']['x']
  4135. self.FindWindowById(self.win['volume']['position']['axis']).SetSelection(0)
  4136. for control in ('slider','text'):
  4137. self.FindWindowById(self.win['volume']['position'][control]).SetValue(xval)
  4138. # set topo range
  4139. mapRange = self._get3dRange(name = layer.name)
  4140. desc = self.FindWindowById(self.win['volume']['desc'])
  4141. desc.SetLabel("%s %.2f - %.2f" % (_("range:"), mapRange[0], mapRange[1]))
  4142. def UpdateVolumeIsosurfPage(self, data):
  4143. """!Update dialog -- isosurface attributes"""
  4144. #
  4145. # isosurface attributes
  4146. #
  4147. for attrb in ('topo', 'color', 'mask',
  4148. 'transp', 'shine'):
  4149. # skip empty attributes
  4150. if attrb not in data:
  4151. self.SetMapObjUseMap(nvizType = 'volume', attrb = attrb, map = None)
  4152. continue
  4153. value = data[attrb]['value']
  4154. if attrb == 'color':
  4155. if data[attrb]['map']:
  4156. self.FindWindowById(self.win['volume'][attrb]['map']).SetValue(value)
  4157. else: # constant
  4158. color = map(int, value.split(':'))
  4159. self.FindWindowById(self.win['volume'][attrb]['const']).SetColour(color)
  4160. else:
  4161. if data[attrb]['map']:
  4162. self.vetoGSelectEvt = True
  4163. win = self.FindWindowById(self.win['volume'][attrb]['map'])
  4164. win.SetValue(value)
  4165. else:
  4166. if value:
  4167. win = self.FindWindowById(self.win['volume'][attrb]['const'])
  4168. if attrb == 'topo':
  4169. win.SetValue(float(value))
  4170. else:
  4171. win.SetValue(self._getPercent(value))
  4172. self.SetMapObjUseMap(nvizType = 'volume',
  4173. attrb = attrb, map = data[attrb]['map'])
  4174. # set inout
  4175. if 'inout' in data:
  4176. self.FindWindowById(self.win['volume']['inout']).SetValue(data['inout'])
  4177. def UpdateVolumeSlicePage(self, data):
  4178. """!Update dialog -- slice attributes"""
  4179. if data:
  4180. for coord in ('x1', 'x2', 'y1', 'y2', 'z1', 'z2'):
  4181. win = self.FindWindowById(self.win['volume']['slice']['slider_' + coord])
  4182. win.Enable()
  4183. win.SetValue(data['position'][coord] * 100)
  4184. win = self.FindWindowById(self.win['volume']['slice']['axes'])
  4185. win.SetSelection(data['position']['axis'])
  4186. win.Enable()
  4187. win = self.FindWindowById(self.win['volume']['slice']['transp'])
  4188. win.SetValue(self._getPercent(data['transp']['value']))
  4189. win.Enable()
  4190. self.FindWindowById(self.win['volume']['slice']['reset']).Enable()
  4191. else:
  4192. for coord in ('x1', 'x2', 'y1', 'y2', 'z1', 'z2'):
  4193. self.FindWindowById(self.win['volume']['slice']['slider_' + coord]).Disable()
  4194. self.FindWindowById(self.win['volume']['slice']['axes']).Disable()
  4195. self.FindWindowById(self.win['volume']['slice']['transp']).Disable()
  4196. self.FindWindowById(self.win['volume']['slice']['reset']).Disable()
  4197. self.UpdateSliceLabels()
  4198. def UpdateSliceLabels(self):
  4199. """!Update text labels of slice controls according to axis"""
  4200. sel = self.FindWindowById(self.win['volume']['slice']['axes']).GetSelection()
  4201. if sel == 0:
  4202. self.FindWindowByName('label_edge_0').SetLabel(_("North edge:"))
  4203. self.FindWindowByName('label_edge_1').SetLabel(_("South edge:"))
  4204. self.FindWindowByName('label_edge_2').SetLabel(_("West edge:"))
  4205. self.FindWindowByName('label_edge_3').SetLabel(_("East edge:"))
  4206. self.FindWindowByName('label_coord_0').SetLabel(_("Northing (Y):"))
  4207. self.FindWindowByName('label_coord_1').SetLabel(_("Height (Z):"))
  4208. self.FindWindowByName('label_coord_2').SetLabel(_("Easting (X):"))
  4209. elif sel == 1:
  4210. self.FindWindowByName('label_edge_0').SetLabel(_("West edge:"))
  4211. self.FindWindowByName('label_edge_1').SetLabel(_("East edge:"))
  4212. self.FindWindowByName('label_edge_2').SetLabel(_("North edge:"))
  4213. self.FindWindowByName('label_edge_3').SetLabel(_("South edge:"))
  4214. self.FindWindowByName('label_coord_0').SetLabel(_("Easting (X):"))
  4215. self.FindWindowByName('label_coord_1').SetLabel(_("Height (Z):"))
  4216. self.FindWindowByName('label_coord_2').SetLabel(_("Northing (Y):"))
  4217. else:
  4218. self.FindWindowByName('label_edge_0').SetLabel(_("West edge:"))
  4219. self.FindWindowByName('label_edge_1').SetLabel(_("East edge:"))
  4220. self.FindWindowByName('label_edge_2').SetLabel(_("Bottom edge:"))
  4221. self.FindWindowByName('label_edge_3').SetLabel(_("Top edge:"))
  4222. self.FindWindowByName('label_coord_0').SetLabel(_("Easting (X):"))
  4223. self.FindWindowByName('label_coord_1').SetLabel(_("Northing (Y):"))
  4224. self.FindWindowByName('label_coord_2').SetLabel(_("Height (Z):"))
  4225. def SetPage(self, name):
  4226. """!Get named page"""
  4227. if name == 'view':
  4228. self.SetSelection(0)
  4229. elif name in ('surface', 'vector', 'volume'):
  4230. self.SetSelection(1)
  4231. else:
  4232. self.SetSelection(2)
  4233. win = self.FindWindowById(self.page[name]['notebook'])
  4234. try:
  4235. win.Expand(win.GetFoldPanel(self.page[name]['id']))
  4236. self.UpdateScrolling((win.GetFoldPanel(self.page[name]['id']).GetGrandParent(),))
  4237. except AttributeError:
  4238. win.SetSelection(self.page[name]['id'])
  4239. class PositionWindow(wx.Window):
  4240. """!Abstract position control window, see subclasses
  4241. ViewPostionWindow and LightPositionWindow"""
  4242. def __init__(self, parent, mapwindow, id = wx.ID_ANY,
  4243. **kwargs):
  4244. self.mapWindow = mapwindow
  4245. self.quick = True
  4246. wx.Window.__init__(self, parent, id, **kwargs)
  4247. self.SetBackgroundColour("WHITE")
  4248. self.pdc = wx.PseudoDC()
  4249. self.pdc.SetBrush(wx.Brush(colour = 'dark green', style = wx.SOLID))
  4250. self.pdc.SetPen(wx.Pen(colour = 'dark green', width = 2, style = wx.SOLID))
  4251. self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x: None)
  4252. self.Bind(wx.EVT_PAINT, self.OnPaint)
  4253. # self.Bind(wx.EVT_MOTION, self.OnMouse)
  4254. self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse)
  4255. def Draw(self, pos, scale = False):
  4256. w, h = self.GetClientSize()
  4257. x, y = pos
  4258. if scale:
  4259. x = x * w
  4260. y = y * h
  4261. self.pdc.Clear()
  4262. self.pdc.BeginDrawing()
  4263. self.pdc.DrawLine(w / 2, h / 2, x, y)
  4264. self.pdc.DrawCircle(x, y, 5)
  4265. self.pdc.EndDrawing()
  4266. def OnPaint(self, event):
  4267. dc = wx.BufferedPaintDC(self)
  4268. dc.SetBackground(wx.Brush("White"))
  4269. dc.Clear()
  4270. self.PrepareDC(dc)
  4271. self.pdc.DrawToDC(dc)
  4272. def UpdatePos(self, xcoord, ycoord):
  4273. """!Update position coordinates (origin: UL)"""
  4274. if xcoord < 0.0:
  4275. xcoord = 0.0
  4276. elif xcoord > 1.0:
  4277. xcoord = 1.0
  4278. if ycoord < 0.0:
  4279. ycoord = 0.0
  4280. elif ycoord > 1.0:
  4281. ycoord = 1.0
  4282. x, y = self.TransformCoordinates(xcoord, ycoord)
  4283. self.data['position']['x'] = x
  4284. self.data['position']['y'] = y
  4285. return xcoord, ycoord
  4286. def OnMouse(self, event):
  4287. if event.LeftIsDown():
  4288. x, y = event.GetPosition()
  4289. self.Draw(pos = (x, y))
  4290. w, h = self.GetClientSize()
  4291. x = float(x) / w
  4292. y = float(y) / h
  4293. self.UpdatePos(x, y)
  4294. self.Refresh(False)
  4295. event.Skip()
  4296. def PostDraw(self):
  4297. x, y = self.UpdatePos(self.data['position']['x'],
  4298. self.data['position']['y'])
  4299. self.Draw(pos = (x,y), scale = True)
  4300. class ViewPositionWindow(PositionWindow):
  4301. """!View position control widget"""
  4302. def __init__(self, parent, mapwindow, id = wx.ID_ANY,
  4303. **kwargs):
  4304. PositionWindow.__init__(self, parent, mapwindow, id, **kwargs)
  4305. self.SetToolTipString(_("Adjusts the look direction (azimuth). "
  4306. "Click and drag the puck to change the current eye position."))
  4307. self.data = self.mapWindow.view
  4308. self.PostDraw()
  4309. def UpdatePos(self, xcoord, ycoord):
  4310. x, y = PositionWindow.UpdatePos(self, xcoord, ycoord)
  4311. event = wxUpdateView(zExag = True)
  4312. wx.PostEvent(self.mapWindow, event)
  4313. return x, y
  4314. def TransformCoordinates(self, x, y, toLight = True):
  4315. return x, y
  4316. def OnMouse(self, event):
  4317. self.mapWindow.iview['dir']['use'] = False # use focus instead of viewdir
  4318. PositionWindow.OnMouse(self, event)
  4319. if event.LeftIsDown():
  4320. self.mapWindow.render['quick'] = self.quick
  4321. self.mapWindow.Refresh(eraseBackground = False)
  4322. elif event.LeftUp():
  4323. self.mapWindow.render['quick'] = False
  4324. self.mapWindow.Refresh(eraseBackground = False)
  4325. event.Skip()
  4326. class LightPositionWindow(PositionWindow):
  4327. """!Light position control widget"""
  4328. def __init__(self, parent, mapwindow, id = wx.ID_ANY,
  4329. **kwargs):
  4330. PositionWindow.__init__(self, parent, mapwindow, id, **kwargs)
  4331. self.SetToolTipString(_("Adjusts the light direction. "
  4332. "Click and drag the puck to change the light direction."))
  4333. self.data = self.mapWindow.light
  4334. self.quick = False
  4335. self.PostDraw()
  4336. def UpdatePos(self, xcoord, ycoord):
  4337. x, y = PositionWindow.UpdatePos(self, xcoord, ycoord)
  4338. event = wxUpdateLight(refresh = False)
  4339. wx.PostEvent(self.mapWindow, event)
  4340. return x, y
  4341. def TransformCoordinates(self, x, y, toLight = True):
  4342. if toLight:
  4343. x = 2 * x - 1
  4344. y = -2 * y + 1
  4345. else:
  4346. x = (x + 1)/2
  4347. y = (1 - y)/2
  4348. return x, y
  4349. def PostDraw(self):
  4350. event = wxUpdateLight(refresh = True)
  4351. wx.PostEvent(self.mapWindow, event)
  4352. x, y = self.data['position']['x'], self.data['position']['y']
  4353. x, y = self.TransformCoordinates(x, y, toLight = False)
  4354. self.Draw(pos = (x,y), scale = True)
  4355. def OnMouse(self, event):
  4356. PositionWindow.OnMouse(self, event)
  4357. if event.LeftUp():
  4358. self.mapWindow.render['quick'] = False
  4359. self.mapWindow.Refresh(eraseBackground = False)