Skip to content

Commit e22c34f

Browse files
authored
feat: add the capacity to split a featureCollection
1 parent 2ef3c0e commit e22c34f

File tree

4 files changed

+302
-0
lines changed

4 files changed

+302
-0
lines changed

geetools/ee_feature_collection.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,3 +796,48 @@ def areaSort(self, ascending: bool = True) -> ee.FeatureCollection:
796796
# sort by area and remove the property from the output
797797
properties = fc.first().propertyNames().remove(name)
798798
return fc.sort(name, ascending).map(lambda feat: feat.select(properties))
799+
800+
def split(self, parts: int = 1) -> ee.List:
801+
"""Split a feature collection in multiple parts.
802+
803+
Args:
804+
parts: The number of parts to split the collection in
805+
806+
Returns:
807+
A list of ee.FeatureCollection
808+
809+
Examples:
810+
.. jupyter-execute::
811+
812+
import ee, geetools
813+
from geetools.utils import initialize_documentation
814+
815+
initialize_documentation()
816+
817+
fc = ee.FeatureCollection("FAO/GAUL/2015/level0")
818+
fc.ldc.split(2).get(1).size().getInfo()
819+
"""
820+
# if parts == 1, then we simply return the initial collection in a list (for consistency)
821+
# in order to avoid extra computation from GEE side
822+
if parts == 1:
823+
return ee.List([self._obj])
824+
825+
# extract the properties of the ee.FeatureCollection object before building
826+
# the random column
827+
properties = self._obj.first().propertyNames()
828+
829+
# build the sequence of steps to split the collection
830+
parts = ee.Number(parts).toInt()
831+
steps = ee.List.sequence(0, 1, count=parts.add(1))
832+
stepsIndex = ee.List.sequence(0, steps.size().subtract(2))
833+
834+
# split the collection and drop the random temp column
835+
prop = ee.String("__geetools_split_prop__")
836+
fc = self._obj.randomColumn(prop)
837+
838+
def split(i):
839+
i, j = ee.Number(i), ee.Number(i).add(1)
840+
col = fc.filter(ee.Filter.rangeContains(prop, steps.get(i), steps.get(j)))
841+
return ee.FeatureCollection(col).select(properties)
842+
843+
return ee.List(stepsIndex.map(split))

