kopia lustrzana https://github.com/OpenDroneMap/WebODM
Add point cloud resampling export
rodzic
320bbafb0b
commit
46bdb25824
|
@ -524,6 +524,7 @@ class Export(TaskNestedView):
|
|||
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
|
||||
|
@ -531,6 +532,7 @@ class Export(TaskNestedView):
|
|||
if epsg == '': epsg = None
|
||||
if color_map == '': color_map = None
|
||||
if hillshade == '': hillshade = None
|
||||
if resample == '': resample = None
|
||||
|
||||
expr = None
|
||||
|
||||
|
@ -552,6 +554,12 @@ class Export(TaskNestedView):
|
|||
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)
|
||||
|
@ -627,9 +635,10 @@ class Export(TaskNestedView):
|
|||
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})
|
||||
|
|
|
@ -10,19 +10,24 @@ logger = logging.getLogger('app.logger')
|
|||
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):
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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 = {};
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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>
|
||||
|
|
|
@ -82,7 +82,8 @@ class TestApiTask(BootTransactionTestCase):
|
|||
('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
|
||||
|
|
Ładowanie…
Reference in New Issue