pyQGIS를 이용한 벡터 데이터 처리 7 : 새 피쳐 추가하기, 피쳐 제거하기

벡터 레이어에 새로운 피쳐를 추가하는 코드는 다음과 같습니다.

QgsProject.instance().removeAllMapLayers()
layer = QgsVectorLayer("D:/__Data__/세종특별자치시_36000/TL_SPRD_MANAGE.shp", "TL_SPRD_MANAGE", "ogr")
QgsProject.instance().addMapLayers([layer])

caps = layer.dataProvider().capabilities()
if caps & QgsVectorDataProvider.AddFeatures:
    feat = QgsFeature(layer.fields())
    feat.setAttribute("RN", "테스트로") # feat.setAttributes([.., .., .., ...])
    geom = QgsGeometry.fromWkt("MULTILINESTRING((968963 1820821, 993152 1819742, 993567 1844387))")
    feat.setGeometry(geom)
    result, outFeature = layer.dataProvider().addFeatures([feat])
    print(result, outFeature)

다음은 피쳐를 삭제하는 코드입니다.

QgsProject.instance().removeAllMapLayers()
layer = QgsVectorLayer("D:/__Data__/세종특별자치시_36000/TL_SPRD_MANAGE.shp", "TL_SPRD_MANAGE", "ogr")
QgsProject.instance().addMapLayers([layer])

caps = layer.dataProvider().capabilities()
fids = []

if caps & QgsVectorDataProvider.DeleteFeatures:
    features = layer.getFeatures()
    for feat in features:
        if feat["RN"] == "테스트로":
            fids.append(feat.id())
    res = layer.dataProvider().deleteFeatures(fids)
    print(res, len(fids))            
    
#layer.triggerRepaint()

pyQGIS를 이용한 벡터 데이터 처리 6 : 피쳐의 속성 및 좌표 편집

이미 저장되어 있는 피쳐의 속성과 좌표를 변경하는 코드를 살펴보겠습니다. 먼저 피쳐의 속성값을 변경하는 코드는 다음과 같습니다.

QgsProject.instance().removeAllMapLayers()

layer = QgsVectorLayer("D:/__Data__/세종특별자치시_36000/TL_SPRD_MANAGE.shp", "TL_SPRD_MANAGE", "ogr")
QgsProject.instance().addMapLayers([layer])
layer.selectByExpression('"RN_CD" = \'3251036\'')
idxField = layer.fields().indexOf('RN')

features = layer.selectedFeatures()
with edit(layer):
    for f in features:
        layer.changeAttributeValue(f.id(), idxField, "짱기로")

위의 코드는 먼저 RN_CD의 값이 3251036인 피쳐를 선택하고 선택된 피쳐의 RN 필드의 값을 “짱기로”로 변경하는 코드입니다.

다음은 위와 동일한 조건으로 피쳐를 선택하고 선택된 피쳐의 좌표를 편집하는 코드입니다.

QgsProject.instance().removeAllMapLayers()

layer = QgsVectorLayer("D:/__Data__/세종특별자치시_36000/TL_SPRD_MANAGE.shp", "TL_SPRD_MANAGE", "ogr")
QgsProject.instance().addMapLayers([layer])
layer.selectByExpression('"RN_CD" = \'2348142\'')

features = layer.selectedFeatures()
with edit(layer):
    for f in features:
        geom = QgsGeometry.fromWkt("MULTILINESTRING((968963 1820821, 993152 1819742, 993567 1844387))")
        layer.changeGeometry(f.id(),geom)

새롭게 정의할 도형의 좌표를 WKT 형식으로 지정하였습니다.

Rust 개발 환경 구성

VS.Code를 이용하므로 이 사이트에서 Rust 개발환경 구성을 참조하였음.

매우 간단한데 rustup-init.exe를 다운로드 받아 실행시키면 콘솔에서 설치가 진행됨. Rust 컴파일러와 Cargo 실행 파일 등이 최신 버전으로 설치가 되며 Path까지 잡아줌. 나중에 Uninstall은 어찌하라는 것인지… 그냥 폴더와 Path 잡힌 것만 제거하면 되는 것인가? VS.Code에서 확장은 rust-analyzer와 CodeLLDB를 설치해주면 됨. 각각 코드 하일라이팅 등의 기능 제공과 디버깅 기능을 제공함.

