def open(self, mode='r', layer='0', overwrite=None): """:: >>> mun = Vector('boundary_municp_sqlite') >>> mun.open() >>> mun.is_open() True >>> mun.close() .. """ if libvect.Vect_set_open_level(self._topo_level) != 0: raise OpenError("Invalid access level.") # update the overwrite attribute self.overwrite = overwrite if overwrite is not None else self.overwrite # check if the mode is valid if mode not in ('r', 'rw', 'w'): raise ValueError("Mode not supported. Use one of: 'r', 'rw', 'w'.") # check if the map exist if self.exist() and mode == 'r': openvect = libvect.Vect_open_old2(self.c_mapinfo, self.name, self.mapset, layer) # If it is opened in write mode if mode == 'w': openvect = libvect.Vect_open_new(self.c_mapinfo, self.name, libvect.WITHOUT_Z) elif mode == 'rw': openvect = libvect.Vect_open_update2(self.c_mapinfo, self.name, self.mapset, layer) # initialize the dblinks object self.dblinks = DBlinks(self.c_mapinfo) # check the C function result. if openvect != self._topo_level: str_err = "Not able to open the map, C function return %d." raise OpenError(str_err % openvect)
def getcoords(self): """ Method creating a dict() of point coordinates: {a:(xa,ya), b:(xb,yb)...} """ # Create a new Map_info() object map = vect.pointer(vect.Map_info()) # Load the vector map to Map_info() object. Level should be 2 (with topology) vect.Vect_open_old2(map, self.layer, "", "-1") # Get number of point features (1) in the layer n_lines = vect.Vect_get_num_primitives(map, 1) # Create new line and categories structures line = vect.Vect_new_line_struct() cats = vect.Vect_new_cats_struct() # Make an empty list to store all feature cats and their coordinates in coordsdict = {} # Iterate through all features and write their coordinates to the list for i in xrange(0, n_lines): # Read next line from Map_info() vect.Vect_read_next_line(map, line, cats, 1) # Get line structure values, i.e. coordinates x = line.contents.x[0] y = line.contents.y[0] # Get the point category number cat = cats.contents.cat[0] coordsdict[cat] = (x, y) # Do some cleanup vect.Vect_destroy_line_struct(line) vect.Vect_destroy_cats_struct(cats) vect.Vect_close(map) # Return coordinate dictionary. Example: {1: (635185.6745587245, 6434401.869609355), 3: (634763.0860512792, 6437526.1793751), 4: (636855.7953351085, 6435785.045250954), 5: (636705.1202666728, 6432286.035328391), 6: (633607.9105266054, 6432286.035328391), 7: (632762.4559759387, 6435655.297275356)} return coordsdict
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 featcount(self): """ Method returning the number of features in the layer """ # Create a new Map_info() object map = vect.pointer(vect.Map_info()) # Load the vector map to Map_info() object. Level should be 2 (with topology) vect.Vect_open_old2(map, self.layer, "", "-1") # Get number of point features (1) in the layer n_feats = vect.Vect_get_num_primitives(map, 1) # Close the Map_info() object vect.Vect_close(map) # Return number of features in the layer (integer) return n_feats
def open( self, mode=None, layer=1, overwrite=None, with_z=None, # parameters valid only if mode == 'w' tab_name='', tab_cols=None, link_name=None, link_key='cat', link_db='$GISDBASE/$LOCATION_NAME/$MAPSET/sqlite/sqlite.db', link_driver='sqlite'): """Open a Vector map. :param mode: open a vector map in ``r`` in reading, ``w`` in writing and in ``rw`` read and write mode :type mode: str :param layer: specify the layer that you want to use :type layer: int :param overwrite: valid only for ``w`` mode :type overwrite: bool :param with_z: specify if vector map must be open with third dimension enabled or not. Valid only for ``w`` mode, default: False :type with_z: bool :param tab_name: define the name of the table that will be generate :type tab_name: str :param tab_cols: define the name and type of the columns of the attribute table of the vecto map :type tab_cols: list of pairs :param link_name: define the name of the link connecttion with the database :type link_name: str :param link_key: define the nema of the column that will be use as vector category :type link_key: str :param link_db: define the database connection parameters :type link_db: str :param link_driver: define witch database driver will be used :param link_driver: str Some of the parameters are valid only with mode ``w`` or ``rw`` See more examples in the documentation of the ``read`` and ``write`` methods """ with_z = libvect.WITH_Z if with_z else libvect.WITHOUT_Z # check if map exists or not if not self.exist() and mode != 'w': raise OpenError("Map <%s> not found." % self._name) if libvect.Vect_set_open_level(self._topo_level) != 0: raise OpenError("Invalid access level.") # update the overwrite attribute self.overwrite = overwrite if overwrite is not None else self.overwrite # check if the mode is valid if mode not in ('r', 'rw', 'w'): raise ValueError("Mode not supported. Use one of: 'r', 'rw', 'w'.") # check if the map exist if self.exist() and mode in ('r', 'rw'): # open in READ mode if mode == 'r': openvect = libvect.Vect_open_old2(self.c_mapinfo, self.name, self.mapset, str(layer)) # open in READ and WRITE mode elif mode == 'rw': openvect = libvect.Vect_open_update2(self.c_mapinfo, self.name, self.mapset, str(layer)) # instantiate class attributes self.dblinks = DBlinks(self.c_mapinfo) # If it is opened in write mode if mode == 'w': openvect = libvect.Vect_open_new(self.c_mapinfo, self.name, with_z) self.dblinks = DBlinks(self.c_mapinfo) if tab_cols: # create a link link = Link(layer, link_name if link_name else self.name, tab_name if tab_name else self.name, link_key, link_db, link_driver) # add the new link self.dblinks.add(link) # create the table table = link.table() table.create(tab_cols) table.conn.commit() # check the C function result. if openvect == -1: str_err = "Not able to open the map, C function return %d." raise OpenError(str_err % openvect) if len(self.dblinks) == 0: self.layer = layer self.table = None self.n_lines = 0 else: self.layer = self.dblinks.by_layer(layer).layer self.table = self.dblinks.by_layer(layer).table() self.n_lines = self.table.n_rows() self.writable = self.mapset == functions.getenv("MAPSET") self.find = { 'by_point': PointFinder(self.c_mapinfo, self.table, self.writable), 'by_box': BboxFinder(self.c_mapinfo, self.table, self.writable), 'by_polygon': PolygonFinder(self.c_mapinfo, self.table, self.writable), }
def open( self, mode=None, layer=1, overwrite=None, with_z=None, # parameters valid only if mode == 'w' tab_name="", tab_cols=None, link_name=None, link_key="cat", link_db="$GISDBASE/$LOCATION_NAME/$MAPSET/sqlite/sqlite.db", link_driver="sqlite", ): """Open a Vector map. :param mode: open a vector map in ``r`` in reading, ``w`` in writing and in ``rw`` read and write mode :type mode: str :param layer: specify the layer that you want to use :type layer: int :param overwrite: valid only for ``w`` mode :type overwrite: bool :param with_z: specify if vector map must be open with third dimension enabled or not. Valid only for ``w`` mode, default: False :type with_z: bool :param tab_name: define the name of the table that will be generate :type tab_name: str :param tab_cols: define the name and type of the columns of the attribute table of the vecto map :type tab_cols: list of pairs :param link_name: define the name of the link connecttion with the database :type link_name: str :param link_key: define the nema of the column that will be use as vector category :type link_key: str :param link_db: define the database connection parameters :type link_db: str :param link_driver: define witch database driver will be used :param link_driver: str Some of the parameters are valid only with mode ``w`` or ``rw`` See more examples in the documentation of the ``read`` and ``write`` methods """ self.mode = mode if mode else self.mode with_z = libvect.WITH_Z if with_z else libvect.WITHOUT_Z # check if map exists or not if not self.exist() and self.mode != "w": raise OpenError("Map <%s> not found." % self._name) if libvect.Vect_set_open_level(self._topo_level) != 0: raise OpenError("Invalid access level.") # update the overwrite attribute self.overwrite = overwrite if overwrite is not None else self.overwrite # check if the mode is valid if self.mode not in ("r", "rw", "w"): raise ValueError("Mode not supported. Use one of: 'r', 'rw', 'w'.") # check if the map exist if self.exist() and self.mode in ("r", "rw"): # open in READ mode if self.mode == "r": openvect = libvect.Vect_open_old2(self.c_mapinfo, self.name, self.mapset, str(layer)) # open in READ and WRITE mode elif self.mode == "rw": openvect = libvect.Vect_open_update2(self.c_mapinfo, self.name, self.mapset, str(layer)) # instantiate class attributes self.dblinks = DBlinks(self.c_mapinfo) # If it is opened in write mode if self.mode == "w": openvect = libvect.Vect_open_new(self.c_mapinfo, self.name, with_z) self.dblinks = DBlinks(self.c_mapinfo) if self.mode in ("w", "rw") and tab_cols: # create a link link = Link( layer, link_name if link_name else self.name, tab_name if tab_name else self.name, link_key, link_db, link_driver, ) # add the new link self.dblinks.add(link) # create the table table = link.table() table.create(tab_cols, overwrite=overwrite) table.conn.commit() # check the C function result. if openvect == -1: str_err = "Not able to open the map, C function return %d." raise OpenError(str_err % openvect) # Load attribute table for selected layer. if len(self.dblinks) == 0: self.layer = layer self.table = None self.n_lines = 0 else: layer_db_link = self.dblinks.by_layer(layer) if not layer_db_link: raise LookupError( "There appears to be no database link for layer %d of <%s>." % (layer, self.name)) if layer_db_link.layer != layer: raise RuntimeError( "The databse link for layer %d of <%s> references layer %d." % (layer, self.name, layer_db_link.layer)) self.layer = layer try: self.table = layer_db_link.table() except Exception as error: raise RuntimeError( "Loading the attribute table for layer %d of <%s> failed." % (layer, self.name)) from error self.n_lines = self.table.n_rows() self.writeable = self.mapset == utils.getenv("MAPSET") # Initialize the finder self.find = { "by_point": PointFinder(self.c_mapinfo, self.table, self.writeable), "by_bbox": BboxFinder(self.c_mapinfo, self.table, self.writeable), "by_polygon": PolygonFinder(self.c_mapinfo, self.table, self.writeable), } self.find_by_point = self.find["by_point"] self.find_by_bbox = self.find["by_bbox"] self.find_by_polygon = self.find["by_polygon"]
def _read_vector_info(name, mapset): """Read the vector map info from the file system and store the content into a dictionary This method uses the ctypes interface to the vector libraries to read the map metadata information :param name: The name of the map :param mapset: The mapset of the map :returns: The key value pairs of the map specific metadata, or None in case of an error """ kvp = {} if not libgis.G_find_vector(name, mapset): return None # The vector map structure Map = libvector.Map_info() # We open the maps always in topology mode first libvector.Vect_set_open_level(2) with_topo = True # Code lend from v.info main.c if libvector.Vect_open_old_head2(byref(Map), name, mapset, "1") < 2: # force level 1, open fully # NOTE: number of points, lines, boundaries, centroids, # faces, kernels is still available libvector.Vect_set_open_level(1) # no topology with_topo = False if libvector.Vect_open_old2(byref(Map), name, mapset, "1") < 1: logging.error( _("Unable to open vector map <%s>" % (libvector.Vect_get_full_name(byref(Map))))) return None # Release the vector spatial index memory when closed libvector.Vect_set_release_support(byref(Map)) # Read the extent information bbox = libvector.bound_box() libvector.Vect_get_map_box(byref(Map), byref(bbox)) kvp["north"] = bbox.N kvp["south"] = bbox.S kvp["east"] = bbox.E kvp["west"] = bbox.W kvp["top"] = bbox.T kvp["bottom"] = bbox.B kvp["map3d"] = bool(libvector.Vect_is_3d(byref(Map))) # Read number of features if with_topo: kvp["points"] = libvector.Vect_get_num_primitives( byref(Map), libvector.GV_POINT) kvp["lines"] = libvector.Vect_get_num_primitives( byref(Map), libvector.GV_LINE) kvp["boundaries"] = libvector.Vect_get_num_primitives( byref(Map), libvector.GV_BOUNDARY) kvp["centroids"] = libvector.Vect_get_num_primitives( byref(Map), libvector.GV_CENTROID) kvp["faces"] = libvector.Vect_get_num_primitives( byref(Map), libvector.GV_FACE) kvp["kernels"] = libvector.Vect_get_num_primitives( byref(Map), libvector.GV_KERNEL) # Summarize the primitives kvp["primitives"] = kvp["points"] + kvp["lines"] + \ kvp["boundaries"] + kvp["centroids"] if kvp["map3d"]: kvp["primitives"] += kvp["faces"] + kvp["kernels"] # Read topology information kvp["nodes"] = libvector.Vect_get_num_nodes(byref(Map)) kvp["areas"] = libvector.Vect_get_num_areas(byref(Map)) kvp["islands"] = libvector.Vect_get_num_islands(byref(Map)) kvp["holes"] = libvector.Vect_get_num_holes(byref(Map)) kvp["volumes"] = libvector.Vect_get_num_primitives( byref(Map), libvector.GV_VOLUME) else: kvp["points"] = None kvp["lines"] = None kvp["boundaries"] = None kvp["centroids"] = None kvp["faces"] = None kvp["kernels"] = None kvp["primitives"] = None kvp["nodes"] = None kvp["areas"] = None kvp["islands"] = None kvp["holes"] = None kvp["volumes"] = None libvector.Vect_close(byref(Map)) return kvp