instructions.py 80 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812
  1. """!
  2. @package psmap.instructions
  3. @brief Map feature objects
  4. Classes:
  5. - dialogs::Instruction
  6. - dialogs::InstructionObject
  7. - dialogs::InitMap
  8. - dialogs::MapFrame
  9. - dialogs::PageSetup
  10. - dialogs::Mapinfo
  11. - dialogs::Text
  12. - dialogs::Image
  13. - dialogs::NorthArrow
  14. - dialogs::Point
  15. - dialogs::Line
  16. - dialogs::Rectangle
  17. - dialogs::Scalebar
  18. - dialogs::RasterLegend
  19. - dialogs::VectorLegend
  20. - dialogs::Raster
  21. - dialogs::Vector
  22. - dialogs::VProperties
  23. (C) 2011-2012 by Anna Kratochvilova, and the GRASS Development Team
  24. This program is free software under the GNU General Public License
  25. (>=v2). Read the file COPYING that comes with GRASS for details.
  26. @author Anna Kratochvilova <kratochanna gmail.com> (bachelor's project)
  27. @author Martin Landa <landa.martin gmail.com> (mentor)
  28. """
  29. import os
  30. import string
  31. from math import ceil
  32. from time import strftime, localtime
  33. import wx
  34. import grass.script as grass
  35. from core.gcmd import RunCommand, GError, GMessage, GWarning
  36. from core.utils import CmdToTuple, GetCmdString
  37. from dbmgr.vinfo import VectorDBInfo
  38. from psmap.utils import *
  39. class Instruction:
  40. """!Class which represents instruction file"""
  41. def __init__(self, parent, objectsToDraw):
  42. self.parent = parent
  43. self.objectsToDraw = objectsToDraw
  44. #here are kept objects like mapinfo, rasterlegend, etc.
  45. self.instruction = list()
  46. def __str__(self):
  47. """!Returns text for instruction file"""
  48. comment = "# timestamp: " + strftime("%Y-%m-%d %H:%M", localtime()) + '\n'
  49. env = grass.gisenv()
  50. comment += "# location: %s\n" % env['LOCATION_NAME']
  51. comment += "# mapset: %s\n" % env['MAPSET']
  52. comment += "# page orientation: %s\n" % self.FindInstructionByType('page')['Orientation']
  53. border = ''
  54. if not self.FindInstructionByType('map'):
  55. border = 'border n\n'
  56. text = [str(each) for each in self.instruction]
  57. return comment + border + '\n'.join(text) + '\nend'
  58. def __getitem__(self, id):
  59. for each in self.instruction:
  60. if each.id == id:
  61. return each
  62. return None
  63. def __contains__(self, id):
  64. """!Test if instruction is included"""
  65. for each in self.instruction:
  66. if each.id == id:
  67. return True
  68. return False
  69. def __delitem__(self, id):
  70. """!Delete instruction"""
  71. for each in self.instruction:
  72. if each.id == id:
  73. if each.type == 'map':
  74. #must remove raster, vector layers too
  75. vektor = self.FindInstructionByType('vector', list = True)
  76. vProperties = self.FindInstructionByType('vProperties', list = True)
  77. raster = self.FindInstructionByType('raster', list = True)
  78. for item in vektor + vProperties + raster:
  79. if item in self.instruction:
  80. self.instruction.remove(item)
  81. self.instruction.remove(each)
  82. if id in self.objectsToDraw:
  83. self.objectsToDraw.remove(id)
  84. return
  85. def AddInstruction(self, instruction):
  86. """!Add instruction"""
  87. # add to instructions
  88. if instruction.type == 'map':
  89. self.instruction.insert(0, instruction)
  90. else:
  91. self.instruction.append(instruction)
  92. # add to drawable objects
  93. if instruction.type not in ('page', 'raster', 'vector', 'vProperties', 'initMap'):
  94. if instruction.type == 'map':
  95. self.objectsToDraw.insert(0, instruction.id)
  96. else:
  97. self.objectsToDraw.append(instruction.id)
  98. def FindInstructionByType(self, type, list = False):
  99. """!Find instruction(s) with the given type"""
  100. inst = []
  101. for each in self.instruction:
  102. if each.type == type:
  103. inst.append(each)
  104. if len(inst) == 1 and not list:
  105. return inst[0]
  106. return inst
  107. def Read(self, filename):
  108. """!Reads instruction file and creates instruction objects"""
  109. self.filename = filename
  110. # open file
  111. try:
  112. file = open(filename, 'r')
  113. except IOError:
  114. GError(message = _("Unable to open file\n%s") % filename)
  115. return
  116. # first read file to get information about region and scaletype
  117. isRegionComment = False
  118. orientation = 'Portrait'
  119. for line in file:
  120. if '# g.region' in line:
  121. self.SetRegion(regionInstruction = line)
  122. isRegionComment = True
  123. break
  124. if '# page orientation' in line:
  125. orientation = line.split(':')[-1].strip()
  126. if not isRegionComment:
  127. self.SetRegion(regionInstruction = None)
  128. # then run ps.map -b to get information for maploc
  129. # compute scale and center
  130. map = self.FindInstructionByType('map')
  131. region = grass.region()
  132. map['center'] = (region['n'] + region['s']) / 2, (region['w'] + region['e']) / 2
  133. mapRect = GetMapBounds(self.filename, portrait = (orientation == 'Portrait'))
  134. map['rect'] = mapRect
  135. proj = projInfo()
  136. toM = 1.0
  137. if proj['units']:
  138. toM = float(proj['meters'])
  139. units = UnitConversion(self.parent)
  140. w = units.convert(value = mapRect.Get()[2], fromUnit = 'inch', toUnit = 'meter') / toM
  141. map['scale'] = w / abs((region['w'] - region['e']))
  142. SetResolution(dpi = 300, width = map['rect'].width, height = map['rect'].height)
  143. # read file again, now with information about map bounds
  144. isBuffer = False
  145. buffer = []
  146. instruction = None
  147. vectorMapNumber = 1
  148. file.seek(0)
  149. for line in file:
  150. if not line.strip():
  151. continue
  152. line = line.strip()
  153. if isBuffer:
  154. buffer.append(line)
  155. if 'end' in line:
  156. isBuffer = False
  157. kwargs = {}
  158. if instruction == 'scalebar':
  159. kwargs['scale'] = map['scale']
  160. elif instruction in ('text', 'eps', 'point', 'line', 'rectangle'):
  161. kwargs['mapInstruction'] = map
  162. elif instruction in ('vpoints', 'vlines', 'vareas'):
  163. kwargs['id'] = wx.NewId()
  164. kwargs['vectorMapNumber'] = vectorMapNumber
  165. vectorMapNumber += 1
  166. elif instruction == 'paper':
  167. kwargs['Orientation'] = orientation
  168. ok = self.SendToRead(instruction, buffer, **kwargs)
  169. if not ok: return False
  170. buffer = []
  171. continue
  172. elif line.startswith('paper'):
  173. instruction = 'paper'
  174. isBuffer = True
  175. buffer.append(line)
  176. elif line.startswith('border'):
  177. if line.split()[1].lower() in ('n', 'no', 'none'):
  178. ok = self.SendToRead('border', [line])
  179. if not ok: return False
  180. elif line.split()[1].lower() in ('y', 'yes'):
  181. instruction = 'border'
  182. isBuffer = True
  183. buffer.append(line)
  184. elif line.startswith('scale '):
  185. if isBuffer:
  186. continue
  187. ok = self.SendToRead('scale', line, isRegionComment = isRegionComment)
  188. if not ok: return False
  189. elif line.startswith('maploc'):
  190. ok = self.SendToRead(instruction = 'maploc', text = line)
  191. if not ok: return False
  192. elif line.startswith('raster'):
  193. ok = self.SendToRead(instruction = 'raster', text = line)
  194. if not ok: return False
  195. elif line.startswith('mapinfo'):
  196. instruction = 'mapinfo'
  197. isBuffer = True
  198. buffer.append(line)
  199. elif line.startswith('scalebar'):
  200. instruction = 'scalebar'
  201. isBuffer = True
  202. buffer.append(line)
  203. elif line.startswith('text'):
  204. instruction = 'text'
  205. isBuffer = True
  206. buffer.append(line)
  207. elif line.startswith('eps'):
  208. instruction = 'eps'
  209. isBuffer = True
  210. buffer.append(line)
  211. elif line.startswith('point'):
  212. instruction = 'point'
  213. isBuffer = True
  214. buffer.append(line)
  215. elif line.startswith('line'):
  216. instruction = 'line'
  217. isBuffer = True
  218. buffer.append(line)
  219. elif line.startswith('rectangle'):
  220. instruction = 'rectangle'
  221. isBuffer = True
  222. buffer.append(line)
  223. elif line.startswith('colortable'):
  224. if len(line.split()) == 2 and line.split()[1].lower() in ('n', 'no', 'none'):
  225. break
  226. instruction = 'colortable'
  227. isBuffer = True
  228. buffer.append(line)
  229. elif line.startswith('vlegend'):
  230. instruction = 'vlegend'
  231. isBuffer = True
  232. buffer.append(line)
  233. elif line.startswith('vpoints'):
  234. instruction = 'vpoints'
  235. isBuffer = True
  236. buffer.append(line)
  237. elif line.startswith('vlines'):
  238. instruction = 'vlines'
  239. isBuffer = True
  240. buffer.append(line)
  241. elif line.startswith('vareas'):
  242. instruction = 'vareas'
  243. isBuffer = True
  244. buffer.append(line)
  245. rasterLegend = self.FindInstructionByType('rasterLegend')
  246. raster = self.FindInstructionByType('raster')
  247. page = self.FindInstructionByType('page')
  248. vector = self.FindInstructionByType('vector')
  249. vectorLegend = self.FindInstructionByType('vectorLegend')
  250. vectorMaps = self.FindInstructionByType('vProperties', list = True)
  251. # check (in case of scaletype 0) if map is drawn also
  252. map['drawMap'] = False
  253. if map['scaleType'] == 0:
  254. mapForRegion = map['map']
  255. if map['mapType'] == 'raster' and raster:
  256. if mapForRegion == raster['raster']:
  257. map['drawMap'] = True
  258. elif map['mapType'] == 'vector' and vector:
  259. for vmap in vector['list']:
  260. if mapForRegion == vmap[0]:
  261. map['drawMap'] = True
  262. # rasterLegend
  263. if rasterLegend:
  264. if rasterLegend['rasterDefault'] and raster:
  265. rasterLegend['raster'] = raster['raster']
  266. if not rasterLegend['discrete']:
  267. rasterType = getRasterType(map = rasterLegend['raster'])
  268. if rasterType == 'CELL':
  269. rasterLegend['discrete'] = 'y'
  270. else:
  271. rasterLegend['discrete'] = 'n'
  272. #estimate size
  273. height = rasterLegend.EstimateHeight(raster = rasterLegend['raster'], discrete = rasterLegend['discrete'],
  274. fontsize = rasterLegend['fontsize'],
  275. cols = rasterLegend['cols'],
  276. height = rasterLegend['height'])
  277. width = rasterLegend.EstimateWidth(raster = rasterLegend['raster'], discrete = rasterLegend['discrete'],
  278. fontsize = rasterLegend['fontsize'],
  279. cols = rasterLegend['cols'] ,
  280. width = rasterLegend['width'],
  281. paperInstr = page)
  282. rasterLegend['rect'] = Rect2D(x = float(rasterLegend['where'][0]), y = float(rasterLegend['where'][1]),
  283. width = width, height = height)
  284. # vectors, vlegend
  285. if vector:
  286. for vmap in vectorMaps:
  287. for i, each in enumerate(vector['list']):
  288. if each[2] == vmap.id:
  289. vector['list'][i][4] = vmap['label']
  290. vector['list'][i][3] = vmap['lpos']
  291. if vectorLegend:
  292. size = vectorLegend.EstimateSize(vectorInstr = vector, fontsize = vectorLegend['fontsize'],
  293. width = vectorLegend['width'], cols = vectorLegend['cols'])
  294. vectorLegend['rect'] = Rect2D(x = float(vectorLegend['where'][0]), y = float(vectorLegend['where'][1]),
  295. width = size[0], height = size[1])
  296. page = self.FindInstructionByType('page')
  297. if not page:
  298. page = PageSetup(wx.NewId())
  299. self.AddInstruction(page)
  300. else:
  301. page['Orientation'] = orientation
  302. #
  303. return True
  304. def SendToRead(self, instruction, text, **kwargs):
  305. psmapInstrDict = dict(paper = ['page'],
  306. maploc = ['map'],
  307. scale = ['map'],
  308. border = ['map'],
  309. raster = ['raster'],
  310. mapinfo = ['mapinfo'],
  311. scalebar = ['scalebar'],
  312. text = ['text'],
  313. eps = ['image', 'northArrow'],
  314. point = ['point'],
  315. line = ['line'],
  316. rectangle = ['rectangle'],
  317. vpoints = ['vector', 'vProperties'],
  318. vlines = ['vector', 'vProperties'],
  319. vareas = ['vector', 'vProperties'],
  320. colortable = ['rasterLegend'],
  321. vlegend = ['vectorLegend']
  322. )
  323. myInstrDict = dict(page = PageSetup,
  324. map = MapFrame,
  325. raster = Raster,
  326. mapinfo = Mapinfo,
  327. scalebar = Scalebar,
  328. text = Text,
  329. image = Image,
  330. northArrow = NorthArrow,
  331. point = Point,
  332. line = Line,
  333. rectangle = Rectangle,
  334. rasterLegend = RasterLegend,
  335. vectorLegend = VectorLegend,
  336. vector = Vector,
  337. vProperties = VProperties
  338. )
  339. myInstruction = psmapInstrDict[instruction]
  340. for i in myInstruction:
  341. instr = self.FindInstructionByType(i)
  342. if i in ('text', 'vProperties', 'image', 'northArrow', 'point', 'line', 'rectangle') or not instr:
  343. id = wx.NewId() #!vProperties expect subtype
  344. if i == 'vProperties':
  345. id = kwargs['id']
  346. newInstr = myInstrDict[i](id, subType = instruction[1:])
  347. elif i in ('image', 'northArrow'):
  348. commentFound = False
  349. for line in text:
  350. if line.find("# north arrow") >= 0:
  351. commentFound = True
  352. if i == 'image' and commentFound or \
  353. i == 'northArrow' and not commentFound:
  354. continue
  355. newInstr = myInstrDict[i](id, settings = self)
  356. else:
  357. newInstr = myInstrDict[i](id)
  358. ok = newInstr.Read(instruction, text, **kwargs)
  359. if ok:
  360. self.AddInstruction(newInstr)
  361. else:
  362. return False
  363. else:
  364. ok = instr.Read(instruction, text, **kwargs)
  365. if not ok:
  366. return False
  367. return True
  368. def SetRegion(self, regionInstruction):
  369. """!Sets region from file comment or sets current region in case of no comment"""
  370. map = MapFrame(wx.NewId())
  371. self.AddInstruction(map)
  372. if regionInstruction:
  373. cmd = CmdToTuple(regionInstruction.strip('# ').split())
  374. # define scaleType
  375. if len(cmd[1]) <= 3:
  376. if 'rast' in cmd[1]:
  377. map['scaleType'] = 0
  378. map['mapType'] = 'raster'
  379. map['map'] = cmd[1]['rast']
  380. elif 'vect' in cmd[1]:
  381. map['scaleType'] = 0
  382. map['mapType'] = 'vector'
  383. map['map'] = cmd[1]['vect']
  384. elif 'region' in cmd[1]:
  385. map['scaleType'] = 1
  386. map['region'] = cmd[1]['region']
  387. else:
  388. map['scaleType'] = 2
  389. else:
  390. map['scaleType'] = 2
  391. grass.del_temp_region()
  392. region = grass.region()
  393. grass.use_temp_region()
  394. cmd = ['g.region', region]
  395. cmdString = GetCmdString(cmd).replace('g.region', '')
  396. GMessage(_("Instruction file will be loaded with following region: %s\n") % cmdString)
  397. try:
  398. RunCommand(cmd[0], **cmd[1])
  399. except grass.ScriptError, e:
  400. GError(_("Region cannot be set\n%s") % e)
  401. return False
  402. class InstructionObject:
  403. """!Abtract class representing single instruction"""
  404. def __init__(self, id):
  405. self.id = id
  406. # default values
  407. self.defaultInstruction = dict()
  408. # current values
  409. self.instruction = self.defaultInstruction
  410. # converting units
  411. self.unitConv = UnitConversion()
  412. def __str__(self):
  413. """!Returns particular part of text instruction"""
  414. return ''
  415. def __getitem__(self, key):
  416. for each in self.instruction.keys():
  417. if each == key:
  418. return self.instruction[key]
  419. return None
  420. def __setitem__(self, key, value):
  421. self.instruction[key] = value
  422. def GetInstruction(self):
  423. """!Get current values"""
  424. return self.instruction
  425. def SetInstruction(self, instruction):
  426. """!Set default values"""
  427. self.instruction = instruction
  428. def Read(self, instruction, text, **kwargs):
  429. """!Read instruction and save them"""
  430. pass
  431. def PercentToReal(self, e, n):
  432. """!Converts text coordinates from percent of region to map coordinates"""
  433. e, n = float(e.strip('%')), float(n.strip('%'))
  434. region = grass.region()
  435. N = region['s'] + (region['n'] - region['s']) / 100 * n
  436. E = region['w'] + (region['e'] - region['w']) / 100 * e
  437. return E, N
  438. class InitMap(InstructionObject):
  439. """!Class representing virtual map"""
  440. def __init__(self, id):
  441. InstructionObject.__init__(self, id = id)
  442. self.type = 'initMap'
  443. # default values
  444. self.defaultInstruction = dict(rect = None, scale = None)
  445. # current values
  446. self.instruction = dict(self.defaultInstruction)
  447. class MapFrame(InstructionObject):
  448. """!Class representing map (instructions maploc, scale, border)"""
  449. def __init__(self, id):
  450. InstructionObject.__init__(self, id = id)
  451. self.type = 'map'
  452. # default values
  453. self.defaultInstruction = dict(map = None, mapType = None, drawMap = True, region = None,
  454. rect = Rect2D(), scaleType = 0, scale = None, center = None,
  455. resolution = 300, border = 'y', width = 1, color = '0:0:0')
  456. # current values
  457. self.instruction = dict(self.defaultInstruction)
  458. def __str__(self):
  459. instr = ''
  460. comment = ''
  461. #region settings
  462. region = grass.region()
  463. if self.instruction['scaleType'] == 0: #match map
  464. map = self.instruction['map']
  465. if self.instruction['mapType'] == 'raster':
  466. comment = "# g.region rast=%s nsres=%s ewres=%s\n" % (map, region['nsres'], region['ewres'])
  467. else:
  468. comment = "# g.region vect=%s\n" % (map)
  469. elif self.instruction['scaleType'] == 1:# saved region
  470. region = self.instruction['region']
  471. comment = "# g.region region=%s\n" % region
  472. elif self.instruction['scaleType'] in (2, 3): #current region, fixed scale
  473. comment = string.Template("# g.region n=$n s=$s e=$e w=$w rows=$rows cols=$cols \n").substitute(**region)
  474. instr += comment
  475. instr += '\n'
  476. # maploc
  477. maplocInstruction = "maploc %.3f %.3f" % (self.instruction['rect'].x, self.instruction['rect'].y)
  478. if self.instruction['scaleType'] != 3:
  479. maplocInstruction += " %.3f %.3f"% (self.instruction['rect'].width, self.instruction['rect'].height)
  480. instr += maplocInstruction
  481. instr += '\n'
  482. # scale
  483. if self.instruction['scaleType'] == 3: #fixed scale
  484. scaleInstruction = "scale 1:%.0f" % (1/self.instruction['scale'])
  485. instr += scaleInstruction
  486. instr += '\n'
  487. # border
  488. borderInstruction = ''
  489. if self.instruction['border'] == 'n':
  490. borderInstruction = "border n"
  491. else:
  492. borderInstruction = "border y\n"
  493. borderInstruction += string.Template(" width $width\n color $color\n").substitute(self.instruction)
  494. borderInstruction += " end"
  495. instr += borderInstruction
  496. instr += '\n'
  497. return instr
  498. def Read(self, instruction, text, **kwargs):
  499. """!Read instruction and save information"""
  500. if 'isRegionComment' in kwargs:
  501. isRegionComment = kwargs['isRegionComment']
  502. instr = {}
  503. if instruction == 'border':
  504. for line in text:
  505. if line.startswith('end'):
  506. break
  507. try:
  508. if line.split()[1].lower() in ('n', 'no', 'none'):
  509. instr['border'] = 'n'
  510. break
  511. elif line.split()[1].lower() in ('y', 'yes'):
  512. instr['border'] = 'y'
  513. elif line.startswith('width'):
  514. instr['width'] = line.split()[1]
  515. elif line.startswith('color'):
  516. instr['color'] = line.split()[1]
  517. except IndexError:
  518. GError(_("Failed to read instruction %s") % instruction)
  519. return False
  520. elif instruction == 'scale':
  521. try:
  522. scaleText = text.strip('scale ').split(':')[1]
  523. # when scale instruction given and region comment also, then scaletype is fixed scale
  524. if not isRegionComment:
  525. instr['scaleType'] = 2
  526. else:
  527. instr['scaleType'] = 3
  528. scale = 1/float(scaleText)
  529. if abs(scale - self.instruction['scale']) > (0.01 * scale):
  530. GWarning(_("Scale has changed, old value: %(old)s\nnew value: %(new)s") % \
  531. { 'old' : scale, 'new' : self.instruction['scale'] })
  532. except (ValueError, IndexError):
  533. GError(_("Failed to read instruction %s.\nUse 1:25000 notation.") % instruction)
  534. return False
  535. elif instruction == 'maploc':
  536. maploc = text.strip('maploc ').split()
  537. if len(maploc) >= 2:
  538. if abs(self.instruction['rect'].Get()[0] - float(maploc[0])) > 0.5 or \
  539. abs(self.instruction['rect'].Get()[1] - float(maploc[1])) > 0.5:
  540. GWarning(_("Map frame position changed, old value: %(old1)s %(old2)s\nnew value: %(new1)s %(new2)s") % \
  541. { 'old1' : maploc[0], 'old2' : maploc[1],
  542. 'new1' : self.instruction['rect'].Get()[0], 'new2' : self.instruction['rect'].Get()[1] })
  543. #instr['rect'] = wx.Rect2D(float(maploc[0]), float(maploc[1]), self.instruction['rect'][2], self.instruction['rect'][3])
  544. if len(maploc) == 4:
  545. if abs(self.instruction['rect'].Get()[2] - float(maploc[2])) > 0.5 or \
  546. abs(self.instruction['rect'].Get()[3] - float(maploc[3])) > 0.5:
  547. GWarning(_("Map frame size changed, old value: %(old1)s %(old2)s\nnew value: %(new1)s %(new2)s") % \
  548. { 'old1' : maploc[2], 'old2' : maploc[3],
  549. 'new1' : self.instruction['rect'].Get()[2], 'new2' : self.instruction['rect'].Get()[3] })
  550. #instr['rect'] = wx.Rect2D(*map(float, maploc))
  551. self.instruction.update(instr)
  552. return True
  553. class PageSetup(InstructionObject):
  554. """!Class representing page instruction"""
  555. def __init__(self, id):
  556. InstructionObject.__init__(self, id = id)
  557. self.type = 'page'
  558. # default values
  559. self.defaultInstruction = dict(Units = 'inch', Format = 'a4', Orientation = 'Portrait',
  560. Width = 8.268, Height = 11.693, Left = 0.5, Right = 0.5, Top = 1, Bottom = 1)
  561. # current values
  562. self.instruction = dict(self.defaultInstruction)
  563. def __str__(self):
  564. if self.instruction['Format'] == 'custom':
  565. instr = string.Template("paper\n width $Width\n height $Height\n").substitute(self.instruction)
  566. else:
  567. instr = string.Template("paper $Format\n").substitute(self.instruction)
  568. instr += string.Template(" left $Left\n right $Right\n bottom $Bottom\n top $Top\n end").substitute(self.instruction)
  569. return instr
  570. def Read(self, instruction, text, **kwargs):
  571. """!Read instruction and save information"""
  572. instr = {}
  573. self.cats = ['Width', 'Height', 'Left', 'Right', 'Top', 'Bottom']
  574. self.subInstr = dict(zip(['width', 'height', 'left', 'right', 'top', 'bottom'], self.cats))
  575. if instruction == 'paper': # just for sure
  576. for line in text:
  577. if line.startswith('paper'):
  578. if len(line.split()) > 1:
  579. pformat = line.split()[1]
  580. availableFormats = self._toDict(grass.read_command('ps.map', flags = 'p',
  581. quiet = True))
  582. # e.g. paper a3
  583. try:
  584. instr['Format'] = pformat
  585. for key, value in availableFormats[pformat].iteritems():
  586. instr[key] = float(value)
  587. break
  588. except KeyError:
  589. GError(_("Failed to read instruction %(file)s.\nUnknown format %(for)s") % \
  590. { 'file' : instruction, 'for' : format })
  591. return False
  592. else:
  593. # paper
  594. # width ...
  595. instr['Format'] = 'custom'
  596. # read subinstructions
  597. elif instr['Format'] == 'custom' and not line.startswith('end'):
  598. text = line.split()
  599. try:
  600. instr[self.subInstr[text[0]]] = float(text[1])
  601. except (IndexError, KeyError):
  602. GError(_("Failed to read instruction %s.") % instruction)
  603. return False
  604. if 'Orientation' in kwargs and kwargs['Orientation'] == 'Landscape':
  605. instr['Width'], instr['Height'] = instr['Height'], instr['Width']
  606. self.instruction.update(instr)
  607. return True
  608. def _toDict(self, paperStr):
  609. sizeDict = dict()
  610. # cats = self.subInstr[ 'Width', 'Height', 'Left', 'Right', 'Top', 'Bottom']
  611. for line in paperStr.strip().split('\n'):
  612. d = dict(zip(self.cats, line.split()[1:]))
  613. sizeDict[line.split()[0]] = d
  614. return sizeDict
  615. class Mapinfo(InstructionObject):
  616. """!Class representing mapinfo instruction"""
  617. def __init__(self, id):
  618. InstructionObject.__init__(self, id = id)
  619. self.type = 'mapinfo'
  620. # default values
  621. self.defaultInstruction = dict(unit = 'inch', where = (0, 0),
  622. font = 'Helvetica', fontsize = 10, color = '0:0:0', background = 'none',
  623. border = 'none', rect = None)
  624. # current values
  625. self.instruction = dict(self.defaultInstruction)
  626. def __str__(self):
  627. instr = "mapinfo\n"
  628. instr += " where %.3f %.3f\n" % (self.instruction['where'][0], self.instruction['where'][1])
  629. instr += string.Template(" font $font\n fontsize $fontsize\n color $color\n").substitute(self.instruction)
  630. instr += string.Template(" background $background\n border $border\n").substitute(self.instruction)
  631. instr += " end"
  632. return instr
  633. def Read(self, instruction, text):
  634. """!Read instruction and save information"""
  635. instr = {}
  636. try:
  637. for line in text:
  638. sub = line.split(None,1)
  639. if sub[0] == 'font':
  640. instr['font'] = sub[1]
  641. elif sub[0] == 'fontsize':
  642. instr['fontsize'] = int(sub[1])
  643. elif sub[0] == 'color':
  644. instr['color'] = sub[1]
  645. elif sub[0] == 'background':
  646. instr['background'] = sub[1]
  647. elif sub[0] == 'border':
  648. instr['border'] = sub[1]
  649. elif sub[0] == 'where':
  650. instr['where'] = float(sub[1].split()[0]), float(sub[1].split()[1])
  651. except (ValueError, IndexError):
  652. GError(_("Failed to read instruction %s") % instruction)
  653. return False
  654. self.instruction.update(instr)
  655. self.instruction['rect'] = self.EstimateRect(mapinfoDict = self.instruction)
  656. return True
  657. def EstimateRect(self, mapinfoDict):
  658. """!Estimate size to draw mapinfo"""
  659. w = mapinfoDict['fontsize'] * 20 # any better estimation?
  660. h = mapinfoDict['fontsize'] * 7
  661. width = self.unitConv.convert(value = w, fromUnit = 'point', toUnit = 'inch')
  662. height = self.unitConv.convert(value = h, fromUnit = 'point', toUnit = 'inch')
  663. return Rect2D(x = float(mapinfoDict['where'][0]), y = float(mapinfoDict['where'][1]),
  664. width = width, height = height)
  665. class Text(InstructionObject):
  666. """!Class representing text instruction"""
  667. def __init__(self, id):
  668. InstructionObject.__init__(self, id = id)
  669. self.type = 'text'
  670. # default values
  671. self.defaultInstruction = dict(text = "", font = "Helvetica", fontsize = 10, color = 'black', background = 'none',
  672. hcolor = 'none', hwidth = 1, border = 'none', width = '1', XY = True,
  673. where = (0,0), unit = 'inch', rotate = None,
  674. ref = "center center", xoffset = 0, yoffset = 0, east = None, north = None)
  675. # current values
  676. self.instruction = dict(self.defaultInstruction)
  677. def __str__(self):
  678. text = self.instruction['text'].replace('\n','\\n')
  679. instr = u"text %s %s" % (self.instruction['east'], self.instruction['north'])
  680. instr += " %s\n" % text
  681. instr += (string.Template(" font $font\n fontsize $fontsize\n color $color\n").
  682. substitute(self.instruction))
  683. instr += string.Template(" hcolor $hcolor\n").substitute(self.instruction)
  684. if self.instruction['hcolor'] != 'none':
  685. instr += string.Template(" hwidth $hwidth\n").substitute(self.instruction)
  686. instr += string.Template(" border $border\n").substitute(self.instruction)
  687. if self.instruction['border'] != 'none':
  688. instr += string.Template(" width $width\n").substitute(self.instruction)
  689. instr += string.Template(" background $background\n").substitute(self.instruction)
  690. if self.instruction["ref"] != '0':
  691. instr += string.Template(" ref $ref\n").substitute(self.instruction)
  692. if self.instruction["rotate"]:
  693. instr += string.Template(" rotate $rotate\n").substitute(self.instruction)
  694. if float(self.instruction["xoffset"]) or float(self.instruction["yoffset"]):
  695. instr += (string.Template(" xoffset $xoffset\n yoffset $yoffset\n").
  696. substitute(self.instruction))
  697. instr += " end"
  698. try:
  699. instr = instr.encode('latin1')
  700. except UnicodeEncodeError, err:
  701. try:
  702. pos = str(err).split('position')[1].split(':')[0].strip()
  703. except IndexError:
  704. pos = ''
  705. if pos:
  706. message = _("Characters on position %s are not supported "
  707. "by ISO-8859-1 (Latin 1) encoding "
  708. "which is required by module ps.map.") % pos
  709. else:
  710. message = _("Not all characters are supported "
  711. "by ISO-8859-1 (Latin 1) encoding "
  712. "which is required by module ps.map.")
  713. GMessage(message = message)
  714. return ''
  715. return instr
  716. def Read(self, instruction, text, **kwargs):
  717. """!Read instruction and save information"""
  718. map = kwargs['mapInstruction']
  719. instr = {}
  720. for line in text:
  721. try:
  722. sub = line.split(None, 1)[0]
  723. if sub == 'text':
  724. e, n = line.split(None, 3)[1:3]
  725. if '%' in e and '%' in n:
  726. instr['XY'] = True
  727. instr['east'], instr['north'] = self.PercentToReal(e, n)
  728. else:
  729. instr['XY'] = False
  730. instr['east'], instr['north'] = float(e), float(n)
  731. instr['text'] = line.split(None, 3)[3].decode('latin_1')
  732. elif sub == 'font':
  733. instr['font'] = line.split(None, 1)[1]
  734. elif sub == 'fontsize':
  735. instr['fontsize'] = float(line.split(None, 1)[1])
  736. elif sub == 'color':
  737. instr['color'] = line.split(None, 1)[1]
  738. elif sub == 'width':
  739. instr['width'] = line.split(None, 1)[1]
  740. elif sub == 'hcolor':
  741. instr['hcolor'] = line.split(None, 1)[1]
  742. elif sub == 'hwidth':
  743. instr['hwidth'] = line.split(None, 1)[1]
  744. elif sub == 'background':
  745. instr['background'] = line.split(None, 1)[1]
  746. elif sub == 'border':
  747. instr['border'] = line.split(None, 1)[1]
  748. elif sub == 'ref':
  749. instr['ref'] = line.split(None, 1)[1]
  750. elif sub == 'rotate':
  751. instr['rotate'] = float(line.split(None, 1)[1])
  752. elif sub == 'xoffset':
  753. instr['xoffset'] = int(line.split(None, 1)[1])
  754. elif sub == 'yoffset':
  755. instr['yoffset'] = int(line.split(None, 1)[1])
  756. elif sub == 'opaque':
  757. if line.split(None, 1)[1].lower() in ('n', 'none'):
  758. instr['background'] = 'none'
  759. except(IndexError, ValueError):
  760. GError(_("Failed to read instruction %s") % instruction)
  761. return False
  762. instr['where'] = PaperMapCoordinates(mapInstr = map, x = instr['east'], y = instr['north'], paperToMap = False)
  763. self.instruction.update(instr)
  764. return True
  765. class Image(InstructionObject):
  766. """!Class representing eps instruction - image"""
  767. def __init__(self, id, settings):
  768. InstructionObject.__init__(self, id = id)
  769. self.settings = settings
  770. self.type = 'image'
  771. # default values
  772. self.defaultInstruction = dict(epsfile = "", XY = True, where = (0,0), unit = 'inch',
  773. east = None, north = None,
  774. rotate = None, scale = 1)
  775. # current values
  776. self.instruction = dict(self.defaultInstruction)
  777. def __str__(self):
  778. self.ChangeRefPoint(toCenter = True)
  779. instr = "eps %s %s\n" % (self.instruction['east'], self.instruction['north'])
  780. instr += string.Template(" epsfile $epsfile\n").substitute(self.instruction)
  781. if self.instruction["rotate"]:
  782. instr += string.Template(" rotate $rotate\n").substitute(self.instruction)
  783. if self.instruction["scale"]:
  784. instr += string.Template(" scale $scale\n").substitute(self.instruction)
  785. instr += " end"
  786. return instr
  787. def Read(self, instruction, text, **kwargs):
  788. """!Read instruction and save information"""
  789. mapInstr = kwargs['mapInstruction']
  790. instr = {}
  791. for line in text:
  792. try:
  793. sub = line.split(None, 1)[0]
  794. if sub == 'eps':
  795. e, n = line.split(None, 3)[1:3]
  796. if '%' in e and '%' in n:
  797. instr['XY'] = True
  798. instr['east'], instr['north'] = self.PercentToReal(e, n)
  799. else:
  800. instr['XY'] = False
  801. instr['east'], instr['north'] = float(e), float(n)
  802. elif sub == 'epsfile':
  803. instr['epsfile'] = line.split(None, 1)[1]
  804. elif sub == 'rotate':
  805. instr['rotate'] = float(line.split(None, 1)[1])
  806. elif sub == 'scale':
  807. instr['scale'] = float(line.split(None, 1)[1])
  808. except(IndexError, ValueError):
  809. GError(_("Failed to read instruction %s") % instruction)
  810. return False
  811. if not os.path.exists(instr['epsfile']):
  812. GError(_("Failed to read instruction %(inst)s: "
  813. "file %(file)s not found.") % { 'inst' : instruction,
  814. 'file' : instr['epsfile'] })
  815. return False
  816. instr['epsfile'] = os.path.abspath(instr['epsfile'])
  817. instr['size'] = self.GetImageOrigSize(instr['epsfile'])
  818. if 'rotate' in instr:
  819. instr['size'] = BBoxAfterRotation(instr['size'][0], instr['size'][1], instr['rotate'])
  820. self.instruction.update(instr)
  821. self.ChangeRefPoint(toCenter = False)
  822. instr['where'] = PaperMapCoordinates(mapInstr = mapInstr, x = self.instruction['east'],
  823. y = self.instruction['north'], paperToMap = False)
  824. w = self.unitConv.convert(value = instr['size'][0], fromUnit = 'point', toUnit = 'inch')
  825. h = self.unitConv.convert(value = instr['size'][1], fromUnit = 'point', toUnit = 'inch')
  826. instr['rect'] = Rect2D(x = float(instr['where'][0]), y = float(instr['where'][1]),
  827. width = w * self.instruction['scale'], height = h * self.instruction['scale'])
  828. self.instruction.update(instr)
  829. return True
  830. def ChangeRefPoint(self, toCenter):
  831. """!Change reference point (left top x center)"""
  832. mapInstr = self.settings.FindInstructionByType('map')
  833. if not mapInstr:
  834. mapInstr = self.settings.FindInstructionByType('initMap')
  835. mapId = mapInstr.id
  836. if toCenter:
  837. center = self.instruction['rect'].GetCentre()
  838. ENCenter = PaperMapCoordinates(mapInstr = self.settings[mapId],
  839. x = center[0], y = center[1], paperToMap = True)
  840. self.instruction['east'], self.instruction['north'] = ENCenter
  841. else:
  842. x, y = PaperMapCoordinates(mapInstr = self.settings[mapId], x = self.instruction['east'],
  843. y = self.instruction['north'], paperToMap = False)
  844. w = self.unitConv.convert(value = self.instruction['size'][0], fromUnit = 'point', toUnit = 'inch')
  845. h = self.unitConv.convert(value = self.instruction['size'][1], fromUnit = 'point', toUnit = 'inch')
  846. x -= w * self.instruction['scale'] / 2
  847. y -= h * self.instruction['scale'] / 2
  848. e, n = PaperMapCoordinates(mapInstr = self.settings[mapId], x = x, y = y, paperToMap = True)
  849. self.instruction['east'], self.instruction['north'] = e, n
  850. def GetImageOrigSize(self, imagePath):
  851. """!Get image size.
  852. If eps, size is read from image header.
  853. """
  854. fileName = os.path.split(imagePath)[1]
  855. # if eps, read info from header
  856. if os.path.splitext(fileName)[1].lower() == '.eps':
  857. bbInfo = "%%BoundingBox"
  858. file = open(imagePath,"r")
  859. w = h = 0
  860. while file:
  861. line = file.readline()
  862. if line.find(bbInfo) == 0:
  863. w, h = line.split()[3:5]
  864. break
  865. file.close()
  866. return float(w), float(h)
  867. else: # we can use wx.Image
  868. img = wx.Image(fileName, type=wx.BITMAP_TYPE_ANY)
  869. return img.GetWidth(), img.GetHeight()
  870. class NorthArrow(Image):
  871. """!Class representing eps instruction -- North Arrow"""
  872. def __init__(self, id, settings):
  873. Image.__init__(self, id = id, settings = settings)
  874. self.type = 'northArrow'
  875. def __str__(self):
  876. self.ChangeRefPoint(toCenter = True)
  877. instr = "eps %s %s\n" % (self.instruction['east'], self.instruction['north'])
  878. instr += "# north arrow\n"
  879. instr += string.Template(" epsfile $epsfile\n").substitute(self.instruction)
  880. if self.instruction["rotate"]:
  881. instr += string.Template(" rotate $rotate\n").substitute(self.instruction)
  882. if self.instruction["scale"]:
  883. instr += string.Template(" scale $scale\n").substitute(self.instruction)
  884. instr += " end"
  885. return instr
  886. class Point(InstructionObject):
  887. """!Class representing point instruction"""
  888. def __init__(self, id):
  889. InstructionObject.__init__(self, id = id)
  890. self.type = 'point'
  891. # default values
  892. self.defaultInstruction = dict(symbol = os.path.join('basic', 'x'),
  893. color = '0:0:0', fcolor = '200:200:200',
  894. rotate = 0, size = 10,
  895. XY = True, where = (0,0), unit = 'inch',
  896. east = None, north = None)
  897. # current values
  898. self.instruction = dict(self.defaultInstruction)
  899. def __str__(self):
  900. instr = string.Template("point $east $north\n").substitute(self.instruction)
  901. instr += string.Template(" symbol $symbol\n").substitute(self.instruction)
  902. instr += string.Template(" color $color\n").substitute(self.instruction)
  903. instr += string.Template(" fcolor $fcolor\n").substitute(self.instruction)
  904. instr += string.Template(" rotate $rotate\n").substitute(self.instruction)
  905. instr += string.Template(" size $size\n").substitute(self.instruction)
  906. instr += " end"
  907. return instr
  908. def Read(self, instruction, text, **kwargs):
  909. """!Read instruction and save information"""
  910. mapInstr = kwargs['mapInstruction']
  911. instr = {}
  912. for line in text:
  913. try:
  914. sub = line.split(None, 1)[0]
  915. if sub == 'point':
  916. e, n = line.split(None, 3)[1:3]
  917. if '%' in e and '%' in n:
  918. instr['XY'] = True
  919. instr['east'], instr['north'] = self.PercentToReal(e, n)
  920. else:
  921. instr['XY'] = False
  922. instr['east'], instr['north'] = float(e), float(n)
  923. elif sub == 'symbol':
  924. instr['symbol'] = line.split(None, 1)[1]
  925. elif sub == 'rotate':
  926. instr['rotate'] = float(line.split(None, 1)[1])
  927. elif sub == 'size':
  928. instr['size'] = float(line.split(None, 1)[1])
  929. elif sub == 'color':
  930. instr['color'] = line.split(None, 1)[1]
  931. elif sub == 'fcolor':
  932. instr['fcolor'] = line.split(None, 1)[1]
  933. except(IndexError, ValueError):
  934. GError(_("Failed to read instruction %s") % instruction)
  935. return False
  936. self.instruction.update(instr)
  937. instr['where'] = PaperMapCoordinates(mapInstr = mapInstr, x = self.instruction['east'],
  938. y = self.instruction['north'], paperToMap = False)
  939. w = h = self.unitConv.convert(value = instr['size'], fromUnit = 'point', toUnit = 'inch')
  940. instr['rect'] = Rect2D(x = float(instr['where'][0]) - w / 2, y = float(instr['where'][1] - h / 2),
  941. width = w, height = h)
  942. self.instruction.update(instr)
  943. return True
  944. class Line(InstructionObject):
  945. """!Class representing line instruction"""
  946. def __init__(self, id):
  947. InstructionObject.__init__(self, id = id)
  948. self.type = 'line'
  949. # default values
  950. self.defaultInstruction = dict(color = '0:0:0', width = 2,
  951. where = [wx.Point2D(), wx.Point2D()],
  952. east1 = None, north1 = None,
  953. east2 = None, north2 = None)
  954. # current values
  955. self.instruction = dict(self.defaultInstruction)
  956. def __str__(self):
  957. instr = string.Template("line $east1 $north1 $east2 $north2\n").substitute(self.instruction)
  958. instr += string.Template(" color $color\n").substitute(self.instruction)
  959. instr += string.Template(" width $width\n").substitute(self.instruction)
  960. instr += " end\n"
  961. return instr
  962. def Read(self, instruction, text, **kwargs):
  963. """!Read instruction and save information"""
  964. mapInstr = kwargs['mapInstruction']
  965. instr = {}
  966. for line in text:
  967. try:
  968. sub = line.split(None, 1)[0]
  969. if sub == 'line':
  970. e1, n1, e2, n2 = line.split(None, 5)[1:5]
  971. if '%' in e1 and '%' in n1 and '%' in e2 and '%' in n2:
  972. instr['east1'], instr['north1'] = self.PercentToReal(e1, n1)
  973. instr['east2'], instr['north2'] = self.PercentToReal(e2, n2)
  974. else:
  975. instr['east1'], instr['north1'] = float(e1), float(n1)
  976. instr['east2'], instr['north2'] = float(e2), float(n2)
  977. elif sub == 'width':
  978. instr['width'] = float(line.split(None, 1)[1])
  979. elif sub == 'color':
  980. instr['color'] = line.split(None, 1)[1]
  981. except(IndexError, ValueError):
  982. GError(_("Failed to read instruction %s") % instruction)
  983. return False
  984. self.instruction.update(instr)
  985. e1, n1 = PaperMapCoordinates(mapInstr = mapInstr, x = self.instruction['east1'],
  986. y = self.instruction['north1'], paperToMap = False)
  987. e2, n2 = PaperMapCoordinates(mapInstr = mapInstr, x = self.instruction['east2'],
  988. y = self.instruction['north2'], paperToMap = False)
  989. instr['where'] = [wx.Point2D(e1, n1), wx.Point2D(e2, n2)]
  990. instr['rect'] = Rect2DPP(instr['where'][0], instr['where'][1])
  991. self.instruction.update(instr)
  992. return True
  993. class Rectangle(InstructionObject):
  994. """!Class representing rectangle instruction"""
  995. def __init__(self, id):
  996. InstructionObject.__init__(self, id = id)
  997. self.type = 'rectangle'
  998. # default values
  999. self.defaultInstruction = dict(color = '0:0:0', fcolor = 'none', width = 2,
  1000. east1 = None, north1 = None,
  1001. east2 = None, north2 = None)
  1002. # current values
  1003. self.instruction = dict(self.defaultInstruction)
  1004. def __str__(self):
  1005. instr = string.Template("rectangle $east1 $north1 $east2 $north2\n").substitute(self.instruction)
  1006. instr += string.Template(" color $color\n").substitute(self.instruction)
  1007. instr += string.Template(" fcolor $fcolor\n").substitute(self.instruction)
  1008. instr += string.Template(" width $width\n").substitute(self.instruction)
  1009. instr += " end\n"
  1010. return instr
  1011. def Read(self, instruction, text, **kwargs):
  1012. """!Read instruction and save information"""
  1013. mapInstr = kwargs['mapInstruction']
  1014. instr = {}
  1015. for line in text:
  1016. try:
  1017. sub = line.split(None, 1)[0]
  1018. if sub == 'rectangle':
  1019. e1, n1, e2, n2 = line.split(None, 5)[1:5]
  1020. if '%' in e1 and '%' in n1 and '%' in e2 and '%' in n2:
  1021. instr['east1'], instr['north1'] = self.PercentToReal(e1, n1)
  1022. instr['east2'], instr['north2'] = self.PercentToReal(e2, n2)
  1023. else:
  1024. instr['east1'], instr['north1'] = float(e1), float(n1)
  1025. instr['east2'], instr['north2'] = float(e2), float(n2)
  1026. elif sub == 'width':
  1027. instr['width'] = float(line.split(None, 1)[1])
  1028. elif sub == 'color':
  1029. instr['color'] = line.split(None, 1)[1]
  1030. elif sub == 'fcolor':
  1031. instr['fcolor'] = line.split(None, 1)[1]
  1032. except(IndexError, ValueError):
  1033. GError(_("Failed to read instruction %s") % instruction)
  1034. return False
  1035. self.instruction.update(instr)
  1036. e1, n1 = PaperMapCoordinates(mapInstr = mapInstr, x = self.instruction['east1'],
  1037. y = self.instruction['north1'], paperToMap = False)
  1038. e2, n2 = PaperMapCoordinates(mapInstr = mapInstr, x = self.instruction['east2'],
  1039. y = self.instruction['north2'], paperToMap = False)
  1040. instr['rect'] = Rect2DPP(wx.Point2D(e1, n1), wx.Point2D(e2, n2))
  1041. self.instruction.update(instr)
  1042. return True
  1043. class Scalebar(InstructionObject):
  1044. """!Class representing scalebar instruction"""
  1045. def __init__(self, id):
  1046. InstructionObject.__init__(self, id = id)
  1047. self.type = 'scalebar'
  1048. # default values
  1049. self.defaultInstruction = dict(unit = 'inch', where = (1,1),
  1050. unitsLength = 'auto', unitsHeight = 'inch',
  1051. length = None, height = 0.1, rect = None,
  1052. fontsize = 10, background = 'y',
  1053. scalebar = 'f', segment = 4, numbers = 1)
  1054. # current values
  1055. self.instruction = dict(self.defaultInstruction)
  1056. def __str__(self):
  1057. instr = string.Template("scalebar $scalebar\n").substitute(self.instruction)
  1058. instr += " where %.3f %.3f\n" % (self.instruction['where'][0], self.instruction['where'][1])
  1059. instr += string.Template(" length $length\n units $unitsLength\n").substitute(self.instruction)
  1060. instr += string.Template(" height $height\n").substitute(self.instruction)
  1061. instr += string.Template(" segment $segment\n numbers $numbers\n").substitute(self.instruction)
  1062. instr += string.Template(" fontsize $fontsize\n background $background\n").substitute(self.instruction)
  1063. instr += " end"
  1064. return instr
  1065. def Read(self, instruction, text, **kwargs):
  1066. """!Read instruction and save information"""
  1067. scale = kwargs['scale']
  1068. instr = {}
  1069. for line in text:
  1070. try:
  1071. if line.startswith('scalebar'):
  1072. if 'scalebar s' in line:
  1073. instr['scalebar'] = 's'
  1074. else:
  1075. instr['scalebar'] = 'f'
  1076. elif line.startswith('where'):
  1077. instr['where'] = map(float, line.split()[1:3])
  1078. elif line.startswith('length'):
  1079. instr['length'] = float(line.split()[1])
  1080. elif line.startswith('units'):
  1081. if line.split()[1] in ['auto', 'meters', 'kilometers', 'feet', 'miles', 'nautmiles']:
  1082. instr['unitsLength'] = line.split()[1]
  1083. elif line.startswith('height'):
  1084. instr['height'] = float(line.split()[1])
  1085. elif line.startswith('fontsize'):
  1086. instr['fontsize'] = float(line.split()[1])
  1087. elif line.startswith('numbers'):
  1088. instr['numbers'] = int(line.split()[1])
  1089. elif line.startswith('segment'):
  1090. instr['segment'] = int(line.split()[1])
  1091. elif line.startswith('background'):
  1092. if line.split()[1].strip().lower() in ('y','yes'):
  1093. instr['background'] = 'y'
  1094. elif line.split()[1].strip().lower() in ('n','no', 'none'):
  1095. instr['background'] = 'n'
  1096. except(IndexError, ValueError):
  1097. GError(_("Failed to read instruction %s") % instruction)
  1098. return False
  1099. self.instruction.update(instr)
  1100. w, h = self.EstimateSize(scalebarDict = self.instruction, scale = scale)
  1101. x = self.instruction['where'][0] - w / 2
  1102. y = self.instruction['where'][1] - h / 2
  1103. self.instruction['rect'] = Rect2D(x, y, w, h)
  1104. return True
  1105. def EstimateSize(self, scalebarDict, scale):
  1106. """!Estimate size to draw scalebar"""
  1107. units = projInfo()['units']
  1108. if not units or units not in self.unitConv.getAllUnits():
  1109. units = 'meters'
  1110. if scalebarDict['unitsLength'] != 'auto':
  1111. length = self.unitConv.convert(value = scalebarDict['length'], fromUnit = scalebarDict['unitsLength'], toUnit = 'inch')
  1112. else:
  1113. length = self.unitConv.convert(value = scalebarDict['length'], fromUnit = units, toUnit = 'inch')
  1114. length *= scale
  1115. length *= 1.1 #for numbers on the edge
  1116. height = scalebarDict['height'] + 2 * self.unitConv.convert(value = scalebarDict['fontsize'], fromUnit = 'point', toUnit = 'inch')
  1117. return (length, height)
  1118. class RasterLegend(InstructionObject):
  1119. """!Class representing colortable instruction"""
  1120. def __init__(self, id):
  1121. InstructionObject.__init__(self, id = id)
  1122. self.type = 'rasterLegend'
  1123. # default values
  1124. self.defaultInstruction = dict(rLegend = False, unit = 'inch', rasterDefault = True, raster = None,
  1125. discrete = None, type = None,
  1126. where = (0, 0),
  1127. width = None, height = None, cols = 1, font = "Helvetica", fontsize = 10,
  1128. #color = '0:0:0', tickbar = False, range = False, min = 0, max = 0,
  1129. color = 'black', tickbar = 'n', range = False, min = 0, max = 0,
  1130. nodata = 'n')
  1131. # current values
  1132. self.instruction = dict(self.defaultInstruction)
  1133. def __str__(self):
  1134. instr = "colortable y\n"
  1135. instr += string.Template(" raster $raster\n").substitute(self.instruction)
  1136. instr += " where %.3f %.3f\n" % (self.instruction['where'][0], self.instruction['where'][1])
  1137. if self.instruction['width']:
  1138. instr += string.Template(" width $width\n").substitute(self.instruction)
  1139. instr += string.Template(" discrete $discrete\n").substitute(self.instruction)
  1140. if self.instruction['discrete'] == 'n':
  1141. if self.instruction['height']:
  1142. instr += string.Template(" height $height\n").substitute(self.instruction)
  1143. instr += string.Template(" tickbar $tickbar\n").substitute(self.instruction)
  1144. if self.instruction['range']:
  1145. instr += string.Template(" range $min $max\n").substitute(self.instruction)
  1146. else:
  1147. instr += string.Template(" cols $cols\n").substitute(self.instruction)
  1148. instr += string.Template(" nodata $nodata\n").substitute(self.instruction)
  1149. instr += string.Template(" font $font\n fontsize $fontsize\n color $color\n")\
  1150. .substitute(self.instruction)
  1151. instr += " end"
  1152. return instr
  1153. def Read(self, instruction, text, **kwargs):
  1154. """!Read instruction and save information"""
  1155. instr = {}
  1156. instr['rLegend'] = True
  1157. for line in text:
  1158. try:
  1159. if line.startswith('where'):
  1160. instr['where'] = map(float, line.split()[1:3])
  1161. elif line.startswith('font '):
  1162. instr['font'] = line.split()[1]
  1163. elif line.startswith('fontsize'):
  1164. instr['fontsize'] = float(line.split()[1])
  1165. elif line.startswith('color '):
  1166. instr['color'] = line.split()[1]
  1167. elif line.startswith('raster'):
  1168. instr['raster'] = line.split()[1]
  1169. elif line.startswith('width'):
  1170. instr['width'] = float(line.split()[1])
  1171. elif line.startswith('height'):
  1172. instr['height'] = float(line.split()[1])
  1173. elif line.startswith('cols'):
  1174. instr['cols'] = int(line.split()[1])
  1175. elif line.startswith('range'):
  1176. instr['range'] = True
  1177. instr['min'] = float(line.split()[1])
  1178. instr['max'] = float(line.split()[2])
  1179. elif line.startswith('nodata'):
  1180. if line.split()[1].strip().lower() in ('y','yes'):
  1181. instr['nodata'] = 'y'
  1182. elif line.split()[1].strip().lower() in ('n','no', 'none'):
  1183. instr['nodata'] = 'n'
  1184. elif line.startswith('tickbar'):
  1185. if line.split()[1].strip().lower() in ('y','yes'):
  1186. instr['tickbar'] = 'y'
  1187. elif line.split()[1].strip().lower() in ('n','no', 'none'):
  1188. instr['tickbar'] = 'n'
  1189. elif line.startswith('discrete'):
  1190. if line.split()[1].strip().lower() in ('y','yes'):
  1191. instr['discrete'] = 'y'
  1192. elif line.split()[1].strip().lower() in ('n','no', 'none'):
  1193. instr['discrete'] = 'n'
  1194. except(IndexError, ValueError):
  1195. GError(_("Failed to read instruction %s") % instruction)
  1196. return False
  1197. if 'raster' in instr:
  1198. instr['rasterDefault'] = False
  1199. if 'discrete' not in instr:
  1200. rasterType = getRasterType(map = instr['raster'])
  1201. instr['type'] = rasterType
  1202. if rasterType == 'CELL':
  1203. instr['discrete'] = 'y'
  1204. else:
  1205. instr['discrete'] = 'n'
  1206. else:
  1207. instr['rasterDefault'] = True
  1208. self.instruction.update(instr)
  1209. # add 'rect' in the end
  1210. return True
  1211. def EstimateHeight(self, raster, discrete, fontsize, cols = None, height = None):
  1212. """!Estimate height to draw raster legend"""
  1213. if discrete == 'n':
  1214. if height:
  1215. height = height
  1216. else:
  1217. height = self.unitConv.convert(value = fontsize * 10,
  1218. fromUnit = 'point', toUnit = 'inch')
  1219. if discrete == 'y':
  1220. if cols:
  1221. cols = cols
  1222. else:
  1223. cols = 1
  1224. rinfo = grass.raster_info(raster)
  1225. if rinfo['datatype'] in ('DCELL', 'FCELL'):
  1226. minim, maxim = rinfo['min'], rinfo['max']
  1227. rows = ceil(maxim / cols )
  1228. else:
  1229. cat = grass.read_command('r.category', map = raster,
  1230. fs = ':').strip().split('\n')
  1231. rows = ceil(float(len(cat)) / cols )
  1232. height = self.unitConv.convert(value = 1.5 * rows * fontsize, fromUnit = 'point', toUnit = 'inch')
  1233. return height
  1234. def EstimateWidth(self, raster, discrete, fontsize, cols = None, width = None, paperInstr = None):
  1235. """!Estimate size to draw raster legend"""
  1236. if discrete == 'n':
  1237. rinfo = grass.raster_info(raster)
  1238. minim, maxim = rinfo['min'], rinfo['max']
  1239. if width:
  1240. width = width
  1241. else:
  1242. width = self.unitConv.convert(value = fontsize * 2,
  1243. fromUnit = 'point', toUnit = 'inch')
  1244. text = len(max(str(minim), str(maxim), key = len))
  1245. textPart = self.unitConv.convert(value = text * fontsize / 2,
  1246. fromUnit = 'point', toUnit = 'inch')
  1247. width += textPart
  1248. elif discrete == 'y':
  1249. if cols:
  1250. cols = cols
  1251. else:
  1252. cols = 1
  1253. if width:
  1254. width = width
  1255. else:
  1256. paperWidth = paperInstr['Width'] - paperInstr['Right'] - paperInstr['Left']
  1257. width = (paperWidth / cols) * (cols - 1) + 1
  1258. return width
  1259. class VectorLegend(InstructionObject):
  1260. """!Class representing colortable instruction"""
  1261. def __init__(self, id):
  1262. InstructionObject.__init__(self, id = id)
  1263. self.type = 'vectorLegend'
  1264. # default values
  1265. self.defaultInstruction = dict(vLegend = False, unit = 'inch', where = (0, 0),
  1266. defaultSize = True, width = 0.4, cols = 1, span = None,
  1267. font = "Helvetica", fontsize = 10,
  1268. border = 'none')
  1269. # current values
  1270. self.instruction = dict(self.defaultInstruction)
  1271. def __str__(self):
  1272. instr = "vlegend\n"
  1273. instr += " where %.3f %.3f\n" % (self.instruction['where'][0], self.instruction['where'][1])
  1274. instr += string.Template(" font $font\n fontsize $fontsize\n").substitute(self.instruction)
  1275. instr += string.Template(" width $width\n cols $cols\n").substitute(self.instruction)
  1276. if self.instruction['span']:
  1277. instr += string.Template(" span $span\n").substitute(self.instruction)
  1278. instr += string.Template(" border $border\n").substitute(self.instruction)
  1279. instr += " end"
  1280. return instr
  1281. def Read(self, instruction, text, **kwargs):
  1282. """!Read instruction and save information"""
  1283. instr = {}
  1284. instr['vLegend'] = True
  1285. for line in text:
  1286. try:
  1287. if line.startswith('where'):
  1288. instr['where'] = map(float, line.split()[1:3])
  1289. elif line.startswith('font '):
  1290. instr['font'] = line.split()[1]
  1291. elif line.startswith('fontsize'):
  1292. instr['fontsize'] = float(line.split()[1])
  1293. elif line.startswith('width'):
  1294. instr['width'] = float(line.split()[1])
  1295. elif line.startswith('cols'):
  1296. instr['cols'] = int(line.split()[1])
  1297. elif line.startswith('span'):
  1298. instr['span'] = float(line.split()[1])
  1299. elif line.startswith('border'):
  1300. instr['border'] = line.split()[1]
  1301. except(IndexError, ValueError):
  1302. GError(_("Failed to read instruction %s") % instruction)
  1303. return False
  1304. self.instruction.update(instr)
  1305. return True
  1306. def EstimateSize(self, vectorInstr, fontsize, width = None, cols = None):
  1307. """!Estimate size to draw vector legend"""
  1308. if width:
  1309. width = width
  1310. else:
  1311. width = fontsize/24.0
  1312. if cols:
  1313. cols = cols
  1314. else:
  1315. cols = 1
  1316. vectors = vectorInstr['list']
  1317. labels = [vector[4] for vector in vectors if vector[3] != 0]
  1318. extent = (len(max(labels, key = len)) * fontsize / 2, fontsize)
  1319. wExtent = self.unitConv.convert(value = extent[0], fromUnit = 'point', toUnit = 'inch')
  1320. hExtent = self.unitConv.convert(value = extent[1], fromUnit = 'point', toUnit = 'inch')
  1321. w = (width + wExtent) * cols
  1322. h = len(labels) * hExtent / cols
  1323. h *= 1.1
  1324. return (w, h)
  1325. class Raster(InstructionObject):
  1326. """!Class representing raster instruction"""
  1327. def __init__(self, id):
  1328. InstructionObject.__init__(self, id = id)
  1329. self.type = 'raster'
  1330. # default values
  1331. self.defaultInstruction = dict(isRaster = False, raster = None)
  1332. # current values
  1333. self.instruction = dict(self.defaultInstruction)
  1334. def __str__(self):
  1335. instr = string.Template("raster $raster").substitute(self.instruction)
  1336. return instr
  1337. def Read(self, instruction, text):
  1338. """!Read instruction and save information"""
  1339. instr = {}
  1340. instr['isRaster'] = True
  1341. try:
  1342. map = text.split()[1]
  1343. except IndexError:
  1344. GError(_("Failed to read instruction %s") % instruction)
  1345. return False
  1346. try:
  1347. info = grass.find_file(map, element = 'cell')
  1348. except grass.ScriptError, e:
  1349. GError(message = e.value)
  1350. return False
  1351. instr['raster'] = info['fullname']
  1352. self.instruction.update(instr)
  1353. return True
  1354. class Vector(InstructionObject):
  1355. """!Class keeps vector layers"""
  1356. def __init__(self, id):
  1357. InstructionObject.__init__(self, id = id)
  1358. self.type = 'vector'
  1359. # default values
  1360. self.defaultInstruction = dict(list = None)# [vmap, type, id, lpos, label]
  1361. # current values
  1362. self.instruction = dict(self.defaultInstruction)
  1363. def __str__(self):
  1364. return ''
  1365. def Read(self, instruction, text, **kwargs):
  1366. """!Read instruction and save information"""
  1367. instr = {}
  1368. for line in text:
  1369. if line.startswith('vpoints') or line.startswith('vlines') or line.startswith('vareas'):
  1370. # subtype
  1371. if line.startswith('vpoints'):
  1372. subType = 'points'
  1373. elif line.startswith('vlines'):
  1374. subType = 'lines'
  1375. elif line.startswith('vareas'):
  1376. subType = 'areas'
  1377. # name of vector map
  1378. vmap = line.split()[1]
  1379. try:
  1380. info = grass.find_file(vmap, element = 'vector')
  1381. except grass.ScriptError, e:
  1382. GError(message = e.value)
  1383. return False
  1384. vmap = info['fullname']
  1385. # id
  1386. id = kwargs['id']
  1387. # lpos
  1388. lpos = kwargs['vectorMapNumber']
  1389. #label
  1390. label = '('.join(vmap.split('@')) + ')'
  1391. break
  1392. instr = [vmap, subType, id, lpos, label]
  1393. if not self.instruction['list']:
  1394. self.instruction['list'] = []
  1395. self.instruction['list'].append(instr)
  1396. return True
  1397. class VProperties(InstructionObject):
  1398. """!Class represents instructions vareas, vlines, vpoints"""
  1399. def __init__(self, id, subType):
  1400. InstructionObject.__init__(self, id = id)
  1401. self.type = 'vProperties'
  1402. self.subType = subType
  1403. # default values
  1404. if self.subType == 'points':
  1405. dd = dict(subType = 'points', name = None, type = 'point or centroid', connection = False, layer = '1',
  1406. masked = 'n', color = '0:0:0', width = 1,
  1407. fcolor = '255:0:0', rgbcolumn = None, symbol = os.path.join('basic', 'x'), eps = None,
  1408. size = 5, sizecolumn = None, scale = None,
  1409. rotation = False, rotate = 0, rotatecolumn = None, label = None, lpos = None)
  1410. elif self.subType == 'lines':
  1411. dd = dict(subType = 'lines', name = None, type = 'line or boundary', connection = False, layer = '1',
  1412. masked = 'n', color = '0:0:0', hwidth = 1,
  1413. hcolor = 'none', rgbcolumn = None,
  1414. width = 1, cwidth = None,
  1415. style = 'solid', linecap = 'butt', label = None, lpos = None)
  1416. else: # areas
  1417. dd = dict(subType = 'areas', name = None, connection = False, layer = '1',
  1418. masked = 'n', color = '0:0:0', width = 1,
  1419. fcolor = 'none', rgbcolumn = None,
  1420. pat = None, pwidth = 1, scale = 1, label = None, lpos = None)
  1421. self.defaultInstruction = dd
  1422. # current values
  1423. self.instruction = dict(self.defaultInstruction)
  1424. def __str__(self):
  1425. dic = self.instruction
  1426. vInstruction = string.Template("v$subType $name\n").substitute(dic)
  1427. #data selection
  1428. if self.subType in ('points', 'lines'):
  1429. vInstruction += string.Template(" type $type\n").substitute(dic)
  1430. if dic['connection']:
  1431. vInstruction += string.Template(" layer $layer\n").substitute(dic)
  1432. if dic.has_key('cats'):
  1433. vInstruction += string.Template(" cats $cats\n").substitute(dic)
  1434. elif dic.has_key('where'):
  1435. vInstruction += string.Template(" where $where\n").substitute(dic)
  1436. vInstruction += string.Template(" masked $masked\n").substitute(dic)
  1437. #colors
  1438. vInstruction += string.Template(" color $color\n").substitute(dic)
  1439. if self.subType in ('points', 'areas'):
  1440. if dic['color'] != 'none':
  1441. vInstruction += string.Template(" width $width\n").substitute(dic)
  1442. if dic['rgbcolumn']:
  1443. vInstruction += string.Template(" rgbcolumn $rgbcolumn\n").substitute(dic)
  1444. vInstruction += string.Template(" fcolor $fcolor\n").substitute(dic)
  1445. else:
  1446. if dic['rgbcolumn']:
  1447. vInstruction += string.Template(" rgbcolumn $rgbcolumn\n").substitute(dic)
  1448. elif dic['hcolor'] != 'none':
  1449. vInstruction += string.Template(" hwidth $hwidth\n").substitute(dic)
  1450. vInstruction += string.Template(" hcolor $hcolor\n").substitute(dic)
  1451. # size and style
  1452. if self.subType == 'points':
  1453. if not dic['eps']:
  1454. vInstruction += string.Template(" symbol $symbol\n").substitute(dic)
  1455. else: #eps
  1456. vInstruction += string.Template(" eps $eps\n").substitute(dic)
  1457. if dic['size']:
  1458. vInstruction += string.Template(" size $size\n").substitute(dic)
  1459. else: # sizecolumn
  1460. vInstruction += string.Template(" sizecolumn $sizecolumn\n").substitute(dic)
  1461. vInstruction += string.Template(" scale $scale\n").substitute(dic)
  1462. if dic['rotation']:
  1463. if dic['rotate'] is not None:
  1464. vInstruction += string.Template(" rotate $rotate\n").substitute(dic)
  1465. else:
  1466. vInstruction += string.Template(" rotatecolumn $rotatecolumn\n").substitute(dic)
  1467. if self.subType == 'areas':
  1468. if dic['pat'] is not None:
  1469. vInstruction += string.Template(" pat $pat\n").substitute(dic)
  1470. vInstruction += string.Template(" pwidth $pwidth\n").substitute(dic)
  1471. vInstruction += string.Template(" scale $scale\n").substitute(dic)
  1472. if self.subType == 'lines':
  1473. if dic['width'] is not None:
  1474. vInstruction += string.Template(" width $width\n").substitute(dic)
  1475. else:
  1476. vInstruction += string.Template(" cwidth $cwidth\n").substitute(dic)
  1477. vInstruction += string.Template(" style $style\n").substitute(dic)
  1478. vInstruction += string.Template(" linecap $linecap\n").substitute(dic)
  1479. #position and label in vlegend
  1480. vInstruction += string.Template(" label $label\n lpos $lpos\n").substitute(dic)
  1481. vInstruction += " end"
  1482. try:
  1483. vInstruction = vInstruction.encode('Latin_1')
  1484. except UnicodeEncodeError, err:
  1485. try:
  1486. pos = str(err).split('position')[1].split(':')[0].strip()
  1487. except IndexError:
  1488. pos = ''
  1489. if pos:
  1490. message = _("Characters on position %s are not supported "
  1491. "by ISO-8859-1 (Latin 1) encoding "
  1492. "which is required by module ps.map.") % pos
  1493. else:
  1494. message = _("Not all characters are supported "
  1495. "by ISO-8859-1 (Latin 1) encoding "
  1496. "which is required by module ps.map.")
  1497. GMessage(message = message)
  1498. return ''
  1499. return vInstruction
  1500. def Read(self, instruction, text, **kwargs):
  1501. """!Read instruction and save information"""
  1502. instr = {}
  1503. try:
  1504. info = grass.find_file(name = text[0].split()[1], element = 'vector')
  1505. except grass.ScriptError, e:
  1506. GError(message = e.value)
  1507. return False
  1508. instr['name'] = info['fullname']
  1509. #connection
  1510. instr['connection'] = True
  1511. self.mapDBInfo = VectorDBInfo(instr['name'])
  1512. self.layers = self.mapDBInfo.layers.keys()
  1513. if not self.layers:
  1514. instr['connection'] = False
  1515. # points
  1516. if text[0].startswith('vpoints'):
  1517. for line in text[1:]:
  1518. if line.startswith('type'):
  1519. tp = []
  1520. if line.find('point') != -1:
  1521. tp.append('point')
  1522. if line.find('centroid') != -1:
  1523. tp.append('centroid')
  1524. instr['type'] = ' or '.join(tp)
  1525. elif line.startswith('fcolor'):
  1526. instr['fcolor'] = line.split()[1]
  1527. elif line.startswith('rgbcolumn'):
  1528. instr['rgbcolumn'] = line.split()[1]
  1529. elif line.startswith('symbol'):
  1530. instr['symbol'] = line.split()[1]
  1531. elif line.startswith('eps'):
  1532. instr['eps'] = line.split()[1]
  1533. elif line.startswith('size '):
  1534. instr['size'] = line.split()[1]
  1535. elif line.startswith('sizecolumn'):
  1536. instr['size'] = None
  1537. instr['sizecolumn'] = line.split()[1]
  1538. elif line.startswith('scale '):
  1539. instr['scale'] = float(line.split()[1])
  1540. elif line.startswith('rotate '):
  1541. instr['rotation'] = True
  1542. instr['rotate'] = line.split()[1]
  1543. elif line.startswith('rotatecolumn'):
  1544. instr['rotatecolumn'] = line.split()[1]
  1545. instr['rotation'] = True
  1546. instr['rotate'] = None
  1547. # lines
  1548. elif text[0].startswith('vlines'):
  1549. for line in text[1:]:
  1550. if line.startswith('type'):
  1551. tp = []
  1552. if line.find('line') != -1:
  1553. tp.append('line')
  1554. if line.find('boundary') != -1:
  1555. tp.append('boundary')
  1556. instr['type'] = ' or '.join(tp)
  1557. elif line.startswith('hwidth'):
  1558. instr['hwidth'] = float(line.split()[1])
  1559. elif line.startswith('hcolor'):
  1560. instr['hcolor'] = line.split()[1]
  1561. elif line.startswith('rgbcolumn'):
  1562. instr['rgbcolumn'] = line.split()[1]
  1563. elif line.startswith('cwidth'):
  1564. instr['cwidth'] = float(line.split()[1])
  1565. instr['width'] = None
  1566. elif line.startswith('style'):
  1567. instr['style'] = line.split()[1]
  1568. elif line.startswith('linecap'):
  1569. instr['linecap'] = line.split()[1]
  1570. elif text[0].startswith('vareas'):
  1571. for line in text[1:]:
  1572. if line.startswith('fcolor'):
  1573. instr['fcolor'] = line.split()[1]
  1574. elif line.startswith('pat'):
  1575. instr['pat'] = line.split()[1]
  1576. elif line.startswith('pwidth'):
  1577. instr['pwidth'] = float(line.split()[1])
  1578. elif line.startswith('scale'):
  1579. instr['scale'] = float(line.split()[1])
  1580. # same properties for all
  1581. for line in text[1:]:
  1582. if line.startswith('lpos'):
  1583. instr['lpos'] = int(line.split()[1])
  1584. elif line.startswith('label'):
  1585. instr['label'] = line.split(None, 1)[1].decode('latin_1')
  1586. elif line.startswith('layer'):
  1587. instr['layer'] = line.split()[1]
  1588. elif line.startswith('masked'):
  1589. if line.split()[1].lower() in ('y', 'yes'):
  1590. instr['masked'] = 'y'
  1591. else:
  1592. instr['masked'] = 'n'
  1593. elif line.startswith('color'):
  1594. instr['color'] = line.split()[1]
  1595. elif line.startswith('rgbcolumn'):
  1596. instr['rgbcolumn'] = line.split()[1]
  1597. elif line.startswith('width'):
  1598. instr['width'] = float(line.split()[1])
  1599. if 'label' not in instr:
  1600. instr['label'] = '('.join(instr['name'].split('@')) + ')'
  1601. if 'lpos' not in instr:
  1602. instr['lpos'] = kwargs['vectorMapNumber']
  1603. self.instruction.update(instr)
  1604. return True