Source code for shakemap.coremods.raster

# stdlib imports
import os.path
import zipfile

# third party imports
from impactutils.io.smcontainers import ShakeMapOutputContainer
from mapio.gdal import GDALGrid
from mapio.geodict import GeoDict
from mapio.grid2d import Grid2D

# local imports
from .base import CoreModule, Contents
from shakemap.utils.config import get_config_paths
from shakelib.utils.imt_string import oq_to_file

FORMATS = {"shapefile": ("ESRI Shapefile", "shp"), "geojson": ("GeoJSON", "json")}

DEFAULT_FILTER_SIZE = 10


[docs]class RasterModule(CoreModule): """ raster -- Generate GIS raster files of all IMT values from shake_result.hdf. """ command_name = "raster" targets = [r"products/raster\.zip"] dependencies = [("products/shake_result.hdf", True)] def __init__(self, eventid): super(RasterModule, self).__init__(eventid) self.contents = Contents(None, None, eventid)
[docs] def execute(self): """ Write raster.zip file containing ESRI Raster files of all the IMTs in shake_result.hdf. Raises: NotADirectoryError: When the event data directory does not exist. FileNotFoundError: When the the shake_result HDF file does not exist. """ install_path, data_path = get_config_paths() datadir = os.path.join(data_path, self._eventid, "current", "products") if not os.path.isdir(datadir): raise NotADirectoryError(f"{datadir} is not a valid directory.") datafile = os.path.join(datadir, "shake_result.hdf") if not os.path.isfile(datafile): raise FileNotFoundError(f"{datafile} does not exist.") # Open the ShakeMapOutputContainer and extract the data container = ShakeMapOutputContainer.load(datafile) if container.getDataType() != "grid": raise NotImplementedError( "raster module can only operate on " "gridded data, not sets of points" ) # create GIS-readable .flt files of imt and uncertainty self.logger.debug("Creating GIS grids...") layers = container.getIMTs() # Package up all of these files into one zip file. zfilename = os.path.join(datadir, "raster.zip") zfile = zipfile.ZipFile(zfilename, mode="w", compression=zipfile.ZIP_DEFLATED) files_written = [] for layer in layers: _, layer = layer.split("/") fileimt = oq_to_file(layer) # This is a bit hacky -- we only produce the raster for the # first IMC returned. It should work as long as we only have # one IMC produced per ShakeMap run. imclist = container.getComponents(layer) imtdict = container.getIMTGrids(layer, imclist[0]) mean_grid = Grid2D(imtdict["mean"], GeoDict(imtdict["mean_metadata"])) std_grid = Grid2D(imtdict["std"], GeoDict(imtdict["std_metadata"])) mean_gdal = GDALGrid.copyFromGrid(mean_grid) std_gdal = GDALGrid.copyFromGrid(std_grid) mean_fname = os.path.join(datadir, f"{fileimt}_mean.flt") mean_hdr = os.path.join(datadir, f"{fileimt}_mean.hdr") std_fname = os.path.join(datadir, f"{fileimt}_std.flt") std_hdr = os.path.join(datadir, f"{fileimt}_std.hdr") self.logger.debug(f"Saving {mean_fname}...") mean_gdal.save(mean_fname) files_written.append(mean_fname) files_written.append(mean_hdr) self.logger.debug(f"Saving {std_fname}...") std_gdal.save(std_fname) files_written.append(std_fname) files_written.append(std_hdr) zfile.write(mean_fname, f"{fileimt}_mean.flt") zfile.write(mean_hdr, f"{fileimt}_mean.hdr") zfile.write(std_fname, f"{fileimt}_std.flt") zfile.write(std_hdr, f"{fileimt}_std.hdr") zfile.close() # nuke all of the copies of the files we just put in the zipfile for file_written in files_written: os.remove(file_written) self.contents.addFile( "rasterData", "ESRI Raster Files", "Data and uncertainty grids in ESRI raster " "format", "raster.zip", "application/zip", ) container.close()