태그 보관물: qgis

qgis

점을 둘러싸는 모든 선을 가져옵니다 문제로 인해 주변 도로가 아닌

QGIS를 사용하는데 포인트와 도로망이 있습니다. 특정 지점을 둘러싼 도로 이름을 자동으로 추출해야합니다. 여기에 이미지 설명을 입력하십시오
가장 가까운 이웃 분석 및 버퍼 구역은 많은 경우에 측정 된 거리 문제로 인해 주변 도로가 아닌 주변 도로에 더 가깝기 때문에 작업을 수행 할 수 없습니다. 주변 도로 만 추출 할 수있는 방법에 대한 아이디어가 있습니까?



답변

내 테스트 데이터에 관하여 :

  1. OSM 도로 데이터와 마찬가지로 모든 단일 도로 지오메트리는 교차로에서 끝납니다.
  2. 모든 도로에는 고유 한 ID가 있습니다.

솔루션 I

두 가지 가정이있는 경우 :

  1. 도로는 숙소를 짓고 있습니다.

  2. 미터법 시스템에서 작업하고 있습니다.

아이디어는 점의 X 및 Y 좌표를 늘리거나 줄이는 것입니다. 미터법 시스템 내에서 작업하는 경우 포인트 동쪽으로 1m 이동하여 새 포인트를 작성하고 원래 포인트로 선을 작성할 수 있습니다. 선이 도로를 교차 할 때까지 동쪽으로 더갑니다. 서부에서 교차점을 찾으려면 원래 X 좌표에서 1m를 뺍니다. Y 좌표에 대해서도 동일합니다. 북 / 동 / 남 / 서에 도로가 없으면 카운터는 1000 (m)에서 멈 춥니 다. 1000m 이상의 거리에 도로가있을 수 있음을 알고 있으면이 값을 변경해야합니다.

다음 코드를 사용하여 작업을 해결할 수 있습니다.

편집

for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.name() == "point":
        startpoint = lyr

for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.name() == "roads":
        roads = lyr

startpoint_iter = startpoint.getFeatures()
for feature in startpoint_iter:
    geom = feature.geometry()
    if geom.type() == QGis.Point:
        xy = geom.asPoint()
        x,y = xy[0], xy[1]

line_start = QgsPoint(x,y)

def reached(direction, count_m):
    road_reached = None
    road = None
    count=1
    while road_reached < 1 and count <=count_m:
        count += 1
        if direction == 'N':
            line_end = QgsPoint(x, y+count)
        if direction == 'E':
            line_end = QgsPoint(x+count,y)
        if direction == 'S':
            line_end = QgsPoint(x,y-count)
        if direction == 'W':
            line_end = QgsPoint(x-count,y)
        line = QgsGeometry.fromPolyline([line_start,line_end])
        for f in roads.getFeatures():
            if line.intersects(f.geometry()):
                road_reached = 1
                road = f['name']
                print road

reached('N', 1000)
reached('E', 1000)
reached('S', 1000)
reached('W', 1000)

동쪽의 도로 e가 지점의 가까운 도로로 인식되지 않음을 보여주는 또 다른 예입니다.

함수를 호출하고 출력하는 방법 :

>>>>reached('N', 1000)
road a
>>>>reached('E', 1000)
road b
>>>>reached('S', 1000)
road c
>>>>reached('W', 1000)
road d

지점을 둘러싸고있는 도로가 4 개 이상인 경우 더 많은 방향을 살펴 봐야합니다 (X와 Y 모두 변경). 또는 선의 방위각을 변경할 수 있습니다. 즉, 0-360 ° 범위 내에서 1도 회전 할 수 있습니다.

솔루션 II

의견에서 영감을 얻어 Polygonize도로를 먼저 할 수도 있습니다. 따라서 QGIS의 도구를 사용할 수 있습니다 Processing > Toolbox > QGIS geoalgorithms > Vector geometry tools > Polygonize. 임시 레이어의 이름을로 바꿉니다 polygon. 도로로 완전히 둘러싸인 지점의 도로 이름 만 원한다고 가정합니다. 그렇지 않으면 솔루션 I 을 사용해야 합니다. 모든 도로가 연결 (스냅) 된 경우에만 작동합니다!

먼저 점이 다각형과 교차해야합니다. 이제는 AND둘러싸는 선의 시작 끝 점이 둘 다 다각형과 교차해야합니다.

for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.name() == "point":
        startpoint = lyr

for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.name() == "polygon":
        poly = lyr

for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.name() == "roads":
        roads = lyr

for h in startpoint.getFeatures():
    for g in poly.getFeatures():
        if h.geometry().intersects(g.geometry()):
            poly_geom = g.geometry()
            for f in roads.getFeatures():
                geom = f.geometry().asPolyline()
                start_point = QgsGeometry.fromPoint(QgsPoint(geom[0]))
                end_point = QgsGeometry.fromPoint(QgsPoint(geom[-1]))
                if poly_geom.intersects(start_point) and poly_geom.intersects(end_point):
                    print f['name']

출력 :

road c
road b
road e
road f

답변