terrakit 0.2.0__tar.gz → 0.2.2__tar.gz
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.
- {terrakit-0.2.0 → terrakit-0.2.2}/PKG-INFO +1 -1
- {terrakit-0.2.0 → terrakit-0.2.2}/pyproject.toml +1 -1
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/collections.json +6 -6
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/data_connectors/nasa_earthdata.py +33 -12
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/data_connectors/sentinelhub.py +39 -7
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/geodata_utils.py +61 -29
- {terrakit-0.2.0 → terrakit-0.2.2}/README.md +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/__init__.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/__main__.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/_version.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/chip/__init__.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/chip/tiling.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/__init__.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/connector.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/data_connectors/__init__.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/data_connectors/cds_utils/cordex_domains.json +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/data_connectors/cds_utils/cordex_utils.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/data_connectors/cds_utils/derived-era5-single-levels-daily-statistics_constraints.json +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/data_connectors/cds_utils/projections-cordex-domains-single-levels_constraints.json +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/data_connectors/cds_utils/projections-cordex-domains-single-levels_constraints_variables.json +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/data_connectors/climate_data_store.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/data_connectors/connector_template.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/data_connectors/ibmresearch_stac.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/data_connectors/local_file_system.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/data_connectors/sentinel_aws.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/data_connectors/theweathercompany.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/download_data.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/raster_file_reader.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/transformations/__init__.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/transformations/download_transformation_template.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/transformations/impute_nans_xarray.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/transformations/scale_data_xarray.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/general_utils/__init__.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/general_utils/curation_metadata.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/general_utils/defaults.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/general_utils/exceptions.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/general_utils/geospatial_util.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/general_utils/labels_downloader.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/general_utils/plotting.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/general_utils/rest.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/general_utils/statistics.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/store/__init__.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/store/taco.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/terrakit.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/transform/__init__.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/transform/labels.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/upload/__init__.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/validate/__init__.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/validate/data_connector.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/validate/download_model.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/validate/helpers.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/validate/labels_model.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/validate/pipeline_model.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/validate/store_model.py +0 -0
- {terrakit-0.2.0 → terrakit-0.2.2}/terrakit/validate/tiling_model.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: terrakit
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A Python package for finding and getting geospatial data.
|
|
5
5
|
Author: Blair Edwards, Rosie Lickorish, Leonardo Pondian Tizzei, Fred Ochieng Otieno, Beldine Moturi, Catherine Wanjiru, Benedikt Blumenstiel, Brian Ogolla, Romeo Kienzler
|
|
6
6
|
Author-email: Blair Edwards <bedwards@uk.ibm.com>
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"B02"
|
|
87
87
|
],
|
|
88
88
|
"resolution_m": 10,
|
|
89
|
-
"query_template": "
|
|
89
|
+
"query_template": " //VERSION=3 \\n function setup() { return { input: [{ bands: ${bands}, units: \"DN\" }], output: { bands: ${num_bands}, sampleType: \"INT16\" } }; } function evaluatePixel(sample) { return ${band_samples}; } ",
|
|
90
90
|
"collection_name": "s2_l1c",
|
|
91
91
|
"modality_tag": "S2L1C",
|
|
92
92
|
"data_collection": "DataCollection.SENTINEL2_L1C",
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
},
|
|
112
112
|
"connector": "sentinelhub",
|
|
113
113
|
"resolution_m": null,
|
|
114
|
-
"query_template": "
|
|
114
|
+
"query_template": " //VERSION=3 \\n\nfunction setup() { return { input: [\"DEM\"], output:{ id: \"default\", bands: 1, sampleType: SampleType.FLOAT32 } } }\nfunction evaluatePixel(sample) { return [sample.DEM] } ",
|
|
115
115
|
"collection_name": "dem",
|
|
116
116
|
"modality_tag": "DEM",
|
|
117
117
|
"data_collection": "DataCollection.DEM_COPERNICUS_30",
|
|
@@ -151,7 +151,7 @@
|
|
|
151
151
|
"connector": "sentinelhub",
|
|
152
152
|
"modality_tag": "S1GRD",
|
|
153
153
|
"resolution_m": 10,
|
|
154
|
-
"query_template": "
|
|
154
|
+
"query_template": " //VERSION=3 \\n function setup() { return { input: [{ bands: ${bands}, units: \"LINEAR_POWER\" }], output: { bands: ${num_bands}, sampleType: \"FLOAT32\" } }; }\nfunction evaluatePixel(sample) { return ${band_samples}; } ",
|
|
155
155
|
"collection_name": "s1_grd",
|
|
156
156
|
"data_collection": "DataCollection.SENTINEL1_IW",
|
|
157
157
|
"request_input_data": {
|
|
@@ -241,7 +241,7 @@
|
|
|
241
241
|
"band": "SCL",
|
|
242
242
|
"encoding": "sentinel2_lulc"
|
|
243
243
|
},
|
|
244
|
-
"query_template": "
|
|
244
|
+
"query_template": " //VERSION=3 \\n function setup() { return { input: [{ bands: ${bands}, units: \"DN\" }], output: { bands: ${num_bands}, sampleType: \"INT16\" } }; } function evaluatePixel(sample) { return ${band_samples}; } ",
|
|
245
245
|
"collection_name": "hls_l30",
|
|
246
246
|
"data_collection": "DataCollection.HARMONIZED_LANDSAT_SENTINEL",
|
|
247
247
|
"request_input_data": {
|
|
@@ -352,7 +352,7 @@
|
|
|
352
352
|
"band": "SCL",
|
|
353
353
|
"encoding": "sentinel2_lulc"
|
|
354
354
|
},
|
|
355
|
-
"query_template": "
|
|
355
|
+
"query_template": " //VERSION=3 \\n function setup() { return { input: [{ bands: ${bands}, units: \"DN\" }], output: { bands: ${num_bands}, sampleType: \"INT16\" } }; } function evaluatePixel(sample) { return ${band_samples}; } ",
|
|
356
356
|
"collection_name": "s2_l2a",
|
|
357
357
|
"data_collection": "DataCollection.SENTINEL2_L2A",
|
|
358
358
|
"request_input_data": {
|
|
@@ -458,7 +458,7 @@
|
|
|
458
458
|
"band": "SCL",
|
|
459
459
|
"encoding": "sentinel2_lulc"
|
|
460
460
|
},
|
|
461
|
-
"query_template": "
|
|
461
|
+
"query_template": " //VERSION=3 function setup() { return { input: [{ bands: ${bands}, units: \"DN\" }], output: { bands: ${num_bands}, sampleType: \"INT16\" } }; } function evaluatePixel(sample) { return ${band_samples}; } ",
|
|
462
462
|
"collection_name": "hls_s30",
|
|
463
463
|
"data_collection": "DataCollection.HARMONIZED_LANDSAT_SENTINEL",
|
|
464
464
|
"request_input_data": {
|
|
@@ -168,25 +168,46 @@ def get_band(date_items, band, bbox, temp_creds_req, working_dir):
|
|
|
168
168
|
# Transform the bounding box to the CRS of the first link
|
|
169
169
|
hls_bbox = list(rio.warp.transform_bounds("EPSG:4326", hls_proj, *bbox))
|
|
170
170
|
|
|
171
|
-
# Prepare the gdalbuildvrt
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
else:
|
|
175
|
-
build_vrt = f"gdalbuildvrt {working_dir}/links_{band}_{date}.vrt -separate --config AWS_ACCESS_KEY_ID {temp_creds_req['accessKeyId']} --config AWS_SECRET_ACCESS_KEY {temp_creds_req['secretAccessKey']} --config AWS_SESSION_TOKEN {temp_creds_req['sessionToken']} --config GDAL_DISABLE_READDIR_ON_OPEN TRUE"
|
|
171
|
+
# Prepare the gdalbuildvrt argument list
|
|
172
|
+
vrt_path = os.path.join(working_dir, f"links_{band}_{date}.vrt")
|
|
173
|
+
build_vrt = ["gdalbuildvrt", vrt_path, "-separate"]
|
|
176
174
|
|
|
177
|
-
|
|
178
|
-
|
|
175
|
+
if NASA_EARTH_BEARER_TOKEN:
|
|
176
|
+
build_vrt += [
|
|
177
|
+
"--config",
|
|
178
|
+
"GDAL_HTTP_AUTH",
|
|
179
|
+
"BEARER",
|
|
180
|
+
"--config",
|
|
181
|
+
"GDAL_HTTP_BEARER",
|
|
182
|
+
NASA_EARTH_BEARER_TOKEN,
|
|
183
|
+
]
|
|
179
184
|
|
|
180
|
-
|
|
181
|
-
|
|
185
|
+
build_vrt += [
|
|
186
|
+
"--config",
|
|
187
|
+
"AWS_ACCESS_KEY_ID",
|
|
188
|
+
temp_creds_req["accessKeyId"],
|
|
189
|
+
"--config",
|
|
190
|
+
"AWS_SECRET_ACCESS_KEY",
|
|
191
|
+
temp_creds_req["secretAccessKey"],
|
|
192
|
+
"--config",
|
|
193
|
+
"AWS_SESSION_TOKEN",
|
|
194
|
+
temp_creds_req["sessionToken"],
|
|
195
|
+
"--config",
|
|
196
|
+
"GDAL_DISABLE_READDIR_ON_OPEN",
|
|
197
|
+
"TRUE",
|
|
198
|
+
]
|
|
199
|
+
|
|
200
|
+
# Each link is a separate list element
|
|
201
|
+
build_vrt += links
|
|
202
|
+
|
|
203
|
+
# Execute gdalbuildvrt directly
|
|
204
|
+
result = subprocess.run(build_vrt, check=True)
|
|
182
205
|
|
|
183
206
|
# Define chunking parameters for efficient reading of the VRT
|
|
184
207
|
chunks = dict(band=1, x=512, y=512)
|
|
185
208
|
|
|
186
209
|
# Open the VRT file using rioxarray
|
|
187
|
-
data = rioxarray.open_rasterio(
|
|
188
|
-
f"{working_dir}/links_{band}_{date}.vrt", chunks=chunks
|
|
189
|
-
)
|
|
210
|
+
data = rioxarray.open_rasterio(vrt_path, chunks=chunks)
|
|
190
211
|
|
|
191
212
|
# Rename the 'band' dimension to 'time' and add a new 'band' dimension
|
|
192
213
|
data = data.rename({"band": "time"})
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
# Assisted by watsonx Code Assistant
|
|
6
6
|
|
|
7
7
|
import os
|
|
8
|
+
import json
|
|
8
9
|
import numpy as np
|
|
9
10
|
import xarray as xr
|
|
10
11
|
import rioxarray
|
|
@@ -93,7 +94,12 @@ def create_request(
|
|
|
93
94
|
data_folder="./",
|
|
94
95
|
maxcc=None,
|
|
95
96
|
):
|
|
96
|
-
|
|
97
|
+
qt = data_details["query_template"]
|
|
98
|
+
if not qt.strip().startswith("//VERSION=3"):
|
|
99
|
+
raise TerrakitValidationError(
|
|
100
|
+
"Invalid query_template value: does not start with //VERSION=3"
|
|
101
|
+
)
|
|
102
|
+
evalscript = Template(qt).substitute(
|
|
97
103
|
{
|
|
98
104
|
"bands": str(bands),
|
|
99
105
|
"num_bands": len(bands),
|
|
@@ -101,17 +107,31 @@ def create_request(
|
|
|
101
107
|
}
|
|
102
108
|
)
|
|
103
109
|
|
|
110
|
+
dc_name = data_details["data_collection"] # e.g. "DataCollection.SENTINEL2_L1C"
|
|
111
|
+
dc_prefix = "DataCollection."
|
|
112
|
+
if not dc_name.startswith(dc_prefix):
|
|
113
|
+
raise TerrakitValidationError(f"Invalid data_collection value: {dc_name!r}")
|
|
114
|
+
member_name = dc_name[len(dc_prefix) :]
|
|
115
|
+
data_collection = getattr(DataCollection, member_name)
|
|
116
|
+
|
|
104
117
|
shr = SentinelHubRequest.input_data(
|
|
105
|
-
data_collection=
|
|
118
|
+
data_collection=data_collection,
|
|
106
119
|
time_interval=(timestamp_start, timestamp_end),
|
|
107
120
|
)
|
|
108
121
|
|
|
109
122
|
if maxcc is not None:
|
|
110
123
|
shr["maxCloudCoverage"] = maxcc / 100.0
|
|
111
124
|
if "mosaicking_order" in data_details["request_input_data"]:
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
125
|
+
mosaicking_order_name = data_details["request_input_data"][
|
|
126
|
+
"mosaicking_order"
|
|
127
|
+
] # i.e. "MosaickingOrder.LEAST_CC"
|
|
128
|
+
mosaicking_order_prefix = "MosaickingOrder."
|
|
129
|
+
if not mosaicking_order_name.startswith(mosaicking_order_prefix):
|
|
130
|
+
raise TerrakitValidationError(
|
|
131
|
+
f"Invalid mosaicking_order value: {mosaicking_order_name!r}"
|
|
132
|
+
)
|
|
133
|
+
member_name = mosaicking_order_name[len(mosaicking_order_prefix) :]
|
|
134
|
+
shr["mosaickingOrder"] = getattr(MosaickingOrder, member_name).value
|
|
115
135
|
|
|
116
136
|
logger.info(shr)
|
|
117
137
|
|
|
@@ -299,7 +319,14 @@ class SentinelHub(Connector):
|
|
|
299
319
|
raise ValueError(error_msg)
|
|
300
320
|
data_connector_spec = data_connector_spec_list[0]
|
|
301
321
|
|
|
302
|
-
|
|
322
|
+
dc_name = data_connector_spec[
|
|
323
|
+
"data_collection"
|
|
324
|
+
] # e.g. "DataCollection.SENTINEL2_L1C"
|
|
325
|
+
dc_prefix = "DataCollection."
|
|
326
|
+
if not dc_name.startswith(dc_prefix):
|
|
327
|
+
raise TerrakitValidationError(f"Invalid data_collection value: {dc_name!r}")
|
|
328
|
+
member_name = dc_name[len(dc_prefix) :]
|
|
329
|
+
data_collection = getattr(DataCollection, member_name)
|
|
303
330
|
|
|
304
331
|
self.sh_config.sh_base_url = data_collection.service_url
|
|
305
332
|
logger.info(self.sh_config.sh_base_url)
|
|
@@ -319,7 +346,12 @@ class SentinelHub(Connector):
|
|
|
319
346
|
filter_string = ""
|
|
320
347
|
|
|
321
348
|
if "fields" in data_connector_spec["search"]:
|
|
322
|
-
|
|
349
|
+
fields_str = data_connector_spec["search"]["fields"]
|
|
350
|
+
if len(fields_str) > 1024:
|
|
351
|
+
raise TerrakitValidationError(
|
|
352
|
+
"search.fields value exceeds maximum allowed length"
|
|
353
|
+
)
|
|
354
|
+
fields_dict = json.loads(fields_str)
|
|
323
355
|
|
|
324
356
|
else:
|
|
325
357
|
fields_dict = {"include": ["id", "properties.datetime"], "exclude": []}
|
|
@@ -23,6 +23,7 @@ from sentinelhub import (
|
|
|
23
23
|
bbox_to_dimensions,
|
|
24
24
|
)
|
|
25
25
|
from pathlib import Path
|
|
26
|
+
from rasterio.warp import calculate_default_transform, reproject, Resampling
|
|
26
27
|
from shapely.geometry import shape
|
|
27
28
|
from typing import Any, Dict, Union
|
|
28
29
|
|
|
@@ -306,44 +307,75 @@ def verify_input_image(image, standard_dimensions=224) -> typing.Tuple[int, str]
|
|
|
306
307
|
Return:
|
|
307
308
|
tuple[int, str]: [verification_status_code, verification_msg]
|
|
308
309
|
"""
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
310
|
+
try:
|
|
311
|
+
with rasterio.open(image) as src:
|
|
312
|
+
dims = (src.height, src.width)
|
|
312
313
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
314
|
+
# Check if image is geotiff
|
|
315
|
+
if src.driver != "GTiff":
|
|
316
|
+
return 1007, f"Input {image} is not a GeoTiff."
|
|
316
317
|
|
|
317
|
-
|
|
318
|
-
|
|
318
|
+
# Check image dimensions
|
|
319
|
+
image_input_dimensions = np.min(dims)
|
|
319
320
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
321
|
+
if image_input_dimensions < standard_dimensions:
|
|
322
|
+
return (
|
|
323
|
+
1002,
|
|
324
|
+
f"Input image too small for image {image} with dimensions {image_input_dimensions}. Both dimensions must be >= 224.",
|
|
325
|
+
)
|
|
326
|
+
else:
|
|
327
|
+
# Log/Show dimensions of the input image
|
|
328
|
+
logger.debug(
|
|
329
|
+
f"Input image {image} has dimensions {image_input_dimensions}"
|
|
330
|
+
)
|
|
331
|
+
return 200, str(image_input_dimensions)
|
|
332
|
+
except rasterio.errors.RasterioIOError as e:
|
|
333
|
+
return 1001, f"Failed to open image {image}: {e}"
|
|
329
334
|
|
|
330
335
|
|
|
331
|
-
def check_projection(file):
|
|
336
|
+
def check_projection(file: Union[str, Path]) -> None:
|
|
332
337
|
"""
|
|
333
|
-
Check the projection is correct, if not reproject to EPSG:4326
|
|
338
|
+
Check the projection is correct, if not reproject to EPSG:4326.
|
|
334
339
|
|
|
335
340
|
Parameters:
|
|
336
|
-
file (str): The path to the input file.
|
|
337
|
-
|
|
338
|
-
Returns:
|
|
339
|
-
None
|
|
341
|
+
file (str | Path): The path to the input file.
|
|
340
342
|
"""
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
343
|
+
file_path = Path(file)
|
|
344
|
+
target_crs = CRS.from_epsg(4326)
|
|
345
|
+
|
|
346
|
+
with rasterio.open(file_path) as src:
|
|
347
|
+
# Check if already in EPSG:4326
|
|
348
|
+
if src.crs == target_crs or (src.crs and src.crs.to_epsg() == 4326):
|
|
349
|
+
return
|
|
350
|
+
|
|
351
|
+
transform, width, height = calculate_default_transform(
|
|
352
|
+
src.crs, target_crs, src.width, src.height, *src.bounds
|
|
353
|
+
)
|
|
354
|
+
kwargs = src.meta.copy()
|
|
355
|
+
kwargs.update(
|
|
356
|
+
{
|
|
357
|
+
"crs": target_crs,
|
|
358
|
+
"transform": transform,
|
|
359
|
+
"width": width,
|
|
360
|
+
"height": height,
|
|
361
|
+
}
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
temp_file = file_path.with_name(f"{file_path.stem}_reprojected.tif")
|
|
365
|
+
with rasterio.open(temp_file, "w", **kwargs) as dst:
|
|
366
|
+
for i in range(1, src.count + 1):
|
|
367
|
+
reproject(
|
|
368
|
+
source=rasterio.band(src, i),
|
|
369
|
+
destination=rasterio.band(dst, i),
|
|
370
|
+
src_transform=src.transform,
|
|
371
|
+
src_crs=src.crs,
|
|
372
|
+
dst_transform=transform,
|
|
373
|
+
dst_crs=target_crs,
|
|
374
|
+
resampling=Resampling.nearest,
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
# Atomically replace original file with reprojected file
|
|
378
|
+
temp_file.replace(file_path)
|
|
347
379
|
|
|
348
380
|
|
|
349
381
|
def pad_bbox(padding_degrees, bbox):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/data_connectors/cds_utils/cordex_domains.json
RENAMED
|
File without changes
|
{terrakit-0.2.0 → terrakit-0.2.2}/terrakit/download/data_connectors/cds_utils/cordex_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|