diff --git a/README.md b/README.md
index a9046f55..0faf35c5 100644
--- a/README.md
+++ b/README.md
@@ -121,6 +121,8 @@ That's it! The certificate will automatically renew when needed.
If you want to specify your own key/certificate pair, simply pass the `--ssl-key` and `--ssl-cert` option to `./webodm.sh`. See `./webodm.sh --help` for more information.
+Note! You cannot pass an IP address to the hostname parameter! You need a DNS record setup.
+
### Where Are My Files Stored?
When using Docker, all processing results are stored in a docker volume and are not available on the host filesystem. If you want to store your files on the host filesystem instead of a docker volume, you need to pass a path via the `--media-dir` option:
diff --git a/app/api/thumbs.py b/app/api/thumbs.py
new file mode 100644
index 00000000..ca945eac
--- /dev/null
+++ b/app/api/thumbs.py
@@ -0,0 +1,36 @@
+import os
+
+from .tasks import TaskNestedView
+from app.security import path_traversal_check
+from django.core.exceptions import SuspiciousFileOperation
+from rest_framework import exceptions
+
+class Thumbnail(TaskNestedView):
+ def get(self, request, pk=None, project_pk=None, image_filename=""):
+ """
+ Generate a thumbnail on the fly for a particular task's image
+ """
+ task = self.get_and_check_task(request, pk)
+
+ image_path = task.task_path(image_filename)
+
+ try:
+ path_traversal_check(image_path, task.task_path(""))
+ except SuspiciousFileOperation:
+ raise exceptions.NotFound()
+
+ if not os.path.isfile(image_path):
+ raise exceptions.NotFound()
+
+ # TODO
+
+ return Response({
+ 'tilejson': '2.1.0',
+ 'name': task.name,
+ 'version': '1.0.0',
+ 'scheme': 'xyz',
+ 'tiles': [get_tile_url(task, tile_type, self.request.query_params)],
+ 'minzoom': minzoom - ZOOM_EXTRA_LEVELS,
+ 'maxzoom': maxzoom + ZOOM_EXTRA_LEVELS,
+ 'bounds': get_extent(task, tile_type).extent
+ })
\ No newline at end of file
diff --git a/app/models/task.py b/app/models/task.py
index 8c5b4175..52658c63 100644
--- a/app/models/task.py
+++ b/app/models/task.py
@@ -192,6 +192,7 @@ class Task(models.Model):
'deferred_compress_dir': 'orthophoto_tiles'
},
'cameras.json': 'cameras.json',
+ 'shots.geojson': os.path.join('odm_report', 'shots.geojson'),
}
STATUS_CODES = (
diff --git a/app/static/app/js/classes/AssetDownloads.js b/app/static/app/js/classes/AssetDownloads.js
index 2c5f207e..4311c0e5 100644
--- a/app/static/app/js/classes/AssetDownloads.js
+++ b/app/static/app/js/classes/AssetDownloads.js
@@ -44,7 +44,9 @@ const api = {
new AssetDownload("Point Cloud (PLY)","georeferenced_model.ply","fa fa-cube"),
new AssetDownload("Point Cloud (CSV)","georeferenced_model.csv","fa fa-cube"),
new AssetDownload("Textured Model","textured_model.zip","fab fa-connectdevelop"),
- new AssetDownload("Camera Parameters","cameras.json","fa fa-camera-retro"),
+ new AssetDownload("Camera Parameters","cameras.json","fa fa-camera"),
+ new AssetDownload("Camera Shots (GeoJSON)","shots.geojson","fa fa-camera"),
+
new AssetDownloadSeparator(),
new AssetDownload("All Assets","all.zip","far fa-file-archive")
];
diff --git a/app/static/app/js/classes/TempLayer.js b/app/static/app/js/classes/TempLayer.js
index 1b2ff8bc..808d63f7 100644
--- a/app/static/app/js/classes/TempLayer.js
+++ b/app/static/app/js/classes/TempLayer.js
@@ -71,7 +71,7 @@ export function addTempLayer(file, cb) {
if (feature.properties) {
if (feature.properties) {
layer.bindPopup(Object.keys(feature.properties).map(function (k) {
- return k + ": " + feature.properties[k];
+ return "" + k + ": " + feature.properties[k];
}).join("
"), {
maxHeight: 200
});
diff --git a/app/static/app/js/components/EditPresetDialog.jsx b/app/static/app/js/components/EditPresetDialog.jsx
index 19687bc8..40a9dc24 100644
--- a/app/static/app/js/components/EditPresetDialog.jsx
+++ b/app/static/app/js/components/EditPresetDialog.jsx
@@ -92,7 +92,7 @@ class EditPresetDialog extends React.Component {
show={true}
onShow={this.onShow}
saveIcon="far fa-edit"
- title="Edit Options"
+ title="Edit Task Options"
saveAction={this.props.saveAction}
deleteWarning={false}
deleteAction={(this.props.preset.id !== -1 && !this.props.preset.system) ? this.props.deleteAction : undefined}>
@@ -105,7 +105,7 @@ class EditPresetDialog extends React.Component {
: ""}