def test_zeros(): with pytest.raises(RuntimeError): cuspatial.point_in_polygon( cudf.Series([0.0]), cudf.Series([0.0]), cudf.Series([0]), cudf.Series([0]), cudf.Series([0.0]), cudf.Series([0.0]), )
def lasso_callback(xs, ys): # set box selected ranges to None self.x_range, self.y_range = None, None # convert datetime to int64 since, point_in_polygon does not # support datetime indices = cuspatial.point_in_polygon( self._to_xaxis_type(self.nodes[self.node_x]), self._to_yaxis_type(self.nodes[self.node_y]), cudf.Series([0], index=["selection"]), [0], xs, ys, ) self.selected_indices = indices.selection nodes = dashboard_cls._query( dashboard_cls._generate_query_str(), local_indices=indices.selection, ) edges = None if self.inspect_neighbors._active: node_ids = nodes[self.node_id] nodes, edges = self.query_graph(node_ids, self.nodes, self.edges) # reload all charts with new queried data (cudf.DataFrame only) dashboard_cls._reload_charts(data=nodes, ignore_cols=[self.name]) # reload graph chart separately as it has an extra edges argument self.reload_chart(data=nodes, edges=edges) del nodes, edges
def lasso_callback(xs, ys): # set box selected ranges to None self.x_range, self.y_range = None, None # convert datetime to int64 since, point_in_polygon does not # support datetime indices = cuspatial.point_in_polygon( self._to_xaxis_type(self.source[self.x]), self._to_yaxis_type(self.source[self.y]), cudf.Series([0], index=["selection"]), [0], xs, ys, ) self.selected_indices = indices.selection temp_data = dashboard_cls._query( dashboard_cls._generate_query_str(), local_indices=indices.selection, ) # reload all charts with new queried data (cudf.DataFrame only) dashboard_cls._reload_charts(data=temp_data, ignore_cols=[self.name]) self.reload_chart(temp_data, False) del temp_data del indices
def point_in_polygon(df, x, y, xs, ys, format_x, format_y): return cuspatial.point_in_polygon( format_x(df[x]), format_y(df[y]), cudf.Series([0], index=["selection"]), [0], xs, ys, )
def point_in_polygon(df, x, y, xs, ys): return cuspatial.point_in_polygon( df[x], df[y], cudf.Series([0], index=["selection"]), [0], xs, ys, )
def test_two_points_out_two_rings(): result = cuspatial.point_in_polygon( cudf.Series([1, -1]), cudf.Series([1, 1]), cudf.Series([0]), cudf.Series([0, 4]), cudf.Series([-1, 0, 1, -1, -1, 0, 1, -1]), cudf.Series([-1, 1, -1, -1, 3, 5, 3, 3]), ) expected = cudf.DataFrame({0: [False, False]}) cudf.testing.assert_frame_equal(expected, result)
def test_one_point_in(): result = cuspatial.point_in_polygon( cudf.Series([0.0]), cudf.Series([0.0]), cudf.Series([0]), cudf.Series([0]), cudf.Series([-1, 0, 1, -1]), cudf.Series([-1, 1, -1, -1]), ) expected = cudf.DataFrame({0: True}) assert_eq(expected, result)
def test_two_points_in_two_rings(): result = cuspatial.point_in_polygon( cudf.Series([0, 0]), cudf.Series([0, 4]), cudf.Series([0]), cudf.Series([0, 4]), cudf.Series([-1, 0, 1, -1, -1, 0, 1, -1]), cudf.Series([-1, 1, -1, -1, 3, 5, 3, 3]), ) expected = cudf.DataFrame({0: [True, True]}) assert_eq(expected, result)
def test_one_point_in_two_rings_no_repeat(): result = cuspatial.point_in_polygon( cudf.Series([0]), cudf.Series([0]), cudf.Series([0]), cudf.Series([0, 3]), cudf.Series([-1, 0, 1, -1, 0, 1]), cudf.Series([-1, 1, -1, 3, 5, 3]), ) expected = cudf.DataFrame({0: True}) cudf.testing.assert_frame_equal(expected, result)
def test_one_point_out_two_rings_no_repeat(): result = cuspatial.point_in_polygon( cudf.Series([1]), cudf.Series([1]), cudf.Series([0]), cudf.Series([0, 3]), cudf.Series([-1, 0, 1, -1, 0, 1]), cudf.Series([-1, 1, -1, 3, 5, 3]), ) expected = cudf.DataFrame({0: False}) assert_eq(expected, result)
def test_one_point_out(): result = cuspatial.point_in_polygon( cudf.Series([1]), cudf.Series([1]), cudf.Series([0]), cudf.Series([0]), cudf.Series([-1, 0, 1, -1]), cudf.Series([-1, 1, -1, -1]), ) expected = cudf.DataFrame({0: False}) cudf.testing.assert_frame_equal(expected, result)
def test_missing_2(): result = cuspatial.point_in_polygon( cudf.Series([0.0]), cudf.Series([0.0]), cudf.Series(), cudf.Series([0]), cudf.Series([0.0]), cudf.Series([0.0]), ) expected = cudf.DataFrame() assert_eq(expected, result)
def query_census_dataset(polygons, census_data): final_polygon = polygons[0] for i in polygons: final_polygon = final_polygon.union(i) lat, lon = final_polygon.exterior.coords.xy transform_4326_to_3857 = Transformer.from_crs('epsg:4326', 'epsg:3857') lon, lat = transform_4326_to_3857.transform(lon, lat) results = cuspatial.point_in_polygon( census_data.x, census_data.y, cudf.Series([0], index=["selection"]), [0], lon, lat ) return census_data[results.selection]
def test_three_points_two_features(): result = cuspatial.point_in_polygon( cudf.Series([0, -8, 6.0]), cudf.Series([0, -8, 6.0]), cudf.Series([0, 1]), cudf.Series([0, 5]), cudf.Series([-10.0, 5, 5, -10, -10, 0, 10, 10, 0, 0]), cudf.Series([-10.0, -10, 5, 5, -10, 0, 0, 10, 10, 0]), ) expected = cudf.DataFrame() expected[0] = [True, True, False] expected[1] = [True, False, True] assert_eq(expected, result)
def lasso_callback(xs, ys): # convert datetime to int64 since, point_in_polygon does not # support datetime indices = cuspatial.point_in_polygon( self._to_xaxis_type(self.source[self.x]), self._to_yaxis_type(self.source[self.y]), cudf.Series([0], index=["selection"]), [0], xs, ys, ) temp_data = self.source[indices.selection] # reload all charts with new queried data (cudf.DataFrame only) dashboard_cls._reload_charts(data=temp_data, ignore_cols=[self.name]) self.reload_chart(temp_data, False) del temp_data del indices
def spatial_select_columnar(xvals, yvals, geometry): if 'cudf' in sys.modules: import cudf if isinstance(xvals, cudf.Series): xvals = xvals.values.astype('float') yvals = yvals.values.astype('float') try: import cuspatial result = cuspatial.point_in_polygon( xvals, yvals, cudf.Series([0], index=["selection"]), [0], geometry[:, 0], geometry[:, 1], ) return result.values except Exception: xvals = np.asarray(xvals) yvals = np.asarray(yvals) x0, x1 = geometry[:, 0].min(), geometry[:, 0].max() y0, y1 = geometry[:, 1].min(), geometry[:, 1].max() mask = (xvals >= x0) & (xvals <= x1) & (yvals >= y0) & (yvals <= y1) masked_xvals = xvals[mask] masked_yvals = yvals[mask] try: from spatialpandas.geometry import Polygon, PointArray points = PointArray( (masked_xvals.astype('float'), masked_yvals.astype('float'))) poly = Polygon([np.concatenate([geometry, geometry[:1]]).flatten()]) geom_mask = points.intersects(poly) except Exception: pass try: from shapely.geometry import Point, Polygon points = (Point(x, y) for x, y in zip(masked_xvals, masked_yvals)) poly = Polygon(geometry) geom_mask = np.array([poly.contains(p) for p in points]) except ImportError: raise ImportError("Lasso selection on tabular data requires " "either spatialpandas or shapely to be available.") mask[np.where(mask)[0]] = geom_mask return mask
from shapely.geometry import Point, Polygon import cuspatial data_dir = "/home/jianting/cuspatial/data/" plyreader = shapefile.Reader(data_dir + "its_4326_roi.shp") polygon = plyreader.shapes() plys = [] for shape in polygon: plys.append(Polygon(shape.points)) pnt_lon, pnt_lat = cuspatial.read_points_lonlat(data_dir + "locust.location") fpos, rpos, plyx, plyy = cuspatial.read_polygon(data_dir + "itsroi.ply") start = time.time() bm = cuspatial.point_in_polygon(pnt_lon, pnt_lat, fpos, rpos, plyx, plyy) end = time.time() print("Python GPU Time in ms (end-to-end)={}".format((end - start) * 1000)) bma = bm.data.to_array() pntx = pnt_lon.data.to_array() pnty = pnt_lat.data.to_array() start = time.time() mis_match = 0 for i in range(pnt_lon.data.size): pt = Point(pntx[i], pnty[i]) res = 0 for j in range(len(plys)): pip = plys[len(plys) - 1 - j].contains(pt) if pip:
def point_in_polygon_gpu( points_df, # cudf.DataFrame with x and y columns of point coordinates poly_df: gpd.GeoDataFrame, # geopandas.GeoDataFrame with polygon shapes points_x_col: str = "x", points_y_col: str = "y", poly_label_col: str = None, ): """ Find polygon labels for each of the input points. This is a GPU accelerated version that requires cuspatial! Parameters ---------- points_df : cudf.DataFrame A dataframe in GPU memory containing the x and y coordinates. points_x_col : str Name of the x coordinate column in points_df. Default is "x". points_y_col : str Name of the y coordinate column in points_df. Default is "y". poly_df : geopandas.GeoDataFrame A geodataframe in CPU memory containing polygons geometries in each row. poly_label_col : str Name of the column in poly_df that will be used to label the points, e.g. "placename". Default is to automatically use the first column unless otherwise specified. Returns ------- point_labels : cudf.Series A column of labels that indicates which polygon the points fall into. """ import cudf import cuspatial poly_df_: gpd.GeoDataFrame = poly_df.reset_index() # Simply use first column of geodataframe as label if not provided (None) # See https://stackoverflow.com/a/22736342/6611055 poly_label_col: str = poly_label_col or poly_df.columns[0] point_labels: cudf.Series = cudf.Series(index=points_df.index).astype( poly_df[poly_label_col].dtype) # Load CPU-based GeoDataFrame into a GPU-based cuspatial friendly format # This is a workaround until the related feature request at # https://github.com/rapidsai/cuspatial/issues/165 is implemented with tempfile.TemporaryDirectory() as tmpdir: # Save geodataframe to a temporary shapefile, # so that we can load it into GPU memory using cuspatial tmpshpfile = os.path.join(tmpdir, "poly_df.shp") poly_df_.to_file(filename=tmpshpfile, driver="ESRI Shapefile") # Load polygon_offsets, ring_offsets and polygon xy points # from temporary shapefile into GPU memory poly_offsets, poly_ring_offsets, poly_points = cuspatial.read_polygon_shapefile( filename=tmpshpfile) # Run the actual point in polygon algorithm! # Note that cuspatial's point_in_polygon function has a 31 polygon limit, # hence the for-loop code below. See also # https://github.com/rapidsai/cuspatial/blob/branch-0.15/notebooks/nyc_taxi_years_correlation.ipynb num_poly: int = len(poly_df_) point_in_poly_iter: list = list(np.arange(0, num_poly, 31)) + [num_poly] for i in range(len(point_in_poly_iter) - 1): start, end = point_in_poly_iter[i], point_in_poly_iter[i + 1] poly_labels: cudf.DataFrame = cuspatial.point_in_polygon( test_points_x=points_df[points_x_col], test_points_y=points_df[points_y_col], poly_offsets=poly_offsets[start:end], poly_ring_offsets=poly_ring_offsets, poly_points_x=poly_points.x, poly_points_y=poly_points.y, ) # Label each point with polygon they fall in for label in poly_labels.columns: point_labels.loc[ poly_labels[label]] = poly_df_.loc[label][poly_label_col] return point_labels
def get_updated_df(lat, lon, nodes_df): results = cuspatial.point_in_polygon( nodes_df.x, nodes_df.y, cudf.Series([0], index=["selection"]), [0], lat, lon ) return nodes_df[results.selection]