psmap_dialogs.py 267 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736
  1. """!
  2. @package psmap_dialogs.py
  3. @brief Map feature objects and dialogs for ps.map
  4. Classes:
  5. - UnitConversion
  6. - TCValidator
  7. - PenStyleComboBox
  8. - CheckListCtrl
  9. - Instruction
  10. - InstructionObject
  11. - InitMap
  12. - MapFrame
  13. - PageSetup
  14. - Mapinfo
  15. - Text
  16. - Scalebar
  17. - RasterLegend
  18. - VectorLegend
  19. - Raster
  20. - Vector
  21. - VProperties
  22. - PsmapDialog
  23. - PageSetupDialog
  24. - MapDialog
  25. - MapFramePanel
  26. - RasterPanel
  27. - VectorPanel
  28. - RasterDialog
  29. - MainVectorDialog
  30. - VPropertiesDialog
  31. - LegendDialog
  32. - MapinfoDialog
  33. - ScalebarDialog
  34. - TextDialog
  35. (C) 2011 by Anna Kratochvilova, and the GRASS Development Team
  36. This program is free software under the GNU General Public License
  37. (>=v2). Read the file COPYING that comes with GRASS for details.
  38. @author Anna Kratochvilova <kratochanna gmail.com> (bachelor's project)
  39. @author Martin Landa <landa.martin gmail.com> (mentor)
  40. """
  41. import os
  42. import sys
  43. import string
  44. from math import ceil, floor
  45. from copy import deepcopy
  46. from time import strftime, localtime
  47. import grass.script as grass
  48. if int(grass.version()['version'].split('.')[0]) > 6:
  49. sys.path.append(os.path.join(os.getenv('GISBASE'), 'etc', 'gui', 'wxpython',
  50. 'gui_modules'))
  51. else:
  52. sys.path.append(os.path.join(os.getenv('GISBASE'), 'etc', 'wxpython',
  53. 'gui_modules'))
  54. import globalvar
  55. import dbm_base
  56. from utils import CmdToTuple, GetCmdString
  57. from gselect import Select
  58. from gcmd import RunCommand, GError, GMessage, GWarning
  59. import wx
  60. import wx.lib.scrolledpanel as scrolled
  61. import wx.lib.filebrowsebutton as filebrowse
  62. from wx.lib.mixins.listctrl import CheckListCtrlMixin, ListCtrlAutoWidthMixin
  63. from wx.lib.expando import ExpandoTextCtrl, EVT_ETC_LAYOUT_NEEDED
  64. try:
  65. import wx.lib.agw.floatspin as fs
  66. except ImportError:
  67. fs = None
  68. grass.set_raise_on_error(True)
  69. PSMAP_COLORS = ['aqua', 'black', 'blue', 'brown', 'cyan', 'gray', 'grey', 'green', 'indigo',
  70. 'magenta','orange', 'purple', 'red', 'violet', 'white', 'yellow']
  71. class UnitConversion:
  72. """! Class for converting units"""
  73. def __init__(self, parent = None):
  74. self.parent = parent
  75. if self.parent:
  76. ppi = wx.PaintDC(self.parent).GetPPI()
  77. else:
  78. ppi = (72, 72)
  79. self._unitsPage = { 'inch' : 1.0,
  80. 'point' : 72.0,
  81. 'centimeter' : 2.54,
  82. 'milimeter' : 25.4}
  83. self._unitsMap = { 'meters' : 0.0254,
  84. 'kilometers' : 2.54e-5,
  85. 'feet' : 1./12,
  86. 'miles' : 1./63360,
  87. 'nautical miles' : 1/72913.44}
  88. self._units = { 'pixel': ppi[0],
  89. 'meter': 0.0254,
  90. 'degrees' : 0.0254 #like 1 meter, incorrect
  91. }
  92. self._units.update(self._unitsPage)
  93. self._units.update(self._unitsMap)
  94. def getPageUnits(self):
  95. return sorted(self._unitsPage.keys())
  96. def getMapUnits(self):
  97. return sorted(self._unitsMap.keys())
  98. def getAllUnits(self):
  99. return sorted(self._units.keys())
  100. def convert(self, value, fromUnit = None, toUnit = None):
  101. return float(value)/self._units[fromUnit]*self._units[toUnit]
  102. class TCValidator(wx.PyValidator):
  103. """!validates input in textctrls, combobox, taken from wxpython demo"""
  104. def __init__(self, flag = None):
  105. wx.PyValidator.__init__(self)
  106. self.flag = flag
  107. self.Bind(wx.EVT_CHAR, self.OnChar)
  108. def Clone(self):
  109. return TCValidator(self.flag)
  110. def Validate(self, win):
  111. tc = self.GetWindow()
  112. val = tc.GetValue()
  113. if self.flag == 'DIGIT_ONLY':
  114. for x in val:
  115. if x not in string.digits:
  116. return False
  117. return True
  118. def OnChar(self, event):
  119. key = event.GetKeyCode()
  120. if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255:
  121. event.Skip()
  122. return
  123. if self.flag == 'DIGIT_ONLY' and chr(key) in string.digits + '.':
  124. event.Skip()
  125. return
  126. ## if self.flag == 'SCALE' and chr(key) in string.digits + ':':
  127. ## event.Skip()
  128. ## return
  129. if self.flag == 'ZERO_AND_ONE_ONLY' and chr(key) in '01':
  130. event.Skip()
  131. return
  132. if not wx.Validator_IsSilent():
  133. wx.Bell()
  134. # Returning without calling even.Skip eats the event before it
  135. # gets to the text control
  136. return
  137. class PenStyleComboBox(wx.combo.OwnerDrawnComboBox):
  138. """!Combo for selecting line style, taken from wxpython demo"""
  139. # Overridden from OwnerDrawnComboBox, called to draw each
  140. # item in the list
  141. def OnDrawItem(self, dc, rect, item, flags):
  142. if item == wx.NOT_FOUND:
  143. # painting the control, but there is no valid item selected yet
  144. return
  145. r = wx.Rect(*rect) # make a copy
  146. r.Deflate(3, 5)
  147. penStyle = wx.SOLID
  148. if item == 1:
  149. penStyle = wx.LONG_DASH
  150. elif item == 2:
  151. penStyle = wx.DOT
  152. elif item == 3:
  153. penStyle = wx.DOT_DASH
  154. pen = wx.Pen(dc.GetTextForeground(), 3, penStyle)
  155. dc.SetPen(pen)
  156. # for painting the items in the popup
  157. dc.DrawText(self.GetString(item ),
  158. r.x + 3,
  159. (r.y + 0) + ((r.height/2) - dc.GetCharHeight() )/2
  160. )
  161. dc.DrawLine(r.x+5, r.y+((r.height/4)*3)+1, r.x+r.width - 5, r.y+((r.height/4)*3)+1 )
  162. def OnDrawBackground(self, dc, rect, item, flags):
  163. """!Overridden from OwnerDrawnComboBox, called for drawing the
  164. background area of each item."""
  165. # If the item is selected, or its item # iseven, or we are painting the
  166. # combo control itself, then use the default rendering.
  167. if (item & 1 == 0 or flags & (wx.combo.ODCB_PAINTING_CONTROL |
  168. wx.combo.ODCB_PAINTING_SELECTED)):
  169. wx.combo.OwnerDrawnComboBox.OnDrawBackground(self, dc, rect, item, flags)
  170. return
  171. # Otherwise, draw every other background with different colour.
  172. bgCol = wx.Colour(240,240,250)
  173. dc.SetBrush(wx.Brush(bgCol))
  174. dc.SetPen(wx.Pen(bgCol))
  175. dc.DrawRectangleRect(rect);
  176. def OnMeasureItem(self, item):
  177. """!Overridden from OwnerDrawnComboBox, should return the height
  178. needed to display an item in the popup, or -1 for default"""
  179. return 30
  180. def OnMeasureItemWidth(self, item):
  181. """!Overridden from OwnerDrawnComboBox. Callback for item width, or
  182. -1 for default/undetermined"""
  183. return -1; # default - will be measured from text width
  184. class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin):
  185. """!List control for managing order and labels of vector maps in legend"""
  186. def __init__(self, parent):
  187. wx.ListCtrl.__init__(self, parent, id = wx.ID_ANY,
  188. style = wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.BORDER_SUNKEN|wx.LC_VRULES|wx.LC_HRULES)
  189. CheckListCtrlMixin.__init__(self)
  190. ListCtrlAutoWidthMixin.__init__(self)
  191. class Instruction:
  192. """!Class which represents instruction file"""
  193. def __init__(self, parent, objectsToDraw):
  194. self.parent = parent
  195. self.objectsToDraw = objectsToDraw
  196. #here are kept objects like mapinfo, rasterlegend, etc.
  197. self.instruction = list()
  198. def __str__(self):
  199. """!Returns text for instruction file"""
  200. comment = "# timestamp: " + strftime("%Y-%m-%d %H:%M", localtime()) + '\n'
  201. env = grass.gisenv()
  202. comment += "# location: %s\n" % env['LOCATION_NAME']
  203. comment += "# mapset: %s\n" % env['MAPSET']
  204. border = ''
  205. if not self.FindInstructionByType('map'):
  206. border = 'border n\n'
  207. text = [str(each) for each in self.instruction]
  208. return comment + border + '\n'.join(text) + '\nend'
  209. def __getitem__(self, id):
  210. for each in self.instruction:
  211. if each.id == id:
  212. return each
  213. return None
  214. def __contains__(self, id):
  215. """!Test if instruction is included"""
  216. for each in self.instruction:
  217. if each.id == id:
  218. return True
  219. return False
  220. def __delitem__(self, id):
  221. """!Delete instruction"""
  222. for each in self.instruction:
  223. if each.id == id:
  224. if each.type == 'map':
  225. #must remove raster, vector layers too
  226. vektor = self.FindInstructionByType('vector', list = True)
  227. vProperties = self.FindInstructionByType('vProperties', list = True)
  228. raster = self.FindInstructionByType('raster', list = True)
  229. for item in vektor + vProperties + raster:
  230. if item in self.instruction:
  231. self.instruction.remove(item)
  232. self.instruction.remove(each)
  233. if id in self.objectsToDraw:
  234. self.objectsToDraw.remove(id)
  235. return
  236. def AddInstruction(self, instruction):
  237. """!Add instruction"""
  238. # add to instructions
  239. if instruction.type == 'map':
  240. self.instruction.insert(0, instruction)
  241. else:
  242. self.instruction.append(instruction)
  243. # add to drawable objects
  244. if instruction.type not in ('page', 'raster', 'vector', 'vProperties', 'initMap'):
  245. if instruction.type == 'map':
  246. self.objectsToDraw.insert(0, instruction.id)
  247. else:
  248. self.objectsToDraw.append(instruction.id)
  249. def FindInstructionByType(self, type, list = False):
  250. """!Find instruction(s) with the given type"""
  251. inst = []
  252. for each in self.instruction:
  253. if each.type == type:
  254. inst.append(each)
  255. if len(inst) == 1 and not list:
  256. return inst[0]
  257. return inst
  258. def Read(self, filename):
  259. """!Reads instruction file and creates instruction objects"""
  260. self.filename = filename
  261. # open file
  262. try:
  263. file = open(filename, 'r')
  264. except IOError:
  265. GError(message = _("Unable to open file\n%s") % filename)
  266. return
  267. # first read file to get information about region and scaletype
  268. isRegionComment = False
  269. for line in file:
  270. if '# g.region' in line:
  271. self.SetRegion(regionInstruction = line)
  272. isRegionComment = True
  273. break
  274. if not isRegionComment:
  275. self.SetRegion(regionInstruction = None)
  276. # then run ps.map -b to get information for maploc
  277. # compute scale and center
  278. map = self.FindInstructionByType('map')
  279. region = grass.region()
  280. map['center'] = (region['n'] + region['s']) / 2, (region['w'] + region['e']) / 2
  281. mapRect = GetMapBounds(self.filename)
  282. map['rect'] = mapRect
  283. proj = projInfo()
  284. toM = 1.0
  285. if proj['units']:
  286. toM = float(proj['meters'])
  287. units = UnitConversion(self.parent)
  288. w = units.convert(value = mapRect.Get()[2], fromUnit = 'inch', toUnit = 'meter') / toM
  289. map['scale'] = w / abs((region['w'] - region['e']))
  290. SetResolution(dpi = 300, width = map['rect'].width, height = map['rect'].height)
  291. # read file again, now with information about map bounds
  292. isBuffer = False
  293. buffer = []
  294. instruction = None
  295. vectorMapNumber = 1
  296. file.seek(0)
  297. for line in file:
  298. if not line.strip():
  299. continue
  300. line = line.strip()
  301. if isBuffer:
  302. buffer.append(line)
  303. if 'end' in line:
  304. isBuffer = False
  305. kwargs = {}
  306. if instruction == 'scalebar':
  307. kwargs['scale'] = map['scale']
  308. elif instruction == 'text':
  309. kwargs['mapInstruction'] = map
  310. elif instruction in ('vpoints', 'vlines', 'vareas'):
  311. kwargs['id'] = wx.NewId()
  312. kwargs['vectorMapNumber'] = vectorMapNumber
  313. vectorMapNumber += 1
  314. ok = self.SendToRead(instruction, buffer, **kwargs)
  315. if not ok: return False
  316. buffer = []
  317. continue
  318. elif line.startswith('paper'):
  319. instruction = 'paper'
  320. isBuffer = True
  321. buffer.append(line)
  322. elif line.startswith('border'):
  323. if line.split()[1].lower() in ('n', 'no', 'none'):
  324. ok = self.SendToRead('border', [line])
  325. if not ok: return False
  326. elif line.split()[1].lower() in ('y', 'yes'):
  327. instruction = 'border'
  328. isBuffer = True
  329. buffer.append(line)
  330. elif line.startswith('scale '):
  331. ok = self.SendToRead('scale', line, isRegionComment = isRegionComment)
  332. if not ok: return False
  333. elif line.startswith('maploc'):
  334. ok = self.SendToRead(instruction = 'maploc', text = line)
  335. if not ok: return False
  336. elif line.startswith('raster'):
  337. ok = self.SendToRead(instruction = 'raster', text = line)
  338. if not ok: return False
  339. elif line.startswith('mapinfo'):
  340. instruction = 'mapinfo'
  341. isBuffer = True
  342. buffer.append(line)
  343. elif line.startswith('scalebar'):
  344. instruction = 'scalebar'
  345. isBuffer = True
  346. buffer.append(line)
  347. elif line.startswith('text'):
  348. instruction = 'text'
  349. isBuffer = True
  350. buffer.append(line)
  351. elif line.startswith('colortable'):
  352. if len(line.split()) == 2 and line.split()[1].lower() in ('n', 'no', 'none'):
  353. break
  354. instruction = 'colortable'
  355. isBuffer = True
  356. buffer.append(line)
  357. elif line.startswith('vlegend'):
  358. instruction = 'vlegend'
  359. isBuffer = True
  360. buffer.append(line)
  361. elif line.startswith('vpoints'):
  362. instruction = 'vpoints'
  363. isBuffer = True
  364. buffer.append(line)
  365. elif line.startswith('vlines'):
  366. instruction = 'vlines'
  367. isBuffer = True
  368. buffer.append(line)
  369. elif line.startswith('vareas'):
  370. instruction = 'vareas'
  371. isBuffer = True
  372. buffer.append(line)
  373. rasterLegend = self.FindInstructionByType('rasterLegend')
  374. raster = self.FindInstructionByType('raster')
  375. page = self.FindInstructionByType('page')
  376. vector = self.FindInstructionByType('vector')
  377. vectorLegend = self.FindInstructionByType('vectorLegend')
  378. vectorMaps = self.FindInstructionByType('vProperties', list = True)
  379. # check (in case of scaletype 0) if map is drawn also
  380. map['drawMap'] = False
  381. if map['scaleType'] == 0:
  382. mapForRegion = map['map']
  383. if map['mapType'] == 'raster' and raster:
  384. if mapForRegion == raster['raster']:
  385. map['drawMap'] = True
  386. elif map['mapType'] == 'vector' and vector:
  387. for vmap in vector['list']:
  388. if mapForRegion == vmap[0]:
  389. map['drawMap'] = True
  390. # rasterLegend
  391. if rasterLegend:
  392. if rasterLegend['rasterDefault'] and raster:
  393. rasterLegend['raster'] = raster['raster']
  394. if not rasterLegend['discrete']:
  395. rasterType = getRasterType(map = rasterLegend['raster'])
  396. if rasterType == 'CELL':
  397. rasterLegend['discrete'] = 'y'
  398. else:
  399. rasterLegend['discrete'] = 'n'
  400. #estimate size
  401. height = rasterLegend.EstimateHeight(raster = rasterLegend['raster'], discrete = rasterLegend['discrete'],
  402. fontsize = rasterLegend['fontsize'],
  403. cols = rasterLegend['cols'],
  404. height = rasterLegend['height'])
  405. width = rasterLegend.EstimateWidth(raster = rasterLegend['raster'], discrete = rasterLegend['discrete'],
  406. fontsize = rasterLegend['fontsize'],
  407. cols = rasterLegend['cols'] ,
  408. width = rasterLegend['width'],
  409. paperInstr = page)
  410. rasterLegend['rect'] = wx.Rect2D(x = float(rasterLegend['where'][0]), y = float(rasterLegend['where'][1]),
  411. w = width, h = height)
  412. # vectors, vlegend
  413. if vector:
  414. for vmap in vectorMaps:
  415. for i, each in enumerate(vector['list']):
  416. if each[2] == vmap.id:
  417. vector['list'][i][4] = vmap['label']
  418. vector['list'][i][3] = vmap['lpos']
  419. if vectorLegend:
  420. size = vectorLegend.EstimateSize(vectorInstr = vector, fontsize = vectorLegend['fontsize'],
  421. width = vectorLegend['width'], cols = vectorLegend['cols'])
  422. vectorLegend['rect'] = wx.Rect2D(x = float(vectorLegend['where'][0]), y = float(vectorLegend['where'][1]),
  423. w = size[0], h = size[1])
  424. page = self.FindInstructionByType('page')
  425. if not page:
  426. page = PageSetup(wx.NewId())
  427. self.AddInstruction(page)
  428. #
  429. return True
  430. def SendToRead(self, instruction, text, **kwargs):
  431. #print 'send to read', instruction, text
  432. psmapInstrDict = dict(paper = ['page'],
  433. maploc = ['map'],
  434. scale = ['map'],
  435. border = ['map'],
  436. raster = ['raster'],
  437. mapinfo = ['mapinfo'],
  438. scalebar = ['scalebar'],
  439. text = ['text'],
  440. vpoints = ['vector', 'vProperties'],
  441. vlines = ['vector', 'vProperties'],
  442. vareas = ['vector', 'vProperties'],
  443. colortable = ['rasterLegend'],
  444. vlegend = ['vectorLegend']
  445. )
  446. myInstrDict = dict(page = PageSetup,
  447. map = MapFrame,
  448. raster = Raster,
  449. mapinfo = Mapinfo,
  450. scalebar = Scalebar,
  451. text = Text,
  452. rasterLegend = RasterLegend,
  453. vectorLegend = VectorLegend,
  454. vector = Vector,
  455. vProperties = VProperties
  456. )
  457. myInstruction = psmapInstrDict[instruction]
  458. for i in myInstruction:
  459. instr = self.FindInstructionByType(i)
  460. if i in ('text', 'vProperties') or not instr:
  461. id = wx.NewId() #!vProperties expect subtype
  462. if i == 'vProperties':
  463. id = kwargs['id']
  464. newInstr = myInstrDict[i](id, subType = instruction[1:])
  465. else:
  466. newInstr = myInstrDict[i](id)
  467. ok = newInstr.Read(instruction, text, **kwargs)
  468. if ok:
  469. self.AddInstruction(newInstr)
  470. else:
  471. return False
  472. else:
  473. ok = instr.Read(instruction, text, **kwargs)
  474. if not ok:
  475. return False
  476. return True
  477. def SetRegion(self, regionInstruction):
  478. """!Sets region from file comment or sets current region in case of no comment"""
  479. map = MapFrame(wx.NewId())
  480. self.AddInstruction(map)
  481. if regionInstruction:
  482. cmd = CmdToTuple(regionInstruction.strip('# ').split())
  483. # define scaleType
  484. if len(cmd[1]) <= 3:
  485. if 'rast' in cmd[1]:
  486. map['scaleType'] = 0
  487. map['mapType'] = 'raster'
  488. map['map'] = cmd[1]['rast']
  489. elif 'vect' in cmd[1]:
  490. map['scaleType'] = 0
  491. map['mapType'] = 'vector'
  492. map['map'] = cmd[1]['vect']
  493. elif 'region' in cmd[1]:
  494. map['scaleType'] = 1
  495. map['region'] = cmd[1]['region']
  496. else:
  497. map['scaleType'] = 2
  498. else:
  499. map['scaleType'] = 2
  500. grass.del_temp_region()
  501. region = grass.region()
  502. grass.use_temp_region()
  503. cmd = ['g.region', region]
  504. cmdString = GetCmdString(cmd).replace('g.region', '')
  505. GMessage(_("Instruction file will be loaded with following region: %s\n") % cmdString)
  506. try:
  507. RunCommand(cmd[0], **cmd[1])
  508. except grass.ScriptError, e:
  509. GError(_("Region cannot be set\n%s") % e)
  510. return False
  511. class InstructionObject:
  512. """!Abtract class representing single instruction"""
  513. def __init__(self, id):
  514. self.id = id
  515. # default values
  516. self.defaultInstruction = dict()
  517. # current values
  518. self.instruction = self.defaultInstruction
  519. # converting units
  520. self.unitConv = UnitConversion()
  521. def __str__(self):
  522. """!Returns particular part of text instruction"""
  523. return ''
  524. def __getitem__(self, key):
  525. for each in self.instruction.keys():
  526. if each == key:
  527. return self.instruction[key]
  528. return None
  529. def __setitem__(self, key, value):
  530. self.instruction[key] = value
  531. def GetInstruction(self):
  532. """!Get current values"""
  533. return self.instruction
  534. def SetInstruction(self, instruction):
  535. """!Set default values"""
  536. self.instruction = instruction
  537. def Read(self, instruction, text, **kwargs):
  538. """!Read instruction and save them"""
  539. pass
  540. class InitMap(InstructionObject):
  541. """!Class representing virtual map"""
  542. def __init__(self, id):
  543. InstructionObject.__init__(self, id = id)
  544. self.type = 'initMap'
  545. # default values
  546. self.defaultInstruction = dict(rect = None, scale = None)
  547. # current values
  548. self.instruction = dict(self.defaultInstruction)
  549. class MapFrame(InstructionObject):
  550. """!Class representing map (instructions maploc, scale, border)"""
  551. def __init__(self, id):
  552. InstructionObject.__init__(self, id = id)
  553. self.type = 'map'
  554. # default values
  555. self.defaultInstruction = dict(map = None, mapType = None, drawMap = True, region = None,
  556. rect = wx.Rect2D(), scaleType = 0, scale = None, center = None,
  557. resolution = 300, border = 'y', width = 1, color = '0:0:0')
  558. # current values
  559. self.instruction = dict(self.defaultInstruction)
  560. def __str__(self):
  561. instr = ''
  562. comment = ''
  563. #region settings
  564. region = grass.region()
  565. if self.instruction['scaleType'] == 0: #match map
  566. map = self.instruction['map']
  567. if self.instruction['mapType'] == 'raster':
  568. comment = "# g.region rast=%s cols=%s rows=%s\n" % (map, region['cols'], region['rows'])
  569. else:
  570. comment = "# g.region vect=%s\n" % (map)
  571. elif self.instruction['scaleType'] == 1:# saved region
  572. region = self.instruction['region']
  573. comment = "# g.region region=%s\n" % region
  574. elif self.instruction['scaleType'] in (2, 3): #current region, fixed scale
  575. comment = string.Template("# g.region n=$n s=$s e=$e w=$w rows=$rows cols=$cols \n").substitute(**region)
  576. instr += comment
  577. instr += '\n'
  578. # maploc
  579. maplocInstruction = "maploc %.3f %.3f" % (self.instruction['rect'].x, self.instruction['rect'].y)
  580. if self.instruction['scaleType'] != 3:
  581. maplocInstruction += " %.3f %.3f"% (self.instruction['rect'].width, self.instruction['rect'].height)
  582. instr += maplocInstruction
  583. instr += '\n'
  584. # scale
  585. if self.instruction['scaleType'] == 3: #fixed scale
  586. scaleInstruction = "scale 1:%.0f" % (1/self.instruction['scale'])
  587. instr += scaleInstruction
  588. instr += '\n'
  589. # border
  590. borderInstruction = ''
  591. if self.instruction['border'] == 'n':
  592. borderInstruction = "border n"
  593. else:
  594. borderInstruction = "border y\n"
  595. borderInstruction += string.Template(" width $width\n color $color\n").substitute(self.instruction)
  596. borderInstruction += " end"
  597. instr += borderInstruction
  598. instr += '\n'
  599. return instr
  600. def Read(self, instruction, text, **kwargs):
  601. """!Read instruction and save information"""
  602. if 'isRegionComment' in kwargs:
  603. isRegionComment = kwargs['isRegionComment']
  604. instr = {}
  605. if instruction == 'border':
  606. for line in text:
  607. if line.startswith('end'):
  608. break
  609. try:
  610. if line.split()[1].lower() in ('n', 'no', 'none'):
  611. instr['border'] = 'n'
  612. break
  613. elif line.split()[1].lower() in ('y', 'yes'):
  614. instr['border'] = 'y'
  615. elif line.startswith('width'):
  616. instr['width'] = line.split()[1]
  617. elif line.startswith('color'):
  618. instr['color'] = line.split()[1]
  619. except IndexError:
  620. GError(_("Failed to read instruction %s") % instruction)
  621. return False
  622. elif instruction == 'scale':
  623. try:
  624. scaleText = text.strip('scale ').split(':')[1]
  625. # when scale instruction given and region comment also, then scaletype is fixed scale
  626. if not isRegionComment:
  627. instr['scaleType'] = 2
  628. else:
  629. instr['scaleType'] = 3
  630. scale = 1/float(scaleText)
  631. if abs(scale - self.instruction['scale']) > (0.01 * scale):
  632. GWarning(_("Scale has changed, old value: %(old)s\nnew value: %(new)s") % \
  633. { 'old' : scale, 'new' : self.instruction['scale'] })
  634. except (ValueError, IndexError):
  635. GError(_("Failed to read instruction %s.\nUse 1:25000 notation.") % instruction)
  636. return False
  637. elif instruction == 'maploc':
  638. maploc = text.strip('maploc ').split()
  639. if len(maploc) >= 2:
  640. if abs(self.instruction['rect'].Get()[0] - float(maploc[0])) > 0.5 or \
  641. abs(self.instruction['rect'].Get()[1] - float(maploc[1])) > 0.5:
  642. GWarning(_("Map frame position changed, old value: %(old1)s %(old2)s\nnew value: %(new1)s %(new2)s") % \
  643. { 'old1' : maploc[0], 'old2' : maploc[1],
  644. 'new1' : self.instruction['rect'].Get()[0], 'new2' : self.instruction['rect'].Get()[1] })
  645. #instr['rect'] = wx.Rect2D(float(maploc[0]), float(maploc[1]), self.instruction['rect'][2], self.instruction['rect'][3])
  646. if len(maploc) == 4:
  647. if abs(self.instruction['rect'].Get()[2] - float(maploc[2])) > 0.5 or \
  648. abs(self.instruction['rect'].Get()[3] - float(maploc[3])) > 0.5:
  649. GWarning(_("Map frame size changed, old value: %(old1)s %(old2)s\nnew value: %(new1)s %(new2)s") % \
  650. { 'old1' : maploc[2], 'old2' : maploc[3],
  651. 'new1' : self.instruction['rect'].Get()[2], 'new2' : self.instruction['rect'].Get()[3] })
  652. #instr['rect'] = wx.Rect2D(*map(float, maploc))
  653. self.instruction.update(instr)
  654. return True
  655. class PageSetup(InstructionObject):
  656. """!Class representing page instruction"""
  657. def __init__(self, id):
  658. InstructionObject.__init__(self, id = id)
  659. self.type = 'page'
  660. # default values
  661. self.defaultInstruction = dict(Units = 'inch', Format = 'a4', Orientation = 'Portrait',
  662. Width = 8.268, Height = 11.693, Left = 0.5, Right = 0.5, Top = 1, Bottom = 1)
  663. # current values
  664. self.instruction = dict(self.defaultInstruction)
  665. def __str__(self):
  666. if self.instruction['Format'] == 'custom':
  667. instr = string.Template("paper\n width $Width\n height $Height\n").substitute(self.instruction)
  668. else:
  669. instr = string.Template("paper $Format\n").substitute(self.instruction)
  670. instr += string.Template(" left $Left\n right $Right\n bottom $Bottom\n top $Top\n end").substitute(self.instruction)
  671. return instr
  672. def Read(self, instruction, text):
  673. """!Read instruction and save information"""
  674. instr = {}
  675. self.cats = ['Width', 'Height', 'Left', 'Right', 'Top', 'Bottom']
  676. self.subInstr = dict(zip(['width', 'height', 'left', 'right', 'top', 'bottom'], self.cats))
  677. if instruction == 'paper': # just for sure
  678. for line in text:
  679. if line.startswith('paper'):
  680. if len(line.split()) > 1:
  681. pformat = line.split()[1]
  682. availableFormats = self._toDict(grass.read_command('ps.map', flags = 'p',
  683. quiet = True))
  684. # e.g. paper a3
  685. try:
  686. instr['Format'] = pformat
  687. for key, value in availableFormats[pformat].iteritems():
  688. instr[key] = float(value)
  689. break
  690. except KeyError:
  691. GError(_("Failed to read instruction %(file)s.\nUnknown format %(for)s") % \
  692. { 'file' : instruction, 'for' : format })
  693. return False
  694. else:
  695. # paper
  696. # width ...
  697. instr['Format'] = 'custom'
  698. # read subinstructions
  699. elif instr['Format'] == 'custom' and not line.startswith('end'):
  700. text = line.split()
  701. try:
  702. instr[self.subInstr[text[0]]] = float(text[1])
  703. except (IndexError, KeyError):
  704. GError(_("Failed to read instruction %s.") % instruction)
  705. return False
  706. self.instruction.update(instr)
  707. return True
  708. def _toDict(self, paperStr):
  709. sizeDict = dict()
  710. # cats = self.subInstr[ 'Width', 'Height', 'Left', 'Right', 'Top', 'Bottom']
  711. for line in paperStr.strip().split('\n'):
  712. d = dict(zip(self.cats, line.split()[1:]))
  713. sizeDict[line.split()[0]] = d
  714. return sizeDict
  715. class Mapinfo(InstructionObject):
  716. """!Class representing mapinfo instruction"""
  717. def __init__(self, id):
  718. InstructionObject.__init__(self, id = id)
  719. self.type = 'mapinfo'
  720. # default values
  721. self.defaultInstruction = dict(unit = 'inch', where = (0, 0),
  722. font = 'Helvetica', fontsize = 10, color = 'black', background = 'none',
  723. #font = 'Sans', fontsize = 10, color = '0:0:0', background = 'none',
  724. border = 'none', rect = None)
  725. # current values
  726. self.instruction = dict(self.defaultInstruction)
  727. def __str__(self):
  728. instr = "mapinfo\n"
  729. instr += " where %.3f %.3f\n" % (self.instruction['where'][0], self.instruction['where'][1])
  730. instr += string.Template(" font $font\n fontsize $fontsize\n color $color\n").substitute(self.instruction)
  731. instr += string.Template(" background $background\n border $border\n").substitute(self.instruction)
  732. instr += " end"
  733. return instr
  734. def Read(self, instruction, text):
  735. """!Read instruction and save information"""
  736. instr = {}
  737. try:
  738. for line in text:
  739. sub = line.split(None,1)
  740. if sub[0] == 'font':
  741. instr['font'] = sub[1]
  742. elif sub[0] == 'fontsize':
  743. instr['fontsize'] = int(sub[1])
  744. elif sub[0] == 'color':
  745. instr['color'] = sub[1]
  746. elif sub[0] == 'background':
  747. instr['background'] = sub[1]
  748. elif sub[0] == 'border':
  749. instr['border'] = sub[1]
  750. elif sub[0] == 'where':
  751. instr['where'] = float(sub[1].split()[0]), float(sub[1].split()[1])
  752. except (ValueError, IndexError):
  753. GError(_("Failed to read instruction %s") % instruction)
  754. return False
  755. self.instruction.update(instr)
  756. self.instruction['rect'] = self.EstimateRect(mapinfoDict = self.instruction)
  757. return True
  758. def EstimateRect(self, mapinfoDict):
  759. """!Estimate size to draw mapinfo"""
  760. w = mapinfoDict['fontsize'] * 20 # any better estimation?
  761. h = mapinfoDict['fontsize'] * 7
  762. width = self.unitConv.convert(value = w, fromUnit = 'point', toUnit = 'inch')
  763. height = self.unitConv.convert(value = h, fromUnit = 'point', toUnit = 'inch')
  764. return wx.Rect2D(x = float(mapinfoDict['where'][0]), y = float(mapinfoDict['where'][1]), w = width, h = height)
  765. class Text(InstructionObject):
  766. """!Class representing text instruction"""
  767. def __init__(self, id):
  768. InstructionObject.__init__(self, id = id)
  769. self.type = 'text'
  770. # default values
  771. self.defaultInstruction = dict(text = "", font = "Helvetica", fontsize = 10, color = 'black', background = 'none',
  772. hcolor = 'none', hwidth = 1, border = 'none', width = '1', XY = True,
  773. where = (0,0), unit = 'inch', rotate = None,
  774. ref = "center center", xoffset = 0, yoffset = 0, east = None, north = None)
  775. # current values
  776. self.instruction = dict(self.defaultInstruction)
  777. def __str__(self):
  778. text = self.instruction['text'].replace('\n','\\n')
  779. instr = "text %s %s" % (self.instruction['east'], self.instruction['north'])
  780. try:
  781. instr += " %s\n" % text.encode('latin_1')
  782. except UnicodeEncodeError, err:
  783. try:
  784. pos = str(err).split('position')[1].split(':')[0].strip()
  785. except IndexError:
  786. pos = ''
  787. if pos:
  788. message = _("Characters on position %s are not supported "
  789. "by ISO-8859-1 (Latin 1) encoding "
  790. "which is required by module ps.map.") % pos
  791. else:
  792. message = _("Not all characters are supported "
  793. "by ISO-8859-1 (Latin 1) encoding "
  794. "which is required by module ps.map.")
  795. GMessage(message = message)
  796. return ''
  797. instr += (string.Template(" font $font\n fontsize $fontsize\n color $color\n").
  798. substitute(self.instruction).
  799. encode('latin_1'))
  800. instr += string.Template(" hcolor $hcolor\n").substitute(self.instruction).encode('latin_1')
  801. if self.instruction['hcolor'] != 'none':
  802. instr += string.Template(" hwidth $hwidth\n").substitute(self.instruction).encode('latin_1')
  803. instr += string.Template(" border $border\n").substitute(self.instruction).encode('latin_1')
  804. if self.instruction['border'] != 'none':
  805. instr += string.Template(" width $width\n").substitute(self.instruction).encode('latin_1')
  806. instr += string.Template(" background $background\n").substitute(self.instruction).encode('latin_1')
  807. if self.instruction["ref"] != '0':
  808. instr += string.Template(" ref $ref\n").substitute(self.instruction).encode('latin_1')
  809. if self.instruction["rotate"]:
  810. instr += string.Template(" rotate $rotate\n").substitute(self.instruction).encode('latin_1')
  811. if float(self.instruction["xoffset"]) or float(self.instruction["yoffset"]):
  812. instr += (string.Template(" xoffset $xoffset\n yoffset $yoffset\n").
  813. substitute(self.instruction).encode('latin_1'))
  814. instr += " end"
  815. return instr
  816. def Read(self, instruction, text, **kwargs):
  817. """!Read instruction and save information"""
  818. map = kwargs['mapInstruction']
  819. instr = {}
  820. for line in text:
  821. try:
  822. sub = line.split(None, 1)[0]
  823. if sub == 'text':
  824. e, n = line.split(None, 3)[1:3]
  825. if '%' in e and '%' in n:
  826. instr['XY'] = True
  827. instr['east'], instr['north'] = self.PercentToReal(e, n)
  828. else:
  829. instr['XY'] = False
  830. instr['east'], instr['north'] = float(e), float(n)
  831. instr['text'] = line.split(None, 3)[3]
  832. elif sub == 'font':
  833. instr['font'] = line.split(None, 1)[1]
  834. elif sub == 'fontsize':
  835. instr['fontsize'] = float(line.split(None, 1)[1])
  836. elif sub == 'color':
  837. instr['color'] = line.split(None, 1)[1]
  838. elif sub == 'width':
  839. instr['width'] = line.split(None, 1)[1]
  840. elif sub == 'hcolor':
  841. instr['hcolor'] = line.split(None, 1)[1]
  842. elif sub == 'hwidth':
  843. instr['hwidth'] = line.split(None, 1)[1]
  844. elif sub == 'background':
  845. instr['background'] = line.split(None, 1)[1]
  846. elif sub == 'border':
  847. instr['border'] = line.split(None, 1)[1]
  848. elif sub == 'ref':
  849. instr['ref'] = line.split(None, 1)[1]
  850. elif sub == 'rotate':
  851. instr['rotate'] = float(line.split(None, 1)[1])
  852. elif sub == 'xoffset':
  853. instr['xoffset'] = int(line.split(None, 1)[1])
  854. elif sub == 'yoffset':
  855. instr['yoffset'] = int(line.split(None, 1)[1])
  856. elif sub == 'opaque':
  857. if line.split(None, 1)[1].lower() in ('n', 'none'):
  858. instr['background'] = 'none'
  859. except(IndexError, ValueError):
  860. GError(_("Failed to read instruction %s") % instruction)
  861. return False
  862. instr['where'] = PaperMapCoordinates(map = map, x = instr['east'], y = instr['north'], paperToMap = False)
  863. self.instruction.update(instr)
  864. return True
  865. def PercentToReal(self, e, n):
  866. """!Converts text coordinates from percent of region to map coordinates"""
  867. e, n = float(e.strip('%')), float(n.strip('%'))
  868. region = grass.region()
  869. N = region['s'] + (region['n'] - region['s']) / 100 * n
  870. E = region['w'] + (region['e'] - region['w']) / 100 * e
  871. return E, N
  872. class Scalebar(InstructionObject):
  873. """!Class representing scalebar instruction"""
  874. def __init__(self, id):
  875. InstructionObject.__init__(self, id = id)
  876. self.type = 'scalebar'
  877. # default values
  878. self.defaultInstruction = dict(unit = 'inch', where = (1,1),
  879. unitsLength = 'auto', unitsHeight = 'inch',
  880. length = None, height = 0.1, rect = None,
  881. fontsize = 10, background = 'y',
  882. scalebar = 'f', segment = 4, numbers = 1)
  883. # current values
  884. self.instruction = dict(self.defaultInstruction)
  885. def __str__(self):
  886. instr = string.Template("scalebar $scalebar\n").substitute(self.instruction)
  887. instr += " where %.3f %.3f\n" % (self.instruction['where'][0], self.instruction['where'][1])
  888. instr += string.Template(" length $length\n units $unitsLength\n").substitute(self.instruction)
  889. instr += string.Template(" height $height\n").substitute(self.instruction)
  890. instr += string.Template(" segment $segment\n numbers $numbers\n").substitute(self.instruction)
  891. instr += string.Template(" fontsize $fontsize\n background $background\n").substitute(self.instruction)
  892. instr += " end"
  893. return instr
  894. def Read(self, instruction, text, **kwargs):
  895. """!Read instruction and save information"""
  896. scale = kwargs['scale']
  897. instr = {}
  898. for line in text:
  899. try:
  900. if line.startswith('scalebar'):
  901. if 'scalebar s' in line:
  902. instr['scalebar'] = 's'
  903. else:
  904. instr['scalebar'] = 'f'
  905. elif line.startswith('where'):
  906. instr['where'] = map(float, line.split()[1:3])
  907. elif line.startswith('length'):
  908. instr['length'] = float(line.split()[1])
  909. elif line.startswith('units'):
  910. if line.split()[1] in ['auto', 'meters', 'kilometers', 'feet', 'miles', 'nautmiles']:
  911. instr['unitsLength'] = line.split()[1]
  912. elif line.startswith('height'):
  913. instr['height'] = float(line.split()[1])
  914. elif line.startswith('fontsize'):
  915. instr['fontsize'] = float(line.split()[1])
  916. elif line.startswith('numbers'):
  917. instr['numbers'] = int(line.split()[1])
  918. elif line.startswith('segment'):
  919. instr['segment'] = int(line.split()[1])
  920. elif line.startswith('background'):
  921. if line.split()[1].strip().lower() in ('y','yes'):
  922. instr['background'] = 'y'
  923. elif line.split()[1].strip().lower() in ('n','no', 'none'):
  924. instr['background'] = 'n'
  925. except(IndexError, ValueError):
  926. GError(_("Failed to read instruction %s") % instruction)
  927. return False
  928. self.instruction.update(instr)
  929. w, h = self.EstimateSize(scalebarDict = self.instruction, scale = scale)
  930. x = self.instruction['where'][0] - w / 2
  931. y = self.instruction['where'][1] - h / 2
  932. self.instruction['rect'] = wx.Rect2D(x, y, w, h)
  933. return True
  934. def EstimateSize(self, scalebarDict, scale):
  935. """!Estimate size to draw scalebar"""
  936. units = projInfo()['units']
  937. if not units or units not in self.unitConv.getAllUnits():
  938. units = 'meters'
  939. if scalebarDict['unitsLength'] != 'auto':
  940. length = self.unitConv.convert(value = scalebarDict['length'], fromUnit = scalebarDict['unitsLength'], toUnit = 'inch')
  941. else:
  942. length = self.unitConv.convert(value = scalebarDict['length'], fromUnit = units, toUnit = 'inch')
  943. length *= scale
  944. length *= 1.1 #for numbers on the edge
  945. height = scalebarDict['height'] + 2 * self.unitConv.convert(value = scalebarDict['fontsize'], fromUnit = 'point', toUnit = 'inch')
  946. return (length, height)
  947. class RasterLegend(InstructionObject):
  948. """!Class representing colortable instruction"""
  949. def __init__(self, id):
  950. InstructionObject.__init__(self, id = id)
  951. self.type = 'rasterLegend'
  952. # default values
  953. self.defaultInstruction = dict(rLegend = False, unit = 'inch', rasterDefault = True, raster = None,
  954. discrete = None, type = None,
  955. where = (0, 0),
  956. width = None, height = None, cols = 1, font = "Helvetica", fontsize = 10,
  957. #color = '0:0:0', tickbar = False, range = False, min = 0, max = 0,
  958. color = 'black', tickbar = 'n', range = False, min = 0, max = 0,
  959. nodata = 'n')
  960. # current values
  961. self.instruction = dict(self.defaultInstruction)
  962. def __str__(self):
  963. instr = "colortable y\n"
  964. instr += string.Template(" raster $raster\n").substitute(self.instruction)
  965. instr += " where %.3f %.3f\n" % (self.instruction['where'][0], self.instruction['where'][1])
  966. if self.instruction['width']:
  967. instr += string.Template(" width $width\n").substitute(self.instruction)
  968. instr += string.Template(" discrete $discrete\n").substitute(self.instruction)
  969. if self.instruction['discrete'] == 'n':
  970. if self.instruction['height']:
  971. instr += string.Template(" height $height\n").substitute(self.instruction)
  972. instr += string.Template(" tickbar $tickbar\n").substitute(self.instruction)
  973. if self.instruction['range']:
  974. instr += string.Template(" range $min $max\n").substitute(self.instruction)
  975. else:
  976. instr += string.Template(" cols $cols\n").substitute(self.instruction)
  977. instr += string.Template(" nodata $nodata\n").substitute(self.instruction)
  978. instr += string.Template(" font $font\n fontsize $fontsize\n color $color\n")\
  979. .substitute(self.instruction)
  980. instr += " end"
  981. return instr
  982. def Read(self, instruction, text, **kwargs):
  983. """!Read instruction and save information"""
  984. instr = {}
  985. instr['rLegend'] = True
  986. for line in text:
  987. try:
  988. if line.startswith('where'):
  989. instr['where'] = map(float, line.split()[1:3])
  990. elif line.startswith('font '):
  991. instr['font'] = line.split()[1]
  992. elif line.startswith('fontsize'):
  993. instr['fontsize'] = float(line.split()[1])
  994. elif line.startswith('color '):
  995. instr['color'] = line.split()[1]
  996. elif line.startswith('raster'):
  997. instr['raster'] = line.split()[1]
  998. elif line.startswith('width'):
  999. instr['width'] = float(line.split()[1])
  1000. elif line.startswith('height'):
  1001. instr['height'] = float(line.split()[1])
  1002. elif line.startswith('cols'):
  1003. instr['cols'] = int(line.split()[1])
  1004. elif line.startswith('range'):
  1005. instr['range'] = True
  1006. instr['min'] = float(line.split()[1])
  1007. instr['max'] = float(line.split()[2])
  1008. elif line.startswith('nodata'):
  1009. if line.split()[1].strip().lower() in ('y','yes'):
  1010. instr['nodata'] = 'y'
  1011. elif line.split()[1].strip().lower() in ('n','no', 'none'):
  1012. instr['nodata'] = 'n'
  1013. elif line.startswith('tickbar'):
  1014. if line.split()[1].strip().lower() in ('y','yes'):
  1015. instr['tickbar'] = 'y'
  1016. elif line.split()[1].strip().lower() in ('n','no', 'none'):
  1017. instr['tickbar'] = 'n'
  1018. elif line.startswith('discrete'):
  1019. if line.split()[1].strip().lower() in ('y','yes'):
  1020. instr['discrete'] = 'y'
  1021. elif line.split()[1].strip().lower() in ('n','no', 'none'):
  1022. instr['discrete'] = 'n'
  1023. except(IndexError, ValueError):
  1024. GError(_("Failed to read instruction %s") % instruction)
  1025. return False
  1026. if 'raster' in instr:
  1027. instr['rasterDefault'] = False
  1028. if 'discrete' not in instr:
  1029. rasterType = getRasterType(map = instr['raster'])
  1030. instr['type'] = rasterType
  1031. if rasterType == 'CELL':
  1032. instr['discrete'] = 'y'
  1033. else:
  1034. instr['discrete'] = 'n'
  1035. else:
  1036. instr['rasterDefault'] = True
  1037. self.instruction.update(instr)
  1038. # add 'rect' in the end
  1039. return True
  1040. def EstimateHeight(self, raster, discrete, fontsize, cols = None, height = None):
  1041. """!Estimate height to draw raster legend"""
  1042. if discrete == 'n':
  1043. if height:
  1044. height = height
  1045. else:
  1046. height = self.unitConv.convert(value = fontsize * 10,
  1047. fromUnit = 'point', toUnit = 'inch')
  1048. if discrete == 'y':
  1049. if cols:
  1050. cols = cols
  1051. else:
  1052. cols = 1
  1053. rinfo = grass.raster_info(raster)
  1054. if rinfo['datatype'] in ('DCELL', 'FCELL'):
  1055. minim, maxim = rinfo['min'], rinfo['max']
  1056. rows = ceil(maxim / cols )
  1057. else:
  1058. cat = grass.read_command('r.category', map = raster,
  1059. fs = ':').strip().split('\n')
  1060. rows = ceil(float(len(cat)) / cols )
  1061. height = self.unitConv.convert(value = 1.5 * rows * fontsize, fromUnit = 'point', toUnit = 'inch')
  1062. return height
  1063. def EstimateWidth(self, raster, discrete, fontsize, cols = None, width = None, paperInstr = None):
  1064. """!Estimate size to draw raster legend"""
  1065. if discrete == 'n':
  1066. rinfo = grass.raster_info(raster)
  1067. minim, maxim = rinfo['min'], rinfo['max']
  1068. if width:
  1069. width = width
  1070. else:
  1071. width = self.unitConv.convert(value = fontsize * 2,
  1072. fromUnit = 'point', toUnit = 'inch')
  1073. text = len(max(str(minim), str(maxim), key = len))
  1074. textPart = self.unitConv.convert(value = text * fontsize / 2,
  1075. fromUnit = 'point', toUnit = 'inch')
  1076. width += textPart
  1077. elif discrete == 'y':
  1078. if cols:
  1079. cols = cols
  1080. else:
  1081. cols = 1
  1082. if width:
  1083. width = width
  1084. else:
  1085. paperWidth = paperInstr['Width'] - paperInstr['Right'] - paperInstr['Left']
  1086. width = (paperWidth / cols) * (cols - 1) + 1
  1087. return width
  1088. class VectorLegend(InstructionObject):
  1089. """!Class representing colortable instruction"""
  1090. def __init__(self, id):
  1091. InstructionObject.__init__(self, id = id)
  1092. self.type = 'vectorLegend'
  1093. # default values
  1094. self.defaultInstruction = dict(vLegend = False, unit = 'inch', where = (0, 0),
  1095. defaultSize = True, width = 0.4, cols = 1, span = None,
  1096. font = "Helvetica", fontsize = 10,
  1097. border = 'none')
  1098. # current values
  1099. self.instruction = dict(self.defaultInstruction)
  1100. def __str__(self):
  1101. instr = "vlegend\n"
  1102. instr += " where %.3f %.3f\n" % (self.instruction['where'][0], self.instruction['where'][1])
  1103. instr += string.Template(" font $font\n fontsize $fontsize\n").substitute(self.instruction)
  1104. instr += string.Template(" width $width\n cols $cols\n").substitute(self.instruction)
  1105. if self.instruction['span']:
  1106. instr += string.Template(" span $span\n").substitute(self.instruction)
  1107. instr += string.Template(" border $border\n").substitute(self.instruction)
  1108. instr += " end"
  1109. return instr
  1110. def Read(self, instruction, text, **kwargs):
  1111. """!Read instruction and save information"""
  1112. instr = {}
  1113. instr['vLegend'] = True
  1114. for line in text:
  1115. try:
  1116. if line.startswith('where'):
  1117. instr['where'] = map(float, line.split()[1:3])
  1118. elif line.startswith('font '):
  1119. instr['font'] = line.split()[1]
  1120. elif line.startswith('fontsize'):
  1121. instr['fontsize'] = float(line.split()[1])
  1122. elif line.startswith('width'):
  1123. instr['width'] = float(line.split()[1])
  1124. elif line.startswith('cols'):
  1125. instr['cols'] = int(line.split()[1])
  1126. elif line.startswith('span'):
  1127. instr['span'] = float(line.split()[1])
  1128. elif line.startswith('border'):
  1129. instr['border'] = line.split()[1]
  1130. except(IndexError, ValueError):
  1131. GError(_("Failed to read instruction %s") % instruction)
  1132. return False
  1133. self.instruction.update(instr)
  1134. return True
  1135. def EstimateSize(self, vectorInstr, fontsize, width = None, cols = None):
  1136. """!Estimate size to draw vector legend"""
  1137. if width:
  1138. width = width
  1139. else:
  1140. width = fontsize/24.0
  1141. if cols:
  1142. cols = cols
  1143. else:
  1144. cols = 1
  1145. vectors = vectorInstr['list']
  1146. labels = [vector[4] for vector in vectors if vector[3] != 0]
  1147. extent = (len(max(labels, key = len)) * fontsize / 2, fontsize)
  1148. wExtent = self.unitConv.convert(value = extent[0], fromUnit = 'point', toUnit = 'inch')
  1149. hExtent = self.unitConv.convert(value = extent[1], fromUnit = 'point', toUnit = 'inch')
  1150. w = (width + wExtent) * cols
  1151. h = len(labels) * hExtent / cols
  1152. h *= 1.1
  1153. return (w, h)
  1154. class Raster(InstructionObject):
  1155. """!Class representing raster instruction"""
  1156. def __init__(self, id):
  1157. InstructionObject.__init__(self, id = id)
  1158. self.type = 'raster'
  1159. # default values
  1160. self.defaultInstruction = dict(isRaster = False, raster = None)
  1161. # current values
  1162. self.instruction = dict(self.defaultInstruction)
  1163. def __str__(self):
  1164. instr = string.Template("raster $raster").substitute(self.instruction)
  1165. return instr
  1166. def Read(self, instruction, text):
  1167. """!Read instruction and save information"""
  1168. instr = {}
  1169. instr['isRaster'] = True
  1170. try:
  1171. map = text.split()[1]
  1172. except IndexError:
  1173. GError(_("Failed to read instruction %s") % instruction)
  1174. return False
  1175. try:
  1176. info = grass.find_file(map, element = 'cell')
  1177. except grass.ScriptError, e:
  1178. GError(message = e.value)
  1179. return False
  1180. instr['raster'] = info['fullname']
  1181. self.instruction.update(instr)
  1182. return True
  1183. class Vector(InstructionObject):
  1184. """!Class keeps vector layers"""
  1185. def __init__(self, id):
  1186. InstructionObject.__init__(self, id = id)
  1187. self.type = 'vector'
  1188. # default values
  1189. self.defaultInstruction = dict(list = None)# [vmap, type, id, lpos, label]
  1190. # current values
  1191. self.instruction = dict(self.defaultInstruction)
  1192. def __str__(self):
  1193. return ''
  1194. def Read(self, instruction, text, **kwargs):
  1195. """!Read instruction and save information"""
  1196. instr = {}
  1197. for line in text:
  1198. if line.startswith('vpoints') or line.startswith('vlines') or line.startswith('vareas'):
  1199. # subtype
  1200. if line.startswith('vpoints'):
  1201. subType = 'points'
  1202. elif line.startswith('vlines'):
  1203. subType = 'lines'
  1204. elif line.startswith('vareas'):
  1205. subType = 'areas'
  1206. # name of vector map
  1207. vmap = line.split()[1]
  1208. try:
  1209. info = grass.find_file(vmap, element = 'vector')
  1210. except grass.ScriptError, e:
  1211. GError(message = e.value)
  1212. return False
  1213. vmap = info['fullname']
  1214. # id
  1215. id = kwargs['id']
  1216. # lpos
  1217. lpos = kwargs['vectorMapNumber']
  1218. #label
  1219. label = '('.join(vmap.split('@')) + ')'
  1220. break
  1221. instr = [vmap, subType, id, lpos, label]
  1222. if not self.instruction['list']:
  1223. self.instruction['list'] = []
  1224. self.instruction['list'].append(instr)
  1225. return True
  1226. class VProperties(InstructionObject):
  1227. """!Class represents instructions vareas, vlines, vpoints"""
  1228. def __init__(self, id, subType):
  1229. InstructionObject.__init__(self, id = id)
  1230. self.type = 'vProperties'
  1231. self.subType = subType
  1232. # default values
  1233. if self.subType == 'points':
  1234. dd = dict(subType = 'points', name = None, type = 'point or centroid', connection = False, layer = '1',
  1235. masked = 'n', color = '0:0:0', width = 1,
  1236. fcolor = '255:0:0', rgbcolumn = None, symbol = os.path.join('basic', 'x'), eps = None,
  1237. size = 5, sizecolumn = None, scale = None,
  1238. rotation = False, rotate = 0, rotatecolumn = None, label = None, lpos = None)
  1239. elif self.subType == 'lines':
  1240. dd = dict(subType = 'lines', name = None, type = 'line or boundary', connection = False, layer = '1',
  1241. masked = 'n', color = '0:0:0', hwidth = 1,
  1242. hcolor = 'none', rgbcolumn = None,
  1243. width = 1, cwidth = None,
  1244. style = 'solid', linecap = 'butt', label = None, lpos = None)
  1245. else: # areas
  1246. dd = dict(subType = 'areas', name = None, connection = False, layer = '1',
  1247. masked = 'n', color = '0:0:0', width = 1,
  1248. fcolor = 'none', rgbcolumn = None,
  1249. pat = None, pwidth = 1, scale = 1, label = None, lpos = None)
  1250. self.defaultInstruction = dd
  1251. # current values
  1252. self.instruction = dict(self.defaultInstruction)
  1253. def __str__(self):
  1254. dic = self.instruction
  1255. vInstruction = string.Template("v$subType $name\n").substitute(dic)
  1256. #data selection
  1257. if self.subType in ('points', 'lines'):
  1258. vInstruction += string.Template(" type $type\n").substitute(dic)
  1259. if dic['connection']:
  1260. vInstruction += string.Template(" layer $layer\n").substitute(dic)
  1261. if dic.has_key('cats'):
  1262. vInstruction += string.Template(" cats $cats\n").substitute(dic)
  1263. elif dic.has_key('where'):
  1264. vInstruction += string.Template(" where $where\n").substitute(dic)
  1265. vInstruction += string.Template(" masked $masked\n").substitute(dic)
  1266. #colors
  1267. vInstruction += string.Template(" color $color\n").substitute(dic)
  1268. if self.subType in ('points', 'areas'):
  1269. if dic['color'] != 'none':
  1270. vInstruction += string.Template(" width $width\n").substitute(dic)
  1271. if dic['rgbcolumn']:
  1272. vInstruction += string.Template(" rgbcolumn $rgbcolumn\n").substitute(dic)
  1273. vInstruction += string.Template(" fcolor $fcolor\n").substitute(dic)
  1274. else:
  1275. if dic['rgbcolumn']:
  1276. vInstruction += string.Template(" rgbcolumn $rgbcolumn\n").substitute(dic)
  1277. elif dic['hcolor'] != 'none':
  1278. vInstruction += string.Template(" hwidth $hwidth\n").substitute(dic)
  1279. vInstruction += string.Template(" hcolor $hcolor\n").substitute(dic)
  1280. # size and style
  1281. if self.subType == 'points':
  1282. if dic['symbol']:
  1283. vInstruction += string.Template(" symbol $symbol\n").substitute(dic)
  1284. else: #eps
  1285. vInstruction += string.Template(" eps $eps\n").substitute(dic)
  1286. if dic['size']:
  1287. vInstruction += string.Template(" size $size\n").substitute(dic)
  1288. else: # sizecolumn
  1289. vInstruction += string.Template(" sizecolumn $sizecolumn\n").substitute(dic)
  1290. vInstruction += string.Template(" scale $scale\n").substitute(dic)
  1291. if dic['rotation']:
  1292. if dic['rotate'] is not None:
  1293. vInstruction += string.Template(" rotate $rotate\n").substitute(dic)
  1294. else:
  1295. vInstruction += string.Template(" rotatecolumn $rotatecolumn\n").substitute(dic)
  1296. if self.subType == 'areas':
  1297. if dic['pat'] is not None:
  1298. vInstruction += string.Template(" pat $pat\n").substitute(dic)
  1299. vInstruction += string.Template(" pwidth $pwidth\n").substitute(dic)
  1300. vInstruction += string.Template(" scale $scale\n").substitute(dic)
  1301. if self.subType == 'lines':
  1302. if dic['width'] is not None:
  1303. vInstruction += string.Template(" width $width\n").substitute(dic)
  1304. else:
  1305. vInstruction += string.Template(" cwidth $cwidth\n").substitute(dic)
  1306. vInstruction += string.Template(" style $style\n").substitute(dic)
  1307. vInstruction += string.Template(" linecap $linecap\n").substitute(dic)
  1308. #position and label in vlegend
  1309. vInstruction += string.Template(" label $label\n lpos $lpos\n").substitute(dic)
  1310. vInstruction += " end"
  1311. return vInstruction
  1312. def Read(self, instruction, text, **kwargs):
  1313. """!Read instruction and save information"""
  1314. instr = {}
  1315. try:
  1316. info = grass.find_file(name = text[0].split()[1], element = 'vector')
  1317. except grass.ScriptError, e:
  1318. GError(message = e.value)
  1319. return False
  1320. instr['name'] = info['fullname']
  1321. #connection
  1322. instr['connection'] = True
  1323. self.mapDBInfo = dbm_base.VectorDBInfo(instr['name'])
  1324. self.layers = self.mapDBInfo.layers.keys()
  1325. if not self.layers:
  1326. instr['connection'] = False
  1327. # points
  1328. if text[0].startswith('vpoints'):
  1329. for line in text[1:]:
  1330. if line.startswith('type'):
  1331. tp = []
  1332. if line.find('point') != -1:
  1333. tp.append('point')
  1334. if line.find('centroid') != -1:
  1335. tp.append('centroid')
  1336. instr['type'] = ' or '.join(tp)
  1337. elif line.startswith('fcolor'):
  1338. instr['fcolor'] = line.split()[1]
  1339. elif line.startswith('rgbcolumn'):
  1340. instr['rgbcolumn'] = line.split()[1]
  1341. elif line.startswith('symbol'):
  1342. instr['symbol'] = line.split()[1]
  1343. elif line.startswith('eps'):
  1344. instr['eps'] = line.split()[1]
  1345. elif line.startswith('size '):
  1346. instr['size'] = line.split()[1]
  1347. elif line.startswith('sizecolumn'):
  1348. instr['size'] = None
  1349. instr['sizecolumn'] = line.split()[1]
  1350. elif line.startswith('scale '):
  1351. instr['scale'] = float(line.split()[1])
  1352. elif line.startswith('rotate '):
  1353. instr['rotation'] = True
  1354. instr['rotate'] = line.split()[1]
  1355. elif line.startswith('rotatecolumn'):
  1356. instr['rotatecolumn'] = line.split()[1]
  1357. instr['rotation'] = True
  1358. instr['rotate'] = None
  1359. # lines
  1360. elif text[0].startswith('vlines'):
  1361. for line in text[1:]:
  1362. if line.startswith('type'):
  1363. tp = []
  1364. if line.find('line') != -1:
  1365. tp.append('line')
  1366. if line.find('boundary') != -1:
  1367. tp.append('boundary')
  1368. instr['type'] = ' or '.join(tp)
  1369. elif line.startswith('hwidth'):
  1370. instr['hwidth'] = float(line.split()[1])
  1371. elif line.startswith('hcolor'):
  1372. instr['hcolor'] = line.split()[1]
  1373. elif line.startswith('rgbcolumn'):
  1374. instr['rgbcolumn'] = line.split()[1]
  1375. elif line.startswith('cwidth'):
  1376. instr['cwidth'] = float(line.split()[1])
  1377. instr['width'] = None
  1378. elif line.startswith('style'):
  1379. instr['style'] = line.split()[1]
  1380. elif line.startswith('linecap'):
  1381. instr['linecap'] = line.split()[1]
  1382. elif text[0].startswith('vareas'):
  1383. for line in text[1:]:
  1384. if line.startswith('fcolor'):
  1385. instr['fcolor'] = line.split()[1]
  1386. elif line.startswith('pat'):
  1387. instr['pat'] = line.split()[1]
  1388. elif line.startswith('pwidth'):
  1389. instr['pwidth'] = float(line.split()[1])
  1390. elif line.startswith('scale'):
  1391. instr['scale'] = float(line.split()[1])
  1392. # same properties for all
  1393. for line in text[1:]:
  1394. if line.startswith('lpos'):
  1395. instr['lpos'] = int(line.split()[1])
  1396. elif line.startswith('label'):
  1397. instr['label'] = line.split(None, 1)[1]
  1398. elif line.startswith('layer'):
  1399. instr['layer'] = line.split()[1]
  1400. elif line.startswith('masked'):
  1401. if line.split()[1].lower() in ('y', 'yes'):
  1402. instr['masked'] = 'y'
  1403. else:
  1404. instr['masked'] = 'n'
  1405. elif line.startswith('color'):
  1406. instr['color'] = line.split()[1]
  1407. elif line.startswith('rgbcolumn'):
  1408. instr['rgbcolumn'] = line.split()[1]
  1409. elif line.startswith('width'):
  1410. instr['width'] = float(line.split()[1])
  1411. if 'label' not in instr:
  1412. instr['label'] = '('.join(instr['name'].split('@')) + ')'
  1413. if 'lpos' not in instr:
  1414. instr['lpos'] = kwargs['vectorMapNumber']
  1415. self.instruction.update(instr)
  1416. return True
  1417. class PsmapDialog(wx.Dialog):
  1418. def __init__(self, parent, id, title, settings, apply = True):
  1419. wx.Dialog.__init__(self, parent = parent, id = wx.ID_ANY,
  1420. title = title, size = wx.DefaultSize,
  1421. style = wx.CAPTION|wx.MINIMIZE_BOX|wx.CLOSE_BOX)
  1422. self.apply = apply
  1423. self.id = id
  1424. self.parent = parent
  1425. self.instruction = settings
  1426. self.objectType = None
  1427. self.unitConv = UnitConversion(self)
  1428. self.spinCtrlSize = (50, -1)
  1429. self.Bind(wx.EVT_CLOSE, self.OnClose)
  1430. def AddUnits(self, parent, dialogDict):
  1431. parent.units = dict()
  1432. parent.units['unitsLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Units:"))
  1433. choices = self.unitConv.getPageUnits()
  1434. parent.units['unitsCtrl'] = wx.Choice(parent, id = wx.ID_ANY, choices = choices)
  1435. parent.units['unitsCtrl'].SetStringSelection(dialogDict['unit'])
  1436. def AddPosition(self, parent, dialogDict):
  1437. parent.position = dict()
  1438. parent.position['comment'] = wx.StaticText(parent, id = wx.ID_ANY,\
  1439. label = _("Position of the top left corner\nfrom the top left edge of the paper"))
  1440. parent.position['xLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("X:"))
  1441. parent.position['yLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Y:"))
  1442. parent.position['xCtrl'] = wx.TextCtrl(parent, id = wx.ID_ANY, value = str(dialogDict['where'][0]), validator = TCValidator(flag = 'DIGIT_ONLY'))
  1443. parent.position['yCtrl'] = wx.TextCtrl(parent, id = wx.ID_ANY, value = str(dialogDict['where'][1]), validator = TCValidator(flag = 'DIGIT_ONLY'))
  1444. if dialogDict.has_key('unit'):
  1445. x = self.unitConv.convert(value = dialogDict['where'][0], fromUnit = 'inch', toUnit = dialogDict['unit'])
  1446. y = self.unitConv.convert(value = dialogDict['where'][1], fromUnit = 'inch', toUnit = dialogDict['unit'])
  1447. parent.position['xCtrl'].SetValue("%5.3f" % x)
  1448. parent.position['yCtrl'].SetValue("%5.3f" % y)
  1449. def AddFont(self, parent, dialogDict, color = True):
  1450. parent.font = dict()
  1451. ## parent.font['fontLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Choose font:"))
  1452. ## parent.font['fontCtrl'] = wx.FontPickerCtrl(parent, id = wx.ID_ANY)
  1453. ##
  1454. ## parent.font['fontCtrl'].SetSelectedFont(
  1455. ## wx.FontFromNativeInfoString(dialogDict['font'] + " " + str(dialogDict['fontsize'])))
  1456. ## parent.font['fontCtrl'].SetMaxPointSize(50)
  1457. ##
  1458. ## if color:
  1459. ## parent.font['colorLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Choose color:"))
  1460. ## parent.font['colorCtrl'] = wx.ColourPickerCtrl(parent, id = wx.ID_ANY, style=wx.FNTP_FONTDESC_AS_LABEL)
  1461. ## parent.font['colorCtrl'].SetColour(dialogDict['color'])
  1462. ## parent.font['colorCtrl'].SetColour(convertRGB(dialogDict['color']))
  1463. parent.font['fontLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Font:"))
  1464. parent.font['fontSizeLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Font size:"))
  1465. fontChoices = [ 'Times-Roman', 'Times-Italic', 'Times-Bold', 'Times-BoldItalic', 'Helvetica',\
  1466. 'Helvetica-Oblique', 'Helvetica-Bold', 'Helvetica-BoldOblique', 'Courier',\
  1467. 'Courier-Oblique', 'Courier-Bold', 'Courier-BoldOblique']
  1468. parent.font['fontCtrl'] = wx.Choice(parent, id = wx.ID_ANY, choices = fontChoices)
  1469. if dialogDict['font'] in fontChoices:
  1470. parent.font['fontCtrl'].SetStringSelection(dialogDict['font'])
  1471. else:
  1472. parent.font['fontCtrl'].SetStringSelection('Helvetica')
  1473. parent.font['fontSizeCtrl'] = wx.SpinCtrl(parent, id = wx.ID_ANY, min = 4, max = 50, initial = 10)
  1474. parent.font['fontSizeCtrl'].SetValue(dialogDict['fontsize'])
  1475. if color:
  1476. parent.font['colorLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Choose color:"))
  1477. parent.font['colorCtrl'] = wx.ColourPickerCtrl(parent, id = wx.ID_ANY)
  1478. parent.font['colorCtrl'].SetColour(convertRGB(dialogDict['color']))
  1479. ## parent.font['colorLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Color:"))
  1480. ## colorChoices = [ 'aqua', 'black', 'blue', 'brown', 'cyan', 'gray', 'green', 'indigo', 'magenta',\
  1481. ## 'orange', 'purple', 'red', 'violet', 'white', 'yellow']
  1482. ## parent.colorCtrl = wx.Choice(parent, id = wx.ID_ANY, choices = colorChoices)
  1483. ## parent.colorCtrl.SetStringSelection(parent.rLegendDict['color'])
  1484. ## parent.font['colorCtrl'] = wx.ColourPickerCtrl(parent, id = wx.ID_ANY)
  1485. ## parent.font['colorCtrl'].SetColour(dialogDict['color'])
  1486. def OnApply(self, event):
  1487. ok = self.update()
  1488. if ok:
  1489. self.parent.DialogDataChanged(id = self.id)
  1490. return True
  1491. else:
  1492. return False
  1493. def OnOK(self, event):
  1494. """!Apply changes, close dialog"""
  1495. ok = self.OnApply(event)
  1496. if ok:
  1497. self.Close()
  1498. def OnCancel(self, event):
  1499. """!Close dialog"""
  1500. self.Close()
  1501. def OnClose(self, event):
  1502. """!Destroy dialog and delete it from open dialogs"""
  1503. if self.objectType:
  1504. for each in self.objectType:
  1505. if each in self.parent.openDialogs:
  1506. del self.parent.openDialogs[each]
  1507. event.Skip()
  1508. self.Destroy()
  1509. def _layout(self, panel):
  1510. #buttons
  1511. btnCancel = wx.Button(self, wx.ID_CANCEL)
  1512. btnOK = wx.Button(self, wx.ID_OK)
  1513. btnOK.SetDefault()
  1514. if self.apply:
  1515. btnApply = wx.Button(self, wx.ID_APPLY)
  1516. # bindigs
  1517. btnOK.Bind(wx.EVT_BUTTON, self.OnOK)
  1518. btnOK.SetToolTipString(_("Close dialog and apply changes"))
  1519. #btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
  1520. btnCancel.SetToolTipString(_("Close dialog and ignore changes"))
  1521. btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
  1522. if self.apply:
  1523. btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
  1524. btnApply.SetToolTipString(_("Apply changes"))
  1525. # sizers
  1526. btnSizer = wx.StdDialogButtonSizer()
  1527. btnSizer.AddButton(btnCancel)
  1528. if self.apply:
  1529. btnSizer.AddButton(btnApply)
  1530. btnSizer.AddButton(btnOK)
  1531. btnSizer.Realize()
  1532. mainSizer = wx.BoxSizer(wx.VERTICAL)
  1533. mainSizer.Add(item = panel, proportion = 1, flag = wx.EXPAND | wx.ALL, border = 5)
  1534. mainSizer.Add(item = btnSizer, proportion = 0,
  1535. flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
  1536. self.SetSizer(mainSizer)
  1537. mainSizer.Layout()
  1538. mainSizer.Fit(self)
  1539. class PageSetupDialog(PsmapDialog):
  1540. def __init__(self, parent, id, settings):
  1541. PsmapDialog.__init__(self, parent = parent, id = id, title = "Page setup", settings = settings)
  1542. self.cat = ['Units', 'Format', 'Orientation', 'Width', 'Height', 'Left', 'Right', 'Top', 'Bottom']
  1543. paperString = RunCommand('ps.map', flags = 'p', read = True, quiet = True)
  1544. self.paperTable = self._toList(paperString)
  1545. self.unitsList = self.unitConv.getPageUnits()
  1546. self.pageSetupDict = settings[id].GetInstruction()
  1547. self._layout()
  1548. if self.pageSetupDict:
  1549. for item in self.cat[:3]:
  1550. self.getCtrl(item).SetSelection(self.getCtrl(item).FindString(self.pageSetupDict[item]))
  1551. for item in self.cat[3:]:
  1552. self.getCtrl(item).SetValue("%4.3f" % self.pageSetupDict[item])
  1553. if self.getCtrl('Format').GetString(self.getCtrl('Format').GetSelection()) != 'custom':
  1554. self.getCtrl('Width').Disable()
  1555. self.getCtrl('Height').Disable()
  1556. else:
  1557. self.getCtrl('Orientation').Disable()
  1558. # events
  1559. self.getCtrl('Units').Bind(wx.EVT_CHOICE, self.OnChoice)
  1560. self.getCtrl('Format').Bind(wx.EVT_CHOICE, self.OnChoice)
  1561. self.getCtrl('Orientation').Bind(wx.EVT_CHOICE, self.OnChoice)
  1562. self.btnOk.Bind(wx.EVT_BUTTON, self.OnOK)
  1563. def update(self):
  1564. self.pageSetupDict['Units'] = self.getCtrl('Units').GetString(self.getCtrl('Units').GetSelection())
  1565. self.pageSetupDict['Format'] = self.paperTable[self.getCtrl('Format').GetSelection()]['Format']
  1566. self.pageSetupDict['Orientation'] = self.getCtrl('Orientation').GetString(self.getCtrl('Orientation').GetSelection())
  1567. for item in self.cat[3:]:
  1568. self.pageSetupDict[item] = self.unitConv.convert(value = float(self.getCtrl(item).GetValue()),
  1569. fromUnit = self.pageSetupDict['Units'], toUnit = 'inch')
  1570. def OnOK(self, event):
  1571. try:
  1572. self.update()
  1573. except ValueError:
  1574. wx.MessageBox(message = _("Literal is not allowed!"), caption = _('Invalid input'),
  1575. style = wx.OK|wx.ICON_ERROR)
  1576. else:
  1577. event.Skip()
  1578. def _layout(self):
  1579. size = (110,-1)
  1580. #sizers
  1581. mainSizer = wx.BoxSizer(wx.VERTICAL)
  1582. pageBox = wx.StaticBox(self, id = wx.ID_ANY, label =" Page size ")
  1583. pageSizer = wx.StaticBoxSizer(pageBox, wx.VERTICAL)
  1584. marginBox = wx.StaticBox(self, id = wx.ID_ANY, label = " Margins ")
  1585. marginSizer = wx.StaticBoxSizer(marginBox, wx.VERTICAL)
  1586. horSizer = wx.BoxSizer(wx.HORIZONTAL)
  1587. #staticText + choice
  1588. choices = [self.unitsList, [item['Format'] for item in self.paperTable], ['Portrait', 'Landscape']]
  1589. propor = [0,1,1]
  1590. border = [5,3,3]
  1591. self.hBoxDict={}
  1592. for i, item in enumerate(self.cat[:3]):
  1593. hBox = wx.BoxSizer(wx.HORIZONTAL)
  1594. stText = wx.StaticText(self, id = wx.ID_ANY, label = item + ':')
  1595. choice = wx.Choice(self, id = wx.ID_ANY, choices = choices[i], size = size)
  1596. hBox.Add(stText, proportion = propor[i], flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = border[i])
  1597. hBox.Add(choice, proportion = 0, flag = wx.ALL, border = border[i])
  1598. if item == 'Units':
  1599. hBox.Add(size,1)
  1600. self.hBoxDict[item] = hBox
  1601. #staticText + TextCtrl
  1602. for item in self.cat[3:]:
  1603. hBox = wx.BoxSizer(wx.HORIZONTAL)
  1604. label = wx.StaticText(self, id = wx.ID_ANY, label = item + ':')
  1605. textctrl = wx.TextCtrl(self, id = wx.ID_ANY, size = size, value = '')
  1606. hBox.Add(label, proportion = 1, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 3)
  1607. hBox.Add(textctrl, proportion = 0, flag = wx.ALIGN_CENTRE|wx.ALL, border = 3)
  1608. self.hBoxDict[item] = hBox
  1609. sizer = list([mainSizer] + [pageSizer]*4 + [marginSizer]*4)
  1610. for i, item in enumerate(self.cat):
  1611. sizer[i].Add(self.hBoxDict[item], 0, wx.GROW|wx.RIGHT|wx.LEFT,5)
  1612. # OK button
  1613. btnSizer = wx.StdDialogButtonSizer()
  1614. self.btnOk = wx.Button(self, wx.ID_OK)
  1615. self.btnOk.SetDefault()
  1616. btnSizer.AddButton(self.btnOk)
  1617. btn = wx.Button(self, wx.ID_CANCEL)
  1618. btnSizer.AddButton(btn)
  1619. btnSizer.Realize()
  1620. horSizer.Add(pageSizer, proportion = 0, flag = wx.LEFT|wx.RIGHT|wx.BOTTOM, border = 10)
  1621. horSizer.Add(marginSizer, proportion = 0, flag = wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.EXPAND, border = 10)
  1622. mainSizer.Add(horSizer, proportion = 0, border = 10)
  1623. mainSizer.Add(btnSizer, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.ALL, border = 10)
  1624. self.SetSizer(mainSizer)
  1625. mainSizer.Fit(self)
  1626. def OnChoice(self, event):
  1627. currPaper = self.paperTable[self.getCtrl('Format').GetSelection()]
  1628. currUnit = self.getCtrl('Units').GetString(self.getCtrl('Units').GetSelection())
  1629. currOrient = self.getCtrl('Orientation').GetString(self.getCtrl('Orientation').GetSelection())
  1630. newSize = dict()
  1631. for item in self.cat[3:]:
  1632. newSize[item] = self.unitConv.convert(float(currPaper[item]), fromUnit = 'inch', toUnit = currUnit)
  1633. enable = True
  1634. if currPaper['Format'] != 'custom':
  1635. if currOrient == 'Landscape':
  1636. newSize['Width'], newSize['Height'] = newSize['Height'], newSize['Width']
  1637. for item in self.cat[3:]:
  1638. self.getCtrl(item).ChangeValue("%4.3f" % newSize[item])
  1639. enable = False
  1640. self.getCtrl('Width').Enable(enable)
  1641. self.getCtrl('Height').Enable(enable)
  1642. self.getCtrl('Orientation').Enable(not enable)
  1643. def getCtrl(self, item):
  1644. return self.hBoxDict[item].GetItem(1).GetWindow()
  1645. def _toList(self, paperStr):
  1646. sizeList = list()
  1647. for line in paperStr.strip().split('\n'):
  1648. d = dict(zip([self.cat[1]]+ self.cat[3:],line.split()))
  1649. sizeList.append(d)
  1650. d = {}.fromkeys([self.cat[1]]+ self.cat[3:], 100)
  1651. d.update(Format = 'custom')
  1652. sizeList.append(d)
  1653. return sizeList
  1654. class MapDialog(PsmapDialog):
  1655. """!Dialog for map frame settings and optionally raster and vector map selection"""
  1656. def __init__(self, parent, id, settings, rect = None, notebook = False):
  1657. PsmapDialog.__init__(self, parent = parent, id = id, title = "", settings = settings)
  1658. self.isNotebook = notebook
  1659. if self.isNotebook:
  1660. self.objectType = ('mapNotebook',)
  1661. else:
  1662. self.objectType = ('map',)
  1663. #notebook
  1664. if self.isNotebook:
  1665. self.notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT)
  1666. self.mPanel = MapFramePanel(parent = self.notebook, id = self.id[0], settings = self.instruction,
  1667. rect = rect, notebook = True)
  1668. self.id[0] = self.mPanel.getId()
  1669. self.rPanel = RasterPanel(parent = self.notebook, id = self.id[1], settings = self.instruction,
  1670. notebook = True)
  1671. self.id[1] = self.rPanel.getId()
  1672. self.vPanel = VectorPanel(parent = self.notebook, id = self.id[2], settings = self.instruction,
  1673. notebook = True)
  1674. self.id[2] = self.vPanel.getId()
  1675. self._layout(self.notebook)
  1676. self.SetTitle(_("Map settings"))
  1677. else:
  1678. self.mPanel = MapFramePanel(parent = self, id = self.id[0], settings = self.instruction,
  1679. rect = rect, notebook = False)
  1680. self.id[0] = self.mPanel.getId()
  1681. self._layout(self.mPanel)
  1682. self.SetTitle(_("Map frame settings"))
  1683. def OnApply(self, event):
  1684. """!Apply changes"""
  1685. if self.isNotebook:
  1686. okV = self.vPanel.update()
  1687. okR = self.rPanel.update()
  1688. if okV and self.id[2] in self.instruction:
  1689. self.parent.DialogDataChanged(id = self.id[2])
  1690. if okR and self.id[1] in self.instruction:
  1691. self.parent.DialogDataChanged(id = self.id[1])
  1692. if not okR or not okV:
  1693. return False
  1694. ok = self.mPanel.update()
  1695. if ok:
  1696. self.parent.DialogDataChanged(id = self.id[0])
  1697. return True
  1698. return False
  1699. def OnCancel(self, event):
  1700. """!Close dialog and remove tmp red box"""
  1701. self.parent.canvas.pdcTmp.RemoveId(self.parent.canvas.idZoomBoxTmp)
  1702. self.parent.canvas.Refresh()
  1703. self.Close()
  1704. def updateDialog(self):
  1705. """!Update raster and vector information"""
  1706. if self.mPanel.scaleChoice.GetSelection() == 0:
  1707. if self.mPanel.rasterTypeRadio.GetValue():
  1708. if 'raster' in self.parent.openDialogs:
  1709. if self.parent.openDialogs['raster'].rPanel.rasterYesRadio.GetValue() and \
  1710. self.parent.openDialogs['raster'].rPanel.rasterSelect.GetValue() == self.mPanel.select.GetValue():
  1711. self.mPanel.drawMap.SetValue(True)
  1712. else:
  1713. self.mPanel.drawMap.SetValue(False)
  1714. else:
  1715. if 'vector' in self.parent.openDialogs:
  1716. found = False
  1717. for each in self.parent.openDialogs['vector'].vPanel.vectorList:
  1718. if each[0] == self.mPanel.select.GetValue():
  1719. found = True
  1720. self.mPanel.drawMap.SetValue(found)
  1721. class MapFramePanel(wx.Panel):
  1722. """!wx.Panel with map (scale, region, border) settings"""
  1723. def __init__(self, parent, id, settings, rect, notebook = True):
  1724. wx.Panel.__init__(self, parent, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
  1725. self.id = id
  1726. self.instruction = settings
  1727. if notebook:
  1728. self.book = parent
  1729. self.book.AddPage(page = self, text = _("Map frame"))
  1730. self.mapDialog = self.book.GetParent()
  1731. else:
  1732. self.mapDialog = parent
  1733. if self.id is not None:
  1734. self.mapFrameDict = self.instruction[self.id].GetInstruction()
  1735. else:
  1736. self.id = wx.NewId()
  1737. mapFrame = MapFrame(self.id)
  1738. self.mapFrameDict = mapFrame.GetInstruction()
  1739. self.mapFrameDict['rect'] = rect
  1740. self._layout()
  1741. self.scale = [None]*4
  1742. self.center = [None]*4
  1743. self.selectedMap = self.mapFrameDict['map']
  1744. self.selectedRegion = self.mapFrameDict['region']
  1745. self.scaleType = self.mapFrameDict['scaleType']
  1746. self.mapType = self.mapFrameDict['mapType']
  1747. self.scaleChoice.SetSelection(self.mapFrameDict['scaleType'])
  1748. if self.instruction[self.id]:
  1749. self.drawMap.SetValue(self.mapFrameDict['drawMap'])
  1750. else:
  1751. self.drawMap.SetValue(True)
  1752. if self.mapFrameDict['scaleType'] == 0 and self.mapFrameDict['map']:
  1753. self.select.SetValue(self.mapFrameDict['map'])
  1754. if self.mapFrameDict['mapType'] == 'raster':
  1755. self.rasterTypeRadio.SetValue(True)
  1756. self.vectorTypeRadio.SetValue(False)
  1757. else:
  1758. self.rasterTypeRadio.SetValue(False)
  1759. self.vectorTypeRadio.SetValue(True)
  1760. elif self.mapFrameDict['scaleType'] == 1 and self.mapFrameDict['region']:
  1761. self.select.SetValue(self.mapFrameDict['region'])
  1762. self.OnMap(None)
  1763. self.scale[self.mapFrameDict['scaleType']] = self.mapFrameDict['scale']
  1764. self.center[self.mapFrameDict['scaleType']] = self.mapFrameDict['center']
  1765. self.OnScaleChoice(None)
  1766. self.OnElementType(None)
  1767. self.OnBorder(None)
  1768. def _layout(self):
  1769. """!Do layout"""
  1770. border = wx.BoxSizer(wx.VERTICAL)
  1771. box = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Map frame"))
  1772. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  1773. gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
  1774. #scale options
  1775. frameText = wx.StaticText(self, id = wx.ID_ANY, label = _("Map frame options:"))
  1776. scaleChoices = [_("fit frame to match selected map"),
  1777. _("fit frame to match saved region"),
  1778. _("fit frame to match current computational region"),
  1779. _("fixed scale and map center")]
  1780. self.scaleChoice = wx.Choice(self, id = wx.ID_ANY, choices = scaleChoices)
  1781. gridBagSizer.Add(frameText, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  1782. gridBagSizer.Add(self.scaleChoice, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  1783. #map and region selection
  1784. self.staticBox = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Map selection"))
  1785. sizerM = wx.StaticBoxSizer(self.staticBox, wx.HORIZONTAL)
  1786. self.mapSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
  1787. self.rasterTypeRadio = wx.RadioButton(self, id = wx.ID_ANY, label = " %s " % _("raster"), style = wx.RB_GROUP)
  1788. self.vectorTypeRadio = wx.RadioButton(self, id = wx.ID_ANY, label = " %s " % _("vector"))
  1789. self.drawMap = wx.CheckBox(self, id = wx.ID_ANY, label = "add selected map")
  1790. self.mapOrRegionText = [_("Map:"), _("Region:")]
  1791. dc = wx.PaintDC(self)# determine size of labels
  1792. width = max(dc.GetTextExtent(self.mapOrRegionText[0])[0], dc.GetTextExtent(self.mapOrRegionText[1])[0])
  1793. self.mapText = wx.StaticText(self, id = wx.ID_ANY, label = self.mapOrRegionText[0], size = (width, -1))
  1794. self.select = Select(self, id = wx.ID_ANY, size = globalvar.DIALOG_GSELECT_SIZE,
  1795. type = 'raster', multiple = False,
  1796. updateOnPopup = True, onPopup = None)
  1797. self.mapSizer.Add(self.rasterTypeRadio, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  1798. self.mapSizer.Add(self.vectorTypeRadio, pos = (0, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  1799. self.mapSizer.Add(self.drawMap, pos = (0, 3), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
  1800. self.mapSizer.Add(self.mapText, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  1801. self.mapSizer.Add(self.select, pos = (1, 1), span = (1, 3), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  1802. sizerM.Add(self.mapSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  1803. gridBagSizer.Add(sizerM, pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  1804. #map scale and center
  1805. boxC = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Map scale and center"))
  1806. sizerC = wx.StaticBoxSizer(boxC, wx.HORIZONTAL)
  1807. self.centerSizer = wx.FlexGridSizer(rows = 2, cols = 5, hgap = 5, vgap = 5)
  1808. centerText = wx.StaticText(self, id = wx.ID_ANY, label = _("Center:"))
  1809. self.eastingText = wx.StaticText(self, id = wx.ID_ANY, label = _("E:"))
  1810. self.northingText = wx.StaticText(self, id = wx.ID_ANY, label = _("N:"))
  1811. self.eastingTextCtrl = wx.TextCtrl(self, id = wx.ID_ANY, style = wx.TE_RIGHT, validator = TCValidator(flag = 'DIGIT_ONLY'))
  1812. self.northingTextCtrl = wx.TextCtrl(self, id = wx.ID_ANY, style = wx.TE_RIGHT, validator = TCValidator(flag = 'DIGIT_ONLY'))
  1813. scaleText = wx.StaticText(self, id = wx.ID_ANY, label = _("Scale:"))
  1814. scalePrefixText = wx.StaticText(self, id = wx.ID_ANY, label = _("1 :"))
  1815. self.scaleTextCtrl = wx.TextCtrl(self, id = wx.ID_ANY, value = "", style = wx.TE_RIGHT, validator = TCValidator('DIGIT_ONLY'))
  1816. self.centerSizer.Add(centerText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, border = 10)
  1817. self.centerSizer.Add(self.eastingText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
  1818. self.centerSizer.Add(self.eastingTextCtrl, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  1819. self.centerSizer.Add(self.northingText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
  1820. self.centerSizer.Add(self.northingTextCtrl, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  1821. self.centerSizer.Add(scaleText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, border = 10)
  1822. self.centerSizer.Add(scalePrefixText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
  1823. self.centerSizer.Add(self.scaleTextCtrl, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  1824. sizerC.Add(self.centerSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  1825. gridBagSizer.Add(sizerC, pos = (3, 0), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  1826. #resolution
  1827. flexSizer = wx.FlexGridSizer(rows = 1, cols = 2, hgap = 5, vgap = 5)
  1828. resolutionText = wx.StaticText(self, id = wx.ID_ANY, label = _("Map max resolution (dpi):"))
  1829. self.resolutionSpin = wx.SpinCtrl(self, id = wx.ID_ANY, min = 1, max = 1000, initial = 300)
  1830. flexSizer.Add(resolutionText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  1831. flexSizer.Add(self.resolutionSpin, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  1832. self.resolutionSpin.SetValue(self.mapFrameDict['resolution'])
  1833. gridBagSizer.Add(flexSizer, pos = (4, 0), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  1834. sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  1835. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  1836. # border
  1837. box = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Border"))
  1838. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  1839. gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
  1840. self.borderCheck = wx.CheckBox(self, id = wx.ID_ANY, label = (_("draw border around map frame")))
  1841. if self.mapFrameDict['border'] == 'y':
  1842. self.borderCheck.SetValue(True)
  1843. else:
  1844. self.borderCheck.SetValue(False)
  1845. self.borderColorText = wx.StaticText(self, id = wx.ID_ANY, label = _("border color:"))
  1846. self.borderWidthText = wx.StaticText(self, id = wx.ID_ANY, label = _("border width (pts):"))
  1847. self.borderColourPicker = wx.ColourPickerCtrl(self, id = wx.ID_ANY)
  1848. self.borderWidthCtrl = wx.SpinCtrl(self, id = wx.ID_ANY, min = 1, max = 100, initial = 1)
  1849. if self.mapFrameDict['border'] == 'y':
  1850. self.borderWidthCtrl.SetValue(int(self.mapFrameDict['width']))
  1851. self.borderColourPicker.SetColour(convertRGB(self.mapFrameDict['color']))
  1852. gridBagSizer.Add(self.borderCheck, pos = (0, 0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  1853. gridBagSizer.Add(self.borderColorText, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  1854. gridBagSizer.Add(self.borderWidthText, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  1855. gridBagSizer.Add(self.borderColourPicker, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  1856. gridBagSizer.Add(self.borderWidthCtrl, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  1857. sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  1858. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  1859. self.SetSizer(border)
  1860. self.Fit()
  1861. if projInfo()['proj'] == 'll':
  1862. self.scaleChoice.SetItems(self.scaleChoice.GetItems()[0:3])
  1863. boxC.Hide()
  1864. for each in self.centerSizer.GetChildren():
  1865. each.GetWindow().Hide()
  1866. # bindings
  1867. self.scaleChoice.Bind(wx.EVT_CHOICE, self.OnScaleChoice)
  1868. self.select.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnMap)
  1869. self.Bind(wx.EVT_RADIOBUTTON, self.OnElementType, self.vectorTypeRadio)
  1870. self.Bind(wx.EVT_RADIOBUTTON, self.OnElementType, self.rasterTypeRadio)
  1871. self.Bind(wx.EVT_CHECKBOX, self.OnBorder, self.borderCheck)
  1872. def OnMap(self, event):
  1873. """!Selected map or region changing"""
  1874. if self.select.GetValue():
  1875. self.selected = self.select.GetValue()
  1876. else:
  1877. self.selected = None
  1878. if self.scaleChoice.GetSelection() == 0:
  1879. self.selectedMap = self.selected
  1880. if self.rasterTypeRadio.GetValue():
  1881. mapType = 'raster'
  1882. else:
  1883. mapType = 'vector'
  1884. self.scale[0], self.center[0], foo = AutoAdjust(self, scaleType = 0, map = self.selected,
  1885. mapType = mapType, rect = self.mapFrameDict['rect'])
  1886. #self.center[0] = self.RegionCenter(self.RegionDict(scaleType = 0))
  1887. elif self.scaleChoice.GetSelection() == 1:
  1888. self.selectedRegion = self.selected
  1889. self.scale[1], self.center[1], foo = AutoAdjust(self, scaleType = 1, region = self.selected, rect = self.mapFrameDict['rect'])
  1890. #self.center[1] = self.RegionCenter(self.RegionDict(scaleType = 1))
  1891. elif self.scaleChoice.GetSelection() == 2:
  1892. self.scale[2], self.center[2], foo = AutoAdjust(self, scaleType = 2, rect = self.mapFrameDict['rect'])
  1893. #self.center[2] = self.RegionCenter(self.RegionDict(scaleType = 2))
  1894. else:
  1895. self.scale[3] = None
  1896. self.center[3] = None
  1897. self.OnScaleChoice(None)
  1898. def OnScaleChoice(self, event):
  1899. """!Selected scale type changing"""
  1900. scaleType = self.scaleChoice.GetSelection()
  1901. if self.scaleType != scaleType:
  1902. self.scaleType = scaleType
  1903. self.select.SetValue("")
  1904. if scaleType in (0, 1): # automatic - region from raster map, saved region
  1905. if scaleType == 0:
  1906. # set map selection
  1907. self.rasterTypeRadio.Show()
  1908. self.vectorTypeRadio.Show()
  1909. self.drawMap.Show()
  1910. self.staticBox.SetLabel(" %s " % _("Map selection"))
  1911. if self.rasterTypeRadio.GetValue():
  1912. stype = 'raster'
  1913. else:
  1914. stype = 'vector'
  1915. self.select.SetElementList(type = stype)
  1916. self.mapText.SetLabel(self.mapOrRegionText[0])
  1917. self.select.SetToolTipString(_("Region is set to match this map,\nraster or vector map must be added later"))
  1918. if scaleType == 1:
  1919. # set region selection
  1920. self.rasterTypeRadio.Hide()
  1921. self.vectorTypeRadio.Hide()
  1922. self.drawMap.Hide()
  1923. self.staticBox.SetLabel(" %s " % _("Region selection"))
  1924. stype = 'region'
  1925. self.select.SetElementList(type = stype)
  1926. self.mapText.SetLabel(self.mapOrRegionText[1])
  1927. self.select.SetToolTipString("")
  1928. for each in self.mapSizer.GetChildren():
  1929. each.GetWindow().Enable()
  1930. for each in self.centerSizer.GetChildren():
  1931. each.GetWindow().Disable()
  1932. if self.scale[scaleType]:
  1933. self.scaleTextCtrl.SetValue("%.0f" % (1/self.scale[scaleType]))
  1934. if self.center[scaleType]:
  1935. self.eastingTextCtrl.SetValue(str(self.center[scaleType][0]))
  1936. self.northingTextCtrl.SetValue(str(self.center[scaleType][1]))
  1937. elif scaleType == 2:
  1938. for each in self.mapSizer.GetChildren():
  1939. each.GetWindow().Disable()
  1940. for each in self.centerSizer.GetChildren():
  1941. each.GetWindow().Disable()
  1942. if self.scale[scaleType]:
  1943. self.scaleTextCtrl.SetValue("%.0f" % (1/self.scale[scaleType]))
  1944. if self.center[scaleType]:
  1945. self.eastingTextCtrl.SetValue(str(self.center[scaleType][0]))
  1946. self.northingTextCtrl.SetValue(str(self.center[scaleType][1]))
  1947. else: # fixed
  1948. for each in self.mapSizer.GetChildren():
  1949. each.GetWindow().Disable()
  1950. for each in self.centerSizer.GetChildren():
  1951. each.GetWindow().Enable()
  1952. if self.scale[scaleType]:
  1953. self.scaleTextCtrl.SetValue("%.0f" % (1/self.scale[scaleType]))
  1954. if self.center[scaleType]:
  1955. self.eastingTextCtrl.SetValue(str(self.center[scaleType][0]))
  1956. self.northingTextCtrl.SetValue(str(self.center[scaleType][1]))
  1957. def OnElementType(self, event):
  1958. """!Changes data in map selection tree ctrl popup"""
  1959. if self.rasterTypeRadio.GetValue():
  1960. mapType = 'raster'
  1961. else:
  1962. mapType = 'vector'
  1963. self.select.SetElementList(type = mapType)
  1964. if self.mapType != mapType and event is not None:
  1965. self.mapType = mapType
  1966. self.select.SetValue('')
  1967. self.mapType = mapType
  1968. def OnBorder(self, event):
  1969. """!Enables/disable the part relating to border of map frame"""
  1970. for each in (self.borderColorText, self.borderWidthText, self.borderColourPicker, self.borderWidthCtrl):
  1971. each.Enable(self.borderCheck.GetValue())
  1972. def getId(self):
  1973. """!Returns id of raster map"""
  1974. return self.id
  1975. def update(self):
  1976. """!Save changes"""
  1977. mapFrameDict = dict(self.mapFrameDict)
  1978. # resolution
  1979. mapFrameDict['resolution'] = self.resolutionSpin.GetValue()
  1980. #scale
  1981. scaleType = self.scaleType
  1982. mapFrameDict['scaleType'] = scaleType
  1983. if mapFrameDict['scaleType'] == 0:
  1984. if self.select.GetValue():
  1985. mapFrameDict['drawMap'] = self.drawMap.GetValue()
  1986. mapFrameDict['map'] = self.select.GetValue()
  1987. mapFrameDict['mapType'] = self.mapType
  1988. mapFrameDict['region'] = None
  1989. if mapFrameDict['drawMap']:
  1990. if mapFrameDict['mapType'] == 'raster':
  1991. mapFile = grass.find_file(mapFrameDict['map'], element = 'cell')
  1992. if mapFile['file'] == '':
  1993. GMessage("Raster %s not found" % mapFrameDict['map'])
  1994. return False
  1995. raster = self.instruction.FindInstructionByType('raster')
  1996. if raster:
  1997. raster['raster'] = mapFrameDict['map']
  1998. else:
  1999. raster = Raster(wx.NewId())
  2000. raster['raster'] = mapFrameDict['map']
  2001. raster['isRaster'] = True
  2002. self.instruction.AddInstruction(raster)
  2003. elif mapFrameDict['mapType'] == 'vector':
  2004. mapFile = grass.find_file(mapFrameDict['map'], element = 'vector')
  2005. if mapFile['file'] == '':
  2006. GMessage("Vector %s not found" % mapFrameDict['map'])
  2007. return False
  2008. vector = self.instruction.FindInstructionByType('vector')
  2009. isAdded = False
  2010. if vector:
  2011. for each in vector['list']:
  2012. if each[0] == mapFrameDict['map']:
  2013. isAdded = True
  2014. if not isAdded:
  2015. topoInfo = grass.vector_info_topo(map = mapFrameDict['map'])
  2016. if topoInfo:
  2017. if bool(topoInfo['areas']):
  2018. topoType = 'areas'
  2019. elif bool(topoInfo['lines']):
  2020. topoType = 'lines'
  2021. else:
  2022. topoType = 'points'
  2023. label = '('.join(mapFrameDict['map'].split('@')) + ')'
  2024. if not vector:
  2025. vector = Vector(wx.NewId())
  2026. vector['list'] = []
  2027. self.instruction.AddInstruction(vector)
  2028. id = wx.NewId()
  2029. vector['list'].insert(0, [mapFrameDict['map'], topoType, id, 1, label])
  2030. vProp = VProperties(id, topoType)
  2031. vProp['name'], vProp['label'], vProp['lpos'] = mapFrameDict['map'], label, 1
  2032. self.instruction.AddInstruction(vProp)
  2033. else:
  2034. return False
  2035. self.scale[0], self.center[0], self.rectAdjusted = AutoAdjust(self, scaleType = 0, map = mapFrameDict['map'],
  2036. mapType = self.mapType, rect = self.mapFrameDict['rect'])
  2037. if self.rectAdjusted:
  2038. mapFrameDict['rect'] = self.rectAdjusted
  2039. else:
  2040. mapFrameDict['rect'] = self.mapFrameDict['rect']
  2041. mapFrameDict['scale'] = self.scale[0]
  2042. mapFrameDict['center'] = self.center[0]
  2043. # set region
  2044. if self.mapType == 'raster':
  2045. RunCommand('g.region', rast = mapFrameDict['map'])
  2046. if self.mapType == 'vector':
  2047. raster = self.instruction.FindInstructionByType('raster')
  2048. if raster:
  2049. rasterId = raster.id
  2050. else:
  2051. rasterId = None
  2052. if rasterId:
  2053. RunCommand('g.region', vect = mapFrameDict['map'], rast = self.instruction[rasterId]['raster'])
  2054. else:
  2055. RunCommand('g.region', vect = mapFrameDict['map'])
  2056. else:
  2057. wx.MessageBox(message = _("No map selected!"),
  2058. caption = _('Invalid input'), style = wx.OK|wx.ICON_ERROR)
  2059. return False
  2060. elif mapFrameDict['scaleType'] == 1:
  2061. if self.select.GetValue():
  2062. mapFrameDict['drawMap'] = False
  2063. mapFrameDict['map'] = None
  2064. mapFrameDict['mapType'] = None
  2065. mapFrameDict['region'] = self.select.GetValue()
  2066. self.scale[1], self.center[1], self.rectAdjusted = AutoAdjust(self, scaleType = 1, region = mapFrameDict['region'],
  2067. rect = self.mapFrameDict['rect'])
  2068. if self.rectAdjusted:
  2069. mapFrameDict['rect'] = self.rectAdjusted
  2070. else:
  2071. mapFrameDict['rect'] = self.mapFrameDict['rect']
  2072. mapFrameDict['scale'] = self.scale[1]
  2073. mapFrameDict['center'] = self.center[1]
  2074. # set region
  2075. RunCommand('g.region', region = mapFrameDict['region'])
  2076. else:
  2077. wx.MessageBox(message = _("No region selected!"),
  2078. caption = _('Invalid input'), style = wx.OK|wx.ICON_ERROR)
  2079. return False
  2080. elif scaleType == 2:
  2081. mapFrameDict['drawMap'] = False
  2082. mapFrameDict['map'] = None
  2083. mapFrameDict['mapType'] = None
  2084. mapFrameDict['region'] = None
  2085. self.scale[2], self.center[2], self.rectAdjusted = AutoAdjust(self, scaleType = 2, rect = self.mapFrameDict['rect'])
  2086. if self.rectAdjusted:
  2087. mapFrameDict['rect'] = self.rectAdjusted
  2088. else:
  2089. mapFrameDict['rect'] = self.mapFrameDict['rect']
  2090. mapFrameDict['scale'] = self.scale[2]
  2091. mapFrameDict['center'] = self.center[2]
  2092. env = grass.gisenv()
  2093. windFilePath = os.path.join(env['GISDBASE'], env['LOCATION_NAME'], env['MAPSET'], 'WIND')
  2094. try:
  2095. windFile = open(windFilePath, 'r').read()
  2096. region = grass.parse_key_val(windFile, sep = ':', val_type = float)
  2097. except IOError:
  2098. region = grass.region()
  2099. raster = self.instruction.FindInstructionByType('raster')
  2100. if raster:
  2101. rasterId = raster.id
  2102. else:
  2103. rasterId = None
  2104. if rasterId: # because of resolution
  2105. RunCommand('g.region', n = region['north'], s = region['south'],
  2106. e = region['east'], w = region['west'], rast = self.instruction[rasterId]['raster'])
  2107. else:
  2108. RunCommand('g.region', n = region['north'], s = region['south'],
  2109. e = region['east'], w = region['west'])
  2110. elif scaleType == 3:
  2111. mapFrameDict['drawMap'] = False
  2112. mapFrameDict['map'] = None
  2113. mapFrameDict['mapType'] = None
  2114. mapFrameDict['region'] = None
  2115. mapFrameDict['rect'] = self.mapFrameDict['rect']
  2116. try:
  2117. scaleNumber = float(self.scaleTextCtrl.GetValue())
  2118. centerE = float(self.eastingTextCtrl.GetValue())
  2119. centerN = float(self.northingTextCtrl.GetValue())
  2120. except (ValueError, SyntaxError):
  2121. wx.MessageBox(message = _("Invalid scale or map center!"),
  2122. caption = _('Invalid input'), style = wx.OK|wx.ICON_ERROR)
  2123. return False
  2124. mapFrameDict['scale'] = 1/scaleNumber
  2125. mapFrameDict['center'] = centerE, centerN
  2126. ComputeSetRegion(self, mapDict = mapFrameDict)
  2127. # check resolution
  2128. SetResolution(dpi = mapFrameDict['resolution'], width = mapFrameDict['rect'].width,
  2129. height = mapFrameDict['rect'].height)
  2130. # border
  2131. if self.borderCheck.GetValue():
  2132. mapFrameDict['border'] = 'y'
  2133. else:
  2134. mapFrameDict['border'] = 'n'
  2135. if mapFrameDict['border'] == 'y':
  2136. mapFrameDict['width'] = self.borderWidthCtrl.GetValue()
  2137. mapFrameDict['color'] = convertRGB(self.borderColourPicker.GetColour())
  2138. if self.id not in self.instruction:
  2139. mapFrame = MapFrame(self.id)
  2140. self.instruction.AddInstruction(mapFrame)
  2141. self.instruction[self.id].SetInstruction(mapFrameDict)
  2142. if self.id not in self.mapDialog.parent.objectId:
  2143. self.mapDialog.parent.objectId.insert(0, self.id)# map frame is drawn first
  2144. return True
  2145. class RasterPanel(wx.Panel):
  2146. """!Panel for raster map settings"""
  2147. def __init__(self, parent, id, settings, notebook = True):
  2148. wx.Panel.__init__(self, parent, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
  2149. self.instruction = settings
  2150. if notebook:
  2151. self.book = parent
  2152. self.book.AddPage(page = self, text = _("Raster map"))
  2153. self.mainDialog = self.book.GetParent()
  2154. else:
  2155. self.mainDialog = parent
  2156. if id:
  2157. self.id = id
  2158. self.rasterDict = self.instruction[self.id].GetInstruction()
  2159. else:
  2160. self.id = wx.NewId()
  2161. raster = Raster(self.id)
  2162. self.rasterDict = raster.GetInstruction()
  2163. self._layout()
  2164. self.OnRaster(None)
  2165. def _layout(self):
  2166. """!Do layout"""
  2167. border = wx.BoxSizer(wx.VERTICAL)
  2168. # choose raster map
  2169. box = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Choose raster map"))
  2170. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  2171. gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
  2172. self.rasterNoRadio = wx.RadioButton(self, id = wx.ID_ANY, label = _("no raster map"), style = wx.RB_GROUP)
  2173. self.rasterYesRadio = wx.RadioButton(self, id = wx.ID_ANY, label = _("raster:"))
  2174. self.rasterSelect = Select(self, id = wx.ID_ANY, size = globalvar.DIALOG_GSELECT_SIZE,
  2175. type = 'raster', multiple = False,
  2176. updateOnPopup = True, onPopup = None)
  2177. if self.rasterDict['isRaster']:
  2178. self.rasterYesRadio.SetValue(True)
  2179. self.rasterNoRadio.SetValue(False)
  2180. self.rasterSelect.SetValue(self.rasterDict['raster'])
  2181. else:
  2182. self.rasterYesRadio.SetValue(False)
  2183. self.rasterNoRadio.SetValue(True)
  2184. mapId = self.instruction.FindInstructionByType('map').id
  2185. if self.instruction[mapId]['map'] and self.instruction[mapId]['mapType'] == 'raster':
  2186. self.rasterSelect.SetValue(self.instruction[mapId]['map'])# raster map from map frame dialog if possible
  2187. else:
  2188. self.rasterSelect.SetValue('')
  2189. gridBagSizer.Add(self.rasterNoRadio, pos = (0, 0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2190. gridBagSizer.Add(self.rasterYesRadio, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2191. gridBagSizer.Add(self.rasterSelect, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  2192. sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  2193. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  2194. #self.rasterSelect.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnRaster)
  2195. self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterNoRadio)
  2196. self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterYesRadio)
  2197. self.SetSizer(border)
  2198. self.Fit()
  2199. def OnRaster(self, event):
  2200. """!Enable/disable raster selection"""
  2201. self.rasterSelect.Enable(self.rasterYesRadio.GetValue())
  2202. def update(self):
  2203. #draw raster
  2204. map = self.instruction.FindInstructionByType('map')
  2205. if self.rasterNoRadio.GetValue() or not self.rasterSelect.GetValue():
  2206. self.rasterDict['isRaster'] = False
  2207. self.rasterDict['raster'] = None
  2208. map['drawMap'] = False
  2209. if self.id in self.instruction:
  2210. del self.instruction[self.id]
  2211. else:
  2212. self.rasterDict['isRaster'] = True
  2213. self.rasterDict['raster'] = self.rasterSelect.GetValue()
  2214. if self.rasterDict['raster'] != map['drawMap']:
  2215. map['drawMap'] = False
  2216. if self.id not in self.instruction:
  2217. raster = Raster(self.id)
  2218. self.instruction.AddInstruction(raster)
  2219. self.instruction[self.id].SetInstruction(self.rasterDict)
  2220. if 'map' in self.mainDialog.parent.openDialogs:
  2221. self.mainDialog.parent.openDialogs['map'].updateDialog()
  2222. return True
  2223. def getId(self):
  2224. return self.id
  2225. class VectorPanel(wx.Panel):
  2226. """!Panel for vector maps settings"""
  2227. def __init__(self, parent, id, settings, notebook = True):
  2228. wx.Panel.__init__(self, parent, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
  2229. self.parent = parent
  2230. self.instruction = settings
  2231. self.tmpDialogDict = {}
  2232. vectors = self.instruction.FindInstructionByType('vProperties', list = True)
  2233. for vector in vectors:
  2234. self.tmpDialogDict[vector.id] = dict(self.instruction[vector.id].GetInstruction())
  2235. if id:
  2236. self.id = id
  2237. self.vectorList = deepcopy(self.instruction[id]['list'])
  2238. else:
  2239. self.id = wx.NewId()
  2240. self.vectorList = []
  2241. vLegend = self.instruction.FindInstructionByType('vectorLegend')
  2242. if vLegend:
  2243. self.vLegendId = vLegend.id
  2244. else:
  2245. self.vLegendId = None
  2246. self._layout()
  2247. if notebook:
  2248. self.parent.AddPage(page = self, text = _("Vector maps"))
  2249. self.parent = self.parent.GetParent()
  2250. def _layout(self):
  2251. """!Do layout"""
  2252. border = wx.BoxSizer(wx.VERTICAL)
  2253. # choose vector map
  2254. box = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Add map"))
  2255. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  2256. gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
  2257. text = wx.StaticText(self, id = wx.ID_ANY, label = _("Map:"))
  2258. self.select = Select(self, id = wx.ID_ANY,# size = globalvar.DIALOG_GSELECT_SIZE,
  2259. type = 'vector', multiple = False,
  2260. updateOnPopup = True, onPopup = None)
  2261. topologyType = [_("points"), _("lines"), _("areas")]
  2262. self.vectorType = wx.RadioBox(self, id = wx.ID_ANY, label = " %s " % _("Data Type"), choices = topologyType,
  2263. majorDimension = 3, style = wx.RA_SPECIFY_COLS)
  2264. self.AddVector = wx.Button(self, id = wx.ID_ANY, label = _("Add"))
  2265. gridBagSizer.Add(text, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2266. gridBagSizer.Add(self.select, pos = (0,1), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2267. gridBagSizer.Add(self.vectorType, pos = (1,1), flag = wx.ALIGN_CENTER, border = 0)
  2268. gridBagSizer.Add(self.AddVector, pos = (1,2), flag = wx.ALIGN_BOTTOM|wx.ALIGN_RIGHT, border = 0)
  2269. sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  2270. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  2271. # manage vector layers
  2272. box = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Manage vector maps"))
  2273. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  2274. gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
  2275. gridBagSizer.AddGrowableCol(0,2)
  2276. gridBagSizer.AddGrowableCol(1,1)
  2277. text = wx.StaticText(self, id = wx.ID_ANY, label = _("The topmost vector map overlaps the others"))
  2278. self.listbox = wx.ListBox(self, id = wx.ID_ANY, choices = [], style = wx.LB_SINGLE|wx.LB_NEEDED_SB)
  2279. self.btnUp = wx.Button(self, id = wx.ID_ANY, label = _("Up"))
  2280. self.btnDown = wx.Button(self, id = wx.ID_ANY, label = _("Down"))
  2281. self.btnDel = wx.Button(self, id = wx.ID_ANY, label = _("Delete"))
  2282. self.btnProp = wx.Button(self, id = wx.ID_ANY, label = _("Properties..."))
  2283. self.updateListBox(selected=0)
  2284. gridBagSizer.Add(text, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2285. gridBagSizer.Add(self.listbox, pos = (1,0), span = (4, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  2286. gridBagSizer.Add(self.btnUp, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  2287. gridBagSizer.Add(self.btnDown, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  2288. gridBagSizer.Add(self.btnDel, pos = (3,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  2289. gridBagSizer.Add(self.btnProp, pos = (4,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  2290. sizer.Add(gridBagSizer, proportion = 0, flag = wx.ALL, border = 5)
  2291. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  2292. self.Bind(wx.EVT_BUTTON, self.OnAddVector, self.AddVector)
  2293. self.Bind(wx.EVT_BUTTON, self.OnDelete, self.btnDel)
  2294. self.Bind(wx.EVT_BUTTON, self.OnUp, self.btnUp)
  2295. self.Bind(wx.EVT_BUTTON, self.OnDown, self.btnDown)
  2296. self.Bind(wx.EVT_BUTTON, self.OnProperties, self.btnProp)
  2297. self.select.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnVector)
  2298. self.SetSizer(border)
  2299. self.Fit()
  2300. self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnProperties, self.listbox)
  2301. def OnVector(self, event):
  2302. """!Gets info about toplogy and enables/disables choices point/line/area"""
  2303. vmap = self.select.GetValue()
  2304. try:
  2305. topoInfo = grass.vector_info_topo(map = vmap)
  2306. except grass.ScriptError:
  2307. return
  2308. if topoInfo:
  2309. self.vectorType.EnableItem(2, bool(topoInfo['areas']))
  2310. self.vectorType.EnableItem(1, bool(topoInfo['boundaries']) or bool(topoInfo['lines']))
  2311. self.vectorType.EnableItem(0, bool(topoInfo['centroids'] or bool(topoInfo['points']) ))
  2312. for item in range(2,-1,-1):
  2313. if self.vectorType.IsItemEnabled(item):
  2314. self.vectorType.SetSelection(item)
  2315. break
  2316. self.AddVector.SetFocus()
  2317. def OnAddVector(self, event):
  2318. """!Adds vector map to list"""
  2319. vmap = self.select.GetValue()
  2320. if vmap:
  2321. mapname = vmap.split('@')[0]
  2322. try:
  2323. mapset = '(' + vmap.split('@')[1] + ')'
  2324. except IndexError:
  2325. mapset = ''
  2326. type = self.vectorType.GetStringSelection()
  2327. record = "%s - %s" % (vmap,type)
  2328. id = wx.NewId()
  2329. lpos = 1
  2330. label = mapname + mapset
  2331. self.vectorList.insert(0, [vmap, type, id, lpos, label])
  2332. self.reposition()
  2333. self.listbox.InsertItems([record], 0)
  2334. vector = VProperties(id, type)
  2335. self.tmpDialogDict[id] = vector.GetInstruction()
  2336. self.tmpDialogDict[id]['name'] = vmap
  2337. self.listbox.SetSelection(0)
  2338. self.listbox.EnsureVisible(0)
  2339. self.btnProp.SetFocus()
  2340. self.enableButtons()
  2341. def OnDelete(self, event):
  2342. """!Deletes vector map from the list"""
  2343. if self.listbox.GetSelections():
  2344. pos = self.listbox.GetSelection()
  2345. id = self.vectorList[pos][2]
  2346. del self.vectorList[pos]
  2347. del self.tmpDialogDict[id]
  2348. for i in range(pos, len(self.vectorList)):
  2349. if self.vectorList[i][3]:# can be 0
  2350. self.vectorList[i][3] -= 1
  2351. if pos < len(self.vectorList) -1:
  2352. selected = pos
  2353. else:
  2354. selected = len(self.vectorList) -1
  2355. self.updateListBox(selected = selected)
  2356. if self.listbox.IsEmpty():
  2357. self.enableButtons(False)
  2358. def OnUp(self, event):
  2359. """!Moves selected map to top"""
  2360. if self.listbox.GetSelections():
  2361. pos = self.listbox.GetSelection()
  2362. if pos:
  2363. self.vectorList.insert(pos - 1, self.vectorList.pop(pos))
  2364. if not self.vLegendId:
  2365. self.reposition()
  2366. if pos > 0:
  2367. self.updateListBox(selected = (pos - 1))
  2368. else:
  2369. self.updateListBox(selected = 0)
  2370. def OnDown(self, event):
  2371. """!Moves selected map to bottom"""
  2372. if self.listbox.GetSelections():
  2373. pos = self.listbox.GetSelection()
  2374. if pos != len(self.vectorList) - 1:
  2375. self.vectorList.insert(pos + 1, self.vectorList.pop(pos))
  2376. if not self.vLegendId:
  2377. self.reposition()
  2378. if pos < len(self.vectorList) -1:
  2379. self.updateListBox(selected = (pos + 1))
  2380. else:
  2381. self.updateListBox(selected = len(self.vectorList) -1)
  2382. def OnProperties(self, event):
  2383. """!Opens vector map properties dialog"""
  2384. if self.listbox.GetSelections():
  2385. pos = self.listbox.GetSelection()
  2386. id = self.vectorList[pos][2]
  2387. dlg = VPropertiesDialog(self, id = id, settings = self.instruction,
  2388. vectors = self.vectorList, tmpSettings = self.tmpDialogDict[id])
  2389. dlg.ShowModal()
  2390. self.parent.FindWindowById(wx.ID_OK).SetFocus()
  2391. def enableButtons(self, enable = True):
  2392. """!Enable/disable up, down, properties, delete buttons"""
  2393. self.btnUp.Enable(enable)
  2394. self.btnDown.Enable(enable)
  2395. self.btnProp.Enable(enable)
  2396. self.btnDel.Enable(enable)
  2397. def updateListBox(self, selected = None):
  2398. mapList = ["%s - %s" % (item[0], item[1]) for item in self.vectorList]
  2399. self.listbox.Set(mapList)
  2400. if self.listbox.IsEmpty():
  2401. self.enableButtons(False)
  2402. else:
  2403. self.enableButtons(True)
  2404. if selected is not None:
  2405. self.listbox.SetSelection(selected)
  2406. self.listbox.EnsureVisible(selected)
  2407. def reposition(self):
  2408. """!Update position in legend, used only if there is no vlegend yet"""
  2409. for i in range(len(self.vectorList)):
  2410. if self.vectorList[i][3]:
  2411. self.vectorList[i][3] = i + 1
  2412. def getId(self):
  2413. return self.id
  2414. def update(self):
  2415. vectors = self.instruction.FindInstructionByType('vProperties', list = True)
  2416. for vector in vectors:
  2417. del self.instruction[vector.id]
  2418. if self.id in self.instruction:
  2419. del self.instruction[self.id]
  2420. if len(self.vectorList) > 0:
  2421. vector = Vector(self.id)
  2422. self.instruction.AddInstruction(vector)
  2423. vector.SetInstruction({'list': deepcopy(self.vectorList)})
  2424. # save new vectors
  2425. for item in self.vectorList:
  2426. id = item[2]
  2427. vLayer = VProperties(id, item[1])
  2428. self.instruction.AddInstruction(vLayer)
  2429. vLayer.SetInstruction(self.tmpDialogDict[id])
  2430. vLayer['name'] = item[0]
  2431. vLayer['label'] = item[4]
  2432. vLayer['lpos'] = item[3]
  2433. else:
  2434. if self.id in self.instruction:
  2435. del self.instruction[self.id]
  2436. if 'map' in self.parent.parent.openDialogs:
  2437. self.parent.parent.openDialogs['map'].updateDialog()
  2438. return True
  2439. class RasterDialog(PsmapDialog):
  2440. def __init__(self, parent, id, settings):
  2441. PsmapDialog.__init__(self, parent = parent, id = id, title = _("Raster map settings"), settings = settings)
  2442. self.objectType = ('raster',)
  2443. self.rPanel = RasterPanel(parent = self, id = self.id, settings = self.instruction, notebook = False)
  2444. self.id = self.rPanel.getId()
  2445. self._layout(self.rPanel)
  2446. def update(self):
  2447. ok = self.rPanel.update()
  2448. if ok:
  2449. return True
  2450. return False
  2451. def OnApply(self, event):
  2452. ok = self.update()
  2453. if not ok:
  2454. return False
  2455. if self.id in self.instruction:
  2456. self.parent.DialogDataChanged(id = self.id)
  2457. else:
  2458. mapId = self.instruction.FindInstructionByType('map').id
  2459. self.parent.DialogDataChanged(id = mapId)
  2460. return True
  2461. def updateDialog(self):
  2462. """!Update information (not used)"""
  2463. pass
  2464. ## if 'map' in self.parent.openDialogs:
  2465. ## if self.parent.openDialogs['map'].mPanel.rasterTypeRadio.GetValue()\
  2466. ## and self.parent.openDialogs['map'].mPanel.select.GetValue():
  2467. ## if self.parent.openDialogs['map'].mPanel.drawMap.IsChecked():
  2468. ## self.rPanel.rasterSelect.SetValue(self.parent.openDialogs['map'].mPanel.select.GetValue())
  2469. class MainVectorDialog(PsmapDialog):
  2470. def __init__(self, parent, id, settings):
  2471. PsmapDialog.__init__(self, parent = parent, id = id, title = _("Vector maps settings"), settings = settings)
  2472. self.objectType = ('vector',)
  2473. self.vPanel = VectorPanel(parent = self, id = self.id, settings = self.instruction, notebook = False)
  2474. self.id = self.vPanel.getId()
  2475. self._layout(self.vPanel)
  2476. def update(self):
  2477. self.vPanel.update()
  2478. def OnApply(self, event):
  2479. self.update()
  2480. if self.id in self.instruction:
  2481. self.parent.DialogDataChanged(id = self.id)
  2482. else:
  2483. mapId = self.instruction.FindInstructionByType('map').id
  2484. self.parent.DialogDataChanged(id = mapId)
  2485. return True
  2486. def updateDialog(self):
  2487. """!Update information (not used)"""
  2488. pass
  2489. class VPropertiesDialog(PsmapDialog):
  2490. def __init__(self, parent, id, settings, vectors, tmpSettings):
  2491. PsmapDialog.__init__(self, parent = parent, id = id, title = "", settings = settings, apply = False)
  2492. vectorList = vectors
  2493. self.vPropertiesDict = tmpSettings
  2494. # determine map and its type
  2495. for item in vectorList:
  2496. if id == item[2]:
  2497. self.vectorName = item[0]
  2498. self.type = item[1]
  2499. self.SetTitle(self.vectorName + " "+ _("properties"))
  2500. #vector map info
  2501. self.connection = True
  2502. try:
  2503. self.mapDBInfo = dbm_base.VectorDBInfo(self.vectorName)
  2504. self.layers = self.mapDBInfo.layers.keys()
  2505. except grass.ScriptError:
  2506. self.connection = False
  2507. self.layers = []
  2508. if not self.layers:
  2509. self.connection = False
  2510. self.layers = []
  2511. self.currLayer = self.vPropertiesDict['layer']
  2512. #path to symbols, patterns
  2513. gisbase = os.getenv("GISBASE")
  2514. self.symbolPath = os.path.join(gisbase, 'etc', 'symbol')
  2515. self.symbols = []
  2516. for dir in os.listdir(self.symbolPath):
  2517. for symbol in os.listdir(os.path.join(self.symbolPath, dir)):
  2518. self.symbols.append(os.path.join(dir, symbol))
  2519. self.patternPath = os.path.join(gisbase, 'etc', 'paint', 'patterns')
  2520. #notebook
  2521. notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT)
  2522. self.DSpanel = self._DataSelectionPanel(notebook)
  2523. self.EnableLayerSelection(enable = self.connection)
  2524. selectPanel = { 'points': [self._ColorsPointAreaPanel, self._StylePointPanel],
  2525. 'lines': [self._ColorsLinePanel, self._StyleLinePanel],
  2526. 'areas': [self._ColorsPointAreaPanel, self._StyleAreaPanel]}
  2527. self.ColorsPanel = selectPanel[self.type][0](notebook)
  2528. self.OnOutline(None)
  2529. if self.type in ('points', 'areas'):
  2530. self.OnFill(None)
  2531. self.OnColor(None)
  2532. self.StylePanel = selectPanel[self.type][1](notebook)
  2533. if self.type == 'points':
  2534. self.OnSize(None)
  2535. self.OnRotation(None)
  2536. if self.type == 'areas':
  2537. self.OnPattern(None)
  2538. self._layout(notebook)
  2539. def _DataSelectionPanel(self, notebook):
  2540. panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
  2541. notebook.AddPage(page = panel, text = _("Data selection"))
  2542. border = wx.BoxSizer(wx.VERTICAL)
  2543. # data type
  2544. self.checkType1 = self.checkType2 = None
  2545. if self.type in ('lines', 'points'):
  2546. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Feature type"))
  2547. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2548. gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
  2549. if self.type == 'points':
  2550. label = (_("points"), _("centroids"))
  2551. else:
  2552. label = (_("lines"), _("boundaries"))
  2553. if self.type == 'points':
  2554. name = ("point", "centroid")
  2555. else:
  2556. name = ("line", "boundary")
  2557. self.checkType1 = wx.CheckBox(panel, id = wx.ID_ANY, label = label[0], name = name[0])
  2558. self.checkType2 = wx.CheckBox(panel, id = wx.ID_ANY, label = label[1], name = name[1])
  2559. self.checkType1.SetValue(self.vPropertiesDict['type'].find(name[0]) >= 0)
  2560. self.checkType2.SetValue(self.vPropertiesDict['type'].find(name[1]) >= 0)
  2561. gridBagSizer.Add(self.checkType1, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2562. gridBagSizer.Add(self.checkType2, pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2563. sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  2564. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  2565. # layer selection
  2566. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Layer selection"))
  2567. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2568. self.gridBagSizerL = wx.GridBagSizer(hgap = 5, vgap = 5)
  2569. self.warning = wx.StaticText(panel, id = wx.ID_ANY, label = "")
  2570. if not self.connection:
  2571. self.warning = wx.StaticText(panel, id = wx.ID_ANY, label = _("Database connection is not defined in DB file."))
  2572. text = wx.StaticText(panel, id = wx.ID_ANY, label = _("Select layer:"))
  2573. self.layerChoice = wx.Choice(panel, id = wx.ID_ANY, choices = map(str, self.layers), size = self.spinCtrlSize)
  2574. self.layerChoice.SetStringSelection(self.currLayer)
  2575. if self.connection:
  2576. table = self.mapDBInfo.layers[int(self.currLayer)]['table']
  2577. else:
  2578. table = ""
  2579. self.radioWhere = wx.RadioButton(panel, id = wx.ID_ANY, label = "SELECT * FROM %s WHERE" % table, style = wx.RB_GROUP)
  2580. self.textCtrlWhere = wx.TextCtrl(panel, id = wx.ID_ANY, value = "")
  2581. if self.connection:
  2582. cols = self.mapDBInfo.GetColumns(self.mapDBInfo.layers[int(self.currLayer)]['table'])
  2583. else:
  2584. cols = []
  2585. self.choiceColumns = wx.Choice(panel, id = wx.ID_ANY, choices = cols)
  2586. self.radioCats = wx.RadioButton(panel, id = wx.ID_ANY, label = "Choose categories ")
  2587. self.textCtrlCats = wx.TextCtrl(panel, id = wx.ID_ANY, value = "")
  2588. self.textCtrlCats.SetToolTipString(_("list of categories (e.g. 1,3,5-7)"))
  2589. if self.vPropertiesDict.has_key('cats'):
  2590. self.radioCats.SetValue(True)
  2591. self.textCtrlCats.SetValue(self.vPropertiesDict['cats'])
  2592. if self.vPropertiesDict.has_key('where'):
  2593. self.radioWhere.SetValue(True)
  2594. where = self.vPropertiesDict['where'].strip().split(" ",1)
  2595. self.choiceColumns.SetStringSelection(where[0])
  2596. self.textCtrlWhere.SetValue(where[1])
  2597. row = 0
  2598. if not self.connection:
  2599. self.gridBagSizerL.Add(self.warning, pos = (0,0), span = (1,3), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2600. row = 1
  2601. self.gridBagSizerL.Add(text, pos = (0 + row,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2602. self.gridBagSizerL.Add(self.layerChoice, pos = (0 + row,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  2603. self.gridBagSizerL.Add(self.radioWhere, pos = (1 + row,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2604. self.gridBagSizerL.Add(self.choiceColumns, pos = (1 + row,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2605. self.gridBagSizerL.Add(self.textCtrlWhere, pos = (1 + row,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2606. self.gridBagSizerL.Add(self.radioCats, pos = (2 + row,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2607. self.gridBagSizerL.Add(self.textCtrlCats, pos = (2 + row,1), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  2608. sizer.Add(self.gridBagSizerL, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  2609. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  2610. #mask
  2611. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Mask"))
  2612. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2613. self.mask = wx.CheckBox(panel, id = wx.ID_ANY, label = _("Use current mask"))
  2614. if self.vPropertiesDict['masked'] == 'y':
  2615. self.mask.SetValue(True)
  2616. else:
  2617. self.mask.SetValue(False)
  2618. sizer.Add(self.mask, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  2619. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  2620. self.Bind(wx.EVT_CHOICE, self.OnLayer, self.layerChoice)
  2621. panel.SetSizer(border)
  2622. panel.Fit()
  2623. return panel
  2624. def _ColorsPointAreaPanel(self, notebook):
  2625. panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
  2626. notebook.AddPage(page = panel, text = _("Colors"))
  2627. border = wx.BoxSizer(wx.VERTICAL)
  2628. #colors - outline
  2629. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Outline"))
  2630. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2631. self.gridBagSizerO = wx.GridBagSizer(hgap = 5, vgap = 2)
  2632. self.outlineCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("draw outline"))
  2633. self.outlineCheck.SetValue(self.vPropertiesDict['color'] != 'none')
  2634. widthText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Width (pts):"))
  2635. if fs:
  2636. self.widthSpin = fs.FloatSpin(panel, id = wx.ID_ANY, min_val = 0, max_val = 30,
  2637. increment = 0.5, value = 1, style = fs.FS_RIGHT)
  2638. self.widthSpin.SetFormat("%f")
  2639. self.widthSpin.SetDigits(2)
  2640. else:
  2641. self.widthSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 25, initial = 1,
  2642. size = self.spinCtrlSize)
  2643. if self.vPropertiesDict['color'] != 'none':
  2644. self.widthSpin.SetValue(self.vPropertiesDict['width'] )
  2645. else:
  2646. self.widthSpin.SetValue(1)
  2647. colorText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Color:"))
  2648. self.colorPicker = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
  2649. if self.vPropertiesDict['color'] != 'none':
  2650. self.colorPicker.SetColour(convertRGB(self.vPropertiesDict['color']))
  2651. else:
  2652. self.colorPicker.SetColour('black')
  2653. self.gridBagSizerO.Add(self.outlineCheck, pos = (0, 0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2654. self.gridBagSizerO.Add(widthText, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2655. self.gridBagSizerO.Add(self.widthSpin, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  2656. self.gridBagSizerO.Add(colorText, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2657. self.gridBagSizerO.Add(self.colorPicker, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2658. sizer.Add(self.gridBagSizerO, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  2659. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  2660. self.Bind(wx.EVT_CHECKBOX, self.OnOutline, self.outlineCheck)
  2661. #colors - fill
  2662. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Fill"))
  2663. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2664. self.gridBagSizerF = wx.GridBagSizer(hgap = 5, vgap = 2)
  2665. self.fillCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("fill color"))
  2666. self.fillCheck.SetValue(self.vPropertiesDict['fcolor'] != 'none' or self.vPropertiesDict['rgbcolumn'] is not None)
  2667. self.colorPickerRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("choose color:"), style = wx.RB_GROUP)
  2668. #set choose color option if there is no db connection
  2669. if self.connection:
  2670. self.colorPickerRadio.SetValue(not self.vPropertiesDict['rgbcolumn'])
  2671. else:
  2672. self.colorPickerRadio.SetValue(False)
  2673. self.fillColorPicker = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
  2674. if self.vPropertiesDict['fcolor'] != 'none':
  2675. self.fillColorPicker.SetColour(convertRGB(self.vPropertiesDict['fcolor']))
  2676. else:
  2677. self.fillColorPicker.SetColour('red')
  2678. self.colorColRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("color from map table column:"))
  2679. self.colorColChoice = self.getColsChoice(parent = panel)
  2680. if self.connection:
  2681. if self.vPropertiesDict['rgbcolumn']:
  2682. self.colorColRadio.SetValue(True)
  2683. self.colorColChoice.SetStringSelection(self.vPropertiesDict['rgbcolumn'])
  2684. else:
  2685. self.colorColRadio.SetValue(False)
  2686. self.colorColChoice.SetSelection(0)
  2687. self.colorColChoice.Enable(self.connection)
  2688. self.colorColRadio.Enable(self.connection)
  2689. self.gridBagSizerF.Add(self.fillCheck, pos = (0, 0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2690. self.gridBagSizerF.Add(self.colorPickerRadio, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2691. self.gridBagSizerF.Add(self.fillColorPicker, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2692. self.gridBagSizerF.Add(self.colorColRadio, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2693. self.gridBagSizerF.Add(self.colorColChoice, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  2694. sizer.Add(self.gridBagSizerF, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  2695. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  2696. self.Bind(wx.EVT_CHECKBOX, self.OnFill, self.fillCheck)
  2697. self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorColRadio)
  2698. self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorPickerRadio)
  2699. panel.SetSizer(border)
  2700. panel.Fit()
  2701. return panel
  2702. def _ColorsLinePanel(self, notebook):
  2703. panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
  2704. notebook.AddPage(page = panel, text = _("Colors"))
  2705. border = wx.BoxSizer(wx.VERTICAL)
  2706. #colors - outline
  2707. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Outline"))
  2708. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2709. self.gridBagSizerO = wx.GridBagSizer(hgap = 5, vgap = 2)
  2710. self.outlineCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("draw outline"))
  2711. self.outlineCheck.SetValue(self.vPropertiesDict['hcolor'] != 'none')
  2712. self.outlineCheck.SetToolTipString(_("No effect for fill color from table column"))
  2713. widthText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Width (pts):"))
  2714. if fs:
  2715. self.outWidthSpin = fs.FloatSpin(panel, id = wx.ID_ANY, min_val = 0, max_val = 30,
  2716. increment = 0.5, value = 1, style = fs.FS_RIGHT)
  2717. self.outWidthSpin.SetFormat("%f")
  2718. self.outWidthSpin.SetDigits(1)
  2719. else:
  2720. self.outWidthSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 30, initial = 1,
  2721. size = self.spinCtrlSize)
  2722. if self.vPropertiesDict['hcolor'] != 'none':
  2723. self.outWidthSpin.SetValue(self.vPropertiesDict['hwidth'] )
  2724. else:
  2725. self.outWidthSpin.SetValue(1)
  2726. colorText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Color:"))
  2727. self.colorPicker = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
  2728. if self.vPropertiesDict['hcolor'] != 'none':
  2729. self.colorPicker.SetColour(convertRGB(self.vPropertiesDict['hcolor']) )
  2730. else:
  2731. self.colorPicker.SetColour('black')
  2732. self.gridBagSizerO.Add(self.outlineCheck, pos = (0, 0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2733. self.gridBagSizerO.Add(widthText, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2734. self.gridBagSizerO.Add(self.outWidthSpin, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  2735. self.gridBagSizerO.Add(colorText, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2736. self.gridBagSizerO.Add(self.colorPicker, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2737. sizer.Add(self.gridBagSizerO, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  2738. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  2739. self.Bind(wx.EVT_CHECKBOX, self.OnOutline, self.outlineCheck)
  2740. #colors - fill
  2741. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Fill"))
  2742. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2743. self.gridBagSizerF = wx.GridBagSizer(hgap = 5, vgap = 2)
  2744. fillText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Color of lines:"))
  2745. self.colorPickerRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("choose color:"), style = wx.RB_GROUP)
  2746. #set choose color option if there is no db connection
  2747. if self.connection:
  2748. self.colorPickerRadio.SetValue(not self.vPropertiesDict['rgbcolumn'])
  2749. else:
  2750. self.colorPickerRadio.SetValue(False)
  2751. self.fillColorPicker = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
  2752. if self.vPropertiesDict['color'] != 'none':
  2753. self.fillColorPicker.SetColour(convertRGB(self.vPropertiesDict['color']) )
  2754. else:
  2755. self.fillColorPicker.SetColour('black')
  2756. self.colorColRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("color from map table column:"))
  2757. self.colorColChoice = self.getColsChoice(parent = panel)
  2758. if self.connection:
  2759. if self.vPropertiesDict['rgbcolumn']:
  2760. self.colorColRadio.SetValue(True)
  2761. self.colorColChoice.SetStringSelection(self.vPropertiesDict['rgbcolumn'])
  2762. else:
  2763. self.colorColRadio.SetValue(False)
  2764. self.colorColChoice.SetSelection(0)
  2765. self.colorColChoice.Enable(self.connection)
  2766. self.colorColRadio.Enable(self.connection)
  2767. self.gridBagSizerF.Add(fillText, pos = (0, 0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2768. self.gridBagSizerF.Add(self.colorPickerRadio, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2769. self.gridBagSizerF.Add(self.fillColorPicker, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2770. self.gridBagSizerF.Add(self.colorColRadio, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2771. self.gridBagSizerF.Add(self.colorColChoice, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  2772. sizer.Add(self.gridBagSizerF, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  2773. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  2774. self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorColRadio)
  2775. self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorPickerRadio)
  2776. panel.SetSizer(border)
  2777. panel.Fit()
  2778. return panel
  2779. def _StylePointPanel(self, notebook):
  2780. panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
  2781. notebook.AddPage(page = panel, text = _("Size and style"))
  2782. border = wx.BoxSizer(wx.VERTICAL)
  2783. #symbology
  2784. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Symbology"))
  2785. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2786. gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
  2787. gridBagSizer.AddGrowableCol(1)
  2788. self.symbolRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("symbol:"), style = wx.RB_GROUP)
  2789. self.symbolRadio.SetValue(bool(self.vPropertiesDict['symbol']))
  2790. self.symbolChoice = wx.Choice(panel, id = wx.ID_ANY, choices = self.symbols)
  2791. self.epsRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("eps file:"))
  2792. self.epsRadio.SetValue(bool(self.vPropertiesDict['eps']))
  2793. self.epsFileCtrl = filebrowse.FileBrowseButton(panel, id = wx.ID_ANY, labelText = '',
  2794. buttonText = _("Browse"), toolTip = _("Type filename or click browse to choose file"),
  2795. dialogTitle = _("Choose a file"), startDirectory = '', initialValue = '',
  2796. fileMask = "Encapsulated PostScript (*.eps)|*.eps|All files (*.*)|*.*", fileMode = wx.OPEN)
  2797. if self.vPropertiesDict['symbol']:
  2798. self.symbolChoice.SetStringSelection(self.vPropertiesDict['symbol'])
  2799. self.epsFileCtrl.SetValue('')
  2800. else: #eps chosen
  2801. self.epsFileCtrl.SetValue(self.vPropertiesDict['eps'])
  2802. self.symbolChoice.SetSelection(0)
  2803. gridBagSizer.Add(self.symbolRadio, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2804. gridBagSizer.Add(self.symbolChoice, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2805. gridBagSizer.Add(self.epsRadio, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2806. gridBagSizer.Add(self.epsFileCtrl, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  2807. sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  2808. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  2809. #size
  2810. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Size"))
  2811. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2812. gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
  2813. gridBagSizer.AddGrowableCol(0)
  2814. self.sizeRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("size:"), style = wx.RB_GROUP)
  2815. self.sizeSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 50, initial = 1)
  2816. self.sizecolumnRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("size from map table column:"))
  2817. self.sizeColChoice = self.getColsChoice(panel)
  2818. self.scaleText = wx.StaticText(panel, id = wx.ID_ANY, label = _("scale:"))
  2819. self.scaleSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 25, initial = 1)
  2820. self.sizeRadio.SetValue(self.vPropertiesDict['size'] is not None)
  2821. self.sizecolumnRadio.SetValue(bool(self.vPropertiesDict['sizecolumn']))
  2822. if self.vPropertiesDict['size']:
  2823. self.sizeSpin.SetValue(self.vPropertiesDict['size'])
  2824. else: self.sizeSpin.SetValue(5)
  2825. if self.vPropertiesDict['sizecolumn']:
  2826. self.scaleSpin.SetValue(self.vPropertiesDict['scale'])
  2827. self.sizeColChoice.SetStringSelection(self.vPropertiesDict['sizecolumn'])
  2828. else:
  2829. self.scaleSpin.SetValue(1)
  2830. self.sizeColChoice.SetSelection(0)
  2831. if not self.connection:
  2832. for each in (self.sizecolumnRadio, self.sizeColChoice, self.scaleSpin, self.scaleText):
  2833. each.Disable()
  2834. gridBagSizer.Add(self.sizeRadio, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2835. gridBagSizer.Add(self.sizeSpin, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2836. gridBagSizer.Add(self.sizecolumnRadio, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2837. gridBagSizer.Add(self.sizeColChoice, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  2838. gridBagSizer.Add(self.scaleText, pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
  2839. gridBagSizer.Add(self.scaleSpin, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2840. sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  2841. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  2842. self.Bind(wx.EVT_RADIOBUTTON, self.OnSize, self.sizeRadio)
  2843. self.Bind(wx.EVT_RADIOBUTTON, self.OnSize, self.sizecolumnRadio)
  2844. #rotation
  2845. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Rotation"))
  2846. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2847. gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
  2848. gridBagSizer.AddGrowableCol(1)
  2849. self.rotateCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("rotate symbols:"))
  2850. self.rotateRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("counterclockwise in degrees:"), style = wx.RB_GROUP)
  2851. self.rotateSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 0, max = 360, initial = 0)
  2852. self.rotatecolumnRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("from map table column:"))
  2853. self.rotateColChoice = self.getColsChoice(panel)
  2854. self.rotateCheck.SetValue(self.vPropertiesDict['rotation'])
  2855. self.rotateRadio.SetValue(self.vPropertiesDict['rotate'] is not None)
  2856. self.rotatecolumnRadio.SetValue(bool(self.vPropertiesDict['rotatecolumn']))
  2857. if self.vPropertiesDict['rotate']:
  2858. self.rotateSpin.SetValue(self.vPropertiesDict['rotate'])
  2859. else:
  2860. self.rotateSpin.SetValue(0)
  2861. if self.vPropertiesDict['rotatecolumn']:
  2862. self.rotateColChoice.SetStringSelection(self.vPropertiesDict['rotatecolumn'])
  2863. else:
  2864. self.rotateColChoice.SetSelection(0)
  2865. gridBagSizer.Add(self.rotateCheck, pos = (0, 0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2866. gridBagSizer.Add(self.rotateRadio, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2867. gridBagSizer.Add(self.rotateSpin, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2868. gridBagSizer.Add(self.rotatecolumnRadio, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2869. gridBagSizer.Add(self.rotateColChoice, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  2870. sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  2871. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  2872. self.Bind(wx.EVT_CHECKBOX, self.OnRotation, self.rotateCheck)
  2873. self.Bind(wx.EVT_RADIOBUTTON, self.OnRotationType, self.rotateRadio)
  2874. self.Bind(wx.EVT_RADIOBUTTON, self.OnRotationType, self.rotatecolumnRadio)
  2875. panel.SetSizer(border)
  2876. panel.Fit()
  2877. return panel
  2878. def _StyleLinePanel(self, notebook):
  2879. panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
  2880. notebook.AddPage(page = panel, text = _("Size and style"))
  2881. border = wx.BoxSizer(wx.VERTICAL)
  2882. #width
  2883. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Width"))
  2884. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2885. gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
  2886. widthText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Set width (pts):"))
  2887. if fs:
  2888. self.widthSpin = fs.FloatSpin(panel, id = wx.ID_ANY, min_val = 0, max_val = 30,
  2889. increment = 0.5, value = 1, style = fs.FS_RIGHT)
  2890. self.widthSpin.SetFormat("%f")
  2891. self.widthSpin.SetDigits(1)
  2892. else:
  2893. self.widthSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 30, initial = 1)
  2894. self.cwidthCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("multiply width by category value"))
  2895. if self.vPropertiesDict['width']:
  2896. self.widthSpin.SetValue(self.vPropertiesDict['width'])
  2897. self.cwidthCheck.SetValue(False)
  2898. else:
  2899. self.widthSpin.SetValue(self.vPropertiesDict['cwidth'])
  2900. self.cwidthCheck.SetValue(True)
  2901. gridBagSizer.Add(widthText, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2902. gridBagSizer.Add(self.widthSpin, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2903. gridBagSizer.Add(self.cwidthCheck, pos = (1, 0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2904. sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  2905. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  2906. #style
  2907. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Line style"))
  2908. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2909. gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
  2910. styleText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Choose line style:"))
  2911. penStyles = ["solid", "dashed", "dotted", "dashdotted"]
  2912. self.styleCombo = PenStyleComboBox(panel, choices = penStyles, validator = TCValidator(flag = 'ZERO_AND_ONE_ONLY'))
  2913. ## self.styleCombo = wx.ComboBox(panel, id = wx.ID_ANY,
  2914. ## choices = ["solid", "dashed", "dotted", "dashdotted"],
  2915. ## validator = TCValidator(flag = 'ZERO_AND_ONE_ONLY'))
  2916. ## self.styleCombo.SetToolTipString(_("It's possible to enter a series of 0's and 1's too. "\
  2917. ## "The first block of repeated zeros or ones represents 'draw', "\
  2918. ## "the second block represents 'blank'. An even number of blocks "\
  2919. ## "will repeat the pattern, an odd number of blocks will alternate the pattern."))
  2920. linecapText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Choose linecap:"))
  2921. self.linecapChoice = wx.Choice(panel, id = wx.ID_ANY, choices = ["butt", "round", "extended_butt"])
  2922. self.styleCombo.SetValue(self.vPropertiesDict['style'])
  2923. self.linecapChoice.SetStringSelection(self.vPropertiesDict['linecap'])
  2924. gridBagSizer.Add(styleText, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2925. gridBagSizer.Add(self.styleCombo, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  2926. gridBagSizer.Add(linecapText, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2927. gridBagSizer.Add(self.linecapChoice, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  2928. sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  2929. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  2930. panel.SetSizer(border)
  2931. panel.Fit()
  2932. return panel
  2933. def _StyleAreaPanel(self, notebook):
  2934. panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
  2935. notebook.AddPage(page = panel, text = _("Size and style"))
  2936. border = wx.BoxSizer(wx.VERTICAL)
  2937. #pattern
  2938. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Pattern"))
  2939. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  2940. gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
  2941. gridBagSizer.AddGrowableCol(1)
  2942. self.patternCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("use pattern:"))
  2943. self.patFileCtrl = filebrowse.FileBrowseButton(panel, id = wx.ID_ANY, labelText = _("Choose pattern file:"),
  2944. buttonText = _("Browse"), toolTip = _("Type filename or click browse to choose file"),
  2945. dialogTitle = _("Choose a file"), startDirectory = self.patternPath, initialValue = '',
  2946. fileMask = "Encapsulated PostScript (*.eps)|*.eps|All files (*.*)|*.*", fileMode = wx.OPEN)
  2947. self.patWidthText = wx.StaticText(panel, id = wx.ID_ANY, label = _("pattern line width (pts):"))
  2948. self.patWidthSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 25, initial = 1)
  2949. self.patScaleText = wx.StaticText(panel, id = wx.ID_ANY, label = _("pattern scale factor:"))
  2950. self.patScaleSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 25, initial = 1)
  2951. self.patternCheck.SetValue(bool(self.vPropertiesDict['pat']))
  2952. if self.patternCheck.GetValue():
  2953. self.patFileCtrl.SetValue(self.vPropertiesDict['pat'])
  2954. self.patWidthSpin.SetValue(self.vPropertiesDict['pwidth'])
  2955. self.patScaleSpin.SetValue(self.vPropertiesDict['scale'])
  2956. gridBagSizer.Add(self.patternCheck, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2957. gridBagSizer.Add(self.patFileCtrl, pos = (1, 0), span = (1, 2),flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  2958. gridBagSizer.Add(self.patWidthText, pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2959. gridBagSizer.Add(self.patWidthSpin, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2960. gridBagSizer.Add(self.patScaleText, pos = (3, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2961. gridBagSizer.Add(self.patScaleSpin, pos = (3, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  2962. sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  2963. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  2964. self.Bind(wx.EVT_CHECKBOX, self.OnPattern, self.patternCheck)
  2965. panel.SetSizer(border)
  2966. panel.Fit()
  2967. return panel
  2968. def OnLayer(self, event):
  2969. """!Change columns on layer change """
  2970. if self.layerChoice.GetStringSelection() == self.currLayer:
  2971. return
  2972. self.currLayer = self.layerChoice.GetStringSelection()
  2973. if self.connection:
  2974. cols = self.mapDBInfo.GetColumns(self.mapDBInfo.layers[int(self.currLayer)]['table'])
  2975. else:
  2976. cols = []
  2977. self.choiceColumns.SetItems(cols)
  2978. self.choiceColumns.SetSelection(0)
  2979. if self.type in ('points', 'lines'):
  2980. self.colorColChoice.SetItems(cols)
  2981. self.colorColChoice.SetSelection(0)
  2982. def OnOutline(self, event):
  2983. for widget in self.gridBagSizerO.GetChildren():
  2984. if widget.GetWindow() != self.outlineCheck:
  2985. widget.GetWindow().Enable(self.outlineCheck.GetValue())
  2986. def OnFill(self, event):
  2987. enable = self.fillCheck.GetValue()
  2988. self.colorColChoice.Enable(enable)
  2989. self.colorColRadio.Enable(enable)
  2990. self.fillColorPicker.Enable(enable)
  2991. self.colorPickerRadio.Enable(enable)
  2992. if enable:
  2993. self.OnColor(None)
  2994. if not self.connection:
  2995. self.colorColChoice.Disable()
  2996. self.colorColRadio.Disable()
  2997. def OnColor(self, event):
  2998. self.colorColChoice.Enable(self.colorColRadio.GetValue())
  2999. self.fillColorPicker.Enable(self.colorPickerRadio.GetValue())
  3000. def OnSize(self, event):
  3001. self.sizeSpin.Enable(self.sizeRadio.GetValue())
  3002. self.sizeColChoice.Enable(self.sizecolumnRadio.GetValue())
  3003. self.scaleText.Enable(self.sizecolumnRadio.GetValue())
  3004. self.scaleSpin.Enable(self.sizecolumnRadio.GetValue())
  3005. def OnRotation(self, event):
  3006. for each in (self.rotateRadio, self.rotatecolumnRadio, self.rotateColChoice, self.rotateSpin):
  3007. if self.rotateCheck.GetValue():
  3008. each.Enable()
  3009. self.OnRotationType(event = None)
  3010. else:
  3011. each.Disable()
  3012. def OnRotationType(self, event):
  3013. self.rotateSpin.Enable(self.rotateRadio.GetValue())
  3014. self.rotateColChoice.Enable(self.rotatecolumnRadio.GetValue())
  3015. def OnPattern(self, event):
  3016. for each in (self.patFileCtrl, self.patWidthText, self.patWidthSpin, self.patScaleText, self.patScaleSpin):
  3017. each.Enable(self.patternCheck.GetValue())
  3018. def EnableLayerSelection(self, enable = True):
  3019. for widget in self.gridBagSizerL.GetChildren():
  3020. if widget.GetWindow() != self.warning:
  3021. widget.GetWindow().Enable(enable)
  3022. def getColsChoice(self, parent):
  3023. """!Returns a wx.Choice with table columns"""
  3024. if self.connection:
  3025. cols = self.mapDBInfo.GetColumns(self.mapDBInfo.layers[int(self.currLayer)]['table'])
  3026. else:
  3027. cols = []
  3028. choice = wx.Choice(parent = parent, id = wx.ID_ANY, choices = cols)
  3029. return choice
  3030. def update(self):
  3031. #feature type
  3032. if self.type in ('lines', 'points'):
  3033. featureType = None
  3034. if self.checkType1.GetValue():
  3035. featureType = self.checkType1.GetName()
  3036. if self.checkType2.GetValue():
  3037. featureType += " or " + self.checkType2.GetName()
  3038. elif self.checkType2.GetValue():
  3039. featureType = self.checkType2.GetName()
  3040. if featureType:
  3041. self.vPropertiesDict['type'] = featureType
  3042. # is connection
  3043. self.vPropertiesDict['connection'] = self.connection
  3044. if self.connection:
  3045. self.vPropertiesDict['layer'] = self.layerChoice.GetStringSelection()
  3046. if self.radioCats.GetValue() and not self.textCtrlCats.IsEmpty():
  3047. self.vPropertiesDict['cats'] = self.textCtrlCats.GetValue()
  3048. elif self.radioWhere.GetValue() and not self.textCtrlWhere.IsEmpty():
  3049. self.vPropertiesDict['where'] = self.choiceColumns.GetStringSelection() + " " \
  3050. + self.textCtrlWhere.GetValue()
  3051. #mask
  3052. if self.mask.GetValue():
  3053. self.vPropertiesDict['masked'] = 'y'
  3054. else:
  3055. self.vPropertiesDict['masked'] = 'n'
  3056. #colors
  3057. if self.type in ('points', 'areas'):
  3058. if self.outlineCheck.GetValue():
  3059. self.vPropertiesDict['color'] = convertRGB(self.colorPicker.GetColour())
  3060. self.vPropertiesDict['width'] = self.widthSpin.GetValue()
  3061. else:
  3062. self.vPropertiesDict['color'] = 'none'
  3063. if self.fillCheck.GetValue():
  3064. if self.colorPickerRadio.GetValue():
  3065. self.vPropertiesDict['fcolor'] = convertRGB(self.fillColorPicker.GetColour())
  3066. self.vPropertiesDict['rgbcolumn'] = None
  3067. if self.colorColRadio.GetValue():
  3068. self.vPropertiesDict['fcolor'] = 'none'# this color is taken in case of no record in rgb column
  3069. self.vPropertiesDict['rgbcolumn'] = self.colorColChoice.GetStringSelection()
  3070. else:
  3071. self.vPropertiesDict['fcolor'] = 'none'
  3072. if self.type == 'lines':
  3073. #hcolor only when no rgbcolumn
  3074. if self.outlineCheck.GetValue():# and self.fillCheck.GetValue() and self.colorColRadio.GetValue():
  3075. self.vPropertiesDict['hcolor'] = convertRGB(self.colorPicker.GetColour())
  3076. self.vPropertiesDict['hwidth'] = self.outWidthSpin.GetValue()
  3077. else:
  3078. self.vPropertiesDict['hcolor'] = 'none'
  3079. if self.colorPickerRadio.GetValue():
  3080. self.vPropertiesDict['color'] = convertRGB(self.fillColorPicker.GetColour())
  3081. self.vPropertiesDict['rgbcolumn'] = None
  3082. if self.colorColRadio.GetValue():
  3083. self.vPropertiesDict['color'] = 'none'# this color is taken in case of no record in rgb column
  3084. self.vPropertiesDict['rgbcolumn'] = self.colorColChoice.GetStringSelection()
  3085. #
  3086. #size and style
  3087. #
  3088. if self.type == 'points':
  3089. #symbols
  3090. if self.symbolRadio.GetValue():
  3091. self.vPropertiesDict['symbol'] = self.symbolChoice.GetStringSelection()
  3092. self.vPropertiesDict['eps'] = None
  3093. else:
  3094. self.vPropertiesDict['eps'] = self.epsFileCtrl.GetValue()
  3095. self.vPropertiesDict['symbol'] = None
  3096. #size
  3097. if self.sizeRadio.GetValue():
  3098. self.vPropertiesDict['size'] = self.sizeSpin.GetValue()
  3099. self.vPropertiesDict['sizecolumn'] = None
  3100. self.vPropertiesDict['scale'] = None
  3101. else:
  3102. self.vPropertiesDict['sizecolumn'] = self.sizeColChoice.GetStringSelection()
  3103. self.vPropertiesDict['scale'] = self.scaleSpin.GetValue()
  3104. self.vPropertiesDict['size'] = None
  3105. #rotation
  3106. self.vPropertiesDict['rotate'] = None
  3107. self.vPropertiesDict['rotatecolumn'] = None
  3108. self.vPropertiesDict['rotation'] = False
  3109. if self.rotateCheck.GetValue():
  3110. self.vPropertiesDict['rotation'] = True
  3111. if self.rotateRadio.GetValue():
  3112. self.vPropertiesDict['rotate'] = self.rotateSpin.GetValue()
  3113. else:
  3114. self.vPropertiesDict['rotatecolumn'] = self.rotateColChoice.GetStringSelection()
  3115. if self.type == 'areas':
  3116. #pattern
  3117. self.vPropertiesDict['pat'] = None
  3118. if self.patternCheck.GetValue() and bool(self.patFileCtrl.GetValue()):
  3119. self.vPropertiesDict['pat'] = self.patFileCtrl.GetValue()
  3120. self.vPropertiesDict['pwidth'] = self.patWidthSpin.GetValue()
  3121. self.vPropertiesDict['scale'] = self.patScaleSpin.GetValue()
  3122. if self.type == 'lines':
  3123. #width
  3124. if self.cwidthCheck.GetValue():
  3125. self.vPropertiesDict['cwidth'] = self.widthSpin.GetValue()
  3126. self.vPropertiesDict['width'] = None
  3127. else:
  3128. self.vPropertiesDict['width'] = self.widthSpin.GetValue()
  3129. self.vPropertiesDict['cwidth'] = None
  3130. #line style
  3131. if self.styleCombo.GetValue():
  3132. self.vPropertiesDict['style'] = self.styleCombo.GetValue()
  3133. else:
  3134. self.vPropertiesDict['style'] = 'solid'
  3135. self.vPropertiesDict['linecap'] = self.linecapChoice.GetStringSelection()
  3136. def OnOK(self, event):
  3137. self.update()
  3138. event.Skip()
  3139. class LegendDialog(PsmapDialog):
  3140. def __init__(self, parent, id, settings, page):
  3141. PsmapDialog.__init__(self, parent = parent, id = id, title = "Legend settings", settings = settings)
  3142. self.objectType = ('rasterLegend', 'vectorLegend')
  3143. self.instruction = settings
  3144. map = self.instruction.FindInstructionByType('map')
  3145. if map:
  3146. self.mapId = map.id
  3147. else:
  3148. self.mapId = None
  3149. vector = self.instruction.FindInstructionByType('vector')
  3150. if vector:
  3151. self.vectorId = vector.id
  3152. else:
  3153. self.vectorId = None
  3154. raster = self.instruction.FindInstructionByType('raster')
  3155. if raster:
  3156. self.rasterId = raster.id
  3157. else:
  3158. self.rasterId = None
  3159. self.pageId = self.instruction.FindInstructionByType('page').id
  3160. currPage = self.instruction[self.pageId].GetInstruction()
  3161. #raster legend
  3162. if self.id[0] is not None:
  3163. self.rasterLegend = self.instruction[self.id[0]]
  3164. self.rLegendDict = self.rasterLegend.GetInstruction()
  3165. else:
  3166. self.id[0] = wx.NewId()
  3167. self.rasterLegend = RasterLegend(self.id[0])
  3168. self.rLegendDict = self.rasterLegend.GetInstruction()
  3169. self.rLegendDict['where'] = currPage['Left'], currPage['Top']
  3170. #vector legend
  3171. if self.id[1] is not None:
  3172. self.vLegendDict = self.instruction[self.id[1]].GetInstruction()
  3173. else:
  3174. self.id[1] = wx.NewId()
  3175. vectorLegend = VectorLegend(self.id[1])
  3176. self.vLegendDict = vectorLegend.GetInstruction()
  3177. self.vLegendDict['where'] = currPage['Left'], currPage['Top']
  3178. if self.rasterId:
  3179. self.currRaster = self.instruction[self.rasterId]['raster']
  3180. else:
  3181. self.currRaster = None
  3182. #notebook
  3183. self.notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT)
  3184. self.panelRaster = self._rasterLegend(self.notebook)
  3185. self.panelVector = self._vectorLegend(self.notebook)
  3186. self.OnRaster(None)
  3187. self.OnRange(None)
  3188. self.OnIsLegend(None)
  3189. self.OnSpan(None)
  3190. self.OnBorder(None)
  3191. self._layout(self.notebook)
  3192. self.notebook.ChangeSelection(page)
  3193. self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGING, self.OnPageChanging)
  3194. def OnPageChanging(self, event):
  3195. """!Workaround to scroll up to see the checkbox"""
  3196. wx.CallAfter(self.FindWindowByName('rasterPanel').ScrollChildIntoView,
  3197. self.FindWindowByName('showRLegend'))
  3198. wx.CallAfter(self.FindWindowByName('vectorPanel').ScrollChildIntoView,
  3199. self.FindWindowByName('showVLegend'))
  3200. def _rasterLegend(self, notebook):
  3201. panel = scrolled.ScrolledPanel(parent = notebook, id = wx.ID_ANY, size = (-1, 500), style = wx.TAB_TRAVERSAL)
  3202. panel.SetupScrolling(scroll_x = False, scroll_y = True)
  3203. panel.SetName('rasterPanel')
  3204. notebook.AddPage(page = panel, text = _("Raster legend"))
  3205. border = wx.BoxSizer(wx.VERTICAL)
  3206. # is legend
  3207. self.isRLegend = wx.CheckBox(panel, id = wx.ID_ANY, label = _("Show raster legend"))
  3208. self.isRLegend.SetValue(self.rLegendDict['rLegend'])
  3209. self.isRLegend.SetName("showRLegend")
  3210. border.Add(item = self.isRLegend, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  3211. # choose raster
  3212. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Source raster"))
  3213. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  3214. flexSizer = wx.FlexGridSizer (cols = 2, hgap = 5, vgap = 5)
  3215. flexSizer.AddGrowableCol(1)
  3216. self.rasterDefault = wx.RadioButton(panel, id = wx.ID_ANY, label = _("current raster"), style = wx.RB_GROUP)
  3217. self.rasterOther = wx.RadioButton(panel, id = wx.ID_ANY, label = _("select raster"))
  3218. self.rasterDefault.SetValue(self.rLegendDict['rasterDefault'])#
  3219. self.rasterOther.SetValue(not self.rLegendDict['rasterDefault'])#
  3220. rasterType = getRasterType(map = self.currRaster)
  3221. self.rasterCurrent = wx.StaticText(panel, id = wx.ID_ANY,
  3222. label = _("%(rast)s: type %(type)s") % { 'rast' : self.currRaster,
  3223. 'type' : rasterType })
  3224. self.rasterSelect = Select(panel, id = wx.ID_ANY, size = globalvar.DIALOG_GSELECT_SIZE,
  3225. type = 'raster', multiple = False,
  3226. updateOnPopup = True, onPopup = None)
  3227. if not self.rLegendDict['rasterDefault']:
  3228. self.rasterSelect.SetValue(self.rLegendDict['raster'])
  3229. else:
  3230. self.rasterSelect.SetValue('')
  3231. flexSizer.Add(self.rasterDefault, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3232. flexSizer.Add(self.rasterCurrent, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.LEFT, border = 10)
  3233. flexSizer.Add(self.rasterOther, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3234. flexSizer.Add(self.rasterSelect, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
  3235. sizer.Add(item = flexSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
  3236. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  3237. # type of legend
  3238. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Type of legend"))
  3239. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  3240. vbox = wx.BoxSizer(wx.VERTICAL)
  3241. self.discrete = wx.RadioButton(parent = panel, id = wx.ID_ANY,
  3242. label = " %s " % _("discrete legend (categorical maps)"), style = wx.RB_GROUP)
  3243. self.continuous = wx.RadioButton(parent = panel, id = wx.ID_ANY,
  3244. label = " %s " % _("continuous color gradient legend (floating point map)"))
  3245. vbox.Add(self.discrete, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 0)
  3246. vbox.Add(self.continuous, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 0)
  3247. sizer.Add(item = vbox, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
  3248. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  3249. # size, position and font
  3250. self.sizePositionFont(legendType = 'raster', parent = panel, mainSizer = border)
  3251. # advanced settings
  3252. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Advanced legend settings"))
  3253. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  3254. gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
  3255. # no data
  3256. self.nodata = wx.CheckBox(panel, id = wx.ID_ANY, label = _('draw "no data" box'))
  3257. if self.rLegendDict['nodata'] == 'y':
  3258. self.nodata.SetValue(True)
  3259. else:
  3260. self.nodata.SetValue(False)
  3261. #tickbar
  3262. self.ticks = wx.CheckBox(panel, id = wx.ID_ANY, label = _("draw ticks across color table"))
  3263. if self.rLegendDict['tickbar'] == 'y':
  3264. self.ticks.SetValue(True)
  3265. else:
  3266. self.ticks.SetValue(False)
  3267. # range
  3268. if self.rasterId and self.instruction[self.rasterId]['raster']:
  3269. rinfo = grass.raster_info(self.instruction[self.rasterId]['raster'])
  3270. self.minim, self.maxim = rinfo['min'], rinfo['max']
  3271. else:
  3272. self.minim, self.maxim = 0,0
  3273. self.range = wx.CheckBox(panel, id = wx.ID_ANY, label = _("range"))
  3274. self.range.SetValue(self.rLegendDict['range'])
  3275. self.minText = wx.StaticText(panel, id = wx.ID_ANY, label = "min (%s)" % self.minim)
  3276. self.maxText = wx.StaticText(panel, id = wx.ID_ANY, label = "max (%s)" % self.maxim)
  3277. self.min = wx.TextCtrl(panel, id = wx.ID_ANY, value = str(self.rLegendDict['min']))
  3278. self.max = wx.TextCtrl(panel, id = wx.ID_ANY, value = str(self.rLegendDict['max']))
  3279. gridBagSizer.Add(self.nodata, pos = (0,0), span = (1,5), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3280. gridBagSizer.Add(self.ticks, pos = (1,0), span = (1,5), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3281. gridBagSizer.Add(self.range, pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3282. gridBagSizer.Add(self.minText, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
  3283. gridBagSizer.Add(self.min, pos = (2,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3284. gridBagSizer.Add(self.maxText, pos = (2,3), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
  3285. gridBagSizer.Add(self.max, pos = (2,4), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3286. sizer.Add(gridBagSizer, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3287. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  3288. panel.SetSizer(border)
  3289. panel.Fit()
  3290. # bindings
  3291. self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterDefault)
  3292. self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterOther)
  3293. self.Bind(wx.EVT_CHECKBOX, self.OnIsLegend, self.isRLegend)
  3294. self.Bind(wx.EVT_RADIOBUTTON, self.OnDiscrete, self.discrete)
  3295. self.Bind(wx.EVT_RADIOBUTTON, self.OnDiscrete, self.continuous)
  3296. ## self.Bind(wx.EVT_CHECKBOX, self.OnDefaultSize, panel.defaultSize)
  3297. self.Bind(wx.EVT_CHECKBOX, self.OnRange, self.range)
  3298. self.rasterSelect.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnRaster)
  3299. return panel
  3300. def _vectorLegend(self, notebook):
  3301. panel = scrolled.ScrolledPanel(parent = notebook, id = wx.ID_ANY, size = (-1, 500), style = wx.TAB_TRAVERSAL)
  3302. panel.SetupScrolling(scroll_x = False, scroll_y = True)
  3303. panel.SetName('vectorPanel')
  3304. notebook.AddPage(page = panel, text = _("Vector legend"))
  3305. border = wx.BoxSizer(wx.VERTICAL)
  3306. # is legend
  3307. self.isVLegend = wx.CheckBox(panel, id = wx.ID_ANY, label = _("Show vector legend"))
  3308. self.isVLegend.SetValue(self.vLegendDict['vLegend'])
  3309. self.isVLegend.SetName("showVLegend")
  3310. border.Add(item = self.isVLegend, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  3311. #vector maps, their order, labels
  3312. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Source vector maps"))
  3313. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  3314. gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
  3315. gridBagSizer.AddGrowableCol(0,3)
  3316. gridBagSizer.AddGrowableCol(1,1)
  3317. vectorText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Choose vector maps and their order in legend"))
  3318. self.vectorListCtrl = CheckListCtrl(panel)
  3319. self.vectorListCtrl.InsertColumn(0, _("Vector map"))
  3320. self.vectorListCtrl.InsertColumn(1, _("Label"))
  3321. if self.vectorId:
  3322. vectors = sorted(self.instruction[self.vectorId]['list'], key = lambda x: x[3])
  3323. for vector in vectors:
  3324. index = self.vectorListCtrl.InsertStringItem(sys.maxint, vector[0].split('@')[0])
  3325. self.vectorListCtrl.SetStringItem(index, 1, vector[4])
  3326. self.vectorListCtrl.SetItemData(index, index)
  3327. self.vectorListCtrl.CheckItem(index, True)
  3328. if vector[3] == 0:
  3329. self.vectorListCtrl.CheckItem(index, False)
  3330. if not self.vectorId:
  3331. self.vectorListCtrl.SetColumnWidth(0, 100)
  3332. else:
  3333. self.vectorListCtrl.SetColumnWidth(0, wx.LIST_AUTOSIZE)
  3334. self.vectorListCtrl.SetColumnWidth(1, wx.LIST_AUTOSIZE)
  3335. self.btnUp = wx.Button(panel, id = wx.ID_ANY, label = _("Up"))
  3336. self.btnDown = wx.Button(panel, id = wx.ID_ANY, label = _("Down"))
  3337. self.btnLabel = wx.Button(panel, id = wx.ID_ANY, label = _("Edit label"))
  3338. gridBagSizer.Add(vectorText, pos = (0,0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3339. gridBagSizer.Add(self.vectorListCtrl, pos = (1,0), span = (3,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  3340. gridBagSizer.Add(self.btnUp, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3341. gridBagSizer.Add(self.btnDown, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3342. gridBagSizer.Add(self.btnLabel, pos = (3,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3343. sizer.Add(gridBagSizer, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  3344. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  3345. # size, position and font
  3346. self.sizePositionFont(legendType = 'vector', parent = panel, mainSizer = border)
  3347. # border
  3348. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Border"))
  3349. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  3350. flexGridSizer = wx.FlexGridSizer(cols = 2, hgap = 5, vgap = 5)
  3351. self.borderCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("draw border around legend"))
  3352. self.borderColorCtrl = wx.ColourPickerCtrl(panel, id = wx.ID_ANY, style = wx.FNTP_FONTDESC_AS_LABEL)
  3353. if self.vLegendDict['border'] == 'none':
  3354. self.borderColorCtrl.SetColour(wx.BLACK)
  3355. self.borderCheck.SetValue(False)
  3356. else:
  3357. self.borderColorCtrl.SetColour(convertRGB(self.vLegendDict['border']))
  3358. self.borderCheck.SetValue(True)
  3359. flexGridSizer.Add(self.borderCheck, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3360. flexGridSizer.Add(self.borderColorCtrl, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3361. sizer.Add(item = flexGridSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
  3362. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  3363. self.Bind(wx.EVT_BUTTON, self.OnUp, self.btnUp)
  3364. self.Bind(wx.EVT_BUTTON, self.OnDown, self.btnDown)
  3365. self.Bind(wx.EVT_BUTTON, self.OnEditLabel, self.btnLabel)
  3366. self.Bind(wx.EVT_CHECKBOX, self.OnIsLegend, self.isVLegend)
  3367. self.Bind(wx.EVT_CHECKBOX, self.OnSpan, panel.spanRadio)
  3368. self.Bind(wx.EVT_CHECKBOX, self.OnBorder, self.borderCheck)
  3369. self.Bind(wx.EVT_FONTPICKER_CHANGED, self.OnFont, panel.font['fontCtrl'])
  3370. panel.SetSizer(border)
  3371. panel.Fit()
  3372. return panel
  3373. def sizePositionFont(self, legendType, parent, mainSizer):
  3374. """!Insert widgets for size, position and font control"""
  3375. if legendType == 'raster':
  3376. legendDict = self.rLegendDict
  3377. else:
  3378. legendDict = self.vLegendDict
  3379. panel = parent
  3380. border = mainSizer
  3381. # size and position
  3382. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Size and position"))
  3383. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  3384. #unit
  3385. self.AddUnits(parent = panel, dialogDict = legendDict)
  3386. unitBox = wx.BoxSizer(wx.HORIZONTAL)
  3387. unitBox.Add(panel.units['unitsLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.LEFT, border = 10)
  3388. unitBox.Add(panel.units['unitsCtrl'], proportion = 1, flag = wx.ALL, border = 5)
  3389. sizer.Add(unitBox, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3390. hBox = wx.BoxSizer(wx.HORIZONTAL)
  3391. posBox = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " %_("Position"))
  3392. posSizer = wx.StaticBoxSizer(posBox, wx.VERTICAL)
  3393. sizeBox = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Size"))
  3394. sizeSizer = wx.StaticBoxSizer(sizeBox, wx.VERTICAL)
  3395. posGridBagSizer = wx.GridBagSizer(hgap = 10, vgap = 5)
  3396. posGridBagSizer.AddGrowableRow(2)
  3397. #position
  3398. self.AddPosition(parent = panel, dialogDict = legendDict)
  3399. posGridBagSizer.Add(panel.position['xLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3400. posGridBagSizer.Add(panel.position['xCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3401. posGridBagSizer.Add(panel.position['yLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3402. posGridBagSizer.Add(panel.position['yCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3403. posGridBagSizer.Add(panel.position['comment'], pos = (2,0), span = (1,2), flag =wx.ALIGN_BOTTOM, border = 0)
  3404. posSizer.Add(posGridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  3405. #size
  3406. width = wx.StaticText(panel, id = wx.ID_ANY, label = _("Width:"))
  3407. if legendDict['width']:
  3408. w = self.unitConv.convert(value = float(legendDict['width']), fromUnit = 'inch', toUnit = legendDict['unit'])
  3409. else:
  3410. w = ''
  3411. panel.widthCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, value = str(w), validator = TCValidator("DIGIT_ONLY"))
  3412. panel.widthCtrl.SetToolTipString(_("Leave the edit field empty, to use default values."))
  3413. if legendType == 'raster':
  3414. ## panel.defaultSize = wx.CheckBox(panel, id = wx.ID_ANY, label = _("Use default size"))
  3415. ## panel.defaultSize.SetValue(legendDict['defaultSize'])
  3416. panel.heightOrColumnsLabel = wx.StaticText(panel, id = wx.ID_ANY, label = _("Height:"))
  3417. if legendDict['height']:
  3418. h = self.unitConv.convert(value = float(legendDict['height']), fromUnit = 'inch', toUnit = legendDict['unit'])
  3419. else:
  3420. h = ''
  3421. panel.heightOrColumnsCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, value = str(h), validator = TCValidator("DIGIT_ONLY"))
  3422. self.rSizeGBSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
  3423. ## self.rSizeGBSizer.Add(panel.defaultSize, pos = (0,0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3424. self.rSizeGBSizer.Add(width, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3425. self.rSizeGBSizer.Add(panel.widthCtrl, pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3426. self.rSizeGBSizer.Add(panel.heightOrColumnsLabel, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3427. self.rSizeGBSizer.Add(panel.heightOrColumnsCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3428. sizeSizer.Add(self.rSizeGBSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  3429. if legendType == 'vector':
  3430. panel.widthCtrl.SetToolTipString(_("Width of the color symbol (for lines)\nin front of the legend text"))
  3431. #columns
  3432. minVect, maxVect = 0, 0
  3433. if self.vectorId:
  3434. minVect = 1
  3435. maxVect = min(10, len(self.instruction[self.vectorId]['list']))
  3436. cols = wx.StaticText(panel, id = wx.ID_ANY, label = _("Columns:"))
  3437. panel.colsCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, value = "",
  3438. min = minVect, max = maxVect, initial = legendDict['cols'])
  3439. #span
  3440. panel.spanRadio = wx.CheckBox(panel, id = wx.ID_ANY, label = _("column span:"))
  3441. panel.spanTextCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, value = '')
  3442. panel.spanTextCtrl.SetToolTipString(_("Column separation distance between the left edges\n"\
  3443. "of two columns in a multicolumn legend"))
  3444. if legendDict['span']:
  3445. panel.spanRadio.SetValue(True)
  3446. s = self.unitConv.convert(value = float(legendDict['span']), fromUnit = 'inch', toUnit = legendDict['unit'])
  3447. panel.spanTextCtrl.SetValue(str(s))
  3448. else:
  3449. panel.spanRadio.SetValue(False)
  3450. self.vSizeGBSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
  3451. self.vSizeGBSizer.AddGrowableCol(1)
  3452. self.vSizeGBSizer.Add(width, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3453. self.vSizeGBSizer.Add(panel.widthCtrl, pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3454. self.vSizeGBSizer.Add(cols, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3455. self.vSizeGBSizer.Add(panel.colsCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3456. self.vSizeGBSizer.Add(panel.spanRadio, pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3457. self.vSizeGBSizer.Add(panel.spanTextCtrl, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3458. sizeSizer.Add(self.vSizeGBSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  3459. hBox.Add(posSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 3)
  3460. hBox.Add(sizeSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 3)
  3461. sizer.Add(hBox, proportion = 0, flag = wx.EXPAND, border = 0)
  3462. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  3463. # font
  3464. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Font settings"))
  3465. fontSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  3466. flexSizer = wx.FlexGridSizer (cols = 2, hgap = 5, vgap = 5)
  3467. flexSizer.AddGrowableCol(1)
  3468. if legendType == 'raster':
  3469. self.AddFont(parent = panel, dialogDict = legendDict, color = True)
  3470. else:
  3471. self.AddFont(parent = panel, dialogDict = legendDict, color = False)
  3472. flexSizer.Add(panel.font['fontLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3473. flexSizer.Add(panel.font['fontCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3474. flexSizer.Add(panel.font['fontSizeLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3475. flexSizer.Add(panel.font['fontSizeCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3476. if legendType == 'raster':
  3477. flexSizer.Add(panel.font['colorLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3478. flexSizer.Add(panel.font['colorCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3479. fontSizer.Add(item = flexSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
  3480. border.Add(item = fontSizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  3481. # some enable/disable methods
  3482. def OnIsLegend(self, event):
  3483. """!Enables and disables controls, it depends if raster or vector legend is checked"""
  3484. page = self.notebook.GetSelection()
  3485. if page == 0 or event is None:
  3486. children = self.panelRaster.GetChildren()
  3487. if self.isRLegend.GetValue():
  3488. for i,widget in enumerate(children):
  3489. widget.Enable()
  3490. self.OnRaster(None)
  3491. self.OnRange(None)
  3492. self.OnDiscrete(None)
  3493. else:
  3494. for widget in children:
  3495. if widget.GetName() != 'showRLegend':
  3496. widget.Disable()
  3497. if page == 1 or event is None:
  3498. children = self.panelVector.GetChildren()
  3499. if self.isVLegend.GetValue():
  3500. for i, widget in enumerate(children):
  3501. widget.Enable()
  3502. self.OnSpan(None)
  3503. self.OnBorder(None)
  3504. else:
  3505. for widget in children:
  3506. if widget.GetName() != 'showVLegend':
  3507. widget.Disable()
  3508. def OnRaster(self, event):
  3509. if self.rasterDefault.GetValue():#default
  3510. self.rasterSelect.Disable()
  3511. type = getRasterType(self.currRaster)
  3512. else:#select raster
  3513. self.rasterSelect.Enable()
  3514. map = self.rasterSelect.GetValue()
  3515. type = getRasterType(map)
  3516. if type == 'CELL':
  3517. self.discrete.SetValue(True)
  3518. elif type in ('FCELL', 'DCELL'):
  3519. self.continuous.SetValue(True)
  3520. if event is None:
  3521. if self.rLegendDict['discrete'] == 'y':
  3522. self.discrete.SetValue(True)
  3523. elif self.rLegendDict['discrete'] == 'n':
  3524. self.continuous.SetValue(True)
  3525. self.OnDiscrete(None)
  3526. def OnDiscrete(self, event):
  3527. """! Change control according to the type of legend"""
  3528. enabledSize = self.panelRaster.heightOrColumnsCtrl.IsEnabled()
  3529. self.panelRaster.heightOrColumnsCtrl.Destroy()
  3530. if self.discrete.GetValue():
  3531. self.panelRaster.heightOrColumnsLabel.SetLabel(_("Columns:"))
  3532. self.panelRaster.heightOrColumnsCtrl = wx.SpinCtrl(self.panelRaster, id = wx.ID_ANY, value = "", min = 1, max = 10, initial = self.rLegendDict['cols'])
  3533. self.panelRaster.heightOrColumnsCtrl.Enable(enabledSize)
  3534. self.nodata.Enable()
  3535. self.range.Disable()
  3536. self.min.Disable()
  3537. self.max.Disable()
  3538. self.minText.Disable()
  3539. self.maxText.Disable()
  3540. self.ticks.Disable()
  3541. else:
  3542. self.panelRaster.heightOrColumnsLabel.SetLabel(_("Height:"))
  3543. if self.rLegendDict['height']:
  3544. h = self.unitConv.convert(value = float(self.rLegendDict['height']), fromUnit = 'inch', toUnit = self.rLegendDict['unit'])
  3545. else:
  3546. h = ''
  3547. self.panelRaster.heightOrColumnsCtrl = wx.TextCtrl(self.panelRaster, id = wx.ID_ANY,
  3548. value = str(h), validator = TCValidator("DIGIT_ONLY"))
  3549. self.panelRaster.heightOrColumnsCtrl.Enable(enabledSize)
  3550. self.nodata.Disable()
  3551. self.range.Enable()
  3552. if self.range.GetValue():
  3553. self.minText.Enable()
  3554. self.maxText.Enable()
  3555. self.min.Enable()
  3556. self.max.Enable()
  3557. self.ticks.Enable()
  3558. self.rSizeGBSizer.Add(self.panelRaster.heightOrColumnsCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3559. self.panelRaster.Layout()
  3560. self.panelRaster.Fit()
  3561. def OnRange(self, event):
  3562. if not self.range.GetValue():
  3563. self.min.Disable()
  3564. self.max.Disable()
  3565. self.minText.Disable()
  3566. self.maxText.Disable()
  3567. else:
  3568. self.min.Enable()
  3569. self.max.Enable()
  3570. self.minText.Enable()
  3571. self.maxText.Enable()
  3572. def OnUp(self, event):
  3573. """!Moves selected map up, changes order in vector legend"""
  3574. if self.vectorListCtrl.GetFirstSelected() != -1:
  3575. pos = self.vectorListCtrl.GetFirstSelected()
  3576. if pos:
  3577. idx1 = self.vectorListCtrl.GetItemData(pos) - 1
  3578. idx2 = self.vectorListCtrl.GetItemData(pos - 1) + 1
  3579. self.vectorListCtrl.SetItemData(pos, idx1)
  3580. self.vectorListCtrl.SetItemData(pos - 1, idx2)
  3581. self.vectorListCtrl.SortItems(cmp)
  3582. if pos > 0:
  3583. selected = (pos - 1)
  3584. else:
  3585. selected = 0
  3586. self.vectorListCtrl.Select(selected)
  3587. def OnDown(self, event):
  3588. """!Moves selected map down, changes order in vector legend"""
  3589. if self.vectorListCtrl.GetFirstSelected() != -1:
  3590. pos = self.vectorListCtrl.GetFirstSelected()
  3591. if pos != self.vectorListCtrl.GetItemCount() - 1:
  3592. idx1 = self.vectorListCtrl.GetItemData(pos) + 1
  3593. idx2 = self.vectorListCtrl.GetItemData(pos + 1) - 1
  3594. self.vectorListCtrl.SetItemData(pos, idx1)
  3595. self.vectorListCtrl.SetItemData(pos + 1, idx2)
  3596. self.vectorListCtrl.SortItems(cmp)
  3597. if pos < self.vectorListCtrl.GetItemCount() -1:
  3598. selected = (pos + 1)
  3599. else:
  3600. selected = self.vectorListCtrl.GetItemCount() -1
  3601. self.vectorListCtrl.Select(selected)
  3602. def OnEditLabel(self, event):
  3603. """!Change legend label of vector map"""
  3604. if self.vectorListCtrl.GetFirstSelected() != -1:
  3605. idx = self.vectorListCtrl.GetFirstSelected()
  3606. default = self.vectorListCtrl.GetItem(idx, 1).GetText()
  3607. dlg = wx.TextEntryDialog(self, message = _("Edit legend label:"), caption = _("Edit label"),
  3608. defaultValue = default, style = wx.OK|wx.CANCEL|wx.CENTRE)
  3609. if dlg.ShowModal() == wx.ID_OK:
  3610. new = dlg.GetValue()
  3611. self.vectorListCtrl.SetStringItem(idx, 1, new)
  3612. dlg.Destroy()
  3613. def OnSpan(self, event):
  3614. self.panelVector.spanTextCtrl.Enable(self.panelVector.spanRadio.GetValue())
  3615. def OnFont(self, event):
  3616. """!Changes default width according to fontsize, width [inch] = fontsize[pt]/24"""
  3617. ## fontsize = self.panelVector.font['fontCtrl'].GetSelectedFont().GetPointSize()
  3618. fontsize = self.panelVector.font['fontSizeCtrl'].GetValue()
  3619. unit = self.panelVector.units['unitsCtrl'].GetStringSelection()
  3620. w = fontsize/24.
  3621. width = self.unitConv.convert(value = w, fromUnit = 'inch', toUnit = unit)
  3622. self.panelVector.widthCtrl.SetValue("%3.2f" % width)
  3623. def OnBorder(self, event):
  3624. """!Enables/disables colorPickerCtrl for border"""
  3625. self.borderColorCtrl.Enable(self.borderCheck.GetValue())
  3626. def updateRasterLegend(self):
  3627. """!Save information from raster legend dialog to dictionary"""
  3628. #is raster legend
  3629. if not self.isRLegend.GetValue():
  3630. self.rLegendDict['rLegend'] = False
  3631. else:
  3632. self.rLegendDict['rLegend'] = True
  3633. #units
  3634. currUnit = self.panelRaster.units['unitsCtrl'].GetStringSelection()
  3635. self.rLegendDict['unit'] = currUnit
  3636. # raster
  3637. if self.rasterDefault.GetValue():
  3638. self.rLegendDict['rasterDefault'] = True
  3639. self.rLegendDict['raster'] = self.currRaster
  3640. else:
  3641. self.rLegendDict['rasterDefault'] = False
  3642. self.rLegendDict['raster'] = self.rasterSelect.GetValue()
  3643. if self.rLegendDict['rLegend'] and not self.rLegendDict['raster']:
  3644. wx.MessageBox(message = _("No raster map selected!"),
  3645. caption = _('No raster'), style = wx.OK|wx.ICON_ERROR)
  3646. return False
  3647. if self.rLegendDict['raster']:
  3648. # type and range of map
  3649. rasterType = getRasterType(self.rLegendDict['raster'])
  3650. if rasterType is None:
  3651. return False
  3652. self.rLegendDict['type'] = rasterType
  3653. #discrete
  3654. if self.discrete.GetValue():
  3655. self.rLegendDict['discrete'] = 'y'
  3656. else:
  3657. self.rLegendDict['discrete'] = 'n'
  3658. # font
  3659. self.rLegendDict['font'] = self.panelRaster.font['fontCtrl'].GetStringSelection()
  3660. self.rLegendDict['fontsize'] = self.panelRaster.font['fontSizeCtrl'].GetValue()
  3661. ## font = self.panelRaster.font['fontCtrl'].GetSelectedFont()
  3662. ## self.rLegendDict['font'] = font.GetFaceName()
  3663. ## self.rLegendDict['fontsize'] = font.GetPointSize()
  3664. color = self.panelRaster.font['colorCtrl'].GetColour()
  3665. ## if color.GetAsString(wx.C2S_NAME) in PSMAP_COLORS:
  3666. ## self.rLegendDict['color'] = color.GetAsString(wx.C2S_NAME)
  3667. ## else:
  3668. self.rLegendDict['color'] = convertRGB(color)
  3669. # position
  3670. x = self.unitConv.convert(value = float(self.panelRaster.position['xCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
  3671. y = self.unitConv.convert(value = float(self.panelRaster.position['yCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
  3672. self.rLegendDict['where'] = (x, y)
  3673. # estimated size
  3674. width = self.panelRaster.widthCtrl.GetValue()
  3675. try:
  3676. width = float(width)
  3677. width = self.unitConv.convert(value = width, fromUnit = currUnit, toUnit = 'inch')
  3678. except ValueError:
  3679. width = None
  3680. self.rLegendDict['width'] = width
  3681. if self.rLegendDict['discrete'] == 'n':
  3682. height = self.panelRaster.heightOrColumnsCtrl.GetValue()
  3683. try:
  3684. height = float(height)
  3685. height = self.unitConv.convert(value = height, fromUnit = currUnit, toUnit = 'inch')
  3686. except ValueError:
  3687. height = None
  3688. self.rLegendDict['height'] = height
  3689. else:
  3690. cols = self.panelRaster.heightOrColumnsCtrl.GetValue()
  3691. self.rLegendDict['cols'] = cols
  3692. drawHeight = self.rasterLegend.EstimateHeight(raster = self.rLegendDict['raster'], discrete = self.rLegendDict['discrete'],
  3693. fontsize = self.rLegendDict['fontsize'], cols = self.rLegendDict['cols'],
  3694. height = self.rLegendDict['height'])
  3695. drawWidth = self.rasterLegend.EstimateWidth(raster = self.rLegendDict['raster'], discrete = self.rLegendDict['discrete'],
  3696. fontsize = self.rLegendDict['fontsize'], cols = self.rLegendDict['cols'],
  3697. width = self.rLegendDict['width'], paperInstr = self.instruction[self.pageId])
  3698. self.rLegendDict['rect'] = wx.Rect2D(x = x, y = y, w = drawWidth, h = drawHeight)
  3699. # no data
  3700. if self.rLegendDict['discrete'] == 'y':
  3701. if self.nodata.GetValue():
  3702. self.rLegendDict['nodata'] = 'y'
  3703. else:
  3704. self.rLegendDict['nodata'] = 'n'
  3705. # tickbar
  3706. elif self.rLegendDict['discrete'] == 'n':
  3707. if self.ticks.GetValue():
  3708. self.rLegendDict['tickbar'] = 'y'
  3709. else:
  3710. self.rLegendDict['tickbar'] = 'n'
  3711. # range
  3712. if self.range.GetValue():
  3713. self.rLegendDict['range'] = True
  3714. self.rLegendDict['min'] = self.min.GetValue()
  3715. self.rLegendDict['max'] = self.max.GetValue()
  3716. else:
  3717. self.rLegendDict['range'] = False
  3718. if not self.id[0] in self.instruction:
  3719. rasterLegend = RasterLegend(self.id[0])
  3720. self.instruction.AddInstruction(rasterLegend)
  3721. self.instruction[self.id[0]].SetInstruction(self.rLegendDict)
  3722. if self.id[0] not in self.parent.objectId:
  3723. self.parent.objectId.append(self.id[0])
  3724. return True
  3725. def updateVectorLegend(self):
  3726. """!Save information from vector legend dialog to dictionary"""
  3727. vector = self.instruction.FindInstructionByType('vector')
  3728. if vector:
  3729. self.vectorId = vector.id
  3730. else:
  3731. self.vectorId = None
  3732. #is vector legend
  3733. if not self.isVLegend.GetValue():
  3734. self.vLegendDict['vLegend'] = False
  3735. else:
  3736. self.vLegendDict['vLegend'] = True
  3737. if self.vLegendDict['vLegend'] == True and self.vectorId is not None:
  3738. # labels
  3739. #reindex order
  3740. idx = 1
  3741. for item in range(self.vectorListCtrl.GetItemCount()):
  3742. if self.vectorListCtrl.IsChecked(item):
  3743. self.vectorListCtrl.SetItemData(item, idx)
  3744. idx += 1
  3745. else:
  3746. self.vectorListCtrl.SetItemData(item, 0)
  3747. if idx == 1:
  3748. self.vLegendDict['vLegend'] = False
  3749. else:
  3750. vList = self.instruction[self.vectorId]['list']
  3751. for i, vector in enumerate(vList):
  3752. item = self.vectorListCtrl.FindItem(start = -1, str = vector[0].split('@')[0])
  3753. vList[i][3] = self.vectorListCtrl.GetItemData(item)
  3754. vList[i][4] = self.vectorListCtrl.GetItem(item, 1).GetText()
  3755. vmaps = self.instruction.FindInstructionByType('vProperties', list = True)
  3756. for vmap, vector in zip(vmaps, vList):
  3757. self.instruction[vmap.id]['lpos'] = vector[3]
  3758. self.instruction[vmap.id]['label'] = vector[4]
  3759. #units
  3760. currUnit = self.panelVector.units['unitsCtrl'].GetStringSelection()
  3761. self.vLegendDict['unit'] = currUnit
  3762. # position
  3763. x = self.unitConv.convert(value = float(self.panelVector.position['xCtrl'].GetValue()),
  3764. fromUnit = currUnit, toUnit = 'inch')
  3765. y = self.unitConv.convert(value = float(self.panelVector.position['yCtrl'].GetValue()),
  3766. fromUnit = currUnit, toUnit = 'inch')
  3767. self.vLegendDict['where'] = (x, y)
  3768. # font
  3769. self.vLegendDict['font'] = self.panelVector.font['fontCtrl'].GetStringSelection()
  3770. self.vLegendDict['fontsize'] = self.panelVector.font['fontSizeCtrl'].GetValue()
  3771. ## self.vLegendDict['font'] = font.GetFaceName()
  3772. ## self.vLegendDict['fontsize'] = font.GetPointSize()
  3773. dc = wx.PaintDC(self)
  3774. font = dc.GetFont()
  3775. dc.SetFont(wx.Font(pointSize = self.vLegendDict['fontsize'], family = font.GetFamily(),
  3776. style = font.GetStyle(), weight = wx.FONTWEIGHT_NORMAL))
  3777. #size
  3778. width = self.unitConv.convert(value = float(self.panelVector.widthCtrl.GetValue()),
  3779. fromUnit = currUnit, toUnit = 'inch')
  3780. self.vLegendDict['width'] = width
  3781. self.vLegendDict['cols'] = self.panelVector.colsCtrl.GetValue()
  3782. if self.panelVector.spanRadio.GetValue() and self.panelVector.spanTextCtrl.GetValue():
  3783. self.vLegendDict['span'] = self.panelVector.spanTextCtrl.GetValue()
  3784. else:
  3785. self.vLegendDict['span'] = None
  3786. # size estimation
  3787. vectors = self.instruction[self.vectorId]['list']
  3788. labels = [vector[4] for vector in vectors if vector[3] != 0]
  3789. extent = dc.GetTextExtent(max(labels, key = len))
  3790. wExtent = self.unitConv.convert(value = extent[0], fromUnit = 'pixel', toUnit = 'inch')
  3791. hExtent = self.unitConv.convert(value = extent[1], fromUnit = 'pixel', toUnit = 'inch')
  3792. w = (width + wExtent) * self.vLegendDict['cols']
  3793. h = len(labels) * hExtent / self.vLegendDict['cols']
  3794. h *= 1.1
  3795. self.vLegendDict['rect'] = wx.Rect2D(x, y, w, h)
  3796. #border
  3797. if self.borderCheck.GetValue():
  3798. color = self.borderColorCtrl.GetColour()
  3799. ## if color.GetAsString(wx.C2S_NAME) in PSMAP_COLORS:
  3800. ## self.vLegendDict['border'] = color.GetAsString(wx.C2S_NAME)
  3801. ## else:
  3802. self.vLegendDict['border'] = convertRGB(color)
  3803. else:
  3804. self.vLegendDict['border'] = 'none'
  3805. if not self.id[1] in self.instruction:
  3806. vectorLegend = VectorLegend(self.id[1])
  3807. self.instruction.AddInstruction(vectorLegend)
  3808. self.instruction[self.id[1]].SetInstruction(self.vLegendDict)
  3809. if self.id[1] not in self.parent.objectId:
  3810. self.parent.objectId.append(self.id[1])
  3811. return True
  3812. def update(self):
  3813. okR = self.updateRasterLegend()
  3814. okV = self.updateVectorLegend()
  3815. if okR and okV:
  3816. return True
  3817. return False
  3818. def updateDialog(self):
  3819. """!Update legend coordinates after moving"""
  3820. # raster legend
  3821. if 'rect' in self.rLegendDict:
  3822. x, y = self.rLegendDict['rect'][:2]
  3823. currUnit = self.panelRaster.units['unitsCtrl'].GetStringSelection()
  3824. x = self.unitConv.convert(value = x, fromUnit = 'inch', toUnit = currUnit)
  3825. y = self.unitConv.convert(value = y, fromUnit = 'inch', toUnit = currUnit)
  3826. self.panelRaster.position['xCtrl'].SetValue("%5.3f" % x)
  3827. self.panelRaster.position['yCtrl'].SetValue("%5.3f" % y)
  3828. #update name and type of raster
  3829. raster = self.instruction.FindInstructionByType('raster')
  3830. if raster:
  3831. self.rasterId = raster.id
  3832. else:
  3833. self.rasterId = None
  3834. if raster:
  3835. currRaster = raster['raster']
  3836. else:
  3837. currRaster = None
  3838. rasterType = getRasterType(map = currRaster)
  3839. self.rasterCurrent.SetLabel(_("%(rast)s: type %(type)s") % \
  3840. { 'rast' : currRaster, 'type' : str(rasterType) })
  3841. # vector legend
  3842. if 'rect' in self.vLegendDict:
  3843. x, y = self.vLegendDict['rect'][:2]
  3844. currUnit = self.panelVector.units['unitsCtrl'].GetStringSelection()
  3845. x = self.unitConv.convert(value = x, fromUnit = 'inch', toUnit = currUnit)
  3846. y = self.unitConv.convert(value = y, fromUnit = 'inch', toUnit = currUnit)
  3847. self.panelVector.position['xCtrl'].SetValue("%5.3f" % x)
  3848. self.panelVector.position['yCtrl'].SetValue("%5.3f" % y)
  3849. # update vector maps
  3850. if self.instruction.FindInstructionByType('vector'):
  3851. vectors = sorted(self.instruction.FindInstructionByType('vector')['list'], key = lambda x: x[3])
  3852. self.vectorListCtrl.DeleteAllItems()
  3853. for vector in vectors:
  3854. index = self.vectorListCtrl.InsertStringItem(sys.maxint, vector[0].split('@')[0])
  3855. self.vectorListCtrl.SetStringItem(index, 1, vector[4])
  3856. self.vectorListCtrl.SetItemData(index, index)
  3857. self.vectorListCtrl.CheckItem(index, True)
  3858. if vector[3] == 0:
  3859. self.vectorListCtrl.CheckItem(index, False)
  3860. self.panelVector.colsCtrl.SetRange(1, min(10, len(self.instruction.FindInstructionByType('vector')['list'])))
  3861. self.panelVector.colsCtrl.SetValue(1)
  3862. else:
  3863. self.vectorListCtrl.DeleteAllItems()
  3864. self.panelVector.colsCtrl.SetRange(0,0)
  3865. self.panelVector.colsCtrl.SetValue(0)
  3866. class MapinfoDialog(PsmapDialog):
  3867. def __init__(self, parent, id, settings):
  3868. PsmapDialog.__init__(self, parent = parent, id = id, title = "Mapinfo settings", settings = settings)
  3869. self.objectType = ('mapinfo',)
  3870. if self.id is not None:
  3871. self.mapinfo = self.instruction[self.id]
  3872. self.mapinfoDict = self.mapinfo.GetInstruction()
  3873. else:
  3874. self.id = wx.NewId()
  3875. self.mapinfo = Mapinfo(self.id)
  3876. self.mapinfoDict = self.mapinfo.GetInstruction()
  3877. page = self.instruction.FindInstructionByType('page').GetInstruction()
  3878. self.mapinfoDict['where'] = page['Left'], page['Top']
  3879. self.panel = self._mapinfoPanel()
  3880. self._layout(self.panel)
  3881. # self.OnIsBackground(None)
  3882. # self.OnIsBorder(None)
  3883. def _mapinfoPanel(self):
  3884. panel = wx.Panel(parent = self, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
  3885. #panel.SetupScrolling(scroll_x = False, scroll_y = True)
  3886. border = wx.BoxSizer(wx.VERTICAL)
  3887. # position
  3888. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Position"))
  3889. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  3890. gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
  3891. gridBagSizer.AddGrowableCol(1)
  3892. self.AddPosition(parent = panel, dialogDict = self.mapinfoDict)
  3893. self.AddUnits(parent = panel, dialogDict = self.mapinfoDict)
  3894. gridBagSizer.Add(panel.units['unitsLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3895. gridBagSizer.Add(panel.units['unitsCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3896. gridBagSizer.Add(panel.position['xLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3897. gridBagSizer.Add(panel.position['xCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3898. gridBagSizer.Add(panel.position['yLabel'], pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3899. gridBagSizer.Add(panel.position['yCtrl'], pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3900. gridBagSizer.Add(panel.position['comment'], pos = (3,0), span = (1,2), flag =wx.ALIGN_BOTTOM, border = 0)
  3901. sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  3902. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  3903. # font
  3904. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Font settings"))
  3905. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  3906. gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
  3907. gridBagSizer.AddGrowableCol(1)
  3908. self.AddFont(parent = panel, dialogDict = self.mapinfoDict)#creates font color too, used below
  3909. ## gridBagSizer.Add(panel.font['fontLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3910. ## gridBagSizer.Add(panel.font['fontCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3911. ## gridBagSizer.Add(panel.font['colorLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3912. ## gridBagSizer.Add(panel.font['colorCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3913. gridBagSizer.Add(panel.font['fontLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3914. gridBagSizer.Add(panel.font['fontCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3915. gridBagSizer.Add(panel.font['fontSizeLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3916. gridBagSizer.Add(panel.font['fontSizeCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3917. gridBagSizer.Add(panel.font['colorLabel'], pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3918. gridBagSizer.Add(panel.font['colorCtrl'], pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3919. sizer.Add(item = gridBagSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
  3920. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  3921. # colors
  3922. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " %_("Color settings"))
  3923. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  3924. flexSizer = wx.FlexGridSizer (cols = 2, hgap = 5, vgap = 5)
  3925. flexSizer.AddGrowableCol(1)
  3926. self.colors = {}
  3927. self.colors['borderCtrl'] = wx.CheckBox(panel, id = wx.ID_ANY, label = _("use border color:"))
  3928. self.colors['backgroundCtrl'] = wx.CheckBox(panel, id = wx.ID_ANY, label = _("use background color:"))
  3929. self.colors['borderColor'] = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
  3930. self.colors['backgroundColor'] = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
  3931. if self.mapinfoDict['border'] == None:
  3932. self.mapinfoDict['border'] = 'none'
  3933. elif self.mapinfoDict['border'] != 'none':
  3934. self.colors['borderCtrl'].SetValue(True)
  3935. self.colors['borderColor'].SetColour(convertRGB(self.mapinfoDict['border']))
  3936. else:
  3937. self.colors['borderCtrl'].SetValue(False)
  3938. self.colors['borderColor'].SetColour('white')
  3939. if self.mapinfoDict['background'] == None:
  3940. self.mapinfoDict['background'] == 'none'
  3941. elif self.mapinfoDict['background'] != 'none':
  3942. self.colors['backgroundCtrl'].SetValue(True)
  3943. self.colors['backgroundColor'].SetColour(convertRGB(self.mapinfoDict['background']))
  3944. else:
  3945. self.colors['backgroundCtrl'].SetValue(False)
  3946. self.colors['backgroundColor'].SetColour('white')
  3947. flexSizer.Add(self.colors['borderCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3948. flexSizer.Add(self.colors['borderColor'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3949. flexSizer.Add(self.colors['backgroundCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3950. flexSizer.Add(self.colors['backgroundColor'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  3951. sizer.Add(item = flexSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
  3952. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  3953. panel.SetSizer(border)
  3954. self.Bind(wx.EVT_CHECKBOX, self.OnIsBorder, self.colors['borderCtrl'])
  3955. self.Bind(wx.EVT_CHECKBOX, self.OnIsBackground, self.colors['backgroundCtrl'])
  3956. return panel
  3957. def OnIsBackground(self, event):
  3958. if self.colors['backgroundCtrl'].GetValue():
  3959. self.colors['backgroundColor'].Enable()
  3960. self.update()
  3961. else:
  3962. self.colors['backgroundColor'].Disable()
  3963. def OnIsBorder(self, event):
  3964. if self.colors['borderCtrl'].GetValue():
  3965. self.colors['borderColor'].Enable()
  3966. self.update()
  3967. else:
  3968. self.colors['borderColor'].Disable()
  3969. def update(self):
  3970. #units
  3971. currUnit = self.panel.units['unitsCtrl'].GetStringSelection()
  3972. self.mapinfoDict['unit'] = currUnit
  3973. # position
  3974. if self.panel.position['xCtrl'].GetValue():
  3975. x = self.panel.position['xCtrl'].GetValue()
  3976. else:
  3977. x = self.mapinfoDict['where'][0]
  3978. if self.panel.position['yCtrl'].GetValue():
  3979. y = self.panel.position['yCtrl'].GetValue()
  3980. else:
  3981. y = self.mapinfoDict['where'][1]
  3982. x = self.unitConv.convert(value = float(self.panel.position['xCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
  3983. y = self.unitConv.convert(value = float(self.panel.position['yCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
  3984. self.mapinfoDict['where'] = (x, y)
  3985. # font
  3986. self.mapinfoDict['font'] = self.panel.font['fontCtrl'].GetStringSelection()
  3987. self.mapinfoDict['fontsize'] = self.panel.font['fontSizeCtrl'].GetValue()
  3988. ## font = self.panel.font['fontCtrl'].GetSelectedFont()
  3989. ## self.mapinfoDict['font'] = font.GetFaceName()
  3990. ## self.mapinfoDict['fontsize'] = font.GetPointSize()
  3991. #colors
  3992. color = self.panel.font['colorCtrl'].GetColour()
  3993. ## if color.GetAsString(wx.C2S_NAME) in PSMAP_COLORS:
  3994. ## self.mapinfoDict['color'] = color.GetAsString(wx.C2S_NAME)
  3995. ## else:
  3996. self.mapinfoDict['color'] = convertRGB(color)
  3997. if self.colors['backgroundCtrl'].GetValue():
  3998. background = self.colors['backgroundColor'].GetColour()
  3999. ## if background.GetAsString(wx.C2S_NAME) in PSMAP_COLORS:
  4000. ## self.mapinfoDict['background'] = background.GetAsString(wx.C2S_NAME)
  4001. ## else:
  4002. self.mapinfoDict['background'] = convertRGB(background)
  4003. else:
  4004. self.mapinfoDict['background'] = 'none'
  4005. if self.colors['borderCtrl'].GetValue():
  4006. border = self.colors['borderColor'].GetColour()
  4007. ## if border.GetAsString(wx.C2S_NAME) in PSMAP_COLORS:
  4008. ## self.mapinfoDict['border'] = border.GetAsString(wx.C2S_NAME)
  4009. ## else:
  4010. self.mapinfoDict['border'] = convertRGB(border)
  4011. else:
  4012. self.mapinfoDict['border'] = 'none'
  4013. # estimation of size
  4014. self.mapinfoDict['rect'] = self.mapinfo.EstimateRect(self.mapinfoDict)
  4015. if self.id not in self.instruction:
  4016. mapinfo = Mapinfo(self.id)
  4017. self.instruction.AddInstruction(mapinfo)
  4018. self.instruction[self.id].SetInstruction(self.mapinfoDict)
  4019. if self.id not in self.parent.objectId:
  4020. self.parent.objectId.append(self.id)
  4021. return True
  4022. def updateDialog(self):
  4023. """!Update mapinfo coordinates, after moving"""
  4024. x, y = self.mapinfoDict['where']
  4025. currUnit = self.panel.units['unitsCtrl'].GetStringSelection()
  4026. x = self.unitConv.convert(value = x, fromUnit = 'inch', toUnit = currUnit)
  4027. y = self.unitConv.convert(value = y, fromUnit = 'inch', toUnit = currUnit)
  4028. self.panel.position['xCtrl'].SetValue("%5.3f" % x)
  4029. self.panel.position['yCtrl'].SetValue("%5.3f" % y)
  4030. class ScalebarDialog(PsmapDialog):
  4031. """!Dialog for scale bar"""
  4032. def __init__(self, parent, id, settings):
  4033. PsmapDialog.__init__(self, parent = parent, id = id, title = "Scale bar settings", settings = settings)
  4034. self.objectType = ('scalebar',)
  4035. if self.id is not None:
  4036. self.scalebar = self.instruction[id]
  4037. self.scalebarDict = self.scalebar.GetInstruction()
  4038. else:
  4039. self.id = wx.NewId()
  4040. self.scalebar = Scalebar(self.id)
  4041. self.scalebarDict = self.scalebar.GetInstruction()
  4042. page = self.instruction.FindInstructionByType('page').GetInstruction()
  4043. self.scalebarDict['where'] = page['Left'], page['Top']
  4044. self.panel = self._scalebarPanel()
  4045. self._layout(self.panel)
  4046. self.mapUnit = projInfo()['units'].lower()
  4047. if projInfo()['proj'] == 'xy':
  4048. self.mapUnit = 'meters'
  4049. if self.mapUnit not in self.unitConv.getAllUnits():
  4050. wx.MessageBox(message = _("Units of current projection are not supported,\n meters will be used!"),
  4051. caption = _('Unsupported units'),
  4052. style = wx.OK|wx.ICON_ERROR)
  4053. self.mapUnit = 'meters'
  4054. def _scalebarPanel(self):
  4055. panel = wx.Panel(parent = self, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
  4056. border = wx.BoxSizer(wx.VERTICAL)
  4057. #
  4058. # position
  4059. #
  4060. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Position"))
  4061. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  4062. gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
  4063. gridBagSizer.AddGrowableCol(1)
  4064. self.AddUnits(parent = panel, dialogDict = self.scalebarDict)
  4065. self.AddPosition(parent = panel, dialogDict = self.scalebarDict)
  4066. if self.scalebarDict['rect']: # set position, ref point is center and not left top corner
  4067. x = self.unitConv.convert(value = self.scalebarDict['where'][0] - self.scalebarDict['rect'].Get()[2]/2,
  4068. fromUnit = 'inch', toUnit = self.scalebarDict['unit'])
  4069. y = self.unitConv.convert(value = self.scalebarDict['where'][1] - self.scalebarDict['rect'].Get()[3]/2,
  4070. fromUnit = 'inch', toUnit = self.scalebarDict['unit'])
  4071. panel.position['xCtrl'].SetValue("%5.3f" % x)
  4072. panel.position['yCtrl'].SetValue("%5.3f" % y)
  4073. gridBagSizer.Add(panel.units['unitsLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4074. gridBagSizer.Add(panel.units['unitsCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4075. gridBagSizer.Add(panel.position['xLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4076. gridBagSizer.Add(panel.position['xCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4077. gridBagSizer.Add(panel.position['yLabel'], pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4078. gridBagSizer.Add(panel.position['yCtrl'], pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4079. gridBagSizer.Add(panel.position['comment'], pos = (3,0), span = (1,2), flag =wx.ALIGN_BOTTOM, border = 0)
  4080. sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  4081. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  4082. #
  4083. # size
  4084. #
  4085. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Size"))
  4086. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  4087. gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
  4088. gridBagSizer.AddGrowableCol(1)
  4089. lengthText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Length:"))
  4090. heightText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Height:"))
  4091. self.lengthTextCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, validator = TCValidator('DIGIT_ONLY'))
  4092. self.lengthTextCtrl.SetToolTipString(_("Scalebar length is given in map units"))
  4093. self.heightTextCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, validator = TCValidator('DIGIT_ONLY'))
  4094. self.heightTextCtrl.SetToolTipString(_("Scalebar height is real height on paper"))
  4095. choices = ['default'] + self.unitConv.getMapUnits()
  4096. self.unitsLength = wx.Choice(panel, id = wx.ID_ANY, choices = choices)
  4097. choices = self.unitConv.getPageUnits()
  4098. self.unitsHeight = wx.Choice(panel, id = wx.ID_ANY, choices = choices)
  4099. # set values
  4100. ok = self.unitsLength.SetStringSelection(self.scalebarDict['unitsLength'])
  4101. if not ok:
  4102. if self.scalebarDict['unitsLength'] == 'auto':
  4103. self.unitsLength.SetSelection(0)
  4104. elif self.scalebarDict['unitsLength'] == 'nautmiles':
  4105. self.unitsLength.SetStringSelection("nautical miles")
  4106. self.unitsHeight.SetStringSelection(self.scalebarDict['unitsHeight'])
  4107. if self.scalebarDict['length']:
  4108. self.lengthTextCtrl.SetValue(str(self.scalebarDict['length']))
  4109. else: #estimate default
  4110. reg = grass.region()
  4111. w = int((reg['e'] - reg['w'])/3)
  4112. w = round(w, -len(str(w)) + 2) #12345 -> 12000
  4113. self.lengthTextCtrl.SetValue(str(w))
  4114. h = self.unitConv.convert(value = self.scalebarDict['height'], fromUnit = 'inch',
  4115. toUnit = self.scalebarDict['unitsHeight'])
  4116. self.heightTextCtrl.SetValue(str(h))
  4117. gridBagSizer.Add(lengthText, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4118. gridBagSizer.Add(self.lengthTextCtrl, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4119. gridBagSizer.Add(self.unitsLength, pos = (0, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  4120. gridBagSizer.Add(heightText, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4121. gridBagSizer.Add(self.heightTextCtrl, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4122. gridBagSizer.Add(self.unitsHeight, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  4123. sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  4124. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  4125. #
  4126. #style
  4127. #
  4128. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Style"))
  4129. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  4130. gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
  4131. sbTypeText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Type:"))
  4132. self.sbCombo = wx.combo.BitmapComboBox(panel, style = wx.CB_READONLY)
  4133. # only temporary, images must be moved away
  4134. imagePath = os.path.join(globalvar.ETCIMGDIR, "scalebar-fancy.png"), os.path.join(globalvar.ETCIMGDIR, "scalebar-simple.png")
  4135. for item, path in zip(['fancy', 'simple'], imagePath):
  4136. if not os.path.exists(path):
  4137. bitmap = wx.EmptyBitmap(0,0)
  4138. else:
  4139. bitmap = wx.Bitmap(path)
  4140. self.sbCombo.Append(item = '', bitmap = bitmap, clientData = item[0])
  4141. #self.sbCombo.Append(item = 'simple', bitmap = wx.Bitmap("./images/scalebar-simple.png"), clientData = 's')
  4142. if self.scalebarDict['scalebar'] == 'f':
  4143. self.sbCombo.SetSelection(0)
  4144. elif self.scalebarDict['scalebar'] == 's':
  4145. self.sbCombo.SetSelection(1)
  4146. sbSegmentsText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Number of segments:"))
  4147. self.sbSegmentsCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 30, initial = 4)
  4148. self.sbSegmentsCtrl.SetValue(self.scalebarDict['segment'])
  4149. sbLabelsText1 = wx.StaticText(panel, id = wx.ID_ANY, label = _("Label every "))
  4150. sbLabelsText2 = wx.StaticText(panel, id = wx.ID_ANY, label = _("segments"))
  4151. self.sbLabelsCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 30, initial = 1)
  4152. self.sbLabelsCtrl.SetValue(self.scalebarDict['numbers'])
  4153. #font
  4154. fontsizeText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Font size:"))
  4155. self.fontsizeCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 4, max = 30, initial = 10)
  4156. self.fontsizeCtrl.SetValue(self.scalebarDict['fontsize'])
  4157. self.backgroundCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("transparent text background"))
  4158. if self.scalebarDict['background'] == 'y':
  4159. self.backgroundCheck.SetValue(False)
  4160. else:
  4161. self.backgroundCheck.SetValue(True)
  4162. gridBagSizer.Add(sbTypeText, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4163. gridBagSizer.Add(self.sbCombo, pos = (0,1), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
  4164. gridBagSizer.Add(sbSegmentsText, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4165. gridBagSizer.Add(self.sbSegmentsCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4166. gridBagSizer.Add(sbLabelsText1, pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4167. gridBagSizer.Add(self.sbLabelsCtrl, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4168. gridBagSizer.Add(sbLabelsText2, pos = (2,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4169. gridBagSizer.Add(fontsizeText, pos = (3,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4170. gridBagSizer.Add(self.fontsizeCtrl, pos = (3,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4171. gridBagSizer.Add(self.backgroundCheck, pos = (4, 0), span = (1,3), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4172. sizer.Add(gridBagSizer, proportion = 1, flag = wx.ALIGN_CENTER_VERTICAL, border = 5)
  4173. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  4174. panel.SetSizer(border)
  4175. return panel
  4176. def update(self):
  4177. """!Save information from dialog"""
  4178. #units
  4179. currUnit = self.panel.units['unitsCtrl'].GetStringSelection()
  4180. self.scalebarDict['unit'] = currUnit
  4181. # position
  4182. if self.panel.position['xCtrl'].GetValue():
  4183. x = self.panel.position['xCtrl'].GetValue()
  4184. else:
  4185. x = self.scalebarDict['where'][0]
  4186. if self.panel.position['yCtrl'].GetValue():
  4187. y = self.panel.position['yCtrl'].GetValue()
  4188. else:
  4189. y = self.scalebarDict['where'][1]
  4190. x = self.unitConv.convert(value = float(self.panel.position['xCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
  4191. y = self.unitConv.convert(value = float(self.panel.position['yCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
  4192. #style
  4193. self.scalebarDict['scalebar'] = self.sbCombo.GetClientData(self.sbCombo.GetSelection())
  4194. self.scalebarDict['segment'] = self.sbSegmentsCtrl.GetValue()
  4195. self.scalebarDict['numbers'] = self.sbLabelsCtrl.GetValue()
  4196. self.scalebarDict['fontsize'] = self.fontsizeCtrl.GetValue()
  4197. if self.backgroundCheck.GetValue():
  4198. self.scalebarDict['background'] = 'n'
  4199. else:
  4200. self.scalebarDict['background'] = 'y'
  4201. # size
  4202. # height
  4203. self.scalebarDict['unitsHeight'] = self.unitsHeight.GetStringSelection()
  4204. try:
  4205. height = float(self.heightTextCtrl.GetValue())
  4206. height = self.unitConv.convert(value = height, fromUnit = self.scalebarDict['unitsHeight'], toUnit = 'inch')
  4207. except (ValueError, SyntaxError):
  4208. height = 0.1 #default in inch
  4209. self.scalebarDict['height'] = height
  4210. #length
  4211. selected = self.unitsLength.GetStringSelection()
  4212. if selected == 'default':
  4213. selected = 'auto'
  4214. elif selected == 'nautical miles':
  4215. selected = 'nautmiles'
  4216. self.scalebarDict['unitsLength'] = selected
  4217. try:
  4218. length = float(self.lengthTextCtrl.GetValue())
  4219. except (ValueError, SyntaxError):
  4220. wx.MessageBox(message = _("Length of scale bar is not defined"),
  4221. caption = _('Invalid input'), style = wx.OK|wx.ICON_ERROR)
  4222. return False
  4223. self.scalebarDict['length'] = length
  4224. # estimation of size
  4225. map = self.instruction.FindInstructionByType('map')
  4226. if not map:
  4227. map = self.instruction.FindInstructionByType('initMap')
  4228. mapId = map.id
  4229. rectSize = self.scalebar.EstimateSize(scalebarDict = self.scalebarDict,
  4230. scale = self.instruction[mapId]['scale'])
  4231. self.scalebarDict['rect'] = wx.Rect2D(x = x, y = y, w = rectSize[0], h = rectSize[1])
  4232. self.scalebarDict['where'] = self.scalebarDict['rect'].GetCentre()
  4233. if self.id not in self.instruction:
  4234. scalebar = Scalebar(self.id)
  4235. self.instruction.AddInstruction(scalebar)
  4236. self.instruction[self.id].SetInstruction(self.scalebarDict)
  4237. if self.id not in self.parent.objectId:
  4238. self.parent.objectId.append(self.id)
  4239. return True
  4240. def updateDialog(self):
  4241. """!Update scalebar coordinates, after moving"""
  4242. x, y = self.scalebarDict['rect'][:2]
  4243. currUnit = self.panel.units['unitsCtrl'].GetStringSelection()
  4244. x = self.unitConv.convert(value = x, fromUnit = 'inch', toUnit = currUnit)
  4245. y = self.unitConv.convert(value = y, fromUnit = 'inch', toUnit = currUnit)
  4246. self.panel.position['xCtrl'].SetValue("%5.3f" % x)
  4247. self.panel.position['yCtrl'].SetValue("%5.3f" % y)
  4248. class TextDialog(PsmapDialog):
  4249. def __init__(self, parent, id, settings):
  4250. PsmapDialog.__init__(self, parent = parent, id = id, title = "Text settings", settings = settings)
  4251. self.objectType = ('text',)
  4252. if self.id is not None:
  4253. self.textDict = self.instruction[id].GetInstruction()
  4254. else:
  4255. self.id = wx.NewId()
  4256. text = Text(self.id)
  4257. self.textDict = text.GetInstruction()
  4258. page = self.instruction.FindInstructionByType('page').GetInstruction()
  4259. self.textDict['where'] = page['Left'], page['Top']
  4260. map = self.instruction.FindInstructionByType('map')
  4261. if not map:
  4262. map = self.instruction.FindInstructionByType('initMap')
  4263. self.mapId = map.id
  4264. self.textDict['east'], self.textDict['north'] = PaperMapCoordinates(map = map, x = self.textDict['where'][0], y = self.textDict['where'][1], paperToMap = True)
  4265. notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT)
  4266. self.textPanel = self._textPanel(notebook)
  4267. self.positionPanel = self._positionPanel(notebook)
  4268. self.OnBackground(None)
  4269. self.OnHighlight(None)
  4270. self.OnBorder(None)
  4271. self.OnPositionType(None)
  4272. self.OnRotation(None)
  4273. self._layout(notebook)
  4274. def _textPanel(self, notebook):
  4275. panel = wx.Panel(parent = notebook, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
  4276. notebook.AddPage(page = panel, text = _("Text"))
  4277. border = wx.BoxSizer(wx.VERTICAL)
  4278. # text entry
  4279. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Text"))
  4280. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  4281. textLabel = wx.StaticText(panel, id = wx.ID_ANY, label = _("Enter text:"))
  4282. self.textCtrl = ExpandoTextCtrl(panel, id = wx.ID_ANY, value = self.textDict['text'])
  4283. sizer.Add(textLabel, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
  4284. sizer.Add(self.textCtrl, proportion = 1, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
  4285. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  4286. #font
  4287. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Font settings"))
  4288. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  4289. flexGridSizer = wx.FlexGridSizer (rows = 3, cols = 2, hgap = 5, vgap = 5)
  4290. flexGridSizer.AddGrowableCol(1)
  4291. self.AddFont(parent = panel, dialogDict = self.textDict)
  4292. flexGridSizer.Add(panel.font['fontLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4293. flexGridSizer.Add(panel.font['fontCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4294. flexGridSizer.Add(panel.font['fontSizeLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4295. flexGridSizer.Add(panel.font['fontSizeCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4296. flexGridSizer.Add(panel.font['colorLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4297. flexGridSizer.Add(panel.font['colorCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4298. sizer.Add(item = flexGridSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
  4299. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  4300. #text effects
  4301. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Text effects"))
  4302. sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  4303. gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
  4304. self.effect = {}
  4305. self.effect['backgroundCtrl'] = wx.CheckBox(panel, id = wx.ID_ANY, label = _("text background"))
  4306. self.effect['backgroundColor'] = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
  4307. self.effect['highlightCtrl'] = wx.CheckBox(panel, id = wx.ID_ANY, label = _("highlight"))
  4308. self.effect['highlightColor'] = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
  4309. self.effect['highlightWidth'] = wx.SpinCtrl(panel, id = wx.ID_ANY, size = self.spinCtrlSize, min = 0, max = 5, initial = 1)
  4310. self.effect['highlightWidthLabel'] = wx.StaticText(panel, id = wx.ID_ANY, label = _("Width (pts):"))
  4311. self.effect['borderCtrl'] = wx.CheckBox(panel, id = wx.ID_ANY, label = _("text border"))
  4312. self.effect['borderColor'] = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
  4313. self.effect['borderWidth'] = wx.SpinCtrl(panel, id = wx.ID_ANY, size = self.spinCtrlSize, min = 1, max = 25, initial = 1)
  4314. self.effect['borderWidthLabel'] = wx.StaticText(panel, id = wx.ID_ANY, label = _("Width (pts):"))
  4315. #set values
  4316. if self.textDict['background'] != 'none':
  4317. self.effect['backgroundCtrl'].SetValue(True)
  4318. else:
  4319. self.effect['backgroundCtrl'].SetValue(False)
  4320. if self.textDict['background'] != 'none':
  4321. self.effect['backgroundColor'].SetColour(convertRGB(self.textDict['background']))
  4322. else:
  4323. self.effect['backgroundColor'].SetColour('white')
  4324. if self.textDict['hcolor'] != 'none':
  4325. self.effect['highlightCtrl'].SetValue(True)
  4326. else:
  4327. self.effect['highlightCtrl'].SetValue(False)
  4328. if self.textDict['hcolor'] != 'none':
  4329. self.effect['highlightColor'].SetColour(convertRGB(self.textDict['hcolor']))
  4330. else:
  4331. self.effect['highlightColor'].SetColour(convertRGB('grey'))
  4332. self.effect['highlightWidth'].SetValue(float(self.textDict['hwidth']))
  4333. if self.textDict['border'] != 'none':
  4334. self.effect['borderCtrl'].SetValue(True)
  4335. else:
  4336. self.effect['borderCtrl'].SetValue(False)
  4337. if self.textDict['border'] != 'none':
  4338. self.effect['borderColor'].SetColour(convertRGB(self.textDict['border']))
  4339. else:
  4340. self.effect['borderColor'].SetColour('black')
  4341. self.effect['borderWidth'].SetValue(float(self.textDict['width']))
  4342. gridBagSizer.Add(self.effect['backgroundCtrl'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4343. gridBagSizer.Add(self.effect['backgroundColor'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4344. gridBagSizer.Add(self.effect['highlightCtrl'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4345. gridBagSizer.Add(self.effect['highlightColor'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4346. gridBagSizer.Add(self.effect['highlightWidthLabel'], pos = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4347. gridBagSizer.Add(self.effect['highlightWidth'], pos = (1,3), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4348. gridBagSizer.Add(self.effect['borderCtrl'], pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4349. gridBagSizer.Add(self.effect['borderColor'], pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4350. gridBagSizer.Add(self.effect['borderWidthLabel'], pos = (2,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4351. gridBagSizer.Add(self.effect['borderWidth'], pos = (2,3), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4352. sizer.Add(item = gridBagSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
  4353. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  4354. self.Bind(EVT_ETC_LAYOUT_NEEDED, self.OnRefit, self.textCtrl)
  4355. self.Bind(wx.EVT_CHECKBOX, self.OnBackground, self.effect['backgroundCtrl'])
  4356. self.Bind(wx.EVT_CHECKBOX, self.OnHighlight, self.effect['highlightCtrl'])
  4357. self.Bind(wx.EVT_CHECKBOX, self.OnBorder, self.effect['borderCtrl'])
  4358. panel.SetSizer(border)
  4359. panel.Fit()
  4360. return panel
  4361. def _positionPanel(self, notebook):
  4362. panel = wx.Panel(parent = notebook, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
  4363. notebook.AddPage(page = panel, text = _("Position"))
  4364. border = wx.BoxSizer(wx.VERTICAL)
  4365. #Position
  4366. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Position"))
  4367. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  4368. gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
  4369. gridBagSizer.AddGrowableCol(0)
  4370. gridBagSizer.AddGrowableCol(1)
  4371. self.positionLabel = wx.StaticText(panel, id = wx.ID_ANY, label = _("Position is given:"))
  4372. self.paperPositionCtrl = wx.RadioButton(panel, id = wx.ID_ANY, label = _("relatively to paper"), style = wx.RB_GROUP)
  4373. self.mapPositionCtrl = wx.RadioButton(panel, id = wx.ID_ANY, label = _("by map coordinates"))
  4374. self.paperPositionCtrl.SetValue(self.textDict['XY'])
  4375. self.mapPositionCtrl.SetValue(not self.textDict['XY'])
  4376. gridBagSizer.Add(self.positionLabel, pos = (0,0), span = (1,3), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT, border = 0)
  4377. gridBagSizer.Add(self.paperPositionCtrl, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT, border = 0)
  4378. gridBagSizer.Add(self.mapPositionCtrl, pos = (1,1),flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT, border = 0)
  4379. # first box - paper coordinates
  4380. box1 = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = "")
  4381. sizerP = wx.StaticBoxSizer(box1, wx.VERTICAL)
  4382. self.gridBagSizerP = wx.GridBagSizer (hgap = 5, vgap = 5)
  4383. self.gridBagSizerP.AddGrowableCol(1)
  4384. self.gridBagSizerP.AddGrowableRow(3)
  4385. self.AddPosition(parent = panel, dialogDict = self.textDict)
  4386. panel.position['comment'].SetLabel(_("Position from the top left\nedge of the paper"))
  4387. self.AddUnits(parent = panel, dialogDict = self.textDict)
  4388. self.gridBagSizerP.Add(panel.units['unitsLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4389. self.gridBagSizerP.Add(panel.units['unitsCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4390. self.gridBagSizerP.Add(panel.position['xLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4391. self.gridBagSizerP.Add(panel.position['xCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4392. self.gridBagSizerP.Add(panel.position['yLabel'], pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4393. self.gridBagSizerP.Add(panel.position['yCtrl'], pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4394. self.gridBagSizerP.Add(panel.position['comment'], pos = (3,0), span = (1,2), flag = wx.ALIGN_BOTTOM, border = 0)
  4395. sizerP.Add(self.gridBagSizerP, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  4396. gridBagSizer.Add(sizerP, pos = (2,0),span = (1,1), flag = wx.ALIGN_CENTER_HORIZONTAL|wx.EXPAND, border = 0)
  4397. # second box - map coordinates
  4398. box2 = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = "")
  4399. sizerM = wx.StaticBoxSizer(box2, wx.VERTICAL)
  4400. self.gridBagSizerM = wx.GridBagSizer (hgap = 5, vgap = 5)
  4401. self.gridBagSizerM.AddGrowableCol(0)
  4402. self.gridBagSizerM.AddGrowableCol(1)
  4403. self.eastingLabel = wx.StaticText(panel, id = wx.ID_ANY, label = "E:")
  4404. self.northingLabel = wx.StaticText(panel, id = wx.ID_ANY, label = "N:")
  4405. self.eastingCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, value = "")
  4406. self.northingCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, value = "")
  4407. east, north = PaperMapCoordinates(map = self.instruction[self.mapId], x = self.textDict['where'][0], y = self.textDict['where'][1], paperToMap = True)
  4408. self.eastingCtrl.SetValue(str(east))
  4409. self.northingCtrl.SetValue(str(north))
  4410. self.gridBagSizerM.Add(self.eastingLabel, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4411. self.gridBagSizerM.Add(self.northingLabel, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4412. self.gridBagSizerM.Add(self.eastingCtrl, pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4413. self.gridBagSizerM.Add(self.northingCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4414. sizerM.Add(self.gridBagSizerM, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  4415. gridBagSizer.Add(sizerM, pos = (2,1), flag = wx.ALIGN_LEFT|wx.EXPAND, border = 0)
  4416. #offset
  4417. box3 = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " %_("Offset"))
  4418. sizerO = wx.StaticBoxSizer(box3, wx.VERTICAL)
  4419. gridBagSizerO = wx.GridBagSizer (hgap = 5, vgap = 5)
  4420. self.xoffLabel = wx.StaticText(panel, id = wx.ID_ANY, label = _("horizontal (pts):"))
  4421. self.yoffLabel = wx.StaticText(panel, id = wx.ID_ANY, label = _("vertical (pts):"))
  4422. self.xoffCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, size = (50, -1), min = -50, max = 50, initial = 0)
  4423. self.yoffCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, size = (50, -1), min = -50, max = 50, initial = 0)
  4424. self.xoffCtrl.SetValue(self.textDict['xoffset'])
  4425. self.yoffCtrl.SetValue(self.textDict['yoffset'])
  4426. gridBagSizerO.Add(self.xoffLabel, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4427. gridBagSizerO.Add(self.yoffLabel, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4428. gridBagSizerO.Add(self.xoffCtrl, pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4429. gridBagSizerO.Add(self.yoffCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
  4430. sizerO.Add(gridBagSizerO, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
  4431. gridBagSizer.Add(sizerO, pos = (3,0), flag = wx.ALIGN_CENTER_HORIZONTAL|wx.EXPAND, border = 0)
  4432. # reference point
  4433. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " %_(" Reference point"))
  4434. sizerR = wx.StaticBoxSizer(box, wx.VERTICAL)
  4435. flexSizer = wx.FlexGridSizer(rows = 3, cols = 3, hgap = 5, vgap = 5)
  4436. flexSizer.AddGrowableCol(0)
  4437. flexSizer.AddGrowableCol(1)
  4438. flexSizer.AddGrowableCol(2)
  4439. ref = []
  4440. for row in ["upper", "center", "lower"]:
  4441. for col in ["left", "center", "right"]:
  4442. ref.append(row + " " + col)
  4443. self.radio = [wx.RadioButton(panel, id = wx.ID_ANY, label = '', style = wx.RB_GROUP, name = ref[0])]
  4444. self.radio[0].SetValue(False)
  4445. flexSizer.Add(self.radio[0], proportion = 0, flag = wx.ALIGN_CENTER, border = 0)
  4446. for i in range(1,9):
  4447. self.radio.append(wx.RadioButton(panel, id = wx.ID_ANY, label = '', name = ref[i]))
  4448. self.radio[-1].SetValue(False)
  4449. flexSizer.Add(self.radio[-1], proportion = 0, flag = wx.ALIGN_CENTER, border = 0)
  4450. self.FindWindowByName(self.textDict['ref']).SetValue(True)
  4451. sizerR.Add(flexSizer, proportion = 1, flag = wx.EXPAND, border = 0)
  4452. gridBagSizer.Add(sizerR, pos = (3,1), flag = wx.ALIGN_LEFT|wx.EXPAND, border = 0)
  4453. sizer.Add(gridBagSizer, proportion = 1, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
  4454. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  4455. #rotation
  4456. box = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Text rotation"))
  4457. sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  4458. self.rotCtrl = wx.CheckBox(panel, id = wx.ID_ANY, label = _("rotate text (counterclockwise)"))
  4459. self.rotValue = wx.SpinCtrl(panel, wx.ID_ANY, size = (50, -1), min = 0, max = 360, initial = 0)
  4460. if self.textDict['rotate']:
  4461. self.rotValue.SetValue(int(self.textDict['rotate']))
  4462. self.rotCtrl.SetValue(True)
  4463. else:
  4464. self.rotValue.SetValue(0)
  4465. self.rotCtrl.SetValue(False)
  4466. sizer.Add(self.rotCtrl, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT|wx.ALL, border = 5)
  4467. sizer.Add(self.rotValue, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT|wx.ALL, border = 5)
  4468. border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
  4469. panel.SetSizer(border)
  4470. panel.Fit()
  4471. self.Bind(wx.EVT_RADIOBUTTON, self.OnPositionType, self.paperPositionCtrl)
  4472. self.Bind(wx.EVT_RADIOBUTTON, self.OnPositionType, self.mapPositionCtrl)
  4473. self.Bind(wx.EVT_CHECKBOX, self.OnRotation, self.rotCtrl)
  4474. return panel
  4475. def OnRefit(self, event):
  4476. self.Fit()
  4477. def OnRotation(self, event):
  4478. if self.rotCtrl.GetValue():
  4479. self.rotValue.Enable()
  4480. else:
  4481. self.rotValue.Disable()
  4482. def OnPositionType(self, event):
  4483. if self.paperPositionCtrl.GetValue():
  4484. for widget in self.gridBagSizerP.GetChildren():
  4485. widget.GetWindow().Enable()
  4486. for widget in self.gridBagSizerM.GetChildren():
  4487. widget.GetWindow().Disable()
  4488. else:
  4489. for widget in self.gridBagSizerM.GetChildren():
  4490. widget.GetWindow().Enable()
  4491. for widget in self.gridBagSizerP.GetChildren():
  4492. widget.GetWindow().Disable()
  4493. def OnBackground(self, event):
  4494. if self.effect['backgroundCtrl'].GetValue():
  4495. self.effect['backgroundColor'].Enable()
  4496. self.update()
  4497. else:
  4498. self.effect['backgroundColor'].Disable()
  4499. def OnHighlight(self, event):
  4500. if self.effect['highlightCtrl'].GetValue():
  4501. self.effect['highlightColor'].Enable()
  4502. self.effect['highlightWidth'].Enable()
  4503. self.effect['highlightWidthLabel'].Enable()
  4504. self.update()
  4505. else:
  4506. self.effect['highlightColor'].Disable()
  4507. self.effect['highlightWidth'].Disable()
  4508. self.effect['highlightWidthLabel'].Disable()
  4509. def OnBorder(self, event):
  4510. if self.effect['borderCtrl'].GetValue():
  4511. self.effect['borderColor'].Enable()
  4512. self.effect['borderWidth'].Enable()
  4513. self.effect['borderWidthLabel'].Enable()
  4514. self.update()
  4515. else:
  4516. self.effect['borderColor'].Disable()
  4517. self.effect['borderWidth'].Disable()
  4518. self.effect['borderWidthLabel'].Disable()
  4519. def update(self):
  4520. #text
  4521. self.textDict['text'] = self.textCtrl.GetValue()
  4522. if not self.textDict['text']:
  4523. wx.MessageBox(_("No text entered!"), _("Error"))
  4524. return False
  4525. #font
  4526. self.textDict['font'] = self.textPanel.font['fontCtrl'].GetStringSelection()
  4527. self.textDict['fontsize'] = self.textPanel.font['fontSizeCtrl'].GetValue()
  4528. ## font = self.textPanel.font['fontCtrl'].GetSelectedFont()
  4529. ## self.textDict['font'] = font.GetFaceName()
  4530. ## self.textDict['fontsize'] = font.GetPointSize()
  4531. color = self.textPanel.font['colorCtrl'].GetColour()
  4532. ## if color.GetAsString(wx.C2S_NAME) in PSMAP_COLORS:
  4533. ## self.textDict['color'] = color.GetAsString(wx.C2S_NAME)
  4534. ## else:
  4535. self.textDict['color'] = convertRGB(color)
  4536. #effects
  4537. if self.effect['backgroundCtrl'].GetValue():
  4538. background = self.effect['backgroundColor'].GetColour()
  4539. self.textDict['background'] = convertRGB(background)
  4540. else:
  4541. self.textDict['background'] = 'none'
  4542. if self.effect['borderCtrl'].GetValue():
  4543. border = self.effect['borderColor'].GetColour()
  4544. self.textDict['border'] = convertRGB(border)
  4545. else:
  4546. self.textDict['border'] = 'none'
  4547. self.textDict['width'] = self.effect['borderWidth'].GetValue()
  4548. if self.effect['highlightCtrl'].GetValue():
  4549. highlight = self.effect['highlightColor'].GetColour()
  4550. self.textDict['hcolor'] = convertRGB(highlight)
  4551. else:
  4552. self.textDict['hcolor'] = 'none'
  4553. self.textDict['hwidth'] = self.effect['highlightWidth'].GetValue()
  4554. #offset
  4555. self.textDict['xoffset'] = self.xoffCtrl.GetValue()
  4556. self.textDict['yoffset'] = self.yoffCtrl.GetValue()
  4557. #position
  4558. if self.paperPositionCtrl.GetValue():
  4559. self.textDict['XY'] = True
  4560. currUnit = self.positionPanel.units['unitsCtrl'].GetStringSelection()
  4561. self.textDict['unit'] = currUnit
  4562. if self.positionPanel.position['xCtrl'].GetValue():
  4563. x = self.positionPanel.position['xCtrl'].GetValue()
  4564. else:
  4565. x = self.textDict['where'][0]
  4566. if self.positionPanel.position['yCtrl'].GetValue():
  4567. y = self.positionPanel.position['yCtrl'].GetValue()
  4568. else:
  4569. y = self.textDict['where'][1]
  4570. x = self.unitConv.convert(value = float(x), fromUnit = currUnit, toUnit = 'inch')
  4571. y = self.unitConv.convert(value = float(y), fromUnit = currUnit, toUnit = 'inch')
  4572. self.textDict['where'] = x, y
  4573. self.textDict['east'], self.textDict['north'] = PaperMapCoordinates(self.instruction[self.mapId], x, y, paperToMap = True)
  4574. else:
  4575. self.textDict['XY'] = False
  4576. if self.eastingCtrl.GetValue():
  4577. self.textDict['east'] = self.eastingCtrl.GetValue()
  4578. else:
  4579. self.textDict['east'] = self.textDict['east']
  4580. if self.northingCtrl.GetValue():
  4581. self.textDict['north'] = self.northingCtrl.GetValue()
  4582. else:
  4583. self.textDict['north'] = self.textDict['north']
  4584. self.textDict['where'] = PaperMapCoordinates(map = self.instruction[self.mapId], x = float(self.textDict['east']),
  4585. y = float(self.textDict['north']), paperToMap = False)
  4586. #rotation
  4587. if self.rotCtrl.GetValue():
  4588. self.textDict['rotate'] = self.rotValue.GetValue()
  4589. else:
  4590. self.textDict['rotate'] = None
  4591. #reference point
  4592. for radio in self.radio:
  4593. if radio.GetValue() == True:
  4594. self.textDict['ref'] = radio.GetName()
  4595. if self.id not in self.instruction:
  4596. text = Text(self.id)
  4597. self.instruction.AddInstruction(text)
  4598. self.instruction[self.id].SetInstruction(self.textDict)
  4599. if self.id not in self.parent.objectId:
  4600. self.parent.objectId.append(self.id)
  4601. return True
  4602. def updateDialog(self):
  4603. """!Update text coordinates, after moving"""
  4604. # XY coordinates
  4605. x, y = self.textDict['where'][:2]
  4606. currUnit = self.positionPanel.units['unitsCtrl'].GetStringSelection()
  4607. x = self.unitConv.convert(value = x, fromUnit = 'inch', toUnit = currUnit)
  4608. y = self.unitConv.convert(value = y, fromUnit = 'inch', toUnit = currUnit)
  4609. self.positionPanel.position['xCtrl'].SetValue("%5.3f" % x)
  4610. self.positionPanel.position['yCtrl'].SetValue("%5.3f" % y)
  4611. # EN coordinates
  4612. e, n = self.textDict['east'], self.textDict['north']
  4613. self.eastingCtrl.SetValue(str(self.textDict['east']))
  4614. self.northingCtrl.SetValue(str(self.textDict['north']))
  4615. def convertRGB(rgb):
  4616. """!Converts wx.Colour(r,g,b,a) to string 'r:g:b' or named color,
  4617. or named color/r:g:b string to wx.Colour, depending on input"""
  4618. # transform a wx.Colour tuple into an r:g:b string
  4619. if type(rgb) == wx.Colour:
  4620. for name, color in grass.named_colors.items():
  4621. if rgb.Red() == int(color[0] * 255) and\
  4622. rgb.Green() == int(color[1] * 255) and\
  4623. rgb.Blue() == int(color[2] * 255):
  4624. return name
  4625. return str(rgb.Red()) + ':' + str(rgb.Green()) + ':' + str(rgb.Blue())
  4626. # transform a GRASS named color or an r:g:b string into a wx.Colour tuple
  4627. else:
  4628. color = (grass.parse_color(rgb)[0]*255,
  4629. grass.parse_color(rgb)[1]*255,
  4630. grass.parse_color(rgb)[2]*255)
  4631. color = wx.Color(*color)
  4632. if color.IsOk():
  4633. return color
  4634. else:
  4635. return None
  4636. def PaperMapCoordinates(map, x, y, paperToMap = True):
  4637. """!Converts paper (inch) coordinates -> map coordinates"""
  4638. unitConv = UnitConversion()
  4639. currRegionDict = grass.region()
  4640. cornerEasting, cornerNorthing = currRegionDict['w'], currRegionDict['n']
  4641. xMap = map['rect'][0]
  4642. yMap = map['rect'][1]
  4643. widthMap = map['rect'][2] * 0.0254 # to meter
  4644. heightMap = map['rect'][3] * 0.0254
  4645. xScale = widthMap / abs(currRegionDict['w'] - currRegionDict['e'])
  4646. yScale = heightMap / abs(currRegionDict['n'] - currRegionDict['s'])
  4647. currScale = (xScale + yScale) / 2
  4648. if not paperToMap:
  4649. textEasting, textNorthing = x, y
  4650. eastingDiff = textEasting - cornerEasting
  4651. if currRegionDict['w'] > currRegionDict['e']:
  4652. eastingDiff = - eastingDiff
  4653. else:
  4654. eastingDiff = eastingDiff
  4655. northingDiff = textNorthing - cornerNorthing
  4656. if currRegionDict['n'] > currRegionDict['s']:
  4657. northingDiff = - northingDiff
  4658. else:
  4659. northingDiff = northingDiff
  4660. xPaper = xMap + unitConv.convert(value = eastingDiff, fromUnit = 'meter', toUnit = 'inch') * currScale
  4661. yPaper = yMap + unitConv.convert(value = northingDiff, fromUnit = 'meter', toUnit = 'inch') * currScale
  4662. return xPaper, yPaper
  4663. else:
  4664. if currRegionDict['w'] < currRegionDict['e']:
  4665. eastingDiff = (x - xMap)
  4666. else:
  4667. eastingDiff = (xMap - x)
  4668. if currRegionDict['n'] < currRegionDict['s']:
  4669. northingDiff = (y - yMap)
  4670. else:
  4671. northingDiff = (yMap - y)
  4672. textEasting = cornerEasting + unitConv.convert(value = eastingDiff, fromUnit = 'inch', toUnit = 'meter') / currScale
  4673. textNorthing = cornerNorthing + unitConv.convert(value = northingDiff, fromUnit = 'inch', toUnit = 'meter') / currScale
  4674. return int(textEasting), int(textNorthing)
  4675. def AutoAdjust(self, scaleType, rect, map = None, mapType = None, region = None):
  4676. """!Computes map scale, center and map frame rectangle to fit region (scale is not fixed)"""
  4677. currRegionDict = {}
  4678. if scaleType == 0 and map:# automatic, region from raster or vector
  4679. res = ''
  4680. if mapType == 'raster':
  4681. try:
  4682. res = grass.read_command("g.region", flags = 'gu', rast = map)
  4683. except grass.ScriptError:
  4684. pass
  4685. elif mapType == 'vector':
  4686. res = grass.read_command("g.region", flags = 'gu', vect = map)
  4687. currRegionDict = grass.parse_key_val(res, val_type = float)
  4688. elif scaleType == 1 and region: # saved region
  4689. res = grass.read_command("g.region", flags = 'gu', region = region)
  4690. currRegionDict = grass.parse_key_val(res, val_type = float)
  4691. elif scaleType == 2: # current region
  4692. env = grass.gisenv()
  4693. windFilePath = os.path.join(env['GISDBASE'], env['LOCATION_NAME'], env['MAPSET'], 'WIND')
  4694. try:
  4695. windFile = open(windFilePath, 'r').read()
  4696. except IOError:
  4697. currRegionDict = grass.region()
  4698. regionDict = grass.parse_key_val(windFile, sep = ':', val_type = float)
  4699. region = grass.read_command("g.region", flags = 'gu', n = regionDict['north'], s = regionDict['south'],
  4700. e = regionDict['east'], w = regionDict['west'])
  4701. currRegionDict = grass.parse_key_val(region, val_type = float)
  4702. else:
  4703. return None, None, None
  4704. if not currRegionDict:
  4705. return None, None, None
  4706. rX = rect.x
  4707. rY = rect.y
  4708. rW = rect.width
  4709. rH = rect.height
  4710. if not hasattr(self, 'unitConv'):
  4711. self.unitConv = UnitConversion(self)
  4712. toM = 1
  4713. if projInfo()['proj'] != 'xy':
  4714. toM = float(projInfo()['meters'])
  4715. mW = self.unitConv.convert(value = (currRegionDict['e'] - currRegionDict['w']) * toM, fromUnit = 'meter', toUnit = 'inch')
  4716. mH = self.unitConv.convert(value = (currRegionDict['n'] - currRegionDict['s']) * toM, fromUnit = 'meter', toUnit = 'inch')
  4717. scale = min(rW/mW, rH/mH)
  4718. if rW/rH > mW/mH:
  4719. x = rX - (rH*(mW/mH) - rW)/2
  4720. y = rY
  4721. rWNew = rH*(mW/mH)
  4722. rHNew = rH
  4723. else:
  4724. x = rX
  4725. y = rY - (rW*(mH/mW) - rH)/2
  4726. rHNew = rW*(mH/mW)
  4727. rWNew = rW
  4728. # center
  4729. cE = (currRegionDict['w'] + currRegionDict['e'])/2
  4730. cN = (currRegionDict['n'] + currRegionDict['s'])/2
  4731. return scale, (cE, cN), wx.Rect2D(x, y, rWNew, rHNew) #inch
  4732. def SetResolution(dpi, width, height):
  4733. """!If resolution is too high, lower it
  4734. @param dpi max DPI
  4735. @param width map frame width
  4736. @param height map frame height
  4737. """
  4738. region = grass.region()
  4739. if region['cols'] > width * dpi or region['rows'] > height * dpi:
  4740. rows = height * dpi
  4741. cols = width * dpi
  4742. RunCommand('g.region', rows = rows, cols = cols)
  4743. def ComputeSetRegion(self, mapDict):
  4744. """!Computes and sets region from current scale, map center coordinates and map rectangle"""
  4745. if mapDict['scaleType'] == 3: # fixed scale
  4746. scale = mapDict['scale']
  4747. if not hasattr(self, 'unitConv'):
  4748. self.unitConv = UnitConversion(self)
  4749. fromM = 1
  4750. if projInfo()['proj'] != 'xy':
  4751. fromM = float(projInfo()['meters'])
  4752. rectHalfInch = (mapDict['rect'].width/2, mapDict['rect'].height/2)
  4753. rectHalfMeter = (self.unitConv.convert(value = rectHalfInch[0], fromUnit = 'inch', toUnit = 'meter')/ fromM /scale,
  4754. self.unitConv.convert(value = rectHalfInch[1], fromUnit = 'inch', toUnit = 'meter')/ fromM /scale)
  4755. centerE = mapDict['center'][0]
  4756. centerN = mapDict['center'][1]
  4757. raster = self.instruction.FindInstructionByType('raster')
  4758. if raster:
  4759. rasterId = raster.id
  4760. else:
  4761. rasterId = None
  4762. if rasterId:
  4763. RunCommand('g.region', n = ceil(centerN + rectHalfMeter[1]),
  4764. s = floor(centerN - rectHalfMeter[1]),
  4765. e = ceil(centerE + rectHalfMeter[0]),
  4766. w = floor(centerE - rectHalfMeter[0]),
  4767. rast = self.instruction[rasterId]['raster'])
  4768. else:
  4769. RunCommand('g.region', n = ceil(centerN + rectHalfMeter[1]),
  4770. s = floor(centerN - rectHalfMeter[1]),
  4771. e = ceil(centerE + rectHalfMeter[0]),
  4772. w = floor(centerE - rectHalfMeter[0]))
  4773. def projInfo():
  4774. """!Return region projection and map units information,
  4775. taken from render.py"""
  4776. projinfo = dict()
  4777. ret = RunCommand('g.proj', read = True, flags = 'p')
  4778. if not ret:
  4779. return projinfo
  4780. for line in ret.splitlines():
  4781. if ':' in line:
  4782. key, val = line.split(':')
  4783. projinfo[key.strip()] = val.strip()
  4784. elif "XY location (unprojected)" in line:
  4785. projinfo['proj'] = 'xy'
  4786. projinfo['units'] = ''
  4787. break
  4788. return projinfo
  4789. def GetMapBounds(filename):
  4790. """!Run ps.map -b to get information about map bounding box"""
  4791. try:
  4792. bb = map(float, grass.read_command('ps.map',
  4793. flags = 'b',
  4794. quiet = True,
  4795. input = filename).strip().split('=')[1].split(','))
  4796. except (grass.ScriptError, IndexError):
  4797. GError(message = _("Unable to run `ps.map -b`"))
  4798. return None
  4799. return wx.Rect2D(bb[0], bb[3], bb[2] - bb[0], bb[1] - bb[3])
  4800. def getRasterType(map):
  4801. """!Returns type of raster map (CELL, FCELL, DCELL)"""
  4802. if map is None:
  4803. map = ''
  4804. file = grass.find_file(name = map, element = 'cell')
  4805. if file['file']:
  4806. rasterType = grass.raster_info(map)['datatype']
  4807. return rasterType
  4808. else:
  4809. return None