eotdl 2023.10.25.post10__py3-none-any.whl → 2023.11.2.post2__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.
Files changed (45) hide show
  1. eotdl/__init__.py +1 -1
  2. eotdl/cli.py +6 -2
  3. eotdl/commands/auth.py +18 -1
  4. eotdl/commands/datasets.py +61 -11
  5. eotdl/commands/models.py +108 -0
  6. eotdl/curation/__init__.py +1 -4
  7. eotdl/curation/stac/assets.py +2 -1
  8. eotdl/curation/stac/dataframe.py +1 -1
  9. eotdl/curation/stac/extensions/label/image_name_labeler.py +6 -5
  10. eotdl/curation/stac/extensions/ml_dataset.py +15 -25
  11. eotdl/curation/stac/extent.py +1 -1
  12. eotdl/curation/stac/stac.py +1 -1
  13. eotdl/datasets/download.py +5 -4
  14. eotdl/datasets/ingest.py +25 -154
  15. eotdl/datasets/retrieve.py +1 -1
  16. eotdl/files/__init__.py +1 -0
  17. eotdl/files/ingest.py +175 -0
  18. eotdl/models/__init__.py +3 -0
  19. eotdl/models/download.py +119 -0
  20. eotdl/models/ingest.py +47 -0
  21. eotdl/models/metadata.py +16 -0
  22. eotdl/models/retrieve.py +26 -0
  23. eotdl/repos/FilesAPIRepo.py +136 -95
  24. eotdl/repos/ModelsAPIRepo.py +40 -0
  25. eotdl/repos/__init__.py +1 -0
  26. eotdl/shared/__init__.py +1 -0
  27. eotdl/tools/__init__.py +5 -6
  28. eotdl/tools/geo_utils.py +15 -1
  29. eotdl/tools/stac.py +144 -8
  30. eotdl/tools/time_utils.py +19 -6
  31. eotdl/tools/tools.py +2 -3
  32. {eotdl-2023.10.25.post10.dist-info → eotdl-2023.11.2.post2.dist-info}/METADATA +1 -1
  33. {eotdl-2023.10.25.post10.dist-info → eotdl-2023.11.2.post2.dist-info}/RECORD +38 -35
  34. eotdl/curation/folder_formatters/__init__.py +0 -1
  35. eotdl/curation/folder_formatters/base.py +0 -19
  36. eotdl/curation/folder_formatters/sentinel_hub.py +0 -135
  37. eotdl/curation/stac/utils/__init__.py +0 -5
  38. eotdl/curation/stac/utils/geometry.py +0 -22
  39. eotdl/curation/stac/utils/stac.py +0 -143
  40. eotdl/curation/stac/utils/time.py +0 -21
  41. /eotdl/{datasets/utils.py → shared/checksum.py} +0 -0
  42. /eotdl/{curation/stac/utils → tools}/metadata.py +0 -0
  43. /eotdl/{curation/stac/utils → tools}/paths.py +0 -0
  44. {eotdl-2023.10.25.post10.dist-info → eotdl-2023.11.2.post2.dist-info}/WHEEL +0 -0
  45. {eotdl-2023.10.25.post10.dist-info → eotdl-2023.11.2.post2.dist-info}/entry_points.txt +0 -0
@@ -1,4 +1,4 @@
1
- eotdl/__init__.py,sha256=6e-DKTCSoISf891-mhz-wlpn-nHO0QhpC8HBips-tv4,30
1
+ eotdl/__init__.py,sha256=vq3__ImOs-riW0l9qLaTFxxobD0xu7idyuL5K_MsdVA,29
2
2
  eotdl/access/__init__.py,sha256=OFdCDemao6Ez1w18-ydQ8G_CqeQ8h43hFcdsJcq2UKI,208
3
3
  eotdl/access/airbus/__init__.py,sha256=KdVilLghjjs_EEMGlbZntveRR7yA6pg_CdV04ulZWiQ,75
4
4
  eotdl/access/airbus/client.py,sha256=thVIfCscsrOp6l2uizY6Fai4Jk4e_r-2luyr15YAxn0,11017
