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,
105 snprintf(stmt,
sizeof(stmt),
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 snprintf(stmt,
sizeof(stmt),
183 "SELECT id FROM topology.topology WHERE name = '%s'",
185 res = PQexec(pg_info->
conn, stmt);
186 if (!
res || PQresultStatus(
res) != PGRES_TUPLES_OK) {
187 G_warning(
"%s\n%s",
_(
"Topology schema not found."),
188 PQresultErrorMessage(
res));
200 _(
"Unable to open feature index file for vector map <%s>"),
207 G_fatal_error(
_(
"GRASS is not compiled with PostgreSQL support"));
236 G_debug(2,
"V1_open_new_pg(): name = %s with_z = %d",
name, with_z);
238 pg_info = &(Map->fInfo.pg);
240 G_warning(
_(
"Connection string not defined"));
245 G_warning(
_(
"PostGIS feature table not defined"));
249 G_debug(1,
"V1_open_new_pg(): conninfo='%s' table='%s'", pg_info->
conninfo,
268 snprintf(stmt,
sizeof(stmt),
269 "SELECT * FROM pg_tables "
270 "WHERE schemaname = '%s' AND tablename = '%s'",
274 res = PQexec(pg_info->
conn, stmt);
275 if (!
res || PQresultStatus(
res) != PGRES_TUPLES_OK)
276 G_fatal_error(
"%s\n%s",
_(
"No feature tables found in database."),
277 PQresultErrorMessage(
res));
279 if (PQntuples(
res) > 0) {
282 G_warning(
_(
"PostGIS layer <%s.%s> already exists and will be "
285 if (drop_table(pg_info) == -1) {
286 G_warning(
_(
"Unable to delete PostGIS layer <%s>"),
293 _(
"PostGIS layer <%s.%s> already exists in database '%s'"),
309 G_fatal_error(
_(
"GRASS is not compiled with PostgreSQL support"));
338 pg_info = &(Map->fInfo.pg);
341 if (check_topo(pg_info, plus) != 0)
349 Map->support_updated =
FALSE;
360 G_fatal_error(
_(
"GRASS is not compiled with PostgreSQL support"));
381 snprintf(stmt,
sizeof(stmt),
382 "SELECT kcu.column_name "
383 "FROM INFORMATION_SCHEMA.TABLES t "
384 "LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc "
385 "ON tc.table_catalog = t.table_catalog "
386 "AND tc.table_schema = t.table_schema "
387 "AND tc.table_name = t.table_name "
388 "AND tc.constraint_type = 'PRIMARY KEY' "
389 "LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu "
390 "ON kcu.table_catalog = tc.table_catalog "
391 "AND kcu.table_schema = tc.table_schema "
392 "AND kcu.table_name = tc.table_name "
393 "AND kcu.constraint_name = tc.constraint_name "
394 "WHERE t.table_schema = '%s' AND t.table_name = '%s'",
398 res = PQexec(pg_info->
conn, stmt);
399 if (!
res || PQresultStatus(
res) != PGRES_TUPLES_OK || PQntuples(
res) != 1 ||
400 strlen(PQgetvalue(
res, 0, 0)) < 1) {
441 G_debug(3,
"ftype_from_string(): type='%s' -> %d", type, sf_type);
460 PGresult *result, *result_drop;
463 snprintf(stmt,
sizeof(stmt),
464 "SELECT COUNT(*) FROM pg_tables WHERE schemaname = 'topology'");
467 snprintf(stmt,
sizeof(stmt),
468 "SELECT t.name FROM topology.layer AS l JOIN "
469 "topology.topology AS t ON l.topology_id = t.id "
470 "WHERE l.table_name = '%s'",
474 result = PQexec(pg_info->
conn, stmt);
475 if (!result || PQresultStatus(result) != PGRES_TUPLES_OK) {
476 G_warning(
_(
"Execution failed: %s"), PQerrorMessage(pg_info->
conn));
480 for (i = 0; i < PQntuples(result); i++) {
481 topo_schema = PQgetvalue(result, i, 0);
482 snprintf(stmt,
sizeof(stmt),
"SELECT topology.DropTopology('%s')",
486 result_drop = PQexec(pg_info->
conn, stmt);
487 if (!result_drop || PQresultStatus(result_drop) != PGRES_TUPLES_OK)
489 PQerrorMessage(pg_info->
conn));
493 PQclear(result_drop);
499 snprintf(stmt,
sizeof(stmt),
"DROP TABLE \"%s\".\"%s\"",
522 if (!strstr(pg_info->
conninfo,
"user")) {
525 const char *user, *passwd, *host, *port;
528 p = strstr(pg_info->
conninfo,
"dbname");
532 p += strlen(
"dbname") + 1;
534 for (i = 0; *p && *p !=
' '; i++, p++)
540 db_get_login(
"pg", dbname, &user, &passwd, &host, &port);
546 if (user || passwd || host || port) {
573 if (PQstatus(pg_info->
conn) == CONNECTION_BAD)
575 _(
"Connection to PostgreSQL database failed. "
576 "Try to set up username/password by db.login."),
577 PQerrorMessage(pg_info->
conn));
586 "SELECT COUNT(*) FROM pg_tables WHERE tablename = 'spatial_ref_sys'");
588 PQfinish(pg_info->
conn);
590 "'spatial_ref_sys' not found."),
598 "SELECT COUNT(*) FROM pg_tables WHERE schemaname = 'topology'");
600 PQfinish(pg_info->
conn);
602 _(
"PostGIS Topology extension not found in the database <%s>"),
633 snprintf(stmt,
sizeof(stmt),
634 "SELECT t.id,t.name,t.hasz,l.feature_column FROM topology.layer "
635 "AS l JOIN topology.topology AS t ON l.topology_id = t.id "
636 "WHERE schema_name = '%s' AND table_name = '%s'",
640 res = PQexec(pg_info->
conn, stmt);
641 if (!
res || PQresultStatus(
res) != PGRES_TUPLES_OK || PQntuples(
res) != 1) {
642 G_debug(1,
"Topology layers for '%s.%s' not found (%s)",
644 PQerrorMessage(pg_info->
conn));
655 snprintf(stmt,
sizeof(stmt),
656 "SELECT COUNT(*) FROM pg_tables WHERE schemaname = '%s' "
657 "AND tablename LIKE '%%_grass'",
664 "PostGIS topology detected: schema = %s column = %s topo_geo_only = %d",
669 if (strcmp(PQgetvalue(
res, 0, 2),
"t") == 0)
685 int parse_bbox(
const char *value,
struct bound_box *bbox)
688 size_t length, prefix_length;
689 char **tokens, **tokens_coord, *coord;
691 if (strlen(value) < 1) {
696 prefix_length = strlen(
"box3d(");
701 length = strlen(value);
702 coord =
G_malloc(length - prefix_length);
703 for (i = prefix_length; i < length; i++)
704 coord[i - prefix_length] = value[i];
705 coord[length - prefix_length - 1] =
'\0';
721 bbox->
W = atof(tokens_coord[0]);
722 bbox->
S = atof(tokens_coord[1]);
723 bbox->
B = atof(tokens_coord[2]);
733 bbox->
E = atof(tokens_coord[0]);
734 bbox->
N = atof(tokens_coord[1]);
735 bbox->
T = atof(tokens_coord[2]);
761 const char *wkb_data,
const char *lines_data,
762 const char *angles_data,
775 lines = angles =
NULL;
777 if (!lines_data && !angles_data) {
782 "SELECT edge_id,'s' as node,"
783 "ST_Azimuth(ST_StartPoint(geom), ST_PointN(geom, 2)) AS angle"
784 " FROM \"%s\".edge WHERE start_node = %d UNION ALL "
785 "SELECT edge_id,'e' as node,"
786 "ST_Azimuth(ST_EndPoint(geom), ST_PointN(geom, "
787 "ST_NumPoints(geom) - 1)) AS angle"
788 " FROM \"%s\".edge WHERE end_node = %d"
789 " ORDER BY angle DESC",
792 res = PQexec(pg_info->
conn, stmt);
793 if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) {
795 _(
"Inconsistency in topology: unable to read node %d"),
id);
800 cnt = PQntuples(res);
803 lines = scan_array(lines_data);
804 angles = scan_array(angles_data);
820 G_debug(4,
"read_p_node(): id = %d, n_lines = %d",
id, cnt);
828 for (i = 0; i < node->
n_lines; i++) {
829 node->
lines[i] = atoi(lines[i]);
830 node->
angles[i] = atof(angles[i]);
840 for (i = 0; i < node->
n_lines; i++) {
841 node->
lines[i] = atoi(PQgetvalue(res, i, 0));
842 if (strcmp(PQgetvalue(res, i, 1),
"s") != 0) {
844 node->
lines[i] *= -1;
846 node->
angles[i] =
M_PI / 2 - atof(PQgetvalue(res, i, 2));
862 G_warning(
_(
"Inconsistency in topology: node %d - unexpected feature "
867 node->
x = points->
x[0];
868 node->
y = points->
y[0];
870 node->
z = points->
z[0];
882 plus->
Node[n] = node;
907 const struct line_data *data,
int topo_geo_only,
913 if (data->start_node == 0 && data->end_node == 0) {
914 if (data->left_face == 0)
919 else if (data->left_face == 0 && data->right_face == 0) {
936 G_debug(4,
"read_p_line(): id/offset = %d type = %d", data->id, line->
type);
946 (data->start_node < 0 || data->end_node < 0))
953 topo->
N1 = data->start_node;
954 topo->
N2 = data->end_node;
960 topo->
N1 = data->start_node;
961 topo->
N2 = data->end_node;
967 topo->
left = data->left_face;
968 topo->
right = data->right_face;
975 topo->
area = data->left_face;
981 data->fid > 0 ? data->fid : -1;
1002 plus->
Line[n] = line;
1020 const char *lines_data,
int centroid,
1021 const char *isles_data)
1029 lines = scan_array(lines_data);
1031 isles = scan_array(isles_data);
1035 G_warning(
_(
"Area %d without boundary detected"), n);
1039 G_debug(3,
"read_p_area(): n = %d nlines = %d nisles = %d", n, nlines,
1049 for (i = 0; i < nlines; i++) {
1055 for (i = 0; i < nisles; i++) {
1065 plus->
Area[n] = area;
1082 const char *lines_data,
int area)
1090 lines = scan_array(lines_data);
1094 G_warning(
_(
"Isle %d without boundary detected"), n);
1098 G_debug(3,
"read_p_isle(): n = %d nlines = %d", n, nlines);
1106 for (i = 0; i < nlines; i++) {
1115 plus->
Isle[n] = isle;
1137 plus = &(Map->
plus);
1144 snprintf(stmt,
sizeof(stmt),
"SELECT %s FROM \"%s\".\"%s\" WHERE %s = %d",
1145 TOPO_BBOX, TOPO_SCHEMA, TOPO_TABLE, TOPO_ID,
1148 res = PQexec(pg_info->
conn, stmt);
1149 if (!res || PQresultStatus(res) != PGRES_TUPLES_OK || PQntuples(res) != 1) {
1153 snprintf(stmt,
sizeof(stmt),
1154 "SELECT ST_3DExtent(%s) FROM \"%s\".\"%s\"",
1158 res = PQexec(pg_info->
conn, stmt);
1159 if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
1160 PQntuples(res) != 1 || strlen(PQgetvalue(res, 0, 0)) < 1) {
1161 G_warning(
_(
"Unable to get map bounding box from topology"));
1167 if (parse_bbox(PQgetvalue(res, 0, 0), &(plus->
box)) != 0) {
1168 G_warning(
_(
"Unable to parse map bounding box:\n%s"),
1169 PQgetvalue(res, 0, 0));
1178 snprintf(stmt,
sizeof(stmt),
1179 "SELECT COUNT(DISTINCT node) FROM (SELECT start_node AS node "
1180 "FROM \"%s\".edge GROUP BY start_node UNION ALL SELECT end_node "
1181 "AS node FROM \"%s\".edge GROUP BY end_node) AS foo",
1188 snprintf(stmt,
sizeof(stmt),
"SELECT COUNT(*) FROM \"%s\".%s",
1192 G_warning(
_(
"Different number of nodes detected (%d, %d)"),
1200 snprintf(stmt,
sizeof(stmt),
"SELECT COUNT(*) FROM \"%s\".edge",
1207 snprintf(stmt,
sizeof(stmt),
1208 "SELECT COUNT(*) FROM \"%s\".face WHERE face_id > 0",
1215 snprintf(stmt,
sizeof(stmt),
"SELECT COUNT(*) FROM \"%s\".%s",
1219 G_warning(
_(
"Different number of areas detected (%d, %d)"),
1230 snprintf(stmt,
sizeof(stmt),
1231 "SELECT COUNT(*) FROM \"%s\".face WHERE face_id < 0",
1238 snprintf(stmt,
sizeof(stmt),
"SELECT COUNT(*) FROM \"%s\".%s",
1242 G_warning(
_(
"Different number of areas detected (%d, %d)"),
1252 snprintf(stmt,
sizeof(stmt),
1253 "SELECT COUNT(*) FROM \"%s\".node WHERE containing_face "
1254 "IS NULL AND node_id NOT IN "
1255 "(SELECT node FROM (SELECT start_node AS node FROM \"%s\".edge "
1256 "GROUP BY start_node UNION ALL SELECT end_node AS node FROM "
1257 "\"%s\".edge GROUP BY end_node) AS foo)",
1264 snprintf(stmt,
sizeof(stmt),
1265 "SELECT COUNT(*) FROM \"%s\".edge WHERE "
1266 "left_face = 0 AND right_face = 0",
1272 snprintf(stmt,
sizeof(stmt),
1273 "SELECT COUNT(*) FROM \"%s\".edge WHERE "
1274 "left_face != 0 OR right_face != 0",
1280 snprintf(stmt,
sizeof(stmt),
1281 "SELECT COUNT(*) FROM \"%s\".node WHERE containing_face "
1282 "IS NOT NULL AND node_id NOT IN "
1283 "(SELECT node FROM (SELECT start_node AS node FROM \"%s\".edge "
1284 "GROUP BY start_node UNION ALL SELECT end_node AS node FROM "
1285 "\"%s\".edge GROUP BY end_node) AS foo)",
1323 plus = &(Map->
plus);
1353 for (line = 1; line <= plus->
n_lines; line++) {
1354 Line = plus->
Line[line];
1358 for (i = 0; i < 2; i++) {
1361 G_debug(3,
"Build area for line = %d, side = %d", i, side);
1370 snprintf(stmt,
sizeof(stmt),
1371 "SELECT area_id,lines,centroid,isles FROM \"%s\".%s ORDER BY "
1376 res = PQexec(pg_info->
conn, stmt);
1377 if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
1378 plus->
n_areas != PQntuples(res)) {
1389 for (i = 0; i < plus->
n_areas; i++) {
1390 read_p_area(plus, i + 1, (
char *)PQgetvalue(res, i, 1),
1391 atoi(PQgetvalue(res, i, 2)),
1392 (
char *)PQgetvalue(res, i, 3));
1417 _(
"To be implemented: isles not attached in Topo-Geo-only mode"));
1421 snprintf(stmt,
sizeof(stmt),
1422 "SELECT isle_id,lines,area FROM \"%s\".%s ORDER BY isle_id",
1426 res = PQexec(pg_info->
conn, stmt);
1427 if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
1428 plus->
n_isles != PQntuples(res)) {
1439 for (i = 0; i < plus->
n_isles; i++) {
1440 read_p_isle(plus, i + 1, (
char *)PQgetvalue(res, i, 1),
1441 atoi(PQgetvalue(res, i, 2)));
1460 for (line = 1; line <= plus->
n_lines; line++) {
1461 Line = plus->
Line[line];
1502 plus = &(Map->
plus);
1504 offset = &(pg_info->
offset);
1509 "SELECT node_id,geom FROM \"%s\".node WHERE node_id IN "
1510 "(SELECT node FROM (SELECT start_node AS node FROM \"%s\".edge "
1511 "GROUP BY start_node UNION ALL SELECT end_node AS node FROM "
1512 "\"%s\".edge GROUP BY end_node) AS foo) ORDER BY node_id",
1518 "SELECT node.node_id,geom,lines,angles FROM \"%s\".node AS node "
1519 "JOIN \"%s\".%s AS node_grass ON node.node_id = node_grass.node_id "
1524 res = PQexec(pg_info->
conn, stmt);
1525 if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
1526 (!geom_only && PQntuples(res) != plus->
n_nodes)) {
1527 G_warning(
_(
"Inconsistency in topology: number of "
1528 "nodes %d (should be %d)"),
1529 PQntuples(res), plus->
n_nodes);
1535 n_nodes = PQntuples(res);
1536 G_debug(3,
"load_plus(): n_nodes = %d", n_nodes);
1540 for (i = 0; i < n_nodes; i++) {
1542 id = atoi(PQgetvalue(res, i, 0));
1545 id, (
const char *)PQgetvalue(res, i, 1),
1546 !pg_info->
topo_geo_only ? (
const char *)PQgetvalue(res, i, 2)
1548 !pg_info->
topo_geo_only ? (
const char *)PQgetvalue(res, i, 3)
1550 pg_info, geom_only);
1552 offset->
array[i] = id;
1574 struct line_data line_data;
1579 plus = &(Map->
plus);
1581 offset = &(pg_info->
offset);
1593 "SELECT tt.node_id,tt.geom,ft.%s FROM \"%s\".node AS tt "
1594 "LEFT JOIN \"%s\".\"%s\" AS ft ON "
1595 "(%s).type = 1 AND (%s).id = node_id WHERE containing_face "
1596 "IS NULL AND node_id NOT IN "
1597 "(SELECT node FROM (SELECT start_node AS node FROM \"%s\".edge "
1598 "GROUP BY start_node UNION ALL SELECT end_node AS node FROM "
1599 "\"%s\".edge GROUP BY end_node) AS foo) ORDER BY node_id",
1605 snprintf(stmt,
sizeof(stmt),
1606 "SELECT tt.node_id,tt.geom,ft.%s "
1607 "FROM \"%s\".node AS tt LEFT JOIN \"%s\".\"%s\" AS ft ON "
1608 "(%s).type = 1 AND (%s).id = node_id WHERE node_id NOT IN "
1609 "(SELECT node_id FROM \"%s\".%s) AND containing_face IS NULL "
1616 res = PQexec(pg_info->
conn, stmt);
1617 if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
1619 G_warning(
_(
"Inconsistency in topology: number of "
1620 "points %d (should be %d)"),
1627 ntuples = PQntuples(res);
1628 G_zero(&line_data,
sizeof(
struct line_data));
1629 for (i = 0; i < ntuples; i++) {
1631 line_data.id = atoi(PQgetvalue(res, i, 0));
1632 line_data.wkb_geom = (
char *)PQgetvalue(res, i, 1);
1633 line_data.fid = atoi(PQgetvalue(res, i, 2));
1635 read_p_line(plus, i + 1, &line_data, pg_info->
topo_geo_only,
1645 snprintf(stmt,
sizeof(stmt),
1646 "SELECT edge_id,start_node,end_node,left_face,right_face AS "
1647 "right_area,tt.geom,ft.%s "
1648 "FROM \"%s\".edge AS tt LEFT JOIN \"%s\".\"%s\" AS ft ON "
1649 "(%s).type = 2 AND "
1650 "(%s).id = edge_id ORDER BY edge_id",
1658 "edge_id,start_node,end_node,left_area,right_area,tt.geom,ft.%s "
1659 "FROM \"%s\".edge AS tt LEFT JOIN \"%s\".\"%s\" ON "
1660 "edge_id = line_id LEFT JOIN \"%s\".\"%s\" AS ft ON (%s).type = 2 "
1662 "(%s).id = edge_id ORDER BY edge_id",
1669 res = PQexec(pg_info->
conn, stmt);
1670 if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
1671 PQntuples(res) > plus->
n_lines) {
1672 G_warning(
_(
"Inconsistency in topology: number of "
1673 "lines %d (should be %d)"),
1674 PQntuples(res), plus->
n_lines);
1681 ntuples = PQntuples(res);
1682 for (i = 0; i < ntuples; i++) {
1683 line_data.id = atoi(PQgetvalue(res, i, 0));
1684 line_data.start_node = remap_node(offset, atoi(PQgetvalue(res, i, 1)));
1685 line_data.end_node = remap_node(offset, atoi(PQgetvalue(res, i, 2)));
1686 line_data.left_face = atoi(PQgetvalue(res, i, 3));
1687 line_data.right_face = atoi(PQgetvalue(res, i, 4));
1688 line_data.wkb_geom = (
char *)PQgetvalue(res, i, 5);
1689 line_data.fid = atoi(PQgetvalue(res, i, 6));
1703 "SELECT node_id,tt.geom,containing_face,ft.%s FROM "
1704 "\"%s\".node AS tt LEFT JOIN \"%s\".\"%s\" AS ft ON "
1705 "(%s).type = 3 AND (%s).id = containing_face WHERE containing_face "
1706 "IS NOT NULL AND node_id NOT IN "
1707 "(SELECT node FROM (SELECT start_node AS node FROM \"%s\".edge "
1708 "GROUP BY start_node UNION ALL SELECT end_node AS node FROM "
1709 "\"%s\".edge GROUP BY end_node) AS foo) ORDER BY node_id",
1715 snprintf(stmt,
sizeof(stmt),
1716 "SELECT tt.node_id,tt.geom,containing_face,ft.%s FROM "
1717 "\"%s\".node AS tt LEFT JOIN \"%s\".\"%s\" AS ft ON "
1718 "(%s).type = 3 AND (%s).id = containing_face WHERE "
1719 "node_id NOT IN (SELECT node_id FROM \"%s\".%s) AND "
1721 "IS NOT NULL ORDER BY node_id",
1727 res = PQexec(pg_info->
conn, stmt);
1728 if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
1729 PQntuples(res) != plus->
n_clines) {
1730 G_warning(
_(
"Inconsistency in topology: number of "
1731 "centroids %d (should be %d)"),
1738 G_zero(&line_data,
sizeof(
struct line_data));
1740 for (i = 0; i < plus->
n_clines; i++) {
1741 line_data.id = atoi(PQgetvalue(res, i, 0));
1742 line_data.wkb_geom = (
char *)PQgetvalue(res, i, 1);
1743 line_data.left_face = atoi(PQgetvalue(res, i, 2));
1744 line_data.fid = atoi(PQgetvalue(res, i, 3));
1747 read_p_line(plus,
id + i, &line_data, pg_info->
topo_geo_only,
1765 fprintf(stderr,
"%s", message);
1781 char **scan_array(
const char *sarray)
1783 char *buf, **tokens;
1787 len = strlen(sarray) - 1;
1790 for (i = 1; i < len; i++)
1791 buf[i - 1] = sarray[i];
1792 buf[len - 1] =
'\0';
1821 return offset->
array[node - 1];
1834 int remap_line(
const struct Plus_head *plus, off_t offset,
int type)
1841 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)