geobox 1.3.0__py3-none-any.whl → 1.3.1__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.
geobox/mosaic.py CHANGED
@@ -295,7 +295,7 @@ class Mosaic(Raster):
295
295
  return super().get_point(lat, lng)
296
296
 
297
297
 
298
- def get_tile_render_url(self, x: int, y: int, z: int) -> str:
298
+ def get_render_png_url(self, x: int, y: int, z: int, **kwargs) -> str:
299
299
  """
300
300
  Get the tile render URL of the mosaic.
301
301
 
@@ -304,6 +304,15 @@ class Mosaic(Raster):
304
304
  y (int): The y coordinate of the tile.
305
305
  z (int): The zoom level of the tile.
306
306
 
307
+ Keyword Args:
308
+ indexes (str, optional): list of comma separated band indexes to be rendered. e.g. 1, 2, 3
309
+ nodata (int, optional)
310
+ expression (str, optional): band math expression. e.g. b1*b2+b3
311
+ rescale (List, optional): comma (',') separated Min,Max range. Can set multiple time for multiple bands.
312
+ color_formula (str, optional): Color formula. e.g. gamma R 0.5
313
+ colormap_name (str, optional)
314
+ colormap (str, optional): JSON encoded custom Colormap. e.g. {"0": "#ff0000", "1": "#00ff00"} or [[[0, 100], "#ff0000"], [[100, 200], "#00ff00"]]
315
+
307
316
  Returns:
308
317
  str: The tile render URL of the mosaic.
309
318
 
@@ -314,7 +323,7 @@ class Mosaic(Raster):
314
323
  >>> mosaic = Mosaic.get_mosaic(client, uuid="12345678-1234-5678-1234-567812345678")
315
324
  >>> mosaic.get_tile_render_url(x=1, y=1, z=1)
316
325
  """
317
- return super().get_tile_render_url(x, y, z)
326
+ return super().get_render_png_url(x, y, z, **kwargs)
318
327
 
319
328
 
320
329
  def get_tile_png_url(self, x: int, y: int, z: int) -> str:
geobox/raster.py CHANGED
@@ -3,6 +3,7 @@ from urllib.parse import urljoin, urlencode
3
3
  from typing import Optional, Dict, List, Optional, Union, TYPE_CHECKING
4
4
  import mimetypes
5
5
  import requests
6
+ import sys
6
7
 
7
8
  from .base import Base
8
9
  from .utils import clean_data
@@ -179,7 +180,6 @@ class Raster(Base):
179
180
  name (str): The name of the raster.
180
181
  display_name (str): The display name of the raster.
181
182
  description (str): The description of the raster.
182
- max_zoom (int): The max zoom of the raster.
183
183
 
184
184
  Returns:
185
185
  None
@@ -194,10 +194,9 @@ class Raster(Base):
194
194
  params = {
195
195
  'name': kwargs.get('name'),
196
196
  'display_name': kwargs.get('display_name'),
197
- 'description': kwargs.get('description'),
198
- 'max_zoom': kwargs.get('max_zoom'),
197
+ 'description': kwargs.get('description')
199
198
  }
200
- super()._update(self.endpoint, params)
199
+ return super()._update(self.endpoint, params)
201
200
 
202
201
 
203
202
  def delete(self) -> None:
@@ -236,7 +235,8 @@ class Raster(Base):
236
235
  return endpoint
237
236
 
238
237
 
239
- def get_raster_info(self) -> Dict:
238
+ @property
239
+ def info(self) -> Dict:
240
240
  """
241
241
  Get the info of the raster.
242
242
 
@@ -248,7 +248,7 @@ class Raster(Base):
248
248
  >>> from geobox.raster import Raster
249
249
  >>> client = GeoboxClient()
250
250
  >>> raster = Raster.get_raster(client, uuid="12345678-1234-5678-1234-567812345678")
251
- >>> raster.get_raster_info()
251
+ >>> raster.info
252
252
  """
253
253
  endpoint = urljoin(self.endpoint, 'info/')
254
254
  return self.api.get(endpoint)
@@ -323,53 +323,74 @@ class Raster(Base):
323
323
 
324
324
  Raises:
325
325
  ValueError: If save_path does not end with a '/'.
