GAIAGEO_DECLARE gaiaGeomCollPtr gaiaCriticalPointFromGEOSmsg_r (const void *p_cache) { /* / Attempts to return a Point Geometry extracted from the latest GEOS / error / warning message */ double x; double y; gaiaGeomCollPtr geom; const char *msg; struct splite_internal_cache *cache = (struct splite_internal_cache *) p_cache; if (cache == NULL) return NULL; if (cache->magic1 == SPATIALITE_CACHE_MAGIC1 || cache->magic2 == SPATIALITE_CACHE_MAGIC2) ; else return NULL; msg = cache->gaia_geos_error_msg; if (msg == NULL) msg = cache->gaia_geos_warning_msg; if (msg == NULL) return NULL; if (!check_geos_critical_point (msg, &x, &y)) return NULL; geom = gaiaAllocGeomColl (); gaiaAddPointToGeomColl (geom, x, y); return geom; }
/* * Creates a 2D (xy) multipoint object in SpatiaLite * * first is a gaiaPointPtr to the first point in a linked list of points. * All of the points given to the function are 2D (xy) points. There will be at least 1 point in the list. * * Returns a geometry collection containing the created multipoint object. */ static gaiaGeomCollPtr geoJSON_multipoint_xy (struct geoJson_data *p_data, gaiaPointPtr first) { gaiaPointPtr p = first; gaiaPointPtr p_n; gaiaGeomCollPtr geom = NULL; /* If no pointers are given, return. */ if (first == NULL) return NULL; /* Creates and allocates a geometry collection containing a multipoint. */ geom = gaiaAllocGeomColl (); if (geom == NULL) return NULL; geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom); geom->DeclaredType = GAIA_MULTIPOINT; /* For every 2D (xy) point, add it to the geometry collection. */ while (p != NULL) { gaiaAddPointToGeomColl (geom, p->X, p->Y); p_n = p->Next; geoJsonMapDynClean (p_data, p); gaiaFreePoint (p); p = p_n; } return geom; }
static gaiaGeomCollPtr gaiaGeoJsonGeometryFromPoint (struct geoJson_data *p_data, gaiaPointPtr point, int srid) { /* builds a GEOMETRY containing a POINT */ gaiaGeomCollPtr geom = NULL; geom = gaiaAllocGeomColl (); geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom); geom->DeclaredType = GAIA_POINT; geom->Srid = srid; gaiaAddPointToGeomColl (geom, point->X, point->Y); geoJsonMapDynClean (p_data, point); gaiaFreePoint (point); return geom; }
static void add_point_to_geometry (struct gml_params *params, gaiaDynamicLinePtr dyn_line) { /* adding a POINT to current Geometry */ gaiaPointPtr pt; if (params->geometry == NULL) params->geometry = gaiaAllocGeomColl (); pt = dyn_line->First; while (pt) { /* inserting any POINT */ gaiaAddPointToGeomColl (params->geometry, pt->X, pt->Y); pt = pt->Next; } gaiaFreeDynamicLine (dyn_line); }
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaExtractPointsFromGeomColl (gaiaGeomCollPtr geom) { /* extracts any POINT from a GeometryCollection */ gaiaGeomCollPtr result; gaiaPointPtr pt; int pts = 0; if (!geom) return NULL; pt = geom->FirstPoint; while (pt) { pts++; pt = pt->Next; } if (!pts) return NULL; if (geom->DimensionModel == GAIA_XY_Z_M) result = gaiaAllocGeomCollXYZM (); else if (geom->DimensionModel == GAIA_XY_Z) result = gaiaAllocGeomCollXYZ (); else if (geom->DimensionModel == GAIA_XY_M) result = gaiaAllocGeomCollXYM (); else result = gaiaAllocGeomColl (); pt = geom->FirstPoint; while (pt) { if (geom->DimensionModel == GAIA_XY_Z_M) gaiaAddPointToGeomCollXYZM (result, pt->X, pt->Y, pt->Z, pt->M); else if (geom->DimensionModel == GAIA_XY_Z) gaiaAddPointToGeomCollXYZ (result, pt->X, pt->Y, pt->Z); else if (geom->DimensionModel == GAIA_XY_M) gaiaAddPointToGeomCollXYM (result, pt->X, pt->Y, pt->M); else gaiaAddPointToGeomColl (result, pt->X, pt->Y); pt = pt->Next; } result->Srid = geom->Srid; result->DeclaredType = GAIA_MULTIPOINT; return result; }
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaCriticalPointFromGEOSmsg (void) { /* / Attempts to return a Point Geometry extracted from the latest GEOS / error / warning message */ double x; double y; gaiaGeomCollPtr geom; const char *msg = gaia_geos_error_msg; if (msg == NULL) msg = gaia_geos_warning_msg; if (msg == NULL) return NULL; if (!check_geos_critical_point (msg, &x, &y)) return NULL; geom = gaiaAllocGeomColl (); gaiaAddPointToGeomColl (geom, x, y); return geom; }
static int kml_parse_point (struct kml_data *p_data, gaiaGeomCollPtr geom, kmlNodePtr node, kmlNodePtr * next) { /* parsing a <Point> */ double x; double y; double z; int has_z; gaiaGeomCollPtr pt; gaiaGeomCollPtr last; if (strcmp (node->Tag, "coordinates") == 0) { /* parsing a KML <Point> */ if (!kml_parse_point_v2 (node->Coordinates, &x, &y, &z, &has_z)) return 0; node = node->Next; if (node == NULL) return 0; if (strcmp (node->Tag, "coordinates") == 0) ; else return 0; node = node->Next; if (node == NULL) return 0; if (strcmp (node->Tag, "Point") == 0) ; else return 0; *next = node->Next; goto ok; } return 0; ok: /* ok, KML nodes match as expected */ if (has_z) { pt = gaiaAllocGeomCollXYZ (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pt); gaiaAddPointToGeomCollXYZ (pt, x, y, z); } else { pt = gaiaAllocGeomColl (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pt); gaiaAddPointToGeomColl (pt, x, y); } last = geom; while (1) { /* searching the last Geometry within chain */ if (last->Next == NULL) break; last = last->Next; } last->Next = pt; return 1; }
static gaiaGeomCollPtr kml_validate_geometry (struct kml_data *p_data, gaiaGeomCollPtr chain) { int xy = 0; int xyz = 0; int pts = 0; int lns = 0; int pgs = 0; gaiaPointPtr pt; gaiaLinestringPtr ln; gaiaPolygonPtr pg; gaiaPointPtr save_pt = NULL; gaiaLinestringPtr save_ln = NULL; gaiaPolygonPtr save_pg = NULL; gaiaRingPtr i_ring; gaiaRingPtr o_ring; int ib; gaiaGeomCollPtr g; gaiaGeomCollPtr geom; g = chain; while (g) { if (g != chain) { if (g->DimensionModel == GAIA_XY) xy++; if (g->DimensionModel == GAIA_XY_Z) xyz++; } pt = g->FirstPoint; while (pt) { pts++; save_pt = pt; pt = pt->Next; } ln = g->FirstLinestring; while (ln) { lns++; save_ln = ln; ln = ln->Next; } pg = g->FirstPolygon; while (pg) { pgs++; save_pg = pg; pg = pg->Next; } g = g->Next; } if (pts == 1 && lns == 0 && pgs == 0) { /* POINT */ if (xy > 0) { /* 2D [XY] */ geom = gaiaAllocGeomColl (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); if (chain->DeclaredType == GAIA_GEOMETRYCOLLECTION) geom->DeclaredType = GAIA_MULTIPOINT; else geom->DeclaredType = GAIA_POINT; gaiaAddPointToGeomColl (geom, save_pt->X, save_pt->Y); return geom; } else { /* 3D [XYZ] */ geom = gaiaAllocGeomCollXYZ (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); if (chain->DeclaredType == GAIA_GEOMETRYCOLLECTION) geom->DeclaredType = GAIA_MULTIPOINT; else geom->DeclaredType = GAIA_POINT; gaiaAddPointToGeomCollXYZ (geom, save_pt->X, save_pt->Y, save_pt->Z); return geom; } } if (pts == 0 && lns == 1 && pgs == 0) { /* LINESTRING */ if (xy > 0) { /* 2D [XY] */ geom = gaiaAllocGeomColl (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); } else { /* 3D [XYZ] */ geom = gaiaAllocGeomCollXYZ (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); } if (chain->DeclaredType == GAIA_GEOMETRYCOLLECTION) geom->DeclaredType = GAIA_MULTILINESTRING; else geom->DeclaredType = GAIA_LINESTRING; ln = gaiaAddLinestringToGeomColl (geom, save_ln->Points); gaiaCopyLinestringCoords (ln, save_ln); return geom; } if (pts == 0 && lns == 0 && pgs == 1) { /* POLYGON */ if (xy > 0) { /* 2D [XY] */ geom = gaiaAllocGeomColl (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); } else { /* 3D [XYZ] */ geom = gaiaAllocGeomCollXYZ (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); } if (chain->DeclaredType == GAIA_GEOMETRYCOLLECTION) geom->DeclaredType = GAIA_MULTIPOLYGON; else geom->DeclaredType = GAIA_POLYGON; i_ring = save_pg->Exterior; pg = gaiaAddPolygonToGeomColl (geom, i_ring->Points, save_pg->NumInteriors); o_ring = pg->Exterior; gaiaCopyRingCoords (o_ring, i_ring); for (ib = 0; ib < save_pg->NumInteriors; ib++) { i_ring = save_pg->Interiors + ib; o_ring = gaiaAddInteriorRing (pg, ib, i_ring->Points); gaiaCopyRingCoords (o_ring, i_ring); } return geom; } if (pts >= 1 && lns == 0 && pgs == 0) { /* MULTIPOINT */ if (xy > 0) { /* 2D [XY] */ geom = gaiaAllocGeomColl (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); geom->DeclaredType = GAIA_MULTIPOINT; g = chain; while (g) { pt = g->FirstPoint; while (pt) { gaiaAddPointToGeomColl (geom, pt->X, pt->Y); pt = pt->Next; } g = g->Next; } return geom; } else { /* 3D [XYZ] */ geom = gaiaAllocGeomCollXYZ (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); geom->DeclaredType = GAIA_MULTIPOINT; g = chain; while (g) { pt = g->FirstPoint; while (pt) { gaiaAddPointToGeomCollXYZ (geom, pt->X, pt->Y, pt->Z); pt = pt->Next; } g = g->Next; } return geom; } } if (pts == 0 && lns >= 1 && pgs == 0) { /* MULTILINESTRING */ if (xy > 0) { /* 2D [XY] */ geom = gaiaAllocGeomColl (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); geom->DeclaredType = GAIA_MULTILINESTRING; g = chain; while (g) { ln = g->FirstLinestring; while (ln) { save_ln = gaiaAddLinestringToGeomColl (geom, ln->Points); gaiaCopyLinestringCoords (save_ln, ln); ln = ln->Next; } g = g->Next; } return geom; } else { /* 3D [XYZ] */ geom = gaiaAllocGeomCollXYZ (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); geom->DeclaredType = GAIA_MULTILINESTRING; g = chain; while (g) { ln = g->FirstLinestring; while (ln) { save_ln = gaiaAddLinestringToGeomColl (geom, ln->Points); gaiaCopyLinestringCoords (save_ln, ln); ln = ln->Next; } g = g->Next; } return geom; } } if (pts == 0 && lns == 0 && pgs >= 1) { /* MULTIPOLYGON */ if (xy > 0) { /* 2D [XY] */ geom = gaiaAllocGeomColl (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); geom->DeclaredType = GAIA_MULTIPOLYGON; g = chain; while (g) { pg = g->FirstPolygon; while (pg) { i_ring = pg->Exterior; save_pg = gaiaAddPolygonToGeomColl (geom, i_ring->Points, pg->NumInteriors); o_ring = save_pg->Exterior; gaiaCopyRingCoords (o_ring, i_ring); for (ib = 0; ib < pg->NumInteriors; ib++) { i_ring = pg->Interiors + ib; o_ring = gaiaAddInteriorRing (save_pg, ib, i_ring->Points); gaiaCopyRingCoords (o_ring, i_ring); } pg = pg->Next; } g = g->Next; } return geom; } else { /* 3D [XYZ] */ geom = gaiaAllocGeomCollXYZ (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); geom->DeclaredType = GAIA_MULTIPOLYGON; g = chain; while (g) { pg = g->FirstPolygon; while (pg) { i_ring = pg->Exterior; save_pg = gaiaAddPolygonToGeomColl (geom, i_ring->Points, pg->NumInteriors); o_ring = save_pg->Exterior; gaiaCopyRingCoords (o_ring, i_ring); for (ib = 0; ib < pg->NumInteriors; ib++) { i_ring = pg->Interiors + ib; o_ring = gaiaAddInteriorRing (save_pg, ib, i_ring->Points); gaiaCopyRingCoords (o_ring, i_ring); } pg = pg->Next; } g = g->Next; } return geom; } } if ((pts + lns + pgs) > 0) { /* GEOMETRYCOLLECTION */ if (xy > 0) { /* 2D [XY] */ geom = gaiaAllocGeomColl (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); geom->DeclaredType = GAIA_GEOMETRYCOLLECTION; g = chain; while (g) { pt = g->FirstPoint; while (pt) { gaiaAddPointToGeomColl (geom, pt->X, pt->Y); pt = pt->Next; } ln = g->FirstLinestring; while (ln) { save_ln = gaiaAddLinestringToGeomColl (geom, ln->Points); gaiaCopyLinestringCoords (save_ln, ln); ln = ln->Next; } pg = g->FirstPolygon; while (pg) { i_ring = pg->Exterior; save_pg = gaiaAddPolygonToGeomColl (geom, i_ring->Points, pg->NumInteriors); o_ring = save_pg->Exterior; gaiaCopyRingCoords (o_ring, i_ring); for (ib = 0; ib < pg->NumInteriors; ib++) { i_ring = pg->Interiors + ib; o_ring = gaiaAddInteriorRing (save_pg, ib, i_ring->Points); gaiaCopyRingCoords (o_ring, i_ring); } pg = pg->Next; } g = g->Next; } return geom; } else { /* 3D [XYZ] */ geom = gaiaAllocGeomCollXYZ (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); geom->DeclaredType = GAIA_GEOMETRYCOLLECTION; g = chain; while (g) { pt = g->FirstPoint; while (pt) { gaiaAddPointToGeomCollXYZ (geom, pt->X, pt->Y, pt->Z); pt = pt->Next; } ln = g->FirstLinestring; while (ln) { save_ln = gaiaAddLinestringToGeomColl (geom, ln->Points); gaiaCopyLinestringCoords (save_ln, ln); ln = ln->Next; } pg = g->FirstPolygon; while (pg) { i_ring = pg->Exterior; save_pg = gaiaAddPolygonToGeomColl (geom, i_ring->Points, pg->NumInteriors); o_ring = save_pg->Exterior; gaiaCopyRingCoords (o_ring, i_ring); for (ib = 0; ib < pg->NumInteriors; ib++) { i_ring = pg->Interiors + ib; o_ring = gaiaAddInteriorRing (save_pg, ib, i_ring->Points); gaiaCopyRingCoords (o_ring, i_ring); } pg = pg->Next; } g = g->Next; } return geom; } } return NULL; }
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; gaiaGeomCollPtr geo = NULL; 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; } /* trying to connect the test DB: - this demo is intended to create a new, empty database */ 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; } 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"); /* we are supposing this one is an empty database, so we have to create the Spatial Metadata */ strcpy (sql, "SELECT InitSpatialMetadata(1)"); ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg); if (ret != SQLITE_OK) { /* an error occurred */ printf ("InitSpatialMetadata() error: %s\n", err_msg); sqlite3_free (err_msg); goto abort; } /* now we can create the test table for simplicity we'll define only one column, the primary key */ 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) { /* an error occurred */ printf ("CREATE TABLE 'test' error: %s\n", err_msg); sqlite3_free (err_msg); goto abort; } /* ... we'll add a Geometry column of POINT type to the test table */ strcpy (sql, "SELECT AddGeometryColumn('test', 'geom', 3003, 'POINT', 2)"); ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg); if (ret != SQLITE_OK) { /* an error occurred */ printf ("AddGeometryColumn() error: %s\n", err_msg); sqlite3_free (err_msg); goto abort; } /* and finally we'll enable this geo-column to have a Spatial Index based on R*Tree */ strcpy (sql, "SELECT CreateSpatialIndex('test', 'geom')"); ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg); if (ret != SQLITE_OK) { /* an error occurred */ printf ("CreateSpatialIndex() 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 (); /* beginning a transaction *** this step is absolutely critical *** the SQLite engine is a TRANSACTIONAL one the whole batch of INSERTs has to be performed as an unique transaction, otherwise performance will be surely very poor */ strcpy (sql, "BEGIN"); ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg); if (ret != SQLITE_OK) { /* an error occurred */ printf ("BEGIN error: %s\n", err_msg); sqlite3_free (err_msg); goto abort; } /* preparing to populate the test table we'll use a Prepared Statement we can reuse in order to insert each row */ strcpy (sql, "INSERT INTO test (pk, geom) VALUES (?, ?)"); ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL); if (ret != SQLITE_OK) { /* an error occurred */ 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++) { /* this double loop will insert 1 million rows into the the test table */ 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); } /* preparing the geometry to insert */ geo = gaiaAllocGeomColl (); geo->Srid = 3003; gaiaAddPointToGeomColl (geo, x, y); /* transforming this geometry into the SpatiaLite BLOB format */ gaiaToSpatiaLiteBlobWkb (geo, &blob, &blob_size); /* we can now destroy the geometry object */ gaiaFreeGeomColl (geo); /* resetting Prepared Statement and bindings */ sqlite3_reset (stmt); sqlite3_clear_bindings (stmt); /* binding parameters to Prepared Statement */ sqlite3_bind_int64 (stmt, 1, pk); sqlite3_bind_blob (stmt, 2, blob, blob_size, free); /* performing actual row insert */ ret = sqlite3_step (stmt); if (ret == SQLITE_DONE || ret == SQLITE_ROW) ; else { /* an 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); /* committing the transaction *** this step is absolutely critical *** if we don't confirm the still pending transaction, any update will be lost */ strcpy (sql, "COMMIT"); ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg); if (ret != SQLITE_OK) { /* an error occurred */ printf ("COMMIT error: %s\n", err_msg); sqlite3_free (err_msg); goto abort; } /* now we'll optimize the table */ strcpy (sql, "ANALYZE test"); ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg); if (ret != SQLITE_OK) { /* an error occurred */ 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); /* now we'll perform the spatial query WITHOUT using the Spatial Index we'll loop 3 times in order to avoid buffering-caching side effects */ 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) { /* an error occurred */ 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); /* we can now free the table results */ sqlite3_free_table (results); } for (ix = 0; ix < 3; ix++) { printf ("\nperforming test#%d - using the R*Tree Spatial Index\n", ix); /* now we'll perform the spatial query USING the R*Tree Spatial Index we'll loop 3 times in order to avoid buffering-caching side effects */ strcpy (sql, "SELECT Count(*) FROM test "); strcat (sql, "WHERE MbrWithin(geom, BuildMbr("); strcat (sql, "1000400.5, 4000400.5, "); strcat (sql, "1000450.5, 4000450.5)) AND ROWID IN ("); strcat (sql, "SELECT pkid FROM idx_test_geom WHERE "); strcat (sql, "xmin > 1000400.5 AND "); strcat (sql, "xmax < 1000450.5 AND "); strcat (sql, "ymin > 4000400.5 AND "); strcat (sql, "ymax < 4000450.5)"); /* YES, this query is a very unhappy one the idea is simply to simulate exactly the same conditions as above */ t0 = clock (); ret = sqlite3_get_table (handle, sql, &results, &n_rows, &n_columns, &err_msg); if (ret != SQLITE_OK) { /* an error occurred */ 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); /* we can now free the table results */ sqlite3_free_table (results); } /* disconnecting the test DB */ ret = sqlite3_close (handle); if (ret != SQLITE_OK) { printf ("close() error: %s\n", sqlite3_errmsg (handle)); return -1; } spatialite_cleanup_ex (cache); printf ("\n\nsample successfully terminated\n"); return 0; abort: sqlite3_close (handle); spatialite_cleanup_ex (cache); spatialite_shutdown(); return -1; }
static gaiaGeomCollPtr gaiaTransformCommon (projCtx handle, gaiaGeomCollPtr org, char *proj_from, char *proj_to) { /* creates a new GEOMETRY reprojecting coordinates from the original one */ int ib; int cnt; int i; double *xx; double *yy; double *zz; double *mm = NULL; double x; double y; double z = 0.0; double m = 0.0; int error = 0; int from_angle; int to_angle; gaiaPointPtr pt; gaiaLinestringPtr ln; gaiaLinestringPtr dst_ln; gaiaPolygonPtr pg; gaiaPolygonPtr dst_pg; gaiaRingPtr rng; gaiaRingPtr dst_rng; projPJ from_cs; projPJ to_cs; gaiaGeomCollPtr dst; if (handle != NULL) { from_cs = pj_init_plus_ctx (handle, proj_from); to_cs = pj_init_plus_ctx (handle, proj_to); } else { from_cs = pj_init_plus (proj_from); to_cs = pj_init_plus (proj_to); } if (!from_cs) { if (to_cs) pj_free (to_cs); return NULL; } if (!to_cs) { pj_free (from_cs); return NULL; } if (org->DimensionModel == GAIA_XY_Z) dst = gaiaAllocGeomCollXYZ (); else if (org->DimensionModel == GAIA_XY_M) dst = gaiaAllocGeomCollXYM (); else if (org->DimensionModel == GAIA_XY_Z_M) dst = gaiaAllocGeomCollXYZM (); else dst = gaiaAllocGeomColl (); /* setting up projection parameters */ from_angle = gaiaIsLongLat (proj_from); to_angle = gaiaIsLongLat (proj_to); cnt = 0; pt = org->FirstPoint; while (pt) { /* counting POINTs */ cnt++; pt = pt->Next; } if (cnt) { /* reprojecting POINTs */ xx = malloc (sizeof (double) * cnt); yy = malloc (sizeof (double) * cnt); zz = malloc (sizeof (double) * cnt); if (org->DimensionModel == GAIA_XY_M || org->DimensionModel == GAIA_XY_Z_M) mm = malloc (sizeof (double) * cnt); i = 0; pt = org->FirstPoint; while (pt) { /* inserting points to be converted in temporary arrays */ if (from_angle) { xx[i] = gaiaDegsToRads (pt->X); yy[i] = gaiaDegsToRads (pt->Y); } else { xx[i] = pt->X; yy[i] = pt->Y; } if (org->DimensionModel == GAIA_XY_Z || org->DimensionModel == GAIA_XY_Z_M) zz[i] = pt->Z; else zz[i] = 0.0; if (org->DimensionModel == GAIA_XY_M || org->DimensionModel == GAIA_XY_Z_M) mm[i] = pt->M; i++; pt = pt->Next; } /* applying reprojection */ if (pj_transform (from_cs, to_cs, cnt, 0, xx, yy, zz) == 0) { /* inserting the reprojected POINTs in the new GEOMETRY */ for (i = 0; i < cnt; i++) { if (to_angle) { x = gaiaRadsToDegs (xx[i]); y = gaiaRadsToDegs (yy[i]); } else { x = xx[i]; y = yy[i]; } if (org->DimensionModel == GAIA_XY_Z || org->DimensionModel == GAIA_XY_Z_M) z = zz[i]; else z = 0.0; if (org->DimensionModel == GAIA_XY_M || org->DimensionModel == GAIA_XY_Z_M) m = mm[i]; else m = 0.0; if (dst->DimensionModel == GAIA_XY_Z) gaiaAddPointToGeomCollXYZ (dst, x, y, z); else if (dst->DimensionModel == GAIA_XY_M) gaiaAddPointToGeomCollXYM (dst, x, y, m); else if (dst->DimensionModel == GAIA_XY_Z_M) gaiaAddPointToGeomCollXYZM (dst, x, y, z, m); else gaiaAddPointToGeomColl (dst, x, y); } } else error = 1; free (xx); free (yy); free (zz); if (org->DimensionModel == GAIA_XY_M || org->DimensionModel == GAIA_XY_Z_M) free (mm); } if (error) goto stop; ln = org->FirstLinestring; while (ln) { /* reprojecting LINESTRINGs */ cnt = ln->Points; xx = malloc (sizeof (double) * cnt); yy = malloc (sizeof (double) * cnt); zz = malloc (sizeof (double) * cnt); if (ln->DimensionModel == GAIA_XY_M || ln->DimensionModel == GAIA_XY_Z_M) mm = malloc (sizeof (double) * cnt); for (i = 0; i < cnt; i++) { /* inserting points to be converted in temporary arrays */ if (ln->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (ln->Coords, i, &x, &y, &z); } else if (ln->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (ln->Coords, i, &x, &y, &m); } else if (ln->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (ln->Coords, i, &x, &y, &z, &m); } else { gaiaGetPoint (ln->Coords, i, &x, &y); } if (from_angle) { xx[i] = gaiaDegsToRads (x); yy[i] = gaiaDegsToRads (y); } else { xx[i] = x; yy[i] = y; } if (ln->DimensionModel == GAIA_XY_Z || ln->DimensionModel == GAIA_XY_Z_M) zz[i] = z; else zz[i] = 0.0; if (ln->DimensionModel == GAIA_XY_M || ln->DimensionModel == GAIA_XY_Z_M) mm[i] = m; } /* applying reprojection */ if (pj_transform (from_cs, to_cs, cnt, 0, xx, yy, zz) == 0) { /* inserting the reprojected LINESTRING in the new GEOMETRY */ dst_ln = gaiaAddLinestringToGeomColl (dst, cnt); for (i = 0; i < cnt; i++) { /* setting LINESTRING points */ if (to_angle) { x = gaiaRadsToDegs (xx[i]); y = gaiaRadsToDegs (yy[i]); } else { x = xx[i]; y = yy[i]; } if (ln->DimensionModel == GAIA_XY_Z || ln->DimensionModel == GAIA_XY_Z_M) z = zz[i]; else z = 0.0; if (ln->DimensionModel == GAIA_XY_M || ln->DimensionModel == GAIA_XY_Z_M) m = mm[i]; else m = 0.0; if (dst_ln->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (dst_ln->Coords, i, x, y, z); } else if (dst_ln->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (dst_ln->Coords, i, x, y, m); } else if (dst_ln->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (dst_ln->Coords, i, x, y, z, m); } else { gaiaSetPoint (dst_ln->Coords, i, x, y); } } } else error = 1; free (xx); free (yy); free (zz); if (ln->DimensionModel == GAIA_XY_M || ln->DimensionModel == GAIA_XY_Z_M) free (mm); if (error) goto stop; ln = ln->Next; } pg = org->FirstPolygon; while (pg) { /* reprojecting POLYGONs */ rng = pg->Exterior; cnt = rng->Points; dst_pg = gaiaAddPolygonToGeomColl (dst, cnt, pg->NumInteriors); xx = malloc (sizeof (double) * cnt); yy = malloc (sizeof (double) * cnt); zz = malloc (sizeof (double) * cnt); if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) mm = malloc (sizeof (double) * cnt); for (i = 0; i < cnt; i++) { /* inserting points to be converted in temporary arrays [EXTERIOR RING] */ if (rng->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (rng->Coords, i, &x, &y, &z); } else if (rng->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (rng->Coords, i, &x, &y, &m); } else if (rng->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (rng->Coords, i, &x, &y, &z, &m); } else { gaiaGetPoint (rng->Coords, i, &x, &y); } if (from_angle) { xx[i] = gaiaDegsToRads (x); yy[i] = gaiaDegsToRads (y); } else { xx[i] = x; yy[i] = y; } if (rng->DimensionModel == GAIA_XY_Z || rng->DimensionModel == GAIA_XY_Z_M) zz[i] = z; else zz[i] = 0.0; if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) mm[i] = m; } /* applying reprojection */ if (pj_transform (from_cs, to_cs, cnt, 0, xx, yy, zz) == 0) { /* inserting the reprojected POLYGON in the new GEOMETRY */ dst_rng = dst_pg->Exterior; for (i = 0; i < cnt; i++) { /* setting EXTERIOR RING points */ if (to_angle) { x = gaiaRadsToDegs (xx[i]); y = gaiaRadsToDegs (yy[i]); } else { x = xx[i]; y = yy[i]; } if (rng->DimensionModel == GAIA_XY_Z || rng->DimensionModel == GAIA_XY_Z_M) z = zz[i]; else z = 0.0; if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) m = mm[i]; else m = 0.0; if (dst_rng->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (dst_rng->Coords, i, x, y, z); } else if (dst_rng->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (dst_rng->Coords, i, x, y, m); } else if (dst_rng->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (dst_rng->Coords, i, x, y, z, m); } else { gaiaSetPoint (dst_rng->Coords, i, x, y); } } } else error = 1; free (xx); free (yy); free (zz); if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) free (mm); if (error) goto stop; for (ib = 0; ib < pg->NumInteriors; ib++) { /* processing INTERIOR RINGS */ rng = pg->Interiors + ib; cnt = rng->Points; xx = malloc (sizeof (double) * cnt); yy = malloc (sizeof (double) * cnt); zz = malloc (sizeof (double) * cnt); if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) mm = malloc (sizeof (double) * cnt); for (i = 0; i < cnt; i++) { /* inserting points to be converted in temporary arrays [INTERIOR RING] */ if (rng->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (rng->Coords, i, &x, &y, &z); } else if (rng->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (rng->Coords, i, &x, &y, &m); } else if (rng->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (rng->Coords, i, &x, &y, &z, &m); } else { gaiaGetPoint (rng->Coords, i, &x, &y); } if (from_angle) { xx[i] = gaiaDegsToRads (x); yy[i] = gaiaDegsToRads (y); } else { xx[i] = x; yy[i] = y; } if (rng->DimensionModel == GAIA_XY_Z || rng->DimensionModel == GAIA_XY_Z_M) zz[i] = z; else zz[i] = 0.0; if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) mm[i] = m; } /* applying reprojection */ if (pj_transform (from_cs, to_cs, cnt, 0, xx, yy, zz) == 0) { /* inserting the reprojected POLYGON in the new GEOMETRY */ dst_rng = gaiaAddInteriorRing (dst_pg, ib, cnt); for (i = 0; i < cnt; i++) { /* setting INTERIOR RING points */ if (to_angle) { x = gaiaRadsToDegs (xx[i]); y = gaiaRadsToDegs (yy[i]); } else { x = xx[i]; y = yy[i]; } if (rng->DimensionModel == GAIA_XY_Z || rng->DimensionModel == GAIA_XY_Z_M) z = zz[i]; else z = 0.0; if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) m = mm[i]; else m = 0.0; if (dst_rng->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (dst_rng->Coords, i, x, y, z); } else if (dst_rng->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (dst_rng->Coords, i, x, y, m); } else if (dst_rng->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (dst_rng->Coords, i, x, y, z, m); } else { gaiaSetPoint (dst_rng->Coords, i, x, y); } } } else error = 1; free (xx); free (yy); free (zz); if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) free (mm); if (error) goto stop; } pg = pg->Next; } /* destroying the PROJ4 params */ stop: pj_free (from_cs); pj_free (to_cs); if (error) { /* some error occurred */ gaiaPointPtr pP; gaiaPointPtr pPn; gaiaLinestringPtr pL; gaiaLinestringPtr pLn; gaiaPolygonPtr pA; gaiaPolygonPtr pAn; pP = dst->FirstPoint; while (pP != NULL) { pPn = pP->Next; gaiaFreePoint (pP); pP = pPn; } pL = dst->FirstLinestring; while (pL != NULL) { pLn = pL->Next; gaiaFreeLinestring (pL); pL = pLn; } pA = dst->FirstPolygon; while (pA != NULL) { pAn = pA->Next; gaiaFreePolygon (pA); pA = pAn; } dst->FirstPoint = NULL; dst->LastPoint = NULL; dst->FirstLinestring = NULL; dst->LastLinestring = NULL; dst->FirstPolygon = NULL; dst->LastPolygon = NULL; } if (dst) { gaiaMbrGeometry (dst); dst->DeclaredType = org->DeclaredType; } return dst; }
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaDissolvePoints (gaiaGeomCollPtr geom) { /* attempts to dissolve a Geometry into points */ gaiaGeomCollPtr result; gaiaPointPtr pt; gaiaLinestringPtr ln; gaiaPolygonPtr pg; gaiaRingPtr rng; int iv; int ib; double x; double y; double z; double m; if (!geom) return NULL; if (geom->DimensionModel == GAIA_XY_Z_M) result = gaiaAllocGeomCollXYZM (); else if (geom->DimensionModel == GAIA_XY_Z) result = gaiaAllocGeomCollXYZ (); else if (geom->DimensionModel == GAIA_XY_M) result = gaiaAllocGeomCollXYM (); else result = gaiaAllocGeomColl (); pt = geom->FirstPoint; while (pt) { if (geom->DimensionModel == GAIA_XY_Z_M) gaiaAddPointToGeomCollXYZM (result, pt->X, pt->Y, pt->Z, pt->M); else if (geom->DimensionModel == GAIA_XY_Z) gaiaAddPointToGeomCollXYZ (result, pt->X, pt->Y, pt->Z); else if (geom->DimensionModel == GAIA_XY_M) gaiaAddPointToGeomCollXYM (result, pt->X, pt->Y, pt->M); else gaiaAddPointToGeomColl (result, pt->X, pt->Y); pt = pt->Next; } ln = geom->FirstLinestring; while (ln) { for (iv = 0; iv < ln->Points; iv++) { if (ln->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m); } else if (ln->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z); } else if (ln->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m); } else { gaiaGetPoint (ln->Coords, iv, &x, &y); } if (geom->DimensionModel == GAIA_XY_Z_M) gaiaAddPointToGeomCollXYZM (result, x, y, z, m); else if (geom->DimensionModel == GAIA_XY_Z) gaiaAddPointToGeomCollXYZ (result, x, y, z); else if (geom->DimensionModel == GAIA_XY_M) gaiaAddPointToGeomCollXYM (result, x, y, m); else gaiaAddPointToGeomColl (result, x, y); } ln = ln->Next; } pg = geom->FirstPolygon; while (pg) { rng = pg->Exterior; for (iv = 0; iv < rng->Points; iv++) { /* exterior Ring */ if (rng->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m); } else if (rng->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z); } else if (rng->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m); } else { gaiaGetPoint (rng->Coords, iv, &x, &y); } if (geom->DimensionModel == GAIA_XY_Z_M) gaiaAddPointToGeomCollXYZM (result, x, y, z, m); else if (geom->DimensionModel == GAIA_XY_Z) gaiaAddPointToGeomCollXYZ (result, x, y, z); else if (geom->DimensionModel == GAIA_XY_M) gaiaAddPointToGeomCollXYM (result, x, y, m); else gaiaAddPointToGeomColl (result, x, y); } for (ib = 0; ib < pg->NumInteriors; ib++) { rng = pg->Interiors + ib; for (iv = 0; iv < rng->Points; iv++) { /* interior Ring */ if (rng->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m); } else if (rng->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z); } else if (rng->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m); } else { gaiaGetPoint (rng->Coords, iv, &x, &y); } if (geom->DimensionModel == GAIA_XY_Z_M) gaiaAddPointToGeomCollXYZM (result, x, y, z, m); else if (geom->DimensionModel == GAIA_XY_Z) gaiaAddPointToGeomCollXYZ (result, x, y, z); else if (geom->DimensionModel == GAIA_XY_M) gaiaAddPointToGeomCollXYM (result, x, y, m); else gaiaAddPointToGeomColl (result, x, y); } } pg = pg->Next; } result->Srid = geom->Srid; return result; }
static void auxGridSnapPoint (int dimension_model, gaiaPointPtr pt, gaiaGeomCollPtr result, double origin_x, double origin_y, double origin_z, double origin_m, double size_x, double size_y, double size_z, double size_m) { /* snapping a Point to a regular Grid */ double x = pt->X; double y = pt->Y; double z = 0.0; double m = 0.0; int has_z = 0; int has_m = 0; gaiaPointPtr ptx; if (pt == NULL || result == NULL) return; if (dimension_model == GAIA_XY_Z || dimension_model == GAIA_XY_Z_M) has_z = 1; if (dimension_model == GAIA_XY_M || dimension_model == GAIA_XY_Z_M) has_m = 1; if (has_z) z = pt->Z; if (has_m) m = pt->M; /* snapping coords to the given grid */ if (size_x > 0.0) x = rint ((x - origin_x) / size_x) * size_x + origin_x; if (size_y > 0.0) y = rint ((y - origin_y) / size_y) * size_y + origin_y; if (has_z && size_z > 0.0) z = rint ((z - origin_z) / size_z) * size_z + origin_z; if (has_m && size_m > 0.0) m = rint ((m - origin_m) / size_m) * size_m + origin_m; ptx = result->FirstPoint; while (ptx) { /* checking if already defined */ if (has_z && has_m) { if (ptx->X == x && ptx->Y == y && ptx->Z == z && ptx->M == m) return; } else if (has_z) { if (ptx->X == x && ptx->Y == y && ptx->Z == z) return; } else if (has_m) { if (ptx->X == x && ptx->Y == y && ptx->M == m) return; } else { if (ptx->X == x && ptx->Y == y) return; } ptx = ptx->Next; } /* inserting the snapped Point into the result Geometry */ if (has_z && has_m) gaiaAddPointToGeomCollXYZM (result, x, y, z, m); else if (has_z) gaiaAddPointToGeomCollXYZ (result, x, y, z); else if (has_m) gaiaAddPointToGeomCollXYM (result, x, y, m); else gaiaAddPointToGeomColl (result, x, y); }
static gaiaGeomCollPtr fromGeosGeometry (const GEOSGeometry * geos, const int dimension_model) { /* converting a GEOS Geometry into a GAIA Geometry */ int type; int itemType; unsigned int dims; int iv; int ib; int it; int sub_it; int nItems; int nSubItems; int holes; unsigned int points; double x; double y; double z; const GEOSCoordSequence *cs; const GEOSGeometry *geos_ring; const GEOSGeometry *geos_item; const GEOSGeometry *geos_sub_item; gaiaGeomCollPtr gaia = NULL; gaiaLinestringPtr ln; gaiaPolygonPtr pg; gaiaRingPtr rng; if (!geos) return NULL; type = GEOSGeomTypeId (geos); switch (type) { case GEOS_POINT: if (dimension_model == GAIA_XY_Z) gaia = gaiaAllocGeomCollXYZ (); else if (dimension_model == GAIA_XY_M) gaia = gaiaAllocGeomCollXYM (); else if (dimension_model == GAIA_XY_Z_M) gaia = gaiaAllocGeomCollXYZM (); else gaia = gaiaAllocGeomColl (); gaia->DeclaredType = GAIA_POINT; gaia->Srid = GEOSGetSRID (geos); cs = GEOSGeom_getCoordSeq (geos); GEOSCoordSeq_getDimensions (cs, &dims); if (dims == 3) { GEOSCoordSeq_getX (cs, 0, &x); GEOSCoordSeq_getY (cs, 0, &y); GEOSCoordSeq_getZ (cs, 0, &z); } else { GEOSCoordSeq_getX (cs, 0, &x); GEOSCoordSeq_getY (cs, 0, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) gaiaAddPointToGeomCollXYZ (gaia, x, y, z); else if (dimension_model == GAIA_XY_M) gaiaAddPointToGeomCollXYM (gaia, x, y, 0.0); else if (dimension_model == GAIA_XY_Z_M) gaiaAddPointToGeomCollXYZM (gaia, x, y, z, 0.0); else gaiaAddPointToGeomColl (gaia, x, y); break; case GEOS_LINESTRING: if (dimension_model == GAIA_XY_Z) gaia = gaiaAllocGeomCollXYZ (); else if (dimension_model == GAIA_XY_M) gaia = gaiaAllocGeomCollXYM (); else if (dimension_model == GAIA_XY_Z_M) gaia = gaiaAllocGeomCollXYZM (); else gaia = gaiaAllocGeomColl (); gaia->DeclaredType = GAIA_LINESTRING; gaia->Srid = GEOSGetSRID (geos); cs = GEOSGeom_getCoordSeq (geos); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); ln = gaiaAddLinestringToGeomColl (gaia, points); for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (ln->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (ln->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (ln->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (ln->Coords, iv, x, y); } } break; case GEOS_POLYGON: if (dimension_model == GAIA_XY_Z) gaia = gaiaAllocGeomCollXYZ (); else if (dimension_model == GAIA_XY_M) gaia = gaiaAllocGeomCollXYM (); else if (dimension_model == GAIA_XY_Z_M) gaia = gaiaAllocGeomCollXYZM (); else gaia = gaiaAllocGeomColl (); gaia->DeclaredType = GAIA_POLYGON; gaia->Srid = GEOSGetSRID (geos); /* exterior ring */ holes = GEOSGetNumInteriorRings (geos); geos_ring = GEOSGetExteriorRing (geos); cs = GEOSGeom_getCoordSeq (geos_ring); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); pg = gaiaAddPolygonToGeomColl (gaia, points, holes); rng = pg->Exterior; for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (rng->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (rng->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (rng->Coords, iv, x, y); } } for (ib = 0; ib < holes; ib++) { /* interior rings */ geos_ring = GEOSGetInteriorRingN (geos, ib); cs = GEOSGeom_getCoordSeq (geos_ring); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); rng = gaiaAddInteriorRing (pg, ib, points); for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (rng->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (rng->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (rng->Coords, iv, x, y); } } } break; case GEOS_MULTIPOINT: case GEOS_MULTILINESTRING: case GEOS_MULTIPOLYGON: case GEOS_GEOMETRYCOLLECTION: if (dimension_model == GAIA_XY_Z) gaia = gaiaAllocGeomCollXYZ (); else if (dimension_model == GAIA_XY_M) gaia = gaiaAllocGeomCollXYM (); else if (dimension_model == GAIA_XY_Z_M) gaia = gaiaAllocGeomCollXYZM (); else gaia = gaiaAllocGeomColl (); if (type == GEOS_MULTIPOINT) gaia->DeclaredType = GAIA_MULTIPOINT; else if (type == GEOS_MULTILINESTRING) gaia->DeclaredType = GAIA_MULTILINESTRING; else if (type == GEOS_MULTIPOLYGON) gaia->DeclaredType = GAIA_MULTIPOLYGON; else gaia->DeclaredType = GAIA_GEOMETRYCOLLECTION; gaia->Srid = GEOSGetSRID (geos); nItems = GEOSGetNumGeometries (geos); for (it = 0; it < nItems; it++) { /* looping on elementaty geometries */ geos_item = GEOSGetGeometryN (geos, it); itemType = GEOSGeomTypeId (geos_item); switch (itemType) { case GEOS_POINT: cs = GEOSGeom_getCoordSeq (geos_item); GEOSCoordSeq_getDimensions (cs, &dims); if (dims == 3) { GEOSCoordSeq_getX (cs, 0, &x); GEOSCoordSeq_getY (cs, 0, &y); GEOSCoordSeq_getZ (cs, 0, &z); } else { GEOSCoordSeq_getX (cs, 0, &x); GEOSCoordSeq_getY (cs, 0, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) gaiaAddPointToGeomCollXYZ (gaia, x, y, z); else if (dimension_model == GAIA_XY_M) gaiaAddPointToGeomCollXYM (gaia, x, y, 0.0); else if (dimension_model == GAIA_XY_Z_M) gaiaAddPointToGeomCollXYZM (gaia, x, y, z, 0.0); else gaiaAddPointToGeomColl (gaia, x, y); break; case GEOS_LINESTRING: cs = GEOSGeom_getCoordSeq (geos_item); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); ln = gaiaAddLinestringToGeomColl (gaia, points); for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (ln->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (ln->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (ln->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (ln->Coords, iv, x, y); } } break; case GEOS_MULTILINESTRING: nSubItems = GEOSGetNumGeometries (geos_item); for (sub_it = 0; sub_it < nSubItems; sub_it++) { /* looping on elementaty geometries */ geos_sub_item = GEOSGetGeometryN (geos_item, sub_it); cs = GEOSGeom_getCoordSeq (geos_sub_item); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); ln = gaiaAddLinestringToGeomColl (gaia, points); for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (ln->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (ln->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (ln->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (ln->Coords, iv, x, y); } } } break; case GEOS_POLYGON: /* exterior ring */ holes = GEOSGetNumInteriorRings (geos_item); geos_ring = GEOSGetExteriorRing (geos_item); cs = GEOSGeom_getCoordSeq (geos_ring); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); pg = gaiaAddPolygonToGeomColl (gaia, points, holes); rng = pg->Exterior; for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (rng->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (rng->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (rng->Coords, iv, x, y); } } for (ib = 0; ib < holes; ib++) { /* interior rings */ geos_ring = GEOSGetInteriorRingN (geos_item, ib); cs = GEOSGeom_getCoordSeq (geos_ring); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); rng = gaiaAddInteriorRing (pg, ib, points); for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (rng->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (rng->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (rng->Coords, iv, x, y); } } } break; }; } break; }; return gaia; }