psmap_dialogs.py 269 KB

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