/*********************************************************************** * * load_wkb.c -- Loads data in Well Known Binary data format. * * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: * Creates a sample dataset using OGIS Well Known Binary functions * ***********************************************************************/ /********************************************************************** * The following libraries contain the objects required during the * linking phase. * * $(INFORMIXDIR)/lib/cli/libifcli.a * $(INFORMIXDIR)/lib/cli/libifdmr.a * * These can be accessed by setting the library search path to * $INFORMIXDIR/lib/cli and specifying the 'ifcli' and 'ifdmr' libraries. * The 'infxcli.h' resource file can be found in $INFORMIXDIR/incl/cli. * * The following command will likely compile this source: * * cc -o load_wkb load_wkb.c -DNO_WIN32 \ * -I$INFORMIXDIR/incl/cli -L$INFORMIXDIR/lib/cli -lifcli -lifdmr * ***********************************************************************/ #include #include #include #include #ifdef WINNT #include #include #include #endif /*WINNT*/ #include /* ODBC typedefs and data structures */ #include "odbcutils.c" /* ODBC utility functions */ #include "commfuncs.h" #include "commfuncs.c" #include "wkbfuncs.c" /********************/ /* Local Prototypes */ /********************/ static void insert_wkb (SQLHDBC handle, SpatialColumn *spatial_column, int id, WkbType type, int data_len, char *binary); static void create_table (SQLHDBC hdbc, SpatialColumn *spatial_column); /************************************************************************ * * main -- Inserts of all wkb types from binary data into a test table. * * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: * Load a table with all types of geometry from wkb format. * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: * argc == (int) The parameter index. * argv == (char[] *) Pointer to an array of parameters. * *************************************************************************/ void main (int argc, char **argv) { SQLHDBC hdbc; SQLHENV henv; char *binary; int rc; SpatialColumn sc; Geometry geom = {0}; int offsets[10]; int suboffsets[10]; Point pt[30]; int data_len; int max_alloced = 0; /* Check for the correct number of arguments entered. */ if (argc < 2) { printf ("Usage: %s []\n", argv[0]); printf ("\n"); printf (" is name of ODBC DSN.\n"); printf (" is optional.\n"); printf ("\nThis program will create a table named 'wkb_test' and\n"); printf ("insert data using various ST_xxxFromWkb functions.\n"); exit (1); } /* Connect to the database. */ server_connect ((SQLCHAR*) argv[1], &henv, &hdbc); /* Load the spatial column structure. */ strcpy (sc.table, "wkb_test"); strcpy (sc.column, "geom"); sc.srid = (argc > 2) ? atoi(argv[2]) : 0; /* Create the test table */ create_table (hdbc, &sc); /* The remainder of the main function prepares the various WKB geometry structures with valid X,Y coordinate data and passes these structures to the insert_wkb function. insert_wkb inserts the geometry into the spatial column of the table, along with an integer id value. The data_len variable maintains the number of bytes written to the WKB geometry structure. insert_wkb passes this number to the ODBC SQLBindParameter function as an indicator of how many bytes to insert into the spatial column. It is the responsibility of the program querying the spatial column to examine the first byte, which indicates the byte-order. After comparing the geometry's byte order with that of the platform's, the program must determine if the bytes of the geometry must be swapped to agree with the platform's byte order. */ geom.offsets = offsets; geom.suboffsets = suboffsets; geom.pt = pt; /*********************************************************/ /* */ /* POINTS */ /* */ /* Points are written into the wkbPoint structure which */ /* includes the byte order (little endian or big */ /* endian), the data type, (in this case point), and */ /* The X,Y coordinate pair. */ /* */ /*********************************************************/ /*======================================================================*/ /* */ /* Insert a single point. */ /* */ /*======================================================================*/ /* Populate the point */ pt[0].x = 10; pt[0].y = -10; geom.type = geomPoint; geom.num_points = 1; geom.num_parts = 1; /* Convert the point to a Well Known Binary representation. */ geom_to_wkb (&geom, &max_alloced, &data_len, &binary); /* Store the point in the table. */ insert_wkb (hdbc, &sc, 1, wkbPoint, data_len, binary); /*********************************************************/ /* */ /* MULTIPOINTS */ /* */ /* Multipoints are collections of points and as such */ /* the wkbMultiPoint structure stores an array of */ /* WKBPoint structures. Therefore the thePoint WKBPoint */ /* variable is populated successively and each one */ /* is stored as an element of the wkbMultiPoint.point[] */ /* array. */ /* */ /*********************************************************/ /*======================================================================*/ /* */ /* Insert a multipoint containing 5 points. This will be a simple */ /* multipoint since none of the points share the same location. */ /* */ /*======================================================================*/ /* Populate the multipoint */ pt[0].x = 1; pt[0].y = 2; pt[1].x = 3; pt[1].y = 4; pt[2].x = 5; pt[2].y = 6; pt[3].x = 7; pt[3].y = 8; pt[4].x = 9; pt[4].y = 10; geom.type = geomMultiPoint; geom.num_points = 5; geom.num_parts = 5; /* Convert the points to a Well Known Binary representation of a */ /* multipoint. */ geom_to_wkb (&geom, &max_alloced, &data_len, &binary); /* Insert the record into the table */ insert_wkb (hdbc, &sc, 2, wkbMultiPoint, data_len, binary); /*======================================================================*/ /* */ /* Insert a multipoint containing a single point. */ /* */ /*======================================================================*/ /* Populate the multipoint. */ pt[0].x = 10.0; pt[0].y = 3.1415927; geom.type = geomMultiPoint; geom.num_points = 1; geom.num_parts = 1; /* Convert the points to a Well Known Binary representation of a */ /* multipoint. */ geom_to_wkb (&geom, &max_alloced, &data_len, &binary); /* Insert the record into the table */ insert_wkb (hdbc, &sc, 3, wkbMultiPoint, data_len, binary); /*======================================================================*/ /* */ /* Insert a multipoint containing three points at the same location. */ /* This is a non-simple multipoint since it contains points that */ /* share the same location. */ /* */ /*======================================================================*/ /* Populate the multipoint. */ pt[0].x = 1; pt[0].y = 1; pt[0].x = 1; pt[0].y = 1; pt[0].x = 1; pt[0].y = 1; geom.type = geomMultiPoint; geom.num_points = 3; geom.num_parts = 3; /* Convert the points to a Well Known Binary representation of a */ /* multipoint. */ geom_to_wkb (&geom, &max_alloced, &data_len, &binary); /* Insert the record into the table. */ insert_wkb (hdbc, &sc, 4, wkbMultiPoint, data_len, binary); /*********************************************************/ /* */ /* LINESTRINGS */ /* */ /* Linestrings are linear paths of X,Y coordinates */ /* assembled in the wkbLineString structure which */ /* includes the byte order, data type (LINESTRING), */ /* number of points in the linestring, and the array */ /* of X,Y coordinates that form the linestring. */ /* */ /*********************************************************/ /*======================================================================*/ /* */ /* Insert a two point linestring. This linestring is simple since does */ /* not intersect its interior. */ /* */ /*======================================================================*/ /* Populate the linestring. */ pt[0].x = -50.123; pt[0].y = -50.1234567; pt[1].x = 50; pt[1].y = 50; geom.type = geomLineString; geom.num_points = 2; geom.num_parts = 1; /* Convert the points to a Well Known Binary representation of a */ /* multipoint. */ geom_to_wkb (&geom, &max_alloced, &data_len, &binary); /* Insert the record into the table */ insert_wkb (hdbc, &sc, 5, wkbLineString, data_len, binary); /*======================================================================*/ /* */ /* Insert a six point linestring. The linestring is simple because it */ /* does not intersect its interior. */ /* */ /*======================================================================*/ /* Populate the linestring. */ pt[0].x = 0; pt[0].y = 0; pt[1].x = 1; pt[1].y = 1; pt[2].x = 2; pt[2].y = 2; pt[3].x = 3; pt[3].y = 3; pt[4].x = 4.5; pt[4].y = 5.4; pt[5].x = 7; pt[5].y = 7; geom.type = geomLineString; geom.num_points = 6; geom.num_parts = 1; /* Convert the points to a Well Known Binary representation of a */ /* multipoint. */ geom_to_wkb (&geom, &max_alloced, &data_len, &binary); /* Insert the record into the table. */ insert_wkb (hdbc, &sc, 6, wkbLineString, data_len, binary); /*======================================================================*/ /* */ /* Insert a closed linestring (ring). This linestring is simple because */ /* the interior is not intersected. */ /* */ /*======================================================================*/ /* Populate the linestring (ring). */ pt[0].x = 10; pt[0].y = 10; pt[1].x = 10; pt[1].y = 20; pt[2].x = 20; pt[2].y = 10; pt[3].x = 10; pt[3].y = 10; geom.type = geomLineString; geom.num_points = 4; geom.num_parts = 1; /* Convert the points to a Well Known Binary representation of a */ /* multipoint. */ geom_to_wkb (&geom, &max_alloced, &data_len, &binary); /* Insert the record into the table. */ insert_wkb (hdbc, &sc, 7, wkbLineString, data_len, binary); /*======================================================================*/ /* */ /* Insert a four point self intersecting linestring. This linestring */ /* is considered non-simple because it intersects its interior. */ /* */ /*======================================================================*/ /* Populate the linestring. */ pt[0].x = 10; pt[0].y = 10; pt[1].x = 20; pt[1].y = 20; pt[2].x = 25; pt[2].y = 15; pt[3].x = 0; pt[3].y = 15; geom.type = geomLineString; geom.num_points = 4; geom.num_parts = 1; /* Convert the points to a Well Known Binary representation of a */ /* multipoint. */ geom_to_wkb (&geom, &max_alloced, &data_len, &binary); /* Insert the record into the table. */ insert_wkb (hdbc, &sc, 8, wkbLineString, data_len, binary); /***********************************************************/ /* */ /* MULTILINESTRINGS */ /* */ /* Multilinestrings are collections of linestrings. The */ /* wkbMultiLineString structure stores an array of */ /* wkbLineString structures. Therefore the theLinestring */ /* variable is populated successively and each one is */ /* stored as an element of the */ /* wkbMultiLineString.linestrings[] array. */ /* */ /***********************************************************/ /*======================================================================*/ /* */ /* Insert a multilinestring containing two intersecting linestrings. */ /* Since the linestrings intersect at their interiors they are */ /* considered non-simple. */ /* */ /*======================================================================*/ /* Populate the first linestring. */ pt[0].x = 10; pt[0].y = 10; offsets[0] = 0; pt[1].x = 10; pt[1].y = 20; /* Populate the second linestring. */ pt[2].x = 5; pt[2].y = 15; offsets[1] = 2; pt[3].x = 15; pt[3].y = 15; geom.type = geomMultiLineString; geom.num_points = 4; geom.num_parts = 2; /* Convert the points to a Well Known Binary representation of a */ /* multilinestring. */ geom_to_wkb (&geom, &max_alloced, &data_len, &binary); /* Insert the record into the table. */ insert_wkb (hdbc, &sc, 9, wkbMultiLineString, data_len, binary); /*======================================================================*/ /* */ /* Insert a multilinestring containing 4 non-intersecting linestrings. */ /* The multilinesting is simple because the linestrings do not */ /* intersect. */ /* */ /*======================================================================*/ /* Populate the first linestring. */ pt[0].x = 1; pt[0].y = 1; offsets[0] = 0; pt[1].x = 11; pt[1].y = 1; pt[2].x = 11; pt[2].y = -9; /* Populate the second linesting. */ pt[3].x = 4; pt[3].y = 10; offsets[1] = 3; pt[4].x = 4; pt[4].y = 20; /* Populate the third linestring. */ pt[5].x = 10; pt[5].y = 10; offsets[2] = 5; pt[6].x = 20; pt[6].y = 10; /* Populate the fourth linestring. */ pt[7].x = -10; pt[7].y = -10; offsets[3] = 7; pt[8].x = -20; pt[8].y = -10; pt[9].x = -30; pt[9].y = -10; pt[10].x = -30; pt[10].y = 0; geom.type = geomMultiLineString; geom.num_points = 11; geom.num_parts = 4; /* Convert the points to a Well Known Binary representation of a */ /* multilinestring. */ geom_to_wkb (&geom, &max_alloced, &data_len, &binary); /* Insert the record into the table. */ insert_wkb (hdbc, &sc, 10, wkbMultiLineString, data_len, binary); /*********************************************************/ /* */ /* POLYGONS */ /* */ /* Polygons are areas formed by the enclosure of an */ /* exterior ring and the exclusion of the area within */ /* any number of non-overlapping interior rings. */ /* The WKBPolygon structure includes the byte-order, */ /* data-type (POLYGON), number of rings, and an array */ /* of ring structures. The ring structures include the */ /* number of points in the ring and the array of X,Y */ /* coordinate points. */ /* */ /*********************************************************/ /*======================================================================*/ /* */ /* Insert a polygon with no interior rings. Notice that to be a polygon */ /* the first and last coordinate must be the same. */ /* */ /*======================================================================*/ /* The exterior ring. */ pt[0].x = 10; pt[0].y = 10; pt[1].x = 10; pt[1].y = 20; pt[2].x = 20; pt[2].y = 20; pt[3].x = 20; pt[3].y = 10; pt[4].x = 10; pt[4].y = 10; suboffsets[0]=0; geom.type = geomPolygon; geom.num_points = 5; geom.num_parts = 1; geom.num_subparts = 1; /* Convert the points to a Well Known Binary representation of a */ /* multipoint. */ geom_to_wkb (&geom, &max_alloced, &data_len, &binary); /* Insert the record into the table. */ insert_wkb (hdbc, &sc, 11, wkbPolygon, data_len, binary); /*======================================================================*/ /* */ /* Insert a polygon containing a single interior ring. */ /* */ /*======================================================================*/ /* The exterior ring. */ pt[0].x = 10; pt[0].y = 10; suboffsets[0] = 0; offsets[0] = 0; pt[1].x = 10; pt[1].y = 20; pt[2].x = 20; pt[2].y = 20; pt[3].x = 20; pt[3].y = 10; pt[4].x = 10; pt[4].y = 10; /* The interior ring */ pt[5].x = 12; pt[5].y = 12; suboffsets[1] = 5; pt[6].x = 12; pt[6].y = 13; pt[7].x = 13; pt[7].y = 13; pt[8].x = 13; pt[8].y = 12; pt[9].x = 12; pt[9].y = 12; geom.type = geomPolygon; geom.num_points = 10; geom.num_parts = 1; geom.num_subparts = 2; /* Convert the points to a Well Known Binary representation of a */ /* multipoint. */ geom_to_wkb (&geom, &max_alloced, &data_len, &binary); /* Insert the record into the table. */ insert_wkb (hdbc, &sc, 12, wkbPolygon, data_len, binary); /*======================================================================*/ /* */ /* Insert a Polygon containing two interior rings. */ /* */ /*======================================================================*/ /* The exterior ring. */ pt[0].x = 10; pt[0].y = 10; suboffsets[0] = 0; offsets[0] = 0; pt[1].x = 10; pt[1].y = 20; pt[2].x = 20; pt[2].y = 20; pt[3].x = 20; pt[3].y = 10; pt[4].x = 10; pt[4].y = 10; /* The first interior ring. */ pt[5].x = 12; pt[5].y = 12; suboffsets[1] = 5; pt[6].x = 12; pt[6].y = 13; pt[7].x = 13; pt[7].y = 13; pt[8].x = 13; pt[8].y = 12; pt[9].x = 12; pt[9].y = 12; /* The second interior ring. */ pt[10].x = 16; pt[10].y = 16; suboffsets[2] = 10; pt[11].x = 16; pt[11].y = 18; pt[12].x = 18; pt[12].y = 18; pt[13].x = 18; pt[13].y = 16; pt[14].x = 16; pt[14].y = 16; geom.type = geomPolygon; geom.num_points = 15; geom.num_parts = 1; geom.num_subparts = 3; /* Convert the points to a Well Known Binary representation of a */ /* polygon. */ geom_to_wkb (&geom, &max_alloced, &data_len, &binary); /* Insert the record into the table. */ insert_wkb (hdbc, &sc, 13, wkbPolygon, data_len, binary); /*********************************************************/ /* */ /* MULTIPOLYGONS */ /* */ /* MultiPolygons are collections of polygons. The */ /* WKBMultipoly structure stores an array of WKBPolygon */ /* structures. The WKBPolygon structure is populated */ /* successively and each one is stored as an element of */ /* the WKBMultiPolygon.polygons[] array. */ /* */ /*********************************************************/ /*======================================================================*/ /* */ /* Insert a multipolygon containing three polygons. The first polygon */ /* contains a single interior ring, the second polygon contains no */ /* interior rings and the third polygon contains 2 interior rings. */ /* */ /*======================================================================*/ /* The first polygon's exterior ring. */ pt[0].x = 10; pt[0].y = 10; suboffsets[0] = 0; offsets[0] = 0; pt[1].x = 10; pt[1].y = 20; pt[2].x = 20; pt[2].y = 20; pt[3].x = 20; pt[3].y = 10; pt[4].x = 10; pt[4].y = 10; /* The first polygon's interior ring. */ pt[5].x = 14; pt[5].y = 14; suboffsets[1] = 5; pt[6].x = 14; pt[6].y = 16; pt[7].x = 16; pt[7].y = 16; pt[8].x = 16; pt[8].y = 14; pt[9].x = 14; pt[9].y = 14; /* The second polygon's exterior ring. */ pt[10].x = 70; pt[10].y = 70; suboffsets[2] = 10; offsets[1] = 2; pt[11].x = 70; pt[11].y = 80; pt[12].x = 80; pt[12].y = 80; pt[13].x = 80; pt[13].y = 70; pt[14].x = 70; pt[14].y = 70; /* The third polygons exterior ring. */ pt[15].x = 50; pt[15].y = 50; suboffsets[3] = 15; offsets[2] = 3; pt[16].x = 50; pt[16].y = 60; pt[17].x = 60; pt[17].y = 60; pt[18].x = 60; pt[18].y = 50; pt[19].x = 50; pt[19].y = 50; /* The third polygon's interior ring. */ pt[20].x = 52; pt[20].y = 52; suboffsets[4] = 20; pt[21].x = 52; pt[21].y = 54; pt[22].x = 54; pt[22].y = 54; pt[23].x = 54; pt[23].y = 52; pt[24].x = 52; pt[24].y = 52; /* The third polygon's interior ring. */ pt[25].x = 56; pt[25].y = 56; suboffsets[5] = 25; pt[26].x = 56; pt[26].y = 58; pt[27].x = 58; pt[27].y = 58; pt[28].x = 58; pt[28].y = 56; pt[29].x = 56; pt[29].y = 56; geom.type = geomMultiPolygon; geom.num_points = 30; geom.num_parts = 3; geom.num_subparts = 6; /* Convert the points to a Well Known Binary representation of a */ /* multipolygon. */ geom_to_wkb (&geom, &max_alloced, &data_len, &binary); /* Insert the multipolygon into the table. */ insert_wkb (hdbc, &sc, 14, wkbMultiPolygon, data_len, binary); /*======================================================================*/ /* */ /* Insert a multipolygon containing two polygons that do not have */ /* interior rings. */ /* */ /*======================================================================*/ /* The first polygon's exterior ring. */ pt[0].x = 10; pt[0].y = 10; suboffsets[0] = 0; offsets[0] = 0; pt[1].x = 10; pt[1].y = 20; pt[2].x = 20; pt[2].y = 20; pt[3].x = 20; pt[3].y = 10; pt[4].x = 10; pt[4].y = 10; /* The second polygon's exterior ring. */ pt[5].x = 1; pt[5].y = 1; suboffsets[1] = 5; offsets[1] = 1; pt[6].x = 1; pt[6].y = 5; pt[7].x = 5; pt[7].y = 5; pt[8].x = 5; pt[8].y = 1; pt[9].x = 1; pt[9].y = 1; geom.type = geomMultiPolygon; geom.num_points = 10; geom.num_parts = 2; geom.num_subparts = 2; /* Convert the points to a Well Known Binary representation of a */ /* multipolygon. */ geom_to_wkb (&geom, &max_alloced, &data_len, &binary); /* Insert the multipolygon into the table. */ insert_wkb (hdbc, &sc, 15, wkbMultiPolygon, data_len, binary); /*======================================================================*/ /* */ /* Insert a multipolygon containing two polygons. The first polygon */ /* contains an interior ring and the second polygon does not. */ /* */ /*======================================================================*/ /* Populate the first polygons exterior ring. */ pt[0].x = 10; pt[0].y = 10; suboffsets[0] = 0; offsets[0] = 0; pt[1].x = 10; pt[1].y = 20; pt[2].x = 20; pt[2].y = 20; pt[3].x = 20; pt[3].y = 10; pt[4].x = 10; pt[4].y = 10; /* Populate the first polygon's interior ring. */ pt[5].x = 14; pt[5].y = 14; suboffsets[1] = 5; pt[6].x = 14; pt[6].y = 16; pt[7].x = 16; pt[7].y = 16; pt[8].x = 16; pt[8].y = 14; pt[9].x = 14; pt[9].y = 14; /* Populate the exterior ring of the second polygon. */ pt[10].x = 1; pt[10].y = 1; suboffsets[2] = 10; offsets[1] = 2; pt[11].x = 1; pt[11].y = 5; pt[12].x = 5; pt[12].y = 5; pt[13].x = 5; pt[13].y = 1; pt[14].x = 1; pt[14].y = 1; geom.type = geomMultiPolygon; geom.num_points = 15; geom.num_parts = 2; geom.num_subparts = 3; /* Convert the points to a Well Known Binary representation of a */ /* multipolygon. */ geom_to_wkb (&geom, &max_alloced, &data_len, &binary); /* Insert the multipolygon into the table. */ insert_wkb (hdbc, &sc, 16, wkbMultiPolygon, data_len, binary); /*===============================*/ /* */ /* Disconnect from the database. */ /* */ /*===============================*/ SQLDisconnect (hdbc); /* Close the connection */ SQLFreeHandle (SQL_HANDLE_DBC, hdbc); /* Free the database handle */ SQLFreeHandle (SQL_HANDLE_ENV, henv); /* Free the ODBC environment */ } /*********************************************************************** * * create_table - Creates a table for inserting spatial data * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: * hdbc == (SQLHDBC) ODBC connection handle. * sc == (SpatialColumn *) Spatial column. * * RETURN == (void) * ***********************************************************************/ static void create_table ( SQLHDBC hdbc, SpatialColumn *sc ) { SQLHSTMT hstmt; char sql_stmt[256]; int rc; /* Allocate memory for the SQL statement handle and * associate the statement handle with the connection handle. */ rc = SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &hstmt); returncode_check(NULL, hstmt, rc, "SQLAllocHandle"); sprintf (sql_stmt, "DROP TABLE %s", sc->table); rc = SQLExecDirect (hstmt, (UCHAR *) sql_stmt, SQL_NTS); sprintf (sql_stmt, "CREATE TABLE %s (id integer, %s ST_Geometry)", sc->table, sc->column); rc = SQLExecDirect (hstmt, (UCHAR *) sql_stmt, SQL_NTS); returncode_check(NULL, hstmt, rc, "SQLExecDirect"); SQLFreeStmt (hstmt, SQL_CLOSE); /* Close the statement handle */ SQLFreeHandle (SQL_HANDLE_STMT, hstmt); /* Free the statement handle */ } /*********************************************************************** * * insert_wkb - Inserts the geometry and integer id values into * the spatial and id columns of the table * specified as arguments to the main program. * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: * The function inserts the geometry WKB binary structure into the * spatial column and an integer into the id column. * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: * hdbc == (SQLHDBC) ODBC connection handle. * sc == (SpatialColumn *) Spatial column. * id == (int) The integer id value. * type == (WkbType) The data type of the geometry. * data_len == (int) The number of bytes in wkb_buffer. * wkb_buffer == (char *) The WKB geometry structure. * * RETURN == (void) * ***********************************************************************/ static void insert_wkb ( SQLHDBC hdbc, SpatialColumn *sc, int id, WkbType type, int data_len, char *wkb_buffer ) { int rc; char wkb_sql[256]; char wkbfunction[19]; SQLHSTMT hstmt; SDWORD pcbvalue1; SDWORD pcbvalue2; /* Set the wkbfunction to the "FromWkb" function that corresponds */ /* to the data type of the WKB geometry representation. */ switch (type) { case wkbPoint: strcpy (wkbfunction,"ST_PointFromWkb"); break; case wkbLineString: strcpy (wkbfunction,"ST_LineFromWkb"); break; case wkbPolygon: strcpy (wkbfunction,"ST_PolyFromWkb"); break; case wkbMultiPoint: strcpy (wkbfunction,"ST_MPointFromWkb"); break; case wkbMultiLineString: strcpy (wkbfunction,"ST_MLineFromWkb"); break; case wkbMultiPolygon: strcpy (wkbfunction,"ST_MPolyFromWkb"); break; } /* Generate the SQL insert expression. The integer value and the */ /* name of the spatial column are entered as bind parameters. */ sprintf (wkb_sql, "insert into %s (id, %s) values (?, %s (?, %d))", sc->table, sc->column, wkbfunction, sc->srid); /* Allocate memory for the SQL statement handle and associate the */ /* statement handle with the connection handle. */ rc = SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &hstmt); returncode_check (hdbc, NULL, rc, "SQLAllocHandle"); /* Prepare the SQL statement for execution. */ fprintf (stdout, "SQL is %s \n", wkb_sql); rc = SQLPrepare (hstmt, (unsigned char *)wkb_sql, SQL_NTS); returncode_check (NULL, hstmt, rc, "SQLPrepare"); /* Bind the integer id value to the first parameter. */ pcbvalue1 = 0; rc = SQLBindParameter (hstmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &id, 0, &pcbvalue1); returncode_check (NULL, hstmt, rc, "SQLBindParameter 1"); /* Bind the wkb geometry representation to the second parameter. */ pcbvalue2 = data_len; rc = SQLBindParameter (hstmt, 2, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_INFX_UDT_LVARCHAR, data_len, 0, wkb_buffer, data_len, &pcbvalue2); returncode_check (NULL, hstmt, rc, "SQLBindParameter 2"); /* Execute the insert statement. */ rc = SQLExecute (hstmt); returncode_check (NULL, hstmt, rc, "SQLExecute"); /* Release the SQL statement handle and free all resources */ /* associated with it. */ rc = SQLFreeHandle (SQL_HANDLE_STMT, hstmt); returncode_check (NULL, hstmt, rc, "SQLFreeHandle"); }