@@ -1093,3 +1093,102 @@ def test_semantic_segmentation_multipolygon_workflow(self):
10931093 kili_result = geojson_feature_collection_to_kili_json_response (geojson_result )
10941094
10951095 assert kili_result == original_kili_response
1096+
1097+ def test_geojson_multipolygon_feature_same_mid_for_all_parts (self ):
1098+ """Test that all parts of a MultiPolygon get the same mid."""
1099+ multipolygon = {
1100+ "type" : "Feature" ,
1101+ "geometry" : {
1102+ "type" : "MultiPolygon" ,
1103+ "coordinates" : [
1104+ [[[0 , 0 ], [1 , 0 ], [1 , 1 ], [0 , 0 ]]], # First polygon
1105+ [[[2 , 2 ], [3 , 2 ], [3 , 3 ], [2 , 2 ]]], # Second polygon
1106+ [[[4 , 4 ], [5 , 4 ], [5 , 5 ], [4 , 4 ]]], # Third polygon
1107+ ],
1108+ },
1109+ "id" : "forest_multipart_001" ,
1110+ "properties" : {
1111+ "kili" : {"categories" : [{"name" : "forest" }], "children" : {}, "type" : "semantic" }
1112+ },
1113+ }
1114+
1115+ result = geojson_polygon_feature_to_kili_segmentation_annotation (multipolygon )
1116+
1117+ # Should return 3 annotations (one for each polygon part)
1118+ assert len (result ) == 3
1119+
1120+ # All annotations should have the same mid
1121+ mids = [ann ["mid" ] for ann in result ]
1122+ assert all (mid == "forest_multipart_001" for mid in mids )
1123+
1124+ # Each annotation should have the correct structure
1125+ for i , annotation in enumerate (result ):
1126+ assert annotation ["type" ] == "semantic"
1127+ assert annotation ["categories" ] == [{"name" : "forest" }]
1128+ assert annotation ["children" ] == {}
1129+ assert annotation ["mid" ] == "forest_multipart_001"
1130+ assert len (annotation ["boundingPoly" ]) == 1 # Single ring per part
1131+
1132+ # Check coordinates match the expected polygon part
1133+ expected_coords = [
1134+ [{"x" : 0 , "y" : 0 }, {"x" : 1 , "y" : 0 }, {"x" : 1 , "y" : 1 }],
1135+ [{"x" : 2 , "y" : 2 }, {"x" : 3 , "y" : 2 }, {"x" : 3 , "y" : 3 }],
1136+ [{"x" : 4 , "y" : 4 }, {"x" : 5 , "y" : 4 }, {"x" : 5 , "y" : 5 }],
1137+ ]
1138+ assert annotation ["boundingPoly" ][0 ]["normalizedVertices" ] == expected_coords [i ]
1139+
1140+ def test_geojson_multipolygon_feature_custom_mid_override (self ):
1141+ """Test that custom mid parameter overrides the feature id."""
1142+ multipolygon = {
1143+ "type" : "Feature" ,
1144+ "geometry" : {
1145+ "type" : "MultiPolygon" ,
1146+ "coordinates" : [
1147+ [[[0 , 0 ], [1 , 0 ], [1 , 1 ], [0 , 0 ]]],
1148+ [[[2 , 2 ], [3 , 2 ], [3 , 3 ], [2 , 2 ]]],
1149+ ],
1150+ },
1151+ "id" : "original_id" ,
1152+ "properties" : {
1153+ "kili" : {"categories" : [{"name" : "water" }], "children" : {}, "type" : "semantic" }
1154+ },
1155+ }
1156+
1157+ custom_mid = "custom_water_id_123"
1158+ result = geojson_polygon_feature_to_kili_segmentation_annotation (
1159+ multipolygon , mid = custom_mid
1160+ )
1161+
1162+ # Should return 2 annotations
1163+ assert len (result ) == 2
1164+
1165+ # Both should have the custom mid, not the original feature id
1166+ for annotation in result :
1167+ assert annotation ["mid" ] == custom_mid
1168+ assert annotation ["mid" ] != "original_id"
1169+
1170+ def test_geojson_multipolygon_feature_no_id_generates_uuid (self ):
1171+ """Test that when no feature id is provided, a mid is generated and used for all parts."""
1172+ multipolygon = {
1173+ "type" : "Feature" ,
1174+ "geometry" : {
1175+ "type" : "MultiPolygon" ,
1176+ "coordinates" : [
1177+ [[[0 , 0 ], [1 , 0 ], [1 , 1 ], [0 , 0 ]]],
1178+ [[[2 , 2 ], [3 , 2 ], [3 , 3 ], [2 , 2 ]]],
1179+ ],
1180+ },
1181+ "properties" : {
1182+ "kili" : {"categories" : [{"name" : "building" }], "children" : {}, "type" : "semantic" }
1183+ },
1184+ }
1185+
1186+ result = geojson_polygon_feature_to_kili_segmentation_annotation (multipolygon )
1187+
1188+ # Should return 2 annotations
1189+ assert len (result ) == 2
1190+
1191+ # Both should have the same generated UUID
1192+ mid_1 = result [0 ]["mid" ]
1193+ mid_2 = result [1 ]["mid" ]
1194+ assert mid_1 == mid_2
0 commit comments