def non_interactive(arg, geofile = None): global gisdbase, location_name, mapset, location # Try non-interactive startup l = None if arg == '-': if location: l = location else: l = arg if l: if l == '.': l = os.getcwd() elif not os.path.isabs(l): l = os.path.abspath(l) l, mapset = os.path.split(l) if not mapset: l, mapset = os.path.split(l) l, location_name = os.path.split(l) gisdbase = l if gisdbase and location_name and mapset: location = os.path.join(gisdbase, location_name, mapset) if not os.access(os.path.join(location, "WIND"), os.R_OK): if location_name == "PERMANENT": fatal(_("<%s> is not a valid GRASS location") % location) else: # the user wants to create mapset on the fly if create_new: if not os.access(os.path.join(os.path.join(gisdbase, location_name, "PERMANENT", "DEFAULT_WIND")), os.F_OK): # create new location gisdbase = os.path.join(gisdbase, location_name) location_name = mapset mapset = "PERMANENT" if os.access(os.path.join(os.path.join(gisdbase, location_name, "PERMANENT", "DEFAULT_WIND")), os.F_OK): fatal(_("Failed to create new location. The location <%s> already exists." % location_name)) sys.path.append(gfile('etc', 'python')) from grass.script import core as grass try: if geofile and geofile.find('EPSG:') > -1: epsg = geofile.split(':', 1)[1] grass.create_location(gisdbase, location_name, epsg = epsg) else: grass.create_location(gisdbase, location_name, filename = geofile) except grass.ScriptError, e: fatal(e.value.strip('"').strip("'").replace('\\n', os.linesep)) else: # create new mapset os.mkdir(location) # copy PERMANENT/DEFAULT_WIND to <mapset>/WIND s = readfile(os.path.join(gisdbase, location_name, "PERMANENT", "DEFAULT_WIND")) writefile(os.path.join(location, "WIND"), s) message(_("Missing WIND file fixed")) else: fatal(_("<%s> is not a valid GRASS location") % location)
def _set_grass(self, wps_request): """Handle given grass_location parameter of the constructor location is either directory name, 'epsg:1234' form or a georeferenced file in the first case, new temporary mapset within the location will be created in the second case, location will be created in self.workdir the mapset should be deleted automatically using self.clean() method """ if self.grass_location: import random import string from grass.script import core as grass from grass.script import setup as gsetup # HOME needs to be set - and that is usually not the case for httpd # server os.environ['HOME'] = self.workdir # GISRC envvariable needs to be set gisrc = open(os.path.join(self.workdir, 'GISRC'), 'w') gisrc.write("GISDBASE: {}\n".format(self.workdir)) gisrc.write("GUI: txt\n") gisrc.close() os.environ['GISRC'] = gisrc.name new_loc_args = dict() mapset_name = 'pywps_ms_{}'.format(''.join( random.sample(string.ascii_letters, 5))) if self.grass_location.startswith('complexinput:'): # create new location from a georeferenced file ref_file_parameter = self.grass_location.split(':')[1] ref_file = wps_request.inputs[ref_file_parameter][0].file new_loc_args.update({'filename': ref_file}) elif self.grass_location.lower().startswith('epsg:'): # create new location from epsg code epsg = self.grass_location.lower().replace('epsg:', '') new_loc_args.update({'epsg': epsg}) if new_loc_args: dbase = self.workdir location = str() while os.path.isdir(os.path.join(dbase, location)): location = 'pywps_loc_{}'.format(''.join( random.sample(string.ascii_letters, 5))) gsetup.init(os.environ['GISBASE'], dbase, location, 'PERMANENT') grass.create_location(dbase=dbase, location=location, **new_loc_args) LOGGER.debug('GRASS location based on {} created'.format( list(new_loc_args.keys())[0])) grass.run_command('g.mapset', mapset=mapset_name, flags='c', dbase=dbase, location=location, quiet=True) # create temporary mapset within existing location elif os.path.isdir(self.grass_location): from grass.pygrass.gis import make_mapset LOGGER.debug('Temporary mapset will be created') dbase = os.path.dirname(self.grass_location) location = os.path.basename(self.grass_location) grass.run_command('g.gisenv', set="GISDBASE={}".format(dbase)) grass.run_command('g.gisenv', set="LOCATION_NAME=%s" % location) while os.path.isdir(os.path.join(dbase, location, mapset_name)): mapset_name = 'pywps_ms_{}'.format(''.join( random.sample(string.ascii_letters, 5))) make_mapset(mapset=mapset_name, location=location, gisdbase=dbase) grass.run_command('g.gisenv', set="MAPSET=%s" % mapset_name) else: raise NoApplicableCode( 'Location does exists or does not seem ' 'to be in "EPSG:XXXX" form nor is it existing directory: {}' .format(location)) # set _grass_mapset attribute - will be deleted once handler ends self._grass_mapset = mapset_name # final initialization LOGGER.debug('GRASS Mapset set to {}'.format(mapset_name)) LOGGER.debug('GRASS environment initialised') LOGGER.debug( 'GISRC {}, GISBASE {}, GISDBASE {}, LOCATION {}, MAPSET {}'. format(os.environ.get('GISRC'), os.environ.get('GISBASE'), dbase, location, os.path.basename(mapset_name)))
def _set_grass(self, wps_request): """Handle given grass_location parameter of the constructor location is either directory name, 'epsg:1234' form or a georeferenced file in the first case, new temporary mapset within the location will be created in the second case, location will be created in self.workdir the mapset should be deleted automatically using self.clean() method """ if not PY2: LOGGER.warning('Seems PyWPS is running in Python-3 ' 'environment, but GRASS GIS supports Python-2 only') return if self.grass_location: from grass.script import core as grass from grass.script import setup as gsetup # HOME needs to be set - and that is usually not the case for httpd # server os.environ['HOME'] = self.workdir # GISRC envvariable needs to be set gisrc = open(os.path.join(self.workdir, 'GISRC'), 'w') gisrc.write("GISDBASE: %s\n" % self.workdir) gisrc.write("GUI: txt\n") gisrc.close() os.environ['GISRC'] = gisrc.name new_loc_args = dict() if self.grass_location.startswith('complexinput:'): # create new location from a georeferenced file ref_file_parameter = self.grass_location.split(':')[1] ref_file = wps_request.inputs[ref_file_parameter][0].file new_loc_args.update({'filename': ref_file}) elif self.grass_location.lower().startswith('epsg:'): # create new location from epsg code epsg = self.grass_location.lower().replace('epsg:', '') new_loc_args.update({'epsg': epsg}) if new_loc_args: dbase = self.workdir location = 'pywps_location' gsetup.init(self.workdir, dbase, location, 'PERMANENT') grass.create_location(dbase=dbase, location=location, **new_loc_args) LOGGER.debug('GRASS location based on {} created'.format( list(new_loc_args.keys())[0])) # create temporary mapset within existing location elif os.path.isdir(self.grass_location): LOGGER.debug('Temporary mapset will be created') dbase = os.path.dirname(self.grass_location) location = os.path.basename(self.grass_location) grass.run_command('g.gisenv', set="GISDBASE=%s" % dbase) else: raise NoApplicableCode( 'Location does exists or does not seem ' 'to be in "EPSG:XXXX" form nor is it existing directory: %s' % location) # copy projection files from PERMAMENT mapset to temporary mapset mapset_name = 'pywps_mapset' grass.run_command('g.mapset', mapset=mapset_name, flags='c', dbase=dbase, location=location) # set _grass_mapset attribute - will be deleted once handler ends self._grass_mapset = mapset_name # final initialization LOGGER.debug('GRASS Mapset set to %s' % mapset_name) LOGGER.debug('GRASS environment initialised') LOGGER.debug( 'GISRC {}, GISBASE {}, GISDBASE {}, LOCATION {}, MAPSET {}'. format(os.environ.get('GISRC'), os.environ.get('GISBASE'), dbase, location, os.path.basename(mapset_name)))
def main(): indb = options['database'] prefix = options['basename'] env = grass.gisenv() #fix sqlite3 db field string multibyte character problem sys.setdefaultencoding('utf-8') # check if 3d or not if flags['z']: d3 = 'z' else: d3 = '' owrite = grass.overwrite() # check if location it is latlong if grass.locn_is_latlong(): locn = True else: locn = False # connection to sqlite geopaparazzi database import sqlite3 conn = sqlite3.connect(indb) curs = conn.cursor() # if it is not a latlong location create a latlong location on the fly if not locn: # create new location and move to it creating new gisrc file new_loc = basename(grass.tempfile(create=False)) new_loc_name = 'geopaparazzi_%s' % new_loc grass.create_location(dbase=env['GISDBASE'], epsg='4326', location=new_loc_name, desc='Temporary location for v.in.geopaparazzi') grc = os.getenv('GISRC') shutil.copyfile(grc, grc + '.old') newrc = open(grc, 'w') newrc.write('GISDBASE: %s\n' % env['GISDBASE']) newrc.write('LOCATION_NAME: %s\n' % new_loc_name) newrc.write('MAPSET: PERMANENT\n') newrc.write('GRASS_GUI: text\n') newrc.close() grass.run_command('db.connect', flags="d", quiet=True) # load bookmarks if flags['b']: # check if elements in bookmarks table are more the 0 if checkEle(curs, 'bookmarks') != 0: bookname = prefix + '_book' pois = importGeom(bookname, 'bookmarks', curs, owrite, '') sql = 'CREATE TABLE %s (cat int, text text)' % bookname grass.write_command('db.execute', input='-', stdin=sql) # select attributes sql = "select text from bookmarks order by _id" allattri = returnClear(curs, sql) # add values using insert statement idcat = 1 for row in allattri: values = "%d,'%s'" % (idcat, str(row)) sql = "insert into %s values(%s)" % (bookname, values) grass.write_command('db.execute', input='-', stdin=sql) idcat += 1 # at the end connect table to vector grass.run_command('v.db.connect', map=bookname, table=bookname, quiet=True) else: grass.warning(_("No bookmarks found, escape them")) # load images if flags['i']: # check if elements in images table are more the 0 if checkEle(curs, 'images') != 0: imagename = prefix + '_image' pois = importGeom(imagename, 'images', curs, owrite, d3) sql = 'CREATE TABLE %s (cat int, azim int, ' % imagename sql += 'path text, ts text, text text)' grass.write_command('db.execute', input='-', stdin=sql) # select attributes sql = "select azim, path, ts, text from images order by _id" allattri = returnAll(curs, sql) # add values using insert statement idcat = 1 for row in allattri: values = "%d,'%d','%s','%s','%s'" % (idcat, row[0], str(row[1]), str(row[2]), str(row[3])) sql = "insert into %s values(%s)" % (imagename, values) grass.write_command('db.execute', input='-', stdin=sql) idcat += 1 # at the end connect table to vector grass.run_command('v.db.connect', map=imagename, table=imagename, quiet=True) else: grass.warning(_("No images found, escape them")) # if tracks or nodes should be imported create a connection with sqlite3 # load notes if flags['n']: # check if elements in notes table are more the 0 if checkEle(curs, 'notes') != 0: # select each categories categories = returnClear(curs, "select cat from notes group by cat") # for each category for cat in categories: # select lat, lon for create point layer catname = prefix + '_notes_' + cat pois = importGeom(catname, 'notes', curs, owrite, d3, cat) # select form to understand the number forms = returnClear(curs, "select _id from notes where cat = '%s' " "and form is not null order by _id" % cat) # if number of form is different from 0 and number of point # remove the vector because some form it is different if len(forms) != 0 and len(forms) != len(pois): grass.run_command('g.remove', flags='f', type='vector', name=catname, quiet=True) grass.warning(_("Vector %s not imported because number" " of points and form is different")) # if form it's 0 there is no form elif len(forms) == 0: # create table without form sql = 'CREATE TABLE %s (cat int, ts text, ' % catname sql += 'text text, geopap_cat text)' grass.write_command('db.execute', input='-', stdin=sql) # select attributes sql = "select ts, text, cat from notes where "\ "cat='%s' order by _id" % cat allattri = returnAll(curs, sql) # add values using insert statement idcat = 1 for row in allattri: values = "%d,'%s','%s','%s'" % (idcat, str(row[0]), str(row[1]), str(row[2])) sql = "insert into %s values(%s)" % (catname, values) grass.write_command('db.execute', input='-', stdin=sql) idcat += 1 # at the end connect table to vector grass.run_command('v.db.connect', map=catname, table=catname, quiet=True) # create table with form else: # select all the attribute sql = "select ts, text, cat, form from notes where "\ "cat='%s' order by _id" % cat allattri = returnAll(curs, sql) # return string of form's categories too create table keys = returnFormKeys(allattri) sql = 'CREATE TABLE %s (cat int, ts text, ' % catname sql += 'text text, geopap_cat text %s)' % keys grass.write_command('db.execute', input='-', stdin=sql) # it's for the number of categories idcat = 1 # for each feature insert value for row in allattri: values = "%d,'%s','%s','%s'," % (idcat, str(row[0]), str(row[1]), str(row[2])) values += returnFormValues(row[3]) sql = "insert into %s values(%s)" % (catname, values) grass.write_command('db.execute', input='-', stdin=sql) idcat += 1 # at the end connect table with vector grass.run_command('v.db.connect', map=catname, table=catname, quiet=True) else: grass.warning(_("No notes found, escape them")) # load tracks if flags['t']: # check if elements in bookmarks table are more the 0 if checkEle(curs, 'gpslogs') != 0: tracksname = prefix + '_tracks' # define string for insert data at the end tracks = '' # return ids of tracks ids = returnClear(curs, "select _id from gpslogs") # for each track for i in ids: # select all the points coordinates tsel = "select lon, lat" if flags['z']: tsel += ", altim" tsel += " from gpslog_data where logid=%s order by _id" % i trackpoints = returnAll(curs, tsel) wpoi = '\n'.join(['|'.join([str(col) for col in row]) for row in trackpoints]) tracks += "%s\n" % wpoi if flags['z']: tracks += 'NaN|NaN|Nan\n' else: tracks += 'NaN|Nan\n' # import lines try: grass.write_command('v.in.lines', flags=d3, input='-', out=tracksname, stdin=tracks, overwrite=owrite, quiet=True) except CalledModuleError: grass.fatal(_("Error importing %s" % tracksname)) # create table for line sql = 'CREATE TABLE %s (cat int, startts text, ' % tracksname sql += 'endts text, text text, color text, width int)' grass.write_command('db.execute', input='-', stdin=sql) sql = "select logid, startts, endts, text, color, width from" \ " gpslogs, gpslogsproperties where gpslogs._id=" \ "gpslogsproperties.logid" # return attributes allattri = returnAll(curs, sql) # for each line insert attribute for row in allattri: values = "%d,'%s','%s','%s','%s',%d" % (row[0], str(row[1]), str(row[2]), str(row[3]), str(row[4]), row[5]) sql = "insert into %s values(%s)" % (tracksname, values) grass.write_command('db.execute', input='-', stdin=sql) # at the end connect map with table grass.run_command('v.db.connect', map=tracksname, table=tracksname, quiet=True) else: grass.warning(_("No tracks found, escape them")) # if location it's not latlong reproject it if not locn: # copy restore the original location shutil.copyfile(grc + '.old', grc) # reproject bookmarks if flags['b'] and checkEle(curs, 'bookmarks') != 0: grass.run_command('v.proj', quiet=True, input=bookname, location='geopaparazzi_%s' % new_loc, mapset='PERMANENT') # reproject images if flags['i'] and checkEle(curs, 'images') != 0: grass.run_command('v.proj', quiet=True, input=imagename, location='geopaparazzi_%s' % new_loc, mapset='PERMANENT') # reproject notes if flags['n'] and checkEle(curs, 'notes') != 0: for cat in categories: catname = prefix + '_node_' + cat grass.run_command('v.proj', quiet=True, input=catname, location='geopaparazzi_%s' % new_loc, mapset='PERMANENT') # reproject track if flags['t'] and checkEle(curs, 'gpslogs') != 0: grass.run_command('v.proj', quiet=True, input=tracksname, location='geopaparazzi_%s' % new_loc, mapset='PERMANENT')
def non_interactive(arg, geofile=None): global gisdbase, location_name, mapset, location # Try non-interactive startup l = None if arg == '-': if location: l = location else: l = arg if l: if l == '.': l = os.getcwd() elif not os.path.isabs(l): l = os.path.abspath(l) l, mapset = os.path.split(l) if not mapset: l, mapset = os.path.split(l) l, location_name = os.path.split(l) gisdbase = l if gisdbase and location_name and mapset: location = os.path.join(gisdbase, location_name, mapset) # check if 'location' is a valid GRASS location/mapset if not os.access(os.path.join(location, "WIND"), os.R_OK): if not create_new: # 'location' is not valid, check if 'location_name' is # a valid GRASS location if not os.path.exists(os.path.join(gisdbase, location_name)): fatal( _("Location <%s> doesn't exist") % os.path.join(gisdbase, location_name)) elif 'PERMANENT' not in os.listdir(os.path.join(gisdbase, location_name)) or \ not os.path.isdir(os.path.join(gisdbase, location_name, 'PERMANENT')) or \ not os.path.isfile((os.path.join(gisdbase, location_name, 'PERMANENT', 'DEFAULT_WIND'))): fatal(_("ERROR: <%s> is not a valid GRASS location") % \ os.path.join(gisdbase, location_name)) else: fatal( _("Mapset <%s> doesn't exist in GRASS location <%s>. " "A new mapset can be created by '-c' switch.") % (mapset, location_name)) else: # 'location' is not valid, the user wants to create # mapset on the fly if not os.access( os.path.join(gisdbase, location_name, "PERMANENT", "DEFAULT_WIND"), os.F_OK): # 'location_name' is not a valid GRASS location, # create new location and 'PERMANENT' mapset gisdbase = os.path.join(gisdbase, location_name) location_name = mapset mapset = "PERMANENT" if os.access( os.path.join( os.path.join(gisdbase, location_name, "PERMANENT", "DEFAULT_WIND")), os.F_OK): fatal( _("Failed to create new location. " "The location <%s> already exists." % location_name)) if gfile('etc', 'python') not in sys.path: sys.path.append(gfile('etc', 'python')) from grass.script import core as grass try: if geofile and geofile.upper().find('EPSG:') > -1: # create location using EPSG code epsg = geofile.split(':', 1)[1] grass.create_location(gisdbase, location_name, epsg=epsg) else: # create location using georeferenced file grass.create_location(gisdbase, location_name, filename=geofile) except grass.ScriptError as e: fatal( e.value.strip('"').strip("'").replace( '\\n', os.linesep)) else: # 'location_name' is a valid GRASS location, # create new mapset os.mkdir(location) # copy PERMANENT/DEFAULT_WIND to <mapset>/WIND s = readfile( os.path.join(gisdbase, location_name, "PERMANENT", "DEFAULT_WIND")) writefile(os.path.join(location, "WIND"), s) message(_("Missing WIND file fixed")) if os.access(gisrc, os.R_OK): kv = read_gisrc() else: kv = {} kv['GISDBASE'] = gisdbase kv['LOCATION_NAME'] = location_name kv['MAPSET'] = mapset write_gisrc(kv) else: fatal( _("GISDBASE, LOCATION_NAME and MAPSET variables not set properly.\n" "Interactive startup needed."))
def _set_grass(self, wps_request): """Handle given grass_location parameter of the constructor location is either directory name, 'epsg:1234' form or a georeferenced file in the first case, new temporary mapset within the location will be created in the second case, location will be created in self.workdir the mapset should be deleted automatically using self.clean() method """ if self.grass_location: import random import string from grass.script import core as grass from grass.script import setup as gsetup # HOME needs to be set - and that is usually not the case for httpd # server os.environ['HOME'] = self.workdir # GISRC envvariable needs to be set gisrc = open(os.path.join(self.workdir, 'GISRC'), 'w') gisrc.write("GISDBASE: {}\n".format(self.workdir)) gisrc.write("GUI: txt\n") gisrc.close() os.environ['GISRC'] = gisrc.name new_loc_args = dict() mapset_name = 'pywps_ms_{}'.format( ''.join(random.sample(string.ascii_letters, 5))) if self.grass_location.startswith('complexinput:'): # create new location from a georeferenced file ref_file_parameter = self.grass_location.split(':')[1] ref_file = wps_request.inputs[ref_file_parameter][0].file new_loc_args.update({'filename': ref_file}) elif self.grass_location.lower().startswith('epsg:'): # create new location from epsg code epsg = self.grass_location.lower().replace('epsg:', '') new_loc_args.update({'epsg': epsg}) if new_loc_args: dbase = self.workdir location = str() while os.path.isdir(os.path.join(dbase, location)): location = 'pywps_loc_{}'.format( ''.join(random.sample(string.ascii_letters, 5))) gsetup.init(os.environ['GISBASE'], dbase, location, 'PERMANENT') grass.create_location(dbase=dbase, location=location, **new_loc_args) LOGGER.debug('GRASS location based on {} created'.format( list(new_loc_args.keys())[0])) grass.run_command('g.mapset', mapset=mapset_name, flags='c', dbase=dbase, location=location, quiet=True) # create temporary mapset within existing location elif os.path.isdir(self.grass_location): from grass.pygrass.gis import make_mapset LOGGER.debug('Temporary mapset will be created') dbase = os.path.dirname(self.grass_location) location = os.path.basename(self.grass_location) grass.run_command('g.gisenv', set="GISDBASE={}".format(dbase)) grass.run_command('g.gisenv', set="LOCATION_NAME=%s" % location) while os.path.isdir(os.path.join(dbase, location, mapset_name)): mapset_name = 'pywps_ms_{}'.format( ''.join(random.sample(string.ascii_letters, 5))) make_mapset(mapset=mapset_name, location=location, gisdbase=dbase) grass.run_command('g.gisenv', set="MAPSET=%s" % mapset_name) else: raise NoApplicableCode('Location does exists or does not seem ' 'to be in "EPSG:XXXX" form nor is it existing directory: {}'.format(location)) # set _grass_mapset attribute - will be deleted once handler ends self._grass_mapset = mapset_name # final initialization LOGGER.debug('GRASS Mapset set to {}'.format(mapset_name)) LOGGER.debug('GRASS environment initialised') LOGGER.debug('GISRC {}, GISBASE {}, GISDBASE {}, LOCATION {}, MAPSET {}'.format( os.environ.get('GISRC'), os.environ.get('GISBASE'), dbase, location, os.path.basename(mapset_name)))
def main(): indb = options["database"] prefix = options["basename"] env = grass.gisenv() # fix sqlite3 db field string multibyte character problem sys.setdefaultencoding("utf-8") # check if 3d or not if flags["z"]: d3 = "z" else: d3 = "" owrite = grass.overwrite() # check if location it is latlong if grass.locn_is_latlong(): locn = True else: locn = False # connection to sqlite geopaparazzi database import sqlite3 conn = sqlite3.connect(indb) curs = conn.cursor() # if it is not a latlong location create a latlong location on the fly if not locn: # create new location and move to it creating new gisrc file new_loc = basename(grass.tempfile(create=False)) new_loc_name = "geopaparazzi_%s" % new_loc grass.create_location( dbase=env["GISDBASE"], epsg="4326", location=new_loc_name, desc="Temporary location for v.in.geopaparazzi", ) grc = os.getenv("GISRC") shutil.copyfile(grc, grc + ".old") newrc = open(grc, "w") newrc.write("GISDBASE: %s\n" % env["GISDBASE"]) newrc.write("LOCATION_NAME: %s\n" % new_loc_name) newrc.write("MAPSET: PERMANENT\n") newrc.write("GRASS_GUI: text\n") newrc.close() grass.run_command("db.connect", flags="d", quiet=True) # load bookmarks if flags["b"]: # check if elements in bookmarks table are more the 0 if checkEle(curs, "bookmarks") != 0: bookname = prefix + "_book" pois = importGeom(bookname, "bookmarks", curs, owrite, "") sql = "CREATE TABLE %s (cat int, text text)" % bookname grass.write_command("db.execute", input="-", stdin=sql) # select attributes sql = "select text from bookmarks order by _id" allattri = returnClear(curs, sql) # add values using insert statement idcat = 1 for row in allattri: values = "%d,'%s'" % (idcat, str(row)) sql = "insert into %s values(%s)" % (bookname, values) grass.write_command("db.execute", input="-", stdin=sql) idcat += 1 # at the end connect table to vector grass.run_command("v.db.connect", map=bookname, table=bookname, quiet=True) else: grass.warning(_("No bookmarks found, escape them")) # load images if flags["i"]: # check if elements in images table are more the 0 if checkEle(curs, "images") != 0: imagename = prefix + "_image" pois = importGeom(imagename, "images", curs, owrite, d3) sql = "CREATE TABLE %s (cat int, azim int, " % imagename sql += "path text, ts text, text text)" grass.write_command("db.execute", input="-", stdin=sql) # select attributes sql = "select azim, path, ts, text from images order by _id" allattri = returnAll(curs, sql) # add values using insert statement idcat = 1 for row in allattri: values = "%d,'%d','%s','%s','%s'" % ( idcat, row[0], str(row[1]), str(row[2]), str(row[3]), ) sql = "insert into %s values(%s)" % (imagename, values) grass.write_command("db.execute", input="-", stdin=sql) idcat += 1 # at the end connect table to vector grass.run_command( "v.db.connect", map=imagename, table=imagename, quiet=True ) else: grass.warning(_("No images found, escape them")) # if tracks or nodes should be imported create a connection with sqlite3 # load notes if flags["n"]: # check if elements in notes table are more the 0 if checkEle(curs, "notes") != 0: # select each categories categories = returnClear(curs, "select cat from notes group by cat") # for each category for cat in categories: # select lat, lon for create point layer catname = prefix + "_notes_" + cat pois = importGeom(catname, "notes", curs, owrite, d3, cat) # select form to understand the number forms = returnClear( curs, "select _id from notes where cat = '%s' " "and form is not null order by _id" % cat, ) # if number of form is different from 0 and number of point # remove the vector because some form it is different if len(forms) != 0 and len(forms) != len(pois): grass.run_command( "g.remove", flags="f", type="vector", name=catname, quiet=True ) grass.warning( _( "Vector %s not imported because number" " of points and form is different" ) ) # if form it's 0 there is no form elif len(forms) == 0: # create table without form sql = "CREATE TABLE %s (cat int, ts text, " % catname sql += "text text, geopap_cat text)" grass.write_command("db.execute", input="-", stdin=sql) # select attributes sql = ( "select ts, text, cat from notes where " "cat='%s' order by _id" % cat ) allattri = returnAll(curs, sql) # add values using insert statement idcat = 1 for row in allattri: values = "%d,'%s','%s','%s'" % ( idcat, str(row[0]), str(row[1]), str(row[2]), ) sql = "insert into %s values(%s)" % (catname, values) grass.write_command("db.execute", input="-", stdin=sql) idcat += 1 # at the end connect table to vector grass.run_command( "v.db.connect", map=catname, table=catname, quiet=True ) # create table with form else: # select all the attribute sql = ( "select ts, text, cat, form from notes where " "cat='%s' order by _id" % cat ) allattri = returnAll(curs, sql) # return string of form's categories too create table keys = returnFormKeys(allattri) sql = "CREATE TABLE %s (cat int, ts text, " % catname sql += "text text, geopap_cat text %s)" % keys grass.write_command("db.execute", input="-", stdin=sql) # it's for the number of categories idcat = 1 # for each feature insert value for row in allattri: values = "%d,'%s','%s','%s'," % ( idcat, str(row[0]), str(row[1]), str(row[2]), ) values += returnFormValues(row[3]) sql = "insert into %s values(%s)" % (catname, values) grass.write_command("db.execute", input="-", stdin=sql) idcat += 1 # at the end connect table with vector grass.run_command( "v.db.connect", map=catname, table=catname, quiet=True ) else: grass.warning(_("No notes found, escape them")) # load tracks if flags["t"]: # check if elements in bookmarks table are more the 0 if checkEle(curs, "gpslogs") != 0: tracksname = prefix + "_tracks" # define string for insert data at the end tracks = "" # return ids of tracks ids = returnClear(curs, "select _id from gpslogs") # for each track for i in ids: # select all the points coordinates tsel = "select lon, lat" if flags["z"]: tsel += ", altim" tsel += " from gpslog_data where logid=%s order by _id" % i trackpoints = returnAll(curs, tsel) wpoi = "\n".join( ["|".join([str(col) for col in row]) for row in trackpoints] ) tracks += "%s\n" % wpoi if flags["z"]: tracks += "NaN|NaN|Nan\n" else: tracks += "NaN|Nan\n" # import lines try: grass.write_command( "v.in.lines", flags=d3, input="-", out=tracksname, stdin=tracks, overwrite=owrite, quiet=True, ) except CalledModuleError: grass.fatal(_("Error importing %s" % tracksname)) # create table for line sql = "CREATE TABLE %s (cat int, startts text, " % tracksname sql += "endts text, text text, color text, width int)" grass.write_command("db.execute", input="-", stdin=sql) sql = ( "select logid, startts, endts, text, color, width from" " gpslogs, gpslogsproperties where gpslogs._id=" "gpslogsproperties.logid" ) # return attributes allattri = returnAll(curs, sql) # for each line insert attribute for row in allattri: values = "%d,'%s','%s','%s','%s',%d" % ( row[0], str(row[1]), str(row[2]), str(row[3]), str(row[4]), row[5], ) sql = "insert into %s values(%s)" % (tracksname, values) grass.write_command("db.execute", input="-", stdin=sql) # at the end connect map with table grass.run_command( "v.db.connect", map=tracksname, table=tracksname, quiet=True ) else: grass.warning(_("No tracks found, escape them")) # if location it's not latlong reproject it if not locn: # copy restore the original location shutil.copyfile(grc + ".old", grc) # reproject bookmarks if flags["b"] and checkEle(curs, "bookmarks") != 0: grass.run_command( "v.proj", quiet=True, input=bookname, location="geopaparazzi_%s" % new_loc, mapset="PERMANENT", ) # reproject images if flags["i"] and checkEle(curs, "images") != 0: grass.run_command( "v.proj", quiet=True, input=imagename, location="geopaparazzi_%s" % new_loc, mapset="PERMANENT", ) # reproject notes if flags["n"] and checkEle(curs, "notes") != 0: for cat in categories: catname = prefix + "_node_" + cat grass.run_command( "v.proj", quiet=True, input=catname, location="geopaparazzi_%s" % new_loc, mapset="PERMANENT", ) # reproject track if flags["t"] and checkEle(curs, "gpslogs") != 0: grass.run_command( "v.proj", quiet=True, input=tracksname, location="geopaparazzi_%s" % new_loc, mapset="PERMANENT", )
epsg = "EPSG:5514" os.environ['GISBASE'] = r'I:\OSGeo4W64\apps\grass\grass78' path_grass_data = "I:/grass" location_name = "test_data" path_grass = Path(path_grass_data) / location_name if path_grass.exists(): shutil.rmtree(str(path_grass)) gsetup.init(os.environ['GISBASE']) gcore.create_location(path_grass_data, location_name) gsetup.init(os.environ['GISBASE'], path_grass_data, location_name) result_rasters = [] for path_file in path_data.iterdir(): file = str(path_file.absolute()) imported = path_file.stem.split("_")[0] region = gscript.parse_command("r.in.xyz", input=file, separator="space", flags="sg", output="bbox",
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(src_mapset_name) # 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 if os.environ.get('WIND_OVERRIDE'): old_temp_region = os.environ['WIND_OVERRIDE'] del os.environ['WIND_OVERRIDE'] else: old_temp_region = None # these lines looks good but anyway when developing the module # switching location seemed fragile and on some errors (while running # unfinished module) location was switched in the command line 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 gcore.create_location(dbase=tgt_gisdbase, location=tgt_location, epsg=epsg_code, datum=None, datum_trans=None) # Mapset object cannot be created if the real mapset does not exists tgt_mapset = Mapset(gisdbase=tgt_gisdbase, location=tgt_location, mapset=tgt_mapset_name) # set the current mapset in the library # we actually don't need to switch when only calling modules # (right GISRC is enough for them) tgt_mapset.current() # 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 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 = gcore.read_command('r.proj', input=map_name, dbase=src_mapset.gisdbase, location=src_mapset.location, mapset=src_mapset.name, output=map_name, flags='g') a = gcore.parse_key_val(rproj_out, sep='=', vsep=' ') gcore.run_command('g.region', **a) # map import gcore.run_command('r.proj', input=map_name, dbase=src_mapset.gisdbase, location=src_mapset.location, mapset=src_mapset.name, output=map_name) # actual export gcore.run_command('r.out.png', input=map_name, output=output_file, compression=compression, flags=routpng_flags) # outputting file with WGS84 coordinates if wgs84_file: gcore.message("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.current() # 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_location_path = Location(gisdbase=tgt_gisdbase, location=tgt_location).path() tgt_mapset.delete() os.rmdir(tgt_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 non_interactive(arg, geofile=None): global gisdbase, location_name, mapset, location # Try non-interactive startup l = None if arg == '-': if location: l = location else: l = arg if l: if l == '.': l = os.getcwd() elif not os.path.isabs(l): l = os.path.abspath(l) l, mapset = os.path.split(l) if not mapset: l, mapset = os.path.split(l) l, location_name = os.path.split(l) gisdbase = l if gisdbase and location_name and mapset: location = os.path.join(gisdbase, location_name, mapset) # check if 'location' is a valid GRASS location/mapset if not os.access(os.path.join(location, "WIND"), os.R_OK): if not create_new: # 'location' is not valid, check if 'location_name' is # a valid GRASS location if not os.path.exists(os.path.join(gisdbase, location_name)): fatal(_("Location <%s> doesn't exist") % os.path.join(gisdbase, location_name)) elif 'PERMANENT' not in os.listdir(os.path.join(gisdbase, location_name)) or \ not os.path.isdir(os.path.join(gisdbase, location_name, 'PERMANENT')) or \ not os.path.isfile((os.path.join(gisdbase, location_name, 'PERMANENT', 'DEFAULT_WIND'))): fatal(_("ERROR: <%s> is not a valid GRASS location") % \ os.path.join(gisdbase, location_name)) else: fatal(_("Mapset <%s> doesn't exist in GRASS location <%s>. " "A new mapset can be created by '-c' switch.") % (mapset, location_name)) else: # 'location' is not valid, the user wants to create # mapset on the fly if not os.access(os.path.join(gisdbase, location_name, "PERMANENT", "DEFAULT_WIND"), os.F_OK): # 'location_name' is not a valid GRASS location, # create new location and 'PERMANENT' mapset gisdbase = os.path.join(gisdbase, location_name) location_name = mapset mapset = "PERMANENT" if os.access(os.path.join(os.path.join(gisdbase, location_name, "PERMANENT", "DEFAULT_WIND")), os.F_OK): fatal(_("Failed to create new location. " "The location <%s> already exists." % location_name)) if gfile('etc', 'python') not in sys.path: sys.path.append(gfile('etc', 'python')) from grass.script import core as grass try: if geofile and geofile.upper().find('EPSG:') > -1: # create location using EPSG code epsg = geofile.split(':', 1)[1] grass.create_location(gisdbase, location_name, epsg=epsg) else: # create location using georeferenced file grass.create_location(gisdbase, location_name, filename=geofile) except grass.ScriptError as e: fatal(e.value.strip('"').strip("'").replace('\\n', os.linesep)) else: # 'location_name' is a valid GRASS location, # create new mapset os.mkdir(location) # copy PERMANENT/DEFAULT_WIND to <mapset>/WIND s = readfile(os.path.join(gisdbase, location_name, "PERMANENT", "DEFAULT_WIND")) writefile(os.path.join(location, "WIND"), s) message(_("Missing WIND file fixed")) if os.access(gisrc, os.R_OK): kv = read_gisrc() else: kv = {} kv['GISDBASE'] = gisdbase kv['LOCATION_NAME'] = location_name kv['MAPSET'] = mapset write_gisrc(kv) else: fatal(_("GISDBASE, LOCATION_NAME and MAPSET variables not set properly.\n" "Interactive startup needed."))
def _set_grass(self, wps_request): """Handle given grass_location parameter of the constructor location is either directory name, 'epsg:1234' form or a georeferenced file in the first case, new temporary mapset within the location will be created in the second case, location will be created in self.workdir the mapset should be deleted automatically using self.clean() method """ if not PY2: LOGGER.warning('Seems PyWPS is running in Python-3 ' 'environment, but GRASS GIS supports Python-2 only') return if self.grass_location: from grass.script import core as grass from grass.script import setup as gsetup # HOME needs to be set - and that is usually not the case for httpd # server os.environ['HOME'] = self.workdir # GISRC envvariable needs to be set gisrc = open(os.path.join(self.workdir, 'GISRC'), 'w') gisrc.write("GISDBASE: %s\n" % self.workdir) gisrc.write("GUI: txt\n") gisrc.close() os.environ['GISRC'] = gisrc.name new_loc_args = dict() if self.grass_location.startswith('complexinput:'): # create new location from a georeferenced file ref_file_parameter = self.grass_location.split(':')[1] ref_file = wps_request.inputs[ref_file_parameter][0].file new_loc_args.update({'filename': ref_file}) elif self.grass_location.lower().startswith('epsg:'): # create new location from epsg code epsg = self.grass_location.lower().replace('epsg:', '') new_loc_args.update({'epsg': epsg}) if new_loc_args: dbase = self.workdir location = 'pywps_location' gsetup.init(self.workdir, dbase, location, 'PERMANENT') grass.create_location(dbase=dbase, location=location, **new_loc_args) LOGGER.debug('GRASS location based on {} created'.format( list(new_loc_args.keys())[0])) # create temporary mapset within existing location elif os.path.isdir(self.grass_location): LOGGER.debug('Temporary mapset will be created') dbase = os.path.dirname(self.grass_location) location = os.path.basename(self.grass_location) grass.run_command('g.gisenv', set="GISDBASE=%s" % dbase) else: raise NoApplicableCode('Location does exists or does not seem ' 'to be in "EPSG:XXXX" form nor is it existing directory: %s' % location) # copy projection files from PERMAMENT mapset to temporary mapset mapset_name = 'pywps_mapset' grass.run_command('g.mapset', mapset=mapset_name, flags='c', dbase=dbase, location=location) # set _grass_mapset attribute - will be deleted once handler ends self._grass_mapset = mapset_name # final initialization LOGGER.debug('GRASS Mapset set to %s' % mapset_name) LOGGER.debug('GRASS environment initialised') LOGGER.debug('GISRC {}, GISBASE {}, GISDBASE {}, LOCATION {}, MAPSET {}'.format( os.environ.get('GISRC'), os.environ.get('GISBASE'), dbase, location, os.path.basename(mapset_name)))