Exemplo n.º 1
0
def place_legend(datadir, document):
    """Place the ShakeMap intensity legend in the upper left corner of
    the viewer's map.

    Args:
        datadir (str): Path to data directory where output KMZ will be written.
        document (Element): LXML KML Document element.

    Returns:
        str: Path to output intensity legend file.
    """
    icon = skml.Icon(href=LEGEND)
    overlayxy = skml.OverlayXY(x=0, y=90, xunits='pixels', yunits='pixels')
    screenxy = skml.ScreenXY(x=5, y=1, xunits='pixels', yunits='fraction')
    size = skml.Size(x=0, y=0, xunits='pixels', yunits='pixels')
    document.newscreenoverlay(name='Intensity Legend', icon=icon,
                              overlayxy=overlayxy,
                              screenxy=screenxy,
                              size=size)

    # we need to find the legend file and copy it to
    # the output directory
    this_dir, _ = os.path.split(__file__)
    data_path = os.path.join(this_dir, '..', 'data', 'mapping')
    legend_file = os.path.join(data_path, LEGEND)
    legdest = os.path.join(datadir, LEGEND)
    shutil.copyfile(legend_file, legdest)
    return legdest
Exemplo n.º 2
0
    def _scalar2kmz(self, d, var, tndx, out_path, cleanup=True):
        """
        Postprocess a single raster variable ``fa`` and store result in out_path.

        :param d: the open netCDF file
        :param var: the variable name
        :param tndx: the temporal index of the grid to store
        :param out_path: the path to the KMZ output
        :param cleanup: if true, delete png files
        :return: the path to the generated KMZ
        """
        # construct kml file
        doc = kml.Kml(name=var)

        # generate the png files
        raster_path, cb_path, corner_coords = self._scalar2png(
            d, var, tndx, out_path)

        # add colorbar to KMZ
        if cb_path is not None:
            cbo = doc.newscreenoverlay(name='colorbar')
            cbo.overlayxy = kml.OverlayXY(x=0,
                                          y=1,
                                          xunits=kml.Units.fraction,
                                          yunits=kml.Units.fraction)
            cbo.screenxy = kml.ScreenXY(x=0.02,
                                        y=0.95,
                                        xunits=kml.Units.fraction,
                                        yunits=kml.Units.fraction)
            cbo.size = kml.Size(x=150,
                                y=300,
                                xunits=kml.Units.pixel,
                                yunits=kml.Units.pixel)
            cbo.color = kml.Color.rgb(255, 255, 255, a=150)
            cbo.visibility = 1
            #doc.addfile(cb_path)
            cbo.icon.href = cb_path

        # add ground overlay
        ground = doc.newgroundoverlay(name=var, color='80ffffff')
        ground.gxlatlonquad.coords = corner_coords
        #doc.addfile(raster_path)
        ground.icon.href = raster_path

        # build output file
        kmz_path = out_path + ".kmz"
        doc.savekmz(kmz_path)

        # cleanup
        if cleanup:
            os.remove(raster_path)
            if cb_path is not None:
                os.remove(cb_path)

        return kmz_path, raster_path, cb_path, corner_coords
