GanosBase Geometry adalah ekstensi mesin spatio-temporal untuk PolarDB for PostgreSQL yang mengimplementasikan standar Simple Features Access (SFA) dari Open Geospatial Consortium (OGC), menyediakan rangkaian lengkap alat untuk menyimpan, mengkueri, dan menganalisis objek geometris — mulai dari titik sederhana hingga kurva majemuk dan koleksi permukaan.
Konsep utama
Hierarki tipe Geometry
Geometry adalah tipe abstrak. Semua nilai geometry konkret termasuk dalam salah satu subtipe-nya, yang dikelompokkan ke dalam tiga kategori:
Tipe atomik — bentuk tak terbagi: Point, LineString, Polygon
Tipe berparameter — bentuk yang didefinisikan oleh kurva dan khas GanosBase: EllipticalString, Bezier3Curve
Tipe koleksi — bentuk berkelompok: MultiPoint, MultiLineString, MultiPolygon, GeometryCollection, CompoundCurve, CurvePolygon
Setiap subtipe dijelaskan secara rinci dalam bagian Tipe data geometry.
Dimensi koordinat
Model geometry merepresentasikan bentuk dalam sistem koordinat 2D atau 3D. Setiap koordinat memiliki nilai x dan y, serta dapat juga menyertakan:
| Koordinat | Makna | Pengaruh terhadap dimensi |
|---|---|---|
| x, y | Posisi pada bidang datar | 2D |
| z | Ketinggian atau kedalaman | Menambahkan dimensi ketiga (3D) |
| m | Nilai ukuran — waktu, jarak, atau referensi linier lainnya | Menambahkan dimensi ketiga (3D) |
| z + m bersama | Baik ketinggian maupun ukuran | 4D |
Jika nilai z atau m ada, nilai tersebut harus didefinisikan untuk setiap titik dalam geometry.
Sistem referensi spasial
Sistem referensi spasial (SRS) mendefinisikan cara koordinat dipetakan ke lokasi tertentu di permukaan Bumi. GanosBase mengaitkan setiap nilai geometry dengan SRS melalui pengenal bilangan bulat yang disebut SRID. SRID merupakan kunci asing yang mereferensikan tabel spatial_ref_sys.
Untuk detail selengkapnya, lihat Spatial reference.
Format input yang didukung
GanosBase menerima data geometry dalam format berikut secara langsung:
| Format | Tipe | Catatan |
|---|---|---|
| Well-Known Text (WKT) | Teks | Standar OGC; mencakup tipe dan koordinat, tanpa SRID |
| Well-Known Binary (WKB) | Biner | Standar OGC; portabel, presisi penuh; tanpa SRID |
| EKWT | Teks | Ekstensi GanosBase dari WKT; menambahkan penyematan SRID serta dukungan 3DZ, 3DM, dan 4D |
| EKWB | Biner | Ekstensi GanosBase dari WKB; penambahan yang sama seperti EKWT |
| KML | XML | — |
| GML | XML | — |
| GeoHash | String | — |
| GeoJSON | JSON | RFC 7946 |
Setiap nilai WKT atau WKB yang valid juga merupakan nilai EKWT atau EKWB yang valid. Untuk format lain seperti Esri Shapefiles, gunakan tool impor eksternal sebelum memuat ke GanosBase.
Tipe data geometry
Tipe atomik
| Tipe | Deskripsi | Contoh |
|---|---|---|
| Point | Geometry berdimensi 0 yang merepresentasikan lokasi tunggal dalam ruang koordinat | POINT (1 2), POINT Z (1 2 3), POINT ZM (1 2 3 4) |
| LineString | Garis berdimensi 1 yang dibentuk oleh rangkaian segmen garis berurutan; dapat berpotongan dengan dirinya sendiri | LINESTRING (1 2, 3 4, 5 6) |
| Polygon | Wilayah planar berdimensi 2 yang dibatasi oleh batas luar (shell) dan nol atau lebih batas dalam (lubang); setiap batas berupa LinearRing | POLYGON ((0 0 0,4 0 0,4 4 0,0 4 0,0 0 0),(1 1 0,2 1 0,2 2 0,1 2 0,1 1 0)) |
Tipe berparameter
Tipe-tipe ini khas GanosBase dan menggunakan parameter matematis alih-alih urutan titik.
| Tipe | Deskripsi | Contoh |
|---|---|---|
| EllipticalString | Busur elips | ELLIPTICALSTRING(-2 0,2 0,0 0,0,0,0,2,0.5) |
| Bezier3Curve | Kurva Bezier orde ketiga yang didefinisikan oleh empat titik kontrol | BEZIER3CURVE(1 1, 2 2, 3 2, 3 1) |
Tipe koleksi
| Tipe | Deskripsi | Contoh |
|---|---|---|
| MultiPoint | Kumpulan Titik | MULTIPOINT ( (0 0), (1 2) ) |
| MultiLineString | Koleksi LineString | MULTILINESTRING ( (0 0,1 1,1 2), (2 3,3 2,5 4) ) |
| MultiPolygon | Koleksi Polygon yang tidak saling tumpang tindih dan tidak bersebelahan; Polygon dapat saling menyentuh di sejumlah titik terbatas | MULTIPOLYGON (((1 5, 5 5, 5 1, 1 1, 1 5)), ((6 5, 9 1, 6 1, 6 5))) |
| GeometryCollection | Koleksi heterogen dari berbagai tipe geometry | GEOMETRYCOLLECTION ( POINT(2 3), LINESTRING(2 3, 3 4)) |
| CompoundCurve | Garis majemuk yang menggabungkan segmen lurus, busur elips, dan kurva Bezier; titik akhir setiap komponen harus berimpit dengan titik awal komponen berikutnya | COMPOUNDCURVE((1 0,2 0),ELLIPTICALSTRING(2 0 ,4 0, 3 0 ,1,0,0,1,0.5)) |
| CurvePolygon | Permukaan tertutup yang dapat memiliki batas berbentuk kurva | CURVEPOLYGON(ELLIPTICALSTRING(2 0,2 0,0 0,0,0,0,2,0.5),CIRCULARSTRING(-0.5 0,0.5 0,-0.5 0)) |
Tampilan geometry_columns
Tampilan geometry_columns membaca semua kolom geometry dari tabel katalog sistem database dan mengikuti Spesifikasi Simple Features untuk SQL yang ditetapkan oleh OGC.
| Kolom | Tipe | Deskripsi |
|---|---|---|
f_table_catalog | varchar(256) | Nama database. Tetap sebagai postgres. |
f_table_schema | varchar(256) | Skema tabel. |
f_table_name | varchar(256) | Nama tabel. |
f_geometry_column | varchar(256) | Nama kolom geometry. |
coord_dimension | integer | Dimensi koordinat. Nilai valid: 2, 3, dan 4. |
srid | integer | SRID kolom; kunci asing yang mereferensikan spatial_ref_sys. |
type | varchar(30) | Tipe geometry OGC. Nilai GEOMETRY menunjukkan tipe campuran. |
Kueri semua kolom geometry di database saat ini:
SELECT * FROM geometry_columns;Indeks spasial
Indeks spasial memungkinkan GanosBase menghindari pemindaian sekuensial global terhadap database saat memproses dataset spasial besar. Indeks ini mengorganisasi data dalam struktur pohon yang dapat dilalui dengan cepat untuk menemukan catatan tertentu.
GanosBase menyediakan tiga jenis indeks spasial:
| Indeks | Deskripsi | Paling cocok untuk |
|---|---|---|
| GiST (Generalized Search Tree) | Pohon pencarian seimbang; performa kueri tinggi; mendukung aturan kustom untuk mendistribusikan tipe data apa pun dan metode akses kustom | Pilihan default untuk sebagian besar tabel spasial |
| BRIN (Block Range Index) | Menyimpan ringkasan tingkat blok; ukuran jauh lebih kecil dan waktu pembuatan lebih cepat daripada GiST, tetapi kueri lebih lambat; memerlukan pemeliharaan manual; lebih efektif untuk kueri yang mengembalikan banyak catatan data | Tabel sangat besar dengan tumpang tindih spasial rendah atau tidak ada (misalnya, data titik), ketika tabel statis atau jarang berubah |
| SP-GiST (Space-Partitioned Generalized Search Tree) | Mendukung pohon pencarian terpartisi seperti quad-tree, k-d tree, dan radix tree; mendukung lebih sedikit operator daripada GiST dan tidak mendukung pencarian KNN | Objek yang tidak saling tumpang tindih; lebih cocok daripada GiST untuk objek yang tidak tumpang tindih |
Kasus penggunaan
Pembuatan dan visualisasi peta: Simpan jalan, sungai, bangunan, dan fitur peta lainnya sebagai nilai geometry, lalu kueri dan render berdasarkan cakupan spasial.
Layanan lokasi: Jalankan kueri spasial dan agregasi pada data titik untuk menemukan sumber daya terdekat, menghitung jarak, atau menilai risiko geografis.
Kueri hubungan spasial: Identifikasi bagaimana fitur saling berhubungan — apakah saling berpotongan, tumpang tindih, berada di dalam, atau bersebelahan satu sama lain.
Analisis dan pengukuran spasial: Hitung luas, panjang, jarak, dan pusat (centroid) lintas dataset.
Memulai cepat
Bagian ini memandu Anda membuat ekstensi ganos_geometry, mendefinisikan tabel geometry, mengimpor data, membangun indeks, dan menjalankan kueri spasial.
Buat ekstensi
-- Buat ekstensi ganos_geometry.
CREATE EXTENSION ganos_geometry CASCADE;Catatan: Buat ekstensi di skema public untuk menghindari masalah izin.
CREATE EXTENSION ganos_geometry WITH SCHEMA public CASCADE;Buat tabel geometry
Dua metode tersedia. Gunakan Metode 1 jika Anda sudah mengetahui tipe geometry dan SRID sejak awal.
Metode 1 — Definisikan kolom geometry dalam pernyataan CREATE TABLE:
CREATE TABLE roads (
id int4,
road_name varchar(25),
geom geometry(LINESTRING, 3857)
);Metode 2 — Tambahkan kolom geometry ke tabel yang sudah ada:
CREATE TABLE roads (id int4, road_name varchar(25));
SELECT AddGeometryColumn('roads', 'geom', 3857, 'LINESTRING', 2);Tambahkan kendala geometry
ALTER TABLE roads ADD CONSTRAINT geometry_valid_check CHECK (ST_IsValid(geom));Impor data geometry
Keenam baris menggunakan ST_GeomFromText untuk mengurai string WKT dengan SRID 3857.
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');Kueri data geometry
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)Buat indeks spasial
Indeks GiST (direkomendasikan):
-- Indeks GiST 2D standar:
CREATE INDEX <index_name> ON <table_name> USING GIST (<geometry_column>);
-- Indeks GiST N-dimensi:
CREATE INDEX <index_name> ON <table_name> USING GIST (<geometry_column> gist_geometry_ops_nd);
-- Perbarui statistik setelah membangun indeks:
VACUUM ANALYZE <table_name> (<geometry_column>);
-- Contoh:
CREATE INDEX sp_geom_index ON roads USING GIST(geom);
VACUUM ANALYZE roads (geom);Indeks BRIN (tabel besar yang sebagian besar statis):
-- Indeks BRIN standar:
CREATE INDEX <index_name> ON <table_name> USING BRIN (<geometry_column>);
-- Indeks BRIN 3D atau 4D:
CREATE INDEX <index_name> ON <table_name> USING BRIN (<geometry_column> brin_geometry_inclusion_ops_3d);
CREATE INDEX <index_name> ON <table_name> USING BRIN (<geometry_column> brin_geometry_inclusion_ops_4d);
-- Indeks BRIN dengan ukuran blok kustom:
CREATE INDEX <index_name> ON <table_name> USING BRIN (<geometry_column>) WITH (pages_per_range = <number>);Ukur dan analisis data spasial
Contoh berikut menggunakan dua tabel sampel:
bc_roads — kolom: gid (integer), name (varchar), the_geom (geometry/LineString)
bc_municipality — kolom: gid (integer), code (integer), name (varchar), the_geom (geometry/Polygon)Hitung total panjang jalan:
SELECT sum(ST_Length(the_geom)) / 1000 AS km_roads FROM bc_roads; km_roads
------------------
70842.1243039643
(1 row)Hitung luas wilayah kota:
SELECT ST_Area(the_geom) / 10000 AS hectares
FROM bc_municipality
WHERE name = 'PRINCE GEORGE'; hectares
------------------
32657.9103824927
(1 row)Jalankan kueri hubungan spasial
GanosBase mendukung seluruh fungsi hubungan spasial OGC. Contoh berikut menunjukkan pola umum.
ST_Contains — temukan jalan dalam setiap wilayah kota:
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; name | roads_km
---------------------+------------------
SURREY | 1539.47553551242
VANCOUVER | 1450.33093486576
LANGLEY DISTRICT | 833.793392535662
BURNABY | 773.769091404338
PRINCE GEORGE | 694.37554369147
...ST_Covers — uji apakah satu lingkaran mencakup lingkaran lain:
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_Disjoint — uji apakah dua geometry tidak memiliki titik yang sama:
SELECT ST_Disjoint('POINT(0 0)'::geometry, 'LINESTRING ( 2 0, 0 2 )'::geometry); st_disjoint
-------------
t
(1 row)SELECT ST_Disjoint('POINT(0 0)'::geometry, 'LINESTRING ( 0 0, 0 2 )'::geometry); st_disjoint
-------------
f
(1 row)ST_Overlaps, ST_Crosses, ST_Intersects, ST_Contains — bandingkan titik dan garis:
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 | tST_Relate — uji pola DE-9IM tertentu:
SELECT ST_Relate(
ST_GeometryFromText('POINT(1 2)'),
ST_Buffer(ST_GeometryFromText('POINT(1 2)'), 2),
'0FFFFF212'
); st_relate
-----------
tST_Touches — uji apakah geometry hanya berbagi titik batas:
SELECT ST_Touches('LINESTRING(0 0, 1 1, 0 2)'::geometry, 'POINT(1 1)'::geometry); st_touches
------------
f
(1 row)SELECT ST_Touches('LINESTRING(0 0, 1 1, 0 2)'::geometry, 'POINT(0 2)'::geometry); st_touches
------------
t
(1 row)ST_Within — uji keterkandungan antara lingkaran yang dibuffer:
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)Akses properti geometry
Periksa apakah geometry bersifat simple:
SELECT ST_IsSimple(ST_GeomFromText('POLYGON((1 2, 3 4, 5 6, 1 2))')); st_issimple
-------------
t
(1 row)SELECT ST_IsSimple(ST_GeomFromText('LINESTRING(1 1,2 2,2 3.5,1 3,1 2,2 1)')); st_issimple
-------------
f
(1 row)Temukan kota terbesar yang memiliki ring interior (lingkaran lalu lintas):
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)Hapus ekstensi
-- Hapus ekstensi ganos_geometry dan semua objek dependennya.
DROP EXTENSION ganos_geometry CASCADE;Langkah selanjutnya
Referensi SQL Geometry — referensi lengkap fungsi untuk semua fungsi GanosBase Geometry
Spatial reference — cara bekerja dengan nilai SRS dan SRID