def compute(self): # computing grass.message('"nnbathy" is performing the interpolation now. \ This may take some time...') grass.verbose("Once it completes an 'All done.' \ message will be printed.") # nnbathy calling fsock = open(self._xyzout, "w") grass.call( [ "nnbathy", "-W", "%d" % 0, "-i", "%s" % self._tmpxyz, "-x", "%f" % self.nn_w, "%f" % self.nn_e, "-y", "%f" % self.nn_n, "%f" % self.nn_s, "-P", "%s" % self.ALG, "-n", "%dx%d" % (self.cols, self.rows), ], stdout=fsock, ) fsock.close()
def ppmtopng(dst, src): if grass.find_program("g.ppmtopng", "--help"): grass.run_command("g.ppmtopng", input=src, output=dst, quiet=True) elif grass.find_program("pnmtopng"): fh = open(dst, "wb") grass.call(["pnmtopng", src], stdout=fh) fh.close() elif grass.find_program("convert"): grass.call(["convert", src, dst]) else: grass.fatal(_("Cannot find g.ppmtopng, pnmtopng or convert"))
def ppmtopng(dst, src): if grass.find_program("g.ppmtopng", '--help'): grass.run_command('g.ppmtopng', input = src, output = dst, quiet = True) elif grass.find_program("pnmtopng"): fh = open(dst, 'wb') grass.call(["pnmtopng", src], stdout = fh) fh.close() elif grass.find_program("convert"): grass.call(["convert", src, dst]) else: grass.fatal(_("Cannot find g.ppmtopng, pnmtopng or convert"))
def compute(self): # computing grass.message('"nnbathy" is performing the interpolation now. \ This may take some time...') grass.verbose("Once it completes an 'All done.' \ message will be printed.") # nnbathy calling fsock = open(self._xyzout, 'w') grass.call(['nnbathy', '-W', '%d' % 0, '-i', '%s' % self._tmpxyz, '-x', '%d' % self.nn_w, '%d' % self.nn_e, '-y', '%d' % self.nn_n, '%d' % self.nn_s, '-P', '%s' % self.ALG, '-n', '%dx%d' % (self.cols, self.rows)], stdout=fsock) fsock.close()
def compute(self): # computing grass.message('"nnbathy" is performing the interpolation now. \ This may take some time...') grass.verbose("Once it completes an 'All done.' \ message will be printed.") # nnbathy calling fsock = open(self._xyzout, 'w') grass.call([ 'nnbathy', '-W', '%d' % 0, '-i', '%s' % self._tmpxyz, '-x', '%f' % self.nn_w, '%f' % self.nn_e, '-y', '%f' % self.nn_n, '%f' % self.nn_s, '-P', '%s' % self.ALG, '-n', '%dx%d' % (self.cols, self.rows) ], stdout=fsock) fsock.close()
def import_aster(proj, srcfile, tempfile, band): #run gdalwarp with selected options (must be in $PATH) #to translate aster image to geotiff grass.message(_("Georeferencing aster image ...")) grass.debug("gdalwarp -t_srs %s %s %s" % (proj, srcfile, tempfile)) if platform.system() == "Darwin": cmd = ["arch", "-i386", "gdalwarp", "-t_srs", proj, srcfile, tempfile ] else: cmd = ["gdalwarp", "-t_srs", proj, srcfile, tempfile ] p = grass.call(cmd) if p != 0: #check to see if gdalwarp executed properly return #import geotiff to GRASS grass.message(_("Importing into GRASS ...")) outfile = "%s.%s" % (output, band) grass.run_command("r.in.gdal", input = tempfile, output = outfile) # write cmd history grass.raster_history(outfile)
def import_aster(proj, srcfile, tempfile, band): #run gdalwarp with selected options (must be in $PATH) #to translate aster image to geotiff grass.message(_("Georeferencing aster image ...")) grass.debug("gdalwarp -t_srs %s %s %s" % (proj, srcfile, tempfile)) if platform.system() == "Darwin": cmd = ["arch", "-i386", "gdalwarp", "-t_srs", proj, srcfile, tempfile] else: cmd = ["gdalwarp", "-t_srs", proj, srcfile, tempfile] p = grass.call(cmd) if p != 0: #check to see if gdalwarp executed properly return #import geotiff to GRASS grass.message(_("Importing into GRASS ...")) outfile = "%s.%s" % (output, band) grass.run_command("r.in.gdal", input=tempfile, output=outfile) # write cmd history grass.raster_history(outfile)
def main(): global tmp, tmp_proj, tmp_gpx, tmp_extr, tmp_vogb format = options['format'] input = options['input'] layer = options['layer'] output = options['output'] type = options['type'] where = options['where'] wpt = flags['w'] rte = flags['r'] trk = flags['t'] nflags = len(filter(None, [wpt, rte, trk])) if nflags > 1: grass.fatal(_("One feature at a time please.")) if nflags < 1: grass.fatal(_("No features requested for export.")) # set some reasonable defaults if not type: if wpt: type = 'point' else: type = 'line' #### check for gpsbabel ### FIXME: may need --help or similar? if not grass.find_program("gpsbabel"): grass.fatal(_("The gpsbabel program was not found, please install it first.\n") + "http://gpsbabel.sourceforge.net") #### check for cs2cs if not grass.find_program("cs2cs"): grass.fatal(_("The cs2cs program was not found, please install it first.\n") + "http://proj.osgeo.org") # check if we will overwrite data if os.path.exists(output) and not grass.overwrite(): grass.fatal(_("Output file already exists.")) #### set temporary files tmp = grass.tempfile() # SQL extract if needed if where: grass.verbose("Extracting data ...") tmp_extr = "tmp_vogb_extr_%d" % os.getpid() ret = grass.run_command('v.extract', input = "$GIS_OPT_INPUT", output = tmp_extr, type = type, layer = layer, where = where, quiet = True) if ret != 0: grass.fatal(_("Error executing SQL query")) kv = grass.vector_info_topo(tmp_extr) if kv['primitives'] == 0: grass.fatal(_("SQL query returned an empty map (no %s features?)") % type) inmap = tmp_extr else: # g.copy "$GIS_OPT_INPUT,tmp_vogb_extr_$$" # to get a copy of DB into local mapset # INMAP="tmp_vogb_extr_$$" inmap = input #### set up projection info # TODO: check if we are already in ll/WGS84. If so skip m.proj step. # TODO: multi layer will probably fail badly due to sed 's/^ 1 /' # output as old GRASS 4 vector ascii and fight with dig_ascii/? # Change to s/^ \([0-9] .*\) /# \1/' ??? mmph. # reproject to lat/lon WGS84 grass.verbose("Reprojecting data ...") re1 = re.compile(r'^\([PLBCFKA]\)') re2 = re.compile(r'^ 1 ') re3 = re.compile(r'\t\([-\.0-9]*\) .*') re4 = re.compile(r'^\([-\.0-9]\)') re5 = re.compile(r'^#') tmp_proj = tmp + ".proj" tf = open(tmp_proj, 'w') p1 = grass.pipe_command('v.out.ascii', input = inmap, format = 'standard') p2 = grass.feed_command('m.proj', input = '-', flags = 'od', quiet = True, stdout = tf) tf.close() lineno = 0 for line in p1.stdout: lineno += 1 if lineno < 11: continue line = re1.sub(r'#\1', line) line = re2.sub(r'# 1 ', line) p2.stdin.write(line) p2.stdin.close() p1.wait() p2.wait() if p1.returncode != 0 or p2.returncode != 0: grass.fatal(_("Error reprojecting data")) tmp_vogb = "tmp_vogb_epsg4326_%d" % os.getpid() p3 = grass.feed_command('v.in.ascii', out = tmp_vogb, format = 'standard', flags = 'n', quiet = True) tf = open(tmp_proj, 'r') for line in tf: line = re3.sub(r' \1', line) line = re4.sub(r' \1', line) line = re5.sub('', line) p3.stdin.write(line) p3.stdin.close() tf.close() p3.wait() if p3.returncode != 0: grass.fatal(_("Error reprojecting data")) # don't v.db.connect directly as source table will be removed with # temporary map in that case. So we make a temp copy of it to work with. kv = vector_db(inmap) if layer in kv: db_params = kv[layer] db_table = db_params['table'] db_key = db_params['key'] db_database = db_params['database'] db_driver = db_params['driver'] ret = grass.run_command('db.copy', from_driver = db_driver, from_database = db_database, from_table = db_table, to_table = tmp_vogb) if ret != 0: grass.fatal(_("Error copying temporary DB")) ret = grass.run_command('v.db.connect', map = tmp_vogb, table = tmp_vogb, quiet = True) if ret != 0: grass.fatal(_("Error reconnecting temporary DB")) # export as GPX using v.out.ogr if trk: linetype = "FORCE_GPX_TRACK=YES" elif rte: linetype = "FORCE_GPX_TRACK=YES" else: linetype = None # BUG: cat is being reported as evelation and attribute output is skipped. # (v.out.ogr DB reading or ->OGR GPX driver bug<- # resolved: see new Create opts at http://www.gdal.org/ogr/drv_gpx.html) # v.out.ogr -> shapefile -> GPX works, but we try to avoid that as it's # lossy. Also that would allow ogr2ogr -a_srs $IN_PROJ -t_srs EPSG:4326 # so skip m.proj pains.. if that is done ogr2ogr -s_srs MUST HAVE +wktext # with PROJ.4 terms or else the +nadgrids will be ignored! best to feed # it IN_PROJ="`g.proj -jf` +wktext" in that case. grass.verbose("Exporting data ...") tmp_gpx = tmp + ".gpx" ret = grass.run_command('v.out.ogr', input = tmp_vogb, dsn = tmp_gpx, type = type, format = 'GPX', lco = linetype, dsco = "GPX_USE_EXTENSIONS=YES", quiet = True) if ret != 0: grass.fatal(_("Error exporting data")) if format == 'gpx': # short circuit, we have what we came for. grass.try_remove(output) os.rename(tmp_gpx, output) grass.verbose("Fast exit.") sys.exit() # run gpsbabel if wpt: gtype = '-w' elif trk: gtype = '-t' elif rte: gtype = '-r' else: gtype = '' grass.verbose("Running GPSBabel ...") ret = grass.call(['gpsbabel', gtype, '-i', 'gpx', '-f', tmp + '.gpx', '-o', format, '-F', output]) if ret != 0: grass.fatal(_("Error running GPSBabel")) grass.verbose("Done.")
def main(): global tile, tmpdir, in_temp in_temp = False input = options['input'] output = options['output'] one = flags['1'] #are we in LatLong location? s = grass.read_command("g.proj", flags='j') kv = grass.parse_key_val(s) if kv['+proj'] != 'longlat': grass.fatal(_("This module only operates in LatLong locations")) # use these from now on: infile = input while infile[-4:].lower() in ['.hgt', '.zip']: infile = infile[:-4] (fdir, tile) = os.path.split(infile) if not output: tileout = tile else: tileout = output zipfile = infile + ".hgt.zip" hgtfile = os.path.join(fdir, tile[:7] + ".hgt") if os.path.isfile(zipfile): #### check if we have unzip if not grass.find_program('unzip'): grass.fatal(_('The "unzip" program is required, please install it first')) # really a ZIP file? # make it quiet in a safe way (just in case -qq isn't portable) tenv = os.environ.copy() tenv['UNZIP'] = '-qq' if grass.call(['unzip', '-t', zipfile], env = tenv) != 0: grass.fatal(_("'%s' does not appear to be a valid zip file.") % zipfile) is_zip = True elif os.path.isfile(hgtfile): # try and see if it's already unzipped is_zip = False else: grass.fatal(_("File '%s' or '%s' not found") % (zipfile, hgtfile)) #make a temporary directory tmpdir = grass.tempfile() grass.try_remove(tmpdir) os.mkdir(tmpdir) if is_zip: shutil.copyfile(zipfile, os.path.join(tmpdir, tile + ".hgt.zip")) else: shutil.copyfile(hgtfile, os.path.join(tmpdir, tile + ".hgt")) #change to temporary directory os.chdir(tmpdir) in_temp = True zipfile = tile + ".hgt.zip" hgtfile = tile[:7] + ".hgt" bilfile = tile + ".bil" if is_zip: #unzip & rename data file: grass.message(_("Extracting '%s'...") % infile) if grass.call(['unzip', zipfile], env = tenv) != 0: grass.fatal(_("Unable to unzip file.")) grass.message(_("Converting input file to BIL...")) os.rename(hgtfile, bilfile) north = tile[0] ll_latitude = int(tile[1:3]) east = tile[3] ll_longitude = int(tile[4:7]) # are we on the southern hemisphere? If yes, make LATITUDE negative. if north == "S": ll_latitude *= -1 # are we west of Greenwich? If yes, make LONGITUDE negative. if east == "W": ll_longitude *= -1 # Calculate Upper Left from Lower Left ulxmap = "%.1f" % ll_longitude # SRTM90 tile size is 1 deg: ulymap = "%.1f" % (ll_latitude + 1) if not one: tmpl = tmpl3sec else: grass.message(_("Attempting to import 1-arcsec data.")) tmpl = tmpl1sec header = tmpl % (ulxmap, ulymap) hdrfile = tile + '.hdr' outf = file(hdrfile, 'w') outf.write(header) outf.close() #create prj file: To be precise, we would need EGS96! But who really cares... prjfile = tile + '.prj' outf = file(prjfile, 'w') outf.write(proj) outf.close() try: grass.run_command('r.in.gdal', input=bilfile, out=tileout) except: grass.fatal(_("Unable to import data")) # nice color table grass.run_command('r.colors', map = tileout, color = 'srtm') # write cmd history: grass.raster_history(tileout) grass.message(_("Done: generated map ") + tileout) grass.message(_("(Note: Holes in the data can be closed with 'r.fillnulls' using splines)"))
def main(): # parameters infile = options['input'] raster_reference = options['raster_reference'] raster_file = options['raster_file'] outfile = options['output'] resolution = options['resolution'] method = options['method'] zrange = options['zrange'] zscale = options['zscale'] output_type = options['type'] percent = options['percent'] pth = options['pth'] trim = options['trim'] footprint = options['footprint'] # flags scan = flags['s'] shell_script_style = flags['g'] # overwrite auf true setzen os.environ['GRASS_OVERWRITE'] = '1' # to hide non-error messages from subprocesses if grass.verbosity() <= 2: outdev = open(os.devnull, 'w') else: outdev = sys.stdout # use temporary region grass.use_temp_region() # scan -s or shell_script_style -g: if scan: if not grass.find_program( options['pdal_cmd'].split(' ')[0], ' '.join(options['pdal_cmd'].split(' ')[1:]) + ' info --summary'): grass.fatal( _("The pdal program is not in the path " + "and executable. Please install first")) command_scan = options['pdal_cmd'].split(' ') command_scan.extend(['info', '--summary', infile]) tmp_scan = grass.tempfile() if tmp_scan is None: grass.fatal("Unable to create temporary files") fh = open(tmp_scan, 'wb') summary = True if grass.call(command_scan, stdout=fh) != 0: fh.close() command_scan = options['pdal_cmd'].split(' ') command_scan.extend(['info', infile]) fh2 = open(tmp_scan, 'wb') if grass.call(command_scan, stdout=fh2) != 0: os.remove(tmp_scan) grass.fatal( _("pdal cannot determine metadata " + "for unsupported format of <%s>") % infile) fh2.close() else: fh2.close() summary = False else: fh.close() data = json.load(open(tmp_scan)) if summary: str1 = u'summary' str2 = u'bounds' y_str = u'Y' x_str = u'X' z_str = u'Z' min_str = u'min' max_str = u'max' try: n = str(data[str1][str2][y_str][max_str]) s = str(data[str1][str2][y_str][min_str]) w = str(data[str1][str2][x_str][min_str]) e = str(data[str1][str2][x_str][max_str]) t = str(data[str1][str2][z_str][max_str]) b = str(data[str1][str2][z_str][min_str]) except: ymin_str = u'miny' xmin_str = u'minx' zmin_str = u'minz' ymax_str = u'maxy' xmax_str = u'maxx' zmax_str = u'maxz' n = str(data[str1][str2][ymax_str]) s = str(data[str1][str2][ymin_str]) w = str(data[str1][str2][xmin_str]) e = str(data[str1][str2][xmax_str]) t = str(data[str1][str2][zmax_str]) b = str(data[str1][str2][zmin_str]) else: str1 = u'stats' str2 = u'bbox' str3 = u'native' str4 = u'bbox' n = str(data[str1][str2][str3][str4][u'maxy']) s = str(data[str1][str2][str3][str4][u'miny']) w = str(data[str1][str2][str3][str4][u'minx']) e = str(data[str1][str2][str3][str4][u'maxx']) t = str(data[str1][str2][str3][str4][u'maxz']) b = str(data[str1][str2][str3][str4][u'minz']) if not shell_script_style: grass.message( _("north: %s\nsouth: %s\nwest: %s\neast: %s\ntop: %s\nbottom: %s" ) % (n, s, w, e, t, b)) else: grass.message( _("n=%s s=%s w=%s e=%s t=%s b=%s") % (n, s, w, e, t, b)) elif footprint: footprint_to_vectormap(infile, footprint) else: # get region with pdal footprint_to_vectormap(infile, 'tiles') if raster_file: raster_reference = 'img' + str(os.getpid()) grass.run_command('r.external', input=raster_file, flags='o', output=raster_reference) result = grass.find_file(name=raster_reference, element='raster') if result[u'fullname'] == u'': raster_reference = raster_reference + '.1' # option 1: set region to extent of tiles while precisely aligning pixel # geometry to raster_reference (including both raster_reference and raster_file) if raster_reference: grass.run_command('g.region', vector='tiles', flags='g', align=raster_reference) else: # option 2: change raster resolution to final resolution while best # effort aligning to pixel geometry grass.run_command('g.region', vector='tiles', flags='ap', res=resolution) # generate PDAL pipeline # . pdal pipline laz2json (STDOUT) | r.in.xyz bn = os.path.basename(infile) infile_format = bn.split('.')[-1] # format_reader from https://pdal.io/stages/readers.html format_reader = '' if infile_format.lower() == 'laz' or infile_format.lower() == 'las': format_reader = 'readers.las' # pts: not tested elif infile_format.lower() == 'pts': format_reader = 'readers.pts' else: grass.run_command('g.remove', flags='f', type='vector', name='tiles', quiet=True) grass.fatal(_("Format .%s is not supported.." % infile_format)) tmp_file_json = 'tmp_file_json_' + str(os.getpid()) data = {} data['pipeline'] = [] data['pipeline'].append({'type': format_reader, 'filename': infile}) data['pipeline'].append({ 'type': 'writers.text', 'format': 'csv', 'order': 'X,Y,Z', 'keep_unspecified': 'false', 'filename': 'STDOUT', 'quote_header': 'false' }) with open(tmp_file_json, 'w') as f: json.dump(data, f) tmp_xyz = grass.tempfile() if tmp_xyz is None: grass.fatal("Unable to create temporary files") command_pdal1 = options['pdal_cmd'].split(' ') if options['pdal_cmd'] != 'pdal': v_index = None cmd_entries = options['pdal_cmd'].split(' ') for cmd_entry, num in zip(cmd_entries, range(len(cmd_entries))): if cmd_entry == '-v': v_index = num break mnt_vol = cmd_entries[v_index + 1].split(':')[1] tmp_file_json2 = os.path.join(mnt_vol, tmp_file_json) else: tmp_file_json2 = tmp_file_json command_pdal1.extend(['pipeline', '--input', tmp_file_json2]) command_pdal2 = [ 'r.in.xyz', 'input=' + tmp_xyz, 'output=' + outfile, 'skip=1', 'separator=comma', 'method=' + method ] if zrange: command_pdal2.append('zrange=' + zrange) if zscale: command_pdal2.append('zscale=' + zscale) if output_type: command_pdal2.append('type=' + output_type) if percent: command_pdal2.append('percent=' + percent) if pth: command_pdal2.append('pth=' + pth) if trim: command_pdal2.append('trim=' + trim) fh = open(tmp_xyz, 'wb') if grass.call(command_pdal1, stdout=fh) != 0: fh.close() # check to see if pdal pipeline executed properly grass.fatal(_("pdal pipeline is broken...")) else: fh.close() if grass.call(command_pdal2, stdout=outdev) != 0: # check to see if r.in.xyz executed properly os.remove(tmp_xyz) grass.fatal(_("r.in.xyz is broken...")) # metadata empty_history = grass.tempfile() if empty_history is None: grass.fatal("Unable to create temporary files") f = open(empty_history, 'w') f.close() grass.run_command('r.support', map=outfile, source1=infile, description='generated by r.in.pdal', loadhistory=empty_history) grass.run_command('r.support', map=outfile, history=os.environ['CMDLINE']) os.remove(empty_history) # Cleanup grass.message(_("Cleaning up...")) grass.run_command('g.remove', flags='f', type='vector', name='tiles', quiet=True) if raster_file: grass.run_command('g.remove', flags='f', type='raster', pattern=raster_reference[:-1] + '*', quiet=True) os.remove(tmp_file_json) os.remove(tmp_xyz) grass.message(_("Generating output raster map <%s>...") % outfile) grass.del_temp_region()
def footprint_to_vectormap(infile, footprint): """ The function generates a footprint as vectormap of the input las-file. It uses pdal info --boundary. Args: infile(string): Name of LAS input file footprint(string): Footprint of the data as vector map """ if not grass.find_program( options['pdal_cmd'].split(' ')[0], ' '.join(options['pdal_cmd'].split(' ')[1:]) + ' info --boundary'): grass.fatal( _("The pdal executable is not available." " Install PDAL or put the pdal executable on path.")) command_fp = options['pdal_cmd'].split(' ') command_fp.extend(['info', '--boundary', infile]) tmp_fp = grass.tempfile() if tmp_fp is None: grass.fatal("Unable to create temporary files") fh = open(tmp_fp, 'wb') if grass.call(command_fp, stdout=fh) != 0: fh.close() # check to see if pdal info executed properly os.remove(tmp_fp) grass.fatal(_("pdal info broken...")) else: fh.close() data = json.load(open(tmp_fp)) xy_in = '' str1 = u'boundary' try: str2 = u'boundary_json' str3 = u'coordinates' coord = data[str1][str2][str3][0][0] for xy in coord: xy_in += str(xy[0]) + ',' + str(xy[1]) + '\n' except Exception: coord_str = str(data[str1][str1]) coord = coord_str[coord_str.find('((') + 2:coord_str.find('))')] x_y = coord.split(',') for xy in x_y: xy_in += xy.rstrip().replace(' ', ',') + '\n' tmp_xy = grass.tempfile() if tmp_xy is None: grass.fatal("Unable to create temporary files") f = open(tmp_xy, 'w') f.write(xy_in[:-1]) f.close() grass.run_command('v.in.lines', input=tmp_xy, output='footprint_line', separator='comma') grass.run_command('g.region', vector='footprint_line') grass.run_command('v.type', input='footprint_line', out='footprint_boundary', from_type='line', to_type='boundary') grass.run_command('v.centroids', input='footprint_boundary', out=footprint) grass.run_command('v.db.addtable', map=footprint, columns='name varchar(50)') grass.run_command('v.db.update', map=footprint, column='name', value=infile) # Cleaning up grass.message(_("Cleaning up...")) os.remove(tmp_fp) os.remove(tmp_xy) grass.run_command('g.remove', flags='f', type='vector', name='footprint_line', quiet=True) grass.run_command('g.remove', flags='f', type='vector', name='footprint_boundary', quiet=True) # metadata grass.run_command('v.support', map=footprint, comment='in ' + os.environ['CMDLINE']) grass.message(_("Generating output vector map <%s>...") % footprint)
def main(): # parameters infile = options['input'] raster_reference = options['raster_reference'] raster_file = options['raster_file'] outfiles = options['output'] resolution = options['resolution'] methods = options['method'] zrange = options['zrange'] zscale = options['zscale'] output_type = options['type'] percent = options['percent'] pth = options['pth'] trim = options['trim'] footprint = options['footprint'] # flags scan = flags['s'] shell_script_style = flags['g'] if len(outfiles.split(",")) != len(methods.split(",")): grass.fatal( _("Number of outputs <%s> does not match number of methods <%s>" % (outfiles, methods))) # overwrite auf true setzen os.environ['GRASS_OVERWRITE'] = '1' # to hide non-error messages from subprocesses if grass.verbosity() <= 2: outdev = open(os.devnull, 'w') else: outdev = sys.stdout # use temporary region grass.use_temp_region() n, s, w, e, t, b = scan_extent(infile) # scan -s or shell_script_style -g: if scan: if not shell_script_style: grass.message( _("north: %s\nsouth: %s\nwest: %s\neast: %s\ntop: %s\nbottom: %s" ) % (n, s, w, e, t, b)) else: # shell script style: print to stdout print("n=%s s=%s w=%s e=%s t=%s b=%s" % (n, s, w, e, t, b)) elif footprint: footprint_to_vectormap(infile, footprint) else: # get region with pdal #footprint_to_vectormap(infile, 'tiles') if raster_file: raster_reference = 'img' + str(os.getpid()) grass.run_command('r.external', input=raster_file, flags='o', output=raster_reference) result = grass.find_file(name=raster_reference, element='raster') if result[u'fullname'] == u'': raster_reference = raster_reference + '.1' # option 1: set region to extent of tiles while precisely aligning pixel # geometry to raster_reference (including both raster_reference and raster_file) if raster_reference: grass.run_command('g.region', n=n, s=s, e=e, w=w, flags='g', align=raster_reference) else: # option 2: change raster resolution to final resolution while best # effort aligning to pixel geometry grass.run_command('g.region', n=n, s=s, e=e, w=w, flags='ap', res=resolution) # generate PDAL pipeline # . pdal pipline laz2json (STDOUT) | r.in.xyz bn = os.path.basename(infile) infile_format = bn.split('.')[-1] # format_reader from https://pdal.io/stages/readers.html format_reader = '' if infile_format.lower() == 'laz' or infile_format.lower() == 'las': format_reader = 'readers.las' # pts: not tested elif infile_format.lower() == 'pts': format_reader = 'readers.pts' else: grass.run_command('g.remove', flags='f', type='vector', name='tiles', quiet=True) grass.fatal(_("Format .%s is not supported.." % infile_format)) grass.message(_("Converting input file <%s>...") % infile) tmp_file_json = 'tmp_file_json_' + str(os.getpid()) data = {} data['pipeline'] = [] data['pipeline'].append({'type': format_reader, 'filename': infile}) data['pipeline'].append({ 'type': 'writers.text', 'format': 'csv', 'order': 'X,Y,Z', 'keep_unspecified': 'false', 'filename': 'STDOUT', 'quote_header': 'false' }) with open(tmp_file_json, 'w') as f: json.dump(data, f) tmp_xyz = grass.tempfile() if tmp_xyz is None: grass.fatal("Unable to create temporary files") command_pdal1 = options['pdal_cmd'].split(' ') if options['pdal_cmd'] != 'pdal': v_index = None cmd_entries = options['pdal_cmd'].split(' ') for cmd_entry, num in zip(cmd_entries, range(len(cmd_entries))): if cmd_entry == '-v': v_index = num break mnt_vol = cmd_entries[v_index + 1].split(':')[1] tmp_file_json2 = os.path.join(mnt_vol, tmp_file_json) else: tmp_file_json2 = tmp_file_json command_pdal1.extend(['pipeline', '--input', tmp_file_json2]) fh = open(tmp_xyz, 'wb') if grass.call(command_pdal1, stdout=fh) != 0: fh.close() # check to see if pdal pipeline executed properly print(command_pdal1) grass.fatal(_("pdal pipeline is broken...")) else: fh.close() for i in range(len(methods.split(","))): method = methods.split(",")[i] outfile = outfiles.split(",")[i] grass.message(_("Generating output raster map <%s>...") % outfile) command_pdal2 = [ 'r.in.xyz', 'input=' + tmp_xyz, 'output=' + outfile, 'skip=1', 'separator=comma', 'method=' + method ] if zrange: command_pdal2.append('zrange=' + zrange) if zscale: command_pdal2.append('zscale=' + zscale) if output_type: command_pdal2.append('type=' + output_type) if percent: command_pdal2.append('percent=' + percent) if pth: command_pdal2.append('pth=' + pth) if trim: command_pdal2.append('trim=' + trim) if grass.call(command_pdal2, stdout=outdev) != 0: # check to see if r.in.xyz executed properly os.remove(tmp_xyz) grass.fatal(_("r.in.xyz is broken...")) # metadata empty_history = grass.tempfile() if empty_history is None: grass.fatal("Unable to create temporary files") f = open(empty_history, 'w') f.close() grass.run_command('r.support', map=outfile, source1=infile, description='generated by r.in.pdal', loadhistory=empty_history) grass.run_command('r.support', map=outfile, history=os.environ['CMDLINE']) os.remove(empty_history) # Cleanup grass.message(_("Cleaning up...")) grass.run_command('g.remove', flags='f', type='vector', name='tiles', quiet=True) if raster_file: grass.run_command('g.remove', flags='f', type='raster', pattern=raster_reference[:-1] + '*', quiet=True) os.remove(tmp_file_json) os.remove(tmp_xyz) grass.del_temp_region()
def scan_extent(infile): if not grass.find_program( options['pdal_cmd'].split(' ')[0], ' '.join(options['pdal_cmd'].split(' ')[1:]) + ' info --summary'): grass.fatal( _("The pdal program is not in the path " + "and executable. Please install first")) command_scan = options['pdal_cmd'].split(' ') command_scan.extend(['info', '--summary', infile]) tmp_scan = grass.tempfile() if tmp_scan is None: grass.fatal("Unable to create temporary files") fh = open(tmp_scan, 'wb') summary = True if grass.call(command_scan, stdout=fh) != 0: fh.close() command_scan = options['pdal_cmd'].split(' ') command_scan.extend(['info', infile]) fh2 = open(tmp_scan, 'wb') if grass.call(command_scan, stdout=fh2) != 0: os.remove(tmp_scan) grass.fatal( _("pdal cannot determine metadata " + "for unsupported format of <%s>") % infile) fh2.close() else: fh2.close() summary = False else: fh.close() data = json.load(open(tmp_scan)) if summary: str1 = u'summary' str2 = u'bounds' y_str = u'Y' x_str = u'X' z_str = u'Z' min_str = u'min' max_str = u'max' try: n = str(data[str1][str2][y_str][max_str]) s = str(data[str1][str2][y_str][min_str]) w = str(data[str1][str2][x_str][min_str]) e = str(data[str1][str2][x_str][max_str]) t = str(data[str1][str2][z_str][max_str]) b = str(data[str1][str2][z_str][min_str]) except: ymin_str = u'miny' xmin_str = u'minx' zmin_str = u'minz' ymax_str = u'maxy' xmax_str = u'maxx' zmax_str = u'maxz' n = str(data[str1][str2][ymax_str]) s = str(data[str1][str2][ymin_str]) w = str(data[str1][str2][xmin_str]) e = str(data[str1][str2][xmax_str]) t = str(data[str1][str2][zmax_str]) b = str(data[str1][str2][zmin_str]) else: str1 = u'stats' str2 = u'bbox' str3 = u'native' str4 = u'bbox' n = str(data[str1][str2][str3][str4][u'maxy']) s = str(data[str1][str2][str3][str4][u'miny']) w = str(data[str1][str2][str3][str4][u'minx']) e = str(data[str1][str2][str3][str4][u'maxx']) t = str(data[str1][str2][str3][str4][u'maxz']) b = str(data[str1][str2][str3][str4][u'minz']) return n, s, w, e, t, b
def main(): global tmp_rmaps # user keys in_raster = options["input"] # in_raster = 'srtm_1sec_amazonia' out_raster = options["output"] # out_raster = 'teste_dnoise' iterations = options["iterations"] threshold = options["threshold"] epsg = options["epsg"] # check if input file exists if not grass.find_file(in_raster)["file"]: grass.fatal(_("Raster map <%s> not found") % in_raster) # name the files tmp_xyz = "{}.xyz".format(grass.tempfile()) tmp_xyz_proj = "{}.xyz".format(grass.tempfile()) tmp_out_dnoise = "{}.xyz".format(grass.tempfile()) tmp_xyz_merge = "{}.xyz".format(grass.tempfile()) # list for cleanup tmp_rmaps = [tmp_xyz, tmp_xyz_proj, tmp_out_dnoise, tmp_xyz_merge] # Export the map to xyz points. grass.message(_("Exporting points...")) grass.run_command("r.out.xyz", input=in_raster, output=tmp_xyz, separator="space", overwrite=True) # check if current location is in a projected coordinate system reproject = check_proj(epsg) # Reproject if necessary if reproject: # define projections loc_proj = grass.read_command("g.proj", flags="jf") loc_proj = pyproj.Proj(loc_proj.strip()) epsg_proj = pyproj.Proj(init="epsg:" + str(epsg)) do_proj(xyz_in=tmp_xyz, xyz_out=tmp_xyz_proj, in_proj=loc_proj, out_proj=epsg_proj) tmp_xyz = tmp_xyz_proj # Denoise. The -z flag preserves the xy positions of the points. grass.message(_("Denoising...")) cmd = (["mdenoise"] + ["-i"] + [tmp_xyz] + ["-t"] + [str(threshold)] + ["-n"] + [str(iterations)] + ["-z"] + ["-o"] + [tmp_out_dnoise]) grass.call(cmd) # As only the z coordinates have changed in denoising, # the new z coordinates are combined with the original xy coordinates. f_merged = open(tmp_xyz_merge, "w") # new, merged # read input coordinates file with open(tmp_out_dnoise) as f_dnoise, open(tmp_xyz) as f_orig: for line_dnoise, line_orig in zip(f_dnoise, f_orig): xyz_dnoise = line_dnoise.split() # denoised xyz_orig = line_orig.split() # original f_merged.write("%s %s %s\n" % (xyz_orig[0], xyz_orig[1], xyz_dnoise[2])) # close files f_merged.close() # Reload data grass.message(_("Reloading data...")) grass.run_command( "r.in.xyz", flags="i", input=tmp_xyz_merge, output=out_raster, method="min", x=1, y=2, z=3, separator="space", overwrite=True, ) # Edit metadata to record denoising parameters grass.run_command("r.support", map=out_raster, title="A denoised version of <%s>" % in_raster) grass.run_command( "r.support", map=out_raster, history="Generated by: r.denoise %s iterations=%s threshold=%s" % (in_raster, str(threshold), str(iterations)), )
def main(): global tile, tmpdir, in_temp in_temp = False input = options['input'] output = options['output'] one = flags['1'] # are we in LatLong location? s = grass.read_command("g.proj", flags='j') kv = grass.parse_key_val(s) if kv['+proj'] != 'longlat': grass.fatal(_("This module only operates in LatLong locations")) # use these from now on: infile = input while infile[-4:].lower() in ['.hgt', '.zip']: infile = infile[:-4] (fdir, tile) = os.path.split(infile) if not output: tileout = tile else: tileout = output zipfile = infile + ".hgt.zip" hgtfile = os.path.join(fdir, tile[:7] + ".hgt") if os.path.isfile(zipfile): # check if we have unzip if not grass.find_program('unzip'): grass.fatal( _('The "unzip" program is required, please install it first')) # really a ZIP file? # make it quiet in a safe way (just in case -qq isn't portable) tenv = os.environ.copy() tenv['UNZIP'] = '-qq' if grass.call(['unzip', '-t', zipfile], env=tenv) != 0: grass.fatal( _("'%s' does not appear to be a valid zip file.") % zipfile) is_zip = True elif os.path.isfile(hgtfile): # try and see if it's already unzipped is_zip = False else: grass.fatal(_("File '%s' or '%s' not found") % (zipfile, hgtfile)) # make a temporary directory tmpdir = grass.tempfile() grass.try_remove(tmpdir) os.mkdir(tmpdir) if is_zip: shutil.copyfile(zipfile, os.path.join(tmpdir, tile + ".hgt.zip")) else: shutil.copyfile(hgtfile, os.path.join(tmpdir, tile + ".hgt")) # change to temporary directory os.chdir(tmpdir) in_temp = True zipfile = tile + ".hgt.zip" hgtfile = tile[:7] + ".hgt" bilfile = tile + ".bil" if is_zip: # unzip & rename data file: grass.message(_("Extracting '%s'...") % infile) if grass.call(['unzip', zipfile], env=tenv) != 0: grass.fatal(_("Unable to unzip file.")) grass.message(_("Converting input file to BIL...")) os.rename(hgtfile, bilfile) north = tile[0] ll_latitude = int(tile[1:3]) east = tile[3] ll_longitude = int(tile[4:7]) # are we on the southern hemisphere? If yes, make LATITUDE negative. if north == "S": ll_latitude *= -1 # are we west of Greenwich? If yes, make LONGITUDE negative. if east == "W": ll_longitude *= -1 # Calculate Upper Left from Lower Left ulxmap = "%.1f" % ll_longitude # SRTM90 tile size is 1 deg: ulymap = "%.1f" % (ll_latitude + 1) if not one: tmpl = tmpl3sec else: grass.message(_("Attempting to import 1-arcsec data.")) tmpl = tmpl1sec header = tmpl % (ulxmap, ulymap) hdrfile = tile + '.hdr' outf = file(hdrfile, 'w') outf.write(header) outf.close() # create prj file: To be precise, we would need EGS96! But who really cares... prjfile = tile + '.prj' outf = file(prjfile, 'w') outf.write(proj) outf.close() try: grass.run_command('r.in.gdal', input=bilfile, out=tileout) except: grass.fatal(_("Unable to import data")) # nice color table grass.run_command('r.colors', map=tileout, color='srtm') # write cmd history: grass.raster_history(tileout) grass.message(_("Done: generated map ") + tileout) grass.message( _("(Note: Holes in the data can be closed with 'r.fillnulls' using splines)" ))
def footprint_to_vectormap(infile, footprint): """The function generates a footprint as vectormap of the input las-file. It uses pdal info --boundary. Args: infile(string): Name of LAS input file footprint(string): Footprint of the data as vector map """ if not grass.find_program( options["pdal_cmd"].split(" ")[0], " ".join(options["pdal_cmd"].split(" ")[1:]) + " info --boundary", ): grass.fatal( _("The pdal executable is not available." " Install PDAL or put the pdal executable on path.")) command_fp = options["pdal_cmd"].split(" ") command_fp.extend(["info", "--boundary", infile]) tmp_fp = grass.tempfile() if tmp_fp is None: grass.fatal("Unable to create temporary files") fh = open(tmp_fp, "wb") if grass.call(command_fp, stdout=fh) != 0: fh.close() # check to see if pdal info executed properly os.remove(tmp_fp) grass.fatal(_("pdal info broken...")) else: fh.close() data = json.load(open(tmp_fp)) xy_in = "" str1 = u"boundary" try: str2 = u"boundary_json" str3 = u"coordinates" coord = data[str1][str2][str3][0][0] for xy in coord: xy_in += str(xy[0]) + "," + str(xy[1]) + "\n" except Exception: coord_str = str(data[str1][str1]) coord = coord_str[coord_str.find("((") + 2:coord_str.find("))")] x_y = coord.split(",") for xy in x_y: xy_in += xy.rstrip().replace(" ", ",") + "\n" tmp_xy = grass.tempfile() if tmp_xy is None: grass.fatal("Unable to create temporary files") f = open(tmp_xy, "w") f.write(xy_in[:-1]) f.close() grass.run_command("v.in.lines", input=tmp_xy, output="footprint_line", separator="comma") grass.run_command("g.region", vector="footprint_line") grass.run_command( "v.type", input="footprint_line", out="footprint_boundary", from_type="line", to_type="boundary", ) grass.run_command("v.centroids", input="footprint_boundary", out=footprint) grass.run_command("v.db.addtable", map=footprint, columns="name varchar(50)") grass.run_command("v.db.update", map=footprint, column="name", value=infile) # Cleaning up grass.message(_("Cleaning up...")) os.remove(tmp_fp) os.remove(tmp_xy) grass.run_command("g.remove", flags="f", type="vector", name="footprint_line", quiet=True) grass.run_command("g.remove", flags="f", type="vector", name="footprint_boundary", quiet=True) # metadata grass.run_command("v.support", map=footprint, comment="in " + os.environ["CMDLINE"]) grass.message(_("Generating output vector map <%s>...") % footprint)
def main(): format = options["format"] input = options["input"] output = options["output"] proj_terms = options["proj"] wpt = flags["w"] rte = flags["r"] trk = flags["t"] points_mode = flags["p"] no_reproj = flags["k"] nflags = len(filter(None, [wpt, rte, trk])) if nflags > 1: grass.fatal(_("One feature at a time please.")) if nflags < 1: grass.fatal(_("No features requested for import.")) #### check for gpsbabel ### FIXME: may need --help or similar? if not grass.find_program("gpsbabel"): grass.fatal( _("The gpsbabel program was not found, please install it first.\n") + "http://gpsbabel.sourceforge.net" ) #### check for cs2cs if not grass.find_program("cs2cs"): grass.fatal( _("The cs2cs program was not found, please install it first.\n") + "http://proj.osgeo.org" ) # todo # # check if we will overwrite data # if grass.findfile(output) and not grass.overwrite(): # grass.fatal(_("Output file already exists.")) #### set temporary files tmp = grass.tempfile() # import as GPX using v.in.ogr # if trk: # linetype = "FORCE_GPX_TRACK=YES" # elif rte: # linetype = "FORCE_GPX_TRACK=YES" # else: # linetype = None if format == "gpx": # short circuit, we have what we came for. # todo # grass.try_remove(output) # os.rename(tmp_gpx, output) grass.verbose("Fast exit.") sys.exit() # run gpsbabel if wpt: gtype = "-w" elif trk: gtype = "-t" elif rte: gtype = "-r" else: gtype = "" grass.verbose("Running GPSBabel ...") ret = grass.call( ["gpsbabel", gtype, "-i", format, "-f", output, "-o", "gpx", "-F", tmp + ".gpx"] ) if ret != 0: grass.fatal(_("Error running GPSBabel")) grass.verbose("Importing data ...") tmp_gpx = tmp + ".gpx" try: grass.run_command( "v.in.ogr", input=tmp_gpx, output=output, type=type, format="GPX", lco=linetype, dsco="GPX_USE_EXTENSIONS=YES", quiet=True, ) except CalledModuleError: grass.fatal(_("Error importing data")) #### set up projection info # TODO: check if we are already in ll/WGS84. If so skip m.proj step. # TODO: multi layer will probably fail badly due to sed 's/^ 1 /' # output as old GRASS 4 vector ascii and fight with dig_ascii/? # Change to s/^ \([0-9] .*\) /# \1/' ??? mmph. # todo (taken from Glynn's v.out.gps) # reproject to lat/lon WGS84 # grass.verbose("Reprojecting data ...") # # re1 = re.compile(r'^\([PLBCFKA]\)') # re2 = re.compile(r'^ 1 ') # # re3 = re.compile(r'\t\([-\.0-9]*\) .*') # re4 = re.compile(r'^\([-\.0-9]\)') # re5 = re.compile(r'^#') # # tmp_proj = tmp + ".proj" # tf = open(tmp_proj, 'w') # p1 = grass.pipe_command('v.out.ascii', input = inmap, format = 'standard') # p2 = grass.feed_command('m.proj', input = '-', flags = 'od', quiet = True, stdout = tf) # tf.close() # # lineno = 0 # for line in p1.stdout: # lineno += 1 # if lineno < 11: # continue # line = re1.sub(r'#\1', line) # line = re2.sub(r'# 1 ', line) # p2.stdin.write(line) # # p2.stdin.close() # p1.wait() # p2.wait() # # if p1.returncode != 0 or p2.returncode != 0: # grass.fatal(_("Error reprojecting data")) # # tmp_vogb = "tmp_vogb_epsg4326_%d" % os.getpid() # p3 = grass.feed_command('v.in.ascii', out = tmp_vogb, format = 'standard', flags = 'n', quiet = True) # tf = open(tmp_proj, 'r') # # for line in tf: # line = re3.sub(r' \1', line) # line = re4.sub(r' \1', line) # line = re5.sub('', line) # p3.stdin.write(line) # # p3.stdin.close() # tf.close() # p3.wait() # # if p3.returncode != 0: # grass.fatal(_("Error reprojecting data")) grass.verbose("Done.")
def main(): # PID global unique # user keys in_raster = options['input'] # in_raster = 'srtm_1sec_amazonia' out_raster = options['output'] # out_raster = 'teste_dnoise' iterations = options['iterations'] threshold = options['threshold'] epsg = options['epsg'] # check if input file exists if not grass.find_file(in_raster)['file']: grass.fatal(_("Raster map <%s> not found") % in_raster) # name the files tmp_xyz = 'tmp_xyz_%s.xyz' % unique tmp_xyz_orig = 'tmp_xyz_%s.xyz' % unique tmp_xyz_proj = 'tmp_xyz_proj_%s.xyz' % unique tmp_out_dnoise = 'tmp_xyz_dnoise_%s.xyz' % unique # tmp_out_dnoise_proj = 'tmp_xyz_dnoise_proj_%s.xyz' % unique tmp_xyz_merge = 'tmp_xyz_merge_%s.xyz' % unique # list for cleanup tmp_rmaps = [ tmp_xyz, tmp_xyz_orig, tmp_xyz_proj, tmp_out_dnoise, tmp_xyz_merge ] # Export the map to xyz points. grass.message(_("Exporting points...")) grass.run_command('r.out.xyz', input=in_raster, output=tmp_xyz, separator='space', overwrite=True) # check if current location is in a projected coordinate system reproject = check_proj(epsg) # Reproject if necessary if reproject: # define projections loc_proj = grass.read_command('g.proj', flags='jf') loc_proj = pyproj.Proj(loc_proj.strip()) epsg_proj = pyproj.Proj(init='epsg:' + str(epsg)) do_proj(xyz_in=tmp_xyz, xyz_out=tmp_xyz_proj, in_proj=loc_proj, out_proj=epsg_proj) tmp_xyz = tmp_xyz_proj # Denoise. The -z flag preserves the xy positions of the points. grass.message(_("Denoising...")) cmd = ['mdenoise'] + ['-i'] + [tmp_xyz] + ['-t'] + [str(threshold)] + [ '-n' ] + [str(iterations)] + ['-z'] + ['-o'] + [tmp_out_dnoise] grass.call(cmd) # As only the z coordinates have changed in denoising, # the new z coordinates are combined with the original xy coordinates. f_merged = open(tmp_xyz_merge, 'w') # new, merged #read input coordinates file with open(tmp_out_dnoise) as f_dnoise, open(tmp_xyz_orig) as f_orig: for line_dnoise, line_orig in izip(f_dnoise, f_orig): xyz_dnoise = line_dnoise.split() # denoised xyz_orig = line_orig.split() # original f_merged.write('%s %s %s\n' % (xyz_orig[0], xyz_orig[1], xyz_dnoise[2])) # close files f_merged.close() # Reload data grass.message(_("Reloading data...")) grass.run_command('r.in.xyz', flags='i', input=tmp_xyz_merge, output=out_raster, method='min', x=1, y=2, z=3, separator='space', overwrite=True) # Edit metadata to record denoising parameters grass.run_command('r.support', map=out_raster, title="A denoised version of <%s>" % in_raster) grass.run_command( 'r.support', map=out_raster, history="Generated by: r.denoise %s iterations=%s threshold=%s" % (in_raster, str(threshold), str(iterations))) # clean tmp files grass.message(_("Removing temporary files...")) tmp_rmaps = [ fname for fname in os.listdir('.') if fname.endswith('%s.xyz' % unique) ] try: for fname in tmp_rmaps: os.remove(fname) except OSError: pass
def main(): # parameters infile = options["input"] raster_reference = options["raster_reference"] raster_file = options["raster_file"] outfiles = options["output"] resolution = options["resolution"] methods = options["method"] zrange = options["zrange"] zscale = options["zscale"] output_type = options["type"] percent = options["percent"] pth = options["pth"] trim = options["trim"] footprint = options["footprint"] # flags scan = flags["s"] shell_script_style = flags["g"] if len(outfiles.split(",")) != len(methods.split(",")): grass.fatal( _("Number of outputs <%s> does not match number of methods <%s>" % (outfiles, methods))) # overwrite auf true setzen os.environ["GRASS_OVERWRITE"] = "1" # to hide non-error messages from subprocesses if grass.verbosity() <= 2: outdev = open(os.devnull, "w") else: outdev = sys.stdout # use temporary region grass.use_temp_region() n, s, w, e, t, b = scan_extent(infile) # scan -s or shell_script_style -g: if scan: if not shell_script_style: grass.message( _("north: %s\nsouth: %s\nwest: %s\neast: %s\ntop: %s\nbottom: %s" ) % (n, s, w, e, t, b)) else: # shell script style: print to stdout print("n=%s s=%s w=%s e=%s t=%s b=%s" % (n, s, w, e, t, b)) elif footprint: footprint_to_vectormap(infile, footprint) else: # get region with pdal # footprint_to_vectormap(infile, 'tiles') if raster_file: raster_reference = "img" + str(os.getpid()) grass.run_command("r.external", input=raster_file, flags="o", output=raster_reference) result = grass.find_file(name=raster_reference, element="raster") if result[u"fullname"] == u"": raster_reference = raster_reference + ".1" # option 1: set region to extent of tiles while precisely aligning pixel # geometry to raster_reference (including both raster_reference and raster_file) if raster_reference: grass.run_command("g.region", n=n, s=s, e=e, w=w, flags="g", align=raster_reference) else: # option 2: change raster resolution to final resolution while best # effort aligning to pixel geometry grass.run_command("g.region", n=n, s=s, e=e, w=w, flags="ap", res=resolution) # generate PDAL pipeline # . pdal pipline laz2json (STDOUT) | r.in.xyz bn = os.path.basename(infile) infile_format = bn.split(".")[-1] # format_reader from https://pdal.io/stages/readers.html format_reader = "" if infile_format.lower() == "laz" or infile_format.lower() == "las": format_reader = "readers.las" # pts: not tested elif infile_format.lower() == "pts": format_reader = "readers.pts" else: grass.run_command("g.remove", flags="f", type="vector", name="tiles", quiet=True) grass.fatal(_("Format .%s is not supported.." % infile_format)) grass.message(_("Converting input file <%s>...") % infile) tmp_file_json = "tmp_file_json_" + str(os.getpid()) data = {} data["pipeline"] = [] data["pipeline"].append({"type": format_reader, "filename": infile}) data["pipeline"].append({ "type": "writers.text", "format": "csv", "order": "X,Y,Z", "keep_unspecified": "false", "filename": "STDOUT", "quote_header": "false", }) with open(tmp_file_json, "w") as f: json.dump(data, f) tmp_xyz = grass.tempfile() if tmp_xyz is None: grass.fatal("Unable to create temporary files") command_pdal1 = options["pdal_cmd"].split(" ") if options["pdal_cmd"] != "pdal": v_index = None cmd_entries = options["pdal_cmd"].split(" ") for cmd_entry, num in zip(cmd_entries, range(len(cmd_entries))): if cmd_entry == "-v": v_index = num break mnt_vol = cmd_entries[v_index + 1].split(":")[1] tmp_file_json2 = os.path.join(mnt_vol, tmp_file_json) else: tmp_file_json2 = tmp_file_json command_pdal1.extend(["pipeline", "--input", tmp_file_json2]) fh = open(tmp_xyz, "wb") if grass.call(command_pdal1, stdout=fh) != 0: fh.close() # check to see if pdal pipeline executed properly print(command_pdal1) grass.fatal(_("pdal pipeline is broken...")) else: fh.close() for i in range(len(methods.split(","))): method = methods.split(",")[i] outfile = outfiles.split(",")[i] grass.message(_("Generating output raster map <%s>...") % outfile) command_pdal2 = [ "r.in.xyz", "input=" + tmp_xyz, "output=" + outfile, "skip=1", "separator=comma", "method=" + method, ] if zrange: command_pdal2.append("zrange=" + zrange) if zscale: command_pdal2.append("zscale=" + zscale) if output_type: command_pdal2.append("type=" + output_type) if percent: command_pdal2.append("percent=" + percent) if pth: command_pdal2.append("pth=" + pth) if trim: command_pdal2.append("trim=" + trim) if grass.call(command_pdal2, stdout=outdev) != 0: # check to see if r.in.xyz executed properly os.remove(tmp_xyz) grass.fatal(_("r.in.xyz is broken...")) # metadata empty_history = grass.tempfile() if empty_history is None: grass.fatal("Unable to create temporary files") f = open(empty_history, "w") f.close() grass.run_command( "r.support", map=outfile, source1=infile, description="generated by r.in.pdal", loadhistory=empty_history, ) grass.run_command("r.support", map=outfile, history=os.environ["CMDLINE"]) os.remove(empty_history) # Cleanup grass.message(_("Cleaning up...")) grass.run_command("g.remove", flags="f", type="vector", name="tiles", quiet=True) if raster_file: grass.run_command( "g.remove", flags="f", type="raster", pattern=raster_reference[:-1] + "*", quiet=True, ) os.remove(tmp_file_json) os.remove(tmp_xyz) grass.del_temp_region()
def scan_extent(infile): if not grass.find_program( options["pdal_cmd"].split(" ")[0], " ".join(options["pdal_cmd"].split(" ")[1:]) + " info --summary", ): grass.fatal( _("The pdal program is not in the path " + "and executable. Please install first")) command_scan = options["pdal_cmd"].split(" ") command_scan.extend(["info", "--summary", infile]) tmp_scan = grass.tempfile() if tmp_scan is None: grass.fatal("Unable to create temporary files") fh = open(tmp_scan, "wb") summary = True if grass.call(command_scan, stdout=fh) != 0: fh.close() command_scan = options["pdal_cmd"].split(" ") command_scan.extend(["info", infile]) fh2 = open(tmp_scan, "wb") if grass.call(command_scan, stdout=fh2) != 0: os.remove(tmp_scan) grass.fatal( _("pdal cannot determine metadata " + "for unsupported format of <%s>") % infile) fh2.close() else: fh2.close() summary = False else: fh.close() data = json.load(open(tmp_scan)) if summary: str1 = u"summary" str2 = u"bounds" y_str = u"Y" x_str = u"X" z_str = u"Z" min_str = u"min" max_str = u"max" try: n = str(data[str1][str2][y_str][max_str]) s = str(data[str1][str2][y_str][min_str]) w = str(data[str1][str2][x_str][min_str]) e = str(data[str1][str2][x_str][max_str]) t = str(data[str1][str2][z_str][max_str]) b = str(data[str1][str2][z_str][min_str]) except: ymin_str = u"miny" xmin_str = u"minx" zmin_str = u"minz" ymax_str = u"maxy" xmax_str = u"maxx" zmax_str = u"maxz" n = str(data[str1][str2][ymax_str]) s = str(data[str1][str2][ymin_str]) w = str(data[str1][str2][xmin_str]) e = str(data[str1][str2][xmax_str]) t = str(data[str1][str2][zmax_str]) b = str(data[str1][str2][zmin_str]) else: str1 = u"stats" str2 = u"bbox" str3 = u"native" str4 = u"bbox" n = str(data[str1][str2][str3][str4][u"maxy"]) s = str(data[str1][str2][str3][str4][u"miny"]) w = str(data[str1][str2][str3][str4][u"minx"]) e = str(data[str1][str2][str3][str4][u"maxx"]) t = str(data[str1][str2][str3][str4][u"maxz"]) b = str(data[str1][str2][str3][str4][u"minz"]) return n, s, w, e, t, b