From 6a2da220cd8ce5ae2a9ae322a2b2b144dd4d93d7 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Thu, 29 Jul 2021 12:03:54 -0400 Subject: [PATCH 1/3] Add additional statistics in dashboard --- app/api/tasks.py | 4 +++ app/models/task.py | 29 +++++++++++++++++++ app/static/app/js/components/TaskListItem.jsx | 16 +++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/app/api/tasks.py b/app/api/tasks.py index cc2d6ec1..fd253909 100644 --- a/app/api/tasks.py +++ b/app/api/tasks.py @@ -40,6 +40,7 @@ class TaskSerializer(serializers.ModelSerializer): processing_node = serializers.PrimaryKeyRelatedField(queryset=ProcessingNode.objects.all()) processing_node_name = serializers.SerializerMethodField() can_rerun_from = serializers.SerializerMethodField() + statistics = serializers.SerializerMethodField() def get_processing_node_name(self, obj): if obj.processing_node is not None: @@ -47,6 +48,9 @@ class TaskSerializer(serializers.ModelSerializer): else: return None + def get_statistics(self, obj): + return obj.get_statistics() + def get_can_rerun_from(self, obj): """ When a task has been associated with a processing node diff --git a/app/models/task.py b/app/models/task.py index 0a75fb60..cf8d1d95 100644 --- a/app/models/task.py +++ b/app/models/task.py @@ -347,6 +347,35 @@ class Task(models.Model): return False + def get_statistics(self): + """ + Parse ODM's stats.json if available + """ + stats_json = self.assets_path("odm_report", "stats.json") + if os.path.exists(stats_json): + try: + with open(stats_json) as f: + j = json.loads(f.read()) + except Exception as e: + logger.warning("Malformed JSON {}: {}".format(stats_json, str(e))) + return {} + + points = None + if j.get('point_cloud_statistics', {}).get('dense', False): + points = j.get('point_cloud_statistics', {}).get('stats', {}).get('statistic', [{}])[0].get('count') + else: + points = j.get('reconstruction_statistics', {}).get('reconstructed_points_count') + + return { + 'pointcloud':{ + 'points': points, + }, + 'gsd': j.get('odm_processing_statistics', {}).get('average_gsd'), + 'area': j.get('processing_statistics', {}).get('area') + } + else: + return {} + def get_asset_download_path(self, asset): """ Get the path to an asset download diff --git a/app/static/app/js/components/TaskListItem.jsx b/app/static/app/js/components/TaskListItem.jsx index c1083eff..e8d7b8c1 100644 --- a/app/static/app/js/components/TaskListItem.jsx +++ b/app/static/app/js/components/TaskListItem.jsx @@ -484,6 +484,8 @@ class TaskListItem extends React.Component { ); })} ); + + const stats = task.statistics; expanded = (
@@ -512,7 +514,19 @@ class TaskListItem extends React.Component { {_("Options:")} {this.optionsToList(task.options)}
: ""} - {/* TODO: List of images? */} + + {stats && stats.gsd ? +
+ {_("Average GSD:")} {stats.gsd.toFixed(2)} cm
+
: ""} + {stats && stats.area ? +
+ {_("Area:")} {stats.area.toFixed(2)} m²
+
: ""} + {stats && stats.pointcloud && stats.pointcloud.points ? +
+ {_("Reconstructed Points:")} {stats.pointcloud.points}
+
: ""} {this.state.view === 'console' ? From 39a624b72300833ede2fae39a0510f2877b135ea Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Thu, 29 Jul 2021 12:07:21 -0400 Subject: [PATCH 2/3] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index db6aca24..c16685b9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "WebODM", - "version": "1.9.3", + "version": "1.9.4", "description": "User-friendly, extendable application and API for processing aerial imagery.", "main": "index.js", "scripts": { From d8824f4481c239f3e6bd963fb60d94099f4f54f6 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Thu, 29 Jul 2021 12:16:46 -0400 Subject: [PATCH 3/3] Point count with commas --- app/static/app/js/components/TaskListItem.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/static/app/js/components/TaskListItem.jsx b/app/static/app/js/components/TaskListItem.jsx index e8d7b8c1..145d7537 100644 --- a/app/static/app/js/components/TaskListItem.jsx +++ b/app/static/app/js/components/TaskListItem.jsx @@ -525,7 +525,7 @@ class TaskListItem extends React.Component { : ""} {stats && stats.pointcloud && stats.pointcloud.points ?
- {_("Reconstructed Points:")} {stats.pointcloud.points}
+ {_("Reconstructed Points:")} {stats.pointcloud.points.toLocaleString()}
: ""}