def _set_c_cat(self, label, min_cat, max_cat=None): """Adds the label for range min through max in category structure cats. int Rast_set_cat(const void * rast1, const void * rast2, const char * label, struct Categories * pcats, RASTER_MAP_TYPE data_type ) """ max_cat = min_cat if max_cat is None else max_cat min_cat = ctypes.pointer(RTYPE[self.mtype]["grass def"](min_cat)) max_cat = ctypes.pointer(RTYPE[self.mtype]["grass def"](max_cat)) err = libraster.Rast_set_cat( ctypes.cast(min_cat, ctypes.c_void_p), ctypes.cast(max_cat, ctypes.c_void_p), label, ctypes.byref(self.c_cats), self._gtype, ) # Manage C function Errors if err == 1: return None elif err == 0: raise GrassError(_("Null value detected")) elif err == -1: raise GrassError(_("Error executing: Rast_set_cat"))
def set_default(self): """Set the Region object to the default GRASS region. It works only in PERMANENT mapset""" from grass.pygrass.gis import Mapset mapset = Mapset() if mapset.name != 'PERMANENT': raise GrassError("ERROR: Unable to change default region. The " \ "current mapset is not <PERMANENT>.") self.adjust() if libgis.G_put_window(self.c_region) < 0: raise GrassError("Cannot change region (DEFAUL_WIND file).")
def build(self): """Close the vector map and build vector Topology""" self.close() libvect.Vect_set_open_level(1) if libvect.Vect_open_old2(self.c_mapinfo, self.name, self.mapset, '0') != 1: str_err = 'Error when trying to open the vector map.' raise GrassError(str_err) # Vect_build returns 1 on success and 0 on error (bool approach) if libvect.Vect_build(self.c_mapinfo) != 1: str_err = 'Error when trying build topology with Vect_build' raise GrassError(str_err) libvect.Vect_close(self.c_mapinfo)
def _check(value, path, type): """Private function to check the correctness of a value. :param value: Name of the directory :type value: str :param path: Path where the directory is located :type path: path :param type: it is a string defining the type that will e checked, valid types are: GISBASE, GISDBASE, LOCATION_NAME, MAPSET :type type: str :return: the value if verify else None and if value is empty return environmental variable :rtype: str """ if value and CHECK_IS[type](join(path, value)): return value elif value is '': from grass.pygrass.functions import getenv return getenv(type) else: raise GrassError("%s <%s> not found" % (type.title(), join(path, value)))
def restore(self, geo_obj): if hasattr(geo_obj, 'offset'): if libvect.Vect_restore_line(self.c_mapinfo, geo_obj.offset, geo_obj.id) == -1: raise GrassError("C function: Vect_restore_line.") else: raise ValueError("The value have not an offset attribute.")
def bbox(self): """Return the BBox of the vecor map """ bbox = Bbox() if libvect.Vect_get_map_box(self.c_mapinfo, bbox.c_bbox) == 0: raise GrassError("I can not find the Bbox.") return bbox
def _get_c_cat(self, index): """Returns i-th description and i-th data range from the list of category descriptions with corresponding data ranges. end points of data interval. Rast_get_ith_cat(const struct Categories * pcats, int i, void * rast1, void * rast2, RASTER_MAP_TYPE data_type ) """ min_cat = ctypes.pointer(RTYPE[self.mtype]['grass def']()) max_cat = ctypes.pointer(RTYPE[self.mtype]['grass def']()) lab = libraster.Rast_get_ith_cat(ctypes.byref(self.c_cats), index, ctypes.cast(min_cat, ctypes.c_void_p), ctypes.cast(max_cat, ctypes.c_void_p), self._gtype) # Manage C function Errors if lab == '': raise GrassError(_("Error executing: Rast_get_ith_cat")) if max_cat.contents.value == min_cat.contents.value: max_cat = None else: max_cat = max_cat.contents.value return lab, min_cat.contents.value, max_cat
def make_mapset(mapset, location=None, gisdbase=None): """Create a new mapset :param mapset: Name of the mapset :type value: str :param location: Name of the location :type location: str :param gisdbase: Name of the gisdbase :type gisdbase: str""" res = libgis.G_make_mapset(gisdbase, location, mapset) if res == -1: raise GrassError("Cannot create new mapset") elif res == -2: raise GrassError("Illegal name")
def delete(self, feature_id): """Remove a feature by its id :param feature_id: the id of the feature :type feature_id: int """ if libvect.Vect_rewrite_line(self.c_mapinfo, feature_id) == -1: raise GrassError("C function: Vect_rewrite_line.")
def select_by_bbox(self, bbox): """Return the BBox of the vector map """ # TODO replace with bbox if bbox else Bbox() ?? bbox = Bbox() if libvect.Vect_get_map_box(self.c_mapinfo, bbox.c_bbox) == 0: raise GrassError("I can not find the Bbox.") return bbox
def get_raster_for_points(poi_vector, raster, column=None, region=None): """Query a raster map for each point feature of a vector Example >>> from grass.pygrass.vector import VectorTopo >>> from grass.pygrass.raster import RasterRow >>> ele = RasterRow('elevation') >>> copy('schools','myschools','vect') >>> sch = VectorTopo('myschools') >>> sch.open(mode='r') >>> get_raster_for_points(sch, ele) # doctest: +ELLIPSIS [(1, 633649.2856743174, 221412.94434781274, 145.06602)... >>> sch.table.columns.add('elevation','double precision') >>> 'elevation' in sch.table.columns True >>> get_raster_for_points(sch, ele, 'elevation') True >>> sch.table.filters.select('NAMESHORT','elevation') Filters(u'SELECT NAMESHORT, elevation FROM myschools;') >>> cur = sch.table.execute() >>> cur.fetchall() # doctest: +ELLIPSIS [(u'SWIFT CREEK', 145.06602), ... (u'9TH GRADE CTR', None)] >>> remove('myschools','vect') :param point: point vector object :param raster: raster object :param str column: column name to update """ from math import isnan if not column: result = [] if region is None: from grass.pygrass.gis.region import Region region = Region() if not poi_vector.is_open(): poi_vector.open() if not raster.is_open(): raster.open() if poi_vector.num_primitive_of('point') == 0: raise GrassError(_("Vector doesn't contain points")) for poi in poi_vector.viter('points'): val = raster.get_value(poi, region) if column: if val is not None and not isnan(val): poi.attrs[column] = val else: if val is not None and not isnan(val): result.append((poi.id, poi.x, poi.y, val)) else: result.append((poi.id, poi.x, poi.y, None)) if not column: return result else: poi.attrs.commit() return True
def open(self, fd, rows, cols, mtype): self.fd = fd self.rows = rows self.cols = cols self.mtype = mtype self.row_size = ctypes.sizeof(RTYPE[mtype]['grass def'] * cols) if (librowio.Rowio_setup(ctypes.byref(self.c_rowio), self.fd, self.rows, self.row_size, get_row[self.mtype], get_row[self.mtype]) == -1): raise GrassError('Fatal error, Rowio not setup correctly.')
def from_string(self, string): """Converts string of categories and cat ranges separated by commas to cat_list. :param string: a string containing the cats separated by commas :type string: str """ num_errors = libvect.Vect_str_to_cat_list(string, self.c_cat_list) if num_errors: from grass.pygrass.errors import GrassError raise GrassError("%d number of errors in ranges" % num_errors)
def rename(self, newname): """Method to rename the Vector map :param newname: the new name for the Vector map :type newname: str """ if self.exist(): if not self.is_open(): functions.rename(self.name, newname, 'vect') else: raise GrassError("The map is open, not able to renamed it.") self._name = newname
def wait(self): """Wait for all Module processes that are in the list to finish and set the modules stdout and stderr output options """ for proc in self._list: if proc: stdout, stderr = proc.popen.communicate(input=proc.stdin) proc.outputs['stdout'].value = stdout if stdout else '' proc.outputs['stderr'].value = stderr if stderr else '' if proc.popen.returncode != 0: GrassError(("Error running module %s") % (proc.name)) self._list = self._num_procs * [None] self._proc_count = 0
def close(self, build=False): """Method to close the Vector :param build: True if the vector map should be build before close it :type build: bool """ if hasattr(self, 'table') and self.table is not None: self.table.conn.close() if self.is_open(): if libvect.Vect_close(self.c_mapinfo) != 0: str_err = 'Error when trying to close the map with Vect_close' raise GrassError(str_err) if ((self.c_mapinfo.contents.mode == libvect.GV_MODE_RW or self.c_mapinfo.contents.mode == libvect.GV_MODE_WRITE) and build): self.build()
def read(self): """Read categories from a raster map The category file for raster map name in mapset is read into the cats structure. If there is an error reading the category file, a diagnostic message is printed. int Rast_read_cats(const char * name, const char * mapset, struct Categories * pcats ) """ self.reset() err = libraster.Rast_read_cats(self.name, self.mapset, ctypes.byref(self.c_cats)) if err == -1: raise GrassError("Can not read the categories.") # copy from C struct to list self._read_cats()
def rewrite(self, line, geo_obj, attrs=None, **kargs): """Rewrite a geometry features """ if self.table is not None and attrs: attr = [ line, ] attr.extend(attrs) self.table.update(key=line, values=attr) elif self.table is None and attrs: print("Table for vector {name} does not exist, attributes not" " loaded".format(name=self.name)) libvect.Vect_cat_set(geo_obj.c_cats, self.layer, line) result = libvect.Vect_rewrite_line(self.c_mapinfo, line, geo_obj.gtype, geo_obj.c_points, geo_obj.c_cats) if result == -1: raise GrassError("Not able to write the vector feature.") # return offset into file where the feature starts geo_obj.offset = result
def write(self): """Writes the region from this region object This function writes this region to the Region file (WIND) in the users current mapset. This function should be carefully used, since the user will ot notice if his region was changed and would expect that only g.region will do this. Example :: >>> from copy import deepcopy >>> r = Region() >>> rn = deepcopy(r) >>> r.north = 20 >>> r.south = 10 >>> r.write() >>> r.read() >>> r.north 20.0 >>> r.south 10.0 >>> rn.write() >>> r.read() >>> r.north 40.0 >>> r.south 0.0 >>> r.read_default() >>> r.write() .. """ self.adjust() if libgis.G_put_window(self.byref()) < 0: raise GrassError("Cannot change region (WIND file).")
def rewrite_obj(self, obj, attrs): """Return """ self.polygon.open('rw', self.layer, with_z=True) cat = attrs[0] if obj.gtype == 1: vtype = 'points' elif obj.gtype == 2: vtype = 'lines' elif obj.gtype == 3: vtype = 'boundary' elif obj.gtype == 4: vtype = 'centroid' line = self.polygon.cat(cat, vtype, self.layer)[0] if self.polygon.table is not None and attrs: self.polygon.table.update(key=line.cat, values=attrs[1:]) elif self.polygon.table is None and attrs: print("Table for vector {name} does not exist, attributes not" " loaded".format(name=self.name)) # libvect.Vect_cat_set(obj.c_cats, self.layer, line.cat) result = libvect.Vect_rewrite_line(self.polygon.c_mapinfo, line.id, obj.gtype, obj.c_points, line.c_cats) if result == -1: raise GrassError("Not able to write the vector feature.") # return offset into file where the feature starts obj.offset = result self.polygon.table.conn.commit() self.polygon.close()
def features_to_wkb_list(self, bbox=None, feature_type="point", field=1): """Return all features of type point, line, boundary or centroid as a list of Well Known Binary representations (WKB) (id, cat, wkb) triplets located in a specific bounding box. :param bbox: The boundingbox to search for features, if bbox=None the boundingbox of the whole vector map layer is used :type bbox: grass.pygrass.vector.basic.Bbox :param feature_type: The type of feature that should be converted to the Well Known Binary (WKB) format. Supported are: 'point' -> libvect.GV_POINT 1 'line' -> libvect.GV_LINE 2 'boundary' -> libvect.GV_BOUNDARY 3 'centroid' -> libvect.GV_CENTROID 4 :type type: string :param field: The category field :type field: integer :return: A list of triplets, or None if nothing was found The well known binary are stored in byte arrays. Examples: >>> from grass.pygrass.vector import VectorTopo >>> from grass.pygrass.vector.basic import Bbox >>> test_vect = VectorTopo(test_vector_name) >>> test_vect.open('r') >>> bbox = Bbox(north=20, south=-1, east=20, west=-1) >>> result = test_vect.features_to_wkb_list(bbox=bbox, ... feature_type="point") >>> len(result) 3 >>> for entry in result: ... f_id, cat, wkb = entry ... print((f_id, cat, len(wkb))) (1, 1, 21) (2, 1, 21) (3, 1, 21) >>> result = test_vect.features_to_wkb_list(bbox=None, ... feature_type="line") >>> len(result) 3 >>> for entry in result: ... f_id, cat, wkb = entry ... print((f_id, cat, len(wkb))) (4, 2, 57) (5, 2, 57) (6, 2, 57) >>> result = test_vect.features_to_wkb_list(bbox=bbox, ... feature_type="boundary") >>> len(result) 11 >>> result = test_vect.features_to_wkb_list(bbox=None, ... feature_type="centroid") >>> len(result) 4 >>> for entry in result: ... f_id, cat, wkb = entry ... print((f_id, cat, len(wkb))) (19, 3, 21) (18, 3, 21) (20, 3, 21) (21, 3, 21) >>> result = test_vect.features_to_wkb_list(bbox=bbox, ... feature_type="blub") Traceback (most recent call last): ... GrassError: Unsupported feature type <blub>, supported are <point,line,boundary,centroid> >>> test_vect.close() """ supported = ['point', 'line', 'boundary', 'centroid'] if feature_type.lower() not in supported: raise GrassError("Unsupported feature type <%s>, "\ "supported are <%s>"%(feature_type, ",".join(supported))) if bbox is None: bbox = self.bbox() bboxlist = self.find_by_bbox.geos(bbox, type=feature_type.lower(), bboxlist_only = True) if bboxlist is not None and len(bboxlist) > 0: l = [] line_p = libvect.line_pnts() line_c = libvect.line_cats() size = ctypes.c_size_t() cat = ctypes.c_int() error = ctypes.c_int() for f_id in bboxlist.ids: barray = libvect.Vect_read_line_to_wkb(self.c_mapinfo, ctypes.byref(line_p), ctypes.byref(line_c), f_id, ctypes.byref(size), ctypes.byref(error)) if not barray: if error == -1: raise GrassError(_("Unable to read line of feature %i"%(f_id))) if error == -2: print("Empty feature %i"%(f_id)) continue ok = libvect.Vect_cat_get(ctypes.byref(line_c), field, ctypes.byref(cat)) if ok < 1: pcat = None else: pcat = cat.value l.append((f_id, pcat, ctypes.string_at(barray, size.value))) libgis.G_free(barray) return l return None
def __init__(self, cmd, *args, **kargs): if isinstance(cmd, unicode): self.name = str(cmd) elif isinstance(cmd, str): self.name = cmd else: raise GrassError( "Problem initializing the module {s}".format(s=cmd)) try: # call the command with --interface-description get_cmd_xml = Popen([cmd, "--interface-description"], stdout=PIPE) except OSError as e: print("OSError error({0}): {1}".format(e.errno, e.strerror)) str_err = "Error running: `%s --interface-description`." raise GrassError(str_err % self.name) # get the xml of the module self.xml = get_cmd_xml.communicate()[0] # transform and parse the xml into an Element class: # http://docs.python.org/library/xml.etree.elementtree.html tree = fromstring(self.xml) for e in tree: if e.tag not in ('parameter', 'flag'): self.__setattr__(e.tag, GETFROMTAG[e.tag](e)) # # extract parameters from the xml # self.params_list = [Parameter(p) for p in tree.findall("parameter")] self.inputs = TypeDict(Parameter) self.outputs = TypeDict(Parameter) self.required = [] # Insert parameters into input/output and required for par in self.params_list: if par.input: self.inputs[par.name] = par else: self.outputs[par.name] = par if par.required: self.required.append(par.name) # # extract flags from the xml # flags_list = [Flag(f) for f in tree.findall("flag")] self.flags = TypeDict(Flag) for flag in flags_list: self.flags[flag.name] = flag # # Add new attributes to the class # self.run_ = True self.finish_ = True self.env_ = None self.stdin_ = None self.stdin = None self.stdout_ = None self.stderr_ = None diz = { 'name': 'stdin', 'required': False, 'multiple': False, 'type': 'all', 'value': None } self.inputs['stdin'] = Parameter(diz=diz) diz['name'] = 'stdout' self.outputs['stdout'] = Parameter(diz=diz) diz['name'] = 'stderr' self.outputs['stderr'] = Parameter(diz=diz) self.popen = None self.time = None if args or kargs: self.__call__(*args, **kargs) self.__call__.__func__.__doc__ = self.__doc__
def write(self, geo_obj, attrs=None, set_cats=True): """Write geometry features and attributes. :param geo_obj: a geometry grass object define in grass.pygrass.vector.geometry :type geo_obj: geometry GRASS object :param attrs: a list with the values that will be insert in the attribute table. :type attrs: list :param set_cats: if True, the category of the geometry feature is set using the default layer of the vector map and a progressive category value (default), otherwise the c_cats attribute of the geometry object will be used. :type set_cats: bool Open a new vector map :: >>> new = VectorTopo('newvect') >>> new.exist() False define the new columns of the attribute table :: >>> cols = [(u'cat', 'INTEGER PRIMARY KEY'), ... (u'name', 'TEXT')] open the vector map in write mode >>> new.open('w', tab_name='newvect', tab_cols=cols) import a geometry feature :: >>> from grass.pygrass.vector.geometry import Point create two points :: >>> point0 = Point(636981.336043, 256517.602235) >>> point1 = Point(637209.083058, 257970.129540) then write the two points on the map, with :: >>> new.write(point0, ('pub', )) >>> new.write(point1, ('resturnat', )) commit the db changes :: >>> new.table.conn.commit() >>> new.table.execute().fetchall() [(1, u'pub'), (2, u'resturnat')] close the vector map :: >>> new.close() >>> new.exist() True then play with the map :: >>> new.open(mode='r') >>> new.read(1) Point(636981.336043, 256517.602235) >>> new.read(2) Point(637209.083058, 257970.129540) >>> new.read(1).attrs['name'] u'pub' >>> new.read(2).attrs['name'] u'resturnat' >>> new.close() >>> new.remove() """ self.n_lines += 1 if self.table is not None and attrs: attr = [self.n_lines, ] attr.extend(attrs) cur = self.table.conn.cursor() cur.execute(self.table.columns.insert_str, attr) cur.close() if set_cats: cats = Cats(geo_obj.c_cats) cats.reset() cats.set(self.n_lines, self.layer) if geo_obj.gtype == _Area.gtype: result = self._write_area(geo_obj) result = libvect.Vect_write_line(self.c_mapinfo, geo_obj.gtype, geo_obj.c_points, geo_obj.c_cats) if result == -1: raise GrassError("Not able to write the vector feature.") if self._topo_level == 2: # return new feature id (on level 2) geo_obj.id = result else: # return offset into file where the feature starts (on level 1) geo_obj.offset = result
def rewrite(self, geo_obj, cat, attrs=None, **kargs): """Rewrite a geometry features >>> cols = [(u'cat', 'INTEGER PRIMARY KEY'), ... (u'name', 'TEXT')] Generate a new vector map >>> test_vect = VectorTopo('newvect_2') >>> test_vect.open('w', tab_name='newvect_2', tab_cols=cols, ... overwrite=True) import a geometry feature :: >>> from grass.pygrass.vector.geometry import Point create two points :: >>> point0 = Point(0, 0) >>> point1 = Point(1, 1) >>> point2 = Point(2, 2) then write the two points on the map, with :: >>> test_vect.write(point0, cat=1, attrs=('pub',)) >>> test_vect.write(point1, cat=2, attrs=('resturant',)) >>> test_vect.table.conn.commit() # save changes in the DB >>> test_vect.table_to_dict() {1: [1, u'pub'], 2: [2, u'resturant']} >>> test_vect.close() Now rewrite one point of the vector map: :: >>> test_vect.open('rw') >>> test_vect.rewrite(point2, cat=1, attrs=('Irish Pub',)) >>> test_vect.table.conn.commit() # save changes in the DB >>> test_vect.close() Check the output: >>> test_vect.open('r') >>> test_vect[1] == point2 True >>> test_vect[1].attrs['name'] == 'Irish Pub' True >>> test_vect.close() >>> test_vect.remove() """ if self.table is not None and attrs: self.table.update(key=cat, values=attrs) elif self.table is None and attrs: print("Table for vector {name} does not exist, attributes not" " loaded".format(name=self.name)) libvect.Vect_cat_set(geo_obj.c_cats, self.layer, cat) result = libvect.Vect_rewrite_line(self.c_mapinfo, cat, geo_obj.gtype, geo_obj.c_points, geo_obj.c_cats) if result == -1: raise GrassError("Not able to write the vector feature.") # return offset into file where the feature starts geo_obj.offset = result
def write(self, geo_obj, cat=None, attrs=None): """Write geometry features and attributes. :param geo_obj: a geometry grass object define in grass.pygrass.vector.geometry :type geo_obj: geometry GRASS object :param attrs: a list with the values that will be insert in the attribute table. :type attrs: list :param cat: The category of the geometry feature, otherwise the c_cats attribute of the geometry object will be used. :type cat: integer Open a new vector map :: >>> new = VectorTopo('newvect') >>> new.exist() False define the new columns of the attribute table :: >>> cols = [(u'cat', 'INTEGER PRIMARY KEY'), ... (u'name', 'TEXT')] open the vector map in write mode >>> new.open('w', tab_name='newvect', tab_cols=cols) import a geometry feature :: >>> from grass.pygrass.vector.geometry import Point create two points :: >>> point0 = Point(0, 0) >>> point1 = Point(1, 1) then write the two points on the map, with :: >>> new.write(point0, cat=1, attrs=('pub',)) >>> new.write(point1, cat=2, attrs=('resturant',)) commit the db changes :: >>> new.table.conn.commit() >>> new.table.execute().fetchall() [(1, u'pub'), (2, u'resturant')] close the vector map :: >>> new.close() >>> new.exist() True then play with the map :: >>> new.open(mode='r') >>> new.read(1) Point(0.000000, 0.000000) >>> new.read(2) Point(1.000000, 1.000000) >>> new.read(1).attrs['name'] u'pub' >>> new.read(2).attrs['name'] u'resturant' >>> new.close() >>> new.remove() """ self.n_lines += 1 if not isinstance(cat, int) and not isinstance(cat, str): # likely the case of using 7.0 API import warnings warnings.warn("Vector.write(geo_obj, attrs=(...)) is" " depreciated, specify cat explicitly", DeprecationWarning) # try to accommodate attrs = cat cat = None if attrs and cat is None: # TODO: this does not work as expected when there are # already features in the map when we opened it cat = (self._cats[-1] if self._cats else 0) + 1 if cat is not None and cat not in self._cats: self._cats.append(cat) if self.table is not None and attrs is not None: attr = [cat, ] attr.extend(attrs) cur = self.table.conn.cursor() cur.execute(self.table.columns.insert_str, attr) cur.close() if cat is not None: cats = Cats(geo_obj.c_cats) cats.reset() cats.set(cat, self.layer) if geo_obj.gtype == _Area.gtype: result = self._write_area(geo_obj) result = libvect.Vect_write_line(self.c_mapinfo, geo_obj.gtype, geo_obj.c_points, geo_obj.c_cats) if result == -1: raise GrassError("Not able to write the vector feature.") if self._topo_level == 2: # return new feature id (on level 2) geo_obj.id = result else: # return offset into file where the feature starts (on level 1) geo_obj.offset = result
def delete(self): """Delete the mapset""" if self.is_current(): raise GrassError("The mapset is in use.") shutil.rmtree(self.path())
def new_location(self): if libgis.G_make_location() != 0: raise GrassError("Cannot create new location")
def areas_to_wkb_list(self, bbox=None, field=1): """Return all features of type point, line, boundary or centroid as a list of Well Known Binary representations (WKB) (id, cat, wkb) triplets located in a specific bounding box. :param bbox: The boundingbox to search for features, if bbox=None the boundingbox of the whole vector map layer is used :type bbox: grass.pygrass.vector.basic.Bbox :param field: The centroid category field :type field: integer :return: A list of triplets, or None if nothing was found The well known binary are stored in byte arrays. Examples: >>> from grass.pygrass.vector import VectorTopo >>> from grass.pygrass.vector.basic import Bbox >>> test_vect = VectorTopo(test_vector_name) >>> test_vect.open('r') >>> bbox = Bbox(north=20, south=-1, east=20, west=-1) >>> result = test_vect.areas_to_wkb_list(bbox=bbox) >>> len(result) 4 >>> for entry in result: ... a_id, cat, wkb = entry ... print((a_id, cat, len(wkb))) (1, 3, 225) (2, 3, 141) (3, 3, 93) (4, 3, 141) >>> result = test_vect.areas_to_wkb_list() >>> len(result) 4 >>> for entry in result: ... a_id, cat, wkb = entry ... print((a_id, cat, len(wkb))) (1, 3, 225) (2, 3, 141) (3, 3, 93) (4, 3, 141) >>> test_vect.close() """ if bbox is None: bbox = self.bbox() bboxlist = self.find_by_bbox.areas(bbox, bboxlist_only = True) if bboxlist is not None and len(bboxlist) > 0: l = [] line_c = libvect.line_cats() size = ctypes.c_size_t() cat = ctypes.c_int() for a_id in bboxlist.ids: barray = libvect.Vect_read_area_to_wkb(self.c_mapinfo, a_id, ctypes.byref(size)) if not barray: raise GrassError(_("Unable to read area with id %i"%(a_id))) pcat = None c_ok = libvect.Vect_get_area_cats(self.c_mapinfo, a_id, ctypes.byref(line_c)) if c_ok == 0: # Centroid found ok = libvect.Vect_cat_get(ctypes.byref(line_c), field, ctypes.byref(cat)) if ok > 0: pcat = cat.value l.append((a_id, pcat, ctypes.string_at(barray, size.value))) libgis.G_free(barray) return l return None
def rewind(self): """Rewind vector map to cause reads to start at beginning.""" if libvect.Vect_rewind(self.c_mapinfo) == -1: raise GrassError("Vect_rewind raise an error.")
def get_raster_for_points(poi_vector, raster, column=None, region=None): """Query a raster map for each point feature of a vector Example >>> from grass.pygrass.raster import RasterRow >>> from grass.pygrass.gis.region import Region >>> from grass.pygrass.vector import VectorTopo >>> from grass.pygrass.vector.geometry import Point Create a vector map >>> cols = [(u'cat', 'INTEGER PRIMARY KEY'), ... (u'value', 'double precision')] >>> vect = VectorTopo("test_vect_2") >>> vect.open("w",tab_name="test_vect_2", ... tab_cols=cols) >>> vect.write(Point(10, 6), cat=1, attrs=[10, ]) >>> vect.write(Point(12, 6), cat=2, attrs=[12, ]) >>> vect.write(Point(14, 6), cat=3, attrs=[14, ]) >>> vect.table.conn.commit() >>> vect.close() Setup the raster sampling >>> region = Region() >>> region.from_rast(test_raster_name) >>> region.set_raster_region() >>> ele = RasterRow(test_raster_name) Sample the raster layer at the given points, return a list of values >>> l = get_raster_for_points(vect, ele, region=region) >>> l[0] # doctest: +ELLIPSIS (1, 10.0, 6.0, 1) >>> l[1] # doctest: +ELLIPSIS (2, 12.0, 6.0, 1) Add a new column and sample again >>> vect.open("r") >>> vect.table.columns.add(test_raster_name,'double precision') >>> vect.table.conn.commit() >>> test_raster_name in vect.table.columns True >>> get_raster_for_points(vect, ele, column=test_raster_name, region=region) True >>> vect.table.filters.select('value', test_raster_name) Filters('SELECT value, Utils_test_raster FROM test_vect_2;') >>> cur = vect.table.execute() >>> r = cur.fetchall() >>> r[0] # doctest: +ELLIPSIS (10.0, 1.0) >>> r[1] # doctest: +ELLIPSIS (12.0, 1.0) >>> remove('test_vect_2','vect') :param poi_vector: A VectorTopo object that contains points :param raster: raster object :param str column: column name to update in the attrinute table, if set to None a list of sampled values will be returned :param region: The region to work with, if not set the current computational region will be used :return: True in case of success and a specified column for update, if column name for update was not set a list of (id, x, y, value) is returned """ from math import isnan if not column: result = [] if region is None: from grass.pygrass.gis.region import Region region = Region() if not poi_vector.is_open(): poi_vector.open("r") if not raster.is_open(): raster.open("r") if poi_vector.num_primitive_of("point") == 0: raise GrassError(_("Vector doesn't contain points")) for poi in poi_vector.viter("points"): val = raster.get_value(poi, region) if column: if val is not None and not isnan(val): poi.attrs[column] = val else: if val is not None and not isnan(val): result.append((poi.id, poi.x, poi.y, val)) else: result.append((poi.id, poi.x, poi.y, None)) if not column: return result else: poi.attrs.commit() return True