【GDAL學習】過濾器,簡單的空間分析,函式和模組
1.屬性過濾器
>>>import ogr,os >>>os.chdir('E:/data/GDAL/ospy_data3') >>>driver=ogr.GetDriverByName('ESRI Shapefile') >>>ds=driver.Open('sites.shp',0) >>>ly=ds.GetLayer() >>>ly.GetFeatureCount() Out[7]: 42 >>>ly.SetAttributeFilter("cover='shrubs'") Out[8]: 0 >>>ly.GetFeatureCount() Out[9]: 6 >>>ly.SetAttributeFilter(None) Out[10]: 0 >>>ly.GetFeatureCount() Out[11]: 42
2.空間過濾器
>>>import ogr >>>import os >>>os.chdir('E:/data/GDAL/ospy_data3') >>>driver = ogr.GetDriverByName('ESRI Shapefile') >>>ds1 = driver.Open('cache_towns.shp', 0) >>>ds2 = driver.Open('sites.shp', 0) >>>ly1 = ds1.GetLayer() >>>ly2 = ds2.GetLayer() >>>fAreas=ly1.GetNextFeature() >>>poly=fAreas.GetGeometryRef() >>>ly2.GetFeatureCount() Out[12]: 42 >>>ly2.SetSpatialFilter(poly) >>>ly2.GetFeatureCount() Out[14]: 0 >>>ly2.SetSpatialFilterRect(460000,4590000,490000,4600000) >>>ly2.GetFeatureCount() Out[16]: 4 >>>ly2.SetSpatialFilter(None) >>>ly2.GetFeatureCount() Out[18]: 42
更強大的查詢功能,執行SQL程式碼,查找出cover型別為grass的Feature並以ID降序排列。
最後一句ReleaseResultSet(<result_layer>)是將查詢結果釋放,在執行下一條SQL語句之前一定要先釋放。
>>>import ogr,os ...os.chdir('E:/data/GDAL/ospy_data3') ...driver=ogr.GetDriverByName('ESRI Shapefile') ...ds=driver.Open('sites.shp',0) ...ly=ds.GetLayer() ...ly.GetFeatureCount() Out[2]: 42 >>>result=ds.ExecuteSQL("select * from sites where cover = 'grass' order by id desc") >>>resultFeat=result.GetNextFeature() >>>while resultFeat: ...print(resultFeat.GetField('id')) ...resultFeat=result.GetNextFeature() 42 40 37 31 28 24 17 13 11 10 4 >>>ds.ReleaseResultSet(result)
接上面程式碼。統計cover為grass的所有Feature的數目
>>>result=ds.ExecuteSQL("select count(*) from sites where cover = 'grass'")
>>>result.GetFeatureCount()
Out[8]: 1
>>>result.GetFeature(0).GetField(0)
Out[9]: 11
>>>ds.ReleaseResultSet(result)
接上面程式碼,列出所有的cover型別
>>>result=ds.ExecuteSQL("select distinct cover from sites")
>>>resultFeat=result.GetNextFeature()
>>>while resultFeat:
...print(resultFeat.GetField(0))
...resultFeat = result.GetNextFeature()
shrubs
trees
rocks
grass
bare
water
>>>ds.ReleaseResultSet(result)
接上面程式碼,統計每種cover型別各有多少個Feature
>>>coverLayer = ds.ExecuteSQL('select distinct cover from sites')
>>>coverFeat = coverLayer.GetNextFeature()
>>>while coverFeat:
...cntLayer = ds.ExecuteSQL("select count(*) from sites where cover = '" + coverFeat.GetField(0) +"'")
...print(coverFeat.GetField(0)+' '+cntLayer.GetFeature(0).GetFieldAsString(0))
...ds.ReleaseResultSet(cntLayer)
...coverFeat = coverLayer.GetNextFeature()
...
shrubs 6
trees 11
rocks 6
grass 11
bare 6
water 2
>>>ds.ReleaseResultSet(coverLayer)
3.空間操作
1)Intersect:判斷兩個要素是否相交,Polygon與Polygon,Polygon與Point,Polygon與Line,Line與Point
>>> poly2.Intersect(poly1)
0
>>> poly2.Intersect(poly3)
1
>>> poly2.Intersect(poly2)
1
>>> poly1.Intersect(ptA)
0
>>> poly1.Intersect(ptB)
1
>>> poly1.Intersect(line)
1
>>> poly3.Intersect(line)
1
>>> line.Intersect(ptB)
1
2)Disjoint:判斷兩個要素是否不相交,Polygon與Polygon,Polygon與Point,Polygon與Line,Line與Point
>>> poly2.Disjoint(poly1)
1
>>> poly2.Disjoint(poly3)
0
>>> poly1.Disjoint(ptA)
1
>>> poly1.Disjoint(ptB)
0
>>> poly1.Disjoint(line)
0
>>> poly3.Disjoint(line)
0
>>> line.Disjoint(ptB)
3)Touches:表示相鄰(擦邊),Polygon與Polygon,Polygon與Point,Polygon與Line
>>> poly2.Touches(poly1)
0
>>> poly2.Touches(poly3)
0
>>> poly1.Touches(line)
0
>>> poly1.Touches(ptB)
0
>>> poly3.Touches(line)
1
4)Crosses:穿越,一般是一條線穿過一個多邊形,一般是Polygon與Line
>>> poly2.Crosses(poly1)
0
>>> poly2.Crosses(poly3)
0
>>> poly2.Crosses(line)
1
>>> poly3.Crosses(line)
0
>>> poly1.Crosses(line)
1
>>> line.Crosses(ptB)
0
5)Within:包含於,一個要素完全被另一個要素圈起來了,Polygon與Polygon,Polygon與Point,Polygon與Line
>>> poly3.Within(poly2)
0
>>> line.Within(poly2)
0
>>> ptA.Within(poly1)
0
>>> ptB.Within(poly1)
1
>>> poly1.Within(ptB)
0
6)Contains:包含,跟Within正好相反,一個要素完全包含另一個要素,Polygon與Polygon,Polygon與Point,Polygon與Line
>>> poly3.Contains(poly2)
0
>>> line.Contains(poly2)
0
>>> poly2.Contains(line)
0
>>> poly1.Contains(ptA)
0
>>> poly1.Contains(ptB)
1
>>> ptB.Contains(poly1)
0
7)Overlaps:重疊,只有兩個多邊形之間才能overlap,Polygon與Polygon
>>> poly2.Overlaps(poly1)
0
>>> poly2.Overlaps(poly3)
1
>>> poly2.Overlaps(line)
0
>>> poly3.Overlaps(line)
0
>>> poly1.Overlaps(ptB)
0
用week3中的資料測試一下,下圖中多邊形的FID是18,在cache_towns.shp檔案中;點的FID是40,cover型別是tree,在sites.shp檔案中。
>>>import ogr
...import os
...os.chdir('E:/data/GDAL/ospy_data3')
...driver = ogr.GetDriverByName('ESRI Shapefile')
...ds1 = driver.Open('sites.shp', 0)
...if ds1 is None:
... print('Cannot open this file:', ds1.name)
...pyLy=ds1.GetLayer()
...treeFe=pyLy.GetFeature(40)
...treePt=treeFe.GetGeometryRef()
...ds2=driver.Open('cache_towns.shp',0)
...if ds2 is None:
... print('Cannot open this file:',ds2.name)
...tnLy=ds2.GetLayer()
...townFe=tnLy.GetFeature(18)
...townPg=townFe.GetGeometryRef()
>>>townPg.Intersect(treePt)
Out[3]: True
>>>treePt.Intersect(townPg)
Out[4]: True
>>>townPg.Disjoint(treePt)
Out[5]: False
>>>townPg.Touches(treePt)
Out[6]: False
>>>townPg.Crosses(treePt)
Out[7]: False
>>>townPg.Within(treePt)
Out[8]: False
>>>townPg.Contains(treePt)
Out[9]: True
Assignment 3a:Use filters and buffers
程式碼1:自己寫的,沒有註釋
- Use an attribute filter to restrict cache_towns.shp to Nibley (“name” field)
- Buffer the Nibley geometry by 1500
- Use the new geometry with a spatial filter on sites.shp to find all sites within 1500 meters of Nibley
- Print out the "id" value for those sites
# Assignment 3a
import ogr
import os
os.chdir('E:/data/GDAL/ospy_data3')
driver = ogr.GetDriverByName('ESRI Shapefile')
ds1 = driver.Open('cache_towns.shp', 0)
if ds1 is None:
print('Cannot open this file:', ds1.name)
ly1 = ds1.GetLayer()
ly1.SetAttributeFilter("NAME='Nibley'")
NibleyFeat = ly1.GetFeature(0)
NibleyGeom = NibleyFeat.GetGeometryRef()
bufferGeom = NibleyGeom.Buffer(1500)
ds2 = driver.Open('sites.shp', 0)
if ds2 is None:
print('Cannot open this file:', ds2.name)
ly2 = ds2.GetLayer()
ly2.SetSpatialFilter(bufferGeom)
# ly2.GetFeatureCount()
siteFeat = ly2.GetNextFeature()
while siteFeat:
print(siteFeat.GetField('ID'))
siteFeat.Destroy()
siteFeat = ly2.GetNextFeature()
ds2.Destroy()
ds1.Destroy()
程式碼2:參考答案,有詳細註釋
# Assignment 3a
# import modules
import ogr, os, sys
# set the working directory
os.chdir('E:/data/GDAL/ospy_data3')
# get the shapefile driver
driver = ogr.GetDriverByName('ESRI Shapefile')
# open sites.shp and get the layer
sitesDS = driver.Open('sites.shp', 0)
if sitesDS is None:
print('Could not open sites.shp')
sys.exit(1)
sitesLayer = sitesDS.GetLayer()
# open cache_towns.shp and get the layer
townsDS = driver.Open('cache_towns.shp', 0)
if townsDS is None:
print('Could not open cache_towns.shp')
sys.exit(1)
townsLayer = townsDS.GetLayer()
# use an attribute filter to restrict cache_towns.shp to "Nibley"
townsLayer.SetAttributeFilter("NAME = 'Nibley'")
# get the Nibley geometry and buffer it by 1500
nibleyFeature = townsLayer.GetFeature(0)
nibleyGeom = nibleyFeature.GetGeometryRef()
bufferGeom = nibleyGeom.Buffer(1500)
# use bufferGeom as a spatial filter on sites.shp to get all sites
# within 1500 meters of Nibley
sitesLayer.SetSpatialFilter(bufferGeom)
# loop through the remaining features in sites.shp and print their
# id values
siteFeature = sitesLayer.GetNextFeature()
while siteFeature:
print(siteFeature.GetField('ID'))
siteFeature.Destroy()
siteFeature = sitesLayer.GetNextFeature()
# close the shapefiles
sitesDS.Destroy()
townsDS.Destroy()
資料下載:https://download.csdn.net/download/qq_37935516/10791607