326
- """
327
- # Get the original filename from data or use uuid
328
- if self.name:
329
- filename = f"{self.name.split('.')[0]}" if len(self.name.split('.')) > 1 else f'{self.name}'
330
- else:
331
- filename = f'{self.uuid}'
332
326
 
327
+ Example:
328
+ >>> from geobox import GeoboxClient
329
+ >>> from geobox.file import File
330
+ >>> from geobox import GeoboxClient
331
+ >>> client = GeoboxClient()
332
+ >>> file_path = File.get_file(client, uuid="12345678-1234-5678-1234-567812345678")
333
+ """
333
334
  # If save_path is provided, check if it ends with a '/'
334
335
  if save_path and save_path.endswith('/'):
335
- return f'{save_path}{filename}'
336
+ return f'{save_path}'
336
337
 
337
338
  if save_path and not save_path.endswith('/'):
338
339
  raise ValueError("save_path must end with a '/'")
339
340
 
340
- return os.path.join(os.getcwd(), filename)
341
+ return os.getcwd()
341
342
 
342
343
 
343
- def _get_file_ext(self, response: requests.Response) -> str:
344
+ def _get_file_name(self, response: requests.Response) -> str:
344
345
  """
345
- Get the file extension of the response.
346
+ Get the file name from the response.
346
347
 
347
348
  Args:
348
349
  response (requests.Response): The response of the request.
349
350
 
350
351
  Returns:
351
- str: The file extension of the response.
352
+ str: The file name
352
353
  """
353
- ext = ""
354
354
  if 'Content-Disposition' in response.headers and 'filename=' in response.headers['Content-Disposition']:
355
- content_disposition = response.headers['Content-Disposition']
356
- filename = content_disposition.split('filename=')[-1].strip().strip('"')
357
- ext = f".{filename.split('.')[-1]}"
355
+ file_name = response.headers['Content-Disposition'].split('filename=')[-1].strip().strip('"')
358
356
 
359
357
  else:
360
358
  content_type = response.headers.get("Content-Type", "")
361
- ext = mimetypes.guess_extension(content_type.split(";")[0])
359
+ file_name = f'{self.name}.{mimetypes.guess_extension(content_type.split(";")[0])}'
362
360
 
363
- return ext
361
+ return file_name
364
362
 
365
363
 
366
- def download(self, save_path: str = None) -> str:
364
+ def _create_progress_bar(self) -> 'tqdm':
365
+ """Creates a progress bar for the task."""
366
+ try:
367
+ from tqdm.auto import tqdm
368
+ except ImportError:
369
+ from .api import logger
370
+ logger.warning("[tqdm] extra is required to show the progress bar. install with: pip insatll geobox[tqdm]")
371
+ return None
372
+
373
+ return tqdm(unit="B",
374
+ total=int(self.size),
375
+ file=sys.stdout,
376
+ dynamic_ncols=True,
377
+ desc="Downloading",
378
+ unit_scale=True,
379
+ unit_divisor=1024,
380
+ ascii=True
381
+ )
382
+
383
+
384
+ def download(self, save_path: str = None, progress_bar: bool = True) -> str:
367
385
  """
368
386
  Download the raster.
369
387
 
370
388
  Args:
371
- save_path (str): The path to save the raster.
372
-
389
+ save_path (str, optional): Path where the file should be saved.
390
+ If not provided, it saves to the current working directory
391
+ using the original filename and appropriate extension.
392
+ progress_bar (bool, optional): Whether to show a progress bar. default: True
393
+
373
394
  Returns:
374
395
  str: The path to save the raster.
375
396
 
@@ -390,23 +411,32 @@ class Raster(Base):
390
411
  save_path = self._get_save_path(save_path)
391
412
  os.makedirs(os.path.dirname(save_path), exist_ok=True)
392
413
 
393
- with self.api.get(f"{self.endpoint}download/", stream=True) as response, \
394
- open(save_path, 'wb') as f:
395
- for chunk in response.iter_content(chunk_size=8192):
396
- f.write(chunk)
414
+ with self.api.get(f"{self.endpoint}download/", stream=True) as response:
415
+ file_name = self._get_file_name(response)
416
+ full_path = f"{save_path}/{file_name}"
417
+ with open(full_path, 'wb') as f:
418
+ pbar = self._create_progress_bar() if progress_bar else None
419
+ for chunk in response.iter_content(chunk_size=8192):
420
+ f.write(chunk)
421
+ if pbar:
422
+ pbar.update(len(chunk))
423
+ pbar.refresh()
424
+ if pbar:
425
+ pbar.close()
397
426
 
398
- final_path = os.path.abspath(save_path) + self._get_file_ext(response)
399
- os.rename(os.path.abspath(save_path), os.path.abspath(final_path))
400
- return os.path.abspath(final_path)
427
+ return os.path.abspath(full_path)
401
428
 
402
429
 
403
- def get_content_file(self, save_path: str = None) -> str:
430
+ def get_content_file(self, save_path: str = None, progress_bar: bool = True) -> str:
404
431
  """