@@ -16,17 +16,15 @@ eotdl/auth/auth.py,sha256=voxwxTERghLQdqrBSyjZrgvKrcF01aWUTc0-vxLFFgY,1601
16
16
  eotdl/auth/errors.py,sha256=PpnFU2DvnRo8xrM77wgskKi0tfEJ1Rhle4xv2RD1qpk,306
17
17
  eotdl/auth/is_logged.py,sha256=QREuhkoDnarZoUZwCxVCNoESGb_Yukh0lJo1pXvrV9Q,115
18
18
  eotdl/auth/logout.py,sha256=P_Sp6WmVvnG3R9V1L9541KNyHFko9DtQPqAKD2vaguw,161
19
- eotdl/cli.py,sha256=2J4atkixx0YZnCaXnQYkTKdKFqnSSEPyKBfw0g2aQ1E,299
19
+ eotdl/cli.py,sha256=7JnlHLgi08Q8p5jjMT02uHIxNdQI8eWh7zSkZ19VqZc,423
20
20
  eotdl/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
- eotdl/commands/auth.py,sha256=SQJj0HOl0L4lEEXp0bWtKkehow4SF_GKpSuVcz7-Lnk,830
22
- eotdl/commands/datasets.py,sha256=9u742U_PpEzj8Zh1I8ucqrQnS7fu3BtP6y8mBC78Auo,1620
23
- eotdl/curation/__init__.py,sha256=vmRCkxL4gxqwQ4lvHMdxHI27ynCtKZoF7pGqCz17qKg,360
24
- eotdl/curation/folder_formatters/__init__.py,sha256=UY2h2uW5yOlYZh8kcaD01StsOpRtvCNOr-yaThbPLEw,43
25
- eotdl/curation/folder_formatters/base.py,sha256=HrwzctBdvSm-Q2A5nV6I_M5X69LAH1frGJRZbgfEEYA,380
26
- eotdl/curation/folder_formatters/sentinel_hub.py,sha256=nCUtjoqC7hFjAhqHoz0XfeETaB5T_n9rRMcPi3nyHjs,5691
21
+ eotdl/commands/auth.py,sha256=z2cfzSWUw-AFRlkiMtnR7sIqYJMVwG94nW-7W5rmMio,1564
22
+ eotdl/commands/datasets.py,sha256=s05OOOtLi54kq-3IWZeztxaAPMVFpTxNiaofA17FEL0,4310
23
+ eotdl/commands/models.py,sha256=r1XLrVlgdG2bFKX2TaLf7CeVvRi0rrBQMT52DNirF-A,4219
24
+ eotdl/curation/__init__.py,sha256=n_zpB3byU4Dg5R33eyIMmMUBAyze_meopR-FjGbNM-Q,243
27
25
  eotdl/curation/stac/__init__.py,sha256=MYeO3zfiLrou6oxSHBujyJtfDefYt6xDHU7Y6-ujMjA,198
28
- eotdl/curation/stac/assets.py,sha256=Xpc8PH_p8tg2obof4e1Fp4cIp-caHny143JP8Sc0yoA,4281
29
- eotdl/curation/stac/dataframe.py,sha256=SX8hFpsWtzaN6uduCcs7QR2B_AG0tzlBQzMr0H-Gvew,5305
26
+ eotdl/curation/stac/assets.py,sha256=Ejdm_vjrcyo7KplaPrxHLZDApirshFGdze6cdq9V7fE,4284
27
+ eotdl/curation/stac/dataframe.py,sha256=OUHEaZBvQGMzovHBJ44aFTeU-v3YQLaSLWzdJ8OQT68,5307
30
28
  eotdl/curation/stac/dataframe_bck.py,sha256=0sMc00gnYNp58ShEGvXWbBh_5QOSpvKKYA0bKC5fFL4,8495
31
29
  eotdl/curation/stac/dataframe_labeling.py,sha256=ZXl5edYHyKAjJDxsQyNXprJcnrPZyz9yzU0zHTgk99o,1414
32
30
  eotdl/curation/stac/extensions/__init__.py,sha256=I3IspniNTkgeyLHdR9a_-kuXZm6TpH92b4dpWafh1Rk,596
@@ -35,26 +33,20 @@ eotdl/curation/stac/extensions/dem.py,sha256=GtDPNuOc_-Qxw1kJJgirGGRzZqk7hJTWHWV
35
33
  eotdl/curation/stac/extensions/eo.py,sha256=aiN5YTNPvyC4kid0gQYzJK5MYAeUe40YmGcU9PfxHQ4,3965
