Python与GIS

Python矢量与栅格数据处理

原创 孟祥帅 祥帅的小屋 2022-10-21 18:55 发表于山东

持续更新ing,欢迎各位点赞关注哦!

Python与GIS_第1张图片

1. Python处理栅格影像

1.1 读取tif

import rasteriofrom rasterio.plot import showfrom matplotlib import colors, cmrs = rasterio.open(r'C:\Users\lenovo\Desktop\pzh_map_dispose\sf1.tif','r')result1=rs.read()

1.2 替换Nodata数据

#满足条件,则替换,否则保持原样result=np.where(result1==result1.min(),np.nan,result1)result# np.unique(rss[0])

out:

array([[[nan, nan, nan, ..., nan, nan, nan],

[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan],
...,
[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan]]])

1.2 显示TIF

import geopandas as gpdshp = gpd.read_file(r"C:\Users\lenovo\Desktop\pzh_map_dispose\pzh_city.shp")fig, ax = plt.subplots(figsize=(5,9))shp.plot(ax=ax,color='none')show(result, transform=rs_mask.transform,ax=ax, cmap='gist_earth')fig.colorbar(cm.ScalarMappable(norm=colors.Normalize(vmin=np.nanmin(result), vmax=np.nanmax(result)), cmap='gist_earth')             , ax=ax,extend='both',fraction=0.05)

Python与GIS_第2张图片

2. 从头开始的一个例子——完整版

2.1 创建shp面,并写入文件

import osimport geopandasfrom shapely import geometryimport matplotlib.pyplot as pltx1,y1=30,30  x2,y2=50,50# 对应shapely.geometry中的Polygon,用于表示面,下面我们创建一个由若干Polygon对象组成cq = geopandas.GeoSeries([geometry.Polygon([(x1,y1), (x2,y1), (x2,y2), (x1,y2)]),                          geometry.Polygon([(x2,y1),(55,40), (x2,y2)])                          ],                         index=['1', '2'],  # 构建一个索引字段                         crs='EPSG:4326',  # 坐标系是:WGS 1984                         )cq.to_file(r'simple_poly.shp',           driver='ESRI Shapefile',           encoding='utf-8')cq

2.2 使用geopandas读取

gdf=geopandas.read_file(r'simple_poly.shp')gdf
gdf.plot(column='index')

Python与GIS_第3张图片

2.3 面转为栅格——根据字段转栅格

# 矢量数据转栅格:不需要模板def shpToRaster2(shp_path,raster_path,cellsize,field):    '''    矢量数据转栅格:不需要模板    :param shp_path:需要转换的矢量数据    :param raster_path:输出后栅格保存路径    :param cellsize:栅格大小    :param field:作为栅格值得矢量数据字段    :return:    '''    shp = ogr.Open(shp_path)    m_layer = shp.GetLayer()    extent = m_layer.GetExtent()    
    Xmin = extent[0]    
    Xmax = extent[1]    
    Ymin = extent[2]    
    Ymax = extent[3]  
    rows = int((Ymax - Ymin)/cellsize);    
    cols = int((Xmax - Xmin) / cellsize);    
    GeoTransform = [Xmin,cellsize,0,Ymax,0,-cellsize]    
    target_ds = gdal.GetDriverByName('GTiff').Create(raster_path, xsize=cols, ysize=rows, bands=1, eType=gdal.GDT_Float32) 
    target_ds.SetGeoTransform(GeoTransform)        target_ds.SetProjection(str(pro)) # 获取投影必须转为字符串    
    band = target_ds.GetRasterBand(1)
    pro = m_layer.GetSpatialRef()

    band.SetNoDataValue(-999)    
    band.FlushCache()
    # target_ds.SetProjection('GEOGCS["GCS_China_Geodetic_Coordinate_System_2000",DATUM["China_2000",SPHEROID["CGCS2000",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST]]')    gdal.RasterizeLayer(target_ds, [1], m_layer, options=["ATTRIBUTE=%s"%field,'ALL_TOUCHED=TRUE'])  # 跟shp字段给栅格像元赋值    
    del target_ds
    shp.Release()
    vector_fn=r'simple_poly.shp'
    raster_fn=r'two_region.tif'
    shpToRaster2(vector_fn,raster_fn,cellsize=0.5,field='index')

2.4 显示栅格影像
def showraster(inputtif):    import rasterio    from rasterio.plot import show    from matplotlib import colors, cm    rs =rasterio.open(inputtif)       rss=rs.read()    #满足条件,则替换,否则保持原样    result=np.where(rss==rss.min(),np.nan,rss)    fig, ax = plt.subplots(figsize=(4,4))    show(result, transform=rs.transform,ax=ax, cmap='cool')    from mpl_toolkits.axes_grid1 import make_axes_locatable    divider = make_axes_locatable(ax)    cax = divider.append_axes("right", size="3%", pad=0.1)    # world.plot(column='pop_est', ax=ax, legend=True, cax=cax)    fig.colorbar(cm.ScalarMappable(norm=colors.Normalize(vmin=np.nanmin(result), vmax=np.nanmax(result)), cmap='cool')                 , ax=ax,extend='both',fraction=0.010,cax=cax)    return fig,ax
showraster(r'two_region.tif')

