Updated API to 1.02, removed uncommon asset download URLs, speeded up archiving code, added test mode for skipping orthophoto generation, updated docs, skip tiling process when orthophoto is missing

pull/1/head
Piero Toffanin 2017-03-14 11:52:50 -04:00
rodzic b74fdc2e6f
commit 6ddbe1feba
9 zmienionych plików z 56 dodań i 50 usunięć

Wyświetl plik

@ -13,5 +13,6 @@
"deamon": false, "deamon": false,
"parallelQueueProcessing": 2, "parallelQueueProcessing": 2,
"cleanupTasksAfter": 3, "cleanupTasksAfter": 3,
"test": false "test": false,
"testSkipOrthophotos": false
} }

Wyświetl plik

@ -34,6 +34,7 @@ Options:
--parallel_queue_processing <number> Number of simultaneous processing tasks (default: 2) --parallel_queue_processing <number> Number of simultaneous processing tasks (default: 2)
--cleanup_tasks_after <number> Number of days that elapse before deleting finished and canceled tasks (default: 3) --cleanup_tasks_after <number> Number of days that elapse before deleting finished and canceled tasks (default: 3)
--test Enable test mode. In test mode, no commands are sent to OpenDroneMap. This can be useful during development or testing (default: false) --test Enable test mode. In test mode, no commands are sent to OpenDroneMap. This can be useful during development or testing (default: false)
--test_skip_orthophotos If test mode is enabled, skip orthophoto results when generating assets. (default: false)
Log Levels: Log Levels:
error | debug | info | verbose | debug | silly error | debug | info | verbose | debug | silly
`); `);
@ -78,5 +79,6 @@ config.deamon = argv.deamonize || argv.d || fromConfigFile("daemon", false);
config.parallelQueueProcessing = argv.parallel_queue_processing || fromConfigFile("parallelQueueProcessing", 2); config.parallelQueueProcessing = argv.parallel_queue_processing || fromConfigFile("parallelQueueProcessing", 2);
config.cleanupTasksAfter = argv.cleanup_tasks_after || fromConfigFile("cleanupTasksAfter", 3); config.cleanupTasksAfter = argv.cleanup_tasks_after || fromConfigFile("cleanupTasksAfter", 3);
config.test = argv.test || fromConfigFile("test", false); config.test = argv.test || fromConfigFile("test", false);
config.testSkipOrthophotos = argv.test_skip_orthophotos || fromConfigFile("testSkipOrthophotos", false);
module.exports = config; module.exports = config;

Wyświetl plik

@ -0,0 +1,2 @@
node generateSwaggerAPI.js
java -jar swagger2markup-cli-1.0.1.jar convert -i swagger.json -f index

Wyświetl plik

