interiorring.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /**************************************************************************
  2. *
  3. * interiorring.c
  4. *
  5. * This program demonstrates how to use ODBC to obtain information about
  6. * spatial data from a database using various Informix Spatial DataBlade
  7. * functions.
  8. *
  9. * The following command will likely compile this source:
  10. *
  11. * cc -o interiorring interiorring.c \
  12. * -I$INFORMIXDIR/incl/cli -L$INFORMIXDIR/lib/cli -lifcli -lifdmr
  13. *
  14. **************************************************************************/
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <float.h>
  19. #ifdef WINNT
  20. #include <io.h>
  21. #include <windows.h>
  22. #include <conio.h>
  23. #endif
  24. #include <infxcli.h> /* ODBC typedefs and data structures */
  25. #include "odbcutils.c" /* ODBC utility functions */
  26. /*
  27. * Constants, macros, typedefs, data structures, & utility functions
  28. */
  29. #include "commfuncs.h"
  30. #include "commfuncs.c"
  31. void main (int argc, char **argv)
  32. {
  33. SQLHDBC hdbc;
  34. SQLHENV henv;
  35. SQLHSTMT hstmt;
  36. char sql_stmt[100];
  37. int rc;
  38. int total_perimeter;
  39. int num_lakes;
  40. int lake_number;
  41. int island_id;
  42. int lake_perimeter;
  43. SQLHSTMT island_cursor;
  44. SQLHSTMT lake_cursor;
  45. SDWORD pcbvalue1, pcbvalue2;
  46. SDWORD id_ind;
  47. SDWORD lake_ind;
  48. SDWORD length_ind;
  49. /* Check for the correct number of arguments entered. */
  50. if (argc < 2)
  51. {
  52. printf ("Usage: %s <datasource>\n", argv[0]);
  53. exit (1);
  54. }
  55. /* Connect to the database. */
  56. server_connect ((UCHAR *) argv[1], &henv, &hdbc);
  57. /* Allocate memory for the SQL statement handle and
  58. * associate the statement handle with the connection handle. */
  59. rc = SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &hstmt);
  60. returncode_check (hdbc, (SQLHSTMT)NULL, rc, "SQLAllocHandle");
  61. rc = SQLExecDirect (hstmt, (UCHAR *) "DROP TABLE islands", SQL_NTS);
  62. rc = SQLExecDirect (hstmt, (UCHAR *) "CREATE TABLE islands (id int, land st_polygon)", SQL_NTS);
  63. returncode_check (NULL, hstmt, rc, "SQLExecDirect");
  64. #if 0
  65. rc = SQLExecDirect (hstmt, (UCHAR *) "INSERT INTO islands VALUES (123, '1000 POLYGON (( 2000 0000, 1847 0765, 1414 1414, 0765 1847, 0000 2000, -0765 1847, -1414 1414, -1847 0765, -2000 0000, -1847 -0765, -1414 -1414, -0765 -1847, 0000 -2000, 0765 -1847, 1414 -1414, 1847 -0765, 2000 0000), (1500 1000, 1300 1300, 1000 1500, 0650 1300, 0500 1000, 0646 0646, 1000 0500, 1354 0646, 1500 1000), (-500 1000, -0646 1354, -1000 1500, -1354 1354, -1500 1000, -1354 0646, -1000 500, -0646 0646, -0500 1000),( 0500 -1000, 0354 -0646, 0000 -0500, -0354 -0646, -0500 -1000, -0354 -1354, 0000 -1500, 0354 -1354, 0500 -1000))')", SQL_NTS);
  66. #else
  67. rc = SQLExecDirect (hstmt, (UCHAR *) "INSERT INTO islands VALUES (123, '0 POLYGON ((10 10, 10 40,40 40,40 10,10 10),(11 11, 11 17,17 17,17 11,11 11),(21 21, 21 31,31 31,31 21,21 21))')", SQL_NTS);
  68. #endif
  69. returncode_check (NULL, hstmt, rc, "SQLExecDirect");
  70. #if 0
  71. rc = SQLExecDirect (hstmt, (UCHAR *) "INSERT INTO islands VALUES (456, '1000 POLYGON (( 8000 6000, 7847 6765, 7414 7414, 6765 7847, 6000 8000, -6765 7847, -7414 7414, -7847 6765, -8000 6000, -7847 -6765, -7414 -7414, -6765 -7847, 6000 -8000, 6765 -7847, 7414 -7414, 7847 -6765, 8000 6000), (7500 7000, 7300 7300, 7038 7500, 6650 7302, 6500 7080, 6646 6646, 7290 6500, 7354 6646, 7500 7000),( 6500 -7000, 6354 -6646, 6000 -6500, -6354 -6646, -6500 -7000, -6354 -7354, 6000 -7500, 6354 -7354, 6500 -7000))')", SQL_NTS);
  72. #else
  73. rc = SQLExecDirect (hstmt, (UCHAR *) "INSERT INTO islands VALUES (456, '0 POLYGON ((100 100, 100 400,400 400,400 100,100 100),(101 101, 101 170,170 170,170 101,101 101))')", SQL_NTS);
  74. #endif
  75. returncode_check (NULL, hstmt, rc, "SQLExecDirect");
  76. /* INFORMIX_EXTEST_BEGIN interiorringn */
  77. /* Prepare and execute the query to get the island IDs and number
  78. of lakes (interior rings); */
  79. sprintf(sql_stmt,
  80. "SELECT id, ST_NumInteriorRing(land) FROM islands");
  81. /* Allocate memory for the island cursor */
  82. rc = SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &island_cursor);
  83. returncode_check (hdbc, (SQLHSTMT)NULL, rc, "SQLAllocHandle");
  84. rc = SQLExecDirect (island_cursor, (UCHAR *)sql_stmt, SQL_NTS);
  85. returncode_check (NULL, hstmt, rc, "SQLExecDirect");
  86. /* Bind the island table's id column to island_id. */
  87. rc = SQLBindCol (island_cursor, 1, SQL_C_SLONG,
  88. &island_id, 0, &id_ind);
  89. /* Bind the result of ST_NumInteriorRing(land) to num_lakes. */
  90. rc = SQLBindCol (island_cursor, 2, SQL_C_SLONG,
  91. &num_lakes, 0, &lake_ind);
  92. /* Allocate memory to the SQL statement handle lake_cursor. */
  93. rc = SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &lake_cursor);
  94. returncode_check (hdbc, (SQLHSTMT)NULL, rc, "SQLAllocHandle");
  95. /* Prepare the query to get the length of an interior ring. For
  96. * efficiency, we only prepare this query once. */
  97. sprintf (sql_stmt,
  98. "SELECT ST_Length(ST_InteriorRingN(land, ?))"
  99. "FROM islands WHERE id = ?");
  100. rc = SQLPrepare (lake_cursor, (UCHAR *)sql_stmt, SQL_NTS);
  101. returncode_check (NULL, hstmt, rc, "SQLPrepare");
  102. /* Bind the lake_number to the first parameter. */
  103. pcbvalue1 = 0;
  104. rc = SQLBindParameter (lake_cursor, 1, SQL_PARAM_INPUT, SQL_C_LONG,
  105. SQL_INTEGER, 0, 0,
  106. &lake_number, 0, &pcbvalue1);
  107. returncode_check (NULL, hstmt, rc, "SQLBindParameter");
  108. /* Bind the island_id to the second parameter. */
  109. pcbvalue2 = 0;
  110. rc = SQLBindParameter (lake_cursor, 2, SQL_PARAM_INPUT, SQL_C_LONG,
  111. SQL_INTEGER, 0, 0,
  112. &island_id, 0, &pcbvalue2);
  113. returncode_check (NULL, hstmt, rc, "SQLBindParameter");
  114. /* Bind the result of the ST_Length function to lake_perimeter. */
  115. rc = SQLBindCol (lake_cursor, 1, SQL_C_SLONG,
  116. &lake_perimeter, 0, &length_ind);
  117. /* Outer loop:
  118. * get the island ids and the number of lakes (interior rings).*/
  119. while (1)
  120. {
  121. /* Fetch an island.*/
  122. rc = SQLFetch (island_cursor);
  123. if (rc == SQL_NO_DATA)
  124. break;
  125. else
  126. returncode_check(NULL, hstmt, rc, "SQLFetch");
  127. /* Inner loop: for this island,
  128. * get the perimeter of all its lakes (interior rings). */
  129. for (total_perimeter = 0,lake_number = 1;
  130. lake_number <= num_lakes;
  131. lake_number++)
  132. {
  133. rc = SQLExecute (lake_cursor);
  134. returncode_check (NULL, hstmt, rc, "SQLExecute");
  135. rc = SQLFetch (lake_cursor);
  136. if (rc == SQL_NO_DATA)
  137. break;
  138. else
  139. returncode_check(NULL, hstmt, rc, "SQLFetch");
  140. total_perimeter += lake_perimeter;
  141. SQLFreeStmt (lake_cursor, SQL_CLOSE);
  142. }
  143. /* Display the island ID and the total perimeter of its lakes.*/
  144. printf ("Island ID = %d, Total lake perimeter = %d\n",
  145. island_id,total_perimeter);
  146. }
  147. SQLFreeStmt (lake_cursor, SQL_DROP);
  148. SQLFreeStmt (island_cursor, SQL_DROP);
  149. /* INFORMIX_EXTEST_END interiorringn */
  150. SQLFreeStmt (hstmt, SQL_CLOSE); /* Close the statement handle */
  151. SQLFreeHandle (SQL_HANDLE_STMT, hstmt); /* Free the statement handle */
  152. SQLDisconnect (hdbc); /* Close the connection */
  153. SQLFreeHandle (SQL_HANDLE_DBC, hdbc); /* Free the database handle */
  154. SQLFreeHandle (SQL_HANDLE_ENV, henv); /* Free the ODBC environment */
  155. printf( "\nTest Complete\n");
  156. }