tools.py 218 KB

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