|
1 | 1 | """Client presentation methods for labels.""" |
2 | 2 |
|
3 | 3 | # pylint: disable=too-many-lines |
| 4 | +import json |
4 | 5 | import warnings |
5 | 6 | from itertools import repeat |
6 | 7 | from typing import ( |
|
16 | 17 | overload, |
17 | 18 | ) |
18 | 19 |
|
| 20 | +from kili_formats.format.geojson import geojson_feature_collection_to_kili_json_response |
19 | 21 | from typeguard import typechecked |
20 | 22 |
|
21 | 23 | from kili.adapters.kili_api_gateway.helpers.queries import QueryOptions |
@@ -1399,3 +1401,65 @@ def append_labels_from_shapefiles( |
1399 | 1401 | json_response_array=[json_response], |
1400 | 1402 | asset_external_id_array=[asset_external_id], |
1401 | 1403 | ) |
| 1404 | + |
| 1405 | + @typechecked |
| 1406 | + def append_labels_from_geojson_files( |
| 1407 | + self, |
| 1408 | + project_id: str, |
| 1409 | + asset_external_id: str, |
| 1410 | + geojson_file_paths: List[str], |
| 1411 | + ): |
| 1412 | + """Import and convert GeoJSON files into annotations for a specific asset in a Kili project. |
| 1413 | +
|
| 1414 | + This method processes GeoJSON feature collections, converts them to the appropriate |
| 1415 | + Kili annotation format, and appends them as labels to the specified asset. |
| 1416 | + The GeoJSON features must contain job names and category information in their properties. |
| 1417 | +
|
| 1418 | + Args: |
| 1419 | + project_id: The ID of the Kili project to add the labels to. |
| 1420 | + asset_external_id: The external ID of the asset to label. |
| 1421 | + geojson_file_paths: List of file paths to the GeoJSON files to be processed. |
| 1422 | + Each file should contain a FeatureCollection with features that have |
| 1423 | + 'kili' metadata in their properties, including 'job', 'type', and 'categories'. |
| 1424 | +
|
| 1425 | + Note: |
| 1426 | + The GeoJSON features must contain a 'kili' property with the following structure: |
| 1427 | + - 'job': The name of the job in the Kili project |
| 1428 | + - 'type': The annotation type ('marker', 'polyline', 'semantic', etc.) |
| 1429 | + - 'categories': List of category objects with 'name' field |
| 1430 | +
|
| 1431 | + Supported geometries: Point, LineString, Polygon, and MultiPolygon. |
| 1432 | + Polygon and MultiPolygon are always mapped to semantic segmentation jobs in Kili. |
| 1433 | +
|
| 1434 | + Examples: |
| 1435 | + >>> kili.append_labels_from_geojson_files( |
| 1436 | + project_id="project_id", |
| 1437 | + asset_external_id="asset_1", |
| 1438 | + geojson_file_paths=["annotations.geojson"] |
| 1439 | + ) |
| 1440 | + """ |
| 1441 | + merged_json_response = {} |
| 1442 | + |
| 1443 | + for file_path in geojson_file_paths: |
| 1444 | + with open(file_path, encoding="utf-8") as f: |
| 1445 | + feature_collection = json.load(f) |
| 1446 | + |
| 1447 | + json_response = geojson_feature_collection_to_kili_json_response(feature_collection) |
| 1448 | + |
| 1449 | + for job_name, job_data in json_response.items(): |
| 1450 | + if job_name not in merged_json_response: |
| 1451 | + merged_json_response[job_name] = job_data |
| 1452 | + else: |
| 1453 | + for key, value in job_data.items(): |
| 1454 | + if key == "annotations": |
| 1455 | + merged_json_response[job_name].setdefault("annotations", []).extend( |
| 1456 | + value |
| 1457 | + ) |
| 1458 | + else: |
| 1459 | + merged_json_response[job_name][key] = value |
| 1460 | + |
| 1461 | + self.append_labels( |
| 1462 | + project_id=project_id, |
| 1463 | + json_response_array=[merged_json_response], |
| 1464 | + asset_external_id_array=[asset_external_id], |
| 1465 | + ) |
0 commit comments