Skip to content

primitives module

Primitives

Source code in src\rlcms\primitives.py
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
class Primitives:
    def __init__(self,
                 inputs=None,
                 training=None,
                 class_name=None,
                 asset_id=None):
        """
        Construct a Primitives ensemble, provided an input ee.Image stack containing feature bands and a training point FeatureCollection
        NOTE: land cover typology in your training dataset should be alpha-numerically sorted (Agriculture: 1, Bare Soil: 2, Built: 3) and should not skip label values (1,2,4,5). There may be unexpected results if this is not handled properly first by the user.

        Args:
            inputs (str|ee.Image): input image stack
            training (str|ee.FeatureCollection): training data
            class_name (str): class property containing class labels (i.e. 1, 2, 3), currently only 'LANDCOVER' is supported
            asset_id (str): Optional, GEE asset path to pre-existing Primitives ee.ImageCollection. Useful for exporting intermediary output approach

        Returns: 
            Primitives object
        """

        # TODO: perform some checks and error handling for training point label formatting 
        def pre_format_pts(pts,class_name):
            # two things: 
            # 1. need to ensure that 'LANDCOVER' is the class_name, if not, set new property in each feature using that
            if class_name != 'LANDCOVER':
                # set user's class_name to 'LANDCOVER' so we don't need to pass custom class_name around to every function
                pts = pts.map(lambda p: p.set('LANDCOVER',p.get(class_name)))
            else:
                # check 'LANDCOVER' is a property in collection
                assert 'LANDCOVER' in pts.first().propertyNames().getInfo(), "'LANDCOVER' is not a property in the collection"
            # 2. ensure that value of 'LANDCOVER' is integer before converting to string
            def to_int(p):
                val = p.get('LANDCOVER')
                # is 'LANDCOVER' always going to be string? can we convert it to string without first knowing if its String or Number?
                int_val = ee.Number(val).round()
                return p.set('LANDCOVER',int_val)
            return pts.map(to_int)

        def format_pts(pts):
            """Turn a FC of training points containing full LC typology into a list of primitive point FCs, 
                    one point FC for each LC primitive"""
            # create sets of binary training pts for each class represented in the full training pts collection
            labels = ee.FeatureCollection(pts).aggregate_array('LANDCOVER').distinct().sort()
            def binaryPts(l):
                # create prim and non prim sets with filters, reset prim to 1, non-prim to 0
                prim = pts.filter(ee.Filter.eq('LANDCOVER',l)).map(lambda f: f.set('PRIM',1))
                non_prim = pts.filter(ee.Filter.neq('LANDCOVER',l)).map(lambda f: f.set('PRIM',0))
                return ee.FeatureCollection(prim).merge(non_prim)
            list_of_prim_pts = ee.List(labels).map(binaryPts)
            return list_of_prim_pts

        def gettop20(dict):
            # if total input features count < 20, take them all, otherwise take top 20 most important
            dict = ee.Dictionary(dict)
            values = dict.values().sort()
            cutoff = ee.Algorithms.If(values.size().gte(20),-20,values.size().multiply(-1))
            def kv_return(key,passedObj):
                passedObj = ee.List(passedObj)
                val = ee.Number(dict.get(key))
                retObj = ee.Algorithms.If(val.gte(cutoff),passedObj.add(key),passedObj)
                return retObj
            newl = dict.keys().iterate(kv_return,ee.List([]))
            return newl

        def RFprim(training_pts,input_stack):
            """Train and apply RF Probability classifier on a Primitive"""
            inputs = ee.Image(input_stack)
            samples = ee.FeatureCollection(training_pts)

            class_value = ee.Number(ee.Feature(samples.sort('PRIM',False).first()).get('LANDCOVER')) #get LC numeric value for the given primitive (i.e. 'PRIM':1, 'LANDCOVER':6) then map to its class label (i.e. 6: 'Water')

            # can experiment with classifier params for model performance
            classifier = ee.Classifier.smileRandomForest(
            numberOfTrees=100, 
            minLeafPopulation=1, 
            bagFraction=0.7, 
            seed=51515).setOutputMode('PROBABILITY')

            # train model with all features
            model = classifier.train(features=samples, 
                                    classProperty='PRIM', 
                                    inputProperties=inputs.bandNames() 
                                    )

            # store for model performance exploration
            oob_all = ee.Dictionary(model.explain()).get('outOfBagErrorEstimate')
            importance_all = ee.Dictionary(model.explain()).get('importance')

            # retrieve top 20 most important features
            top20 = gettop20(importance_all)

            # re-train model with top20 important features
            model = classifier.train(features=samples, 
                                    classProperty='PRIM', 
                                    inputProperties=top20
                                    )

            oob_top20 = ee.Dictionary(model.explain()).get('outOfBagErrorEstimate')
            importance_top20 = ee.Dictionary(model.explain()).get('importance')
            schema = ee.List(ee.Classifier(model).schema())
            output = (ee.Image(inputs)
                      .classify(model,'Probability')
                      # lists and dictionaries do not propagate thru as properties on Batch exported Images
                      .set('Primitive',class_value,
                           'importance',importance_top20, 
                           'schema',schema, 
                           'model',model,
                           'oobError',oob_top20, 
                           ))
            return output

        def primitives_to_collection(input_stack,
                                     training_pts,
                                     class_name):
            """
            Create LC Primitive image for each LC class in training points

            args:
                input_stack (ee.Image): of all covariates and predictor
                training_pts (ee.FeatureCollection): training pts containing full LC typology
                class_name (str): property name in training points containing model classes

            returns:
                ee.ImageCollection of Primitive ee.Images
            """

            input_stack = ee.Image(input_stack)
            training_pts = ee.FeatureCollection(training_pts)

            # list of distinct LANDCOVER values
            labels = training_pts.aggregate_array(class_name).distinct().sort().getInfo() # .sort() should fix Prims exporting out of order (i.e. 2,3,4,7,6)

            # converting to index of the list of distinct LANDCOVER primtive FC's (prim_pts below)
            indices = list(range(len(labels))) # handles dynamic land cover strata

            prim_list = []
            for i in indices: # running one LC class at a time
                prim_pts = ee.FeatureCollection(ee.List(format_pts(training_pts)).get(i)) # format training pts to 1/0 prim format
                img = RFprim(prim_pts,input_stack) # run RF primitive model, get output image and metrics
                prim_list.append(img)

            return ee.ImageCollection.fromImages(prim_list)

        # you can construct Primitives object from a pre-existing Primitives ImgColl
        if asset_id != None:
            try:
                primitives = ee.ImageCollection(asset_id)
                self.collection = primitives
                self.region = primitives.first().geometry().getInfo()
                self.training_data = None
            except: 
                raise(EEException)
        else:
            primitives = primitives_to_collection(inputs,training,class_name)
            self.collection = primitives
            self.region = ee.Image(inputs).geometry().getInfo()
            self.training_data = ee.FeatureCollection(training)

    def assemble_max_probability(self):
        """
        Take Image Collection of RF Primitives, perform pixel-wise maximum of all Primitive probability images to return single-band LC image
        Array computation returns img values from 0 to n-1 due to 0-base indexing, so we .add(1) to match LC strata

        Args:
            image: multiband image of probabilities
            remapNum: list, list of intergers 0-N matching the number of probability bands
            originalNum: list, list of inergers n-N matching the number of probability bands
                        that represent their desired map values

        Returns: ee.Image of Land Cover                            
        """
        def max_prob(image):

            maxProbClassification = (image.toArray()
                                    .arrayArgmax()
                                    .arrayFlatten([['classification']])
                                    .rename('classification')
                                    )
            return maxProbClassification

        image  = self.collection.toBands()
        max_probability = max_prob(image)
        output = max_probability.add(1).rename('LANDCOVER')
        return output

    def export_metrics(self,metrics_path):
            """
            Parse variable importance and OOB Error estimate from trained model, output to local files respectively
            Currently only works for Primitives objects in memory (not loaded from pre-existing ImgColl)
            """
            # Var Importance to csv file
            imgColl = self.collection
            to_list = ee.List(imgColl.toList(imgColl.size()))
            for i in list(range(imgColl.size().getInfo())):
                img = ee.Image(to_list.get(i))
                prim_value = str(img.get('Primitive').getInfo())

                # Variable Importance to .csv
                dct = ee.Dictionary(img.get('importance')).getInfo()
                _list = dct.values()
                idx = dct.keys()
                df = pd.DataFrame(_list, index = idx)
                df.to_csv(os.path.join(metrics_path,f"varImportancePrimitive{prim_value}.csv"))

                # OOB error to .txt file
                oob = img.get('oobError')
                with open(os.path.join(metrics_path,f'oobErrorPrimitive{prim_value}.txt'),mode='w') as f:
                    f.write(ee.String(ee.Number(oob).format()).getInfo())
                    f.close()

    def export_to_asset(self,
                        collection_assetId=None,
                        scale=None,
                        crs=None,
                        crsTransform=None,
                        maxPixels=None,
                        **kwargs):
        """
        Export Primitives to Asset as an ImageCollection

        Args:
            collection_assetId (str): output ImageCollection asset path 
            scale (int): export scale
            crs (str): export CRS ('EPSG:4326')
            crsTransform (list): export CRS Transform
            maxPixels (int): max Pixels

        Returns: 
            None, Submits all Export Image tasks for Primitive collection
        """

        # make the empty IC
        print(f"Creating empty Primitives ImageCollection: {collection_assetId}.\n")
        os.popen(f"earthengine create collection {collection_assetId}").read()
        prims_count = self.collection.size().getInfo()
        prims_list = ee.ImageCollection(self.collection).toList(prims_count)
        aoi = ee.Image(prims_list.get(0)).geometry()
        for i in list(range(prims_count)):
            prim = ee.Image(prims_list.get(i))
            desc = f"Primitive{str(ee.Image(prim).get('Primitive').getInfo())}" # this would need to be defined in the Prims img for-loop
            asset_id = f'{collection_assetId}/{desc}'
            export_img_to_asset(image=prim,
                                description=desc,
                                assetId=asset_id,
                                region=aoi,
                                scale=scale,
                                crs=crs,
                                crsTransform=None,
                                maxPixels=1e13)

        return

    def export_to_drive(self,
                        description,
                        folder,
                        fileNamePrefix,
                        dimensions=None,
                        region=None,
                        scale=None,
                        crs=None,
                        crsTransform=None,
                        maxPixels=None,
                        shardSize=None,
                        fileDimensions=None,
                        skipEmptyTiles=None,
                        fileFormat=None,
                        formatOptions=None,
                        **kwargs,):
        """
        Export Primitives to Drive as a Multi-band GeoTiff

        See rlcms.utils.export_img_to_drive() docs for Args

        Returns: 
            None, Submits all Export Image tasks for Primitive collection
        """

        prim_img = self.collection.toBands()
        export_image_to_drive(image=prim_img,
                                description=description,
                                folder=folder,
                                fileNamePrefix=fileNamePrefix,
                                dimensions=dimensions,
                                region=region,
                                scale=scale,
                                crs=crs,
                                crsTransform=crsTransform,
                                maxPixels=maxPixels,
                                shardSize=shardSize,
                                fileDimensions=fileDimensions,
                                skipEmptyTiles=skipEmptyTiles,
                                fileFormat=fileFormat,
                                formatOptions=formatOptions,
                                **kwargs,)
        return

