Skip to content

Commit

Permalink
Add point cloud resampling export
Browse files Browse the repository at this point in the history
  • Loading branch information
pierotofy committed Jan 24, 2025
1 parent 320bbaf commit 46bdb25
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 8 deletions.
13 changes: 11 additions & 2 deletions app/api/tiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,13 +524,15 @@ def post(self, request, pk=None, project_pk=None, asset_type=None):
epsg = request.data.get('epsg')
color_map = request.data.get('color_map')
hillshade = request.data.get('hillshade')
resample = request.data.get('resample')

if formula == '': formula = None
if bands == '': bands = None
if rescale == '': rescale = None
if epsg == '': epsg = None
if color_map == '': color_map = None
if hillshade == '': hillshade = None
if resample == '': resample = None

expr = None

Expand All @@ -552,6 +554,12 @@ def post(self, request, pk=None, project_pk=None, asset_type=None):
except InvalidColorMapName:
raise exceptions.ValidationError(_("Not a valid color_map value"))

if resample is not None:
try:
resample = float(resample)
except ValueError:
raise exceptions.ValidationError(_("Invalid resample value: %(value)s") % {'value': resample})

if epsg is not None:
try:
epsg = int(epsg)
Expand Down Expand Up @@ -627,9 +635,10 @@ def post(self, request, pk=None, project_pk=None, asset_type=None):
return Response({'celery_task_id': celery_task_id, 'filename': filename})
elif asset_type == 'georeferenced_model':
# Shortcut the process if no processing is required
if export_format == 'laz' and (epsg == task.epsg or epsg is None):
if export_format == 'laz' and (epsg == task.epsg or epsg is None) and (resample is None or resample == 0):
return Response({'url': '/api/projects/{}/tasks/{}/download/{}.laz'.format(task.project.id, task.id, asset_type), 'filename': filename})
else:
celery_task_id = export_pointcloud.delay(url, epsg=epsg,
format=export_format).task_id
format=export_format,
resample=resample).task_id
return Response({'celery_task_id': celery_task_id, 'filename': filename})
9 changes: 7 additions & 2 deletions app/pointcloud_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,24 @@
def export_pointcloud(input, output, **opts):
epsg = opts.get('epsg')
export_format = opts.get('format')
resample = float(opts.get('resample', 0))

resample_args = []
reprojection_args = []
extra_args = []

if epsg:
reprojection_args = ["reprojection",
"--filters.reprojection.out_srs=%s" % double_quote("EPSG:" + str(epsg))]

if export_format == "ply":
extra_args = ['--writers.ply.sized_types', 'false',
'--writers.ply.storage_mode', 'little endian']

subprocess.check_output(["pdal", "translate", input, output] + reprojection_args + extra_args)
if resample > 0:
resample_args = ['sample', '--filters.sample.radius=%s' % resample]

subprocess.check_output(["pdal", "translate", input, output] + resample_args + reprojection_args + extra_args)


def is_pointcloud_georeferenced(laz_path):
Expand Down
24 changes: 21 additions & 3 deletions app/static/app/js/components/ExportAssetPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export default class ExportAssetPanel extends React.Component {
format: props.exportFormats[0],
epsg: this.props.task.epsg || null,
customEpsg: Storage.getItem("last_export_custom_epsg") || "4326",
resample: 0,
exporting: false
}
}
Expand All @@ -97,6 +98,10 @@ export default class ExportAssetPanel extends React.Component {
this.setState({customEpsg: e.target.value});
}

handleChangeResample = e => {
this.setState({resample: parseFloat(e.target.value) || 0});
}

getExportParams = (format) => {
let params = {};

Expand All @@ -111,9 +116,15 @@ export default class ExportAssetPanel extends React.Component {
const epsg = this.getEpsg();
if (epsg) params.epsg = this.getEpsg();

if (this.state.resample > 0) params.resample = this.state.resample;

return params;
}

isPointCloud = () => {
return this.props.asset == "georeferenced_model";
}

handleExport = (format) => {
if (!format) format = this.state.format;

Expand Down Expand Up @@ -171,7 +182,7 @@ export default class ExportAssetPanel extends React.Component {
}

render(){
const {epsg, customEpsg, exporting, format } = this.state;
const {epsg, customEpsg, exporting, format, resample } = this.state;
const { exportFormats } = this.props;
const utmEPSG = this.props.task.epsg;

Expand Down Expand Up @@ -200,14 +211,21 @@ export default class ExportAssetPanel extends React.Component {

let exportSelector = null;
if (this.props.selectorOnly){
exportSelector = (<div className="row form-group form-inline">
exportSelector = [<div key={1} className="row form-group form-inline">
<label className="col-sm-3 control-label">{_("Format:")}</label>
<div className="col-sm-9 ">
<select className="form-control" value={format} onChange={this.handleSelectFormat}>
{exportFormats.map(ef => <option key={ef} value={ef}>{this.efInfo[ef].label}</option>)}
</select>
</div>
</div>);
</div>,
this.isPointCloud() ? <div key={2} className="row form-group form-inline">
<label className="col-sm-3 control-label">{_("Resample (meters):")}</label>
<div className="col-sm-9 ">
<input type="number" min="0" className="form-control custom-interval" value={resample} onChange={this.handleChangeResample} />
</div>
</div>
: ""];
}else{
exportSelector = (<div className="row form-group form-inline">
<label className="col-sm-3 control-label">{_("Export:")}</label>
Expand Down
3 changes: 2 additions & 1 deletion app/tests/test_api_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ def test_exports(self):
('orthophoto', {'formula': 'NDVI', 'bands': 'RGN'}, status.HTTP_200_OK),
('dsm', {'epsg': 4326}, status.HTTP_200_OK),
('dtm', {'epsg': 4326}, status.HTTP_200_OK),
('georeferenced_model', {'epsg': 4326}, status.HTTP_200_OK)
('georeferenced_model', {'epsg': 4326}, status.HTTP_200_OK),
('georeferenced_model', {'epsg': 4326, 'resample': 2.5}, status.HTTP_200_OK)
]

# Cannot export stuff
Expand Down

0 comments on commit 46bdb25

Please sign in to comment.