tests/test_FeatureCollection.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,3 +371,14 @@ def test_area_sort(self, ee_list_regression):
371371
fc = fc.geetools.areaSort()
372372
property = fc.aggregate_array("ADM0_NAME")
373373
ee_list_regression.check(property)
374+
375+
376+
class TestSplit:
377+
"""Test the ``split`` method."""
378+
379+
def test_split(self, ee_dictionary_regression):
380+
asset = "FAO/GAUL/2015/level0"
381+
fc = ee.FeatureCollection(asset).limit(10)
382+
fc = ee.FeatureCollection(fc.geetools.split(3).get(0))
383+
dict = fc.geetools.toDictionary()
384+
ee_dictionary_regression.check(dict)
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
result: '0'
2+
values:
3+
'0':
4+
functionInvocationValue:
5+
arguments:
6+
keys:
7+
functionInvocationValue:
8+
arguments:
9+
baseAlgorithm:
10+
functionDefinitionValue:
11+
argumentNames:
12+
- _MAPPING_VAR_0_0
13+
body: '1'
14+
dropNulls:
15+
constantValue: false
16+
list:
17+
functionInvocationValue:
18+
arguments:
19+
collection:
20+
valueReference: '2'
21+
property:
22+
constantValue: system:index
23+
functionName: AggregateFeatureCollection.array
24+
functionName: List.map
25+
values:
26+
functionInvocationValue:
27+
arguments:
28+
baseAlgorithm:
29+
functionDefinitionValue:
30+
argumentNames:
31+
- _MAPPING_VAR_2_0
32+
body: '8'
33+
dropNulls:
34+
constantValue: false
35+
list:
36+
functionInvocationValue:
37+
arguments:
38+
collection:
39+
valueReference: '2'
40+
count:
41+
functionInvocationValue:
42+
arguments:
43+
collection:
44+
valueReference: '2'
45+
functionName: Collection.size
46+
functionName: Collection.toList
47+
functionName: List.map
48+
functionName: Dictionary.fromLists
49+
'1':
50+
functionInvocationValue:
51+
arguments:
52+
input:
53+
argumentReference: _MAPPING_VAR_0_0
54+
functionName: String
55+
'2':
56+
functionInvocationValue:
57+
arguments:
58+
index:
59+
constantValue: 0
60+
list:
61+
functionInvocationValue:
62+
arguments:
63+
baseAlgorithm:
64+
functionDefinitionValue:
65+
argumentNames:
66+
- _MAPPING_VAR_1_0
67+
body: '3'
68+
dropNulls:
69+
constantValue: false
70+
list:
71+
functionInvocationValue:
72+
arguments:
73+
end:
74+
functionInvocationValue:
75+
arguments:
76+
left:
77+
functionInvocationValue:
78+
arguments:
79+
list:
80+
valueReference: '7'
81+
functionName: List.size
82+
right:
83+
constantValue: 2
84+
functionName: Number.subtract
85+
start:
86+
constantValue: 0
87+
functionName: List.sequence
88+
functionName: List.map
89+
functionName: List.get
90+
'3':
91+
functionInvocationValue:
92+
arguments:
93+
baseAlgorithm:
94+
functionDefinitionValue:
95+
argumentNames:
96+
- _MAPPING_VAR_0_0
97+
body: '4'
98+
collection:
99+
functionInvocationValue:
100+
arguments:
101+
collection:
102+
functionInvocationValue:
103+
arguments:
104+
collection:
105+
valueReference: '5'
106+
columnName:
107+
valueReference: '6'
108+
functionName: Collection.randomColumn
109+
filter:
110+
functionInvocationValue:
111+
arguments:
112+
field:
113+
valueReference: '6'
114+
maxValue:
115+
functionInvocationValue:
116+
arguments:
117+
index:
118+
functionInvocationValue:
119+
arguments:
120+
left:
121+
argumentReference: _MAPPING_VAR_1_0
122+
right:
123+
constantValue: 1
124+
functionName: Number.add
125+
list:
126+
valueReference: '7'
127+
functionName: List.get
128+
minValue:
129+
functionInvocationValue:
130+
arguments:
131+
index:
132+
argumentReference: _MAPPING_VAR_1_0
133+
list:
134+
valueReference: '7'
135+
functionName: List.get
136+
functionName: Filter.rangeContains
137+
functionName: Collection.filter
138+
functionName: Collection.map
139+
'4':
140+
functionInvocationValue:
141+
arguments:
142+
input:
143+
argumentReference: _MAPPING_VAR_0_0
144+
propertySelectors:
145+
functionInvocationValue:
146+
arguments:
147+
element:
148+
functionInvocationValue:
149+
arguments:
150+
collection:
151+
valueReference: '5'
152+
functionName: Collection.first
153+
functionName: Element.propertyNames
154+
retainGeometry:
155+
constantValue: true
156+
functionName: Feature.select
157+
'5':
158+
functionInvocationValue:
159+
arguments:
160+
collection:
161+
functionInvocationValue:
162+
arguments:
163+
tableId:
164+
constantValue: FAO/GAUL/2015/level0
165+
functionName: Collection.loadTable
166+
limit:
167+
constantValue: 10
168+
functionName: Collection.limit
169+
'6':
170+
constantValue: __geetools_split_prop__
171+
'7':
172+
functionInvocationValue:
173+
arguments:
174+
count:
175+
functionInvocationValue:
176+
arguments:
177+
left:
178+
functionInvocationValue:
179+
arguments:
180+
input:
181+
constantValue: 3
182+
functionName: Number.toInt
183+
right:
184+
constantValue: 1
185+
functionName: Number.add
186+
end:
187+
constantValue: 1
188+
start:
189+
constantValue: 0
190+
functionName: List.sequence
191+
'8':
192+
functionInvocationValue:
193+
arguments:
194+
element:
195+
argumentReference: _MAPPING_VAR_2_0
196+
properties:
197+
functionInvocationValue:
198+
arguments:
199+
element:
200+
functionInvocationValue:
201+
arguments:
202+
collection:
203+
valueReference: '2'
204+
functionName: Collection.first
205+
functionName: Element.propertyNames
206+
functionName: Element.toDictionary
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
0000000000000000000c:
2+
ADM0_CODE: 2648
3+
ADM0_NAME: Serbia
4+
DISP_AREA: 'NO'
5+
EXP0_YEAR: 3000
6+
STATUS: Member State
7+
STR0_YEAR: 2006
8+
Shape_Area: 9.934731
9+
Shape_Leng: 24.909326
10+
system:index: 0000000000000000000c
11+
0000000000000000002e:
12+
ADM0_CODE: 74
13+
ADM0_NAME: South Sudan
14+
DISP_AREA: 'NO'
15+
EXP0_YEAR: 3000
16+
STATUS: Member State
17+
STR0_YEAR: 2011
18+
Shape_Area: 51.599166
19+
Shape_Leng: 46.905431
20+
system:index: 0000000000000000002e
21+
0000000000000000004c:
22+
ADM0_CODE: 6
23+
ADM0_NAME: Sudan
24+
DISP_AREA: 'NO'
25+
EXP0_YEAR: 3000
26+
STATUS: Member State
27+
STR0_YEAR: 2011
28+
Shape_Area: 155.888802
29+
Shape_Leng: 81.910242
30+
system:index: 0000000000000000004c
31+
000000000000000000b5:
32+
ADM0_CODE: 82
33+
ADM0_NAME: Faroe Islands
34+
DISP_AREA: 'NO'
35+
EXP0_YEAR: 3000
36+
STATUS: DK Territory
37+
STR0_YEAR: 1000
38+
Shape_Area: 0.240299
39+
Shape_Leng: 15.952426
40+
system:index: 000000000000000000b5

0 commit comments

Comments
 (0)