shp文件自相交處理

今天基於GDAL使用shp文件對柵格影像進行裁剪時出現了下面的問題,提示多邊形自相交了

Warning 1: Ring Self-intersection at or near point 112.48666420300003 34.830899357000078
ERROR 1: Cutline polygon is invalid.


很多人的第一反應是使用ArcGIS進行**拓撲檢查**,或使用ArcToolBox裏的**修復幾何**。確實我的第一反應也是去做這些東西。但是結果缺沒有檢查出任務拓撲錯誤,幾何修復也沒有檢查出問題。


使用ArcGIS檢查不到的原因


強大的ArcGIS居然檢查不到,最終找到了這個原因。
在ArcGIS 中無論是拓撲、shapefile文件、還是個人地理數據庫都是設置有容差的,小於這個容差的自相交,都是無法檢測到的。


解決方案


查閱了很多資料,最終整理了如下的解決方案。

  1. 使用PostGIS將shape文件導入Postgresql數據庫,記得導入的時候要勾選下面的選項。
  2. 從表裏提取出自相交的多邊形
    CREATE TABLE temp1 as select * from m2 where ST_IsValid(geom) = false

     

  3. 刪除原表中的自相交圖形
    delete from  m2 where ST_IsValid(geom) = false

     

  4. 修復多邊形

    update temp1 set geom =ST_Buffer(geom, 0.0) 
    -- update temp1 set geom =ST_MakeValid(geom) 也可以

     

  5. 修復完的數據恢復到原來的表

    insert into m2 select * from temp1

     

  6. 最後通過PostGIS插件導出shp文件即可

 結果檢測

使用gdal對結果進行檢測
 

from osgeo import ogr

shpFile = 'F:/m2.shp'  # 裁剪矩形

# # # 註冊所有的驅動
ogr.RegisterAll()


def check_shp():
    # 打開數據
    ds = ogr.Open(shpFile, 0)
    if ds is None:
        print("打開文件【%s】失敗!", shpFile)
        return
    print("打開文件【%s】成功!", shpFile)
    # 獲取該數據源中的圖層個數,一般shp數據圖層只有一個,如果是mdb、dxf等圖層就會有多個
    m_layer_count = ds.GetLayerCount()
    m_layer = ds.GetLayerByIndex(0)
    if m_layer is None:
        print("獲取第%d個圖層失敗!\n", 0)
        return
    # 對圖層進行初始化,如果對圖層進行了過濾操作,執行這句後,之前的過濾全部清空
    m_layer.ResetReading()
    count = 0
    m_feature = m_layer.GetNextFeature()
    while m_feature is not None:
        o_geometry = m_feature.GetGeometryRef()
        if not ogr.Geometry.IsValid(o_geometry):
            print(m_feature.GetFID())
            count = count + 1

        m_feature = m_layer.GetNextFeature()
    print("無效多邊形共" + str(count) + "個")


check_shp()

運行結果

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章