jblindsay / whitebox-tools

An advanced geospatial data analysis platform
https://www.whiteboxgeo.com/
MIT License
967 stars 161 forks source link

Missing functions in python API? #133

Closed NO645 closed 3 years ago

NO645 commented 3 years ago

User manual contains python API examples of functions such as wbt.extract_raster_values_at_points() but these tools do not appear to actually be in the python API. Calling the function fails, and it does not show up in wbt.list_tools().

It looks like there are other missing functions as well, filter_raster_features_by_area, find_lowest_or_highest_points, etc.

jblindsay commented 3 years ago

I'm not sure why you say these tools are missing because as far as I know, they are not. For example,

filter_raster_features_by_area:

And the list_tools() function must locate them, otherwise they wouldn't show up in the WhiteboxTools Runner, which they do:

Screen Shot 2021-01-14 at 2 15 20 PM
NO645 commented 3 years ago

This is the message I get back from a help call to the function:

help(wbt.extract_raster_values_at_points)
Traceback (most recent call last):

  File "<ipython-input-80-2a9eb75925ef>", line 1, in <module>
    help(wbt.extract_raster_values_at_points)

AttributeError: 'WhiteboxTools' object has no attribute 'extract_raster_values_at_points'

A list of the raster tools also has no indication of the extract_raster_values_at_points function:

