การวิเคราะห์เส้นทางภูมิสารสนเทศด้วย pgRouting ใน ServBay
pgRouting
คือส่วนขยายที่ทรงพลังสำหรับฐานข้อมูล PostgreSQL และ PostGIS ซึ่งออกแบบมาเพื่อวิเคราะห์เส้นทางและเครือข่ายข้อมูลภูมิศาสตร์โดยเฉพาะ คุณสามารถใช้ pgRouting
เพื่อทำการค้นหาเส้นทางที่สั้นที่สุดระหว่างจุดสองจุด แก้ปัญหา Traveling Salesperson Problem (TSP) หรือวิเคราะห์ขอบเขตพื้นที่บริการ — ฟีเจอร์เหล่านี้จำเป็นมากสำหรับการสร้างแอปพลิเคชันแผนที่, การวางแผนโลจิสติกส์, และการวิเคราะห์จราจร
คู่มือฉบับนี้จะแนะนำขั้นตอนการเปิดใช้ pgRouting
บน ServBay ซึ่งเป็นสภาพแวดล้อมสำหรับพัฒนาเว็บแบบ local โดยละเอียด พร้อมการตั้งค่าพื้นฐานและตัวอย่างการวิเคราะห์เส้นทางให้คุณทำตามได้ทันที
ภาพรวม
ServBay คือเครื่องมือพัฒนา local บน macOS แบบ All-in-One สำหรับนักพัฒนา รวมเอา Web server, ฐานข้อมูล และภาษาโปรแกรมยอดนิยมมาให้ในตัว PostgreSQL ที่มากับ ServBay ได้รวมทั้ง pgRouting
และ PostGIS
ไว้แล้ว คุณไม่จำเป็นต้องดาวน์โหลดหรือคอมไพล์ส่วนขยายเหล่านี้เอง เพียงแค่เปิดใช้งานในฐานข้อมูลของคุณเท่านั้น
ข้อกำหนดเบื้องต้น
ก่อนเริ่มใช้งาน pgRouting
โปรดตรวจสอบข้อกำหนดดังต่อไปนี้:
- ติดตั้งและเปิดใช้งาน ServBay แล้ว: หากยังไม่ได้ติดตั้ง สามารถดาวน์โหลดเวอร์ชันล่าสุดได้ที่ ServBay เว็บไซต์ทางการ
- ติดตั้งและเปิดใช้งาน PostgreSQL package ใน ServBay: ในหน้าหลักของแอป ServBay ตรวจสอบให้แน่ใจว่า PostgreSQL ถูกติดตั้งและขึ้นสถานะ "กำลังทำงาน"
- มีความรู้พื้นฐานเกี่ยวกับ SQL และ PostgreSQL: คู่มือนี้สมมติว่าคุณเข้าใจ SQL และการดำเนินการขั้นพื้นฐานกับ PostgreSQL
- เข้าใจพื้นฐานของ PostGIS: เนื่องจาก
pgRouting
ต้องอาศัยPostGIS
ในการจัดการข้อมูลเชิงภูมิศาสตร์ ตรวจสอบว่าฐานข้อมูลของคุณได้เปิด PostGIS แล้ว (ซึ่ง ServBay จัดเตรียมมาให้ในแพ็คเกจ)
การติดตั้งและเปิดใช้งาน pgRouting
ServBay เตรียมไฟล์ส่วนขยาย pgRouting
มาให้เรียบร้อยแล้ว คุณเพียงแค่เปิดใช้งานมันกับฐานข้อมูลเป้าหมาย
เชื่อมต่อกับ PostgreSQL:
คุณสามารถเชื่อมต่อกับฐานข้อมูล PostgreSQL ได้หลายวิธี เช่นผ่าน
psql
บนเทอร์มินัล, เครื่องมือ GUI (เช่น pgAdmin, DBeaver) หรือไลบรารีของภาษาต่างๆวิธีที่ง่ายและรวดเร็วที่สุดคือใช้
psql
ผ่านเทอร์มินัลใน ServBay คุณสามารถกดปุ่ม "Terminal" ในแอปเพื่อเปิดเทอร์มินัลที่ตั้งค่าพาธให้เรียบร้อยแล้ว หรือจะเพิ่ม bin directory ของ ServBay ลงใน PATH เองก็ได้จากเทอร์มินัล ใช้คำสั่งต่อไปนี้เพื่อเชื่อมต่อกับฐานข้อมูลที่ต้องการ (ตัวอย่างใช้ชื่อ
servbay_geo_db
และ userservbay
):bashpsql -U servbay -d servbay_geo_db
1ถ้าชื่อฐานข้อมูล, username, หรือรหัสผ่านต่างกัน ให้ปรับคำสั่งให้ตรง
ตรวจสอบและเปิดใช้งาน PostGIS (ถ้ายังไม่ได้เปิด):
pgRouting
จำเป็นต้องใช้PostGIS
ให้แน่ใจว่าได้เปิด PostGIS ในฐานข้อมูล โดยรัน:sqlCREATE EXTENSION IF NOT EXISTS postgis;
1คำสั่งนี้จะสร้างส่วนขยาย PostGIS หรือข้ามถ้าติดตั้งอยู่แล้ว
สร้างส่วนขยาย pgRouting:
ในการเชื่อมต่อเดียวกัน รันคำสั่ง SQL ต่อไปนี้เพื่อสร้าง pgRouting:
sqlCREATE EXTENSION pgrouting;
1ถ้าสำเร็จจะแสดงข้อความ
CREATE EXTENSION
ตรวจสอบการติดตั้ง:
คุณสามารถตรวจสอบว่าส่วนขยายถูกติดตั้งแล้วหรือไม่ ด้วยคำสั่ง:
sql\dx
1ควรเห็น
postgis
กับpgrouting
ปรากฏในรายการ
การเตรียมข้อมูลถนนและสร้างโทโพโลยีสำหรับ pgRouting
อัลกอริทึมของ pgRouting
ต้องทำงานกับตารางที่ออกแบบให้เก็บโครงสร้างเครือข่ายถนน โดยปกติจะมีตารางที่เก็บแต่ละเส้นทาง (road segment) พร้อมจุดเริ่มต้น จุดปลาย และน้ำหนัก (เช่น ระยะทาง, เวลา) เพื่อวิเคราะห์เส้นทางอย่างมีประสิทธิภาพ ต้องสร้างโทโพโลยี — เชื่อมโยงจุด (nodes) กับแต่ละเส้นทาง (edges)
การสร้างตารางข้อมูลเครือข่ายถนน
ตัวอย่างนี้จะแสดงการสร้างตาราง ways
สำหรับเก็บข้อมูลถนน แต่ละแถวเก็บ ID เส้นทาง, ID จุดเริ่มและจุดสิ้นสุด, ต้นทุนเดินทางสองทิศทาง (cost
, reverse_cost
) และ geometry ของเส้นด้วยชนิด GEOMETRY
จาก PostGIS
sql
-- สร้างตารางหลักสำหรับข้อมูลถนน
CREATE TABLE ways (
id SERIAL PRIMARY KEY, -- Primary Key ของถนน (unique)
source INTEGER, -- Node เริ่มต้น
target INTEGER, -- Node สิ้นสุด
cost DOUBLE PRECISION, -- ต้นทุนเดินทางไปข้างหน้า (เช่น ระยะทาง, เวลา)
reverse_cost DOUBLE PRECISION, -- ต้นทุนย้อนกลับ
geom GEOMETRY(LineString, 4326) -- geometry ประเภท LineString, ใช้พิกัด WGS 84 (SRID 4326)
);
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
คำอธิบาย:
SERIAL PRIMARY KEY
: สร้างเลขรหัสเฉพาะอัตโนมัติให้แต่ละถนนsource
,target
: เก็บลำดับจุดเชื่อมต่อ (nodes) จะถูกเติมเต็มตอนสร้างโทโพโลยีcost
,reverse_cost
: น้ำหนัก (เช่น ระยะทาง, เวลา) กำหนดทิศทางได้ ถ้าเป็นทางเดินรถทางเดียวสามารถกำหนดreverse_cost
เป็น NULL หรือค่ามากๆgeom
: ใช้ชนิดข้อมูลเชิงภูมิศาสตร์จาก PostGIS สำหรับเก็บรูปร่างเส้นถนน
การเพิ่มข้อมูลตัวอย่าง
เพิ่มข้อมูลถนนตัวอย่างลงในตาราง ways
:
sql
-- เพิ่มถนนตัวอย่างลงใน ways
INSERT INTO ways (source, target, cost, reverse_cost, geom) VALUES
(1, 2, 1.0, 1.0, ST_SetSRID(ST_MakeLine(ST_MakePoint(116.4074, 39.9042), ST_MakePoint(116.4084, 39.9052)), 4326)),
(2, 3, 1.0, 1.0, ST_SetSRID(ST_MakeLine(ST_MakePoint(116.4084, 39.9052), ST_MakePoint(116.4094, 39.9062)), 4326)),
(3, 4, 1.0, 1.0, ST_SetSRID(ST_MakeLine(ST_MakePoint(116.4094, 39.9062), ST_MakePoint(116.4104, 39.9072)), 4326));
1
2
3
4
5
2
3
4
5
คำอธิบาย:
ST_MakePoint(x, y)
: สร้างจุดจากค่าพิกัดละติจูด ลองจิจูดST_MakeLine(point1, point2)
: สร้างเส้นเชื่อมสองจุดST_SetSRID(geometry, srid)
: กำหนดพิกัดอ้างอิงของ geometry- ข้อมูลตัวอย่างนี้คือสามเส้นถนนที่เชื่อมกันในพื้นที่ตัวอย่างของกรุงปักกิ่ง
การสร้างโทโพโลยี
หลังเตรียมข้อมูลถนน ให้ใช้ฟังก์ชัน pgr_createTopology
เพื่อวิเคราะห์ geometry หาจุดเชื่อมต่อ แล้วเติมค่าคอลัมน์ source
และ target
รวมถึงสร้างตาราง node (โดยทั่วไปชื่อ [ชื่อ_ตาราง]_vertices_pgr
)
sql
-- สร้างโทโพโลยีสำหรับตาราง ways
-- พารามิเตอร์:
-- 'ways' คือชื่อตาราง
-- 0.00001 คือ tolerance หรือระยะที่ใช้พิจารณาว่าสองจุดเป็น node เดียวกัน
-- 'geom' คือคอลัมน์ geometry
-- 'id' คือคอลัมน์ Primary Key
SELECT pgr_createTopology('ways', 0.00001, 'geom', 'id');
1
2
3
4
5
6
7
2
3
4
5
6
7
คำอธิบาย:
pgr_createTopology
: ฟังก์ชันหลักของ pgRouting สำหรับสร้างโมเดลกราฟ nodes-edges- tolerance (ค่าความใกล้): ระยะที่กำหนดว่าจุดไหนจัดเป็น node เดียวกัน แนะนำให้เลือกตามความละเอียดข้อมูลของคุณ
เมื่อรันสำเร็จ จะมีการเติมค่า source
, target
ใน ways
และสร้างตาราง ways_vertices_pgr
ที่รวม nodes ทั้งหมด
การวิเคราะห์เส้นทางด้วย pgRouting
เมื่อเตรียมโทโพโลยีแล้ว คุณสามารถใช้ฟังก์ชันวิเคราะห์เส้นทางใน pgRouting
ได้ทันที ตัวอย่างอัลกอริทึมยอดนิยม:
การหาเส้นทางสั้นที่สุด (Dijkstra)
หาเส้นทางที่สั้นที่สุดระหว่างสองจุด ใช้ Dijkstra algorithm ดังตัวอย่าง
sql
-- ค้นหาเส้นทางสั้นที่สุดจาก node 1 ไป node 4
-- 'SELECT id, source, target, cost FROM ways' เป็น query สร้างกราฟ ต้องมี id, source, target, cost
-- 1 คือ node เริ่ม, 4 คือ node สิ้นสุด
-- directed := true กำหนดกราฟมีทิศทาง
SELECT seq, id1 AS node, id2 AS edge, cost, geom
FROM pgr_dijkstra(
'SELECT id, source, target, cost FROM ways',
1, -- node เริ่ม
4, -- node สิ้นสุด
directed := true -- กำหนดทิศทาง; ถ้าต้องการตรวจสอบย้อนกลับ ตั้ง false หรือไม่ใส่
)
JOIN ways ON edge = ways.id; -- Join เพื่อดึง geometry เส้นทาง
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
คำอธิบาย:
pgr_dijkstra
: อัลกอริทึมหาเส้นทางสั้นที่สุด- Query แรกต้องให้ข้อมูล edge (id, source, target, cost)
- ถ้าต้องพิจารณาน้ำหนักย้อนกลับreverse_cost ต้องเปลี่ยน directed เป็น false และ query column ให้ครบ
- Join กับตาราง ways เพื่อเอา geometry ไปแสดงผล
ปัญหา Traveling Salesperson Problem (TSP)
TSP คือปัญหาการเดินทางเยี่ยมจุดให้ครบในต้นทุนต่ำสุด
sql
-- แก้ปัญหา TSP สำหรับ node 1, 2, 3, 4 โดยเริ่มจาก node 1
-- Query ต้องเลือก id, x, y (พิกัด)
-- start_id := 1 คือ node เริ่ม
SELECT seq, node, edge, cost
FROM pgr_tsp(
'SELECT id, ST_X(the_geom)::float8 AS x, ST_Y(the_geom)::float8 AS y FROM ways_vertices_pgr WHERE id IN (1, 2, 3, 4)',
start_id := 1
);
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
คำอธิบาย:
pgr_tsp
: แก้ปัญหา Traveling Salesperson- คิวรีจะดึงข้อมูล nodes ที่ต้องการเยี่ยม, ต้องมี
id
,x
,y
- นิยมใช้ตาราง
ways_vertices_pgr
ที่สร้างตอนทำโทโพโลยี
การวิเคราะห์พื้นที่บริการ (Driving Distance/Driving Time)
หาพื้นที่ที่เข้าถึงได้ภายใต้ค่าสูงสุด (เช่นระยะทาง เวลา) จากจุดเริ่มหนึ่งจุดหรือหลายจุด
sql
-- หาเส้นทาง/โซนที่เข้าถึงได้ใน cost ≤ 2 จาก node 1
SELECT seq, id1 AS node, id2 AS edge, cost, geom
FROM pgr_drivingDistance(
'SELECT id, source, target, cost FROM ways',
1, -- node เริ่ม
2, -- cost สูงสุด
directed := true
)
JOIN ways ON edge = ways.id;
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
คำอธิบาย:
pgr_drivingDistance
: ใช้คำนวณขอบเขตที่เข้าถึงได้ในต้นทุนที่กำหนด- Query ต้องเหมือนกับฟังก์ชันอื่น (id, source, target, cost)
- Join เพื่อแสดงผลข้อมูลเส้นแนวพื้นที่บริการ
การแสดงผลลัพธ์เส้นทางแบบ Visual
การแสดงผลลัพธ์ของ pgRouting
ในแผนที่ช่วยให้คุณเข้าใจและนำเสนอข้อมูลได้ดียิ่งขึ้น คุณสามารถเลือกวิธีแสดงผลได้ทั้งผ่านโปรแกรม GIS เช่น QGIS หรือในเว็บด้วยไลบรารีแผนที่
การใช้ QGIS (GIS Desktop)
QGIS เป็นซอฟต์แวร์ GIS ฟรียอดนิยม เชื่อมต่อกับ PostgreSQL/PostGIS ได้โดยตรง เหมาะสำหรับนักวิเคราะห์ข้อมูลภูมิศาสตร์
- เปิดโปรแกรม QGIS
- ไปที่ Layer (ชั้นข้อมูล) > Data Source Manager (ตัวจัดการแหล่งข้อมูล)
- เลือกเมนูซ้าย PostGIS
- กด New เพื่อสร้างการเชื่อมต่อฐานข้อมูล
- กรอกข้อมูลการเชื่อมต่อของ ServBay PostgreSQL เช่น Host:
localhost
| Port:5432
| Database:servbay_geo_db
| User:servbay
| Password: (ระบุรหัสผ่าน) - ทดสอบการเชื่อมต่อ และถ้าเชื่อมต่อสำเร็จจะเห็นตาราง
ways
และways_vertices_pgr
- เลือกตารางหรือ view ที่ต้องการ เช่น คำสั่ง query ผลลัพธ์เส้นทาง แล้วกด Add เพื่อแสดงผลใน QGIS
แสดงผลใน Web Application (Leaflet หรือ OpenLayers)
กรณีเว็บแอป คุณจำเป็นต้องมี backend (เช่น PHP, Node.js, Python บน ServBay) สั่งรัน query pgRouting และแปลงผลลัพธ์ geometry เป็น GeoJSON ให้ frontend นำข้อมูลไปแสดงด้วยไลบรารีแผนที่ Leaflet หรือ OpenLayers
ตัวอย่าง HTML แสดงเส้นทางใน Leaflet (ข้อมูล GeoJSON จำลอง):
html
<!DOCTYPE html>
<html>
<head>
<title>ตัวอย่างการแสดงผล pgRouting ด้วย ServBay</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<style>
#map { height: 600px; width: 100%; } /* ตั้งขนาดกล่องแผนที่ */
</style>
</head>
<body>
<h1>การแสดงผลเส้นทางด้วย pgRouting และ ServBay</h1>
<div id="map"></div>
<script>
// ตั้งค่าศูนย์กลางแผนที่และซูม
var map = L.map('map').setView([39.906, 116.409], 14);
// เพิ่มพื้นหลัง OpenStreetMap
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
// ข้อมูล GeoJSON จากผลลัพธ์ pgRouting (ตัวอย่าง)
var geojsonData = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"id": 1,
"cost": 1.0
},
"geometry": {
"type": "LineString",
"coordinates": [
[116.4074, 39.9042],
[116.4084, 39.9052]
]
}
},
{
"type": "Feature",
"properties": {
"id": 2,
"cost": 1.0
},
"geometry": {
"type": "LineString",
"coordinates": [
[116.4084, 39.9052],
[116.4094, 39.9062]
]
}
},
{
"type": "Feature",
"properties": {
"id": 3,
"cost": 1.0
},
"geometry": {
"type": "LineString",
"coordinates": [
[116.4094, 39.9062],
[116.4104, 39.9072]
]
}
}
]
};
// แสดง GeoJSON ลงแผนที่
L.geoJSON(geojsonData, {
style: function (feature) {
return {color: "#ff0000", weight: 4}; // เส้นสีแดง หนา
}
}).addTo(map);
// ปรับขอบเขตแผนที่ให้พอดีกับเส้นทาง
if (L.geoJSON(geojsonData).getBounds().isValid()) {
map.fitBounds(L.geoJSON(geojsonData).getBounds());
}
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
ให้บันทึกไฟล์ตัวอย่างนี้ลงเว็บไซต์ ServBay (เช่น /Applications/ServBay/www/pgrouting-demo/index.html
) แล้วเข้าใช้งานผ่านเบราว์เซอร์ — เช่น http://pgrouting-demo.servbay.demo
จะเห็นแผนที่และเส้นทางตัวอย่าง (ในระบบจริง GeoJSON ต้องมาจาก backend ผ่าน API)
ข้อควรระวังในการใช้งาน
- คุณภาพข้อมูล: ผลของ
pgRouting
ขึ้นอยู่กับคุณภาพของข้อมูลถนนเป็นสำคัญ ต้องตรวจสอบให้แน่ใจว่าข้อมูลครบถ้วนถูกต้องและตรงตามโทโพโลยีจริง - ประสิทธิภาพ: หากโครงข่ายถนนมีขนาดใหญ่มาก การคำนวณจะใช้เวลานาน ปรับปรุงประสิทธิภาพได้โดยการสร้าง index, ลดขนาดข้อมูล หรือเลือกอัลกอริทึมให้เหมาะสม
- การจัดการหน่วยความจำ: ข้อความโทโพโลยีขนาดใหญ่อาจใช้ RAM มาก ตรวจสอบว่าสเปคฐานข้อมูลของคุณเพียงพอ
คำถามที่พบบ่อย (FAQ)
ถาม: รัน CREATE EXTENSION pgrouting;
แล้วแจ้งว่าไม่มี extension นี้?
ตอบ: ตรวจสอบว่า PostgreSQL ของคุณใน ServBay ถูกติดตั้งและเปิดใช้งานแล้วหรือไม่ รวมทั้งรุ่นที่ใช้รองรับ pgRouting
หรือไม่ — ServBay ปกติจะเตรียมมาให้ ถ้ายังมีปัญหาให้ตรวจสอบ log ของ ServBay หรือ PostgreSQL เพิ่มเติม และตรวจสอบว่าบัญชีที่ใช้มีสิทธิ์พอ (เช่น user servbay
)
ถาม: จะเลือก tolerance ใน pgr_createTopology
อย่างไรดี?
ตอบ: tolerance ขึ้นอยู่กับความละเอียดตำแหน่งพิกัดของข้อมูล ยิ่งแม่นยำมาก (เช่นจาก GPS) ยิ่งควรตั้งให้น้อย (เช่น 0.000001 หรือน้อยกว่า) ถ้าข้อมูลมาจากหลายแหล่งหรือความละเอียดน้อย อาจต้องใช้ tolerance มากกว่านั้น (แต่ถ้ามากเกินไปจะเชื่อมเส้นโดยไม่ถูกต้อง)
ถาม: จะรองรับถนนเดินรถทางเดียวหรือห้ามกลับรถ/ยูเทิร์นได้อย่างไร?
ตอบ: กำหนดค่า cost
และ reverse_cost
ในตาราง ways
สำหรับทางเดียว ให้ reverse_cost
เป็น NULL หรือใหญ่สุด (ค่าไม่อนุญาตให้ย้อนทาง) สำหรับเรื่องห้ามกลับรถ อาจต้องโมเดลโครงข่ายซับซ้อนขึ้น หรือจัดการผลลัพธ์ทีหลัง — pgRouting มีฟีเจอร์ขั้นสูงรองรับบางกรณี
สรุป
ServBay ช่วยให้คุณติดตั้งและใช้งานฐานข้อมูล PostgreSQL ที่มีส่วนขยาย pgRouting
ได้ง่ายใน local development environment บน macOS เพียงเตรียมคำสั่ง SQL สั้นๆ คุณก็เปิดใช้งาน extension และสร้างโครงข่ายถนนพร้อมโทโพโลยีสำหรับวิเคราะห์เส้นทางภูมิศาสตร์ได้ ท่านสามารถแสดงผลเส้นทางทั้งใน QGIS หรือเว็บด้วย Leaflet/OpenLayers เพื่อตอบโจทย์โปรเจกต์ geo-spatial ได้ทันท่วงที ServBay ออกแบบมาเพื่อลดภาระการตั้งค่าซับซ้อนด้าน infrastructure ให้คุณโฟกัสกับการพัฒนา logic และฟีเจอร์หลักในแอปของคุณ