|
1 | 1 | """Extra methods for the :py:class:`ee.Dictionary` class."""
|
2 | 2 | from __future__ import annotations
|
3 | 3 |
|
| 4 | +from typing import Literal |
| 5 | + |
4 | 6 | import ee
|
5 | 7 |
|
6 | 8 | from .accessors import register_class_accessor
|
@@ -84,3 +86,122 @@ def getMany(self, list: list | ee.List) -> ee.List:
|
84 | 86 | d.getInfo()
|
85 | 87 | """
|
86 | 88 | return ee.List(list).map(lambda key: self._obj.get(key))
|
| 89 | + |
| 90 | + def toTable( |
| 91 | + self, valueType: Literal["dict", "list", "value"] = "value" |
| 92 | + ) -> ee.FeatureCollection: |
| 93 | + """Convert a :py:class:`ee.Dictionary` to a :py:class:`ee.FeatureCollection` with no geometries (table). |
| 94 | +
|
| 95 | + There are 3 different type of values handled by this method: |
| 96 | +
|
| 97 | + 1. value (default): when values are a :py:class:`ee.String` or |
| 98 | + :py:class:`ee.Number`, the keys will be saved in the column |
| 99 | + ``system:index`` and the values in the column "value". |
| 100 | +
|
| 101 | + 2. dict: when values are a :py:class:`ee.Dictionary`, the keys will be |
| 102 | + saved in the column ``system:index`` and the values will be treated |
| 103 | + as each Feature's properties. |
| 104 | +
|
| 105 | + 3. list: when values are a :py:class:`ee.List` of numbers or strings, |
| 106 | + the keys will be saved in the column ``system:index`` and the values |
| 107 | + in as many columns as items in the list. The column name pattern is |
| 108 | + "value_{i}" where i is the position of the element in the list. |
| 109 | +
|
| 110 | + These are the only supported patterns. Other patterns should be converted |
| 111 | + to one of these. For example, the values of a reduction using the |
| 112 | + reducer :py:meth:`ee.Reducer.frequencyHistogram` are of type |
| 113 | + :py:class:`ee.Array` and the array contains lists. |
| 114 | +
|
| 115 | + Parameters: |
| 116 | + valueType: this will define how to process the values. |
| 117 | +
|
| 118 | + Returns: |
| 119 | + a collection in which the keys of the :py:class:`ee.Dictionary` are |
| 120 | + in the ``system:index`` and the values are in new columns. |
| 121 | +
|
| 122 | + Examples: |
| 123 | + .. jupyter-execute:: |
| 124 | +
|
| 125 | + import ee, geetools |
| 126 | + from geetools.utils import initialize_documentation |
| 127 | +
|
| 128 | + initialize_documentation() |
| 129 | +
|
| 130 | + d = ee.Dictionary({"foo": 1, "bar": 2}) |
| 131 | + d.geetools.toTable().getInfo() |
| 132 | +
|
| 133 | + .. jupyter-execute:: |
| 134 | +
|
| 135 | + import ee, geetools |
| 136 | + from geetools.utils import initialize_documentation |
| 137 | +
|
| 138 | + initialize_documentation() |
| 139 | +
|
| 140 | + d = ee.Dictionary({ |
| 141 | + "Argentina": {"ADM0_CODE": 12, "Shape_Area": 278.289196625}, |
| 142 | + "Armenia": {"ADM0_CODE": 13, "Shape_Area": 3.13783139285}, |
| 143 | + }) |
| 144 | + d.geetools.toTable('dict').getInfo() |
| 145 | +
|
| 146 | + .. jupyter-execute:: |
| 147 | +
|
| 148 | + import ee, geetools |
| 149 | + from geetools.utils import initialize_documentation |
| 150 | +
|
| 151 | + initialize_documentation() |
| 152 | +
|
| 153 | + d = ee.Dictionary({ |
| 154 | + "Argentina": [12, 278.289196625], |
| 155 | + "Armenia": [13, 3.13783139285], |
| 156 | + }) |
| 157 | + d.geetools.toTable().getInfo() |
| 158 | +
|
| 159 | + .. jupyter-execute:: |
| 160 | +
|
| 161 | + import ee, geetools |
| 162 | + from geetools.utils import initialize_documentation |
| 163 | +
|
| 164 | + initialize_documentation() |
| 165 | +
|
| 166 | + # reduction |
| 167 | + ran = ee.Image.random().multiply(10).reduceRegion( |
| 168 | + reducer=ee.Reducer.fixedHistogram(0, 1.1, 11), |
| 169 | + geometry=ee.Geometry.Point([0,0]).buffer(1000), |
| 170 | + scale=100 |
| 171 | + ) |
| 172 | +
|
| 173 | + # process to get desired format |
| 174 | + res = ee.Array(ee.Dictionary(ran).get('random')) |
| 175 | + reslist = res.toList() |
| 176 | + keys = reslist.map(lambda i: ee.Number(ee.List(i).get(0)).multiply(100).toInt().format()) |
| 177 | + values = reslist.map(lambda i: ee.Number(ee.List(i).get(1)).toInt()) |
| 178 | + final = ee.Dictionary.fromLists(keys, values) |
| 179 | +
|
| 180 | + # fetch |
| 181 | + final.geetools.toTable().getInfo() |
| 182 | + """ |
| 183 | + |
| 184 | + def features_from_dict(key, value) -> ee.Feature: |
| 185 | + index = {"system:index": ee.String(key)} |
| 186 | + props = ee.Dictionary(value).combine(index) |
| 187 | + return ee.Feature(None, props) |
| 188 | + |
| 189 | + def features_from_list(key, value) -> ee.Feature: |
| 190 | + index = {"system:index": ee.String(key)} |
| 191 | + values = ee.List(value) |
| 192 | + columns = ee.List.sequence(0, values.size().subtract(1)) |
| 193 | + columns = columns.map(lambda k: ee.String("value_").cat(ee.Number(k).toInt())) |
| 194 | + props = ee.Dictionary.fromLists(columns, values).combine(index) |
| 195 | + return ee.Feature(None, props) |
| 196 | + |
| 197 | + def features_from_any(key, value) -> ee.Feature: |
| 198 | + props = {"system:index": ee.String(key), "value": value} |
| 199 | + return ee.Feature(None, props) |
| 200 | + |
| 201 | + make_features = { |
| 202 | + "list": features_from_list, |
| 203 | + "dict": features_from_dict, |
| 204 | + "value": features_from_any, |
| 205 | + } |
| 206 | + features = self._obj.map(make_features[valueType]).values() |
| 207 | + return ee.FeatureCollection(features) |
0 commit comments