Exemplo n.º 3
0
def create_kmz(maplayer, outfile, mask=None, levels=None, colorlist=None):
    """
    Create kmz files of models

    Args:
        maplayer (dict): Dictionary of one model result formatted like:

            .. code-block:: python

                {
                    'grid': mapio grid2D object,
                    'label': 'label for colorbar and top line of subtitle',
                    'type': 'output or input to model',
                    'description': 'description for subtitle'
                }
        outfile (str): File extension
        mask (float): make all cells below this value transparent
        levels (array): list of bin edges for each color, must be same length
        colorlist (array): list of colors for each bin, should be length one less than levels

    Returns:
        kmz file
    """
    # Figure out lims
    if levels is None:
        levels = DFBINS
    if colorlist is None:
        colorlist = DFCOLORS

    if len(levels)-1 != len(colorlist):
        raise Exception('len(levels) must be one longer than len(colorlist)')

    # Make place to put temporary files
    temploc = tempfile.TemporaryDirectory()

    # Figure out file names
    name, ext = os.path.splitext(outfile)
    basename = os.path.basename(name)
    if ext != '.kmz':
        ext = '.kmz'
    filename = '%s%s' % (name, ext)
    mapfile = os.path.join(temploc.name, '%s.tiff' % basename)
    legshort = '%s_legend.png' % basename
    legfile = os.path.join(temploc.name, legshort)

    # Make colored geotiff
    out = make_rgba(maplayer['grid'], mask=mask,
                    levels=levels, colorlist=colorlist)
    rgba_img, extent, lmin, lmax, cmap = out
    # Save as a tiff
    plt.imsave(mapfile, rgba_img, vmin=lmin, vmax=lmax, cmap=cmap)

    # Start creating kmz
    L = simplekml.Kml()

    # Set zoom window
    doc = L.document  # have to put lookat in root document directory
    doc.altitudemode = simplekml.AltitudeMode.relativetoground
    boundaries1 = get_zoomextent(maplayer['grid'])
    doc.lookat.latitude = np.mean([boundaries1['ymin'], boundaries1['ymax']])
    doc.lookat.longitude = np.mean([boundaries1['xmax'], boundaries1['xmin']])
    doc.lookat.altitude = 0.
    doc.lookat.range = (boundaries1['ymax']-boundaries1['ymin']) * 111. * 1000.  # dist in m from point
    doc.description = 'USGS near-real-time earthquake-triggered %s model for \
                       event id %s' % (maplayer['description']['parameters'] \
                       ['modeltype'], maplayer['description']['event_id'])

    prob = L.newgroundoverlay(name=maplayer['label'])
    prob.icon.href = 'files/%s.tiff' % basename
    prob.latlonbox.north = extent[3]
    prob.latlonbox.south = extent[2]
    prob.latlonbox.east = extent[1]
    prob.latlonbox.west = extent[0]
    L.addfile(mapfile)

    # Add legend and USGS icon as screen overlays
    # Make legend
    make_legend(levels, colorlist, filename=legfile, title=maplayer['label'])

    size1 = simplekml.Size(x=0.3, xunits=simplekml.Units.fraction)
    leg = L.newscreenoverlay(name='Legend', size=size1)
    leg.icon.href = 'files/%s' % legshort
    leg.screenxy = simplekml.ScreenXY(x=0.2, y=0.05, xunits=simplekml.Units.fraction,
                                      yunits=simplekml.Units.fraction)
    L.addfile(legfile)

    size2 = simplekml.Size(x=0.15, xunits=simplekml.Units.fraction)
    icon = L.newscreenoverlay(name='USGS', size=size2)
    icon.icon.href = 'files/USGS_ID_white.png'
    icon.screenxy = simplekml.ScreenXY(x=0.8, y=0.95, xunits=simplekml.Units.fraction,
                                       yunits=simplekml.Units.fraction)
    L.addfile(os.path.join(os.path.dirname(os.path.abspath(__file__)),
                           os.pardir, 'content', 'USGS_ID_white.png'))

    L.savekmz(filename)
    return filename
