Пример #1
0
    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)
Пример #2
0
def make_circular_polygon(centers, radii, attributes=None):
    """Create circular polygon in geographic coordinates

    Args:
        centers: list of (longitude, latitude)

        radii: desired approximate radii in meters (must be
        monotonically ascending).

        Can be either one number or list of numbers
        attributes (optional): Attributes for each center

    Returns:
        Vector polygon layer representing circle in WGS84
    """

    if not isinstance(radii, list):
        radii = [radii]

    # FIXME (Ole): Check that radii are monotonically increasing

    circles = []
    new_attributes = []
    for i, center in enumerate(centers):
        p = Point(longitude=center[0], latitude=center[1])
        inner_rings = None
        for radius in radii:
            # Generate circle polygon
            C = p.generate_circle(radius)
            circles.append(Polygon(outer_ring=C, inner_rings=inner_rings))

            # Store current circle and inner ring for next poly
            inner_rings = [C]

            # Carry attributes for center forward
            attr = {}
            if attributes is not None:
                for key in attributes[i]:
                    attr[key] = attributes[i][key]

            # Add radius to this ring
            attr['Radius'] = radius

            new_attributes.append(attr)

    Z = Vector(
        geometry=circles,  # List with circular polygons
        data=new_attributes,  # Associated attributes
        geometry_type='polygon')

    return Z
Пример #3
0
def buffer_points(centers, radii, hazard_zone_attribute, data_table=None):
    """Buffer points for each center with defined radii.

    If the data_table is defined, then the data will also be copied to the
    result. This function is used for making buffer of volcano point hazard.

    :param centers: All center of each point (longitude, latitude)
    :type centers: list

    :param radii: Desired approximate radii in meters (must be
        monotonically ascending). Can be either one number or list of numbers
    :type radii: int, list

    :param hazard_zone_attribute: The name of the attributes representing
        hazard zone.
    :type hazard_zone_attribute: str

    :param data_table: Data for each center (optional)
    :type data_table: list

    :return: Vector polygon layer representing circle in WGS84
    :rtype: Vector
    """
    if not isinstance(radii, list):
        radii = [radii]

    # Check that radii are monotonically increasing
    monotonically_increasing_flag = all(
        x < y for x, y in zip(radii, radii[1:]))
    if not monotonically_increasing_flag:
        raise RadiiException(RadiiException.suggestion)

    circles = []
    new_data_table = []
    for i, center in enumerate(centers):
        p = Point(longitude=center[0], latitude=center[1])
        inner_rings = None
        for radius in radii:
            # Generate circle polygon
            circle = p.generate_circle(radius)
            circles.append(Polygon(outer_ring=circle, inner_rings=inner_rings))

            # Store current circle and inner ring for next poly
            inner_rings = [circle]

            # Carry attributes for center forward (deep copy)
            row = {}
            if data_table is not None:
                for key in data_table[i]:
                    row[key] = data_table[i][key]

            # Add radius to this ring
            row[hazard_zone_attribute] = radius

            new_data_table.append(row)

    circular_polygon = Vector(
        geometry=circles,  # List with circular polygons
        data=new_data_table,  # Associated attributes
        geometry_type='polygon')

    return circular_polygon