def __init__(self, epsg='5514'): ########### self.file_type = None self.grass_layer_types = {} gisdb = os.path.join(tempfile.gettempdir(), 'grassdata') if not os.path.isdir(gisdb): os.mkdir(gisdb) # location/mapset: use random names for batch jobs string_length = 16 location = binascii.hexlify(os.urandom(string_length)) mapset = 'PERMANENT' location_path = os.path.join(gisdb, location) temp_dir = gisdb # Create new location # GRASS session must be initialized first gsetup.init(os.environ['GISBASE'], gisdb, location, mapset) try: gscript.create_location(gisdb, location, epsg, overwrite=True) except ScriptError as e: raise ErosionError('{}'.format(e)) # Be quiet, print only error messages os.environ['GRASS_VERBOSE'] = '0'
def setup_wrkspace(gisdbase, ccr_grassrc, geo_file): """Setup GRASS workspace and modify windows path for GRASS GDAL""" lm_util.gprint("Creating GRASS workspace") gisbase = cc_env.gisbase location = "gcwd" mapset = "PERMANENT" os.environ['GISRC'] = ccr_grassrc os.environ['LD_LIBRARY_PATH'] = os.path.join(gisbase, "lib") os.environ['GRASS_SH'] = os.path.join(gisbase, "msys", "bin", "sh.exe") try: grass.create_location(gisdbase, location, filename=geo_file) except: cc_util.gdal_fail_check() arcpy.AddWarning("GRASS ERROR. Try rebooting and restarting ArcGIS.") arcpy.AddWarning("If that doesn't work you can try using ") arcpy.AddWarning("the 'CC Run Script.py' python script in the ") arcpy.AddWarning("demo directory where the Linkage Mapper toolbox") arcpy.AddWarning("is installed instead of ArcGIS to call the tool") arcpy.AddWarning("(see user guide).") raise Exception("GRASS ERROR: Cannot create workspace.") gsetup.init(gisbase, gisdbase, location, mapset) run_grass_cmd("g.gisenv", set="OVERWRITE=1") os.environ['GRASS_VERBOSE'] = "0" # Only errors and warnings are printed
def setup_location(name, path, epsg, src_env): """Setup temporary location with different projection but same computational region as source location :param str name: name of new location :param path path: path to new location's database :param str epsg: EPSG code :param dict src_env: source environment :return str rcfile: name of new locations rcfile :return dict new_env: new environment """ # Create new environment rcfile, new_env = gs.create_environment(path, name, "PERMANENT") # Location and mapset gs.create_location(path, name, epsg=epsg, overwrite=True) # Reproject region region = get_region(env=src_env) from_proj = get_location_proj_string(src_env) to_proj = get_location_proj_string(env=new_env) new_region = reproject_region(region, from_proj, to_proj) # Set region to match original region extent gs.run_command( "g.region", n=new_region["north"], s=new_region["south"], e=new_region["east"], w=new_region["west"], env=new_env, ) return rcfile, new_env
def setup_wrkspace(gisdbase, ccr_grassrc, geo_file): """Configure GRASS workspace.""" lm_util.gprint("Creating GRASS workspace") gisbase = cc_env.gisbase location = "gcwd" mapset = "PERMANENT" os.environ['GISRC'] = ccr_grassrc os.environ['LD_LIBRARY_PATH'] = os.path.join(gisbase, "lib") os.environ['GRASS_SH'] = os.path.join(gisbase, "msys", "bin", "sh.exe") try: grass.create_location(gisdbase, location, filename=geo_file) except grass.ScriptError: warn_msg = ("Cannot create GRASS workspace.\n" "Try rebooting and restarting ArcGIS. If that doesn't\n" "work you can try using the 'cc_demo.py' python script\n" "in the demo/demo_scripts/ directory where the Linkage\n" "Mapper toolbox is installed instead of ArcGIS to call\n" "the tool (see user guide).") raise Exception(warn_msg) gsetup.init(gisbase, gisdbase, location, mapset) run_grass_cmd("g.gisenv", set="OVERWRITE=1") os.environ['GRASS_VERBOSE'] = "0" # Only errors and warnings are printed
def __init__(self): # create temp GRASS location import tempfile import binascii import grass.script as gs from grass.script import setup as gsetup # path to temp location gisdb = os.path.join(tempfile.gettempdir(), 'grassdata') if not os.path.isdir(gisdb): os.mkdir(gisdb) # location: use random names for batch jobs string_length = 16 location = binascii.hexlify(os.urandom(string_length)).decode("utf-8") # initialize GRASS session gsetup.init(os.environ['GISBASE'], gisdb, location, 'PERMANENT') # create location try: gs.create_location(gisdb, location, epsg='5514', overwrite=True) except SmoderpError as e: raise SmoderpError('{}'.format(e)) # test GRASS env varible if not os.getenv('GISRC'): raise SmoderpError('GRASS not found.') super().__init__()
def setup_wrkspace(gisdbase, ccr_grassrc, geo_file): """Setup GRASS workspace and modify windows path for GRASS GDAL""" lm_util.gprint("Creating GRASS workspace") gisbase = cc_env.gisbase location = "gcwd" mapset = "PERMANENT" os.environ['GISRC'] = ccr_grassrc os.environ['LD_LIBRARY_PATH'] = os.path.join(gisbase, "lib") os.environ['GRASS_SH'] = os.path.join(gisbase, "msys", "bin", "sh.exe") try: grass.create_location(gisdbase, location, filename=geo_file) except: cc_util.gdal_fail_check() arcpy.AddWarning("GRASS ERROR. Try rebooting and restarting ArcGIS.") arcpy.AddWarning("If that doesn't work you can try using ") arcpy.AddWarning("the 'CC Run Script.py' python script in the ") arcpy.AddWarning("demo directory where the Linkage Mapper toolbox") arcpy.AddWarning("is installed instead of ArcGIS to call the tool") arcpy.AddWarning("(see user guide).") raise Exception("GRASS ERROR: Cannot create workspace.") gsetup.init(gisbase, gisdbase, location, mapset) run_grass_cmd("g.gisenv", set="OVERWRITE=1") os.environ['GRASS_VERBOSE'] = "0" # Only errors and warnings are printed
def init_grass(): """!Intialize GRASS session""" gisdbase = os.path.join(tempfile.gettempdir()) location = "test_vfk_%d" % os.getpid() import grass.script.setup as gsetup gsetup.init(gisbase, gisdbase, location) grass.create_location(gisdbase, location, epsg = 2065, overwrite=True)
def __init__(self, epsg='5514', location_path=None): """USLE constructor. Two modes are available - creating temporal location, input data are imported - use existing location, in this case specified location must contain maps defined by self.maps directory :param epsg: EPSG code for creating new temporal location :param location_path: path to existing location """ self.file_type = None self.grass_layer_types = {} if not location_path: gisdb = os.path.join(tempfile.gettempdir(), 'grassdata') if not os.path.isdir(gisdb): os.mkdir(gisdb) # location/mapset: use random names for batch jobs string_length = 16 location = binascii.hexlify(os.urandom(string_length)) mapset = 'PERMANENT' temp_dir = gisdb self.temporal_location = True else: dirname, mapset = os.path.split(location_path.rstrip(os.path.sep)) gisdb, location = os.path.split(dirname) self.temporal_location = False # GRASS session must be initialized first gsetup.init(os.environ['GISBASE'], gisdb, location, mapset) # Create temporal location if requested if not location_path: try: gscript.create_location(gisdb, location, epsg, overwrite=True) except ScriptError as e: raise ErosionError('{}'.format(e)) # Be quiet, print only error messages os.environ['GRASS_VERBOSE'] = '0' # Manage temporal maps self._temp_maps = [] self._map_counter = 0 self._pid = os.getpid()
def setup_location(name, path, epsg, src_env): """Setup temporary location with different projection but same computational region as source location :param str name: name of new location :param path path: path to new location's database :param str epsg: EPSG code :param dict src_env: source environment :return str rcfile: name of new locations rcfile :return dict new_env: new environment """ # Create new environment rcfile, new_env = gs.create_environment(path, name, "PERMANENT") # Location and mapset gs.create_location(path, name, epsg=epsg, overwrite=True) # Reproject region set_target_region(src_env, new_env) return rcfile, new_env
def import_stds(input, output, directory, title=None, descr=None, location=None, link=False, exp=False, overr=False, create=False, stds_type="strds", base=None, set_current_region=False, memory=300): """Import space time datasets of type raster and vector :param input: Name of the input archive file :param output: The name of the output space time dataset :param directory: The extraction directory :param title: The title of the new created space time dataset :param descr: The description of the new created space time dataset :param location: The name of the location that should be created, maps are imported into this location :param link: Switch to link raster maps instead importing them :param exp: Extend location extents based on new dataset :param overr: Override projection (use location's projection) :param create: Create the location specified by the "location" parameter and exit. Do not import the space time datasets. :param stds_type: The type of the space time dataset that should be imported :param base: The base name of the new imported maps, it will be extended using a numerical index. :param memory: Cache size for raster rows, used in r.in.gdal """ global raise_on_error old_state = gscript.raise_on_error gscript.set_raise_on_error(True) # Check if input file and extraction directory exits if not os.path.exists(input): gscript.fatal( _("Space time raster dataset archive <%s> not found") % input) if not create and not os.path.exists(directory): gscript.fatal(_("Extraction directory <%s> not found") % directory) tar = tarfile.open(name=input, mode='r') # Check for important files msgr = get_tgis_message_interface() msgr.message( _("Checking validity of input file (size: %0.1f MB). Make take a while..." % (os.path.getsize(input) / (1024 * 1024.0)))) members = tar.getnames() # Make sure that the basenames of the files are used for comparison member_basenames = [os.path.basename(name) for name in members] if init_file_name not in member_basenames: gscript.fatal(_("Unable to find init file <%s>") % init_file_name) if list_file_name not in member_basenames: gscript.fatal(_("Unable to find list file <%s>") % list_file_name) if proj_file_name not in member_basenames: gscript.fatal( _("Unable to find projection file <%s>") % proj_file_name) msgr.message(_("Extracting data...")) tar.extractall(path=directory) tar.close() # We use a new list file name for map registration new_list_file_name = list_file_name + "_new" # Save current working directory path old_cwd = os.getcwd() # Switch into the data directory os.chdir(directory) # Check projection information if not location: temp_name = gscript.tempfile() temp_file = open(temp_name, "w") proj_name = os.path.abspath(proj_file_name) # We need to convert projection strings generated # from other programs than g.proj into # new line format so that the grass file comparison function # can be used to compare the projections proj_name_tmp = temp_name + "_in_projection" proj_file = open(proj_name, "r") proj_content = proj_file.read() proj_content = proj_content.replace(" +", "\n+") proj_content = proj_content.replace("\t+", "\n+") proj_file.close() proj_file = open(proj_name_tmp, "w") proj_file.write(proj_content) proj_file.close() p = gscript.start_command("g.proj", flags="j", stdout=temp_file) p.communicate() temp_file.close() if not gscript.compare_key_value_text_files( temp_name, proj_name_tmp, sep="="): if overr: gscript.warning( _("Projection information does not match. " "Proceeding...")) else: diff = ''.join(gscript.diff_files(temp_name, proj_name)) gscript.warning( _("Difference between PROJ_INFO file of " "imported map and of current location:" "\n{diff}").format(diff=diff)) gscript.fatal( _("Projection information does not match. " "Aborting.")) # Create a new location based on the projection information and switch # into it old_env = gscript.gisenv() if location: try: proj4_string = open(proj_file_name, 'r').read() gscript.create_location(dbase=old_env["GISDBASE"], location=location, proj4=proj4_string) # Just create a new location and return if create: os.chdir(old_cwd) return except Exception as e: gscript.fatal( _("Unable to create location %(l)s. Reason: %(e)s") % { 'l': location, 'e': str(e) }) # Switch to the new created location try: gscript.run_command("g.mapset", mapset="PERMANENT", location=location, dbase=old_env["GISDBASE"]) except CalledModuleError: gscript.fatal(_("Unable to switch to location %s") % location) # create default database connection try: gscript.run_command("t.connect", flags="d") except CalledModuleError: gscript.fatal( _("Unable to create default temporal database " "in new location %s") % location) try: # Make sure the temporal database exists factory.init() fs = "|" maplist = [] mapset = get_current_mapset() list_file = open(list_file_name, "r") new_list_file = open(new_list_file_name, "w") # get number of lines to correctly form the suffix max_count = -1 for max_count, l in enumerate(list_file): pass max_count += 1 list_file.seek(0) # Read the map list from file line_count = 0 while True: line = list_file.readline() if not line: break line_list = line.split(fs) # The filename is actually the base name of the map # that must be extended by the file suffix filename = line_list[0].strip().split(":")[0] if base: mapname = "%s_%s" % ( base, gscript.get_num_suffix(line_count + 1, max_count)) mapid = "%s@%s" % (mapname, mapset) else: mapname = filename mapid = mapname + "@" + mapset row = {} row["filename"] = filename row["name"] = mapname row["id"] = mapid row["start"] = line_list[1].strip() row["end"] = line_list[2].strip() new_list_file.write("%s%s%s%s%s\n" % (mapname, fs, row["start"], fs, row["end"])) maplist.append(row) line_count += 1 list_file.close() new_list_file.close() # Read the init file fs = "=" init = {} init_file = open(init_file_name, "r") while True: line = init_file.readline() if not line: break kv = line.split(fs) init[kv[0]] = kv[1].strip() init_file.close() if "temporal_type" not in init or \ "semantic_type" not in init or \ "number_of_maps" not in init: gscript.fatal( _("Key words %(t)s, %(s)s or %(n)s not found in init" " file.") % { 't': "temporal_type", 's': "semantic_type", 'n': "number_of_maps" }) if line_count != int(init["number_of_maps"]): gscript.fatal(_("Number of maps mismatch in init and list file.")) format_ = "GTiff" type_ = "strds" if "stds_type" in init: type_ = init["stds_type"] if "format" in init: format_ = init["format"] if stds_type != type_: gscript.fatal( _("The archive file is of wrong space time dataset" " type")) # Check the existence of the files if format_ == "GTiff": for row in maplist: filename = row["filename"] + ".tif" if not os.path.exists(filename): gscript.fatal( _("Unable to find GeoTIFF raster file " "<%s> in archive.") % filename) elif format_ == "AAIGrid": for row in maplist: filename = row["filename"] + ".asc" if not os.path.exists(filename): gscript.fatal( _("Unable to find AAIGrid raster file " "<%s> in archive.") % filename) elif format_ == "GML": for row in maplist: filename = row["filename"] + ".xml" if not os.path.exists(filename): gscript.fatal( _("Unable to find GML vector file " "<%s> in archive.") % filename) elif format_ == "pack": for row in maplist: if type_ == "stvds": filename = str(row["filename"].split(":")[0]) + ".pack" else: filename = row["filename"] + ".pack" if not os.path.exists(filename): gscript.fatal( _("Unable to find GRASS package file " "<%s> in archive.") % filename) else: gscript.fatal(_("Unsupported input format")) # Check the space time dataset id = output + "@" + mapset sp = dataset_factory(type_, id) if sp.is_in_db() and gscript.overwrite() is False: gscript.fatal( _("Space time %(t)s dataset <%(sp)s> is already in" " the database. Use the overwrite flag.") % { 't': type_, 'sp': sp.get_id() }) # Import the maps if type_ == "strds": if format_ == "GTiff" or format_ == "AAIGrid": _import_raster_maps_from_gdal(maplist, overr, exp, location, link, format_, set_current_region, memory) if format_ == "pack": _import_raster_maps(maplist, set_current_region) elif type_ == "stvds": if format_ == "GML": _import_vector_maps_from_gml(maplist, overr, exp, location, link) if format_ == "pack": _import_vector_maps(maplist) # Create the space time dataset if sp.is_in_db() and gscript.overwrite() is True: gscript.info( _("Overwrite space time %(sp)s dataset " "<%(id)s> and unregister all maps.") % { 'sp': sp.get_new_map_instance(None).get_type(), 'id': sp.get_id() }) sp.delete() sp = sp.get_new_instance(id) temporal_type = init["temporal_type"] semantic_type = init["semantic_type"] relative_time_unit = None if temporal_type == "relative": if "relative_time_unit" not in init: gscript.fatal( _("Key word %s not found in init file.") % ("relative_time_unit")) relative_time_unit = init["relative_time_unit"] sp.set_relative_time_unit(relative_time_unit) gscript.verbose( _("Create space time %s dataset.") % sp.get_new_map_instance(None).get_type()) sp.set_initial_values(temporal_type=temporal_type, semantic_type=semantic_type, title=title, description=descr) sp.insert() # register the maps fs = "|" register_maps_in_space_time_dataset( type=sp.get_new_map_instance(None).get_type(), name=output, file=new_list_file_name, start="file", end="file", unit=relative_time_unit, dbif=None, fs=fs, update_cmd_list=False) os.chdir(old_cwd) except: raise # Make sure the location is switched back correctly finally: if location: # Switch to the old location try: gscript.run_command("g.mapset", mapset=old_env["MAPSET"], location=old_env["LOCATION_NAME"], gisdbase=old_env["GISDBASE"]) except CalledModuleError: grass.warning(_("Switching to original location failed")) gscript.set_raise_on_error(old_state)
gisdb = os.path.join(tempfile.gettempdir(), 'grassdata') if not os.path.isdir(gisdb): os.mkdir(gisdb) # location/mapset: use random names for batch jobs string_length = 16 location = binascii.hexlify(os.urandom(string_length)) mapset = 'PERMANENT' # GRASS session must be initialized first gsetup.init(os.environ['GISBASE'], gisdb, location, mapset) print(gisdb + location + mapset) # for debug # Create temporal location try: gscript.create_location(gisdb, location, overwrite=True) except ScriptError as e: raise StandardError('{}'.format(e)) # def main(): # set_location() # find_moduls() # info = gtask.command_info('v.surf.rst') # # # if __name__ == "__main__": # main() def print_name_desc(modul, output):
def export_png_in_projection(src_mapset_name, map_name, output_file, epsg_code, routpng_flags, compression, wgs84_file, use_region=True): """ :param use_region: use computation region and not map extent """ if use_region: src_region = get_region() src_proj_string = get_location_proj_string() # TODO: change only location and not gisdbase? # we rely on the tmp dir having enough space for our map tgt_gisdbase = tempfile.mkdtemp() # this is not needed if we use mkdtemp but why not tgt_location = 'r.out.png.proj_location_%s' % epsg_code # because we are using PERMANENT we don't have to create mapset explicitly tgt_mapset_name = 'PERMANENT' src_mapset = Mapset(name=src_mapset_name, use_current=True) assert src_mapset.exists() # get source (old) and set target (new) GISRC enviromental variable # TODO: set environ only for child processes could be enough and it would # enable (?) parallel runs src_gisrc = os.environ['GISRC'] tgt_gisrc = gsetup.write_gisrc(tgt_gisdbase, tgt_location, tgt_mapset_name) os.environ['GISRC'] = tgt_gisrc # we do this only after we obtained region, so it was applied # and we don't need it in the temporary (tgt) mapset if os.environ.get('WIND_OVERRIDE'): old_temp_region = os.environ['WIND_OVERRIDE'] del os.environ['WIND_OVERRIDE'] else: old_temp_region = None tgt_mapset = Mapset(tgt_gisdbase, tgt_location, tgt_mapset_name) try: # the function itself is not safe for other (backgroud) processes # (e.g. GUI), however we already switched GISRC for us # and child processes, so we don't influece others gs.create_location(dbase=tgt_gisdbase, location=tgt_location, epsg=epsg_code, datum=None, datum_trans=None) assert tgt_mapset.exists() # we need to make the mapset change in the current GISRC (tgt) # note that the C library for this process still holds the # path to the old GISRC file (src) tgt_mapset.set_as_current(gisrc=tgt_gisrc) # setting region if use_region: # respecting computation region of the src location # by previous use g.region in src location # and m.proj and g.region now # respecting MASK of the src location would be hard # null values in map are usually enough tgt_proj_string = get_location_proj_string() tgt_region = reproject_region(src_region, from_proj=src_proj_string, to_proj=tgt_proj_string) # uses g.region thus and sets region only for child processes # which is enough now # TODO: unlike the other branch, this keeps the current # resolution which is not correct set_region(tgt_region) else: # find out map extent to import everything # using only classic API because of some problems with pygrass # on ms windows rproj_out = gs.read_command('r.proj', input=map_name, dbase=src_mapset.database, location=src_mapset.location, mapset=src_mapset.name, output=map_name, flags='g') a = gs.parse_key_val(rproj_out, sep='=', vsep=' ') gs.run_command('g.region', **a) # map import gs.message("Reprojecting...") gs.run_command('r.proj', input=map_name, dbase=src_mapset.database, location=src_mapset.location, mapset=src_mapset.name, output=map_name, quiet=True) # actual export gs.message("Rendering...") raster_to_png(map_name, output_file, compression=compression, routpng_flags=routpng_flags) # outputting file with WGS84 coordinates if wgs84_file: gs.verbose("Projecting coordinates to LL WGS 84...") with open(wgs84_file, 'w') as data_file: if use_region: # map which is smaller than region is imported in its own # small extent, but we export image in region, so we need # bounds to be for region, not map # hopefully this is consistent with r.out.png behavior data_file.write( map_extent_to_file_content(proj_to_wgs84(get_region())) + '\n') else: # use map to get extent # the result is actually the same as using map # if region is the same as map (use_region == False) data_file.write( map_extent_to_file_content( get_map_extent_for_location(map_name)) + '\n') finally: # juts in case we need to do something in the old location # our callers probably do os.environ['GISRC'] = src_gisrc if old_temp_region: os.environ['WIND_OVERRIDE'] = old_temp_region # set current in library src_mapset.set_as_current(gisrc=src_gisrc) # delete the whole gisdbase # delete file by file to ensure that we are deleting only our things # exception will be raised when removing non-empty directory tgt_mapset.delete() os.rmdir(tgt_mapset.location_path) # dir created by tempfile.mkdtemp() needs to be romved manually os.rmdir(tgt_gisdbase) # we have to remove file created by tempfile.mkstemp function # in write_gisrc function os.remove(tgt_gisrc)
def export_png_in_projection(src_mapset_name, map_name, output_file, epsg_code, routpng_flags, compression, wgs84_file, use_region=True): """ :param use_region: use computation region and not map extent """ if use_region: src_region = get_region() src_proj_string = get_location_proj_string() # TODO: change only location and not gisdbase? # we rely on the tmp dir having enough space for our map tgt_gisdbase = tempfile.mkdtemp() # this is not needed if we use mkdtemp but why not tgt_location = 'r.out.png.proj_location_%s' % epsg_code # because we are using PERMANENT we don't have to create mapset explicitly tgt_mapset_name = 'PERMANENT' src_mapset = Mapset(name=src_mapset_name, use_current=True) assert src_mapset.exists() # get source (old) and set target (new) GISRC enviromental variable # TODO: set environ only for child processes could be enough and it would # enable (?) parallel runs src_gisrc = os.environ['GISRC'] tgt_gisrc = gsetup.write_gisrc(tgt_gisdbase, tgt_location, tgt_mapset_name) os.environ['GISRC'] = tgt_gisrc # we do this only after we obtained region, so it was applied # and we don't need it in the temporary (tgt) mapset if os.environ.get('WIND_OVERRIDE'): old_temp_region = os.environ['WIND_OVERRIDE'] del os.environ['WIND_OVERRIDE'] else: old_temp_region = None tgt_mapset = Mapset(tgt_gisdbase, tgt_location, tgt_mapset_name) try: # the function itself is not safe for other (backgroud) processes # (e.g. GUI), however we already switched GISRC for us # and child processes, so we don't influece others gs.create_location(dbase=tgt_gisdbase, location=tgt_location, epsg=epsg_code, datum=None, datum_trans=None) assert tgt_mapset.exists() # we need to make the mapset change in the current GISRC (tgt) # note that the C library for this process still holds the # path to the old GISRC file (src) tgt_mapset.set_as_current(gisrc=tgt_gisrc) # setting region if use_region: # respecting computation region of the src location # by previous use g.region in src location # and m.proj and g.region now # respecting MASK of the src location would be hard # null values in map are usually enough tgt_proj_string = get_location_proj_string() tgt_region = reproject_region(src_region, from_proj=src_proj_string, to_proj=tgt_proj_string) # uses g.region thus and sets region only for child processes # which is enough now # TODO: unlike the other branch, this keeps the current # resolution which is not correct set_region(tgt_region) else: # find out map extent to import everything # using only classic API because of some problems with pygrass # on ms windows rproj_out = gs.read_command('r.proj', input=map_name, dbase=src_mapset.database, location=src_mapset.location, mapset=src_mapset.name, output=map_name, flags='g') a = gs.parse_key_val(rproj_out, sep='=', vsep=' ') gs.run_command('g.region', **a) # map import gs.message("Reprojecting...") gs.run_command('r.proj', input=map_name, dbase=src_mapset.database, location=src_mapset.location, mapset=src_mapset.name, output=map_name, quiet=True) # actual export gs.message("Rendering...") raster_to_png(map_name, output_file, compression=compression, routpng_flags=routpng_flags) # outputting file with WGS84 coordinates if wgs84_file: gs.verbose("Projecting coordinates to LL WGS 84...") with open(wgs84_file, 'w') as data_file: if use_region: # map which is smaller than region is imported in its own # small extent, but we export image in region, so we need # bounds to be for region, not map # hopefully this is consistent with r.out.png behavior data_file.write( map_extent_to_file_content( proj_to_wgs84(get_region())) + '\n') else: # use map to get extent # the result is actually the same as using map # if region is the same as map (use_region == False) data_file.write( map_extent_to_file_content( get_map_extent_for_location(map_name)) + '\n') finally: # juts in case we need to do something in the old location # our callers probably do os.environ['GISRC'] = src_gisrc if old_temp_region: os.environ['WIND_OVERRIDE'] = old_temp_region # set current in library src_mapset.set_as_current(gisrc=src_gisrc) # delete the whole gisdbase # delete file by file to ensure that we are deleting only our things # exception will be raised when removing non-empty directory tgt_mapset.delete() os.rmdir(tgt_mapset.location_path) # dir created by tempfile.mkdtemp() needs to be romved manually os.rmdir(tgt_gisdbase) # we have to remove file created by tempfile.mkstemp function # in write_gisrc function os.remove(tgt_gisrc)
def import_stds(input, output, directory, title=None, descr=None, location=None, link=False, exp=False, overr=False, create=False, stds_type="strds", base=None, set_current_region=False): """Import space time datasets of type raster and vector :param input: Name of the input archive file :param output: The name of the output space time dataset :param directory: The extraction directory :param title: The title of the new created space time dataset :param descr: The description of the new created space time dataset :param location: The name of the location that should be created, maps are imported into this location :param link: Switch to link raster maps instead importing them :param exp: Extend location extents based on new dataset :param overr: Override projection (use location's projection) :param create: Create the location specified by the "location" parameter and exit. Do not import the space time datasets. :param stds_type: The type of the space time dataset that should be imported :param base: The base name of the new imported maps, it will be extended using a numerical index. """ global raise_on_error old_state = gscript.raise_on_error gscript.set_raise_on_error(True) # Check if input file and extraction directory exits if not os.path.exists(input): gscript.fatal(_("Space time raster dataset archive <%s> not found") % input) if not create and not os.path.exists(directory): gscript.fatal(_("Extraction directory <%s> not found") % directory) tar = tarfile.open(name=input, mode='r') # Check for important files msgr = get_tgis_message_interface() msgr.message(_("Checking validity of input file (size: %0.1f MB). Make take a while..." % (os.path.getsize(input)/(1024*1024.0)))) members = tar.getnames() # Make sure that the basenames of the files are used for comparison member_basenames = [os.path.basename(name) for name in members] if init_file_name not in member_basenames: gscript.fatal(_("Unable to find init file <%s>") % init_file_name) if list_file_name not in member_basenames: gscript.fatal(_("Unable to find list file <%s>") % list_file_name) if proj_file_name not in member_basenames: gscript.fatal(_("Unable to find projection file <%s>") % proj_file_name) msgr.message(_("Extracting data...")) tar.extractall(path=directory) tar.close() # We use a new list file name for map registration new_list_file_name = list_file_name + "_new" # Save current working directory path old_cwd = os.getcwd() # Switch into the data directory os.chdir(directory) # Check projection information if not location: temp_name = gscript.tempfile() temp_file = open(temp_name, "w") proj_name = os.path.abspath(proj_file_name) # We need to convert projection strings generated # from other programms than g.proj into # new line format so that the grass file comparison function # can be used to compare the projections proj_name_tmp = temp_name + "_in_projection" proj_file = open(proj_name, "r") proj_content = proj_file.read() proj_content = proj_content.replace(" +", "\n+") proj_content = proj_content.replace("\t+", "\n+") proj_file.close() proj_file = open(proj_name_tmp, "w") proj_file.write(proj_content) proj_file.close() p = gscript.start_command("g.proj", flags="j", stdout=temp_file) p.communicate() temp_file.close() if not gscript.compare_key_value_text_files(temp_name, proj_name_tmp, sep="="): if overr: gscript.warning(_("Projection information does not match. " "Proceeding...")) else: diff = ''.join(gscript.diff_files(temp_name, proj_name)) gscript.warning(_("Difference between PROJ_INFO file of " "imported map and of current location:" "\n{diff}").format(diff=diff)) gscript.fatal(_("Projection information does not match. " "Aborting.")) # Create a new location based on the projection information and switch # into it old_env = gscript.gisenv() if location: try: proj4_string = open(proj_file_name, 'r').read() gscript.create_location(dbase=old_env["GISDBASE"], location=location, proj4=proj4_string) # Just create a new location and return if create: os.chdir(old_cwd) return except Exception as e: gscript.fatal(_("Unable to create location %(l)s. Reason: %(e)s") % {'l': location, 'e': str(e)}) # Switch to the new created location try: gscript.run_command("g.mapset", mapset="PERMANENT", location=location, dbase=old_env["GISDBASE"]) except CalledModuleError: gscript.fatal(_("Unable to switch to location %s") % location) # create default database connection try: gscript.run_command("t.connect", flags="d") except CalledModuleError: gscript.fatal(_("Unable to create default temporal database " "in new location %s") % location) try: # Make sure the temporal database exists factory.init() fs = "|" maplist = [] mapset = get_current_mapset() list_file = open(list_file_name, "r") new_list_file = open(new_list_file_name, "w") # get number of lines to correctly form the suffix max_count = -1 for max_count, l in enumerate(list_file): pass max_count += 1 list_file.seek(0) # Read the map list from file line_count = 0 while True: line = list_file.readline() if not line: break line_list = line.split(fs) # The filename is actually the base name of the map # that must be extended by the file suffix filename = line_list[0].strip().split(":")[0] if base: mapname = "%s_%s" % (base, gscript.get_num_suffix(line_count + 1, max_count)) mapid = "%s@%s" % (mapname, mapset) else: mapname = filename mapid = mapname + "@" + mapset row = {} row["filename"] = filename row["name"] = mapname row["id"] = mapid row["start"] = line_list[1].strip() row["end"] = line_list[2].strip() new_list_file.write("%s%s%s%s%s\n" % (mapname, fs, row["start"], fs, row["end"])) maplist.append(row) line_count += 1 list_file.close() new_list_file.close() # Read the init file fs = "=" init = {} init_file = open(init_file_name, "r") while True: line = init_file.readline() if not line: break kv = line.split(fs) init[kv[0]] = kv[1].strip() init_file.close() if "temporal_type" not in init or \ "semantic_type" not in init or \ "number_of_maps" not in init: gscript.fatal(_("Key words %(t)s, %(s)s or %(n)s not found in init" " file.") % {'t': "temporal_type", 's': "semantic_type", 'n': "number_of_maps"}) if line_count != int(init["number_of_maps"]): gscript.fatal(_("Number of maps mismatch in init and list file.")) format_ = "GTiff" type_ = "strds" if "stds_type" in init: type_ = init["stds_type"] if "format" in init: format_ = init["format"] if stds_type != type_: gscript.fatal(_("The archive file is of wrong space time dataset" " type")) # Check the existence of the files if format_ == "GTiff": for row in maplist: filename = row["filename"] + ".tif" if not os.path.exists(filename): gscript.fatal(_("Unable to find GeoTIFF raster file " "<%s> in archive.") % filename) elif format_ == "AAIGrid": for row in maplist: filename = row["filename"] + ".asc" if not os.path.exists(filename): gscript.fatal(_("Unable to find AAIGrid raster file " "<%s> in archive.") % filename) elif format_ == "GML": for row in maplist: filename = row["filename"] + ".xml" if not os.path.exists(filename): gscript.fatal(_("Unable to find GML vector file " "<%s> in archive.") % filename) elif format_ == "pack": for row in maplist: if type_ == "stvds": filename = str(row["filename"].split(":")[0]) + ".pack" else: filename = row["filename"] + ".pack" if not os.path.exists(filename): gscript.fatal(_("Unable to find GRASS package file " "<%s> in archive.") % filename) else: gscript.fatal(_("Unsupported input format")) # Check the space time dataset id = output + "@" + mapset sp = dataset_factory(type_, id) if sp.is_in_db() and gscript.overwrite() is False: gscript.fatal(_("Space time %(t)s dataset <%(sp)s> is already in" " the database. Use the overwrite flag.") % {'t': type_, 'sp': sp.get_id()}) # Import the maps if type_ == "strds": if format_ == "GTiff" or format_ == "AAIGrid": _import_raster_maps_from_gdal(maplist, overr, exp, location, link, format_, set_current_region) if format_ == "pack": _import_raster_maps(maplist, set_current_region) elif type_ == "stvds": if format_ == "GML": _import_vector_maps_from_gml( maplist, overr, exp, location, link) if format_ == "pack": _import_vector_maps(maplist) # Create the space time dataset if sp.is_in_db() and gscript.overwrite() is True: gscript.info(_("Overwrite space time %(sp)s dataset " "<%(id)s> and unregister all maps.") % {'sp': sp.get_new_map_instance(None).get_type(), 'id': sp.get_id()}) sp.delete() sp = sp.get_new_instance(id) temporal_type = init["temporal_type"] semantic_type = init["semantic_type"] relative_time_unit = None if temporal_type == "relative": if "relative_time_unit" not in init: gscript.fatal(_("Key word %s not found in init file.") % ("relative_time_unit")) relative_time_unit = init["relative_time_unit"] sp.set_relative_time_unit(relative_time_unit) gscript.verbose(_("Create space time %s dataset.") % sp.get_new_map_instance(None).get_type()) sp.set_initial_values(temporal_type=temporal_type, semantic_type=semantic_type, title=title, description=descr) sp.insert() # register the maps fs = "|" register_maps_in_space_time_dataset( type=sp.get_new_map_instance(None).get_type(), name=output, file=new_list_file_name, start="file", end="file", unit=relative_time_unit, dbif=None, fs=fs, update_cmd_list=False) os.chdir(old_cwd) except: raise # Make sure the location is switched back correctly finally: if location: # Switch to the old location try: gscript.run_command("g.mapset", mapset=old_env["MAPSET"], location=old_env["LOCATION_NAME"], gisdbase=old_env["GISDBASE"]) except CalledModuleError: grass.warning(_("Switching to original location failed")) gscript.set_raise_on_error(old_state)
import sys sys.path.insert(0, '/usr/lib/grass76/etc/python') import grass.script as gs import grass.script.setup as gsetup gsetup.init('/tmp', 'qgis_test', 'PERMANENT') gs.create_location('/tmp', 'qgis_test', epsg=4326) print(gs.gisenv())