Exemplo n.º 4
0
def make_kmz(job_id, steps, mode, only_vars):
    """
    Create KMZ file from visualization stored in wrfxweb.
    :param job_id: string, the name of job directory
    :param steps: string '1,1,1,3' takes every 3rd frame in domain 4, etc. Default: all 1
    :param mode: string, 'inc', ' to include image files (default), 'ref' to use links only
    :param only_var: list of strings variables to include or None to include  all
    """

    logging.info('make_kmz: job_id=%s' % job_id)
    job_path = osp.join(osp.abspath(sys_cfg.sims_path),job_id)
    url_prefix = pxp.join(sys_cfg.url_root,sys_cfg.sims_url_path,job_id)
    logging.debug('make_kmz: job_path %s' % job_path)
    logging.debug('make_kmz: url_prefix %s' % url_prefix)


    if mode == '' or mode == "inc":
        kmz_filename = job_id + '_inc.kmz'
        href_prefix = osp.abspath(job_path)
        href_join = osp.join
        logging.debug('make_kmz: kmz file will include images from %s' % href_prefix)
        logging.info('make_kmz: kmz file will include images')
    elif mode == "ref":
        kmz_filename = job_id + '_ref.kmz'    
        href_prefix = url_prefix
        href_join = pxp.join
        logging.debug('make_kmz: kmz file will link to images from %s' % href_prefix)
        logging.info('make_kmz: kmz file will link to images')
    else:
        logging.error('make_kmz: arg 2 must be "inc" or "ref" or omitted')
        exit(1)
   
    # read the catalog and the manifest
    cat_path = osp.join(job_path,'catalog.json')
    cat = json.load(open(cat_path))
    if job_id not in cat:
         logging.error('job id %s not in the catalog' % job_id)
         sys.exit(1)
    cat_entry = cat[job_id]
    mf = json.load(open(osp.join(sys_cfg.sims_path,cat_entry['manifest_path'])))

    mdomain = max(map(int, mf.keys()))
    if steps=='':
        step=[1]
    else:
        step=map(int, steps.split(','))
    if len(step) == 1:
        step = step*mdomain
    elif len(step) != mdomain:
        logging.error('make_kmz: steps needed for all up to max domain number = %s' % mdomain)
        sys.exit(1)

    description = cat_entry['description']
    logging.info('make_kmz: job description: %s' % description)
    
    # transpose var and time in manifest, output to frame
    frame={}
    for domain in mf:
        for ts_esmf in mf[domain]:
            for var in mf[domain][ts_esmf]:
                if only_vars is None or var in only_vars:
                    update_nested_dict(frame,{domain:{var:{ts_esmf:mf[domain][ts_esmf][var]}}})
                     
    doc = kml.Kml(name=description)
    
    for domain in sorted(frame):
        domain_folder = doc.newfolder(name = domain)
        istep = step[int(domain)-1]
        logging.info('make_kmz: processing domain %s step %s' % (domain, istep))
        for var in frame[domain]:
            var_folder = domain_folder.newfolder(name = var)
            ts_esmf = sorted(frame[domain][var].keys())
            ts_esmf = ts_esmf[1::istep]
            ts_esmf1 = ts_esmf[1:]
            ts_esmf1.append(None)
            for ts_esmf,ts_esmf1 in zip(ts_esmf,ts_esmf1):
                ts_folder = var_folder.newfolder(name = ts_esmf)
                ts_folder.timespan.begin = ts_esmf.replace('_','T')+'Z'
                if ts_esmf1 is not None:
                     ts_folder.timespan.end = ts_esmf1.replace('_','T')+'Z'
                frame_data = frame[domain][var][ts_esmf]
                raster_path = frame_data['raster']
                coords = frame_data['coords']
                if 'colorbar' in frame_data:
                    # add colorbar to KMZ
                    cb_path = frame_data['colorbar']
                    cbo = ts_folder.newscreenoverlay(name='colorbar')
                    cbo.overlayxy = kml.OverlayXY(x=0,y=1,xunits=kml.Units.fraction,yunits=kml.Units.fraction)
                    cbo.screenxy = kml.ScreenXY(x=0.02,y=0.95,xunits=kml.Units.fraction,yunits=kml.Units.fraction)
                    cbo.size = kml.Size(x=150,y=300,xunits=kml.Units.pixel,yunits=kml.Units.pixel)
                    cbo.color = kml.Color.rgb(255,255,255,a=150)
                    cbo.visibility = 0
                    cbo.icon.href = href_join(href_prefix,cb_path)

                # add ground overlay
                ground = ts_folder.newgroundoverlay(name=var,color='80ffffff')
                ground.gxlatlonquad.coords = coords
                ground.visibility = 0
                ground.icon.href = href_join(href_prefix,raster_path)
    
    # build output file
    kmz_path = osp.join(job_path,kmz_filename)
    logging.info('make_kmz: creating file %s' % kmz_path) 
    doc.savekmz(kmz_path)
    url = pxp.join(url_prefix,kmz_filename)
    logging.info('make_kmz: file created at %s' % url) 
    try:
        r = requests.get(url, stream=True)
        content_size = int(r.headers['Content-Length'])
        logging.info('make_kmz: file size is %s' % content_size) 
        cat[job_id]['kml_url']=url
        cat[job_id]['kml_size']=content_size
        json.dump(cat, open(cat_path,'w'), indent=4, separators=(',', ': '))
    except:
        logging.warning('make_kmz: accessing the file over the web failed') 
Exemplo n.º 5
0
    cb_name = 'colorbar-' + base_name + '.png'
    with open(cb_name, 'w') as f:
        f.write(cb_png_data)
    doc.addfile(cb_name)

    cbo = doc.newscreenoverlay(name='colorbar')
    cbo.overlayxy = kml.OverlayXY(x=0,
                                  y=1,
                                  xunits=kml.Units.fraction,
                                  yunits=kml.Units.fraction)
    cbo.screenxy = kml.ScreenXY(x=0.02,
                                y=0.95,
                                xunits=kml.Units.fraction,
                                yunits=kml.Units.fraction)
    cbo.size = kml.Size(x=150,
                        y=300,
                        xunits=kml.Units.pixel,
                        yunits=kml.Units.pixel)
    cbo.color = kml.Color.rgb(255, 255, 255, a=150)
    cbo.visibility = 1
    cbo.icon.href = cb_name

    print(
        '[raster2kml] rendering raster from variable %s (Mercator projection) ...'
        % varname)
    ground = doc.newgroundoverlay(name=varname, color='80ffffff')
    raster_png_data, corner_coords = basemap_raster_mercator(
        lon, lat, fa, fa_min, fa_max, cmap)
    raster_name = 'raster-' + base_name + '.png'
    with open(raster_name, 'w') as f:
        f.write(raster_png_data)
    doc.addfile(raster_name)