psmap_dialogs.py 266 KB

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