[GRASS-SVN] r51378 - grass/trunk/lib/vector/Vlib
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Apr 11 10:34:58 EDT 2012
Author: martinl
Date: 2012-04-11 07:34:58 -0700 (Wed, 11 Apr 2012)
New Revision: 51378
Modified:
grass/trunk/lib/vector/Vlib/build_pg.c
grass/trunk/lib/vector/Vlib/close_pg.c
grass/trunk/lib/vector/Vlib/open_pg.c
grass/trunk/lib/vector/Vlib/read_pg.c
grass/trunk/lib/vector/Vlib/rewind_pg.c
grass/trunk/lib/vector/Vlib/write_pg.c
Log:
vlib(pg): follow C indentation rules
no tabs (tabs -> spaces)
Modified: grass/trunk/lib/vector/Vlib/build_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build_pg.c 2012-04-11 10:42:29 UTC (rev 51377)
+++ grass/trunk/lib/vector/Vlib/build_pg.c 2012-04-11 14:34:58 UTC (rev 51378)
@@ -6,18 +6,18 @@
Higher level functions for reading/writing/manipulating vectors.
\todo Implement build_topo()
-
+
Line offset is
- - centroids : FID
- - other types : index of the first record (which is FID) in offset array.
-
+ - centroids : FID
+ - other types : index of the first record (which is FID) in offset array.
+
(C) 2012 by the GRASS Development Team
This program is free software under the GNU General Public License
(>=v2). Read the file COPYING that comes with GRASS for details.
\author Martin Landa <landa.martin gmail.com>
-*/
+ */
#include <grass/vector.h>
#include <grass/glocale.h>
@@ -32,12 +32,12 @@
\brief Build topology for PostGIS layer
Build levels:
- - GV_BUILD_NONE
- - GV_BUILD_BASE
- - GV_BUILD_ATTACH_ISLES
- - GV_BUILD_CENTROIDS
- - GV_BUILD_ALL
-
+ - GV_BUILD_NONE
+ - GV_BUILD_BASE
+ - GV_BUILD_ATTACH_ISLES
+ - GV_BUILD_CENTROIDS
+ - GV_BUILD_ALL
+
\param Map pointer to Map_info structure
\param build build level
@@ -50,19 +50,19 @@
struct Plus_head *plus;
struct Format_info_pg *pg_info;
- plus = &(Map->plus);
- pg_info = &(Map->fInfo.pg);
-
+ plus = &(Map->plus);
+ pg_info = &(Map->fInfo.pg);
+
G_debug(1, "Vect_build_pg(): db='%s' table='%s', build=%d",
pg_info->db_name, pg_info->table_name, build);
-
+
if (build == plus->built)
return 1; /* do nothing */
-
+
/* TODO move this init to better place (Vect_open_ ?), because in
theory build may be reused on level2 */
if (build >= plus->built && build > GV_BUILD_BASE) {
- G_free((void *) pg_info->offset.array);
+ G_free((void *)pg_info->offset.array);
G_zero(&(pg_info->offset), sizeof(struct Format_info_offset));
}
@@ -80,17 +80,16 @@
}
/* commit transaction block (update mode only) */
- if (pg_info->inTransaction &&
- execute(pg_info->conn, "COMMIT") == -1)
+ if (pg_info->inTransaction && execute(pg_info->conn, "COMMIT") == -1)
return -1;
-
+
pg_info->inTransaction = FALSE;
-
+
if (build > GV_BUILD_NONE)
G_message(_("Using external data format '%s' (feature type '%s')"),
Vect_get_finfo_format_info(Map),
Vect_get_finfo_geometry_type(Map));
-
+
return Vect__build_sfa(Map, build);
#else
G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
Modified: grass/trunk/lib/vector/Vlib/close_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/close_pg.c 2012-04-11 10:42:29 UTC (rev 51377)
+++ grass/trunk/lib/vector/Vlib/close_pg.c 2012-04-11 14:34:58 UTC (rev 51378)
@@ -11,7 +11,7 @@
(>=v2). Read the file COPYING that comes with GRASS for details.
\author Martin Landa <landa.martin gmail.com>
-*/
+ */
#include <stdlib.h>
#include <grass/vector.h>
@@ -23,57 +23,57 @@
#endif
/*!
- \brief Close vector map (PostGIS layer) on level 1
+ \brief Close vector map (PostGIS layer) on level 1
- \param Map pointer to Map_info structure
+ \param Map pointer to Map_info structure
- \return 0 on success
- \return non-zero on error
-*/
+ \return 0 on success
+ \return non-zero on error
+ */
int V1_close_pg(struct Map_info *Map)
{
#ifdef HAVE_POSTGRES
int i;
struct Format_info_pg *pg_info;
-
+
G_debug(3, "V2_close_pg() name = %s mapset = %s", Map->name, Map->mapset);
-
+
if (!VECT_OPEN(Map))
- return -1;
-
+ return -1;
+
pg_info = &(Map->fInfo.pg);
if (Map->mode == GV_MODE_WRITE || Map->mode == GV_MODE_RW)
- Vect__write_head(Map);
-
+ Vect__write_head(Map);
+
/* close connection */
if (pg_info->res) {
- char stmt[DB_SQL_MAX];
-
- PQclear(pg_info->res);
- pg_info->res = NULL;
-
- sprintf(stmt, "CLOSE %s_%s%p",
- pg_info->schema_name, pg_info->table_name, pg_info->conn);
- if (execute(pg_info->conn, stmt) == -1) {
- G_warning(_("Unable to close cursor"));
- return -1;
- }
- execute(pg_info->conn, "COMMIT");
+ char stmt[DB_SQL_MAX];
+
+ PQclear(pg_info->res);
+ pg_info->res = NULL;
+
+ sprintf(stmt, "CLOSE %s_%s%p",
+ pg_info->schema_name, pg_info->table_name, pg_info->conn);
+ if (execute(pg_info->conn, stmt) == -1) {
+ G_warning(_("Unable to close cursor"));
+ return -1;
+ }
+ execute(pg_info->conn, "COMMIT");
}
-
+
PQfinish(pg_info->conn);
-
+
/* close DB connection (for atgtributes) */
if (pg_info->dbdriver) {
- db_close_database_shutdown_driver(pg_info->dbdriver);
+ db_close_database_shutdown_driver(pg_info->dbdriver);
}
-
+
/* free allocated space */
for (i = 0; i < pg_info->cache.lines_alloc; i++) {
- Vect_destroy_line_struct(pg_info->cache.lines[i]);
+ Vect_destroy_line_struct(pg_info->cache.lines[i]);
}
if (pg_info->cache.lines)
- G_free(pg_info->cache.lines);
+ G_free(pg_info->cache.lines);
G_free(pg_info->db_name);
G_free(pg_info->schema_name);
@@ -88,28 +88,28 @@
}
/*!
- \brief Close vector map (PostGIS layer) on topological level (write out fidx file)
+ \brief Close vector map (PostGIS layer) on topological level (write out fidx file)
- \param Map pointer to Map_info structure
-
- \return 0 on success
- \return non-zero on error
-*/
+ \param Map pointer to Map_info structure
+
+ \return 0 on success
+ \return non-zero on error
+ */
int V2_close_pg(struct Map_info *Map)
{
#ifdef HAVE_POSTGRES
G_debug(3, "V2_close_pg() name = %s mapset = %s", Map->name, Map->mapset);
if (!VECT_OPEN(Map))
- return -1;
+ return -1;
/* write fidx for maps in the current mapset */
if (Vect_save_fidx(Map, &(Map->fInfo.pg.offset)) != 1)
- G_warning(_("Unable to save feature index file for vector map <%s>"),
- Map->name);
-
+ G_warning(_("Unable to save feature index file for vector map <%s>"),
+ Map->name);
+
G_free(Map->fInfo.pg.offset.array);
-
+
return 0;
#else
G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
Modified: grass/trunk/lib/vector/Vlib/open_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/open_pg.c 2012-04-11 10:42:29 UTC (rev 51377)
+++ grass/trunk/lib/vector/Vlib/open_pg.c 2012-04-11 14:34:58 UTC (rev 51378)
@@ -26,100 +26,100 @@
static char *get_key_column(struct Format_info_pg *);
static SF_FeatureType ftype_from_string(const char *);
static int drop_table(struct Format_info_pg *);
-static int check_schema(const struct Format_info_pg*);
+static int check_schema(const struct Format_info_pg *);
static int create_table(struct Format_info_pg *, const struct field_info *);
#endif
/*!
\brief Open existing PostGIS feature table (level 1 - without topology)
-
+
\todo Check database instead of geometry_columns
-
+
\param[in,out] Map pointer to Map_info structure
\param update TRUE for write mode, otherwise read-only
-
+
\return 0 success
\return -1 error
-*/
+ */
int V1_open_old_pg(struct Map_info *Map, int update)
{
#ifdef HAVE_POSTGRES
int found;
-
+
char stmt[DB_SQL_MAX];
-
+
PGresult *res;
-
+
struct Format_info_pg *pg_info;
-
+
pg_info = &(Map->fInfo.pg);
if (!pg_info->conninfo) {
- G_warning(_("Connection string not defined"));
- return -1;
+ G_warning(_("Connection string not defined"));
+ return -1;
}
-
+
if (!pg_info->table_name) {
- G_warning(_("PostGIS feature table not defined"));
- return -1;
+ G_warning(_("PostGIS feature table not defined"));
+ return -1;
}
- G_debug(1, "V1_open_old_pg(): conninfo='%s' table='%s'", pg_info->conninfo,
- pg_info->table_name);
+ G_debug(1, "V1_open_old_pg(): conninfo='%s' table='%s'",
+ pg_info->conninfo, pg_info->table_name);
/* connect database */
pg_info->conn = PQconnectdb(pg_info->conninfo);
G_debug(2, " PQconnectdb(): %s", pg_info->conninfo);
if (PQstatus(pg_info->conn) == CONNECTION_BAD)
- G_fatal_error("%s\n%s", _("Connection ton PostgreSQL database failed."),
- PQerrorMessage(pg_info->conn));
+ G_fatal_error("%s\n%s",
+ _("Connection ton PostgreSQL database failed."),
+ PQerrorMessage(pg_info->conn));
/* get DB name */
pg_info->db_name = G_store(PQdb(pg_info->conn));
if (!pg_info->db_name) {
- G_warning(_("Unable to get database name"));
- return -1;
+ G_warning(_("Unable to get database name"));
+ return -1;
}
-
+
/* if schema not defined, use 'public' */
if (!pg_info->schema_name) {
- pg_info->schema_name = G_store("public");
+ pg_info->schema_name = G_store("public");
}
-
+
/* get fid and geometry column */
sprintf(stmt, "SELECT f_geometry_column, coord_dimension, srid, type "
- "FROM geometry_columns WHERE f_table_schema = '%s' AND "
- "f_table_name = '%s'",
- pg_info->schema_name, pg_info->table_name);
+ "FROM geometry_columns WHERE f_table_schema = '%s' AND "
+ "f_table_name = '%s'", pg_info->schema_name, pg_info->table_name);
G_debug(2, "SQL: %s", stmt);
-
+
res = PQexec(pg_info->conn, stmt);
if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
- G_fatal_error("%s\n%s", _("No feature tables found in database."),
- PQresultErrorMessage(res));
-
+ G_fatal_error("%s\n%s", _("No feature tables found in database."),
+ PQresultErrorMessage(res));
+
found = PQntuples(res) > 0 ? TRUE : FALSE;
if (found) {
- /* geometry column */
- pg_info->geom_column = G_store(PQgetvalue(res, 0, 0));
- G_debug(3, "\t-> table = %s column = %s", pg_info->table_name,
- pg_info->geom_column);
- /* fid column */
- pg_info->fid_column = get_key_column(pg_info);
- /* coordinates dimension */
- pg_info->coor_dim = atoi(PQgetvalue(res, 0, 1));
- /* SRS ID */
- pg_info->srid = atoi(PQgetvalue(res, 0, 2));
- /* feature type */
- pg_info->feature_type = ftype_from_string(PQgetvalue(res, 0, 3));
+ /* geometry column */
+ pg_info->geom_column = G_store(PQgetvalue(res, 0, 0));
+ G_debug(3, "\t-> table = %s column = %s", pg_info->table_name,
+ pg_info->geom_column);
+ /* fid column */
+ pg_info->fid_column = get_key_column(pg_info);
+ /* coordinates dimension */
+ pg_info->coor_dim = atoi(PQgetvalue(res, 0, 1));
+ /* SRS ID */
+ pg_info->srid = atoi(PQgetvalue(res, 0, 2));
+ /* feature type */
+ pg_info->feature_type = ftype_from_string(PQgetvalue(res, 0, 3));
}
PQclear(res);
-
+
/* no feature in cache */
pg_info->cache.fid = -1;
if (!found) {
- G_warning(_("Feature table <%s> not found in 'geometry_columns'"),
- pg_info->table_name);
+ G_warning(_("Feature table <%s> not found in 'geometry_columns'"),
+ pg_info->table_name);
}
return 0;
@@ -133,23 +133,23 @@
\brief Open existing PostGIS layer (level 2 - feature index)
\param[in,out] Map pointer to Map_info structure
-
+
\return 0 success
\return -1 error
-*/
+ */
int V2_open_old_pg(struct Map_info *Map)
{
#ifdef HAVE_POSTGRES
G_debug(3, "V2_open_old_pg(): name = %s mapset = %s", Map->name,
- Map->mapset);
+ Map->mapset);
if (Vect_open_fidx(Map, &(Map->fInfo.pg.offset)) != 0) {
- G_warning(_("Unable to open feature index file for vector map <%s>"),
- Vect_get_full_name(Map));
- G_zero(&(Map->fInfo.pg.offset), sizeof(struct Format_info_offset));
+ G_warning(_("Unable to open feature index file for vector map <%s>"),
+ Vect_get_full_name(Map));
+ G_zero(&(Map->fInfo.pg.offset), sizeof(struct Format_info_offset));
}
-
+
return 0;
#else
G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
@@ -162,104 +162,105 @@
(level 1)
\todo To implement
-
+
\param[out] Map pointer to Map_info structure
\param name name of PostGIS feature table to create
\param with_z WITH_Z for 3D vector data otherwise WITHOUT_Z
\return 0 success
\return -1 error
-*/
+ */
int V1_open_new_pg(struct Map_info *Map, const char *name, int with_z)
{
#ifdef HAVE_POSTGRES
char stmt[DB_SQL_MAX];
-
+
struct Format_info_pg *pg_info;
-
+
PGresult *res;
-
+
pg_info = &(Map->fInfo.pg);
if (!pg_info->conninfo) {
- G_warning(_("Connection string not defined"));
- return -1;
+ G_warning(_("Connection string not defined"));
+ return -1;
}
-
+
if (!pg_info->table_name) {
- G_warning(_("PostGIS feature table not defined"));
- return -1;
+ G_warning(_("PostGIS feature table not defined"));
+ return -1;
}
- G_debug(1, "V1_open_new_pg(): conninfo='%s' table='%s'", pg_info->conninfo,
- pg_info->table_name);
+ G_debug(1, "V1_open_new_pg(): conninfo='%s' table='%s'",
+ pg_info->conninfo, pg_info->table_name);
/* connect database */
pg_info->conn = PQconnectdb(pg_info->conninfo);
G_debug(2, " PQconnectdb(): %s", pg_info->conninfo);
if (PQstatus(pg_info->conn) == CONNECTION_BAD)
- G_fatal_error("%s\n%s", _("Connection ton PostgreSQL database failed."),
- PQerrorMessage(pg_info->conn));
+ G_fatal_error("%s\n%s",
+ _("Connection ton PostgreSQL database failed."),
+ PQerrorMessage(pg_info->conn));
/* get DB name */
pg_info->db_name = G_store(PQdb(pg_info->conn));
if (!pg_info->db_name) {
- G_warning(_("Unable to get database name"));
- return -1;
+ G_warning(_("Unable to get database name"));
+ return -1;
}
-
+
/* if schema not defined, use 'public' */
if (!pg_info->schema_name) {
- pg_info->schema_name = G_store("public");
+ pg_info->schema_name = G_store("public");
}
/* if fid_column not defined, use 'ogc_fid' */
if (!pg_info->fid_column) {
- pg_info->fid_column = G_store("ogc_fid");
+ pg_info->fid_column = G_store("ogc_fid");
}
/* if geom_column not defined, use 'wkb_geometry' */
if (!pg_info->geom_column) {
- pg_info->geom_column = G_store("wkb_geometry");
+ pg_info->geom_column = G_store("wkb_geometry");
}
-
+
/* check if feature table already exists */
sprintf(stmt, "SELECT * FROM pg_tables "
- "WHERE schemaname = '%s' AND tablename = '%s'",
- pg_info->schema_name, pg_info->table_name);
+ "WHERE schemaname = '%s' AND tablename = '%s'",
+ pg_info->schema_name, pg_info->table_name);
G_debug(2, "SQL: %s", stmt);
-
+
res = PQexec(pg_info->conn, stmt);
if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
- G_fatal_error("%s\n%s", _("No feature tables found in database."),
- PQresultErrorMessage(res));
+ G_fatal_error("%s\n%s", _("No feature tables found in database."),
+ PQresultErrorMessage(res));
if (PQntuples(res) > 0) {
- /* table found */
- if (G_get_overwrite()) {
- G_warning(_("PostGIS layer <%s.%s> already exists and will be overwritten"),
- pg_info->schema_name, pg_info->table_name);
- if (drop_table(pg_info) == -1) {
- G_warning(_("Unable to delete PostGIS layer <%s>"),
- pg_info->table_name);
- return -1;
- }
- }
- else {
- G_fatal_error(_("PostGIS layer <%s.%s> already exists in database '%s'"),
- pg_info->schema_name, pg_info->table_name,
- pg_info->db_name);
- return -1;
- }
+ /* table found */
+ if (G_get_overwrite()) {
+ G_warning(_("PostGIS layer <%s.%s> already exists and will be overwritten"),
+ pg_info->schema_name, pg_info->table_name);
+ if (drop_table(pg_info) == -1) {
+ G_warning(_("Unable to delete PostGIS layer <%s>"),
+ pg_info->table_name);
+ return -1;
+ }
+ }
+ else {
+ G_fatal_error(_("PostGIS layer <%s.%s> already exists in database '%s'"),
+ pg_info->schema_name, pg_info->table_name,
+ pg_info->db_name);
+ return -1;
+ }
}
-
+
/* no feature in cache */
pg_info->cache.fid = -1;
/* unknown feature type */
pg_info->feature_type = SF_UNKNOWN;
-
+
PQclear(res);
-
+
return 0;
#else
G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
@@ -273,90 +274,90 @@
V1_open_new_pg() is required to be called before this function.
List of currently supported types:
- - GV_POINT (SF_POINT)
- - GV_LINE (SF_LINESTRING)
- - GV_BOUNDARY (SF_POLYGON)
+ - GV_POINT (SF_POINT)
+ - GV_LINE (SF_LINESTRING)
+ - GV_BOUNDARY (SF_POLYGON)
\param[in,out] Map pointer to Map_info structure
\param type feature type (GV_POINT, GV_LINE, ...)
\return 0 success
\return -1 error
-*/
+ */
int V2_open_new_pg(struct Map_info *Map, int type)
{
#ifdef HAVE_POSTGRES
int ndblinks;
-
+
struct Format_info_pg *pg_info;
struct field_info *Fi;
struct Key_Value *projinfo, *projunits;
-
+
Fi = NULL;
-
+
pg_info = &(Map->fInfo.pg);
if (!pg_info->conninfo) {
- G_warning(_("Connection string not defined"));
- return -1;
+ G_warning(_("Connection string not defined"));
+ return -1;
}
if (!pg_info->table_name) {
- G_warning(_("PostGIS feature table not defined"));
- return -1;
+ G_warning(_("PostGIS feature table not defined"));
+ return -1;
}
G_debug(1, "V2_open_new_pg(): conninfo='%s' table='%s' -> type = %d",
- pg_info->conninfo, pg_info->table_name, type);
-
+ pg_info->conninfo, pg_info->table_name, type);
+
/* get spatial reference */
- projinfo = G_get_projinfo();
+ projinfo = G_get_projinfo();
projunits = G_get_projunits();
- pg_info->srid = 0; /* TODO */
+ pg_info->srid = 0; /* TODO */
// Ogr_spatial_ref = GPJ_grass_to_osr(projinfo, projunits);
G_free_key_value(projinfo);
G_free_key_value(projunits);
/* determine geometry type */
- switch(type) {
+ switch (type) {
case GV_POINT:
- pg_info->feature_type = SF_POINT;
- break;
+ pg_info->feature_type = SF_POINT;
+ break;
case GV_LINE:
- pg_info->feature_type = SF_LINESTRING;
- break;
+ pg_info->feature_type = SF_LINESTRING;
+ break;
case GV_BOUNDARY:
- pg_info->feature_type = SF_POLYGON;
- break;
+ pg_info->feature_type = SF_POLYGON;
+ break;
default:
- G_warning(_("Unsupported geometry type (%d)"), type);
- return -1;
+ G_warning(_("Unsupported geometry type (%d)"), type);
+ return -1;
}
/* coordinate dimension */
pg_info->coor_dim = Vect_is_3d(Map) ? 3 : 2;
-
+
/* create new PostGIS table */
ndblinks = Vect_get_num_dblinks(Map);
if (ndblinks > 0) {
- Fi = Vect_get_dblink(Map, 0);
- if (Fi) {
- if (ndblinks > 1)
- G_warning(_("More layers defined, using driver <%s> and "
- "database <%s>"), Fi->driver, Fi->database);
- }
- else {
- G_warning(_("Database connection not defined. "
- "Unable to write attributes."));
- }
+ Fi = Vect_get_dblink(Map, 0);
+ if (Fi) {
+ if (ndblinks > 1)
+ G_warning(_("More layers defined, using driver <%s> and "
+ "database <%s>"), Fi->driver, Fi->database);
+ }
+ else {
+ G_warning(_("Database connection not defined. "
+ "Unable to write attributes."));
+ }
}
-
+
if (create_table(pg_info, Fi) == -1) {
- G_warning(_("Unable to create new PostGIS table"));
- return -1;
+ G_warning(_("Unable to create new PostGIS table"));
+ return -1;
}
- if (Fi)
- G_free(Fi);
-
+ if (Fi)
+ G_free(Fi);
+
return 0;
#else
G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
@@ -369,36 +370,36 @@
{
char *key_column;
char stmt[DB_SQL_MAX];
-
+
PGresult *res;
-
+
sprintf(stmt,
- "SELECT kcu.column_name "
- "FROM INFORMATION_SCHEMA.TABLES t "
- "LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc "
- "ON tc.table_catalog = t.table_catalog "
- "AND tc.table_schema = t.table_schema "
- "AND tc.table_name = t.table_name "
- "AND tc.constraint_type = 'PRIMARY KEY' "
- "LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu "
- "ON kcu.table_catalog = tc.table_catalog "
- "AND kcu.table_schema = tc.table_schema "
- "AND kcu.table_name = tc.table_name "
- "AND kcu.constraint_name = tc.constraint_name "
- "WHERE t.table_schema = '%s' AND t.table_name = '%s'",
- pg_info->schema_name, pg_info->table_name);
+ "SELECT kcu.column_name "
+ "FROM INFORMATION_SCHEMA.TABLES t "
+ "LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc "
+ "ON tc.table_catalog = t.table_catalog "
+ "AND tc.table_schema = t.table_schema "
+ "AND tc.table_name = t.table_name "
+ "AND tc.constraint_type = 'PRIMARY KEY' "
+ "LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu "
+ "ON kcu.table_catalog = tc.table_catalog "
+ "AND kcu.table_schema = tc.table_schema "
+ "AND kcu.table_name = tc.table_name "
+ "AND kcu.constraint_name = tc.constraint_name "
+ "WHERE t.table_schema = '%s' AND t.table_name = '%s'",
+ pg_info->schema_name, pg_info->table_name);
G_debug(2, "SQL: %s", stmt);
-
+
res = PQexec(pg_info->conn, stmt);
if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
- PQntuples(res) != 1 || strlen(PQgetvalue(res, 0, 0)) < 1) {
- G_warning(_("No key column detected."));
- if (res)
- PQclear(res);
- return NULL;
+ PQntuples(res) != 1 || strlen(PQgetvalue(res, 0, 0)) < 1) {
+ G_warning(_("No key column detected."));
+ if (res)
+ PQclear(res);
+ return NULL;
}
key_column = G_store(PQgetvalue(res, 0, 0));
-
+
PQclear(res);
return key_column;
@@ -409,24 +410,24 @@
SF_FeatureType sf_type;
if (G_strcasecmp(type, "POINT") == 0)
- return SF_POINT;
+ return SF_POINT;
else if (G_strcasecmp(type, "LINESTRING") == 0)
- return SF_LINESTRING;
+ return SF_LINESTRING;
else if (G_strcasecmp(type, "POLYGON") == 0)
- return SF_POLYGON;
+ return SF_POLYGON;
else if (G_strcasecmp(type, "MULTIPOINT") == 0)
- return SF_MULTIPOINT;
+ return SF_MULTIPOINT;
else if (G_strcasecmp(type, "MULTILINESTRING") == 0)
- return SF_MULTILINESTRING;
+ return SF_MULTILINESTRING;
else if (G_strcasecmp(type, "MULTIPOLYGON") == 0)
- return SF_MULTIPOLYGON;
+ return SF_MULTIPOLYGON;
else if (G_strcasecmp(type, "GEOMETRYCOLLECTION") == 0)
- return SF_GEOMETRYCOLLECTION;
-
+ return SF_GEOMETRYCOLLECTION;
+
return SF_UNKNOWN;
-
+
G_debug(3, "ftype_from_string(): type='%s' -> %d", type, sf_type);
-
+
return sf_type;
}
@@ -435,12 +436,12 @@
char stmt[DB_SQL_MAX];
sprintf(stmt, "DROP TABLE \"%s\".\"%s\"",
- pg_info->schema_name, pg_info->table_name);
+ pg_info->schema_name, pg_info->table_name);
G_debug(2, "SQL: %s", stmt);
-
+
if (execute(pg_info->conn, stmt) == -1) {
- return -1;
- }
+ return -1;
+ }
return 0;
}
@@ -448,38 +449,39 @@
{
int i, found, nschema;
char stmt[DB_SQL_MAX];
-
+
PGresult *result;
-
+
/* add geometry column */
sprintf(stmt, "SELECT nspname FROM pg_namespace");
G_debug(2, "SQL: %s", stmt);
result = PQexec(pg_info->conn, stmt);
-
+
if (!result || PQresultStatus(result) != PGRES_TUPLES_OK) {
- PQclear(result);
- execute(pg_info->conn, "ROLLBACK");
- return -1;
+ PQclear(result);
+ execute(pg_info->conn, "ROLLBACK");
+ return -1;
}
-
+
found = FALSE;
nschema = PQntuples(result);
for (i = 0; i < nschema && !found; i++) {
- if (strcmp(pg_info->schema_name, PQgetvalue(result, i, 0)) == 0)
- found = TRUE;
+ if (strcmp(pg_info->schema_name, PQgetvalue(result, i, 0)) == 0)
+ found = TRUE;
}
-
+
PQclear(result);
-
+
if (!found) {
- sprintf(stmt, "CREATE SCHEMA %s", pg_info->schema_name);
- if (execute(pg_info->conn, stmt) == -1) {
- execute(pg_info->conn, "ROLLBACK");
- return -1;
- }
- G_warning(_("Schema <%s> doesn't exist, created"), pg_info->schema_name);
+ sprintf(stmt, "CREATE SCHEMA %s", pg_info->schema_name);
+ if (execute(pg_info->conn, stmt) == -1) {
+ execute(pg_info->conn, "ROLLBACK");
+ return -1;
+ }
+ G_warning(_("Schema <%s> doesn't exist, created"),
+ pg_info->schema_name);
}
-
+
return 0;
}
@@ -493,194 +495,195 @@
/* by default create spatial index & add primary key */
spatial_index = primary_key = TRUE;
if (G_find_file2("", "PG", G_mapset())) {
- FILE *fp;
- const char *p;
-
- struct Key_Value *key_val;
-
- fp = G_fopen_old("", "PG", G_mapset());
- if (!fp) {
- G_fatal_error(_("Unable to open PG file"));
- }
- key_val = G_fread_key_value(fp);
- fclose(fp);
-
- /* disable spatial index ? */
- p = G_find_key_value("spatial_index", key_val);
- if (p && G_strcasecmp(p, "off") == 0)
- spatial_index = FALSE;
- /* disable primary key ? */
- p = G_find_key_value("primary_key", key_val);
- if (p && G_strcasecmp(p, "off") == 0)
- primary_key = FALSE;
+ FILE *fp;
+ const char *p;
+
+ struct Key_Value *key_val;
+
+ fp = G_fopen_old("", "PG", G_mapset());
+ if (!fp) {
+ G_fatal_error(_("Unable to open PG file"));
+ }
+ key_val = G_fread_key_value(fp);
+ fclose(fp);
+
+ /* disable spatial index ? */
+ p = G_find_key_value("spatial_index", key_val);
+ if (p && G_strcasecmp(p, "off") == 0)
+ spatial_index = FALSE;
+ /* disable primary key ? */
+ p = G_find_key_value("primary_key", key_val);
+ if (p && G_strcasecmp(p, "off") == 0)
+ primary_key = FALSE;
}
/* create schema if not exists */
if (G_strcasecmp(pg_info->schema_name, "public") != 0) {
- if (check_schema(pg_info) != 0)
- return -1;
+ if (check_schema(pg_info) != 0)
+ return -1;
}
-
+
/* prepare CREATE TABLE statement */
sprintf(stmt, "CREATE TABLE \"%s\".\"%s\" (%s SERIAL",
- pg_info->schema_name, pg_info->table_name,
- pg_info->fid_column);
-
+ pg_info->schema_name, pg_info->table_name, pg_info->fid_column);
+
if (Fi) {
- /* append attributes */
- int col, ncols, sqltype, length, ctype;
- char stmt_col[DB_SQL_MAX];
- const char *colname;
-
- dbString dbstmt;
- dbHandle handle;
- dbDriver *driver;
- dbCursor cursor;
- dbTable *table;
- dbColumn *column;
-
- db_init_string(&dbstmt);
- db_init_handle(&handle);
-
- pg_info->dbdriver = driver = db_start_driver(Fi->driver);
- if (!driver) {
- G_warning(_("Unable to start driver <%s>"), Fi->driver);
- return -1;
- }
- db_set_handle(&handle, Fi->database, NULL);
- if (db_open_database(driver, &handle) != DB_OK) {
- G_warning(_("Unable to open database <%s> by driver <%s>"),
- Fi->database, Fi->driver);
- db_close_database_shutdown_driver(driver);
- pg_info->dbdriver = NULL;
- return -1;
- }
+ /* append attributes */
+ int col, ncols, sqltype, length, ctype;
+ char stmt_col[DB_SQL_MAX];
+ const char *colname;
- /* describe table */
- db_set_string(&dbstmt, "select * from ");
- db_append_string(&dbstmt, Fi->table);
- db_append_string(&dbstmt, " where 0 = 1");
-
- if (db_open_select_cursor(driver, &dbstmt,
- &cursor, DB_SEQUENTIAL) != DB_OK) {
- G_warning(_("Unable to open select cursor: '%s'"),
- db_get_string(&dbstmt));
- db_close_database_shutdown_driver(driver);
- pg_info->dbdriver = NULL;
- return -1;
- }
-
- table = db_get_cursor_table(&cursor);
- ncols = db_get_table_number_of_columns(table);
-
- G_debug(3, "copying attributes: driver = %s database = %s table = %s cols = %d",
- Fi->driver, Fi->database, Fi->table, ncols);
-
- for (col = 0; col < ncols; col++) {
- column = db_get_table_column(table, col);
- colname = db_get_column_name(column);
- sqltype = db_get_column_sqltype(column);
- ctype = db_sqltype_to_Ctype(sqltype);
- length = db_get_column_length(column);
-
- G_debug(3, "\tcolumn = %d name = %s type = %d length = %d",
- col, colname, sqltype, length);
-
- if (strcmp(pg_info->fid_column, colname) == 0) {
- /* skip fid column if exists */
- G_debug(3, "\t%s skipped", pg_info->fid_column);
- continue;
- }
-
- /* append column */
- sprintf(stmt_col, ",%s %s", colname, db_sqltype_name(sqltype));
- strcat(stmt, stmt_col);
- if (ctype == DB_C_TYPE_STRING) {
- /* length only for string columns */
- sprintf(stmt_col, "(%d)", length);
- strcat(stmt, stmt_col);
- }
- }
+ dbString dbstmt;
+ dbHandle handle;
+ dbDriver *driver;
+ dbCursor cursor;
+ dbTable *table;
+ dbColumn *column;
- db_free_string(&dbstmt);
+ db_init_string(&dbstmt);
+ db_init_handle(&handle);
+
+ pg_info->dbdriver = driver = db_start_driver(Fi->driver);
+ if (!driver) {
+ G_warning(_("Unable to start driver <%s>"), Fi->driver);
+ return -1;
+ }
+ db_set_handle(&handle, Fi->database, NULL);
+ if (db_open_database(driver, &handle) != DB_OK) {
+ G_warning(_("Unable to open database <%s> by driver <%s>"),
+ Fi->database, Fi->driver);
+ db_close_database_shutdown_driver(driver);
+ pg_info->dbdriver = NULL;
+ return -1;
+ }
+
+ /* describe table */
+ db_set_string(&dbstmt, "select * from ");
+ db_append_string(&dbstmt, Fi->table);
+ db_append_string(&dbstmt, " where 0 = 1");
+
+ if (db_open_select_cursor(driver, &dbstmt,
+ &cursor, DB_SEQUENTIAL) != DB_OK) {
+ G_warning(_("Unable to open select cursor: '%s'"),
+ db_get_string(&dbstmt));
+ db_close_database_shutdown_driver(driver);
+ pg_info->dbdriver = NULL;
+ return -1;
+ }
+
+ table = db_get_cursor_table(&cursor);
+ ncols = db_get_table_number_of_columns(table);
+
+ G_debug(3,
+ "copying attributes: driver = %s database = %s table = %s cols = %d",
+ Fi->driver, Fi->database, Fi->table, ncols);
+
+ for (col = 0; col < ncols; col++) {
+ column = db_get_table_column(table, col);
+ colname = db_get_column_name(column);
+ sqltype = db_get_column_sqltype(column);
+ ctype = db_sqltype_to_Ctype(sqltype);
+ length = db_get_column_length(column);
+
+ G_debug(3, "\tcolumn = %d name = %s type = %d length = %d",
+ col, colname, sqltype, length);
+
+ if (strcmp(pg_info->fid_column, colname) == 0) {
+ /* skip fid column if exists */
+ G_debug(3, "\t%s skipped", pg_info->fid_column);
+ continue;
+ }
+
+ /* append column */
+ sprintf(stmt_col, ",%s %s", colname, db_sqltype_name(sqltype));
+ strcat(stmt, stmt_col);
+ if (ctype == DB_C_TYPE_STRING) {
+ /* length only for string columns */
+ sprintf(stmt_col, "(%d)", length);
+ strcat(stmt, stmt_col);
+ }
+ }
+
+ db_free_string(&dbstmt);
}
- strcat(stmt, ")"); /* close CREATE TABLE statement */
-
+ strcat(stmt, ")"); /* close CREATE TABLE statement */
+
/* begin transaction (create table) */
if (execute(pg_info->conn, "BEGIN") == -1) {
- return -1;
+ return -1;
}
-
+
/* create table */
G_debug(2, "SQL: %s", stmt);
if (execute(pg_info->conn, stmt) == -1) {
- execute(pg_info->conn, "ROLLBACK");
- return -1;
+ execute(pg_info->conn, "ROLLBACK");
+ return -1;
}
-
+
/* add primary key ? */
if (primary_key) {
- sprintf(stmt, "ALTER TABLE \"%s\".\"%s\" ADD PRIMARY KEY (%s)",
- pg_info->schema_name, pg_info->table_name,
- pg_info->fid_column);
- G_debug(2, "SQL: %s", stmt);
- if (execute(pg_info->conn, stmt) == -1) {
- execute(pg_info->conn, "ROLLBACK");
- return -1;
- }
+ sprintf(stmt, "ALTER TABLE \"%s\".\"%s\" ADD PRIMARY KEY (%s)",
+ pg_info->schema_name, pg_info->table_name,
+ pg_info->fid_column);
+ G_debug(2, "SQL: %s", stmt);
+ if (execute(pg_info->conn, stmt) == -1) {
+ execute(pg_info->conn, "ROLLBACK");
+ return -1;
+ }
}
-
+
/* determine geometry type (string) */
- switch(pg_info->feature_type) {
+ switch (pg_info->feature_type) {
case (SF_POINT):
- geom_type = "POINT";
- break;
+ geom_type = "POINT";
+ break;
case (SF_LINESTRING):
- geom_type = "LINESTRING";
- break;
+ geom_type = "LINESTRING";
+ break;
case (SF_POLYGON):
- geom_type = "POLYGON";
- break;
+ geom_type = "POLYGON";
+ break;
default:
- G_warning(_("Unsupported feature type %d"), pg_info->feature_type);
- execute(pg_info->conn, "ROLLBACK");
- return -1;
+ G_warning(_("Unsupported feature type %d"), pg_info->feature_type);
+ execute(pg_info->conn, "ROLLBACK");
+ return -1;
}
/* add geometry column */
sprintf(stmt, "SELECT AddGeometryColumn('%s', '%s', "
- "'%s', %d, '%s', %d)",
- pg_info->schema_name, pg_info->table_name,
- pg_info->geom_column, pg_info->srid,
- geom_type, pg_info->coor_dim);
+ "'%s', %d, '%s', %d)",
+ pg_info->schema_name, pg_info->table_name,
+ pg_info->geom_column, pg_info->srid,
+ geom_type, pg_info->coor_dim);
G_debug(2, "SQL: %s", stmt);
result = PQexec(pg_info->conn, stmt);
-
+
if (!result || PQresultStatus(result) != PGRES_TUPLES_OK) {
- PQclear(result);
- execute(pg_info->conn, "ROLLBACK");
- return -1;
+ PQclear(result);
+ execute(pg_info->conn, "ROLLBACK");
+ return -1;
}
-
+
/* create index ? */
if (spatial_index) {
- sprintf(stmt, "CREATE INDEX %s_%s_idx ON \"%s\".\"%s\" USING GIST (%s)",
- pg_info->table_name, pg_info->geom_column,
- pg_info->schema_name, pg_info->table_name,
- pg_info->geom_column);
- G_debug(2, "SQL: %s", stmt);
-
- if (execute(pg_info->conn, stmt) == -1) {
- execute(pg_info->conn, "ROLLBACK");
- return -1;
- }
+ sprintf(stmt,
+ "CREATE INDEX %s_%s_idx ON \"%s\".\"%s\" USING GIST (%s)",
+ pg_info->table_name, pg_info->geom_column,
+ pg_info->schema_name, pg_info->table_name,
+ pg_info->geom_column);
+ G_debug(2, "SQL: %s", stmt);
+
+ if (execute(pg_info->conn, stmt) == -1) {
+ execute(pg_info->conn, "ROLLBACK");
+ return -1;
+ }
}
-
+
/* close transaction (create table) */
if (execute(pg_info->conn, "COMMIT") == -1) {
- return -1;
+ return -1;
}
-
+
return 0;
}
#endif
Modified: grass/trunk/lib/vector/Vlib/read_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/read_pg.c 2012-04-11 10:42:29 UTC (rev 51377)
+++ grass/trunk/lib/vector/Vlib/read_pg.c 2012-04-11 14:34:58 UTC (rev 51378)
@@ -1,21 +1,21 @@
/*!
- \file lib/vector/Vlib/read_pg.c
-
- \brief Vector library - reading features (PostGIS format)
-
- Higher level functions for reading/writing/manipulating vectors.
-
- \todo Currently only points, linestrings and polygons are supported,
- implement also other types
-
- (C) 2011-2012 by the GRASS Development Team
-
- This program is free software under the GNU General Public License
- (>=v2). Read the file COPYING that comes with GRASS for details.
-
- \author Martin Landa <landa.martin gmail.com>
-*/
+ \file lib/vector/Vlib/read_pg.c
+ \brief Vector library - reading features (PostGIS format)
+
+ Higher level functions for reading/writing/manipulating vectors.
+
+ \todo Currently only points, linestrings and polygons are supported,
+ implement also other types
+
+ (C) 2011-2012 by the GRASS Development Team
+
+ This program is free software under the GNU General Public License
+ (>=v2). Read the file COPYING that comes with GRASS for details.
+
+ \author Martin Landa <landa.martin gmail.com>
+ */
+
#include <stdlib.h>
#include <string.h>
#include <limits.h>
@@ -28,21 +28,21 @@
#include "pg_local_proto.h"
static unsigned char *wkb_data;
-static unsigned int wkb_data_length;
+static unsigned int wkb_data_length;
static int read_next_line_pg(struct Map_info *,
- struct line_pnts *, struct line_cats *, int);
+ struct line_pnts *, struct line_cats *, int);
SF_FeatureType get_feature(struct Format_info_pg *, int);
static unsigned char *hex_to_wkb(const char *, int *);
static int point_from_wkb(const unsigned char *, int, int, int,
- struct line_pnts *);
+ struct line_pnts *);
static int linestring_from_wkb(const unsigned char *, int, int, int,
- struct line_pnts *, int);
+ struct line_pnts *, int);
static int polygon_from_wkb(const unsigned char *, int, int, int,
- struct Format_info_cache *, int *);
+ struct Format_info_cache *, int *);
static int geometry_collection_from_wkb(const unsigned char *, int, int, int,
- struct Format_info_cache *,
- struct feat_parts *);
+ struct Format_info_cache *,
+ struct feat_parts *);
static int error_corrupted_data(const char *);
static int set_initial_query();
static void reallocate_cache(struct Format_info_cache *, int);
@@ -50,34 +50,33 @@
#endif
/*!
- \brief Read next feature from PostGIS layer. Skip
- empty features (level 1 without topology).
- t
- This function implements sequential access.
-
- The action of this routine can be modified by:
+ \brief Read next feature from PostGIS layer. Skip
+ empty features (level 1 without topology).
+ t
+ This function implements sequential access.
+
+ The action of this routine can be modified by:
- Vect_read_constraint_region()
- Vect_read_constraint_type()
- Vect_remove_constraints()
-
- \param Map pointer to Map_info structure
- \param[out] line_p container used to store line points within
- (pointer to line_pnts struct)
- \param[out] line_c container used to store line categories within
- (pointer line_cats struct)
-
- \return feature type
- \return -2 no more features (EOF)
- \return -1 out of memory
-*/
+
+ \param Map pointer to Map_info structure
+ \param[out] line_p container used to store line points within
+ (pointer to line_pnts struct)
+ \param[out] line_c container used to store line categories within
+ (pointer line_cats struct)
+
+ \return feature type
+ \return -2 no more features (EOF)
+ \return -1 out of memory
+ */
int V1_read_next_line_pg(struct Map_info *Map,
- struct line_pnts *line_p,
- struct line_cats *line_c)
+ struct line_pnts *line_p, struct line_cats *line_c)
{
#ifdef HAVE_POSTGRES
G_debug(3, "V1_read_next_line_pg()");
- /* constraints not ignored */
+ /* constraints not ignored */
return read_next_line_pg(Map, line_p, line_c, FALSE);
#else
G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
@@ -86,196 +85,196 @@
}
/*!
- \brief Read next feature from PostGIS layer on topological level.
+ \brief Read next feature from PostGIS layer on topological level.
- This function implements sequential access.
+ This function implements sequential access.
- \param Map pointer to Map_info structure
- \param[out] line_p container used to store line points within
- (pointer to line_pnts struct)
- \param[out] line_c container used to store line categories within
- (pointer to line_cats struct)
-
- \return feature type
- \return -2 no more features (EOF)
- \return -1 on failure
-*/
+ \param Map pointer to Map_info structure
+ \param[out] line_p container used to store line points within
+ (pointer to line_pnts struct)
+ \param[out] line_c container used to store line categories within
+ (pointer to line_cats struct)
+
+ \return feature type
+ \return -2 no more features (EOF)
+ \return -1 on failure
+ */
int V2_read_next_line_pg(struct Map_info *Map, struct line_pnts *line_p,
- struct line_cats *line_c)
+ struct line_cats *line_c)
{
#ifdef HAVE_POSTGRES
int line, ret;
struct P_line *Line;
struct bound_box lbox, mbox;
-
+
G_debug(3, "V2_read_next_line_pg()");
-
+
if (Map->constraint.region_flag)
- Vect_get_constraint_box(Map, &mbox);
-
+ Vect_get_constraint_box(Map, &mbox);
+
ret = -1;
- while(TRUE) {
- line = Map->next_line;
+ while (TRUE) {
+ line = Map->next_line;
- if (Map->next_line > Map->plus.n_lines)
- return -2;
+ if (Map->next_line > Map->plus.n_lines)
+ return -2;
- Line = Map->plus.Line[line];
- if (Line == NULL) { /* skip dead features */
- Map->next_line++;
- continue;
- }
+ Line = Map->plus.Line[line];
+ if (Line == NULL) { /* skip dead features */
+ Map->next_line++;
+ continue;
+ }
- if (Map->constraint.type_flag) {
- /* skip by type */
- if (!(Line->type & Map->constraint.type)) {
- Map->next_line++;
- continue;
- }
- }
+ if (Map->constraint.type_flag) {
+ /* skip by type */
+ if (!(Line->type & Map->constraint.type)) {
+ Map->next_line++;
+ continue;
+ }
+ }
- if (Line->type == GV_CENTROID) {
- G_debug(4, "Centroid");
-
- Map->next_line++;
-
- if (line_p != NULL) {
- int i, found;
- struct bound_box box;
- struct boxlist list;
- struct P_topo_c *topo = (struct P_topo_c *)Line->topo;
-
- /* get area bbox */
- Vect_get_area_box(Map, topo->area, &box);
- /* search in spatial index for centroid with area bbox */
- dig_init_boxlist(&list, TRUE);
- Vect_select_lines_by_box(Map, &box, Line->type, &list);
-
- found = -1;
- for (i = 0; i < list.n_values; i++) {
- if (list.id[i] == line) {
- found = i;
- break;
- }
- }
-
- if (found > -1) {
- Vect_reset_line(line_p);
- Vect_append_point(line_p, list.box[found].E, list.box[found].N, 0.0);
- }
- }
- if (line_c != NULL) {
- /* cat = FID and offset = FID for centroid */
- Vect_reset_cats(line_c);
- Vect_cat_set(line_c, 1, (int) Line->offset);
- }
+ if (Line->type == GV_CENTROID) {
+ G_debug(4, "Centroid");
- ret = GV_CENTROID;
- }
- else {
- /* ignore constraints, Map->next_line incremented */
- ret = read_next_line_pg(Map, line_p, line_c, TRUE);
- if (ret != Line->type)
- G_fatal_error(_("Unexpected feature type (%s) - should be (%d)"),
- ret, Line->type);
- }
+ Map->next_line++;
- if (Map->constraint.region_flag) {
- /* skip by region */
- Vect_line_box(line_p, &lbox);
- if (!Vect_box_overlap(&lbox, &mbox)) {
- continue;
- }
- }
-
- /* skip by field ignored */
-
- return ret;
+ if (line_p != NULL) {
+ int i, found;
+ struct bound_box box;
+ struct boxlist list;
+ struct P_topo_c *topo = (struct P_topo_c *)Line->topo;
+
+ /* get area bbox */
+ Vect_get_area_box(Map, topo->area, &box);
+ /* search in spatial index for centroid with area bbox */
+ dig_init_boxlist(&list, TRUE);
+ Vect_select_lines_by_box(Map, &box, Line->type, &list);
+
+ found = -1;
+ for (i = 0; i < list.n_values; i++) {
+ if (list.id[i] == line) {
+ found = i;
+ break;
+ }
+ }
+
+ if (found > -1) {
+ Vect_reset_line(line_p);
+ Vect_append_point(line_p, list.box[found].E,
+ list.box[found].N, 0.0);
+ }
+ }
+ if (line_c != NULL) {
+ /* cat = FID and offset = FID for centroid */
+ Vect_reset_cats(line_c);
+ Vect_cat_set(line_c, 1, (int)Line->offset);
+ }
+
+ ret = GV_CENTROID;
+ }
+ else {
+ /* ignore constraints, Map->next_line incremented */
+ ret = read_next_line_pg(Map, line_p, line_c, TRUE);
+ if (ret != Line->type)
+ G_fatal_error(_("Unexpected feature type (%s) - should be (%d)"),
+ ret, Line->type);
+ }
+
+ if (Map->constraint.region_flag) {
+ /* skip by region */
+ Vect_line_box(line_p, &lbox);
+ if (!Vect_box_overlap(&lbox, &mbox)) {
+ continue;
+ }
+ }
+
+ /* skip by field ignored */
+
+ return ret;
}
#else
G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
#endif
- return -1; /* not reached */
+ return -1; /* not reached */
}
/*!
- \brief Read feature from PostGIS layer at given offset (level 1 without topology)
-
- This function implements random access on level 1.
+ \brief Read feature from PostGIS layer at given offset (level 1 without topology)
- \param Map pointer to Map_info structure
- \param[out] line_p container used to store line points within
- (pointer line_pnts struct)
- \param[out] line_c container used to store line categories within
- (pointer line_cats struct)
- \param offset given offset
-
- \return line type
- \return 0 dead line
- \return -2 no more features
- \return -1 out of memory
-*/
+ This function implements random access on level 1.
+
+ \param Map pointer to Map_info structure
+ \param[out] line_p container used to store line points within
+ (pointer line_pnts struct)
+ \param[out] line_c container used to store line categories within
+ (pointer line_cats struct)
+ \param offset given offset
+
+ \return line type
+ \return 0 dead line
+ \return -2 no more features
+ \return -1 out of memory
+ */
int V1_read_line_pg(struct Map_info *Map,
- struct line_pnts *line_p, struct line_cats *line_c, off_t offset)
+ struct line_pnts *line_p, struct line_cats *line_c,
+ off_t offset)
{
#ifdef HAVE_POSTGRES
long fid;
- int ipart, type;
-
- struct Format_info_pg *pg_info;
-
+ int ipart, type;
+
+ struct Format_info_pg *pg_info;
+
pg_info = &(Map->fInfo.pg);
-
+
G_debug(3, "V1_read_line_pg(): offset = %lu offset_num = %lu",
- (long) offset, (long) pg_info->offset.array_num);
-
+ (long)offset, (long)pg_info->offset.array_num);
+
if (offset >= pg_info->offset.array_num)
- return -2; /* nothing to read */
-
+ return -2; /* nothing to read */
+
if (line_p != NULL)
- Vect_reset_line(line_p);
+ Vect_reset_line(line_p);
if (line_c != NULL)
- Vect_reset_cats(line_c);
+ Vect_reset_cats(line_c);
fid = pg_info->offset.array[offset];
G_debug(4, " fid = %ld", fid);
-
+
/* read feature to cache if necessary */
if (pg_info->cache.fid != fid) {
- int type;
-
- G_debug(3, "read (%s) feature (fid = %ld) to cache",
- pg_info->table_name, fid);
- get_feature(pg_info, fid);
-
- if (pg_info->cache.sf_type == SF_NONE) {
- G_warning(_("Feature %d without geometry skipped"), fid);
- return -1;
- }
-
- type = (int) pg_info->cache.sf_type;
- if (type < 0) /* -1 || - 2 */
- return type;
+ int type;
+
+ G_debug(3, "read (%s) feature (fid = %ld) to cache",
+ pg_info->table_name, fid);
+ get_feature(pg_info, fid);
+
+ if (pg_info->cache.sf_type == SF_NONE) {
+ G_warning(_("Feature %d without geometry skipped"), fid);
+ return -1;
+ }
+
+ type = (int)pg_info->cache.sf_type;
+ if (type < 0) /* -1 || - 2 */
+ return type;
}
-
+
/* get data from cache */
if (pg_info->cache.sf_type == SF_POINT ||
- pg_info->cache.sf_type == SF_LINESTRING)
- ipart = 0;
- else
- ipart = pg_info->offset.array[offset + 1];
- type = pg_info->cache.lines_types[ipart];
- G_debug(3, "read feature part: %d -> type = %d",
- ipart, type);
-
+ pg_info->cache.sf_type == SF_LINESTRING)
+ ipart = 0;
+ else
+ ipart = pg_info->offset.array[offset + 1];
+ type = pg_info->cache.lines_types[ipart];
+ G_debug(3, "read feature part: %d -> type = %d", ipart, type);
+
if (line_p)
- Vect_append_points(line_p,
- pg_info->cache.lines[ipart], GV_FORWARD);
-
+ Vect_append_points(line_p, pg_info->cache.lines[ipart], GV_FORWARD);
+
if (line_c)
- Vect_cat_set(line_c, 1, (int) fid);
-
+ Vect_cat_set(line_c, 1, (int)fid);
+
return type;
#else
G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
@@ -285,552 +284,561 @@
#ifdef HAVE_POSTGRES
/*!
- \brief Read next feature from PostGIS layer.
-
- \param Map pointer to Map_info structure
- \param[out] line_p container used to store line points within
- (pointer to line_pnts struct)
- \param[out] line_c container used to store line categories within
- (pointer line_cats struct)
- \param ignore_constraints TRUE to ignore constraints (type, region)
-
- \return feature type
- \return -2 no more features (EOF)
- \return -1 out of memory
-*/
+ \brief Read next feature from PostGIS layer.
+
+ \param Map pointer to Map_info structure
+ \param[out] line_p container used to store line points within
+ (pointer to line_pnts struct)
+ \param[out] line_c container used to store line categories within
+ (pointer line_cats struct)
+ \param ignore_constraints TRUE to ignore constraints (type, region)
+
+ \return feature type
+ \return -2 no more features (EOF)
+ \return -1 out of memory
+ */
int read_next_line_pg(struct Map_info *Map,
- struct line_pnts *line_p, struct line_cats *line_c,
- int ignore_constraints)
+ struct line_pnts *line_p, struct line_cats *line_c,
+ int ignore_constraints)
{
int line, itype;
SF_FeatureType sf_type;
-
- struct Format_info_pg *pg_info;
+
+ struct Format_info_pg *pg_info;
struct bound_box mbox, lbox;
struct line_pnts *iline;
pg_info = &(Map->fInfo.pg);
-
+
if (Map->constraint.region_flag && !ignore_constraints)
- Vect_get_constraint_box(Map, &mbox);
-
+ Vect_get_constraint_box(Map, &mbox);
+
while (TRUE) {
- line = Map->next_line++; /* level 2 only */
-
- /* reset data structures */
- if (line_p != NULL)
- Vect_reset_line(line_p);
- if (line_c != NULL)
- Vect_reset_cats(line_c);
+ line = Map->next_line++; /* level 2 only */
- /* read feature to cache if necessary */
- while (pg_info->cache.lines_next == pg_info->cache.lines_num) {
- /* cache feature -> line_p & line_c */
- sf_type = get_feature(pg_info, -1);
-
- if (sf_type == SF_NONE) {
- G_warning(_("Feature %d without geometry skipped"),
- line);
- return -1;
- }
+ /* reset data structures */
+ if (line_p != NULL)
+ Vect_reset_line(line_p);
+ if (line_c != NULL)
+ Vect_reset_cats(line_c);
- if ((int) sf_type < 0) /* -1 || - 2 */
- return (int) sf_type;
+ /* read feature to cache if necessary */
+ while (pg_info->cache.lines_next == pg_info->cache.lines_num) {
+ /* cache feature -> line_p & line_c */
+ sf_type = get_feature(pg_info, -1);
- if (sf_type == SF_UNKNOWN || sf_type == SF_NONE) {
- G_warning(_("Feature without geometry. Skipped."));
- pg_info->cache.lines_next = pg_info->cache.lines_num = 0;
- continue;
- }
-
- G_debug(4, "%d lines read to cache", pg_info->cache.lines_num);
- }
-
- /* get data from cache */
- itype = pg_info->cache.lines_types[pg_info->cache.lines_next];
- iline = pg_info->cache.lines[pg_info->cache.lines_next];
-
- G_debug(4, "read next cached line %d (type = %d)",
- pg_info->cache.lines_next, itype);
+ if (sf_type == SF_NONE) {
+ G_warning(_("Feature %d without geometry skipped"), line);
+ return -1;
+ }
- /* apply constraints */
- if (Map->constraint.type_flag && !ignore_constraints) {
- /* skip feature by type */
- if (!(itype & Map->constraint.type))
- continue;
- }
+ if ((int)sf_type < 0) /* -1 || - 2 */
+ return (int)sf_type;
- if (line_p && Map->constraint.region_flag &&
- !ignore_constraints) {
- /* skip feature by region */
- Vect_line_box(iline, &lbox);
-
- if (!Vect_box_overlap(&lbox, &mbox))
- continue;
- }
-
- /* skip feature by field ignored */
-
- if (line_p)
- Vect_append_points(line_p, iline, GV_FORWARD);
-
- if (line_c)
- Vect_cat_set(line_c, 1, (int) pg_info->cache.fid);
-
- pg_info->cache.lines_next++;
-
- return itype;
+ if (sf_type == SF_UNKNOWN || sf_type == SF_NONE) {
+ G_warning(_("Feature without geometry. Skipped."));
+ pg_info->cache.lines_next = pg_info->cache.lines_num = 0;
+ continue;
+ }
+
+ G_debug(4, "%d lines read to cache", pg_info->cache.lines_num);
+ }
+
+ /* get data from cache */
+ itype = pg_info->cache.lines_types[pg_info->cache.lines_next];
+ iline = pg_info->cache.lines[pg_info->cache.lines_next];
+
+ G_debug(4, "read next cached line %d (type = %d)",
+ pg_info->cache.lines_next, itype);
+
+ /* apply constraints */
+ if (Map->constraint.type_flag && !ignore_constraints) {
+ /* skip feature by type */
+ if (!(itype & Map->constraint.type))
+ continue;
+ }
+
+ if (line_p && Map->constraint.region_flag && !ignore_constraints) {
+ /* skip feature by region */
+ Vect_line_box(iline, &lbox);
+
+ if (!Vect_box_overlap(&lbox, &mbox))
+ continue;
+ }
+
+ /* skip feature by field ignored */
+
+ if (line_p)
+ Vect_append_points(line_p, iline, GV_FORWARD);
+
+ if (line_c)
+ Vect_cat_set(line_c, 1, (int)pg_info->cache.fid);
+
+ pg_info->cache.lines_next++;
+
+ return itype;
}
- return -1; /* not reached */
+ return -1; /* not reached */
}
/*!
- \brief Read feature geometry
+ \brief Read feature geometry
- Geometry is stored in lines cache.
-
- \param[in,out] pg_info pointer to Format_info_pg struct
- \param fid feature id to be read (-1 for next)
- \param[out] line_c pointer to line_cats structure (or NULL)
+ Geometry is stored in lines cache.
- \return simple feature type (SF_POINT, SF_LINESTRING, ...)
- \return -1 on error
-*/
-SF_FeatureType get_feature(struct Format_info_pg *pg_info, int fid)
+ \param[in,out] pg_info pointer to Format_info_pg struct
+ \param fid feature id to be read (-1 for next)
+ \param[out] line_c pointer to line_cats structure (or NULL)
+
+ \return simple feature type (SF_POINT, SF_LINESTRING, ...)
+ \return -1 on error
+ */
+SF_FeatureType get_feature(struct Format_info_pg * pg_info, int fid)
{
char *data;
char stmt[DB_SQL_MAX];
if (!pg_info->geom_column) {
- G_warning(_("No geometry column defined"));
- return -1;
+ G_warning(_("No geometry column defined"));
+ return -1;
}
if (fid < 1) {
- /* next (read n features) */
- if (!pg_info->res) {
- if (set_initial_query(pg_info) == -1)
- return -1;
- }
+ /* next (read n features) */
+ if (!pg_info->res) {
+ if (set_initial_query(pg_info) == -1)
+ return -1;
+ }
}
else {
- if (!pg_info->fid_column) {
- G_warning(_("Random access not supported. "
- "Primary key not defined."));
- return -1;
- }
-
- if (execute(pg_info->conn, "BEGIN") == -1)
- return -1;
-
- sprintf(stmt, "DECLARE %s_%s%p CURSOR FOR SELECT %s FROM \"%s\".\"%s\" "
- "WHERE %s = %d",
- pg_info->schema_name, pg_info->table_name, pg_info->conn,
- pg_info->geom_column, pg_info->schema_name,
- pg_info->table_name, pg_info->fid_column, fid);
+ if (!pg_info->fid_column) {
+ G_warning(_("Random access not supported. "
+ "Primary key not defined."));
+ return -1;
+ }
- if (execute(pg_info->conn, stmt) == -1)
- return -1;
-
- sprintf(stmt, "FETCH ALL in %s_%s%p",
- pg_info->schema_name, pg_info->table_name, pg_info->conn);
- pg_info->res = PQexec(pg_info->conn, stmt);
- pg_info->next_line = 0;
+ if (execute(pg_info->conn, "BEGIN") == -1)
+ return -1;
+
+ sprintf(stmt,
+ "DECLARE %s_%s%p CURSOR FOR SELECT %s FROM \"%s\".\"%s\" "
+ "WHERE %s = %d", pg_info->schema_name, pg_info->table_name,
+ pg_info->conn, pg_info->geom_column, pg_info->schema_name,
+ pg_info->table_name, pg_info->fid_column, fid);
+
+ if (execute(pg_info->conn, stmt) == -1)
+ return -1;
+
+ sprintf(stmt, "FETCH ALL in %s_%s%p",
+ pg_info->schema_name, pg_info->table_name, pg_info->conn);
+ pg_info->res = PQexec(pg_info->conn, stmt);
+ pg_info->next_line = 0;
}
if (!pg_info->res || PQresultStatus(pg_info->res) != PGRES_TUPLES_OK) {
- PQclear(pg_info->res);
- pg_info->res = NULL;
- return -1; /* reading failed */
+ PQclear(pg_info->res);
+ pg_info->res = NULL;
+ return -1; /* reading failed */
}
-
+
/* do we need to fetch more records ? */
if (PQntuples(pg_info->res) == CURSOR_PAGE &&
PQntuples(pg_info->res) == pg_info->next_line) {
- char stmt[DB_SQL_MAX];
- PQclear(pg_info->res);
+ char stmt[DB_SQL_MAX];
- sprintf(stmt, "FETCH %d in %s_%s%p", CURSOR_PAGE,
- pg_info->schema_name, pg_info->table_name, pg_info->conn);
- pg_info->res = PQexec(pg_info->conn, stmt);
- if (!pg_info->res) {
- execute(pg_info->conn, "ROLLBACK");
- return -1;
- }
- pg_info->next_line = 0;
+ PQclear(pg_info->res);
+
+ sprintf(stmt, "FETCH %d in %s_%s%p", CURSOR_PAGE,
+ pg_info->schema_name, pg_info->table_name, pg_info->conn);
+ pg_info->res = PQexec(pg_info->conn, stmt);
+ if (!pg_info->res) {
+ execute(pg_info->conn, "ROLLBACK");
+ return -1;
+ }
+ pg_info->next_line = 0;
}
/* out of results ? */
if (PQntuples(pg_info->res) == pg_info->next_line) {
- if (pg_info->res) {
- PQclear(pg_info->res);
- pg_info->res = NULL;
-
- sprintf(stmt, "CLOSE %s_%s%p",
- pg_info->schema_name, pg_info->table_name, pg_info->conn);
- if (execute(pg_info->conn, stmt) == -1) {
- execute(pg_info->conn, "ROLLBACK");
- G_warning(_("Unable to close cursor"));
- return -1;
- }
- execute(pg_info->conn, "COMMIT");
- }
- return -2;
+ if (pg_info->res) {
+ PQclear(pg_info->res);
+ pg_info->res = NULL;
+
+ sprintf(stmt, "CLOSE %s_%s%p",
+ pg_info->schema_name, pg_info->table_name, pg_info->conn);
+ if (execute(pg_info->conn, stmt) == -1) {
+ execute(pg_info->conn, "ROLLBACK");
+ G_warning(_("Unable to close cursor"));
+ return -1;
+ }
+ execute(pg_info->conn, "COMMIT");
+ }
+ return -2;
}
data = (char *)PQgetvalue(pg_info->res, pg_info->next_line, 0);
-
- pg_info->cache.sf_type = cache_feature(data, FALSE, &(pg_info->cache), NULL);
+
+ pg_info->cache.sf_type =
+ cache_feature(data, FALSE, &(pg_info->cache), NULL);
if (fid < 0) {
- pg_info->cache.fid = atoi(PQgetvalue(pg_info->res, pg_info->next_line, 1));
- pg_info->next_line++;
+ pg_info->cache.fid =
+ atoi(PQgetvalue(pg_info->res, pg_info->next_line, 1));
+ pg_info->next_line++;
}
else {
- pg_info->cache.fid = fid;
+ pg_info->cache.fid = fid;
- PQclear(pg_info->res);
- pg_info->res = NULL;
-
- sprintf(stmt, "CLOSE %s_%s%p",
- pg_info->schema_name, pg_info->table_name, pg_info->conn);
- if (execute(pg_info->conn, stmt) == -1) {
- G_warning(_("Unable to close cursor"));
- return -1;
- }
+ PQclear(pg_info->res);
+ pg_info->res = NULL;
- if (execute(pg_info->conn, "COMMIT") == -1)
- return -1;
+ sprintf(stmt, "CLOSE %s_%s%p",
+ pg_info->schema_name, pg_info->table_name, pg_info->conn);
+ if (execute(pg_info->conn, stmt) == -1) {
+ G_warning(_("Unable to close cursor"));
+ return -1;
+ }
+
+ if (execute(pg_info->conn, "COMMIT") == -1)
+ return -1;
}
-
+
return pg_info->cache.sf_type;
}
/*!
- \brief Convert HEX to WKB data
+ \brief Convert HEX to WKB data
- \param hex_data HEX data
- \param[out] nbytes number of bytes in output buffer
+ \param hex_data HEX data
+ \param[out] nbytes number of bytes in output buffer
- \return pointer to WKB data buffer
-*/
+ \return pointer to WKB data buffer
+ */
unsigned char *hex_to_wkb(const char *hex_data, int *nbytes)
{
unsigned int length;
int i;
-
+
length = strlen(hex_data) / 2 + 1;
if (length > wkb_data_length) {
- wkb_data_length = length;
- wkb_data = G_realloc(wkb_data, wkb_data_length);
+ wkb_data_length = length;
+ wkb_data = G_realloc(wkb_data, wkb_data_length);
}
-
+
*nbytes = length - 1;
for (i = 0; i < (*nbytes); i++) {
- wkb_data[i] = (unsigned char) ((hex_data[2 * i] > 'F' ? hex_data[2 * i] - 0x57 :
- hex_data[2 * i] > '9' ? hex_data[2 * i] - 0x37 :
- hex_data[2 * i] - 0x30) << 4);
- wkb_data[i] |= (unsigned char) (hex_data[2 * i + 1] > 'F' ? hex_data[2 * i + 1] - 0x57 :
- hex_data[2 * i + 1] > '9' ? hex_data[2 * i + 1] - 0x37 :
- hex_data[2 * i + 1] - 0x30);
+ wkb_data[i] =
+ (unsigned
+ char)((hex_data[2 * i] >
+ 'F' ? hex_data[2 * i] - 0x57 : hex_data[2 * i] >
+ '9' ? hex_data[2 * i] - 0x37 : hex_data[2 * i] -
+ 0x30) << 4);
+ wkb_data[i] |=
+ (unsigned char)(hex_data[2 * i + 1] >
+ 'F' ? hex_data[2 * i + 1] -
+ 0x57 : hex_data[2 * i + 1] >
+ '9' ? hex_data[2 * i + 1] -
+ 0x37 : hex_data[2 * i + 1] - 0x30);
}
-
+
wkb_data[(*nbytes)] = 0;
-
+
return wkb_data;
}
/*!
- \brief Read geometry from HEX data
+ \brief Read geometry from HEX data
- This code is inspired by OGRGeometryFactory::createFromWkb() from
- GDAL/OGR library.
+ This code is inspired by OGRGeometryFactory::createFromWkb() from
+ GDAL/OGR library.
- \param data HEX data
- \param skip_polygon skip polygons (level 1)
- \param[out] cache lines cache
- \param[out] fparts used for building pseudo-topology (or NULL)
-
- \return simple feature type
- \return SF_UNKNOWN on error
-*/
+ \param data HEX data
+ \param skip_polygon skip polygons (level 1)
+ \param[out] cache lines cache
+ \param[out] fparts used for building pseudo-topology (or NULL)
+
+ \return simple feature type
+ \return SF_UNKNOWN on error
+ */
SF_FeatureType cache_feature(const char *data, int skip_polygon,
- struct Format_info_cache *cache,
- struct feat_parts *fparts)
+ struct Format_info_cache * cache,
+ struct feat_parts * fparts)
{
int ret, byte_order, nbytes, is3D;
unsigned char *wkb_data;
unsigned int wkb_flags;
SF_FeatureType ftype;
-
+
/* reset cache */
cache->lines_num = 0;
- cache->fid = -1;
+ cache->fid = -1;
/* next to be read from cache */
cache->lines_next = 0;
-
+
if (fparts)
- fparts->n_parts = 0;
-
+ fparts->n_parts = 0;
+
wkb_flags = 0;
- wkb_data = hex_to_wkb(data, &nbytes);
-
+ wkb_data = hex_to_wkb(data, &nbytes);
+
if (nbytes < 5) {
- /* G_free(wkb_data); */
- if (nbytes > 0) {
- G_debug(3, "cache_feature(): invalid geometry");
- G_warning(_("Invalid WKB content: %d bytes"), nbytes);
- return SF_UNKNOWN;
- }
- else {
- G_debug(3, "cache_feature(): no geometry");
- return SF_NONE;
- }
+ /* G_free(wkb_data); */
+ if (nbytes > 0) {
+ G_debug(3, "cache_feature(): invalid geometry");
+ G_warning(_("Invalid WKB content: %d bytes"), nbytes);
+ return SF_UNKNOWN;
+ }
+ else {
+ G_debug(3, "cache_feature(): no geometry");
+ return SF_NONE;
+ }
}
-
+
/* parsing M coordinate not supported */
memcpy(&wkb_flags, wkb_data + 1, 4);
byte_order = (wkb_data[0] == 0 ? ENDIAN_BIG : ENDIAN_LITTLE);
if (byte_order == ENDIAN_BIG)
- wkb_flags = SWAP32(wkb_flags);
-
+ wkb_flags = SWAP32(wkb_flags);
+
if (wkb_flags & 0x40000000) {
G_warning(_("Reading EWKB with 4-dimensional coordinates (XYZM) "
- "is not supported"));
- /* G_free(wkb_data); */
- return SF_UNKNOWN;
+ "is not supported"));
+ /* G_free(wkb_data); */
+ return SF_UNKNOWN;
}
/* PostGIS EWKB format includes an SRID, but this won't be
understood by OGR, so if the SRID flag is set, we remove the
SRID (bytes at offset 5 to 8).
- */
+ */
if (nbytes > 9 &&
((byte_order == ENDIAN_BIG && (wkb_data[1] & 0x20)) ||
- (byte_order == ENDIAN_LITTLE && (wkb_data[4] & 0x20)))) {
- memmove(wkb_data + 5, wkb_data + 9, nbytes -9);
+ (byte_order == ENDIAN_LITTLE && (wkb_data[4] & 0x20)))) {
+ memmove(wkb_data + 5, wkb_data + 9, nbytes - 9);
nbytes -= 4;
- if(byte_order == ENDIAN_BIG)
+ if (byte_order == ENDIAN_BIG)
wkb_data[1] &= (~0x20);
else
wkb_data[4] &= (~0x20);
}
-
+
if (nbytes < 9 && nbytes != -1) {
- /* G_free(wkb_data); */
- return SF_UNKNOWN;
+ /* G_free(wkb_data); */
+ return SF_UNKNOWN;
}
-
- /* Get the geometry feature type. For now we assume that geometry
- type is between 0 and 255 so we only have to fetch one byte.
- */
+
+ /* Get the geometry feature type. For now we assume that geometry
+ type is between 0 and 255 so we only have to fetch one byte.
+ */
if (byte_order == ENDIAN_LITTLE) {
ftype = (SF_FeatureType) wkb_data[1];
- is3D = wkb_data[4] & 0x80 || wkb_data[2] & 0x80;
+ is3D = wkb_data[4] & 0x80 || wkb_data[2] & 0x80;
}
else {
ftype = (SF_FeatureType) wkb_data[4];
- is3D = wkb_data[1] & 0x80 || wkb_data[3] & 0x80;
+ is3D = wkb_data[1] & 0x80 || wkb_data[3] & 0x80;
}
G_debug(3, "cache_feature(): sf_type = %d", ftype);
-
+
/* allocate space in lines cache - be minimalistic
-
+
more lines require eg. polygon with more rings, multi-features
or geometry collections
- */
+ */
if (!cache->lines) {
- reallocate_cache(cache, 1);
+ reallocate_cache(cache, 1);
}
-
+
ret = -1;
if (ftype == SF_POINT) {
- cache->lines_num = 1;
- cache->lines_types[0] = GV_POINT;
- ret = point_from_wkb(wkb_data, nbytes, byte_order,
- is3D, cache->lines[0]);
- add_fpart(fparts, ftype, 0, 1);
+ cache->lines_num = 1;
+ cache->lines_types[0] = GV_POINT;
+ ret = point_from_wkb(wkb_data, nbytes, byte_order,
+ is3D, cache->lines[0]);
+ add_fpart(fparts, ftype, 0, 1);
}
else if (ftype == SF_LINESTRING) {
- cache->lines_num = 1;
- cache->lines_types[0] = GV_LINE;
- ret = linestring_from_wkb(wkb_data, nbytes, byte_order,
- is3D, cache->lines[0], FALSE);
- add_fpart(fparts, ftype, 0, 1);
+ cache->lines_num = 1;
+ cache->lines_types[0] = GV_LINE;
+ ret = linestring_from_wkb(wkb_data, nbytes, byte_order,
+ is3D, cache->lines[0], FALSE);
+ add_fpart(fparts, ftype, 0, 1);
}
else if (ftype == SF_POLYGON && !skip_polygon) {
- int nrings;
-
- ret = polygon_from_wkb(wkb_data, nbytes, byte_order,
- is3D, cache, &nrings);
- add_fpart(fparts, ftype, 0, nrings);
+ int nrings;
+
+ ret = polygon_from_wkb(wkb_data, nbytes, byte_order,
+ is3D, cache, &nrings);
+ add_fpart(fparts, ftype, 0, nrings);
}
else if (ftype == SF_MULTIPOINT ||
- ftype == SF_MULTILINESTRING ||
- ftype == SF_MULTIPOLYGON ||
- ftype == SF_GEOMETRYCOLLECTION) {
- ret = geometry_collection_from_wkb(wkb_data, nbytes, byte_order,
- is3D, cache, fparts);
+ ftype == SF_MULTILINESTRING ||
+ ftype == SF_MULTIPOLYGON || ftype == SF_GEOMETRYCOLLECTION) {
+ ret = geometry_collection_from_wkb(wkb_data, nbytes, byte_order,
+ is3D, cache, fparts);
}
- else {
- G_warning(_("Unsupported feature type %d"), ftype);
+ else {
+ G_warning(_("Unsupported feature type %d"), ftype);
}
/* read next feature from cache */
cache->lines_next = 0;
-
+
/* G_free(wkb_data); */
-
+
return ret > 0 ? ftype : SF_UNKNOWN;
}
/*!
- \brief Read point for WKB data
+ \brief Read point for WKB data
- See OGRPoint::importFromWkb() from GDAL/OGR library
+ See OGRPoint::importFromWkb() from GDAL/OGR library
- \param wkb_data WKB data
- \param nbytes number of bytes (WKB data buffer)
- \param byte_order byte order (ENDIAN_LITTLE, ENDIAN_BIG)
- \param with_z WITH_Z for 3D data
- \param[out] line_p point geometry (pointer to line_pnts struct)
+ \param wkb_data WKB data
+ \param nbytes number of bytes (WKB data buffer)
+ \param byte_order byte order (ENDIAN_LITTLE, ENDIAN_BIG)
+ \param with_z WITH_Z for 3D data
+ \param[out] line_p point geometry (pointer to line_pnts struct)
- \return wkb size
- \return -1 on error
-*/
+ \return wkb size
+ \return -1 on error
+ */
int point_from_wkb(const unsigned char *wkb_data, int nbytes, int byte_order,
- int with_z, struct line_pnts *line_p)
+ int with_z, struct line_pnts *line_p)
{
double x, y, z;
- if (nbytes < 21 && nbytes != -1 )
- return -1;
+ if (nbytes < 21 && nbytes != -1)
+ return -1;
+
/* get vertex */
memcpy(&x, wkb_data + 5, 8);
memcpy(&y, wkb_data + 5 + 8, 8);
-
+
if (byte_order == ENDIAN_BIG) {
SWAPDOUBLE(&x);
SWAPDOUBLE(&y);
}
if (with_z) {
- if (nbytes < 29 && nbytes != -1 )
+ if (nbytes < 29 && nbytes != -1)
return -1;
-
+
memcpy(&z, wkb_data + 5 + 16, 8);
- if (byte_order == ENDIAN_BIG) {
- SWAPDOUBLE(&z);
- }
+ if (byte_order == ENDIAN_BIG) {
+ SWAPDOUBLE(&z);
+ }
}
else {
z = 0.0;
}
-
+
if (line_p) {
- Vect_reset_line(line_p);
- Vect_append_point(line_p, x, y, z);
+ Vect_reset_line(line_p);
+ Vect_append_point(line_p, x, y, z);
}
-
+
return 5 + 8 * (with_z == WITH_Z ? 3 : 2);
}
/*!
- \brief Read line for WKB data
+ \brief Read line for WKB data
- See OGRLineString::importFromWkb() from GDAL/OGR library
+ See OGRLineString::importFromWkb() from GDAL/OGR library
- \param wkb_data WKB data
- \param nbytes number of bytes (WKB data buffer)
- \param byte_order byte order (ENDIAN_LITTLE, ENDIAN_BIG)
- \param with_z WITH_Z for 3D data
- \param[out] line_p line geometry (pointer to line_pnts struct)
+ \param wkb_data WKB data
+ \param nbytes number of bytes (WKB data buffer)
+ \param byte_order byte order (ENDIAN_LITTLE, ENDIAN_BIG)
+ \param with_z WITH_Z for 3D data
+ \param[out] line_p line geometry (pointer to line_pnts struct)
- \return wkb size
- \return -1 on error
-*/
-int linestring_from_wkb(const unsigned char *wkb_data, int nbytes, int byte_order,
- int with_z, struct line_pnts *line_p, int is_ring)
+ \return wkb size
+ \return -1 on error
+ */
+int linestring_from_wkb(const unsigned char *wkb_data, int nbytes,
+ int byte_order, int with_z, struct line_pnts *line_p,
+ int is_ring)
{
int npoints, point_size, buff_min_size, offset;
int i;
double x, y, z;
if (is_ring)
- offset = 5;
+ offset = 5;
else
- offset = 0;
-
+ offset = 0;
+
if (is_ring && nbytes < 4 && nbytes != -1)
return error_corrupted_data(NULL);
-
+
/* get the vertex count */
memcpy(&npoints, wkb_data + (5 - offset), 4);
-
+
if (byte_order == ENDIAN_BIG) {
- npoints = SWAP32(npoints);
+ npoints = SWAP32(npoints);
}
-
+
/* check if the wkb stream buffer is big enough to store fetched
number of points. 16 or 24 - size of point structure
- */
+ */
point_size = with_z ? 24 : 16;
if (npoints < 0 || npoints > INT_MAX / point_size)
return error_corrupted_data(NULL);
-
+
buff_min_size = point_size * npoints;
-
+
if (nbytes != -1 && buff_min_size > nbytes - (9 - offset))
return error_corrupted_data(_("Length of input WKB is too small"));
-
+
if (line_p)
- Vect_reset_line(line_p);
-
+ Vect_reset_line(line_p);
+
/* get the vertex */
for (i = 0; i < npoints; i++) {
- memcpy(&x, wkb_data + (9 - offset) + i * point_size, 8);
- memcpy(&y, wkb_data + (9 - offset) + 8 + i * point_size, 8);
- if (with_z)
+ memcpy(&x, wkb_data + (9 - offset) + i * point_size, 8);
+ memcpy(&y, wkb_data + (9 - offset) + 8 + i * point_size, 8);
+ if (with_z)
memcpy(&z, wkb_data + (9 - offset) + 16 + i * point_size, 8);
else
- z = 0.0;
+ z = 0.0;
- if (byte_order == ENDIAN_BIG) {
- SWAPDOUBLE(&x);
- SWAPDOUBLE(&y);
- if (with_z)
- SWAPDOUBLE(&z);
- }
-
- if (line_p)
- Vect_append_point(line_p, x, y, z);
+ if (byte_order == ENDIAN_BIG) {
+ SWAPDOUBLE(&x);
+ SWAPDOUBLE(&y);
+ if (with_z)
+ SWAPDOUBLE(&z);
+ }
+
+ if (line_p)
+ Vect_append_point(line_p, x, y, z);
}
-
+
return (9 - offset) + (with_z == WITH_Z ? 3 : 2) * 8 * line_p->n_points;
}
/*!
- \brief Read polygon for WKB data
+ \brief Read polygon for WKB data
- See OGRPolygon::importFromWkb() from GDAL/OGR library
+ See OGRPolygon::importFromWkb() from GDAL/OGR library
- \param wkb_data WKB data
- \param nbytes number of bytes (WKB data buffer)
- \param byte_order byte order (ENDIAN_LITTLE, ENDIAN_BIG)
- \param with_z WITH_Z for 3D data
- \param[out] line_p array of rings (pointer to line_pnts struct)
- \param[out] nrings number of rings
-
- \return wkb size
- \return -1 on error
-*/
-int polygon_from_wkb(const unsigned char *wkb_data, int nbytes, int byte_order,
- int with_z, struct Format_info_cache *cache, int *nrings)
+ \param wkb_data WKB data
+ \param nbytes number of bytes (WKB data buffer)
+ \param byte_order byte order (ENDIAN_LITTLE, ENDIAN_BIG)
+ \param with_z WITH_Z for 3D data
+ \param[out] line_p array of rings (pointer to line_pnts struct)
+ \param[out] nrings number of rings
+
+ \return wkb size
+ \return -1 on error
+ */
+int polygon_from_wkb(const unsigned char *wkb_data, int nbytes,
+ int byte_order, int with_z,
+ struct Format_info_cache *cache, int *nrings)
{
int data_offset, i, nsize, isize;
struct line_pnts *line_i;
-
+
if (nbytes < 9 && nbytes != -1)
- return -1;
-
+ return -1;
+
/* get the ring count */
memcpy(nrings, wkb_data + 5, 4);
if (byte_order == ENDIAN_BIG) {
@@ -839,11 +847,11 @@
if (*nrings < 0) {
return -1;
}
-
+
/* reallocate space for islands if needed */
reallocate_cache(cache, *nrings);
cache->lines_num += *nrings;
-
+
/* each ring has a minimum of 4 bytes (point count) */
if (nbytes != -1 && nbytes - 9 < (*nrings) * 4) {
return error_corrupted_data(_("Length of input WKB is too small"));
@@ -852,60 +860,61 @@
data_offset = 9;
if (nbytes != -1)
nbytes -= data_offset;
-
+
/* get the rings */
nsize = 9;
- for (i = 0; i < (*nrings); i++ ) {
- if (cache->lines_next >= cache->lines_num)
- G_fatal_error(_("Invalid cache index %d (max: %d)"),
- cache->lines_next, cache->lines_num);
- line_i = cache->lines[cache->lines_next];
- cache->lines_types[cache->lines_next++] = GV_BOUNDARY;
-
- linestring_from_wkb(wkb_data + data_offset, nbytes, byte_order,
- with_z, line_i, TRUE);
-
+ for (i = 0; i < (*nrings); i++) {
+ if (cache->lines_next >= cache->lines_num)
+ G_fatal_error(_("Invalid cache index %d (max: %d)"),
+ cache->lines_next, cache->lines_num);
+ line_i = cache->lines[cache->lines_next];
+ cache->lines_types[cache->lines_next++] = GV_BOUNDARY;
+
+ linestring_from_wkb(wkb_data + data_offset, nbytes, byte_order,
+ with_z, line_i, TRUE);
+
if (nbytes != -1) {
- isize = 4 + 8 * (with_z == WITH_Z ? 3 : 2) * line_i->n_points;
- nbytes -= isize;
- }
-
- nsize += isize;
+ isize = 4 + 8 * (with_z == WITH_Z ? 3 : 2) * line_i->n_points;
+ nbytes -= isize;
+ }
+
+ nsize += isize;
data_offset += isize;
}
-
+
return nsize;
}
/*!
- \brief Read geometry collection for WKB data
+ \brief Read geometry collection for WKB data
- See OGRGeometryCollection::importFromWkbInternal() from GDAL/OGR library
+ See OGRGeometryCollection::importFromWkbInternal() from GDAL/OGR library
- \param wkb_data WKB data
- \param nbytes number of bytes (WKB data buffer)
- \param byte_order byte order (ENDIAN_LITTLE, ENDIAN_BIG)
- \param with_z WITH_Z for 3D data
- \param ipart part to cache (starts at 0)
- \param[out] cache lines cache
- \param[in,out] fparts feature parts (required for building pseudo-topology)
+ \param wkb_data WKB data
+ \param nbytes number of bytes (WKB data buffer)
+ \param byte_order byte order (ENDIAN_LITTLE, ENDIAN_BIG)
+ \param with_z WITH_Z for 3D data
+ \param ipart part to cache (starts at 0)
+ \param[out] cache lines cache
+ \param[in,out] fparts feature parts (required for building pseudo-topology)
- \return number of parts
- \return -1 on error
-*/
-int geometry_collection_from_wkb(const unsigned char *wkb_data, int nbytes, int byte_order,
- int with_z, struct Format_info_cache *cache,
- struct feat_parts *fparts)
+ \return number of parts
+ \return -1 on error
+ */
+int geometry_collection_from_wkb(const unsigned char *wkb_data, int nbytes,
+ int byte_order, int with_z,
+ struct Format_info_cache *cache,
+ struct feat_parts *fparts)
{
int ipart, nparts, data_offset, nsize;
unsigned char *wkb_subdata;
SF_FeatureType ftype;
-
+
if (nbytes < 9 && nbytes != -1)
- return error_corrupted_data(NULL);
-
+ return error_corrupted_data(NULL);
+
/* get the geometry count */
- memcpy(&nparts, wkb_data + 5, 4 );
+ memcpy(&nparts, wkb_data + 5, 4);
if (byte_order == ENDIAN_BIG) {
nparts = SWAP32(nparts);
}
@@ -913,7 +922,7 @@
return error_corrupted_data(NULL);
}
G_debug(5, "\t(geometry collections) parts: %d", nparts);
-
+
/* each geometry has a minimum of 9 bytes */
if (nbytes != -1 && nbytes - 9 < nparts * 9) {
return error_corrupted_data(_("Length of input WKB is too small"));
@@ -925,133 +934,133 @@
/* reallocate space for parts if needed */
reallocate_cache(cache, nparts);
-
+
/* get parts */
for (ipart = 0; ipart < nparts; ipart++) {
- wkb_subdata = (unsigned char *)wkb_data + data_offset;
- if (nbytes < 9 && nbytes != -1)
- return error_corrupted_data(NULL);
-
- if (byte_order == ENDIAN_LITTLE) {
- ftype = (SF_FeatureType) wkb_subdata[1];
- }
- else {
- ftype = (SF_FeatureType) wkb_subdata[4];
- }
-
- if (ftype == SF_POINT) {
- cache->lines_types[cache->lines_next] = GV_POINT;
- nsize = point_from_wkb(wkb_subdata, nbytes, byte_order, with_z,
- cache->lines[cache->lines_next]);
- cache->lines_num++;
- add_fpart(fparts, ftype, cache->lines_next, 1);
- cache->lines_next++;
- }
- else if (ftype == SF_LINESTRING) {
- cache->lines_types[cache->lines_next] = GV_LINE;
- nsize = linestring_from_wkb(wkb_subdata, nbytes, byte_order, with_z,
- cache->lines[cache->lines_next],
- FALSE);
- cache->lines_num++;
- add_fpart(fparts, ftype, cache->lines_next, 1);
- cache->lines_next++;
- }
- else if (ftype == SF_POLYGON) {
- int idx, nrings;
+ wkb_subdata = (unsigned char *)wkb_data + data_offset;
+ if (nbytes < 9 && nbytes != -1)
+ return error_corrupted_data(NULL);
- idx = cache->lines_next;
- nsize = polygon_from_wkb(wkb_subdata, nbytes, byte_order,
- with_z, cache, &nrings);
- add_fpart(fparts, ftype, idx, nrings);
- }
- else if (ftype == SF_GEOMETRYCOLLECTION ||
- ftype == SF_MULTIPOLYGON ||
- ftype == SF_MULTILINESTRING ||
- ftype == SF_MULTIPOLYGON) {
- geometry_collection_from_wkb(wkb_subdata, nbytes, byte_order,
- with_z, cache, fparts);
- }
- else {
- G_warning(_("Unsupported feature type %d"), ftype);
- }
+ if (byte_order == ENDIAN_LITTLE) {
+ ftype = (SF_FeatureType) wkb_subdata[1];
+ }
+ else {
+ ftype = (SF_FeatureType) wkb_subdata[4];
+ }
+ if (ftype == SF_POINT) {
+ cache->lines_types[cache->lines_next] = GV_POINT;
+ nsize = point_from_wkb(wkb_subdata, nbytes, byte_order, with_z,
+ cache->lines[cache->lines_next]);
+ cache->lines_num++;
+ add_fpart(fparts, ftype, cache->lines_next, 1);
+ cache->lines_next++;
+ }
+ else if (ftype == SF_LINESTRING) {
+ cache->lines_types[cache->lines_next] = GV_LINE;
+ nsize =
+ linestring_from_wkb(wkb_subdata, nbytes, byte_order, with_z,
+ cache->lines[cache->lines_next], FALSE);
+ cache->lines_num++;
+ add_fpart(fparts, ftype, cache->lines_next, 1);
+ cache->lines_next++;
+ }
+ else if (ftype == SF_POLYGON) {
+ int idx, nrings;
+
+ idx = cache->lines_next;
+ nsize = polygon_from_wkb(wkb_subdata, nbytes, byte_order,
+ with_z, cache, &nrings);
+ add_fpart(fparts, ftype, idx, nrings);
+ }
+ else if (ftype == SF_GEOMETRYCOLLECTION ||
+ ftype == SF_MULTIPOLYGON ||
+ ftype == SF_MULTILINESTRING || ftype == SF_MULTIPOLYGON) {
+ geometry_collection_from_wkb(wkb_subdata, nbytes, byte_order,
+ with_z, cache, fparts);
+ }
+ else {
+ G_warning(_("Unsupported feature type %d"), ftype);
+ }
+
if (nbytes != -1) {
- nbytes -= nsize;
- }
-
+ nbytes -= nsize;
+ }
+
data_offset += nsize;
}
-
+
return nparts;
}
/*!
- \brief Report error message
+ \brief Report error message
- \param msg message (NULL)
+ \param msg message (NULL)
- \return -1
-*/
+ \return -1
+ */
int error_corrupted_data(const char *msg)
{
if (msg)
- G_warning(_("Corrupted data. %s."), msg);
+ G_warning(_("Corrupted data. %s."), msg);
else
- G_warning(_("Corrupted data"));
-
+ G_warning(_("Corrupted data"));
+
return -1;
}
/*!
- \brief Set initial SQL query for sequential access
+ \brief Set initial SQL query for sequential access
- \param pg_info pointer to Format_info_pg struct
+ \param pg_info pointer to Format_info_pg struct
- \return 0 on success
- \return -1 on error
-*/
+ \return 0 on success
+ \return -1 on error
+ */
int set_initial_query(struct Format_info_pg *pg_info)
{
char stmt[DB_SQL_MAX];
-
+
if (execute(pg_info->conn, "BEGIN") == -1)
- return -1;
-
- sprintf(stmt, "DECLARE %s_%s%p CURSOR FOR SELECT %s,%s FROM \"%s\".\"%s\"",
- pg_info->schema_name, pg_info->table_name, pg_info->conn,
- pg_info->geom_column, pg_info->fid_column,
- pg_info->schema_name, pg_info->table_name);
+ return -1;
+
+ sprintf(stmt,
+ "DECLARE %s_%s%p CURSOR FOR SELECT %s,%s FROM \"%s\".\"%s\"",
+ pg_info->schema_name, pg_info->table_name, pg_info->conn,
+ pg_info->geom_column, pg_info->fid_column, pg_info->schema_name,
+ pg_info->table_name);
G_debug(2, "SQL: %s", stmt);
-
+
if (execute(pg_info->conn, stmt) == -1) {
- execute(pg_info->conn, "ROLLBACK");
- return -1;
+ execute(pg_info->conn, "ROLLBACK");
+ return -1;
}
-
+
sprintf(stmt, "FETCH %d in %s_%s%p", CURSOR_PAGE,
- pg_info->schema_name, pg_info->table_name, pg_info->conn);
+ pg_info->schema_name, pg_info->table_name, pg_info->conn);
pg_info->res = PQexec(pg_info->conn, stmt);
if (!pg_info->res) {
- execute(pg_info->conn, "ROLLBACK");
- return -1;
+ execute(pg_info->conn, "ROLLBACK");
+ return -1;
}
pg_info->next_line = 0;
-
+
return 0;
}
/*!
- \brief Execute SQL statement
+ \brief Execute SQL statement
- See pg_local_proto.h
+ See pg_local_proto.h
- \param conn pointer to PGconn
- \param stmt query
+ \param conn pointer to PGconn
+ \param stmt query
- \return 0 on success
- \return -1 on error
-*/
-int execute(PGconn *conn, const char *stmt)
+ \return 0 on success
+ \return -1 on error
+ */
+int execute(PGconn * conn, const char *stmt)
{
PGresult *result;
@@ -1060,10 +1069,10 @@
G_debug(3, "execute(): %s", stmt);
result = PQexec(conn, stmt);
if (!result || PQresultStatus(result) != PGRES_COMMAND_OK) {
- PQclear(result);
+ PQclear(result);
- G_warning(_("Execution failed: %s"), PQerrorMessage(conn));
- return -1;
+ G_warning(_("Execution failed: %s"), PQerrorMessage(conn));
+ return -1;
}
PQclear(result);
@@ -1071,66 +1080,66 @@
}
/*!
- \brief Reallocate lines cache
-*/
+ \brief Reallocate lines cache
+ */
void reallocate_cache(struct Format_info_cache *cache, int num)
{
int i;
-
+
if (cache->lines_alloc >= num)
- return;
+ return;
if (!cache->lines) {
- /* most of features requires only one line cache */
- cache->lines_alloc = 1;
+ /* most of features requires only one line cache */
+ cache->lines_alloc = 1;
}
else {
- cache->lines_alloc += 20;
+ cache->lines_alloc += 20;
}
- cache->lines = (struct line_pnts **) G_realloc(cache->lines,
- cache->lines_alloc *
- sizeof(struct line_pnts *));
- cache->lines_types = (int *) G_realloc(cache->lines_types,
- cache->lines_alloc *
- sizeof(int));
-
+ cache->lines = (struct line_pnts **)G_realloc(cache->lines,
+ cache->lines_alloc *
+ sizeof(struct line_pnts *));
+ cache->lines_types = (int *)G_realloc(cache->lines_types,
+ cache->lines_alloc * sizeof(int));
+
if (cache->lines_alloc > 1) {
- for (i = cache->lines_alloc - 20; i < cache->lines_alloc; i++) {
- cache->lines[i] = Vect_new_line_struct();
- cache->lines_types[i] = -1;
- }
+ for (i = cache->lines_alloc - 20; i < cache->lines_alloc; i++) {
+ cache->lines[i] = Vect_new_line_struct();
+ cache->lines_types[i] = -1;
+ }
}
else {
- cache->lines[0] = Vect_new_line_struct();
- cache->lines_types[0] = -1;
+ cache->lines[0] = Vect_new_line_struct();
+ cache->lines_types[0] = -1;
}
}
void add_fpart(struct feat_parts *fparts, SF_FeatureType ftype,
- int idx, int nlines)
+ int idx, int nlines)
{
if (!fparts)
- return;
-
+ return;
+
if (fparts->a_parts == 0 || fparts->n_parts >= fparts->a_parts) {
- if (fparts->a_parts == 0)
- fparts->a_parts = 1;
- else
- fparts->a_parts += 20;
-
- fparts->ftype = (SF_FeatureType *) G_realloc(fparts->ftype,
- fparts->a_parts * sizeof(SF_FeatureType));
- fparts->nlines = (int *) G_realloc(fparts->nlines,
- fparts->a_parts * sizeof(int));
- fparts->idx = (int *) G_realloc(fparts->idx,
- fparts->a_parts * sizeof(int));
+ if (fparts->a_parts == 0)
+ fparts->a_parts = 1;
+ else
+ fparts->a_parts += 20;
+
+ fparts->ftype = (SF_FeatureType *) G_realloc(fparts->ftype,
+ fparts->a_parts *
+ sizeof(SF_FeatureType));
+ fparts->nlines =
+ (int *)G_realloc(fparts->nlines, fparts->a_parts * sizeof(int));
+ fparts->idx =
+ (int *)G_realloc(fparts->idx, fparts->a_parts * sizeof(int));
}
-
- fparts->ftype[fparts->n_parts] = ftype;
- fparts->idx[fparts->n_parts] = idx;
+
+ fparts->ftype[fparts->n_parts] = ftype;
+ fparts->idx[fparts->n_parts] = idx;
fparts->nlines[fparts->n_parts] = nlines;
-
+
fparts->n_parts++;
}
#endif
Modified: grass/trunk/lib/vector/Vlib/rewind_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/rewind_pg.c 2012-04-11 10:42:29 UTC (rev 51377)
+++ grass/trunk/lib/vector/Vlib/rewind_pg.c 2012-04-11 14:34:58 UTC (rev 51378)
@@ -11,7 +11,7 @@
(>=v2). Read the file COPYING that comes with GRASS for details.
\author Martin Landa <landa.martin gmail.com>
-*/
+ */
#include <grass/vector.h>
#include <grass/glocale.h>
@@ -21,46 +21,46 @@
#endif
/*!
- \brief Rewind vector map (PostGIS layer) to cause reads to start
- at beginning (level 1)
-
- \param Map pointer to Map_info structure
-
- \return 0 on success
- \return -1 on error
+ \brief Rewind vector map (PostGIS layer) to cause reads to start
+ at beginning (level 1)
+
+ \param Map pointer to Map_info structure
+
+ \return 0 on success
+ \return -1 on error
*/
int V1_rewind_pg(struct Map_info *Map)
{
G_debug(2, "V1_rewind_pg(): name = %s", Map->name);
-
+
#ifdef HAVE_POSTGRES
struct Format_info_pg *pg_info;
pg_info = &(Map->fInfo.pg);
-
+
/* reset reading */
pg_info->next_line = 0;
/* reset cache */
pg_info->cache.lines_num = pg_info->cache.lines_next = 0;
pg_info->cache.fid = -1;
-
+
/* close DB cursor if necessary */
if (pg_info->res) {
- char stmt[DB_SQL_MAX];
-
- PQclear(pg_info->res);
- pg_info->res = NULL;
-
- sprintf(stmt, "CLOSE %s_%s%p",
- pg_info->schema_name, pg_info->table_name, pg_info->conn);
- if (execute(pg_info->conn, stmt) == -1) {
- G_warning(_("Unable to close cursor"));
- return -1;
- }
- execute(pg_info->conn, "COMMIT");
+ char stmt[DB_SQL_MAX];
+
+ PQclear(pg_info->res);
+ pg_info->res = NULL;
+
+ sprintf(stmt, "CLOSE %s_%s%p",
+ pg_info->schema_name, pg_info->table_name, pg_info->conn);
+ if (execute(pg_info->conn, stmt) == -1) {
+ G_warning(_("Unable to close cursor"));
+ return -1;
+ }
+ execute(pg_info->conn, "COMMIT");
}
-
+
return 0;
#else
G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
@@ -69,13 +69,13 @@
}
/*!
- \brief Rewind vector map (PostGIS layer) to cause reads to start
- at beginning on topological level (level 2)
-
- \param Map pointer to Map_info structure
+ \brief Rewind vector map (PostGIS layer) to cause reads to start
+ at beginning on topological level (level 2)
- \return 0 on success
- \return -1 on error
+ \param Map pointer to Map_info structure
+
+ \return 0 on success
+ \return -1 on error
*/
int V2_rewind_pg(struct Map_info *Map)
{
Modified: grass/trunk/lib/vector/Vlib/write_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write_pg.c 2012-04-11 10:42:29 UTC (rev 51377)
+++ grass/trunk/lib/vector/Vlib/write_pg.c 2012-04-11 14:34:58 UTC (rev 51378)
@@ -32,159 +32,155 @@
#define WKBSRIDFLAG 0x20000000
static char *binary_to_hex(int, const unsigned char *);
-static unsigned char *point_to_wkb(int, const struct line_pnts *,
- int, int*);
+static unsigned char *point_to_wkb(int, const struct line_pnts *, int, int *);
static unsigned char *linestring_to_wkb(int, const struct line_pnts *,
- int, int*);
+ int, int *);
static unsigned char *polygon_to_wkb(int, const struct line_pnts *,
- int, int*);
-static int write_feature(struct Format_info_pg *,
- int, const struct line_pnts *, int,
- int, const struct field_info *);
+ int, int *);
+static int write_feature(struct Format_info_pg *,
+ int, const struct line_pnts *, int,
+ int, const struct field_info *);
static char *build_insert_stmt(const struct Format_info_pg *, const char *,
- int, const struct field_info *);
+ int, const struct field_info *);
#endif
/*!
- \brief Writes feature on level 1 (PostGIS interface)
+ \brief Writes feature on level 1 (PostGIS interface)
- Note:
+ Note:
- centroids are not supported in PostGIS, pseudotopo holds virtual
- centroids
+ centroids
- boundaries are not supported in PostGIS, pseudotopo treats polygons
- as boundaries
-
- \param Map pointer to Map_info structure
- \param type feature type (GV_POINT, GV_LINE, ...)
- \param points pointer to line_pnts structure (feature geometry)
- \param cats pointer to line_cats structure (feature categories)
-
- \return feature offset into file
- \return -1 on error
-*/
+ as boundaries
+
+ \param Map pointer to Map_info structure
+ \param type feature type (GV_POINT, GV_LINE, ...)
+ \param points pointer to line_pnts structure (feature geometry)
+ \param cats pointer to line_cats structure (feature categories)
+
+ \return feature offset into file
+ \return -1 on error
+ */
off_t V1_write_line_pg(struct Map_info *Map, int type,
- const struct line_pnts *points,
- const struct line_cats *cats)
+ const struct line_pnts *points,
+ const struct line_cats *cats)
{
#ifdef HAVE_POSTGRES
int cat;
off_t offset;
-
+
SF_FeatureType sf_type;
struct field_info *Fi;
struct Format_info_pg *pg_info;
struct Format_info_offset *offset_info;
-
+
pg_info = &(Map->fInfo.pg);
offset_info = &(pg_info->offset);
-
+
if (!pg_info->conn) {
- G_warning(_("No connection defined"));
- return -1;
+ G_warning(_("No connection defined"));
+ return -1;
}
if (!pg_info->table_name) {
- G_warning(_("PostGIS feature table not defined"));
- return -1;
+ G_warning(_("PostGIS feature table not defined"));
+ return -1;
}
if (pg_info->feature_type == SF_UNKNOWN) {
- /* create PostGIS table if doesn't exist */
- if (V2_open_new_pg(Map, type) < 0)
- return -1;
+ /* create PostGIS table if doesn't exist */
+ if (V2_open_new_pg(Map, type) < 0)
+ return -1;
}
-
- Fi = NULL; /* no attributes to be written */
+
+ Fi = NULL; /* no attributes to be written */
cat = -1;
if (cats->n_cats > 0 && Vect_get_num_dblinks(Map) > 0) {
- /* check for attributes */
- Fi = Vect_get_dblink(Map, 0);
- if (Fi) {
- if (!Vect_cat_get(cats, Fi->number, &cat))
- G_warning(_("No category defined for layer %d"), Fi->number);
- if (cats->n_cats > 1) {
- G_warning(_("Feature has more categories, using "
- "category %d (from layer %d)"),
- cat, cats->field[0]);
- }
- }
+ /* check for attributes */
+ Fi = Vect_get_dblink(Map, 0);
+ if (Fi) {
+ if (!Vect_cat_get(cats, Fi->number, &cat))
+ G_warning(_("No category defined for layer %d"), Fi->number);
+ if (cats->n_cats > 1) {
+ G_warning(_("Feature has more categories, using "
+ "category %d (from layer %d)"),
+ cat, cats->field[0]);
+ }
+ }
}
sf_type = pg_info->feature_type;
-
+
/* determine matching PostGIS feature geometry type */
if (type & (GV_POINT | GV_KERNEL)) {
- if (sf_type != SF_POINT &&
- sf_type != SF_POINT25D) {
- G_warning(_("Feature is not a point. Skipping."));
- return -1;
- }
+ if (sf_type != SF_POINT && sf_type != SF_POINT25D) {
+ G_warning(_("Feature is not a point. Skipping."));
+ return -1;
+ }
}
else if (type & GV_LINE) {
- if (sf_type != SF_LINESTRING &&
- sf_type != SF_LINESTRING25D) {
- G_warning(_("Feature is not a line. Skipping."));
- return -1;
- }
+ if (sf_type != SF_LINESTRING && sf_type != SF_LINESTRING25D) {
+ G_warning(_("Feature is not a line. Skipping."));
+ return -1;
+ }
}
else if (type & GV_BOUNDARY) {
- if (sf_type != SF_POLYGON) {
- G_warning(_("Feature is not a polygon. Skipping."));
- return -1;
- }
+ if (sf_type != SF_POLYGON) {
+ G_warning(_("Feature is not a polygon. Skipping."));
+ return -1;
+ }
}
else if (type & GV_FACE) {
- if (sf_type != SF_POLYGON25D) {
- G_warning(_("Feature is not a face. Skipping."));
- return -1;
- }
+ if (sf_type != SF_POLYGON25D) {
+ G_warning(_("Feature is not a face. Skipping."));
+ return -1;
+ }
}
else {
- G_warning(_("Unsupported feature type (%d)"), type);
- return -1;
+ G_warning(_("Unsupported feature type (%d)"), type);
+ return -1;
}
G_debug(3, "V1_write_line_pg(): type = %d n_points = %d cat = %d",
- type, points->n_points, cat);
+ type, points->n_points, cat);
if (sf_type == SF_POLYGON || sf_type == SF_POLYGON25D) {
- int npoints;
-
- npoints = points->n_points - 1;
- if (points->x[0] != points->x[npoints] ||
- points->y[0] != points->y[npoints] ||
- points->z[0] != points->z[npoints]) {
- G_warning(_("Boundary is not closed. Skipping."));
- return -1;
- }
+ int npoints;
+
+ npoints = points->n_points - 1;
+ if (points->x[0] != points->x[npoints] ||
+ points->y[0] != points->y[npoints] ||
+ points->z[0] != points->z[npoints]) {
+ G_warning(_("Boundary is not closed. Skipping."));
+ return -1;
+ }
}
/* write feature's geometry and fid */
if (-1 == write_feature(pg_info, type, points,
- Vect_is_3d(Map) ? WITH_Z : WITHOUT_Z,
- cat, Fi)) {
- execute(pg_info->conn, "ROLLBACK");
- return -1;
+ Vect_is_3d(Map) ? WITH_Z : WITHOUT_Z, cat, Fi)) {
+ execute(pg_info->conn, "ROLLBACK");
+ return -1;
}
/* update offset array */
if (offset_info->array_num >= offset_info->array_alloc) {
- offset_info->array_alloc += 1000;
- offset_info->array = (int *) G_realloc(offset_info->array,
- offset_info->array_alloc *
- sizeof(int));
+ offset_info->array_alloc += 1000;
+ offset_info->array = (int *)G_realloc(offset_info->array,
+ offset_info->array_alloc *
+ sizeof(int));
}
offset = offset_info->array_num;
-
+
offset_info->array[offset_info->array_num++] = cat;
if (sf_type == SF_POLYGON || sf_type == SF_POLYGON25D) {
- /* register first part in offset array */
- offset_info->array[offset_info->array_num++] = 0;
+ /* register first part in offset array */
+ offset_info->array[offset_info->array_num++] = 0;
}
G_debug(3, "V1_write_line_pg(): -> offset = %lu offset_num = %d cat = %d",
- (unsigned long) offset, offset_info->array_num, cat);
+ (unsigned long)offset, offset_info->array_num, cat);
return offset;
#else
@@ -194,27 +190,28 @@
}
/*!
- \brief Rewrites feature at the given offset (level 1) (PostGIS interface)
-
- \param Map pointer to Map_info structure
- \param offset feature offset
- \param type feature type (GV_POINT, GV_LINE, ...)
- \param points feature geometry
- \param cats feature categories
-
- \return feature offset (rewriten feature)
- \return -1 on error
-*/
-off_t V1_rewrite_line_pg(struct Map_info *Map,
- int line, int type, off_t offset,
- const struct line_pnts *points, const struct line_cats *cats)
+ \brief Rewrites feature at the given offset (level 1) (PostGIS interface)
+
+ \param Map pointer to Map_info structure
+ \param offset feature offset
+ \param type feature type (GV_POINT, GV_LINE, ...)
+ \param points feature geometry
+ \param cats feature categories
+
+ \return feature offset (rewriten feature)
+ \return -1 on error
+ */
+off_t V1_rewrite_line_pg(struct Map_info * Map,
+ int line, int type, off_t offset,
+ const struct line_pnts * points,
+ const struct line_cats * cats)
{
G_debug(3, "V1_rewrite_line_pg(): line=%d type=%d offset=%llu",
- line, type, offset);
+ line, type, offset);
#ifdef HAVE_POSTGRES
if (type != V1_read_line_pg(Map, NULL, NULL, offset)) {
- G_warning(_("Unable to rewrite feature (incompatible feature types)"));
- return -1;
+ G_warning(_("Unable to rewrite feature (incompatible feature types)"));
+ return -1;
}
/* delete old */
@@ -228,56 +225,56 @@
}
/*!
- \brief Deletes feature at the given offset (level 1)
-
- \param Map pointer Map_info structure
- \param offset feature offset
-
- \return 0 on success
- \return -1 on error
-*/
+ \brief Deletes feature at the given offset (level 1)
+
+ \param Map pointer Map_info structure
+ \param offset feature offset
+
+ \return 0 on success
+ \return -1 on error
+ */
int V1_delete_line_pg(struct Map_info *Map, off_t offset)
{
#ifdef HAVE_POSTGRES
long fid;
char stmt[DB_SQL_MAX];
-
+
struct Format_info_pg *pg_info;
-
+
pg_info = &(Map->fInfo.pg);
-
+
if (!pg_info->conn || !pg_info->table_name) {
- G_warning(_("No connection defined"));
- return -1;
+ G_warning(_("No connection defined"));
+ return -1;
}
-
+
if (offset >= pg_info->offset.array_num) {
- G_warning(_("Invalid offset (%d)"), offset);
- return -1;
+ G_warning(_("Invalid offset (%d)"), offset);
+ return -1;
}
fid = pg_info->offset.array[offset];
-
+
G_debug(3, "V1_delete_line_pg(), offset = %lu -> fid = %ld",
- (unsigned long) offset, fid);
+ (unsigned long)offset, fid);
if (!pg_info->inTransaction) {
- /* start transaction */
- pg_info->inTransaction = TRUE;
- if (execute(pg_info->conn, "BEGIN") == -1)
- return -1;
+ /* start transaction */
+ pg_info->inTransaction = TRUE;
+ if (execute(pg_info->conn, "BEGIN") == -1)
+ return -1;
}
-
+
sprintf(stmt, "DELETE FROM %s WHERE %s = %ld",
- pg_info->table_name, pg_info->fid_column, fid);
+ pg_info->table_name, pg_info->fid_column, fid);
G_debug(2, "SQL: %s", stmt);
-
+
if (execute(pg_info->conn, stmt) == -1) {
- G_warning(_("Unable to delete feature"));
- execute(pg_info->conn, "ROLLBACK");
- return -1;
+ G_warning(_("Unable to delete feature"));
+ execute(pg_info->conn, "ROLLBACK");
+ return -1;
}
-
+
return 0;
#else
G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
@@ -287,29 +284,29 @@
#ifdef HAVE_POSTGRES
/*!
- \brief Binary data to HEX
+ \brief Binary data to HEX
- Allocated buffer should be freed by G_free().
-
- \param nbytes number of bytes to allocate
- \param wkb_data WKB data
+ Allocated buffer should be freed by G_free().
- \return allocated buffer with HEX data
-*/
+ \param nbytes number of bytes to allocate
+ \param wkb_data WKB data
+
+ \return allocated buffer with HEX data
+ */
char *binary_to_hex(int nbytes, const unsigned char *wkb_data)
{
char *hex_data;
int i, nlow, nhigh;
static const char ach_hex[] = "0123456789ABCDEF";
- hex_data = (char *) G_malloc(nbytes * 2 + 1);
+ hex_data = (char *)G_malloc(nbytes * 2 + 1);
hex_data[nbytes * 2] = '\0';
for (i = 0; i < nbytes; i++) {
- nlow = wkb_data[i] & 0x0f;
+ nlow = wkb_data[i] & 0x0f;
nhigh = (wkb_data[i] & 0xf0) >> 4;
- hex_data[i * 2] = ach_hex[nhigh];
+ hex_data[i * 2] = ach_hex[nhigh];
hex_data[i * 2 + 1] = ach_hex[nlow];
}
@@ -317,50 +314,50 @@
}
/*!
- \bried Write point into WKB buffer
+ \bried Write point into WKB buffer
- See OGRPoint::exportToWkb from GDAL/OGR library
+ See OGRPoint::exportToWkb from GDAL/OGR library
- \param byte_order byte order (ENDIAN_LITTLE or BIG_ENDIAN)
- \param points feature geometry
- \param with_z WITH_Z for 3D data
- \param[out] nsize buffer size
-
- \return allocated WKB buffer
- \return NULL on error
-*/
+ \param byte_order byte order (ENDIAN_LITTLE or BIG_ENDIAN)
+ \param points feature geometry
+ \param with_z WITH_Z for 3D data
+ \param[out] nsize buffer size
+
+ \return allocated WKB buffer
+ \return NULL on error
+ */
unsigned char *point_to_wkb(int byte_order,
- const struct line_pnts *points, int with_z,
- int *nsize)
+ const struct line_pnts *points, int with_z,
+ int *nsize)
{
unsigned char *wkb_data;
unsigned int sf_type;
-
+
if (points->n_points != 1)
- return NULL;
-
+ return NULL;
+
/* allocate buffer */
*nsize = with_z ? 29 : 21;
wkb_data = G_malloc(*nsize);
G_zero(wkb_data, *nsize);
-
+
G_debug(5, "\t->point size=%d (with_z = %d)", *nsize, with_z);
-
+
/* set the byte order */
if (byte_order == ENDIAN_LITTLE)
- wkb_data[0] = '\001';
+ wkb_data[0] = '\001';
else
- wkb_data[0] = '\000';
-
+ wkb_data[0] = '\000';
+
/* set the geometry feature type */
sf_type = with_z ? SF_POINT25D : SF_POINT;
-
+
if (byte_order == ENDIAN_LITTLE)
- sf_type = LSBWORD32(sf_type);
+ sf_type = LSBWORD32(sf_type);
else
sf_type = MSBWORD32(sf_type);
memcpy(wkb_data + 1, &sf_type, 4);
-
+
/* copy in the raw data */
memcpy(wkb_data + 5, &(points->x[0]), 8);
memcpy(wkb_data + 5 + 8, &(points->y[0]), 8);
@@ -371,9 +368,9 @@
/* swap if needed */
if (byte_order == ENDIAN_BIG) {
- SWAPDOUBLE(wkb_data + 5);
+ SWAPDOUBLE(wkb_data + 5);
SWAPDOUBLE(wkb_data + 5 + 8);
-
+
if (with_z)
SWAPDOUBLE(wkb_data + 5 + 16);
}
@@ -382,28 +379,28 @@
}
/*!
- \bried Write linestring into WKB buffer
+ \bried Write linestring into WKB buffer
- See OGRLineString::exportToWkb from GDAL/OGR library
+ See OGRLineString::exportToWkb from GDAL/OGR library
- \param byte_order byte order (ENDIAN_LITTLE or ENDIAN_BIG)
- \param points feature geometry
- \param with_z WITH_Z for 3D data
- \param[out] nsize buffer size
-
- \return allocated WKB buffer
- \return NULL on error
-*/
+ \param byte_order byte order (ENDIAN_LITTLE or ENDIAN_BIG)
+ \param points feature geometry
+ \param with_z WITH_Z for 3D data
+ \param[out] nsize buffer size
+
+ \return allocated WKB buffer
+ \return NULL on error
+ */
unsigned char *linestring_to_wkb(int byte_order,
- const struct line_pnts *points, int with_z,
- int *nsize)
+ const struct line_pnts *points, int with_z,
+ int *nsize)
{
int i, point_size;
unsigned char *wkb_data;
unsigned int sf_type;
if (points->n_points < 1)
- return NULL;
+ return NULL;
/* allocate buffer */
point_size = 8 * (with_z ? 3 : 2);
@@ -415,42 +412,41 @@
/* set the byte order */
if (byte_order == ENDIAN_LITTLE)
- wkb_data[0] = '\001';
+ wkb_data[0] = '\001';
else
- wkb_data[0] = '\000';
+ wkb_data[0] = '\000';
/* set the geometry feature type */
sf_type = with_z ? SF_LINESTRING25D : SF_LINESTRING;
-
+
if (byte_order == ENDIAN_LITTLE)
- sf_type = LSBWORD32(sf_type);
+ sf_type = LSBWORD32(sf_type);
else
sf_type = MSBWORD32(sf_type);
memcpy(wkb_data + 1, &sf_type, 4);
-
+
/* copy in the data count */
memcpy(wkb_data + 5, &(points->n_points), 4);
-
+
/* copy in the raw data */
for (i = 0; i < points->n_points; i++) {
- memcpy(wkb_data + 9 + point_size * i, &(points->x[i]), 8);
- memcpy(wkb_data + 9 + 8 + point_size * i, &(points->y[i]), 8);
-
- if (with_z) {
- memcpy(wkb_data + 9 + 16 + point_size * i, &(points->z[i]), 8);
- }
+ memcpy(wkb_data + 9 + point_size * i, &(points->x[i]), 8);
+ memcpy(wkb_data + 9 + 8 + point_size * i, &(points->y[i]), 8);
+
+ if (with_z) {
+ memcpy(wkb_data + 9 + 16 + point_size * i, &(points->z[i]), 8);
+ }
}
-
+
/* swap if needed */
if (byte_order == ENDIAN_BIG) {
int npoints, nitems;
-
+
npoints = SWAP32(points->n_points);
- memcpy(wkb_data+5, &npoints, 4);
+ memcpy(wkb_data + 5, &npoints, 4);
- nitems = (with_z ? 3 : 2) * points->n_points;
- for(i = 0; i < nitems; i++ )
- {
+ nitems = (with_z ? 3 : 2) * points->n_points;
+ for (i = 0; i < nitems; i++) {
SWAPDOUBLE(wkb_data + 9 + 4 + 8 * i);
}
}
@@ -459,28 +455,28 @@
}
/*!
- \bried Write polygon into WKB buffer
+ \bried Write polygon into WKB buffer
- See OGRPolygon::exportToWkb from GDAL/OGR library
+ See OGRPolygon::exportToWkb from GDAL/OGR library
- \param byte_order byte order (ENDIAN_LITTLE or ENDIAN_BIG)
- \param points feature geometry
- \param with_z WITH_Z for 3D data
- \param[out] nsize buffer size
-
- \return allocated WKB buffer
- \return NULL on error
-*/
+ \param byte_order byte order (ENDIAN_LITTLE or ENDIAN_BIG)
+ \param points feature geometry
+ \param with_z WITH_Z for 3D data
+ \param[out] nsize buffer size
+
+ \return allocated WKB buffer
+ \return NULL on error
+ */
unsigned char *polygon_to_wkb(int byte_order,
- const struct line_pnts *points, int with_z,
- int *nsize)
+ const struct line_pnts *points, int with_z,
+ int *nsize)
{
int i, point_size, nrings;
unsigned char *wkb_data;
unsigned int sf_type;
if (points->n_points < 3)
- return NULL;
+ return NULL;
/* allocate buffer */
point_size = 8 * (with_z ? 3 : 2);
@@ -491,53 +487,54 @@
G_zero(wkb_data, *nsize);
G_debug(5, "\t->polygon size=%d (with_z = %d)", *nsize, with_z);
-
+
/* set the byte order */
if (byte_order == ENDIAN_LITTLE)
- wkb_data[0] = '\001';
+ wkb_data[0] = '\001';
else
- wkb_data[0] = '\000';
+ wkb_data[0] = '\000';
/* set the geometry feature type */
sf_type = with_z ? SF_POLYGON25D : SF_POLYGON;
-
+
if (byte_order == ENDIAN_LITTLE)
- sf_type = LSBWORD32(sf_type);
+ sf_type = LSBWORD32(sf_type);
else
sf_type = MSBWORD32(sf_type);
memcpy(wkb_data + 1, &sf_type, 4);
-
+
/* copy in the raw data */
if (byte_order == ENDIAN_BIG) {
int ncount;
-
+
ncount = SWAP32(nrings);
memcpy(wkb_data + 5, &ncount, 4);
}
else {
memcpy(wkb_data + 5, &nrings, 4);
}
-
+
/* serialize ring */
memcpy(wkb_data + 9, &(points->n_points), 4);
for (i = 0; i < points->n_points; i++) {
- memcpy(wkb_data + 9 + 4 + point_size * i, &(points->x[i]), 8);
- memcpy(wkb_data + 9 + 4 + 8 + point_size * i, &(points->y[i]), 8);
-
- if (with_z) {
- memcpy(wkb_data + 9 + 4 + 16 + point_size * i, &(points->z[i]), 8);
- }
+ memcpy(wkb_data + 9 + 4 + point_size * i, &(points->x[i]), 8);
+ memcpy(wkb_data + 9 + 4 + 8 + point_size * i, &(points->y[i]), 8);
+
+ if (with_z) {
+ memcpy(wkb_data + 9 + 4 + 16 + point_size * i, &(points->z[i]),
+ 8);
+ }
}
/* swap if needed */
if (byte_order == ENDIAN_BIG) {
int npoints, nitems;
-
+
npoints = SWAP32(points->n_points);
- memcpy(wkb_data+5, &npoints, 4);
+ memcpy(wkb_data + 5, &npoints, 4);
- nitems = (with_z ? 3 : 2) * points->n_points;
- for(i = 0; i < nitems; i++ ) {
+ nitems = (with_z ? 3 : 2) * points->n_points;
+ for (i = 0; i < nitems; i++) {
SWAPDOUBLE(wkb_data + 9 + 4 + 8 * i);
}
}
@@ -546,65 +543,65 @@
}
/*!
- \brief Insert feature into table
+ \brief Insert feature into table
- \param pg_info pointer to Format_info_pg struct
- \param type feature type (GV_POINT, GV_LINE, ...)
- \param points pointer to line_pnts struct
- \param with_z WITH_Z for 3D data
- \param cat category number (-1 for no category)
- \param Fi pointer to field_info (attributes to copy, NULL for no attributes)
+ \param pg_info pointer to Format_info_pg struct
+ \param type feature type (GV_POINT, GV_LINE, ...)
+ \param points pointer to line_pnts struct
+ \param with_z WITH_Z for 3D data
+ \param cat category number (-1 for no category)
+ \param Fi pointer to field_info (attributes to copy, NULL for no attributes)
- \return -1 on error
- \retirn 0 on success
-*/
+ \return -1 on error
+ \retirn 0 on success
+ */
int write_feature(struct Format_info_pg *pg_info,
- int type, const struct line_pnts *points, int with_z,
- int cat, const struct field_info *Fi)
+ int type, const struct line_pnts *points, int with_z,
+ int cat, const struct field_info *Fi)
{
- int byte_order, nbytes, nsize;
+ int byte_order, nbytes, nsize;
unsigned int sf_type;
unsigned char *wkb_data;
- char *stmt, *text_data, *text_data_p, *hex_data;
-
+ char *stmt, *text_data, *text_data_p, *hex_data;
+
if (with_z && pg_info->coor_dim != 3) {
- G_warning(_("Trying to insert 3D data into feature table "
- "which store 2D data only"));
- return -1;
+ G_warning(_("Trying to insert 3D data into feature table "
+ "which store 2D data only"));
+ return -1;
}
if (!with_z && pg_info->coor_dim != 2) {
- G_warning(_("Trying to insert 2D data into feature table "
- "which store 3D data only"));
- return -1;
+ G_warning(_("Trying to insert 2D data into feature table "
+ "which store 3D data only"));
+ return -1;
}
-
+
byte_order = ENDIAN_LITTLE; /* TODO: get endianness for system from dig__byte_order_out()? */
-
+
/* get wkb data */
nbytes = -1;
wkb_data = NULL;
- if (type == GV_POINT)
- wkb_data = point_to_wkb(byte_order, points, with_z, &nbytes);
+ if (type == GV_POINT)
+ wkb_data = point_to_wkb(byte_order, points, with_z, &nbytes);
else if (type == GV_LINE)
- wkb_data = linestring_to_wkb(byte_order, points, with_z, &nbytes);
- else if (type == GV_BOUNDARY)
- wkb_data = polygon_to_wkb(byte_order, points, with_z, &nbytes);
-
+ wkb_data = linestring_to_wkb(byte_order, points, with_z, &nbytes);
+ else if (type == GV_BOUNDARY)
+ wkb_data = polygon_to_wkb(byte_order, points, with_z, &nbytes);
+
if (!wkb_data || nbytes < 1) {
- G_warning(_("Unsupported feature type %d"), type);
- return -1;
+ G_warning(_("Unsupported feature type %d"), type);
+ return -1;
}
-
+
/* When converting to hex, each byte takes 2 hex characters. In
addition we add in 8 characters to represent the SRID integer
in hex, and one for a null terminator */
nsize = nbytes * 2 + 8 + 1;
- text_data = text_data_p = (char *) G_malloc(nsize);
-
+ text_data = text_data_p = (char *)G_malloc(nsize);
+
/* convert the 1st byte, which is the endianess flag, to hex */
hex_data = binary_to_hex(1, wkb_data);
strcpy(text_data_p, hex_data);
- G_free (hex_data);
+ G_free(hex_data);
text_data_p += 2;
/* get the geom type which is bytes 2 through 5 */
@@ -612,25 +609,27 @@
/* add the SRID flag if an SRID is provided */
if (pg_info->srid > 0) {
- unsigned int srs_flag;
- /* change the flag to little endianess */
+ unsigned int srs_flag;
+
+ /* change the flag to little endianess */
srs_flag = LSBWORD32(WKBSRIDFLAG);
/* apply the flag */
sf_type = sf_type | srs_flag;
}
/* write the geom type which is 4 bytes */
- hex_data = binary_to_hex(4, (unsigned char*) &sf_type);
+ hex_data = binary_to_hex(4, (unsigned char *)&sf_type);
strcpy(text_data_p, hex_data);
G_free(hex_data);
text_data_p += 8;
/* include SRID if provided */
if (pg_info->srid > 0) {
- unsigned int srs_id;
+ unsigned int srs_id;
+
/* force the srsid to little endianess */
srs_id = LSBWORD32(pg_info->srid);
- hex_data = binary_to_hex(sizeof(srs_id), (unsigned char*) &srs_id);
+ hex_data = binary_to_hex(sizeof(srs_id), (unsigned char *)&srs_id);
strcpy(text_data_p, hex_data);
G_free(hex_data);
text_data_p += 8;
@@ -645,157 +644,157 @@
/* build INSERT statement */
stmt = build_insert_stmt(pg_info, text_data, cat, Fi);
G_debug(2, "SQL: %s", stmt);
-
+
if (!pg_info->inTransaction) {
- /* start transaction */
- pg_info->inTransaction = TRUE;
- if (execute(pg_info->conn, "BEGIN") == -1)
- return -1;
+ /* start transaction */
+ pg_info->inTransaction = TRUE;
+ if (execute(pg_info->conn, "BEGIN") == -1)
+ return -1;
}
-
+
if (execute(pg_info->conn, stmt) == -1) {
- /* rollback transaction */
- execute(pg_info->conn, "ROLLBACK");
- return -1;
+ /* rollback transaction */
+ execute(pg_info->conn, "ROLLBACK");
+ return -1;
}
G_free(wkb_data);
G_free(text_data);
G_free(stmt);
-
+
return 0;
}
/*!
- \brief Build INSERT statement to insert new feature to the table
+ \brief Build INSERT statement to insert new feature to the table
- \param pg_info pointer to Format_info_pg structure
- \param cat category number (or -1 for no category)
- \param Fi pointer to field_info structure (NULL for no attributes)
+ \param pg_info pointer to Format_info_pg structure
+ \param cat category number (or -1 for no category)
+ \param Fi pointer to field_info structure (NULL for no attributes)
- \return allocated string with INSERT statement
-*/
+ \return allocated string with INSERT statement
+ */
char *build_insert_stmt(const struct Format_info_pg *pg_info,
- const char *geom_data,
- int cat, const struct field_info *Fi)
+ const char *geom_data,
+ int cat, const struct field_info *Fi)
{
char *stmt, buf[DB_SQL_MAX];
-
+
stmt = NULL;
if (Fi && cat > -1) {
- int col, ncol, more;
- int sqltype, ctype;
- char buf_val[DB_SQL_MAX], buf_tmp[DB_SQL_MAX];
- char *str_val;
-
- const char *colname;
-
- dbString dbstmt;
- dbCursor cursor;
- dbTable *table;
- dbColumn *column;
- dbValue *value;
-
- db_init_string(&dbstmt);
- buf_val[0] = '\0';
-
- /* read & set attributes */
- sprintf(buf, "SELECT * FROM %s WHERE %s = %d", Fi->table, Fi->key,
- cat);
- G_debug(4, "SQL: %s", buf);
- db_set_string(&dbstmt, buf);
+ int col, ncol, more;
+ int sqltype, ctype;
+ char buf_val[DB_SQL_MAX], buf_tmp[DB_SQL_MAX];
+ char *str_val;
- /* prepare INSERT statement */
- sprintf(buf, "INSERT INTO \"%s\".\"%s\" (%s",
- pg_info->schema_name, pg_info->table_name,
- pg_info->geom_column);
-
- /* select data */
- if (db_open_select_cursor(pg_info->dbdriver, &dbstmt,
- &cursor, DB_SEQUENTIAL) != DB_OK) {
- G_warning(_("Unable to select attributes for category %d"),
- cat);
- }
- else {
- if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK) {
- G_warning(_("Unable to fetch data from table <%s>"),
- Fi->table);
- }
-
- if (!more) {
- G_warning(_("No database record for category %d, "
- "no attributes will be written"), cat);
- }
- else {
- table = db_get_cursor_table(&cursor);
- ncol = db_get_table_number_of_columns(table);
+ const char *colname;
- for (col = 0; col < ncol; col++) {
- column = db_get_table_column(table, col);
- colname = db_get_column_name(column);
-
- /* skip fid column */
- if (strcmp(pg_info->fid_column, colname) == 0)
- continue;
-
- /* -> columns */
- sprintf(buf_tmp, ",%s", colname);
- strcat(buf, buf_tmp);
-
- /* -> values */
- value = db_get_column_value(column);
- /* for debug only */
- db_convert_column_value_to_string(column, &dbstmt);
- G_debug(2, "col %d : val = %s", col,
- db_get_string(&dbstmt));
+ dbString dbstmt;
+ dbCursor cursor;
+ dbTable *table;
+ dbColumn *column;
+ dbValue *value;
- sqltype = db_get_column_sqltype(column);
- ctype = db_sqltype_to_Ctype(sqltype);
+ db_init_string(&dbstmt);
+ buf_val[0] = '\0';
- /* prevent writing NULL values */
- if (!db_test_value_isnull(value)) {
- switch (ctype) {
- case DB_C_TYPE_INT:
- sprintf(buf_tmp, ",%d", db_get_value_int(value));
- break;
- case DB_C_TYPE_DOUBLE:
- sprintf(buf_tmp, ",%.14f", db_get_value_double(value));
- break;
- case DB_C_TYPE_STRING:
- str_val = G_store(db_get_value_string(value));
- G_str_to_sql(str_val);
- sprintf(buf_tmp, ",'%s'", str_val);
- G_free(str_val);
- break;
- case DB_C_TYPE_DATETIME:
- db_convert_column_value_to_string(column,
- &dbstmt);
- sprintf(buf_tmp, ",%s", db_get_string(&dbstmt));
- break;
- default:
- G_warning(_("Unsupported column type %d"), ctype);
- sprintf(buf_tmp, ",NULL");
- break;
- }
- }
- else {
- sprintf(buf_tmp, ",NULL");
- }
- strcat(buf_val, buf_tmp);
- }
-
- G_asprintf(&stmt, "%s) VALUES ('%s'::GEOMETRY%s)",
- buf, geom_data, buf_val);
- }
- }
+ /* read & set attributes */
+ sprintf(buf, "SELECT * FROM %s WHERE %s = %d", Fi->table, Fi->key,
+ cat);
+ G_debug(4, "SQL: %s", buf);
+ db_set_string(&dbstmt, buf);
+
+ /* prepare INSERT statement */
+ sprintf(buf, "INSERT INTO \"%s\".\"%s\" (%s",
+ pg_info->schema_name, pg_info->table_name,
+ pg_info->geom_column);
+
+ /* select data */
+ if (db_open_select_cursor(pg_info->dbdriver, &dbstmt,
+ &cursor, DB_SEQUENTIAL) != DB_OK) {
+ G_warning(_("Unable to select attributes for category %d"), cat);
+ }
+ else {
+ if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK) {
+ G_warning(_("Unable to fetch data from table <%s>"),
+ Fi->table);
+ }
+
+ if (!more) {
+ G_warning(_("No database record for category %d, "
+ "no attributes will be written"), cat);
+ }
+ else {
+ table = db_get_cursor_table(&cursor);
+ ncol = db_get_table_number_of_columns(table);
+
+ for (col = 0; col < ncol; col++) {
+ column = db_get_table_column(table, col);
+ colname = db_get_column_name(column);
+
+ /* skip fid column */
+ if (strcmp(pg_info->fid_column, colname) == 0)
+ continue;
+
+ /* -> columns */
+ sprintf(buf_tmp, ",%s", colname);
+ strcat(buf, buf_tmp);
+
+ /* -> values */
+ value = db_get_column_value(column);
+ /* for debug only */
+ db_convert_column_value_to_string(column, &dbstmt);
+ G_debug(2, "col %d : val = %s", col,
+ db_get_string(&dbstmt));
+
+ sqltype = db_get_column_sqltype(column);
+ ctype = db_sqltype_to_Ctype(sqltype);
+
+ /* prevent writing NULL values */
+ if (!db_test_value_isnull(value)) {
+ switch (ctype) {
+ case DB_C_TYPE_INT:
+ sprintf(buf_tmp, ",%d", db_get_value_int(value));
+ break;
+ case DB_C_TYPE_DOUBLE:
+ sprintf(buf_tmp, ",%.14f",
+ db_get_value_double(value));
+ break;
+ case DB_C_TYPE_STRING:
+ str_val = G_store(db_get_value_string(value));
+ G_str_to_sql(str_val);
+ sprintf(buf_tmp, ",'%s'", str_val);
+ G_free(str_val);
+ break;
+ case DB_C_TYPE_DATETIME:
+ db_convert_column_value_to_string(column,
+ &dbstmt);
+ sprintf(buf_tmp, ",%s", db_get_string(&dbstmt));
+ break;
+ default:
+ G_warning(_("Unsupported column type %d"), ctype);
+ sprintf(buf_tmp, ",NULL");
+ break;
+ }
+ }
+ else {
+ sprintf(buf_tmp, ",NULL");
+ }
+ strcat(buf_val, buf_tmp);
+ }
+
+ G_asprintf(&stmt, "%s) VALUES ('%s'::GEOMETRY%s)",
+ buf, geom_data, buf_val);
+ }
+ }
}
if (!stmt) {
- /* no attributes */
- G_asprintf(&stmt, "INSERT INTO \"%s\".\"%s\" (%s) VALUES "
- "('%s'::GEOMETRY)",
- pg_info->schema_name, pg_info->table_name,
- pg_info->geom_column, geom_data);
+ /* no attributes */
+ G_asprintf(&stmt, "INSERT INTO \"%s\".\"%s\" (%s) VALUES "
+ "('%s'::GEOMETRY)",
+ pg_info->schema_name, pg_info->table_name,
+ pg_info->geom_column, geom_data);
}
return stmt;
More information about the grass-commit
mailing list