Gibt den nen inneren Ring eines Polygons als Linienfolge zurück. Die Ringe sind nicht nach ihrer geometrischen Anordnung geordnet. Sie sind entsprechend den Regeln der internen geometrischen Prüfroutinen angeordnet. Die Reihenfolge der Ringe kann daher nicht vordefiniert werden.
Syntax
ST_InteriorRingN(p ST_Polygon, n Integer)
Rückgabetyp
db2gse.ST_LineString
Beispiele
Ein Ornithologe, der den Vogelbestand auf verschiedenen Südseeinseln untersucht, weiß, daß sich die Zone für die Nahrungssuche einer bestimmten passiven Spezies auf die Küstenlinie beschränkt. Auf manchen der Inseln gibt es kleine Seen. Die Ufer der Seen werden ausschließlich von einer aggressiveren Spezies bevölkert. Der Ornithologe weiß, daß ab einer bestimmten Uferlänge an den Seen die aggressive Spezies so zahlreich wird, daß sie die passive Spezies an der Küste bedroht. Der Ornithologe will daher die Summe der Uferlängen der inneren Ringe der Inseln wissen.
In Abbildung 34 stellen die äußeren Ringe der Inseln die ökologische Schnittstelle zwischen den Inseln und dem Meer dar. Auf manchen der Inseln gibt es Seen, die als innere Ringe der Polygone dargestellt sind.
Abbildung 34. Mit ST_InteriorRingN die Länge der Seeufer auf allen Inseln ermitteln
Die Spalten ID und name der Tabelle ISLANDS kennzeichnen alle Inseln, und die Polygonspalte land speichert die Geometrie dieser Inseln.
CREATE TABLE ISLANDS (id integer, name varchar(32), land db2gse.ST_Polygon);
Das folgende ODBC-Programm extrahiert mit der Funktion ST_InteriorRingN den inneren Ring (lake) aus jedem Inselpolygon als Linienfolge. Der Umfang der zurückgegebenen Linienfolge wird akkumuliert und zusammen mit der ID der Insel angezeigt.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "sg.h" #include "sgerr.h" #include "sqlcli1.h" /*** *** *** Change these constants *** *** ***/ #define USER_NAME "sdetest" /* your user name */ #define USER_PASS "acid.rain" /* your user password */ #define DB_NAME "mydb" /* database to connect to */ 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; /* Allocate memory for the ODBC environment handle henv and initialize the application. */ rc = SQLAllocEnv (&henv); if (rc != SQL_SUCCESS) { printf ("SQLAllocEnv failed with %d\n", rc); exit(0); } /* Allocate memory for a connection handle within the henv environment. */ rc = SQLAllocConnect (henv, &handle); if (rc != SQL_SUCCESS) { printf ("SQLAllocConnect failed with %d\n", rc); exit(0); } /* Load the ODBC driver and connect to the data source identified by the database, user, and password.*/ 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"); /* Allocate memory to the SQL statement handle island_cursor. */ rc = SQLAllocStmt (handle, &island_cursor); check_sql_err (handle, NULL, rc, "SQLAllocStmt"); /* Prepare and execute the query to get the island IDs and number of lakes (interior rings) */ 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"); /* Bind the island table's ID column to the variable island_id */ rc = SQLBindCol (island_cursor, 1, SQL_C_SLONG, &island_id, 0, &id_ind); check_sql_err (NULL, island_cursor, rc, "SQLBindCol"); /* Bind the result of numinteriorrings(land) to the num_lakes variable. */ rc = SQLBindCol (island_cursor, 2, SQL_C_SLONG, &num_lakes, 0, &lake_ind); check_sql_err (NULL, island_cursor, rc, "SQLBindCol"); /* Allocate memory to the SQL statement handle lake_cursor. */ rc = SQLAllocStmt (handle, &lake_cursor); check_sql_err (handle, NULL, rc, "SQLAllocStmt"); /* Prepare the query to get the length of an interior ring. */ 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"); /* Bind the lake_number variable as the first input parameter */ 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"); /* Bind the island_id as the second input parameter */ 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))) an die Variable lake_perimeter binden */ rc = SQLBindCol (lake_cursor, 1, SQL_C_SLONG, &lake_perimeter, 0, &length_ind); check_sql_err (NULL, island_cursor, rc, "SQLBindCol"); /* Outer loop, get the island ids and the number of lakes (interior rings) */ while (SQL_SUCCESS == rc) { /* Fetch an island */ rc = SQLFetch (island_cursor); if (rc != SQL_NO_DATA) { check_sql_err (NULL, island_cursor, rc, "SQLFetch"); /* Inner loop, for this island, get the perimeter of all of its lakes (interior rings) */ 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); } } /* Display the Island id and the total perimeter of its lakes. */ 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 fertig ...\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); } }