36
34
  eotdl/curation/stac/extensions/label/__init__.py,sha256=1MDoAAm9Va4eRkFALwzFTQ5CcWbIN25KSnjL6k75nSQ,121
37
35
  eotdl/curation/stac/extensions/label/base.py,sha256=n914NVhtH7FTMmmhPIFbJh0n1wJasVgxTrvgSUMxP3c,4063
38
- eotdl/curation/stac/extensions/label/image_name_labeler.py,sha256=uzw6DiGcff2_z0Otxkoxl7P8qn3nq0bGYnNk-WK_T_o,7853
36
+ eotdl/curation/stac/extensions/label/image_name_labeler.py,sha256=ZhUG5njBSCeo17SC0_LCdNnYxVPvqSNuFGTrWd_XtUI,7922
39
37
  eotdl/curation/stac/extensions/label/scaneo.py,sha256=C_3azPqN3QzMWNGJcrxt0wKO_14YFKL5D6bg83pSPqs,8757
40
- eotdl/curation/stac/extensions/ml_dataset.py,sha256=lxCFUDCaWyhIBrnVbjgvQpVVRWQfgPiOPzRgf9rfFuw,19554
38
+ eotdl/curation/stac/extensions/ml_dataset.py,sha256=HKtszM6nl-rI5PQHgdgYdho9v3w2SIPJHb-VCe2pMe4,19222
41
39
  eotdl/curation/stac/extensions/projection.py,sha256=NZndrCnqa_0PWtfcTAFbXjkpO83Szj2fldaUAMWM7Jc,1200
42
40
  eotdl/curation/stac/extensions/raster.py,sha256=UD6cTtb4HTILw5iie1xvl7b0SmypxzyRyamFlf1YZXo,1399
43
41
  eotdl/curation/stac/extensions/sar.py,sha256=_1a9MWA7YElem6u1z9ynjdfLWaeI6J8qwF8yDRqr3XI,1582
44
- eotdl/curation/stac/extent.py,sha256=NYjLZcFNWR0btAM4gsUEzrkAXJoEwSyNQ7QY1F8BFxg,4939
42
+ eotdl/curation/stac/extent.py,sha256=6RMaiZ9d_iDHrewldmRZ_g6h4hh_smEawvS_9QslDYI,4941
45
43
  eotdl/curation/stac/parsers.py,sha256=KumL2ieBt0ATGgKoGyc-AJ99zSMeLD4-tI5MF9ruYPw,1380
46
- eotdl/curation/stac/stac.py,sha256=KMqrV4NiGt9gamY2jGzsjozk1wWk9ny5wyW9JMorjcE,13351
47
- eotdl/curation/stac/utils/__init__.py,sha256=VWbLLESvyTJGNcHutnMFosKsCQpyV4xnb4bIHuBJZqE,108
48
- eotdl/curation/stac/utils/geometry.py,sha256=wkS7E9YjfXtbWL4hQtgjT6bh62BZZyOYmJA-9xkjWwY,388
49
- eotdl/curation/stac/utils/metadata.py,sha256=YzXyOHfF3j6c_Az6RRgIHEI9n69vOI2DvYaMmLNatSU,1658
50
- eotdl/curation/stac/utils/paths.py,sha256=IEzfpjadd3KnwOQ6F_1vBRyxnm12QcD1TboPRd-I15w,1166
51
- eotdl/curation/stac/utils/stac.py,sha256=mvAdCxDTX3t634qvJ2YXEXfUo8vhZFKx57WRm3z0VVo,4840
52
- eotdl/curation/stac/utils/time.py,sha256=hj3-SYnLriQfX-7jqJwYdFcfzzvT5KU3L8IZwGyE4FE,463
44
+ eotdl/curation/stac/stac.py,sha256=Rm5ogUxj3xLqZon4ub2VmXJfyjfim7ul-PMQe6rRTOo,13353
53
45
  eotdl/datasets/__init__.py,sha256=GIfgqrFq1LblG8qT1zNthm28drw1faLAenGbKjX0rdw,174
