GeometryCollection::GeometryCollection(SpatiaLite::Blob const & blob) : Buffer<GeometryCollectionType>(gaiaFromSpatiaLiteBlobWkb( blob.get(), blob.getSize()), gaiaFreeGeomColl) { }
GeometryCollection::GeometryCollection(SQLite::Column const & blob) : Buffer<GeometryCollectionType>(gaiaFromSpatiaLiteBlobWkb( (const unsigned char*)blob.getBlob(), blob.getBytes()), gaiaFreeGeomColl) { }
gaiaGeomCollPtr SpatiaLiteDB::Geom(int col) throw (std::string) { // throw an exception if the requested column doesn't exist checkColumn(SQLITE_BLOB, col); const void* blob; int blob_size; gaiaGeomCollPtr geom; blob = Blob(col, blob_size); /// @todoDoes geom need to be freed at some time? geom = gaiaFromSpatiaLiteBlobWkb((const unsigned char*) blob, blob_size); return geom; }
int main (int argc, char *argv[]) { int ret; sqlite3 *handle; sqlite3_stmt *stmt; gaiaGeomCollPtr geom; char sql[256]; int i; int ic; char **results; int n_rows; int n_columns; char *err_msg = NULL; int len; char *table_name; char **p_geotables = NULL; int n_geotables = 0; int row_no; const void *blob; int blob_size; int geom_type; double measure; void *cache; if (argc != 2) { fprintf (stderr, "usage: %s test_db_path\n", argv[0]); return -1; } /* trying to connect the test DB: - this demo was designed in order to connect the standard TEST-2.3.SQLITE sample DB - but you can try to use any SQLite/SpatiaLite DB at your will Please notice: we'll establish a READ ONLY connection */ ret = sqlite3_open_v2 (argv[1], &handle, SQLITE_OPEN_READONLY, NULL); if (ret != SQLITE_OK) { printf ("cannot open '%s': %s\n", argv[1], sqlite3_errmsg (handle)); sqlite3_close (handle); return -1; } /* VERY IMPORTANT: you must initialize the SpatiaLite extension [and related] BEFORE attempting to perform any other SQLite call ========================================================== Please note: starting since 4.1.0 this is completely canged: - a separate memory block (internal cache) is required by each single connection - allocating/freeing this block falls under the responsibility of the program handling the connection - in multithreaded programs a connection can never be share by different threads; the internal-cache block must be allocated by the same thread holding the connection */ cache = spatialite_alloc_connection (); spatialite_init_ex (handle, cache, 0); /* showing the SQLite version */ printf ("SQLite version: %s\n", sqlite3_libversion ()); /* showing the SpatiaLite version */ printf ("SpatiaLite version: %s\n", spatialite_version ()); printf ("\n\n"); /* SQL query #1 we'll retrieve GEOMETRY tables from Spatial Metadata we are assuming this query will return only few rows, so this time we'll use the sqlite3_get_table() interface this interface is very simple to use the result set is returned as a rectangular array [rows/columns] allocated in a temporary memory storage so, this interface is well suited for small sized result sets, but performs badly when accessing a large sized resul set as a side effect, each column value is returned as text, and isn't possible at all to retrieve true column types (INTEGER, FLOAT ...) */ strcpy (sql, "SELECT DISTINCT f_table_name FROM geometry_columns ORDER BY 1"); ret = sqlite3_get_table (handle, sql, &results, &n_rows, &n_columns, &err_msg); if (ret != SQLITE_OK) { /* some error occurred */ printf ("query#1 SQL error: %s\n", err_msg); sqlite3_free (err_msg); goto abort; } if (n_rows > 1) { /* first row always contains column names and is meaningless in this context */ n_geotables = n_rows; /* allocating a dynamic pointer array to store geotable names */ p_geotables = malloc (sizeof (char *) * n_geotables); for (i = 1; i <= n_rows; i++) { /* now we'll fetch one row at each time [and we have only one column to fetch] this one is is a simplified demo; but when writing a real application you always must check for NULL values !!!! */ table_name = results[(i * n_columns) + 0]; /* and we'll store each geotable name into the dynamic pointer array */ len = strlen (table_name); p_geotables[i - 1] = malloc (len + 1); strcpy (p_geotables[i - 1], table_name); } /* we can now free the table results */ sqlite3_free_table (results); } for (i = 0; i < n_geotables; i++) { /* now we'll scan each geotable we've found in Spatial Metadata */ printf ("========= table '%s' ========================\n", p_geotables[i]); /* SQL query #2 we'll retrieve any column from the current geotable we are assuming this query will return lots of rows, so we have to use sqlite3_prepare_v2() interface this interface is a more complex one, but is well suited in order to access huge sized result sets and true value type control is supported */ sprintf (sql, "SELECT * FROM %s", p_geotables[i]); ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL); if (ret != SQLITE_OK) { /* some error occurred */ printf ("query#2 SQL error: %s\n", sqlite3_errmsg (handle)); goto abort; } /* the sqlite3_prepare_v2() call simply parses the SQL statement, checking for syntax validity, allocating internal structs etc but no result set row is really yet available */ /* we'll now save the #columns within the result set */ n_columns = sqlite3_column_count (stmt); row_no = 0; while (1) { /* this is an infinite loop, intended to fetch any row */ /* we are now trying to fetch the next available row */ ret = sqlite3_step (stmt); if (ret == SQLITE_DONE) { /* there are no more rows to fetch - we can stop looping */ break; } if (ret == SQLITE_ROW) { /* ok, we've just fetched a valid row to process */ row_no++; printf ("row #%d\n", row_no); for (ic = 0; ic < n_columns; ic++) { /* and now we'll fetch column values for each column we'll then get: - the column name - a column value, that can be of type: SQLITE_NULL, SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT or SQLITE_BLOB, according to internal DB storage type */ printf ("\t%-10s = ", sqlite3_column_name (stmt, ic)); switch (sqlite3_column_type (stmt, ic)) { case SQLITE_NULL: printf ("NULL"); break; case SQLITE_INTEGER: printf ("%d", sqlite3_column_int (stmt, ic)); break; case SQLITE_FLOAT: printf ("%1.4f", sqlite3_column_double (stmt, ic)); break; case SQLITE_TEXT: printf ("'%s'", sqlite3_column_text (stmt, ic)); break; case SQLITE_BLOB: blob = sqlite3_column_blob (stmt, ic); blob_size = sqlite3_column_bytes (stmt, ic); /* checking if this BLOB actually is a GEOMETRY */ geom = gaiaFromSpatiaLiteBlobWkb (blob, blob_size); if (!geom) { /* for sure this one is not a GEOMETRY */ printf ("BLOB [%d bytes]", blob_size); } else { geom_type = gaiaGeometryType (geom); if (geom_type == GAIA_UNKNOWN) printf ("EMPTY or NULL GEOMETRY"); else { char *geom_name; if (geom_type == GAIA_POINT) geom_name = "POINT"; if (geom_type == GAIA_LINESTRING) geom_name = "LINESTRING"; if (geom_type == GAIA_POLYGON) geom_name = "POLYGON"; if (geom_type == GAIA_MULTIPOINT) geom_name = "MULTIPOINT"; if (geom_type == GAIA_MULTILINESTRING) geom_name = "MULTILINESTRING"; if (geom_type == GAIA_MULTIPOLYGON) geom_name = "MULTIPOLYGON"; if (geom_type == GAIA_GEOMETRYCOLLECTION) geom_name = "GEOMETRYCOLLECTION"; printf ("%s SRID=%d", geom_name, geom->Srid); if (geom_type == GAIA_LINESTRING || geom_type == GAIA_MULTILINESTRING) { #ifndef OMIT_GEOS /* GEOS is required */ gaiaGeomCollLength (geom, &measure); printf (" length=%1.2f", measure); #else printf (" length=?? [no GEOS support available]"); #endif /* GEOS enabled/disabled */ } if (geom_type == GAIA_POLYGON || geom_type == GAIA_MULTIPOLYGON) { #ifndef OMIT_GEOS /* GEOS is required */ gaiaGeomCollArea (geom, &measure); printf (" area=%1.2f", measure); #else printf ("area=?? [no GEOS support available]"); #endif /* GEOS enabled/disabled */ } } /* we have now to free the GEOMETRY */ gaiaFreeGeomColl (geom); } break; }; printf ("\n"); } if (row_no >= 5) { /* we'll exit the loop after the first 5 rows - this is only a demo :-) */ break; } } else { /* some unexpected error occurred */ printf ("sqlite3_step() error: %s\n", sqlite3_errmsg (handle)); sqlite3_finalize (stmt); goto abort; } } /* we have now to finalize the query [memory cleanup] */ sqlite3_finalize (stmt); printf ("\n\n"); } /* disconnecting the test DB */ ret = sqlite3_close (handle); if (ret != SQLITE_OK) { printf ("close() error: %s\n", sqlite3_errmsg (handle)); return -1; } /* freeing the internal-cache memory block */ spatialite_cleanup_ex (cache); printf ("\n\nsample successfully terminated\n"); /* we have to free the dynamic pointer array used to store geotable names */ for (i = 0; i < n_geotables; i++) { /* freeing each tablename */ free (p_geotables[i]); } free (p_geotables); spatialite_shutdown(); return 0; abort: sqlite3_close (handle); /* freeing the internal-cache memory block */ spatialite_cleanup_ex (cache); if (p_geotables) { /* we have to free the dynamic pointer array used to store geotable names */ for (i = 0; i < n_geotables; i++) { /* freeing each tablename */ free (p_geotables[i]); } free (p_geotables); } spatialite_shutdown(); return -1; }
static int vspidx_filter (sqlite3_vtab_cursor * pCursor, int idxNum, const char *idxStr, int argc, sqlite3_value ** argv) { /* setting up a cursor filter */ char *db_prefix = NULL; char *table_name = NULL; char *geom_column; char *xtable = NULL; char *xgeom = NULL; char *idx_name; char *idx_nameQ; char *sql_statement; gaiaGeomCollPtr geom = NULL; int ok_table = 0; int ok_geom = 0; const unsigned char *blob; int size; int exists; int ret; sqlite3_stmt *stmt; float minx; float miny; float maxx; float maxy; double tic; double tic2; VirtualSpatialIndexCursorPtr cursor = (VirtualSpatialIndexCursorPtr) pCursor; VirtualSpatialIndexPtr spidx = (VirtualSpatialIndexPtr) cursor->pVtab; if (idxStr) idxStr = idxStr; /* unused arg warning suppression */ cursor->eof = 1; if (idxNum == 1 && argc == 3) { /* retrieving the Table/Column/MBR params */ if (sqlite3_value_type (argv[0]) == SQLITE_TEXT) { char *tn = (char *) sqlite3_value_text (argv[0]); vspidx_parse_table_name (tn, &db_prefix, &table_name); ok_table = 1; } if (sqlite3_value_type (argv[1]) == SQLITE_TEXT) { geom_column = (char *) sqlite3_value_text (argv[1]); ok_geom = 1; } if (sqlite3_value_type (argv[2]) == SQLITE_BLOB) { blob = sqlite3_value_blob (argv[2]); size = sqlite3_value_bytes (argv[2]); geom = gaiaFromSpatiaLiteBlobWkb (blob, size); } if (ok_table && ok_geom && geom) ; else { /* invalid args */ goto stop; } } if (idxNum == 2 && argc == 2) { /* retrieving the Table/MBR params */ if (sqlite3_value_type (argv[0]) == SQLITE_TEXT) { char *tn = (char *) sqlite3_value_text (argv[0]); vspidx_parse_table_name (tn, &db_prefix, &table_name); ok_table = 1; } if (sqlite3_value_type (argv[1]) == SQLITE_BLOB) { blob = sqlite3_value_blob (argv[1]); size = sqlite3_value_bytes (argv[1]); geom = gaiaFromSpatiaLiteBlobWkb (blob, size); } if (ok_table && geom) ; else { /* invalid args */ goto stop; } } /* checking if the corresponding R*Tree exists */ if (ok_geom) exists = vspidx_check_rtree (spidx->db, db_prefix, table_name, geom_column, &xtable, &xgeom); else exists = vspidx_find_rtree (spidx->db, db_prefix, table_name, &xtable, &xgeom); if (!exists) goto stop; /* building the RTree query */ idx_name = sqlite3_mprintf ("idx_%s_%s", xtable, xgeom); idx_nameQ = gaiaDoubleQuotedSql (idx_name); if (db_prefix == NULL) { sql_statement = sqlite3_mprintf ("SELECT pkid FROM \"%s\" WHERE " "xmin <= ? AND xmax >= ? AND ymin <= ? AND ymax >= ?", idx_nameQ); } else { char *quoted_db = gaiaDoubleQuotedSql (db_prefix); sql_statement = sqlite3_mprintf ("SELECT pkid FROM \"%s\".\"%s\" WHERE " "xmin <= ? AND xmax >= ? AND ymin <= ? AND ymax >= ?", quoted_db, idx_nameQ); free (quoted_db); } free (idx_nameQ); sqlite3_free (idx_name); ret = sqlite3_prepare_v2 (spidx->db, sql_statement, strlen (sql_statement), &stmt, NULL); sqlite3_free (sql_statement); if (ret != SQLITE_OK) goto stop; /* binding stmt params [MBR] */ gaiaMbrGeometry (geom); /* adjusting the MBR so to compensate for DOUBLE/FLOAT truncations */ minx = (float) (geom->MinX); miny = (float) (geom->MinY); maxx = (float) (geom->MaxX); maxy = (float) (geom->MaxY); tic = fabs (geom->MinX - minx); tic2 = fabs (geom->MinY - miny); if (tic2 > tic) tic = tic2; tic2 = fabs (geom->MaxX - maxx); if (tic2 > tic) tic = tic2; tic2 = fabs (geom->MaxY - maxy); if (tic2 > tic) tic = tic2; tic *= 2.0; sqlite3_bind_double (stmt, 1, geom->MaxX + tic); sqlite3_bind_double (stmt, 2, geom->MinX - tic); sqlite3_bind_double (stmt, 3, geom->MaxY + tic); sqlite3_bind_double (stmt, 4, geom->MinY - tic); cursor->stmt = stmt; cursor->eof = 0; /* fetching the first ResultSet's row */ ret = sqlite3_step (cursor->stmt); if (ret == SQLITE_ROW) cursor->CurrentRowId = sqlite3_column_int64 (cursor->stmt, 0); else cursor->eof = 1; stop: if (geom) gaiaFreeGeomColl (geom); if (xtable) free (xtable); if (xgeom) free (xgeom); if (db_prefix) free (db_prefix); if (table_name) free (table_name); return SQLITE_OK; }
static int vknn_filter (sqlite3_vtab_cursor * pCursor, int idxNum, const char *idxStr, int argc, sqlite3_value ** argv) { /* setting up a cursor filter */ char *db_prefix = NULL; char *table_name = NULL; char *geom_column = NULL; char *xtable = NULL; char *xgeom = NULL; char *xgeomQ; char *xtableQ; char *idx_name; char *idx_nameQ; char *sql_statement; gaiaGeomCollPtr geom = NULL; int ok_table = 0; int ok_geom = 0; int ok_max = 0; int max_items = 3; int is_geographic; const unsigned char *blob; int size; int exists; int ret; sqlite3_stmt *stmt = NULL; sqlite3_stmt *stmt_dist = NULL; sqlite3_stmt *stmt_rect = NULL; VirtualKnnCursorPtr cursor = (VirtualKnnCursorPtr) pCursor; VirtualKnnPtr knn = (VirtualKnnPtr) cursor->pVtab; VKnnContextPtr vknn_context = knn->knn_ctx; if (idxStr) idxStr = idxStr; /* unused arg warning suppression */ cursor->eof = 1; if (idxStr) idxStr = idxStr; /* unused arg warning suppression */ cursor->eof = 1; if (idxNum == 1 && argc == 3) { /* retrieving the Table/Column/Geometry params */ if (sqlite3_value_type (argv[0]) == SQLITE_TEXT) { char *tn = (char *) sqlite3_value_text (argv[0]); vknn_parse_table_name (tn, &db_prefix, &table_name); ok_table = 1; } if (sqlite3_value_type (argv[1]) == SQLITE_TEXT) { geom_column = (char *) sqlite3_value_text (argv[1]); ok_geom = 1; } if (sqlite3_value_type (argv[2]) == SQLITE_BLOB) { blob = sqlite3_value_blob (argv[2]); size = sqlite3_value_bytes (argv[2]); geom = gaiaFromSpatiaLiteBlobWkb (blob, size); } if (ok_table && ok_geom && geom) ; else { /* invalid args */ goto stop; } } if (idxNum == 2 && argc == 2) { /* retrieving the Table/Geometry params */ if (sqlite3_value_type (argv[0]) == SQLITE_TEXT) { char *tn = (char *) sqlite3_value_text (argv[0]); vknn_parse_table_name (tn, &db_prefix, &table_name); ok_table = 1; } if (sqlite3_value_type (argv[1]) == SQLITE_BLOB) { blob = sqlite3_value_blob (argv[1]); size = sqlite3_value_bytes (argv[1]); geom = gaiaFromSpatiaLiteBlobWkb (blob, size); } if (ok_table && geom) ; else { /* invalid args */ goto stop; } } if (idxNum == 3 && argc == 4) { /* retrieving the Table/Column/Geometry/MaxItems params */ if (sqlite3_value_type (argv[0]) == SQLITE_TEXT) { char *tn = (char *) sqlite3_value_text (argv[0]); vknn_parse_table_name (tn, &db_prefix, &table_name); ok_table = 1; } if (sqlite3_value_type (argv[1]) == SQLITE_TEXT) { geom_column = (char *) sqlite3_value_text (argv[1]); ok_geom = 1; } if (sqlite3_value_type (argv[2]) == SQLITE_BLOB) { blob = sqlite3_value_blob (argv[2]); size = sqlite3_value_bytes (argv[2]); geom = gaiaFromSpatiaLiteBlobWkb (blob, size); } if (sqlite3_value_type (argv[3]) == SQLITE_INTEGER) { max_items = sqlite3_value_int (argv[3]); if (max_items > 1024) max_items = 1024; if (max_items < 1) max_items = 1; ok_max = 1; } if (ok_table && ok_geom && geom && ok_max) ; else { /* invalid args */ goto stop; } } if (idxNum == 4 && argc == 3) { /* retrieving the Table/Geometry/MaxItems params */ if (sqlite3_value_type (argv[0]) == SQLITE_TEXT) { char *tn = (char *) sqlite3_value_text (argv[0]); vknn_parse_table_name (tn, &db_prefix, &table_name); ok_table = 1; } if (sqlite3_value_type (argv[1]) == SQLITE_BLOB) { blob = sqlite3_value_blob (argv[1]); size = sqlite3_value_bytes (argv[1]); geom = gaiaFromSpatiaLiteBlobWkb (blob, size); } if (sqlite3_value_type (argv[2]) == SQLITE_INTEGER) { max_items = sqlite3_value_int (argv[2]); if (max_items > 1024) max_items = 1024; if (max_items < 1) max_items = 1; ok_max = 1; } if (ok_table && geom && ok_max) ; else { /* invalid args */ goto stop; } } /* checking if the corresponding R*Tree exists */ if (ok_geom) exists = vknn_check_rtree (knn->db, db_prefix, table_name, geom_column, &xtable, &xgeom, &is_geographic); else exists = vknn_find_rtree (knn->db, db_prefix, table_name, &xtable, &xgeom, &is_geographic); if (!exists) goto stop; /* building the Distance query */ xgeomQ = gaiaDoubleQuotedSql (xgeom); xtableQ = gaiaDoubleQuotedSql (xtable); if (is_geographic) sql_statement = sqlite3_mprintf ("SELECT ST_Distance(?, \"%s\", 1) FROM \"%s\" WHERE rowid = ?", xgeomQ, xtableQ); else sql_statement = sqlite3_mprintf ("SELECT ST_Distance(?, \"%s\") FROM \"%s\" WHERE rowid = ?", xgeomQ, xtableQ); free (xgeomQ); free (xtableQ); ret = sqlite3_prepare_v2 (knn->db, sql_statement, strlen (sql_statement), &stmt_dist, NULL); sqlite3_free (sql_statement); if (ret != SQLITE_OK) goto stop; /* building the RTree MBR Distance query */ sql_statement = "SELECT ST_Distance(?, BuildMbr(?, ?, ?, ?))"; ret = sqlite3_prepare_v2 (knn->db, sql_statement, strlen (sql_statement), &stmt_rect, NULL); if (ret != SQLITE_OK) goto stop; /* installing the R*Tree query callback */ gaiaMbrGeometry (geom); vknn_init_context (vknn_context, xtable, xgeom, geom, max_items, stmt_dist, stmt_rect); gaiaFreeGeomColl (geom); geom = NULL; /* releasing ownership on geom */ stmt_dist = NULL; /* releasing ownership on stmt_dist */ stmt_rect = NULL; /* releasing ownership on stmt_rect */ sqlite3_rtree_query_callback (knn->db, "knn_position", vknn_query_callback, vknn_context, NULL); /* building the RTree query */ idx_name = sqlite3_mprintf ("idx_%s_%s", xtable, xgeom); idx_nameQ = gaiaDoubleQuotedSql (idx_name); if (db_prefix == NULL) { sql_statement = sqlite3_mprintf ("SELECT pkid FROM \"%s\" WHERE pkid MATCH knn_position(1)", idx_nameQ); } else { char *quoted_db = gaiaDoubleQuotedSql (db_prefix); sql_statement = sqlite3_mprintf ("SELECT pkid FROM \"%s\".\"%s\" WHERE pkid MATCH knn_position(1)", quoted_db, idx_nameQ); free (quoted_db); } free (idx_nameQ); sqlite3_free (idx_name); ret = sqlite3_prepare_v2 (knn->db, sql_statement, strlen (sql_statement), &stmt, NULL); sqlite3_free (sql_statement); if (ret != SQLITE_OK) goto stop; vknn_context->curr_level = -1; while (vknn_context->curr_level != 0) { /* querying the R*Tree: step #1 tree MBRs */ sqlite3_step (stmt); if (vknn_context->curr_level == -1) break; /* found an empty R*Tree, preasumably */ vknn_context->curr_level -= 1; } if (vknn_context->curr_level == 0) { /* querying the R*Tree: step #2 features */ sqlite3_step (stmt); } if (vknn_context->curr_items == 0) cursor->eof = 1; else cursor->eof = 0; cursor->CurrentIndex = 0; stop: if (geom) gaiaFreeGeomColl (geom); if (xtable) free (xtable); if (xgeom) free (xgeom); if (db_prefix) free (db_prefix); if (table_name) free (table_name); if (stmt != NULL) sqlite3_finalize (stmt); if (stmt_dist != NULL) sqlite3_finalize (stmt_dist); if (stmt_rect != NULL) sqlite3_finalize (stmt_rect); return SQLITE_OK; }
static int check_extended (void *cache, const char *path, int mode) { /* validating an XML Sample */ FILE *fl; int sz = 0; int rd; unsigned char *xml = NULL; int iso; int style; int svg; unsigned char *p_result = NULL; int len; char *file_id = NULL; char *parent_id = NULL; char *title = NULL; char *abstract = NULL; unsigned char *geom_blob; int geom_size; gaiaGeomCollPtr geom; /* loading the XMLDocument */ fl = fopen (path, "rb"); if (!fl) { fprintf (stderr, "cannot open \"%s\"\n", path); return 0; } if (fseek (fl, 0, SEEK_END) == 0) sz = ftell (fl); xml = malloc (sz); rewind (fl); rd = fread (xml, 1, sz, fl); if (rd != sz) { fprintf (stderr, "read error \"%s\"\n", path); return 0; } fclose (fl); /* simple parsing without validation */ gaiaXmlToBlob (cache, xml, rd, 1, NULL, &p_result, &len, NULL, NULL); if (p_result == NULL) { fprintf (stderr, "unable to parse \"%s\"\n", path); return 0; } /* checking the payload type */ iso = gaiaIsIsoMetadataXmlBlob (p_result, len); style = gaiaIsSldSeRasterStyleXmlBlob (p_result, len); style = gaiaIsSldSeVectorStyleXmlBlob (p_result, len); svg = gaiaIsSvgXmlBlob (p_result, len); if (mode == ISO_METADATA && iso && !style && !svg) ; else if (mode == SLD_SE_STYLE && !iso && style && !svg) ; else if (mode == SVG && !iso && !style && svg) ; else { fprintf (stderr, "mismatching type: \"%s\" iso=%d style=%d svg=%d\n", path, iso, style, svg); return 0; } /* testing ISO Metadata attributes */ file_id = gaiaXmlBlobGetFileId (p_result, len); parent_id = gaiaXmlBlobGetParentId (p_result, len); title = gaiaXmlBlobGetTitle (p_result, len); abstract = gaiaXmlBlobGetAbstract (p_result, len); gaiaXmlBlobGetGeometry (p_result, len, &geom_blob, &geom_size); if (mode == ISO_METADATA) { /* verifying ISO Metadata attributes */ if (file_id == NULL) { fprintf (stderr, "unexpected NULL FileIdentifier in \"%s\"\n", path); return 0; } if (strcmp (file_id, "029097fd-2ef2-487c-a5ca-6ec7a3dbac53") != 0) { fprintf (stderr, "unexpected FileIdentifier in \"%s\" [%s]\n", path, file_id); return 0; } if (parent_id == NULL) { fprintf (stderr, "unexpected NULL ParentIdentifier in \"%s\"\n", path); return 0; } if (strcmp (parent_id, "024027fd-3ef2-487c-a8ca-6ec8a3dfac57") != 0) { fprintf (stderr, "unexpected ParentIdentifier in \"%s\" [%s]\n", path, parent_id); return 0; } if (title == NULL) { fprintf (stderr, "unexpected NULL Title in \"%s\"\n", path); return 0; } if (strcmp (title, "Image2000 Product 1 (nl2) Multispectral") != 0) { fprintf (stderr, "unexpected Title in \"%s\" [%s]\n", path, title); return 0; } if (abstract == NULL) { fprintf (stderr, "unexpected NULL Abstract in \"%s\"\n", path); return 0; } if (strcmp (abstract, "IMAGE2000 product 1 individual orthorectified scenes.") != 0) { fprintf (stderr, "unexpected Abstract in \"%s\" [%s]\n", path, abstract); return 0; } if (geom_blob == NULL) { fprintf (stderr, "unexpected NULL Geometry in \"%s\"\n", path); return 0; } geom = gaiaFromSpatiaLiteBlobWkb (geom_blob, geom_size); if (geom == NULL) { fprintf (stderr, "unexpected invalid Geometry in \"%s\"\n", path); return 0; } if (geom->Srid != 4326) { fprintf (stderr, "unexpected Geometry SRID in \"%s\" [%d]\n", path, geom->Srid); return 0; } if (geom->DeclaredType != GAIA_MULTIPOLYGON) { fprintf (stderr, "unexpected Geometry Type in \"%s\" [%d]\n", path, geom->DeclaredType); return 0; } if (geom->MinX != 3.93000000) { fprintf (stderr, "unexpected Geometry MinX in \"%s\" [%1.8f]\n", path, geom->MinX); return 0; } if (geom->MinY != 52.10000000) { fprintf (stderr, "unexpected Geometry MinY in \"%s\" [%1.8f]\n", path, geom->MinY); return 0; } if (geom->MaxX != 7.57000000) { fprintf (stderr, "unexpected Geometry MaxX in \"%s\" [%1.8f]\n", path, geom->MaxX); return 0; } if (geom->MaxY != 54.10000000) { fprintf (stderr, "unexpected Geometry MaxY in \"%s\" [%1.8f]\n", path, geom->MaxY); return 0; } gaiaFreeGeomColl (geom); } else { /* not ISO Metadata */ if (strcmp (path, "stazioni_se.xml") == 0) { if (strcmp (title, "Railway Stations - blue star") != 0) { fprintf (stderr, "unexpected Title in \"%s\"\n", path); return 0; } if (strcmp (abstract, "a simple SE Point Symbolizer") != 0) { fprintf (stderr, "unexpected Abstract in \"%s\"\n", path); return 0; } } else { if (title != NULL) { fprintf (stderr, "unexpected Title in \"%s\"\n", path); return 0; } if (abstract != NULL) { fprintf (stderr, "unexpected Abstract in \"%s\"\n", path); return 0; } } } free (p_result); free (xml); if (file_id) free (file_id); if (parent_id) free (parent_id); if (title) free (title); if (abstract) free (abstract); if (geom_blob) free (geom_blob); return 1; }
GAIAGEO_DECLARE int gaiaExportDxf (gaiaDxfWriterPtr dxf, sqlite3 * db_handle, const char *sql, const char *layer_col_name, const char *geom_col_name, const char *label_col_name, const char *text_height_col_name, const char *text_rotation_col_name, gaiaGeomCollPtr geom_filter) { /* exporting a complex DXF by executing an arbitrary SQL query */ sqlite3_stmt *stmt = NULL; int ret; int params; int first_row = 1; int layer_col = -1; int geom_col = -1; int label_col = -1; int text_height_col = -1; int text_rotation_col = -1; int i; unsigned char *p_blob; const unsigned char *blob; int len; const char *layer; const char *label = NULL; gaiaGeomCollPtr geom; gaiaDxfExportPtr aux = NULL; gaiaDxfExportLayerPtr lyr; if (dxf == NULL) return 0; if (dxf->error) return 0; if (dxf->out == NULL) return 0; if (db_handle == NULL) return 0; if (sql == NULL) return 0; if (layer_col_name == NULL) return 0; if (geom_col_name == NULL) return 0; /* attempting to create the SQL prepared statement */ ret = sqlite3_prepare_v2 (db_handle, sql, strlen (sql), &stmt, NULL); if (ret != SQLITE_OK) { spatialite_e ("exportDXF - CREATE STATEMENT error: %s\n", sqlite3_errmsg (db_handle)); goto stop; } params = sqlite3_bind_parameter_count (stmt); if (params > 0 && geom_filter != NULL) { /* parameter binding - Spatial Filter */ sqlite3_reset (stmt); sqlite3_clear_bindings (stmt); for (i = 1; i <= params; i++) { gaiaToSpatiaLiteBlobWkb (geom_filter, &p_blob, &len); ret = sqlite3_bind_blob (stmt, i, p_blob, len, free); if (ret != SQLITE_OK) { spatialite_e ("exportDXF - parameter BIND error: %s\n", sqlite3_errmsg (db_handle)); goto stop; } } } /* pass #1 - sniffing the result set */ while (1) { /* scrolling the result set rows */ ret = sqlite3_step (stmt); if (ret == SQLITE_DONE) break; /* end of result set */ if (ret == SQLITE_ROW) { if (first_row) { /* this one is the first row of the resultset */ for (i = 0; i < sqlite3_column_count (stmt); i++) { /* attempting to identify the resultset columns */ if (strcasecmp (layer_col_name, sqlite3_column_name (stmt, i)) == 0) layer_col = i; if (strcasecmp (geom_col_name, sqlite3_column_name (stmt, i)) == 0) geom_col = i; if (label_col_name != NULL) { if (strcasecmp (label_col_name, sqlite3_column_name (stmt, i)) == 0) label_col = i; } if (text_height_col_name != NULL) { if (strcasecmp (text_height_col_name, sqlite3_column_name (stmt, i)) == 0) text_height_col = i; } if (text_rotation_col_name != NULL) { if (strcasecmp (text_rotation_col_name, sqlite3_column_name (stmt, i)) == 0) text_rotation_col = i; } } if (layer_col < 0) { spatialite_e ("exportDXF - Layer Column not found into the resultset\n"); goto stop; } if (geom_col < 0) { spatialite_e ("exportDXF - Geometry Column not found into the resultset\n"); goto stop; } first_row = 0; aux = alloc_aux_exporter (); } layer = (const char *) sqlite3_column_text (stmt, layer_col); blob = sqlite3_column_blob (stmt, geom_col); len = sqlite3_column_bytes (stmt, geom_col); geom = gaiaFromSpatiaLiteBlobWkb (blob, len); if (geom) { update_aux_exporter (aux, layer, geom); gaiaFreeGeomColl (geom); } } } /* pass #2 - exporting the DXF file */ gaiaDxfWriteHeader (dxf, aux->minx, aux->miny, 0, aux->maxx, aux->maxy, 0); gaiaDxfWriteTables (dxf); lyr = aux->first; while (lyr != NULL) { gaiaDxfWriteLayer (dxf, lyr->layer_name); lyr = lyr->next; } gaiaDxfWriteEndSection (dxf); gaiaDxfWriteEntities (dxf); sqlite3_reset (stmt); while (1) { /* scrolling the result set rows */ int ival; double height = 10.0; double rotation = 0.0; ret = sqlite3_step (stmt); if (ret == SQLITE_DONE) break; /* end of result set */ if (ret == SQLITE_ROW) { layer = (const char *) sqlite3_column_text (stmt, layer_col); if (label_col >= 0) label = (const char *) sqlite3_column_text (stmt, label_col); if (text_height_col >= 0) { if (sqlite3_column_type (stmt, text_height_col) == SQLITE_INTEGER) { ival = sqlite3_column_int (stmt, text_height_col); height = ival; } if (sqlite3_column_type (stmt, text_height_col) == SQLITE_FLOAT) height = sqlite3_column_double (stmt, text_height_col); } if (text_rotation_col >= 0) { if (sqlite3_column_type (stmt, text_rotation_col) == SQLITE_INTEGER) { ival = sqlite3_column_int (stmt, text_rotation_col); rotation = ival; } if (sqlite3_column_type (stmt, text_height_col) == SQLITE_FLOAT) rotation = sqlite3_column_double (stmt, text_rotation_col); } blob = sqlite3_column_blob (stmt, geom_col); len = sqlite3_column_bytes (stmt, geom_col); geom = gaiaFromSpatiaLiteBlobWkb (blob, len); if (geom) { gaiaDxfWriteGeometry (dxf, layer, label, height, rotation, geom); gaiaFreeGeomColl (geom); } } } gaiaDxfWriteEndSection (dxf); gaiaDxfWriteFooter (dxf); sqlite3_finalize (stmt); if (aux != NULL) destroy_aux_exporter (aux); return dxf->count; stop: if (stmt != NULL) sqlite3_finalize (stmt); if (aux != NULL) destroy_aux_exporter (aux); return 0; }