GRASS commands POC for cutlines generation

pull/979/head
Piero Toffanin 2019-04-25 18:17:45 -04:00
rodzic 3dfa632d0e
commit 15045d542a
5 zmienionych plików z 63 dodań i 27 usunięć

Wyświetl plik

@ -2,7 +2,7 @@
# max_concurrency: maximum number of parallel processes to use # max_concurrency: maximum number of parallel processes to use
# memory: maximum MB of memory to use # memory: maximum MB of memory to use
# ------ # ------
# output: If successful, prints the full path to the contours file. Otherwise it prints "error" # output: If successful, prints the full path to the cutlines file. Otherwise it prints "error"
# Split string using ',' separator # Split string using ',' separator
IFS=',' read -ra DST <<< "${orthophoto_files}" IFS=',' read -ra DST <<< "${orthophoto_files}"
@ -10,14 +10,40 @@ ORTHOPHOTO_FILES=("$${DST[@]}")
i=0 i=0
existing_cutlines="" existing_cutlines=""
current_rasters=""
for orthophoto_file in "$${ORTHOPHOTO_FILES[@]}"; do for orthophoto_file in "$${ORTHOPHOTO_FILES[@]}"; do
# Import orthophoto # Import orthophoto (green band only)
r.external input=$$orthophoto_file output=ortho$$i --overwrite r.external band=2 input="$$orthophoto_file" output=ortho$$i --overwrite
# Generate cutlines # Generate polygon area
i.cutlines --overwrite input=ortho$$i output=cutline$$i number_lines=4 edge_detection=zc processes=${max_concurrency} memory=${memory} gdal_polygonize.py -b 4 -f GeoPKG
# Set nodata
r.null map=ortho$$i setnull=0
current_rasters="ortho$$i,$$current_rasters"
g.region raster="$$current_rasters"
# Generate cutlines
i.cutlines.py --overwrite input=ortho$$i output=cutline$$i number_lines=4 edge_detection=zc existing_cutlines=$$existing_cutlines processes=${max_concurrency} memory=${memory}
# TODO: use below for values (canny, etc.)
#i.cutlines.py --overwrite input=ortho2.blue@PERMANENT output=cutline number_lines=16 edge_detection=canny no_edge_friction=10 lane_border_multiplier=100 processes=1 memory=300
# TODO select only polygons within safe area
#v.select ainput=cutline -binput=area -output=result operator=within
# TODO add these too
# GRASS commands for dissolve don't seem to work as expected
#ogr2ogr -f GPKG -overwrite -explodecollections -dialect SQLite -sql "SELECT ST_Union(geom) FROM result" -nln dissolved dissolved.gpkg result.gpkg
#ogr2ogr -f GPKG -overwrite -dialect SQLITE -sql "SELECT * FROM dissolved ORDER BY ST_AREA(geom) DESC LIMIT 1" -nln cutline cutline.gpkg dissolved.gpkg
# Export
v.out.ogr input="cutline$$i" output="cutline$$i.gpkg" format=GPKG
# Prepend cutline to list of cutlines # Prepend cutline to list of cutlines
existing_cutlines="cutline$$i,$$existing_cutlines" existing_cutlines="cutline$$i,$$existing_cutlines"
@ -25,13 +51,8 @@ for orthophoto_file in "$${ORTHOPHOTO_FILES[@]}"; do
i=$$[i+1] i=$$[i+1]
done done
last_cutline="cutline$$[i-1]" if [ -e "cutline0.gpkg" ]; then
echo "$$(pwd)/cutline0.gpkg"
# Export
v.out.ogr input="$$last_cutline" output="cutline.gpkg" format=GPKG
if [ -e "cutline.gpkg" ]; then
echo "$$(pwd)/cutline.gpkg"
else else
echo "error" echo "error"
fi fi

Wyświetl plik

