23 #include "local_proto.h"
26 #include "pg_local_proto.h"
43 static int parse_bbox(
const char *,
struct bound_box *);
44 static struct P_node *read_p_node(
struct Plus_head *,
int,
int,
const char *,
45 const char *,
const char *,
48 const struct line_data *,
int,
50 static struct P_area *read_p_area(
struct Plus_head *,
int,
const char *,
int,
52 static struct P_isle *read_p_isle(
struct Plus_head *,
int,
const char *,
int);
54 static char **scan_array(
const char *);
56 static int remap_line(
const struct Plus_head *, off_t,
int);
60 #define NOPG_UNUSED UNUSED
84 G_debug(2,
"V1_open_old_pg(): update = %d", update);
86 pg_info = &(Map->fInfo.pg);
93 G_warning(
_(
"PostGIS feature table not defined"));
97 G_debug(1,
"V1_open_old_pg(): conninfo='%s' table='%s'", pg_info->
conninfo,
106 "SELECT f_geometry_column, coord_dimension, srid, type "
107 "FROM geometry_columns WHERE f_table_schema = '%s' AND "
108 "f_table_name = '%s'",
112 res = PQexec(pg_info->
conn, stmt);
113 if (!
res || PQresultStatus(
res) != PGRES_TUPLES_OK)
114 G_fatal_error(
"%s\n%s",
_(
"No feature tables found in database."),
115 PQresultErrorMessage(
res));
124 pg_info->
fid_column = get_key_column(pg_info);
128 pg_info->
srid = atoi(PQgetvalue(
res, 0, 2));
138 G_warning(
_(
"Feature table <%s> not found in 'geometry_columns'"),
144 check_topo(pg_info, &(Map->plus));
148 G_fatal_error(
_(
"GRASS is not compiled with PostgreSQL support"));
173 G_debug(3,
"V2_open_old_pg(): name = %s mapset = %s", Map->name,
176 pg_info = &(Map->fInfo.pg);
182 sprintf(stmt,
"SELECT id FROM topology.topology WHERE name = '%s'",
184 res = PQexec(pg_info->
conn, stmt);
185 if (!
res || PQresultStatus(
res) != PGRES_TUPLES_OK) {
186 G_warning(
"%s\n%s",
_(
"Topology schema not found."),
187 PQresultErrorMessage(
res));
199 _(
"Unable to open feature index file for vector map <%s>"),
206 G_fatal_error(
_(
"GRASS is not compiled with PostgreSQL support"));
235 G_debug(2,
"V1_open_new_pg(): name = %s with_z = %d",
name, with_z);
237 pg_info = &(Map->fInfo.pg);
239 G_warning(
_(
"Connection string not defined"));
244 G_warning(
_(
"PostGIS feature table not defined"));
248 G_debug(1,
"V1_open_new_pg(): conninfo='%s' table='%s'", pg_info->
conninfo,
268 "SELECT * FROM pg_tables "
269 "WHERE schemaname = '%s' AND tablename = '%s'",
273 res = PQexec(pg_info->
conn, stmt);
274 if (!
res || PQresultStatus(
res) != PGRES_TUPLES_OK)
275 G_fatal_error(
"%s\n%s",
_(
"No feature tables found in database."),
276 PQresultErrorMessage(
res));
278 if (PQntuples(
res) > 0) {
281 G_warning(
_(
"PostGIS layer <%s.%s> already exists and will be "
284 if (drop_table(pg_info) == -1) {
285 G_warning(
_(
"Unable to delete PostGIS layer <%s>"),
292 _(
"PostGIS layer <%s.%s> already exists in database '%s'"),
308 G_fatal_error(
_(
"GRASS is not compiled with PostgreSQL support"));
337 pg_info = &(Map->fInfo.pg);
340 if (check_topo(pg_info, plus) != 0)
348 Map->support_updated =
FALSE;
359 G_fatal_error(
_(
"GRASS is not compiled with PostgreSQL support"));
381 "SELECT kcu.column_name "
382 "FROM INFORMATION_SCHEMA.TABLES t "
383 "LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc "
384 "ON tc.table_catalog = t.table_catalog "
385 "AND tc.table_schema = t.table_schema "
386 "AND tc.table_name = t.table_name "
387 "AND tc.constraint_type = 'PRIMARY KEY' "
388 "LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu "
389 "ON kcu.table_catalog = tc.table_catalog "
390 "AND kcu.table_schema = tc.table_schema "
391 "AND kcu.table_name = tc.table_name "
392 "AND kcu.constraint_name = tc.constraint_name "
393 "WHERE t.table_schema = '%s' AND t.table_name = '%s'",
397 res = PQexec(pg_info->
conn, stmt);
398 if (!
res || PQresultStatus(
res) != PGRES_TUPLES_OK || PQntuples(
res) != 1 ||
399 strlen(PQgetvalue(
res, 0, 0)) < 1) {
440 G_debug(3,
"ftype_from_string(): type='%s' -> %d", type, sf_type);
459 PGresult *result, *result_drop;
463 "SELECT COUNT(*) FROM pg_tables WHERE schemaname = 'topology'");
467 "SELECT t.name FROM topology.layer AS l JOIN "
468 "topology.topology AS t ON l.topology_id = t.id "
469 "WHERE l.table_name = '%s'",
473 result = PQexec(pg_info->
conn, stmt);
474 if (!result || PQresultStatus(result) != PGRES_TUPLES_OK) {
475 G_warning(
_(
"Execution failed: %s"), PQerrorMessage(pg_info->
conn));
479 for (i = 0; i < PQntuples(result); i++) {
480 topo_schema = PQgetvalue(result, i, 0);
481 sprintf(stmt,
"SELECT topology.DropTopology('%s')", topo_schema);
484 result_drop = PQexec(pg_info->
conn, stmt);
485 if (!result_drop || PQresultStatus(result_drop) != PGRES_TUPLES_OK)
487 PQerrorMessage(pg_info->
conn));
491 PQclear(result_drop);
497 sprintf(stmt,
"DROP TABLE \"%s\".\"%s\"", pg_info->
schema_name,
520 if (!strstr(pg_info->
conninfo,
"user")) {
523 const char *user, *passwd, *host, *port;
526 p = strstr(pg_info->
conninfo,
"dbname");
530 p += strlen(
"dbname") + 1;
532 for (i = 0; *p && *p !=
' '; i++, p++)
538 db_get_login(
"pg", dbname, &user, &passwd, &host, &port);
544 if (user || passwd || host || port) {
571 if (PQstatus(pg_info->
conn) == CONNECTION_BAD)
573 _(
"Connection to PostgreSQL database failed. "
574 "Try to set up username/password by db.login."),
575 PQerrorMessage(pg_info->
conn));
584 "SELECT COUNT(*) FROM pg_tables WHERE tablename = 'spatial_ref_sys'");
586 PQfinish(pg_info->
conn);
588 "'spatial_ref_sys' not found."),
595 "SELECT COUNT(*) FROM pg_tables WHERE schemaname = 'topology'");
597 PQfinish(pg_info->
conn);
599 _(
"PostGIS Topology extension not found in the database <%s>"),
631 "SELECT t.id,t.name,t.hasz,l.feature_column FROM topology.layer "
632 "AS l JOIN topology.topology AS t ON l.topology_id = t.id "
633 "WHERE schema_name = '%s' AND table_name = '%s'",
637 res = PQexec(pg_info->
conn, stmt);
638 if (!
res || PQresultStatus(
res) != PGRES_TUPLES_OK || PQntuples(
res) != 1) {
639 G_debug(1,
"Topology layers for '%s.%s' not found (%s)",
641 PQerrorMessage(pg_info->
conn));
653 "SELECT COUNT(*) FROM pg_tables WHERE schemaname = '%s' "
654 "AND tablename LIKE '%%_grass'",
661 "PostGIS topology detected: schema = %s column = %s topo_geo_only = %d",
666 if (strcmp(PQgetvalue(
res, 0, 2),
"t") == 0)
682 int parse_bbox(
const char *value,
struct bound_box *bbox)
685 size_t length, prefix_length;
686 char **tokens, **tokens_coord, *coord;
688 if (strlen(value) < 1) {
693 prefix_length = strlen(
"box3d(");
698 length = strlen(value);
699 coord =
G_malloc(length - prefix_length);
700 for (i = prefix_length; i < length; i++)
701 coord[i - prefix_length] = value[i];
702 coord[length - prefix_length - 1] =
'\0';
718 bbox->
W = atof(tokens_coord[0]);
719 bbox->
S = atof(tokens_coord[1]);
720 bbox->
B = atof(tokens_coord[2]);
730 bbox->
E = atof(tokens_coord[0]);
731 bbox->
N = atof(tokens_coord[1]);
732 bbox->
T = atof(tokens_coord[2]);
758 const char *wkb_data,
const char *lines_data,
759 const char *angles_data,
772 lines = angles =
NULL;
774 if (!lines_data && !angles_data) {
779 "SELECT edge_id,'s' as node,"
780 "ST_Azimuth(ST_StartPoint(geom), ST_PointN(geom, 2)) AS angle"
781 " FROM \"%s\".edge WHERE start_node = %d UNION ALL "
782 "SELECT edge_id,'e' as node,"
783 "ST_Azimuth(ST_EndPoint(geom), ST_PointN(geom, "
784 "ST_NumPoints(geom) - 1)) AS angle"
785 " FROM \"%s\".edge WHERE end_node = %d"
786 " ORDER BY angle DESC",
789 res = PQexec(pg_info->
conn, stmt);
790 if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) {
792 _(
"Inconsistency in topology: unable to read node %d"),
id);
797 cnt = PQntuples(res);
800 lines = scan_array(lines_data);
801 angles = scan_array(angles_data);
817 G_debug(4,
"read_p_node(): id = %d, n_lines = %d",
id, cnt);
825 for (i = 0; i < node->
n_lines; i++) {
826 node->
lines[i] = atoi(lines[i]);
827 node->
angles[i] = atof(angles[i]);
837 for (i = 0; i < node->
n_lines; i++) {
838 node->
lines[i] = atoi(PQgetvalue(res, i, 0));
839 if (strcmp(PQgetvalue(res, i, 1),
"s") != 0) {
841 node->
lines[i] *= -1;
843 node->
angles[i] =
M_PI / 2 - atof(PQgetvalue(res, i, 2));
859 G_warning(
_(
"Inconsistency in topology: node %d - unexpected feature "
864 node->
x = points->
x[0];
865 node->
y = points->
y[0];
867 node->
z = points->
z[0];
879 plus->
Node[n] = node;
904 const struct line_data *data,
int topo_geo_only,
910 if (data->start_node == 0 && data->end_node == 0) {
911 if (data->left_face == 0)
916 else if (data->left_face == 0 && data->right_face == 0) {
933 G_debug(4,
"read_p_line(): id/offset = %d type = %d", data->id, line->
type);
943 (data->start_node < 0 || data->end_node < 0))
950 topo->
N1 = data->start_node;
951 topo->
N2 = data->end_node;
957 topo->
N1 = data->start_node;
958 topo->
N2 = data->end_node;
964 topo->
left = data->left_face;
965 topo->
right = data->right_face;
972 topo->
area = data->left_face;
978 data->fid > 0 ? data->fid : -1;
999 plus->
Line[n] = line;
1017 const char *lines_data,
int centroid,
1018 const char *isles_data)
1026 lines = scan_array(lines_data);
1028 isles = scan_array(isles_data);
1032 G_warning(
_(
"Area %d without boundary detected"), n);
1036 G_debug(3,
"read_p_area(): n = %d nlines = %d nisles = %d", n, nlines,
1046 for (i = 0; i < nlines; i++) {
1052 for (i = 0; i < nisles; i++) {
1062 plus->
Area[n] = area;
1079 const char *lines_data,
int area)
1087 lines = scan_array(lines_data);
1091 G_warning(
_(
"Isle %d without boundary detected"), n);
1095 G_debug(3,
"read_p_isle(): n = %d nlines = %d", n, nlines);
1103 for (i = 0; i < nlines; i++) {
1112 plus->
Isle[n] = isle;
1134 plus = &(Map->
plus);
1141 sprintf(stmt,
"SELECT %s FROM \"%s\".\"%s\" WHERE %s = %d", TOPO_BBOX,
1144 res = PQexec(pg_info->
conn, stmt);
1145 if (!res || PQresultStatus(res) != PGRES_TUPLES_OK || PQntuples(res) != 1) {
1149 sprintf(stmt,
"SELECT ST_3DExtent(%s) FROM \"%s\".\"%s\"",
1153 res = PQexec(pg_info->
conn, stmt);
1154 if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
1155 PQntuples(res) != 1 || strlen(PQgetvalue(res, 0, 0)) < 1) {
1156 G_warning(
_(
"Unable to get map bounding box from topology"));
1162 if (parse_bbox(PQgetvalue(res, 0, 0), &(plus->
box)) != 0) {
1163 G_warning(
_(
"Unable to parse map bounding box:\n%s"),
1164 PQgetvalue(res, 0, 0));
1174 "SELECT COUNT(DISTINCT node) FROM (SELECT start_node AS node "
1175 "FROM \"%s\".edge GROUP BY start_node UNION ALL SELECT end_node "
1176 "AS node FROM \"%s\".edge GROUP BY end_node) AS foo",
1183 sprintf(stmt,
"SELECT COUNT(*) FROM \"%s\".%s",
1187 G_warning(
_(
"Different number of nodes detected (%d, %d)"),
1195 sprintf(stmt,
"SELECT COUNT(*) FROM \"%s\".edge", pg_info->
toposchema_name);
1201 sprintf(stmt,
"SELECT COUNT(*) FROM \"%s\".face WHERE face_id > 0",
1208 sprintf(stmt,
"SELECT COUNT(*) FROM \"%s\".%s",
1212 G_warning(
_(
"Different number of areas detected (%d, %d)"),
1223 sprintf(stmt,
"SELECT COUNT(*) FROM \"%s\".face WHERE face_id < 0",
1230 sprintf(stmt,
"SELECT COUNT(*) FROM \"%s\".%s",
1234 G_warning(
_(
"Different number of areas detected (%d, %d)"),
1245 "SELECT COUNT(*) FROM \"%s\".node WHERE containing_face "
1246 "IS NULL AND node_id NOT IN "
1247 "(SELECT node FROM (SELECT start_node AS node FROM \"%s\".edge "
1248 "GROUP BY start_node UNION ALL SELECT end_node AS node FROM "
1249 "\"%s\".edge GROUP BY end_node) AS foo)",
1257 "SELECT COUNT(*) FROM \"%s\".edge WHERE "
1258 "left_face = 0 AND right_face = 0",
1265 "SELECT COUNT(*) FROM \"%s\".edge WHERE "
1266 "left_face != 0 OR right_face != 0",
1273 "SELECT COUNT(*) FROM \"%s\".node WHERE containing_face "
1274 "IS NOT NULL AND node_id NOT IN "
1275 "(SELECT node FROM (SELECT start_node AS node FROM \"%s\".edge "
1276 "GROUP BY start_node UNION ALL SELECT end_node AS node FROM "
1277 "\"%s\".edge GROUP BY end_node) AS foo)",
1315 plus = &(Map->
plus);
1345 for (line = 1; line <= plus->
n_lines; line++) {
1346 Line = plus->
Line[line];
1350 for (i = 0; i < 2; i++) {
1353 G_debug(3,
"Build area for line = %d, side = %d", i, side);
1363 "SELECT area_id,lines,centroid,isles FROM \"%s\".%s ORDER BY "
1368 res = PQexec(pg_info->
conn, stmt);
1369 if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
1370 plus->
n_areas != PQntuples(res)) {
1381 for (i = 0; i < plus->
n_areas; i++) {
1382 read_p_area(plus, i + 1, (
char *)PQgetvalue(res, i, 1),
1383 atoi(PQgetvalue(res, i, 2)),
1384 (
char *)PQgetvalue(res, i, 3));
1409 _(
"To be implemented: isles not attached in Topo-Geo-only mode"));
1414 "SELECT isle_id,lines,area FROM \"%s\".%s ORDER BY isle_id",
1418 res = PQexec(pg_info->
conn, stmt);
1419 if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
1420 plus->
n_isles != PQntuples(res)) {
1431 for (i = 0; i < plus->
n_isles; i++) {
1432 read_p_isle(plus, i + 1, (
char *)PQgetvalue(res, i, 1),
1433 atoi(PQgetvalue(res, i, 2)));
1452 for (line = 1; line <= plus->
n_lines; line++) {
1453 Line = plus->
Line[line];
1494 plus = &(Map->
plus);
1496 offset = &(pg_info->
offset);
1500 "SELECT node_id,geom FROM \"%s\".node WHERE node_id IN "
1501 "(SELECT node FROM (SELECT start_node AS node FROM \"%s\".edge "
1502 "GROUP BY start_node UNION ALL SELECT end_node AS node FROM "
1503 "\"%s\".edge GROUP BY end_node) AS foo) ORDER BY node_id",
1509 "SELECT node.node_id,geom,lines,angles FROM \"%s\".node AS node "
1510 "JOIN \"%s\".%s AS node_grass ON node.node_id = node_grass.node_id "
1515 res = PQexec(pg_info->
conn, stmt);
1516 if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
1517 (!geom_only && PQntuples(res) != plus->
n_nodes)) {
1518 G_warning(
_(
"Inconsistency in topology: number of "
1519 "nodes %d (should be %d)"),
1520 PQntuples(res), plus->
n_nodes);
1526 n_nodes = PQntuples(res);
1527 G_debug(3,
"load_plus(): n_nodes = %d", n_nodes);
1531 for (i = 0; i < n_nodes; i++) {
1533 id = atoi(PQgetvalue(res, i, 0));
1536 id, (
const char *)PQgetvalue(res, i, 1),
1537 !pg_info->
topo_geo_only ? (
const char *)PQgetvalue(res, i, 2)
1539 !pg_info->
topo_geo_only ? (
const char *)PQgetvalue(res, i, 3)
1541 pg_info, geom_only);
1543 offset->
array[i] = id;
1565 struct line_data line_data;
1570 plus = &(Map->
plus);
1572 offset = &(pg_info->
offset);
1583 "SELECT tt.node_id,tt.geom,ft.%s FROM \"%s\".node AS tt "
1584 "LEFT JOIN \"%s\".\"%s\" AS ft ON "
1585 "(%s).type = 1 AND (%s).id = node_id WHERE containing_face "
1586 "IS NULL AND node_id NOT IN "
1587 "(SELECT node FROM (SELECT start_node AS node FROM \"%s\".edge "
1588 "GROUP BY start_node UNION ALL SELECT end_node AS node FROM "
1589 "\"%s\".edge GROUP BY end_node) AS foo) ORDER BY node_id",
1596 "SELECT tt.node_id,tt.geom,ft.%s "
1597 "FROM \"%s\".node AS tt LEFT JOIN \"%s\".\"%s\" AS ft ON "
1598 "(%s).type = 1 AND (%s).id = node_id WHERE node_id NOT IN "
1599 "(SELECT node_id FROM \"%s\".%s) AND containing_face IS NULL "
1606 res = PQexec(pg_info->
conn, stmt);
1607 if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
1609 G_warning(
_(
"Inconsistency in topology: number of "
1610 "points %d (should be %d)"),
1617 ntuples = PQntuples(res);
1618 G_zero(&line_data,
sizeof(
struct line_data));
1619 for (i = 0; i < ntuples; i++) {
1621 line_data.id = atoi(PQgetvalue(res, i, 0));
1622 line_data.wkb_geom = (
char *)PQgetvalue(res, i, 1);
1623 line_data.fid = atoi(PQgetvalue(res, i, 2));
1625 read_p_line(plus, i + 1, &line_data, pg_info->
topo_geo_only,
1636 "SELECT edge_id,start_node,end_node,left_face,right_face AS "
1637 "right_area,tt.geom,ft.%s "
1638 "FROM \"%s\".edge AS tt LEFT JOIN \"%s\".\"%s\" AS ft ON "
1639 "(%s).type = 2 AND "
1640 "(%s).id = edge_id ORDER BY edge_id",
1648 "edge_id,start_node,end_node,left_area,right_area,tt.geom,ft.%s "
1649 "FROM \"%s\".edge AS tt LEFT JOIN \"%s\".\"%s\" ON "
1650 "edge_id = line_id LEFT JOIN \"%s\".\"%s\" AS ft ON (%s).type = 2 "
1652 "(%s).id = edge_id ORDER BY edge_id",
1659 res = PQexec(pg_info->
conn, stmt);
1660 if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
1661 PQntuples(res) > plus->
n_lines) {
1662 G_warning(
_(
"Inconsistency in topology: number of "
1663 "lines %d (should be %d)"),
1664 PQntuples(res), plus->
n_lines);
1671 ntuples = PQntuples(res);
1672 for (i = 0; i < ntuples; i++) {
1673 line_data.id = atoi(PQgetvalue(res, i, 0));
1674 line_data.start_node = remap_node(offset, atoi(PQgetvalue(res, i, 1)));
1675 line_data.end_node = remap_node(offset, atoi(PQgetvalue(res, i, 2)));
1676 line_data.left_face = atoi(PQgetvalue(res, i, 3));
1677 line_data.right_face = atoi(PQgetvalue(res, i, 4));
1678 line_data.wkb_geom = (
char *)PQgetvalue(res, i, 5);
1679 line_data.fid = atoi(PQgetvalue(res, i, 6));
1693 "SELECT node_id,tt.geom,containing_face,ft.%s FROM "
1694 "\"%s\".node AS tt LEFT JOIN \"%s\".\"%s\" AS ft ON "
1695 "(%s).type = 3 AND (%s).id = containing_face WHERE containing_face "
1696 "IS NOT NULL AND node_id NOT IN "
1697 "(SELECT node FROM (SELECT start_node AS node FROM \"%s\".edge "
1698 "GROUP BY start_node UNION ALL SELECT end_node AS node FROM "
1699 "\"%s\".edge GROUP BY end_node) AS foo) ORDER BY node_id",
1706 "SELECT tt.node_id,tt.geom,containing_face,ft.%s FROM "
1707 "\"%s\".node AS tt LEFT JOIN \"%s\".\"%s\" AS ft ON "
1708 "(%s).type = 3 AND (%s).id = containing_face WHERE "
1709 "node_id NOT IN (SELECT node_id FROM \"%s\".%s) AND "
1711 "IS NOT NULL ORDER BY node_id",
1717 res = PQexec(pg_info->
conn, stmt);
1718 if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
1719 PQntuples(res) != plus->
n_clines) {
1720 G_warning(
_(
"Inconsistency in topology: number of "
1721 "centroids %d (should be %d)"),
1728 G_zero(&line_data,
sizeof(
struct line_data));
1730 for (i = 0; i < plus->
n_clines; i++) {
1731 line_data.id = atoi(PQgetvalue(res, i, 0));
1732 line_data.wkb_geom = (
char *)PQgetvalue(res, i, 1);
1733 line_data.left_face = atoi(PQgetvalue(res, i, 2));
1734 line_data.fid = atoi(PQgetvalue(res, i, 3));
1737 read_p_line(plus,
id + i, &line_data, pg_info->
topo_geo_only,
1755 fprintf(stderr,
"%s", message);
1771 char **scan_array(
const char *sarray)
1773 char *buf, **tokens;
1777 len = strlen(sarray) - 1;
1780 for (i = 1; i < len; i++)
1781 buf[i - 1] = sarray[i];
1782 buf[len - 1] =
'\0';
1811 return offset->
array[node - 1];
1824 int remap_line(
const struct Plus_head *plus, off_t offset,
int type)
1831 Line = plus->
Line[i];
int Vect__clean_grass_db_topo(struct Format_info_pg *pg_info)
Clean-up GRASS Topology tables.
int db_get_login(const char *, const char *, const char **, const char **, const char **, const char **)
Get login parameters for driver/database.
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
void void G_verbose_message(const char *,...) __attribute__((format(printf
int G_get_overwrite(void)
Get overwrite value.
int G_verbose(void)
Get current verbosity level.
void G_free_tokens(char **)
Free memory allocated to tokens.
int G_number_of_tokens(char **)
Return number of tokens.
int int G_strcasecmp(const char *, const char *)
String compare ignoring case (upper or lower)
int G_strncasecmp(const char *, const char *, int)
String compare ignoring case (upper or lower) - limited number of characters.
int G_debug(int, const char *,...) __attribute__((format(printf
int G_verbose_std(void)
Get standard verbosity level.
char * G_store(const char *)
Copy string to allocated memory.
char ** G_tokenize(const char *, const char *)
Tokenize string.
void Vect_destroy_line_struct(struct line_pnts *)
Frees all memory associated with a line_pnts structure, including the structure itself.
int Vect_open_fidx(struct Map_info *, struct Format_info_offset *)
Open feature index file.
int Vect_build_line_area(struct Map_info *, int, int)
Build area on given side of line (GV_LEFT or GV_RIGHT)
const char * Vect_get_full_name(struct Map_info *)
Get fully qualified name of vector map.
int Vect_get_isle_points(struct Map_info *, int, struct line_pnts *)
Returns polygon array of points for given isle.
int Vect_get_area_points(struct Map_info *, int, struct line_pnts *)
Returns polygon array of points (outer ring) of given area.
void Vect_destroy_list(struct ilist *)
Frees all memory associated with a struct ilist, including the struct itself.
int Vect_read_line(struct Map_info *, struct line_pnts *, struct line_cats *, int)
Read vector feature (topological level required)
struct ilist * Vect_new_list(void)
Creates and initializes a struct ilist.
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
int Vect_find_area(struct Map_info *, double, double)
Find the nearest area.
SF_FeatureType
Simple feature types.
#define VECT_OPEN_CODE
Vector map open code.
#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_ALL
Topology levels - build everything (currently same as GV_BUILD_CENTROIDS)
#define GV_BUILD_AREAS
Topology levels - build areas.
#define GV_BUILD_CENTROIDS
Topology levels - assign centroids to areas.
#define GV_PG_GEOMETRY_COLUMN
GRASS-PostGIS data provider - default geometry column.
#define GV_LEFT
Boundary side indicator left/right.
#define GV_PG_FID_COLUMN
GRASS-PostGIS data provider - default fid column.
int dig_spidx_add_isle(struct Plus_head *, int, const struct bound_box *)
Add new island to spatial index.
void dig_node_add_updated(struct Plus_head *, int)
Add node to updated.
int dig_alloc_nodes(struct Plus_head *, int)
Reallocate array of pointers to nodes.
struct P_isle * dig_alloc_isle(void)
Allocate new isle structure.
int dig_cidx_add_cat(struct Plus_head *, int, int, int, int)
int dig_spidx_add_area(struct Plus_head *, int, const struct bound_box *)
Add new area to spatial index.
int dig_alloc_areas(struct Plus_head *, int)
Reallocate array of pointers to areas.
int dig_init_plus(struct Plus_head *)
Initialize Plus_head structure.
int dig_alloc_isles(struct Plus_head *, int)
Reallocate array of pointers to isles.
int dig_spidx_add_node(struct Plus_head *, int, double, double, double)
Add new node to spatial index.
int dig_area_alloc_isle(struct P_area *, int)
Allocate space in P_area for add new isles.
int dig_node_alloc_line(struct P_node *, int)
Allocate space in P_node struct.
void * dig_alloc_topo(char)
Allocate new topo struct.
int dig_alloc_lines(struct Plus_head *, int)
Reallocate array of pointers to lines.
struct P_area * dig_alloc_area(void)
Allocate new area structure.
void dig_line_add_updated(struct Plus_head *, int, off_t)
Add new line to updated.
struct P_line * dig_alloc_line(void)
Allocate new line structure.
int dig_isle_alloc_line(struct P_isle *, int)
Allocate space in P_isle for add new lines.
int dig_area_alloc_line(struct P_area *, int)
allocate space in P_area for add new lines
int dig_spidx_add_line(struct Plus_head *, int, const struct bound_box *)
Add new line to spatial index.
int dig_line_box(const struct line_pnts *, struct bound_box *)
struct P_node * dig_alloc_node(void)
Allocate new node structure.
#define UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
int V2_open_old_pg(struct Map_info *Map NOPG_UNUSED)
Open vector map - PostGIS feature table on topological level.
int Vect__load_plus_head(struct Map_info *Map)
Read topo from PostGIS topology schema – header info only.
int Vect__load_map_nodes_pg(struct Map_info *Map, int geom_only)
Read nodes from DB.
int Vect__open_topo_pg(struct Map_info *Map NOPG_UNUSED, int head_only NOPG_UNUSED, int update NOPG_UNUSED)
Read full-topology for PostGIS links.
void notice_processor(void *arg UNUSED, const char *message)
int Vect__load_map_lines_pg(struct Map_info *Map)
Read features from DB.
int Vect__load_plus_pg(struct Map_info *Map, int head_only)
Read topo info from PostGIS topology schema.
int V1_open_old_pg(struct Map_info *Map NOPG_UNUSED, int update NOPG_UNUSED)
Open vector map - PostGIS feature table on non-topological level.
int V1_open_new_pg(struct Map_info *Map NOPG_UNUSED, const char *name NOPG_UNUSED, int with_z NOPG_UNUSED)
Prepare PostGIS database for creating new feature table (level 1)
int Vect__execute_get_value_pg(PGconn *conn, const char *stmt)
Execute SQL statement and get value.
int Vect__execute_pg(PGconn *conn, const char *stmt)
Execute SQL statement.
SF_FeatureType Vect__cache_feature_pg(const char *data, int skip_polygon, int force_type, struct Format_info_cache *cache, struct feat_parts *fparts)
Read geometry from HEX data.
struct Format_info fInfo
Format info for non-native formats.
struct Plus_head plus
Plus info (topology, version, ...)
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.
double z
Z coordinate (used only for 3D data)
plus_t left
Area number to the left, negative for isle.
plus_t right
Area number to the right, negative for isle.
plus_t area
Area number, negative for duplicate centroid.
Basic topology-related info.
int do_uplist
Indicates if the list of updated features is maintained.
int with_z
2D/3D vector data
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_plines
Current number of points.
int off_t_size
Offset size.
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.
plus_t n_clines
Current number of centroids.
int cidx_up_to_date
Category index to be updated.
int update_cidx
Update category index if vector is modified.
plus_t n_isles
Current number of isles.
struct Plus_head::@10 uplist
List of updated lines/nodes.
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.
plus_t n_llines
Current number of lines.
Feature geometry info - coordinates.
double * y
Array of Y coordinates.
double * x
Array of X coordinates.
double * z
Array of Z coordinates.
void Vect__free_cache(struct Format_info_cache *cache)