def wms(): """ Return response according to request. """ get_parameters = utils.get_parameters() request = get_parameters['request'].lower() request_handlers = dict( getinfo=responses.get_response_for_getinfo, getmap=responses.get_response_for_getmap, ) return request_handlers[request](get_parameters=get_parameters)
def data(): """ Return data according to request: getprofile, gettimeseries, get """ get_parameters = utils.get_parameters() request = get_parameters['request'].lower() request_handlers = dict( getprofile=responses.get_response_for_getprofile, gettimeseries=responses.get_response_for_gettimeseries, getquantity=responses.get_response_for_getquantity, getcontours=responses.get_response_for_getcontours, ) return request_handlers[request](get_parameters=get_parameters)
def tms(x, y, zoom): # Determe bbox from tile indices and zoomlevel # Could use tms option for leaflet to inverse y-axis! limit = 2 * np.pi * 6378137 step = limit / 2 ** zoom left = step * x - limit / 2 right = step * (x + 1) - limit / 2 bottom = limit - step * (y + 1) - limit / 2 top = limit - step * y - limit / 2 srs = 'EPSG:3857' bbox = ','.join(map(str, [left, bottom, right, top])) width, height = '256', '256' # Standard tile size always? #request = 'GetMap' get_parameters = utils.get_parameters() get_parameters.update(srs=srs, bbox=bbox, width=width, height=height) return responses.get_response_for_getmap(get_parameters=get_parameters)
def stations_normals(): """ Return station normals data in JSON format """ # Get query parameters args = utils.get_parameters(parameters) # Check if required parameters are set if args['station']: try: # Get data if args['start'] and args['end']: # Get number of years between start and end year year_diff = args['end'] - args['start'] # Check date range if year_diff < 0: # Bad request abort(400) data = Normals(args['station'], args['start'], args['end']) else: data = Normals(args['station']) # Check if any data if data.count() > 0: # Normalize data data = data.normalize() # Unit conversion if args['units'] == 'imperial': data = data.convert(units.imperial) elif args['units'] == 'scientific': data = data.convert(units.scientific) # Fetch DataFrame data = data.fetch() # To JSON data = data.reset_index().to_json(orient="records") else: # No data data = '[]' # Inject meta data meta = {} meta['generated'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') # Generate output string output = f'''{{"meta":{json.dumps(meta)},"data":{data}}}''' # Return return utils.send_response(output, cache_time) except BaseException: # Bad request abort(400) else: # Bad request abort(400)
def point_monthly(): """ Return monthly point data in JSON format """ # Get query parameters args = utils.get_parameters(parameters) # Check if required parameters are set if args['lat'] and args['lon'] and len(args['start']) == 10 and len( args['end']) == 10: try: # Convert start & end date strings to datetime start = datetime.strptime(args['start'], '%Y-%m-%d') end = datetime.strptime(f'{args["end"]} 23:59:59', '%Y-%m-%d %H:%M:%S') # Get number of days between start and end date date_diff = (end - start).days # Check date range if date_diff < 0: # Bad request abort(400) # Caching Monthly.max_age = 60 * 60 * 24 * 7 # Create a point location = Point(args['lat'], args['lon'], args['alt']) # Get data data = Monthly(location, start, end, model=args['model']) # Check if any data if data.count() > 0: # Normalize data data = data.normalize() # Aggregate if args['freq']: data = data.aggregate(args['freq']) # Unit conversion if args['units'] == 'imperial': data = data.convert(units.imperial) elif args['units'] == 'scientific': data = data.convert(units.scientific) # Fetch DataFrame data = data.fetch() # Convert to integer data['tsun'] = data['tsun'].astype('Int64') # DateTime Index to String data.index = data.index.strftime('%Y-%m-%d') data.index.rename('date', inplace=True) data = data.reset_index().to_json(orient="records") else: # No data data = '[]' # Inject meta data meta = {} meta['generated'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') meta['stations'] = location.stations.to_list() # Generate output string output = f'''{{"meta":{json.dumps(meta)},"data":{data}}}''' # Return return utils.send_response(output, cache_time) except BaseException: # Bad request abort(400) else: # Bad request abort(400)
def stations_nearby(): """ Return station meta data in JSON format """ # Get query parameters args = utils.get_parameters(parameters) # Check if required parameters are set if args['lat'] and args['lon']: try: # Get data from DB query = utils.db_query( ''' SELECT `stations`.`id` AS `id`, `stations`.`name` AS `name`, `stations`.`name_alt` AS `name_alt`, ROUND( ( 6371000 * acos( cos( radians(:lat) ) * cos( radians( `latitude` ) ) * cos( radians( `longitude` ) - radians(:lon) ) + sin( radians(:lat) ) * sin( radians( `latitude` ) ) ) ) , 1) AS `distance` FROM `stations` LEFT JOIN ( SELECT `station`, `start`, `end` FROM `inventory` WHERE `mode` = 'P' ) AS `inventory_model` ON `stations`.`id` = `inventory_model`.`station` LEFT JOIN ( SELECT `station`, `start`, `end` FROM `inventory` WHERE `mode` = 'H' ) AS `inventory_hourly` ON `stations`.`id` = `inventory_hourly`.`station` LEFT JOIN ( SELECT `station`, `start`, `end` FROM `inventory` WHERE `mode` = 'D' ) AS `inventory_daily` ON `stations`.`id` = `inventory_daily`.`station` LEFT JOIN ( SELECT `station`, `start`, `end` FROM `inventory` WHERE `mode` = 'M' ) AS `inventory_monthly` ON `stations`.`id` = `inventory_monthly`.`station` WHERE `stations`.`latitude` IS NOT NULL AND ABS(`stations`.`latitude`) <= 90 AND `stations`.`longitude` IS NOT NULL AND ABS(`stations`.`longitude`) <= 180 AND ( `inventory_hourly`.`start` IS NOT NULL OR `inventory_daily`.`start` IS NOT NULL OR `inventory_monthly`.`start` IS NOT NULL ) GROUP BY `stations`.`id` HAVING `distance` <= :radius ORDER BY `distance` LIMIT :limit ''', { 'lat': args['lat'], 'lon': args['lon'], 'radius': args['radius'], 'limit': args['limit'] }) if query.rowcount > 0: # Fetch results results = query.fetchall() # Output list output = [] # Go through stations for data in results: # Create dict of names try: names = json.loads(data['name_alt']) except BaseException: names = {} names['en'] = data['name'] # Create JSON output output.append({ 'id': data['id'], 'name': names, 'distance': data['distance'] }) # Stringify output output = json.dumps(output) else: output = '[]' # Inject meta data meta = {} meta['generated'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') # Generate output string output = f'''{{"meta":{json.dumps(meta)},"data":{output}}}''' # Return return utils.send_response(output, cache_time) except BaseException: # Bad request abort(400) else: # Bad request abort(400)
def stations_meta(): """ Return station meta data in JSON format """ # Get query parameters args = utils.get_parameters(parameters) # Check if required parameters are set if args['id'] or args['wmo'] or args['icao']: try: # Get data from DB query = utils.db_query( ''' SELECT `stations`.`id` AS `id`, `stations`.`name` AS `name`, `stations`.`name_alt` AS `name_alt`, `stations`.`country` AS `country`, `stations`.`region` AS `region`, `stations`.`national_id` AS `national_id`, CAST(`stations`.`wmo` AS CHAR(5)) AS `wmo`, `stations`.`icao` AS `icao`, `stations`.`latitude` AS `latitude`, `stations`.`longitude` AS `longitude`, `stations`.`altitude` AS `altitude`, `stations`.`tz` as `timezone`, MIN(`inventory_model`.`start`) AS 'model_start', MAX(`inventory_model`.`end`) AS 'model_end', MIN(`inventory_hourly`.`start`) AS 'hourly_start', MAX(`inventory_hourly`.`end`) AS 'hourly_end', MIN(`inventory_daily`.`start`) AS 'daily_start', MAX(`inventory_daily`.`end`) AS 'daily_end', YEAR(MIN(`inventory_monthly`.`start`)) AS 'monthly_start', YEAR(MAX(`inventory_monthly`.`end`)) AS 'monthly_end', YEAR(MIN(`inventory_normals`.`start`)) AS 'normals_start', YEAR(MAX(`inventory_normals`.`end`)) AS 'normals_end' FROM `stations` LEFT JOIN ( SELECT `station`, `start`, `end` FROM `inventory` WHERE `mode` = 'P' ) AS `inventory_model` ON `stations`.`id` = `inventory_model`.`station` LEFT JOIN ( SELECT `station`, `start`, `end` FROM `inventory` WHERE `mode` = 'H' ) AS `inventory_hourly` ON `stations`.`id` = `inventory_hourly`.`station` LEFT JOIN ( SELECT `station`, `start`, `end` FROM `inventory` WHERE `mode` = 'D' ) AS `inventory_daily` ON `stations`.`id` = `inventory_daily`.`station` LEFT JOIN ( SELECT `station`, `start`, `end` FROM `inventory` WHERE `mode` = 'M' ) AS `inventory_monthly` ON `stations`.`id` = `inventory_monthly`.`station` LEFT JOIN ( SELECT `station`, `start`, `end` FROM `inventory` WHERE `mode` = 'N' ) AS `inventory_normals` ON `stations`.`id` = `inventory_normals`.`station` WHERE `stations`.`id` = :id OR `stations`.`wmo` = :wmo OR `stations`.`icao` = :icao GROUP BY `stations`.`id` LIMIT 1 ''', { 'id': args['id'], 'wmo': args['wmo'], 'icao': args['icao'] }) if query.rowcount > 0: # Fetch result data = query.fetchone() # Create dict of names try: names = json.loads(data['name_alt']) except BaseException: names = {} names['en'] = data['name'] # Create JSON output output = json.dumps({ 'id': data['id'], 'name': names, 'country': data['country'], 'region': data['region'], 'identifier': { 'national': data['national_id'], 'wmo': data['wmo'], 'icao': data['icao'] }, 'location': { 'latitude': data['latitude'], 'longitude': data['longitude'], 'elevation': data['altitude'] }, 'timezone': data['timezone'], 'inventory': { 'model': { 'start': data['model_start'].strftime('%Y-%m-%d') if data['model_start'] is not None else None, 'end': data['model_end'].strftime('%Y-%m-%d') if data['model_end'] is not None else None }, 'hourly': { 'start': data['hourly_start'].strftime('%Y-%m-%d') if data['hourly_start'] is not None else None, 'end': data['hourly_end'].strftime('%Y-%m-%d') if data['hourly_end'] is not None else None }, 'daily': { 'start': data['daily_start'].strftime('%Y-%m-%d') if data['daily_start'] is not None else None, 'end': data['daily_end'].strftime('%Y-%m-%d') if data['daily_end'] is not None else None }, 'monthly': { 'start': data['monthly_start'], 'end': data['monthly_end'] }, 'normals': { 'start': data['normals_start'], 'end': data['normals_end'] } } }) else: output = 'null' # Inject meta data meta = {} meta['generated'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') # Generate output string output = f'''{{"meta":{json.dumps(meta)},"data":{output}}}''' # Return return utils.send_response(output, cache_time) except BaseException: # Bad request abort(400) else: # Bad request abort(400)