สร้างฟิลด์ใหม่ทุกเลเยอร์ และคำนวณเนื้อที่ใน QGIS โดยใช้ไพธอน ไม่ใช่เรื่องยาก ในกรณีที่ท่านไม่เคยใช้งานไพธอนมาก่อน ก็น่าจะทำได้เช่นกัน ในบล็อกนี้พยายามอธิบายวิธีการขั้นตอนโดยละเอียดแล้ว
มีคำถามว่า “ถ้าต้องการสร้างฟิลด์ใหม่สำหรับคำนวณทุกเลเยอร์ใน QGIS จะต้องทำอย่างไร”
คำตอบนั้นมีหลากหลาย แต่สำหรับ DataRevol.com นั้นเลือกที่จะใช้ไพธอนในการจัดการ
แนวคิดหลักของสคริปต์ (Conceptual Model)
สคริปต์นี้ จะตอบโจทย์ 4 ข้อ:
- ประมวลผลทุกเลเยอร์ในโปรเจกต์ (ไม่ต้องเลือกทีละเลเยอร์)
- เลือกเฉพาะ Vector Layer ที่เป็น Polygon (ถ้าเป็นจุดหรือเส้นจะข้ามไป)
- ตั้งค่า CRS ให้เครื่องมือคำนวณพื้นที่ทุกครั้งตามเลเยอร์ (เนื่องจากอาจะมี CRS ต่างกัน)
- ป้องกันข้อมูลผิดพลาด (geometry เสีย, NaN, NULL)
หัวใจสคริปต์นี้คือคลาส `QgsDistanceArea` ซึ่งทำหน้าที่คำนวณพื้นที่
ปัญหาที่พบบ่อยในการคำนวณพื้นที่ใน QGIS
จากการทำงาน พบปัญหาความคลาดเคลื่อนดังนี้
- คำนวณพื้นที่แล้วได้ค่า `NULL` หรือ `NaN`
- เลเยอร์แต่ละชุดใช้ระบบพิกัด (CRS) ไม่เหมือนกัน
สาเหตุหลักคือ:
- การคำนวณพื้นที่ ขึ้นกับระบบพิกัดของข้อมูล
- พื้นที่ในหน่วยองศา (degree) เพราะเป็นระบบพิกัดแบบ Geographic Coordinate System – GCS
สคริปต์นี้ออกแบบมาเพื่อแก้ปัญหาเหล่านี้
โครงสร้างการทำงานของสคริปต์ (Flow)
ลำดับการทำงานเป็นดังนี้:
- จัดการกับเลเยอร์ทั้งหมดในโปรเจกต์
- กรองเฉพาะเลเยอร์ที่เป็น Polygon
- ตั้งค่า CRS ให้ตัวคำนวณพื้นที่ตามเลเยอร์นั้น
- เปิดโหมดแก้ไขข้อมูล (Editing)
- เพิ่มฟิลด์ `Area_Calc` ถ้ายังไม่มี
- คำนวณพื้นที่ทีละเลเยอร์
- บันทึกผลลัพธ์
วิธีใช้งานจริง (Step-by-step)
- เปิด QGIS และโปรเจกต์ที่มีเลเยอร์ Polygon
- ไปที่เมนู Plugins → Python Console
- เปิดแท็บ Editor
- วางสคริปต์ทั้งหมดลงไป
- กด Run Script
- ตรวจสอบ Attribute Table ของแต่ละเลเยอร์

จะพบฟิลด์ `Area_Calc` พร้อมค่าพื้นที่ (ตารางเมตร)
โปรดคัดลอกสคริปต์ที่ GitHub
โปรดชมวิธีใช้งานสคริปต์นี้ด้านล่าง
อธิบายโค้ด
Import โมดูลที่จำเป็น
from qgis.core import (
QgsProject,
QgsField,
QgsDistanceArea,
QgsMapLayerType,
QgsWkbTypes
)
from qgis.PyQt.QtCore import QVariant
ขั้นแรกคือการนำเข้าโมดูลต่าง ๆ ที่จำเป็นสำหรับการดำเนินการ
- `QgsProject` : เข้าถึงโปรเจกต์ปัจจุบัน
- `QgsDistanceArea` : เครื่องมือคำนวณพื้นที่/ระยะทาง
- `QgsMapLayerType`, `QgsWkbTypes` : ใช้ตรวจสอบชนิดเลเยอร์
- `QgsField`, `QVariant` : ใช้สร้างฟิลด์ใหม่
การตั้งค่าพื้นฐาน
field_name = 'Area_Calc'
project = QgsProject.instance()
คำอธิบาย
- `Area_Calc` คือชื่อฟิลด์ผลลัพธ์ (หรือจะเปลี่ยนเป็นอื่น ๆ ได้ตามต้องการ) สร้างฟิลด์ใหม่ทุกเลเยอร์
- `project` คืออ้างอิงโปรเจกต์ที่เปิดอยู่ใน QGIS
การเตรียมเครื่องมือคำนวณพื้นที่
d = QgsDistanceArea(
d.setEllipsoid(project.ellipsoid())
– ใช้ Ellipsoid เดียวกับโปรเจกต์ (สำหรับประเทศไทยมักใช้กับ EPSG 24047 / 24048)
การวนลูปทุกเลเยอร์ในโปรเจกต์
for layer in project.mapLayers().values():
จากนั้นกรองเฉพาะเลเยอร์ที่เป็น Polygon
if layer.type() != QgsMapLayerType.VectorLayer:
continue
if layer.geometryType() != QgsWkbTypes.PolygonGeometry:
continue
เลเยอร์เส้น (Line) หรือจุด (Point) จะถูกข้ามทันที
ตั้งค่า CRS ให้ QgsDistanceArea
d.setSourceCrs(layer.crs(), project.transformContext())
บรรทัดนี้คือ หัวใจของสคริปต์ หากไม่มีบรรทัดนี้:
- QGIS ไม่รู้ว่าค่าพิกัดอยู่ในหน่วยอะไร
- ผลลัพธ์พื้นที่จะเป็น `NaN` ถ้าเป็นระบบพิกัดแบบ Geographic Coordinate System
แนวคิดคือ พื้นที่จะถูกคำนวณตาม CRS ของแต่ละเลเยอร์ ไม่ใช่ CRS ของโปรเจกต์
สร้างฟิลด์ใหม่ทุกเลเยอร์
if layer.fields().indexFromName(field_name) == -1:
layer.dataProvider().addAttributes([
QgsField(field_name, QVariant.Double, 'double', 20, 3)
])
layer.updateFields()
- ป้องกันการเพิ่มฟิลด์ซ้ำ ถ้ามีฟิลด์ชื่อนี้อยู่แล้วจะไม่สร้างใหม่
- ใช้ data type เป็น `Double`
- ทศนิยม 3 ตำแหน่ง
การคำนวณพื้นที่รายฟีเจอร์
geom = feature.geometry()
ตรวจสอบ geometry ก่อน
if geom is None or geom.isEmpty():
continue
คำนวณพื้นที่
area_val = d.measureArea(geom)
ป้องกันค่า NaN:
if area_val is None or area_val != area_val:
continue
บันทึกค่าลงฟิลด์:
layer.changeAttributeValue(
feature.id(),
field_index,
round(area_val, 3)
)
บันทึกผลลัพธ์
layer.commitChanges()
หากไม่ commit การเปลี่ยนแปลง ข้อมูลจะไม่ถูกบันทึก
เมื่อเข้าใจแนวคิดเรื่อง CRS และ `QgsDistanceArea` แล้ว การคำนวณพื้นที่ใน QGIS จะง่ายขึ้น