Kaynağa Gözat

vlib/pg: fix sequatial access when features cached
update category index


git-svn-id: https://svn.osgeo.org/grass/grass/trunk@58299 15284696-431f-4ddb-bdfa-cd5b030d7da7

Martin Landa 11 yıl önce
ebeveyn
işleme
0634382e12

+ 10 - 0
lib/vector/Vlib/build_pg.c

@@ -20,6 +20,8 @@
 #include <grass/vector.h>
 #include <grass/vector.h>
 #include <grass/glocale.h>
 #include <grass/glocale.h>
 
 
+#include "local_proto.h"
+
 #ifdef HAVE_POSTGRES
 #ifdef HAVE_POSTGRES
 #include "pg_local_proto.h"
 #include "pg_local_proto.h"
 
 
@@ -156,6 +158,10 @@ int build_topo(struct Map_info *Map, int build)
     if (build < GV_BUILD_BASE)
     if (build < GV_BUILD_BASE)
         return 1; /* nothing to print */
         return 1; /* nothing to print */
     
     
+    /* cache features to speed-up random access (when attaching isles
+       to areas) */
+    if (build >= GV_BUILD_BASE)
+        pg_info->cache.ctype = CACHE_MAP;
     /* update TopoGeometry based on GRASS-like topology */
     /* update TopoGeometry based on GRASS-like topology */
     Vect_build_nat(Map, build);
     Vect_build_nat(Map, build);
     
     
