Pertama kali pakai QGIS untuk olah data spasial, saya cuma pakai menu klik-klik doang. Klik Vector, klik Geoprocessing, klik Buffer. Capek banget kalau harus ulangin proses yang sama buat 50 layer. Akhirnya saya nemu kalau QGIS punya Python scripting yang bisa otomasiin semua itu. Sekarang, satu script 50 baris bisa gantiin kerja manual 2 jam.
PyQGIS adalah API Python yang disediakan QGIS untuk akses semua fitur GIS dari kode. Kamu bisa bikin processing script, plugin, atau bahkan menjalankan QGIS headless dari terminal tanpa GUI. Cocok banget buat GIS developer yang mau scale up workflow mereka.
QGIS punya built-in Python console yang bisa diakses dari menu Plugins -> Python Console. Di situ kamu bisa langsung ketik Python code dan QGIS akan eksekusi secara real-time. Ini cara paling cepat buat coba-coba PyQGIS.
# Ambil layer aktif di QGIS
layer = iface.activeLayer()
# Cek jumlah fitur
print(f"Jumlah fitur: {layer.featureCount()}")
# Cek CRS (Coordinate Reference System)
print(f"CRS: {layer.crs().authid()}")
# Loop semua fitur dan print atribut
for feature in layer.getFeatures():
print(feature['nama_kab'])
Kalau kamu familiar dengan Python, PyQGIS feel-nya mirip pakai library spatial seperti Fiona atau Shapely, tapi terintegrasi langsung dengan QGIS. Kamu bisa akses layer, symbology, processing tools, dan layout dari kode.
Ada 3 cara utama pakai Python di QGIS:
Processing Script adalah cara termudah buat mulai otomasi di QGIS. Kamu tulis script Python, simpan di folder processing, dan script muncul di Processing Toolbox seperti tool bawaan QGIS.
Misalnya kamu punya 10 shapefile kabupaten dan mau bikin buffer 5 km untuk masing-masing. Manual: klik 10 kali. Script: sekali run, selesai.
from qgis.core import (QgsProcessing, QgsProcessingAlgorithm,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterNumber,
QgsProcessingParameterFeatureSink,
QgsProcessingException)
import processing
class BufferBatchAlgorithm(QgsProcessingAlgorithm):
INPUT = 'INPUT'
DISTANCE = 'DISTANCE'
OUTPUT = 'OUTPUT'
def initAlgorithm(self, config=None):
self.addParameter(
QgsProcessingParameterFeatureSource(
self.INPUT, 'Input layer',
[QgsProcessing.TypeVectorAnyGeometry]))
self.addParameter(
QgsProcessingParameterNumber(
self.DISTANCE, 'Buffer distance (meters)',
QgsProcessingParameterNumber.Double,
defaultValue=5000))
self.addParameter(
QgsProcessingParameterFeatureSink(
self.OUTPUT, 'Buffered'))
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
distance = self.parameterAsDouble(parameters, self.DISTANCE, context)
if source is None:
raise QgsProcessingException("Invalid input layer")
# Jalankan native buffer
result = processing.run("native:buffer", {
'INPUT': parameters[self.INPUT],
'DISTANCE': distance,
'SEGMENTS': 25,
'END_CAP_STYLE': 0, # Round
'JOIN_STYLE': 0, # Round
'MITER_LIMIT': 2,
'DISSOLVE': False,
'OUTPUT': parameters[self.OUTPUT]
}, context=context, feedback=feedback)
return {self.OUTPUT: result['OUTPUT']}
def name(self):
return 'bufferbatch'
def displayName(self):
return 'Buffer Batch Processing'
def group(self):
return 'Custom Scripts'
def createInstance(self):
return BufferBatchAlgorithm()
Script di atas bikin tool "Buffer Batch Processing" yang muncul di Processing Toolbox. User tinggal pilih input layer, set jarak buffer, dan klik Run. Semua proses geoprocessing QGIS tersedia lewat processing.run().
Yang bikin PyQGIS powerfull adalah kamu bisa jalanin tanpa GUI. Ini cocok buat server-side processing atau cron job yang jalan otomatis setiap malam.
Di Ubuntu, QGIS menyediakan qgis_process CLI tool:
# Jalankan processing algorithm dari terminal
qgis_process run native:buffer -- \
INPUT=/data/kabupaten.shp \
DISTANCE=5000 \
SEGMENTS=25 \
END_CAP_STYLE=0 \
OUTPUT=/data/kabupaten_buffer.shp
# Jalankan custom script
qgis_process run script:/path/to/my_script.py -- \
INPUT=/data/points.shp \
DISTANCE=1000 \
OUTPUT=/data/buffer_result.gpkg
Buat Python headless tanpa qgis_process CLI, kamu bisa setup environment manual:
import sys
import os
# Set path ke QGIS Python (sesuaikan dengan instalasi kamu)
qgis_path = '/usr/share/qgis/python'
sys.path.insert(0, qgis_path)
os.environ['QT_QPA_PLATFORM'] = 'offscreen'
from qgis.core import (
QgsApplication, QgsProject, QgsVectorLayer,
QgsProcessingFeedback
)
# Inisialisasi QGIS tanpa GUI
qgs = QgsApplication([], False)
qgs.setPrefixPath('/usr', True)
qgs.initQgis()
# Load layer
layer = QgsVectorLayer('/data/jalan.shp', 'jalan', 'ogr')
if not layer.isValid():
print("Layer gagal di-load!")
sys.exit(1)
print(f"Layer loaded: {layer.name()}")
print(f"Features: {layer.featureCount()}")
print(f"CRS: {layer.crs().authid()}")
# Jalankan processing
import processing
result = processing.run("native:dissolve", {
'INPUT': layer,
'FIELD': ['jenis_jalan'],
'OUTPUT': '/data/jalan_dissolved.gpkg'
})
print(f"Output: {result['OUTPUT']}")
# Cleanup
qgs.exitQgis()
Simpan sebagai process_gis.py dan jalankan:
python3 process_gis.py
Kalau kamu deploy di server Ubuntu, install QGIS dulu:
# Tambahkan QGIS repo
sudo apt-get update
sudo apt-get install -y software-properties-common
sudo add-apt-repository ppa:ubuntugis/ubuntugis-unstable
sudo apt-get update
# Install QGIS dan processing
sudo apt-get install -y qgis qgis-plugin-grass
# Verifikasi instalasi
qgis_process --version
python3 -c "from qgis.core import QgsApplication; print('PyQGIS OK')"
Untuk tutorial setup VPS yang lebih lengkap, kamu bisa cek artikel tutorial MySQL indexing yang bahas optimasi database buat aplikasi GIS.
Ini use case yang paling sering saya temui. Kamu punya folder penuh shapefile dan mau apply proses yang sama ke semua file. Manual? Butuh seharian. Script? 5 menit.
import glob
import processing
from qgis.core import (
QgsVectorLayer, QgsProject, QgsProcessingFeedback
)
# Path ke folder berisi shapefiles
input_folder = '/data/raw/kabupaten/'
output_folder = '/data/processed/'
# Cari semua shapefile
shapefiles = glob.glob(f"{input_folder}/*.shp")
print(f"Ditemukan {len(shapefiles)} shapefile")
feedback = QgsProcessingFeedback()
for i, shp_path in enumerate(shapefiles, 1):
filename = shp_path.split('/')[-1].replace('.shp', '')
print(f"[{i}/{len(shapefiles)}] Processing: {filename}")
# Load layer
layer = QgsVectorLayer(shp_path, filename, 'ogr')
if not layer.isValid():
print(f" SKIP: {filename} tidak valid")
continue
# Step 1: Reproject ke EPSG:4326
reprojected = processing.run("native:reprojectlayer", {
'INPUT': layer,
'TARGET_CRS': 'EPSG:4326',
'OUTPUT': 'memory:'
}, feedback=feedback)
# Step 2: Fix geometri invalid
fixed = processing.run("native:fixgeometries", {
'INPUT': reprojected['OUTPUT'],
'OUTPUT': 'memory:'
}, feedback=feedback)
# Step 3: Simplifikasi geometri (kurangi ukuran file)
simplified = processing.run("native:simplifygeometries", {
'INPUT': fixed['OUTPUT'],
'TOLERANCE': 0.001,
'OUTPUT': 'memory:'
}, feedback=feedback)
# Step 4: Simpan ke GeoPackage
output_path = f"{output_folder}/{filename}.gpkg"
processing.run("native:savefeatures", {
'INPUT': simplified['OUTPUT'],
'OUTPUT': output_path,
'LAYER_NAME': filename
}, feedback=feedback)
print(f" Saved: {output_path}")
print("Batch processing selesai!")
Script di atas melakukan 4 tahap proses untuk setiap shapefile: reproject ke WGS84, fix geometri invalid, simplifikasi, dan simpan ke GeoPackage. Proses yang biasanya makan waktu berjam-jam kalau manual, selesai dalam hitungan menit.
Kalau kamu tertarik dengan database spatial untuk simpan hasil olahan, baca juga tutorial PostGIS untuk developer web yang bahas setup database spasial dari nol.
Plugin QGIS adalah cara paling profesional buat distribusi tools. Plugin bisa punya GUI, toolbar button, menu entry, dan bahkan icon sendiri. Untuk bikin plugin, kamu butuh Plugin Builder (install dari QGIS Plugin Manager).
Struktur folder plugin:
my_plugin/
__init__.py # Entry point
my_plugin.py # Main class
my_plugin_dialog.py # Dialog UI
my_plugin_dialog.ui # Qt Designer UI file
icon.png # Plugin icon
metadata.txt # Plugin metadata
README.md
Contoh plugin sederhana yang menambahkan fitur "Zoom to Selected Feature" di toolbar:
# __init__.py
def classFactory(iface):
from .zoom_to_selected import ZoomToSelectedPlugin
return ZoomToSelectedPlugin(iface)
# zoom_to_selected.py
from qgis.PyQt.QtWidgets import QAction
from qgis.PyQt.QtGui import QIcon
import os
class ZoomToSelectedPlugin:
def __init__(self, iface):
self.iface = iface
self.action = None
def initGui(self):
icon_path = os.path.join(os.path.dirname(__file__), 'icon.png')
self.action = QAction(
QIcon(icon_path),
"Zoom to Selected",
self.iface.mainWindow()
)
self.action.triggered.connect(self.run)
self.iface.addToolBarIcon(self.action)
self.iface.addPluginToMenu(
"&Zoom to Selected", self.action)
def unload(self):
self.iface.removeToolBarIcon(self.action)
self.iface.removePluginMenu(
"&Zoom to Selected", self.action)
def run(self):
layer = self.iface.activeLayer()
if layer is None:
self.iface.messageBar().pushWarning(
"Warning", "Pilih layer dulu")
return
selected = layer.selectedFeatures()
if not selected:
self.iface.messageBar().pushWarning(
"Warning", "Pilih fitur dulu")
return
# Zoom ke extent fitur yang dipilih
self.iface.mapCanvas().setExtent(
layer.boundingBoxOfSelected())
self.iface.mapCanvas().refresh()
Plugin ini simpel tapi berguna banget kalau kamu sering inspeksi fitur tertentu di dataset besar. Tinggal select fitur, klik toolbar button, dan QGIS langsung zoom ke sana.
Ini beberapa snippet yang sering saya pakai sehari-hari:
# 1. Ambil semua layer di project
project = QgsProject.instance()
for layer_id, layer in project.mapLayers().items():
print(f"{layer.name()} - {layer.type()}")
# 2. Filter fitur dengan expression
from qgis.core import QgsExpression, QgsFeatureRequest
expr = QgsExpression("populasi > 100000")
request = QgsFeatureRequest(expr)
for feature in layer.getFeatures(request):
print(feature['nama_kab'], feature['populasi'])
# 3. Tambah field baru ke layer
from qgis.core import QgsField
from qgis.PyQt.QtCore import QVariant
layer.startEditing()
layer.addAttribute(QgsField('luas_km2', QVariant.Double))
layer.updateFields()
for feature in layer.getFeatures():
area = feature.geometry().area() / 1e6 # m2 ke km2
layer.changeAttributeValue(
feature.id(),
layer.fields().indexOf('luas_km2'),
round(area, 2))
layer.commitChanges()
# 4. Export layer ke berbagai format
processing.run("gdal:vector_translate", {
'INPUT': layer,
'OUTPUT': '/data/output.geojson',
'OPTIONS': 'COORDINATE_PRECISION=6'
})
# 5. Buat layer dari GeoJSON string
from qgis.core import QgsVectorLayer
geojson = '{"type":"Point","coordinates":[106.8,-6.2]}'
point_layer = QgsVectorLayer(geojson, 'point', 'ogr')
PyQGIS sangat powerful tapi dokumentasinya kadang tersebar. Bookmark halaman PyQGIS Developer Cookbook di docs resmi QGIS - itu referensi paling lengkap.
Satu hal yang bikin frustrasi: error di PyQGIS kadang cuma muncul di QGIS Log Messages panel, bukan di console. Ini beberapa tips debugging:
# Aktifkan semua log messages
import qgis.utils
from qgis.core import QgsMessageLog
# Custom message log handler
def log_message(message, tag, level):
levels = {0: 'INFO', 1: 'WARNING', 2: 'CRITICAL'}
print(f"[{levels.get(level, 'UNKNOWN')}] {tag}: {message}")
QgsMessageLog.instance().messageReceived.connect(log_message)
# Error handling untuk processing
try:
result = processing.run("native:buffer", {
'INPUT': invalid_layer,
'DISTANCE': 1000,
'OUTPUT': 'memory:'
})
except QgsProcessingException as e:
print(f"Processing error: {str(e)}")
except Exception as e:
print(f"Unexpected error: {str(e)}")
Tips penting: selalu cek layer.isValid() sebelum proses. Layer yang gagal load biasanya karena path salah atau CRS bermasalah.
PyQGIS mengubah QGIS dari tool point-and-click jadi platform GIS development yang powerful. Dengan Python scripting, kamu bisa otomasiin proses geoprocessing yang berulang, bikin custom tools, dan bahkan jalanin GIS processing di server tanpa GUI.
Mulai dari Python Console buat eksperimen kecil, naik ke Processing Script buat workflow yang reuseable, dan kalau butuh distribusi ke tim, bikin plugin. Semua fleksibel dan scalable.
Punya pertanyaan soal PyQGIS atau mau share pengalaman otomasi GIS? Drop komentar di bawah!