From 82603399ebb35f871a61c6f04dd7d03d9c67a723 Mon Sep 17 00:00:00 2001 From: Leah Wasser Date: Wed, 25 Mar 2020 20:24:53 -0600 Subject: [PATCH] Deprecate Clip: remove rtree which is causing pip install issues (#509) * rtree is causing pip install issues i'm not sure we are even still using it so i'm going to test a local remove to see what happens. * Remove clip (#515) * Update codecov from 2.0.15 to 2.0.22 (#506) * Update tox from 3.14.2 to 3.14.6 (#511) * Update pytest from 5.3.5 to 5.4.1 (#503) * Deprecated clip! (I think) * changelog * Update CHANGELOG.md * remote rtree language in readme Co-authored-by: pyup.io bot Co-authored-by: Leah Wasser * small syntax updates * rtd envt slim down * test for rtd resources * cleanup docs envt Co-authored-by: Nathan Korinek Co-authored-by: pyup.io bot --- CHANGELOG.md | 1 + CONTRIBUTING.rst | 2 +- README.md | 5 +- docs/earthpy-data-subsets.rst | 1 - docs/environment.yml | 1 - docs/get-started.rst | 4 +- earthpy/clip.py | 234 ++++++---------------------------- earthpy/tests/test_clip.py | 161 +++++------------------ examples/plot_clip.py | 128 ------------------- paper.md | 3 +- setup.py | 1 - 11 files changed, 75 insertions(+), 466 deletions(-) delete mode 100644 examples/plot_clip.py diff --git a/CHANGELOG.md b/CHANGELOG.md index c6d40a01..1e54744a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +* Deprecate clip function from earthpy given it's moved to geopandas now (@nkorinek, #510) * Fix twitter flood data key in get_data (@lwasser, #512) * Added new landsat data as a download option to get_data (@nkorinek) * Fix clip vignette. Cant plot w empty geoms (@lwasser, #475) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 41ecfc41..ceadbcd8 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -290,5 +290,5 @@ copies of that data object are required by multiple tests, we can use create and tear down those objects independently for each test. See `earthpy/tests/conftest.py `_ for fixture definitions, and -`earthpy/tests/test_clip.py `_ +`earthpy/tests/test_crop_image.py `_ for example usage of fixtures in tests. diff --git a/README.md b/README.md index 7b950717..56c99b03 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,6 @@ code needed to: * [Create discrete (categorical) legends](https://earthpy.readthedocs.io/en/latest/gallery_vignettes/plot_draw_legend_docs.html) * [Calculate vegetation indices such as Normalized Difference Vegetation Index (`normalized_diff()`)](https://earthpy.readthedocs.io/en/latest/gallery_vignettes/plot_calculate_classify_ndvi.html) * [Create hillshade from a DEM](https://earthpy.readthedocs.io/en/latest/gallery_vignettes/plot_dem_hillshade.html) -* [Clip point, line, and polygon geometries](https://earthpy.readthedocs.io/en/latest/gallery_vignettes/plot_clip.html) EarthPy also has an `io` module that allows users to @@ -69,8 +68,8 @@ $ conda install earthpy ### Install via Pip -EarthPy uses the rtree package for some of its operations which depends upon `libspatialindex`. This package can be -challenging to install using pip whereas it will automagically be installed if you use conda. +We strongly suggest that you install EarthPy using conda-forge given pip can be more prone to +spatial library dependency conflicts. However, you can install earthpy using pip. To install EarthPy via `pip` use: diff --git a/docs/earthpy-data-subsets.rst b/docs/earthpy-data-subsets.rst index 51c29515..faaaf046 100644 --- a/docs/earthpy-data-subsets.rst +++ b/docs/earthpy-data-subsets.rst @@ -69,7 +69,6 @@ Land-Use Satellite `(Landsat) >> import earthpy.spatial as es >>> import earthpy.plot as ep - >>> import earthpy.clip as ec >>> import earthpy.mask as em Data diff --git a/earthpy/clip.py b/earthpy/clip.py index 895486bb..82f1db12 100644 --- a/earthpy/clip.py +++ b/earthpy/clip.py @@ -10,220 +10,66 @@ import geopandas as gpd +# @deprecate def _clip_points(shp, clip_obj): - """Clip point geometry to the clip_obj GeoDataFrame extent. + """This function has been deprecated from earthpy. - Clip an input point GeoDataFrame to the polygon extent of the clip_obj - parameter. Points that intersect the clip_obj geometry are extracted with - associated attributes and returned. - - Parameters - ---------- - shp : GeoDataFrame - Composed of point geometry that is clipped to clip_obj. - - clip_obj : GeoDataFrame - Reference polygon for clipping. - - Returns - ------- - GeoDataFrame - The returned GeoDataFrame is a subset of shp that intersects - with clip_obj. + Please use the _clip_points() function in GeoPandas instead. """ - poly = clip_obj.geometry.unary_union - return shp[shp.geometry.intersects(poly)] + raise Warning( + "_clip_points is deprecated. Use the _clip_points() function in " + "GeoPandas. Exiting..." + ) + sys.exit() +# @deprecate def _clip_multi_point(shp, clip_obj): - """Clip multi point features to the clip_obj GeoDataFrame extent. - - Clip an input multi point to the polygon extent of the clip_obj - parameter. Points that intersect the clip_obj geometry are - extracted with associated attributes returned. - - Parameters - ---------- - shp : GeoDataFrame - multipoint geometry that is clipped to clip_obj. - - clip_obj : GeoDataFrame - Reference polygon for clipping. + """This function has been deprecated from earthpy. - Returns - ------- - GeoDataFrame - The returned GeoDataFrame is a clipped subset of shp - containing multi-point and point features. + Please use the _clip_points() function in GeoPandas instead. """ - - # Explode multi-point features when clipping then recreate geom - clipped = _clip_points(shp.explode().reset_index(level=[1]), clip_obj) - clipped = clipped.dissolve(by=[clipped.index]).drop(columns="level_1")[ - shp.columns.tolist() - ] - - return clipped + raise Warning( + "_clip_multi_point is deprecated. Use the _clip_points() function in " + "GeoPandas. Exiting..." + ) + sys.exit() +# @deprecate def _clip_line_poly(shp, clip_obj): - """Clip line and polygon geometry to the clip_obj GeoDataFrame extent. - - Clip an input line or polygon to the polygon extent of the clip_obj - parameter. Lines or Polygons that intersect the clip_obj geometry are - extracted with associated attributes and returned. - - Parameters - ---------- - shp : GeoDataFrame - Line or polygon geometry that is clipped to clip_obj. - - clip_obj : GeoDataFrame - Reference polygon for clipping. + """This function has been deprecated from earthpy. - Returns - ------- - GeoDataFrame - The returned GeoDataFrame is a clipped subset of shp - that intersects with clip_obj. + Please use the _clip_line_poly() function in GeoPandas instead. """ - # Create a single polygon object for clipping - poly = clip_obj.geometry.unary_union - spatial_index = shp.sindex - - # Create a box for the initial intersection - bbox = poly.bounds - # Get a list of id's for each object that overlaps the bounding box and - # subset the data to just those lines - sidx = list(spatial_index.intersection(bbox)) - shp_sub = shp.iloc[sidx] - - # Clip the data - with these data - clipped = shp_sub.copy() - clipped["geometry"] = shp_sub.intersection(poly) - - # Return the clipped layer with no null geometry values - return clipped[clipped.geometry.notnull()] + raise Warning( + "_clip_line_poly is deprecated. Use the _clip_line_poly() function in " + "GeoPandas. Exiting..." + ) + sys.exit() +# @deprecate def _clip_multi_poly_line(shp, clip_obj): - """Clip multi lines and polygons to the clip_obj GeoDataFrame extent. - - Clip an input multi line or polygon to the polygon extent of the clip_obj - parameter. Lines or Polygons that intersect the clip_obj geometry are - extracted with associated attributes and returned. - - Parameters - ---------- - shp : GeoDataFrame - multiLine or multipolygon geometry that is clipped to clip_obj. - - clip_obj : GeoDataFrame - Reference polygon for clipping. + """This function has been deprecated from earthpy. - Returns - ------- - GeoDataFrame - The returned GeoDataFrame is a clipped subset of shp - that intersects with clip_obj. + Please use the _clip_line_poly() function in GeoPandas instead. """ - - # Clip multi polygons - clipped = _clip_line_poly(shp.explode().reset_index(level=[1]), clip_obj) - - lines = clipped[ - (clipped.geometry.type == "MultiLineString") - | (clipped.geometry.type == "LineString") - ] - line_diss = lines.dissolve(by=[lines.index]).drop(columns="level_1") - - polys = clipped[clipped.geometry.type == "Polygon"] - poly_diss = polys.dissolve(by=[polys.index]).drop(columns="level_1") - - return gpd.GeoDataFrame( - pd.concat([poly_diss, line_diss], ignore_index=True) + raise Warning( + "_clip_multi_poly_line is deprecated. Use the _clip_line_poly() " + "function in GeoPandas. Exiting..." ) + sys.exit() +# @deprecate def clip_shp(shp, clip_obj): - """Clip points, lines, or polygon geometries to the clip_obj extent. - - Both layers must be in the same Coordinate Reference System (CRS) and will - be clipped to the full extent of the clip object. - - If there are multiple polygons in clip_obj, - data from shp will be clipped to the total boundary of - all polygons in clip_obj. - - Parameters - ---------- - shp : GeoDataFrame - Vector layer (point, line, polygon) to be clipped to clip_obj. - clip_obj : GeoDataFrame - Polygon vector layer used to clip shp. - The clip_obj's geometry is dissolved into one geometric feature - and intersected with shp. - - Returns - ------- - GeoDataFrame - Vector data (points, lines, polygons) from shp clipped to - polygon boundary from clip_obj. - - Examples - -------- - Clipping points (glacier locations in the state of Colorado) with - a polygon (the boundary of Rocky Mountain National Park): - - >>> import geopandas as gpd - >>> import earthpy.clip as cl - >>> from earthpy.io import path_to_example - >>> rmnp = gpd.read_file(path_to_example('rmnp.shp')) - >>> glaciers = gpd.read_file(path_to_example('colorado-glaciers.geojson')) - >>> glaciers.shape - (134, 2) - >>> rmnp_glaciers = cl.clip_shp(glaciers, rmnp) - >>> rmnp_glaciers.shape - (36, 2) - - Clipping a line (the Continental Divide Trail) with a - polygon (the boundary of Rocky Mountain National Park): - - >>> cdt = gpd.read_file(path_to_example('continental-div-trail.geojson')) - >>> rmnp_cdt_section = cl.clip_shp(cdt, rmnp) - >>> cdt['geometry'].length > rmnp_cdt_section['geometry'].length - 0 True - dtype: bool - - Clipping a polygon (Colorado counties) with another polygon - (the boundary of Rocky Mountain National Park): - - >>> counties = gpd.read_file(path_to_example('colorado-counties.geojson')) - >>> counties.shape - (64, 13) - >>> rmnp_counties = cl.clip_shp(counties, rmnp) - >>> rmnp_counties.shape - (4, 13) + """This function has been deprecated from earthpy. + + Please use the clip() function in GeoPandas instead. """ - try: - shp.geometry - clip_obj.geometry - except AttributeError: - raise AttributeError( - "Please make sure that your input and clip GeoDataFrames have a" - " valid geometry column" - ) - - if not any(shp.intersects(clip_obj.unary_union)): - raise ValueError("Shape and crop extent do not overlap.") - - if any(shp.geometry.type == "MultiPoint"): - return _clip_multi_point(shp, clip_obj) - elif any(shp.geometry.type == "Point"): - return _clip_points(shp, clip_obj) - elif any(shp.geometry.type == "MultiPolygon") or any( - shp.geometry.type == "MultiLineString" - ): - return _clip_multi_poly_line(shp, clip_obj) - else: - return _clip_line_poly(shp, clip_obj) + raise Warning( + "clip_shp is deprecated. Use the clip() function in " + "GeoPandas. Exiting..." + ) + sys.exit() diff --git a/earthpy/tests/test_clip.py b/earthpy/tests/test_clip.py index fda95e23..dae72062 100644 --- a/earthpy/tests/test_clip.py +++ b/earthpy/tests/test_clip.py @@ -3,7 +3,6 @@ import pytest import numpy as np from shapely.geometry import Polygon, Point, LineString -import shapely import geopandas as gpd import earthpy.clip as cl @@ -27,37 +26,6 @@ def single_rectangle_gdf(): return gdf -@pytest.fixture -def larger_single_rectangle_gdf(): - """Create a slightly larger rectangle for clipping. - - The smaller single rectangle is used to test the edge case where slivers - are returned when you clip polygons. This fixture is larger which - eliminates the slivers in the clip return.""" - poly_inters = Polygon([(-5, -5), (-5, 15), (15, 15), (15, -5), (-5, -5)]) - gdf = gpd.GeoDataFrame([1], geometry=[poly_inters], crs="epsg:4326") - gdf["attr2"] = ["study area"] - return gdf - - -@pytest.fixture -def buffered_locations(point_gdf): - """Buffer points to create a multi-polygon. """ - buffered_locs = point_gdf - buffered_locs["geometry"] = buffered_locs.buffer(4) - buffered_locs["type"] = "plot" - return buffered_locs - - -@pytest.fixture -def donut_geometry(buffered_locations, single_rectangle_gdf): - """ Make a geometry with a hole in the middle (a donut). """ - donut = gpd.overlay( - buffered_locations, single_rectangle_gdf, how="symmetric_difference" - ) - return donut - - @pytest.fixture def two_line_gdf(): """ Create Line Objects For Testing """ @@ -67,18 +35,6 @@ def two_line_gdf(): return gdf -@pytest.fixture -def multi_poly_gdf(donut_geometry): - """ Create a multi-polygon GeoDataFrame. """ - multi_poly = donut_geometry.unary_union - out_df = gpd.GeoDataFrame( - geometry=gpd.GeoSeries(multi_poly), crs="epsg:4326" - ) - out_df = out_df.rename(columns={0: "geometry"}).set_geometry("geometry") - out_df["attr"] = ["pool"] - return out_df - - @pytest.fixture def multi_line(two_line_gdf): """ Create a multi-line GeoDataFrame. @@ -111,99 +67,40 @@ def multi_point(point_gdf): return out_df -def test_not_gdf(single_rectangle_gdf): - """Non-GeoDataFrame inputs raise attribute errors.""" - with pytest.raises(AttributeError): - cl.clip_shp((2, 3), single_rectangle_gdf) - with pytest.raises(AttributeError): - cl.clip_shp(single_rectangle_gdf, (2, 3)) - - -def test_returns_gdf(point_gdf, single_rectangle_gdf): - """Test that function returns a GeoDataFrame (or GDF-like) object.""" - out = cl.clip_shp(point_gdf, single_rectangle_gdf) - assert hasattr(out, "geometry") - - -def test_non_overlapping_geoms(): - """Test that a bounding box returns error if the extents don't overlap""" - unit_box = Polygon([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)]) - unit_gdf = gpd.GeoDataFrame([1], geometry=[unit_box], crs="epsg:4326") - non_overlapping_gdf = unit_gdf.copy() - non_overlapping_gdf = non_overlapping_gdf.geometry.apply( - lambda x: shapely.affinity.translate(x, xoff=20) - ) - with pytest.raises(ValueError): - cl.clip_shp(unit_gdf, non_overlapping_gdf) - - -def test_input_gdfs(single_rectangle_gdf): - """Test that function fails if not provided with 2 GDFs.""" - with pytest.raises(AttributeError): - cl.clip_shp(list(), single_rectangle_gdf) - with pytest.raises(AttributeError): - cl.clip_shp(single_rectangle_gdf, list()) - - -def test_clip_points(point_gdf, single_rectangle_gdf): - """Test clipping a points GDF with a generic polygon geometry.""" - clip_pts = cl.clip_shp(point_gdf, single_rectangle_gdf) - assert len(clip_pts.geometry) == 3 and clip_pts.geom_type[1] == "Point" - - -def test_clip_poly(buffered_locations, single_rectangle_gdf): - """Test clipping a polygon GDF with a generic polygon geometry.""" - clipped_poly = cl.clip_shp(buffered_locations, single_rectangle_gdf) - assert len(clipped_poly.geometry) == 3 - assert all(clipped_poly.geom_type == "Polygon") - - -def test_clip_multipoly(multi_poly_gdf, single_rectangle_gdf): - """Test a multi poly object can be clipped properly. - - Also the bounds of the object should == the bounds of the clip object - if they fully overlap (as they do in these fixtures). """ - clip = cl.clip_shp(multi_poly_gdf, single_rectangle_gdf) - assert hasattr(clip, "geometry") - assert np.array_equal(clip.total_bounds, single_rectangle_gdf.total_bounds) - # 2 features should be returned with an attribute column - assert len(clip.attr) == 2 - - -def test_clip_single_multipolygon( - buffered_locations, larger_single_rectangle_gdf -): - """Test clipping a multi poly with another poly that - - no sliver shapes should be returned in this clip. """ - - multi = buffered_locations.dissolve(by="type").reset_index() - clip = cl.clip_shp(multi, larger_single_rectangle_gdf) - - assert hasattr(clip, "geometry") and clip.geom_type[0] == "Polygon" - - -def test_clip_multiline(multi_line, single_rectangle_gdf): - """Test that clipping a multiline feature with a poly returns expected output.""" +def test_warning_main_clip_function(point_gdf, single_rectangle_gdf): + with pytest.raises( + Warning, match="clip_shp is deprecated. Use the clip()" + ): + cl.clip_shp(point_gdf, single_rectangle_gdf) - clip = cl.clip_shp(multi_line, single_rectangle_gdf) - assert hasattr(clip, "geometry") and clip.geom_type[0] == "MultiLineString" +def test_warning_multi_line_clip_function(multi_line, single_rectangle_gdf): + with pytest.raises( + Warning, + match="_clip_multi_poly_line is deprecated. Use the " + "_clip_line_poly()", + ): + cl._clip_multi_poly_line(multi_line, single_rectangle_gdf) -def test_clip_multipoint(single_rectangle_gdf, multi_point): - """Clipping a multipoint feature with a polygon works as expected. - should return a geodataframe with a single multi point feature""" +def test_warning_line_clip_function(two_line_gdf, single_rectangle_gdf): + with pytest.raises( + Warning, + match="_clip_line_poly is deprecated. Use the _clip_line_poly()", + ): + cl._clip_line_poly(two_line_gdf, single_rectangle_gdf) - clip = cl.clip_shp(multi_point, single_rectangle_gdf) - assert hasattr(clip, "geometry") and clip.geom_type[0] == "MultiPoint" - assert hasattr(clip, "attr") - # All points should intersect the clip geom - assert all(clip.intersects(single_rectangle_gdf.unary_union)) +def test_warning_mutli_point_clip_function(multi_point, single_rectangle_gdf): + with pytest.raises( + Warning, + match="_clip_multi_point is deprecated. Use the _clip_points()", + ): + cl._clip_multi_point(multi_point, single_rectangle_gdf) -def test_clip_lines(two_line_gdf, single_rectangle_gdf): - """Test what happens when you give the clip_extent a line GDF.""" - clip_line = cl.clip_shp(two_line_gdf, single_rectangle_gdf) - assert len(clip_line.geometry) == 2 +def test_warning_point_clip_function(point_gdf, single_rectangle_gdf): + with pytest.raises( + Warning, match="_clip_points is deprecated. Use the _clip_points()", + ): + cl._clip_points(point_gdf, single_rectangle_gdf) diff --git a/examples/plot_clip.py b/examples/plot_clip.py deleted file mode 100644 index 790cbfcb..00000000 --- a/examples/plot_clip.py +++ /dev/null @@ -1,128 +0,0 @@ -""" -Clip Vector Data with EarthPy -================================================================== - -Learn how to clip point, line, or polygon geometries to the country_boundary -of a polygon geometry using EarthPy. - -""" - -############################################################################### -# Clip Vector Data in Python Using EarthPy -# --------------------------------------------- -# -# .. note:: -# The example below will show you how to use the clip_shp() function to clip -# vector data such as points, lines and polygons to a vector boundary. -# -# The example below walks you through a typical workflow for clipping one -# vector data file to the shape of another. Both vector data files must be -# opened with GeoPandas as GeoDataFrames and be in the same Coordinate -# Reference System (CRS) for the ``clip_shp()`` function in EarthPy to work. -# -# This example uses a line shapefile containing all major roads in North America -# and a polygon shapefile containing the United States boundary to show you how -# to prepare and clip vector data. In this example, the roads will be clipped -# to the United States boundary. -# -# .. note:: -# The object to be clipped will be clipped to the full extent of the clip -# object. If there are multiple polygons in clip object, the input data will -# be clipped to the total boundary of all polygons in clip object. - -############################################################################### -# Import Packages -# --------------- -# -# To begin, import the needed packages. You will primarily use EarthPy's clip -# utility alongside GeoPandas. - -import os -import matplotlib.pyplot as plt -import geopandas as gpd -import earthpy as et -import earthpy.clip as ec - -############################################################################### -# Import Example Data -# ------------------- -# -# Once the packages have been imported, download the data needed for this -# example: one line shapefile containing all major roads in North America, -# and one polygon shapefile containing the United States boundary. - -data = et.data.get_data("spatial-vector-lidar") - -############################################################################### -# Open Files with GeoPandas and Reproject the Data -# ------------------------------------------------- -# -# Start by setting your working directory. Then, import the data files to -# GeoDataFrames using GeoPandas. -# -# Recall that the data must be in the same CRS in order to use the -# ``clip_shp()`` function. If the data are not in the same CRS, be sure to use -# the ``to_crs()`` function from GeoPandas to match the projects between the -# two objects, as shown below. - -# Set your home environment -os.chdir(os.path.join(et.io.HOME, "earth-analytics")) - -# Open both files with GeoPandas -road_path = os.path.join( - "data", - "spatial-vector-lidar", - "global", - "ne_10m_roads", - "ne_10m_n_america_roads.shp", -) -roads = gpd.read_file(road_path) - -country_path = os.path.join( - "data", "spatial-vector-lidar", "usa", "usa-boundary-dissolved.shp" -) -country_boundary = gpd.read_file(country_path) - -# Reproject the roads layer to match the US boundary CRS -roads = roads.to_crs(country_boundary.crs) - -############################################################################### -# The plot below shows the roads data before it has been clipped. Notice that -# the ``.boundary`` method for a GeoPandas object is used to plot the -# boundary rather than the filled polygon. This allows for other data, such as -# the roads data, to be overlayed on top of the polygon boundary. - -fig, ax = plt.subplots(figsize=(12, 8)) -roads.plot(ax=ax, color="grey") -country_boundary.boundary.plot(ax=ax, color="black") -ax.set_title("Major NA Roads Unclipped to US Border", fontsize=20) -ax.set_axis_off() -plt.show() - -############################################################################### -# Clip the Data -# -------------- -# -# Now that the data are opened as GeoDataFrame objects and in the same -# projection, the data can be clipped! Recall that in this example, the roads -# will be clipped to the United States boundary. -# -# To clip the data, make -# sure you put the object to be clipped as the first argument in -# ``clip_shp()``, followed by the vector object (boundary) to which you want -# the first object clipped. The function will return the clipped GeoDataFrame -# of the object that is being clipped (e.g. roads). - -roads_clipped = ec.clip_shp(roads, country_boundary) -# Remove empty geometries -roads_clipped = roads_clipped[~roads_clipped.is_empty] - -# Plot the clipped data -# The plot below shows the results of the clip function applied to the roads -# sphinx_gallery_thumbnail_number = 2 -fig, ax = plt.subplots(figsize=(12, 8)) -roads_clipped.plot(ax=ax, color="grey") -country_boundary.boundary.plot(ax=ax, color="black") -ax.set_title("Major NA Roads Clipped to US Border", fontsize=20) -ax.set_axis_off() -plt.show() diff --git a/paper.md b/paper.md index 657028e6..2fbaf875 100644 --- a/paper.md +++ b/paper.md @@ -60,7 +60,7 @@ The above operations are crucial to understanding a dataset and identifying issu `EarthPy` was originally designed to support the Earth Analytics Education program at Earth Lab - University of Colorado, Boulder. Our program teaches students how to work with a suite of earth and environmental data using open source `Python`. All lessons are published as free open education resources on our online learning portal (https://www.earthdatascience.org). Through this publication process, we identified that many spatial data exploration and cleanup tasks which were performed regularly required many steps that could be easily wrapped into helper functions. We modeled these functions after those available in the `R` ecosystem, given the experience of the developers' many years of working and teaching with `R`. -`EarthPy` allows the user to streamline common geospatial data operations in a modular way. This reduces the amount of repetitive coding required to open and stack raster datasets, clip the data to a defined area, and in particular, plotting data for investigation. +`EarthPy` allows the user to streamline common geospatial data operations in a modular way. This reduces the amount of repetitive coding required to open and stack raster datasets, crop the data to a defined area, and in particular, plotting data for investigation. # EarthPy Functionality @@ -70,7 +70,6 @@ The above operations are crucial to understanding a dataset and identifying issu * [mask: Mask out cloud and shadow covered pixels from raster data](https://earthpy.readthedocs.io/en/latest/api/earthpy.mask.html): helper functions to mask remote sensing images using a cloud mask or QA (i.e. quality) layer. * [plot: Visualizing spatial data](https://earthpy.readthedocs.io/en/latest/api/earthpy.plot.html): plotting utilities including plotting a set of bands saved in a numpy array format, creating a custom colorbar, and custom legends with unique symbology. * [spatial: Raster processing and analysis](https://earthpy.readthedocs.io/en/latest/api/earthpy.spatial.html): utilities to crop a set of bands to a defined spatial extent, create a hillshade, stack bands, and calculate normalized difference rasters. -* [clip: Vector data subsetting](https://earthpy.readthedocs.io/en/latest/api/earthpy.clip.html): A module to clip vector data using GeoPandas. Allows for clipping of points, lines, and polygon data within a specified polygon. ## EarthPy Vignettes diff --git a/setup.py b/setup.py index 83207b4c..d29ff6be 100644 --- a/setup.py +++ b/setup.py @@ -29,7 +29,6 @@ "matplotlib>=2.0.0", "numpy>=1.14.0", "rasterio", - "Rtree>=0.8", "scikit-image", "requests", ],