print(wbt.list_tools(['raster']))
{'absolute_value': 'Calculates the absolute value of every cell in a raster.', 'add': 'Performs an addition operation on two rasters or a raster and a constant value.', 'aggregate_raster': 'Aggregates a raster to a lower resolution.', 'and': 'Performs a logical AND operator on two Boolean raster images.', 'anova': 'Performs an analysis of variance (ANOVA) test on a raster dataset.', 'arc_cos': 'Returns the inverse cosine (arccos) of each values in a raster.', 'arc_sin': 'Returns the inverse sine (arcsin) of each values in a raster.', 'arc_tan': 'Returns the inverse tangent (arctan) of each values in a raster.', 'aspect': 'Calculates an aspect raster from an input DEM.', 'average_overlay': 'Calculates the average for each grid cell from a group of raster images.', 'block_maximum': 'Creates a block-maximum raster from an input LAS file. When the input/output parameters are not specified, the tool grids all LAS files contained within the working directory.', 'block_minimum': 'Creates a block-minimum raster from an input LAS file. When the input/output parameters are not specified, the tool grids all LAS files contained within the working directory.', 'buffer_raster': 'Maps a distance-based buffer around each non-background (non-zero/non-nodata) grid cell in an input image.', 'ceil': 'Returns the smallest (closest to negative infinity) value that is greater than or equal to the values in a raster.', 'centroid': 'Calculates the centroid, or average location, of raster polygon objects.', 'clip_raster_to_polygon': 'Clips a raster to a vector polygon.', 'convert_nodata_to_zero': 'Converts nodata values in a raster to zero.', 'convert_raster_format': 'Converts raster data from one format to another.', 'cos': 'Returns the cosine (cos) of each values in a raster.', 'cosh': 'Returns the hyperbolic cosine (cosh) of each values in a raster.', 'count_if': 'Counts the number of occurrences of a specified value in a cell-stack of rasters.', 'create_plane': 'Creates a raster image based on the equation for a simple plane.', 'cumulative_distribution': 'Converts a raster image to its cumulative distribution function.', 'd8_flow_accumulation': 'Calculates a D8 flow accumulation raster from an input DEM.', 'd8_pointer': 'Calculates a D8 flow pointer raster from an input DEM.', 'd_inf_flow_accumulation': 'Calculates a D-infinity flow accumulation raster from an input DEM.', 'd_inf_pointer': 'Calculates a D-infinity flow pointer (flow direction) raster from an input DEM.', 'decrement': 'Decreases the values of each grid cell in an input raster by 1.0 (see also InPlaceSubtract).', 'diversity_filter': 'Assigns each cell in the output grid the number of different values in a moving window centred on each grid cell in the input raster.', 'divide': 'Performs a division operation on two rasters or a raster and a constant value.', 'edge_proportion': 'Calculate the proportion of cells in a raster polygon that are edge cells.', 'elev_percentile': 'Calculates the elevation percentile raster from a DEM.', 'equal_to': 'Performs a equal-to comparison operation on two rasters or a raster and a constant value.', 'erase_polygon_from_raster': 'Erases (cuts out) a vector polygon from a raster.', 'euclidean_allocation': 'Assigns grid cells in the output raster the value of the nearest target cell in the input image, measured by the Shih and Wu (2004) Euclidean distance transform.', 'exp': 'Returns the exponential (base e) of values in a raster.', 'exp2': 'Returns the exponential (base 2) of values in a raster.', 'extract_raster_statistics': 'Extracts descriptive statistics for a group of patches in a raster.', 'extract_streams': 'Extracts stream grid cells from a flow accumulation raster.', 'fd8_flow_accumulation': 'Calculates an FD8 flow accumulation raster from an input DEM.', 'fd8_pointer': 'Calculates an FD8 flow pointer raster from an input DEM.', 'find_parallel_flow': 'Finds areas of parallel flow in D8 flow direction rasters.', 'flatten_lakes': 'Flattens lake polygons in a raster DEM.', 'flightline_overlap': 'Reads a LiDAR (LAS) point file and outputs a raster containing the number of overlapping flight lines in each grid cell.', 'floor': 'Returns the largest (closest to positive infinity) value that is less than or equal to the values in a raster.', 'flow_accumulation_full_workflow': 'Resolves all of the depressions in a DEM, outputting a breached DEM, an aspect-aligned non-divergent flow pointer, a flow accumulation raster.', 'greater_than': 'Performs a greater-than comparison operation on two rasters or a raster and a constant value.', 'highest_position': 'Identifies the stack position of the maximum value within a raster stack on a cell-by-cell basis.', 'hillshade': 'Calculates a hillshade raster from an input DEM.', 'histogram_matching': 'Alters the statistical distribution of a raster image matching it to a specified PDF.', 'histogram_matching_two_images': 'This tool alters the cumulative distribution function of a raster image to that of another image.', 'increment': 'Increases the values of each grid cell in an input raster by 1.0. (see also InPlaceAdd)', 'integer_division': 'Performs an integer division operation on two rasters or a raster and a constant value.', 'ks_test_for_normality': 'Evaluates whether the values in a raster are normally distributed.', 'kappa_index': 'Performs a kappa index of agreement (KIA) analysis on two categorical raster files.', 'less_than': 'Performs a less-than comparison operation on two rasters or a raster and a constant value.', 'lidar_point_stats': 'Creates several rasters summarizing the distribution of LAS point data. When the input/output parameters are not specified, the tool works on all LAS files contained within the working directory.', 'line_thinning': 'Performs line thinning a on Boolean raster image; intended to be used with the RemoveSpurs tool.', 'ln': 'Returns the natural logarithm of values in a raster.', 'log10': 'Returns the base-10 logarithm of values in a raster.', 'log2': 'Returns the base-2 logarithm of values in a raster.', 'lowest_position': 'Identifies the stack position of the minimum value within a raster stack on a cell-by-cell basis.', 'majority_filter': 'Assigns each cell in the output grid the most frequently occurring value (mode) in a moving window centred on each grid cell in the input raster.', 'max': 'Performs a MAX operation on two rasters or a raster and a constant value.', 'max_absolute_overlay': 'Evaluates the maximum absolute value for each grid cell from a stack of input rasters.', 'max_overlay': 'Evaluates the maximum value for each grid cell from a stack of input rasters.', 'maximum_filter': 'Assigns each cell in the output grid the maximum value in a moving window centred on each grid cell in the input raster.', 'min': 'Performs a MIN operation on two rasters or a raster and a constant value.', 'min_absolute_overlay': 'Evaluates the minimum absolute value for each grid cell from a stack of input rasters.', 'min_overlay': 'Evaluates the minimum value for each grid cell from a stack of input rasters.', 'minimum_filter': 'Assigns each cell in the output grid the minimum value in a moving window centred on each grid cell in the input raster.', 'modulo': 'Performs a modulo operation on two rasters or a raster and a constant value.', 'multiply': 'Performs a multiplication operation on two rasters or a raster and a constant value.', 'multiscale_topographic_position_image': 'Creates a multiscale topographic position image from three DEVmax rasters of differing spatial scale ranges.', 'negate': 'Changes the sign of values in a raster or the 0-1 values of a Boolean raster.', 'new_raster_from_base': 'Creates a new raster using a base image.', 'not': 'Performs a logical NOT operator on two Boolean raster images.', 'not_equal_to': 'Performs a not-equal-to comparison operation on two rasters or a raster and a constant value.', 'or': 'Performs a logical OR operator on two Boolean raster images.', 'percent_equal_to': 'Calculates the percentage of a raster stack that have cell values equal to an input on a cell-by-cell basis.', 'percent_greater_than': 'Calculates the percentage of a raster stack that have cell values greather than an input on a cell-by-cell basis.', 'percent_less_than': 'Calculates the percentage of a raster stack that have cell values less than an input on a cell-by-cell basis.', 'pick_from_list': 'Outputs the value from a raster stack specified by a position raster.', 'plan_curvature': 'Calculates a plan (contour) curvature raster from an input DEM.', 'power': 'Raises the values in grid cells of one rasters, or a constant value, by values in another raster or constant value.', 'profile_curvature': 'Calculates a profile curvature raster from an input DEM.', 'quantiles': 'Transforms raster values into quantiles.', 'range_filter': 'Assigns each cell in the output grid the range of values in a moving window centred on each grid cell in the input raster.', 'raster_cell_assignment': 'Assign row or column number to cells.', 'raster_histogram': 'Creates a histogram from raster values.', 'raster_summary_stats': 'Measures a rasters average, standard deviation, num. non-nodata cells, and total.', 'rasterize_streams': 'Rasterizes vector streams based on Lindsay (2016) method.', 'reciprocal': 'Returns the reciprocal (i.e. 1 / z) of values in a raster.', 'reclass': 'Reclassifies the values in a raster image.', 'reclass_equal_interval': 'Reclassifies the values in a raster image based on equal-ranges.', 'reclass_from_file': 'Reclassifies the values in a raster image using reclass ranges in a text file.', 'remove_off_terrain_objects': 'Removes off-terrain objects from a raster digital elevation model (DEM).', 'rho8_pointer': 'Calculates a stochastic Rho8 flow pointer raster from an input DEM.', 'round': 'Rounds the values in an input raster to the nearest integer value.', 'sin': 'Returns the sine (sin) of each values in a raster.', 'sinh': 'Returns the hyperbolic sine (sinh) of each values in a raster.', 'slope': 'Calculates a slope raster from an input DEM.', 'square': 'Squares the values in a raster.', 'square_root': 'Returns the square root of the values in a raster.', 'standard_deviation_filter': 'Assigns each cell in the output grid the standard deviation of values in a moving window centred on each grid cell in the input raster.', 'subtract': 'Performs a differencing operation on two rasters or a raster and a constant value.', 'tan': 'Returns the tangent (tan) of each values in a raster.', 'tangential_curvature': 'Calculates a tangential curvature raster from an input DEM.', 'tanh': 'Returns the hyperbolic tangent (tanh) of each values in a raster.', 'thicken_raster_line': 'Thickens single-cell wide lines within a raster image.', 'to_degrees': 'Converts a raster from radians to degrees.', 'to_radians': 'Converts a raster from degrees to radians.', 'total_curvature': 'Calculates a total curvature raster from an input DEM.', 'trend_surface': 'Estimates the trend surface of an input raster file.', 'truncate': 'Truncates the values in a raster to the desired number of decimal places.', 'vector_lines_to_raster': 'Converts a vector containing polylines into a raster.', 'vector_points_to_raster': 'Converts a vector containing points into a raster.', 'vector_polygons_to_raster': 'Converts a vector containing polygons into a raster.', 'weighted_overlay': 'Performs a weighted sum on multiple input rasters after converting each image to a common scale. The tool performs a multi-criteria evaluation (MCE).', 'weighted_sum': 'Performs a weighted-sum overlay on multiple input raster images.', 'xor': 'Performs a logical XOR operator on two Boolean raster images.', 'z_scores': 'Standardizes the values in an input raster by converting to z-scores.'}

