Skip to content
Snippets Groups Projects
FACT_elevation.jl 5.99 KiB
"""
    elevation_data_full(ws_host_port::String, selection::Dict) -> DataFrame

Retrieve comprehensive elevation data for specified geographic regions from a web service.

This function sends POST requests to a web service to obtain various elevation statistics (minimum, maximum, mean, standard deviation, median, and entropy) for specified geographic regions. The regions are defined by their shapes and IDs provided in the `selection` dictionary.

# Arguments
- `ws_host_port::String`: The host and port of the web service providing the elevation data.
- `selection::Dict`: A dictionary containing `geo_id` and `shape_obj`, representing geographic identifiers and their corresponding shapes.

# Returns
- `DataFrame`: A DataFrame with columns for geographic ID, minimum elevation, maximum elevation, mean elevation, standard deviation of elevation, median elevation, and entropy of elevation data.

# Example
> ws_host_port = "http://example.com:5003"
> selection = Dict("geo_id" => ["ID1", "ID2"], "shape_obj" => ["SHAPE1", "SHAPE2"])
> df = elevation_data_full(ws_host_port, selection)

In this example, the function queries a web service for elevation data for specified regions and returns the results in a DataFrame.
"""
function elevation_data_full(ws_host_port::String, selection::Dict)
    # getting valuable info from dictionary
    geo_id = selection["geo_id"]
    shape_obj = selection["shape_obj"]
    # Arrays to store column data
    geo_ids = String[]
    min_elevations = Float64[]
    max_elevations = Float64[]
    mean_elevations = Float64[]
    std_elevations = Float64[]
    median_elevations = Float64[]
    entropy_elevations = Float64[]
    
    for (id, shape) in zip(geo_id, shape_obj)
        # setting starting values to missing
        min_elevation = missing
        max_elevation = missing
        mean_elevation = missing
        std_elevation = missing
        median_elevation = missing
        entropy_elevation = missing


        # Construct the JSON payload
        json_payload = JSON.json(Dict("polygon_wkt" => shape))
        # Construct the URL
        url = "$ws_host_port/band_statistics"
        # Set headers for JSON content type
        headers = Dict("Content-Type" => "application/json")

        try
            # Make the POST request
            response = HTTP.post(url, headers, json_payload)
            # Ensure the response status code is 200 (OK)
            if response.status != 200
                throw(Exception("Request failed with status code $(response.status)"))
            end
            # Parse the response
            data = JSON.parse(String(response.body))
            # Access the nested dictionary for band_0
            band_data = data["band_0"]
            # extract relevant info
            min_elevation = band_data["min"][1]
            max_elevation = band_data["max"][1]
            mean_elevation = band_data["mean"][1]
            std_elevation = band_data["std"][1]
            median_elevation = band_data["median"][1]
            entropy_elevation = band_data["entropy"][1]
        catch e
            println("Error during HTTP request or response parsing: ", e)
        end

        # update info
        push!(geo_ids, id)
        push!(min_elevations, min_elevation)
        push!(max_elevations, max_elevation)
        push!(mean_elevations, mean_elevation)
        push!(std_elevations, std_elevation)
        push!(median_elevations, median_elevation)
        push!(entropy_elevations, entropy_elevation)
    end
    # object to be returned
    dftemp = DataFrame(
        geo_id = geo_ids,
        min_elevation = min_elevations,
        max_elevation = max_elevations,
        mean_elevation = mean_elevations,
        std_elevation = std_elevations,
        median_elevation = median_elevations,
        entropy_elevation = entropy_elevations
    )
    return dftemp
end

"""
    get_elevation_data(service_query::String, selection::Dict; host::String="127.0.0.1") -> DataFrame

Retrieve elevation data based on the specified service query and selection criteria.

This function determines the appropriate function to fetch elevation data based on the provided `service_query` argument. It then retrieves the relevant data using the `elevation_data_full` function and the given `selection` dictionary.

# Arguments
- `service_query::String`: Specifies the service query type (e.g., 'elevation_data_full').
- `selection::Dict`: A dictionary containing selection criteria.
- `host::String` (optional): The hostname for the web service, defaulting to '127.0.0.1'.

# Returns
- `DataFrame`: A DataFrame containing elevation data, with columns for geographic ID, minimum elevation, maximum elevation, mean elevation, standard deviation of elevation, median elevation, and entropy of elevation.

# Example
> service_query = "elevation_data_full"
> selection = Dict("geo_id" => ["ID1"], "shape_obj" => ["SHAPE1"])
> df = get_elevation_data(service_query, selection)

In this example, elevation data for the specified region is retrieved using a specified service query and returned in a DataFrame.
"""
function get_elevation_data(service_query::String, selection::Dict; host::String="127.0.0.1")
    service_dict = Dict(
        "elevation_data_full" => elevation_data_full
    )
    df_template = DataFrame(
        geo_id = String[],  # Column for Origin Geo IDs
        min_elevation = Float64[], # 'min' elevation,
        max_elevation = Float64[], # 'max' elevation,
        mean_elevation = Float64[], # 'mean' elevation,
        std_elevation = Float64[], # 'std' standard deviation of elevation,
        median_elevation = Float64[], # 'median' elevation,
        entropy_elevation = Float64[] # 'entropy', which is the Shannon entropy measure of elevation data.
    )

    # Check if the service is supported
    if !haskey(service_dict, service_query)
        error("Unsupported service: $service_query. Please check the available services: $(keys(service_dict)).")
    end
    
    # data retrieval
    df = get_results_from_service(service_query, df_template, service_dict, selection; host=host, port=5003)
    return df
end