405
432
  Get Raster Content URL
406
433
 
407
434
  Args:
408
- save_path (str): The path to save the raster.
409
-
435
+ save_path (str, optional): Path where the file should be saved.
436
+ If not provided, it saves to the current working directory
437
+ using the original filename and appropriate extension.
438
+ progress_bar (bool, optional): Whether to show a progress bar. default: True
439
+
410
440
  Returns:
411
441
  str: The path to save the raster.
412
442
 
@@ -427,17 +457,23 @@ class Raster(Base):
427
457
  save_path = self._get_save_path(save_path)
428
458
  os.makedirs(os.path.dirname(save_path), exist_ok=True)
429
459
 
430
- with self.api.get(f"{self.endpoint}content/", stream=True) as response, \
431
- open(save_path, 'wb') as f:
432
- for chunk in response.iter_content(chunk_size=8192):
433
- f.write(chunk)
460
+ with self.api.get(f"{self.endpoint}content/", stream=True) as response:
461
+ file_name = self._get_file_name(response)
462
+ full_path = f"{save_path}/{file_name}"
463
+ with open(full_path, 'wb') as f:
464
+ pbar = self._create_progress_bar() if progress_bar else None
465
+ for chunk in response.iter_content(chunk_size=8192):
466
+ f.write(chunk)
467
+ if pbar:
468
+ pbar.update(len(chunk))
469
+ pbar.refresh()
470
+ if pbar:
471
+ pbar.close()
434
472
 
435
- final_path = os.path.abspath(save_path) + self._get_file_ext(response)
436
- os.rename(os.path.abspath(save_path), os.path.abspath(final_path))
437
- return os.path.abspath(final_path)
473
+ return os.path.abspath(full_path)
438
474
 
439
475
 
440
- def get_tile_render_url(self, x: int, y: int, z: int) -> str:
476
+ def get_render_png_url(self, x: int, y: int, z: int, **kwargs) -> str:
441
477
  """
442
478
  Get the PNG URL of the raster.
443
479
 
@@ -446,6 +482,15 @@ class Raster(Base):
446
482
  y (int): The y coordinate of the tile.
447
483
  z (int): The zoom level of the tile.
448
484
 
485
+ Keyword Args:
486
+ indexes (str, optional): list of comma separated band indexes to be rendered. e.g. 1, 2, 3
487
+ nodata (int, optional)
488
+ expression (str, optional): band math expression. e.g. b1*b2+b3
489
+ rescale (List, optional): comma (',') separated Min,Max range. Can set multiple time for multiple bands.
490
+ color_formula (str, optional): Color formula. e.g. gamma R 0.5
491
+ colormap_name (str, optional)
492
+ colormap (str, optional): JSON encoded custom Colormap. e.g. {"0": "#ff0000", "1": "#00ff00"} or [[[0, 100], "#ff0000"], [[100, 200], "#00ff00"]]
493
+
449
494
  Returns:
450
495
  str: The PNG Render URL of the raster.
451
496
 
@@ -456,7 +501,18 @@ class Raster(Base):
456
501
  >>> raster = Raster.get_raster(client, uuid="12345678-1234-5678-1234-567812345678")
457
502
  >>> raster.get_tile_render_url(x=10, y=20, z=1)
458
503
  """
504
+ params = clean_data({
505
+ 'indexes': kwargs.get('indexes'),
506
+ 'nodata': kwargs.get('nodata'),
507
+ 'expression': kwargs.get('expression'),
508
+ 'rescale': kwargs.get('rescale'),
509
+ 'color_formula': kwargs.get('color_formula'),
510
+ 'colormap_name': kwargs.get('colormap_name'),
511
+ 'colormap': kwargs.get('colormap')
512
+ })
513
+ query_string = urlencode(clean_data(params))
459
514
  endpoint = urljoin(self.api.base_url, f'{self.endpoint}render/{z}/{x}/{y}.png')