Python与GIS_第4张图片

2.5 创建一个掩膜形状

import osimport geopandasfrom shapely import geometryimport matplotlib.pyplot as plt# 对应shapely.geometry中的Polygon,用于表示面,下面我们创建一个由若干Polygon对象组成cq = geopandas.GeoSeries(geometry.Polygon([(47,35),(53,35),(54,48),(45,45)]),                         index=['1'],  # 构建一个索引字段                         crs='EPSG:4326',  # 坐标系是:WGS 1984                         )cq.to_file(r'simple_mask.shp',           driver='ESRI Shapefile',           encoding='utf-8')gdf=geopandas.read_file(r'simple_mask.shp')gdf.plot()

Python与GIS_第5张图片

2.6 同时显示​​​​​​​

def showraster2(inputtif,inputshp):    import rasterio    from rasterio.plot import show    from matplotlib import colors, cm    rs =rasterio.open(inputtif)       rss=rs.read()    #满足条件,则替换,否则保持原样    result=np.where(rss==rss.min(),np.nan,rss)    shp = gpd.read_file(inputshp)    fig, ax = plt.subplots(figsize=(4,4))    shp.plot(ax=ax,color='none')    show(result, transform=rs.transform,ax=ax, cmap='cool')    from mpl_toolkits.axes_grid1 import make_axes_locatable    divider = make_axes_locatable(ax)    cax = divider.append_axes("right", size="3%", pad=0.1)    # world.plot(column='pop_est', ax=ax, legend=True, cax=cax)    
    fig.colorbar(cm.ScalarMappable(norm=colors.Normalize(vmin=np.nanmin(result), vmax=np.nanmax(result)), cmap='cool', ax=ax,extend='both',fraction=0.010,cax=cax))                ​​​​​​​

Python与GIS_第6张图片

2.7 掩膜提取

# 利用上面的掩膜提取栅格def shp_mask(inputtif,inputshp,outtif):    import fiona    import rasterio    import rasterio.mask    rs = rasterio.open(inputtif,'r')    with fiona.open(inputshp, "r") as shapefile:        shapes = [feature["geometry"] for feature in shapefile]    out_image, out_transform = rasterio.mask.mask(rs,shapes,crop=True)    out_meta = rs.meta    out_meta.update({"driver": "GTiff",                     "height": out_image.shape[1],                     "width": out_image.shape[2],                     "transform": out_transform})    with rasterio.open(outtif, "w", **out_meta) as dest:        dest.write(out_image)​​​​​​​inputtif=r'two_region.tif'inputshp=r'simple_mask.shp'outtif=r'tif_mask.tif'shp_mask(inputtif,inputshp,outtif

2.8 结果显示

showraster2(r'tif_mask.tif',r'simple_mask.shp')

Python与GIS_第7张图片

3  根据点提取栅格数据

3.1 第一种方法

import geopandasimport rasterioimport matplotlib.pyplot as pltfrom shapely.geometry import Point# Create sampling pointspoints = [Point(101.4, 27.0), Point(101.6,26.6), Point(101.6,26.8), Point(102.0,27)]gdf = geopandas.GeoDataFrame([1, 2, 3, 4], geometry=points, crs=4326)src = rasterio.open(r'C:\Users\lenovo\Desktop\pzh_map_dispose\sf1.tif','r')result1=src.read()#满足条件,则替换,否则保持原样result=np.where(result1==result1.min(),np.nan,result1)result# np.unique(rss[0])from rasterio.plot import showfrom matplotlib import colors, cmfig, ax = plt.subplots()# # transform rasterio plot to real world coords# extent=[src.bounds[0], src.bounds[2], src.bounds[1], src.bounds[3]]ax = rasterio.plot.show(src,ax=ax, cmap='gist_earth')gdf.plot(ax=ax,color='red')
​​​​​​​fig.colorbar(cm.ScalarMappable(norm=colors.Normalize(vmin=np.nanmin(result), vmax=np.nanmax(result)), cmap='gist_earth', ax=ax,extend='both',fraction=0.05))             

Python与GIS_第8张图片

coord_list = [(x,y) for x,y in zip(gdf['geometry'].x , gdf['geometry'].y)]coord_listgdf['value'] = [x for x in src.sample(coord_list)]gdf.head()

Python与GIS_第9张图片

3.2 第二种方法

from rasterstats import gen_point_querypointData=gdfpoint_raster_value=gen_point_query(pointData['geometry'],r'C:\Users\lenovo\Desktop\pzh_map_dispose\sf1.tif')print(*point_raster_value)

谢谢大家点赞关注哦!您的支持就是我不竭的动力!

Python与GIS_第10张图片

Matplotlib绘制误差曲线图

使用网络爬虫下载全球10m土地覆盖类型数据

机器学习——梯度下降与链式求导

Mayavi三维绘图可视化

Matplotlib曲线分段拟合与细节处理

Jupyter notebook的扩展插件

Mathematica基础及应用

Markdown与Latex基本语法

Mathematica解微分方程并绘图

图内内嵌图和水平柱状图--科研美图

Matplotlib--在图像中使用LaTex公式及标注箭头的使用

孟祥帅创作

Email: [email protected]

你可能感兴趣的:(绘图,GIS,Python,python,numpy,matplotlib)