[GRASS-SVN] r52076 - grass/trunk/lib/vector/Vlib
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Jun 15 03:48:59 PDT 2012
Author: martinl
Date: 2012-06-15 03:48:58 -0700 (Fri, 15 Jun 2012)
New Revision: 52076
Modified:
grass/trunk/lib/vector/Vlib/read_pg.c
Log:
vlib/pg: fix for polygons with more then 20 rings
build centroids from spidx or postgis topo
Modified: grass/trunk/lib/vector/Vlib/read_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/read_pg.c 2012-06-15 10:20:33 UTC (rev 52075)
+++ grass/trunk/lib/vector/Vlib/read_pg.c 2012-06-15 10:48:58 UTC (rev 52076)
@@ -32,7 +32,7 @@
static int read_next_line_pg(struct Map_info *,
struct line_pnts *, struct line_cats *, int);
-SF_FeatureType get_feature(struct Format_info_pg *, int, const char *);
+SF_FeatureType get_feature(struct Format_info_pg *, int, int);
static unsigned char *hex_to_wkb(const char *, int *);
static int point_from_wkb(const unsigned char *, int, int, int,
struct line_pnts *);
@@ -46,7 +46,8 @@
static int error_corrupted_data(const char *);
static void reallocate_cache(struct Format_info_cache *, int);
static void add_fpart(struct feat_parts *, SF_FeatureType, int, int);
-static int read_centroid_pg(struct Format_info_pg *, int, struct line_pnts *);
+static int get_centroid_topo(struct Format_info_pg *, int, struct line_pnts *);
+static int get_centroid(struct Map_info *, int, struct line_pnts *);
#endif
/*!
@@ -249,7 +250,7 @@
G_debug(3, "read (%s) feature (fid = %ld) to cache",
pg_info->table_name, fid);
- get_feature(pg_info, fid, NULL);
+ get_feature(pg_info, fid, -1);
if (pg_info->cache.sf_type == SF_NONE) {
G_warning(_("Feature %d without geometry skipped"), fid);
@@ -287,8 +288,7 @@
struct line_cats *line_c, int line)
{
#ifdef HAVE_POSTGRES
- int type;
- char *topotable_name;
+ int type, fid;
struct Format_info_pg *pg_info;
struct P_line *Line;
@@ -314,20 +314,21 @@
if (line_c)
Vect_cat_set(line_c, 1, (int) Line->offset);
- if (Line->type == GV_POINT)
- topotable_name = "node";
- else if (Line->type & GV_LINES)
- topotable_name = "edge";
- else if (Line->type == GV_CENTROID) {
- return read_centroid_pg(pg_info, (int) Line->offset, line_p);
+ if (Line->type == GV_CENTROID) {
+ if (pg_info->toposchema_name)
+ return get_centroid_topo(pg_info, line, line_p);
+ else
+ return get_centroid(Map, line, line_p);
}
- else {
- G_warning(_("Unsupported feature type %d"), Line->type);
- return -1;
- }
- get_feature(pg_info, Line->offset, topotable_name);
+ /* get feature id */
+ if (pg_info->toposchema_name)
+ fid = Line->offset;
+ else
+ fid = pg_info->offset.array[Line->offset];
+ get_feature(pg_info, fid, Line->type);
+
if (pg_info->cache.sf_type == SF_NONE) {
G_warning(_("Feature %d without geometry skipped"), Line->offset);
return -1;
@@ -393,7 +394,7 @@
/* 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, NULL);
+ sf_type = get_feature(pg_info, -1, -1);
if (sf_type == SF_NONE) {
G_warning(_("Feature %d without geometry skipped"), line);
@@ -462,15 +463,14 @@
\return simple feature type (SF_POINT, SF_LINESTRING, ...)
\return -1 on error
*/
-SF_FeatureType get_feature(struct Format_info_pg *pg_info, int fid,
- const char *topotable_name)
+SF_FeatureType get_feature(struct Format_info_pg *pg_info, int fid, int type)
{
char *data;
char stmt[DB_SQL_MAX];
int left_face, right_face;
- if (!topotable_name && !pg_info->geom_column) {
- G_warning(_("No geometry column defined"));
+ if (!pg_info->geom_column && !pg_info->topogeom_column) {
+ G_warning(_("No geometry or topo geometry column defined"));
return -1;
}
if (fid < 1) {
@@ -481,7 +481,7 @@
}
}
else {
- if (!topotable_name && !pg_info->fid_column) {
+ if (!pg_info->fid_column) {
G_warning(_("Random access not supported. "
"Primary key not defined."));
return -1;
@@ -490,7 +490,7 @@
if (execute(pg_info->conn, "BEGIN") == -1)
return -1;
- if (!topotable_name) {
+ if (!pg_info->toposchema_name) {
/* simple feature access */
sprintf(stmt,
"DECLARE %s_%s%p CURSOR FOR SELECT %s FROM \"%s\".\"%s\" "
@@ -500,6 +500,18 @@
}
else {
/* topological access */
+ char *topotable_name;
+
+ if (type == GV_POINT)
+ topotable_name = "node";
+ else if (type & GV_LINES)
+ topotable_name = "edge";
+ else {
+ G_warning(_("Unsupported feature type %d"), type);
+ execute(pg_info->conn, "ROLLBACK");
+ return -1;
+ }
+
sprintf(stmt,
"DECLARE %s_%s%p CURSOR FOR SELECT geom,left_face,right_face "
" FROM \"%s\".\"%s\" "
@@ -1219,7 +1231,7 @@
cache->lines_alloc = 1;
}
else {
- cache->lines_alloc += 20;
+ cache->lines_alloc += num;
}
cache->lines = (struct line_pnts **)G_realloc(cache->lines,
@@ -1229,7 +1241,7 @@
cache->lines_alloc * sizeof(int));
if (cache->lines_alloc > 1) {
- for (i = cache->lines_alloc - 20; i < cache->lines_alloc; i++) {
+ for (i = cache->lines_alloc - num; i < cache->lines_alloc; i++) {
cache->lines[i] = Vect_new_line_struct();
cache->lines_types[i] = -1;
}
@@ -1250,7 +1262,7 @@
if (fparts->a_parts == 0)
fparts->a_parts = 1;
else
- fparts->a_parts += 20;
+ fparts->a_parts += fparts->n_parts;
fparts->ftype = (SF_FeatureType *) G_realloc(fparts->ftype,
fparts->a_parts *
@@ -1268,8 +1280,18 @@
fparts->n_parts++;
}
-int read_centroid_pg(struct Format_info_pg *pg_info,
- int centroid, struct line_pnts *line_p)
+/*
+ \brief Get centroid from PostGIS topology
+
+ \param pg_info pointer to Format_info_pg
+ \param centroid centroid id
+ \param[out] line_p output geometry
+
+ \return GV_CENTROID on success
+ \return -1 on error
+*/
+int get_centroid_topo(struct Format_info_pg *pg_info,
+ int centroid, struct line_pnts *line_p)
{
char stmt[DB_SQL_MAX];
char *data;
@@ -1300,4 +1322,51 @@
return GV_CENTROID;
}
+
+/*
+ \brief Get centroid
+
+ \param pg_info pointer to Format_info_pg
+ \param centroid centroid id
+ \param[out] line_p output geometry
+
+ \return GV_CENTROID on success
+ \return -1 on error
+*/
+int get_centroid(struct Map_info *Map, int centroid,
+ struct line_pnts *line_p)
+{
+ int i, found;
+ struct bound_box box;
+ struct boxlist list;
+ struct P_line *Line;
+ struct P_topo_c *topo;
+
+ Line = Map->plus.Line[centroid];
+ 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] == centroid) {
+ found = i;
+ break;
+ }
+ }
+
+ if (found == -1)
+ return -1;
+
+ if (line_p) {
+ Vect_reset_line(line_p);
+ Vect_append_point(line_p, list.box[found].E, list.box[found].N, 0.0);
+ }
+
+ return GV_CENTROID;
+}
#endif
More information about the grass-commit
mailing list