gis shp與shp相交實現

2021-10-24 07:47:16 字數 4394 閱讀 6646

工作要解決的問題:

專案根據衛星影像和演算法得到同一區域兩個時間的變化情況,可以得到乙個包含變化圖斑的.shp檔案,但是該區域中不同區域的性質不同,需要進行區別處理。

依據是甲方提供的乙個區域分割的圖斑.shp檔案。

最後,需要輸出的是甲方每個圖斑中真實的變化情況(即前shp檔案和後shp檔案求交集),還要將兩個shp中的圖斑屬性進行綜合。

最先參考文章

ogr layer intersection

之後(最終使用方案)

intersect shapefiles using shapely

之後還參考

fiona使用者手冊

首先碰到的是兩個shp無交集,但是軟體做有,最後發現是兩個shp的座標參考係不同

在進行圖斑相交處理過程中會碰到

topologyexception: input geom 1

is invalid: ring self-intersection at or near

報錯:topologyexception: input geom 1 is invalid

嘗試此種方法無果。

多邊形自相交處理-selfintersection

最後解決方案參考文章:

修復不合法的polygon

編碼問題

最後綜合的屬性中,中文列印為亂碼,因此將encoding設定為utf-8即可解決

fiona使用過程中

with fiona.

open

('oriented-ccw.shp'

,'w'

, crs=source.crs,

# 該引數報錯

driver=source.driver,

schema=sink_schema,

)as sink:

# 值後嘗試此種

sink = fiona.

open

('/tmp/foo.shp'

,'w'

,**source.meta)

最後傳參使用 crs_wkt 進行傳遞成功

有序字典的合併

merge 兩個 ordereddict 到乙個 ordereddict 中的可用和不可用方法

import time

import fiona

import rtree

defintersect_shp_shp

(manager_shp_path,input_shp_path,output_shp_path,min_area=

none):

""" manager_shp_path : 第一shp檔案路徑 該專案中是 林地小班

input_shp_path : 第二shp檔案路徑 該專案中是 演算法產生的變化圖斑

output_shp_path : 輸出shp檔案路徑

min_area : 用於圖斑面積篩選(面積小於該值的圖斑,將會pass,也提高演算法執行時間)

return none

"""start_=time.time(

)with fiona.

open

(manager_shp_path,

'r',encoding=

'utf-8'

)as layer1:

with fiona.

open

(input_shp_path,

'r',encoding=

'utf-8'

)as layer2:

if layer1.crs[

'init'

]!=layer2.crs[

'init']:

raise exception(

'shapefile的座標系不同,無法進行計算!請先轉換座標系!'

)# 合併兩shp的schema

schema3 = layer2.schema.copy(

) schema3[

'properties'

].update(layer1.schema[

'properties'])

# 新增面積屬性

schema3[

'properties'][

'area']=

'float'

# schema3['geometry']='polygon'

with fiona.

open

(output_shp_path, mode=

'w', schema=schema3,driver=

'esri shapefile'

,crs_wkt=layer2.meta[

'crs_wkt'

],encoding=

'utf-8'

)as layer3:

# 建立rtree索引

print

('開始建立索引......'

) index = rtree.index.index(

) manager_num=

0for feat1 in layer1:

fid =

int(feat1[

'id'])

geom1 = shape(feat1[

'geometry'])

index.insert(fid, geom1.bounds)

manager_num+=

1print

('林地小班數量共有:%d 個,建立索引共耗時%.2f s'

%(manager_num,time.time(

)-start_)

)# 執行相交運算

intersect_execute(layer1,layer2,layer3,index,min_area)

print

('完成本次運算共耗時%.2f s'

%(time.time(

)-start_,))

defintersect_execute

(layer1,layer2,layer3,index,min_area)

:print

('開始進行交集運算......'

) result_num,polygon_num,small_num=0,

0,0for feat2 in layer2:

polygon_num+=

1 geom2 = shape(feat2[

'geometry'])

if min_area and geom2.areasmall_num+=

1continue

# 檢測合法性,並進行合法化(主要針對 有洞的polygon)

ifnot geom2.is_valid:

geom2=geom2.

buffer(0

)for fid in

list

(index.intersection(geom2.bounds)):

feat1 = layer1[fid]

geom1 = shape(feat1[

'geometry'])

ifnot geom1.is_valid:

geom1=geom1.

buffer(0

)if geom1.intersects(geom2)

:# 合併屬性

props = feat2[

'properties'

].copy(

) props.update(feat1[

'properties'])

intersect=geom1.intersection(geom2)

if min_area and intersect.areacontinue

# 給area屬性賦值

props[

'area'

]=intersect.area

try: layer3.write(

) result_num+=

1except exception as e:

print

(e)print

('輸入圖斑數量 %d 個,小面積的圖斑有 %d 個,得到符合要求的圖斑共: %d 個'

%(polygon_num,small_num,result_num,))

if __name__ ==

"__main__"

: intersect_shp_shp(

)

shp與geojson格式轉換

有兩種方法,第一種是用arcgismap自帶的toolbox裡的工具,路徑為 system toolboxes conversion tools json json to features與features to json。這裡shp轉json一般不會報錯。主要說明一下json轉shp。1.首先你的...

相交 光線與球

光線與球之間的相交很容易計算。如果光線的兩端分別是 x1,y1,z1 和 x2,y2,z2 則第一步是將光線引數化 x x1 x2 x1 t x1 it y y1 y2 y1 t y1 jt z z1 z2 z1 t z1 kt 其中0 t 1 中心在 l,m,n 半徑為r的球由下式給出 x l 2...

IDL實現向量 shp 裁剪柵格TASK(一

隨著envi idl版本的更新,idl對向量和柵格資料的處理也變得越來越簡單化。其提供了很多方便的介面,使得使用者呼叫和學習練習便捷成為了可能。最近接觸idl,發現好多網上的 都是延後的,新的介面 理解和編寫起來都比較方便,尤其是在做大量資料研究和應用時,使用批處理的方式顯得尤其重要。新的介面還在摸...