The ST_InteriorRingN() function
The ST_InteriorRingN() function returns the nth interior ring of a polygon as an ST_LineString.
The order of the rings cannot be predefined since the rings are organized according to the rules defined by the internal geometry verification routines and not by geometric orientation.
Syntax
ST_InteriorRingN(pl1 ST_Polygon, index integer)
Return type
ST_LineString
Example
An ornithologist studying the bird population on several South Sea islands knows that the feeding zone of this passive species is restricted to the seashore. Some of the islands are so large they have several lakes on them. The shorelines of the lakes are inhabited exclusively by another more aggressive species. The ornithologist knows that if the perimeter of the ponds on each island exceeds a certain threshold, the aggressive species will become so numerous that it will threaten the passive seashore species. Therefore, the ornithologist requires the aggregated perimeter of the interior rings of the islands.
CREATE TABLE islands (id integer,
name varchar(32),
land ST_Polygon);
/* Prepare and execute the query to get the island IDs and number
of lakes (interior rings); */
sprintf(sql_stmt,
"SELECT id, ST_NumInteriorRing(land) FROM islands");
/* Allocate memory for the island cursor */
rc = SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &island_cursor);
rc = SQLExecDirect (island_cursor, (UCHAR *)sql_stmt, SQL_NTS);
/* Bind the island table's id column to island_id. */
rc = SQLBindCol (island_cursor, 1, SQL_C_SLONG,
&island_id, 0, &id_ind);
/* Bind the result of ST_NumInteriorRing(land) to num_lakes. */
rc = SQLBindCol (island_cursor, 2, SQL_C_SLONG,
&num_lakes, 0, &lake_ind);
/* Allocate memory to the SQL statement handle lake_cursor. */
rc = SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &lake_cursor);
/* Prepare the query to get the length of an interior ring. For
* efficiency, we only prepare this query once. */
sprintf (sql_stmt,
"SELECT ST_Length(ST_InteriorRingN(land, ?))"
"FROM islands WHERE id = ?");
rc = SQLPrepare (lake_cursor, (UCHAR *)sql_stmt, SQL_NTS);
/* Bind the lake_number to the first parameter. */
pcbvalue1 = 0;
rc = SQLBindParameter (lake_cursor, 1, SQL_PARAM_INPUT, SQL_C_LONG,
SQL_INTEGER, 0, 0,
&lake_number, 0, &pcbvalue1);
/* Bind the island_id to the second parameter. */
pcbvalue2 = 0;
rc = SQLBindParameter (lake_cursor, 2, SQL_PARAM_INPUT, SQL_C_LONG,
SQL_INTEGER, 0, 0,
&island_id, 0, &pcbvalue2);
/* Bind the result of the ST_Length function to lake_perimeter. */
rc = SQLBindCol (lake_cursor, 1, SQL_C_SLONG,
&lake_perimeter, 0, &length_ind);
/* Outer loop:
* get the island ids and the number of lakes (interior rings).*/
while (1)
{
/* Fetch an island.*/
rc = SQLFetch (island_cursor);
if (rc == SQL_NO_DATA)
break;
else
returncode_check(NULL, hstmt, rc, "SQLFetch");
/* Inner loop: for this island,
* get the perimeter of all its lakes (interior rings). */
for (total_perimeter = 0,lake_number = 1;
lake_number <= num_lakes;
lake_number++)
{
rc = SQLExecute (lake_cursor);
rc = SQLFetch (lake_cursor);
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);