@@ -81,3 +81,83 @@ def apply(self, img: ImageData) -> ImageData:
81
81
crs = img .crs ,
82
82
bounds = img .bounds ,
83
83
)
84
+
85
+
86
+ class Terrarium (BaseAlgorithm ):
87
+ """Encode DEM into RGB (Mapzen Terrarium)."""
88
+
89
+ input_nbands : int = 1
90
+
91
+ output_nbands : int = 3
92
+ output_dtype : str = "uint8"
93
+
94
+ def apply (self , img : ImageData ) -> ImageData :
95
+ """Encode DEM into RGB."""
96
+ data = numpy .clip (img .data [0 ] + 32768.0 , 0.0 , 65535.0 )
97
+ r = data / 256
98
+ g = data % 256
99
+ b = (data * 256 ) % 256
100
+ arr = numpy .stack ([r , g , b ]).astype (numpy .uint8 )
101
+ print (arr .shape )
102
+ return ImageData (
103
+ arr ,
104
+ img .mask ,
105
+ assets = img .assets ,
106
+ crs = img .crs ,
107
+ bounds = img .bounds ,
108
+ )
109
+
110
+
111
+ class TerrainRGB (BaseAlgorithm ):
112
+ """Encode DEM into RGB (Mapbox Terrain RGB)."""
113
+
114
+ interval : int = 1
115
+ baseval : int = - 10000
116
+
117
+ input_nbands : int = 1
118
+
119
+ output_nbands : int = 3
120
+ output_dtype : str = "uint8"
121
+
122
+ def apply (self , img : ImageData ) -> ImageData :
123
+ """Encode DEM into RGB (Mapbox Terrain RGB).
124
+
125
+ Code from https://github.com/mapbox/rio-rgbify/blob/master/rio_rgbify/encoders.py (MIT)
126
+
127
+ """
128
+
129
+ def _range_check (datarange ):
130
+ """
131
+ Utility to check if data range is outside of precision for 3 digit base 256
132
+ """
133
+ maxrange = 256 ** 3
134
+
135
+ return datarange > maxrange
136
+
137
+ round_digits = 0
138
+
139
+ data = img .data [0 ].astype (numpy .float64 )
140
+ data -= self .baseval
141
+ data /= self .interval
142
+
143
+ data = numpy .around (data / 2 ** round_digits ) * 2 ** round_digits
144
+
145
+ rows , cols = data .shape
146
+ datarange = data .max () - data .min ()
147
+ if _range_check (datarange ):
148
+ raise ValueError ("Data of {} larger than 256 ** 3" .format (datarange ))
149
+
150
+ rgb = numpy .zeros ((3 , rows , cols ), dtype = numpy .uint8 )
151
+ rgb [2 ] = ((data / 256 ) - (data // 256 )) * 256
152
+ rgb [1 ] = (((data // 256 ) / 256 ) - ((data // 256 ) // 256 )) * 256
153
+ rgb [0 ] = (
154
+ (((data // 256 ) // 256 ) / 256 ) - (((data // 256 ) // 256 ) // 256 )
155
+ ) * 256
156
+
157
+ return ImageData (
158
+ rgb ,
159
+ img .mask ,
160
+ assets = img .assets ,
161
+ crs = img .crs ,
162
+ bounds = img .bounds ,
163
+ )
0 commit comments