__init__.py 23 KB

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