def test_polygon_from_empty(): polygon = Polygon() assert polygon.is_empty assert polygon.exterior.coords[:] == [] polygon = Polygon([]) assert polygon.is_empty assert polygon.exterior.coords[:] == []
def test_polygon_from_linestring(): coords = [(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 0.0)] line = LineString(coords) polygon = Polygon(line) assert polygon.exterior.coords[:] == coords # from unclosed linestring line = LineString(coords[:-1]) polygon = Polygon(line) assert polygon.exterior.coords[:] == coords
def test_polygon_from_polygon(): coords = [(0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0)] polygon = Polygon(coords, [((0.25, 0.25), (0.25, 0.5), (0.5, 0.5), (0.5, 0.25))]) # Test from another Polygon copy = Polygon(polygon) assert len(copy.exterior.coords) == 5 assert len(copy.interiors) == 1 assert len(copy.interiors[0].coords) == 5
def test_polygon_from_coordinate_sequence(): coords = [(0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (0.0, 0.0)] # Construct a polygon, exterior ring only polygon = Polygon(((0.0, 0.0), (0.0, 1.0), (1.0, 1.0))) assert polygon.exterior.coords[:] == coords assert len(polygon.interiors) == 0 polygon = Polygon([(0.0, 0.0), (0.0, 1.0), (1.0, 1.0)]) assert polygon.exterior.coords[:] == coords assert len(polygon.interiors) == 0
def test_polygon(self): coords = ((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0)) # Construct a polygon, exterior ring only polygon = Polygon(coords) assert len(polygon.exterior.coords) == 5 # Ring Access assert isinstance(polygon.exterior, LinearRing) ring = polygon.exterior assert len(ring.coords) == 5 assert ring.coords[0] == ring.coords[4] assert ring.coords[0] == (0.0, 0.0) assert ring.is_ring is True assert len(polygon.interiors) == 0 # Create a new polygon from WKB data = polygon.wkb polygon = None ring = None polygon = load_wkb(data) ring = polygon.exterior assert len(ring.coords) == 5 assert ring.coords[0] == ring.coords[4] assert ring.coords[0] == (0.0, 0.0) assert ring.is_ring is True polygon = None # Interior rings (holes) polygon = Polygon(coords, [((0.25, 0.25), (0.25, 0.5), (0.5, 0.5), (0.5, 0.25))]) assert len(polygon.exterior.coords) == 5 assert len(polygon.interiors[0].coords) == 5 with pytest.raises(IndexError): # index out of range polygon.interiors[1] # Coordinate getter raises exceptions with pytest.raises(NotImplementedError): polygon.coords # Geo interface assert polygon.__geo_interface__ == { "type": "Polygon", "coordinates": ( ((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0), (0.0, 0.0)), ((0.25, 0.25), (0.25, 0.5), (0.5, 0.5), (0.5, 0.25), (0.25, 0.25)), ), }
def test_empty_equality(self): # Test equals operator, including empty geometries # see issue #338 point1 = Point(0, 0) polygon1 = Polygon(((0.0, 0.0), (0.0, 1.0), (-1.0, 1.0), (-1.0, 0.0))) polygon2 = Polygon(((0.0, 0.0), (0.0, 1.0), (-1.0, 1.0), (-1.0, 0.0))) polygon_empty1 = Polygon() polygon_empty2 = Polygon() assert point1 != polygon1 assert polygon_empty1 == polygon_empty2 assert polygon1 != polygon_empty1 assert polygon1 == polygon2 assert polygon_empty1 is not None
def domain_bounds(ds, project=True, test=None): from shapely.geometry import MultiPoint, Polygon, LinearRing if project: from pyproj import Proj pr = Proj(**proj_params(ds)) coords = np.vstack(pr(ds.corner_lons[-4:], ds.corner_lats[-4:])).T if test is not None: test = np.vstack(pr(*test.T)).T else: coords = np.vstack((ds.corner_lons[-4:], ds.corner_lats[-4:])).T p = Polygon(LinearRing(coords)) if test is None: return p else: return [p.contains(i) for i in MultiPoint(test)]
def generateParticles(buildingMap): mapBuilder = BuildingMapProto.BuildingMap.MergeFrom(buildingMap) mapBuilder.clearFloors() for floor in buildingMap.floors: floorBuilder = FloorProto.Floor.MergeFrom(floor) floorBuilder.clearLandmarks() navigableArea = createAccessibleArea(floor.navigableSpaces) for landmark in floor.landmarks: radius = 0.5 while radius < 5.0: rect = box( landmark.location.x - radius, landmark.location.y - radius, landmark.location.x + (2 * radius), landmark.location.y + (2 * radius)) intersection = Polygon(navigableArea) if rect.intersects(navigableArea): break radius += 0.5 landmarkBuilder = Landmark.MergeFrom(landmark) if radius > 5.0: pass else: for i in range(0,NUM_OF_PARTICLES_PER_LANDMARK): x,y = 0.0 while !navigableArea.contains(Point(x, y)): x = landmark.location.x + 2 * (random.random() - 0.5) * radius x = landmark.location.y + 2 * (random.random() - 0.5) * radius coordinatesBuilder = Coordinates(x, y) landmarkBuilder.addParticles(coordinatesBuilder) floorBuilder.addLandmarks(landmarkBuilder) mapBuilder.addFloors(floorBuilder) return mapBuilder
def test_dimensions(self): # Background: see http://trac.gispython.org/lab/ticket/168 # http://lists.gispython.org/pipermail/community/2008-August/001859.html coords = ((0.0, 0.0, 0.0), (0.0, 1.0, 0.0), (1.0, 1.0, 0.0), (1.0, 0.0, 0.0)) polygon = Polygon(coords) assert polygon._ndim == 3 gi = polygon.__geo_interface__ assert gi["coordinates"] == (( (0.0, 0.0, 0.0), (0.0, 1.0, 0.0), (1.0, 1.0, 0.0), (1.0, 0.0, 0.0), (0.0, 0.0, 0.0), ), ) e = polygon.exterior assert e._ndim == 3 gi = e.__geo_interface__ assert gi["coordinates"] == ( (0.0, 0.0, 0.0), (0.0, 1.0, 0.0), (1.0, 1.0, 0.0), (1.0, 0.0, 0.0), (0.0, 0.0, 0.0), )
def test_polygon_from_linearring(): coords = [(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 0.0)] ring = LinearRing(coords) polygon = Polygon(ring) assert polygon.exterior.coords[:] == coords assert len(polygon.interiors) == 0 # from shell and holes linearrings shell = LinearRing([(0.0, 0.0), (70.0, 120.0), (140.0, 0.0), (0.0, 0.0)]) holes = [ LinearRing([(60.0, 80.0), (80.0, 80.0), (70.0, 60.0), (60.0, 80.0)]), LinearRing([(30.0, 10.0), (50.0, 10.0), (40.0, 30.0), (30.0, 10.0)]), LinearRing([(90.0, 10), (110.0, 10.0), (100.0, 30.0), (90.0, 10.0)]), ] polygon = Polygon(shell, holes) assert polygon.exterior.coords[:] == shell.coords[:] assert len(polygon.interiors) == 3 for i in range(3): assert polygon.interiors[i].coords[:] == holes[i].coords[:]
def test_polygon_from_coordinate_sequence_with_holes(): coords = [(0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (0.0, 0.0)] # Interior rings (holes) polygon = Polygon(coords, [((0.25, 0.25), (0.25, 0.5), (0.5, 0.5), (0.5, 0.25))]) assert polygon.exterior.coords[:] == coords assert len(polygon.interiors) == 1 assert len(polygon.interiors[0].coords) == 5 # Multiple interior rings with different length coords = [(0, 0), (0, 10), (10, 10), (10, 0), (0, 0)] holes = [ [(1, 1), (2, 1), (2, 2), (1, 2), (1, 1)], [(3, 3), (3, 4), (4, 5), (5, 4), (5, 3), (3, 3)], ] polygon = Polygon(coords, holes) assert polygon.exterior.coords[:] == coords assert len(polygon.interiors) == 2 assert len(polygon.interiors[0].coords) == 5 assert len(polygon.interiors[1].coords) == 6
def test_polygon_from_numpy(): a = np.array(((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0), (0.0, 0.0))) polygon = Polygon(a) assert len(polygon.exterior.coords) == 5 assert polygon.exterior.coords[:] == [ (0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0), (0.0, 0.0), ] assert len(polygon.interiors) == 0
def test_attribute_chains(self): # Attribute Chaining # See also ticket #151. p = Polygon(((0.0, 0.0), (0.0, 1.0), (-1.0, 1.0), (-1.0, 0.0))) assert list(p.boundary.coords) == [ (0.0, 0.0), (0.0, 1.0), (-1.0, 1.0), (-1.0, 0.0), (0.0, 0.0), ] ec = list(Point(0.0, 0.0).buffer(1.0, 1).exterior.coords) assert isinstance(ec, list) # TODO: this is a poor test # Test chained access to interiors p = Polygon( ((0.0, 0.0), (0.0, 1.0), (-1.0, 1.0), (-1.0, 0.0)), [((-0.25, 0.25), (-0.25, 0.75), (-0.75, 0.75), (-0.75, 0.25))], ) assert p.area == 0.75 """Not so much testing the exact values here, which are the responsibility of the geometry engine (GEOS), but that we can get chain functions and properties using anonymous references. """ assert list(p.interiors[0].coords) == [ (-0.25, 0.25), (-0.25, 0.75), (-0.75, 0.75), (-0.75, 0.25), (-0.25, 0.25), ] xy = list(p.interiors[0].buffer(1).exterior.coords)[0] assert len(xy) == 2 # Test multiple operators, boundary of a buffer ec = list(p.buffer(1).boundary.coords) assert isinstance(ec, list) # TODO: this is a poor test
def test_index_linearring(self): shell = LinearRing([(0.0, 0.0), (70.0, 120.0), (140.0, 0.0), (0.0, 0.0)]) holes = [ LinearRing([(60.0, 80.0), (80.0, 80.0), (70.0, 60.0), (60.0, 80.0)]), LinearRing([(30.0, 10.0), (50.0, 10.0), (40.0, 30.0), (30.0, 10.0)]), LinearRing([(90.0, 10), (110.0, 10.0), (100.0, 30.0), (90.0, 10.0)]), ] g = Polygon(shell, holes) for i in range(-3, 3): assert g.interiors[i].equals(holes[i]) with pytest.raises(IndexError): g.interiors[3] with pytest.raises(IndexError): g.interiors[-4]
def cells(grid_lon, grid_lat, lon, lat, mask=None): """Get grid indexes corresponding to lat/lon points, using shapely polygons. :param grid_lon: grid of corner longitudes ('LONG_C' in geo_em... file) :param grid_lat: grid of corner latitudes ('LAT_C' in geo_em... file) :param lon: array of point longitudes :param lat: array of point latitudes :param mask: 1-0 mask of grid points to be taken into account (e.g. land mask) :returns: tuple(k, i, j) where i, j are the lat, lon (matrix order) index arrays corresponding to index array k in the input lon, lat arrays (in case of masking) """ from shapely.geometry import MultiPoint, Polygon, LinearRing s = np.array(grid_lon.shape) - 1 if mask is None: def ll(i, j): return np.r_[grid_lon[i:i + s[0], j:j + s[1]], grid_lat[i:i + s[0], j:j + s[1]]].reshape((2, -1)).T k = np.r_[ll(0, 0), ll(1, 0), ll(1, 1), ll(0, 1)].reshape((4, -1, 2)).transpose(1, 0, 2) else: def ll(i, j): return np.r_[ grid_lon.isel_points(south_north_stag=i, west_east_stag=j), grid_lat.isel_points(south_north_stag=i, west_east_stag=j )].reshape((2, -1)).T i, j = np.where(mask) k = np.r_[ll(i, j), ll(i + 1, j), ll(i + 1, j + 1), ll(i, j + 1)].reshape((4, -1, 2)).transpose(1, 0, 2) lr = [Polygon(LinearRing(a)) for a in k] mp = MultiPoint(list(zip(lon, lat))) c = [[l for l, r in enumerate(lr) if r.contains(p)] for p in mp] l, c = zip(*[(l, r[0]) for l, r in enumerate(c) if len(r) > 0]) return tuple( np.r_[(l, ), np.unravel_index(c, s)]) if mask is None else (l, i[list(c)], j[list(c)])
def test_slice_linearring(self): shell = LinearRing([(0.0, 0.0), (70.0, 120.0), (140.0, 0.0), (0.0, 0.0)]) holes = [ LinearRing([(60.0, 80.0), (80.0, 80.0), (70.0, 60.0), (60.0, 80.0)]), LinearRing([(30.0, 10.0), (50.0, 10.0), (40.0, 30.0), (30.0, 10.0)]), LinearRing([(90.0, 10), (110.0, 10.0), (100.0, 30.0), (90.0, 10.0)]), ] g = Polygon(shell, holes) t = [a.equals(b) for (a, b) in zip(g.interiors[1:], holes[1:])] assert all(t) t = [a.equals(b) for (a, b) in zip(g.interiors[:-1], holes[:-1])] assert all(t) t = [a.equals(b) for (a, b) in zip(g.interiors[::-1], holes[::-1])] assert all(t) t = [a.equals(b) for (a, b) in zip(g.interiors[::2], holes[::2])] assert all(t) t = [a.equals(b) for (a, b) in zip(g.interiors[:3], holes[:3])] assert all(t) assert g.interiors[3:] == holes[3:] == []
def kml(name, lon, lat, code=None, nc=None): from simplekml import Kml, Style from shapely import Polygon, Point if nc is not None: x = nc.variables['XLONG_M'][0, :, :] y = nc.variables['XLAT_M'][0, :, :] xc = nc.variables['XLONG_C'][0, :, :] yc = nc.variables['XLAT_C'][0, :, :] k = Kml() z = zip(name, lon, lat) if code is None else zip(name, lon, lat, code) for s in z: p = k.newpoint(name=s[3] if len(s) == 4 else s[0], coords=[s[1:3]]) p.style.iconstyle.icon.href = "http://maps.google.com/mapfiles/kml/paddle/red-circle.png" p.style.balloonstyle.text = s[0] if nc is not None: i, j, d = nearest(x, y, s[1], s[2]) coords = [(xc[i, j], yc[i, j]), (xc[i, j + 1], yc[i, j]), (xc[i, j + 1], yc[i + 1, j]), (xc[i, j], yc[i + 1, j]), (xc[i, j], yc[i, j])] if Polygon(coords).contains(Point(*s[1:3])): l = k.newlinestring(coords=[s[1:3], (x[i, j], y[i, j])]) r = k.newlinestring(coords=coords) return k
assert bool(LineString()) is False def test_point(): assert bool(Point()) is False def test_geometry_collection(): assert bool(GeometryCollection()) is False geometries_all_types = [ Point(1, 1), LinearRing([(0, 0), (1, 1), (0, 1), (0, 0)]), LineString([(0, 0), (1, 1), (0, 1), (0, 0)]), Polygon([(0, 0), (1, 1), (0, 1), (0, 0)]), MultiPoint([(1, 1)]), MultiLineString([[(0, 0), (1, 1), (0, 1), (0, 0)]]), MultiPolygon([Polygon([(0, 0), (1, 1), (0, 1), (0, 0)])]), GeometryCollection([Point(1, 1)]), ] @pytest.mark.parametrize("geom", geometries_all_types) def test_setattr_disallowed(geom): with pytest.raises(AttributeError): geom.name = "test" @pytest.mark.parametrize("geom", geometries_all_types) def test_comparison_notimplemented(geom):
def test_empty_polygon(self): assert Polygon().is_empty assert Polygon(None).is_empty assert Polygon([]).is_empty assert Polygon(empty_generator()).is_empty
def test_index_linearring_misc(self): g = Polygon() # empty with pytest.raises(IndexError): g.interiors[0] with pytest.raises(TypeError): g.interiors[0.0]
def test_empty_polygon_exterior(self): p = Polygon() assert p.exterior == LinearRing()
def test_from_bounds(self): xmin, ymin, xmax, ymax = -180, -90, 180, 90 coords = [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)] assert Polygon(coords) == Polygon.from_bounds(xmin, ymin, xmax, ymax)
def test_numpy_object_array(): geoms = [Point(), GeometryCollection()] arr = np.empty(2, object) arr[:] = geoms def test_shape_empty(): empty_mp = MultiPolygon() empty_json = mapping(empty_mp) empty_shape = shape(empty_json) assert empty_shape.is_empty @pytest.mark.parametrize( "geom", [ Point(), LineString(), Polygon(), MultiPoint(), MultiLineString(), MultiPolygon(), GeometryCollection(), LinearRing(), ], ) def test_empty_geometry_bounds(geom): """The bounds of an empty geometry is a tuple of NaNs""" assert len(geom.bounds) == 4 assert all(math.isnan(v) for v in geom.bounds)
def test_multipolygon(self): # From coordinate tuples coords = [ ( ((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0)), [((0.25, 0.25), (0.25, 0.5), (0.5, 0.5), (0.5, 0.25))], ) ] geom = MultiPolygon(coords) assert isinstance(geom, MultiPolygon) assert len(geom.geoms) == 1 assert dump_coords(geom) == [ [ (0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0), (0.0, 0.0), [(0.25, 0.25), (0.25, 0.5), (0.5, 0.5), (0.5, 0.25), (0.25, 0.25)], ] ] # Or from polygons p = Polygon( ((0, 0), (0, 1), (1, 1), (1, 0)), [((0.25, 0.25), (0.25, 0.5), (0.5, 0.5), (0.5, 0.25))], ) geom = MultiPolygon([p]) assert len(geom.geoms) == 1 assert dump_coords(geom) == [ [ (0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0), (0.0, 0.0), [(0.25, 0.25), (0.25, 0.5), (0.5, 0.5), (0.5, 0.25), (0.25, 0.25)], ] ] # Or from another multi-polygon geom2 = MultiPolygon(geom) assert len(geom2.geoms) == 1 assert dump_coords(geom2) == [ [ (0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0), (0.0, 0.0), [(0.25, 0.25), (0.25, 0.5), (0.5, 0.5), (0.5, 0.25), (0.25, 0.25)], ] ] # Sub-geometry Access assert isinstance(geom.geoms[0], Polygon) assert dump_coords(geom.geoms[0]) == [ (0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0), (0.0, 0.0), [(0.25, 0.25), (0.25, 0.5), (0.5, 0.5), (0.5, 0.25), (0.25, 0.25)], ] with pytest.raises(IndexError): # index out of range geom.geoms[1] # Geo interface assert geom.__geo_interface__ == { "type": "MultiPolygon", "coordinates": [ ( ((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0), (0.0, 0.0)), ((0.25, 0.25), (0.25, 0.5), (0.5, 0.5), (0.5, 0.25), (0.25, 0.25)), ) ], }
def test_subgeom_access(self): poly0 = Polygon([(0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0)]) poly1 = Polygon([(0.25, 0.25), (0.25, 0.5), (0.5, 0.5), (0.5, 0.25)]) self.subgeom_access_test(MultiPolygon, [poly0, poly1])
def test_polygon(): assert bool(Polygon()) is False
def test_numpy_object_array(): geom = Polygon([(0.0, 0.0), (0.0, 1.0), (1.0, 1.0)]) ar = np.empty(1, object) ar[:] = [geom] assert ar[0] == geom
def test_polygon_from_invalid(): # Error handling with pytest.raises(ValueError): # A LinearRing must have at least 3 coordinate tuples Polygon([[1, 2], [2, 3]])