22import numpy
33
44from worldengine .drawing_functions import draw_ancientmap , \
5- draw_rivers_on_image , gradient
5+ draw_rivers_on_image
66
77# -------------
88# Helper values
@@ -167,43 +167,33 @@ def draw_simple_elevation(world, sea_level, target):
167167 """ This function can be used on a generic canvas (either an image to save
168168 on disk or a canvas part of a GUI)
169169 """
170- min_elev_sea = None
171- max_elev_sea = None
172- min_elev_land = None
173- max_elev_land = None
174- for y in range (world .height ):
175- for x in range (world .width ):
176- e = world .elevation ['data' ][y ,x ]
177- if sea_level is None :
178- if min_elev_land is None or e < min_elev_land :
179- min_elev_land = e
180- if max_elev_land is None or e > max_elev_land :
181- max_elev_land = e
182- elif world .is_land ((x , y )):
183- if min_elev_land is None or e < min_elev_land :
184- min_elev_land = e
185- if max_elev_land is None or e > max_elev_land :
186- max_elev_land = e
187- else :
188- if min_elev_sea is None or e < min_elev_sea :
189- min_elev_sea = e
190- if max_elev_sea is None or e > max_elev_sea :
191- max_elev_sea = e
170+ e = world .elevation ['data' ]
192171
193- elev_delta_land = (max_elev_land - min_elev_land )/ 11
194- if sea_level != None :
172+ c = numpy .empty (e .shape , dtype = numpy .float )
173+ if sea_level is None or world .ocean is None or not world .ocean .any (): # or 'not any ocean'
174+ mask = numpy .ma .array (e , mask = False ) # the whole map
175+ min_elev_land = mask .min ()
176+ max_elev_land = mask .max ()
177+ elev_delta_land = (max_elev_land - min_elev_land ) / 11.0
178+
179+ c = ((e - min_elev_land ) / elev_delta_land ) + 1
180+ else :
181+ mask = numpy .ma .array (e , mask = world .ocean ) # only land
182+ min_elev_land = mask .min ()
183+ max_elev_land = mask .max ()
184+ elev_delta_land = (max_elev_land - min_elev_land ) / 11.0
185+
186+ mask = numpy .ma .array (e , mask = numpy .logical_not (world .ocean )) # only ocean
187+ min_elev_sea = mask .min ()
188+ max_elev_sea = mask .max ()
195189 elev_delta_sea = max_elev_sea - min_elev_sea
196-
190+
191+ c [world .ocean ] = ((e [world .ocean ] - min_elev_sea ) / elev_delta_sea )
192+ c [numpy .invert (world .ocean )] = ((e [numpy .invert (world .ocean )] - min_elev_land ) / elev_delta_land ) + 1
193+
197194 for y in range (world .height ):
198195 for x in range (world .width ):
199- e = world .elevation ['data' ][y , x ]
200- if sea_level is None :
201- c = ((e - min_elev_land ) / elev_delta_land ) + 1
202- elif world .is_land ((x , y )):
203- c = ((e - min_elev_land ) / elev_delta_land ) + 1
204- else :
205- c = ((e - min_elev_sea ) / elev_delta_sea )
206- r , g , b = elevation_color (c , sea_level )
196+ r , g , b = elevation_color (c [y , x ], sea_level )
207197 target .set_pixel (x , y , (int (r * 255 ), int (g * 255 ),
208198 int (b * 255 ), 255 ))
209199
@@ -212,46 +202,34 @@ def draw_riversmap(world, target):
212202 sea_color = (255 , 255 , 255 , 255 )
213203 land_color = (0 , 0 , 0 , 255 )
214204
215- for y in range (world .height ):#TODO: numpy
205+ for y in range (world .height ):
216206 for x in range (world .width ):
217- if world .ocean [y , x ]:
218- target .set_pixel (x , y , sea_color )
219- else :
220- target .set_pixel (x , y , land_color )
207+ target .set_pixel (x , y , sea_color if world .ocean [y , x ] else land_color )
221208
222209 draw_rivers_on_image (world , target , factor = 1 )
223210
224211
225212def draw_grayscale_heightmap (world , target ):
226- min_elev_sea = None
227- max_elev_sea = None
228- min_elev_land = None
229- max_elev_land = None
230- for y in range (world .height ):
231- for x in range (world .width ):
232- e = world .elevation ['data' ][y , x ]
233- if world .is_land ((x , y )):
234- if min_elev_land is None or e < min_elev_land :
235- min_elev_land = e
236- if max_elev_land is None or e > max_elev_land :
237- max_elev_land = e
238- else :
239- if min_elev_sea is None or e < min_elev_sea :
240- min_elev_sea = e
241- if max_elev_sea is None or e > max_elev_sea :
242- max_elev_sea = e
213+ e = world .elevation ['data' ]
243214
215+ mask = numpy .ma .array (e , mask = world .ocean ) # only land
216+ min_elev_land = mask .min ()
217+ max_elev_land = mask .max ()
244218 elev_delta_land = max_elev_land - min_elev_land
219+
220+ mask = numpy .ma .array (e , mask = numpy .logical_not (world .ocean )) # only ocean
221+ min_elev_sea = mask .min ()
222+ max_elev_sea = mask .max ()
245223 elev_delta_sea = max_elev_sea - min_elev_sea
246224
225+ c = numpy .empty (e .shape , dtype = numpy .float )
226+ c [numpy .invert (world .ocean )] = (e [numpy .invert (world .ocean )] - min_elev_land ) * 127 / elev_delta_land + 128
227+ c [world .ocean ] = (e [world .ocean ] - min_elev_sea ) * 127 / elev_delta_sea
228+ c = numpy .rint (c ).astype (dtype = numpy .int32 ) # proper rounding
229+
247230 for y in range (world .height ):
248231 for x in range (world .width ):
249- e = world .elevation ['data' ][y , x ]
250- if world .is_land ((x , y )):
251- c = int (((e - min_elev_land ) * 127 ) / elev_delta_land )+ 128
252- else :
253- c = int (((e - min_elev_sea ) * 127 ) / elev_delta_sea )
254- target .set_pixel (x , y , (c , c , c , 255 ))
232+ target .set_pixel (x , y , (c [y , x ], c [y , x ], c [y , x ], 255 ))
255233
256234
257235def draw_elevation (world , shadow , target ):
@@ -267,7 +245,7 @@ def draw_elevation(world, shadow, target):
267245 max_elev = mask .max ()
268246 elev_delta = max_elev - min_elev
269247
270- for y in range (height ):#TODO: numpy optimisation for the code below
248+ for y in range (height ):
271249 for x in range (width ):
272250 if ocean [y , x ]:
273251 target .set_pixel (x , y , (0 , 0 , 255 , 255 ))
@@ -306,24 +284,16 @@ def draw_precipitation(world, target, black_and_white=False):
306284 height = world .height
307285
308286 if black_and_white :
309- low = None
310- high = None
311- for y in range (height ):
312- for x in range (width ):
313- p = world .precipitations_at ((x , y ))
314- if low is None or p < low :
315- low = p
316- if high is None or p > high :
317- high = p
287+ low = world .precipitation ['data' ].min ()
288+ high = world .precipitation ['data' ].max ()
289+ floor = 0
290+ ceiling = 255
291+
292+ colors = numpy .interp (world .precipitation ['data' ], [low , high ], [floor , ceiling ])
293+ colors = numpy .rint (colors ).astype (dtype = numpy .int32 ) # proper rounding
318294 for y in range (height ):
319295 for x in range (width ):
320- p = world .precipitations_at ((x , y ))
321- if p <= low :
322- target .set_pixel (x , y , (0 , 0 , 0 , 255 ))
323- elif p >= high :
324- target .set_pixel (x , y , (255 , 255 , 255 , 255 ))
325- else :
326- target .set_pixel (x , y , gradient (p , low , high , (0 , 0 , 0 ), (255 , 255 , 255 )))
296+ target .set_pixel (x , y , (colors [y , x ], colors [y , x ], colors [y , x ], 255 ))
327297 else :
328298 for y in range (height ):
329299 for x in range (width ):
@@ -366,15 +336,14 @@ def draw_temperature_levels(world, target, black_and_white=False):
366336 if black_and_white :
367337 low = world .temperature_thresholds ()[0 ][1 ]
368338 high = world .temperature_thresholds ()[5 ][1 ]
339+ floor = 0
340+ ceiling = 255
341+
342+ colors = numpy .interp (world .temperature ['data' ], [low , high ], [floor , ceiling ])
343+ colors = numpy .rint (colors ).astype (dtype = numpy .int32 ) # proper rounding
369344 for y in range (height ):
370345 for x in range (width ):
371- t = world .temperature_at ((x , y ))
372- if t <= low :
373- target .set_pixel (x , y , (0 , 0 , 0 , 255 ))
374- elif t >= high :
375- target .set_pixel (x , y , (255 , 255 , 255 , 255 ))
376- else :
377- target .set_pixel (x , y , gradient (t , low , high , (0 , 0 , 0 ), (255 , 255 , 255 )))
346+ target .set_pixel (x , y , (colors [y , x ], colors [y , x ], colors [y , x ], 255 ))
378347
379348 else :
380349 for y in range (height ):
0 commit comments