__init__(inputs=None, training=None, class_name=None, asset_id=None)

Construct a Primitives ensemble, provided an input ee.Image stack containing feature bands and a training point FeatureCollection NOTE: land cover typology in your training dataset should be alpha-numerically sorted (Agriculture: 1, Bare Soil: 2, Built: 3) and should not skip label values (1,2,4,5). There may be unexpected results if this is not handled properly first by the user.

Parameters:

Name Type Description Default
inputs str | Image

input image stack

None
training str | FeatureCollection

training data

None
class_name str

class property containing class labels (i.e. 1, 2, 3), currently only 'LANDCOVER' is supported

None
asset_id str

Optional, GEE asset path to pre-existing Primitives ee.ImageCollection. Useful for exporting intermediary output approach

None

Returns:

Type Description

Primitives object

Source code in src\rlcms\primitives.py
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
def __init__(self,
             inputs=None,
             training=None,
             class_name=None,
             asset_id=None):
    """
    Construct a Primitives ensemble, provided an input ee.Image stack containing feature bands and a training point FeatureCollection
    NOTE: land cover typology in your training dataset should be alpha-numerically sorted (Agriculture: 1, Bare Soil: 2, Built: 3) and should not skip label values (1,2,4,5). There may be unexpected results if this is not handled properly first by the user.

    Args:
        inputs (str|ee.Image): input image stack
        training (str|ee.FeatureCollection): training data
        class_name (str): class property containing class labels (i.e. 1, 2, 3), currently only 'LANDCOVER' is supported
        asset_id (str): Optional, GEE asset path to pre-existing Primitives ee.ImageCollection. Useful for exporting intermediary output approach

    Returns: 
        Primitives object
    """

    # TODO: perform some checks and error handling for training point label formatting 
    def pre_format_pts(pts,class_name):
        # two things: 
        # 1. need to ensure that 'LANDCOVER' is the class_name, if not, set new property in each feature using that
        if class_name != 'LANDCOVER':
            # set user's class_name to 'LANDCOVER' so we don't need to pass custom class_name around to every function
            pts = pts.map(lambda p: p.set('LANDCOVER',p.get(class_name)))
        else:
            # check 'LANDCOVER' is a property in collection
            assert 'LANDCOVER' in pts.first().propertyNames().getInfo(), "'LANDCOVER' is not a property in the collection"
        # 2. ensure that value of 'LANDCOVER' is integer before converting to string
        def to_int(p):
            val = p.get('LANDCOVER')
            # is 'LANDCOVER' always going to be string? can we convert it to string without first knowing if its String or Number?
            int_val = ee.Number(val).round()
            return p.set('LANDCOVER',int_val)
        return pts.map(to_int)

    def format_pts(pts):
        """Turn a FC of training points containing full LC typology into a list of primitive point FCs, 
                one point FC for each LC primitive"""
        # create sets of binary training pts for each class represented in the full training pts collection
        labels = ee.FeatureCollection(pts).aggregate_array('LANDCOVER').distinct().sort()
        def binaryPts(l):
            # create prim and non prim sets with filters, reset prim to 1, non-prim to 0
            prim = pts.filter(ee.Filter.eq('LANDCOVER',l)).map(lambda f: f.set('PRIM',1))
            non_prim = pts.filter(ee.Filter.neq('LANDCOVER',l)).map(lambda f: f.set('PRIM',0))
            return ee.FeatureCollection(prim).merge(non_prim)
        list_of_prim_pts = ee.List(labels).map(binaryPts)
        return list_of_prim_pts

    def gettop20(dict):
        # if total input features count < 20, take them all, otherwise take top 20 most important
        dict = ee.Dictionary(dict)
        values = dict.values().sort()
        cutoff = ee.Algorithms.If(values.size().gte(20),-20,values.size().multiply(-1))
        def kv_return(key,passedObj):
            passedObj = ee.List(passedObj)
            val = ee.Number(dict.get(key))
            retObj = ee.Algorithms.If(val.gte(cutoff),passedObj.add(key),passedObj)
            return retObj
        newl = dict.keys().iterate(kv_return,ee.List([]))
        return newl

    def RFprim(training_pts,input_stack):
        """Train and apply RF Probability classifier on a Primitive"""
        inputs = ee.Image(input_stack)
        samples = ee.FeatureCollection(training_pts)

        class_value = ee.Number(ee.Feature(samples.sort('PRIM',False).first()).get('LANDCOVER')) #get LC numeric value for the given primitive (i.e. 'PRIM':1, 'LANDCOVER':6) then map to its class label (i.e. 6: 'Water')

        # can experiment with classifier params for model performance
        classifier = ee.Classifier.smileRandomForest(
        numberOfTrees=100, 
        minLeafPopulation=1, 
        bagFraction=0.7, 
        seed=51515).setOutputMode('PROBABILITY')

        # train model with all features
        model = classifier.train(features=samples, 
                                classProperty='PRIM', 
                                inputProperties=inputs.bandNames() 
                                )

        # store for model performance exploration
        oob_all = ee.Dictionary(model.explain()).get('outOfBagErrorEstimate')
        importance_all = ee.Dictionary(model.explain()).get('importance')

        # retrieve top 20 most important features
        top20 = gettop20(importance_all)

        # re-train model with top20 important features
        model = classifier.train(features=samples, 
                                classProperty='PRIM', 
                                inputProperties=top20
                                )

        oob_top20 = ee.Dictionary(model.explain()).get('outOfBagErrorEstimate')
        importance_top20 = ee.Dictionary(model.explain()).get('importance')
        schema = ee.List(ee.Classifier(model).schema())
        output = (ee.Image(inputs)
                  .classify(model,'Probability')
                  # lists and dictionaries do not propagate thru as properties on Batch exported Images
                  .set('Primitive',class_value,
                       'importance',importance_top20, 
                       'schema',schema, 
                       'model',model,
                       'oobError',oob_top20, 
                       ))
        return output

    def primitives_to_collection(input_stack,
                                 training_pts,
                                 class_name):
        """
        Create LC Primitive image for each LC class in training points

        args:
            input_stack (ee.Image): of all covariates and predictor
            training_pts (ee.FeatureCollection): training pts containing full LC typology
            class_name (str): property name in training points containing model classes

        returns:
            ee.ImageCollection of Primitive ee.Images
        """

        input_stack = ee.Image(input_stack)
        training_pts = ee.FeatureCollection(training_pts)

        # list of distinct LANDCOVER values
        labels = training_pts.aggregate_array(class_name).distinct().sort().getInfo() # .sort() should fix Prims exporting out of order (i.e. 2,3,4,7,6)

        # converting to index of the list of distinct LANDCOVER primtive FC's (prim_pts below)
        indices = list(range(len(labels))) # handles dynamic land cover strata

        prim_list = []
        for i in indices: # running one LC class at a time
            prim_pts = ee.FeatureCollection(ee.List(format_pts(training_pts)).get(i)) # format training pts to 1/0 prim format
            img = RFprim(prim_pts,input_stack) # run RF primitive model, get output image and metrics
            prim_list.append(img)

        return ee.ImageCollection.fromImages(prim_list)

    # you can construct Primitives object from a pre-existing Primitives ImgColl
    if asset_id != None:
        try:
            primitives = ee.ImageCollection(asset_id)
            self.collection = primitives
            self.region = primitives.first().geometry().getInfo()
            self.training_data = None
        except: 
            raise(EEException)
    else:
        primitives = primitives_to_collection(inputs,training,class_name)
        self.collection = primitives
        self.region = ee.Image(inputs).geometry().getInfo()
        self.training_data = ee.FeatureCollection(training)

