匯入 ESRI Shapefile 至 PostgreSQL 空間資料庫(postgis)

安裝

安裝有好幾種方法,而且都很簡單,如果是 BSD 平台,就用 ports / pkg_add 之類的套件管理系統,GNU/Linux 例如 Debian ubuntu 就用 aptitude / apt-get 之類的,Mac 就用 Macports 或Homebrew。Windows 就去抓 package 自己安裝,例如 PostgreSQL for Windows
要安裝的東西有兩個,第一個是 DBMS,即PostgreSQL,第二個則是 PostGIS,則是讓 PostgreSQL 具有支援空間資料庫的功能。建議安裝 PostgreSQL 9.3 版,以及 PostGIS 2.0 以上的版本(因為之後設定比較方便,建議用 2.0 以上版本)。另外如果你是使用 EnterpriseDB 公司所出品的安裝程式,就可以在安裝完 PostgreSQL 後利用 Stack Builder 來選擇延伸模組。

設定

先建立一個新的資料庫,可以用 pgAdmin ,或是用 PostgreSQL 的 shell 來建立一個名為 test 的資料庫,然後擁有者是你(選項 -O),並且這個資料庫是 utf8 編碼:

createdb -E utf8 -l en_US.UTF-8 -O _yourusername_ test

接下來建立 postgis extension,先進入 PostgreSQL shell

$ psql -d test

建立 postgis extension

test=# CREATE EXTENSION postgis;
test=# CREATE EXTENSION postgis_topology;

這樣就讓 PostgreSQL 建立 postgis 支援了!

匯入 shape file

這個步驟可以選擇用 QGIS 的 SPIT 延伸套件來匯入:

Screen Shot 2012-12-25 at 1.05.25 AM

另外一個方法就是使用 shp2pgsql 這隻程式,假設要匯入的資料是 TWD1997 TM2 投影座標系統(EPSG:3826)

# -I 代表建立空間索引(spatial index)
# -D 代表使用 postgresql dump 代替 INSERT statement
# -s 座標系統,請參考 [Spatial reference](http://spatialreference.org/)
shp2pgsql -I -D -s 3826 filename.shp schema.tablename | psql -d _dbname_

註:如果原本 shapefile 是落後的 Big5 編碼的話,你可以考慮把它轉成 UTF-8 或是用 -W big5 參數轉換

之後就可以用 QGIS 連 postgis 資料庫了,如下圖:

Image

同時讓 TWD1997 TM2 及 WGS 84 經緯度座標系統存在同一個 table 中

因為常常需要處理 TWD1997 TM2 及經緯度座標,我希望能同時有 WGS84 經緯度座標系統和臺灣的 TWD1997 TM2 座標系統共存,這樣就可以輕鬆地選擇想要的座標系統而不需多做轉換,以下的這個方法是用 ST_Transform() 來轉換座標系統

  1. 匯入的時候,記得將 geometry column 命名成易懂好記的名稱:
    shp2pgsql -I -D -s 3826 -g geom_twd97 filename.shp schema.tablename | psql -d dbname
    
  2. 接下來
    -- AddGeometryColumn 中的參數為:表格名稱、geometry 欄位名稱、座標系統代碼、圖徵(point, line, polygon, etc.)以及維度(2-D/3-D)
    SELECT AddGeometryColumn ('table_name', 'geom_wgs84', 4326, 'POINT', 2);
    UPDATE table_name 
    SET geom_wgs84 = ST_Transform(geom_twd97, 4326) 
    

註:如果你的資料表中不是從 shapefile 匯入,但有經緯度或 TWD1997 TM2 座標的話,可以用 ST_GeomFromText()來匯入

-- 假設你的資料表中, TWD1997 TM2 座標的欄位是 tm2x 及 tm2y
SELECT AddGeometryColumn ('table_name', 'geom_twd97', 3826, 'POINT', 2);
UPDATE table_name 
SET geom_twd97 = ST_GeomFromText('point('||tm2x||' '||tm2y||')', 3826);

參考資料
[1] PostGIS manual (http://postgis.net/docs/manual-2.1/)

Comments

comments powered by Disqus