: 내가 할 노력하고 무엇 루프 포인트 Shape 파일을 통해 떨어지면 각 지점 선택 에 다각형을.
다음 코드는 책에서 찾은 공간 쿼리 예제에서 영감을 얻은 것입니다.
mitte_path = r"D:\PythonTesting\SelectByLocation\mitte.shp"
punkte_path = r"D:\PythonTesting\SelectByLocation\punkte.shp"
polygon = QgsVectorLayer(mitte_path, 'Mitte', 'ogr')
points = QgsVectorLayer(punkte_path, 'Berlin Punkte', 'ogr')
QgsMapLayerRegistry.instance().addMapLayer(polygon)
QgsMapLayerRegistry.instance().addMapLayer(points)
polyFeatures = polygon.getFeatures()
pointsCount = 0
for poly_feat in polyFeatures:
polyGeom = poly_feat.geometry()
pointFeatures = points.getFeatures(QgsFeatureRequest().setFilterRect(polyGeom.boundingBox()))
for point_feat in pointFeatures:
points.select(point_feat.id())
pointsCount += 1
print 'Total:',pointsCount
이것은 작동하고 데이터 세트를 선택하지만 문제는 경계 상자로 선택 하므로 관심이없는 점을 분명히 반환 한다는 것 입니다.
qgis : selectbylocation 을 사용하지 않고 다각형 내 에서 점을 반환하는 방법은 무엇입니까?
within () 및 intersects () 메서드를 사용해 보았지만 작동하지 않기 때문에 위 코드를 사용했습니다. 그러나 아마도 그들은 결국 열쇠 일 것입니다.
답변
당신은 ( “레이 캐스팅”으로) 특별한 기능이 필요하지 않습니다, 모든 (PyQGIS에 포함 () 에서 PyQGIS 기하학 처리 )
polygons = [feature for feature in polygons.getFeatures()]
points = [feature for feature in points.getFeatures()]
for pt in points:
point = pt.geometry() # only and not pt.geometry().asPolygon()
for pol in polygons:
poly = pol.geometry()
if poly.contains(point):
print "ok"
또는 한 줄로
polygons = [feature for feature in polygons.getFeatures()]
points = [feature for feature in points.getFeatures()]
resulting = [pt for pt in points for poly in polygons if poly.geometry().contains(pt.geometry())]
print len(resulting)
...
직접 사용할 수도 있습니다
[pt.geometry().asPoint() for pt in points for poly in polygons if poly.geometry().contains(pt.geometry())]
여기서 문제는 모든 도형 (다각형과 점)을 반복해야한다는 것입니다. 경계 공간 인덱스를 사용하는 것이 더 재미있다 : (에서 ‘필터’, 모양 당신으로 반복 만 현재의 지오메트리와 교차 할 수있는 기회를 가지고있는 형상을 통해 ? 효율적이 QgsSpatialIndex에 의해 반환 된 기능에 액세스하는 방법 )
답변
PyQGIS와 함께 사용하도록 약간 조정 한 “레이 캐스팅” 알고리즘 을 사용할 수 있습니다 .
def point_in_poly(point,poly):
x = point.x()
y = point.y()
n = len(poly)
inside = False
p1x,p1y = poly[0]
for i in range(n+1):
p2x,p2y = poly[i % n]
if y > min(p1y,p2y):
if y <= max(p1y,p2y):
if x <= max(p1x,p2x):
if p1y != p2y:
xints = (y-p1y)*(p2x-p1x)/(p2y-p1y)+p1x
if p1x == p2x or x <= xints:
inside = not inside
p1x,p1y = p2x,p2y
return inside
## Test
mapcanvas = iface.mapCanvas()
layers = mapcanvas.layers()
#For polygon
polygon = [feature.geometry().asPolygon()
for feature in layers[1].getFeatures()]
points = [feat.geometry().asPoint()
for feat in layers[0].getFeatures()]
## Call the function with the points and the polygon
count = [0]*(layers[1].featureCount())
for point in points:
i = 0
for feat in polygon:
if point_in_poly(point, feat[0]) == True:
count[i] += 1
i += 1
print count
이 상황에 적용 :
파이썬 콘솔에서 결과는 다음과 같습니다.
[2, 2]
효과가있었습니다.
편집 참고 사항 :
더 간결한 유전자 제안 코드 :
mapcanvas = iface.mapCanvas()
layers = mapcanvas.layers()
count = [0]*(layers[1].featureCount())
polygon = [feature
for feature in layers[1].getFeatures()]
points = [feature
for feature in layers[0].getFeatures()]
for point in points:
i = 0
geo_point = point.geometry()
for pol in polygon:
geo_pol = pol.geometry()
if geo_pol.contains(geo_point):
count[i] += 1
i += 1
print count
답변
직장 동료의 조언으로 마침내 within ()을 사용하여 작동하도록했습니다.
일반적인 논리
- 다각형의 특징을 얻다
- 포인트의 특징을 얻다
- 다각형 파일에서 각 기능을 반복합니다.
- 기하학을 얻다
- 모든 지점을 돌다
- 단일 지점의 지오메트리를 얻습니다
- 기하학이 다각형의 기하학 내에 있는지 테스트
코드는 다음과 같습니다.
mitte_path = r"D:\PythonTesting\SelectByLocation\mitte.shp"
punkte_path = r"D:\PythonTesting\SelectByLocation\punkte.shp"
poly = QgsVectorLayer(mitte_path, 'Mitte', 'ogr')
points = QgsVectorLayer(punkte_path, 'Berlin Punkte', 'ogr')
QgsMapLayerRegistry.instance().addMapLayer(poly)
QgsMapLayerRegistry.instance().addMapLayer(points)
polyFeatures = poly.getFeatures()
pointFeatures = points.getFeatures()
pointCounter = 0
for polyfeat in polyFeatures:
polyGeom = polyfeat.geometry()
for pointFeat in pointFeatures:
pointGeom = pointFeat.geometry()
if pointGeom.within(polyGeom):
pointCounter += 1
points.select(pointFeat.id())
print 'Total',pointCounter
이것은 within () 대신 intersects () 에서도 작동 합니다. 포인트를 사용할 때는 둘 다 동일한 결과를 반환하므로 어떤 포인트를 사용 하든 상관 없습니다 . 라인 / 폴리곤을 검사 할 때, 그러나, 중요한 차이를 만들 수 있습니다 () 반환 객체 내에서 완전히 교차은 () 안에 모두있는 개체 retuns 반면, 내을 하고 있는 일부 내 (즉 그 교차 기능 등을 가진 이름이 표시됩니다).