def gp2cellids(grid, gp, idomain, idomain_active=True, type="polygon", layer=0, areas=3): """ this function extract the cellids of the intersection between a geopandas object and a grid """ ix = GridIntersect(grid) if type == "polygon": result = ix.intersect_polygon(gp.geometry[0]) result = result[result.areas > ( np.max(result.areas) / 3 )] # only take into account cells that have a least 1/3 intersected by the polygon if type == "boundary": result = ix.intersect_linestring(gp.geometry[0].boundary) if type == "line": result = ix.intersect_linestring(gp.geometry[0]) lst = [] for irow, icol in result.cellids: lst.append(((layer, irow, icol))) if idomain_active: idomain[irow * grid.ncol + icol] = 1 return lst
def import_riv(grid,gp): """ This function extract infos about a river (geopandas object, LINESTRING),cellids + lengths of in each cells in the right order. Format : import_riv (Grid (from the gwf model, gwf.modelgrid for ex.), gp (a geopandas object containing a unique Linestring)) Return a dataframe containing these datas, post-processing necessary to remove cells that are already counted as BC in the model """ ix = GridIntersect(grid) coord_riv=[] for x,y in zip(gp.geometry[0].xy[0],gp.geometry[0].xy[1]): coord_riv.append((x,y)) verti=[] df_tot_ord = pd.DataFrame() # empty DF for i in range(len(coord_riv)): if i < len(coord_riv)-1: lsi = LineString([coord_riv[i],coord_riv[i+1]]) # create the linestring btw point i and i+1 res = ix.intersect_linestring(lsi) # do the intersection cellids = res.cellids # extract cellids if len(cellids)>1: # if more than one cells is intersected --> we need to order them dirx = coord_riv[i+1][0]-coord_riv[i][0] # Xdirection of the linestring for x,y in res.vertices: # extract the 1st vertice of the intersections in order to organize verti.append(x) vertix = np.array(verti)[:,0] df = pd.DataFrame({"cellids":cellids,"vertix":vertix,"lengths":res.lengths}) # create a DF to order verti=[] #organize the cells given the direction if dirx > 0: df.sort_values(by=["vertix"],ascending=True,inplace=True) if dirx < 0: df.sort_values(by=["vertix"],ascending=False,inplace=True) # append these data in a big DF df_tot_ord = df_tot_ord.append(df).drop(["vertix"],axis=1) else : # if only one cell is intersected by the linestring df_tot_ord = df_tot_ord.append(pd.DataFrame({"cellids":cellids,"lengths":res.lengths})) df_riv = df_tot_ord.groupby(["cellids"],sort=False).sum() # retrieve data lst_len_Riv = df_riv["lengths"].values cellids_Riv=[]; # list of all the cells intersected by the river cellids = df_riv.index for irow,icol in cellids: cell = (0,irow,icol) if cell not in cellids_Riv: cellids_Riv.append(cell) df_riv = pd.DataFrame({"cellids":cellids_Riv,"lengths":lst_len_Riv}) return df_riv
def test_rect_grid_linestring_outside_shapely(): # avoid test fail when shapely not available try: import shapely except: return gr = get_rect_grid() ix = GridIntersect(gr) result = ix.intersect_linestring(LineString([(25., 25.), (21., 5.)])) assert len(result) == 0 return result
def test_linestring_offset_rot_structured_grid(): # avoid test fail when shapely not available try: import shapely except: return sgr = get_rect_grid(angrot=45., xyoffset=10.) ls = LineString([(5, 10. + np.sqrt(200.)), (15, 10. + np.sqrt(200.))]) ix = GridIntersect(sgr, method="structured") result = ix.intersect_linestring(ls) # assert len(result) == 2. return result
def gp2cellids(grid, gp, idomain, idomain_active=True, type="polygon", layer=0, areas=3): """ this function extract the cellids of the intersection between a geopandas object and a grid grid : modelgrid gp : geopandas object (polygon, linestring only) idomain : the idomain array to update it idomain_active : bool, if true the idomain is update (cells intersect by the gp will be noted as active), prevents some issues type : str, features type (polygon or line) layer : int, the layer on which is the gp areas : factor that determine if a cell is accounted intersected or not based on the total area intersected in this cell (a value of 3, for example, mean only cells which have 1/3 of their area intersected by the polygon will be taken into account) """ ix = GridIntersect(grid) if type == "polygon": result = ix.intersect_polygon(gp.geometry[0]) result = result[result.areas > ( np.max(result.areas) / 3 )] # only take into account cells that have a least 1/3 intersected result = result[result.areas != 0] # fix bug if type == "boundary": result = ix.intersect_linestring(gp.geometry[0].boundary) if type == "line": result = ix.intersect_linestring(gp.geometry[0]) lst = [] for irow, icol in result.cellids: lst.append(((layer, irow, icol))) if idomain_active: idomain[irow * grid.ncol + icol] = 1 return lst
def test_tri_grid_linestring_outside(): # avoid test fail when shapely not available try: import shapely except: return gr = get_tri_grid(triangle_exe=triangle_exe) if gr == -1: return ix = GridIntersect(gr) result = ix.intersect_linestring(LineString([(25., 25.), (21., 5.)])) assert len(result) == 0 return result
def test_rect_grid_linestring_on_inner_boundary_shapely(): # avoid test fail when shapely not available try: import shapely except: return gr = get_rect_grid() ix = GridIntersect(gr) result = ix.intersect_linestring(LineString([(5., 10.), (15., 10.)])) assert len(result) == 2 assert result.lengths.sum() == 10. assert result.cellids[0] == (0, 0) assert result.cellids[1] == (0, 1) return result
def test_rect_grid_linestring_in_2cells(): # avoid test fail when shapely not available try: import shapely except: return gr = get_rect_grid() ix = GridIntersect(gr, method="structured") result = ix.intersect_linestring(LineString([(5., 5.), (15., 5.)])) assert len(result) == 2 assert result.lengths.sum() == 10. assert result.cellids[0] == (1, 0) assert result.cellids[1] == (1, 1) return result
def test_rect_grid_linestring_in_and_out_of_cell_shapely(): # avoid test fail when shapely not available try: import shapely except: return gr = get_rect_grid() ix = GridIntersect(gr) result = ix.intersect_linestring(LineString([(5., 9), (15., 5.), (5., 1.)])) assert len(result) == 2 assert result.cellids[0] == (1, 0) assert result.cellids[1] == (1, 1) assert np.allclose(result.lengths.sum(), 21.540659228538015) return result
def test_tri_grid_linestring_on_inner_boundary(): # avoid test fail when shapely not available try: import shapely except: return gr = get_tri_grid(triangle_exe=triangle_exe) if gr == -1: return ix = GridIntersect(gr) result = ix.intersect_linestring(LineString([(5., 10.), (15., 10.)])) assert len(result) == 2 assert result.lengths.sum() == 10. assert result.cellids[0] == 0 assert result.cellids[1] == 1 return result
def test_tri_grid_linestring_on_outer_boundary(rtree=True): # avoid test fail when shapely not available try: import shapely except: return gr = get_tri_grid() if gr == -1: return ix = GridIntersect(gr, rtree=rtree) result = ix.intersect_linestring(LineString([(15., 20.), (5., 20.)])) assert len(result) == 2 assert result.lengths.sum() == 10. assert result.cellids[0] == 2 assert result.cellids[1] == 7 return result
def test_rect_grid_multilinestring_in_one_cell_shapely(): # avoid test fail when shapely not available try: import shapely except: return gr = get_rect_grid() ix = GridIntersect(gr) result = ix.intersect_linestring( MultiLineString([ LineString([(1., 1), (9., 1.)]), LineString([(1., 9.), (9., 9.)]) ])) assert len(result) == 1 assert result.lengths == 16. assert result.cellids[0] == (1, 0) return result
def test_tri_grid_multilinestring_in_one_cell(): # avoid test fail when shapely not available try: import shapely except: return gr = get_tri_grid(triangle_exe=triangle_exe) if gr == -1: return ix = GridIntersect(gr) result = ix.intersect_linestring( MultiLineString([ LineString([(1., 1), (9., 1.)]), LineString([(2., 2.), (9., 2.)]) ])) assert len(result) == 1 assert result.lengths == 15. assert result.cellids[0] == 4 return result