@ -2,6 +2,8 @@ import shutil
import tempfile import tempfile
import subprocess import subprocess
import os import os
import sys
import time
from opendm import log from opendm import log
from opendm import system from opendm import system
@ -88,20 +90,29 @@ class GrassContext:
f.write(tmpl.substitute(self.template_args)) f.write(tmpl.substitute(self.template_args))
# Execute it # Execute it
log.ODM_INFO("Executing grass script from {}: {} -c {} location --exec sh script.sh".format(self.get_cwd(), self.grass_binary, self.location)) log.ODM_INFO("Executing grass script from {}: {} --tmp-location {} --exec bash script.sh".format(self.get_cwd(), self.grass_binary, self.location))
env = os.environ.copy() env = os.environ.copy()
env["GRASS_ADDON_PATH"] = env.get("GRASS_ADDON_PATH", "") + ":" + os.path.abspath(os.path.join("scripts/grass_addons")) env["GRASS_ADDON_PATH"] = env.get("GRASS_ADDON_PATH", "") + os.path.abspath(os.path.join("scripts/grass_addons"))
p = subprocess.Popen([self.grass_binary, '-c', self.location, 'location', '--exec', 'sh', 'script.sh'],
cwd=self.get_cwd(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) filename = os.path.join(self.get_cwd(), 'output.log')
out, err = p.communicate() with open(filename, 'wb') as writer, open(filename, 'rb', 1) as reader:
p = subprocess.Popen([self.grass_binary, '--tmp-location', self.location, '--exec', 'bash', 'script.sh'],
cwd=self.get_cwd(), stdout=subprocess.PIPE, stderr=writer, env=env)
while p.poll() is None:
sys.stdout.write(reader.read())
time.sleep(0.5)
# Read the remaining
sys.stdout.write(reader.read())
out = out.decode('utf-8').strip() out, err = p.communicate()
err = err.decode('utf-8').strip() out = out.decode('utf-8').strip()
if p.returncode == 0: if p.returncode == 0:
return out return out
else: else:
raise GrassEngineException("Could not execute GRASS script {} from {}: {}".format(script, self.get_cwd(), err)) raise GrassEngineException("Could not execute GRASS script {} from {}: {}".format(script, self.get_cwd(), err))
def serialize(self): def serialize(self):
return { return {

2
run.py
Wyświetl plik

@ -43,7 +43,7 @@ if __name__ == '__main__':
app.execute() app.execute()
# Do not show ASCII art for local submodels runs # Do not show ASCII art for local submodels runs
if not "submodels/submodel_" in args.project_path: if False and not "submodels/submodel_" in args.project_path:
log.ODM_INFO('MMMMMMMMMMMNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNMMMMMMMMMMM') log.ODM_INFO('MMMMMMMMMMMNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNMMMMMMMMMMM')
log.ODM_INFO('MMMMMMdo:..---../sNMMMMMMMMMMMMMMMMMMMMMMMMMMNs/..---..:odMMMMMM') log.ODM_INFO('MMMMMMdo:..---../sNMMMMMMMMMMMMMMMMMMMMMMMMMMNs/..---..:odMMMMMM')
log.ODM_INFO('MMMMy-.odNMMMMMNy/`/mMMMMMMMMMMMMMMMMMMMMMMm/`/hNMMMMMNdo.-yMMMM') log.ODM_INFO('MMMMy-.odNMMMMMNy/`/mMMMMMMMMMMMMMMMMMMMMMMm/`/hNMMMMMNdo.-yMMMM')

Wyświetl plik

Wyświetl plik

@ -136,13 +136,17 @@ class ODMMergeStage(types.ODM_Stage):
if len(all_orthophotos) > 1: if len(all_orthophotos) > 1:
gctx = grass.create_context({'auto_cleanup' : False}) gctx = grass.create_context({'auto_cleanup' : False})
gctx.add_param('orthophoto_files', ",".join(map(quote, all_orthophotos))) gctx.add_param('orthophoto_files', ",".join(all_orthophotos))
gctx.add_param('max_concurrency', args.max_concurrency) gctx.add_param('max_concurrency', args.max_concurrency)
gctx.add_param('memory', concurrency.get_max_memory_mb(300)) gctx.add_param('memory', int(concurrency.get_max_memory_mb(300)))
gctx.set_location(all_orthophotos[0]) gctx.set_location(all_orthophotos[0])
cutline_file = gctx.execute(os.path.join("opendm", "grass", "generate_cutlines.grass")) cutline_file = gctx.execute(os.path.join("opendm", "grass", "generate_cutlines.grass"))
if cutline_file != 'error':
log.ODM_INFO("YAY")
log.ODM_INFO(cutline_file)
else:
log.ODM_WARNING("Could not generate orthophoto cutlines. An error occured when running GRASS. No orthophoto will be generated.")
elif len(all_orthophotos) == 1: elif len(all_orthophotos) == 1:
# Simply copy # Simply copy
log.ODM_WARNING("A single orthophoto was found between all submodels.") log.ODM_WARNING("A single orthophoto was found between all submodels.")