QGIS 속성 테이블 필드를 자동으로 만드시겠습니까?


9

QGIS와 내가 가지고있는 Excel 워크 시트를 사용하여 수문 프로젝트를 만드는 방법으로 노력하고 있습니다. 이를 위해 파이프 섹션을 나타내는 벡터 레이어에 포함 된 선의 일부 정보를 추출하려고합니다.

추출해야 할 정보는 다음과 같습니다.

  • ID 번호
  • 길이
  • X, Y 시작 및 끝 좌표

"$ length"와 X 및 Y 좌표에 대한 다른 알고리즘을 사용하여이 필드를 캡처하는 방법을 찾았지만 속성 테이블을 열고 각 속성 열에 표현식을 넣고 클릭하여 필드를 업데이트해야합니다.

선을 그릴 때 이러한 필드가 자동으로 채워지는 방법이 있습니까? 즉, 선을 그리거나 편집하고 (편집 시작 또는 종료 노드) 속성 테이블을 열면 길이 필드와 좌표 X, Y가 채워지고 업데이트됩니다.


1
임시 테이블에서와 같이 편집 모드에서 가능한지 확실하게 알 수 없습니다. 그러나 조치를 살펴볼 수도 있습니다. 예를 들어 파이썬 코드를 실행하여 계산을 채울 수 있습니다. 글쎄 당신은 속성 표에서 그것을 실행하려면 추가 버튼을 눌러야합니다. 가능성을 살펴보고 아이디어에 맞는지 확인할 수 있습니다.
Matt

답변:


7

QGIS 내에 이러한 필드 만 필요한 경우 가상 필드를 사용할 수 있습니다. 이것들은 $length다른 값이나 기하학에 의존 하는 식 (예 :)을 사용할 수있게 합니다.

필드 계산기를 열고 이름 길이의 새 필드를 추가 한 다음 "가상 필드"확인란을 선택하고 $length표현식 (또는 다른 필드의 다른 항목)으로 입력하십시오 .

그러나 이들은 Excel 파일에 저장되지 않습니다.

Excel 파일 을 형상 의 shp 파일과 동기화하고 Excel 파일에 파생 필드를 포함 시키려면 ShpSync 라는 플러그인이 있으며이 개념을 인식하고 기능이 변경, 추가 또는 삭제 될 때 필드를 자동으로 업데이트합니다.


사실, 아래의 답변은 내가 원하는 방식으로 정확하게 작동하지만,이 플러그인은 내 프로젝트의 다음 단계에서 작동합니다. 도와 주셔서 감사합니다
LeoNazareth

15

재미있는 질문! 원하는 것을 달성하는 다른 방법은 없지만 PyQGIS를 사용하고 있습니다.

아래 코드를 읽으십시오. 그것은 그것의 일부 텍스트를 가지고 : 'lines', 'length', 'startX', 'startY', 'endX', 'endY'. 데이터에서 작업하기 위해 스크립트에서 해당 이름을 조정할 수 있습니다. 첫 번째는 레이어 이름이고 나머지는 필드 이름에 해당합니다. 선 레이어에 해당 필드가 있다고 가정합니다 (결국 거기에 값을 쓰려고합니다).

레이어 이름과 자동으로 업데이트 할 필드 이름을 조정했으면 스크립트를 복사하여 QGIS Python 콘솔에 붙여 넣습니다.

모든 것이 잘되면 필드 값이 두 가지 시나리오에서 자동으로 업데이트되는 것을 볼 수 있어야합니다. 1) 새 기능이 추가 된 경우 및 2) 지오메트리가 수정 된 경우.

# Initialize required variables
myLayer = QgsMapLayerRegistry.instance().mapLayersByName( 'lines' )[0]
lengthField = myLayer.fieldNameIndex( 'length' )
startXField = myLayer.fieldNameIndex( 'startX' )
startYField = myLayer.fieldNameIndex( 'startY' )
endXField = myLayer.fieldNameIndex( 'endX' )
endYField = myLayer.fieldNameIndex( 'endY' )

# Slot, updates field values
def updateFeatureAttrs( fId, geom=None ):
    f = myLayer.getFeatures( QgsFeatureRequest( fId ) ).next()    
    if not geom:
        geom = f.geometry() 
    myLayer.changeAttributeValue( fId, lengthField, geom.length() )
    myLayer.changeAttributeValue( fId, startXField, geom.vertexAt( 0 )[0] )
    myLayer.changeAttributeValue( fId, startYField, geom.vertexAt( 0 )[1] )
    myLayer.changeAttributeValue( fId, endXField, geom.asPolyline()[-1][0] )
    myLayer.changeAttributeValue( fId, endYField, geom.asPolyline()[-1][1] )

# Update feature attributes when new features are added or geometry changes
myLayer.featureAdded.connect( updateFeatureAttrs )
myLayer.geometryChanged.connect( updateFeatureAttrs )

이것이 작동하는 방식입니다.

QGIS에서 필드 자동 업데이트

스크립트를 실행하는 동안 문제가 발생하면이 답변 아래에 설명을 추가하십시오.

QGIS 프로젝트를 열 때이 기능을 이미 사용 가능하게하는 것이 편리 할 수 ​​있습니다. 그런 경우에는 지시를 게시하십시오.


편집하다:

QGIS 프로젝트를 열 때마다이 기능을 사용할 수 있으려면 (예 : .qgs라인 레이어를 포함 하는 파일) 다음 단계를 수행해야합니다.

  1. 로 이동 QGIS->Project->Project Properties->Macros하여 Python macros옵션을 확인하고 전체 코드를이 코드로 바꿉니다 (레이어 및 필드 이름을 나타내는 값 조정).

    from qgis.core import QgsMapLayerRegistry, QgsFeatureRequest
    def openProject():    
        # Initialize required variables
        myLayer = QgsMapLayerRegistry.instance().mapLayersByName( 'lines' )[0]
    
        # Update feature attributes when new features are added or geometry changes
        myLayer.featureAdded.connect( updateFeatureAttrs )
        myLayer.geometryChanged.connect( updateFeatureAttrs )
    
    # Slot, updates field values
    def updateFeatureAttrs( fId, geom=None ):
        myLayer = QgsMapLayerRegistry.instance().mapLayersByName( 'lines' )[0]
        lengthField = myLayer.fieldNameIndex( 'length' )
        startXField = myLayer.fieldNameIndex( 'startX' )
        startYField = myLayer.fieldNameIndex( 'startY' )
        endXField = myLayer.fieldNameIndex( 'endX' )
        endYField = myLayer.fieldNameIndex( 'endY' )
        f = myLayer.getFeatures( QgsFeatureRequest( fId ) ).next()    
        if not geom:
            geom = f.geometry() 
        myLayer.changeAttributeValue( fId, lengthField, geom.length() )
        myLayer.changeAttributeValue( fId, startXField, geom.vertexAt( 0 )[0] )
        myLayer.changeAttributeValue( fId, startYField, geom.vertexAt( 0 )[1] )
        myLayer.changeAttributeValue( fId, endXField, geom.asPolyline()[-1][0] )
        myLayer.changeAttributeValue( fId, endYField, geom.asPolyline()[-1][1] )
    
    def saveProject():
        pass
    
    def closeProject():
        pass
    
  2. 다음과 같은 방법으로 프로젝트에서 매크로를 활성화하십시오 Settings->Options->General->Enable macros: Always.

  3. QGIS 프로젝트를 저장하십시오.

이제 .qgs방금 저장 한 파일 을 열 때마다 새로운 피쳐를 추가하거나 형상을 수정할 때 라인 레이어의 속성이 자동으로 업데이트됩니다 (즉, 더 이상 QGIS Python Console에 아무 것도 복사 할 필요 없음).


2 차 편집 :

방금 사람들이 이런 종류의 문제를 해결할 수 있도록 AutoFields라는 플러그인을 게시했습니다 . 나는 당신의 소란을 해결하는 방법을 보여주는 비디오를 만들었습니다.

https://vimeo.com/germap/autofields-geometric-properties

AutoFields 설명서 : http://geotux.tuxfamily.org/index.php/en/geo-blogs/item/333-autofields-plugin-for-qgis


2
이것이 바로 내가 찾던 것입니다. 실제로 나는이 게시물 링크 의 이전 답변에서 찾은 X, Y 좌표를 잡기 위해 코드를 사용하고 있었고 지금 게시 한 것과 동일합니다. 나는 이미 자동화를 테스트했으며 완벽하게 작동합니다. 파이썬 코드를 ".pycl"파일로 저장했습니다. QGIS 프로젝트를 열 때 어떻게 사용할 수 있는지 설명해 주시면 좋습니다. 도와 주셔서 감사합니다.
LeoNazareth

1
독일어, 그거 대단한 대답이었습니다! 감사! 게시 한 내용을 통해 많은 것을 배웠습니다.
jbgramm

1
나는 실제로 당신이 정확히 그렇게 할 수있게 해주는 플러그인을 개발하고 있습니다. 여가 시간에만 개발에 전념 할 수 있기 때문에 출시 예정일을 알 수 없습니다. 그동안 Tramo.shp를 추가하고 다음을 조정 한 후 첫 번째 코드 스 니펫을 실행할 수 있습니다. myLayer = QgsMapLayerRegistry.instance().mapLayersByName( 'Tramo' )[0]향후 플러그인에 관심이 있다면 제안 사항을 보내 주시면 감사하겠습니다. GeoTux 에서 저에게 연락 할 수 있습니다 .
Germán Carrillo

1
그것은 나에게 좋을 것입니다 (물론 많은 사람들에게), 나는 당신이 제안한이 조정으로 코드를 이미 사용하고 있습니다. 나는 당신의 새로운 플러그인을 걱정스럽게 기다릴 것이고, 유용한 것으로 생각되면 연락을 드릴 것입니다. 모든 것에 감사드립니다.
LeoNazareth

1
@LeoNazareth, 플러그인을 테스트 하시겠습니까? 준비 중이지만 릴리스하기 전에 몇 가지 테스트를 수행하고 싶습니다. 시험해보고 싶으시면 이메일을 보내 주시기 바랍니다 .
Germán Carrillo

2

QGIS 3 받는 이동 Layers Properties=> Attributes Form=> (예, 기하학 값을 사용하여 필드를 선택 area) => 유형 $area에서 Defaults value상자와 체크 Apply default value on update. 이것은 또한 유용 할 수있다 : $perimeter, $y, $x,$id


1

데이터를 데이터베이스 (PostGIS)에 넣고 (아마 구체화 된)보기로 QGIS에 데이터를 추출합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.