assemble_max_probability()

Take Image Collection of RF Primitives, perform pixel-wise maximum of all Primitive probability images to return single-band LC image Array computation returns img values from 0 to n-1 due to 0-base indexing, so we .add(1) to match LC strata

Parameters:

Name Type Description Default
image

multiband image of probabilities

required
remapNum

list, list of intergers 0-N matching the number of probability bands

required
originalNum

list, list of inergers n-N matching the number of probability bands that represent their desired map values

required

Returns: ee.Image of Land Cover

Source code in src\rlcms\primitives.py
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
def assemble_max_probability(self):
    """
    Take Image Collection of RF Primitives, perform pixel-wise maximum of all Primitive probability images to return single-band LC image
    Array computation returns img values from 0 to n-1 due to 0-base indexing, so we .add(1) to match LC strata

    Args:
        image: multiband image of probabilities
        remapNum: list, list of intergers 0-N matching the number of probability bands
        originalNum: list, list of inergers n-N matching the number of probability bands
                    that represent their desired map values

    Returns: ee.Image of Land Cover                            
    """
    def max_prob(image):

        maxProbClassification = (image.toArray()
                                .arrayArgmax()
                                .arrayFlatten([['classification']])
                                .rename('classification')
                                )
        return maxProbClassification

    image  = self.collection.toBands()
    max_probability = max_prob(image)
    output = max_probability.add(1).rename('LANDCOVER')
    return output

