GanosBase Geometry adalah ekstensi geometri spasial untuk AnalyticDB for PostgreSQL. Ekstensi ini mematuhi standar OpenGIS dan mendukung data spasial 2D (X, Y), 3D (X, Y, Z), serta 4D (X, Y, Z, M). GanosBase Geometry sepenuhnya kompatibel dengan PostGIS, sehingga memungkinkan migrasi aplikasi yang sudah ada secara mulus.GanosBaseGanosBase
Dengan GanosBase Geometry, Anda dapat:
Menyimpan titik, line string, dan poligon dalam satu kolom geometry
Membuat indeks spasial GiST (Generalized Search Tree) untuk kueri kedekatan dan kandungan yang cepat
Menggunakan seluruh fungsi dan operator spasial PostGIS
Prasyarat
Sebelum memulai, pastikan Anda telah memiliki:
Instans AnalyticDB for PostgreSQL
Ekstensi
ganos_spatialrefdanganos_geometryyang terinstal — submit a ticket untuk meminta instalasi
Panduan cepat
Langkah-langkah berikut menjelaskan alur kerja lengkap: membuat tabel geometri, menambahkan data, membuat indeks spasial, dan menjalankan kueri spasial.
Langkah 1: Buat tabel geometri
Tersedia dua metode. Gunakan Metode 1 jika Anda sudah mengetahui tipe geometri sejak awal. Gunakan Metode 2 jika Anda perlu menambahkan kolom geometri ke tabel yang sudah ada.
Metode 1 — Definisikan kolom geometry dalam pernyataan CREATE TABLE:
CREATE TABLE roads (
id int4,
road_name varchar(25),
geom geometry(LINESTRING, 3857)
) DISTRIBUTED BY (id);Metode 2 — Tambahkan kolom geometry ke tabel yang sudah ada:
CREATE TABLE roads (
id int4,
road_name varchar(25)
) DISTRIBUTED BY (id);
SELECT AddGeometryColumn('roads', 'geom', 3857, 'LINESTRING', 2);SRID 3857 pada kedua contoh mengacu pada proyeksi Web Mercator (EPSG:3857), yang merepresentasikan koordinat dalam satuan meter. Pilih SRID yang sesuai dengan sistem referensi koordinat data Anda.Langkah 2: Tambahkan batasan geometri
Terapkan validasi geometri sebelum memasukkan data:
ALTER TABLE roads
ADD CONSTRAINT geometry_valid_check CHECK (ST_IsValid(geom));Langkah 3: Masukkan data geometri
Gunakan ST_GeomFromText untuk mengonversi string Well-Known Text (WKT) menjadi nilai geometri. Fungsi ini menerima representasi WKT dan SRID-nya.
Koordinat ditentukan sebagai X Y (longitude latitude). Longitude ditulis terlebih dahulu karena merepresentasikan sumbu x. Untuk SRID 3857, koordinat dinyatakan dalam satuan meter, bukan derajat.
INSERT INTO roads (id, geom, road_name) VALUES
(1, ST_GeomFromText('LINESTRING(191232 243118,191108 243242)', 3857), 'North Fifth-ring Road'),
(2, ST_GeomFromText('LINESTRING(189141 244158,189265 244817)', 3857), 'East Fifth-ring Road'),
(3, ST_GeomFromText('LINESTRING(192783 228138,192612 229814)', 3857), 'South Fifth-ring Road'),
(4, ST_GeomFromText('LINESTRING(189412 252431,189631 259122)', 3857), 'West Fifth-ring Road'),
(5, ST_GeomFromText('LINESTRING(190131 224148,190871 228134)', 3857), 'East Chang''an Avenue'),
(6, ST_GeomFromText('LINESTRING(198231 263418,198213 268322)', 3857), 'West Chang''an Avenue');Verifikasi baris yang dimasukkan dengan membaca kembali geometrinya sebagai WKT menggunakan ST_AsText:
SELECT id, ST_AsText(geom) AS geom, road_name FROM roads;Output yang diharapkan:
id | geom | road_name
----+-----------------------------------------+-----------------------
1 | LINESTRING(191232 243118,191108 243242) | North Fifth-ring Road
2 | LINESTRING(189141 244158,189265 244817) | East Fifth-ring Road
3 | LINESTRING(192783 228138,192612 229814) | South Fifth-ring Road
4 | LINESTRING(189412 252431,189631 259122) | West Fifth-ring Road
5 | LINESTRING(190131 224148,190871 228134) | East Chang'an Avenue
6 | LINESTRING(198231 263418,198213 268322) | West Chang'an Avenue
(6 rows)Langkah 4: Buat indeks spasial GiST
Indeks GiST mempercepat kueri spasial seperti pemeriksaan tumpang tindih Kotak pembatas dan kandungan. Buat indeks pada kolom geometry, lalu jalankan VACUUM ANALYZE untuk memperbarui statistik.
-- Indeks 2D standar
CREATE INDEX sp_geom_index ON roads USING GIST (geom);
-- Indeks N-dimensi (untuk data 3D atau 4D)
-- CREATE INDEX sp_geom_index_nd ON roads USING GIST (geom gist_geometry_ops_nd);
VACUUM ANALYZE roads (geom);Langkah 5: Jalankan kueri spasial
Contoh berikut menggunakan dua tabel sampel. Buat tabel-tabel ini dan isi dengan data Anda sendiri sebelum menjalankan kueri.
bc_roads — jaringan jalan:
| Kolom | Tipe | Deskripsi |
|---|---|---|
gid | integer | ID unik |
name | character varying | Nama jalan |
the_geom | geometry | Geometri lokasi (linestring) |
bc_municipality — batas wilayah administratif:
| Kolom | Tipe | Deskripsi |
|---|---|---|
gid | integer | ID unik |
code | integer | Kode unik |
name | character varying | Nama kota atau desa |
the_geom | geometry | Geometri lokasi (polygon) |
Ukur geometri
Gunakan ST_Length dan ST_Area untuk menghitung jarak dan luas. Kedua fungsi ini mengembalikan hasil dalam satuan sistem referensi koordinat geometri tersebut (meter untuk SRID 3857).
-- Total panjang jalan dalam kilometer
SELECT SUM(ST_Length(the_geom)) / 1000 AS km_roads FROM bc_roads; km_roads
------------------
70842.1243039643
(1 row)-- Luas wilayah administratif tertentu dalam hektar
SELECT ST_Area(the_geom) / 10000 AS hectares
FROM bc_municipality
WHERE name = 'PRINCE GEORGE'; hectares
------------------
32657.9103824927
(1 row)Uji hubungan spasial
GanosBase Geometry mendukung seluruh fungsi hubungan spasial PostGIS. Tabel berikut mencantumkan fungsi-fungsi yang paling umum digunakan.
| Fungsi | Mengembalikan true ketika |
|---|---|
ST_Contains(A, B) | A sepenuhnya memuat B |
ST_Covers(A, B) | A menutupi B (termasuk batasnya) |
ST_Within(A, B) | A sepenuhnya berada di dalam B |
ST_Intersects(A, B) | A dan B memiliki setidaknya satu titik yang sama |
ST_Disjoint(A, B) | A dan B tidak memiliki titik yang sama |
ST_Touches(A, B) | A dan B hanya berbagi titik batas |
ST_Overlaps(A, B) | A dan B saling tumpang tindih tetapi tidak saling memuat |
ST_Crosses(A, B) | A dan B saling bersilangan (interseksi berdimensi berbeda) |
ST_Relate(A, B, matrix) | A dan B memenuhi pola DE-9IM yang diberikan |
Contoh — cari panjang jalan per wilayah administratif menggunakan ST_Contains:
SELECT m.name, SUM(ST_Length(r.the_geom)) / 1000 AS roads_km
FROM bc_roads AS r, bc_municipality AS m
WHERE ST_Contains(m.the_geom, r.the_geom)
GROUP BY m.name
ORDER BY roads_km;Contoh — bandingkan cakupan antara dua lingkaran menggunakan ST_Covers:
SELECT
ST_Covers(smallc, smallc) AS smallinsmall,
ST_Covers(smallc, bigc) AS smallcoversbig,
ST_Covers(bigc, ST_ExteriorRing(bigc)) AS bigcoversexterior,
ST_Contains(bigc, ST_ExteriorRing(bigc)) AS bigcontainsexterior
FROM (
SELECT
ST_Buffer(ST_GeomFromText('POINT(1 2)'), 10) AS smallc,
ST_Buffer(ST_GeomFromText('POINT(1 2)'), 20) AS bigc
) AS foo; smallinsmall | smallcoversbig | bigcoversexterior | bigcontainsexterior
--------------+----------------+-------------------+---------------------
t | f | t | f
(1 row)ST_CoversdanST_Containsberbeda dalam cara menangani titik batas.ST_Coversmengembalikan true ketika A menutupi batas B;ST_Containstidak demikian.
Contoh — uji titik dan garis yang saling lepas menggunakan ST_Disjoint:
-- Titik tidak berada pada garis: saling lepas
SELECT ST_Disjoint('POINT(0 0)'::geometry, 'LINESTRING ( 2 0, 0 2 )'::geometry);
-- Hasil: t
-- Titik berada pada garis: tidak saling lepas
SELECT ST_Disjoint('POINT(0 0)'::geometry, 'LINESTRING ( 0 0, 0 2 )'::geometry);
-- Hasil: fContoh — uji tumpang tindih dan interseksi menggunakan ST_Overlaps:
SELECT ST_Overlaps(a, b) AS a_overlap_b,
ST_Crosses(a, b) AS a_crosses_b,
ST_Intersects(a, b) AS a_intersects_b,
ST_Contains(b, a) AS b_contains_a
FROM (
SELECT ST_GeomFromText('POINT(1 0.5)') AS a,
ST_GeomFromText('LINESTRING(1 0, 1 1, 3 5)') AS b
) AS foo; a_overlap_b | a_crosses_b | a_intersects_b | b_contains_a
-------------+-------------+----------------+--------------
f | f | t | tContoh — uji hubungan spasial menggunakan ST_Relate:
SELECT ST_Relate(ST_GeometryFromText('POINT(1 2)'), ST_Buffer(ST_GeometryFromText('POINT(1 2)'), 2), '0FFFFF212'); st_relate
-----------
tContoh — uji apakah suatu titik menyentuh garis menggunakan ST_Touches:
-- Titik interior: tidak menyentuh (ST_Touches hanya berlaku untuk kontak batas)
SELECT ST_Touches('LINESTRING(0 0, 1 1, 0 2)'::geometry, 'POINT(1 1)'::geometry);
-- Hasil: f
-- Titik ujung garis: menyentuh
SELECT ST_Touches('LINESTRING(0 0, 1 1, 0 2)'::geometry, 'POINT(0 2)'::geometry);
-- Hasil: tContoh — periksa kandungan untuk lingkaran bersarang menggunakan ST_Within:
SELECT
ST_Within(smallc, smallc) AS smallinsmall,
ST_Within(smallc, bigc) AS smallinbig,
ST_Within(bigc, smallc) AS biginsmall,
ST_Within(ST_Union(smallc, bigc), bigc) AS unioninbig,
ST_Within(bigc, ST_Union(smallc, bigc)) AS biginunion,
ST_Equals(bigc, ST_Union(smallc, bigc)) AS bigisunion
FROM (
SELECT
ST_Buffer(ST_GeomFromText('POINT(50 50)'), 20) AS smallc,
ST_Buffer(ST_GeomFromText('POINT(50 50)'), 40) AS bigc
) AS foo; smallinsmall | smallinbig | biginsmall | unioninbig | biginunion | bigisunion
--------------+------------+------------+------------+------------+------------
t | t | f | t | t | t
(1 row)Periksa validitas geometri
Gunakan ST_IsSimple untuk memverifikasi bahwa geometri tidak memiliki self-intersection, dan ST_NRings untuk menghitung jumlah ring dalam sebuah poligon.
-- Ring tertutup yang valid (poligon simple)
SELECT ST_IsSimple(ST_GeomFromText('POLYGON((1 2, 3 4, 5 6, 1 2))'));
-- Hasil: t
-- Linestring yang saling berpotongan (tidak simple)
SELECT ST_IsSimple(ST_GeomFromText('LINESTRING(1 1,2 2,2 3.5,1 3,1 2,2 1)'));
-- Hasil: f
-- Temukan wilayah administratif dengan luas terbesar yang memiliki lebih dari satu ring
SELECT gid, name, ST_Area(the_geom) AS area
FROM bc_municipality
WHERE ST_NRings(the_geom) > 1
ORDER BY area DESC
LIMIT 1; gid | name | area
-----+--------+------------------
12 | Anning | 257374619.430216
(1 row)Langkah 6: Hapus ekstensi
Untuk menguninstall GanosBase Geometry, hapus ekstensi dalam urutan berikut:
DROP EXTENSION ganos_geometry;
DROP EXTENSION ganos_spatialref;Menghapus ekstensi akan menghilangkan semua fungsi dan operator geometri. Tabel apa pun yang memiliki kolom geometry akan kehilangan kemampuan menggunakan fungsi spasial hingga ekstensi dipasang ulang.
Referensi SQL
GanosBase Geometry sepenuhnya kompatibel dengan PostGIS. Untuk daftar lengkap fungsi dan operator yang didukung, lihat PostGIS reference.