23#include "local_proto.h"
26#include "pg_local_proto.h"
28static int build_topo(
struct Map_info *,
int);
29static int build_topogeom_stmt(
const struct Format_info_pg *,
int,
int,
int,
39static void build_stmt_id(
const void *,
int,
int,
const struct Plus_head *,
41static int create_simple_feature_from_topo(
struct Map_info *);
44#define NOPG_UNUSED UNUSED
72 G_debug(1,
"Vect_build_pg(): db='%s' table='%s', build=%d",
101 G_warning(
_(
"Feature table <%s> has no primary key defined"),
103 G_warning(
_(
"Random read is not supported for this layer. "
104 "Unable to build topology."));
109 G_message(
_(
"Using external data format '%s' (feature type '%s')"),
113 G_message(
_(
"Building pseudo-topology over simple features..."));
116 _(
"Building topology from PostGIS topology schema <%s>..."),
126 G_fatal_error(
_(
"GRASS is not compiled with PostgreSQL support"));
145 int line, type, s, n_nodes = 0;
218 if (n_nodes !=
Map->plus.n_nodes)
220 _(
"Inconsistency in topology: number of nodes %d (should be %d)"),
221 Map->plus.n_nodes, n_nodes);
245 G_message(
_(
"Cleaning-up topology schema..."));
248 "UPDATE \"%s\".node SET containing_face = 0 WHERE "
249 "containing_face IS NOT NULL",
259 "UPDATE \"%s\".edge_data SET left_face = 0, right_face = 0",
269 "DELETE FROM \"%s\".face WHERE "
278 snprintf(stmt,
sizeof(stmt),
"DELETE FROM \"%s\".%s",
286 snprintf(stmt,
sizeof(stmt),
"DELETE FROM \"%s\".%s",
312 G_debug(3,
"Area %d without centroid, skipped",
area);
318 "UPDATE \"%s\".node SET "
319 "containing_face = %d WHERE node_id = %d",
331 for (line = 1; line <= plus->
n_lines; line++) {
337 Line =
Map->plus.Line[line];
339 G_warning(
_(
"Inconsistency in topology detected. "
340 "Dead line found."));
346 for (s = 0; s < 2; s++) {
354 G_debug(3,
"update edge %d: left_face = %d, right_face = %d",
358 "UPDATE \"%s\".edge_data SET "
359 "left_face = %d, right_face = %d "
360 "WHERE edge_id = %d",
395 G_message(
_(
"Updating TopoGeometry data..."));
396 for (area = 1; area <= plus->
n_areas; area++) {
402 Line = plus->
Line[centroid];
408 (
int)Line->
offset, stmt) &&
444 if (create_simple_feature_from_topo(
Map) != 0)
468 int topo_id,
int fid,
char *stmt)
484 G_warning(
_(
"Unsupported topo geometry type %d"), type);
489 "UPDATE \"%s\".\"%s\" SET %s = "
490 "'(%d, 1, %d, %d)'::topology.TopoGeometry "
491 "WHERE (%s).id = %d",
514 if (create_topo_grass(
pg_info) == -1) {
524 "UPDATE \"%s\".\"%s\" SET %s = "
525 "'BOX3D(%.12f %.12f %.12f, %.12f %.12f %.12f)'::box3d WHERE %s "
534 "INSERT INTO \"%s\".\"%s\" (%s, %s) "
535 "VALUES(%d, 'BOX3D(%.12f %.12f %.12f, %.12f %.12f %.12f)'::box3d)",
537 box->
W, box->
S, box->
B, box->
E, box->
N, box->
T);
562 "SELECT COUNT(*) FROM information_schema.tables "
563 "WHERE table_schema = '%s' AND table_name = '%s'",
582 "CREATE TABLE \"%s\".\"%s\" (%s INTEGER, %s box3d)",
TOPO_SCHEMA,
589 "ALTER TABLE \"%s\".\"%s\" ADD PRIMARY KEY (%s)",
TOPO_SCHEMA,
598 "ALTER TABLE \"%s\".\"%s\" ADD CONSTRAINT \"%s_%s_fkey\" "
599 "FOREIGN KEY (%s) REFERENCES topology.topology(id) ON DELETE CASCADE",
625 "SELECT COUNT(*) FROM \"%s\".\"%s\" "
660int write_nodes(
const struct Plus_head *plus,
667 const struct P_node *Node;
676 G_warning(
_(
"Unable to write nodes, offset array mismatch"));
684 for (i = 1; i <= plus->
n_nodes; i++) {
685 Node = plus->
Node[i];
704 "INSERT INTO \"%s\".%s VALUES ("
705 "%d, '{%s}', '{%s}')",
736int write_lines(
const struct Plus_head *plus,
742 const struct P_line *Line;
748 "SELECT edge_id FROM \"%s\".edge_data WHERE "
749 "left_face != 0 OR right_face != 0 ORDER BY edge_id",
755 G_warning(
_(
"Inconsistency in topology: number of "
756 "boundaries %d (should be %d)"),
763 for (row = 0, i = 1; i <= plus->
n_lines; i++) {
764 Line = plus->
Line[i];
775 "INSERT INTO \"%s\".%s VALUES ("
802int write_areas(
const struct Plus_head *plus,
809 const struct P_line *Line;
810 const struct P_area *Area;
816 for (area = 1; area <= plus->
n_areas; area++) {
817 Area = plus->
Area[area];
819 G_debug(3,
"Area %d skipped (dead)", area);
833 G_warning(
_(
"Topology for centroid %d not available. Area %d "
850 "INSERT INTO \"%s\".%s VALUES ("
851 "%d, '{%s}', %d, '{%s}')",
879int write_isles(
const struct Plus_head *plus,
886 const struct P_isle *Isle;
907 "INSERT INTO \"%s\".%s VALUES ("
932void build_stmt_id(
const void *array,
int nitems,
int is_int,
961 for (i = 0; i < nitems; i++) {
1005 snprintf(stmt,
sizeof(stmt),
"DELETE FROM \"%s\".\"%s\"",
1010 snprintf(stmt,
sizeof(stmt),
"DELETE FROM \"%s\".\"%s\"",
1015 snprintf(stmt,
sizeof(stmt),
"DELETE FROM \"%s\".\"%s\"",
1020 snprintf(stmt,
sizeof(stmt),
"DELETE FROM \"%s\".\"%s\"",
1036int create_simple_feature_from_topo(
struct Map_info *
Map)
1044 G_debug(1,
"build_simple_feature_from_topo(): %d",
pg_info->feature_type);
1046 G_message(
_(
"Create simple features topology from topogeometry data..."));
1051 "UPDATE \"%s\".\"%s\" SET %s = (SELECT geom FROM \"%s\".node "
1052 "WHERE node_id = (%s).id)",
1066 G_warning(
_(
"Unable to build simple features from topogeometry data. "
1067 "Unsupported type %d."),
int Vect__clean_grass_db_topo(struct Format_info_pg *pg_info)
Clean-up GRASS Topology tables.
int Vect_build_pg(struct Map_info *Map, int build)
Build topology for PostGIS layer.
void G_percent(long, long, int)
Print percent complete messages.
void G_zero(void *, int)
Zero out a buffer, buf, of length i.
void G_free(void *)
Free allocated memory.
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
FILE * G_fopen_old(const char *, const char *, const char *)
Open a database file for reading.
const char * G_find_file2(const char *, const char *, const char *)
Searches for a file from the mapset search list or in a specified mapset. (look but don't touch)
void G_free_key_value(struct Key_Value *)
Free allocated Key_Value structure.
const char * G_find_key_value(const char *, const struct Key_Value *)
Find given key (case sensitive)
struct Key_Value * G_fread_key_value(FILE *)
Read key/values pairs from file.
int int G_strcasecmp(const char *, const char *)
String compare ignoring case (upper or lower)
void G_message(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
const char * G_mapset(void)
Get current mapset name.
plus_t Vect_get_num_islands(struct Map_info *)
Get number of islands in vector map.
plus_t Vect_get_num_areas(struct Map_info *)
Get number of areas in vector map.
void Vect__build_downgrade(struct Map_info *, int)
Downgrade build level (for internal use only)
int Vect_build_nat(struct Map_info *, int)
Build topology.
int Vect__build_sfa(struct Map_info *, int)
Build pseudo-topology (for simple features) - internal use only.
const char * Vect_get_finfo_format_info(struct Map_info *)
Get format info as string (relevant only for non-native formats)
int Vect_read_line(struct Map_info *, struct line_pnts *, struct line_cats *, int)
Read vector feature (topological level required)
const char * Vect_get_finfo_geometry_type(struct Map_info *)
Get geometry type as string (relevant only for non-native formats)
int Vect_build_partial(struct Map_info *, int)
Build partial topology for vector map.
int Vect_get_area_centroid(struct Map_info *, int)
Returns centroid id for given area.
#define GV_BUILD_NONE
Topology levels - nothing to build.
#define GV_POINT
Feature types used in memory on run time (may change)
#define GV_BUILD_ATTACH_ISLES
Topology levels - attach islands to areas.
#define GV_BUILD_BASE
Topology levels - basic level (without areas and isles)
#define GV_BUILD_AREAS
Topology levels - build areas.
#define GV_BUILD_CENTROIDS
Topology levels - assign centroids to areas.
#define LEVEL_2
Vector level - with 2D topology.
#define GV_MODE_RW
Read-write vector map open mode.
void dig_free_plus(struct Plus_head *)
Free Plus structure.
int dig_init_plus(struct Plus_head *)
Initialize Plus_head structure.
int Vect__load_map_nodes_pg(struct Map_info *Map, int geom_only)
Read nodes from DB.
int Vect__execute_pg(PGconn *conn, const char *stmt)
Execute SQL statement.
plus_t n_isles
Number of islands inside.
plus_t * isles
1st generation interior islands
plus_t n_lines
Number of boundary lines.
plus_t * lines
List of boundary lines.
plus_t centroid
Number of first centroid within area.
plus_t * lines
List of boundary lines.
plus_t n_lines
Number of boundary lines.
plus_t area
Area it exists w/in, if any.
off_t offset
Offset in coor file for line.
void * topo
Topology info.
Topological feature - node.
plus_t n_lines
Number of attached lines (size of lines, angle)
float * angles
List of angles of connected lines.
plus_t * lines
List of connected lines.
plus_t left
Area number to the left, negative for isle.
plus_t right
Area number to the right, negative for isle.
Basic topology-related info.
struct P_line ** Line
Array of vector geometries.
plus_t n_lines
Current number of lines.
int Spidx_new
Build new spatial index.
plus_t n_nodes
Current number of topological features derived from vector geometries.
plus_t n_blines
Current number of boundaries.
struct P_area ** Area
Array of areas.
int update_cidx
Update category index if vector is modified.
plus_t n_isles
Current number of isles.
struct bound_box box
Bounding box of features.
struct P_isle ** Isle
Array of isles.
struct P_node ** Node
Array of nodes.
plus_t n_areas
Current number of areas.
int built
Highest level of topology currently available.
void Vect__free_offset(struct Format_info_offset *offset)
void Vect__free_cache(struct Format_info_cache *cache)
int Vect__copy_areas(struct Map_info *In, int field, struct Map_info *Out)
Copy areas as polygons (OGR/PostGIS simple features access only)
int Vect__define_topo_relation(const struct Format_info_pg *pg_info, int topo_id, int element_id)
int Vect__insert_face_pg(struct Map_info *Map, int area)
Insert new face to the 'face' table (topo only)