geovisio 2.9.0__py3-none-any.whl → 2.10.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- geovisio/__init__.py +6 -1
- geovisio/config_app.py +5 -5
- geovisio/translations/ar/LC_MESSAGES/messages.mo +0 -0
- geovisio/translations/ar/LC_MESSAGES/messages.po +818 -0
- geovisio/translations/br/LC_MESSAGES/messages.po +1 -1
- geovisio/translations/da/LC_MESSAGES/messages.mo +0 -0
- geovisio/translations/da/LC_MESSAGES/messages.po +4 -3
- geovisio/translations/de/LC_MESSAGES/messages.mo +0 -0
- geovisio/translations/de/LC_MESSAGES/messages.po +55 -2
- geovisio/translations/el/LC_MESSAGES/messages.po +1 -1
- geovisio/translations/en/LC_MESSAGES/messages.mo +0 -0
- geovisio/translations/en/LC_MESSAGES/messages.po +193 -139
- geovisio/translations/eo/LC_MESSAGES/messages.mo +0 -0
- geovisio/translations/eo/LC_MESSAGES/messages.po +53 -4
- geovisio/translations/es/LC_MESSAGES/messages.po +1 -1
- geovisio/translations/fi/LC_MESSAGES/messages.po +1 -1
- geovisio/translations/fr/LC_MESSAGES/messages.mo +0 -0
- geovisio/translations/fr/LC_MESSAGES/messages.po +91 -3
- geovisio/translations/hu/LC_MESSAGES/messages.po +1 -1
- geovisio/translations/it/LC_MESSAGES/messages.mo +0 -0
- geovisio/translations/it/LC_MESSAGES/messages.po +63 -3
- geovisio/translations/ja/LC_MESSAGES/messages.po +1 -1
- geovisio/translations/ko/LC_MESSAGES/messages.po +1 -1
- geovisio/translations/messages.pot +185 -129
- geovisio/translations/nl/LC_MESSAGES/messages.mo +0 -0
- geovisio/translations/nl/LC_MESSAGES/messages.po +292 -63
- geovisio/translations/oc/LC_MESSAGES/messages.mo +0 -0
- geovisio/translations/oc/LC_MESSAGES/messages.po +818 -0
- geovisio/translations/pl/LC_MESSAGES/messages.po +1 -1
- geovisio/translations/sv/LC_MESSAGES/messages.mo +0 -0
- geovisio/translations/sv/LC_MESSAGES/messages.po +4 -3
- geovisio/translations/ti/LC_MESSAGES/messages.mo +0 -0
- geovisio/translations/ti/LC_MESSAGES/messages.po +762 -0
- geovisio/translations/zh_Hant/LC_MESSAGES/messages.po +1 -1
- geovisio/utils/annotations.py +14 -17
- geovisio/utils/auth.py +14 -13
- geovisio/utils/cql2.py +2 -2
- geovisio/utils/fields.py +14 -2
- geovisio/utils/items.py +44 -0
- geovisio/utils/model_query.py +2 -2
- geovisio/utils/pic_shape.py +1 -1
- geovisio/utils/pictures.py +111 -18
- geovisio/utils/semantics.py +32 -3
- geovisio/utils/sentry.py +1 -1
- geovisio/utils/sequences.py +51 -34
- geovisio/utils/upload_set.py +285 -198
- geovisio/utils/website.py +1 -1
- geovisio/web/annotations.py +209 -68
- geovisio/web/auth.py +1 -1
- geovisio/web/collections.py +26 -22
- geovisio/web/configuration.py +24 -4
- geovisio/web/docs.py +93 -11
- geovisio/web/items.py +197 -121
- geovisio/web/params.py +44 -31
- geovisio/web/pictures.py +34 -0
- geovisio/web/tokens.py +49 -1
- geovisio/web/upload_set.py +150 -32
- geovisio/web/users.py +4 -4
- geovisio/web/utils.py +2 -2
- geovisio/workers/runner_pictures.py +128 -23
- {geovisio-2.9.0.dist-info → geovisio-2.10.0.dist-info}/METADATA +13 -13
- geovisio-2.10.0.dist-info/RECORD +105 -0
- geovisio-2.9.0.dist-info/RECORD +0 -98
- {geovisio-2.9.0.dist-info → geovisio-2.10.0.dist-info}/WHEEL +0 -0
- {geovisio-2.9.0.dist-info → geovisio-2.10.0.dist-info}/licenses/LICENSE +0 -0
geovisio/utils/sequences.py
CHANGED
|
@@ -55,7 +55,7 @@ class Collections:
|
|
|
55
55
|
"""
|
|
56
56
|
|
|
57
57
|
collections: List[Dict[Any, Any]] = field(default_factory=lambda: [])
|
|
58
|
-
# Bounds of the field used by the first field of the `ORDER BY` (
|
|
58
|
+
# Bounds of the field used by the first field of the `ORDER BY` (useful especially for pagination)
|
|
59
59
|
query_bounds: Optional[Bounds] = None
|
|
60
60
|
|
|
61
61
|
|
|
@@ -157,23 +157,24 @@ def get_collections(request: CollectionsRequest) -> Collections:
|
|
|
157
157
|
s.min_picture_ts AS mints,
|
|
158
158
|
s.max_picture_ts AS maxts,
|
|
159
159
|
s.nb_pictures AS nbpic,
|
|
160
|
+
s.upload_set_id,
|
|
160
161
|
{status},
|
|
161
162
|
s.computed_capture_date AS datetime,
|
|
162
163
|
s.user_agent,
|
|
163
164
|
ROUND(ST_Length(s.geom::geography)) / 1000 AS length_km,
|
|
164
165
|
s.computed_h_pixel_density,
|
|
165
166
|
s.computed_gps_accuracy,
|
|
166
|
-
|
|
167
|
+
COALESCE(seq_sem.semantics, '[]'::json) AS semantics
|
|
167
168
|
FROM sequences s
|
|
168
169
|
LEFT JOIN accounts on s.account_id = accounts.id
|
|
169
170
|
LEFT JOIN (
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
171
|
+
SELECT sequence_id, json_agg(json_strip_nulls(json_build_object(
|
|
172
|
+
'key', key,
|
|
173
|
+
'value', value
|
|
174
|
+
)) ORDER BY key, value) AS semantics
|
|
175
|
+
FROM sequences_semantics
|
|
176
|
+
GROUP BY sequence_id
|
|
177
|
+
) seq_sem ON seq_sem.sequence_id = s.id
|
|
177
178
|
WHERE {filter}
|
|
178
179
|
ORDER BY {order1}
|
|
179
180
|
LIMIT {limit}
|
|
@@ -427,7 +428,7 @@ def sort_collection(db, collectionId: UUID, sortby: CollectionSort):
|
|
|
427
428
|
"""
|
|
428
429
|
Sort a collection by a given parameter
|
|
429
430
|
|
|
430
|
-
Note: the transaction is not
|
|
431
|
+
Note: the transaction is not committed at the end, you need to commit it or use an autocommit connection
|
|
431
432
|
"""
|
|
432
433
|
|
|
433
434
|
# Remove existing order, and keep list of pictures IDs
|
|
@@ -519,8 +520,8 @@ def update_headings(
|
|
|
519
520
|
db,
|
|
520
521
|
sequenceId: UUID,
|
|
521
522
|
editingAccount: Optional[UUID] = None,
|
|
522
|
-
relativeHeading: int =
|
|
523
|
-
updateOnlyMissing: bool =
|
|
523
|
+
relativeHeading: Optional[int] = None,
|
|
524
|
+
updateOnlyMissing: Optional[bool] = None,
|
|
524
525
|
):
|
|
525
526
|
"""Defines pictures heading according to sequence path.
|
|
526
527
|
Database is not committed in this function, to make entry definitively stored
|
|
@@ -532,27 +533,42 @@ def update_headings(
|
|
|
532
533
|
Database connection
|
|
533
534
|
sequenceId : uuid
|
|
534
535
|
The sequence's uuid, as stored in the database
|
|
535
|
-
relativeHeading : int
|
|
536
|
+
relativeHeading : Optional[int]
|
|
536
537
|
Camera relative orientation compared to path, in degrees clockwise.
|
|
537
538
|
Example: 0° = looking forward, 90° = looking to right, 180° = looking backward, -90° = looking left.
|
|
538
|
-
|
|
539
|
+
If not provided, will first use the relative_heading stored in the sequence's metadata, then the relative_heading of its upload_set (if if none is set, default to 0).
|
|
540
|
+
updateOnlyMissing : Optional[bool]
|
|
539
541
|
If true, doesn't change existing heading values in database
|
|
542
|
+
if not provided, we check if some relative heading has been set (either in the sequence or in its upload_set), and if so, we recompute all
|
|
540
543
|
"""
|
|
541
|
-
|
|
542
544
|
db.execute(
|
|
543
545
|
SQL(
|
|
544
|
-
"""
|
|
545
|
-
|
|
546
|
+
"""WITH
|
|
547
|
+
relative_heading AS (
|
|
548
|
+
SELECT COALESCE(
|
|
549
|
+
%(relativeHeading)s,
|
|
550
|
+
(SELECT (metadata->>'relative_heading')::int FROM sequences WHERE id = %(seq)s),
|
|
551
|
+
(SELECT upload_sets.relative_heading FROM sequences JOIN upload_sets ON sequences.upload_set_id = upload_sets.id WHERE sequences.id = %(seq)s),
|
|
552
|
+
0
|
|
553
|
+
) AS heading,
|
|
554
|
+
COALESCE(
|
|
555
|
+
%(update_only_missing)s,
|
|
556
|
+
(SELECT metadata->'relative_heading' IS NULL FROM sequences WHERE id = %(seq)s and metadata ? 'relative_heading'),
|
|
557
|
+
(SELECT upload_sets.relative_heading IS NULL FROM sequences JOIN upload_sets ON sequences.upload_set_id = upload_sets.id WHERE sequences.id = %(seq)s)
|
|
558
|
+
) AS update_only_missing
|
|
559
|
+
)
|
|
560
|
+
, h AS (
|
|
546
561
|
SELECT
|
|
547
562
|
p.id,
|
|
548
563
|
p.heading AS old_heading,
|
|
549
564
|
CASE
|
|
550
565
|
WHEN LEAD(sp.rank) OVER othpics IS NULL AND LAG(sp.rank) OVER othpics IS NULL
|
|
551
|
-
|
|
566
|
+
-- if there is a single picture, we take the relative heading directly
|
|
567
|
+
THEN (SELECT heading FROM relative_heading)
|
|
552
568
|
WHEN LEAD(sp.rank) OVER othpics IS NULL
|
|
553
|
-
THEN (360 + FLOOR(DEGREES(ST_Azimuth(LAG(p.geom) OVER othpics, p.geom)))::int + (
|
|
569
|
+
THEN (360 + FLOOR(DEGREES(ST_Azimuth(LAG(p.geom) OVER othpics, p.geom)))::int + ((SELECT heading FROM relative_heading) %% 360)) %% 360
|
|
554
570
|
ELSE
|
|
555
|
-
(360 + FLOOR(DEGREES(ST_Azimuth(p.geom, LEAD(p.geom) OVER othpics)))::int + (
|
|
571
|
+
(360 + FLOOR(DEGREES(ST_Azimuth(p.geom, LEAD(p.geom) OVER othpics)))::int + ((SELECT heading FROM relative_heading) %% 360)) %% 360
|
|
556
572
|
END AS heading
|
|
557
573
|
FROM pictures p
|
|
558
574
|
JOIN sequences_pictures sp ON sp.pic_id = p.id AND sp.seq_id = %(seq)s
|
|
@@ -561,13 +577,15 @@ def update_headings(
|
|
|
561
577
|
UPDATE pictures p
|
|
562
578
|
SET heading = h.heading, heading_computed = true {editing_account}
|
|
563
579
|
FROM h
|
|
564
|
-
WHERE h.id = p.id
|
|
580
|
+
WHERE h.id = p.id AND (
|
|
581
|
+
(SELECT NOT update_only_missing FROM relative_heading)
|
|
582
|
+
OR (p.heading IS NULL OR p.heading = 0 OR p.heading_computed) -- # lots of camera have heading set to 0 for unset heading, so we recompute the heading when it's 0 too, even if this could be a valid value
|
|
583
|
+
)
|
|
565
584
|
"""
|
|
566
585
|
).format(
|
|
567
|
-
update_missing=SQL(" AND (p.heading IS NULL OR p.heading = 0 OR p.heading_computed)") if updateOnlyMissing else SQL(""),
|
|
568
586
|
editing_account=SQL(", last_account_to_edit = %(account)s") if editingAccount is not None else SQL(""),
|
|
569
|
-
),
|
|
570
|
-
{"seq": sequenceId, "
|
|
587
|
+
),
|
|
588
|
+
{"seq": sequenceId, "relativeHeading": relativeHeading, "account": editingAccount, "update_only_missing": updateOnlyMissing},
|
|
571
589
|
)
|
|
572
590
|
|
|
573
591
|
|
|
@@ -593,14 +611,13 @@ def finalize(cursor, seqId: UUID, logger: logging.Logger = logging.getLogger()):
|
|
|
593
611
|
span.set_data("sequence_id", seqId)
|
|
594
612
|
logger.debug(f"Finalizing sequence {seqId}")
|
|
595
613
|
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
update_headings(cursor, seqId)
|
|
614
|
+
# Complete missing headings in pictures
|
|
615
|
+
update_headings(cursor, seqId)
|
|
599
616
|
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
617
|
+
# Change sequence database status in DB
|
|
618
|
+
# Also generates data in computed columns
|
|
619
|
+
cursor.execute(
|
|
620
|
+
"""WITH
|
|
604
621
|
aggregated_pictures AS (
|
|
605
622
|
SELECT
|
|
606
623
|
sp.seq_id,
|
|
@@ -629,10 +646,10 @@ computed_gps_accuracy = gpsacc
|
|
|
629
646
|
FROM aggregated_pictures
|
|
630
647
|
WHERE id = %(seq)s
|
|
631
648
|
""",
|
|
632
|
-
|
|
633
|
-
|
|
649
|
+
{"seq": seqId},
|
|
650
|
+
)
|
|
634
651
|
|
|
635
|
-
|
|
652
|
+
logger.info(f"Sequence {seqId} is ready")
|
|
636
653
|
|
|
637
654
|
|
|
638
655
|
def update_pictures_grid() -> Optional[datetime.datetime]:
|