Exemple #1
0
def get_response_for_getquantity(get_parameters):
    """ Return json with quantity for all calculation cells. """

    # Determine layer and time
    layer = get_parameters['layers']
    time = int(get_parameters['time'])
    quantity = get_parameters['quantity']
    try:
        decimals = int(get_parameters['decimals'])
    except KeyError:
        decimals = None

    # Load quantity from netcdf
    netcdf_path = utils.get_netcdf_path(layer)
    with Dataset(netcdf_path) as dataset:
        # Explicitly make a masked array. Some quantities (unorm, q) return an
        # ndarray.
        ma = np.ma.masked_array(dataset.variables[quantity][time])
        #ma = dataset.variables[quantity][time]
    nodatavalue = ma.fill_value
    if decimals is None:
        data = dict(enumerate(ma.filled().tolist()))
    else:
        data = dict(enumerate(ma.filled().round(decimals).tolist()))
    content = json.dumps(dict(nodatavalue=nodatavalue, data=data))
    return content, 200, {'content-type': 'application/json',
                          'Access-Control-Allow-Origin': '*',
                          'Access-Control-Allow-Methods': 'GET'}
Exemple #2
0
def get_response_for_getcontours(get_parameters):
    """ Return json with quantity for all calculation cells. """

    # Determine layer and time
    layer = get_parameters['layers']

    # Load contours from netcdf
    netcdf_path = utils.get_netcdf_path(layer)
    with Dataset(netcdf_path) as dataset:
        x = dataset.variables['FlowElemContour_x'][:]
        y = dataset.variables['FlowElemContour_y'][:]
    contours = dict(enumerate(np.dstack([x, y]).tolist()))
    content = json.dumps(dict(contours=contours))
    return content, 200, {'content-type': 'application/json',
                          'Access-Control-Allow-Origin': '*',
                          'Access-Control-Allow-Methods': 'GET'}
Exemple #3
0
def get_response_for_getinfo(get_parameters):
    """ Return json with bounds and timesteps. """
    # Read netcdf
    path = utils.get_netcdf_path(layer=get_parameters['layers'])
    with Dataset(path) as dataset:
        v = dataset.variables
        fex, fey = v['FlowElemContour_x'][:], v['FlowElemContour_y'][:]
        timesteps = v['s1'].shape[0]
        bathymetry = v['bath'][0, :]

    limits = bathymetry.min(), bathymetry.max()
    netcdf_extent = fex.min(), fey.min(), fex.max(), fey.max()

    # Determine transformed extent
    srs = get_parameters['srs']
    if srs:
        # Read projection from bathymetry file, defaults to RD.
        bathy_path = utils.get_bathymetry_path(layer=get_parameters['layers'])
        # It defaults to Rijksdriehoek RD
        source_projection = utils.get_bathymetry_srs(bathy_path)

        logging.info('Source projection: %r' % source_projection)
        #source_projection = 22234 if 'kaapstad' in path.lower() else rasters.RD
        target_projection = srs
        extent = gislib_utils.get_transformed_extent(
            extent=netcdf_extent,
            source_projection=source_projection,
            target_projection=target_projection,
        )
    else:
        logging.warning('No srs data available.')
        extent = netcdf_extent

    # Prepare response
    content = json.dumps(dict(bounds=extent,
                              limits=limits,
                              timesteps=timesteps))
    return content, 200, {
        'content-type': 'application/json',
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'GET'}
Exemple #4
0
    def __init__(self, layer, time, variable='s1', netcdf_path=None):
        """ Load data from netcdf. """
        #logging.debug('Loading dynamic data layer {}...'.format(layer))
        if netcdf_path is None:
            netcdf_path = utils.get_netcdf_path(layer)
        with Dataset(netcdf_path) as dataset:
            waterlevel_variable = dataset.variables[variable]
            #logging.debug(waterlevel_variable)

            # Initialize empty array with one element more than amount of quads
            self.waterlevel = np.ma.array(
                np.empty(waterlevel_variable.shape[1] + 1),
                mask=True,
            )

            # Fill with waterlevel from netcdf
            if time < waterlevel_variable.shape[0]:
                corrected_time = time
            else:
                corrected_time = waterlevel_variable.shape[0] - 1
            self.waterlevel[0:-1] = waterlevel_variable[corrected_time]