515
+ endpoint = urljoin(endpoint, f'?{query_string}')
460
516
  return endpoint
461
517
 
462
518
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: geobox
3
- Version: 1.3.0
3
+ Version: 1.3.1
4
4
  Summary: SDK for Geobox's APIs
5
5
  Author-email: Hamid Heydari <heydari.h62@gmail.com>
6
6
  License: MIT
@@ -13,10 +13,10 @@ geobox/file.py,sha256=Ula8r8pZaCmifsnUHDbaJujw53SLxUiCiBzVS358o88,19967
13
13
  geobox/log.py,sha256=ZTmVErhyAszf7M5YFxT5mqXNNDGPnRwXPeGLDS1G6PE,3582
14
14
  geobox/map.py,sha256=RjuhbOVQN-OBwjBtO46AosB_Ta348EA1nExBdnxH3nw,31252
15
15
  geobox/model3d.py,sha256=qRYCx-q9LpGhdu5oz3av0uUoiDimuk4BvXXwMW5bo9Q,12061
16
- geobox/mosaic.py,sha256=RmMyvzt6C2Fd8a0nJX5gUOGJnO3MrCWgwmYfhJ9d_Jw,23025
16
+ geobox/mosaic.py,sha256=feBRsAgvhl0tKoghfZiQsxFntS7skAnzEYYuU4GKbP0,23672
17
17
  geobox/plan.py,sha256=_ZV9F6loG92uQZGJl_9T08Kg85g3hnODmpccSkTYVdw,11193
18
18
  geobox/query.py,sha256=1guO9O9DAEb8oj_iMiW3PhEDgMVMAN9ccEp19dnwAWE,24209
19
- geobox/raster.py,sha256=DkvajG2jWDlGFbS2ywv4XCVOyfR82ouUMT3tdIE1PsU,26437
19
+ geobox/raster.py,sha256=06L95vTFdbOwykDxo6XDRkNIDJKMpFcsjbFg75WGLLA,29177
20
20
  geobox/route.py,sha256=cKZTTHBHM8woWbhHIpCvrRX_doJcTkGktouee0z7oG0,2723
21
21
  geobox/scene.py,sha256=Sz2tiyJk-bXYjktfcp1d2gGrW3gt2T4D1FAMoRHOCng,11369
22
22
  geobox/settings.py,sha256=rGRdM18Vo7xnjfZXPLRMbKeoVC_lZmzkNRPS0SQv05o,5660
@@ -30,8 +30,8 @@ geobox/vectorlayer.py,sha256=1xjhWpvb1hFhLRei2hwU7IY5KxDKzynZMb3fbIDTMZE,51092
30
30
  geobox/version.py,sha256=0GLPhxCeEb2bAkdpPJWtXPXc1KP6kQ_TOMwLAL0ldo0,9374
31
31
  geobox/view.py,sha256=sIi6Mi7NUAX5gN83cpubD3l7AcZ-1g5kG2NKHeVeW-g,37518
32
32
  geobox/workflow.py,sha256=6hKnSw4G0_ZlgmUb0g3fxT-UVsFbiYpF2FbEO5fpQv0,11606
33
- geobox-1.3.0.dist-info/licenses/LICENSE,sha256=AvFB7W94sJYKLDhBxLRshL3upexCOG8HQY_1JibB96w,1063
34
- geobox-1.3.0.dist-info/METADATA,sha256=UW0-KY-DuDA4blEJeWwoP05fxSMQ-yOa7AjfIs0dzzg,2556
35
- geobox-1.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
36
- geobox-1.3.0.dist-info/top_level.txt,sha256=ppXH8Bu2mlB-pLQ6lsoWEm2Gr6wZx1uzkhetsYA5ins,7
37
- geobox-1.3.0.dist-info/RECORD,,
33
+ geobox-1.3.1.dist-info/licenses/LICENSE,sha256=AvFB7W94sJYKLDhBxLRshL3upexCOG8HQY_1JibB96w,1063
34
+ geobox-1.3.1.dist-info/METADATA,sha256=mK4pFtm6hb68Yy5t_t1E6HCi3z9M5W18fV_N-MOYmgM,2556
35
+ geobox-1.3.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
36
+ geobox-1.3.1.dist-info/top_level.txt,sha256=ppXH8Bu2mlB-pLQ6lsoWEm2Gr6wZx1uzkhetsYA5ins,7
37
+ geobox-1.3.1.dist-info/RECORD,,
File without changes