Velog Dark Theme
로 봐야 잘 보입니다 !
최근 python
을 배워봤는데, 이곳 저곳 쓸 수 있는 분야가 많다는 것에 많이 놀란다.
그리고 요즘 조금씩 끄적이고 있는 QGIS 에서도 Python 을 쓸 수 있다는 것을 알아냈다.
배우고 사용해보니, 일일이 손으로 하던 작업을 코드 한방에 해결하니 편한 점이 있었다.
하지만 시간이 지나면 까먹을 거 같아서 미리 기록해두려 한다.
일단은 당장 아는 것 까지만 작성하고, 추후에 뭔가 더 알아내게 되면
계속해서 글을 추가적으로 덧붙이는 식으로 작성하겠다.
(아직 초기여서 내용이 많지 않다 😥)
참고: 여기에서 사용하는
QGIS
버전은3.22.14-Białowieża
입니다.
ctrl + alt + p
를 누르면 콘솔 화면이 보인다.show editor
버튼 클릭하면 옆에 에디터 화면이 보인다.ctrl + shift + e
를 누르거나, 콘솔화면 상단의QgsProject.instance().setCrs(QgsCoordinateReferenceSystem(5186))
QGIS 에 위 그림처럼 미리 Layer 를 생성해 두고 아래처럼 코드를 실행해보면...
# 모든 레이어 조회
all_layers = QgsProject.instance().mapLayers().values()
print(all_layers)
# 이름으로 찾는 법. 하지만 이름은 얼마든지 중복될 수 있으니 조심!
specific_named_layers = QgsProject.instance().mapLayersByName('continue_map_layer')
print(specific_named_layers)
# tip: 만약에 특정 문자열이 있는 것을 찾거나 하고 싶다면...
# layerList
# = [lyr for lyr in QgsProject.instance().mapLayers().values()\
# if "triangle" in lyr.name()]
print 결과
print(all_layers) 결과:
dict_values([<QgsRasterLayer: 'Google Satellite' (wms)>, <QgsVectorLayer: 'continue_map_layer' (postgres)>, <QgsVectorLayer: 'rectangle_layer' (ogr)>])
print(specific_named_layers) 결과:
[<QgsVectorLayer: 'continue_map_layer' (postgres)>]
all_layers = QgsProject.instance().mapLayers().values()
for val in all_layers:
print(val.crs().authid())
출력은 아래와 같은 형태로 나온다
EPSG:3857
EPSG:5186
EPSG:4326
EPSG:4326
# point_4326 이라는 레이어를 조회한다.
point_4326 = QgsProject.instance().mapLayersByName('point_4326')[0]
### 참고:
### PC 에 있는 SHP 파일을 조회해서 바로 reproject 를 하고 싶다면?
### shp_path = 'C:/study/qgis/python/point_4326.shp'
### point_4326 = QgsVectorLayer(shp_path, 'rectangle_layer', 'ogr')
parameter = {
'INPUT': point_4326,
'TARGET_CRS': 'EPSG:5186',
'OUTPUT': 'memory:point_5186' # 실제 shp 파일로 저장하고 싶다면 경로 작성
}
result = processing.run('native:reprojectlayer', parameter)['OUTPUT']
QgsProject.instance().addMapLayer(result)
참고: 지리 좌표계인 레이어는 다른 투영 좌표계를 사용하는 레이어와 거리 연산(그외 벡터 연산 등)을 하기 위해서는 반드시 투영 좌표계로 재투영을 먼저 해줘야 한다.
shp_path_rectangles = 'C:/study/pyQGIS/rectangles.shp'
vector_layer = QgsVectorLayer(shp_path_rectangles, 'rectangle_layer', 'ogr')
QgsProject.instance().addMapLayer(vector_layer)
QgsVectorLayer
의 2번째 파라미터는 생성될 Layer
의 이름이고
3번째 파라미터는 shp 파일 포맷을 지원하는 라이브러리의 이름을 작성한 것이다.
QgsVectorLayer
가 받는 input(= 1번째 파라미터)
에 따라 3번째 인자값이 다르다.
uri = QgsDataSourceUri()
# 파라미터 순서대로...
### 1: host, 2: port , 3: database , 4: username, 5.: password
uri.setConnection('localhost', '5432', 'sdb_course', 'postgres', 'root')
# 1번째 인자: 스키마
# 2번째 인자: 테이블 명
# 3번째 인자: 지오메트리 컬럼
# 4번째 인자: where 구분을 작성하는 곳이다. ex) pnu like '4143%'
# 5번째 인자: primary key column
uri.setDataSource('public', 'continue_map', 'geom', '', 'pnu')
postgis_vector_layer = QgsVectorLayer(uri.uri(False), "continue_map_layer", "postgres")
QgsProject.instance().addMapLayer(postgis_vector_layer)
# https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z} 중에서
# 일부만 url encoding 하여 urlWithParams 문자열에 적용
urlWithParams = 'type=xyz&url=https://mt1.google.com/vt/lyrs%3Ds%26x%3D%7Bx%7D%26y%3D%7By%7D%26z%3D%7Bz%7D&zmax=19&zmin=0'
rlayer = QgsRasterLayer(urlWithParams, 'Google Satellite', 'wms')
if rlayer.isValid():
QgsProject.instance().addMapLayer(rlayer)
else:
print('invalid layer')
# 전체 삭제
QgsProject.instance().removeAllMapLayers()
# 특정 하나 삭제
layers = QgsProject.instance().mapLayersByName('continue_map_layer')
QgsProject.instance().removeMapLayer(layers[0].id())
from qgis.core import *
import qgis.utils
layer = qgis.utils.iface.activeLayer()
for feat in layer.getFeatures():
print(feat.geometry().asWkt());
PostGIS
테이블의 geometry
정보와 Intersect
, Within
같은
공간연산 쿼리로 짜기 위해서 비교대상이 되는 테스트 데이터가 필요한 경우가 많았다.
그럴 때 QGIS 에서 임시 스크래치 레이어
를 생성하고,
레이어에 도형을 그린 위의 Python
코드를 돌려서 WKT
문자열을 구하면 쉽게
PostGIS 에서 테스트를 돌릴 수 있다.
select
st_setsrid(
st_geomfromewkt('WKT문자열 복붙!')
, 5186)
그런데 만약 하나의 Geometry
에 대해서만 WKT 의 값을 알고 싶은 것이라면
QGIS
의 Identify Feature
기능을 사용하면 된다. (아래 그림 참고)