export_metrics(metrics_path)

Parse variable importance and OOB Error estimate from trained model, output to local files respectively Currently only works for Primitives objects in memory (not loaded from pre-existing ImgColl)

Source code in src\rlcms\primitives.py
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
def export_metrics(self,metrics_path):
        """
        Parse variable importance and OOB Error estimate from trained model, output to local files respectively
        Currently only works for Primitives objects in memory (not loaded from pre-existing ImgColl)
        """
        # Var Importance to csv file
        imgColl = self.collection
        to_list = ee.List(imgColl.toList(imgColl.size()))
        for i in list(range(imgColl.size().getInfo())):
            img = ee.Image(to_list.get(i))
            prim_value = str(img.get('Primitive').getInfo())

            # Variable Importance to .csv
            dct = ee.Dictionary(img.get('importance')).getInfo()
            _list = dct.values()
            idx = dct.keys()
            df = pd.DataFrame(_list, index = idx)
            df.to_csv(os.path.join(metrics_path,f"varImportancePrimitive{prim_value}.csv"))

            # OOB error to .txt file
            oob = img.get('oobError')
            with open(os.path.join(metrics_path,f'oobErrorPrimitive{prim_value}.txt'),mode='w') as f:
                f.write(ee.String(ee.Number(oob).format()).getInfo())
                f.close()

