| 1 | # -*- coding: utf-8 -*-
|
|---|
| 2 | import itertools
|
|---|
| 3 | import fnmatch
|
|---|
| 4 | import os
|
|---|
| 5 | from sqlite3 import OperationalError
|
|---|
| 6 |
|
|---|
| 7 | import grass.lib.gis as libgis
|
|---|
| 8 | libgis.G_gisinit('')
|
|---|
| 9 | import grass.lib.raster as libraster
|
|---|
| 10 | from grass.lib.ctypes_preamble import String
|
|---|
| 11 | from grass.script import core as grasscore
|
|---|
| 12 | from grass.script import utils as grassutils
|
|---|
| 13 |
|
|---|
| 14 | from grass.pygrass.errors import GrassError
|
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 | test_vector_name="Utils_test_vector"
|
|---|
| 18 | test_raster_name="Utils_test_raster"
|
|---|
| 19 |
|
|---|
| 20 | def looking(obj, filter_string):
|
|---|
| 21 | """
|
|---|
| 22 | >>> import grass.lib.vector as libvect
|
|---|
| 23 | >>> sorted(looking(libvect, '*by_box*')) # doctest: +NORMALIZE_WHITESPACE
|
|---|
| 24 | ['Vect_select_areas_by_box', 'Vect_select_isles_by_box',
|
|---|
| 25 | 'Vect_select_lines_by_box', 'Vect_select_nodes_by_box']
|
|---|
| 26 |
|
|---|
| 27 | """
|
|---|
| 28 | word_list = dir(obj)
|
|---|
| 29 | word_list.sort()
|
|---|
| 30 | return fnmatch.filter(word_list, filter_string)
|
|---|
| 31 |
|
|---|
| 32 |
|
|---|
| 33 | def findfiles(dirpath, match=None):
|
|---|
| 34 | """Return a list of the files"""
|
|---|
| 35 | res = []
|
|---|
| 36 | for f in sorted(os.listdir(dirpath)):
|
|---|
| 37 | abspath = os.path.join(dirpath, f)
|
|---|
| 38 | if os.path.isdir(abspath):
|
|---|
| 39 | res.extend(findfiles(abspath, match))
|
|---|
| 40 |
|
|---|
| 41 | if match:
|
|---|
| 42 | if fnmatch.fnmatch(abspath, match):
|
|---|
| 43 | res.append(abspath)
|
|---|
| 44 | else:
|
|---|
| 45 | res.append(abspath)
|
|---|
| 46 | return res
|
|---|
| 47 |
|
|---|
| 48 |
|
|---|
| 49 | def findmaps(type, pattern=None, mapset='', location='', gisdbase=''):
|
|---|
| 50 | """Return a list of tuple contining the names of the:
|
|---|
| 51 |
|
|---|
| 52 | * map
|
|---|
| 53 | * mapset,
|
|---|
| 54 | * location,
|
|---|
| 55 | * gisdbase
|
|---|
| 56 |
|
|---|
| 57 | """
|
|---|
| 58 | from grass.pygrass.gis import Gisdbase, Location, Mapset
|
|---|
| 59 |
|
|---|
| 60 | def find_in_location(type, pattern, location):
|
|---|
| 61 | res = []
|
|---|
| 62 | for msetname in location.mapsets():
|
|---|
| 63 | mset = Mapset(msetname, location.name, location.gisdbase)
|
|---|
| 64 | res.extend([(m, mset.name, mset.location, mset.gisdbase)
|
|---|
| 65 | for m in mset.glist(type, pattern)])
|
|---|
| 66 | return res
|
|---|
| 67 |
|
|---|
| 68 | def find_in_gisdbase(type, pattern, gisdbase):
|
|---|
| 69 | res = []
|
|---|
| 70 | for loc in gisdbase.locations():
|
|---|
| 71 | res.extend(find_in_location(type, pattern,
|
|---|
| 72 | Location(loc, gisdbase.name)))
|
|---|
| 73 | return res
|
|---|
| 74 |
|
|---|
| 75 | if gisdbase and location and mapset:
|
|---|
| 76 | mset = Mapset(mapset, location, gisdbase)
|
|---|
| 77 | return [(m, mset.name, mset.location, mset.gisdbase)
|
|---|
| 78 | for m in mset.glist(type, pattern)]
|
|---|
| 79 | elif gisdbase and location:
|
|---|
| 80 | loc = Location(location, gisdbase)
|
|---|
| 81 | return find_in_location(type, pattern, loc)
|
|---|
| 82 | elif gisdbase:
|
|---|
| 83 | gis = Gisdbase(gisdbase)
|
|---|
| 84 | return find_in_gisdbase(type, pattern, gis)
|
|---|
| 85 | elif location:
|
|---|
| 86 | loc = Location(location)
|
|---|
| 87 | return find_in_location(type, pattern, loc)
|
|---|
| 88 | elif mapset:
|
|---|
| 89 | mset = Mapset(mapset)
|
|---|
| 90 | return [(m, mset.name, mset.location, mset.gisdbase)
|
|---|
| 91 | for m in mset.glist(type, pattern)]
|
|---|
| 92 | else:
|
|---|
| 93 | gis = Gisdbase()
|
|---|
| 94 | return find_in_gisdbase(type, pattern, gis)
|
|---|
| 95 |
|
|---|
| 96 |
|
|---|
| 97 | def remove(oldname, maptype):
|
|---|
| 98 | """Remove a map"""
|
|---|
| 99 | grasscore.run_command('g.remove', quiet=True, flags='f',
|
|---|
| 100 | type=maptype, name=oldname)
|
|---|
| 101 |
|
|---|
| 102 |
|
|---|
| 103 | def rename(oldname, newname, maptype, **kwargs):
|
|---|
| 104 | """Rename a map"""
|
|---|
| 105 | kwargs.update({maptype: '{old},{new}'.format(old=oldname, new=newname), })
|
|---|
| 106 | grasscore.run_command('g.rename', quiet=True, **kwargs)
|
|---|
| 107 |
|
|---|
| 108 |
|
|---|
| 109 | def copy(existingmap, newmap, maptype, **kwargs):
|
|---|
| 110 | """Copy a map
|
|---|
| 111 |
|
|---|
| 112 | >>> copy(test_vector_name, 'mycensus', 'vector')
|
|---|
| 113 | >>> rename('mycensus', 'mynewcensus', 'vector')
|
|---|
| 114 | >>> remove('mynewcensus', 'vector')
|
|---|
| 115 |
|
|---|
| 116 | """
|
|---|
| 117 | kwargs.update({maptype: '{old},{new}'.format(old=existingmap, new=newmap)})
|
|---|
| 118 | grasscore.run_command('g.copy', quiet=True, **kwargs)
|
|---|
| 119 |
|
|---|
| 120 |
|
|---|
| 121 | def decode(obj, encoding=None):
|
|---|
| 122 | """Decode string coming from c functions,
|
|---|
| 123 | can be ctypes class String, bytes, or None
|
|---|
| 124 | """
|
|---|
| 125 | if isinstance(obj, String):
|
|---|
| 126 | return grassutils.decode(obj.data, encoding=encoding)
|
|---|
| 127 | elif isinstance(obj, bytes):
|
|---|
| 128 | return grassutils.decode(obj)
|
|---|
| 129 | else:
|
|---|
| 130 | # eg None
|
|---|
| 131 | return obj
|
|---|
| 132 |
|
|---|
| 133 |
|
|---|
| 134 | def getenv(env):
|
|---|
| 135 | """Return the current grass environment variables
|
|---|
| 136 |
|
|---|
| 137 | >>> from grass.script.core import gisenv
|
|---|
| 138 | >>> getenv("MAPSET") == gisenv()["MAPSET"]
|
|---|
| 139 | True
|
|---|
| 140 |
|
|---|
| 141 | """
|
|---|
| 142 | return decode(libgis.G_getenv_nofatal(env))
|
|---|
| 143 |
|
|---|
| 144 |
|
|---|
| 145 | def get_mapset_raster(mapname, mapset=''):
|
|---|
| 146 | """Return the mapset of the raster map
|
|---|
| 147 |
|
|---|
| 148 | >>> get_mapset_raster(test_raster_name) == getenv("MAPSET")
|
|---|
| 149 | True
|
|---|
| 150 |
|
|---|
| 151 | """
|
|---|
| 152 | return decode(libgis.G_find_raster2(mapname, mapset))
|
|---|
| 153 |
|
|---|
| 154 |
|
|---|
| 155 | def get_mapset_vector(mapname, mapset=''):
|
|---|
| 156 | """Return the mapset of the vector map
|
|---|
| 157 |
|
|---|
| 158 | >>> get_mapset_vector(test_vector_name) == getenv("MAPSET")
|
|---|
| 159 | True
|
|---|
| 160 |
|
|---|
| 161 | """
|
|---|
| 162 | return decode(libgis.G_find_vector2(mapname, mapset))
|
|---|
| 163 |
|
|---|
| 164 |
|
|---|
| 165 | def is_clean_name(name):
|
|---|
| 166 | """Return if the name is valid
|
|---|
| 167 |
|
|---|
| 168 | >>> is_clean_name('census')
|
|---|
| 169 | True
|
|---|
| 170 | >>> is_clean_name('0census')
|
|---|
| 171 | True
|
|---|
| 172 | >>> is_clean_name('census?')
|
|---|
| 173 | True
|
|---|
| 174 | >>> is_clean_name('cénsus')
|
|---|
| 175 | False
|
|---|
| 176 |
|
|---|
| 177 | """
|
|---|
| 178 | if libgis.G_legal_filename(name) < 0:
|
|---|
| 179 | return False
|
|---|
| 180 | return True
|
|---|
| 181 |
|
|---|
| 182 |
|
|---|
| 183 | def coor2pixel(coord, region):
|
|---|
| 184 | """Convert coordinates into a pixel row and col
|
|---|
| 185 |
|
|---|
| 186 | >>> from grass.pygrass.gis.region import Region
|
|---|
| 187 | >>> reg = Region()
|
|---|
| 188 | >>> coor2pixel((reg.west, reg.north), reg)
|
|---|
| 189 | (0.0, 0.0)
|
|---|
| 190 | >>> coor2pixel((reg.east, reg.south), reg) == (reg.rows, reg.cols)
|
|---|
| 191 | True
|
|---|
| 192 |
|
|---|
| 193 | """
|
|---|
| 194 | (east, north) = coord
|
|---|
| 195 | return (libraster.Rast_northing_to_row(north, region.byref()),
|
|---|
| 196 | libraster.Rast_easting_to_col(east, region.byref()))
|
|---|
| 197 |
|
|---|
| 198 |
|
|---|
| 199 | def pixel2coor(pixel, region):
|
|---|
| 200 | """Convert row and col of a pixel into a coordinates
|
|---|
| 201 |
|
|---|
| 202 | >>> from grass.pygrass.gis.region import Region
|
|---|
| 203 | >>> reg = Region()
|
|---|
| 204 | >>> pixel2coor((0, 0), reg) == (reg.north, reg.west)
|
|---|
| 205 | True
|
|---|
| 206 | >>> pixel2coor((reg.cols, reg.rows), reg) == (reg.south, reg.east)
|
|---|
| 207 | True
|
|---|
| 208 |
|
|---|
| 209 | """
|
|---|
| 210 | (col, row) = pixel
|
|---|
| 211 | return (libraster.Rast_row_to_northing(row, region.byref()),
|
|---|
| 212 | libraster.Rast_col_to_easting(col, region.byref()))
|
|---|
| 213 |
|
|---|
| 214 |
|
|---|
| 215 | def get_raster_for_points(poi_vector, raster, column=None, region=None):
|
|---|
| 216 | """Query a raster map for each point feature of a vector
|
|---|
| 217 |
|
|---|
| 218 | Example
|
|---|
| 219 |
|
|---|
| 220 | >>> from grass.pygrass.raster import RasterRow
|
|---|
| 221 | >>> from grass.pygrass.gis.region import Region
|
|---|
| 222 | >>> from grass.pygrass.vector import VectorTopo
|
|---|
| 223 | >>> from grass.pygrass.vector.geometry import Point
|
|---|
| 224 |
|
|---|
| 225 | Create a vector map
|
|---|
| 226 |
|
|---|
| 227 | >>> cols = [(u'cat', 'INTEGER PRIMARY KEY'),
|
|---|
| 228 | ... (u'value', 'double precision')]
|
|---|
| 229 | >>> vect = VectorTopo("test_vect_2")
|
|---|
| 230 | >>> vect.open("w",tab_name="test_vect_2",
|
|---|
| 231 | ... tab_cols=cols)
|
|---|
| 232 | >>> vect.write(Point(10, 6), cat=1, attrs=[10, ])
|
|---|
| 233 | >>> vect.write(Point(12, 6), cat=2, attrs=[12, ])
|
|---|
| 234 | >>> vect.write(Point(14, 6), cat=3, attrs=[14, ])
|
|---|
| 235 | >>> vect.table.conn.commit()
|
|---|
| 236 | >>> vect.close()
|
|---|
| 237 |
|
|---|
| 238 | Setup the raster sampling
|
|---|
| 239 |
|
|---|
| 240 | >>> region = Region()
|
|---|
| 241 | >>> region.from_rast(test_raster_name)
|
|---|
| 242 | >>> region.set_raster_region()
|
|---|
| 243 | >>> ele = RasterRow(test_raster_name)
|
|---|
| 244 |
|
|---|
| 245 | Sample the raster layer at the given points, return a list of values
|
|---|
| 246 |
|
|---|
| 247 | >>> l = get_raster_for_points(vect, ele, region=region)
|
|---|
| 248 | >>> l[0] # doctest: +ELLIPSIS
|
|---|
| 249 | (1, 10.0, 6.0, 1)
|
|---|
| 250 | >>> l[1] # doctest: +ELLIPSIS
|
|---|
| 251 | (2, 12.0, 6.0, 1)
|
|---|
| 252 |
|
|---|
| 253 | Add a new column and sample again
|
|---|
| 254 |
|
|---|
| 255 | >>> vect.open("r")
|
|---|
| 256 | >>> vect.table.columns.add(test_raster_name,'double precision')
|
|---|
| 257 | >>> vect.table.conn.commit()
|
|---|
| 258 | >>> test_raster_name in vect.table.columns
|
|---|
| 259 | True
|
|---|
| 260 | >>> get_raster_for_points(vect, ele, column=test_raster_name, region=region)
|
|---|
| 261 | True
|
|---|
| 262 | >>> vect.table.filters.select('value', test_raster_name)
|
|---|
| 263 | Filters(u'SELECT value, Utils_test_raster FROM test_vect_2;')
|
|---|
| 264 | >>> cur = vect.table.execute()
|
|---|
| 265 | >>> r = cur.fetchall()
|
|---|
| 266 | >>> r[0] # doctest: +ELLIPSIS
|
|---|
| 267 | (10.0, 1.0)
|
|---|
| 268 | >>> r[1] # doctest: +ELLIPSIS
|
|---|
| 269 | (12.0, 1.0)
|
|---|
| 270 | >>> remove('test_vect_2','vect')
|
|---|
| 271 |
|
|---|
| 272 | :param poi_vector: A VectorTopo object that contains points
|
|---|
| 273 | :param raster: raster object
|
|---|
| 274 | :param str column: column name to update in the attrinute table,
|
|---|
| 275 | if set to None a list of sampled values will be returned
|
|---|
| 276 | :param region: The region to work with, if not set the current computational region will be used
|
|---|
| 277 |
|
|---|
| 278 | :return: True in case of success and a specified column for update,
|
|---|
| 279 | if column name for update was not set a list of (id, x, y, value) is returned
|
|---|
| 280 | """
|
|---|
| 281 | from math import isnan
|
|---|
| 282 | if not column:
|
|---|
| 283 | result = []
|
|---|
| 284 | if region is None:
|
|---|
| 285 | from grass.pygrass.gis.region import Region
|
|---|
| 286 | region = Region()
|
|---|
| 287 | if not poi_vector.is_open():
|
|---|
| 288 | poi_vector.open("r")
|
|---|
| 289 | if not raster.is_open():
|
|---|
| 290 | raster.open("r")
|
|---|
| 291 | if poi_vector.num_primitive_of('point') == 0:
|
|---|
| 292 | raise GrassError(_("Vector doesn't contain points"))
|
|---|
| 293 |
|
|---|
| 294 | for poi in poi_vector.viter('points'):
|
|---|
| 295 | val = raster.get_value(poi, region)
|
|---|
| 296 | if column:
|
|---|
| 297 | if val is not None and not isnan(val):
|
|---|
| 298 | poi.attrs[column] = val
|
|---|
| 299 | else:
|
|---|
| 300 | if val is not None and not isnan(val):
|
|---|
| 301 | result.append((poi.id, poi.x, poi.y, val))
|
|---|
| 302 | else:
|
|---|
| 303 | result.append((poi.id, poi.x, poi.y, None))
|
|---|
| 304 | if not column:
|
|---|
| 305 | return result
|
|---|
| 306 | else:
|
|---|
| 307 | poi.attrs.commit()
|
|---|
| 308 | return True
|
|---|
| 309 |
|
|---|
| 310 |
|
|---|
| 311 | def r_export(rast, output='', fmt='png', **kargs):
|
|---|
| 312 | from grass.pygrass.modules import Module
|
|---|
| 313 | if rast.exist():
|
|---|
| 314 | output = output if output else "%s_%s.%s" % (rast.name, rast.mapset,
|
|---|
| 315 | fmt)
|
|---|
| 316 | Module('r.out.%s' % fmt, input=rast.fullname(), output=output,
|
|---|
| 317 | overwrite=True, **kargs)
|
|---|
| 318 | return output
|
|---|
| 319 | else:
|
|---|
| 320 | raise ValueError('Raster map does not exist.')
|
|---|
| 321 |
|
|---|
| 322 |
|
|---|
| 323 | def get_lib_path(modname, libname=None):
|
|---|
| 324 | """Return the path of the libname contained in the module.
|
|---|
| 325 |
|
|---|
| 326 | .. deprecated:: 7.1
|
|---|
| 327 | Use :func:`grass.script.utils.get_lib_path` instead.
|
|---|
| 328 | """
|
|---|
| 329 | from grass.script.utils import get_lib_path
|
|---|
| 330 | return get_lib_path(modname=modname, libname=libname)
|
|---|
| 331 |
|
|---|
| 332 |
|
|---|
| 333 | def set_path(modulename, dirname=None, path='.'):
|
|---|
| 334 | """Set sys.path looking in the the local directory GRASS directories.
|
|---|
| 335 |
|
|---|
| 336 | :param modulename: string with the name of the GRASS module
|
|---|
| 337 | :param dirname: string with the directory name containing the python
|
|---|
| 338 | libraries, default None
|
|---|
| 339 | :param path: string with the path to reach the dirname locally.
|
|---|
| 340 |
|
|---|
| 341 | .. deprecated:: 7.1
|
|---|
| 342 | Use :func:`grass.script.utils.set_path` instead.
|
|---|
| 343 | """
|
|---|
| 344 | from grass.script.utils import set_path
|
|---|
| 345 | return set_path(modulename=modulename, dirname=dirname, path=path)
|
|---|
| 346 |
|
|---|
| 347 |
|
|---|
| 348 | def split_in_chunk(iterable, length=10):
|
|---|
| 349 | """Split a list in chunk.
|
|---|
| 350 |
|
|---|
| 351 | >>> for chunk in split_in_chunk(range(25)): print chunk
|
|---|
| 352 | (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
|
|---|
| 353 | (10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
|
|---|
| 354 | (20, 21, 22, 23, 24)
|
|---|
| 355 | >>> for chunk in split_in_chunk(range(25), 3): print chunk
|
|---|
| 356 | (0, 1, 2)
|
|---|
| 357 | (3, 4, 5)
|
|---|
| 358 | (6, 7, 8)
|
|---|
| 359 | (9, 10, 11)
|
|---|
| 360 | (12, 13, 14)
|
|---|
| 361 | (15, 16, 17)
|
|---|
| 362 | (18, 19, 20)
|
|---|
| 363 | (21, 22, 23)
|
|---|
| 364 | (24,)
|
|---|
| 365 | """
|
|---|
| 366 | it = iter(iterable)
|
|---|
| 367 | while True:
|
|---|
| 368 | chunk = tuple(itertools.islice(it, length))
|
|---|
| 369 | if not chunk:
|
|---|
| 370 | return
|
|---|
| 371 | yield chunk
|
|---|
| 372 |
|
|---|
| 373 |
|
|---|
| 374 | def table_exist(cursor, table_name):
|
|---|
| 375 | """Return True if the table exist False otherwise"""
|
|---|
| 376 | try:
|
|---|
| 377 | # sqlite
|
|---|
| 378 | cursor.execute("SELECT name FROM sqlite_master"
|
|---|
| 379 | " WHERE type='table' AND name='%s';" % table_name)
|
|---|
| 380 | except OperationalError:
|
|---|
| 381 | try:
|
|---|
| 382 | # pg
|
|---|
| 383 | cursor.execute("SELECT EXISTS(SELECT * FROM "
|
|---|
| 384 | "information_schema.tables "
|
|---|
| 385 | "WHERE table_name=%s)" % table_name)
|
|---|
| 386 | except OperationalError:
|
|---|
| 387 | return False
|
|---|
| 388 | one = cursor.fetchone() if cursor else None
|
|---|
| 389 | return True if one and one[0] else False
|
|---|
| 390 |
|
|---|
| 391 |
|
|---|
| 392 | def create_test_vector_map(map_name="test_vector"):
|
|---|
| 393 | """This functions creates a vector map layer with points, lines, boundaries,
|
|---|
| 394 | centroids, areas, isles and attributes for testing purposes
|
|---|
| 395 |
|
|---|
| 396 | This should be used in doc and unit tests to create location/mapset
|
|---|
| 397 | independent vector map layer. This map includes 3 points, 3 lines,
|
|---|
| 398 | 11 boundaries and 4 centroids. The attribute table contains cat, name
|
|---|
| 399 | and value columns.
|
|---|
| 400 |
|
|---|
| 401 | param map_name: The vector map name that should be used
|
|---|
| 402 |
|
|---|
| 403 |
|
|---|
| 404 |
|
|---|
| 405 | P1 P2 P3
|
|---|
| 406 | 6 * * *
|
|---|
| 407 | 5
|
|---|
| 408 | 4 _______ ___ ___ L1 L2 L3
|
|---|
| 409 | Y 3 |A1___ *| *| *| | | |
|
|---|
| 410 | 2 | |A2*| | | | | | |
|
|---|
| 411 | 1 | |___| |A3 |A4 | | | |
|
|---|
| 412 | 0 |_______|___|___| | | |
|
|---|
| 413 | -1
|
|---|
| 414 | -1 0 1 2 3 4 5 6 7 8 9 10 12 14
|
|---|
| 415 | X
|
|---|
| 416 | """
|
|---|
| 417 |
|
|---|
| 418 | from grass.pygrass.vector import VectorTopo
|
|---|
| 419 | from grass.pygrass.vector.geometry import Point, Line, Centroid, Boundary
|
|---|
| 420 |
|
|---|
| 421 | cols = [(u'cat', 'INTEGER PRIMARY KEY'),
|
|---|
| 422 | (u'name','varchar(50)'),
|
|---|
| 423 | (u'value', 'double precision')]
|
|---|
| 424 | with VectorTopo(map_name, mode='w', tab_name=map_name,
|
|---|
| 425 | tab_cols=cols) as vect:
|
|---|
| 426 |
|
|---|
| 427 | # Write 3 points
|
|---|
| 428 | vect.write(Point(10, 6), cat=1, attrs=("point", 1))
|
|---|
| 429 | vect.write(Point(12, 6), cat=1)
|
|---|
| 430 | vect.write(Point(14, 6), cat=1)
|
|---|
| 431 | # Write 3 lines
|
|---|
| 432 | vect.write(Line([(10, 4), (10, 2), (10,0)]), cat=2, attrs=("line", 2))
|
|---|
| 433 | vect.write(Line([(12, 4), (12, 2), (12,0)]), cat=2)
|
|---|
| 434 | vect.write(Line([(14, 4), (14, 2), (14,0)]), cat=2)
|
|---|
| 435 | # boundaries 1 - 4
|
|---|
| 436 | vect.write(Boundary(points=[(0, 0), (0,4)]))
|
|---|
| 437 | vect.write(Boundary(points=[(0, 4), (4,4)]))
|
|---|
| 438 | vect.write(Boundary(points=[(4, 4), (4,0)]))
|
|---|
| 439 | vect.write(Boundary(points=[(4, 0), (0,0)]))
|
|---|
| 440 | # 5. boundary (Isle)
|
|---|
| 441 | vect.write(Boundary(points=[(1, 1), (1,3), (3, 3), (3,1), (1,1)]))
|
|---|
| 442 | # boundaries 6 - 8
|
|---|
| 443 | vect.write(Boundary(points=[(4, 4), (6,4)]))
|
|---|
| 444 | vect.write(Boundary(points=[(6, 4), (6,0)]))
|
|---|
| 445 | vect.write(Boundary(points=[(6, 0), (4,0)]))
|
|---|
| 446 | # boundaries 9 - 11
|
|---|
| 447 | vect.write(Boundary(points=[(6, 4), (8,4)]))
|
|---|
| 448 | vect.write(Boundary(points=[(8, 4), (8,0)]))
|
|---|
| 449 | vect.write(Boundary(points=[(8, 0), (6,0)]))
|
|---|
| 450 | # Centroids, all have the same cat and attribute
|
|---|
| 451 | vect.write(Centroid(x=3.5, y=3.5), cat=3, attrs=("centroid", 3))
|
|---|
| 452 | vect.write(Centroid(x=2.5, y=2.5), cat=3)
|
|---|
| 453 | vect.write(Centroid(x=5.5, y=3.5), cat=3)
|
|---|
| 454 | vect.write(Centroid(x=7.5, y=3.5), cat=3)
|
|---|
| 455 |
|
|---|
| 456 | vect.organization = 'Thuenen Institut'
|
|---|
| 457 | vect.person = 'Soeren Gebbert'
|
|---|
| 458 | vect.title = 'Test dataset'
|
|---|
| 459 | vect.comment = 'This is a comment'
|
|---|
| 460 |
|
|---|
| 461 | vect.table.conn.commit()
|
|---|
| 462 |
|
|---|
| 463 | vect.organization = "Thuenen Institut"
|
|---|
| 464 | vect.person = "Soeren Gebbert"
|
|---|
| 465 | vect.title = "Test dataset"
|
|---|
| 466 | vect.comment = "This is a comment"
|
|---|
| 467 | vect.close()
|
|---|
| 468 |
|
|---|
| 469 | def create_test_stream_network_map(map_name="streams"):
|
|---|
| 470 | """
|
|---|
| 471 | This functions creates a vector map layer with lines that represent
|
|---|
| 472 | a stream network with two different graphs. The first graph
|
|---|
| 473 | contains a loop, the second can be used as directed graph.
|
|---|
| 474 |
|
|---|
| 475 | This should be used in doc and unit tests to create location/mapset
|
|---|
| 476 | independent vector map layer.
|
|---|
| 477 |
|
|---|
| 478 | param map_name: The vector map name that should be used
|
|---|
| 479 |
|
|---|
| 480 | 1(0,2) 3(2,2)
|
|---|
| 481 | \ /
|
|---|
| 482 | 1 \ / 2
|
|---|
| 483 | \ /
|
|---|
| 484 | 2(1,1)
|
|---|
| 485 | 6(0,1) || 5(2,1)
|
|---|
| 486 | 5 \ || / 4
|
|---|
| 487 | \||/
|
|---|
| 488 | 4(1,0)
|
|---|
| 489 | |
|
|---|
| 490 | | 6
|
|---|
| 491 | |7(1,-1)
|
|---|
| 492 |
|
|---|
| 493 | 7(0,-1) 8(2,-1)
|
|---|
| 494 | \ /
|
|---|
| 495 | 8 \ / 9
|
|---|
| 496 | \ /
|
|---|
| 497 | 9(1, -2)
|
|---|
| 498 | |
|
|---|
| 499 | | 10
|
|---|
| 500 | |
|
|---|
| 501 | 10(1,-3)
|
|---|
| 502 | """
|
|---|
| 503 |
|
|---|
| 504 | from grass.pygrass.vector import VectorTopo
|
|---|
| 505 | from grass.pygrass.vector.geometry import Line
|
|---|
| 506 |
|
|---|
| 507 | cols = [(u'cat', 'INTEGER PRIMARY KEY'), (u'id', 'INTEGER')]
|
|---|
| 508 | with VectorTopo(map_name, mode='w', tab_name=map_name,
|
|---|
| 509 | tab_cols=cols) as streams:
|
|---|
| 510 |
|
|---|
| 511 | # First flow graph
|
|---|
| 512 | l = Line([(0,2), (0.22, 1.75), (0.55, 1.5), (1,1)])
|
|---|
| 513 | streams.write(l, cat=1, attrs=(1,))
|
|---|
| 514 | l = Line([(2,2),(1,1)])
|
|---|
| 515 | streams.write(l, cat=2, attrs=(2,))
|
|---|
| 516 | l = Line([(1,1), (0.85, 0.5), (1,0)])
|
|---|
| 517 | streams.write(l, cat=3, attrs=(3,))
|
|---|
| 518 | l = Line([(2,1),(1,0)])
|
|---|
| 519 | streams.write(l, cat=4, attrs=(4,))
|
|---|
| 520 | l = Line([(0,1),(1,0)])
|
|---|
| 521 | streams.write(l, cat=5, attrs=(5,))
|
|---|
| 522 | l = Line([(1,0),(1,-1)])
|
|---|
| 523 | streams.write(l, cat=6, attrs=(6,))
|
|---|
| 524 | # Reverse line 3
|
|---|
| 525 | l = Line([(1,0), (1.15, 0.5),(1,1)])
|
|---|
| 526 | streams.write(l, cat=7, attrs=(7,))
|
|---|
| 527 |
|
|---|
| 528 | # second flow graph
|
|---|
| 529 | l = Line([(0,-1),(1,-2)])
|
|---|
| 530 | streams.write(l, cat=8, attrs=(8,))
|
|---|
| 531 | l = Line([(2,-1),(1,-2)])
|
|---|
| 532 | streams.write(l, cat=9, attrs=(9,))
|
|---|
| 533 | l = Line([(1,-2),(1,-3)])
|
|---|
| 534 | streams.write(l, cat=10, attrs=(10,))
|
|---|
| 535 |
|
|---|
| 536 | streams.organization = 'Thuenen Institut'
|
|---|
| 537 | streams.person = 'Soeren Gebbert'
|
|---|
| 538 | streams.title = 'Test dataset for stream networks'
|
|---|
| 539 | streams.comment = 'This is a comment'
|
|---|
| 540 |
|
|---|
| 541 | streams.table.conn.commit()
|
|---|
| 542 | streams.close()
|
|---|
| 543 |
|
|---|
| 544 | if __name__ == "__main__":
|
|---|
| 545 |
|
|---|
| 546 | import doctest
|
|---|
| 547 | from grass.pygrass import utils
|
|---|
| 548 | from grass.script.core import run_command
|
|---|
| 549 |
|
|---|
| 550 | utils.create_test_vector_map(test_vector_name)
|
|---|
| 551 | run_command("g.region", n=50, s=0, e=60, w=0, res=1)
|
|---|
| 552 | run_command("r.mapcalc", expression="%s = 1"%(test_raster_name),
|
|---|
| 553 | overwrite=True)
|
|---|
| 554 |
|
|---|
| 555 | doctest.testmod()
|
|---|
| 556 |
|
|---|
| 557 | """Remove the generated vector map, if exist"""
|
|---|
| 558 | mset = utils.get_mapset_vector(test_vector_name, mapset='')
|
|---|
| 559 | if mset:
|
|---|
| 560 | run_command("g.remove", flags='f', type='vector', name=test_vector_name)
|
|---|
| 561 | mset = utils.get_mapset_raster(test_raster_name, mapset='')
|
|---|
| 562 | if mset:
|
|---|
| 563 | run_command("g.remove", flags='f', type='raster', name=test_raster_name)
|
|---|