load_shapes.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263
  1. /***********************************************************************
  2. *
  3. * load_shapes.c -- Inserts of all shape types from binary.
  4. *
  5. *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  6. *
  7. * Purpose:
  8. * Tests inserts of all shape types from binary.
  9. *
  10. ***********************************************************************/
  11. /**********************************************************************
  12. * The following libraries contain the objects required during the
  13. * linking phase.
  14. *
  15. * $(INFORMIXDIR)/lib/cli/libifcli.a
  16. * $(INFORMIXDIR)/lib/cli/libifdmr.a
  17. *
  18. * These can be accessed by setting the library search path to
  19. * $INFORMIXDIR/lib/cli and specifying the 'ifcli' and 'ifdmr' libraries.
  20. * The 'infxcli.h' resource file can be found in $INFORMIXDIR/incl/cli.
  21. *
  22. * The following command will likely compile this source:
  23. *
  24. * cc -o load_shapes load_shapes.c -DNO_WIN32 \
  25. * -I$INFORMIXDIR/incl/cli -L$INFORMIXDIR/lib/cli -lifcli -lifdmr
  26. *
  27. ***********************************************************************/
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <float.h>
  32. #ifdef WINNT
  33. #include <io.h>
  34. #include <windows.h>
  35. #include <conio.h>
  36. #endif /*WINNT*/
  37. #include <infxcli.h> /* ODBC typedefs and data structures */
  38. #include "odbcutils.c" /* ODBC utility functions */
  39. #include "commfuncs.h"
  40. #include "commfuncs.c"
  41. #include "shapefuncs.c"
  42. /********************/
  43. /* Local Prototypes */
  44. /********************/
  45. static void insert_shape (SQLHDBC hdbc,
  46. SpatialColumn *sc,
  47. int id,
  48. GeomType geom_type,
  49. int data_len,
  50. char *binary);
  51. static void create_table (SQLHDBC hdbc,
  52. SpatialColumn *spatial_column);
  53. /***********************************************************************
  54. *
  55. * main -- Inserts of all shape types from binary shape format into a
  56. * test table.
  57. *
  58. *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  59. *
  60. * Purpose:
  61. * Load a table with all types of geometry from shapes.
  62. *
  63. *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  64. *
  65. * Parameters:
  66. * argc <Input> == (int) The parameter index.
  67. * argv <Input> == (char[] *) Pointer to an array of parameters.
  68. *
  69. ***********************************************************************/
  70. void main (int argc, char **argv)
  71. {
  72. SQLHDBC hdbc;
  73. SQLHENV henv;
  74. char *binary;
  75. SpatialColumn sc;
  76. Geometry geom = {0};
  77. int offsets[6];
  78. Point pt[30];
  79. double z[30];
  80. double m[30];
  81. int data_len;
  82. int max_alloced = 0;
  83. /* Check for the correct number of arguments entered. */
  84. if (argc < 2)
  85. {
  86. printf ("Usage: %s <datasource> [<srid>]\n", argv[0]);
  87. printf ("\n");
  88. printf ("<datasource> is name of ODBC DSN.\n");
  89. printf ("<srid> is optional.\n");
  90. printf ("\nThis program will create a table named 'shape_test' and\n");
  91. printf ("insert data using various SE_xxxFromShape functions.\n");
  92. exit (1);
  93. }
  94. /* Connect to database */
  95. server_connect ((SQLCHAR*) argv[1], &henv, &hdbc);
  96. strcpy (sc.table, "shape_test");
  97. strcpy (sc.column, "geom");
  98. sc.srid = (argc > 2) ? atoi(argv[2]) : 0;
  99. /* Create the test table */
  100. create_table (hdbc, &sc);
  101. /* The remainder of the main function prepares the various
  102. geometry data types with valid X, Y coordinates, Z ordinates and
  103. measures. It passes these geometries to make_shape function
  104. which converts them into shapes. The shapes are then passed to
  105. the insert_shape function which inserts the shapes into the spatial
  106. column of the table. Insert_shape also inserts an integer key into
  107. the table.
  108. The make_shape function also returns data_len, the number of bytes
  109. in the shape. The insert_shape function passes this number to the
  110. ODBC SQLBindParameter function. */
  111. geom.offsets = offsets;
  112. geom.pt = pt;
  113. geom.z = z;
  114. geom.m = m;
  115. /**********/
  116. /* */
  117. /* POINTS */
  118. /* */
  119. /**********/
  120. /*======================================================================*/
  121. /* */
  122. /* Insert a single point. */
  123. /* */
  124. /*======================================================================*/
  125. /* Populate the point. */
  126. pt[0].x = 10; pt[0].y = -10;
  127. geom.type = geomPoint;
  128. geom.num_points = 1;
  129. geom.num_parts = 1;
  130. /* Convert the point to an ESRI shape. */
  131. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  132. /* Insert the shape into the table */
  133. insert_shape (hdbc, &sc, 1, geomPoint, data_len, binary);
  134. /*======================================================================*/
  135. /* */
  136. /* Insert a point with a Z coordinate. */
  137. /* */
  138. /*======================================================================*/
  139. /* Populate the point. */
  140. pt[0].x = -50.123; pt[0].y = -50.1234567; z[0] = 50;
  141. geom.type = geomPointZ;
  142. geom.num_points = 1;
  143. geom.num_parts = 1;
  144. /* Convert the point to an ESRI shape. */
  145. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  146. /* Insert the shape into the table. */
  147. insert_shape (hdbc, &sc, 2, geomPoint, data_len, binary);
  148. /*======================================================================*/
  149. /* */
  150. /* Insert a point with a measure. */
  151. /* */
  152. /*======================================================================*/
  153. /* Populate the point. */
  154. pt[0].x = -.123; pt[0].y = -.1234567; m[0] = 10;
  155. geom.type = geomPointM;
  156. geom.num_points = 1;
  157. geom.num_parts = 1;
  158. /* Convert the point to an ESRI shape. */
  159. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  160. /* Insert the shape into the table. */
  161. insert_shape (hdbc, &sc, 3, geomPoint, data_len, binary);
  162. /*======================================================================*/
  163. /* */
  164. /* Insert a point with a Z coordinate and a measure. */
  165. /* */
  166. /*======================================================================*/
  167. /* Populate the point. */
  168. pt[0].x = 1; pt[0].y = 2; z[0] = 3; m[0] = 4;
  169. geom.type = geomPointZM;
  170. geom.num_points = 1;
  171. geom.num_parts = 1;
  172. /* Convert the point to an ESRI shape. */
  173. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  174. /* Insert the shape into the table. */
  175. insert_shape (hdbc, &sc, 4, geomPoint, data_len, binary);
  176. /***************/
  177. /* */
  178. /* MULTIPOINTS */
  179. /* */
  180. /***************/
  181. /*======================================================================*/
  182. /* */
  183. /* Insert a multipoint containing 5 points. */
  184. /* */
  185. /*======================================================================*/
  186. /* Populate the multipoint */
  187. pt[0].x = 1; pt[0].y = 2;
  188. pt[1].x = 3; pt[1].y = 4;
  189. pt[2].x = 5; pt[2].y = 6;
  190. pt[3].x = 7; pt[3].y = 8;
  191. pt[4].x = 9; pt[4].y = 10;
  192. geom.type = geomMultiPoint;
  193. geom.num_points = 5;
  194. geom.num_parts = 5;
  195. /* Convert the multipoint into an ESRI shape. */
  196. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  197. /* Insert the shape into a table. */
  198. insert_shape (hdbc, &sc, 5, geomMultiPoint, data_len, binary);
  199. /*======================================================================*/
  200. /* */
  201. /* Insert a multipoint containing a single point. */
  202. /* */
  203. /*======================================================================*/
  204. /* Populate the multipoint. */
  205. pt[0].x = 10.0; pt[0].y = 3.1415927;
  206. geom.type = geomMultiPoint;
  207. geom.num_points = 1;
  208. geom.num_parts = 1;
  209. /* Convert the multipoint into an ESRI shape. */
  210. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  211. /* Insert the shape into a table. */
  212. insert_shape (hdbc, &sc, 6, geomMultiPoint, data_len, binary);
  213. /*======================================================================*/
  214. /* */
  215. /* Insert a multipoint containing a three points sharing the same */
  216. /* location. This multipoint is non-simple since some of its points */
  217. /* share the same location. */
  218. /* */
  219. /*======================================================================*/
  220. /* Populate the multipoint. */
  221. pt[0].x = 1; pt[0].y = 1;
  222. pt[1].x = 1; pt[1].y = 1;
  223. pt[2].x = 1; pt[2].y = 1;
  224. geom.type = geomMultiPoint;
  225. geom.num_points = 3;
  226. geom.num_parts = 3;
  227. /* Convert the multipoint into an ESRI shape. */
  228. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  229. /* Insert the shape into a table. */
  230. insert_shape (hdbc, &sc, 7, geomMultiPoint, data_len, binary);
  231. /*======================================================================*/
  232. /* */
  233. /* Insert a multipoint containing a single point with a measure. */
  234. /* */
  235. /*======================================================================*/
  236. /* Populate the multipoint. */
  237. pt[0].x = -0.123; pt[0].y = -0.1234567; m[0] = 10;
  238. geom.type = geomMultiPointM;
  239. geom.num_points = 1;
  240. geom.num_parts = 1;
  241. /* Convert the multipoint into an ESRI shape. */
  242. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  243. /* Insert the shape into a multipoint. */
  244. insert_shape (hdbc, &sc, 8, geomMultiPoint, data_len, binary);
  245. /*======================================================================*/
  246. /* */
  247. /* Insert a multipoint containing three points with z coordinates and */
  248. /* measures. */
  249. /* */
  250. /*======================================================================*/
  251. /* Populate the multipoint. */
  252. pt[0].x = 1; pt[0].y = 2; z[0] = 3; m[0] = 4;
  253. pt[1].x = 5; pt[1].y = 6; z[1] = 7; m[1] = 8;
  254. pt[2].x = 9; pt[2].y = 10; z[2] = 11; m[2] = 12;
  255. geom.type = geomMultiPointZM;
  256. geom.num_points = 3;
  257. geom.num_parts = 3;
  258. /* Convert the multipoint into an ESRI shape. */
  259. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  260. /* Insert the shape into a multipoint. */
  261. insert_shape (hdbc, &sc, 9, geomMultiPoint, data_len, binary);
  262. /***************/
  263. /* */
  264. /* LINESTRINGS */
  265. /* */
  266. /***************/
  267. /*======================================================================*/
  268. /* */
  269. /* Insert a linestring containing two vertices. */
  270. /* */
  271. /*======================================================================*/
  272. /* Populate the linestring. */
  273. pt[0].x = -50.123; pt[0].y = -50.1234567;
  274. pt[1].x = 50; pt[1].y = 50;
  275. geom.type = geomLineString;
  276. geom.num_points = 2;
  277. geom.num_parts = 1;
  278. /* Convert the linestring into a shape. */
  279. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  280. /* Insert the shape into a table. */
  281. insert_shape (hdbc, &sc, 10, geomLineString, data_len, binary);
  282. /*======================================================================*/
  283. /* */
  284. /* Insert a linestring contain 6 vertices. */
  285. /* */
  286. /*======================================================================*/
  287. /* Populate the linestring. */
  288. pt[0].x = 0; pt[0].y = 0;
  289. pt[1].x = 1; pt[1].y = 1;
  290. pt[2].x = 2; pt[2].y = 2;
  291. pt[3].x = 3; pt[3].y = 3;
  292. pt[4].x = 4.5; pt[4].y = 5.4;
  293. pt[5].x = 7; pt[5].y = 7;
  294. geom.type = geomLineString;
  295. geom.num_points = 6;
  296. geom.num_parts = 1;
  297. /* Convert the linestring into a shape. */
  298. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  299. /* Insert the shape into the table. */
  300. insert_shape (hdbc, &sc, 11, geomLineString, data_len, binary);
  301. /*======================================================================*/
  302. /* */
  303. /* Insert a linestring that is a ring containing 4 vertices. */
  304. /* */
  305. /*======================================================================*/
  306. /* Populate the linestring. */
  307. pt[0].x = 10; pt[0].y = 10;
  308. pt[1].x = 10; pt[1].y = 20;
  309. pt[2].x = 20; pt[2].y = 10;
  310. pt[3].x = 10; pt[3].y = 10;
  311. geom.type = geomLineString;
  312. geom.num_points = 4;
  313. geom.num_parts = 1;
  314. /* Convert the linestring into a shape. */
  315. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  316. /* Insert the shape into the table. */
  317. insert_shape (hdbc, &sc, 12, geomLineString, data_len, binary);
  318. /*======================================================================*/
  319. /* */
  320. /* Insert a linestring that intersects its interior and therefore is */
  321. /* non-simple. */
  322. /* */
  323. /*======================================================================*/
  324. /* Populate the linestring. */
  325. pt[0].x = 10; pt[0].y = 10;
  326. pt[1].x = 20; pt[1].y = 20;
  327. pt[2].x = 25; pt[2].y = 15;
  328. pt[3].x = 0; pt[3].y = 15;
  329. geom.type = geomLineString;
  330. geom.num_points = 4;
  331. geom.num_parts = 1;
  332. /* Convert the linestring into a shape. */
  333. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  334. /* Insert the shape into the table. */
  335. insert_shape (hdbc, &sc, 13, geomLineString, data_len, binary);
  336. /*======================================================================*/
  337. /* */
  338. /* Insert a linestring containing two vertices with Z coordinates. */
  339. /* */
  340. /*======================================================================*/
  341. /* Populate the linestring. */
  342. pt[0].x = -50.123; pt[0].y = -50.1234567; z[0] = 50;
  343. pt[1].x = 1; pt[1].y = 2; z[1] = 60;
  344. geom.type = geomLineStringZ;
  345. geom.num_points = 2;
  346. geom.num_parts = 1;
  347. /* Convert the linestring into a shape. */
  348. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  349. /* Insert the shape into the table. */
  350. insert_shape (hdbc, &sc, 14, geomLineString, data_len, binary);
  351. /*======================================================================*/
  352. /* */
  353. /* Insert a linestring containing two vertices with measures. */
  354. /* */
  355. /*======================================================================*/
  356. /* Populate the linestring. */
  357. pt[0].x = 1; pt[0].y = 2; m[0] = 3;
  358. pt[1].x = 4; pt[1].y = 5; m[1] = 6;
  359. geom.type = geomLineStringM;
  360. geom.num_points = 2;
  361. geom.num_parts = 1;
  362. /* Convert the linestring into a shape. */
  363. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  364. /* Insert the shape into the table. */
  365. insert_shape (hdbc, &sc, 15, geomLineString, data_len, binary);
  366. /*======================================================================*/
  367. /* */
  368. /* Insert a linestring containing two vertices with Z ordinate and */
  369. /* measures. */
  370. /* */
  371. /*======================================================================*/
  372. /* Populate the linestring. */
  373. pt[0].x = 7; pt[0].y = 8; z[0] = 9; m[0] = 10;
  374. pt[1].x = 11; pt[1].y = 12; z[1] = 13; m[1] = 14;
  375. geom.type = geomLineStringZM;
  376. geom.num_points = 2;
  377. geom.num_parts = 1;
  378. /* Convert the linestring into a shape. */
  379. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  380. /* Insert the shape into the table. */
  381. insert_shape (hdbc, &sc, 16, geomLineString, data_len, binary);
  382. /********************/
  383. /* */
  384. /* MULTILINESTRINGS */
  385. /* */
  386. /********************/
  387. /*======================================================================*/
  388. /* */
  389. /* Insert a multilinestring containing two linestrings that intersect */
  390. /* each others interiors. Since the elements of the multilinestring */
  391. /* intersect at their interior it is not simple. */
  392. /* */
  393. /*======================================================================*/
  394. /* The first linestring. */
  395. pt[0].x = 10; pt[0].y = 10; offsets[0] = 0;
  396. pt[1].x = 10; pt[1].y = 20;
  397. /* The second linestring. */
  398. pt[2].x = 5; pt[2].y = 15; offsets[1] = 2;
  399. pt[3].x = 15; pt[3].y = 15;
  400. geom.type = geomLineString;
  401. geom.num_points = 4;
  402. geom.num_parts = 2;
  403. /* Convert the multilinestring into a shape. */
  404. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  405. /* Insert the shape into the table. */
  406. insert_shape (hdbc, &sc, 17, geomMultiLineString, data_len, binary);
  407. /*======================================================================*/
  408. /* */
  409. /* Insert a multilinestring containing four linestrings that do not */
  410. /* intersect. The multilinestring is simple since its interior is not */
  411. /* intersected. */
  412. /* */
  413. /*======================================================================*/
  414. /* The first linestring. */
  415. pt[0].x = 1; pt[0].y = 1; offsets[0] = 0;
  416. pt[1].x = 11; pt[1].y = 1;
  417. pt[2].x = 11; pt[2].y = -9;
  418. /* The second linestring. */
  419. pt[3].x = 4; pt[3].y = 10; offsets[1] = 3;
  420. pt[4].x = 4; pt[4].y = 20;
  421. /* The third linestring. */
  422. pt[5].x = 10; pt[5].y = 10; offsets[2] = 5;
  423. pt[6].x = 20; pt[6].y = 10;
  424. /* The fourth linestring. */
  425. pt[7].x = -10; pt[7].y = -10; offsets[3] = 7;
  426. pt[8].x = -20; pt[8].y = -10;
  427. pt[9].x = -30; pt[9].y = -10;
  428. pt[10].x = -30; pt[10].y = 0;
  429. geom.type = geomLineString;
  430. geom.num_points = 11;
  431. geom.num_parts = 4;
  432. /* Convert the multilinestring into a shape. */
  433. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  434. /* Insert the shape into the table. */
  435. insert_shape (hdbc, &sc, 18, geomMultiLineString, data_len, binary);
  436. /*======================================================================*/
  437. /* */
  438. /* Insert a multilinestring containing 3 linestrings with Z ordinates. */
  439. /* */
  440. /*======================================================================*/
  441. /* The first linestring. */
  442. pt[0].x = 1; pt[0].y = 1; z[0] = 10; offsets[0] = 0;
  443. pt[1].x = 11; pt[1].y = 1; z[1] = 20;
  444. pt[2].x = 11; pt[2].y = 11; z[2] = 30;
  445. /* The second linestring. */
  446. pt[3].x = 4; pt[3].y = 10; z[3] = -1; offsets[1] = 3;
  447. pt[4].x = 4; pt[4].y = 20; z[4] = 2;
  448. /* The third linestring. */
  449. pt[5].x = 10; pt[5].y = 10; z[5] = 10;
  450. pt[6].x = 20; pt[6].y = 10; z[6] = 20; offsets[2] = 5;
  451. geom.type = geomLineStringZ;
  452. geom.num_points = 7;
  453. geom.num_parts = 3;
  454. /* Convert the multilinestring into a shape. */
  455. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  456. /* Insert the shape into the table. */
  457. insert_shape (hdbc, &sc, 19, geomMultiLineString, data_len, binary);
  458. /*======================================================================*/
  459. /* */
  460. /* Insert a multilinestring containing 2 linestrings with measures. */
  461. /* */
  462. /*======================================================================*/
  463. /* The first linestring. */
  464. pt[0].x = 1; pt[0].y = 1; m[0] = 10; offsets[0] = 0;
  465. pt[1].x = 1; pt[1].y = 10; m[1] = 20;
  466. /* The second linestring. */
  467. pt[2].x = 11; pt[2].y = 11; m[2] = 30; offsets[1] = 2;
  468. pt[3].x = 21; pt[3].y = 10; m[3] = -1;
  469. geom.type = geomLineStringM;
  470. geom.num_points = 4;
  471. geom.num_parts = 2;
  472. /* Convert the multilinestring into a shape. */
  473. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  474. /* Insert the shape into the table. */
  475. insert_shape (hdbc, &sc, 20, geomMultiLineString, data_len, binary);
  476. /*======================================================================*/
  477. /* */
  478. /* Insert a multilinestring comtaining two linestrings with Z ordinates */
  479. /* and measures. */
  480. /* */
  481. /*======================================================================*/
  482. /* The first linestring. */
  483. pt[0].x = 1; pt[0].y = 1; z[0] = 10; m[0] = 10; offsets[0] = 0;
  484. pt[1].x = 11; pt[1].y = 1; z[1] = 15; m[1] = 20;
  485. pt[2].x = 11; pt[2].y = 11; z[2] = 25; m[2] = 30;
  486. /* The second linestring. */
  487. pt[3].x = 4; pt[3].y = 10; z[3] = 35; m[3] = 40; offsets[1] = 3;
  488. pt[4].x = 4; pt[4].y = 20; z[4] = 45; m[4] = 50;
  489. geom.type = geomLineStringZM;
  490. geom.num_points = 5;
  491. geom.num_parts = 2;
  492. /* Convert the multilinestring into a shape. */
  493. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  494. /* Insert the shape into the table. */
  495. insert_shape (hdbc, &sc, 21, geomMultiLineString, data_len, binary);
  496. /************/
  497. /* */
  498. /* POLYGONS */
  499. /* */
  500. /************/
  501. /*======================================================================*/
  502. /* */
  503. /* Insert a polygon with no interior rings. */
  504. /* */
  505. /*======================================================================*/
  506. /* The exterior ring */
  507. pt[0].x = 10; pt[0].y = 10;
  508. pt[1].x = 10; pt[1].y = 20;
  509. pt[2].x = 20; pt[2].y = 20;
  510. pt[3].x = 20; pt[3].y = 10;
  511. pt[4].x = 10; pt[4].y = 10;
  512. geom.type = geomPolygon;
  513. geom.num_points = 5;
  514. geom.num_parts = 1;
  515. /* Convert the polygon into a shape. */
  516. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  517. /* Insert the shape into a table. */
  518. insert_shape (hdbc, &sc, 22, geomPolygon, data_len, binary);
  519. /*======================================================================*/
  520. /* */
  521. /* Insert a polygon with one interior ring. */
  522. /* */
  523. /*======================================================================*/
  524. /* The exterior ring. */
  525. pt[0].x = 10; pt[0].y = 10; offsets[0] = 0;
  526. pt[1].x = 10; pt[1].y = 20;
  527. pt[2].x = 20; pt[2].y = 20;
  528. pt[3].x = 20; pt[3].y = 10;
  529. pt[4].x = 10; pt[4].y = 10;
  530. /* The interior ring. */
  531. pt[5].x = 12; pt[5].y = 12; offsets[1] = 5;
  532. pt[6].x = 12; pt[6].y = 13;
  533. pt[7].x = 13; pt[7].y = 13;
  534. pt[8].x = 13; pt[8].y = 12;
  535. pt[9].x = 12; pt[9].y = 12;
  536. geom.type = geomPolygon;
  537. geom.num_points = 10;
  538. geom.num_parts = 2;
  539. /* Convert the polygon into a shape. */
  540. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  541. /* Insert the shape into the table. */
  542. insert_shape (hdbc, &sc, 23, geomPolygon, data_len, binary);
  543. /*======================================================================*/
  544. /* */
  545. /* Insert a polygon with 2 interior rings and Z ordinates. */
  546. /* */
  547. /*======================================================================*/
  548. /* The exterior ring. */
  549. pt[0].x = 10; pt[0].y = 10; z[0] = 1; offsets[0] = 0;
  550. pt[1].x = 10; pt[1].y = 20; z[1] = 2;
  551. pt[2].x = 20; pt[2].y = 20; z[2] = 3;
  552. pt[3].x = 20; pt[3].y = 10; z[3] = 4;
  553. pt[4].x = 10; pt[4].y = 10; z[4] = 1;
  554. /* The first interior ring. */
  555. pt[5].x = 12; pt[5].y = 12; z[5] = 6; offsets[1] = 5;
  556. pt[6].x = 12; pt[6].y = 13; z[6] = 7;
  557. pt[7].x = 13; pt[7].y = 13; z[7] = 8;
  558. pt[8].x = 13; pt[8].y = 12; z[8] = 9;
  559. pt[9].x = 12; pt[9].y = 12; z[9] = 6;
  560. /* The second interior ring. */
  561. pt[10].x = 16; pt[10].y = 16; z[10] = 11; offsets[2] = 10;
  562. pt[11].x = 16; pt[11].y = 18; z[11] = 12;
  563. pt[12].x = 18; pt[12].y = 18; z[12] = 13;
  564. pt[13].x = 18; pt[13].y = 16; z[13] = 14;
  565. pt[14].x = 16; pt[14].y = 16; z[14] = 11;
  566. geom.type = geomPolygonZ;
  567. geom.num_points = 15;
  568. geom.num_parts = 3;
  569. /* Convert the polygon into a shape. */
  570. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  571. /* Insert the shape into a table. */
  572. insert_shape (hdbc, &sc, 24, geomPolygon, data_len, binary);
  573. /*======================================================================*/
  574. /* */
  575. /* Insert a polygon containing no interior rings with measures. */
  576. /* */
  577. /*======================================================================*/
  578. /* The exterior ring. */
  579. pt[0].x = 10; pt[0].y = 10; m[0] = 100;
  580. pt[1].x = 10; pt[1].y = 20; m[1] = -1;
  581. pt[2].x = 20; pt[2].y = 20; m[2] = 300;
  582. pt[3].x = 20; pt[3].y = 10; m[3] = -2;
  583. pt[4].x = 10; pt[4].y = 10; m[4] = 400;
  584. geom.type = geomPolygonM;
  585. geom.num_points = 5;
  586. geom.num_parts = 1;
  587. /* Convert the polygon into a shape. */
  588. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  589. /* Insert the shape into a table. */
  590. insert_shape (hdbc, &sc, 25, geomPolygon, data_len, binary);
  591. /*======================================================================*/
  592. /* */
  593. /* Insert a polygon with Z ordinates measures but no interior rings. */
  594. /* */
  595. /*======================================================================*/
  596. /* The exterior ring. */
  597. pt[0].x = 20; pt[0].y = 20; z[0] = 100; m[0] = -1;
  598. pt[1].x = 20; pt[1].y = 30; z[1] = -1; m[1] = -2;
  599. pt[2].x = 30; pt[2].y = 30; z[2] = 300; m[2] = -3;
  600. pt[3].x = 30; pt[3].y = 20; z[3] = -2; m[3] = -5;
  601. pt[4].x = 20; pt[4].y = 20; z[4] = 100; m[4] = -1;
  602. geom.type = geomPolygonZM;
  603. geom.num_points = 5;
  604. geom.num_parts = 1;
  605. /* Convert the polygon into a shape. */
  606. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  607. /* Insert the shape into a table. */
  608. insert_shape (hdbc, &sc, 26, geomPolygon, data_len, binary);
  609. /******************/
  610. /* */
  611. /* MULTIPOLYGONS */
  612. /* */
  613. /******************/
  614. /*======================================================================*/
  615. /* */
  616. /* Insert a multipolygon. The first polygon contains one interior ring, */
  617. /* the second polygon contains no interior rings, and the third polygon */
  618. /* contains two interior rings. */
  619. /* */
  620. /*======================================================================*/
  621. /* The first polygon's exterior ring. */
  622. pt[0].x = 10; pt[0].y = 10; offsets[0] = 0;
  623. pt[1].x = 10; pt[1].y = 20;
  624. pt[2].x = 20; pt[2].y = 20;
  625. pt[3].x = 20; pt[3].y = 10;
  626. pt[4].x = 10; pt[4].y = 10;
  627. /* The first polygon's interior ring. */
  628. pt[5].x = 14; pt[5].y = 14; offsets[1] = 5;
  629. pt[6].x = 14; pt[6].y = 16;
  630. pt[7].x = 16; pt[7].y = 16;
  631. pt[8].x = 16; pt[8].y = 14;
  632. pt[9].x = 14; pt[9].y = 14;
  633. /* The second polygon's exterior ring. */
  634. pt[10].x = 10; pt[10].y = 10; offsets[2] = 10;
  635. pt[11].x = 10; pt[11].y = 20;
  636. pt[12].x = 20; pt[12].y = 20;
  637. pt[13].x = 20; pt[13].y = 10;
  638. pt[14].x = 10; pt[14].y = 10;
  639. /* The third polygon's exterior ring. */
  640. pt[15].x = 50; pt[15].y = 50; offsets[3] = 15;
  641. pt[16].x = 50; pt[16].y = 60;
  642. pt[17].x = 60; pt[17].y = 60;
  643. pt[18].x = 60; pt[18].y = 50;
  644. pt[19].x = 50; pt[19].y = 50;
  645. /* The third polygon's interior ring. */
  646. pt[20].x = 52; pt[20].y = 52; offsets[4] = 20;
  647. pt[21].x = 52; pt[21].y = 54;
  648. pt[22].x = 54; pt[22].y = 54;
  649. pt[23].x = 54; pt[23].y = 52;
  650. pt[24].x = 52; pt[24].y = 52;
  651. /* The second polygon's interior ring. */
  652. pt[25].x = 56; pt[25].y = 56; offsets[5] = 25;
  653. pt[26].x = 56; pt[26].y = 58;
  654. pt[27].x = 58; pt[27].y = 58;
  655. pt[28].x = 58; pt[28].y = 56;
  656. pt[29].x = 56; pt[29].y = 56;
  657. geom.type = geomMultiPolygon;
  658. geom.num_points = 30;
  659. geom.num_parts = 6;
  660. /* Convert the multipolygon into a shape. */
  661. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  662. /* Insert the shape into the table. */
  663. insert_shape (hdbc, &sc, 27, geomMultiPolygon, data_len, binary);
  664. /*======================================================================*/
  665. /* */
  666. /* Insert a multipolygon containing two polygons with Z ordinates */
  667. /* and no interior rings. */
  668. /* */
  669. /*======================================================================*/
  670. /* The first polygon's exterior ring. */
  671. pt[0].x = 10; pt[0].y = 10; z[0] = 1; offsets[0] = 0;
  672. pt[1].x = 10; pt[1].y = 20; z[1] = 2;
  673. pt[2].x = 20; pt[2].y = 20; z[2] = 3;
  674. pt[3].x = 20; pt[3].y = 10; z[3] = 4;
  675. pt[4].x = 10; pt[4].y = 10; z[4] = 1;
  676. /* The second polygon's exterior ring. */
  677. pt[5].x = 1; pt[5].y = 1; z[5] = 1; offsets[1] = 5;
  678. pt[6].x = 1; pt[6].y = 5; z[6] = 2;
  679. pt[7].x = 5; pt[7].y = 5; z[7] = 3;
  680. pt[8].x = 5; pt[8].y = 1; z[8] = 4;
  681. pt[9].x = 1; pt[9].y = 1; z[9] = 1;
  682. geom.type = geomMultiPolygonZ;
  683. geom.num_points = 10;
  684. geom.num_parts = 2;
  685. /* Convert the multipolygon into a shape. */
  686. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  687. /* Insert the shape into a table. */
  688. insert_shape (hdbc, &sc, 28, geomMultiPolygon, data_len, binary);
  689. /*======================================================================*/
  690. /* */
  691. /* Insert a multipolygon containing two polygons with measures and no */
  692. /* interior rings. */
  693. /* */
  694. /*======================================================================*/
  695. /* The first polygon's exterior ring. */
  696. pt[0].x = 10; pt[0].y = 10; m[0] = 1; offsets[0] = 0;
  697. pt[1].x = 10; pt[1].y = 20; m[1] = 2;
  698. pt[2].x = 20; pt[2].y = 20; m[2] = 3;
  699. pt[3].x = 20; pt[3].y = 10; m[3] = 4;
  700. pt[4].x = 10; pt[4].y = 10; m[4] = 1;
  701. /* The second polygon's exterior ring. */
  702. pt[5].x = 1; pt[5].y = 1; m[5] = 5; offsets[1] = 5;
  703. pt[6].x = 1; pt[6].y = 5; m[6] = 6;
  704. pt[7].x = 5; pt[7].y = 5; m[7] = 7;
  705. pt[8].x = 5; pt[8].y = 1; m[8] = 8;
  706. pt[9].x = 1; pt[9].y = 1; m[9] = 9;
  707. geom.type = geomMultiPolygonM;
  708. geom.num_points = 10;
  709. geom.num_parts = 2;
  710. /* Convert the multipolygon into a shape. */
  711. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  712. /* Insert the shape into the table. */
  713. insert_shape (hdbc, &sc, 29, geomMultiPolygon, data_len, binary);
  714. /*======================================================================*/
  715. /* */
  716. /* Insert a multipolygon containing a two polygons with Z ordinates and */
  717. /* measures. The first polygon contains an interior ring, but the */
  718. /* second one does not. */
  719. /* */
  720. /*======================================================================*/
  721. /* The first polygon's exterior ring. */
  722. pt[0].x = 10; pt[0].y = 10; z[0] = 1; m[0] = 6; offsets[0] = 0;
  723. pt[1].x = 10; pt[1].y = 20; z[1] = 2; m[1] = 7;
  724. pt[2].x = 20; pt[2].y = 20; z[2] = 3; m[2] = 8;
  725. pt[3].x = 20; pt[3].y = 10; z[3] = 4; m[3] = 9;
  726. pt[4].x = 10; pt[4].y = 10; z[4] = 1; m[4] = 10;
  727. /* The first polygon's interior ring. */
  728. pt[5].x = 14; pt[5].y = 14; z[5] = -1; m[5] = -2; offsets[1] = 5;
  729. pt[6].x = 14; pt[6].y = 16; z[6] = 3; m[6] = 4;
  730. pt[7].x = 16; pt[7].y = 16; z[7] = -5; m[7] = 6;
  731. pt[8].x = 16; pt[8].y = 14; z[8] = 7; m[8] = -8;
  732. pt[9].x = 14; pt[9].y = 14; z[9] = -1; m[9] = -10.01;
  733. /* The second polygon's exterior ring. */
  734. pt[10].x = 1; pt[10].y = 1; z[10] = 9; m[10] = 6; offsets[2] = 10;
  735. pt[11].x = 1; pt[11].y = 5; z[11] = 6; m[11] = 7;
  736. pt[12].x = 5; pt[12].y = 5; z[12] = 7; m[12] = 8;
  737. pt[13].x = 5; pt[13].y = 1; z[13] = 8; m[13] = 9;
  738. pt[14].x = 1; pt[14].y = 1; z[14] = 9; m[14] = 16;
  739. geom.type = geomMultiPolygonZM;
  740. geom.num_points = 15;
  741. geom.num_parts = 3;
  742. /* Convert the multipolygon into a shape. */
  743. geom_to_shape (&geom, &max_alloced, &data_len, &binary);
  744. /* Insert the shape into the table. */
  745. insert_shape (hdbc, &sc, 30, geomMultiPolygon, data_len, binary);
  746. /**********************************/
  747. /* */
  748. /* Disconnect from the database. */
  749. /* */
  750. /**********************************/
  751. SQLDisconnect (hdbc); /* Close the connection */
  752. SQLFreeHandle (SQL_HANDLE_DBC, hdbc); /* Free the database handle */
  753. SQLFreeHandle (SQL_HANDLE_ENV, henv); /* Free the ODBC environment */
  754. }
  755. /***********************************************************************
  756. *
  757. * create_table - Creates a table for inserting spatial data
  758. *
  759. *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  760. *
  761. * Purpose:
  762. *
  763. *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  764. *
  765. * Parameters:
  766. * hdbc <Input> == (SQLHDBC) ODBC connection handle.
  767. * sc <Input> == (SpatialColumn *) Spatial column.
  768. *
  769. * RETURN <Output> == (void)
  770. *
  771. ***********************************************************************/
  772. static void create_table (
  773. SQLHDBC hdbc,
  774. SpatialColumn *sc
  775. )
  776. {
  777. SQLHSTMT hstmt;
  778. char sql_stmt[256];
  779. int rc;
  780. /* Allocate memory for the SQL statement handle and
  781. * associate the statement handle with the connection handle. */
  782. rc = SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &hstmt);
  783. returncode_check(NULL, hstmt, rc, "SQLAllocHandle");
  784. sprintf (sql_stmt, "DROP TABLE %s", sc->table);
  785. rc = SQLExecDirect (hstmt, (UCHAR *) sql_stmt, SQL_NTS);
  786. sprintf (sql_stmt, "CREATE TABLE %s (id integer, %s ST_Geometry)",
  787. sc->table, sc->column);
  788. rc = SQLExecDirect (hstmt, (UCHAR *) sql_stmt, SQL_NTS);
  789. returncode_check(NULL, hstmt, rc, "SQLExecDirect");
  790. SQLFreeStmt (hstmt, SQL_CLOSE); /* Close the statement handle */
  791. SQLFreeHandle (SQL_HANDLE_STMT, hstmt); /* Free the statement handle */
  792. }
  793. /***********************************************************************
  794. *
  795. * insert_shape - Inserts the shape and integer id values
  796. * into the spatial and id columns of the table
  797. * specified as arguments to the main program.
  798. *
  799. *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  800. *
  801. * Purpose:
  802. * The function inserts the shape into the
  803. * spatial column and an integer into the id column.
  804. *
  805. *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  806. *
  807. * Parameters:
  808. * hdbc <Input> == (SQLHDBC) ODBC connection handle.
  809. * sc <Input> == (SpatialColumn) Spatial column.
  810. * id <Input> == (int) The integer id value.
  811. * type <Input> == (GeomType) The data type of the geometry.
  812. * data_len <Input> == (int) The number of bytes in shape.
  813. * shape_buffer <Input> == (char *) The shape.
  814. *
  815. * RETURN <Output> == (void)
  816. *
  817. ***********************************************************************/
  818. static void insert_shape (
  819. SQLHDBC hdbc,
  820. SpatialColumn *sc,
  821. int id,
  822. GeomType type,
  823. int data_len,
  824. char *shape_buffer
  825. )
  826. {
  827. int rc;
  828. char shp_sql[256];
  829. char shpfunction[19];
  830. SQLHSTMT hstmt;
  831. SDWORD pcbvalue1;
  832. SDWORD pcbvalue2;
  833. /* Set the shpfunction to the "FromShape" function that corresponds */
  834. /* to the data type of the geometry representation. */
  835. switch (type)
  836. {
  837. case geomPoint:
  838. strcpy (shpfunction, "SE_PointFromShape");
  839. break;
  840. case geomLineString:
  841. strcpy (shpfunction, "SE_LineFromShape");
  842. break;
  843. case geomPolygon:
  844. strcpy (shpfunction, "SE_PolyFromShape");
  845. break;
  846. case geomMultiPoint:
  847. strcpy (shpfunction, "SE_MPointFromShape");
  848. break;
  849. case geomMultiLineString:
  850. strcpy (shpfunction, "SE_MLineFromShape");
  851. break;
  852. case geomMultiPolygon:
  853. strcpy (shpfunction, "SE_MPolyFromShape");
  854. break;
  855. }
  856. /* Generate the SQL insert expression. The integer value and the */
  857. /* name of the spatial column are entered as bind parameters. */
  858. sprintf (shp_sql,
  859. "insert into %s (id, %s) values (?, %s (?, %d))",
  860. sc->table, sc->column, shpfunction, sc->srid);
  861. /* Allocate memory for the SQL statement handle and associate the */
  862. /* statement handle with the connection handle. */
  863. rc = SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &hstmt);
  864. returncode_check (hdbc, NULL, rc, "SQLAllocHandle");
  865. /* Prepare the SQL statement for execution. */
  866. fprintf (stdout, "SQL is %s \n", shp_sql);
  867. rc = SQLPrepare (hstmt, (unsigned char *)shp_sql, SQL_NTS);
  868. returncode_check (NULL, hstmt, rc, "SQLPrepare");
  869. /* Bind the integer id value to the first parameter. */
  870. pcbvalue1 = 0;
  871. rc = SQLBindParameter (hstmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG,
  872. SQL_INTEGER, 0, 0, &id, 0, &pcbvalue1);
  873. returncode_check (NULL, hstmt, rc, "SQLBindParameter 1");
  874. /* Bind the shape to the second parameter. */
  875. pcbvalue2 = data_len;
  876. rc = SQLBindParameter (hstmt, 2, SQL_PARAM_INPUT, SQL_C_BINARY,
  877. SQL_INFX_UDT_LVARCHAR, data_len, 0,
  878. shape_buffer, data_len, &pcbvalue2);
  879. returncode_check (NULL, hstmt, rc, "SQLBindParameter 2");
  880. /* Execute the insert statement. */
  881. rc = SQLExecute (hstmt);
  882. returncode_check (NULL, hstmt, rc, "SQLExecute");
  883. /* Release the SQL statement handle and free all resources */
  884. /* associated with it. */
  885. rc = SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
  886. returncode_check (NULL, hstmt, rc, "SQLFreeHandle");
  887. }