54
- eotdl/datasets/download.py,sha256=SRcZkiq7zWiWw0GQH6GIHbq5Fvevy97XXY3dGSqYk9E,4357
55
- eotdl/datasets/ingest.py,sha256=DSM50a1y5m2A7jPA_0bf5xSK_eo-FdTi9OIQTisaMVY,6599
46
+ eotdl/datasets/download.py,sha256=SBUsYqnKahw4MMOSzT2pxX5bDD1f1wAu31ovtuQu4Fo,4381
47
+ eotdl/datasets/ingest.py,sha256=oQ3KycGXRC8qBiV4VFfdyDfQn2HP86RAx78ZiM2MKf8,1792
56
48
  eotdl/datasets/metadata.py,sha256=L23_EziGVSDJ-WZbYUYNN22GrgbCdMGxwJhgK9uzW0U,390
57
- eotdl/datasets/retrieve.py,sha256=pL7SEbW_6yfr-s3MIT43zyhbw4SPyAwpHSQ8kYG5eac,1037
49
+ eotdl/datasets/retrieve.py,sha256=DJz5K1bCLizg9YNwBnhHMFzcxMXar2socYkFONdSL4c,1041
58
50
  eotdl/datasets/usecases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
51
  eotdl/datasets/usecases/datasets/DownloadFile.py,sha256=PoP0Dl2LBshKzbgArgxwxIVs-KT2IsfZKi0qSyiBsoI,936
60
52
  eotdl/datasets/usecases/datasets/DownloadFileURL.py,sha256=6OcNuCys45MXu9-7GtES0zg2QmY02EAkj_P3cVKVUvo,603
@@ -63,19 +55,30 @@ eotdl/datasets/usecases/datasets/IngestLargeDataset.py,sha256=yRl4eqDCNPcmbU0rrt
63
55
  eotdl/datasets/usecases/datasets/IngestLargeDatasetParallel.py,sha256=G6uVmpZLkn6lqUVQkjw0ne1xlBcJKHoJik4xLnlqd6o,1612
64
56
  eotdl/datasets/usecases/datasets/IngestSTAC.py,sha256=QAMLSkMFlc-ic0JWaIdAf0SXPkYcawy-RJqfvDqTD7A,3075
65
57
  eotdl/datasets/usecases/datasets/__init__.py,sha256=Tx4ISHtcjbu4KUVgjTac_pjpT0vsN-QpkIwtyx8xUYg,383
66
- eotdl/datasets/utils.py,sha256=4IB6N9jRO0chMDNJzpdnFDhC9wcFF9bO5oHq2HodcHw,479
58
+ eotdl/files/__init__.py,sha256=71KfzCidZzFV82Zmc2GRxXzpB9sZKGI95lBxySRxbPY,33
59
+ eotdl/files/ingest.py,sha256=mnjqellKIf-jVVAjharV5rehU4mmv7GxGhRwJ2BtCcw,6020
60
+ eotdl/models/__init__.py,sha256=fe1VfnlOxlfviphkkzaY4q8mkm0QxcdJxB3peScBZYk,108
61
+ eotdl/models/download.py,sha256=hWFEuJUZsjYnSDixMkHgmYDwxNMJEQ13-AJQPnyZOiY,4340
62
+ eotdl/models/ingest.py,sha256=Zxv9oL5VOqPXgJgaOROt7v2twRPqzajllpP5ZgyNf3Q,1519
63
+ eotdl/models/metadata.py,sha256=L23_EziGVSDJ-WZbYUYNN22GrgbCdMGxwJhgK9uzW0U,390
64
+ eotdl/models/retrieve.py,sha256=-Ij7dT4J1p7MW4n13OlPB9OW4tBaBXPwk9dW8IuCZPc,664
67
65
  eotdl/repos/APIRepo.py,sha256=tjvtr96d1fhnKEdGDmc90NrwBW7YVCtdsKLLtV82SBE,402
68
66
  eotdl/repos/AuthAPIRepo.py,sha256=T-TPDjZa1u-JnUsKoKp-T9x__L0aUfLUUdP7xZFV_hI,770
69
67
  eotdl/repos/AuthRepo.py,sha256=6AWOdWgXKAVYJ2pB3Fj6X2KABoH2u-tpUyhEkNMWxX0,1001
