/*********************************************************************** * * load_shapes.c -- Inserts of all shape types from binary. * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: * Tests inserts of all shape types from binary. * ***********************************************************************/ /********************************************************************** * 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_shapes load_shapes.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 "shapefuncs.c" /********************/ /* Local Prototypes */ /********************/ static void insert_shape (SQLHDBC hdbc, SpatialColumn *sc, int id, GeomType geom_type, int data_len, char *binary); static void create_table (SQLHDBC hdbc, SpatialColumn *spatial_column); /*********************************************************************** * * main -- Inserts of all shape types from binary shape format into a * test table. * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: * Load a table with all types of geometry from shapes. * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * 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; SpatialColumn sc; Geometry geom = {0}; int offsets[6]; Point pt[30]; double z[30]; double m[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 'shape_test' and\n"); printf ("insert data using various SE_xxxFromShape functions.\n"); exit (1); } /* Connect to database */ server_connect ((SQLCHAR*) argv[1], &henv, &hdbc); strcpy (sc.table, "shape_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 geometry data types with valid X, Y coordinates, Z ordinates and measures. It passes these geometries to make_shape function which converts them into shapes. The shapes are then passed to the insert_shape function which inserts the shapes into the spatial column of the table. Insert_shape also inserts an integer key into the table. The make_shape function also returns data_len, the number of bytes in the shape. The insert_shape function passes this number to the ODBC SQLBindParameter function. */ geom.offsets = offsets; geom.pt = pt; geom.z = z; geom.m = m; /**********/ /* */ /* POINTS */ /* */ /**********/ /*======================================================================*/ /* */ /* 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 an ESRI shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into the table */ insert_shape (hdbc, &sc, 1, geomPoint, data_len, binary); /*======================================================================*/ /* */ /* Insert a point with a Z coordinate. */ /* */ /*======================================================================*/ /* Populate the point. */ pt[0].x = -50.123; pt[0].y = -50.1234567; z[0] = 50; geom.type = geomPointZ; geom.num_points = 1; geom.num_parts = 1; /* Convert the point to an ESRI shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into the table. */ insert_shape (hdbc, &sc, 2, geomPoint, data_len, binary); /*======================================================================*/ /* */ /* Insert a point with a measure. */ /* */ /*======================================================================*/ /* Populate the point. */ pt[0].x = -.123; pt[0].y = -.1234567; m[0] = 10; geom.type = geomPointM; geom.num_points = 1; geom.num_parts = 1; /* Convert the point to an ESRI shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into the table. */ insert_shape (hdbc, &sc, 3, geomPoint, data_len, binary); /*======================================================================*/ /* */ /* Insert a point with a Z coordinate and a measure. */ /* */ /*======================================================================*/ /* Populate the point. */ pt[0].x = 1; pt[0].y = 2; z[0] = 3; m[0] = 4; geom.type = geomPointZM; geom.num_points = 1; geom.num_parts = 1; /* Convert the point to an ESRI shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into the table. */ insert_shape (hdbc, &sc, 4, geomPoint, data_len, binary); /***************/ /* */ /* MULTIPOINTS */ /* */ /***************/ /*======================================================================*/ /* */ /* Insert a multipoint containing 5 points. */ /* */ /*======================================================================*/ /* 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 multipoint into an ESRI shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into a table. */ insert_shape (hdbc, &sc, 5, geomMultiPoint, 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 multipoint into an ESRI shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into a table. */ insert_shape (hdbc, &sc, 6, geomMultiPoint, data_len, binary); /*======================================================================*/ /* */ /* Insert a multipoint containing a three points sharing the same */ /* location. This multipoint is non-simple since some of its points */ /* share the same location. */ /* */ /*======================================================================*/ /* Populate the multipoint. */ pt[0].x = 1; pt[0].y = 1; pt[1].x = 1; pt[1].y = 1; pt[2].x = 1; pt[2].y = 1; geom.type = geomMultiPoint; geom.num_points = 3; geom.num_parts = 3; /* Convert the multipoint into an ESRI shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into a table. */ insert_shape (hdbc, &sc, 7, geomMultiPoint, data_len, binary); /*======================================================================*/ /* */ /* Insert a multipoint containing a single point with a measure. */ /* */ /*======================================================================*/ /* Populate the multipoint. */ pt[0].x = -0.123; pt[0].y = -0.1234567; m[0] = 10; geom.type = geomMultiPointM; geom.num_points = 1; geom.num_parts = 1; /* Convert the multipoint into an ESRI shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into a multipoint. */ insert_shape (hdbc, &sc, 8, geomMultiPoint, data_len, binary); /*======================================================================*/ /* */ /* Insert a multipoint containing three points with z coordinates and */ /* measures. */ /* */ /*======================================================================*/ /* Populate the multipoint. */ pt[0].x = 1; pt[0].y = 2; z[0] = 3; m[0] = 4; pt[1].x = 5; pt[1].y = 6; z[1] = 7; m[1] = 8; pt[2].x = 9; pt[2].y = 10; z[2] = 11; m[2] = 12; geom.type = geomMultiPointZM; geom.num_points = 3; geom.num_parts = 3; /* Convert the multipoint into an ESRI shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into a multipoint. */ insert_shape (hdbc, &sc, 9, geomMultiPoint, data_len, binary); /***************/ /* */ /* LINESTRINGS */ /* */ /***************/ /*======================================================================*/ /* */ /* Insert a linestring containing two vertices. */ /* */ /*======================================================================*/ /* 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 linestring into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into a table. */ insert_shape (hdbc, &sc, 10, geomLineString, data_len, binary); /*======================================================================*/ /* */ /* Insert a linestring contain 6 vertices. */ /* */ /*======================================================================*/ /* 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 linestring into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into the table. */ insert_shape (hdbc, &sc, 11, geomLineString, data_len, binary); /*======================================================================*/ /* */ /* Insert a linestring that is a ring containing 4 vertices. */ /* */ /*======================================================================*/ /* Populate the linestring. */ 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 linestring into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into the table. */ insert_shape (hdbc, &sc, 12, geomLineString, data_len, binary); /*======================================================================*/ /* */ /* Insert a linestring that intersects its interior and therefore is */ /* non-simple. */ /* */ /*======================================================================*/ /* 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 linestring into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into the table. */ insert_shape (hdbc, &sc, 13, geomLineString, data_len, binary); /*======================================================================*/ /* */ /* Insert a linestring containing two vertices with Z coordinates. */ /* */ /*======================================================================*/ /* Populate the linestring. */ pt[0].x = -50.123; pt[0].y = -50.1234567; z[0] = 50; pt[1].x = 1; pt[1].y = 2; z[1] = 60; geom.type = geomLineStringZ; geom.num_points = 2; geom.num_parts = 1; /* Convert the linestring into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into the table. */ insert_shape (hdbc, &sc, 14, geomLineString, data_len, binary); /*======================================================================*/ /* */ /* Insert a linestring containing two vertices with measures. */ /* */ /*======================================================================*/ /* Populate the linestring. */ pt[0].x = 1; pt[0].y = 2; m[0] = 3; pt[1].x = 4; pt[1].y = 5; m[1] = 6; geom.type = geomLineStringM; geom.num_points = 2; geom.num_parts = 1; /* Convert the linestring into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into the table. */ insert_shape (hdbc, &sc, 15, geomLineString, data_len, binary); /*======================================================================*/ /* */ /* Insert a linestring containing two vertices with Z ordinate and */ /* measures. */ /* */ /*======================================================================*/ /* Populate the linestring. */ pt[0].x = 7; pt[0].y = 8; z[0] = 9; m[0] = 10; pt[1].x = 11; pt[1].y = 12; z[1] = 13; m[1] = 14; geom.type = geomLineStringZM; geom.num_points = 2; geom.num_parts = 1; /* Convert the linestring into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into the table. */ insert_shape (hdbc, &sc, 16, geomLineString, data_len, binary); /********************/ /* */ /* MULTILINESTRINGS */ /* */ /********************/ /*======================================================================*/ /* */ /* Insert a multilinestring containing two linestrings that intersect */ /* each others interiors. Since the elements of the multilinestring */ /* intersect at their interior it is not simple. */ /* */ /*======================================================================*/ /* The first linestring. */ pt[0].x = 10; pt[0].y = 10; offsets[0] = 0; pt[1].x = 10; pt[1].y = 20; /* The second linestring. */ pt[2].x = 5; pt[2].y = 15; offsets[1] = 2; pt[3].x = 15; pt[3].y = 15; geom.type = geomLineString; geom.num_points = 4; geom.num_parts = 2; /* Convert the multilinestring into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into the table. */ insert_shape (hdbc, &sc, 17, geomMultiLineString, data_len, binary); /*======================================================================*/ /* */ /* Insert a multilinestring containing four linestrings that do not */ /* intersect. The multilinestring is simple since its interior is not */ /* intersected. */ /* */ /*======================================================================*/ /* 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; /* The second linestring. */ pt[3].x = 4; pt[3].y = 10; offsets[1] = 3; pt[4].x = 4; pt[4].y = 20; /* The third linestring. */ pt[5].x = 10; pt[5].y = 10; offsets[2] = 5; pt[6].x = 20; pt[6].y = 10; /* 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 = geomLineString; geom.num_points = 11; geom.num_parts = 4; /* Convert the multilinestring into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into the table. */ insert_shape (hdbc, &sc, 18, geomMultiLineString, data_len, binary); /*======================================================================*/ /* */ /* Insert a multilinestring containing 3 linestrings with Z ordinates. */ /* */ /*======================================================================*/ /* The first linestring. */ pt[0].x = 1; pt[0].y = 1; z[0] = 10; offsets[0] = 0; pt[1].x = 11; pt[1].y = 1; z[1] = 20; pt[2].x = 11; pt[2].y = 11; z[2] = 30; /* The second linestring. */ pt[3].x = 4; pt[3].y = 10; z[3] = -1; offsets[1] = 3; pt[4].x = 4; pt[4].y = 20; z[4] = 2; /* The third linestring. */ pt[5].x = 10; pt[5].y = 10; z[5] = 10; pt[6].x = 20; pt[6].y = 10; z[6] = 20; offsets[2] = 5; geom.type = geomLineStringZ; geom.num_points = 7; geom.num_parts = 3; /* Convert the multilinestring into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into the table. */ insert_shape (hdbc, &sc, 19, geomMultiLineString, data_len, binary); /*======================================================================*/ /* */ /* Insert a multilinestring containing 2 linestrings with measures. */ /* */ /*======================================================================*/ /* The first linestring. */ pt[0].x = 1; pt[0].y = 1; m[0] = 10; offsets[0] = 0; pt[1].x = 1; pt[1].y = 10; m[1] = 20; /* The second linestring. */ pt[2].x = 11; pt[2].y = 11; m[2] = 30; offsets[1] = 2; pt[3].x = 21; pt[3].y = 10; m[3] = -1; geom.type = geomLineStringM; geom.num_points = 4; geom.num_parts = 2; /* Convert the multilinestring into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into the table. */ insert_shape (hdbc, &sc, 20, geomMultiLineString, data_len, binary); /*======================================================================*/ /* */ /* Insert a multilinestring comtaining two linestrings with Z ordinates */ /* and measures. */ /* */ /*======================================================================*/ /* The first linestring. */ pt[0].x = 1; pt[0].y = 1; z[0] = 10; m[0] = 10; offsets[0] = 0; pt[1].x = 11; pt[1].y = 1; z[1] = 15; m[1] = 20; pt[2].x = 11; pt[2].y = 11; z[2] = 25; m[2] = 30; /* The second linestring. */ pt[3].x = 4; pt[3].y = 10; z[3] = 35; m[3] = 40; offsets[1] = 3; pt[4].x = 4; pt[4].y = 20; z[4] = 45; m[4] = 50; geom.type = geomLineStringZM; geom.num_points = 5; geom.num_parts = 2; /* Convert the multilinestring into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into the table. */ insert_shape (hdbc, &sc, 21, geomMultiLineString, data_len, binary); /************/ /* */ /* POLYGONS */ /* */ /************/ /*======================================================================*/ /* */ /* Insert a polygon with no interior rings. */ /* */ /*======================================================================*/ /* 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; geom.type = geomPolygon; geom.num_points = 5; geom.num_parts = 1; /* Convert the polygon into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into a table. */ insert_shape (hdbc, &sc, 22, geomPolygon, data_len, binary); /*======================================================================*/ /* */ /* Insert a polygon with one interior ring. */ /* */ /*======================================================================*/ /* The exterior ring. */ pt[0].x = 10; pt[0].y = 10; 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; offsets[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 = 2; /* Convert the polygon into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into the table. */ insert_shape (hdbc, &sc, 23, geomPolygon, data_len, binary); /*======================================================================*/ /* */ /* Insert a polygon with 2 interior rings and Z ordinates. */ /* */ /*======================================================================*/ /* The exterior ring. */ pt[0].x = 10; pt[0].y = 10; z[0] = 1; offsets[0] = 0; pt[1].x = 10; pt[1].y = 20; z[1] = 2; pt[2].x = 20; pt[2].y = 20; z[2] = 3; pt[3].x = 20; pt[3].y = 10; z[3] = 4; pt[4].x = 10; pt[4].y = 10; z[4] = 1; /* The first interior ring. */ pt[5].x = 12; pt[5].y = 12; z[5] = 6; offsets[1] = 5; pt[6].x = 12; pt[6].y = 13; z[6] = 7; pt[7].x = 13; pt[7].y = 13; z[7] = 8; pt[8].x = 13; pt[8].y = 12; z[8] = 9; pt[9].x = 12; pt[9].y = 12; z[9] = 6; /* The second interior ring. */ pt[10].x = 16; pt[10].y = 16; z[10] = 11; offsets[2] = 10; pt[11].x = 16; pt[11].y = 18; z[11] = 12; pt[12].x = 18; pt[12].y = 18; z[12] = 13; pt[13].x = 18; pt[13].y = 16; z[13] = 14; pt[14].x = 16; pt[14].y = 16; z[14] = 11; geom.type = geomPolygonZ; geom.num_points = 15; geom.num_parts = 3; /* Convert the polygon into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into a table. */ insert_shape (hdbc, &sc, 24, geomPolygon, data_len, binary); /*======================================================================*/ /* */ /* Insert a polygon containing no interior rings with measures. */ /* */ /*======================================================================*/ /* The exterior ring. */ pt[0].x = 10; pt[0].y = 10; m[0] = 100; pt[1].x = 10; pt[1].y = 20; m[1] = -1; pt[2].x = 20; pt[2].y = 20; m[2] = 300; pt[3].x = 20; pt[3].y = 10; m[3] = -2; pt[4].x = 10; pt[4].y = 10; m[4] = 400; geom.type = geomPolygonM; geom.num_points = 5; geom.num_parts = 1; /* Convert the polygon into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into a table. */ insert_shape (hdbc, &sc, 25, geomPolygon, data_len, binary); /*======================================================================*/ /* */ /* Insert a polygon with Z ordinates measures but no interior rings. */ /* */ /*======================================================================*/ /* The exterior ring. */ pt[0].x = 20; pt[0].y = 20; z[0] = 100; m[0] = -1; pt[1].x = 20; pt[1].y = 30; z[1] = -1; m[1] = -2; pt[2].x = 30; pt[2].y = 30; z[2] = 300; m[2] = -3; pt[3].x = 30; pt[3].y = 20; z[3] = -2; m[3] = -5; pt[4].x = 20; pt[4].y = 20; z[4] = 100; m[4] = -1; geom.type = geomPolygonZM; geom.num_points = 5; geom.num_parts = 1; /* Convert the polygon into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into a table. */ insert_shape (hdbc, &sc, 26, geomPolygon, data_len, binary); /******************/ /* */ /* MULTIPOLYGONS */ /* */ /******************/ /*======================================================================*/ /* */ /* Insert a multipolygon. The first polygon contains one interior ring, */ /* the second polygon contains no interior rings, and the third polygon */ /* contains two interior rings. */ /* */ /*======================================================================*/ /* The first polygon's exterior ring. */ pt[0].x = 10; pt[0].y = 10; 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; offsets[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 = 10; pt[10].y = 10; offsets[2] = 10; pt[11].x = 10; pt[11].y = 20; pt[12].x = 20; pt[12].y = 20; pt[13].x = 20; pt[13].y = 10; pt[14].x = 10; pt[14].y = 10; /* The third polygon's exterior ring. */ pt[15].x = 50; pt[15].y = 50; offsets[3] = 15; 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; offsets[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 second polygon's interior ring. */ pt[25].x = 56; pt[25].y = 56; offsets[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 = 6; /* Convert the multipolygon into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into the table. */ insert_shape (hdbc, &sc, 27, geomMultiPolygon, data_len, binary); /*======================================================================*/ /* */ /* Insert a multipolygon containing two polygons with Z ordinates */ /* and no interior rings. */ /* */ /*======================================================================*/ /* The first polygon's exterior ring. */ pt[0].x = 10; pt[0].y = 10; z[0] = 1; offsets[0] = 0; pt[1].x = 10; pt[1].y = 20; z[1] = 2; pt[2].x = 20; pt[2].y = 20; z[2] = 3; pt[3].x = 20; pt[3].y = 10; z[3] = 4; pt[4].x = 10; pt[4].y = 10; z[4] = 1; /* The second polygon's exterior ring. */ pt[5].x = 1; pt[5].y = 1; z[5] = 1; offsets[1] = 5; pt[6].x = 1; pt[6].y = 5; z[6] = 2; pt[7].x = 5; pt[7].y = 5; z[7] = 3; pt[8].x = 5; pt[8].y = 1; z[8] = 4; pt[9].x = 1; pt[9].y = 1; z[9] = 1; geom.type = geomMultiPolygonZ; geom.num_points = 10; geom.num_parts = 2; /* Convert the multipolygon into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into a table. */ insert_shape (hdbc, &sc, 28, geomMultiPolygon, data_len, binary); /*======================================================================*/ /* */ /* Insert a multipolygon containing two polygons with measures and no */ /* interior rings. */ /* */ /*======================================================================*/ /* The first polygon's exterior ring. */ pt[0].x = 10; pt[0].y = 10; m[0] = 1; offsets[0] = 0; pt[1].x = 10; pt[1].y = 20; m[1] = 2; pt[2].x = 20; pt[2].y = 20; m[2] = 3; pt[3].x = 20; pt[3].y = 10; m[3] = 4; pt[4].x = 10; pt[4].y = 10; m[4] = 1; /* The second polygon's exterior ring. */ pt[5].x = 1; pt[5].y = 1; m[5] = 5; offsets[1] = 5; pt[6].x = 1; pt[6].y = 5; m[6] = 6; pt[7].x = 5; pt[7].y = 5; m[7] = 7; pt[8].x = 5; pt[8].y = 1; m[8] = 8; pt[9].x = 1; pt[9].y = 1; m[9] = 9; geom.type = geomMultiPolygonM; geom.num_points = 10; geom.num_parts = 2; /* Convert the multipolygon into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into the table. */ insert_shape (hdbc, &sc, 29, geomMultiPolygon, data_len, binary); /*======================================================================*/ /* */ /* Insert a multipolygon containing a two polygons with Z ordinates and */ /* measures. The first polygon contains an interior ring, but the */ /* second one does not. */ /* */ /*======================================================================*/ /* The first polygon's exterior ring. */ pt[0].x = 10; pt[0].y = 10; z[0] = 1; m[0] = 6; offsets[0] = 0; pt[1].x = 10; pt[1].y = 20; z[1] = 2; m[1] = 7; pt[2].x = 20; pt[2].y = 20; z[2] = 3; m[2] = 8; pt[3].x = 20; pt[3].y = 10; z[3] = 4; m[3] = 9; pt[4].x = 10; pt[4].y = 10; z[4] = 1; m[4] = 10; /* The first polygon's interior ring. */ pt[5].x = 14; pt[5].y = 14; z[5] = -1; m[5] = -2; offsets[1] = 5; pt[6].x = 14; pt[6].y = 16; z[6] = 3; m[6] = 4; pt[7].x = 16; pt[7].y = 16; z[7] = -5; m[7] = 6; pt[8].x = 16; pt[8].y = 14; z[8] = 7; m[8] = -8; pt[9].x = 14; pt[9].y = 14; z[9] = -1; m[9] = -10.01; /* The second polygon's exterior ring. */ pt[10].x = 1; pt[10].y = 1; z[10] = 9; m[10] = 6; offsets[2] = 10; pt[11].x = 1; pt[11].y = 5; z[11] = 6; m[11] = 7; pt[12].x = 5; pt[12].y = 5; z[12] = 7; m[12] = 8; pt[13].x = 5; pt[13].y = 1; z[13] = 8; m[13] = 9; pt[14].x = 1; pt[14].y = 1; z[14] = 9; m[14] = 16; geom.type = geomMultiPolygonZM; geom.num_points = 15; geom.num_parts = 3; /* Convert the multipolygon into a shape. */ geom_to_shape (&geom, &max_alloced, &data_len, &binary); /* Insert the shape into the table. */ insert_shape (hdbc, &sc, 30, geomMultiPolygon, 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_shape - Inserts the shape 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 shape 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 == (GeomType) The data type of the geometry. * data_len == (int) The number of bytes in shape. * shape_buffer == (char *) The shape. * * RETURN == (void) * ***********************************************************************/ static void insert_shape ( SQLHDBC hdbc, SpatialColumn *sc, int id, GeomType type, int data_len, char *shape_buffer ) { int rc; char shp_sql[256]; char shpfunction[19]; SQLHSTMT hstmt; SDWORD pcbvalue1; SDWORD pcbvalue2; /* Set the shpfunction to the "FromShape" function that corresponds */ /* to the data type of the geometry representation. */ switch (type) { case geomPoint: strcpy (shpfunction, "SE_PointFromShape"); break; case geomLineString: strcpy (shpfunction, "SE_LineFromShape"); break; case geomPolygon: strcpy (shpfunction, "SE_PolyFromShape"); break; case geomMultiPoint: strcpy (shpfunction, "SE_MPointFromShape"); break; case geomMultiLineString: strcpy (shpfunction, "SE_MLineFromShape"); break; case geomMultiPolygon: strcpy (shpfunction, "SE_MPolyFromShape"); break; } /* Generate the SQL insert expression. The integer value and the */ /* name of the spatial column are entered as bind parameters. */ sprintf (shp_sql, "insert into %s (id, %s) values (?, %s (?, %d))", sc->table, sc->column, shpfunction, 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", shp_sql); rc = SQLPrepare (hstmt, (unsigned char *)shp_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 shape to the second parameter. */ pcbvalue2 = data_len; rc = SQLBindParameter (hstmt, 2, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_INFX_UDT_LVARCHAR, data_len, 0, shape_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"); }