@@ -547,6 +553,10 @@ int write_nodes(const struct Plus_head *plus,
     const struct Format_info_offset *offset;
     const struct Format_info_offset *offset;
 
 
     offset = &(pg_info->offset);
     offset = &(pg_info->offset);
+    
+    if (offset->array_num < 1) /* nothing to write */
+        return 0;
+    
     if (plus->n_nodes != offset->array_num) {
     if (plus->n_nodes != offset->array_num) {
         G_warning(_("Unable to write nodes, offset array mismatch"));
         G_warning(_("Unable to write nodes, offset array mismatch"));
         return -1;
         return -1;

+ 42 - 23
lib/vector/Vlib/open_pg.c

@@ -346,8 +346,9 @@ int Vect_open_topo_pg(struct Map_info *Map, int head_only)
     
     
     /* free and init plus structure */
     /* free and init plus structure */
     dig_init_plus(plus);
     dig_init_plus(plus);
-    plus->Spidx_new = TRUE;
-    
+    plus->Spidx_new = TRUE;   /* force to create new spatial index */
+    plus->update_cidx = TRUE; /* force to update category index */
+
     return Vect__load_plus_pg(Map, head_only);
     return Vect__load_plus_pg(Map, head_only);
 #else
 #else
     G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
     G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
@@ -779,7 +780,8 @@ struct P_node *read_p_node(struct Plus_head *plus, int n,
         node->z = 0.0;
         node->z = 0.0;
     
     
     /* update spatial index */
     /* update spatial index */
-    dig_spidx_add_node(plus, n, node->x, node->y, node->z);
+    if (plus->Spidx_new)
+        dig_spidx_add_node(plus, n, node->x, node->y, node->z);
     
     
     if (plus->uplist.do_uplist)
     if (plus->uplist.do_uplist)
         /* collect updated nodes if requested */
         /* collect updated nodes if requested */
@@ -812,12 +814,9 @@ struct P_line *read_p_line(struct Plus_head *plus, int n,
                            const struct line_data *data,
                            const struct line_data *data,
                            struct Format_info_cache *cache)
                            struct Format_info_cache *cache)
 {
 {
-    int tp;
+    int tp, cat;
     struct P_line *line;
     struct P_line *line;
     
     
-    struct line_pnts *points;
-    struct bound_box box;
-    
     if (data->start_node == 0 && data->end_node == 0) {
     if (data->start_node == 0 && data->end_node == 0) {
         if (data->left_face == 0)
         if (data->left_face == 0)
             tp = GV_POINT;
             tp = GV_POINT;
@@ -880,12 +879,22 @@ struct P_line *read_p_line(struct Plus_head *plus, int n,
     }
     }
 
 
     Vect__cache_feature_pg(data->wkb_geom, FALSE, tp, cache, NULL);
     Vect__cache_feature_pg(data->wkb_geom, FALSE, tp, cache, NULL);
-    cache->lines_cats[cache->lines_num-1] = data->fid > 0 ? data->fid : -1;
-
-    points = cache->lines[cache->lines_num-1];
-    dig_line_box(points, &box);
-    dig_spidx_add_line(plus, n, &box);
+    cat = cache->lines_cats[cache->lines_num-1] = data->fid > 0 ? data->fid : -1;
 
 
+    /* update spatial index */
+    if (plus->Spidx_new) {
+        struct line_pnts *points;
+        struct bound_box box;
+    
+        points = cache->lines[cache->lines_num-1];
+        dig_line_box(points, &box);
+        dig_spidx_add_line(plus, n, &box);
+    }
+    
+    /* update category index */
+    if (plus->update_cidx)
+        dig_cidx_add_cat(plus, cat > 0 ? 1 : 0, cat > 0 ? cat : 0, n, tp);
+    
     if (plus->uplist.do_uplist) {
     if (plus->uplist.do_uplist) {
         /* collect updated lines if requested */
         /* collect updated lines if requested */
         dig_line_add_updated(plus, n);
         dig_line_add_updated(plus, n);
@@ -1202,6 +1211,7 @@ int Vect__load_plus_pg(struct Map_info *Map, int head_only)
     struct P_line *Line;
     struct P_line *Line;
     struct line_pnts *Points;
     struct line_pnts *Points;
     struct ilist *List;
     struct ilist *List;
+    struct bound_box box;
     
     
     PGresult *res;
     PGresult *res;
   
   
@@ -1357,7 +1367,6 @@ int Vect__load_plus_pg(struct Map_info *Map, int head_only)
 
 
         id = plus->n_plines + i + 1; /* points already registered */
         id = plus->n_plines + i + 1; /* points already registered */
         read_p_line(plus, id, &line_data, &(pg_info->cache));
         read_p_line(plus, id, &line_data, &(pg_info->cache));
-        /* TODO: update category index */
     }
     }
     PQclear(res);
     PQclear(res);
 
 
@@ -1433,6 +1442,8 @@ int Vect__load_plus_pg(struct Map_info *Map, int head_only)
         }
         }
     }
     }
     else {
     else {
+        int cat;
+        
         /* read areas from 'area_grass' table */
         /* read areas from 'area_grass' table */
         sprintf(stmt,
         sprintf(stmt,
                 "SELECT area_id,lines,centroid,isles FROM \"%s\".%s ORDER BY area_id",
                 "SELECT area_id,lines,centroid,isles FROM \"%s\".%s ORDER BY area_id",
@@ -1456,11 +1467,18 @@ int Vect__load_plus_pg(struct Map_info *Map, int head_only)
             read_p_area(plus, i + 1, (char *)PQgetvalue(res, i, 1),
             read_p_area(plus, i + 1, (char *)PQgetvalue(res, i, 1),
                         atoi(PQgetvalue(res, i, 2)), (char *)PQgetvalue(res, i, 3));
                         atoi(PQgetvalue(res, i, 2)), (char *)PQgetvalue(res, i, 3));
             
             
-            /* update spatial index -- needed ?
-            Vect_get_area_points(Map, i+1, Points);
-            dig_line_box(Points, &box);
-            dig_spidx_add_area(&(Map->plus), i+1, &box);
-            */
+            if (plus->Spidx_new) {
+                /* update spatial index */
+                Vect_get_area_points(Map, i+1, Points);
+                dig_line_box(Points, &box);
+                dig_spidx_add_area(&(Map->plus), i+1, &box);
+            }
+
+            if (plus->update_cidx) {
+                /* update category index */
+                cat = pg_info->cache.lines_cats[plus->Area[i+1]->centroid-1];
+                dig_cidx_add_cat(plus, cat > 0 ? 1 : 0, cat > 0 ? cat : 0, i+1, GV_AREA);
+            }
         }
         }
         PQclear(res);
         PQclear(res);
     }
     }
@@ -1494,11 +1512,12 @@ int Vect__load_plus_pg(struct Map_info *Map, int head_only)
             read_p_isle(plus, i + 1, (char *)PQgetvalue(res, i, 1),
             read_p_isle(plus, i + 1, (char *)PQgetvalue(res, i, 1),
                         atoi(PQgetvalue(res, i, 2)));
                         atoi(PQgetvalue(res, i, 2)));
 
 
-            /* update spatial index -- needed ?
-            Vect_get_isle_points(Map, i+1, Points);
-            dig_line_box(Points, &box);
-            dig_spidx_add_isle(&(Map->plus), i+1, &box);
-            */
+            if (plus->Spidx_new) {
+                /* update spatial index */
+                Vect_get_isle_points(Map, i+1, Points);
+                dig_line_box(Points, &box);
+                dig_spidx_add_isle(&(Map->plus), i+1, &box);
+            }
         }
         }
         PQclear(res);
         PQclear(res);
     }
     }