70
68
  eotdl/repos/DatasetsAPIRepo.py,sha256=HQh4PCS9zP6zPK86lsfUX08jhKIlOKUOswZaROVMkYY,9979
71
- eotdl/repos/FilesAPIRepo.py,sha256=p96nsM54OT4CTnp8n0tBbSu57clr-s6Wl8n1RqqXr90,10057
72
- eotdl/repos/__init__.py,sha256=wm4a7R88T7L8NGka0xWN-P-0lHcCR7HAGuIex32GmK0,181
73
- eotdl/tools/__init__.py,sha256=gyK267V-fiXSV1yk7PoZwV7l8WJLixMDTmTXlJ1Dvg8,274
74
- eotdl/tools/geo_utils.py,sha256=2J_wktL6RCDe6Mitr8j8WmgFzbrF31YUNNZTakUMOqk,6857
75
- eotdl/tools/stac.py,sha256=buKcAbvddlsjKegg0IyTvJws3orca4e6JtGghqSVhWg,1120
76
- eotdl/tools/time_utils.py,sha256=wwobnCpM998IhfPiufIbOwEcDiaDw2xGIkVRgMPWLD4,3952
77
- eotdl/tools/tools.py,sha256=RNafEs6qY8OGV74TJoIxHEwZOFxxO90gVlUNU79-SjU,6118
78
- eotdl-2023.10.25.post10.dist-info/METADATA,sha256=YrXZDXy837y9ayv8Yhmo2ImYkCyZjWjMpF4EC1lfQEk,3931
79
- eotdl-2023.10.25.post10.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
80
- eotdl-2023.10.25.post10.dist-info/entry_points.txt,sha256=s6sfxUfRrSX2IP2UbrzTFTvRCtLgw3_OKcHlOKf_5F8,39
81
- eotdl-2023.10.25.post10.dist-info/RECORD,,
69
+ eotdl/repos/FilesAPIRepo.py,sha256=WgGTyYljlSFxD8-0BePEwdks6voVy5rPjqdTruc31MQ,10924
70
+ eotdl/repos/ModelsAPIRepo.py,sha256=6PDn1eHb0g3dVyQyB5aEGnIlWi9Ez8Vlnj4A_QL3Ea8,1211
71
+ eotdl/repos/__init__.py,sha256=WvX5TP49k7yYb5dWWNjv5kzbdluO3dJ4LqjQxRIOUVc,222
72
+ eotdl/shared/__init__.py,sha256=mF7doJC8Z5eTPmB01UQvPivThZac32DRY33T6qshXfg,41
73
+ eotdl/shared/checksum.py,sha256=4IB6N9jRO0chMDNJzpdnFDhC9wcFF9bO5oHq2HodcHw,479
74
+ eotdl/tools/__init__.py,sha256=keLICmgtaXy3rc6oOHNDli8H9YHFhElTg2GtF8Vb-eM,136
75
+ eotdl/tools/geo_utils.py,sha256=vrTOq456Ck-qZiFT1mYM2cnlacm-4Q8D_dPadsqr_NY,7153
76
+ eotdl/tools/metadata.py,sha256=YzXyOHfF3j6c_Az6RRgIHEI9n69vOI2DvYaMmLNatSU,1658
77
+ eotdl/tools/paths.py,sha256=IEzfpjadd3KnwOQ6F_1vBRyxnm12QcD1TboPRd-I15w,1166
78
+ eotdl/tools/stac.py,sha256=cqv9Dc2uUnonMKF6MP9C5h9fHs-oENjgmcnRJNRWNgA,5937
79
+ eotdl/tools/time_utils.py,sha256=pb8h4bCQTTarNHq38UfjNotefm5l4qGjpYBENzzcqHY,4212
80
+ eotdl/tools/tools.py,sha256=x2UFa5wHunX4qn3lqZYP0BtPHZB-w3dMwK1fac8LUhI,6100
81
+ eotdl-2023.11.2.post2.dist-info/METADATA,sha256=SZCcWR1nXbqijiUCFCeSOThICABwsDLvQ0K_iQ8zzWc,3929
82
+ eotdl-2023.11.2.post2.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
83
+ eotdl-2023.11.2.post2.dist-info/entry_points.txt,sha256=s6sfxUfRrSX2IP2UbrzTFTvRCtLgw3_OKcHlOKf_5F8,39
84
+ eotdl-2023.11.2.post2.dist-info/RECORD,,
@@ -1 +0,0 @@
1
- from .sentinel_hub import SHFolderFormatter
@@ -1,19 +0,0 @@
1
- '''
2
- Module for folder formatter classes
3
- '''
4
-
5
-
6
- class FolderFormatter:
7
-
8
- def format_folders(self) -> None:
9
- """
10
- Format the folder structure of the downloaded data to a
11
- digestible format
12
- """
13
- pass
14
-
15
- def generate_raster_metadata(self) -> None:
16
- """
17
- Generate metadata.json file for a raster file
18
- """
19
- pass
@@ -1,135 +0,0 @@
1
- """
2
- Module for formatter classes
3
- """
4
-
5
- import json
6
- import rasterio
7
-
8
- from typing import Optional
9
- from os.path import join, dirname
10
- from os import makedirs
11
- from glob import glob
12
- from shutil import rmtree, copyfile
13
- from .base import FolderFormatter
14
-
15
-
16
- class SHFolderFormatter(FolderFormatter):
17
- """
18
- Class for formatting the directories of Sentinel images downloaded from Sentinel Hub Services
19
- """
20
-
21
- def __init__(self, root_folder):
22
- super().__init__()
23
- self.root = root_folder
24
-
25
- @classmethod
26
- def structured_format_folders(self) -> None:
27
- """
28
- Format the folder structure of the downloaded data from Sentinel Hub to a
29
- digestible format, suitable for STAC metadata generation.
30
-
31
- This formatted format is a structured format, where every image is located in
32
- a single folder, with its metadata.
33
- """
34
- images = glob(join(self.root, '**/*.tiff'), recursive=True)
35
-
36
- for image in images:
37
- # Folder with the request and response, with the if of the request
38
- image_dir = dirname(image)
39
- # Destination folder, with format <id>_<date>
40
- dest_dir = dirname(image_dir)
41
- # Get the request.json file with the request parameters
42
- request_file = join(image_dir, 'request.json')
43
- request_json = json.load(open(request_file))
44
- # Generate a metadata.json file of the raster in the destination folder
45
- # It will extract some needed parameters, which will be used later
46
- # for the STAC generation
47
- # It also returns the data type of the response
48
- data_type = self.generate_raster_metadata(request_json, image, dest_dir)
49
- # Copy the response tiff to the destination folder
50
- copyfile(image, join(dest_dir, f'{data_type}.tiff'))
51
- # Remove the request and response folder
52
- rmtree(image_dir)
53
-
54
- def unestructured_format_folders(self, output_folder: Optional[str] = None) -> None:
55
- """
56
- Format the folder structure of the downloaded data from Sentinel Hub to a
57
- digestible format, suitable for STAC metadata generation and labeling with SCANEO.
58
-
59
- This formatted format is a unestructured format, where all the images are located
60
- into the same folder, with them metadata files with the same name as the image.
61
- """
62
- images = glob(join(self.root, '**/*.tiff'), recursive=True)
63
-
64
- if not output_folder:
65
- output_folder = self.root
66
- makedirs(output_folder, exist_ok=True)
67
-
68
- n = 0
69
- for image in images:
70
- # Folder with the request and response, with the id of the request
71
- image_dir = dirname(image)
72
- # Parent image folder, with format <id>_<date>
73
- parent_dir = dirname(image_dir)
74
- parent_dir_name = parent_dir.split('/')[-1]
75
- parent_dir_name_split = parent_dir_name.split('_')
76
- id = parent_dir_name_split[0] # ID of the given location
77
- # Get the request.json file with the request parameters
78
- request_file = join(image_dir, 'request.json')
79
- request_json = json.load(open(request_file))
80
- # Generate a metadata.json file of the raster in the destination folder
81
- # It will extract some needed parameters, which will be used later
82
- # for the STAC generation
83
- # As file name, we give the same name as de image, which is <id>_<n>
84
- n += 1
85
- filename = f'{id}_{n}'
86
- self.generate_raster_metadata(request_json, image, output_folder, filename)
87
- # Copy the response tiff to the destination folder
88
- copyfile(image, join(output_folder, f'{filename}.tif'))
89
- # Remove the request and response folder
90
- rmtree(parent_dir)
91
-
92
- def generate_raster_metadata(self,
93
- request_json: dict,
94
- raster_path: str,
95
- output_folder: str,
96
- output_name: Optional[str] = 'metadata'
97
- ) -> None:
98
- """
99
- Generate metadata.json file for a raster file
100
-
101
- :param raster_path: path to the raster file
102
- :param output_folder: output folder to write the metadata.json file to
103
- :param date_adquired: date adquired of the raster file
104
- :param output_name: name of the metadata file
105
- """
106
- # Get the date adquired from the request json
107
- with rasterio.open(raster_path) as ds:
108
- bounds = ds.bounds
109
- dst_crs = "EPSG:4326"
110
- left, bottom, right, top = rasterio.warp.transform_bounds(
111
- ds.crs, dst_crs, *bounds
112
- )
113
- bbox = [left, bottom, right, top]
114
-
115
- payload_data = request_json['request']['payload']['input']['data'][0]
116
- # Get the data type from the request json
117
- data_type = payload_data['type']
118
- # Get the acquision date from the request json
119
- if 'timeRange' in payload_data['dataFilter']:
120
- data_acquisition_date = payload_data['dataFilter']['timeRange']['from']
121
- else: # DEM data does not have a timeRange
122
- data_acquisition_date = None
123
-
124
- # Generate the metadata.json file
125
- metadata_path = join(output_folder, f"{output_name}.json")
126
- metadata = {
127
- "acquisition-date": data_acquisition_date,
128
- "bounding-box": bbox,
129
- "type": data_type,
130
- }
131
-
132
- with open(metadata_path, "w") as f:
133
- json.dump(metadata, f)
134
-
135
- return data_type
@@ -1,5 +0,0 @@
1
- from .time import *
2
- from .stac import *
3
- from .geometry import *
4
- from .metadata import *
5
- from .paths import *
@@ -1,22 +0,0 @@
1
- '''
2
- Geometry utils
3
- '''
4
-
5
- from pandas import isna
6
-
7
-
8
- def convert_df_geom_to_shape(row):
9
- """
10
- Convert the geometry of a dataframe row to a shapely shape
11
-
12
- :param row: row of a dataframe
13
- """
14
- from shapely.geometry import shape
15
-
16
- if not isna(row["geometry"]):
17
- geo = shape(row["geometry"])
18
- wkt = geo.wkt
19
- else:
20
- wkt = "POLYGON EMPTY"
21
-
22
- return wkt
@@ -1,143 +0,0 @@
1
- '''
2
- STAC utils
3
- '''
4
-
5
- import pystac
6
-
7
- from os.path import dirname, join, abspath
8
- from typing import Union, Optional
9
- from tqdm import tqdm
10
- from traceback import print_exc
11
- from shutil import rmtree
12
-
13
-
14
- def get_all_children(obj: pystac.STACObject) -> list:
15
- """
16
- Get all the children of a STAC object
17
-
18
- :param obj: STAC object
19
- """
20
- children = []
21
- # Append the current object to the list
22
- children.append(obj.to_dict())
23
-
24
- # Collections
25
- collections = list(obj.get_collections())
26
-
27
- for collection in collections:
28
- children.append(collection.to_dict())
29
-
30
- # Items
31
- items = obj.get_items()
32
- for item in items:
33
- children.append(item.to_dict())
34
-
35
- # Items from collections
36
- for collection in collections:
37
- items = collection.get_items()
38
- for item in items:
39
- children.append(item.to_dict())
40
-
41
- return children
42
-
43
-
44
- def make_links_relative_to_path(path: str,
45
- catalog: Union[pystac.Catalog, str],
46
- ) -> pystac.Catalog:
47
- """
48
- Makes all asset HREFs in the catalog relative to a given path
49
-
50
- :param path: path to make the links relative
51
- :param catalog: catalog to make the links relative
52
-
53
- :return: catalog with the links relative
54
- """
55
- if isinstance(catalog, str):
56
- catalog = pystac.read_file(catalog)
57
- path = abspath(path)
58
-
59
- catalog.make_all_asset_hrefs_absolute()
60
-
61
- for collection in catalog.get_children():
62
- new_collection = collection.clone()
63
- new_collection.set_self_href(join(path, collection.id, f"collection.json"))
64
- new_collection.set_root(catalog)
65
- new_collection.set_parent(catalog)
66
- catalog.remove_child(collection.id)
67
- catalog.add_child(new_collection)
68
- for item in collection.get_all_items():
69
- new_item = item.clone()
70
- new_item.set_self_href(join(path, item.id, f"{item.id}.json"))
71
- new_item.set_parent(collection)
72
- new_item.set_root(catalog)
73
- new_collection.add_item(new_item)
74
-
75
- catalog.make_all_asset_hrefs_relative()
76
-
77
- return catalog
78
-
79
-
80
- def merge_stac_catalogs(catalog_1: Union[pystac.Catalog, str],
81
- catalog_2: Union[pystac.Catalog, str],
82
- destination: Optional[str] = None,
83
- keep_extensions: Optional[bool] = False,
84
- catalog_type: Optional[pystac.CatalogType] = pystac.CatalogType.SELF_CONTAINED
85
- ) -> None:
86
- """
87
- Merge two STAC catalogs, keeping the properties, collection and items of both catalogs
88
-
89
- :param catalog_1: first catalog to merge
90
- :param catalog_2: second catalog to merge
91
- :param destination: destination folder to save the merged catalog
92
- :param keep_extensions: keep the extensions of the first catalog
93
- :param catalog_type: type of the catalog
94
- """
95
- if isinstance(catalog_1, str):
96
- catalog_1 = pystac.Catalog.from_file(catalog_1)
97
- if isinstance(catalog_2, str):
98
- catalog_2 = pystac.Catalog.from_file(catalog_2)
99
-
100
- for col1 in tqdm(catalog_1.get_children(), desc='Merging catalogs...'):
101
- # Check if the collection exists in catalog_2
102
- col2 = catalog_2.get_child(col1.id)
103
- if col2 is None:
104
- # If it does not exist, add it
105
- col1_ = col1.clone()
106
- catalog_2.add_child(col1)
107
- col2 = catalog_2.get_child(col1.id)
108
- col2.clear_items()
109
- for i in col1_.get_stac_objects(pystac.RelType.ITEM):
110
- col2.add_item(i)
111
- else:
112
- # If it exists, merge the items
113
- for item1 in col1.get_items():
114
- if col2.get_item(item1.id) is None:
115
- col2.add_item(item1)
116
-
117
- if keep_extensions:
118
- for ext in catalog_1.stac_extensions:
119
- if ext not in catalog_2.stac_extensions:
120
- catalog_2.stac_extensions.append(ext)
121
-
122
- for extra_field_name, extra_field_value in catalog_1.extra_fields.items():
123
- if extra_field_name not in catalog_2.extra_fields:
124
- catalog_2.extra_fields[extra_field_name] = extra_field_value
125
-
126
- if destination:
127
- # TODO test
128
- make_links_relative_to_path(destination, catalog_2)
129
- else:
130
- destination = dirname(catalog_2.get_self_href())
131
-
132
- # Save the merged catalog
133
- try:
134
- print("Validating and saving...")
135
- catalog_2.validate()
136
- rmtree(destination) if not destination else None # Remove the old catalog and replace it with the new one
137
- catalog_2.normalize_and_save(root_href=destination,
138
- catalog_type=catalog_type
139
- )
140
- print("Success!")
141
- except pystac.STACValidationError:
142
- # Return full callback
143
- print_exc()
@@ -1,21 +0,0 @@
1
- '''
2
- Time utils
3
- '''
4
-
5
- from typing import Union
6
- from datetime import datetime
7
- from dateutil import parser
8
-
9
-
10
- def format_time_acquired(dt: Union[str, datetime]) -> str:
11
- """
12
- Format the date time to the required format for STAC
13
-
14
- :param dt: date time to format
15
- """
16
- dt_str = parser.parse(dt).strftime("%Y-%m-%dT%H:%M:%S.%f")
17
-
18
- # convert the string to datetime object
19
- dt_obj = datetime.strptime(dt_str, "%Y-%m-%dT%H:%M:%S.%f")
20
-
21
- return dt_obj
File without changes
File without changes
File without changes