wcps_rasdaman.py 4.49 KB
Newer Older
1
def wcps_rasdaman(query, ip='saocompute.eurac.edu/sincohmap', file_name=''):
2
3
4
5
6
7
    """
    Sends a WCPS query to a Rasdaman server and wraps the response for further use in Python depending on the 
    the response format chosen in the query.
    
    Args: 
        query (str) -- WCPS query you want to send to the Rasdaman server
8
        ip (str) -- IP of Rasdaman server (default saocompute.eurac.edu)
9
10
11
12
13
14
15
16
17
18
19
20
    
    Returns:
        Either one of the following
        - Numpy array for JSON/CSV formatted response
        - Xarray Dataset for a netCDF formatted response
        - Filepath to a TIFF/JPEG/JP2/PNG file saved to disk, in respect to the response image type
        - The response object, when the response could not be processed
    
    Sources:
        http://xarray.pydata.org/en/stable/io.html#netcdf
        http://xarray.pydata.org/en/stable/data-structures.html
        
21
    Author: Harald Kristen, Alexander Jacob
22
    Date: 2019-05-29
23
24
25
26
27
28
29
30
31
32
33
    """

    import requests
    import json
    import werkzeug
    import numpy as np
    import io
    import xarray as xr
    import uuid
    import os
    import xml.etree.ElementTree as ET
Jacob Alexander's avatar
Jacob Alexander committed
34
    import base64
35
36

    #set the work directory
Jacob Alexander's avatar
Jacob Alexander committed
37
38
39
    work_directory = ''#os.getcwd()
    
    #print('WCPS init')
40
    
41
42
    if ip == 'saocompute.eurac.edu/sincohmap' or ip == 'saocompute.eurac.edu':
        url = 'http://' + ip + '/rasdaman/ows?SERVICE=WCS&VERSION=2.0.1&REQUEST=ProcessCoverages'  
43
44
    else:
        url = 'http://' + ip + ':8080/rasdaman/ows?SERVICE=WCS&VERSION=2.0.1&REQUEST=ProcessCoverages'
Jacob Alexander's avatar
Jacob Alexander committed
45
46
47
48
49
    
    #Fix the special characters used the input query like ' ', $ and so on
    query = werkzeug.url_fix(query)
    print('This is the URL, used for the request:\n' + url + '&query=' + query)
    url = url + '&query=' + query
50

Jacob Alexander's avatar
Jacob Alexander committed
51
52
53
54
55
56
57
    try:
        #Send the request to Rasdaman and save the response in the variable "r"
        r = requests.get(url, stream=True)
    except Exception as ex:
        print(tpye(ex))
        print(ex.args)
        print(ex)
58
59
60
61
62
63
64
65

    #If there is an error, plot the error message that comes from Rasdaman & exit script
    if r.status_code != requests.codes.ok:
        print('HTTP Error ' + str(r.status_code))
        root = ET.fromstring(r.text)
        for element in root.iter():
            if element.tag == '{http://www.opengis.net/ows/2.0}ExceptionText':
                print(element.text)
Jacob Alexander's avatar
Jacob Alexander committed
66
67

    print('currently receiving content of type: ' + r.headers['Content-Type'])
68

Jacob Alexander's avatar
Jacob Alexander committed
69
    #print('This is the URL, used for the request \n' + r.url)
70
71
72
73

    if r.headers['Content-Type'] == 'text/plain':
        #print('return type is text')
        # Convert CSV or json to NumpyArray
Jacob Alexander's avatar
Jacob Alexander committed
74
75
        response_text = r.text()
        output = response_text
76
        # The JSON version also works for 2D arrays.
Jacob Alexander's avatar
Jacob Alexander committed
77
78
79
80
        if response_text.startswith("{"):
            loaded = r.json()
            output = np.array(loaded)
        else:
81
82
83
84
            output = np.fromstring(response_text[1:-1], dtype = float, sep = ',')

    elif r.headers['Content-Type'] == 'application/json':
        # Convert JSON to NumpyArray
Jacob Alexander's avatar
Jacob Alexander committed
85
86
        loaded = r.json()
        output = np.array(loaded)
87
88

    elif r.headers['Content-Type'] == 'application/netcdf':
89
        print(r.headers)
90
        # create x array dataset from input stream
91
92
93
94
95
96
        if file_name == '':
            file_name = 'wcps_' + str(uuid.uuid4()) + '.nc'
        print('the following file has been saved locally: ' + file_name)
        with io.open(file_name, 'wb') as outfile:
            outfile.write(r.content)        
        output_open = xr.open_dataset(file_name)
97
98
99
100
        # Xarray is normally lazy loading netCDF files
        # As we want to perform intense computation, we load the file directly in the main memory with Dataset.load()
        output = xr.Dataset.load(output_open)

Jacob Alexander's avatar
Jacob Alexander committed
101
    elif r.headers['Content-Type'] in ['image/tiff', 'image/png', 'image/jp2', 'image/jpeg']:
102
103
        # Write response in choosen image format to disk and print filepath
        image_type = r.headers['Content-Type']
104
105
106
107
108
109
        if file_name == '':
            file_ending = image_type[6:]
            # write TIFF to disk and print filepath
            tf = 'wcps_' + str(uuid.uuid4())
            file_name = tf + '.' + file_ending
        with io.open(file_name, 'wb') as outfile:
110
            outfile.write(r.content)
111
112
        print('the following file has been saved locally: ' + file_name)
        output = file_name
113
114
115
116
117
118
119

    else:
        output = r
        output_type = r.headers['Content-Type']
        print('The response could not be processed, as it is a ' + output_type)

    return output