def run(self): logging.debug("Computation started") psc = self.input_psc.getValue() map_name = 'obce_psc_{}'.format(psc) obce = VectorTopo('obce', mapset='psc') obce.open('r') vystup = VectorTopo(map_name) vystup.open('w', tab_cols=[('cat', 'INTEGER PRIMARY KEY'), ('nazev', 'TEXT'), ('psc', 'INTEGER')]) obec_id = None obce_psc = set() for prvek in obce.viter('areas'): if prvek.attrs is None: continue if prvek.attrs['psc'] == psc: if obec_id is None: obec_id = prvek.id for b in prvek.boundaries(): for n in b.read_area_ids(): if n != -1 and n != obec_id: obce_psc.add(n) obce_psc.add(obec_id) hranice = list() cat = 1 for prvek in obce.viter('areas'): if prvek.id not in obce_psc: continue for b in prvek.boundaries(): if b.id not in hranice: hranice.append(b.id) vystup.write(b) vystup.write(prvek.centroid(), cat=cat, attrs=(prvek.attrs['nazev'], prvek.attrs['psc'])) cat += 1 vystup.table.conn.commit() vystup.close() obce.close() logging.debug("Computation finished") return map_name
def sample(vect_in_name, rast_in_name): """sample('point00', 'field')""" # instantiate the object maps vect_in = VectorTopo(vect_in_name) rast_in = RasterRow(rast_in_name) vect_out = VectorTopo('test_' + vect_in_name) # define the columns of the attribute table of the new vector map columns = [(u'cat', 'INTEGER PRIMARY KEY'), (rast_in_name, 'DOUBLE')] # open the maps vect_in.open('r') rast_in.open('r') vect_out.open('w', tab_cols=columns, link_driver='sqlite') # get the current region region = Region() # initialize the counter counter = 0 data = [] for pnt in vect_in.viter('points'): counter += 1 # transform the spatial coordinates in row and col value x, y = coor2pixel(pnt.coords(), region) value = rast_in[int(x)][int(y)] data.append((counter, None if np.isnan(value) else float(value))) # write the geometry features vect_out.write(pnt) # write the attributes vect_out.table.insert(data, many=True) vect_out.table.conn.commit() # close the maps vect_in.close() rast_in.close() vect_out.close()
def obce_psc(psc): obce = VectorTopo('obce') obce.open('r') vystup = VectorTopo('obce_psc_{}'.format(psc)) vystup.open('w', tab_cols=[('cat', 'INTEGER PRIMARY KEY'), ('nazev', 'TEXT'), ('psc', 'INTEGER')]) obec_id = None obce_psc = set() for prvek in obce.viter('areas'): if prvek.attrs is None: continue if prvek.attrs['psc'] == psc: if obec_id is None: obec_id = prvek.id for b in prvek.boundaries(): for n in b.read_area_ids(): if n != -1 and n != obec_id: obce_psc.add(n) obce_psc.add(obec_id) hranice = list() for prvek in obce.viter('areas'): if prvek.id not in obce_psc: continue for b in prvek.boundaries(): if b.id not in hranice: hranice.append(b.id) vystup.write(b, attrs=(None, None)) vystup.write(prvek.centroid(), attrs=(prvek.attrs['nazev'], prvek.attrs['psc'])) vystup.table.conn.commit() vystup.close() obce.close()
def main(): from dateutil.parser import parse try: from pygbif import occurrences from pygbif import species except ImportError: grass.fatal( _("Cannot import pygbif (https://github.com/sckott/pygbif)" " library." " Please install it (pip install pygbif)" " or ensure that it is on path" " (use PYTHONPATH variable).")) # Parse input options output = options["output"] mask = options["mask"] species_maps = flags["i"] no_region_limit = flags["r"] no_topo = flags["b"] print_species = flags["p"] print_species_table = flags["t"] print_species_shell = flags["g"] print_occ_number = flags["o"] allow_no_geom = flags["n"] hasGeoIssue = flags["s"] taxa_list = options["taxa"].split(",") institutionCode = options["institutioncode"] basisofrecord = options["basisofrecord"] recordedby = options["recordedby"].split(",") date_from = options["date_from"] date_to = options["date_to"] country = options["country"] continent = options["continent"] rank = options["rank"] # Define static variable # Initialize cat cat = 0 # Number of occurrences to fetch in one request chunk_size = 300 # lat/lon proj string latlon_crs = [ "+proj=longlat +no_defs +a=6378137 +rf=298.257223563 +towgs84=0.000,0.000,0.000", "+proj=longlat +no_defs +a=6378137 +rf=298.257223563 +towgs84=0,0,0,0,0,0,0", "+proj=longlat +no_defs +a=6378137 +rf=298.257223563 +towgs84=0.000,0.000,0.000 +type=crs", ] # List attributes available in Darwin Core # not all attributes are returned in each request # to avoid key errors when accessing the dictionary returned by pygbif # presence of DWC keys in the returned dictionary is checked using this list # The number of keys in this list has to be equal to the number of columns # in the attribute table and the attributes written for each occurrence dwc_keys = [ "key", "taxonRank", "taxonKey", "taxonID", "scientificName", "species", "speciesKey", "genericName", "genus", "genusKey", "family", "familyKey", "order", "orderKey", "class", "classKey", "phylum", "phylumKey", "kingdom", "kingdomKey", "eventDate", "verbatimEventDate", "startDayOfYear", "endDayOfYear", "year", "month", "day", "occurrenceID", "occurrenceStatus", "occurrenceRemarks", "Habitat", "basisOfRecord", "preparations", "sex", "type", "locality", "verbatimLocality", "decimalLongitude", "decimalLatitude", "coordinateUncertaintyInMeters", "geodeticDatum", "higerGeography", "continent", "country", "countryCode", "stateProvince", "gbifID", "protocol", "identifier", "recordedBy", "identificationID", "identifiers", "dateIdentified", "modified", "institutionCode", "lastInterpreted", "lastParsed", "references", "relations", "catalogNumber", "occurrenceDetails", "datasetKey", "datasetName", "collectionCode", "rights", "rightsHolder", "license", "publishingOrgKey", "publishingCountry", "lastCrawled", "specificEpithet", "facts", "issues", "extensions", "language", ] # Deinfe columns for attribute table cols = [ ("cat", "INTEGER PRIMARY KEY"), ("g_search", "varchar(100)"), ("g_key", "integer"), ("g_taxonrank", "varchar(50)"), ("g_taxonkey", "integer"), ("g_taxonid", "varchar(50)"), ("g_scientificname", "varchar(255)"), ("g_species", "varchar(255)"), ("g_specieskey", "integer"), ("g_genericname", "varchar(255)"), ("g_genus", "varchar(50)"), ("g_genuskey", "integer"), ("g_family", "varchar(50)"), ("g_familykey", "integer"), ("g_order", "varchar(50)"), ("g_orderkey", "integer"), ("g_class", "varchar(50)"), ("g_classkey", "integer"), ("g_phylum", "varchar(50)"), ("g_phylumkey", "integer"), ("g_kingdom", "varchar(50)"), ("g_kingdomkey", "integer"), ("g_eventdate", "text"), ("g_verbatimeventdate", "varchar(50)"), ("g_startDayOfYear", "integer"), ("g_endDayOfYear", "integer"), ("g_year", "integer"), ("g_month", "integer"), ("g_day", "integer"), ("g_occurrenceid", "varchar(255)"), ("g_occurrenceStatus", "varchar(50)"), ("g_occurrenceRemarks", "varchar(50)"), ("g_Habitat", "varchar(50)"), ("g_basisofrecord", "varchar(50)"), ("g_preparations", "varchar(50)"), ("g_sex", "varchar(50)"), ("g_type", "varchar(50)"), ("g_locality", "varchar(255)"), ("g_verbatimlocality", "varchar(255)"), ("g_decimallongitude", "double precision"), ("g_decimallatitude", "double precision"), ("g_coordinateUncertaintyInMeters", "double precision"), ("g_geodeticdatum", "varchar(50)"), ("g_higerGeography", "varchar(255)"), ("g_continent", "varchar(50)"), ("g_country", "varchar(50)"), ("g_countryCode", "varchar(50)"), ("g_stateProvince", "varchar(50)"), ("g_gbifid", "varchar(255)"), ("g_protocol", "varchar(255)"), ("g_identifier", "varchar(50)"), ("g_recordedby", "varchar(255)"), ("g_identificationid", "varchar(255)"), ("g_identifiers", "text"), ("g_dateidentified", "text"), ("g_modified", "text"), ("g_institutioncode", "varchar(50)"), ("g_lastinterpreted", "text"), ("g_lastparsed", "text"), ("g_references", "varchar(255)"), ("g_relations", "text"), ("g_catalognumber", "varchar(50)"), ("g_occurrencedetails", "text"), ("g_datasetkey", "varchar(50)"), ("g_datasetname", "varchar(255)"), ("g_collectioncode", "varchar(50)"), ("g_rights", "varchar(255)"), ("g_rightsholder", "varchar(255)"), ("g_license", "varchar(50)"), ("g_publishingorgkey", "varchar(50)"), ("g_publishingcountry", "varchar(50)"), ("g_lastcrawled", "text"), ("g_specificepithet", "varchar(50)"), ("g_facts", "text"), ("g_issues", "text"), ("g_extensions", "text"), ("g_language", "varchar(50)"), ] # maybe no longer required in Python3 set_output_encoding() # Set temporal filter if requested by user # Initialize eventDate filter eventDate = None # Check if date from is compatible (ISO compliant) if date_from: try: parse(date_from) except: grass.fatal("Invalid invalid start date provided") if date_from and not date_to: eventDate = "{}".format(date_from) # Check if date to is compatible (ISO compliant) if date_to: try: parse(date_to) except: grass.fatal("Invalid invalid end date provided") # Check if date to is after date_from if parse(date_from) < parse(date_to): eventDate = "{},{}".format(date_from, date_to) else: grass.fatal( "Invalid date range: End date has to be after start date!") # Set filter on basisOfRecord if requested by user if basisofrecord == "ALL": basisOfRecord = None else: basisOfRecord = basisofrecord # Allow also occurrences with spatial issues if requested by user hasGeospatialIssue = False if hasGeoIssue: hasGeospatialIssue = True # Allow also occurrences without coordinates if requested by user hasCoordinate = True if allow_no_geom: hasCoordinate = False # Set reprojection parameters # Set target projection of current LOCATION proj_info = grass.parse_command("g.proj", flags="g") target_crs = grass.read_command("g.proj", flags="fj").rstrip() target = osr.SpatialReference() # Prefer EPSG CRS definitions if proj_info["epsg"]: target.ImportFromEPSG(int(proj_info["epsg"])) else: target.ImportFromProj4(target_crs) # GDAL >= 3 swaps x and y axis, see: github.com/gdal/issues/1546 if int(gdal_version[0]) >= 3: target.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER) if target_crs == "XY location (unprojected)": grass.fatal("Sorry, XY locations are not supported!") # Set source projection from GBIF source = osr.SpatialReference() source.ImportFromEPSG(4326) # GDAL >= 3 swaps x and y axis, see: github.com/gdal/issues/1546 if int(gdal_version[0]) >= 3: source.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER) if target_crs not in latlon_crs: transform = osr.CoordinateTransformation(source, target) reverse_transform = osr.CoordinateTransformation(target, source) # Generate WKT polygon to use for spatial filtering if requested if mask: if len(mask.split("@")) == 2: m = VectorTopo(mask.split("@")[0], mapset=mask.split("@")[1]) else: m = VectorTopo(mask) if not m.exist(): grass.fatal("Could not find vector map <{}>".format(mask)) m.open("r") if not m.is_open(): grass.fatal("Could not open vector map <{}>".format(mask)) # Use map Bbox as spatial filter if map contains <> 1 area if m.number_of("areas") == 1: region_pol = [area.to_wkt() for area in m.viter("areas")][0] else: bbox = (str(m.bbox()).replace("Bbox(", "").replace( " ", "").rstrip(")").split(",")) region_pol = "POLYGON (({0} {1}, {0} {3}, {2} {3}, {2} {1}, {0} {1}))".format( bbox[2], bbox[0], bbox[3], bbox[1]) m.close() else: # Do not limit import spatially if LOCATION is able to take global data if no_region_limit: if target_crs not in latlon_crs: grass.fatal("Import of data from outside the current region is" "only supported in a WGS84 location!") region_pol = None else: # Limit import spatially to current region # if LOCATION is !NOT! able to take global data # to avoid pprojection ERRORS region = grass.parse_command("g.region", flags="g") region_pol = "POLYGON (({0} {1},{0} {3},{2} {3},{2} {1},{0} {1}))".format( region["e"], region["n"], region["w"], region["s"]) # Do not reproject in latlon LOCATIONS if target_crs not in latlon_crs: pol = ogr.CreateGeometryFromWkt(region_pol) pol.Transform(reverse_transform) pol = pol.ExportToWkt() else: pol = region_pol # Create output map if not output maps for each species are requested if (not species_maps and not print_species and not print_species_shell and not print_occ_number and not print_species_table): mapname = output new = Vector(mapname) new.open("w", tab_name=mapname, tab_cols=cols) cat = 1 # Import data for each species for s in taxa_list: # Get the taxon key if not the taxon key is provided as input try: key = int(s) except: try: species_match = species.name_backbone(s, rank=rank, strict=False, verbose=True) key = species_match["usageKey"] except: grass.error( "Data request for taxon {} failed. Are you online?".format( s)) continue # Return matching taxon and alternatives and exit if print_species: print("Matching taxon for {} is:".format(s)) print("{} {}".format(species_match["scientificName"], species_match["status"])) if "alternatives" in list(species_match.keys()): print("Alternative matches might be: {}".format(s)) for m in species_match["alternatives"]: print("{} {}".format(m["scientificName"], m["status"])) else: print("No alternatives found for the given taxon") continue if print_species_shell: print("match={}".format(species_match["scientificName"])) if "alternatives" in list(species_match.keys()): alternatives = [] for m in species_match["alternatives"]: alternatives.append(m["scientificName"]) print("alternatives={}".format(",".join(alternatives))) continue if print_species_table: if "alternatives" in list(species_match.keys()): if len(species_match["alternatives"]) == 0: print("{0}|{1}|{2}|".format( s, key, species_match["scientificName"])) else: alternatives = [] for m in species_match["alternatives"]: alternatives.append(m["scientificName"]) print("{0}|{1}|{2}|{3}".format( s, key, species_match["scientificName"], ",".join(alternatives), )) continue try: returns_n = occurrences.search( taxonKey=key, hasGeospatialIssue=hasGeospatialIssue, hasCoordinate=hasCoordinate, institutionCode=institutionCode, basisOfRecord=basisOfRecord, recordedBy=recordedby, eventDate=eventDate, continent=continent, country=country, geometry=pol, limit=1, )["count"] except: grass.error( "Data request for taxon {} faild. Are you online?".format(s)) returns_n = 0 # Exit if search does not give a return # Print only number of returns for the given search and exit if print_occ_number: print("Found {0} occurrences for taxon {1}...".format( returns_n, s)) continue elif returns_n <= 0: grass.warning( "No occurrences for current search for taxon {0}...".format(s)) continue elif returns_n >= 200000: grass.warning( "Your search for {1} returns {0} records.\n" "Unfortunately, the GBIF search API is limited to 200,000 records per request.\n" "The download will be incomplete. Please consider to split up your search." .format(returns_n, s)) # Get the number of chunks to download chunks = int(math.ceil(returns_n / float(chunk_size))) grass.verbose("Downloading {0} occurrences for taxon {1}...".format( returns_n, s)) # Create a map for each species if requested using map name as suffix if species_maps: mapname = "{}_{}".format(s.replace(" ", "_"), output) new = Vector(mapname) new.open("w", tab_name=mapname, tab_cols=cols) cat = 0 # Download the data from GBIF for c in range(chunks): # Define offset offset = c * chunk_size # Adjust chunk_size to the hard limit of 200,000 records in GBIF API # if necessary if offset + chunk_size >= 200000: chunk_size = 200000 - offset # Get the returns for the next chunk returns = occurrences.search( taxonKey=key, hasGeospatialIssue=hasGeospatialIssue, hasCoordinate=hasCoordinate, institutionCode=institutionCode, basisOfRecord=basisOfRecord, recordedBy=recordedby, eventDate=eventDate, continent=continent, country=country, geometry=pol, limit=chunk_size, offset=offset, ) # Write the returned data to map and attribute table for res in returns["results"]: if target_crs not in latlon_crs: point = ogr.CreateGeometryFromWkt("POINT ({} {})".format( res["decimalLongitude"], res["decimalLatitude"])) point.Transform(transform) x = point.GetX() y = point.GetY() else: x = res["decimalLongitude"] y = res["decimalLatitude"] point = Point(x, y) for k in dwc_keys: if k not in list(res.keys()): res.update({k: None}) cat = cat + 1 new.write( point, cat=cat, attrs=( "{}".format(s), res["key"], res["taxonRank"], res["taxonKey"], res["taxonID"], res["scientificName"], res["species"], res["speciesKey"], res["genericName"], res["genus"], res["genusKey"], res["family"], res["familyKey"], res["order"], res["orderKey"], res["class"], res["classKey"], res["phylum"], res["phylumKey"], res["kingdom"], res["kingdomKey"], "{}".format(res["eventDate"]) if res["eventDate"] else None, "{}".format(res["verbatimEventDate"]) if res["verbatimEventDate"] else None, res["startDayOfYear"], res["endDayOfYear"], res["year"], res["month"], res["day"], res["occurrenceID"], res["occurrenceStatus"], res["occurrenceRemarks"], res["Habitat"], res["basisOfRecord"], res["preparations"], res["sex"], res["type"], res["locality"], res["verbatimLocality"], res["decimalLongitude"], res["decimalLatitude"], res["coordinateUncertaintyInMeters"], res["geodeticDatum"], res["higerGeography"], res["continent"], res["country"], res["countryCode"], res["stateProvince"], res["gbifID"], res["protocol"], res["identifier"], res["recordedBy"], res["identificationID"], ",".join(res["identifiers"]), "{}".format(res["dateIdentified"]) if res["dateIdentified"] else None, "{}".format(res["modified"]) if res["modified"] else None, res["institutionCode"], "{}".format(res["lastInterpreted"]) if res["lastInterpreted"] else None, "{}".format(res["lastParsed"]) if res["lastParsed"] else None, res["references"], ",".join(res["relations"]), res["catalogNumber"], "{}".format(res["occurrenceDetails"]) if res["occurrenceDetails"] else None, res["datasetKey"], res["datasetName"], res["collectionCode"], res["rights"], res["rightsHolder"], res["license"], res["publishingOrgKey"], res["publishingCountry"], "{}".format(res["lastCrawled"]) if res["lastCrawled"] else None, res["specificEpithet"], ",".join(res["facts"]), ",".join(res["issues"]), ",".join(res["extensions"]), res["language"], ), ) cat = cat + 1 # Close the current map if a map for each species is requested if species_maps: new.table.conn.commit() new.close() if not no_topo: grass.run_command("v.build", map=mapname, option="build") # Write history to map grass.vector_history(mapname) # Close the output map if not a map for each species is requested if (not species_maps and not print_species and not print_species_shell and not print_occ_number and not print_species_table): new.table.conn.commit() new.close() if not no_topo: grass.run_command("v.build", map=mapname, option="build") # Write history to map grass.vector_history(mapname)
def main(): in_vector = options["input"].split("@")[0] if len(options["input"].split("@")) > 1: in_mapset = options["input"].split("@")[1] else: in_mapset = None raster_maps = options["raster"].split( ",") # raster file(s) to extract from output = options["output"] methods = tuple(options["methods"].split(",")) percentile = (None if options["percentile"] == "" else map( float, options["percentile"].split(","))) column_prefix = tuple(options["column_prefix"].split(",")) buffers = options["buffers"].split(",") types = options["type"].split(",") layer = options["layer"] sep = options["separator"] update = flags["u"] tabulate = flags["t"] percent = flags["p"] remove = flags["r"] use_label = flags["l"] empty_buffer_warning = ( "No data in raster map {} within buffer {} around geometry {}") # Do checks using pygrass for rmap in raster_maps: r_map = RasterAbstractBase(rmap) if not r_map.exist(): grass.fatal("Could not find raster map {}.".format(rmap)) user_mask = False m_map = RasterAbstractBase("MASK", Mapset().name) if m_map.exist(): grass.warning("Current MASK is temporarily renamed.") user_mask = True unset_mask() invect = VectorTopo(in_vector) if not invect.exist(): grass.fatal("Vector file {} does not exist".format(in_vector)) if output: if output == "-": out = None else: out = open(output, "w") # Check if input map is in current mapset (and thus editable) if in_mapset and unicode(in_mapset) != unicode(Mapset()): grass.fatal( "Input vector map is not in current mapset and cannot be modified. \ Please consider copying it to current mapset.".format( output)) buffers = [] for buf in options["buffers"].split(","): try: b = float(buf) if b.is_integer(): buffers.append(int(b)) else: buffers.append(b) except: grass.fatal("") if b < 0: grass.fatal("Negative buffer distance not supported!") ### Define column types depenting on statistic, map type and ### DB backend (SQLite supports only double and not real) # int: statistic produces allways integer precision # double: statistic produces allways floating point precision # map_type: precision f statistic depends on map type int_dict = { "number": (0, "int", "n"), "number_null": (1, "int", "null_cells"), "minimum": (3, "map_type", "min"), "maximum": (4, "map_type", "max"), "range": (5, "map_type", "range"), "average": (6, "double", "mean"), "average_abs": (7, "double", "mean_of_abs"), "stddev": (8, "double", "stddev"), "variance": (9, "double", "variance"), "coeff_var": (10, "double", "coeff_var"), "sum": (11, "map_type", "sum"), "first_quartile": (12, "map_type", "first_quartile"), "median": (13, "map_type", "median"), "third_quartile": (14, "map_type", "third_quartile"), "percentile": (15, "map_type", "percentile"), } if len(raster_maps) != len(column_prefix): grass.fatal( "Number of maps and number of column prefixes has to be equal!") # Generate list of required column names and types col_names = [] valid_labels = [] col_types = [] for p in column_prefix: rmaptype, val_lab, rcats = raster_type( raster_maps[column_prefix.index(p)], tabulate, use_label) valid_labels.append(val_lab) for b in buffers: b_str = str(b).replace(".", "_") if tabulate: if rmaptype == "double precision": grass.fatal( "{} has floating point precision. Can only tabulate integer maps" .format(raster_maps[column_prefix.index(p)])) col_names.append("{}_{}_b{}".format(p, "ncats", b_str)) col_types.append("int") col_names.append("{}_{}_b{}".format(p, "mode", b_str)) col_types.append("int") col_names.append("{}_{}_b{}".format(p, "null", b_str)) col_types.append("double precision") col_names.append("{}_{}_b{}".format(p, "area_tot", b_str)) col_types.append("double precision") for rcat in rcats: if use_label and valid_labels: rcat = rcat[0].replace(" ", "_") else: rcat = rcat[1] col_names.append("{}_{}_b{}".format(p, rcat, b_str)) col_types.append("double precision") else: for m in methods: col_names.append("{}_{}_b{}".format( p, int_dict[m][2], b_str)) col_types.append(rmaptype if int_dict[m][1] == "map_type" else int_dict[m][1]) if percentile: for perc in percentile: col_names.append("{}_percentile_{}_b{}".format( p, int(perc) if (perc).is_integer() else perc, b_str)) col_types.append(rmaptype if int_dict[m][1] == "map_type" else int_dict[m][1]) # Open input vector map in_vect = VectorTopo(in_vector, layer=layer) in_vect.open(mode="r") # Get name for temporary map global TMP_MAPS TMP_MAPS.append(tmp_map) # Setup stats collectors if tabulate: # Collector for raster category statistics stats = Module("r.stats", run_=False, stdout_=PIPE) stats.inputs.sort = "desc" stats.inputs.null_value = "null" stats.flags.quiet = True stats.flags.l = True if percent: stats.flags.p = True stats.flags.n = True else: stats.flags.a = True else: # Collector for univariat statistics univar = Module("r.univar", run_=False, stdout_=PIPE) univar.inputs.separator = sep univar.flags.g = True univar.flags.quiet = True # Add extended statistics if requested if set(methods).intersection( set(["first_quartile", "median", "third_quartile"])): univar.flags.e = True if percentile is not None: univar.flags.e = True univar.inputs.percentile = percentile # Check if attribute table exists if not output: if not in_vect.table: grass.fatal( "No attribute table found for vector map {}".format(in_vect)) # Modify table as needed tab = in_vect.table tab_name = tab.name tab_cols = tab.columns # Add required columns existing_cols = list(set(tab_cols.names()).intersection(col_names)) if len(existing_cols) > 0: if not update: in_vect.close() grass.fatal( "Column(s) {} already exist! Please use the u-flag \ if you want to update values in those columns". format(",".join(existing_cols))) else: grass.warning("Column(s) {} already exist!".format( ",".join(existing_cols))) for e in existing_cols: idx = col_names.index(e) del col_names[idx] del col_types[idx] tab_cols.add(col_names, col_types) conn = tab.conn cur = conn.cursor() sql_str_start = "UPDATE {} SET ".format(tab_name) elif output == "-": print("cat{0}raster_map{0}buffer{0}statistic{0}value".format(sep)) else: out.write("cat{0}raster_map{0}buffer{0}statistic{0}value{1}".format( sep, os.linesep)) # Get computational region grass.use_temp_region() r = Region() r.read() # Adjust region extent to buffer around geometry # reg = deepcopy(r) # Create iterator for geometries of all selected types geoms = chain() geoms_n = 0 n_geom = 1 for geom_type in types: geoms_n += in_vect.number_of(geom_type) if in_vect.number_of(geom_type) > 0: geoms = chain(in_vect.viter(geom_type)) # Loop over geometries for geom in geoms: # Get cat cat = geom.cat # Add where clause to UPDATE statement sql_str_end = " WHERE cat = {};".format(cat) # Loop over ser provided buffer distances for buf in buffers: b_str = str(buf).replace(".", "_") # Buffer geometry if buf <= 0: buffer_geom = geom else: buffer_geom = geom.buffer(buf) # Create temporary vector map with buffered geometry tmp_vect = VectorTopo(tmp_map, quiet=True) tmp_vect.open(mode="w") tmp_vect.write(Boundary(points=buffer_geom[0].to_list())) # , c_cats=int(cat), set_cats=True if callable(buffer_geom[1]): tmp_vect.write(Centroid(x=buffer_geom[1]().x, y=buffer_geom[1]().y), cat=int(cat)) else: tmp_vect.write(Centroid(x=buffer_geom[1].x, y=buffer_geom[1].y), cat=int(cat)) ################################################# # How to silence VectorTopo??? ################################################# # Save current stdout # original = sys.stdout # f = open(os.devnull, 'w') # with open('output.txt', 'w') as f: # sys.stdout = io.BytesIO() # sys.stdout.fileno() = os.devnull # sys.stderr = f # os.environ.update(dict(GRASS_VERBOSE='0')) tmp_vect.close(build=False) grass.run_command("v.build", map=tmp_map, quiet=True) # os.environ.update(dict(GRASS_VERBOSE='1')) # reg = Region() # reg.read() # r.from_vect(tmp_map) r = align_current(r, buffer_geom[0].bbox()) r.write() # Check if the following is needed # needed specially with r.stats -p # grass.run_command('g.region', vector=tmp_map, flags='a') # Create a MASK from buffered geometry if user_mask: grass.run_command( "v.to.rast", input=tmp_map, output=tmp_map, use="val", value=int(cat), quiet=True, ) mc_expression = ( "MASK=if(!isnull({0}) && !isnull({0}_MASK), {1}, null())". format(tmp_map, cat)) grass.run_command("r.mapcalc", expression=mc_expression, quiet=True) else: grass.run_command( "v.to.rast", input=tmp_map, output="MASK", use="val", value=int(cat), quiet=True, ) # reg.write() updates = [] # Compute statistics for every raster map for rm, rmap in enumerate(raster_maps): # rmap = raster_maps[rm] prefix = column_prefix[rm] if tabulate: # Get statistics on occurrence of raster categories within buffer stats.inputs.input = rmap stats.run() t_stats = (stats.outputs["stdout"].value.rstrip( os.linesep).replace(" ", " ").replace( "no data", "no_data").replace( " ", "_b{} = ".format(b_str)).split(os.linesep)) if t_stats == [""]: grass.warning( empty_buffer_warning.format(rmap, buf, cat)) continue if (t_stats[0].split( "_b{} = ".format(b_str))[0].split("_")[-1] != "null"): mode = (t_stats[0].split( "_b{} = ".format(b_str))[0].split("_")[-1]) elif len(t_stats) == 1: mode = "NULL" else: mode = (t_stats[1].split( "_b{} = ".format(b_str))[0].split("_")[-1]) if not output: updates.append("\t{}_{}_b{} = {}".format( prefix, "ncats", b_str, len(t_stats))) updates.append("\t{}_{}_b{} = {}".format( prefix, "mode", b_str, mode)) area_tot = 0 for l in t_stats: # check if raster maps has category or not if len(l.split("=")) == 2: updates.append("\t{}_{}".format( prefix, l.rstrip("%"))) elif not l.startswith("null"): vals = l.split("=") updates.append("\t{}_{} = {}".format( prefix, vals[-2].strip() if valid_labels[rm] else vals[0].strip(), vals[-1].strip().rstrip("%"), )) if not l.startswith("null"): area_tot += float( l.rstrip("%").split("= ")[-1]) if not percent: updates.append("\t{}_{}_b{} = {}".format( prefix, "area_tot", b_str, area_tot)) else: out_str = "{1}{0}{2}{0}{3}{0}{4}{0}{5}{6}".format( sep, cat, prefix, buf, "ncats", len(t_stats), os.linesep) out_str += "{1}{0}{2}{0}{3}{0}{4}{0}{5}{6}".format( sep, cat, prefix, buf, "mode", mode, os.linesep) area_tot = 0 for l in t_stats: rcat = (l.split("= ")[1].rstrip( "_b{} = ".format(b_str)) if valid_labels[rm] else l.split("_")[0]) area = l.split("= ")[-1] out_str += "{1}{0}{2}{0}{3}{0}{4}{0}{5}{6}".format( sep, cat, prefix, buf, "area {}".format(rcat), area, os.linesep, ) if rcat != "null": area_tot = area_tot + float( l.rstrip("%").split("= ")[-1]) if not percent: out_str += "{1}{0}{2}{0}{3}{0}{4}{0}{5}{6}".format( sep, cat, prefix, buf, "area total", area_tot, os.linesep, ) if output == "-": print(out_str.rstrip(os.linesep)) else: out.write(out_str) else: # Get univariate statistics within buffer univar.inputs.map = rmap univar.run() u_stats = (univar.outputs["stdout"].value.rstrip( os.linesep).replace( "=", "_b{} = ".format(b_str)).split(os.linesep)) # Test if u_stats is empty and give warning # Needs to be adjusted to number of requested stats? if ((percentile and len(u_stats) < 14) or (univar.flags.e and len(u_stats) < 13) or len(u_stats) < 12): grass.warning( empty_buffer_warning.format(rmap, buf, cat)) break # Extract statistics for selected methods for m in methods: if not output: # Add to list of UPDATE statements updates.append("\t{}_{}".format( prefix, u_stats[int_dict[m][0]] if is_number( u_stats[int_dict[m][0]].split(" = ")[1]) else " = ".join([ u_stats[int_dict[m][0]].split(" = ")[0], "NULL", ]), )) else: out_str = "{1}{0}{2}{0}{3}{0}{4}{0}{5}".format( sep, cat, prefix, buf, m, u_stats[int_dict[m][0]].split("= ")[1], ) if output == "-": print(out_str) else: out.write("{}{}".format(out_str, os.linesep)) if percentile: perc_count = 0 for perc in percentile: if not output: updates.append( "{}_percentile_{}_b{} = {}".format( p, int(perc) if (perc).is_integer() else perc, b_str, u_stats[15 + perc_count].split("= ")[1], )) else: out_str = "{1}{0}{2}{0}{3}{0}{4}{0}{5}".format( sep, cat, prefix, buf, "percentile_{}".format( int(perc) if ( perc).is_integer() else perc), u_stats[15 + perc_count].split("= ")[1], ) if output == "-": print(out_str) else: out.write(out_str) perc_count = perc_count + 1 if not output and len(updates) > 0: cur.execute("{}{}{}".format(sql_str_start, ",\n".join(updates), sql_str_end)) # Remove temporary maps # , stderr=os.devnull, stdout_=os.devnull) grass.run_command("g.remove", flags="f", type="raster", name="MASK", quiet=True) grass.run_command("g.remove", flags="f", type="vector", name=tmp_map, quiet=True) # Give progress information grass.percent(n_geom, geoms_n, 1) n_geom = n_geom + 1 if not output: conn.commit() # Close cursor and DB connection if not output and not output == "-": cur.close() conn.close() # Update history grass.vector.vector_history(in_vector) elif output != "-": # write results to file out.close() if remove and not output: dropcols = [] selectnum = "select count({}) from {}" for i in col_names: thisrow = grass.read_command("db.select", flags="c", sql=selectnum.format(i, in_vector)) if int(thisrow) == 0: dropcols.append(i) grass.debug("Columns to delete: {}".format(", ".join(dropcols)), debug=2) if dropcols: grass.run_command("v.db.dropcolumn", map=in_vector, columns=dropcols)
def main(): in_vector = options['input'].split('@')[0] if len(options['input'].split('@')) > 1: in_mapset = options['input'].split('@')[1] else: in_mapset = None raster_maps = options['raster'].split(',') # raster file(s) to extract from output = options['output'] methods = tuple(options['methods'].split(',')) percentile = None if options['percentile'] == '' else map(float, options['percentile'].split(',')) column_prefix = tuple(options['column_prefix'].split(',')) buffers = options['buffers'].split(',') types = options['type'].split(',') layer = options['layer'] sep = options['separator'] update = flags['u'] tabulate = flags['t'] percent = flags['p'] remove = flags['r'] use_lable = False empty_buffer_warning = 'No data in raster map {} within buffer {} around geometry {}' # Do checks using pygrass for rmap in raster_maps: r_map = RasterAbstractBase(rmap) if not r_map.exist(): grass.fatal('Could not find raster map {}.'.format(rmap)) user_mask = False m_map = RasterAbstractBase('MASK', Mapset().name) if m_map.exist(): grass.warning("Current MASK is temporarily renamed.") user_mask = True unset_mask() invect = VectorTopo(in_vector) if not invect.exist(): grass.fatal("Vector file {} does not exist".format(in_vector)) if output: if output == '-': out = None else: out = open(output, 'w') # Check if input map is in current mapset (and thus editable) if in_mapset and unicode(in_mapset) != unicode(Mapset()): grass.fatal("Input vector map is not in current mapset and cannot be modified. \ Please consider copying it to current mapset.".format(output)) buffers = [] for buf in options['buffers'].split(','): try: b = float(buf) if b.is_integer(): buffers.append(int(b)) else: buffers.append(b) except: grass.fatal('') if b < 0: grass.fatal("Negative buffer distance not supported!") ### Define column types depenting on statistic, map type and ### DB backend (SQLite supports only double and not real) # int: statistic produces allways integer precision # double: statistic produces allways floating point precision # map_type: precision f statistic depends on map type int_dict = {'number': (0, 'int', 'n'), 'number_null': (1, 'int', 'null_cells'), 'minimum': (3, 'map_type', 'min'), 'maximum': (4, 'map_type', 'max'), 'range': (5, 'map_type', 'range'), 'average': (6, 'double', 'mean'), 'average_abs': (7, 'double', 'mean_of_abs'), 'stddev': (8, 'double', 'stddev'), 'variance': (9, 'double', 'variance'), 'coeff_var': (10, 'double', 'coeff_var'), 'sum': (11, 'map_type', 'sum'), 'first_quartile': (12, 'map_type', 'first_quartile'), 'median': (13, 'map_type', 'median'), 'third_quartile': (14, 'map_type', 'third_quartile'), 'percentile': (15, 'map_type', 'percentile')} if len(raster_maps) != len(column_prefix): grass.fatal('Number of maps and number of column prefixes has to be equal!') # Generate list of required column names and types col_names = [] col_types = [] for p in column_prefix: rmaptype, rcats = raster_type(raster_maps[column_prefix.index(p)], tabulate, use_lable) for b in buffers: b_str = str(b).replace('.', '_') if tabulate: if rmaptype == 'double precision': grass.fatal('{} has floating point precision. Can only tabulate integer maps'.format(raster_maps[column_prefix.index(p)])) col_names.append('{}_{}_b{}'.format(p, 'ncats', b_str)) col_types.append('int') col_names.append('{}_{}_b{}'.format(p, 'mode', b_str)) col_types.append('int') col_names.append('{}_{}_b{}'.format(p, 'null', b_str)) col_types.append('double precision') col_names.append('{}_{}_b{}'.format(p, 'area_tot', b_str)) col_types.append('double precision') for rcat in rcats: if use_lable: rcat = rcat[1].replace(" ", "_") else: rcat = rcat[0] col_names.append('{}_{}_b{}'.format(p, rcat, b_str)) col_types.append('double precision') else: for m in methods: col_names.append('{}_{}_b{}'.format(p, int_dict[m][2], b_str)) col_types.append(rmaptype if int_dict[m][1] == 'map_type' else int_dict[m][1]) if percentile: for perc in percentile: col_names.append('{}_percentile_{}_b{}'.format(p, int(perc) if (perc).is_integer() else perc, b_str)) col_types.append(rmaptype if int_dict[m][1] == 'map_type' else int_dict[m][1]) # Open input vector map in_vect = VectorTopo(in_vector, layer=layer) in_vect.open(mode='r') # Get name for temporary map TMP_MAPS.append(tmp_map) # Setup stats collectors if tabulate: # Collector for raster category statistics stats = Module('r.stats', run_=False, stdout_=PIPE) stats.inputs.sort = 'desc' stats.inputs.null_value = 'null' stats.flags.quiet = True if percent: stats.flags.p = True stats.flags.n = True else: stats.flags.a = True else: # Collector for univariat statistics univar = Module('r.univar', run_=False, stdout_=PIPE) univar.inputs.separator = sep univar.flags.g = True univar.flags.quiet = True # Add extended statistics if requested if set(methods).intersection(set(['first_quartile', 'median', 'third_quartile'])): univar.flags.e = True if percentile is not None: univar.flags.e = True univar.inputs.percentile = percentile # Check if attribute table exists if not output: if not in_vect.table: grass.fatal('No attribute table found for vector map {}'.format(in_vect)) # Modify table as needed tab = in_vect.table tab_name = tab.name tab_cols = tab.columns # Add required columns existing_cols = list(set(tab_cols.names()).intersection(col_names)) if len(existing_cols) > 0: if not update: grass.fatal('Column(s) {} already exist! Please use the u-flag \ if you want to update values in those columns'.format(','.join(existing_cols))) else: grass.warning('Column(s) {} already exist!'.format(','.join(existing_cols))) for e in existing_cols: idx = col_names.index(e) del col_names[idx] del col_types[idx] tab_cols.add(col_names, col_types) conn = tab.conn cur = conn.cursor() sql_str_start = 'UPDATE {} SET '.format(tab_name) elif output == '-': print('cat{0}raster_map{0}buffer{0}statistic{0}value'.format(sep)) else: out.write('cat{0}raster_map{0}buffer{0}statistic{0}value{1}'.format(sep, os.linesep)) # Get computational region grass.use_temp_region() r = Region() r.read() # Adjust region extent to buffer around geometry #reg = deepcopy(r) # Create iterator for geometries of all selected types geoms = chain() geoms_n = 0 n_geom = 1 for geom_type in types: geoms_n += in_vect.number_of(geom_type) if in_vect.number_of(geom_type) > 0: geoms = chain(in_vect.viter(geom_type)) # Loop over geometries for geom in geoms: # Get cat cat = geom.cat # Add where clause to UPDATE statement sql_str_end = ' WHERE cat = {};'.format(cat) # Loop over ser provided buffer distances for buf in buffers: b_str = str(buf).replace('.', '_') # Buffer geometry if buf <= 0: buffer_geom = geom else: buffer_geom = geom.buffer(buf) # Create temporary vector map with buffered geometry tmp_vect = VectorTopo(tmp_map, quiet=True) tmp_vect.open(mode='w') #print(int(cat)) tmp_vect.write(Boundary(points=buffer_geom[0].to_list())) # , c_cats=int(cat), set_cats=True tmp_vect.write(Centroid(x=buffer_geom[1].x, y=buffer_geom[1].y), cat=int(cat)) ################################################# # How to silence VectorTopo??? ################################################# # Save current stdout #original = sys.stdout #f = open(os.devnull, 'w') #with open('output.txt', 'w') as f: #sys.stdout = io.BytesIO() #sys.stdout.fileno() = os.devnull #sys.stderr = f #os.environ.update(dict(GRASS_VERBOSE='0')) tmp_vect.close(build=False) grass.run_command('v.build', map=tmp_map, quiet=True) #os.environ.update(dict(GRASS_VERBOSE='1')) #reg = Region() #reg.read() #r.from_vect(tmp_map) r = align_current(r, buffer_geom[0].bbox()) r.write() # Check if the following is needed # needed specially with r.stats -p #grass.run_command('g.region', vector=tmp_map, flags='a') # Create a MASK from buffered geometry if user_mask: grass.run_command('v.to.rast', input=tmp_map, output=tmp_map, use='val', value=int(cat), quiet=True) mc_expression = "MASK=if(!isnull({0}) && !isnull({0}_MASK), {1}, null())".format(tmp_map, cat) grass.run_command('r.mapcalc', expression=mc_expression, quiet=True) else: grass.run_command('v.to.rast', input=tmp_map, output='MASK', use='val', value=int(cat), quiet=True) #reg.write() updates = [] # Compute statistics for every raster map for rm in range(len(raster_maps)): rmap = raster_maps[rm] prefix = column_prefix[rm] if tabulate: # Get statistics on occurrence of raster categories within buffer stats.inputs.input = rmap stats.run() t_stats = stats.outputs['stdout'].value.rstrip(os.linesep).replace(' ', '_b{} = '.format(b_str)).split(os.linesep) if t_stats[0].split('_b{} = '.format(b_str))[0].split('_')[-1] != 'null': mode = t_stats[0].split('_b{} = '.format(b_str))[0].split('_')[-1] elif len(t_stats) == 1: mode = 'NULL' else: mode = t_stats[1].split('_b{} = '.format(b_str))[0].split('_')[-1] if not output: updates.append('\t{}_{}_b{} = {}'.format(prefix, 'ncats', b_str, len(t_stats))) updates.append('\t{}_{}_b{} = {}'.format(prefix, 'mode', b_str, mode)) area_tot = 0 for l in t_stats: updates.append('\t{}_{}'.format(prefix, l.rstrip('%'))) if l.split('_b{} ='.format(b_str))[0].split('_')[-1] != 'null': area_tot = area_tot + float(l.rstrip('%').split('= ')[1]) if not percent: updates.append('\t{}_{}_b{} = {}'.format(prefix, 'area_tot', b_str, area_tot)) else: out_str = '{1}{0}{2}{0}{3}{0}{4}{0}{5}{6}'.format(sep, cat, prefix, buf, 'ncats', len(t_stats), os.linesep) out_str += '{1}{0}{2}{0}{3}{0}{4}{0}{5}{6}'.format(sep, cat, prefix, buf, 'mode', mode, os.linesep) area_tot = 0 if not t_stats[0]: grass.warning(empty_buffer_warning.format(rmap, buf, cat)) continue for l in t_stats: rcat = l.split('_b{} ='.format(b_str))[0].split('_')[-1] area = l.split('= ')[1] out_str += '{1}{0}{2}{0}{3}{0}{4}{0}{5}{6}'.format(sep, cat, prefix, buf, 'area {}'.format(rcat), area, os.linesep) if rcat != 'null': area_tot = area_tot + float(l.rstrip('%').split('= ')[1]) out_str += '{1}{0}{2}{0}{3}{0}{4}{0}{5}{6}'.format(sep, cat, prefix, buf, 'area_tot', area_tot, os.linesep) if output == '-': print(out_str.rstrip(os.linesep)) else: out.write(out_str) else: # Get univariate statistics within buffer univar.inputs.map = rmap univar.run() u_stats = univar.outputs['stdout'].value.rstrip(os.linesep).replace('=', '_b{} = '.format(b_str)).split(os.linesep) # Test if u_stats is empty and give warning # Needs to be adjusted to number of requested stats? if (percentile and len(u_stats) < 14) or (univar.flags.e and len(u_stats) < 13) or len(u_stats) < 12: grass.warning(empty_buffer_warning.format(rmap, buf, cat)) break # Extract statistics for selected methods for m in methods: if not output: # Add to list of UPDATE statements updates.append('\t{}_{}'.format(prefix, u_stats[int_dict[m][0]])) else: out_str = '{1}{0}{2}{0}{3}{0}{4}{0}{5}'.format(sep, cat, prefix, buf, m, u_stats[int_dict[m][0]].split('= ')[1]) if output == '-': print(out_str) else: out.write("{}{}".format(out_str, os.linesep)) if percentile: perc_count = 0 for perc in percentile: if not output: updates.append('{}_percentile_{}_b{} = {}'.format(p, int(perc) if (perc).is_integer() else perc, b_str, u_stats[15+perc_count].split('= ')[1])) else: out_str = '{1}{0}{2}{0}{3}{0}{4}{0}{5}'.format(sep, cat, prefix, buf, 'percentile_{}'.format(int(perc) if (perc).is_integer() else perc), u_stats[15+perc_count].split('= ')[1]) if output == '-': print(out_str) else: out.write(out_str) perc_count = perc_count + 1 if not output and len(updates) > 0: cur.execute('{}{}{}'.format(sql_str_start, ',\n'.join(updates), sql_str_end)) # Remove temporary maps #, stderr=os.devnull, stdout_=os.devnull) grass.run_command('g.remove', flags='f', type='raster', name='MASK', quiet=True) grass.run_command('g.remove', flags='f', type='vector', name=tmp_map, quiet=True) # Give progress information grass.percent(n_geom, geoms_n, 1) n_geom = n_geom + 1 if not output: conn.commit() # Close cursor and DB connection if not output and not output == "-": cur.close() conn.close() # Update history grass.vector.vector_history(in_vector) elif output != "-": # write results to file out.close() if remove: dropcols = [] selectnum = 'select count({}) from {}' for i in col_names: thisrow = grass.read_command('db.select', flags='c', sql=selectnum.format(i, in_vector)) if int(thisrow) == 0: dropcols.append(i) grass.debug("Columns to delete: {}".format(', '.join(dropcols)), debug=2) grass.run_command('v.db.dropcolumn', map=in_vector, columns=dropcols)
#!/usr/bin/env python3 from grass.pygrass.vector import VectorTopo psc = '41115' obce = VectorTopo('obce') obce.open('r') print("Seznam obci s PSC {}:".format(psc)) obce_psc = set() for prvek in obce.viter('areas'): if prvek.attrs is None or prvek.attrs['psc'] != psc: continue obce_psc.add(prvek.id) print("{0}: {1}".format(psc, prvek.attrs['nazev'])) sousede = set() for prvek in obce.viter('areas'): if prvek.id not in obce_psc: continue for b in prvek.boundaries(): for n in b.read_area_ids(): if n != -1 and n != prvek.id: sousede.add(n) print("Seznam sousednich obce:") for prvek in obce.viter('areas'): if prvek.id not in sousede or \ prvek.attrs['psc'] == psc:
#!/usr/bin/env python3 from grass.pygrass.vector import VectorTopo counties = VectorTopo('counties') counties.open('r') for o in counties.viter('areas'): neighbours = set() for b in o.boundaries(): for n in b.read_area_ids(): if n != -1 and n != o.id: neighbours.add(n) if o.attrs: print('{:25}: {}'.format(o.attrs['name'], len(neighbours))) counties.close()
#!/usr/bin/env python3 from grass.pygrass.vector import VectorTopo okresy = VectorTopo('okresy', mapset='ruian') okresy.open('r') for o in okresy.viter('areas'): sousede = set() for b in o.boundaries(): for n in b.read_area_ids(): if n != -1 and n != o.id: sousede.add(n) print('{:20}: {}'.format(o.attrs['nazev'], len(sousede))) okresy.close()
def main(): try: from pygbif import occurrences from pygbif import species except ImportError: grass.fatal(_("Cannot import pygbif (https://github.com/sckott/pygbif)" " library." " Please install it (pip install pygbif)" " or ensure that it is on path" " (use PYTHONPATH variable).")) # Parse input options output = options['output'] mask = options['mask'] species_maps = flags['i'] no_region_limit = flags['r'] no_topo = flags['b'] print_species = flags['p'] print_species_table = flags['t'] print_species_shell = flags['g'] print_occ_number = flags['o'] allow_no_geom = flags['n'] hasGeoIssue = flags['s'] taxa_list = options['taxa'].split(',') institutionCode = options['institutioncode'] basisofrecord = options['basisofrecord'] recordedby = options['recordedby'].split(',') date_from = options['date_from'] date_to = options['date_to'] country = options['country'] continent = options['continent'] rank = options['rank'] # Define static variable #Initialize cat cat = 0 # Number of occurrences to fetch in one request chunk_size = 300 # lat/lon proj string latlon_crs = ['+proj=longlat +no_defs +a=6378137 +rf=298.257223563 +towgs84=0.000,0.000,0.000', '+proj=longlat +no_defs +a=6378137 +rf=298.257223563 +towgs84=0,0,0,0,0,0,0'] # List attributes available in Darwin Core # not all attributes are returned in each request # to avoid key errors when accessing the dictionary returned by pygbif # presence of DWC keys in the returned dictionary is checked using this list # The number of keys in this list has to be equal to the number of columns # in the attribute table and the attributes written for each occurrence dwc_keys = ['key', 'taxonRank', 'taxonKey', 'taxonID', 'scientificName', 'species', 'speciesKey', 'genericName', 'genus', 'genusKey', 'family', 'familyKey', 'order', 'orderKey', 'class', 'classKey', 'phylum', 'phylumKey', 'kingdom', 'kingdomKey', 'eventDate', 'verbatimEventDate', 'startDayOfYear', 'endDayOfYear', 'year', 'month', 'day', 'occurrenceID', 'occurrenceStatus', 'occurrenceRemarks', 'Habitat', 'basisOfRecord', 'preparations', 'sex', 'type', 'locality', 'verbatimLocality', 'decimalLongitude', 'decimalLatitude', 'geodeticDatum', 'higerGeography', 'continent', 'country', 'countryCode', 'stateProvince', 'gbifID', 'protocol', 'identifier', 'recordedBy', 'identificationID', 'identifiers', 'dateIdentified', 'modified', 'institutionCode', 'lastInterpreted', 'lastParsed', 'references', 'relations', 'catalogNumber', 'occurrenceDetails', 'datasetKey', 'datasetName', 'collectionCode', 'rights', 'rightsHolder', 'license', 'publishingOrgKey', 'publishingCountry', 'lastCrawled', 'specificEpithet', 'facts', 'issues', 'extensions', 'language'] # Deinfe columns for attribute table cols = [('cat', 'INTEGER PRIMARY KEY'), ('g_search', 'varchar(100)'), ('g_key', 'integer'), ('g_taxonrank', 'varchar(50)'), ('g_taxonkey', 'integer'), ('g_taxonid', 'varchar(50)'), ('g_scientificname', 'varchar(255)'), ('g_species', 'varchar(255)'), ('g_specieskey', 'integer'), ('g_genericname', 'varchar(255)'), ('g_genus', 'varchar(50)'), ('g_genuskey', 'integer'), ('g_family', 'varchar(50)'), ('g_familykey', 'integer'), ('g_order', 'varchar(50)'), ('g_orderkey', 'integer'), ('g_class', 'varchar(50)'), ('g_classkey', 'integer'), ('g_phylum', 'varchar(50)'), ('g_phylumkey', 'integer'), ('g_kingdom', 'varchar(50)'), ('g_kingdomkey', 'integer'), ('g_eventdate', 'text'), ('g_verbatimeventdate', 'varchar(50)'), ('g_startDayOfYear', 'integer'), ('g_endDayOfYear', 'integer'), ('g_year', 'integer'), ('g_month', 'integer'), ('g_day', 'integer'), ('g_occurrenceid', 'varchar(255)'), ('g_occurrenceStatus', 'varchar(50)'), ('g_occurrenceRemarks', 'varchar(50)'), ('g_Habitat', 'varchar(50)'), ('g_basisofrecord', 'varchar(50)'), ('g_preparations', 'varchar(50)'), ('g_sex', 'varchar(50)'), ('g_type', 'varchar(50)'), ('g_locality', 'varchar(255)'), ('g_verbatimlocality', 'varchar(255)'), ('g_decimallongitude', 'double precision'), ('g_decimallatitude', 'double precision'), ('g_geodeticdatum', 'varchar(50)'), ('g_higerGeography', 'varchar(255)'), ('g_continent', 'varchar(50)'), ('g_country', 'varchar(50)'), ('g_countryCode', 'varchar(50)'), ('g_stateProvince', 'varchar(50)'), ('g_gbifid', 'varchar(255)'), ('g_protocol', 'varchar(255)'), ('g_identifier', 'varchar(50)'), ('g_recordedby', 'varchar(255)'), ('g_identificationid', 'varchar(255)'), ('g_identifiers', 'text'), ('g_dateidentified', 'text'), ('g_modified', 'text'), ('g_institutioncode', 'varchar(50)'), ('g_lastinterpreted', 'text'), ('g_lastparsed', 'text'), ('g_references', 'varchar(255)'), ('g_relations', 'text'), ('g_catalognumber', 'varchar(50)'), ('g_occurrencedetails', 'text'), ('g_datasetkey', 'varchar(50)'), ('g_datasetname', 'varchar(255)'), ('g_collectioncode', 'varchar(50)'), ('g_rights', 'varchar(255)'), ('g_rightsholder', 'varchar(255)'), ('g_license', 'varchar(50)'), ('g_publishingorgkey', 'varchar(50)'), ('g_publishingcountry', 'varchar(50)'), ('g_lastcrawled', 'text'), ('g_specificepithet', 'varchar(50)'), ('g_facts', 'text'), ('g_issues', 'text'), ('g_extensions', 'text'), ('g_language', 'varchar(50)')] set_output_encoding() # Set temporal filter if requested by user # Initialize eventDate filter eventDate = None # Check if date from is compatible (ISO compliant) if date_from: try: parse(date_from) except: grass.fatal("Invalid invalid start date provided") if date_from and not date_to: eventDate = '{}'.format(date_from) # Check if date to is compatible (ISO compliant) if date_to: try: parse(date_to) except: grass.fatal("Invalid invalid end date provided") # Check if date to is after date_from if parse(date_from) < parse(date_to): eventDate = '{},{}'.format(date_from, date_to) else: grass.fatal("Invalid date range: End date has to be after start date!") # Set filter on basisOfRecord if requested by user if basisofrecord == 'ALL': basisOfRecord = None else: basisOfRecord = basisofrecord # Allow also occurrences with spatial issues if requested by user hasGeospatialIssue = False if hasGeoIssue: hasGeospatialIssue = True # Allow also occurrences without coordinates if requested by user hasCoordinate = True if allow_no_geom: hasCoordinate = False # Set reprojection parameters # Set target projection of current LOCATION target_crs = grass.read_command('g.proj', flags='fj').rstrip(os.linesep) target = osr.SpatialReference(target_crs) target.ImportFromProj4(target_crs) if target == 'XY location (unprojected)': grass.fatal("Sorry, XY locations are not supported!") # Set source projection from GBIF source = osr.SpatialReference() source.ImportFromEPSG(4326) if target_crs not in latlon_crs: transform = osr.CoordinateTransformation(source, target) reverse_transform = osr.CoordinateTransformation(target, source) # Generate WKT polygon to use for spatial filtering if requested if mask: if len(mask.split('@')) == 2: m = VectorTopo(mask.split('@')[0], mapset=mask.split('@')[1]) else: m = VectorTopo(mask) if not m.exist(): grass.fatal('Could not find vector map <{}>'.format(mask)) m.open('r') if not m.is_open(): grass.fatal('Could not open vector map <{}>'.format(mask)) # Use map Bbox as spatial filter if map contains <> 1 area if m.number_of('areas') == 1: region_pol = [area.to_wkt() for area in m.viter("areas")][0] else: bbox = str(m.bbox()).replace('Bbox(', '').replace(' ', '').rstrip(')').split(',') region_pol = 'POLYGON(({0} {1}, {0} {3}, {2} {3}, {2} {1}, {0} {1}))'.format(bbox[2], bbox[0], bbox[3], bbox[1]) m.close() else: # Do not limit import spatially if LOCATION is able to take global data if no_region_limit: if target_crs not in latlon_crs: grass.fatal('Import of data from outside the current region is' 'only supported in a WGS84 location!') region_pol = None else: # Limit import spatially to current region # if LOCATION is !NOT! able to take global data # to avoid pprojection ERRORS region = grass.parse_command('g.region', flags='g') region_pol = 'POLYGON(({0} {1}, {0} {3}, {2} {3}, {2} {1}, {0} {1}))'.format(region['e'], region['n'], region['w'], region['s']) # Do not reproject in latlon LOCATIONS if target_crs not in latlon_crs: pol = ogr.CreateGeometryFromWkt(region_pol) pol.Transform(reverse_transform) pol = pol.ExportToWkt() else: pol = region_pol # Create output map if not output maps for each species are requested if not species_maps and not print_species and not print_species_shell and not print_occ_number and not print_species_table: mapname = output new = Vector(mapname) new.open('w', tab_name=mapname, tab_cols=cols) cat = 1 # Import data for each species for s in taxa_list: # Get the taxon key if not the taxon key is provided as input try: key = int(s) except: try: species_match = species.name_backbone(s, rank=rank, strict=False, verbose=True) key = species_match['usageKey'] except: grass.error('Data request for taxon {} failed. Are you online?'.format(s)) continue # Return matching taxon and alternatives and exit if print_species: print('Matching taxon for {} is:'.format(s)) print('{} {}'.format(species_match['scientificName'], species_match['status'])) if 'alternatives' in list(species_match.keys()): print('Alternative matches might be:'.format(s)) for m in species_match['alternatives']: print('{} {}'.format(m['scientificName'], m['status'])) else: print('No alternatives found for the given taxon') continue if print_species_shell: print('match={}'.format(species_match['scientificName'])) if 'alternatives' in list(species_match.keys()): alternatives = [] for m in species_match['alternatives']: alternatives.append(m['scientificName']) print('alternatives={}'.format(','.join(alternatives))) continue if print_species_table: if 'alternatives' in list(species_match.keys()): if len(species_match['alternatives']) == 0: print('{0}|{1}|{2}|'.format(s, key, species_match['scientificName'])) else: alternatives = [] for m in species_match['alternatives']: alternatives.append(m['scientificName']) print('{0}|{1}|{2}|{3}'.format(s, key, species_match['scientificName'], ','.join(alternatives))) continue try: returns_n = occurrences.search(taxonKey=key, hasGeospatialIssue=hasGeospatialIssue, hasCoordinate=hasCoordinate, institutionCode=institutionCode, basisOfRecord=basisOfRecord, recordedBy=recordedby, eventDate=eventDate, continent=continent, country=country, geometry=pol, limit=1)['count'] except: grass.error('Data request for taxon {} faild. Are you online?'.format(s)) returns_n = 0 # Exit if search does not give a return # Print only number of returns for the given search and exit if print_occ_number: grass.message('Found {0} occurrences for taxon {1}...'.format(returns_n, s)) continue elif returns_n <= 0: grass.warning('No occurrences for current search for taxon {0}...'.format(s)) continue elif returns_n >= 200000: grass.warning('Your search for {1} returns {0} records.\n' 'Unfortunately, the GBIF search API is limited to 200,000 records per request.\n' 'The download will be incomplete. Please consider to split up your search.'.format(returns_n, s)) # Get the number of chunks to download chunks = int(math.ceil(returns_n / float(chunk_size))) grass.verbose('Downloading {0} occurrences for taxon {1}...'.format(returns_n, s)) # Create a map for each species if requested using map name as suffix if species_maps: mapname = '{}_{}'.format(s.replace(' ', '_'), output) new = Vector(mapname) new.open('w', tab_name=mapname, tab_cols=cols) cat = 0 # Download the data from GBIF for c in range(chunks): # Define offset offset = c * chunk_size # Adjust chunk_size to the hard limit of 200,000 records in GBIF API # if necessary if offset + chunk_size >= 200000: chunk_size = 200000 - offset # Get the returns for the next chunk returns = occurrences.search(taxonKey=key, hasGeospatialIssue=hasGeospatialIssue, hasCoordinate=hasCoordinate, institutionCode=institutionCode, basisOfRecord=basisOfRecord, recordedBy=recordedby, eventDate=eventDate, continent=continent, country=country, geometry=pol, limit=chunk_size, offset=offset) # Write the returned data to map and attribute table for res in returns['results']: if target_crs not in latlon_crs: point = ogr.CreateGeometryFromWkt('POINT ({} {})'.format(res['decimalLongitude'], res['decimalLatitude'])) point.Transform(transform) x = point.GetX() y = point.GetY() else: x = res['decimalLongitude'] y = res['decimalLatitude'] point = Point(x, y) for k in dwc_keys: if k not in list(res.keys()): res.update({k: None}) cat = cat + 1 new.write(point, cat=cat, attrs=( '{}'.format(s), res['key'], res['taxonRank'], res['taxonKey'], res['taxonID'], res['scientificName'], res['species'], res['speciesKey'], res['genericName'], res['genus'], res['genusKey'], res['family'], res['familyKey'], res['order'], res['orderKey'], res['class'], res['classKey'], res['phylum'], res['phylumKey'], res['kingdom'], res['kingdomKey'], '{}'.format(res['eventDate']) if res['eventDate'] else None, '{}'.format(res['verbatimEventDate']) if res['verbatimEventDate'] else None, res['startDayOfYear'], res['endDayOfYear'], res['year'], res['month'], res['day'], res['occurrenceID'], res['occurrenceStatus'], res['occurrenceRemarks'], res['Habitat'], res['basisOfRecord'], res['preparations'], res['sex'], res['type'], res['locality'], res['verbatimLocality'], res['decimalLongitude'], res['decimalLatitude'], res['geodeticDatum'], res['higerGeography'], res['continent'], res['country'], res['countryCode'], res['stateProvince'], res['gbifID'], res['protocol'], res['identifier'], res['recordedBy'], res['identificationID'], ','.join(res['identifiers']), '{}'.format(res['dateIdentified']) if res['dateIdentified'] else None, '{}'.format(res['modified']) if res['modified'] else None, res['institutionCode'], '{}'.format(res['lastInterpreted']) if res['lastInterpreted'] else None, '{}'.format(res['lastParsed']) if res['lastParsed'] else None, res['references'], ','.join(res['relations']), res['catalogNumber'], '{}'.format(res['occurrenceDetails']) if res['occurrenceDetails'] else None, res['datasetKey'], res['datasetName'], res['collectionCode'], res['rights'], res['rightsHolder'], res['license'], res['publishingOrgKey'], res['publishingCountry'], '{}'.format(res['lastCrawled']) if res['lastCrawled'] else None, res['specificEpithet'], ','.join(res['facts']), ','.join(res['issues']), ','.join(res['extensions']), res['language'],)) cat = cat + 1 # Close the current map if a map for each species is requested if species_maps: new.table.conn.commit() new.close() if not no_topo: grass.run_command('v.build', map=mapname, option='build') # Close the output map if not a map for each species is requested if not species_maps and not print_species and not print_species_shell and not print_occ_number and not print_species_table: new.table.conn.commit() new.close() if not no_topo: grass.run_command('v.build', map=mapname, option='build')
#!/usr/bin/env python from grass.pygrass.vector import VectorTopo psc = '41115' obce = VectorTopo('obce') obce.open('r') print ("Seznam obci s PSC {}:".format(psc)) obce_psc = set() for prvek in obce.viter('areas'): if prvek.attrs['psc'] != psc: continue obce_psc.add(prvek.id) print (u"{0}: {1}".format(psc, prvek.attrs['nazev'])) sousede = set() for prvek in obce.viter('areas'): if prvek.id not in obce_psc: continue for b in prvek.boundaries(): for n in b.get_left_right(): if n != -1 and n != prvek.id: sousede.add(n) print ("Seznam sousednich obce:") for prvek in obce.viter('areas'): if prvek.id not in sousede or \ prvek.attrs['psc'] == psc:
#!/usr/bin/env python from grass.pygrass.vector import VectorTopo okresy = VectorTopo('okresy_polygon', mapset='ruian') okresy.open('r') for o in okresy.viter('areas'): sousede = set() for b in o.boundaries(): for n in b.get_left_right(): if n != -1 and n != o.id: sousede.add(n) print (u'{:20}: {}'.format(o.attrs['nazev'], len(sousede))) okresy.close()
def run_test_C(val_pts, dsm, source, memory, cores, density, radius, method, elev, val_file): """Test combination of parametrisation methods and exposure radii :val_pts: Validation points :param dsm: Input DSM :param source: Exposure source :param memory: Allocated memory [MB] :param cores: Number of cores :param density: Sampling density :param radius: Exposure range :param methods: Parametrisation method :param elev: Observer elevation :param val_file: File to store the validation results """ nsres = grass.raster_info(dsm)["nsres"] ewres = grass.raster_info(dsm)["ewres"] # new VectorTopo object val_pts_topo = VectorTopo(val_pts) val_pts_topo.open("rw") no_points = val_pts_topo.number_of("points") counter = 0 # open file where validation outputs will be written with open(val_file, "a") as outfile: fieldnames = [ "pt_id", "method", "radius", "density", "gvi", "ela_t", "usr_t", "sys_t", "cpu", "mem", "exit", ] writer = csv.DictWriter(outfile, fieldnames=fieldnames) writer.writeheader() # iterate over points for pt in val_pts_topo.viter("points"): grass.percent(counter, no_points, 1) counter += 1 pt_id = pt.attrs["img_no"] pt_x = pt.x pt_y = pt.y # set region around processed point grass.run_command( "g.region", align=dsm, n=pt_y + (radius + nsres / 2.0), s=pt_y - (radius + nsres / 2.0), e=pt_x + (radius + ewres / 2.0), w=pt_x - (radius + ewres / 2.0), ) # Calculate GVI r_GVI = "tmp_GVI_{p}_{r}_{m}_{s}_m".format(p=pt_id, s=density, r=radius, m=method) r_viewshed_profile = Popen( [ "/usr/bin/time", "-v", "r.viewshed.exposure", "--q", "--o", "input={}".format(dsm), "output={}".format(r_GVI), "source={}".format(source), "observer_elevation={}".format(elev), "range={}".format(radius), "function={}".format(method), "sample_density={}".format(density), "memory={}".format(memory), "nprocs={}".format(cores), ], stdout=PIPE, stderr=PIPE, ).communicate() r_viewshed_profile = (r_viewshed_profile[1].decode("utf8").strip() [r_viewshed_profile[1].decode("utf8"). find("Command being timed") - 1:]) r_viewshed_profile = dict( item.split(": ") for item in r_viewshed_profile.replace("\t", "").split("\n")) # check if r.viewshed.exposure finished sucessfuly if r_viewshed_profile["Exit status"] == "0": # extract GVI value at point gvi = grass.read_command("r.what", map=r_GVI, coordinates="{},{}".format( pt_x, pt_y)).split("|")[3] else: gvi = 0.0 # write profiling information cpu = r_viewshed_profile["Percent of CPU this job got"].replace( "%", "") el_time_list = r_viewshed_profile[ "Elapsed (wall clock) time (h:mm:ss or m:ss)"].split(":") el_time_s = (float(el_time_list[-1]) + 60 * float(el_time_list[-2]) + (3600 * float(el_time_list[-3]) if len(el_time_list) > 2 else 0)) writer.writerow({ "pt_id": pt_id, "method": method, "radius": radius, "density": density, "gvi": gvi, "ela_t": el_time_s, "usr_t": r_viewshed_profile["User time (seconds)"], "sys_t": r_viewshed_profile["System time (seconds)"], "cpu": cpu, "mem": r_viewshed_profile["Maximum resident set size (kbytes)"], "exit": r_viewshed_profile["Exit status"], }) grass.message("{},{},{},{},{},{},{},{},{},{},{}".format( pt_id, method, radius, density, gvi, el_time_s, r_viewshed_profile["User time (seconds)"], r_viewshed_profile["System time (seconds)"], cpu, r_viewshed_profile["Maximum resident set size (kbytes)"], r_viewshed_profile["Exit status"], )) # Close vector access val_pts_topo.close() return