def get_ring_coords(polygon): # outer ring must be reversed to be counterclockwise[::-1] coords = [pg.get_coordinates(pg.get_exterior_ring(polygon)).tolist()] for i in range(pg.get_num_interior_rings(polygon)): # inner rings must be reversed to be clockwise[::-1] coords.append( pg.get_coordinates(pg.get_interior_ring(polygon, i)).tolist()) return coords
def test_get_rings_return_index(): geom = np.array([polygon, None, empty_polygon, polygon_with_hole]) expected_parts = [] expected_index = [] for i, g in enumerate(geom): if g is None or pygeos.is_empty(g): continue expected_parts.append(pygeos.get_exterior_ring(g)) expected_index.append(i) for j in range(0, pygeos.get_num_interior_rings(g)): expected_parts.append(pygeos.get_interior_ring(g, j)) expected_index.append(i) parts, index = pygeos.get_rings(geom, return_index=True) assert len(parts) == len(expected_parts) assert np.all(pygeos.equals_exact(parts, expected_parts)) assert np.array_equal(index, expected_index)
def second_areal_moment(collection): """ Using equation listed on en.wikipedia.org/Second_Moment_of_area, the second moment of area is actually the cross-moment of area between the X and Y dimensions: I_xy = (1/24)\sum^{i=N}^{i=1} (x_iy_{i+1} + 2*x_iy_i + 2*x_{i+1}y_{i+1} + x_{i+1}y_i)(x_iy_i - x_{i+1}y_i) where x_i, y_i is the current point and x_{i+1}, y_{i+1} is the next point, and where x_{n+1} = x_1, y_{n+1} = 1. This relation is known as the: - second moment of area - moment of inertia of plane area - area moment of inertia - second area moment and is *not* the mass moment of inertia, a property of the distribution of mass around a shape. """ ga = _cast(collection) result = numpy.zeros(len(ga)) n_holes_per_geom = pygeos.get_num_interior_rings(ga) for i, geometry in enumerate(ga): n_holes = n_holes_per_geom[i] for hole_ix in range(n_holes): hole = pygeos.get_coordinates(pygeos.get_interior_ring( ga, hole_ix)) result[i] -= _second_moa_ring(hole) n_parts = pygeos.get_num_geometries(geometry) for part in pygeos.get_parts(geometry): result[i] += _second_moa_ring(pygeos.get_coordinates(part)) # must divide everything by 24 and flip if polygon is clockwise. signflip = numpy.array([-1, 1])[pygeos.is_ccw(ga).astype(int)] return result * (1 / 24) * signflip
def get_interior_rings(polygons): """Return array of inner rings for all polygons. Parameters ---------- polygons : ndarray All items must be Polygon geometry type Returns ------- (outer_index, inner_index, rings) """ num_rings = pg.get_num_interior_rings(polygons) outer_index = [] inner_index = [] rings = [] for i in range(len(polygons)): if num_rings[i]: ix = np.arange(num_rings[i]) rings.extend(pg.get_interior_ring(polygons[i], ix)) inner_index.extend(ix) outer_index.extend([i] * num_rings[i]) return outer_index, inner_index, rings
def test_get_num_interior_rings(): actual = pygeos.get_num_interior_rings(all_types + (polygon_with_hole, None)) assert actual.tolist() == [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]