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;
}
Beispiel #4
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}