def clip_grid_by_polygons(A, geotransform, polygons): """Clip raster grid by polygon. Args: * A: MxN array of grid points * geotransform: 6-tuple used to locate A geographically (top left x, w-e pixel resolution, rotation, top left y, rotation, n-s pixel resolution) * polygons: list of polygon geometry objects or list of polygon arrays Returns: points_covered: List of (points, values) - one per input polygon. Implementing algorithm suggested in https://github.com/AIFDR/inasafe/issues/91#issuecomment-7025120 .. note:: Grid points are considered to be pixel-registered which means that each point represents the center of its grid cell. The required half cell shifts are taken care of by the function :func:`geotransform_to_axes`. If multiple polygons overlap, the one first encountered will be used. """ # Convert raster grid to Nx2 array of points and an N array of pixel values ny, nx = A.shape x, y = geotransform_to_axes(geotransform, nx, ny) points, values = grid_to_points(A, x, y) # Generate list of points and values that fall inside each polygon points_covered = [] remaining_points = points remaining_values = values for polygon in polygons: # print 'Remaining points', len(remaining_points) if hasattr(polygon, 'outer_ring'): outer_ring = polygon.outer_ring inner_rings = polygon.inner_rings else: # Assume it is an array outer_ring = polygon inner_rings = None inside, outside = in_and_outside_polygon(remaining_points, outer_ring, holes=inner_rings, closed=True, check_input=False) # Add features inside this polygon points_covered.append( (remaining_points[inside], remaining_values[inside])) # Select remaining points to clip remaining_points = remaining_points[outside] remaining_values = remaining_values[outside] return points_covered
def test_grid2points(self): """Raster grids can be converted to point data.""" # Pixel values A = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]] A = numpy.array(A, dtype='f') M, N = A.shape L = M * N # Axis longitudes = numpy.linspace(100, 110, N, endpoint=False) latitudes = numpy.linspace(-4, 0, M, endpoint=True) # Call function to be tested P, V = grid_to_points(A, longitudes, latitudes) # Assert correctness assert P.shape[0] == L assert P.shape[1] == 2 assert len(V) == L assert numpy.allclose(P[:N, 0], longitudes) assert numpy.allclose(P[:L:N, 1], latitudes[::-1]) assert numpy.allclose(V, A.flat[:])
def to_vector_points(self): """Convert raster grid to vector point data Returns: * coordinates: Nx2 array of x, y (lon, lat) coordinates * values: N array of corresponding grid values """ # Convert grid data to point data A = self.get_data() x, y = self.get_geometry() P, V = grid_to_points(A, x, y) return P, V
def clip_grid_by_polygons(grid_data, geotransform, polygons): """Clip raster grid by polygon. Implementing algorithm suggested in https://github.com/AIFDR/inasafe/issues/91#issuecomment-7025120 .. note:: Grid points are considered to be pixel-registered which means that each point represents the center of its grid cell. The required half cell shifts are taken care of by the function :func:`geotransform_to_axes`. If multiple polygons overlap, the one first encountered will be used. :param grid_data: MxN array of grid points. :param geotransform: 6-tuple used to locate A geographically (top left x, w-e pixel resolution, rotation, top left y, rotation, n-s pixel resolution) :param polygons: list of polygon geometry objects or list of polygon arrays :returns: Tuple of (points_covered, grid_covered). points_covered = List of tuple (points, values) - points covered and its value per polygon. values_covered = grid_data that coincide with the polygons """ # Convert raster grid to Nx2 array of points and an N array of pixel values ny, nx = grid_data.shape x, y = geotransform_to_axes(geotransform, nx, ny) points, values = grid_to_points(grid_data, x, y) # Generate list of points and values that fall inside each polygon points_covered = [] # List of indices that are inside the polygons values_indices = set([]) for polygon in polygons: if hasattr(polygon, 'outer_ring'): outer_ring = polygon.outer_ring inner_rings = polygon.inner_rings else: # Assume it is an array outer_ring = polygon inner_rings = None inside, _ = in_and_outside_polygon( points, outer_ring, holes=inner_rings, closed=True, check_input=False ) # Get non intersected inside inside_set = set(inside) intersected_inside = inside_set & values_indices inside = list(inside_set - intersected_inside) # Add features inside this polygon points_covered.append((points[inside], values[inside])) # Union inside to values indices values_indices |= inside_set # Values covered, set to NaN if it's not covered by any polygons values_covered = values.astype(numpy.float, copy=False) values_indices = list(values_indices) mask = numpy.ones(values.shape, dtype=bool) mask[values_indices] = False values_covered[mask] = numpy.NaN # Reshape to the grid_data shape grid_covered = numpy.reshape(values_covered, grid_data.shape) return points_covered, grid_covered
def clip_grid_by_polygons(grid_data, geotransform, polygons): """Clip raster grid by polygon. Implementing algorithm suggested in https://github.com/AIFDR/inasafe/issues/91#issuecomment-7025120 .. note:: Grid points are considered to be pixel-registered which means that each point represents the center of its grid cell. The required half cell shifts are taken care of by the function :func:`geotransform_to_axes`. If multiple polygons overlap, the one first encountered will be used. :param grid_data: MxN array of grid points. :param geotransform: 6-tuple used to locate A geographically (top left x, w-e pixel resolution, rotation, top left y, rotation, n-s pixel resolution) :param polygons: list of polygon geometry objects or list of polygon arrays :returns: Tuple of (points_covered, grid_covered). points_covered = List of tuple (points, values) - points covered and its value per polygon. values_covered = grid_data that coincide with the polygons """ # Convert raster grid to Nx2 array of points and an N array of pixel values ny, nx = grid_data.shape x, y = geotransform_to_axes(geotransform, nx, ny) points, values = grid_to_points(grid_data, x, y) # Generate list of points and values that fall inside each polygon points_covered = [] # List of indices that are inside the polygons values_indices = set([]) for polygon in polygons: if hasattr(polygon, 'outer_ring'): outer_ring = polygon.outer_ring inner_rings = polygon.inner_rings else: # Assume it is an array outer_ring = polygon inner_rings = None inside, _ = in_and_outside_polygon(points, outer_ring, holes=inner_rings, closed=True, check_input=False) # Get non intersected inside inside_set = set(inside) intersected_inside = inside_set & values_indices inside = list(inside_set - intersected_inside) # Add features inside this polygon points_covered.append((points[inside], values[inside])) # Union inside to values indices values_indices |= inside_set # Values covered, set to NaN if it's not covered by any polygons values_covered = values.astype(numpy.float, copy=False) values_indices = list(values_indices) mask = numpy.ones(values.shape, dtype=bool) mask[values_indices] = False values_covered[mask] = numpy.NaN # Reshape to the grid_data shape grid_covered = numpy.reshape(values_covered, grid_data.shape) return points_covered, grid_covered