__init__.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Fri May 25 12:56:33 2012
  4. @author: pietro
  5. """
  6. from __future__ import (nested_scopes, generators, division, absolute_import,
  7. with_statement, print_function, unicode_literals)
  8. import os
  9. import ctypes
  10. import numpy as np
  11. #
  12. # import GRASS modules
  13. #
  14. from grass.script import fatal, warning
  15. from grass.script import core as grasscore
  16. import grass.lib.gis as libgis
  17. import grass.lib.raster as libraster
  18. import grass.lib.rowio as librowio
  19. #
  20. # import pygrass modules
  21. #
  22. from grass.pygrass.errors import OpenError, must_be_open
  23. from grass.pygrass.gis.region import Region
  24. from grass.pygrass import functions
  25. #
  26. # import raster classes
  27. #
  28. from grass.pygrass.raster.abstract import RasterAbstractBase
  29. from grass.pygrass.raster.raster_type import TYPE as RTYPE, RTYPE_STR
  30. from grass.pygrass.raster.buffer import Buffer
  31. from grass.pygrass.raster.segment import Segment
  32. from grass.pygrass.raster.rowio import RowIO
  33. class RasterRow(RasterAbstractBase):
  34. """Raster_row_access": Inherits: "Raster_abstract_base" and implements
  35. the default row access of the Rast library.
  36. * Implements row access using row id
  37. * The get_row() method must accept a Row object as argument that will
  38. be used for value storage, so no new buffer will be allocated
  39. * Implements sequential writing of rows
  40. * Implements indexed value read only access using the [row][col]
  41. operator
  42. * Implements the [row] read method that returns a new Row object
  43. * Writing is limited using the put_row() method which accepts a
  44. Row as argument
  45. * No mathematical operation like __add__ and stuff for the Raster
  46. object (only for rows), since r.mapcalc is more sophisticated and
  47. faster
  48. Examples
  49. --------
  50. >>> elev = RasterRow('elevation')
  51. >>> elev.exist()
  52. True
  53. >>> elev.is_open()
  54. False
  55. >>> elev.open()
  56. >>> elev.is_open()
  57. True
  58. >>> elev.has_cats()
  59. False
  60. >>> elev.mode
  61. u'r'
  62. >>> elev.mtype
  63. 'FCELL'
  64. >>> elev.num_cats()
  65. 0
  66. >>> elev.info.range
  67. (56, 156)
  68. >>> elev.info
  69. elevation@
  70. rows: 1350
  71. cols: 1500
  72. north: 228500.0 south: 215000.0 nsres:10.0
  73. east: 645000.0 west: 630000.0 ewres:10.0
  74. range: 56, 156
  75. proj: 99
  76. <BLANKLINE>
  77. Each Raster map have an attribute call ``cats`` that allow user
  78. to interact with the raster categories. ::
  79. >>> land = RasterRow('geology')
  80. >>> land.open()
  81. >>> land.cats # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
  82. [('Zml', 1, None),
  83. ...
  84. ('Tpyw', 1832, None)]
  85. Open a raster map using the *with statement*: ::
  86. >>> with RasterRow('elevation') as elev:
  87. ... for row in elev[:3]:
  88. ... row[:4]
  89. ...
  90. Buffer([ 141.99613953, 141.27848816, 141.37904358, 142.29821777], dtype=float32)
  91. Buffer([ 142.90461731, 142.39450073, 142.68611145, 143.59086609], dtype=float32)
  92. Buffer([ 143.81854248, 143.54707336, 143.83972168, 144.59527588], dtype=float32)
  93. >>> elev.is_open()
  94. False
  95. """
  96. def __init__(self, name, mapset='', *args, **kargs):
  97. super(RasterRow, self).__init__(name, mapset, *args, **kargs)
  98. # mode = "r", method = "row",
  99. @must_be_open
  100. def get_row(self, row, row_buffer=None):
  101. """Private method that return the row using the read mode
  102. call the `Rast_get_row` C function.
  103. :param row: the number of row to obtain
  104. :type row: int
  105. :param row_buffer: specify the Buffer object that will be instantiate
  106. :type row_buffer: bool
  107. >>> elev = RasterRow('elevation')
  108. >>> elev.open()
  109. >>> elev[0] # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
  110. Buffer([ 141.99613953, 141.27848816, 141.37904358, ..., 58.40825272,
  111. 58.30711365, 58.18310547], dtype=float32)
  112. >>> elev.get_row(0) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
  113. Buffer([ 141.99613953, 141.27848816, 141.37904358, ..., 58.40825272,
  114. 58.30711365, 58.18310547], dtype=float32)
  115. """
  116. if row_buffer is None:
  117. row_buffer = Buffer((self._cols,), self.mtype)
  118. libraster.Rast_get_row(self._fd, row_buffer.p, row, self._gtype)
  119. return row_buffer
  120. @must_be_open
  121. def put_row(self, row):
  122. """Private method to write the row sequentially.
  123. :param row: a Row object to insert into raster
  124. :type row: Buffer object
  125. """
  126. libraster.Rast_put_row(self._fd, row.p, self._gtype)
  127. def open(self, mode=None, mtype=None, overwrite=None):
  128. """Open the raster if exist or created a new one.
  129. :param mode: Specify if the map will be open with read or write mode
  130. ('r', 'w')
  131. :type mode: str
  132. :param type: If a new map is open, specify the type of the map(`CELL`,
  133. `FCELL`, `DCELL`)
  134. :type type: str
  135. :param overwrite: Use this flag to set the overwrite mode of existing
  136. raster maps
  137. :type overwrite: bool
  138. if the map already exist, automatically check the type and set:
  139. * self.mtype
  140. Set all the privite, attributes:
  141. * self._fd;
  142. * self._gtype
  143. * self._rows and self._cols
  144. """
  145. self.mode = mode if mode else self.mode
  146. self.mtype = mtype if mtype else self.mtype
  147. self.overwrite = overwrite if overwrite is not None else self.overwrite
  148. # check if exist and instantiate all the private attributes
  149. if self.exist():
  150. self.info.read()
  151. self.cats.mtype = self.mtype
  152. self.cats.read()
  153. self.hist.read()
  154. if self.mode == 'r':
  155. # the map exist, read mode
  156. self._fd = libraster.Rast_open_old(self.name, self.mapset)
  157. self._gtype = libraster.Rast_get_map_type(self._fd)
  158. self.mtype = RTYPE_STR[self._gtype]
  159. # try:
  160. # self.cats.read(self)
  161. # self.hist.read(self.name)
  162. # except:
  163. # import ipdb; ipdb.set_trace()
  164. elif self.overwrite:
  165. if self._gtype is None:
  166. raise OpenError(_("Raster type not defined"))
  167. self._fd = libraster.Rast_open_new(self.name, self._gtype)
  168. else:
  169. str_err = _("Raster map <{0}> already exists")
  170. raise OpenError(str_err.format(self))
  171. else:
  172. # Create a new map
  173. if self.mode == 'r':
  174. # check if we are in read mode
  175. str_err = _("The map does not exist, I can't open in 'r' mode")
  176. raise OpenError(str_err)
  177. self._fd = libraster.Rast_open_new(self.name, self._gtype)
  178. # read rows and cols from the active region
  179. self._rows = libraster.Rast_window_rows()
  180. self._cols = libraster.Rast_window_cols()
  181. class RasterRowIO(RasterRow):
  182. """Raster_row_cache_access": The same as "Raster_row_access" but uses
  183. the ROWIO library for cached row access
  184. """
  185. def __init__(self, name, *args, **kargs):
  186. self.rowio = RowIO()
  187. super(RasterRowIO, self).__init__(name, *args, **kargs)
  188. def open(self, mode=None, mtype=None, overwrite=False):
  189. """Open the raster if exist or created a new one.
  190. :param mode: specify if the map will be open with read or write mode
  191. ('r', 'w')
  192. :type mode: str
  193. :param type: if a new map is open, specify the type of the map(`CELL`,
  194. `FCELL`, `DCELL`)
  195. :type type: str
  196. :param overwrite: use this flag to set the overwrite mode of existing
  197. raster maps
  198. :type overwrite: bool
  199. """
  200. super(RasterRowIO, self).open(mode, mtype, overwrite)
  201. self.rowio.open(self._fd, self._rows, self._cols, self.mtype)
  202. @must_be_open
  203. def close(self):
  204. """Function to close the raster"""
  205. self.rowio.release()
  206. libraster.Rast_close(self._fd)
  207. # update rows and cols attributes
  208. self._rows = None
  209. self._cols = None
  210. self._fd = None
  211. @must_be_open
  212. def get_row(self, row, row_buffer=None):
  213. """This method returns the row using:
  214. * the read mode and
  215. * `rowcache` method
  216. :param row: the number of row to obtain
  217. :type row: int
  218. :param row_buffer: Specify the Buffer object that will be instantiate
  219. :type row_buffer: Buffer object
  220. """
  221. if row_buffer is None:
  222. row_buffer = Buffer((self._cols,), self.mtype)
  223. rowio_buf = librowio.Rowio_get(ctypes.byref(self.rowio.c_rowio), row)
  224. ctypes.memmove(row_buffer.p, rowio_buf, self.rowio.row_size)
  225. return row_buffer
  226. class RasterSegment(RasterAbstractBase):
  227. """Raster_segment_access": Inherits "Raster_abstract_base" and uses the
  228. segment library for cached randomly reading and writing access.
  229. * Implements the [row][col] operator for read and write access using
  230. segement_get() and segment_put() functions internally
  231. * Implements row read and write access with the [row] operator using
  232. segment_get_row() segment_put_row() internally
  233. * Implements the get_row() and put_row() method using
  234. segment_get_row() segment_put_row() internally
  235. * Implements the flush_segment() method
  236. * Implements the copying of raster maps to segments and vice verse
  237. * Overwrites the open and close methods
  238. * No mathematical operation like __add__ and stuff for the Raster
  239. object (only for rows), since r.mapcalc is more sophisticated and
  240. faster
  241. """
  242. def __init__(self, name, srows=64, scols=64, maxmem=100,
  243. *args, **kargs):
  244. self.segment = Segment(srows, scols, maxmem)
  245. super(RasterSegment, self).__init__(name, *args, **kargs)
  246. def _get_mode(self):
  247. return self._mode
  248. def _set_mode(self, mode):
  249. if mode and mode.lower() not in ('r', 'w', 'rw'):
  250. str_err = _("Mode type: {0} not supported ('r', 'w','rw')")
  251. raise ValueError(str_err.format(mode))
  252. self._mode = mode
  253. mode = property(fget=_get_mode, fset=_set_mode,
  254. doc="Set or obtain the opening mode of raster")
  255. def __setitem__(self, key, row):
  256. """Return the row of Raster object, slice allowed."""
  257. if isinstance(key, slice):
  258. #Get the start, stop, and step from the slice
  259. return [self.put_row(ii, row)
  260. for ii in range(*key.indices(len(self)))]
  261. elif isinstance(key, tuple):
  262. x, y = key
  263. return self.put(x, y, row)
  264. elif isinstance(key, int):
  265. if key < 0: # Handle negative indices
  266. key += self._rows
  267. if key >= self._rows:
  268. raise IndexError(_("Index out of range: %r.") % key)
  269. return self.put_row(key, row)
  270. else:
  271. raise TypeError("Invalid argument type.")
  272. @must_be_open
  273. def map2segment(self):
  274. """Transform an existing map to segment file.
  275. """
  276. row_buffer = Buffer((self._cols), self.mtype)
  277. for row in range(self._rows):
  278. libraster.Rast_get_row(
  279. self._fd, row_buffer.p, row, self._gtype)
  280. self.segment.put_row(row, row_buffer)
  281. @must_be_open
  282. def segment2map(self):
  283. """Transform the segment file to a map.
  284. """
  285. row_buffer = Buffer((self._cols), self.mtype)
  286. for row in range(self._rows):
  287. row_buffer = self.segment.get_row(row, row_buffer)
  288. libraster.Rast_put_row(self._fd, row_buffer.p, self._gtype)
  289. @must_be_open
  290. def get_row(self, row, row_buffer=None):
  291. """Return the row using the `segment.get_row` method
  292. :param row: specify the row number
  293. :type row: int
  294. :param row_buffer: specify the Buffer object that will be instantiate
  295. :type row_buffer: Buffer object
  296. """
  297. if row_buffer is None:
  298. row_buffer = Buffer((self._cols), self.mtype)
  299. return self.segment.get_row(row, row_buffer)
  300. @must_be_open
  301. def put_row(self, row, row_buffer):
  302. """Write the row using the `segment.put_row` method
  303. :param row: a Row object to insert into raster
  304. :type row: Buffer object
  305. """
  306. self.segment.put_row(row, row_buffer)
  307. @must_be_open
  308. def get(self, row, col):
  309. """Return the map value using the `segment.get` method
  310. :param row: Specify the row number
  311. :type row: int
  312. :param col: Specify the column number
  313. :type col: int
  314. """
  315. return self.segment.get(row, col)
  316. @must_be_open
  317. def put(self, row, col, val):
  318. """Write the value to the map using the `segment.put` method
  319. :param row: Specify the row number
  320. :type row: int
  321. :param col: Specify the column number
  322. :type col: int
  323. :param val: Specify the value that will be write to the map cell
  324. :type val: value
  325. """
  326. self.segment.val.value = val
  327. self.segment.put(row, col)
  328. def open(self, mode=None, mtype=None, overwrite=None):
  329. """Open the map, if the map already exist: determine the map type
  330. and copy the map to the segment files;
  331. else, open a new segment map.
  332. :param mode: specify if the map will be open with read, write or
  333. read/write mode ('r', 'w', 'rw')
  334. :type mode: str
  335. :param mtype: specify the map type, valid only for new maps: CELL,
  336. FCELL, DCELL
  337. :type mtype: str
  338. :param overwrite: use this flag to set the overwrite mode of existing
  339. raster maps
  340. :type overwrite: bool
  341. """
  342. # read rows and cols from the active region
  343. self._rows = libraster.Rast_window_rows()
  344. self._cols = libraster.Rast_window_cols()
  345. self.mode = mode if mode else self.mode
  346. self.mtype = mtype if mtype else self.mtype
  347. self.overwrite = overwrite if overwrite is not None else self.overwrite
  348. if self.exist():
  349. self.info.read()
  350. self.cats.mtype = self.mtype
  351. self.cats.read()
  352. self.hist.read()
  353. if ((self.mode == "w" or self.mode == "rw") and
  354. self.overwrite is False):
  355. str_err = _("Raster map <{0}> already exists. Use overwrite.")
  356. fatal(str_err.format(self))
  357. # We copy the raster map content into the segments
  358. if self.mode == "rw" or self.mode == "r":
  359. self._fd = libraster.Rast_open_old(self.name, self.mapset)
  360. self._gtype = libraster.Rast_get_map_type(self._fd)
  361. self.mtype = RTYPE_STR[self._gtype]
  362. # initialize the segment, I need to determine the mtype of the
  363. # map
  364. # before to open the segment
  365. self.segment.open(self)
  366. self.map2segment()
  367. self.segment.flush()
  368. self.cats.read(self)
  369. self.hist.read(self.name)
  370. if self.mode == "rw":
  371. warning(_(WARN_OVERWRITE.format(self)))
  372. # Close the file descriptor and open it as new again
  373. libraster.Rast_close(self._fd)
  374. self._fd = libraster.Rast_open_new(
  375. self.name, self._gtype)
  376. # Here we simply overwrite the existing map without content copying
  377. elif self.mode == "w":
  378. #warning(_(WARN_OVERWRITE.format(self)))
  379. self._gtype = RTYPE[self.mtype]['grass type']
  380. self.segment.open(self)
  381. self._fd = libraster.Rast_open_new(self.name, self._gtype)
  382. else:
  383. if self.mode == "r":
  384. str_err = _("Raster map <{0}> does not exists")
  385. raise OpenError(str_err.format(self.name))
  386. self._gtype = RTYPE[self.mtype]['grass type']
  387. self.segment.open(self)
  388. self._fd = libraster.Rast_open_new(self.name, self._gtype)
  389. @must_be_open
  390. def close(self, rm_temp_files=True):
  391. """Close the map, copy the segment files to the map.
  392. :param rm_temp_files: if True all the segments file will be removed
  393. :type rm_temp_files: bool
  394. """
  395. if self.mode == "w" or self.mode == "rw":
  396. self.segment.flush()
  397. self.segment2map()
  398. if rm_temp_files:
  399. self.segment.close()
  400. else:
  401. self.segment.release()
  402. libraster.Rast_close(self._fd)
  403. # update rows and cols attributes
  404. self._rows = None
  405. self._cols = None
  406. self._fd = None
  407. FLAGS = {1: {'b': 'i', 'i': 'i', 'u': 'i'},
  408. 2: {'b': 'i', 'i': 'i', 'u': 'i'},
  409. 4: {'f': 'f', 'i': 'i', 'b': 'i', 'u': 'i'},
  410. 8: {'f': 'd'}, }
  411. class RasterNumpy(np.memmap, RasterAbstractBase):
  412. """Raster_cached_narray": Inherits "Raster_abstract_base" and
  413. "numpy.memmap". Its purpose is to allow numpy narray like access to
  414. raster maps without loading the map into the main memory.
  415. * Behaves like a numpy array and supports all kind of mathematical
  416. operations: __add__, ...
  417. * Overrides the open and close methods
  418. * Be aware of the 2Gig file size limit
  419. >>> import grass.pygrass as pygrass
  420. >>> elev = pygrass.raster.RasterNumpy('elevation')
  421. >>> elev.open()
  422. >>> elev[:5, :3]
  423. RasterNumpy([[ 141.99613953, 141.27848816, 141.37904358],
  424. [ 142.90461731, 142.39450073, 142.68611145],
  425. [ 143.81854248, 143.54707336, 143.83972168],
  426. [ 144.56524658, 144.58493042, 144.86477661],
  427. [ 144.99488831, 145.22894287, 145.57142639]], dtype=float32)
  428. >>> el = elev < 144
  429. >>> el[:5, :3]
  430. RasterNumpy([[1, 1, 1],
  431. [1, 1, 1],
  432. [1, 1, 1],
  433. [0, 0, 0],
  434. [0, 0, 0]], dtype=int32)
  435. >>> el.exist()
  436. False
  437. >>> el.close('elev_bool', overwrite=True)
  438. >>> el.exist()
  439. True
  440. >>> el.remove()
  441. """
  442. def __new__(cls, name, mapset="", mtype='CELL', mode='r+',
  443. overwrite=False):
  444. reg = Region()
  445. shape = (reg.rows, reg.cols)
  446. mapset = libgis.G_find_raster(name, mapset)
  447. gtype = None
  448. if mapset:
  449. # map exist, set the map type
  450. gtype = libraster.Rast_map_type(name, mapset)
  451. mtype = RTYPE_STR[gtype]
  452. filename = grasscore.tempfile()
  453. obj = np.memmap.__new__(cls, filename=filename,
  454. dtype=RTYPE[mtype]['numpy'],
  455. mode=mode,
  456. shape=shape)
  457. obj.mtype = mtype.upper()
  458. obj.gtype = gtype if gtype else RTYPE[mtype]['grass type']
  459. obj._rows = reg.rows
  460. obj._cols = reg.cols
  461. obj.filename = filename
  462. obj._name = name
  463. obj.mapset = mapset
  464. obj.reg = reg
  465. obj.overwrite = overwrite
  466. return obj
  467. def __array_finalize__(self, obj):
  468. if hasattr(obj, '_mmap'):
  469. self._mmap = obj._mmap
  470. self.filename = grasscore.tempfile()
  471. self.offset = obj.offset
  472. self.mode = obj.mode
  473. self._rows = obj._rows
  474. self._cols = obj._cols
  475. self._name = None
  476. self.mapset = ''
  477. self.reg = obj.reg
  478. self.overwrite = obj.overwrite
  479. self.mtype = obj.mtype
  480. self._fd = obj._fd
  481. else:
  482. self._mmap = None
  483. def _get_mode(self):
  484. return self._mode
  485. def _set_mode(self, mode):
  486. if mode.lower() not in ('r', 'w+', 'r+', 'c'):
  487. raise ValueError(_("Mode type: {0} not supported.").format(mode))
  488. self._mode = mode
  489. mode = property(fget=_get_mode, fset=_set_mode,
  490. doc="Set or obtain the opening mode of raster")
  491. def __array_wrap__(self, out_arr, context=None):
  492. """See:
  493. http://docs.scipy.org/doc/numpy/user/
  494. basics.subclassing.html#array-wrap-for-ufuncs"""
  495. if out_arr.dtype.kind in 'bui':
  496. # there is not support for boolean maps, so convert into integer
  497. out_arr = out_arr.astype(np.int32)
  498. out_arr.mtype = 'CELL'
  499. #out_arr.p = out_arr.ctypes.data_as(out_arr.pointer_type)
  500. return np.ndarray.__array_wrap__(self, out_arr, context)
  501. def __init__(self, name, *args, **kargs):
  502. ## Private attribute `_fd` that return the file descriptor of the map
  503. self._fd = None
  504. rows, cols = self._rows, self._cols
  505. RasterAbstractBase.__init__(self, name)
  506. self._rows, self._cols = rows, cols
  507. def __unicode__(self):
  508. return RasterAbstractBase.__unicode__(self)
  509. def __str__(self):
  510. return self.__unicode__()
  511. def _get_flags(self, size, kind):
  512. if size in FLAGS:
  513. if kind in FLAGS[size]:
  514. return size, FLAGS[size][kind]
  515. else:
  516. raise ValueError(_('Invalid type {0}'.format(kind)))
  517. else:
  518. raise ValueError(_('Invalid size {0}'.format(size)))
  519. def _read(self):
  520. """!Read raster map into array
  521. @return 0 on success
  522. @return non-zero code on failure
  523. """
  524. with RasterRow(self.name, self.mapset, mode='r') as rst:
  525. buff = rst[0]
  526. for i in range(len(rst)):
  527. self[i] = rst.get_row(i, buff)
  528. def _write(self, name, overwrite):
  529. """Write the numpy array into map
  530. """
  531. if not self.exist() or self.mode != 'r':
  532. self.flush()
  533. buff = Buffer(self[0].shape, mtype=self.mtype)
  534. with RasterRow(name, self.mapset, mode='w',
  535. mtype=self.mtype, overwrite=overwrite) as rst:
  536. for i in range(len(rst)):
  537. buff[:] = self[i][:]
  538. rst.put_row(buff[:])
  539. self.name = name
  540. def open(self, mtype='', null=None, overwrite=None):
  541. """Open the map, if the map already exist: determine the map type
  542. and copy the map to the segment files;
  543. else, open a new segment map.
  544. :param mtype: specify the map type, valid only for new maps: CELL,
  545. FCELL, DCELL;
  546. :type mtype: str
  547. :param null:
  548. :type null:
  549. :param overwrite: use this flag to set the overwrite mode of existing
  550. raster maps
  551. :type overwrite: bool
  552. """
  553. if overwrite is not None:
  554. self.overwrite = overwrite
  555. self.null = null
  556. # rows and cols already set in __new__
  557. if self.exist():
  558. self.info.read()
  559. self.cats.mtype = self.mtype
  560. self.cats.read()
  561. self.hist.read()
  562. self._read()
  563. else:
  564. if mtype:
  565. self.mtype = mtype
  566. self._gtype = RTYPE[self.mtype]['grass type']
  567. # set _fd, because this attribute is used to check
  568. # if the map is open or not
  569. self._fd = 1
  570. def close(self, name='', overwrite=False):
  571. """Function to close the map
  572. :param name: the name of raster
  573. :type name: str
  574. """
  575. if self.is_open():
  576. name = name if name else self.name
  577. if not name:
  578. raise RuntimeError('Raster name not set neither '
  579. 'given as parameter.')
  580. self._write(name, overwrite)
  581. os.remove(self.filename)
  582. self._fd = None
  583. def get_value(self, point, region=None):
  584. """This method returns the pixel value of a given pair of coordinates:
  585. :param point: pair of coordinates in tuple object
  586. :type point: tuple
  587. :param region: the region to crop the request
  588. :type region: Region object
  589. """
  590. if not region:
  591. region = Region()
  592. x, y = functions.coor2pixel(point.coords(), region)
  593. return self[x][y]
  594. def random_map_only_columns(mapname, mtype, overwrite=True, factor=100):
  595. region = Region()
  596. random_map = RasterRow(mapname)
  597. row_buf = Buffer((region.cols, ), mtype,
  598. buffer=(np.random.random(region.cols,) * factor).data)
  599. random_map.open('w', mtype, overwrite)
  600. for _ in range(region.rows):
  601. random_map.put_row(row_buf)
  602. random_map.close()
  603. return random_map
  604. def random_map(mapname, mtype, overwrite=True, factor=100):
  605. region = Region()
  606. random_map = RasterRow(mapname)
  607. random_map.open('w', mtype, overwrite)
  608. for _ in range(region.rows):
  609. row_buf = Buffer((region.cols, ), mtype,
  610. buffer=(np.random.random(region.cols,) * factor).data)
  611. random_map.put_row(row_buf)
  612. random_map.close()
  613. return random_map