export_to_asset(collection_assetId=None, scale=None, crs=None, crsTransform=None, maxPixels=None, **kwargs)

Export Primitives to Asset as an ImageCollection

Parameters:

Name Type Description Default
collection_assetId str

output ImageCollection asset path

None
scale int

export scale

None
crs str

export CRS ('EPSG:4326')

None
crsTransform list

export CRS Transform

None
maxPixels int

max Pixels

None

Returns:

Type Description

None, Submits all Export Image tasks for Primitive collection

Source code in src\rlcms\primitives.py
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
def export_to_asset(self,
                    collection_assetId=None,
                    scale=None,
                    crs=None,
                    crsTransform=None,
                    maxPixels=None,
                    **kwargs):
    """
    Export Primitives to Asset as an ImageCollection

    Args:
        collection_assetId (str): output ImageCollection asset path 
        scale (int): export scale
        crs (str): export CRS ('EPSG:4326')
        crsTransform (list): export CRS Transform
        maxPixels (int): max Pixels

    Returns: 
        None, Submits all Export Image tasks for Primitive collection
    """

    # make the empty IC
    print(f"Creating empty Primitives ImageCollection: {collection_assetId}.\n")
    os.popen(f"earthengine create collection {collection_assetId}").read()
    prims_count = self.collection.size().getInfo()
    prims_list = ee.ImageCollection(self.collection).toList(prims_count)
    aoi = ee.Image(prims_list.get(0)).geometry()
    for i in list(range(prims_count)):
        prim = ee.Image(prims_list.get(i))
        desc = f"Primitive{str(ee.Image(prim).get('Primitive').getInfo())}" # this would need to be defined in the Prims img for-loop
        asset_id = f'{collection_assetId}/{desc}'
        export_img_to_asset(image=prim,
                            description=desc,
                            assetId=asset_id,
                            region=aoi,
                            scale=scale,
                            crs=crs,
                            crsTransform=None,
                            maxPixels=1e13)

    return

