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

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

답변