Beispiel #1
0
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)
Beispiel #2
0
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)
Beispiel #3
0
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)
Beispiel #4
0
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)
Beispiel #5
0
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)
Beispiel #6
0
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)
Beispiel #7
0
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)