This is a sample C source showing how to use the SQLite / SpatiaLite Spatial Index [MbrCache].It is very similar to demo3.c, but uses a different indexing approach
The typical output of this demo is shown below (where test.sqlite does not exist before the run).
As for demo3.c, note the significant speed difference between the indexed and non-indexed queries.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sqlite3.h>
int
main (int argc, char *argv[])
{
int ret;
sqlite3 *handle;
sqlite3_stmt *stmt;
char sql[256];
char *err_msg = NULL;
double x;
double y;
int pk;
int ix;
int iy;
unsigned char *blob;
int blob_size;
int i;
char **results;
int n_rows;
int n_columns;
char *count;
clock_t t0;
clock_t t1;
void *cache;
if (argc != 2)
{
fprintf (stderr, "usage: %s test_db_path\n", argv[0]);
return -1;
}
ret = sqlite3_open_v2 (argv[1], &handle,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
if (ret != SQLITE_OK)
{
printf ("cannot open '%s': %s\n", argv[1], sqlite3_errmsg (handle));
sqlite3_close (handle);
return -1;
}
printf ("SQLite version: %s\n", sqlite3_libversion ());
printf ("\n\n");
strcpy (sql, "SELECT InitSpatialMetadata(1)");
ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
if (ret != SQLITE_OK)
{
printf ("InitSpatialMetadata() error: %s\n", err_msg);
sqlite3_free (err_msg);
goto abort;
}
strcpy (sql, "CREATE TABLE test (");
strcat (sql, "PK INTEGER NOT NULL PRIMARY KEY)");
ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
if (ret != SQLITE_OK)
{
printf ("CREATE TABLE 'test' error: %s\n", err_msg);
sqlite3_free (err_msg);
goto abort;
}
strcpy (sql, "SELECT AddGeometryColumn('test', 'geom', 3003, 'POINT', 2)");
ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
if (ret != SQLITE_OK)
{
printf ("AddGeometryColumn() error: %s\n", err_msg);
sqlite3_free (err_msg);
goto abort;
}
strcpy (sql, "SELECT CreateMbrCache('test', 'geom')");
ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
if (ret != SQLITE_OK)
{
printf ("CreateMbrCache() error: %s\n", err_msg);
sqlite3_free (err_msg);
goto abort;
}
printf
("\nnow we are going to insert 1 million POINTs; wait, please ...\n\n");
t0 = clock ();
strcpy (sql, "BEGIN");
ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
if (ret != SQLITE_OK)
{
printf ("BEGIN error: %s\n", err_msg);
sqlite3_free (err_msg);
goto abort;
}
strcpy (sql, "INSERT INTO test (pk, geom) VALUES (?, ?)");
ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
if (ret != SQLITE_OK)
{
printf ("INSERT SQL error: %s\n", sqlite3_errmsg (handle));
goto abort;
}
pk = 0;
for (ix = 0; ix < 1000; ix++)
{
x = 1000000.0 + (ix * 10.0);
for (iy = 0; iy < 1000; iy++)
{
y = 4000000.0 + (iy * 10.0);
pk++;
if ((pk % 25000) == 0)
{
t1 = clock ();
printf ("insert row: %d\t\t[elapsed time: %1.3f]\n",
pk, (double) (t1 - t0) / CLOCKS_PER_SEC);
}
sqlite3_reset (stmt);
sqlite3_clear_bindings (stmt);
sqlite3_bind_int64 (stmt, 1, pk);
sqlite3_bind_blob (stmt, 2, blob, blob_size, free);
ret = sqlite3_step (stmt);
if (ret == SQLITE_DONE || ret == SQLITE_ROW)
;
else
{
printf ("sqlite3_step() error: %s\n",
sqlite3_errmsg (handle));
sqlite3_finalize (stmt);
goto abort;
}
}
}
sqlite3_finalize (stmt);
strcpy (sql, "COMMIT");
ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
if (ret != SQLITE_OK)
{
printf ("COMMIT error: %s\n", err_msg);
sqlite3_free (err_msg);
goto abort;
}
strcpy (sql, "ANALYZE test");
ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
if (ret != SQLITE_OK)
{
printf ("ANALYZE error: %s\n", err_msg);
sqlite3_free (err_msg);
goto abort;
}
for (ix = 0; ix < 3; ix++)
{
printf ("\nperforming test#%d - not using Spatial Index\n", ix);
strcpy (sql, "SELECT Count(*) FROM test ");
strcat (sql, "WHERE MbrWithin(geom, BuildMbr(");
strcat (sql, "1000400.5, 4000400.5, ");
strcat (sql, "1000450.5, 4000450.5))");
t0 = clock ();
ret = sqlite3_get_table (handle, sql, &results, &n_rows, &n_columns,
&err_msg);
if (ret != SQLITE_OK)
{
printf ("NoSpatialIndex SQL error: %s\n", err_msg);
sqlite3_free (err_msg);
goto abort;
}
count = "";
for (i = 1; i <= n_rows; i++)
{
count = results[(i * n_columns) + 0];
}
t1 = clock ();
printf ("Count(*) = %d\t\t[elapsed time: %1.4f]\n", atoi (count),
(double) (t1 - t0) / CLOCKS_PER_SEC);
sqlite3_free_table (results);
}
for (ix = 0; ix < 3; ix++)
{
printf ("\nperforming test#%d - using the MBR cache Spatial Index\n",
ix);
strcpy (sql, "SELECT Count(*) FROM test ");
strcat (sql, "WHERE ROWID IN (");
strcat (sql, "SELECT rowid FROM cache_test_geom WHERE ");
strcat (sql,
"mbr = FilterMbrWithin(1000400.5, 4000400.5, 1000450.5, 4000450.5))");
t0 = clock ();
ret = sqlite3_get_table (handle, sql, &results, &n_rows, &n_columns,
&err_msg);
if (ret != SQLITE_OK)
{
printf ("SpatialIndex SQL error: %s\n", err_msg);
sqlite3_free (err_msg);
goto abort;
}
count = "";
for (i = 1; i <= n_rows; i++)
{
count = results[(i * n_columns) + 0];
}
t1 = clock ();
printf ("Count(*) = %d\t\t[elapsed time: %1.4f]\n", atoi (count),
(double) (t1 - t0) / CLOCKS_PER_SEC);
sqlite3_free_table (results);
}
ret = sqlite3_close (handle);
if (ret != SQLITE_OK)
{
printf ("close() error: %s\n", sqlite3_errmsg (handle));
return -1;
}
printf ("\n\nsample successfully terminated\n");
return 0;
abort:
sqlite3_close (handle);
return -1;
}
Geometry handling functions and constants.
GAIAGEO_DECLARE void gaiaAddPointToGeomColl(gaiaGeomCollPtr p, double x, double y)
Creates a new 2D Point [XY] object into a Geometry object.
GAIAGEO_DECLARE void gaiaFreeGeomColl(gaiaGeomCollPtr geom)
Destroys a Geometry object.
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaAllocGeomColl(void)
Allocates a 2D Geometry [XY].
Main SpatiaLite header file.
SPATIALITE_DECLARE void spatialite_cleanup_ex(const void *ptr)
Cleanup a SpatiaLite connection.
SPATIALITE_DECLARE void * spatialite_alloc_connection(void)
Initializes the internal memory block supporting each connection.
SPATIALITE_DECLARE void spatialite_init_ex(sqlite3 *db_handle, const void *ptr, int verbose)
Initializes a SpatiaLite connection.
SPATIALITE_DECLARE const char * spatialite_version(void)
Return the current library version.
SPATIALITE_DECLARE void spatialite_shutdown(void)
Finalizes the library.
Container for OGC GEOMETRYCOLLECTION Geometry.
Definition: gg_structs.h:227
int Srid
the SRID
Definition: gg_structs.h:230