export_to_drive(description, folder, fileNamePrefix, dimensions=None, region=None, scale=None, crs=None, crsTransform=None, maxPixels=None, shardSize=None, fileDimensions=None, skipEmptyTiles=None, fileFormat=None, formatOptions=None, **kwargs)

Export Primitives to Drive as a Multi-band GeoTiff

See rlcms.utils.export_img_to_drive() docs for Args

Returns:

Type Description

None, Submits all Export Image tasks for Primitive collection

Source code in src\rlcms\primitives.py
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
def export_to_drive(self,
                    description,
                    folder,
                    fileNamePrefix,
                    dimensions=None,
                    region=None,
                    scale=None,
                    crs=None,
                    crsTransform=None,
                    maxPixels=None,
                    shardSize=None,
                    fileDimensions=None,
                    skipEmptyTiles=None,
                    fileFormat=None,
                    formatOptions=None,
                    **kwargs,):
    """
    Export Primitives to Drive as a Multi-band GeoTiff

    See rlcms.utils.export_img_to_drive() docs for Args

    Returns: 
        None, Submits all Export Image tasks for Primitive collection
    """

    prim_img = self.collection.toBands()
    export_image_to_drive(image=prim_img,
                            description=description,
                            folder=folder,
                            fileNamePrefix=fileNamePrefix,
                            dimensions=dimensions,
                            region=region,
                            scale=scale,
                            crs=crs,
                            crsTransform=crsTransform,
                            maxPixels=maxPixels,
                            shardSize=shardSize,
                            fileDimensions=fileDimensions,
                            skipEmptyTiles=skipEmptyTiles,
                            fileFormat=fileFormat,
                            formatOptions=formatOptions,
                            **kwargs,)
    return