Rust 프로젝트를 하나 생성하기 위해서는 콘설에서 다음 코드를 실행하면 됨. 원하는 폴더에서 아래 명령을 실행하면 hello_world라는 폴더가 만들어지고 필요한 파일도 생성됨.

cargo new hello_world

VS.Code를 실행하고 hello_world 폴더를 열면 됨. 그리고 컴파일은 VS.Code의 Shell에서 다음 명령을 실행하면 됨. 아래 명령을 통해 실행 파일이 만들어짐.

cargo build

컴파일과 함께 실행을 동시에 하고 싶다면 다음 명령.

cargo run

물론 VS.Code에서도 그냥 실행이 가능하고 라인 단위 디버깅도 가능함. (단, launch.json 파일 생성이 필요하고 앞서 언급한 CodeLLDB 확장 기능 설치가 필요함.

pyQGIS를 이용한 벡터 데이터 처리 5 : 피쳐 선택하고 저장하기

가장 먼저 피쳐의 ID 값으로 선택하는 코드입니다.

QgsProject.instance().removeAllMapLayers()
layer = QgsVectorLayer("D:/__Data__/세종특별자치시_36000/TL_SPRD_MANAGE.shp", "TL_SPRD_MANAGE", "ogr")
QgsProject.instance().addMapLayers([layer])

selectid = [0, 1, 2, 3, 4]
layer.select(selectid)

아래는 선택된 피쳐를 순회하는 코드입니다.

QgsProject.instance().removeAllMapLayers()
layer = QgsVectorLayer("D:/__Data__/세종특별자치시_36000/TL_SPRD_MANAGE.shp", "TL_SPRD_MANAGE", "ogr")
QgsProject.instance().addMapLayers([layer])

selectid = [0, 1, 2, 3, 4]
layer.select(selectid)
QgsProject.instance().removeAllMapLayers()
layer = QgsVectorLayer("D:/__Data__/세종특별자치시_36000/TL_SPRD_MANAGE.shp", "TL_SPRD_MANAGE", "ogr")
QgsProject.instance().addMapLayers([layer])

selectid = [0, 1, 2, 3, 4]
layer.select(selectid)

selection = layer.selectedFeatures()
for feat in selection:
    print(feat['RN'])

다음은 SQL의 Where 조건 형태의 조건으로 피쳐를 선택하고 선택된 피쳐만을 새로운 SHP 파일로 저장하는 코드입니다.

QgsProject.instance().removeAllMapLayers()

layer = QgsVectorLayer("D:/__Data__/세종특별자치시_36000/TL_SPRD_MANAGE.shp", "TL_SPRD_MANAGE", "ogr")
QgsProject.instance().addMapLayers([layer])
layer.selectByExpression('"RN" like \'%로\'')

fn = "D:/__Data__/aa.shp"
writer = QgsVectorFileWriter.writeAsVectorFormat(layer, fn, 
    "utf-8", 
    driverName="ESRI ShapeFile", 
    onlySelected=True
)

print("DONE")

newLayer = QgsVectorLayer(fn, "aa")
QgsProject.instance().addMapLayers([newLayer])

다음은 사각형 영역을 지정해서 이 영역과 교차하는 피쳐를 선택하는 코드입니다.

QgsProject.instance().removeAllMapLayers()
layer = QgsVectorLayer("D:/__Data__/세종특별자치시_36000/TL_SPRD_MANAGE.shp", "TL_SPRD_MANAGE", "ogr")
QgsProject.instance().addMapLayers([layer])

areaOfInterest = QgsRectangle(982413, 1835226, 987413, 1840226)
request = QgsFeatureRequest().setFilterRect(areaOfInterest)

selected = []

for feature in layer.getFeatures(request):
    selected.append(feature.id())
    
layer.select(selected)