class Plotter(datatypes.Plotter): supported_crss = tuple(_CRSS.values()) geographic_bounding_box = macro.wmscrs()["geographic_bounding_box"] log = logging.getLogger(__name__) def __init__(self, baselayer=None, styles=None): if styles is None: styles = {} self._styles = styles layers = [ StaticLayer("foreground", title="Foreground", zindex=99999), StaticLayer("background", title="Background", zindex=-99999), StaticLayer("grid", title="Grid", zindex=99999), StaticLayer("boundaries", title="Boundaries", zindex=99999), OceanLayer("oceans", title="Oceans", zindex=99999), USLayer("us-states", title="Us States", zindex=99999), ] if baselayer: name = os.path.basename(baselayer) try: name = os.path.basename(baselayer) except: name = "user defined baselayer" base = UserBaseLayer(name, title=name, zindex=99999) base.layer = baselayer layers.append(base) self._layers = {layer.name: layer for layer in layers} def layers(self): for layer in self._layers.values(): yield layer def layer(self, name, time=None): try: return self._layers[name] except KeyError: raise errors.LayerNotDefined("Unknown layer '{}'".format(name)) def plot( self, context, output, bbox, crs, format, height, layers, styles, version, width, transparent, _macro=False, bgcolor=None, elevation=None, exceptions=None, time=None, ): lon_vertical = 0.0 if crs.startswith("EPSG:32661:"): crs_name = "polar_north" lon_vertical = float(crs.split(":")[2]) elif crs.startswith("EPSG:32761:"): crs_name = "polar_south" lon_vertical = float(crs.split(":")[2]) elif crs == "EPSG:32761": crs_name = "EPSG:32761" else: try: crs = _CRSS[crs] crs_name = crs.name except KeyError: raise ValueError("Unsupported CRS '{}'".format(crs)) try: magics_format = MAGICS_OUTPUT_TYPES[format] except KeyError: raise errors.InvalidFormat(format) output_fname = output.target(magics_format) path, _ = os.path.splitext(output_fname) with LOCK: min_x, min_y, max_x, max_y = bbox # Magics is talking in cm. width_cm = width / 40.0 height_cm = height / 40.0 macro.silent() coordinates_system = {"EPSG:4326": "latlon"} map_params = { "subpage_map_projection": crs_name, "subpage_lower_left_latitude": min_y, "subpage_lower_left_longitude": min_x, "subpage_upper_right_latitude": max_y, "subpage_upper_right_longitude": max_x, "subpage_coordinates_system": coordinates_system.get(crs_name, "projection"), "subpage_frame": "off", "page_x_length": width_cm, "page_y_length": height_cm, "super_page_x_length": width_cm, "super_page_y_length": height_cm, "subpage_x_length": width_cm, "subpage_y_length": height_cm, "subpage_x_position": 0.0, "subpage_y_position": 0.0, "output_width": width, "page_frame": "off", "skinny_mode": "on", "page_id_line": "off", } # add extra settings for polar stereographic projection when # vertical longitude is not 0 if crs_name in ["polar_north", "polar_south"]: map_params["subpage_map_vertical_longitude"] = lon_vertical if crs_name in ["polar_north"]: map_params["subpage_map_true_scale_north"] = 90 if crs_name in ["polar_south"]: map_params["subpage_map_true_scale_south"] = -90 args = [ macro.output( output_formats=[magics_format], output_name_first_page_number="off", output_cairo_transparent_background=transparent, output_width=width, output_name=path, ), macro.mmap(**map_params), ] for layer, style in zip(layers, styles): style = layer.style(style) args += layer.render(context, macro, style) if _macro: return ( "text/x-python", self.macro_text( args, output.target(".py"), getattr(context, "data_url", None), layers, styles, ), ) # self.log.debug('plot(): Calling macro.plot(%s)', args) try: macro.plot(*args) except Exception as e: self.log.exception("Magics error: %s", e) raise self.log.debug("plot(): Size of %s: %s", output_fname, os.stat(output_fname).st_size) return format, output_fname def legend(self, context, output, format, height, layer, style, version, width, transparent): try: magics_format = MAGICS_OUTPUT_TYPES[format] except KeyError: raise errors.InvalidFormat(format) output_fname = output.target(magics_format) path, _ = os.path.splitext(output_fname) with LOCK: # Magics is talking in cm. width_cm = float(width) / 40.0 height_cm = float(height) / 40.0 args = [ macro.output( output_formats=[magics_format], output_name_first_page_number="off", output_cairo_transparent_background=transparent, output_width=width, output_name=path, ), macro.mmap( subpage_frame="off", page_x_length=width_cm, page_y_length=height_cm, super_page_x_length=width_cm, super_page_y_length=height_cm, subpage_x_length=width_cm, subpage_y_length=height_cm, subpage_x_position=0.0, subpage_y_position=0.0, output_width=width, page_frame="off", page_id_line="off", ), ] contour = layer.style(style, ) args += layer.render(context, macro, contour, { "legend": "on", "contour_legend_only": True }) legend_font_size = "25%" if width_cm < height_cm: legend_font_size = "5%" legend_title = layer.title if hasattr(layer, legend_title): legend_title = layer.legend_title legend = macro.mlegend( legend_title="on", legend_title_text=legend_title, legend_display_type="continuous", legend_box_mode="positional", legend_only=True, legend_box_x_position=0.00, legend_box_y_position=0.00, legend_box_x_length=width_cm, legend_box_y_length=height_cm, legend_box_blanking=not transparent, legend_text_font_size=legend_font_size, legend_text_colour="white", ) # self.log.debug('plot(): Calling macro.plot(%s)', args) try: macro.plot(*args, legend) except Exception as e: self.log.exception("Magics error: %s", e) raise self.log.debug("plot(): Size of %s: %s", output_fname, os.stat(output_fname).st_size) return output_fname def macro_text(self, args, output, data_url, layers, styles): head = [] for layer, style in zip(layers, styles): style = layer.style(style) head.append("# LAYER: %s" % (layer, )) head.append("# STYLE: %s" % (style, )) path = None text = [] for a in args: params = dict(**a.args) for k, v in list(params.items()): if k in ("output_name", "netcdf_filename", "grib_input_file_name"): params[k] = os.path.basename(v) if "netcdf_filename" in params: path = params["netcdf_filename"] if "grib_input_file_name" in params: path = params["grib_input_file_name"] text.append("") text.append("a = %s" % (pprint.pformat(params), )) text.append("args.append(macro.%s(**a))" % (a.verb, )) if path and data_url: text.append('download("%s", "%s")' % (data_url, path)) with open(output, "w") as f: f.write(MACRO_TEXT.format("\n".join(head), "\n".join(text))) return output
class Plotter(datatypes.Plotter): supported_crss = tuple(_CRSS.values()) geographic_bounding_box = macro.wmscrs()['geographic_bounding_box'] log = logging.getLogger(__name__) def __init__(self, styles=None): if styles is None: styles = {} self._styles = styles self._layers = { layer.name: layer for layer in [ StaticLayer('foreground', title='Foreground', zindex=99999), StaticLayer('background', title='Background', zindex=-99999), StaticLayer('grid', title='Grid', zindex=99999), StaticLayer('boundaries', title='Boundaries', zindex=99999), ] } def layers(self): for layer in self._layers.values(): yield layer def layer(self, name, time=None): try: return self._layers[name] except KeyError: raise errors.LayerNotDefined("Unknown layer '{}'".format(name)) def plot(self, context, output, bbox, crs, format, height, layers, styles, version, width, transparent, _macro=False, bgcolor=None, elevation=None, exceptions=None, time=None, ): try: crs = _CRSS[crs] except KeyError: raise ValueError("Unsupported CRS '{}'".format(crs)) try: magics_format = MAGICS_OUTPUT_TYPES[format] except KeyError: raise errors.InvalidFormat(format) output_fname = output.target(magics_format) print("OUTPUT", output_fname) path, _ = os.path.splitext(output_fname) with LOCK: min_x, min_y, max_x, max_y = bbox # Magics is talking in cm. width_cm = width / 40. height_cm = height / 40. macro.silent() args = [ macro.output(output_formats=[magics_format], output_name_first_page_number='off', output_cairo_transparent_background=transparent, output_width=width, output_name=path), macro.mmap(subpage_map_projection=crs.name, subpage_lower_left_latitude=min_x, subpage_lower_left_longitude=min_y, subpage_upper_right_latitude=max_x, subpage_upper_right_longitude=max_y, subpage_frame='off', page_x_length=width_cm, page_y_length=height_cm, super_page_x_length=width_cm, super_page_y_length=height_cm, subpage_x_length=width_cm, subpage_y_length=height_cm, subpage_x_position=0., subpage_y_position=0., output_width=width, page_frame='off', page_id_line='off',), ] for layer, style in zip(layers, styles): style = layer.style(style) args += layer.render(context, macro, style) if _macro: return self.macro_text(args, output.target('.py'), getattr(context, 'data_url', None), layers, styles) # self.log.debug('plot(): Calling macro.plot(%s)', args) try: macro.plot(*args) except Exception as e: self.log.exception('Magics error: %s', e) raise self.log.debug('plot(): Size of %s: %s', output_fname, os.stat(output_fname).st_size) return output_fname def legend(self, context, output, format, height, layer, style, version, width, transparent ): try: magics_format = MAGICS_OUTPUT_TYPES[format] except KeyError: raise errors.InvalidFormat(format) output_fname = output.target(magics_format) print(output_fname) path, _ = os.path.splitext(output_fname) with LOCK: # Magics is talking in cm. width_cm = float(width )/ 40. height_cm = float(height)/ 40. args = [ macro.output(output_formats=[magics_format], output_name_first_page_number='off', output_cairo_transparent_background=transparent, output_width=width, output_name=path), macro.mmap( subpage_frame='off', page_x_length=width_cm, page_y_length=height_cm, super_page_x_length=width_cm, super_page_y_length=height_cm, subpage_x_length=width_cm, subpage_y_length=height_cm, subpage_x_position=0., subpage_y_position=0., output_width=width, page_frame='off', page_id_line='off',), ] contour = layer.style(style, ) args += layer.render(context, macro, contour, { 'legend' : 'on', "contour_legend_only" : True}) legend_font_size = "25%" if width_cm < height_cm : legend_font_size = "5%" legend = macro.mlegend( legend_title = "on", legend_title_text = layer.title, legend_display_type = "continuous", legend_box_mode = "positional", legend_only = True, legend_box_x_position = 0.00, legend_box_y_position = 0.00, legend_box_x_length = width_cm, legend_box_y_length = height_cm, legend_box_blanking = not transparent, legend_text_font_size = legend_font_size, legend_text_colour = "navy", ) # self.log.debug('plot(): Calling macro.plot(%s)', args) try: macro.plot(*args, legend) except Exception as e: self.log.exception('Magics error: %s', e) raise self.log.debug('plot(): Size of %s: %s', output_fname, os.stat(output_fname).st_size) return output_fname def macro_text(self, args, output, data_url, layers, styles): head = [] for layer, style in zip(layers, styles): style = layer.style(style) head.append('# LAYER: %s' % (layer,)) head.append('# STYLE: %s' % (style,)) path = None text = [] for a in args: params = dict(**a.args) for k, v in list(params.items()): if k in ('output_name', 'netcdf_filename', 'grib_input_file_name'): params[k] = os.path.basename(v) if 'netcdf_filename' in params: path = params['netcdf_filename'] if 'grib_input_file_name' in params: path = params['grib_input_file_name'] text.append('') text.append("a = %s" % (pprint.pformat(params),)) text.append('args.append(macro.%s(**a))' % (a.verb,)) if path and data_url: text.append('download("%s", "%s")' % (data_url, path)) with open(output, 'w') as f: f.write(MACRO_TEXT.format('\n'.join(head), '\n'.join(text))) return output
import threading import pprint from Magics import macro from skinnywms import datatypes, errors __all__ = [ "Plotter", ] mimetypes.add_type("application/x-grib", ".grib", strict=False) mimetypes.add_type("application/x-netcdf", ".nc", strict=False) mimetypes.add_type("application/x-netcdf", ".nc4", strict=False) _CRSS = {crs["name"]: datatypes.CRS(**crs) for crs in macro.wmscrs()["crss"]} MAGICS_OUTPUT_TYPES = { "image/png": "png", } LOCK = threading.Lock() MACRO_TEXT = """ {} from Magics import macro import os try: import requests
from Magics import macro from skinnywms import datatypes, errors __all__ = [ 'Plotter', ] mimetypes.add_type('application/x-grib', '.grib', strict=False) mimetypes.add_type('application/x-netcdf', '.nc', strict=False) mimetypes.add_type('application/x-netcdf', '.nc4', strict=False) _CRSS = {crs['name']: datatypes.CRS(**crs) for crs in macro.wmscrs()['crss']} MAGICS_OUTPUT_TYPES = { 'image/png': 'png', } LOCK = threading.Lock() MACRO_TEXT = """ {} from Magics import macro import os try: