開源GIS-geos實現空間快速連線
開源GIS-geos實現空間快速連線
其中關於空間計算的只有簡單的判斷
標題
而要真正實現空間連線,是需要將兩個shp檔案進行裡外迴圈,例如,以其中一個shp的要素個數為外迴圈,以另一個shp要素數量為內迴圈,逐一判斷是否存在空間上的關聯(包含、被包含。。。)
如此做迴圈肯定會影響程式執行的速度。因此可以使用Rtree作為索引,加快迴圈的檢索。
話不多說,下面上程式碼,以“包含”的空間關係做空間連線為例
#-----------------開啟OSM資料---------------------------
osm_ds = ogr.Open(osmfile)
osm_lyr=osm_ds.GetLayer(0)
feat=osm_lyr.GetFeature(0)
keys_osm=feat.keys()
spatial=osm_lyr.GetSpatialRef()
count=osm_lyr.GetFeatureCount()
#---開啟BUffer-----------
buffer_s=ogr.Open(bufferfile)
buff_lyr=buffer_s.GetLayer(0)
buff_feature=buff_lyr.GetFeature(0)
keys_buff=buff_feature.keys()
#--建立索引--
shp_index=index.Index()
#--shp幾何資料匯入Rtree--
for i,feat in enumerate(buff_lyr):
# geom=feat.GeometryDef()
geom = feat.GetGeometryRef()
bbox=geom.GetEnvelope()#--left,right,buttom,top
# print("Type of bbox",type(bbox),":",bbox)
shp_index.insert(i,(bbox[0],bbox[2],bbox[1],bbox[3]))#---idx.insert(0, (left, bottom, right, top))
#--空間連線
# print()
gdal.SetConfigOption( "GDAL_FILENAME_IS_UTF8", "YES")
gdal.SetConfigOption( "SHAPE_ENCODING", "UTF-8")
Spatial_driver = ogr.GetDriverByName("ESRI Shapefile")
spatial_ds = Spatial_driver.CreateDataSource(matchedfile)
match_lyr = spatial_ds.CreateLayer('matched',spatial) # 建立緩衝區
#建立欄位
# print("osm_keys:",keys_osm)
osm_def = osm_lyr.GetLayerDefn()
# for i,each in enumerate(keys_osm):
# fielddef=osm_def.GetFieldDefn(i)
# if fielddef==None:
# break
# # print(fielddef)
# # print(each)
# fieldDefn = ogr.FieldDefn(each,fielddef.GetType())
# match_lyr.CreateField(fieldDefn)
# print("Buffer_keys:", keys_buff)
keys_match=keys_buff.copy()
keys_match.extend(keys_osm)
# print("matchedfile Fields:", keys_match)
buff_def = buff_lyr.GetLayerDefn()
count_field=0
for i,key in enumerate(keys_match):
field=None
if key in keys_buff:
field=buff_def.GetFieldDefn(i)
count_field+=1
else:
field = osm_def.GetFieldDefn(i-count_field)
if field is None:
break
fieldDef= ogr.FieldDefn(key,ogr.OFTString)
fieldDef.SetWidth(254)
match_lyr.CreateField(fieldDef)
#---新增幾何屬性和欄位屬性----------
match_feat = ogr.Feature(match_lyr.GetLayerDefn())
# print("--建立空間連線...")
for i,osm_feat in enumerate(osm_lyr):
# print(i+1,"/%d"%count,end=',')
geom = osm_feat.geometry().Clone()
match_feat.SetGeometry(geom)
# print("type of geom",type(geom))
#--buffer屬性
feat_within=[]
#--在Rtree中尋找相交的部分要素
bbox=geom.GetEnvelope()
feat_id = list(shp_index.intersection((bbox[0],bbox[2],bbox[1],bbox[3])))
# for buffer_feat in buff_lyr: 大連人流手術費用
# if geom.Within(buffer_feat.geometry().Clone()):
# feat_within.append(buffer_feat)
#---被包含的要素--
for idx in feat_id:
feat_temp=buff_lyr.GetFeature(idx)
if geom.Within(feat_temp.geometry().Clone()):
feat_within.append(feat_temp)
if len(feat_within)==1:
for key in keys_match:
if key in keys_osm:
match_feat.SetField(key, str(osm_feat.GetField(key)))
# print(key, "(one):", osm_feat.GetField(key), end=',')
if key in keys_buff:
# print(key, "(one):", feat_within[0].GetField(key), end=',')
match_feat.SetField(key, (feat_within[0].GetField(key)))
elif len(feat_within)>1:
data = getMostvalue(feat_within)
for key in keys_match:
if key in keys_osm:
match_feat.SetField(key, str(osm_feat.GetField(key)))
# print(key, "(one of):", osm_feat.GetField(key), end=',')
if key in keys_buff:
# print(key,"(one of):",feat_within[data].GetField(key),end=',')
match_feat.SetField(key,str(feat_within[data].GetField(key)))
else:
# --osm屬性
for key in keys_match:
if key in keys_osm:
match_feat.SetField(key, str(osm_feat.GetField(key)))
# print(key, "(None):", osm_feat.GetField(key), end=',')
else:
match_feat.SetField(key,"None")
print(key, "(None):","None", end=',')
match_lyr.CreateFeature(match_feat)
# print()
feat_within.clear()
#--進度條---
# time.sleep(0.5)
# sys.stdout.write("建立空間連線... %2f%% \r" % (100*(i+1)/count))
# sys.stdout.flush()
# print()
spatial_ds.Destroy()
以上是個人在做的一個專案的程式,簡單的實現了快速的空間連線,關於Rtree的教程,可以百度搜尋Rtree,使用的庫包為geos和rtree。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69945560/viewspace-2765530/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 開源資源快速連結(一)
- 空間分析開源庫GEOS
- 根據源庫表空間實際使用建立表空間指令碼指令碼
- docker快速部署DNS,實現快速上線DockerDNS
- not in 用外連線實現
- 【TABLESPACE】使用“ALTER TABLESPACE”命令的“RENAME”功能實現表空間快速重新命名
- liunx使用者空間和核心空間之間的通訊實現(在PPC下的實現)(轉)
- 開源,架起理想和現實之間的橋樑
- Windows 7實現開機自動連線寬頻Windows
- MySQL空間函式實現位置打卡MySql函式
- Windows 7快捷方式:快速開啟本地連線Windows
- ORA-02396: 超出最大空閒時間, 請重新連線
- 大神教你實現redis鍵空間通知Redis
- js 實現鏈式呼叫名稱空間JS
- [譯] Go 實現百萬 WebSocket 連線GoWeb
- Swoole MySQL 連線池的實現MySql
- 實現一個redis連線池Redis
- Python實現MySQL連線池PythonMySql
- Django使用channels實現Websocket連線DjangoWeb
- ofbiz 連線池如何實現?
- mysql的jdbc連線java實現MySqlJDBCJava
- 資料庫連線池實現資料庫
- oracle UNDO表空間一個bug——undo表空間快速擴充套件Oracle套件
- 空間曲線和曲面方程
- iOS 實現時間線列表效果iOS
- 騰訊釋出雲實驗室、開源開發工具,助力開發者連線 AI 未來AI
- DIY 實現 ThinkPHP 核心框架(四)名稱空間PHP框架
- 一個RecyclerView實現QQ空間相簿佈局View
- 跨平臺表空間傳輸的實現
- 使用RMAN實現可傳輸的表空間
- 利用PLSQL實現表空間的遷移(一)SQL
- 利用PLSQL實現表空間的遷移(二)SQL
- 利用PLSQL實現表空間的遷移(四)SQL
- 利用PLSQL實現表空間的遷移(三)SQL
- 利用PLSQL實現表空間的遷移(五)SQL
- nginx連線資源管理Nginx
- 資源連線彙總
- 內網滲透 IPC$ [空連線]內網