如何在 ServBay 中使用 PostGIS:為 PostgreSQL 加入地理空間能力
PostGIS
是一款功能強大的 PostgreSQL 資料庫擴充套件,能夠為 PostgreSQL 提供地理空間資料型態、函數與索引支援。這代表您可以在資料庫中儲存點、線、多邊形等空間資訊,並執行複雜的空間查詢與分析。對於處理地圖、定位服務或任何與地理資訊相關的網頁應用開發者而言,PostGIS 絕對是不可或缺的重要工具。
ServBay 是專為 macOS 設計的本地網頁開發環境,已整合 PostgreSQL 套件,且預設捆綁了 PostGIS 擴充套件。這大幅簡化本地使用 PostGIS 的流程,無需自行編譯或安裝依賴。
本文將詳細介紹如何在 ServBay 環境下啟用並開始使用 PostGIS,協助您快速為專案加入地理空間應用能力。
前置準備
在使用 PostGIS 之前,請確保您已完成以下準備:
- 安裝並執行 ServBay: 請確定您已在 macOS 系統上成功安裝 ServBay。
- 啟用並啟動 PostgreSQL 套件: 於 ServBay 控制面板確認 PostgreSQL 套件已啟用且正在執行。如尚未啟用,請於控制面板中勾選啟用後啟動該套件。
- 連線 PostgreSQL 資料庫: 了解如何利用指令列工具
psql
或圖形化客戶端(如 TablePlus、pgAdmin)連接到 ServBay 執行的 PostgreSQL 資料庫。預設情況下,您可透過psql -U postgres
直接連線本機資料庫。
安裝與啟用 PostGIS 擴充套件
ServBay 已預先安裝好 PostGIS 擴充套件檔案,無需額外下載。您只需在欲使用 PostGIS 的指定資料庫內「啟用」該擴充套件即可。
以下為啟用 PostGIS 擴充套件的步驟:
連線至目標 PostgreSQL 資料庫: 開啟終端機應用程式,以
psql
命令連線至您的資料庫。請將your_username
替換為資料庫使用者名稱(例如postgres
),your_database
替換為欲啟用 PostGIS 的資料庫名稱。bashpsql -U your_username -d your_database
1若想於預設的
postgres
使用者與資料庫啟用,可直接執行:bashpsql -U postgres
1在資料庫中建立 PostGIS 擴充套件: 連線成功後,於
psql
指令列介面執行以下 SQL 指令:sqlCREATE EXTENSION postgis;
1此指令會於目前連線的資料庫安裝及設定 PostGIS 所需的所有物件(如新增資料型態、函數、運算子等)。
驗證 PostGIS 是否成功安裝: 於
psql
指令列中,可使用\dx
指令列出當前資料庫已安裝的所有擴充套件。sql\dx
1若 PostGIS 擴充套件已成功啟用,您將於列表中看見
postgis
條目及其版本資訊。List of installed extensions Name | Version | Schema | Description -----------+---------+------------+-------------------------------------------------------------- plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language postgis | 3.3.2 | public | PostGIS geometry and geography spatial types and functions (2 rows)
1
2
3
4
5
6(注意:PostGIS 版本號可能依 ServBay 版本而有差異)
至此,您已成功於指定的 PostgreSQL 資料庫啟用了 PostGIS 擴充套件,可立即開始運用其地理空間功能。
設定 PostGIS 資料
啟用 PostGIS 後,您可建立包含地理空間資料的新資料表,或於現有表格新增地理空間欄位。PostGIS 提供 geometry
和 geography
兩大主要空間資料型態。geometry
適用於平面座標計算;geography
則能處理球體座標系(如地球曲面),特別適合儲存與查詢經緯度資料。
建立帶有地理空間欄位的資料表
以下範例說明如何建立名為 locations
的資料表,並新增一個專儲存點位的地理空間欄位。
建立資料表: 於已連線的
psql
或圖形化客戶端執行:sqlCREATE TABLE locations ( id SERIAL PRIMARY KEY, name VARCHAR(100), geom GEOMETRY(Point, 4326) );
1
2
3
4
5GEOMETRY(Point, 4326)
:指定geom
欄位型態為GEOMETRY
,儲存點(Point)幾何,SRID4326
代表 WGS84 座標系,為 GPS 與多數線上地圖(如 OpenStreetMap、Google Maps)通用經緯度標準。- 您可根據需求選用其他幾何型態(如
LineString
、Polygon
、MultiPoint
等)及不同 SRID。
插入範例資料: 利用 PostGIS 函數將幾何資料插入表中。
ST_GeomFromText()
常用於自 WKT 格式(Well-Known Text)生成幾何物件。sqlINSERT INTO locations (name, geom) VALUES ('ServBay 總部', ST_GeomFromText('POINT(116.4074 39.9042)', 4326)), -- 北京座標範例 ('ServBay 上海辦公室', ST_GeomFromText('POINT(121.4737 31.2304)', 4326)); -- 上海座標範例
1
2
3注意,
POINT(經度 緯度)
的順序遵循 WKT 標準。
建立地理空間索引
面對大量地理空間資料,建立空間索引對提升查詢效能至關重要,特別是範圍查詢、包含查詢或最近鄰查詢。PostGIS 最常見的空間索引為 GiST(Generalized Search Tree)索引。
建立 GiST 索引: 於已連線的
psql
或資料庫客戶端執行:sqlCREATE INDEX idx_locations_geom ON locations USING GIST (geom);
1此命令會於
locations
表的geom
欄位建立 GiST 索引。查詢優化器會自動利用該索引加速空間查詢。
運用 PostGIS 進行地理空間查詢
PostGIS 提供上百種地理空間函數,涵蓋各類查詢運算。下列舉出部份在網頁應用開發時常用的查詢範例:
查詢兩點距離
計算兩地理位置間的直線距離。
SELECT ST_Distance(
ST_GeomFromText('POINT(116.4074 39.9042)', 4326), -- 點 A
ST_GeomFromText('POINT(121.4737 31.2304)', 4326) -- 點 B
);
2
3
4
ST_Distance()
:計算兩個幾何物件間的距離。對geometry
型態且 SRID 4326 的物件,回傳單位為度的近似值。若需更精確、以公尺為單位的值,建議改用geography
型態或ST_Distance(geography_a, geography_b, use_spheroid)
函數。
查詢包含關係
判斷一幾何物件是否包含另一個,舉例查詢某點是否落於特定區域(多邊形)內。
SELECT name FROM locations
WHERE ST_Contains(
ST_GeomFromText('POLYGON((116.0 39.0, 117.0 39.0, 117.0 40.0, 116.0 40.0, 116.0 39.0))', 4326), -- 矩形區範例
geom
);
2
3
4
5
ST_Contains(geometry A, geometry B)
:若幾何 A 完全包含幾何 B 回傳 true。
查詢最近鄰
尋找與某指定點最接近的地點。GiST 索引可高效支援該類查詢。
SELECT name, ST_Distance(geom, ST_GeomFromText('POINT(116.4074 39.9042)', 4326)) AS distance
FROM locations
ORDER BY geom <-> ST_GeomFromText('POINT(116.4074 39.9042)', 4326) -- 利用 <-> 運算子搭配 GiST 索引排序
LIMIT 5;
2
3
4
<->
運算子為 PostGIS 提供的「距離排序」符號,能配合 GiST 索引高速搜尋與指定地理物件最近的資料。
運用 PostGIS 進行地理空間分析
除了基本查詢,PostGIS 還有強大的地理分析函數,像是建立緩衝區、計算交集、合併幾何等。
緩衝區分析
為某幾何物件創建指定距離的緩衝區(多邊形區域)。
SELECT ST_Buffer(geom, 0.01) -- 以度為單位建立緩衝區,0.01 度約為 1.1 公里
FROM locations
WHERE name = 'ServBay 總部';
2
3
ST_Buffer(geometry, distance)
:依指定距離建立緩衝多邊形。對經緯度座標的geometry
型態,距離單位同座標(通常為度)。
交集分析
計算幾何物件間重疊區域,返回新的幾何物件。
SELECT ST_Intersection(
ST_GeomFromText('POLYGON((116.0 39.0, 117.0 39.0, 117.0 40.0, 116.0 40.0, 116.0 39.0))', 4326),
geom
)
FROM locations
WHERE name = 'ServBay 總部';
2
3
4
5
6
ST_Intersection(geometry A, geometry B)
:回傳 A 與 B 交疊的幾何物件。
合併分析
將多個幾何合併成單一(或可能為多部分的)幾何物件。
SELECT ST_Union(geom)
FROM locations;
2
ST_Union(geometry set)
:將所有輸入集合中的幾何物件合併為一。
地理空間資料視覺化
將儲存在 PostGIS 資料庫中的地理空間資料視覺化是許多網頁開發的常見需求。您可以運用桌面 GIS 軟體或網頁地圖前端工具達成。
使用桌面 GIS 工具(如 QGIS)
QGIS 是知名的開源桌面 GIS 軟體,可直接連線至 PostGIS 資料庫,並呈現空間資料。
連線至 ServBay 的 PostgreSQL 資料庫:
- 開啟 QGIS。
- 選擇功能表
圖層 (Layer)
->新增圖層 (Add Layer)
->新增 PostGIS 圖層... (Add PostGIS Layers...)
。 - 彈出窗口點選
新建 (New)
,建立新的資料庫連線。 - 資料連線設定:
- Name (名稱): 輸入描述性名稱,如
ServBay PostGIS
。 - Host (主機):
localhost
或127.0.0.1
。 - Port (埠號): PostgreSQL 預設
5432
(ServBay 亦然)。 - Database (資料庫): 您欲啟用 PostGIS 的資料庫名稱。
- Username (用戶): 您的資料庫使用者名稱(如
postgres
)。 - Password (密碼): 若有設定請輸入。
- Name (名稱): 輸入描述性名稱,如
- 點選
Test Connection (測試連線)
,確認成功。 - 按下
OK
儲存後,主界面再點選Connect (連線)
。
載入地理空間資料:
- 連線成功後,可見所有資料表。
- 找出具有空間欄位的表(如
locations
),QGIS 會自動辨識空間欄。 - 選取欲載入的表後,點擊
Add (新增)
,再點選Close (關閉)
,地理空間資料即會顯示於 QGIS 地圖。
使用網頁地圖前端(如 Leaflet)
您可於前端運用 JavaScript 地圖函式庫(如 Leaflet、OpenLayers、Mapbox GL JS),經由後端服務自 PostGIS 資料庫獲取空間資料並於網頁上呈現。以下提供簡版 Leaflet 範例,於 HTML 靜態網頁載入地圖。資料實際上需以後端(如 PHP、Node.js、Python 等,ServBay 皆支援)讀取 PostGIS 並返回 GeoJSON 格式至前端。
請將此 HTML 儲存於 ServBay 網站根目錄(預設 /Applications/ServBay/www
)下任一子目錄,例如 /Applications/ServBay/www/postgis-map/index.html
,再經由 ServBay 網域(如 postgis-map.servbay.demo
)於本機開啟。
<!DOCTYPE html>
<html>
<head>
<title>ServBay PostGIS Leaflet 範例</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: 400px; width: 100%; } /* 設定地圖容器大小 */
</style>
</head>
<body>
<h1>PostGIS 資料視覺化示例(Leaflet)</h1>
<div id="map"></div>
<script>
// 初始化地圖,設定中心點與縮放等級
// 本例中心設於北京附近
var map = L.map('map').setView([39.9042, 116.4074], 10);
// 加入 OpenStreetMap 圖層
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
// 範例:手動加入一個標記(實際應用會由 PostGIS 動態載入資料)
// 此點對應於前述插入的 'ServBay 總部' 資料
var marker = L.marker([39.9042, 116.4074]).addTo(map)
.bindPopup('<b>ServBay 總部</b><br>示例位置')
.openPopup();
// 實務案中,可經由 Ajax/Fetch 從後端取得 PostGIS GeoJSON,再由 L.geoJSON() 顯示於地圖
/*
fetch('/api/locations') // 假設後端提供 /api/locations API 以 GeoJSON 格式返回資料
.then(response => response.json())
.then(data => {
L.geoJSON(data).addTo(map);
});
*/
</script>
</body>
</html>
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
以上僅為 Leaflet 最基本示範。若需將 PostGIS 資料載入頁面,得撰寫後端程式連接資料庫、查詢空間資料、轉換成 GeoJSON 並以 HTTP 介面供前端請求。ServBay 支援多種後端語言,開發相當便利。
常見問題解答(FAQ)
Q: 執行
CREATE EXTENSION postgis;
出現錯誤怎麼辦?- A: 請先確認已成功連線 PostgreSQL 資料庫且所用帳號具有建立擴充套件權限(如
postgres
使用者)。並確認 ServBay 的 PostgreSQL 套件已運行中。若問題仍在,可檢查 ServBay 與 PostgreSQL 的日誌,有可能提供進一步線索。
- A: 請先確認已成功連線 PostgreSQL 資料庫且所用帳號具有建立擴充套件權限(如
Q: 什麼是 SRID 4326?可以用其他 SRID 嗎?
- A: SRID(Spatial Reference Identifier)是用來唯一標識座標參考系統的數字碼。4326 即 WGS84 經緯度坐標系,為網頁地圖最常用系統。當然可以改用其他 SRID,如 Web Mercator(SRID 3857)等投影座標系。如何選擇請依資料來源及應用需求決定。若主要處理經緯度並於網頁地圖展示,4326 或 3857 都很適合。
Q:
geometry
與geography
型態有什麼不同?- A:
geometry
代表平面直角座標系資料,計算距離與面積基於歐幾里得幾何。geography
則表示球面座標系(如地表經緯度),計算距離與面積會考慮地球曲率,結果更精確,特別適用於大範圍地理資料。若處理區域較小或不需高精度,可用geometry
,其效能較佳;若屬全球性經緯度應用且需高精度,推薦geography
。
- A:
總結
PostGIS 讓 PostgreSQL 具備強大地理空間資料處理能力,是建構位置感知應用的基石。透過 ServBay,您可於 macOS 本機環境輕鬆啟用並運用 PostGIS,免去繁複安裝設定流程。
本教學詳述如何於 ServBay 啟用 PostGIS 擴充套件、新增與管理地理空間資料、執行空間查詢與分析,並簡要示範資料視覺化方法。掌握這些基礎後,您即可開始開發功能完備的地理空間網頁應用。建議多查閱 PostGIS 官方文件,探索更多強大函數與特性,發揮地理空間資料潛能!