ベクトルデータとラスターデータは、最も一般的な空間データの種類であり、様々な分野の GIS 関連アプリケーションで広く使用されています。GanosBase は、ベクトルデータとラスターデータを処理するための包括的な機能を提供します。従来のソリューションと比較して、PolarDB for PostgreSQL の弾力的な並列処理機能を活用し、計算効率を数倍から数十倍に向上させます。このトピックでは、GanosBase が提供する、ベクトルデータとラスターデータを取り込むための効率的な方法について説明します。これにより、クラウドネイティブデータベースに空間データを書き込むためのソリューションを迅速に理解し、ベクトルデータとラスターデータを処理するための GanosBase の機能をより良く活用できます。
背景情報
PostgreSQL Community Edition の PostGIS 拡張機能は、ベクターデータとラスターデータを迅速にインポートするためのコマンドラインツール shp2pgsql および raster2pgsql を提供します。これらのツールでは、SRID、ファイルエンコーディング、テーブル名などの情報を指定する必要があります。ラスターデータの場合、ラスターバンドやタイルサイズなどのパラメーターも指定する必要があります。このアプローチは、いくつかの理由により、クラウドネイティブデータベースである PolarDB には適していません。
-
クラウドネイティブデータベースの PolarDB は共有ストレージアーキテクチャを採用しており、ローカルディスクを持ちません。その弾力的なリソース管理のため、基盤となるホストの情報は公開されません。
-
PostGIS Raster と GanosBase Raster は、ストレージ構造が大幅に異なります。詳細な比較については、「地域的な地表降雨量分析の実行」をご参照ください。
クラウドネイティブなアーキテクチャの観点から、GanosBase は Object Storage Service (OSS) と統合することで、ベクターデータとラスターデータの高速なインジェストをサポートする、より便利な関数ベースのインポートツールを提供します。
ベクターデータとラスターデータのインポート方法
ベクターデータのインポート
GIS デスクトップツールを使用したデータインポート
GanosBase は PolarDB for PostgreSQL を基盤としているため、PostgreSQL と完全に互換性があります。PostgreSQL データソースとして PolarDB データベースに接続し、ツールのデータインポート機能を使用します。
FDW を使用したデータインポート
GanosBase は、ベクターデータのインポートに 外部データラッパー (FDW) の使用を推奨します。FDW は、同じクラスター内の他のデータベースや他のインスタンスなど、外部データソースにアクセスするための PostgreSQL の拡張機能です。GanosBase FDW は、さまざまな空間データ型への統一されたアクセスを提供し、ジオメトリ空間データ型を Geometry 型に自動的にマッピングします。これにより、外部テーブルと内部テーブルを一貫してクエリできます。
たとえば、OSS に格納されている poly.shp ファイルを、Geometry 型のデータテーブルとして GanosBase にインポートできます。次の手順に従います。
-
必要な拡張機能をインストールします。
CREATE EXTENSION ganos_spatialref; CREATE EXTENSION ganos_geometry; CREATE EXTENSION ganos_fdw; -
ST_RegForeignTables 関数を使用して、空間データファイル
poly.shpを外部テーブルとして登録します。SELECT ST_RegForeignTables('oss://<access_id>:<secret_key>@[<Endpoint>]/<bucket>/path_to/poly.shp'); -
外部テーブルが登録された後、
information_schema.foreign_tablesビューをクエリして、新しく登録された FDW テーブル (poly) を確認できます。SELECT foreign_table_name FROM information_schema.foreign_tables ORDER BY foreign_table_name ASC;説明外部データを外部テーブルとして登録しても、データを表示するためのマッピングが作成されるだけで、実際のデータはデータベースに書き込まれません。したがって、次のコマンドを使用してデータベーステーブルを作成し、データを挿入する必要があります。
CREATE TABLE poly_db AS SELECT * FROM poly;
ラスターデータのインポート
GanosBase は、外部のラスターデータソースをデータベースにインポートするための ST_ImportFrom および ST_CreateRast 関数を提供します。どちらの関数も、外部のラスターデータから Raster 型オブジェクトを作成して、画像データのメタデータを格納します。これらの主な違いは、ST_ImportFrom 関数がデータを標準サイズ (デフォルトでは 256 × 256 ピクセル) のチャンクに分割し、データベースに格納することです。格納場所は chunkTableName パラメーターで指定します。対照的に、ST_CreateRast 関数は Raster オブジェクトを作成するだけで、実際のピクセルデータはデータベースにインポートしません。
TIFF データのインポート
TIFF は、最も一般的なラスターデータ形式の 1 つです。次の例は、OSS から TIFF ファイルを GanosBase にインポートする方法を示しています。
-
OSS で TIFF データを準備します。ご自身のデータを使用してもかまいません。
-
TIFF データを格納するための Raster フィールドを含むテーブルを作成します。
CREATE TABLE raster_table ( id integer, format text, rast raster ); -
TIFF データをインポートします。
-
ST_ImportFrom関数を使用します。INSERT INTO raster_table SELECT 1, 'TIFF', ST_ImportFrom('chunk_table','oss://<access_id>:<secret_key>@[<Endpoint>]/<bucket>/path_to/file'); -
ST_CreateRast関数を使用します。INSERT INTO raster_table SELECT 2, 'TIFF', ST_CreateRast('oss://<access_id>:<secret_key>@[<Endpoint>]/<bucket>/path_to/file');
-
-
インポートが成功すると、両方のメソッドが Raster オブジェクトを作成することがわかります。GanosBase が提供するラスター UDF を使用して、いずれのオブジェクトも操作できます。
SELECT id,ST_Georeference(rast),st_extent(rast),ST_NumBands(rast),ST_SRID(rast),st_value(rast,0,100,100),st_value(rast,1,200,200) FROM raster_table;クエリは、
idの値がそれぞれ 1 と 2 の 2 つの行を返します。他の列の値は両方の行で同じです。ST_Georeferenceは2e-05,0,113.99999,0,-2e-05,26.6666766666667、st_extentは(114.25001,26.6666766666667),(113.99999,26.4999766666667)、ST_NumBandsは 3、ST_SRIDは 4326、2 つのst_valueの結果は 112 と 90 です。結果が同じであることは、両方のメソッドで作成された Raster オブジェクトが同等であることを示します。ただし、
ST_ImportFromは新しいテーブル (chunk_table) を作成してピクセルデータを格納します。これは、OSS 内の元のファイルが削除されても、データがデータベースに永続化されることを意味します。対照的に、ST_CreateRastは外部画像への論理参照を持つ Raster オブジェクトを作成するだけです。データは OSS に残ります。OSS 内の元のファイルが削除されると、データにアクセスできなくなります。
HDF5 および NetCDF データのインポート
HDF5 と NetCDF は、地球観測や科学技術計算、特に気象学、海洋学、地球科学などの分野で広く使用されている、他の一般的な 2 つのラスターデータ形式です。ST_ImportFrom および ST_CreateRast 関数は、HDF5 および NetCDF データのインポートもサポートしています。SQL 構文は、TIFF データの場合と同様です。
-
ST_ImportFrom関数を使用します。INSERT INTO raster_table Select 3, 'NC', ST_ImportFrom('chunk_table','oss://<access_id>:<secret_key>@[<Endpoint>]/<bucket>/path_to/file'); -
ST_CreateRast関数を使用します。INSERT INTO raster_table Select 4, 'NC', ST_CreateRast('oss://<access_id>:<secret_key>@[<Endpoint>]/<bucket>/path_to/file');
TIFF データとは異なり、HDF5 および NetCDF ファイルには複数の サブデータセット を含めることができます。インポート時には、次の例に示すように、ファイルパスに サブデータセット の名前を追加して指定する必要があります。
-
NetCDF ファイル
INSERT INTO raster_table Select 5, 'NC', ST_ImportFrom('chunk_table','oss://<access_id>:<secret_key>@[<Endpoint>]/<bucket>/path_to/file.nc:sub_name'); -
HDF5 ファイル
INSERT INTO raster_table Select 5, 'HDF5', ST_ImportFrom('chunk_table','oss://<access_id>:<secret_key>@[<Endpoint>]/<bucket>/path_to/file.hdf5://path/sub_name');
3次元を超える NetCDF または HDF5 ファイルの場合、chunkdim パラメーターも指定する必要があります。これは、Raster データが (w, h, b) 次元のチャンクとしてデータベースにロードおよび格納されるためです。ここで、w はチャンクの幅、h はチャンクの高さ、b はバンドの数です。2つ以上の空間次元を持つファイルの場合、x および y 次元以外のすべての次元のサイズの積に b を設定する必要があります。たとえば、次の NetCDF ファイルを考えます。
netcdf /Users/xiaofei/Data/raster/nc_demo.nc {
dimensions:
lon = 73;
lat = 73;
time = 10;
isobaric = 12;
variables:
...
}
この例では、空間次元 lon および lat に加えて、time と isobaric という他の 2 つの次元があります。ST_ImportFrom を使用してこのデータをインポートする場合、正しいクエリ結果を保証するために、chunkdim パラメーターのバンド数 (b) は lon と lat を除くすべての次元のサイズの積である必要があります。この場合、値は 10 × 12 = 120 です。対応する SQL 文は次のようになります。
INSERT INTO nc_table VALUES(1, ST_ImportFrom('nc_rbt', '/Users/xiaofei/Data/raster/nc_demo.nc','{"chunkdim":"(256,256,120)"}'));
データの一括インポート
OSS から複数のファイルを一括でインポートするには、スクリプトを使用できます。次の Python の例は、OSS からデータベースにラスターデータをインポートする方法を示しています。
次の例は、OSS からデータベースにラスターデータを一括でインポートする場合にのみ使用できます。開始する前に、Python を初期化する必要があります。詳細については、「Pythonの初期化」をご参照ください。
# 必要なライブラリをインポート
import oss2
import psycopg2
import logging
# --- 接続詳細 ---
# プレースホルダーを実際の認証情報とエンドポイント情報に置き換えてください。
OSS_ACCESS_KEY_ID = "YOUR_ACCESS_KEY_ID"
OSS_ACCESS_KEY_SECRET = "YOUR_ACCESS_KEY_SECRET"
OSS_ENDPOINT = "YOUR_OSS_ENDPOINT" # 例:'oss-us-west-1.aliyuncs.com'
OSS_BUCKET_NAME = "YOUR_BUCKET_NAME"
OSS_PREFIX = "your_data_prefix/" # データが格納されているバケット内のフォルダー。
DB_HOST = "your_host"
DB_PORT = "your_port"
DB_NAME = "your_database"
DB_USER = "your_user"
DB_PASSWORD = "your_password"
DB_SCHEMA = "your_schema" # ラスターテーブルが配置されているスキーマ。
RASTER_TABLE_NAME = "your_raster_table"
# --- スクリプトロジック ---
# ロギングの設定
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# OSSへの接続
auth = oss2.Auth(OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET)
bucket = oss2.Bucket(auth, OSS_ENDPOINT, OSS_BUCKET_NAME)
# データベースへの接続
try:
con = psycopg2.connect(
database=DB_NAME,
user=DB_USER,
password=DB_PASSWORD,
host=DB_HOST,
port=DB_PORT,
options=f"-c search_path={DB_SCHEMA},public"
)
cur = con.cursor()
logging.info("データベースへの接続に成功しました。")
except (Exception, psycopg2.Error) as error:
logging.error(f"PostgreSQLへの接続中にエラーが発生しました: {error}")
exit()
# 挿入用のSQL文
# この例ではST_CreateRastを使用します。必要に応じてST_ImportFromに変更してください。
# 注:ST_ImportFromの場合、チャンクテーブル名も指定する必要があります。
insert_sql = f"INSERT INTO {RASTER_TABLE_NAME}(filename, rast) VALUES (%s, ST_CreateRast(%s))"
# OSS内のファイルを反復処理し、SQLを生成してインポート
try:
for obj in oss2.ObjectIterator(bucket, prefix=OSS_PREFIX):
if obj.key.endswith(".hdf5"): # または .tif、.ncなど
filename = obj.key.split('/')[-1]
# Ganos関数用の完全なOSSパスを構築
oss_path = f"oss://{OSS_ACCESS_KEY_ID}:{OSS_ACCESS_KEY_SECRET}@{OSS_ENDPOINT}/{OSS_BUCKET_NAME}/{obj.key}"
try:
cur.execute(insert_sql, (filename, oss_path))
con.commit()
logging.info(f"{filename} のインポートに成功しました")
except (Exception, psycopg2.Error) as e:
con.rollback() # エラー時にトランザクションをロールバック
logging.error(f"{filename} のインポート中にエラーが発生しました: {e}")
finally:
# カーソルと接続を閉じる
if 'con' in locals() and con:
cur.close()
con.close()
logging.info("データベース接続が閉じられました。")
まとめ
クラウドネイティブデータベース PolarDB は、データインジェストに独自のアプローチを提供します。GanosBase の関数ベースのインポートツールを使用すると、データのインポート、クエリ、分析、および提供のための統合ワークフローを完全に SQL 内で構築できます。この SQL 中心のアプローチは、ビジネスの全段階におけるデータ操作を簡素化し、全体的な使いやすさを向上させます。