+ 13 - 8
lib/vector/Vlib/read_pg.c

@@ -362,6 +362,9 @@ int V2_read_line_pg(struct Map_info *Map, struct line_pnts *line_p,
     if (pg_info->cache.ctype == CACHE_MAP) {
     if (pg_info->cache.ctype == CACHE_MAP) {
         cache_idx = line - 1;
         cache_idx = line - 1;
         
         
+        if (cache_idx >= pg_info->cache.lines_num)
+            G_fatal_error(_("Requesting invalid feature from cache (%d). Number of features in cache: %d"),
+                          cache_idx, pg_info->cache.lines_num);
         if (pg_info->cache.lines_types[cache_idx] != Line->type)
         if (pg_info->cache.lines_types[cache_idx] != Line->type)
             G_warning(_("Feature %d: unexpected type (%d) - should be %d"), 
             G_warning(_("Feature %d: unexpected type (%d) - should be %d"), 
                       line, pg_info->cache.lines_types[cache_idx], Line->type);
                       line, pg_info->cache.lines_types[cache_idx], Line->type);
@@ -455,8 +458,7 @@ int read_next_line_pg(struct Map_info *Map,
             Vect_reset_cats(line_c);
             Vect_reset_cats(line_c);
 
 
         /* read feature to cache if necessary */
         /* read feature to cache if necessary */
-        while (pg_info->cache.ctype != CACHE_MAP &&
-               pg_info->cache.lines_next == pg_info->cache.lines_num) {
+        while (pg_info->cache.lines_next == pg_info->cache.lines_num) {
             /* cache feature -> line_p & line_c */
             /* cache feature -> line_p & line_c */
             sf_type = get_feature(pg_info, -1, -1);
             sf_type = get_feature(pg_info, -1, -1);
             
             
@@ -529,7 +531,7 @@ int read_next_line_pg(struct Map_info *Map,
                 Vect_cat_set(line_c, 1, cat);
                 Vect_cat_set(line_c, 1, cat);
         }
         }
 
 
-        pg_info->cache.lines_next++;
+        pg_info->cache.lines_next++; /* read next line from cache */
 
 
         return itype;
         return itype;
     }
     }
@@ -749,11 +751,12 @@ SF_FeatureType Vect__cache_feature_pg(const char *data, int skip_polygon,
     /* reset cache */
     /* reset cache */
     if (cache->ctype == CACHE_MAP)
     if (cache->ctype == CACHE_MAP)
         cache->lines_num++;
         cache->lines_num++;
-    else
+    else {
+        /* next to be read from cache */
+        cache->lines_next = 0;
         cache->lines_num = 1;
         cache->lines_num = 1;
+    }
     cache->fid = -1;
     cache->fid = -1;
-    /* next to be read from cache */
-    cache->lines_next = 0;
 
 
     if (fparts)
     if (fparts)
         fparts->n_parts = 0;
         fparts->n_parts = 0;
@@ -865,8 +868,10 @@ SF_FeatureType Vect__cache_feature_pg(const char *data, int skip_polygon,
         G_warning(_("Unsupported feature type %d"), ftype);
         G_warning(_("Unsupported feature type %d"), ftype);
     }
     }
 
 
-    /* read next feature from cache */
-    cache->lines_next = 0;
+    if (cache->ctype != CACHE_MAP) {
+        /* read next feature from cache */
+        cache->lines_next = 0;
+    }
 
 
     /* G_free(wkb_data); */
     /* G_free(wkb_data); */