def __init__(self, channels, area, time_slot, mode="L", crange=None, fill_value=None, palette=None): self.area = area self.time_slot = time_slot self.tags = {} self.gdal_options = {} Image.__init__(self, channels, mode, crange, fill_value, palette)
def to_image(dataset, copy=True, **kwargs): # Only add keywords if they are present for key in ["mode", "fill_value", "palette"]: if key in dataset.info: kwargs.setdefault(key, dataset.info[key]) if dataset.ndim == 2: return Image([dataset], copy=copy, **kwargs) elif dataset.ndim == 3: return Image([band for band in dataset], copy=copy, **kwargs) else: raise ValueError( "Don't know how to convert array with ndim %d to image" % dataset.ndim)
def __init__(self, channels, area, start_time, copy=True, mode="L", crange=None, fill_value=None, palette=None, **kwargs): self.area = area # FIXME: Should we be concerned with start time and end time? self.time_slot = start_time self.tags = {} self.gdal_options = {} Image.__init__(self, channels=channels, mode=mode, color_range=crange, fill_value=fill_value, palette=palette, copy=copy)
def plot(data, text, minmax=None, transpose=False, filename=None, position=(-16.743860721,64.915348712,712.4), tilt=None, target_position=None, target_name="", vfov=18.5, tick_distance=50.0): if transpose: data = data.transpose() if minmax is None: rainbow.set_range(data.min(),data.max()) else: rainbow.set_range(minmax[0],minmax[1]) img = Image(data, mode="L") img.colorize(rainbow) img = img.pil_image() # Decoration dc = DecoratorAGG(img) dc.align_bottom() #dc.add_logo("/home/sat/dev/pydecorate/logos/VI_Logo_Transp.png") #dc.add_logo("Nicarnica-Aviation-22-oct-300x102.png") try: dc.add_logo("/home/master/bin/futurevolc_logo.png", height=47) dc.add_logo("/home/master/bin/nicarnica_logo.png") dc.add_logo("/home/master/bin/vi_logo.png") except IOError: dc.add_logo("bin/futurevolc_logo.png", height=47) dc.add_logo("bin/nicarnica_logo.png") dc.add_logo("bin/vi_logo.png") dc.add_text(text, font=font) tick_space = 5.0 #dc.add_scale(rainbow, extend=True, unit='°C', tick_marks=tick_space, minor_tick_marks=tick_space) # target distance and km/px ny = data.shape[0] nx = data.shape[1] distance = distance_longlat(target_position,position) # plot grid lines, texts = prepare_graticule(nx, ny, distance=distance, vfov=vfov, tilt=tilt, tick_distance=tick_distance, height=position[2],target_height=target_position[2], target_name=target_name) draw_lines(img, lines) draw_texts(img, texts) if filename == None: img.show() else: img.save(filename, "JPEG", quality=90)
def save(self, filename, compression=6, tags=None, gdal_options=None, fformat=None, blocksize=256, **kwargs): """Save the image to the given *filename*. If the extension is "tif", the image is saved to geotiff_ format, in which case the *compression* level can be given ([0, 9], 0 meaning off). See also :meth:`image.Image.save`, :meth:`image.Image.double_save`, and :meth:`image.Image.secure_save`. The *tags* argument is a dict of tags to include in the image (as metadata), and the *gdal_options* holds options for the gdal saving driver. A *blocksize* other than 0 will result in a tiled image (if possible), with tiles of size equal to *blocksize*. If the specified format *fformat* is not know to satpy (and PIL), we will try to import module *fformat* and call the method `fformat.save`. .. _geotiff: http://trac.osgeo.org/geotiff/ """ file_tuple = os.path.splitext(filename) fformat = fformat or file_tuple[1][1:] if fformat.lower() in ('tif', 'tiff'): return self.geotiff_save(filename, compression, tags, gdal_options, blocksize, **kwargs) try: # Let image.pil_save it ? Image.save(self, filename, compression, fformat=fformat) except UnknownImageFormat: # No ... last resort, try to import an external module. logger.info("Importing image writer module '%s'" % fformat) try: saver = __import__(fformat, globals(), locals(), ['save']) except ImportError: raise UnknownImageFormat("Unknown image format '%s'" % fformat) saver.save(self, filename, **kwargs)
def _create_colorbar_image( colormap, minval, maxval, scale_height, scale_width, is_vertical ): if TImage is None: raise ImportError( "Missing 'trollimage' dependency. Required colorbar creation." ) if is_vertical: linedata = np.ones((scale_width, 1)) * np.arange( minval, maxval, float(maxval - minval) / scale_height ) linedata = linedata.transpose() else: linedata = np.ones((scale_height, 1)) * np.arange( minval, maxval, float(maxval - minval) / scale_width ) timg = TImage(linedata, mode="L") timg.colorize(colormap) return timg.pil_image()
def save(self, filename, compression=6, tags=None, gdal_options=None, fformat=None, blocksize=256, **kwargs): """Save the image to the given *filename*. If the extension is "tif", the image is saved to geotiff_ format, in which case the *compression* level can be given ([0, 9], 0 meaning off). See also :meth:`image.Image.save`, :meth:`image.Image.double_save`, and :meth:`image.Image.secure_save`. The *tags* argument is a dict of tags to include in the image (as metadata), and the *gdal_options* holds options for the gdal saving driver. A *blocksize* other than 0 will result in a tiled image (if possible), with tiles of size equal to *blocksize*. If the specified format *fformat* is not know to MPOP (and PIL), we will try to import module *fformat* and call the method `fformat.save`. .. _geotiff: http://trac.osgeo.org/geotiff/ """ file_tuple = os.path.splitext(filename) fformat = fformat or file_tuple[1][1:] if fformat.lower() in ('tif', 'tiff'): return self.geotiff_save(filename, compression, tags, gdal_options, blocksize, **kwargs) try: # Let image.pil_save it ? Image.save(self, filename, compression, fformat=fformat) except UnknownImageFormat: # No ... last resort, try to import an external module. logger.info("Importing image writer module '%s'" % fformat) try: saver = __import__(fformat, globals(), locals(), ['save']) except ImportError: raise UnknownImageFormat( "Unknown image format '%s'" % fformat) saver.save(self, filename, **kwargs)
def pilimage2trollimage(pimage): (r, g, b) = _image2array(pimage) return Image((r, g, b), mode="RGB")
Image.alpha_composite(background, foreground).save(outputFile) cw = ContourWriterAGG('/opt/pytroll/shapes') cw.add_coastlines_to_file(outputFile, swiss, outline="blue", resolution='h', level=2) cw.add_borders_to_file(outputFile, swiss, outline="yellow", resolution='i',level=3) img = Image.open(outputFile) draw = ImageDraw.Draw(img) draw.rectangle([(0, 0), (img.size[0], 25)], fill=(0,0,0,200)) font = ImageFont.truetype("/usr/openv/java/jre/lib/fonts/LucidaTypewriterBold.ttf", 18) draw.text((5, 3),"MSG HRV vs IR10.8 (DayNight) ccs4 20"+yearS+"-"+monthS+"-"+dayS+" "+hourS+":"+minS,(255,255,255),font=font) img.save(outputFile) imgarr = np.array(local_scene["IR_108"].data) imgarr = gaussian_filter(imgarr, sigma=1) img = Timage(imgarr, mode="L") #black = greys #black.colors[0] = np.array([0.,0.,0.]) #black.set_range(-40 + 273.15, 30 + 273.15) greys.set_range(-30 + 273.15, 30 + 273.15) #spectral.set_range(-90 + 273.15, -40.00001 + 273.15) #my_cm = spectral + greys setvak = cmap_from_text("setvak_rev.rgb", norm=True) setvak_new = setvak.colors[:,:3] setvak.colors = setvak_new setvak.set_range(-73 + 273.15, -30.00001 + 273.15) my_cm = setvak + greys img.colorize(my_cm) tmpFile = "/tmp/colir.png" img.save(tmpFile)
def _add_scale(self, colormap, title=None, **kwargs): # synchronize kwargs into style self.set_style(**kwargs) # sizes, current xy and margins x = self.style['cursor'][0] y = self.style['cursor'][1] mx = self.style['margins'][0] my = self.style['margins'][1] x_size, y_size = self.image.size # horizontal/vertical? is_vertical = False if self.style['propagation'][1] != 0: is_vertical = True # left/right? is_right = False if self.style['alignment'][0] == 1.0: is_right = True # top/bottom? is_bottom = False if self.style['alignment'][1] == 1.0: is_bottom = True # adjust new size based on extend (fill space) style, if self.style['extend']: if self.style['propagation'][0] == 1: self.style['width'] = (x_size - x) elif self.style['propagation'][0] == -1: self.style['width'] = x if self.style['propagation'][1] == 1: self.style['height'] = (y_size - y) elif self.style['propagation'][1] == -1: self.style['height'] = y # set scale spacer for units and other x_spacer = 0 y_spacer = 0 if self.style['unit']: if is_vertical: y_spacer = 40 else: x_spacer = 40 # draw object draw = self._get_canvas(self.image) # draw base px = (self.style['propagation'][0] + self.style['newline_propagation'][0]) py = (self.style['propagation'][1] + self.style['newline_propagation'][1]) x1 = x + px * self.style['width'] y1 = y + py * self.style['height'] self._draw_rectangle(draw, [x, y, x1, y1], **self.style) # scale dimensions scale_width = self.style['width'] - 2 * mx - x_spacer scale_height = self.style['height'] - 2 * my - y_spacer # generate color scale image obj inset by margin size mx my, from trollimage.image import Image as TImage #### THIS PART TO BE INGESTED INTO A COLORMAP FUNCTION #### minval, maxval = colormap.values[0], colormap.values[-1] if is_vertical: linedata = np.ones( (scale_width, 1)) * np.arange(minval, maxval, float(maxval - minval) / scale_height) linedata = linedata.transpose() else: linedata = np.ones( (scale_height, 1)) * np.arange(minval, maxval, float(maxval - minval) / scale_width) timg = TImage(linedata, mode="L") timg.colorize(colormap) scale = timg.pil_image() ########################################################### # finalize (must be before paste) self._finalize(draw) # paste scale onto image pos = (min(x, x1) + mx, min(y, y1) + my) self.image.paste(scale, pos) # reload draw object draw = self._get_canvas(self.image) # draw tick marks val_steps = _round_arange2(minval, maxval, self.style['tick_marks']) minor_steps = _round_arange( minval, maxval, self.style['minor_tick_marks']) ffra, fpow = _optimize_scale_numbers( minval, maxval, self.style['tick_marks']) form = "%" + "." + str(ffra) + "f" last_x = x + px * mx last_y = y + py * my ref_w, ref_h = self._draw_text( draw, (0, 0), form % (val_steps[0]), dry_run=True, **self.style) if is_vertical: # major offset_start = val_steps[0] - minval offset_end = val_steps[-1] - maxval y_steps = py * (val_steps - minval - offset_start - offset_end) * scale_height / (maxval - minval) + y + py * my y_steps = y_steps[::-1] for i, ys in enumerate(y_steps): self._draw_line( draw, [(x + px * mx, ys), (x + px * (mx + scale_width / 3.0), ys)], **self.style) if abs(ys - last_y) > ref_h: self._draw_text( draw, (x + px * (mx + 2 * scale_width / 3.0), ys), (form % (val_steps[i])).strip(), **self.style) last_y = ys # minor y_steps = py * (minor_steps - minval) * \ scale_height / (maxval - minval) + y + py * my y_steps = y_steps[::-1] for i, ys in enumerate(y_steps): self._draw_line( draw, [(x + px * mx, ys), (x + px * (mx + scale_width / 6.0), ys)], **self.style) else: # major x_steps = px * (val_steps - minval) * \ scale_width / (maxval - minval) + x + px * mx for i, xs in enumerate(x_steps): self._draw_line( draw, [(xs, y + py * my), (xs, y + py * (my + scale_height / 3.0))], **self.style) if abs(xs - last_x) > ref_w: self._draw_text( draw, (xs, y + py * (my + 2 * scale_height / 3.0)), (form % (val_steps[i])).strip(), **self.style) last_x = xs # minor x_steps = px * (minor_steps - minval) * \ scale_width / (maxval - minval) + x + px * mx for i, xs in enumerate(x_steps): self._draw_line( draw, [(xs, y + py * my), (xs, y + py * (my + scale_height / 6.0))], **self.style) # draw unit and/or power if set if self.style['unit']: # calculate position if is_vertical: if is_right: x_ = x - mx - scale_width / 2.0 else: x_ = x + mx + scale_width / 2.0 y_ = y + my + scale_height + y_spacer / 2.0 else: x_ = x + mx + scale_width + x_spacer / 2.0 if is_bottom: y_ = y - my - scale_height / 2.0 else: y_ = y + my + scale_height / 2.0 # draw marking self._draw_text(draw, (x_, y_), self.style['unit'], **self.style) if title: # calculate position tw, th = draw.textsize(title, self.style['font']) if is_vertical: # TODO: Rotate the text? if is_right: x = x - mx - scale_width - tw else: x = x + mx + scale_width + tw y = y + my + scale_height / 2.0 else: x = x + mx + scale_width / 2.0 if is_bottom: y = y - my - scale_height - th else: y = y + my + scale_height + th self._draw_text(draw, (x, y), title, **self.style) # finalize self._finalize(draw)
plt.show() if save_black_white_png: local_scene.save_dataset('lscl', './lscl_' + area + '.png') print(dir(local_scene.save_dataset)) print('display ./lscl_' + area + '.png &') # save png file for SATLive ############################## if area == "cosmo1x150" or area == "cosmo1": png_file = start_time.strftime('/data/cinesat/out/MSG_lscl-' + area + '_%y%m%d%H%M.png') from trollimage.colormap import spectral, greys, ylorrd, rdgy imgarr = np.array(local_scene['lscl'].data) from trollimage.image import Image as Timage img = Timage(imgarr, mode="L") img.colorize(rdgy.reverse()) img.save(png_file) # local_scene.save_dataset( 'lscl', png_file ) from pyresample.utils import load_area swiss = load_area("/opt/users/hau/monti-pytroll/etc/areas.def", area) from pycoast import ContourWriterAGG cw = ContourWriterAGG('/opt/users/common/shapes') cw.add_borders_to_file(png_file, swiss, outline="green", resolution='i', level=3,
cot_img.enhance(stretch="crude") #bgimg = germ_scene[10.8].as_image() bgimg = germ_scene.image.ir108() fls_img, fogmask = germ_scene.image.fls_day(elevation_ger.image_data, cot_ger.image_data, reff_ger.image_data, cwp_ger.image_data) snow_rgb = germ_scene.image.snow() daymicro_rgb = germ_scene.image.day_microphysics() overview = germ_scene.image.overview() # Merge masked and colorized fog clouds with backgrund infrared image bgimg.convert("RGB") fls_img = Image(fls_img.channels[0], mode='L') fls_img.colorize(fogcol) fls_img.merge(bgimg) ele_img = Image(ele_img.channels[0], mode='L') #cwp_img = Image(cwp_img.channels[0], mode='L') #cwp_masked = np.ma.array(cwp_ger.image_data, mask=fogmask) #print(np.histogram(cwp_masked.compressed())) #ele_img.show() #cwp_img.show() #overview.show() #fls_img.show() #snow_rgb.show() #daymicro_rgb.show() ele_img.save("/tmp/fog_example_msg_ger_elevation_{}.png".format( time.strftime("%Y%m%d%H%M")))
scn.load(['sea_surface_temperature']) lcd = scn.resample('euro4', radius_of_influence=2000) sstdata = lcd['sea_surface_temperature'][:] import numpy as np arr = np.ma.where(np.less_equal(sstdata, 0), 0, sstdata - 273.15) # Convert sst to numbers between 0 and 28, corresponding to the lut: data = np.ma.where(np.less(arr, 0), 28, 28.0 - arr) data = np.ma.where(np.greater(arr, 23.0), 4, data).round().astype('uint8') from trollimage.image import Image from satpy.imageo import palettes palette = palettes.sstlut_osisaf_metno() img = Image(data, mode='P', palette=palette) img.show() img.save('osisaf_sst_viirs_satpy.png') from pycoast import ContourWriter cw_ = ContourWriter('/home/a000680/data/shapes') pilim = img.pil_image() area_def = lcd['sea_surface_temperature'].info['area'] cw_.add_coastlines(pilim, area_def, resolution='i', level=1, outline=(220, 220, 220)) pilim.show() pilim.save('./osisaf_sst_viirs_satpy_withovl.png')
) scn.load(['sea_surface_temperature']) lcd = scn.resample('euro4', radius_of_influence=2000) sstdata = lcd['sea_surface_temperature'][:] import numpy as np arr = np.ma.where(np.less_equal(sstdata, 0), 0, sstdata - 273.15) # Convert sst to numbers between 0 and 28, corresponding to the lut: data = np.ma.where(np.less(arr, 0), 28, 28.0 - arr) data = np.ma.where(np.greater(arr, 23.0), 4, data).round().astype('uint8') from trollimage.image import Image from satpy.imageo import palettes palette = palettes.sstlut_osisaf_metno() img = Image(data, mode='P', palette=palette) img.show() img.save('osisaf_sst_viirs_satpy.png') from pycoast import ContourWriter cw_ = ContourWriter('/home/a000680/data/shapes') pilim = img.pil_image() area_def = lcd['sea_surface_temperature'].info['area'] cw_.add_coastlines( pilim, area_def, resolution='i', level=1, outline=(220, 220, 220)) pilim.show() pilim.save('./osisaf_sst_viirs_satpy_withovl.png')
def _add_scale(self, colormap, title=None, **kwargs): # synchronize kwargs into style self.set_style(**kwargs) # sizes, current xy and margins x = self.style['cursor'][0] y = self.style['cursor'][1] mx = self.style['margins'][0] my = self.style['margins'][1] x_size, y_size = self.image.size # horizontal/vertical? is_vertical = False if self.style['propagation'][1] != 0: is_vertical = True # left/right? is_right = False if self.style['alignment'][0] == 1.0: is_right = True # top/bottom? is_bottom = False if self.style['alignment'][1] == 1.0: is_bottom = True # adjust new size based on extend (fill space) style, if self.style['extend']: if self.style['propagation'][0] == 1: self.style['width'] = (x_size - x) elif self.style['propagation'][0] == -1: self.style['width'] = x if self.style['propagation'][1] == 1: self.style['height'] = (y_size - y) elif self.style['propagation'][1] == -1: self.style['height'] = y # set scale spacer for units and other x_spacer = 0 y_spacer = 0 if self.style['unit']: if is_vertical: y_spacer = 40 else: x_spacer = 40 # draw object draw = self._get_canvas(self.image) # draw base px = (self.style['propagation'][0] + self.style['newline_propagation'][0]) py = (self.style['propagation'][1] + self.style['newline_propagation'][1]) x1 = x + px * self.style['width'] y1 = y + py * self.style['height'] self._draw_rectangle(draw, [x, y, x1, y1], **self.style) # scale dimensions scale_width = self.style['width'] - 2 * mx - x_spacer scale_height = self.style['height'] - 2 * my - y_spacer # generate color scale image obj inset by margin size mx my, from trollimage.image import Image as TImage #### THIS PART TO BE INGESTED INTO A COLORMAP FUNCTION #### minval, maxval = colormap.values[0], colormap.values[-1] if is_vertical: linedata = np.ones((scale_width, 1)) * np.arange( minval, maxval, float(maxval - minval) / scale_height) linedata = linedata.transpose() else: linedata = np.ones((scale_height, 1)) * np.arange( minval, maxval, float(maxval - minval) / scale_width) timg = TImage(linedata, mode="L") timg.colorize(colormap) scale = timg.pil_image() ########################################################### # finalize (must be before paste) self._finalize(draw) # paste scale onto image pos = (min(x, x1) + mx, min(y, y1) + my) self.image.paste(scale, pos) # reload draw object draw = self._get_canvas(self.image) # draw tick marks val_steps = _round_arange2(minval, maxval, self.style['tick_marks']) minor_steps = _round_arange(minval, maxval, self.style['minor_tick_marks']) ffra, fpow = _optimize_scale_numbers(minval, maxval, self.style['tick_marks']) form = "%" + "." + str(ffra) + "f" last_x = x + px * mx last_y = y + py * my ref_w, ref_h = self._draw_text(draw, (0, 0), form % (val_steps[0]), dry_run=True, **self.style) if is_vertical: # major offset_start = val_steps[0] - minval offset_end = val_steps[-1] - maxval y_steps = py * (val_steps - minval - offset_start - offset_end ) * scale_height / (maxval - minval) + y + py * my y_steps = y_steps[::-1] for i, ys in enumerate(y_steps): self._draw_line(draw, [(x + px * mx, ys), (x + px * (mx + scale_width / 3.0), ys)], **self.style) if abs(ys - last_y) > ref_h: self._draw_text( draw, (x + px * (mx + 2 * scale_width / 3.0), ys), (form % (val_steps[i])).strip(), **self.style) last_y = ys # minor y_steps = py * (minor_steps - minval) * \ scale_height / (maxval - minval) + y + py * my y_steps = y_steps[::-1] for i, ys in enumerate(y_steps): self._draw_line(draw, [(x + px * mx, ys), (x + px * (mx + scale_width / 6.0), ys)], **self.style) else: # major x_steps = px * (val_steps - minval) * \ scale_width / (maxval - minval) + x + px * mx for i, xs in enumerate(x_steps): self._draw_line(draw, [(xs, y + py * my), (xs, y + py * (my + scale_height / 3.0))], **self.style) if abs(xs - last_x) > ref_w: self._draw_text( draw, (xs, y + py * (my + 2 * scale_height / 3.0)), (form % (val_steps[i])).strip(), **self.style) last_x = xs # minor x_steps = px * (minor_steps - minval) * \ scale_width / (maxval - minval) + x + px * mx for i, xs in enumerate(x_steps): self._draw_line(draw, [(xs, y + py * my), (xs, y + py * (my + scale_height / 6.0))], **self.style) # draw unit and/or power if set if self.style['unit']: # calculate position if is_vertical: if is_right: x_ = x - mx - scale_width / 2.0 else: x_ = x + mx + scale_width / 2.0 y_ = y + my + scale_height + y_spacer / 2.0 else: x_ = x + mx + scale_width + x_spacer / 2.0 if is_bottom: y_ = y - my - scale_height / 2.0 else: y_ = y + my + scale_height / 2.0 # draw marking self._draw_text(draw, (x_, y_), self.style['unit'], **self.style) if title: # calculate position tw, th = draw.textsize(title, self.style['font']) if is_vertical: # TODO: Rotate the text? if is_right: x = x - mx - scale_width - tw else: x = x + mx + scale_width + tw y = y + my + scale_height / 2.0 else: x = x + mx + scale_width / 2.0 if is_bottom: y = y - my - scale_height - th else: y = y + my + scale_height + th self._draw_text(draw, (x, y), title, **self.style) # finalize self._finalize(draw)
print(arr.shape) print(np.min(arr)) # Get bufr file base = os.path.split(fogpy.__file__) inbufr = os.path.join(base[0], '..', 'etc', 'result_{}.bufr'.format(time.strftime("%Y%m%d"))) # bufr_dir = '/data/tleppelt/skydata/' # bufr_file = "result_{}".format(time.strftime("%Y%m%d")) # inbufr = os.path.join(bufr_dir, bufr_file) area_id = "geos_germ" name = "geos_germ" proj_id = "geos" proj_dict = { 'a': '6378169.00', 'lon_0': '0.00', 'h': '35785831.00', 'b': '6356583.80', 'proj': 'geos', 'lat_0': '0.00' } x_size = 298 * resize y_size = 141 * resize area_extent = (214528.82635591552, 4370087.2110124603, 1108648.9697693815, 4793144.0573926577) area_def = geometry.AreaDefinition(area_id, name, proj_id, proj_dict, x_size, y_size, area_extent) print(area_def) img = Image(arr[:, :, :3], mode='RGB') add_to_image(img, area_def, time, inbufr)
def add_to_image(image, area, time, bufr, savedir='/tmp', name=None, bgimg=None, resize=None, ptsize=None, save=False): """Add synoptical visibility reports from station data to provided geolocated image array """ arrshp = image.shape[:2] # Add optional background image if bgimg is not None: # Get background image bg_img = Image(bgimg.squeeze(), mode='L', fill_value=None) bg_img.stretch("crude") bg_img.convert("RGB") # bg_img.invert() image.merge(bg_img) # Import bufr stations = read_synop(bufr, 'visibility') currentstations = stations[time.strftime("%Y%m%d%H0000")] lats = [i[2] for i in currentstations] lons = [i[3] for i in currentstations] vis = [i[4] for i in currentstations] # Create array for synop parameter visarr = np.empty(arrshp) visarr.fill(np.nan) # Red - Violet - Blue - Green vis_colset = Colormap((0, (228 / 255.0, 26 / 255.0, 28 / 255.0)), (1000, (152 / 255.0, 78 / 255.0, 163 / 255.0)), (5000, (55 / 255.0, 126 / 255.0, 184 / 255.0)), (10000, (77 / 255.0, 175 / 255.0, 74 / 255.0))) x, y = (area.get_xy_from_lonlat(lons, lats)) vis_ma = np.ma.array(vis, mask=x.mask) if ptsize: xpt = np.array([]) ypt = np.array([]) for i, j in zip(x, y): xmesh, ymesh = np.meshgrid( np.linspace(i - ptsize, i + ptsize, ptsize * 2 + 1), np.linspace(j - ptsize, j + ptsize, ptsize * 2 + 1)) xpt = np.append(xpt, xmesh.ravel()) ypt = np.append(ypt, ymesh.ravel()) vispt = np.ma.array( [np.full(((ptsize * 2 + 1, ptsize * 2 + 1)), p) for p in vis_ma]) visarr[ypt.astype(int), xpt.astype(int)] = vispt.ravel() else: visarr[y.compressed(), x.compressed()] = vis_ma.compressed() visarr_ma = np.ma.masked_invalid(visarr) station_img = Image(visarr_ma, mode='L') station_img.colorize(vis_colset) image.convert("RGB") station_img.merge(image) if resize is not None: station_img.resize((arrshp[0] * resize, arrshp[1] * resize)) if name is None: timestr = time.strftime("%Y%m%d%H%M") name = "fog_filter_example_stations_{}.png".format(timestr) if save: savepath = os.path.join(savedir, name) station_img.save(savepath) return (station_img)
def add_to_array(arr, area, time, bufr, savedir='/tmp', name=None, mode='L', resize=None, ptsize=None, save=False): """Add synoptical reports from stations to provided geolocated image array """ # Create array image arrshp = arr.shape[:2] print(np.nanmin(arr), np.nanmax(arr)) arr_img = Image(arr, mode=mode) # arr_img = Image(channels=[arr[:, :, 0], arr[:, :, 1], arr[:, :, 2]], # mode='RGB') arr_img.stretch('crude') arr_img.invert() arr_img.colorize(maskcol) arr_img.invert() # Import bufr stations = read_synop(bufr, 'visibility') currentstations = stations[time.strftime("%Y%m%d%H0000")] lats = [i[2] for i in currentstations] lons = [i[3] for i in currentstations] vis = [i[4] for i in currentstations] # Create array for synop parameter visarr = np.empty(arrshp) visarr.fill(np.nan) x, y = (area.get_xy_from_lonlat(lons, lats)) vis_ma = np.ma.array(vis, mask=x.mask) if ptsize: xpt = np.array([]) ypt = np.array([]) for i, j in zip(x, y): xmesh, ymesh = np.meshgrid( np.linspace(i - ptsize, i + ptsize, ptsize * 2 + 1), np.linspace(j - ptsize, j + ptsize, ptsize * 2 + 1)) xpt = np.append(xpt, xmesh.ravel()) ypt = np.append(ypt, ymesh.ravel()) vispt = np.ma.array( [np.full(((ptsize * 2 + 1, ptsize * 2 + 1)), p) for p in vis_ma]) visarr[ypt.astype(int), xpt.astype(int)] = vispt.ravel() else: visarr[y.compressed(), x.compressed()] = vis_ma.compressed() visarr_ma = np.ma.masked_invalid(visarr) station_img = Image(visarr_ma, mode='L') station_img.colorize(vis_colset) station_img.merge(arr_img) if resize is not None: station_img.resize((arrshp[0] * resize, arrshp[1] * resize)) if name is None: timestr = time.strftime("%Y%m%d%H%M") name = "fog_filter_example_stations_{}.png".format(timestr) if save: savepath = os.path.join(savedir, name) station_img.save(savepath) return (station_img)
def save(self, filename, compression=6, tags=None, gdal_options=None, fformat=None, blocksize=256, writer_options=None, **kwargs): """Save the image to the given *filename*. If the extension is "tif", the image is saved to geotiff_ format, in which case the *compression* level can be given ([0, 9], 0 meaning off). See also :meth:`image.Image.save`, :meth:`image.Image.double_save`, and :meth:`image.Image.secure_save`. The *tags* argument is a dict of tags to include in the image (as metadata), and the *gdal_options* holds options for the gdal saving driver. A *blocksize* other than 0 will result in a tiled image (if possible), with tiles of size equal to *blocksize*. If the specified format *fformat* is not know to MPOP (and PIL), we will try to import module *fformat* and call the method `fformat.save`. Use *writer_options* to define parameters that should be forwarded to custom writers. Dictionary keys listed in mpop.imageo.formats.writer_options will be interpreted by this function instead of *compression*, *blocksize* and nbits in *tags* dict. .. _geotiff: http://trac.osgeo.org/geotiff/ """ fformat = fformat or os.path.splitext(filename)[1][1:] # prefer parameters in writer_options dict # fill dict if parameters are missing writer_options = writer_options or {} tags = tags or {} if writer_options.get(write_opts.WR_OPT_COMPRESSION, None): compression = writer_options[write_opts.WR_OPT_COMPRESSION] elif compression is not None: writer_options[write_opts.WR_OPT_COMPRESSION] = compression if writer_options.get(write_opts.WR_OPT_BLOCKSIZE, None): blocksize = writer_options[write_opts.WR_OPT_BLOCKSIZE] elif blocksize is not None: writer_options[write_opts.WR_OPT_BLOCKSIZE] = blocksize if writer_options.get(write_opts.WR_OPT_NBITS, None): tags['NBITS'] = writer_options[write_opts.WR_OPT_NBITS] elif tags.get('NBITS') is not None: writer_options[write_opts.WR_OPT_NBITS] = tags.get('NBITS') if fformat.lower() in ('tif', 'tiff'): kwargs = kwargs or {} kwargs['writer_options'] = writer_options return self.geotiff_save(filename, compression, tags, gdal_options, blocksize, **kwargs) try: # Let image.pil_save it ? Image.save(self, filename, compression, fformat=fformat) except UnknownImageFormat: # No ... last resort, try to import an external module. logger.info("Importing image writer module '%s'" % fformat) try: saver = __import__(fformat, globals(), locals(), ['save']) except ImportError: raise UnknownImageFormat( "Unknown image format '%s'" % fformat) kwargs = kwargs or {} kwargs['writer_options'] = writer_options saver.save(self, filename, **kwargs)
def _add_scale(self, colormap, **kwargs): # synchronize kwargs into style self.set_style(**kwargs) gamma = kwargs.get('gamma', 1.0) # sizes, current xy and margins x=self.style['cursor'][0] y=self.style['cursor'][1] mx=self.style['margins'][0] my=self.style['margins'][1] x_size,y_size = self.image.size #print('Cursor', x, y) # horizontal/vertical? is_vertical = False if self.style['propagation'][1] != 0: is_vertical = True # left/right? is_right = False if self.style['alignment'][0] == 1.0: is_right = True # top/bottom? is_bottom = False if self.style['alignment'][1] == 1.0: is_bottom = True #print('ISBOTTO: '+is_bottom) # adjust new size based on extend (fill space) style, if self.style['extend']: if self.style['propagation'][0] == 1: self.style['width'] = (x_size - x) elif self.style['propagation'][0] == -1: self.style['width'] = x if self.style['propagation'][1] == 1: self.style['height'] = (y_size - y) elif self.style['propagation'][1] == -1: self.style['height'] = y # set scale spacer for units and other x_spacer = 0 y_spacer = 0 if self.style['unit']: if is_vertical: y_spacer = 40 else: x_spacer = 40 # draw object draw = self._get_canvas(self.image) # draw base px = (self.style['propagation'][0] + self.style['newline_propagation'][0]) py = (self.style['propagation'][1] + self.style['newline_propagation'][1]) x1 = x + px*self.style['width'] y1 = y + py*self.style['height'] self._draw_rectangle(draw,[x,y,x1,y1],**self.style) # scale dimensions scale_width = self.style['width'] - 2*mx - x_spacer scale_height = self.style['height'] - 2*my - y_spacer # generate color scale image obj inset by margin size mx my, from trollimage.image import Image as TImage #### THIS PART TO BE INGESTED INTO A COLORMAP FUNCTION #### minval,maxval = colormap.values[0],colormap.values[-1] if is_vertical: #linedata = np.ones((scale_width/2.0,1)) * np.arange(minval,maxval,(maxval-minval)/scale_height) #linedata = np.ones((scale_width/2.0,1))**gamma *np.linspace(minval, maxval, scale_width) linedata = np.ones((scale_width/2,1))*(np.linspace(0,1,scale_height)**(1.0 / gamma) *(maxval-minval)+minval) linedata = linedata.transpose() else: #linedata = np.ones((scale_height/2.0,1)) * np.arange(minval,maxval,(maxval-minval)/scale_width) #linedata = np.ones((scale_height/2.0,1))**gamma *np.linspace(minval, maxval, scale_width) linedata = np.ones((scale_height/2,1))*(np.linspace(0,1,scale_width)**(1.0 / gamma) *(maxval-minval)+minval) timg = TImage(linedata,mode="L") print(kwargs.get('palettize')) if kwargs.get('palettize', False): timg.palettize(colormap) else: timg.colorize(colormap) scale = timg.pil_image() ########################################################### # finalize (must be before paste) self._finalize(draw) # paste scale onto image pos =(min(x,x1)+mx,min(y,y1)+my) self.image.paste(scale,pos) # reload draw object draw = self._get_canvas(self.image) # draw tick marks val_steps = _round_arange2( minval, maxval , self.style['tick_marks'] ) minor_steps = _round_arange( minval, maxval , self.style['minor_tick_marks'] ) ffra, fpow = _optimize_scale_numbers( minval, maxval, self.style['tick_marks'] ) form = "%"+"."+str(ffra)+"f" last_x = x+px*mx last_y = y+py*my ref_w, ref_h = self._draw_text(draw, (0,0), form%(val_steps[0]), dry_run=True, **self.style) #tick_length=10 tick_length=round(scale_height*0.20) #print('scale_height: '+str(scale_height)) if is_vertical: # major offset_start = val_steps[0] - minval offset_end = val_steps[-1] - maxval y_steps = py*(val_steps - minval - offset_start - offset_end)*scale_height/(maxval-minval)+y+py*my y_steps = y_steps[::-1] for i, ys in enumerate(y_steps): self._draw_line(draw,[(x+px*mx,ys),(x+px*(mx+scale_width/3.0),ys)],**self.style) if abs(ys-last_y)>ref_h: self._draw_text(draw,(x+px*(mx+2*scale_width/3.0),ys), (form%(val_steps[i])).strip(), **self.style) last_y = ys # minor y_steps = py*(minor_steps - minval)*scale_height/(maxval-minval)+y+py*my y_steps = y_steps[::-1] for i, ys in enumerate(y_steps): self._draw_line(draw,[(x+px*mx,ys),(x+px*(mx+scale_width/6.0),ys)],**self.style) else: # major x_steps = px*(val_steps - minval)*scale_width/(maxval-minval)+x+px*mx #print(x_steps) #print(y, py,(my+2*scale_height/3.0)) for i, xs in enumerate(x_steps): #self._draw_line(draw,[(xs,y+py*my+scale_height/2.0-tick_length/2.0),(xs,y+py*(my+scale_height/2.0+tick_length/2.0))],**self.style) self._draw_line(draw,[(xs,y+py*(my+scale_height/2.0-tick_length/2.0)),(xs,y+py*(my+scale_height/2.0+tick_length/2.0))],**self.style) #print(abs(xs-last_x),xs,last_x, ref_w) #print((form%(val_steps[i])).strip()) if abs(xs-last_x)>ref_w or xs==last_x: center_y=y+py*(my+scale_height/2.0) font_height=self.style['font'].getmetrics()[0] #self._draw_text(draw,(xs, y+py*(my+2*scale_height/3.0)), (form%(val_steps[i])).strip(), **self.style) self._draw_text(draw,(xs, center_y+tick_length/2.0+font_height/2.0), (form%(val_steps[i])).strip(), **self.style) last_x = xs # minor x_steps = px*(minor_steps - minval)*scale_width/(maxval-minval)+x+px*mx for i, xs in enumerate(x_steps): self._draw_line(draw,[(xs,y+py*(my+scale_height/2.0-tick_length/4.0)),(xs,y+py*(my+scale_height/2.0+tick_length/4.0))],**self.style) # self._draw_line(draw,[(xs,y+py*my),(xs,y+py*(my+scale_height/6.0))],**self.style) # draw unit and/or power if set if self.style['unit']: # calculate position if is_vertical: if is_right: x = x - mx - scale_width/2.0 else: x = x + mx + scale_width/2.0 y = y + my + scale_height + y_spacer/2.0 else: x = x + mx + scale_width + x_spacer/2.0 if is_bottom: y = y - my - scale_height/2.0 else: y = y + my + scale_height/2.0 # draw marking self._draw_text(draw,(x,y),self.style['unit'],**self.style) # finalize self._finalize(draw)