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'}
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'}
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'}
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]
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))
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'}