天天看點

Python之shp檔案

1、讀取shp

pip install pyshp
           

pyshp(Python Shapefile Library)

是一個Python庫,用于在Python腳本中對ArcGIS中的Shapefile檔案(.shp,.shx,.dbf等格式)進行讀寫操作。

Reader類, 對shapefile檔案讀取;Editor類,對shapefile檔案編輯;Writer類,對shapefile檔案寫操作

每個檔案包含 “幾何資料”(Geometry)和"屬性資料"(Attribute Record) ,兩個檔案資料一一對應。

每個幾何對象包含有4個屬性:資料類型(shapeType),代表該"幾何資料"對象的資料類型(點,shapeType=1,線,shapeType=3,多邊形,shapeType=5);資料範圍(bbox),隻針對多點資料,代表該"幾何資料"對象的邊界範圍;資料塊(parts),隻針對線或者多邊形,代表該"幾何資料"對象各個塊的第一個點的索引;點集(points),代表該"幾何資料"對象的所有點坐标。 "屬性資料"即每個"幾何資料"對象在屬性表中的對應項。

import shapefile
import pandas as pd

    sf = shapefile.Reader("E:/test/wanzhou_yudong_bdy.shp")
    shapes = sf.shapes()
    arr = []
    for i in range(0, len(shapes)):
        arr.append(shapes[i].bbox)
    grids = pd.DataFrame(arr, columns=['min_lon', 'min_lat', 'max_lon', 'max_lat'])
    min_lon = grids['min_lon'].min()
    min_lat = grids['min_lat'].min()
    max_lon = grids['max_lon'].max()
    max_lat = grids['max_lat'].max()
           

shp的最大最小經緯度,和上面結果一樣

import shapefile

sf = shapefile.Reader("E:/tif/shp/1.shp")
min_x, min_y, max_x, max_y = sf.bbox
           

2、判斷某個點是否在shp中

import shapefile
import shapely.geometry as geometry

		lons, lats = [], []
		.... # lons = np.linspace(113.77, 114.59, 50)
			 # lats = np.linspace(22.47, 22.83, 25)
        grid_lon, grid_lat = np.meshgrid(lons, lats)
        flat_lon = grid_lon.flatten()
        flat_lat = grid_lat.flatten()
        flat_points = np.column_stack((flat_lon, flat_lat))
        in_shape_points = []
        sf = shapefile.Reader("E:/test/中小河流.shp", encoding='gbk')
        shapes = sf.shapes()
        for pt in flat_points:
            # make a point and see if it's in the polygon
            if geometry.Point(pt).within(geometry.shape(shapes[0])):
                in_shape_points.append(pt)
                print("The point is in shp")
            else:
                print("The point is not in shp")
        print(in_shape_points)
           

3、gdal生成shp

import osgeo.ogr as ogr
import osgeo.osr as osr

def run():
    driver = ogr.GetDriverByName("ESRI Shapefile")
    data_source = driver.CreateDataSource("Gooise.shp")

    srs = osr.SpatialReference()
    srs.ImportFromEPSG(32631)

    layer = data_source.CreateLayer("Gooise", srs, ogr.wkbMultiPolygon)

    # field_name = ogr.FieldDefn("Name", ogr.OFTString)
    # field_name.SetWidth(24)
    # layer.CreateField(field_name)
    #
    # field_name = ogr.FieldDefn("Car_per_house", ogr.OFTString)
    # field_name.SetWidth(24)
    # layer.CreateField(field_name)

    feature = ogr.Feature(layer.GetLayerDefn())
    # feature.SetField("Name", 'Gooise')
    # feature = ogr.Feature(layer.GetLayerDefn())
    # feature.SetField("Car_per_house", '1.2')

    wkt = 'polygon((646080 5797460,648640 5797460,648640 5794900,646080 5794900,646080 5797460))'
    polygon = ogr.CreateGeometryFromWkt(wkt)
    feature.SetGeometry(polygon)
    layer.CreateFeature(feature)
    feature = None
    data_source = None
           

4、shp拆分多個shp

import osgeo.ogr as ogr
import osgeo.osr as osr

def run():
    driver = ogr.GetDriverByName('ESRI Shapefile')
    fileName = "E:/cq/中小河流.shp"
    dataSource = driver.Open(fileName, 0)
    layer = dataSource.GetLayer(0)
    print("空間參考 :{0}".format(layer.GetSpatialRef()))
    for i in range(0, layer.GetFeatureCount()):
        feat = layer.GetFeature(i)
        wkt = feat.geometry()
        print(wkt)
        create_shp(i, str(wkt))


def create_shp(shp_name,wkt):
    driver = ogr.GetDriverByName("ESRI Shapefile")
    data_source = driver.CreateDataSource(f'E:/cq/tif/shp/{shp_name}.shp')
    srs = osr.SpatialReference()
    srs.ImportFromEPSG(4326)
    layer = data_source.CreateLayer(f'{shp_name}', srs, ogr.wkbMultiPolygon)
    feature = ogr.Feature(layer.GetLayerDefn())
    polygon = ogr.CreateGeometryFromWkt(wkt)
    feature.SetGeometry(polygon)
    layer.CreateFeature(feature)
    feature = None
    data_source = None
           

5、shp截取tif

from osgeo import gdal

    input_raster = r"E:/chqqh/tif/FA/o0001.tif"
    input_raster = gdal.Open(input_raster)
    input_shape = r"E:/chqqh/tif/shp/1.shp"  # or any other format
    output_raster = r'E:\chqqh\tif\test\o0001_1.tif'
    ds = gdal.Warp(output_raster,
                   input_raster,
                   format='GTiff',
                   cutlineDSName=input_shape,  # or any other file format
                   cutlineWhere="FIELD = 'whatever'",
                   # optionally you can filter your cutline (shapefile) based on attribute values
                   dstNodata=-9999)  # select the no data value you like
    ds = None