tools.py 219 KB

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