Exemple #5
0
def make_monolith(layer):
    """ Build a monolith from a netcdf. """
    logging.info('Building monolith for {}'.format(layer))
    # Get paths
    monolith_path = utils.get_monolith_path(layer)
    netcdf_path = utils.get_netcdf_path(layer)
    bathy_path = utils.get_bathymetry_path(layer)
    projection = utils.get_bathymetry_srs(bathy_path)
    #if projection is not None: 
    #    projection = int(projection)
    logging.info('Monolith projection is {}'.format(projection))
    # Create monolith
    try:
        monolith = rasters.Monolith(path=monolith_path, compression='DEFLATE')
        if monolith.has_data():
            logging.info('Monolith has data for {}'.format(layer))
            return
        monolith.add(quads.get_dataset(path=netcdf_path, projection=projection))
    except rasters.LockError:
        logging.info('Monolith busy for {}'.format(layer))
        return
    logging.info('Monolith completed for {}'.format(layer))
Exemple #6
0
def get_response_for_gettimeseries(get_parameters):
    """ Return json with timeseries.

    provide layers=<modelname>:<mode>, where mode is one of

    s1 (default), bath, su, vol, dep, ucx, ucy, interception, rain, evap

    options:
    quad=<quadtree index>
    absolute=true (default false): do not subtract height from s1
    timestep=<max timestep you want to see>
    """
    # This request features a point, but an bbox is needed for reprojection.
    point = np.array(map(float,
                         get_parameters['point'].split(','))).reshape(1, 2)
    #bbox = ','.join(map(str, np.array(point + np.array([[-1], [1]])).ravel()))
    # Make a fake bounding box. Beware: units depend on epsg (wgs84)
    bbox = ','.join(map(str, np.array(point + np.array([[-0.0000001], [0.0000001]])).ravel()))
    get_parameters_extra = dict(height='1', width='1', bbox=bbox)
    get_parameters_extra.update(get_parameters)

    timeformat = get_parameters.get('timeformat', 'iso')  # iso or epoch
    # For 1D test
    quad = get_parameters.get('quad', None)
    if quad is not None:
        quad = int(quad)
    absolute = get_parameters.get('absolute', 'false')
    timestep = get_parameters.get('timestep', None)
    if timestep is not None:
        timestep = int(timestep)
        if timestep == 0:
            timestep = 1  # Or it won't work correctly

    # Determine layers
    layer_parameter = get_parameters['layers']
    if ':' in layer_parameter:
        layer, mode = layer_parameter.split(':')
        get_parameters['layers'] = layer
    else:
        layer, mode = layer_parameter, 's1'

    # Get height and quad
    static_data = StaticData.get(layer=layer)
    quads, ms = get_data(container=static_data.monolith,
                         ma=True, **get_parameters_extra)
    if quad is None:
        quad = int(quads[0, 0])
        logging.debug('Got quads in {} ms.'.format(ms))
    logging.debug('Quad = %r' % quad)

    bathymetry, ms = get_data(container=static_data.pyramid,
                              ma=True, **get_parameters_extra)
    height = bathymetry[0, 0]
    if not height:
        logging.debug('Got not height.')
        height = 0
    logging.debug('Got height {}.'.format(height))
    logging.debug('Got bathymetry in {} ms.'.format(ms))

    # Read data from netcdf
    path = utils.get_netcdf_path(layer=get_parameters['layers'])
    with Dataset(path) as dataset:
        v = dataset.variables
        units = v['time'].getncattr('units')
        time = v['time'][:]
        # Depth values can be negative or non existent.
        # Note: all variables can be looked up here, so 'depth' is misleading.
        if mode == 's1':
            if absolute == 'false':
                depth = np.ma.maximum(v[mode][:, quad] - height, 0).filled(0)
            else:
                if timestep:
                    depth = v[mode][:timestep, quad]
                else:
                    depth = v[mode][:, quad]
        else:
            #depth = np.ma.maximum(v[mode][:, quad], 0).filled(0)
            if absolute == 'true':
                # For unorm, q
                depth = np.ma.abs(v[mode][:, quad])
            else:
                depth = v[mode][:, quad]
        var_units = v[mode].getncattr('units')

    compressed_time = time
    compressed_depth = depth

    if compressed_time.size:
        if timeformat == 'iso':
            time_list = map(lambda t: t.isoformat(),
                            num2date(compressed_time, units=units))
        else:
            # Time in milliseconds from epoch.
            time_list = map(lambda t: 1000*float(t.strftime('%s')),
                            num2date(compressed_time, units=units))
    else:
        time_list = []
    depth_list = compressed_depth.round(3).tolist()

    content_dict = dict(
        timeseries=zip(time_list, depth_list),
        height=float(height),
        units=var_units)
    content = json.dumps(content_dict)
    return content, 200, {
        'content-type': 'application/json',
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'GET'}