I'm not sure what I'm missing. Below is the conda version readout if that helps. whitebox_tools 0.8.0dev py36_0 conda-forge

jblindsay commented 3 years ago

I believe the format of the function you are trying to call is:

wbt.tool_help("extract_raster_values_at_points")

At least, that is the signature for retrieving help for a tool from the whitebox_tools.py Python API that is distributed with the WhiteboxTools. There is an alternative Python front-end. I'm not sure if Qiusheng perhaps modified these original functions from my formulation. If this is the case, then you should close this issue on the WhiteboxTools backend (this repository) and open the issue on the Python package front-end for WhiteboxTools, for which I am not the maintainer.

NO645 commented 3 years ago

This is the result of that input:

wbt.tool_help("extract_raster_values_at_points")
Out[82]: "thread 'main' panicked at 'Unrecognized tool name ExtractRasterValuesAtPoints.', src\\main.rs:49:21\nnote: Run with `RUST_BACKTRACE=1` for a backtrace.\n"

The typical help() call works great on other wbt functions so I expected it to work universally:

help(wbt.aggregate_raster)
Help on method aggregate_raster in module whitebox_tools:

aggregate_raster(i, output, agg_factor=2, type='mean', callback=<function default_callback at 0x000001E687ACAF28>) method of whitebox_tools.WhiteboxTools instance
    Aggregates a raster to a lower resolution.

    Keyword arguments:

    i -- Input raster file. 
    output -- Output raster file. 
    agg_factor -- Aggregation factor, in pixels. 
    type -- Statistic used to fill output pixels. 
    callback -- Custom functon for handling tool text outputs.

Help calls notwithstanding this is the output of an actual function call with data:


  File "<ipython-input-61-b9bccf65a85a>", line 2, in ExtractFromRaster
    results = wbt.extract_raster_values_at_points(raster, points, out_text=True)

AttributeError: 'WhiteboxTools' object has no attribute 'extract_raster_values_at_points'
NO645 commented 3 years ago

The "Home" entry in conda-forge seems to suggest it's coming from this repository. https://anaconda.org/conda-forge/whitebox_tools

jblindsay commented 3 years ago

It looks to me that the conda repo, which again is not something that I created or maintain, has not been updated for over 2 years. This repository is for the back-end only. The back-end does come with a simply Python API, in the whitebox_tools.py script, and I do support that. However, I cannot provide support for the various front-ends to WhiteboxTools that various users in the community have created.

I would suggest that the solution to your problem is to use the Python interface provided by the main WhiteboxTools back-end in this repository and outlined in the WhiteboxTools user manual.

giswqs commented 3 years ago

@NO645 You can try the Python frontend https://github.com/giswqs/whitebox-python.

I just tested it and it worked fine.

NO645 commented 3 years ago

Python frontend from giswqs recognizes the functions in question. Thank you!