def testS2PolylineRegion(self): polyline = s2.S2Polyline() polyline.InitFromS2LatLngs([ s2.S2LatLng.FromDegrees(0.0, 0.0), s2.S2LatLng.FromDegrees(1.0, 1.0) ]) # Contains(S2Point) always return false. self.assertFalse( polyline.Contains(s2.S2LatLng.FromDegrees(0.0, 0.0).ToPoint())) self.assertFalse( polyline.Contains(s2.S2Cell(s2.S2LatLng.FromDegrees(0.0, 0.0)))) self.assertTrue( polyline.MayIntersect(s2.S2Cell(s2.S2LatLng.FromDegrees(0.0, 0.0)))) self.assertFalse( polyline.MayIntersect(s2.S2Cell(s2.S2LatLng.FromDegrees(3.0, 4.0)))) cap_bound = polyline.GetCapBound() self.assertTrue( cap_bound.Contains(s2.S2LatLng.FromDegrees(0.0, 0.0).ToPoint())) self.assertFalse( cap_bound.Contains(s2.S2LatLng.FromDegrees(2.0, 2.0).ToPoint())) rect_bound = polyline.GetRectBound() self.assertTrue( rect_bound.Contains(s2.S2LatLng.FromDegrees(0.0, 0.0).ToPoint())) self.assertFalse( rect_bound.Contains(s2.S2LatLng.FromDegrees(2.0, 2.0).ToPoint()))
def testCovererIsWrappedCorrectly(self): london = s2.S2LatLngRect(s2.S2LatLng.FromDegrees(51.3368602, 0.4931979), s2.S2LatLng.FromDegrees(51.7323965, 0.1495211)) e14lj = s2.S2LatLngRect(s2.S2LatLng.FromDegrees(51.5213527, -0.0476026), s2.S2LatLng.FromDegrees(51.5213527, -0.0476026)) coverer = s2.S2RegionCoverer() coverer.set_max_cells(6) self.assertEqual(6, coverer.max_cells()) covering = coverer.GetCovering(e14lj) self.assertLessEqual(len(covering), 6) for cellid in covering: self.assertTrue(london.Contains(s2.S2Cell(cellid))) interior = coverer.GetInteriorCovering(e14lj) for cellid in interior: self.assertTrue(london.Contains(s2.S2Cell(cellid)))
def create_s2_geom_cells(extent, resolutions): # Create s2 rectangle to fill with s2 cells region_rect = s2.S2LatLngRect( s2.S2LatLng.FromDegrees(extent.bounds[1], extent.bounds[0]), s2.S2LatLng.FromDegrees(extent.bounds[3], extent.bounds[2])) coverer = s2.S2RegionCoverer() # Projection for cell area calculation transformer = Transformer.from_crs("epsg:4326", 'proj=isea') # Iterate through given resolutions, create and populate geopandas for each for r in resolutions: coverer.min_level = r coverer.max_level = r covering = coverer.GetCovering(region_rect) geoms = gpd.GeoDataFrame() geoms['cell_id'] = None geoms['area'] = None geoms['geometry'] = None for cellid in covering: new_cell = s2.S2Cell(cellid) vertices = [] for i in range(0, 4): vertex = new_cell.GetS2LatLngVertex(i) vertices.append((vertex.lng().degrees, vertex.lat().degrees)) geom = Polygon(vertices) geoms.loc[len(geoms)] = [cellid.get, transform(transformer.transform, geom).area, geom] geoms.to_file("s2_level{}.geojson".format(r), driver='GeoJSON')
def testS2PolygonIntersectsWithPolyline(self): london = s2.S2LatLng.FromDegrees(51.5001525, -0.1262355) polygon = s2.S2Polygon(s2.S2Cell(s2.S2CellId(london).parent(15))) line = s2.S2Polyline() line.InitFromS2LatLngs([s2.S2LatLng.FromDegrees(51.5, -0.128), s2.S2LatLng.FromDegrees(51.5, -0.125)]) intersections = polygon.IntersectWithPolyline(line) self.assertEqual(1, len(intersections))
def s2_geometry_from_cellid(cell_id): new_cell = s2.S2Cell(s2.S2CellId.FromToken(cell_id,len(cell_id))) vertices = [] for i in range(0, 4): vertex = new_cell.GetS2LatLngVertex(i) vertices.append((vertex.lng().degrees(), vertex.lat().degrees())) geom = Polygon(vertices) return geom
def testS2CapRegion(self): center = s2.S2LatLng.FromDegrees(2.0, 3.0).ToPoint() cap = s2.S2Cap(center, s2.S1Angle.Degrees(1.0)) inside = s2.S2LatLng.FromDegrees(2.1, 2.9).ToPoint() outside = s2.S2LatLng.FromDegrees(0.0, 0.0).ToPoint() self.assertTrue(cap.Contains(inside)) self.assertFalse(cap.Contains(outside)) self.assertTrue(cap.Contains(s2.S2Cell(inside))) self.assertFalse(cap.Contains(s2.S2Cell(outside))) self.assertTrue(cap.MayIntersect(s2.S2Cell(inside))) self.assertFalse(cap.MayIntersect(s2.S2Cell(outside))) self.assertTrue(cap.ApproxEquals(cap.GetCapBound())) rect_bound = cap.GetRectBound() self.assertTrue(rect_bound.Contains(inside)) self.assertFalse(rect_bound.Contains(outside))
def testGetS2LatLngVertexIsWrappedCorrectly(self): london = s2.S2LatLng.FromDegrees(51.5001525, -0.1262355) polygon = s2.S2Polygon(s2.S2Cell(s2.S2CellId(london))) loop = polygon.loop(0) first_vertex = loop.GetS2LatLngVertex(0) self.assertIsInstance(first_vertex, s2.S2LatLng) self.assertEqual("51.500152,-0.126235", first_vertex.ToStringInDegrees()) second_vertex = loop.GetS2LatLngVertex(1) self.assertIsInstance(second_vertex, s2.S2LatLng) self.assertEqual("51.500153,-0.126235", second_vertex.ToStringInDegrees())
def testS2LatLngRectRegion(self): rect = s2.S2LatLngRect(s2.S2LatLng.FromDegrees(1.0, 2.0), s2.S2LatLng.FromDegrees(3.0, 4.0)) inside = s2.S2LatLng.FromDegrees(2.0, 3.0).ToPoint() outside = s2.S2LatLng.FromDegrees(0.0, 0.0).ToPoint() self.assertTrue(rect.Contains(inside)) self.assertFalse(rect.Contains(outside)) self.assertTrue(rect.Contains(s2.S2Cell(inside))) self.assertFalse(rect.Contains(s2.S2Cell(outside))) self.assertTrue(rect.MayIntersect(s2.S2Cell(inside))) self.assertFalse(rect.MayIntersect(s2.S2Cell(outside))) cap_bound = rect.GetCapBound() self.assertTrue(cap_bound.Contains(inside)) self.assertFalse(cap_bound.Contains(outside)) self.assertTrue(rect.ApproxEquals(rect.GetRectBound()))
def testS2LoopIsWrappedCorrectly(self): london = s2.S2LatLng.FromDegrees(51.5001525, -0.1262355) polygon = s2.S2Polygon(s2.S2Cell(s2.S2CellId(london))) loop = polygon.loop(0) self.assertTrue(loop.IsValid()) self.assertEqual(0, loop.depth()) self.assertFalse(loop.is_hole()) self.assertEqual(4, loop.num_vertices()) point = london.ToPoint() self.assertTrue(loop.Contains(point))
def testS2PolygonGetAreaIsWrappedCorrectly(self): # Cell at level 10 containing central London. london_level_10 = s2.S2CellId( s2.S2LatLng.FromDegrees(51.5001525, -0.1262355)).parent(10) polygon = s2.S2Polygon(s2.S2Cell(london_level_10)) # Because S2Cell.ExactArea() isn't swigged, compare S2Polygon.GetArea() with # S2CellUnion.ExactArea(). cell_union = s2.S2CellUnion() cell_union.Init([london_level_10.id()]) self.assertAlmostEqual(cell_union.ExactArea(), polygon.GetArea(), places=10)
def testS2CellRegion(self): cell = s2.S2Cell(s2.S2CellId(s2.S2LatLng.FromDegrees(3.0, 4.0)).parent(8)) inside = s2.S2LatLng.FromDegrees(3.0, 4.0).ToPoint() outside = s2.S2LatLng.FromDegrees(30.0, 40.0).ToPoint() self.assertTrue(cell.Contains(inside)) self.assertFalse(cell.Contains(outside)) self.assertTrue(cell.Contains(s2.S2Cell(inside))) self.assertFalse(cell.Contains(s2.S2Cell(outside))) self.assertTrue(cell.MayIntersect(s2.S2Cell(inside))) self.assertFalse(cell.MayIntersect(s2.S2Cell(outside))) cap_bound = cell.GetCapBound() self.assertTrue(cap_bound.Contains(inside)) self.assertFalse(cap_bound.Contains(outside)) rect_bound = cell.GetRectBound() self.assertTrue(rect_bound.Contains(inside)) self.assertFalse(rect_bound.Contains(outside))
def get_vertices(self): cellid = int(self.cellid, base=16) cell = s2.S2Cell(s2.S2CellId(cellid)) loop = s2.S2Loop(cell) v0 = loop.GetS2LatLngVertex(0) v0 = [v0.lat().degrees(), v0.lng().degrees()] v1 = loop.GetS2LatLngVertex(1) v1 = [v1.lat().degrees(), v1.lng().degrees()] v2 = loop.GetS2LatLngVertex(2) v2 = [v2.lat().degrees(), v2.lng().degrees()] v3 = loop.GetS2LatLngVertex(3) v3 = [v3.lat().degrees(), v3.lng().degrees()] return [v0, v1, v2, v3]
def testS2CellUnionRegion(self): cell_id = s2.S2CellId(s2.S2LatLng.FromDegrees(3.0, 4.0)).parent(8) cell_union = s2.S2CellUnion() cell_union.Init([cell_id.id()]) inside = s2.S2LatLng.FromDegrees(3.0, 4.0).ToPoint() outside = s2.S2LatLng.FromDegrees(30.0, 40.0).ToPoint() self.assertTrue(cell_union.Contains(inside)) self.assertFalse(cell_union.Contains(outside)) self.assertTrue(cell_union.Contains(s2.S2Cell(inside))) self.assertFalse(cell_union.Contains(s2.S2Cell(outside))) self.assertTrue(cell_union.MayIntersect(s2.S2Cell(inside))) self.assertFalse(cell_union.MayIntersect(s2.S2Cell(outside))) cap_bound = cell_union.GetCapBound() self.assertTrue(cap_bound.Contains(inside)) self.assertFalse(cap_bound.Contains(outside)) rect_bound = cell_union.GetRectBound() self.assertTrue(rect_bound.Contains(inside)) self.assertFalse(rect_bound.Contains(outside))
def testEncodeDecode(self): london = s2.S2LatLng.FromDegrees(51.5001525, -0.1262355) polygon = s2.S2Polygon(s2.S2Cell(s2.S2CellId(london).parent(15))) self.assertEqual(polygon.num_loops(), 1) encoder = s2.Encoder() polygon.Encode(encoder) encoded = encoder.buffer() decoder = s2.Decoder(encoded) decoded_polygon = s2.S2Polygon() self.assertTrue(decoded_polygon.Decode(decoder)) self.assertEqual(decoded_polygon.num_loops(), 1) self.assertTrue(decoded_polygon.Equals(polygon))
def testS2CellDistance(self): # Level-0 cell (i.e. face) centered at (0, 0) cell = s2.S2Cell(s2.S2CellId(0x1000000000000000)) p1 = s2.S2LatLng.FromDegrees(0, 0).ToPoint() self.assertTrue(cell.Contains(p1)) d1 = cell.GetDistance(p1).ToAngle().degrees() # Inside, so distance is 0, but boundary distance is not. self.assertEqual(0.0, d1) bd1 = cell.GetBoundaryDistance(p1).ToAngle().degrees() self.assertEqual(45.0, bd1) p2 = s2.S2LatLng.FromDegrees(0, 90).ToPoint() self.assertFalse(cell.Contains(p2)) d2 = cell.GetDistance(p2).ToAngle().degrees() self.assertAlmostEqual(45.0, d2) bd2 = cell.GetBoundaryDistance(p2).ToAngle().degrees() # Outside, so distance and boundary distance are the same. self.assertAlmostEqual(45.0, bd2)
def testS2PolygonInitNestedWithIncorrectTypeIsWrappedCorrectly(self): london = s2.S2LatLng.FromDegrees(51.5001525, -0.1262355) loop = s2.S2Loop(s2.S2Cell(s2.S2CellId(london))) polygon = s2.S2Polygon() with self.assertRaises(TypeError): polygon.InitNested([loop, s2.S2CellId()])
def testS2PolygonInitNestedIsWrappedCorrectly(self): london = s2.S2LatLng.FromDegrees(51.5001525, -0.1262355) small_loop = s2.S2Loop(s2.S2Cell(s2.S2CellId(london))) big_loop = s2.S2Loop(s2.S2Cell(s2.S2CellId(london).parent(1))) polygon = s2.S2Polygon() polygon.InitNested([big_loop, small_loop])
def testS2PolygonCopiesLoopInConstructorBecauseItTakesOwnership(self): london = s2.S2LatLng.FromDegrees(51.5001525, -0.1262355) loop = s2.S2Loop(s2.S2Cell(s2.S2CellId(london))) s2.S2Polygon(loop)
def testS2PolygonIsWrappedCorrectly(self): london = s2.S2LatLng.FromDegrees(51.5001525, -0.1262355) polygon = s2.S2Polygon(s2.S2Cell(s2.S2CellId(london))) self.assertEqual(polygon.num_loops(), 1) point = london.ToPoint() self.assertTrue(polygon.Contains(point))
def raster_to_s2(raster_path, value_name, cell_min_res, cell_max_res, extent=None, pix_size_factor=3): """Load raster values into s2 dggs cells Parameters: raster (string): path to raster file for uploading value_name (string): name of a value to be uploaded cell_min_res (integer): min h3 resolution to look for based on raster cell size cell_max_res (integer): max h3 resolution to look for based on raster cell size extent (list): Extent as array of 2 lon lat pairs to get raster values for pix_size_factor (pinteger): how times smaller h3 hex size should be comparing with raster cell size Returns: Pandas dataframe """ # Open raster rs = rasterio.open(raster_path) # Get extent to fill with s2 squares if extent: region_rect = s2.S2LatLngRect( s2.S2LatLng_FromDegrees(extent[1], extent[0]), s2.S2LatLng_FromDegrees(extent[3], extent[2])) else: region_rect = s2.S2LatLngRect( s2.S2LatLng_FromDegrees(rs.bounds.bottom, rs.bounds.left), s2.S2LatLng_FromDegrees(rs.bounds.top, rs.bounds.right)) # Get resolution dict resolutions = {} coverer = s2.S2RegionCoverer() # transformer = Transformer.from_crs("epsg:4326", 'proj=isea') for i in range(cell_min_res, cell_max_res, 1): # get s2 cell at level i coverer.set_fixed_level(i) cell = s2.S2Cell(coverer.GetCovering(region_rect)[0]) # get s2 edge size at resolution i p1 = cell.GetS2LatLngVertex(0) p2 = cell.GetS2LatLngVertex(1) # edge = Point(transformer.transform(p2.lat().degrees(), p2.lng().degrees())).distance(Point(transformer.transform(p1.lat().degrees(), p2.lng().degrees()))) edge = __haversine(p2.lat().degrees(), p2.lng().degrees(), p1.lat().degrees(), p2.lng().degrees()) resolutions[i] = edge # Get two neighbour pixels in raster x1 = rs.transform[2] y1 = rs.transform[5] x2 = rs.transform[2] + rs.transform[0] y2 = rs.transform[5] - rs.transform[4] # Get pixel size from projected src size = __haversine(x1, y1, x1, y2) print(f"Raster pixel size {size}") # Get raster band as np array raster_band_array = rs.read(1) # Get h3 resolution for raster pixel size for key, value in resolutions.items(): print(value) if value < size / pix_size_factor: resolution = key break print(resolution) coverer.set_fixed_level(resolution) # Create dataframe with cell_ids from cover with given resolution print(f"Start filling raster extent with s2 indexes at resolution {resolution}") df = pd.DataFrame({'cell_id': [x.ToToken() for x in coverer.GetCovering(region_rect)]}) # Get raster values for each hex_id print(f"Start getting raster values for s2 cells at resolution {resolution}") df[value_name] = df['cell_id'].apply(lambda x: raster_band_array[ rs.index(s2.S2CellId.FromToken(x,len(x)).ToLatLng().lng().degrees(), s2.S2CellId.FromToken(x,len(x)).ToLatLng().lat().degrees())]) # Drop nodata df = df[df[value_name] != rs.nodata] return df