def test_clip_points_by_polygons(self): """Points can be clipped by polygons (real data) """ # Name input files point_name = join(TESTDATA, 'population_5x5_jakarta_points.shp') point_layer = read_layer(point_name) points = numpy.array(point_layer.get_geometry()) attrs = point_layer.get_data() # Loop through polygons for filename in [ 'polygon_0.shp', 'polygon_1.shp', 'polygon_2.shp', 'polygon_3.shp', 'polygon_4.shp', 'polygon_5.shp', 'polygon_6.shp' ]: polygon_layer = read_layer(join(TESTDATA, filename)) polygon = polygon_layer.get_geometry()[0] # Clip indices = inside_polygon(points, polygon) # Sanity for point in points[indices, :]: assert is_inside_polygon(point, polygon) # Explicit tests if filename == 'polygon_0.shp': assert len(indices) == 6 elif filename == 'polygon_1.shp': assert len(indices) == 2 assert numpy.allclose(points[indices[0], :], [106.8125, -6.1875]) assert numpy.allclose(points[indices[1], :], [106.8541667, -6.1875]) assert numpy.allclose(attrs[indices[0]]['value'], 331941.6875) assert numpy.allclose(attrs[indices[1]]['value'], 496445.8125) elif filename == 'polygon_2.shp': assert len(indices) == 7 elif filename == 'polygon_3.shp': assert len(indices) == 0 # Degenerate elif filename == 'polygon_4.shp': assert len(indices) == 0 # Degenerate elif filename == 'polygon_5.shp': assert len(indices) == 8 elif filename == 'polygon_6.shp': assert len(indices) == 6
def test_clip_points_by_polygons(self): """Points can be clipped by polygons (real data) """ # Name input files point_name = join(TESTDATA, 'population_5x5_jakarta_points.shp') point_layer = read_layer(point_name) points = numpy.array(point_layer.get_geometry()) attrs = point_layer.get_data() # Loop through polygons for filename in ['polygon_0.shp', 'polygon_1.shp', 'polygon_2.shp', 'polygon_3.shp', 'polygon_4.shp', 'polygon_5.shp', 'polygon_6.shp']: polygon_layer = read_layer(join(TESTDATA, filename)) polygon = polygon_layer.get_geometry()[0] # Clip indices = inside_polygon(points, polygon) # Sanity for point in points[indices, :]: assert is_inside_polygon(point, polygon) # Explicit tests if filename == 'polygon_0.shp': assert len(indices) == 6 elif filename == 'polygon_1.shp': assert len(indices) == 2 assert numpy.allclose(points[indices[0], :], [106.8125, -6.1875]) assert numpy.allclose(points[indices[1], :], [106.8541667, -6.1875]) assert numpy.allclose(attrs[indices[0]]['value'], 331941.6875) assert numpy.allclose(attrs[indices[1]]['value'], 496445.8125) elif filename == 'polygon_2.shp': assert len(indices) == 7 elif filename == 'polygon_3.shp': assert len(indices) == 0 # Degenerate elif filename == 'polygon_4.shp': assert len(indices) == 0 # Degenerate elif filename == 'polygon_5.shp': assert len(indices) == 8 elif filename == 'polygon_6.shp': assert len(indices) == 6
def aggregate_point_data(data=None, boundaries=None, attribute_name=None, aggregation_function='count'): """Clip data to boundaries and aggregate their values for each. Input data: Point dataset boundaries: Polygon dataset attribute_name: Name of attribute to aggrate over. aggregation_function: Function to apply ('count' or 'sum') Output List of aggregated values for each polygon. Note Aggregated values depend on aggregation function: 'sum': Sum of values for attribute_name 'count': Dictionary with counts of occurences of each value of attribute_name """ msg = ('Input argument "data" must be point type. I got type: %s' % data.get_geometry_type()) if not data.is_point_data: raise Exception(msg) msg = ('Input argument "boundaries" must be polygon type. I got type: %s' % boundaries.get_geometry_type()) if not boundaries.is_polygon_data: raise Exception(msg) polygon_geoms = boundaries.get_geometry() #polygon_attrs = boundaries.get_data() points = data.get_geometry() attributes = data.get_data() result = [] #for i, polygon in enumerate(polygon_geoms): for polygon in polygon_geoms: indices = inside_polygon(points, polygon) #print 'Found %i points in polygon %i' % (len(indices), i) # Aggregate numbers if aggregation_function == 'count': bins = {} for att in numpy.take(attributes, indices): val = att[attribute_name] # Count occurences of val if val not in bins: bins[val] = 0 bins[val] += 1 result.append(bins) elif aggregation_function == 'sum': sum_ = 0 for att in numpy.take(attributes, indices): val = att[attribute_name] sum_ += val result.append(sum_) return result
def interpolate_polygon_points(source, target, layer_name=None): """Interpolate from polygon vector layer to point vector data Args: * source: Vector data set (polygon) * target: Vector data set (points) * layer_name: Optional name of returned interpolated layer. If None the name of target is used for the returned layer. Output I: Vector data set; points located as target with values interpolated from source Note All attribute names from polygons are transferred to the points that are inside them. """ msg = ('Vector layer to interpolate to must be point geometry. ' 'I got OGR geometry type %s' % geometrytype2string(target.geometry_type)) verify(target.is_point_data, msg) msg = ('Name must be either a string or None. I got %s' % (str(type(target)))[1:-1]) verify(layer_name is None or isinstance(layer_name, basestring), msg) attribute_names = source.get_attribute_names() #---------------- # Start algorithm #---------------- # Extract point features points = ensure_numeric(target.get_geometry()) attributes = target.get_data() original_geometry = target.get_geometry() # Geometry for returned data # Extract polygon features geom = source.get_geometry(as_geometry_objects=True) data = source.get_data() verify(len(geom) == len(data)) # Include polygon_id as attribute attribute_names.append('polygon_id') attribute_names.append(DEFAULT_ATTRIBUTE) # Augment point features with empty attributes from polygon for a in attributes: # Create all attributes that exist in source for key in attribute_names: a[key] = None # Traverse polygons and assign attributes to points that fall inside for i, polygon in enumerate(geom): # Carry all attributes across from source poly_attr = data[i] # Assign default attribute to indicate points inside poly_attr[DEFAULT_ATTRIBUTE] = True # Clip data points by polygons and add polygon attributes indices = inside_polygon(points, polygon.outer_ring, holes=polygon.inner_rings) for k in indices: for key in poly_attr: # Assign attributes from polygon to points attributes[k][key] = poly_attr[key] attributes[k]['polygon_id'] = i # Store id for associated polygon # Create new Vector instance and return V = Vector(data=attributes, projection=target.get_projection(), geometry=original_geometry, name=layer_name) return V
def interpolate_polygon_points(source, target, layer_name=None): """Interpolate from polygon vector layer to point vector data Args: * source: Vector data set (polygon) * target: Vector data set (points) * layer_name: Optional name of returned interpolated layer. If None the name of target is used for the returned layer. Output I: Vector data set; points located as target with values interpolated from source Note All attribute names from polygons are transferred to the points that are inside them. """ msg = ('Vector layer to interpolate to must be point geometry. ' 'I got OGR geometry type %s' % geometry_type_to_string(target.geometry_type)) verify(target.is_point_data, msg) msg = ('Name must be either a string or None. I got %s' % (str(type(target)))[1:-1]) verify(layer_name is None or isinstance(layer_name, basestring), msg) attribute_names = source.get_attribute_names() #---------------- # Start algorithm #---------------- # Extract point features points = ensure_numeric(target.get_geometry()) attributes = target.get_data() original_geometry = target.get_geometry() # Geometry for returned data # Extract polygon features geom = source.get_geometry(as_geometry_objects=True) data = source.get_data() verify(len(geom) == len(data)) # Include polygon_id as attribute attribute_names.append('polygon_id') attribute_names.append(DEFAULT_ATTRIBUTE) # Augment point features with empty attributes from polygon for a in attributes: # Create all attributes that exist in source for key in attribute_names: a[key] = None # Traverse polygons and assign attributes to points that fall inside for i, polygon in enumerate(geom): # Carry all attributes across from source poly_attr = data[i] # Assign default attribute to indicate points inside poly_attr[DEFAULT_ATTRIBUTE] = True # Clip data points by polygons and add polygon attributes indices = inside_polygon(points, polygon.outer_ring, holes=polygon.inner_rings) for k in indices: for key in poly_attr: # Assign attributes from polygon to points attributes[k][key] = poly_attr[key] attributes[k]['polygon_id'] = i # Store id for associated polygon # Create new Vector instance and return V = Vector(data=attributes, projection=target.get_projection(), geometry=original_geometry, name=layer_name) return V
def test_clip_points_by_polygons_with_holes_real(self): """Points can be clipped by polygons with holes (real data) """ # Read real polygon with holes filename = '%s/%s' % (TESTDATA, 'donut.shp') L = read_layer(filename) # -------------------------------------------- # Pick one polygon that has 2 inner rings P = L.get_geometry(as_geometry_objects=True)[1] outer_ring = P.outer_ring inner_ring0 = P.inner_rings[0] inner_ring1 = P.inner_rings[1] # Make some test points points_in_bbox = generate_random_points_in_bbox(outer_ring, 1000) points_in_inner_ring0 = populate_polygon(inner_ring0, 2, seed=13) points_in_inner_ring1 = populate_polygon(inner_ring1, 2, seed=17) points = numpy.concatenate( (points_in_bbox, points_in_inner_ring0, points_in_inner_ring1)) # Clip indices = inside_polygon(points, P.outer_ring, holes=P.inner_rings) # Sanity for point in points[indices, :]: # Must be inside outer ring assert is_inside_polygon(point, outer_ring) # But not in any of the inner rings assert not is_inside_polygon(point, inner_ring0) assert not is_inside_polygon(point, inner_ring1) # --------------------------------------------------------- # Pick a polygon that has 1 inner ring (nice visualisation) P = L.get_geometry(as_geometry_objects=True)[9] outer_ring = P.outer_ring inner_ring = P.inner_rings[0] # Make some test points points = generate_random_points_in_bbox(outer_ring, 500) # Clip indices = inside_polygon(points, P.outer_ring, holes=P.inner_rings) # Sanity for point in points[indices, :]: # Must be inside outer ring assert is_inside_polygon(point, outer_ring) # But not in the inner ring assert not is_inside_polygon(point, inner_ring) # Store for visual check (nice one!) # Uncomment os.remove if you want see the layers pol = Vector(geometry=[P]) tmp_filename = unique_filename(suffix='.shp') pol.write_to_file(tmp_filename) # print 'Polygon with holes written to %s' % tmp_filename os.remove(tmp_filename) pts = Vector(geometry=points[indices, :]) tmp_filename = unique_filename(suffix='.shp') pts.write_to_file(tmp_filename) # print 'Clipped points written to %s' % tmp_filename os.remove(tmp_filename)
def test_clip_points_by_polygons_with_holes0(self): """Points can be clipped by polygons with holes """ # Define an outer ring outer_ring = numpy.array([[106.79, -6.233], [106.80, -6.24], [106.78, -6.23], [106.77, -6.21], [106.79, -6.233]]) # Define inner rings inner_rings = [ numpy.array([[106.77827, -6.2252], [106.77775, -6.22378], [106.78, -6.22311], [106.78017, -6.22530], [106.77827, -6.2252]])[::-1], numpy.array([[106.78652, -6.23215], [106.78642, -6.23075], [106.78746, -6.23143], [106.78831, -6.23307], [106.78652, -6.23215]])[::-1] ] v = Vector( geometry=[Polygon(outer_ring=outer_ring, inner_rings=inner_rings)]) assert v.is_polygon_data # Write it to file tmp_filename = unique_filename(suffix='.shp') v.write_to_file(tmp_filename) # Read polygon it back L = read_layer(tmp_filename) P = L.get_geometry(as_geometry_objects=True)[0] outer_ring = P.outer_ring inner_ring0 = P.inner_rings[0] inner_ring1 = P.inner_rings[1] # Make some test points points = generate_random_points_in_bbox(outer_ring, 1000, seed=13) # Clip to outer ring, excluding holes indices = inside_polygon(points, P.outer_ring, holes=P.inner_rings) # Sanity for point in points[indices, :]: # Must be inside outer ring assert is_inside_polygon(point, outer_ring) # But not in any of the inner rings assert not is_inside_polygon(point, inner_ring0) assert not is_inside_polygon(point, inner_ring1) if False: # Store for visual check pol = Vector(geometry=[P]) tmp_filename = unique_filename(suffix='.shp') pol.write_to_file(tmp_filename) print 'Polygon with holes written to %s' % tmp_filename pts = Vector(geometry=points[indices, :]) tmp_filename = unique_filename(suffix='.shp') pts.write_to_file(tmp_filename) print 'Clipped points written to %s' % tmp_filename
def test_clip_points_by_polygons_with_holes_real(self): """Points can be clipped by polygons with holes (real data) """ # Read real polygon with holes filename = '%s/%s' % (TESTDATA, 'donut.shp') L = read_layer(filename) # -------------------------------------------- # Pick one polygon that has 2 inner rings P = L.get_geometry(as_geometry_objects=True)[1] outer_ring = P.outer_ring inner_ring0 = P.inner_rings[0] inner_ring1 = P.inner_rings[1] # Make some test points points_in_bbox = generate_random_points_in_bbox(outer_ring, 1000) points_in_inner_ring0 = populate_polygon(inner_ring0, 2, seed=13) points_in_inner_ring1 = populate_polygon(inner_ring1, 2, seed=17) points = numpy.concatenate((points_in_bbox, points_in_inner_ring0, points_in_inner_ring1)) # Clip indices = inside_polygon(points, P.outer_ring, holes=P.inner_rings) # Sanity for point in points[indices, :]: # Must be inside outer ring assert is_inside_polygon(point, outer_ring) # But not in any of the inner rings assert not is_inside_polygon(point, inner_ring0) assert not is_inside_polygon(point, inner_ring1) # --------------------------------------------------------- # Pick a polygon that has 1 inner ring (nice visualisation) P = L.get_geometry(as_geometry_objects=True)[9] outer_ring = P.outer_ring inner_ring = P.inner_rings[0] # Make some test points points = generate_random_points_in_bbox(outer_ring, 500) # Clip indices = inside_polygon(points, P.outer_ring, holes=P.inner_rings) # Sanity for point in points[indices, :]: # Must be inside outer ring assert is_inside_polygon(point, outer_ring) # But not in the inner ring assert not is_inside_polygon(point, inner_ring) # Store for visual check (nice one!) # Uncomment os.remove if you want see the layers pol = Vector(geometry=[P]) tmp_filename = unique_filename(suffix='.shp') pol.write_to_file(tmp_filename) #print 'Polygon with holes written to %s' % tmp_filename os.remove(tmp_filename) pts = Vector(geometry=points[indices, :]) tmp_filename = unique_filename(suffix='.shp') pts.write_to_file(tmp_filename) #print 'Clipped points written to %s' % tmp_filename os.remove(tmp_filename)
def test_clip_points_by_polygons_with_holes0(self): """Points can be clipped by polygons with holes """ # Define an outer ring outer_ring = numpy.array([[106.79, -6.233], [106.80, -6.24], [106.78, -6.23], [106.77, -6.21], [106.79, -6.233]]) # Define inner rings inner_rings = [numpy.array([[106.77827, -6.2252], [106.77775, -6.22378], [106.78, -6.22311], [106.78017, -6.22530], [106.77827, -6.2252]])[::-1], numpy.array([[106.78652, -6.23215], [106.78642, -6.23075], [106.78746, -6.23143], [106.78831, -6.23307], [106.78652, -6.23215]])[::-1]] v = Vector(geometry=[Polygon(outer_ring=outer_ring, inner_rings=inner_rings)]) assert v.is_polygon_data # Write it to file tmp_filename = unique_filename(suffix='.shp') v.write_to_file(tmp_filename) # Read polygon it back L = read_layer(tmp_filename) P = L.get_geometry(as_geometry_objects=True)[0] outer_ring = P.outer_ring inner_ring0 = P.inner_rings[0] inner_ring1 = P.inner_rings[1] # Make some test points points = generate_random_points_in_bbox(outer_ring, 1000, seed=13) # Clip to outer ring, excluding holes indices = inside_polygon(points, P.outer_ring, holes=P.inner_rings) # Sanity for point in points[indices, :]: # Must be inside outer ring assert is_inside_polygon(point, outer_ring) # But not in any of the inner rings assert not is_inside_polygon(point, inner_ring0) assert not is_inside_polygon(point, inner_ring1) if False: # Store for visual check pol = Vector(geometry=[P]) tmp_filename = unique_filename(suffix='.shp') pol.write_to_file(tmp_filename) print 'Polygon with holes written to %s' % tmp_filename pts = Vector(geometry=points[indices, :]) tmp_filename = unique_filename(suffix='.shp') pts.write_to_file(tmp_filename) print 'Clipped points written to %s' % tmp_filename
def interpolate_polygon_points(source, target, layer_name=None, attribute_name=None): """Interpolate from polygon vector layer to point vector data Args: * source: Vector data set (polygon) * target: Vector data set (points) * layer_name: Optional name of returned interpolated layer. If None the name of target is used for the returned layer. * attribute_name: Name for new attribute. If None (default) the name of source is used Output I: Vector data set; points located as target with values interpolated from source """ msg = ('Vector layer to interpolate to must be point geometry. ' 'I got OGR geometry type %s' % geometrytype2string(target.geometry_type)) verify(target.is_point_data, msg) msg = ('Name must be either a string or None. I got %s' % (str(type(target)))[1:-1]) verify(layer_name is None or isinstance(layer_name, basestring), msg) msg = ('Attribute must be either a string or None. I got %s' % (str(type(target)))[1:-1]) verify(attribute_name is None or isinstance(attribute_name, basestring), msg) attribute_names = source.get_attribute_names() if attribute_name is not None: msg = ('Requested attribute "%s" did not exist in %s' % (attribute_name, attribute_names)) verify(attribute_name in attribute_names, msg) #---------------- # Start algorithm #---------------- # Extract point features points = ensure_numeric(target.get_geometry()) attributes = target.get_data() original_geometry = target.get_geometry() # Geometry for returned data # Extract polygon features geom = source.get_geometry() data = source.get_data() verify(len(geom) == len(data)) # Augment point features with empty attributes from polygon for a in attributes: if attribute_name is None: # Use all attributes for key in attribute_names: a[key] = None else: # Use only requested attribute # FIXME (Ole): Test for this is not finished a[attribute_name] = None # Always create default attribute flagging if point was # inside any of the polygons a[DEFAULT_ATTRIBUTE] = None # Traverse polygons and assign attributes to points that fall inside for i, polygon in enumerate(geom): if attribute_name is None: # Use all attributes poly_attr = data[i] else: # Use only requested attribute poly_attr = {attribute_name: data[i][attribute_name]} # Assign default attribute to indicate points inside poly_attr[DEFAULT_ATTRIBUTE] = True # Clip data points by polygons and add polygon attributes indices = inside_polygon(points, polygon) for k in indices: for key in poly_attr: # Assign attributes from polygon to points attributes[k][key] = poly_attr[key] # Create new Vector instance and return V = Vector(data=attributes, projection=target.get_projection(), geometry=original_geometry, name=layer_name) return V