@ -8,7 +8,7 @@ REST API to access OpenDroneMap
=== Version information === Version information
[%hardbreaks] [%hardbreaks]
_Version_ : 1.0.1 _Version_ : 1.0.2
=== Contact information === Contact information
@ -257,7 +257,7 @@ Retrieves an asset (the output of OpenDroneMap's processing) associated with a t
|=== |===
|Type|Name|Description|Schema|Default |Type|Name|Description|Schema|Default
|*Path*|*asset* + |*Path*|*asset* +
_required_|Type of asset to download. Use "all.zip" for zip file containing all assets.|enum (all.zip, georeferenced_model.ply.zip, georeferenced_model.las.zip, georeferenced_model.csv.zip, orthophoto.png, orthophoto.tif, textured_model.zip, orthophoto_tiles.zip)| _required_|Type of asset to download. Use "all.zip" for zip file containing all assets.|enum (all.zip, orthophoto.tif)|
|*Path*|*uuid* + |*Path*|*uuid* +
_required_|UUID of the task|string| _required_|UUID of the task|string|
|=== |===

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -295,13 +295,7 @@ app.get('/task/:uuid/output', getTaskFromUuid, (req, res) => {
* required: true * required: true
* enum: * enum:
* - all.zip * - all.zip
* - georeferenced_model.ply.zip
* - georeferenced_model.las.zip
* - georeferenced_model.csv.zip
* - orthophoto.png
* - orthophoto.tif * - orthophoto.tif
* - textured_model.zip
* - orthophoto_tiles.zip
* responses: * responses:
* 200: * 200:
* description: Asset File * description: Asset File

Wyświetl plik

@ -121,25 +121,17 @@ module.exports = class Task{
// Get the path of the archive where all assets // Get the path of the archive where all assets
// outputted by this task are stored. // outputted by this task are stored.
getAssetsArchivePath(filename){ getAssetsArchivePath(filename){
switch(filename){ if (filename == 'all.zip'){
case "all.zip": // OK, do nothing
case "georeferenced_model.ply.zip": }else if (filename == 'orthophoto.tif'){
case "georeferenced_model.las.zip": if (config.test){
case "georeferenced_model.csv.zip": if (config.testSkipOrthophotos) return false;
case "textured_model.zip": else filename = path.join('..', '..', 'processing_results', 'odm_orthophoto', `odm_${filename}`);
case "orthophoto_tiles.zip": }else{
// OK filename = path.join('odm_orthophoto', `odm_${filename}`);
break; }
case "orthophoto.png": }else{
case "orthophoto.tif": return false; // Invalid
// Append missing pieces to the path
filename = !config.test ?
path.join('odm_orthophoto', `odm_${filename}`) :
path.join('..', '..', 'processing_results', 'odm_orthophoto', `odm_${filename}`);
break;
default:
// Invalid
return false;
} }
return path.join(this.getProjectFolderPath(), filename); return path.join(this.getProjectFolderPath(), filename);
@ -306,11 +298,20 @@ module.exports = class Task{
const generateTiles = (inputFile, outputDir) => { const generateTiles = (inputFile, outputDir) => {
return (done) => { return (done) => {
const inputFilePath = path.join(this.getProjectFolderPath(), inputFile);
// Not all datasets generate an orthophoto, so we skip
// tiling if the orthophoto is missing
if (fs.existsSync(inputFilePath)){
this.runningProcesses.push(processRunner.runTiler({ this.runningProcesses.push(processRunner.runTiler({
zoomLevels: "12-21", zoomLevels: "12-21",
inputFile: path.join(this.getProjectFolderPath(), inputFile), inputFile: inputFilePath,
outputDir: path.join(this.getProjectFolderPath(), outputDir) outputDir: path.join(this.getProjectFolderPath(), outputDir)
}, handleProcessExit(done), handleOutput)); }, handleProcessExit(done), handleOutput));
}else{
handleOutput(`${inputFilePath} file not found, skipping tiles generation\n`);
done();
}
}; };
}; };
@ -324,19 +325,21 @@ module.exports = class Task{
}; };
// All paths are relative to the project directory (./data/<uuid>/) // All paths are relative to the project directory (./data/<uuid>/)
let allFolders = ['odm_orthophoto', 'odm_georeferencing', 'odm_texturing', 'odm_meshing', 'orthophoto_tiles', 'potree_pointcloud'];
if (config.test && config.testSkipOrthophotos){
logger.info("Test mode will skip orthophoto generation");
// Exclude these folders from the all.zip archive
['odm_orthophoto', 'orthophoto_tiles'].forEach(dir => {
allFolders.splice(allFolders.indexOf(dir), 1);
});
}
async.series([ async.series([
generateTiles(path.join('odm_orthophoto', 'odm_orthophoto.tif'), 'orthophoto_tiles'), generateTiles(path.join('odm_orthophoto', 'odm_orthophoto.tif'), 'orthophoto_tiles'),
generatePotreeCloud(path.join('odm_georeferencing', 'odm_georeferenced_model.ply.las'), 'potree_pointcloud'), generatePotreeCloud(path.join('odm_georeferencing', 'odm_georeferenced_model.ply.las'), 'potree_pointcloud'),
createZipArchive('all.zip', ['odm_orthophoto', 'odm_georeferencing', 'odm_texturing', 'odm_meshing', 'orthophoto_tiles', 'potree_pointcloud']), createZipArchive('all.zip', allFolders)
createZipArchive('georeferenced_model.ply.zip', [path.join('odm_georeferencing', 'odm_georeferenced_model.ply')]),
createZipArchive('georeferenced_model.las.zip', [path.join('odm_georeferencing', 'odm_georeferenced_model.ply.las')]),
createZipArchive('georeferenced_model.csv.zip', [path.join('odm_georeferencing', 'odm_georeferenced_model.csv')]),
createZipArchive('textured_model.zip', [
path.join('odm_texturing', '*.jpg'),
path.join('odm_texturing', 'odm_textured_model_geo.obj'),
path.join('odm_texturing', 'odm_textured_model_geo.mtl')
]),
createZipArchive('orthophoto_tiles.zip', ['orthophoto_tiles'])
], (err) => { ], (err) => {
if (!err){ if (!err){
this.setStatus(statusCodes.COMPLETED); this.setStatus(statusCodes.COMPLETED);
@ -361,7 +364,7 @@ module.exports = class Task{
runnerOptions["pmvs-num-cores"] = os.cpus().length; runnerOptions["pmvs-num-cores"] = os.cpus().length;
if (this.gpcFiles.length > 0){ if (this.gpcFiles.length > 0){
runnerOptions["gcp"] = fs.realpathSync(path.join(this.getGpcFolderPath(), this.gpcFiles[0])); runnerOptions.gcp = fs.realpathSync(path.join(this.getGpcFolderPath(), this.gpcFiles[0]));
} }
this.runningProcesses.push(odmRunner.run(runnerOptions, (err, code, signal) => { this.runningProcesses.push(odmRunner.run(runnerOptions, (err, code, signal) => {

Wyświetl plik

@ -41,7 +41,8 @@ module.exports = {
// (num cores can be set programmatically, so can gcpFile, etc.) // (num cores can be set programmatically, so can gcpFile, etc.)
if (["-h", "--project-path", "--cmvs-maxImages", "--time", if (["-h", "--project-path", "--cmvs-maxImages", "--time",
"--zip-results", "--pmvs-num-cores", "--zip-results", "--pmvs-num-cores",
"--start-with", "--gcp", "--end-with"].indexOf(option) !== -1) continue; "--start-with", "--gcp", "--end-with", "--images",
"--slam-config", "--video"].indexOf(option) !== -1) continue;
let values = json[option]; let values = json[option];
@ -129,6 +130,9 @@ module.exports = {
}, },
'string': function(value){ 'string': function(value){
return value; // No conversion needed return value; // No conversion needed
},
'path': function(value){
return value; // No conversion needed
} }
}; };
@ -178,9 +182,9 @@ module.exports = {
} }
}, },
{ {
regex: /^string$/, regex: /^(string|path)$/,
validate: function(){ validate: function(){
return true; // All strings are fine return true; // All strings/paths are fine
} }
} }
]; ];

Wyświetl plik

@ -1,6 +1,6 @@
{ {
"name": "node-opendronemap", "name": "node-opendronemap",
"version": "1.0.1", "version": "1.0.2",
"description": "REST API to access OpenDroneMap", "description": "REST API to access OpenDroneMap",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {