Make contours plugin respect crop

pull/1636/head
Piero Toffanin 2025-03-27 19:09:58 -04:00
rodzic d00e1df5c0
commit d375d50f91
2 zmienionych plików z 25 dodań i 5 usunięć

Wyświetl plik

@ -57,4 +57,3 @@ def geom_transform_wkt_bbox(geom, dataset, bbox_crs="geographic", wkt_crs="raste
return wkt, (minx, miny, maxx, maxy) return wkt, (minx, miny, maxx, maxy)
else: else:
raise ValueError("Cannot transform complex geometries to WKT") raise ValueError("Cannot transform complex geometries to WKT")

Wyświetl plik

@ -9,12 +9,13 @@ from django.utils.translation import gettext_lazy as _
class ContoursException(Exception): class ContoursException(Exception):
pass pass
def calc_contours(dem, epsg, interval, output_format, simplify, zfactor = 1): def calc_contours(dem, epsg, interval, output_format, simplify, zfactor = 1, crop = None):
import os import os
import subprocess import subprocess
import tempfile import tempfile
import shutil import shutil
import glob import glob
import json
from webodm import settings from webodm import settings
ext = "" ext = ""
@ -31,11 +32,31 @@ def calc_contours(dem, epsg, interval, output_format, simplify, zfactor = 1):
tmpdir = os.path.join(settings.MEDIA_TMP, os.path.basename(tempfile.mkdtemp('_contours', dir=settings.MEDIA_TMP))) tmpdir = os.path.join(settings.MEDIA_TMP, os.path.basename(tempfile.mkdtemp('_contours', dir=settings.MEDIA_TMP)))
gdal_contour_bin = shutil.which("gdal_contour") gdal_contour_bin = shutil.which("gdal_contour")
ogr2ogr_bin = shutil.which("ogr2ogr") ogr2ogr_bin = shutil.which("ogr2ogr")
gdalwarp_bin = shutil.which("gdalwarp")
if gdal_contour_bin is None: if gdal_contour_bin is None:
return {'error': 'Cannot find gdal_contour'} return {'error': 'Cannot find gdal_contour'}
if ogr2ogr_bin is None: if ogr2ogr_bin is None:
return {'error': 'Cannot find ogr2ogr'} return {'error': 'Cannot find ogr2ogr'}
if gdalwarp_bin is None and crop is not None:
return {'error': 'Cannot find gdalwarp'}
# Make a VRT with the crop area
if crop is not None:
crop_geojson = os.path.join(tmpdir, "crop.geojson")
dem_vrt = os.path.join(tmpdir, "dem.vrt")
with open(crop_geojson, "w", encoding="utf-8") as f:
f.write(crop)
p = subprocess.Popen([gdalwarp_bin, "-cutline", crop_geojson,
'-crop_to_cutline', '-dstnodata', '-9999', '-of', 'VRT',
dem, dem_vrt], cwd=tmpdir, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
out = out.decode('utf-8').strip()
err = err.decode('utf-8').strip()
if p.returncode != 0:
return {'error': f'Error calling gdalwarp: {str(err)}'}
dem = dem_vrt
contours_file = f"contours.gpkg" contours_file = f"contours.gpkg"
p = subprocess.Popen([gdal_contour_bin, "-q", "-a", "level", "-3d", "-f", "GPKG", "-i", str(interval), dem, contours_file], cwd=tmpdir, stdout=subprocess.PIPE, stderr=subprocess.PIPE) p = subprocess.Popen([gdal_contour_bin, "-q", "-a", "level", "-3d", "-f", "GPKG", "-i", str(interval), dem, contours_file], cwd=tmpdir, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@ -46,7 +67,7 @@ def calc_contours(dem, epsg, interval, output_format, simplify, zfactor = 1):
success = p.returncode == 0 success = p.returncode == 0
if not success: if not success:
return {'error', f'Error calling gdal_contour: {str(err)}'} return {'error': f'Error calling gdal_contour: {str(err)}'}
outfile = os.path.join(tmpdir, f"output.{ext}") outfile = os.path.join(tmpdir, f"output.{ext}")
p = subprocess.Popen([ogr2ogr_bin, outfile, contours_file, "-simplify", str(simplify), "-f", output_format, "-t_srs", f"EPSG:{epsg}", "-nln", "contours", p = subprocess.Popen([ogr2ogr_bin, outfile, contours_file, "-simplify", str(simplify), "-f", output_format, "-t_srs", f"EPSG:{epsg}", "-nln", "contours",
@ -58,7 +79,7 @@ def calc_contours(dem, epsg, interval, output_format, simplify, zfactor = 1):
success = p.returncode == 0 success = p.returncode == 0
if not success: if not success:
return {'error', f'Error calling ogr2ogr: {str(err)}'} return {'error': f'Error calling ogr2ogr: {str(err)}'}
if not os.path.isfile(outfile): if not os.path.isfile(outfile):
return {'error': f'Cannot find output file: {outfile}'} return {'error': f'Cannot find output file: {outfile}'}
@ -104,7 +125,7 @@ class TaskContoursGenerate(TaskView):
simplify = float(request.data.get('simplify', 0.01)) simplify = float(request.data.get('simplify', 0.01))
zfactor = float(request.data.get('zfactor', 1)) zfactor = float(request.data.get('zfactor', 1))
celery_task_id = run_function_async(calc_contours, dem, epsg, interval, format, simplify, zfactor).task_id celery_task_id = run_function_async(calc_contours, dem, epsg, interval, format, simplify, zfactor, task.crop.geojson if task.crop is not None else None).task_id
return Response({'celery_task_id': celery_task_id}, status=status.HTTP_200_OK) return Response({'celery_task_id': celery_task_id}, status=status.HTTP_200_OK)
except ContoursException as e: except ContoursException as e:
return Response({'error': str(e)}, status=status.HTTP_200_OK) return Response({'error': str(e)}, status=status.HTTP_200_OK)