以線串傳回多邊形的第 n 個內環。 這些內環不是按照幾何方位排列。而是根據內部幾何驗證常式定義的規則排列。 所以無法預先定義內環次序。
語法
ST_InteriorRingN(p ST_Polygon, n Integer)
回覆類型
db2gse.ST_LineString
範例
研究幾個南海島嶼上的鳥群的一位鳥類學家,知道某特定弱勢鳥類的哺育區侷限於海岸線。 部份島嶼有湖泊。另一種較具侵略性鳥類獨佔這些湖泊的湖岸。 這位鳥類學家知道,就每一個島嶼來說,若湖泊的周邊長度超過某臨界值,侵略性鳥類不斷繁殖而威脅到弱勢海岸鳥類的生存。 因此這位鳥類學家需要島嶼的內環周長總計。
在圖 34中,這些島嶼的外環代表每一個島嶼與海洋共用的生態介面。 部份島嶼有湖泊,多邊形的內環代表這些湖泊。
圖 34. 使用 ST_InteriorRingN 判斷島嶼內的湖岸長度。
![]() |
ISLANDS 表格的 ID 和名稱直欄識別各個島嶼,用地多邊形直欄儲存島嶼的幾何。
CREATE TABLE ISLANDS (id integer, name varchar(32), land db2gse.ST_Polygon);
下列 ODBC 程式使用 ST_InteriorRingN 函數,從每一個島嶼多邊形取出內環 (湖泊) 作為線串。 長度函數傳回的線串周長經過總計並連同島嶼 ID 一起顯示。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "sg.h" #include "sgerr.h" #include "sqlcli1.h" /*** *** *** 變更這些常數 *** *** ***/ #define USER_NAME "sdetest" /* 您的使用者名稱 */ #define USER_PASS "acid.rain" /* 您的使用者通行碼 */ #define DB_NAME "mydb" /* 要連接的資料庫 */ static void check_sql_err (SQLHDBC handle, SQLHSTMT hstmt, LONG rc, CHAR *str); void main( argc, argv ) int argc; char *argv[]; { SQLHDBC handle; SQLHENV henv; CHAR sql_stmt[256]; LONG rc, total_perimeter, num_lakes, lake_number, island_id, lake_perimeter; SQLHSTMT island_cursor, lake_cursor; SDWORD pcbvalue, id_ind, lake_ind, length_ind; /* 配置記憶體給 ODBC 環境 handle henv 並起始設定應用程式。 */ rc = SQLAllocEnv (&henv); if (rc != SQL_SUCCESS) { printf ("SQLAllocEnv failed with %d\n", rc); exit(0); } /* 配置記憶體給 henv 環境內的連接 handle。 */ rc = SQLAllocConnect (henv, &handle); if (rc != SQL_SUCCESS) { printf ("SQLAllocConnect failed with %d\n", rc); exit(0); } /* 載入 ODBC 驅動程式,並連接資料庫、使用者和通行碼所識別的資料來源。*/ rc = SQLConnect (handle, (UCHAR *)DB_NAME, SQL_NTS, (UCHAR *)USER_NAME, SQL_NTS, (UCHAR *)USER_PASS, SQL_NTS); check_sql_err (handle, NULL, rc, "SQLConnect"); /* 配置記憶體給 SQL 陳述式 handle island_cursor。 */ rc = SQLAllocStmt (handle, &island_cursor); check_sql_err (handle, NULL, rc, "SQLAllocStmt"); /* 準備並執行查詢以取得島嶼 ID 和湖泊數目 (內環) */ strcpy (sql_stmt, "select id, db2gse.ST_NumInteriorRings(land) from ISLANDS"); rc = SQLExecDirect (island_cursor, (UCHAR *)sql_stmt, SQL_NTS); check_sql_err (NULL, island_cursor, rc, "SQLExecDirect"); /* 連結島嶼表格的 ID 直欄與變數 island_id */ rc = SQLBindCol (island_cursor, 1, SQL_C_SLONG, &island_id, 0, &id_ind); check_sql_err (NULL, island_cursor, rc, "SQLBindCol"); /* 連結 numinteriorrings(land) 的結果與 num_lakes 變數。 */ rc = SQLBindCol (island_cursor, 2, SQL_C_SLONG, &num_lakes, 0, &lake_ind); check_sql_err (NULL, island_cursor, rc, "SQLBindCol"); /* 配置記憶體給 SQL 陳述式 handle lake_cursor。 */ rc = SQLAllocStmt (handle, &lake_cursor); check_sql_err (handle, NULL, rc, "SQLAllocStmt"); /* 準備查詢以取得內環的長度。 */ strcpy (sql_stmt, "select Length(db2gse.ST_InteriorRingN(land, cast (? as integer))) from ISLANDS where id = ?"); rc = SQLPrepare (lake_cursor, (UCHAR *)sql_stmt, SQL_NTS); check_sql_err (NULL, lake_cursor, rc, "SQLPrepare"); /* 連結 lake_number 變數成為第一個輸入參數 */ pcbvalue = 0; rc = SQLBindParameter (lake_cursor, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &lake_number, 0, &pcbvalue); check_sql_err (NULL, lake_cursor, rc, "SQLBindParameter"); /* 連結 island_id 成為第二個輸入參數 */ pcbvalue = 0; rc = SQLBindParameter (lake_cursor, 2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &island_id, 0, &pcbvalue); check_sql_err (NULL, lake_cursor, rc, "SQLBindParameter"); /* Bind the result of the Length(db2gse.ST_InteriorRingN(land, cast (? as integer))) to the variable lake_perimeter */ rc = SQLBindCol (lake_cursor, 1, SQL_C_SLONG, &lake_perimeter, 0, &length_ind); check_sql_err (NULL, island_cursor, rc, "SQLBindCol"); /* 外部迴圈, 取得島嶼 ID 和湖泊數目 (內環) */ while (SQL_SUCCESS == rc) { /* 提取一個島嶼 */ rc = SQLFetch (island_cursor); if (rc != SQL_NO_DATA) { check_sql_err (NULL, island_cursor, rc, "SQLFetch"); /* 內部迴圈, 針對此島嶼, 取得其全部湖泊的周長 (內環) */ for (total_perimeter = 0,lake_number = 1; lake_number <= num_lakes; lake_number++) { rc = SQLExecute (lake_cursor); check_sql_err (NULL, lake_cursor, rc, "SQLExecute"); rc = SQLFetch (lake_cursor); check_sql_err (NULL, lake_cursor, rc, "SQLFetch"); total_perimeter += lake_perimeter; SQLFreeStmt (lake_cursor, SQL_CLOSE); } } /* 顯示島嶼 ID 及其湖泊的總周長。*/ printf ("Island ID = %d, Total lake perimeter = %d\n", island_id,total_perimeter); } SQLFreeStmt (lake_cursor, SQL_DROP); SQLFreeStmt (island_cursor, SQL_DROP); SQLDisconnect (handle); SQLFreeConnect (handle); SQLFreeEnv (henv); printf( "\nTest Complete ...\n" ); } static void check_sql_err (SQLHDBC handle, SQLHSTMT hstmt, LONG rc, CHAR *str) { SDWORD dbms_err = 0; SWORD length; UCHAR err_msg[SQL_MAX_MESSAGE_LENGTH], state[6]; if (rc != SQL_SUCCESS) { SQLError (SQL_NULL_HENV, handle, hstmt, state, &dbms_err, err_msg, SQL_MAX_MESSAGE_LENGTH - 1, &length); printf ("%s ERROR (%d): DBMS code:%d, SQL state: %s, message: \n %s\n", str, rc, dbms_err, state, err_msg); if (handle) { SQLDisconnect (handle); SQLFreeConnect (handle); } exit(1); } }