CHƯƠNG 3 XỬ LÝ TRUY VẤN KHÔNG GIAN
3.3. Tìm hiểu về PostGIS
3.3.1.Giới thiệu
PostGIS là một phần mở rộng của cơ sở dữ liệu đối tượng quan hệ PostgreSQL cho phép các đối tượng GIS được lưu trữ trong CSDL. PostGIS được phát triển bởi Refractions Research Inc.
PostGIS hổ trợ lưu trữ các đối tượng GIS cơ bản - như được định nghĩa bởi OpenGIS. PostGIS biểu diễn các đối tượng không gian theo hai dạng chuẩn: chuẩn định dạngWell-Know-Text (WKT) và định dạng Well-Know Binary (WKB). Ngoài ra khi lưu trữ các đối tượng không gian, OpenGIS yêu cầu trong dữ liệu lưu phải chứa một tham chiếu đến hệ thống nhận diện không gian (SRID).
3.3.2.Sử dụng các chuẩn OpenGIS
OpenGIS định nghĩa các loại đối tượng GIS chuẩn, các chức năng để thao tác với chúng, và một tập các bảng meta-data. Trong PostGIS có 2 bảng meta-data theo chuẩn của OpenGIS là: SPATIAL_REF_SYS và GEOMETRY_COLUMNS.
Tạo một bảng với dữ liệu không gian, được thực hiện theo 2 bước:
• Tạo một bảng non-spatial bình thường
• Thêm cột không gian vào bảng sử dụng hàm “AddGeometryColumn” của OpenGIS Cú pháp là: AddGeometryColumn( <schema_name>, <table_name>, <column_name>, <srid>, <type>, <dimension> ) Hoặc: AddGeometryColumn( <table_name>, <column_name>, <srid>, <type>, <dimension> )
3.3.3.Import dữ liệu GIS
Có hai cách để đưa dữ liệu vào một csdl PostGIS/PostgreSQL: sử dụng các câu lệnh dạng SQL hoặc sử dụng chương trình tải shapefile – sh2gpsql.
3.3.4.Xuất bản dữ liệu GIS
Dữ liệu trong PostGIS/PostgreSQL cũng có thể được xuất bản bằng câu lệnh SQL hoặc các trình loader/dumper shapefile.
33
3.3.5.Tạo indexs
Đánh chỉ số cho phép các trình lên kế hoạch của một CSDL đưa ra những phương pháp xử lý truy vấn hiệu quả giúp giảm thời gian thực hiện, cũng như tài nguyên hệ thống. Với các CSDL thông thường cấu trúc đánh chỉ số phổ biến là B- trees. Nhưng với CSDL không gian, phương pháp đánh chỉ số B-tree khơng cịn phù hợp. PostgreSQL mặc định hổ trợ 3 loại đánh chỉ số: B-Tree indexes, R-Tree indexes và GiST indexes.
• B-Trees được sử dụng cho những dữ liệu có thể sắp xếp theo 1 trục; ví dụ: số, ký tự, ngày tháng. Dữ liệu GIS không thể được sắp xếp một cách logic theo trục, do đó B-Tree indexes khơng phù hợp.
• R-Trees chia dữ liệu thành những hình chử nhật, và những hình chử nhật con, và những hình chử nhật con, … R-Tree được sử dụng cho một số CSDL không gian để đánh chỉ số CSDL không gian, nhưng hiệu năng của R-tree trong PosstgreSQL khơng mạnh bằng GiST.
• GiST (Generalized Search Trees) indexes chia dữ liệu thành "things to one side", "things which overlap", "things which are inside" và có thể được sử dụng trên một tập rông các loại dữ liệu, bao gồm cả dữ liệu GIS. PostGIS sử dụng 1 R-Tree index trên đỉnh của GiST để đánh chỉ số dữ liệu GIS.
Cú pháp để xây dựng một GiST index trên một cột “geometry” là :
CREATE INDEX [indexname] ON [tablename] USING GIST ( [geometryfield] );
3.3.6.Một số truy vấn spatial SQL đơn giản
Trong PostGIS cung cấp các hàm xử lý không gian, giúp cho việc truy vấn không gian đạt hiệu quả. Để sử dụng PostGIS hiệu quả yêu cầu phải biết về các hàm khơng gian đang có, và sử dụng một cách hợp lý để có thể đạt được hiệu năng truy vấn tốt.
Các ví dụ dưới đấy sẽ sử dụng 2 bảng, 1 bảng các đường đường phố, và 1 bảng các đa giác đường biên đô thị.
Bảng các đường phố bc_roads:
Column | Type | Description
--------+-----------------+------------------------- gid |integer | Unique ID
name |character varying| Road Name
34
Bảng các đa giác đường biên đô thị bc_municipality:
Column | Type |Description
--------+-----------------+------------------------ gid |integer |Unique ID
code |integer |Unique ID
name |character varying|City / Town Name
the_geom| geometry |Location Geometry (Polygon)
Tổng số chiều dài của các đường là bao nhiều (km) - sử dụng hàm ST_Length để tính độ dài đường?
SELECT sum(ST_Length(the_geom))/1000 AS km_roads FROM
bc_roads;
Diện tích của thành phố Prince George là bao nhiêu (hectar) – sử dụng hàm ST_Area để tính diện tích một đa giác ?
SELECT ST_Area(the_geom)/10000 AS hectares FROM bc_municipality
WHERE name = ’PRINCE GEORGE’;
Khu vực nào là rộng nhất trong tỉnh (theo diện tích) ?
SELECT name,ST_Area(the_geom)/10000 AS hectares FROM bc_municipality
ORDER BY hectares DESC LIMIT 1;
Độ dài của đường đầy đủ chứa trong mỗi đơ thị là gì - hàm ST_Contains kiểm tra xem một đối tượng geometry có được chứa trong một đối tượng geometry khác hay không?
SELECT m.name,sum(ST_Length(r.the_geom))/1000 as roads_km FROM bc_roads AS r,bc_municipality AS m
35 GROUP BY m.name ORDER BY roads_km; Kết quả trả về: name | roads_km ----------------+------------------------------ SURREY | 1539.47553551242 VANCOUVER | 1450.33093486576 LANGLEY DISTRICT| 833.793392535662 BURNABY | 773.769091404338 PRINCE GEORGE | 694.37554369147
Tạo một bảng lưu tất cả các đường trong thanh phố Prince George – hàm ST_Intersects trả về các đối tượng geometry giao nhau.
CREATE TABLE pg_roads as
SELECT ST_Intersection(r.the_geom, m.the_geom) AS intersection_geom,
ST_Length(r.the_geom) AS rd_orig_length, r.* FROM bc_roads AS r,bc_municipality AS m
WHERE m.name = ’PRINCE GEORGE’ AND ST_Intersects(r.the_geom, m.the_geom);
36