Skip to content

Commit fdf59c5

Browse files
authored
Merge pull request #1926 from kili-technology/feature/lab-3719-aau-i-can-upload-geojson-labels-directly-without-conversion
feat(LAB-3719): add `append_labels_from_geojson_files` method
2 parents 7cc7394 + 1c5aba4 commit fdf59c5

File tree

4 files changed

+1333
-1185
lines changed

4 files changed

+1333
-1185
lines changed

pyproject.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ dependencies = [
4444
"filelock >= 3.0.0, < 4.0.0",
4545
"pip-system-certs >= 4.0.0, < 5.0.0; platform_system=='Windows'",
4646
"pyrate-limiter >= 3, < 4",
47-
"kili-formats == 0.2.3"
47+
"kili-formats == 0.2.7"
4848
]
4949
urls = { homepage = "https://github.com/kili-technology/kili-python-sdk" }
5050

@@ -84,7 +84,7 @@ dev = [
8484
"vulture==2.11",
8585
"dead==1.5.2",
8686
# optional dependencies
87-
"kili-formats[all] == 0.2.3",
87+
"kili-formats[all] == 0.2.7",
8888
"opencv-python >= 4.0.0, < 5.0.0",
8989
"azure-storage-blob >= 12.0.0, < 13.0.0",
9090
# optional dependencies gis
@@ -101,7 +101,7 @@ dev = [
101101
all = [
102102
# aggregate all optional deps without dev
103103
"azure-storage-blob >= 12.0.0, < 13.0.0",
104-
"kili-formats[all] == 0.2.3",
104+
"kili-formats[all] == 0.2.7",
105105
"opencv-python >= 4.0.0, < 5.0.0",
106106
"Pillow >=9.0.0, <11.0.0",
107107
"pyproj == 3.6.1; python_version >= '3.9'",
@@ -115,7 +115,7 @@ cli = [
115115
"tabulate >= 0.9.0, < 0.10.0"
116116
]
117117
coco = [
118-
"kili-formats[coco] == 0.2.3"
118+
"kili-formats[coco] == 0.2.7"
119119
]
120120
gis = [
121121
"pyproj >= 2.6.1, < 3; python_version < '3.9'",
@@ -124,12 +124,12 @@ gis = [
124124
]
125125
image = [
126126
"Pillow >=9.0.0, <11.0.0",
127-
"kili-formats[image] == 0.2.3"
127+
"kili-formats[image] == 0.2.7"
128128
]
129129
image-utils = ["opencv-python >= 4.0.0, < 5.0.0"]
130130

131131
video = [
132-
"kili-formats[video] == 0.2.3"
132+
"kili-formats[video] == 0.2.7"
133133
]
134134
yolo = [
135135
"pyyaml >= 6.0, < 7.0"

src/kili/presentation/client/label.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Client presentation methods for labels."""
22

33
# pylint: disable=too-many-lines
4+
import json
45
import warnings
56
from itertools import repeat
67
from typing import (
@@ -16,6 +17,7 @@
1617
overload,
1718
)
1819

20+
from kili_formats.format.geojson import geojson_feature_collection_to_kili_json_response
1921
from typeguard import typechecked
2022

2123
from kili.adapters.kili_api_gateway.helpers.queries import QueryOptions
@@ -1399,3 +1401,65 @@ def append_labels_from_shapefiles(
13991401
json_response_array=[json_response],
14001402
asset_external_id_array=[asset_external_id],
14011403
)
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

Comments
 (0)