geobox 1.4.0__py3-none-any.whl → 1.4.2__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/api.py +11 -7
- geobox/attachment.py +27 -12
- geobox/basemap.py +1 -2
- geobox/enums.py +0 -8
- geobox/log.py +20 -1
- geobox/map.py +103 -3
- geobox/model3d.py +101 -16
- geobox/mosaic.py +19 -0
- geobox/query.py +3 -1
- geobox/raster.py +19 -0
- geobox/vectorlayer.py +99 -2
- geobox/view.py +99 -1
- {geobox-1.4.0.dist-info → geobox-1.4.2.dist-info}/METADATA +1 -1
- {geobox-1.4.0.dist-info → geobox-1.4.2.dist-info}/RECORD +17 -17
- {geobox-1.4.0.dist-info → geobox-1.4.2.dist-info}/WHEEL +0 -0
- {geobox-1.4.0.dist-info → geobox-1.4.2.dist-info}/licenses/LICENSE +0 -0
- {geobox-1.4.0.dist-info → geobox-1.4.2.dist-info}/top_level.txt +0 -0
geobox/api.py
CHANGED
|
@@ -29,7 +29,7 @@ from .route import Routing
|
|
|
29
29
|
from .plan import Plan
|
|
30
30
|
from .dashboard import Dashboard
|
|
31
31
|
from .basemap import Basemap
|
|
32
|
-
from .attachment import Attachment
|
|
32
|
+
from .attachment import Attachment
|
|
33
33
|
from .apikey import ApiKey
|
|
34
34
|
from .log import Log
|
|
35
35
|
from .usage import Usage, UsageScale, UsageParam
|
|
@@ -2294,13 +2294,12 @@ class GeoboxClient:
|
|
|
2294
2294
|
return Basemap.proxy_basemap(self, url)
|
|
2295
2295
|
|
|
2296
2296
|
|
|
2297
|
-
def get_attachments(self,
|
|
2297
|
+
def get_attachments(self, resource: Union['Map', 'VectorLayer', 'VectorLayerView'], **kwargs) -> List['Attachment']:
|
|
2298
2298
|
"""
|
|
2299
|
-
Get
|
|
2299
|
+
Get the resouces attachments
|
|
2300
2300
|
|
|
2301
2301
|
Args:
|
|
2302
|
-
|
|
2303
|
-
resource_uuid (str): The Resoource uuid of the attachment.
|
|
2302
|
+
resource (Map | VectorLayer | VectorLayerView): options are: Map, Vector, View objects
|
|
2304
2303
|
|
|
2305
2304
|
Keyword Args:
|
|
2306
2305
|
element_id (str): the id of the element with attachment.
|
|
@@ -2313,12 +2312,17 @@ class GeoboxClient:
|
|
|
2313
2312
|
Returns:
|
|
2314
2313
|
List[Attachment] | int: A list of attachments instances or the total number of attachments.
|
|
2315
2314
|
|
|
2315
|
+
Raises:
|
|
2316
|
+
TypeError: if the resource type is not supported
|
|
2317
|
+
|
|
2316
2318
|
Example:
|
|
2317
2319
|
>>> from geobox import GeoboxClient
|
|
2320
|
+
>>> from geobox.attachment import Attachment
|
|
2318
2321
|
>>> client = GeoboxClient()
|
|
2319
|
-
>>>
|
|
2322
|
+
>>> map = client.get_maps()[0]
|
|
2323
|
+
>>> attachments = client.get_attachments(resource=map)
|
|
2320
2324
|
"""
|
|
2321
|
-
return Attachment.get_attachments(self,
|
|
2325
|
+
return Attachment.get_attachments(self, resource=resource, **kwargs)
|
|
2322
2326
|
|
|
2323
2327
|
|
|
2324
2328
|
def create_attachment(self,
|
geobox/attachment.py
CHANGED
|
@@ -3,7 +3,6 @@ from urllib.parse import urljoin
|
|
|
3
3
|
|
|
4
4
|
from .base import Base
|
|
5
5
|
from .utils import clean_data
|
|
6
|
-
from .enums import AttachmentResourceType
|
|
7
6
|
from .map import Map
|
|
8
7
|
from .vectorlayer import VectorLayer
|
|
9
8
|
from .view import VectorLayerView
|
|
@@ -56,14 +55,13 @@ class Attachment(Base):
|
|
|
56
55
|
|
|
57
56
|
|
|
58
57
|
@classmethod
|
|
59
|
-
def get_attachments(cls, api: 'GeoboxClient',
|
|
58
|
+
def get_attachments(cls, api: 'GeoboxClient', resource: Union['Map', 'VectorLayer', 'VectorLayerView'], **kwargs) -> Union[List['Attachment'], int]:
|
|
60
59
|
"""
|
|
61
60
|
Get list of attachments with optional filtering and pagination.
|
|
62
61
|
|
|
63
62
|
Args:
|
|
64
63
|
api (GeoboxClient): The GeoboxClient instance for making requests.
|
|
65
|
-
|
|
66
|
-
resource_uuid (str): The Resoource uuid of the attachment.
|
|
64
|
+
resource (Map | VectorLayer | VectorLayerView): options are: Map, Vector, View objects
|
|
67
65
|
|
|
68
66
|
Keyword Args:
|
|
69
67
|
element_id (str): the id of the element with attachment.
|
|
@@ -76,17 +74,34 @@ class Attachment(Base):
|
|
|
76
74
|
Returns:
|
|
77
75
|
List[Attachment] | int: A list of attachments instances or the total number of attachments.
|
|
78
76
|
|
|
77
|
+
Raises:
|
|
78
|
+
TypeError: if the resource type is not supported
|
|
79
|
+
|
|
79
80
|
Example:
|
|
80
81
|
>>> from geobox import GeoboxClient
|
|
81
82
|
>>> from geobox.attachment import Attachment
|
|
82
83
|
>>> client = GeoboxClient()
|
|
83
|
-
>>>
|
|
84
|
+
>>> map = client.get_maps()[0]
|
|
85
|
+
>>> attachments = Attachment.get_attachments(client, resource=map, q="name LIKE '%My attachment%'")
|
|
84
86
|
or
|
|
85
|
-
>>> attachments = client.get_attachments(q="name LIKE '%My attachment%'")
|
|
87
|
+
>>> attachments = client.get_attachments(resource=map, q="name LIKE '%My attachment%'")
|
|
86
88
|
"""
|
|
89
|
+
if type(resource) == VectorLayer:
|
|
90
|
+
resource_type = 'vector'
|
|
91
|
+
|
|
92
|
+
elif type(resource) == VectorLayerView:
|
|
93
|
+
resource_type = 'view'
|
|
94
|
+
|
|
95
|
+
elif type(resource) == Map:
|
|
96
|
+
resource_type = 'map'
|
|
97
|
+
|
|
98
|
+
else:
|
|
99
|
+
raise TypeError('resource must be a vectorlayer or view or map object')
|
|
100
|
+
|
|
101
|
+
|
|
87
102
|
params = {
|
|
88
|
-
'resource_type': resource_type
|
|
89
|
-
'resource_uuid':
|
|
103
|
+
'resource_type': resource_type,
|
|
104
|
+
'resource_uuid': resource.uuid,
|
|
90
105
|
'element_id': kwargs.get('element_id'),
|
|
91
106
|
'search': kwargs.get('search'),
|
|
92
107
|
'order_by': kwargs.get('order_by'),
|
|
@@ -155,13 +170,13 @@ class Attachment(Base):
|
|
|
155
170
|
... description="Attachment Description")
|
|
156
171
|
"""
|
|
157
172
|
if isinstance(resource, VectorLayer):
|
|
158
|
-
resource_type =
|
|
173
|
+
resource_type = 'vector'
|
|
159
174
|
|
|
160
175
|
if isinstance(resource, VectorLayerView):
|
|
161
|
-
resource_type =
|
|
176
|
+
resource_type = 'view'
|
|
162
177
|
|
|
163
178
|
if isinstance(resource, Map):
|
|
164
|
-
resource_type =
|
|
179
|
+
resource_type = 'map'
|
|
165
180
|
|
|
166
181
|
data = {
|
|
167
182
|
"name": name,
|
|
@@ -171,7 +186,7 @@ class Attachment(Base):
|
|
|
171
186
|
"loc_y": loc_y,
|
|
172
187
|
"resource_type": resource_type,
|
|
173
188
|
"resource_uuid": resource.uuid,
|
|
174
|
-
"element_id": feature.id,
|
|
189
|
+
"element_id": feature.id if feature else None,
|
|
175
190
|
"file_id": file.id
|
|
176
191
|
}
|
|
177
192
|
return super()._create(api, cls.BASE_ENDPOINT, data, factory_func=lambda api, item: Attachment(api, item['id'], item))
|
geobox/basemap.py
CHANGED
geobox/enums.py
CHANGED
|
@@ -272,14 +272,6 @@ class UserStatus(Enum):
|
|
|
272
272
|
DISABLED = "Disabled"
|
|
273
273
|
|
|
274
274
|
|
|
275
|
-
class AttachmentResourceType(Enum):
|
|
276
|
-
Map = "map"
|
|
277
|
-
|
|
278
|
-
Vector = "vector"
|
|
279
|
-
|
|
280
|
-
View = "view"
|
|
281
|
-
|
|
282
|
-
|
|
283
275
|
class MaxLogPolicy(Enum):
|
|
284
276
|
OverwriteFirstLog = "OverwriteFirstLog"
|
|
285
277
|
|
geobox/log.py
CHANGED
|
@@ -6,6 +6,7 @@ from .base import Base
|
|
|
6
6
|
|
|
7
7
|
if TYPE_CHECKING:
|
|
8
8
|
from . import GeoboxClient
|
|
9
|
+
from .user import User
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class Log(Base):
|
|
@@ -98,4 +99,22 @@ class Log(Base):
|
|
|
98
99
|
>>> log.delete()
|
|
99
100
|
"""
|
|
100
101
|
super().delete(self.endpoint)
|
|
101
|
-
self.log_id = None
|
|
102
|
+
self.log_id = None
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def user(self) -> Union['User', None]:
|
|
107
|
+
"""
|
|
108
|
+
Get the owner user for the log
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
User | None: if the log has owner user
|
|
112
|
+
|
|
113
|
+
Example:
|
|
114
|
+
>>> from geobox import Geobox
|
|
115
|
+
>>> from geopox.log import Log
|
|
116
|
+
>>> client = GeoboxClient()
|
|
117
|
+
>>> log = Log.get_logs(client)[0]
|
|
118
|
+
>>> log.user
|
|
119
|
+
"""
|
|
120
|
+
return self.api.get_user(self.owner_id)
|
geobox/map.py
CHANGED
|
@@ -4,11 +4,15 @@ from urllib.parse import urljoin, urlencode
|
|
|
4
4
|
from .base import Base
|
|
5
5
|
from .utils import clean_data, join_url_params
|
|
6
6
|
from .model3d import Model
|
|
7
|
+
from .file import File
|
|
8
|
+
from .feature import Feature
|
|
7
9
|
|
|
8
10
|
if TYPE_CHECKING:
|
|
9
11
|
from . import GeoboxClient
|
|
10
12
|
from .user import User
|
|
11
13
|
from .task import Task
|
|
14
|
+
from .attachment import Attachment
|
|
15
|
+
|
|
12
16
|
|
|
13
17
|
|
|
14
18
|
class Map(Base):
|
|
@@ -570,11 +574,30 @@ class Map(Base):
|
|
|
570
574
|
'view_settings': {},
|
|
571
575
|
'toc_settings': []
|
|
572
576
|
})
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
def update_settings(self, settings: Dict) -> Dict:
|
|
580
|
+
"""
|
|
581
|
+
Update the settings
|
|
582
|
+
|
|
583
|
+
settings (Dict): settings dictionary
|
|
584
|
+
|
|
585
|
+
Returns:
|
|
586
|
+
Dict: updated settings
|
|
587
|
+
|
|
588
|
+
Example:
|
|
589
|
+
>>> from geobox import GeoboxClient
|
|
590
|
+
>>> client = GeoboxClient()
|
|
591
|
+
>>> map1 = client.get_map(uuid="12345678-1234-5678-1234-567812345678")
|
|
592
|
+
>>> map2 = client.get_map(uuid="12345678-1234-5678-1234-567812345678")
|
|
593
|
+
>>> map1.update_settings(map2.settings)
|
|
594
|
+
"""
|
|
595
|
+
return super()._set_settings(self.endpoint, settings)
|
|
573
596
|
|
|
574
597
|
|
|
575
598
|
def set_settings(self, **kwargs) -> Dict:
|
|
576
599
|
"""
|
|
577
|
-
Set the settings of the map
|
|
600
|
+
Set the settings of the map using keywords
|
|
578
601
|
|
|
579
602
|
Keyword Args:
|
|
580
603
|
map_unit (str): 'latlng' | 'utm'.
|
|
@@ -732,7 +755,7 @@ class Map(Base):
|
|
|
732
755
|
if not response or json:
|
|
733
756
|
return response
|
|
734
757
|
else:
|
|
735
|
-
return [Model(self.api, model['obj'], model) for model in response['objects']]
|
|
758
|
+
return [Model(self.api, model['obj'], model) for model in response['objects'] if response.get('objects')]
|
|
736
759
|
|
|
737
760
|
|
|
738
761
|
def set_models(self, data: Dict) -> List['Model']:
|
|
@@ -767,7 +790,7 @@ class Map(Base):
|
|
|
767
790
|
"""
|
|
768
791
|
endpoint = urljoin(self.endpoint, 'models/')
|
|
769
792
|
response = self.api.put(endpoint, data)
|
|
770
|
-
return [Model(self.api, model['obj'], model) for model in response['objects']]
|
|
793
|
+
return [Model(self.api, model['obj'], model) for model in response['objects'] if response.get('objects')]
|
|
771
794
|
|
|
772
795
|
|
|
773
796
|
def add_model(self,
|
|
@@ -899,3 +922,80 @@ class Map(Base):
|
|
|
899
922
|
endpoint = f"{endpoint}?{query_string}"
|
|
900
923
|
response = self.api.post(endpoint)
|
|
901
924
|
return self.api.get_task(response['task_id'])
|
|
925
|
+
|
|
926
|
+
|
|
927
|
+
def get_attachments(self, **kwargs) -> List['Attachment']:
|
|
928
|
+
"""
|
|
929
|
+
Get the resouces attachments
|
|
930
|
+
|
|
931
|
+
Keyword Args:
|
|
932
|
+
element_id (str): the id of the element with attachment.
|
|
933
|
+
search (str): search term for keyword-based searching among all textual fields.
|
|
934
|
+
order_by (str): comma separated list of fields for sorting results [field1 A|D, field2 A|D, …]. e.g. name A, type D. NOTE: "A" denotes ascending order and "D" denotes descending order.
|
|
935
|
+
skip (int): Number of items to skip. default is 0.
|
|
936
|
+
limit (int): Number of items to return. default is 10.
|
|
937
|
+
return_count (bool): Whether to return total count. default is False.
|
|
938
|
+
|
|
939
|
+
Returns:
|
|
940
|
+
List[Attachment] | int: A list of attachments instances or the total number of attachments.
|
|
941
|
+
|
|
942
|
+
Raises:
|
|
943
|
+
TypeError: if the resource type is not supported
|
|
944
|
+
|
|
945
|
+
Example:
|
|
946
|
+
>>> from geobox import GeoboxClient
|
|
947
|
+
>>> from geobox.map import Map
|
|
948
|
+
>>> client = GeoboxClient()
|
|
949
|
+
>>> map = Map.get_map(client, uuid="12345678-1234-5678-1234-567812345678")
|
|
950
|
+
>>> map.get_attachments()
|
|
951
|
+
"""
|
|
952
|
+
from .attachment import Attachment
|
|
953
|
+
|
|
954
|
+
return Attachment.get_attachments(self.api, resource=self, **kwargs)
|
|
955
|
+
|
|
956
|
+
|
|
957
|
+
def create_attachment(self,
|
|
958
|
+
name: str,
|
|
959
|
+
loc_x: int,
|
|
960
|
+
loc_y: int,
|
|
961
|
+
file: 'File',
|
|
962
|
+
feature: 'Feature' = None,
|
|
963
|
+
display_name: str = None,
|
|
964
|
+
description: str = None) -> 'Attachment':
|
|
965
|
+
"""
|
|
966
|
+
Create a new Attachment.
|
|
967
|
+
|
|
968
|
+
Args:
|
|
969
|
+
name (str): The name of the scene.
|
|
970
|
+
loc_x (int): x parameter of the attachment location.
|
|
971
|
+
loc_y (int): y parameter of the attachment location.
|
|
972
|
+
file (File): the file object.
|
|
973
|
+
feature (Feature, optional): the feature object.
|
|
974
|
+
display_name (str, optional): The display name of the scene.
|
|
975
|
+
description (str, optional): The description of the scene.
|
|
976
|
+
|
|
977
|
+
Returns:
|
|
978
|
+
Attachment: The newly created Attachment instance.
|
|
979
|
+
|
|
980
|
+
Raises:
|
|
981
|
+
ValidationError: If the Attachment data is invalid.
|
|
982
|
+
|
|
983
|
+
Example:
|
|
984
|
+
>>> from geobox import GeoboxClient
|
|
985
|
+
>>> from geobox.map import Map
|
|
986
|
+
>>> client = GeoboxClient()
|
|
987
|
+
>>> map = Map.get_map(client, uuid="12345678-1234-5678-1234-567812345678")
|
|
988
|
+
>>> file = client.get_files()[0]
|
|
989
|
+
>>> map.create_attachment(name='test', loc_x=10, loc_y=10, file=file)
|
|
990
|
+
"""
|
|
991
|
+
from .attachment import Attachment
|
|
992
|
+
|
|
993
|
+
return Attachment.create_attachment(self.api,
|
|
994
|
+
name=name,
|
|
995
|
+
loc_x=loc_x,
|
|
996
|
+
loc_y=loc_y,
|
|
997
|
+
resource=self,
|
|
998
|
+
file=file,
|
|
999
|
+
feature=feature,
|
|
1000
|
+
display_name=display_name,
|
|
1001
|
+
description=description)
|
geobox/model3d.py
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
from typing import Dict, List, Optional, Optional, Union, TYPE_CHECKING
|
|
2
2
|
from urllib.parse import urljoin, urlencode
|
|
3
|
+
import os
|
|
4
|
+
import zipfile
|
|
5
|
+
import sys
|
|
6
|
+
import requests
|
|
7
|
+
import mimetypes
|
|
3
8
|
|
|
4
9
|
from .base import Base
|
|
5
10
|
from .exception import ApiRequestError
|
|
@@ -216,33 +221,113 @@ class Model(Base):
|
|
|
216
221
|
super().delete(self.endpoint)
|
|
217
222
|
|
|
218
223
|
|
|
219
|
-
def
|
|
224
|
+
def _get_save_path(self, save_path: str = None) -> str:
|
|
220
225
|
"""
|
|
221
|
-
Get the
|
|
226
|
+
Get the path where the file should be saved.
|
|
227
|
+
|
|
228
|
+
Args:
|
|
229
|
+
save_path (str, optional): The path to save the file.
|
|
222
230
|
|
|
223
231
|
Returns:
|
|
224
|
-
|
|
232
|
+
str: The path where the file is saved.
|
|
233
|
+
|
|
234
|
+
Raises:
|
|
235
|
+
ValueError: If save_path does not end with a '/'.
|
|
236
|
+
|
|
237
|
+
Example:
|
|
238
|
+
>>> from geobox import GeoboxClient
|
|
239
|
+
>>> from geobox.file import File
|
|
240
|
+
>>> from geobox import GeoboxClient
|
|
241
|
+
>>> client = GeoboxClient()
|
|
242
|
+
>>> file_path = File.get_file(client, uuid="12345678-1234-5678-1234-567812345678")
|
|
243
|
+
"""
|
|
244
|
+
# If save_path is provided, check if it ends with a '/'
|
|
245
|
+
if save_path and save_path.endswith('/'):
|
|
246
|
+
return f'{save_path}'
|
|
247
|
+
|
|
248
|
+
if save_path and not save_path.endswith('/'):
|
|
249
|
+
raise ValueError("save_path must end with a '/'")
|
|
250
|
+
|
|
251
|
+
return os.getcwd()
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def _create_progress_bar(self) -> 'tqdm':
|
|
255
|
+
"""Creates a progress bar for the task."""
|
|
256
|
+
try:
|
|
257
|
+
from tqdm.auto import tqdm
|
|
258
|
+
except ImportError:
|
|
259
|
+
from .api import logger
|
|
260
|
+
logger.warning("[tqdm] extra is required to show the progress bar. install with: pip insatll geobox[tqdm]")
|
|
261
|
+
return None
|
|
262
|
+
|
|
263
|
+
return tqdm(unit="B",
|
|
264
|
+
total=int(self.size),
|
|
265
|
+
file=sys.stdout,
|
|
266
|
+
dynamic_ncols=True,
|
|
267
|
+
desc="Downloading",
|
|
268
|
+
unit_scale=True,
|
|
269
|
+
unit_divisor=1024,
|
|
270
|
+
ascii=True
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def download(self, save_path: str = None, progress_bar: bool = True) -> str:
|
|
275
|
+
"""
|
|
276
|
+
Download the 3D model, save it as a .glb file, zip it, and return the zip file path.
|
|
277
|
+
|
|
278
|
+
Args:
|
|
279
|
+
save_path (str, optional): Directory where the file should be saved.
|
|
280
|
+
progress_bar (bool, optional): Whether to show a progress bar. Default: True
|
|
281
|
+
|
|
282
|
+
Returns:
|
|
283
|
+
str: Path to the .zip file containing the .glb model.
|
|
225
284
|
|
|
226
285
|
Raises:
|
|
227
286
|
ApiRequestError: If the API request fails.
|
|
228
287
|
|
|
229
288
|
Example:
|
|
230
289
|
>>> from geobox import GeoboxClient
|
|
231
|
-
>>> from geobox.model3d import Model
|
|
232
290
|
>>> client = GeoboxClient()
|
|
233
|
-
>>> model =
|
|
234
|
-
>>>
|
|
235
|
-
>>> # Save the content to a file
|
|
236
|
-
>>> with open('model.gltf', 'wb') as f:
|
|
237
|
-
... f.write(content)
|
|
291
|
+
>>> model = client.get_models()[0]
|
|
292
|
+
>>> model.get_content()
|
|
238
293
|
"""
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
if
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
294
|
+
if not self.uuid:
|
|
295
|
+
raise ValueError("Model UUID is required to download content")
|
|
296
|
+
|
|
297
|
+
if self.data.get('obj'):
|
|
298
|
+
model = self.api.get_model(self.obj)
|
|
299
|
+
else:
|
|
300
|
+
model = self
|
|
301
|
+
|
|
302
|
+
save_path = model._get_save_path(save_path)
|
|
303
|
+
os.makedirs(save_path, exist_ok=True)
|
|
304
|
+
|
|
305
|
+
endpoint = urljoin(model.api.base_url, f"{model.endpoint}/content/")
|
|
306
|
+
with model.api.session.get(endpoint, stream=True) as response:
|
|
307
|
+
if response.status_code != 200:
|
|
308
|
+
raise ApiRequestError(f"Failed to get model content: {response.status_code}")
|
|
309
|
+
|
|
310
|
+
glb_filename = f"{model.name}.glb"
|
|
311
|
+
glb_path = os.path.join(save_path, glb_filename)
|
|
312
|
+
|
|
313
|
+
with open(glb_path, "wb") as f:
|
|
314
|
+
pbar = model._create_progress_bar() if progress_bar else None
|
|
315
|
+
for chunk in response.iter_content(chunk_size=8192):
|
|
316
|
+
f.write(chunk)
|
|
317
|
+
if pbar:
|
|
318
|
+
pbar.update(len(chunk))
|
|
319
|
+
pbar.refresh()
|
|
320
|
+
if pbar:
|
|
321
|
+
pbar.close()
|
|
322
|
+
|
|
323
|
+
zip_filename = f"{model.name}.zip"
|
|
324
|
+
zip_path = os.path.join(save_path, zip_filename)
|
|
325
|
+
with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zipf:
|
|
326
|
+
zipf.write(glb_path, arcname=os.path.basename(glb_path))
|
|
327
|
+
|
|
328
|
+
os.remove(glb_path)
|
|
329
|
+
|
|
330
|
+
return os.path.abspath(zip_path)
|
|
246
331
|
|
|
247
332
|
|
|
248
333
|
@property
|
geobox/mosaic.py
CHANGED
|
@@ -401,6 +401,25 @@ class Mosaic(Raster):
|
|
|
401
401
|
"""
|
|
402
402
|
return super().settings
|
|
403
403
|
|
|
404
|
+
|
|
405
|
+
def update_settings(self, settings: Dict) -> Dict:
|
|
406
|
+
"""
|
|
407
|
+
Update the settings
|
|
408
|
+
|
|
409
|
+
settings (Dict): settings dictionary
|
|
410
|
+
|
|
411
|
+
Returns:
|
|
412
|
+
Dict: updated settings
|
|
413
|
+
|
|
414
|
+
Example:
|
|
415
|
+
>>> from geobox import GeoboxClient
|
|
416
|
+
>>> client = GeoboxClient()
|
|
417
|
+
>>> mosaic1 = client.get_mosaic(uuid="12345678-1234-5678-1234-567812345678")
|
|
418
|
+
>>> mosaic2 = client.get_mosaic(uuid="12345678-1234-5678-1234-567812345678")
|
|
419
|
+
>>> mosaic1.update_settings(mosaic2.settings)
|
|
420
|
+
"""
|
|
421
|
+
return super().update_settings(settings)
|
|
422
|
+
|
|
404
423
|
|
|
405
424
|
def set_settings(self, **kwargs) -> None:
|
|
406
425
|
"""
|
geobox/query.py
CHANGED
|
@@ -179,7 +179,7 @@ class Query(Base):
|
|
|
179
179
|
|
|
180
180
|
|
|
181
181
|
@classmethod
|
|
182
|
-
def create_query(cls, api: 'GeoboxClient', name: str, display_name: str = None, sql: str = None, params: List = None) -> 'Query':
|
|
182
|
+
def create_query(cls, api: 'GeoboxClient', name: str, display_name: str = None, description:str = None, sql: str = None, params: List = None) -> 'Query':
|
|
183
183
|
"""
|
|
184
184
|
Creates a new query.
|
|
185
185
|
|
|
@@ -187,6 +187,7 @@ class Query(Base):
|
|
|
187
187
|
api (Api): The GeoboxClient instance for making requests.
|
|
188
188
|
name (str): The name of the query.
|
|
189
189
|
display_name (str, optional): The display name of the query.
|
|
190
|
+
description (str, optional): The description of the query.
|
|
190
191
|
sql (str, optional): The SQL statement for the query.
|
|
191
192
|
params (list, optional): The parameters for the SQL statement.
|
|
192
193
|
|
|
@@ -204,6 +205,7 @@ class Query(Base):
|
|
|
204
205
|
data = {
|
|
205
206
|
"name": name,
|
|
206
207
|
"display_name": display_name,
|
|
208
|
+
"description": description,
|
|
207
209
|
"sql": sql,
|
|
208
210
|
"params": params
|
|
209
211
|
}
|
geobox/raster.py
CHANGED
|
@@ -641,6 +641,25 @@ class Raster(Base):
|
|
|
641
641
|
>>> raster.settings
|
|
642
642
|
"""
|
|
643
643
|
return super()._get_settings(self.endpoint)
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
def update_settings(self, settings: Dict) -> Dict:
|
|
647
|
+
"""
|
|
648
|
+
Update the settings
|
|
649
|
+
|
|
650
|
+
settings (Dict): settings dictionary
|
|
651
|
+
|
|
652
|
+
Returns:
|
|
653
|
+
Dict: updated settings
|
|
654
|
+
|
|
655
|
+
Example:
|
|
656
|
+
>>> from geobox import GeoboxClient
|
|
657
|
+
>>> client = GeoboxClient()
|
|
658
|
+
>>> raster1 = client.get_raster(uuid="12345678-1234-5678-1234-567812345678")
|
|
659
|
+
>>> raster2 = client.get_raster(uuid="12345678-1234-5678-1234-567812345678")
|
|
660
|
+
>>> raster1.update_settings(raster2.settings)
|
|
661
|
+
"""
|
|
662
|
+
return super()._set_settings(self.endpoint, settings)
|
|
644
663
|
|
|
645
664
|
|
|
646
665
|
def set_settings(self, **kwargs) -> None:
|
geobox/vectorlayer.py
CHANGED
|
@@ -11,12 +11,13 @@ from .task import Task
|
|
|
11
11
|
from .enums import InputGeomType, FileOutputFormat
|
|
12
12
|
from .version import VectorLayerVersion
|
|
13
13
|
|
|
14
|
-
|
|
15
14
|
if TYPE_CHECKING:
|
|
16
15
|
from .api import GeoboxClient
|
|
17
16
|
from .view import VectorLayerView
|
|
18
17
|
from .user import User
|
|
19
18
|
from .file import File
|
|
19
|
+
from .attachment import Attachment
|
|
20
|
+
|
|
20
21
|
|
|
21
22
|
class VectorLayer(Base):
|
|
22
23
|
"""
|
|
@@ -1061,6 +1062,25 @@ class VectorLayer(Base):
|
|
|
1061
1062
|
>>> setting = layer.setting
|
|
1062
1063
|
"""
|
|
1063
1064
|
return super()._get_settings(endpoint=self.endpoint)
|
|
1065
|
+
|
|
1066
|
+
|
|
1067
|
+
def update_settings(self, settings: Dict) -> Dict:
|
|
1068
|
+
"""
|
|
1069
|
+
Update the settings
|
|
1070
|
+
|
|
1071
|
+
settings (Dict): settings dictionary
|
|
1072
|
+
|
|
1073
|
+
Returns:
|
|
1074
|
+
Dict: updated settings
|
|
1075
|
+
|
|
1076
|
+
Example:
|
|
1077
|
+
>>> from geobox import GeoboxClient
|
|
1078
|
+
>>> client = GeoboxClient()
|
|
1079
|
+
>>> layer1 = client.get_vector(uuid="12345678-1234-5678-1234-567812345678")
|
|
1080
|
+
>>> layer2 = client.get_vector(uuid="12345678-1234-5678-1234-567812345678")
|
|
1081
|
+
>>> layer1.update_settings(layer2.settings)
|
|
1082
|
+
"""
|
|
1083
|
+
return super()._set_settings(self.endpoint, settings)
|
|
1064
1084
|
|
|
1065
1085
|
|
|
1066
1086
|
def set_settings(self, **kwargs) -> Dict:
|
|
@@ -1227,4 +1247,81 @@ class VectorLayer(Base):
|
|
|
1227
1247
|
>>> layer.prune_edited_areas()
|
|
1228
1248
|
"""
|
|
1229
1249
|
endpoint = urljoin(self.endpoint, 'prune/')
|
|
1230
|
-
return self.api.post(endpoint)
|
|
1250
|
+
return self.api.post(endpoint)
|
|
1251
|
+
|
|
1252
|
+
|
|
1253
|
+
def get_attachments(self, **kwargs) -> List['Attachment']:
|
|
1254
|
+
"""
|
|
1255
|
+
Get the resouces attachments
|
|
1256
|
+
|
|
1257
|
+
Keyword Args:
|
|
1258
|
+
element_id (str): the id of the element with attachment.
|
|
1259
|
+
search (str): search term for keyword-based searching among all textual fields.
|
|
1260
|
+
order_by (str): comma separated list of fields for sorting results [field1 A|D, field2 A|D, …]. e.g. name A, type D. NOTE: "A" denotes ascending order and "D" denotes descending order.
|
|
1261
|
+
skip (int): Number of items to skip. default is 0.
|
|
1262
|
+
limit (int): Number of items to return. default is 10.
|
|
1263
|
+
return_count (bool): Whether to return total count. default is False.
|
|
1264
|
+
|
|
1265
|
+
Returns:
|
|
1266
|
+
List[Attachment] | int: A list of attachments instances or the total number of attachments.
|
|
1267
|
+
|
|
1268
|
+
Raises:
|
|
1269
|
+
TypeError: if the resource type is not supported
|
|
1270
|
+
|
|
1271
|
+
Example:
|
|
1272
|
+
>>> from geobox import GeoboxClient
|
|
1273
|
+
>>> from geobox.vectorlayer import VectorLayer
|
|
1274
|
+
>>> client = GeoboxClient()
|
|
1275
|
+
>>> layer = VectorLayer.get_vector(api=client, uuid="12345678-1234-5678-1234-567812345678")
|
|
1276
|
+
>>> layer.get_attachments()
|
|
1277
|
+
"""
|
|
1278
|
+
from .attachment import Attachment
|
|
1279
|
+
|
|
1280
|
+
return Attachment.get_attachments(self.api, resource=self, **kwargs)
|
|
1281
|
+
|
|
1282
|
+
|
|
1283
|
+
def create_attachment(self,
|
|
1284
|
+
name: str,
|
|
1285
|
+
loc_x: int,
|
|
1286
|
+
loc_y: int,
|
|
1287
|
+
file: 'File',
|
|
1288
|
+
feature: 'Feature' = None,
|
|
1289
|
+
display_name: str = None,
|
|
1290
|
+
description: str = None) -> 'Attachment':
|
|
1291
|
+
"""
|
|
1292
|
+
Create a new Attachment.
|
|
1293
|
+
|
|
1294
|
+
Args:
|
|
1295
|
+
name (str): The name of the scene.
|
|
1296
|
+
loc_x (int): x parameter of the attachment location.
|
|
1297
|
+
loc_y (int): y parameter of the attachment location.
|
|
1298
|
+
file (File): the file object.
|
|
1299
|
+
feature (Feature, optional): the feature object.
|
|
1300
|
+
display_name (str, optional): The display name of the scene.
|
|
1301
|
+
description (str, optional): The description of the scene.
|
|
1302
|
+
|
|
1303
|
+
Returns:
|
|
1304
|
+
Attachment: The newly created Attachment instance.
|
|
1305
|
+
|
|
1306
|
+
Raises:
|
|
1307
|
+
ValidationError: If the Attachment data is invalid.
|
|
1308
|
+
|
|
1309
|
+
Example:
|
|
1310
|
+
>>> from geobox import GeoboxClient
|
|
1311
|
+
>>> from geobox.vectorlayer import VectorLayer
|
|
1312
|
+
>>> client = GeoboxClient()
|
|
1313
|
+
>>> layer = VectorLayer.get_vector(api=client, uuid="12345678-1234-5678-1234-567812345678")
|
|
1314
|
+
>>> file = client.get_files()[0]
|
|
1315
|
+
>>> layer.create_attachment(name='test', loc_x=10, loc_y=10, file=file)
|
|
1316
|
+
"""
|
|
1317
|
+
from .attachment import Attachment
|
|
1318
|
+
|
|
1319
|
+
return Attachment.create_attachment(self.api,
|
|
1320
|
+
name=name,
|
|
1321
|
+
loc_x=loc_x,
|
|
1322
|
+
loc_y=loc_y,
|
|
1323
|
+
resource=self,
|
|
1324
|
+
file=file,
|
|
1325
|
+
feature=feature,
|
|
1326
|
+
display_name=display_name,
|
|
1327
|
+
description=description)
|
geobox/view.py
CHANGED
|
@@ -7,9 +7,11 @@ if TYPE_CHECKING:
|
|
|
7
7
|
from . import GeoboxClient
|
|
8
8
|
from .field import Field
|
|
9
9
|
from .user import User
|
|
10
|
-
from .enums import InputGeomType
|
|
10
|
+
from .enums import InputGeomType
|
|
11
11
|
from .task import Task
|
|
12
12
|
from .file import File
|
|
13
|
+
from .attachment import Attachment
|
|
14
|
+
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
class VectorLayerView(VectorLayer):
|
|
@@ -720,6 +722,25 @@ class VectorLayerView(VectorLayer):
|
|
|
720
722
|
return super().settings
|
|
721
723
|
|
|
722
724
|
|
|
725
|
+
def update_settings(self, settings: Dict) -> Dict:
|
|
726
|
+
"""
|
|
727
|
+
Update the settings
|
|
728
|
+
|
|
729
|
+
settings (Dict): settings dictionary
|
|
730
|
+
|
|
731
|
+
Returns:
|
|
732
|
+
Dict: updated settings
|
|
733
|
+
|
|
734
|
+
Example:
|
|
735
|
+
>>> from geobox import GeoboxClient
|
|
736
|
+
>>> client = GeoboxClient()
|
|
737
|
+
>>> view1 = client.get_view(uuid="12345678-1234-5678-1234-567812345678")
|
|
738
|
+
>>> view2 = client.get_view(uuid="12345678-1234-5678-1234-567812345678")
|
|
739
|
+
>>> view1.update_settings(view2.settings)
|
|
740
|
+
"""
|
|
741
|
+
return super().update_settings(settings)
|
|
742
|
+
|
|
743
|
+
|
|
723
744
|
def set_settings(self, **kwargs) -> Dict:
|
|
724
745
|
"""
|
|
725
746
|
Set the settings of the Vector Layer.
|
|
@@ -862,3 +883,80 @@ class VectorLayerView(VectorLayer):
|
|
|
862
883
|
>>> view.prune_edited_areas()
|
|
863
884
|
"""
|
|
864
885
|
return super().prune_edited_areas()
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
def get_attachments(self, **kwargs) -> List['Attachment']:
|
|
889
|
+
"""
|
|
890
|
+
Get the resouces attachments
|
|
891
|
+
|
|
892
|
+
Keyword Args:
|
|
893
|
+
element_id (str): the id of the element with attachment.
|
|
894
|
+
search (str): search term for keyword-based searching among all textual fields.
|
|
895
|
+
order_by (str): comma separated list of fields for sorting results [field1 A|D, field2 A|D, …]. e.g. name A, type D. NOTE: "A" denotes ascending order and "D" denotes descending order.
|
|
896
|
+
skip (int): Number of items to skip. default is 0.
|
|
897
|
+
limit (int): Number of items to return. default is 10.
|
|
898
|
+
return_count (bool): Whether to return total count. default is False.
|
|
899
|
+
|
|
900
|
+
Returns:
|
|
901
|
+
List[Attachment] | int: A list of attachments instances or the total number of attachments.
|
|
902
|
+
|
|
903
|
+
Raises:
|
|
904
|
+
TypeError: if the resource type is not supported
|
|
905
|
+
|
|
906
|
+
Example:
|
|
907
|
+
>>> from geobox import GeoboxClient
|
|
908
|
+
>>> from geobox.view import VectorLayerView
|
|
909
|
+
>>> client = GeoboxClient()
|
|
910
|
+
>>> view = VectorLayerView.get_view(client, uuid="12345678-1234-5678-1234-567812345678")
|
|
911
|
+
>>> view.get_attachments()
|
|
912
|
+
"""
|
|
913
|
+
from .attachment import Attachment
|
|
914
|
+
|
|
915
|
+
return Attachment.get_attachments(self.api, resource=self, **kwargs)
|
|
916
|
+
|
|
917
|
+
|
|
918
|
+
def create_attachment(self,
|
|
919
|
+
name: str,
|
|
920
|
+
loc_x: int,
|
|
921
|
+
loc_y: int,
|
|
922
|
+
file: 'File',
|
|
923
|
+
feature: 'Feature' = None,
|
|
924
|
+
display_name: str = None,
|
|
925
|
+
description: str = None) -> 'Attachment':
|
|
926
|
+
"""
|
|
927
|
+
Create a new Attachment.
|
|
928
|
+
|
|
929
|
+
Args:
|
|
930
|
+
name (str): The name of the scene.
|
|
931
|
+
loc_x (int): x parameter of the attachment location.
|
|
932
|
+
loc_y (int): y parameter of the attachment location.
|
|
933
|
+
file (File): the file object.
|
|
934
|
+
feature (Feature, optional): the feature object.
|
|
935
|
+
display_name (str, optional): The display name of the scene.
|
|
936
|
+
description (str, optional): The description of the scene.
|
|
937
|
+
|
|
938
|
+
Returns:
|
|
939
|
+
Attachment: The newly created Attachment instance.
|
|
940
|
+
|
|
941
|
+
Raises:
|
|
942
|
+
ValidationError: If the Attachment data is invalid.
|
|
943
|
+
|
|
944
|
+
Example:
|
|
945
|
+
>>> from geobox import GeoboxClient
|
|
946
|
+
>>> from geobox.view import VectorLayerView
|
|
947
|
+
>>> client = GeoboxClient()
|
|
948
|
+
>>> view = VectorLayerView.get_view(client, uuid="12345678-1234-5678-1234-567812345678")
|
|
949
|
+
>>> file = client.get_files()[0]
|
|
950
|
+
>>> view.create_attachment(name='test', loc_x=10, loc_y=10, file=file)
|
|
951
|
+
"""
|
|
952
|
+
from .attachment import Attachment
|
|
953
|
+
|
|
954
|
+
return Attachment.create_attachment(self.api,
|
|
955
|
+
name=name,
|
|
956
|
+
loc_x=loc_x,
|
|
957
|
+
loc_y=loc_y,
|
|
958
|
+
resource=self,
|
|
959
|
+
file=file,
|
|
960
|
+
feature=feature,
|
|
961
|
+
display_name=display_name,
|
|
962
|
+
description=description)
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
geobox/__init__.py,sha256=iRkJAFIjMXiAaLTVXvZcW5HM7ttyipGdxFZ15NCM8qU,1895
|
|
2
|
-
geobox/api.py,sha256=
|
|
2
|
+
geobox/api.py,sha256=8wO1AvyIWf0n2gi-Jv22IM6gyjtbX4KGBYXJTKTh01A,105230
|
|
3
3
|
geobox/apikey.py,sha256=OXsf1ltXcN1jIQJHECdnIE5R_Qksb897xVJOkORRsxw,7522
|
|
4
|
-
geobox/attachment.py,sha256=
|
|
4
|
+
geobox/attachment.py,sha256=Q5LVn2j8gm-CptDVhpqtfzyQTDDd1FjW_9MEJBRQb6M,11865
|
|
5
5
|
geobox/base.py,sha256=OdabLbBflglLkNWM7TGCWtPh73M_-42_Ph963K26JQg,12931
|
|
6
|
-
geobox/basemap.py,sha256=
|
|
6
|
+
geobox/basemap.py,sha256=fQhCj6ERYCEaY4RLINrftEt4RDakddKZ-wG9Av4Rv_8,4468
|
|
7
7
|
geobox/dashboard.py,sha256=x99jUGzUJra4cdcffSYC0_FvrihZh6sPI4o79f-Aptc,11694
|
|
8
|
-
geobox/enums.py,sha256=
|
|
8
|
+
geobox/enums.py,sha256=Ur8zbUjfx09oxXb-uzwFfDT_Nt8I4AP5pFQKJ9bxVxI,6204
|
|
9
9
|
geobox/exception.py,sha256=jvpnv0M2Ck1FpxHTL_aKYWxGvLnCQ3d9vOrMIktjw1U,1507
|
|
10
10
|
geobox/feature.py,sha256=3Kbc1LjIkBt1YqRAry84BrR7qxx9BexvBB3YQ8D9mGk,18504
|
|
11
11
|
geobox/field.py,sha256=p9eitUpnsiGj6GUhjSomk6HWlsNJSbE-Oh_4VcjaqVo,10562
|
|
12
12
|
geobox/file.py,sha256=cMm-SwTzRKALiIj-gkY4UJzUsOuN5SGz50eU1ylNAxk,20079
|
|
13
13
|
geobox/layout.py,sha256=TdE5FJ7fzbhkexojY8h-r68hXb5UYM6MIfNkxfs_RKA,11285
|
|
14
|
-
geobox/log.py,sha256=
|
|
15
|
-
geobox/map.py,sha256=
|
|
16
|
-
geobox/model3d.py,sha256=
|
|
17
|
-
geobox/mosaic.py,sha256=
|
|
14
|
+
geobox/log.py,sha256=Xuq4oKPwaypZ4nYEOIXu13dH4AkQcf0pkTw85gDQqS4,4063
|
|
15
|
+
geobox/map.py,sha256=kksFBS79TOKN9KBByXzj2atSvZhIAuMA85hSjo_szeA,36788
|
|
16
|
+
geobox/model3d.py,sha256=acT5dXwq3Lmhfq5-cPOnYJMZR1gzj3cfF6kyxMleHag,14924
|
|
17
|
+
geobox/mosaic.py,sha256=zKo6cEtaqz7fFcWIzhURxZIkICUQlpEhpFBjGJ5GJ1M,24385
|
|
18
18
|
geobox/plan.py,sha256=jUzl6CQBY6IsdieEppJOmE0sSjwvu6eHO89pC_JFs6I,12066
|
|
19
|
-
geobox/query.py,sha256=
|
|
20
|
-
geobox/raster.py,sha256=
|
|
19
|
+
geobox/query.py,sha256=ubS1Og3rC_6-zW-cbR30o7bZw2MZNZY652VLCvVvmWE,24173
|
|
20
|
+
geobox/raster.py,sha256=fTIM9HKVddaFfO9o-mEbZSM31qpCr6KAszguInZjd2A,30702
|
|
21
21
|
geobox/route.py,sha256=cKZTTHBHM8woWbhHIpCvrRX_doJcTkGktouee0z7oG0,2723
|
|
22
22
|
geobox/scene.py,sha256=GEzvWB-l-xO-8IodwFAPt4T7lZxuzEKJ1H0cqfx78W4,11301
|
|
23
23
|
geobox/settings.py,sha256=rGRdM18Vo7xnjfZXPLRMbKeoVC_lZmzkNRPS0SQv05o,5660
|
|
@@ -27,12 +27,12 @@ geobox/tileset.py,sha256=bQOckE04F31vb-NYmNsQzXndZSTDZyskWspRikjZuBs,24241
|
|
|
27
27
|
geobox/usage.py,sha256=_54xL-n-2Bg9wGpoOBKnh85WqdpMWEtqxRJVaFlVWe0,7908
|
|
28
28
|
geobox/user.py,sha256=YY72uRvjKUUWUZbxhrft37FVBlqDeosPMf3EpMVBhc0,15069
|
|
29
29
|
geobox/utils.py,sha256=qLtchKIdw-az3KCiiFv0-Cpmx9RfBxORjlATvVyDIaQ,1314
|
|
30
|
-
geobox/vectorlayer.py,sha256=
|
|
30
|
+
geobox/vectorlayer.py,sha256=s8zH68ALeBvep5bW5wuHkDm9x07Z52GhPaeDbznJ3wY,57066
|
|
31
31
|
geobox/version.py,sha256=0GLPhxCeEb2bAkdpPJWtXPXc1KP6kQ_TOMwLAL0ldo0,9374
|
|
32
|
-
geobox/view.py,sha256=
|
|
32
|
+
geobox/view.py,sha256=xAxBhxwoWAoiG8YJBEF93UJ4e4VeJx17rZpfdl2Q8DU,41507
|
|
33
33
|
geobox/workflow.py,sha256=_WEIy1zLpBFx5yeuZ4ClnwPdU90jQbdy5bWYYIRa4JY,11549
|
|
34
|
-
geobox-1.4.
|
|
35
|
-
geobox-1.4.
|
|
36
|
-
geobox-1.4.
|
|
37
|
-
geobox-1.4.
|
|
38
|
-
geobox-1.4.
|
|
34
|
+
geobox-1.4.2.dist-info/licenses/LICENSE,sha256=AvFB7W94sJYKLDhBxLRshL3upexCOG8HQY_1JibB96w,1063
|
|
35
|
+
geobox-1.4.2.dist-info/METADATA,sha256=5-4FR_CCE6LGfz96_urdMuEjN1s0xikKEn8vG2Q5WPI,2658
|
|
36
|
+
geobox-1.4.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
37
|
+
geobox-1.4.2.dist-info/top_level.txt,sha256=ppXH8Bu2mlB-pLQ6lsoWEm2Gr6wZx1uzkhetsYA5ins,7
|
|
38
|
+
geobox-1.4.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|