23#include "local_proto.h"
26#include "pg_local_proto.h"
43static int parse_bbox(
const char *,
struct bound_box *);
44static struct P_node *read_p_node(
struct Plus_head *,
int,
int,
const char *,
45 const char *,
const char *,
48 const struct line_data *,
int,
50static struct P_area *read_p_area(
struct Plus_head *,
int,
const char *,
int,
52static struct P_isle *read_p_isle(
struct Plus_head *,
int,
const char *,
int);
53static void notice_processor(
void *,
const char *);
54static char **scan_array(
const char *);
60#define NOPG_UNUSED UNUSED
84 G_debug(2,
"V1_open_old_pg(): update = %d", update);
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'",
114 G_fatal_error(
"%s\n%s",
_(
"No feature tables found in database."),
138 G_warning(
_(
"Feature table <%s> not found in 'geometry_columns'"),
148 G_fatal_error(
_(
"GRASS is not compiled with PostgreSQL support"));
178 if (
pg_info->toposchema_name) {
183 "SELECT id FROM topology.topology WHERE name = '%s'",
187 G_warning(
"%s\n%s",
_(
"Topology schema not found."),
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);
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,
269 "SELECT * FROM pg_tables "
270 "WHERE schemaname = '%s' AND tablename = '%s'",
276 G_fatal_error(
"%s\n%s",
_(
"No feature tables found in database."),
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"));
341 if (check_topo(
pg_info, plus) != 0)
360 G_fatal_error(
_(
"GRASS is not compiled with PostgreSQL support"));
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'",
441 G_debug(3,
"ftype_from_string(): type='%s' -> %d", type, sf_type);
464 "SELECT COUNT(*) FROM pg_tables WHERE schemaname = 'topology'");
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'",
480 for (i = 0; i <
PQntuples(result); i++) {
482 snprintf(stmt,
sizeof(stmt),
"SELECT topology.DropTopology('%s')",
499 snprintf(stmt,
sizeof(stmt),
"DROP TABLE \"%s\".\"%s\"",
525 const char *user, *
passwd, *host, *port;
532 p +=
strlen(
"dbname") + 1;
534 for (i = 0; *p && *p !=
' '; i++, p++)
546 if (user ||
passwd || host || port) {
575 _(
"Connection to PostgreSQL database failed. "
576 "Try to set up username/password by db.login."),
586 "SELECT COUNT(*) FROM pg_tables WHERE tablename = 'spatial_ref_sys'");
590 "'spatial_ref_sys' not found."),
594 if (
pg_info->toposchema_name) {
598 "SELECT COUNT(*) FROM pg_tables WHERE schemaname = 'topology'");
602 _(
"PostGIS Topology extension not found in the database <%s>"),
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'",
642 G_debug(1,
"Topology layers for '%s.%s' not found (%s)",
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",
775 lines = angles =
NULL;
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",
795 _(
"Inconsistency in topology: unable to read node %d"),
id);
820 G_debug(4,
"read_p_node(): id = %d, n_lines = %d",
id,
cnt);
828 for (i = 0; i < node->
n_lines; i++) {
840 for (i = 0; i < node->
n_lines; i++) {
844 node->
lines[i] *= -1;
862 G_warning(
_(
"Inconsistency in topology: node %d - unexpected feature "
866 points =
pg_info->cache.lines[0];
867 node->
x = points->
x[0];
868 node->
y = points->
y[0];
870 node->
z = points->
z[0];
878 if (plus->
uplist.do_uplist)
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;
964 topo->left = topo->right = 0;
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;
997 if (plus->
uplist.do_uplist) {
1002 plus->
Line[n] = line;
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;
1094 G_warning(
_(
"Isle %d without boundary detected"), n);
1098 G_debug(3,
"read_p_isle(): n = %d nlines = %d", n, nlines);
1105 isle->n_lines = nlines;
1106 for (i = 0; i < nlines; i++) {
1137 plus = &(
Map->plus);
1144 snprintf(stmt,
sizeof(stmt),
"SELECT %s FROM \"%s\".\"%s\" WHERE %s = %d",
1154 "SELECT ST_3DExtent(%s) FROM \"%s\".\"%s\"",
1161 G_warning(
_(
"Unable to get map bounding box from topology"));
1168 G_warning(
_(
"Unable to parse map bounding box:\n%s"),
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",
1184 if (!
pg_info->topo_geo_only) {
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",
1208 "SELECT COUNT(*) FROM \"%s\".face WHERE face_id > 0",
1211 if (!
pg_info->topo_geo_only) {
1215 snprintf(stmt,
sizeof(stmt),
"SELECT COUNT(*) FROM \"%s\".%s",
1219 G_warning(
_(
"Different number of areas detected (%d, %d)"),
1231 "SELECT COUNT(*) FROM \"%s\".face WHERE face_id < 0",
1234 if (!
pg_info->topo_geo_only) {
1238 snprintf(stmt,
sizeof(stmt),
"SELECT COUNT(*) FROM \"%s\".%s",
1242 G_warning(
_(
"Different number of areas detected (%d, %d)"),
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)",
1265 "SELECT COUNT(*) FROM \"%s\".edge WHERE "
1266 "left_face = 0 AND right_face = 0",
1273 "SELECT COUNT(*) FROM \"%s\".edge WHERE "
1274 "left_face != 0 OR right_face != 0",
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);
1371 "SELECT area_id,lines,centroid,isles FROM \"%s\".%s ORDER BY "
1389 for (i = 0; i < plus->
n_areas; i++) {
1390 read_p_area(plus, i + 1, (
char *)
PQgetvalue(res, i, 1),
1404 pg_info->cache.lines_cats[plus->
Area[i + 1]->centroid - 1];
1417 _(
"To be implemented: isles not attached in Topo-Geo-only mode"));
1422 "SELECT isle_id,lines,area FROM \"%s\".%s ORDER BY isle_id",
1439 for (i = 0; i < plus->
n_isles; i++) {
1440 read_p_isle(plus, i + 1, (
char *)
PQgetvalue(res, i, 1),
1460 for (line = 1; line <= plus->
n_lines; line++) {
1461 Line = plus->
Line[line];
1502 plus = &(
Map->plus);
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 "
1527 G_warning(
_(
"Inconsistency in topology: number of "
1528 "nodes %d (should be %d)"),
1536 G_debug(3,
"load_plus(): n_nodes = %d", n_nodes);
1540 for (i = 0; i < n_nodes; i++) {
1552 offset->
array[i] = id;
1574 struct line_data line_data;
1579 plus = &(
Map->plus);
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",
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 "
1619 G_warning(
_(
"Inconsistency in topology: number of "
1620 "points %d (should be %d)"),
1628 G_zero(&line_data,
sizeof(
struct line_data));
1629 for (i = 0; i <
ntuples; i++) {
1632 line_data.wkb_geom = (
char *)
PQgetvalue(res, i, 1);
1635 read_p_line(plus, i + 1, &line_data,
pg_info->topo_geo_only,
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",
1672 G_warning(
_(
"Inconsistency in topology: number of "
1673 "lines %d (should be %d)"),
1682 for (i = 0; i <
ntuples; i++) {
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)));
1688 line_data.wkb_geom = (
char *)
PQgetvalue(res, i, 5);
1692 read_p_line(plus,
id, &line_data,
pg_info->topo_geo_only,
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",
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",
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++) {
1742 line_data.wkb_geom = (
char *)
PQgetvalue(res, i, 1);
1747 read_p_line(plus,
id + i, &line_data,
pg_info->topo_geo_only,
1781char **scan_array(
const char *
sarray)
1790 for (i = 1; i < len; i++)
1792 buf[len - 1] =
'\0';
1821 return offset->
array[node - 1];
1834int 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.
AMI_err name(char **stream_name)
Main header of GRASS DataBase Management Interface.
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.
char ** G_tokenize(const char *, const char *)
Tokenize string.
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)
char * G_store(const char *)
Copy string to allocated memory.
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.
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)
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.
const char * Vect_get_full_name(struct Map_info *)
Get fully qualified name of vector map.
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.
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.
struct P_node * dig_alloc_node(void)
Allocate new node structure.
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.
void * dig_alloc_topo(char)
Allocate new topo struct.
struct P_line * dig_alloc_line(void)
Allocate new line structure.
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.
int dig_alloc_lines(struct Plus_head *, int)
Reallocate array of pointers to lines.
void dig_line_add_updated(struct Plus_head *, int, off_t)
Add new line to updated.
struct P_isle * dig_alloc_isle(void)
Allocate new isle structure.
struct P_area * dig_alloc_area(void)
Allocate new area 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 *)
#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)
Open vector map - PostGIS feature table on topological level.
int V1_open_new_pg(struct Map_info *Map, const char *name, int with_z)
Prepare PostGIS database for creating new feature table (level 1)
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__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 Vect__open_topo_pg(struct Map_info *Map, int head_only, int update)
Read full-topology for PostGIS links.
int V1_open_old_pg(struct Map_info *Map, int update)
Open vector map - PostGIS feature table on non-topological level.
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.
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 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 area
Area number, negative for duplicate centroid.
Basic topology-related info.
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)