26 #include "local_proto.h"
29 #include "pg_local_proto.h"
32 #define SEP "-----------------------------------\n"
34 #if !defined HAVE_OGR || !defined HAVE_POSTGRES
37 G_fatal_error(
_(
"Requested format is not compiled in this version"));
81 int area, isle, n_lines;
91 G_debug(3,
"Vect_build_line_area() line = %d, side = %d", iline, side);
100 G_debug(3,
" area/isle = %d -> skip", area);
106 G_debug(3,
" n_lines = %d", n_lines);
108 G_debug(3,
" unable to build area with line %d", iline);
118 G_warning(
_(
"Area of size = 0.0 (less than 4 vertices) ignored"));
128 G_debug(3,
" area/isle size = %f", area_size);
136 G_debug(3,
" -> area %d", area);
139 else if (area_size < 0) {
144 G_debug(3,
" -> isle %d", isle);
158 static int sort_by_size(
const void *a,
const void *
b)
160 BOX_SIZE *as = (BOX_SIZE *)a;
161 BOX_SIZE *bs = (BOX_SIZE *)
b;
163 if (as->size < bs->size)
166 return (as->size > bs->size);
182 int i, j, line, sel_area, area, poly;
191 static BOX_SIZE *size_list;
192 static int alloc_size_list = 0;
200 G_debug(3,
"Vect_isle_find_area () island = %d", isle);
204 G_warning(
_(
"Request to find area outside nonexistent isle"));
210 alloc_size_list = 10;
211 size_list =
G_malloc(alloc_size_list *
sizeof(BOX_SIZE));
214 Isle = plus->
Isle[isle];
215 line = abs(Isle->
lines[0]);
216 Line = plus->
Line[line];
218 Node = plus->
Node[topo->
N1];
237 if (alloc_size_list < List->n_values) {
239 size_list =
G_realloc(size_list, alloc_size_list *
sizeof(BOX_SIZE));
243 for (i = 0; i < List->
n_values; i++) {
244 abox = &List->
box[i];
246 if (box->
E > abox->
E || box->
W < abox->
W || box->
N > abox->
N ||
248 G_debug(3,
" isle not completely inside area box");
252 List->
id[j] = List->
id[i];
253 List->
box[j] = List->
box[i];
254 size_list[j].i = List->
id[j];
255 size_list[j].box = List->
box[j];
256 size_list[j].size = (abox->
N - abox->
S) * (abox->
E - abox->
W);
264 if (size_list[1].size < size_list[0].size) {
265 size_list[0].i = List->
id[1];
266 size_list[1].i = List->
id[0];
267 size_list[0].box = List->
box[1];
268 size_list[1].box = List->
box[0];
272 qsort(size_list, List->
n_values,
sizeof(BOX_SIZE), sort_by_size);
276 for (i = 0; i < List->
n_values; i++) {
277 area = size_list[i].i;
280 Area = plus->
Area[area];
284 if (abs(Isle->
lines[0]) == abs(Area->
lines[0])) {
285 G_debug(3,
" area inside isolated isle");
297 abox = &size_list[i].box;
299 if (box->
E > abox->
E || box->
W < abox->
W || box->
N > abox->
N ||
301 G_debug(3,
" isle not completely inside area box");
306 G_debug(3,
" poly = %d", poly);
328 G_debug(1,
"slow version of Vect_isle_find_area()");
339 G_debug(3,
" first area size = %f (n points = %d)",
340 cur_size, APoints->n_points);
350 G_debug(3,
" area size = %f (n points = %d)", size,
353 if (size > 0 && size < cur_size) {
359 G_warning(
_(
"Larger bbox but smaller area!!!"));
362 G_debug(3,
"sel_area = %d cur_size = %f", sel_area, cur_size);
367 G_debug(3,
"Island %d in area %d", isle, sel_area);
370 G_debug(3,
"Island %d is not in area", isle);
395 G_debug(3,
"Vect_attach_isle(): isle = %d", isle);
400 G_debug(3,
"\tisle = %d -> area outside = %d", isle, area);
405 "Attempt to attach isle %d to more areas "
406 "(=>topology is not clean)",
434 G_debug(3,
"Vect_attach_isles()");
444 for (i = 0; i < List->
n_values; i++) {
457 G_debug(3,
"Outer area is fully inside search box");
508 static int first = 1;
516 G_debug(3,
"Vect_attach_centroids()");
527 for (i = 0; i < List->
n_values; i++) {
541 if (box->
W < abox.
W && box->
E > abox.
E && box->
S < abox.
S &&
543 G_debug(3,
"Centroid's area is fully inside search box");
558 G_debug(3,
"\tcentroid %d is in area %d", centr,
area);
562 G_debug(3,
"\tfirst centroid -> attach to area");
569 G_debug(3,
"\tduplicate centroid -> do not attach to area");
607 int nerrors, n_zero_lines, n_zero_boundaries;
617 G_message(
_(
"Checking for topological errors..."));
623 n_zero_lines = n_zero_boundaries = 0;
625 for (line = 1; line <= nlines; line++) {
652 G_warning(
_(
"Number of lines of length zero: %d"), n_zero_lines);
653 if (n_zero_boundaries)
654 G_warning(
_(
"Number of boundaries of length zero: %d"),
664 G_warning(
_(
"Number of boundary intersections: %d"), nerrors);
669 for (line = 1; line <= nlines; line++) {
682 G_debug(3,
"line = %d left = %d right = %d", line, topo->
left,
689 G_warning(
_(
"Skipping further checks because of incorrect boundaries"));
696 for (area = 1; area <= nareas; area++) {
704 for (i = 0; i < List->
n_values; i++) {
705 line = List->
value[i];
739 G_warning(
_(
"Number of redundant holes: %d"), nerrors);
783 for (line = 1; line <= plus->
n_lines; line++) {
784 Line = plus->
Line[line];
799 for (line = 1; line <= plus->
n_lines; line++) {
800 Line = plus->
Line[line];
866 G_debug(3,
"Vect_build(): build = %d", build);
881 _(
"Unable to open spatial index file for vector map <%s>"),
888 G_message(
_(
"Building topology for vector map <%s>..."),
899 ret = ((*Build_array[Map->
format])(Map, build));
932 int line, nlines, area, nareas, err_boundaries, err_centr_out,
941 err_boundaries = err_centr_out = err_centr_dupl = 0;
942 for (line = 1; line <= nlines; line++) {
950 G_debug(3,
"line = %d left = %d right = %d", line,
960 else if (topo->
area < 0)
981 G_message(
_(
"Number of areas without centroid: %d"), err_nocentr);
985 G_warning(
_(
"Number of centroids exceeds number of areas: %d > %d"),
989 G_warning(
_(
"Number of incorrect boundaries: %d"), err_boundaries);
992 G_warning(
_(
"Number of centroids outside area: %d"), err_centr_out);
995 G_warning(
_(
"Number of duplicate centroids: %d"), err_centr_dupl);
1018 G_debug(1,
"Vect_save_topo()");
1021 plus = &(Map->
plus);
1027 G_warning(
_(
"Unable to create topo file for vector map <%s>"),
1056 int i, j, line, isle;
1065 plus = &(Map->
plus);
1067 fprintf(out,
"---------- TOPOLOGY DUMP ----------\n");
1069 fprintf(out,
"Topology format: ");
1071 fprintf(out,
"native");
1074 fprintf(out,
"PostGIS");
1077 fprintf(out,
"pseudo (simple features)");
1079 fprintf(out,
" @ OGR");
1081 fprintf(out,
" @ PostgreSQL");
1089 fprintf(out,
"N,S,E,W,T,B: %f, %f, %f, %f, %f, %f\n",
box.
N,
box.
S,
box.
E,
1095 fprintf(out,
"Nodes (%d nodes, alive + dead):\n", plus->
n_nodes);
1096 for (i = 1; i <= plus->
n_nodes; i++) {
1101 fprintf(out,
"node = %d, n_lines = %d, xyz = %f, %f, %f\n", i,
1109 fprintf(out,
" line = %3d, type = %d, angle = %f (%.4f)\n", line,
1117 fprintf(out,
"Lines (%d lines, alive + dead):\n", plus->
n_lines);
1118 for (i = 1; i <= plus->
n_lines; i++) {
1124 fprintf(out,
"line = %d, type = %d, offset = %lu\n", i,
Line->
type,
1130 fprintf(out,
"line = %d, type = %d, offset = %lu, area = %d\n", i,
1137 out,
"line = %d, type = %d, offset = %lu, n1 = %d, n2 = %d\n",
1144 "line = %d, type = %d, offset = %lu, n1 = %d, n2 = %d, "
1145 "left = %d, right = %d\n",
1153 "line = %d, type = %d, offset = %lu, e1 = %d, e2 = %d, "
1154 "e3 = %d, left = %d, right = %d\n",
1155 i, Line->
type, (
unsigned long)Line->
offset, topo->
E[0],
1161 fprintf(out,
"line = %d, type = %d, offset = %lu, volume = %d", i,
1169 fprintf(out,
"Areas (%d areas, alive + dead):\n", plus->
n_areas);
1170 for (i = 1; i <= plus->
n_areas; i++) {
1174 Area = plus->
Area[i];
1176 fprintf(out,
"area = %d, n_lines = %d, n_isles = %d centroid = %d\n", i,
1179 for (j = 0; j < Area->
n_lines; j++) {
1180 line = Area->
lines[j];
1181 Line = plus->
Line[abs(line)];
1182 fprintf(out,
" line = %3d\n", line);
1184 for (j = 0; j < Area->
n_isles; j++) {
1185 isle = Area->
isles[j];
1186 fprintf(out,
" isle = %3d\n", isle);
1193 fprintf(out,
"Islands (%d islands, alive + dead):\n", plus->
n_isles);
1194 for (i = 1; i <= plus->
n_isles; i++) {
1198 Isle = plus->
Isle[i];
1200 fprintf(out,
"isle = %d, n_lines = %d area = %d\n", i, Isle->
n_lines,
1203 for (j = 0; j < Isle->
n_lines; j++) {
1204 line = Isle->
lines[j];
1205 Line = plus->
Line[abs(line)];
1206 fprintf(out,
" line = %3d\n", line);
1226 if (Map->
level < 2) {
1228 "vector map is not opened at topology level 2"));
1248 G_warning(
_(
"%s is no longer supported"),
"Vect_build_sidx_from_topo()");
1266 G_debug(1,
"Vect_save_spatial_index()");
1268 plus = &(Map->
plus);
1271 G_warning(
_(
"Spatial index not available, can not be saved"));
1279 G_debug(1,
"Open sidx: %s", file_path);
1284 _(
"Unable to create spatial index file for vector map <%s>"),
1293 G_warning(
_(
"Error writing out spatial index file"));
1321 fprintf(out,
"---------- SPATIAL INDEX DUMP ----------\n");
void Vect__build_downgrade(struct Map_info *Map, int build)
Downgrade build level (for internal use only)
int Vect_build_sidx_from_topo(struct Map_info *Map)
Create spatial index from topology if necessary (not longer supported)
int Vect_attach_isle(struct Map_info *Map, int isle, const struct bound_box *box)
(Re)Attach isle to area
int Vect_isle_find_area(struct Map_info *Map, int isle, const struct bound_box *box)
Find area outside island.
int Vect_topo_dump(struct Map_info *Map, FILE *out)
Dump topology to file.
int Vect_build(struct Map_info *Map)
Build topology for vector map.
int Vect_build_partial(struct Map_info *Map, int build)
Build partial topology for vector map.
int Vect_build_line_area(struct Map_info *Map, int iline, int side)
Build area on given side of line (GV_LEFT or GV_RIGHT)
int Vect_build_sidx(struct Map_info *Map)
Create spatial index if necessary.
int Vect_sidx_dump(struct Map_info *Map, FILE *out)
Dump spatial index to file.
int Vect_attach_centroids(struct Map_info *Map, const struct bound_box *box)
(Re)Attach centroids in given bounding box to areas
int Vect_attach_isles(struct Map_info *Map, const struct bound_box *box)
(Re)Attach isles in given bounding box to areas
int Vect_topo_check(struct Map_info *Map, struct Map_info *Err)
Extensive tests for correct topology.
int Vect_get_built(struct Map_info *Map)
Return current highest built level (part)
int Vect_save_sidx(struct Map_info *Map)
Save spatial index file for vector map.
int Vect_save_topo(struct Map_info *Map)
Save topology file for vector map.
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
void G_message(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
FILE * G_fopen_new(const char *, const char *)
Open a new database file.
void Vect_destroy_line_struct(struct line_pnts *)
Frees all memory associated with a line_pnts structure, including the structure itself.
plus_t Vect_get_num_lines(struct Map_info *)
Fetch number of features (points, lines, boundaries, centroids) in vector map.
int Vect_select_isles_by_box(struct Map_info *, const struct bound_box *, struct boxlist *)
Select isles with bounding boxes by box.
double Vect_line_length(const struct line_pnts *)
Calculate line length, 3D-length in case of 3D vector line.
plus_t Vect_get_num_areas(struct Map_info *)
Get number of areas in vector map.
int Vect_area_alive(struct Map_info *, int)
Check if area is alive or dead (topological level required)
int Vect_build_pg(struct Map_info *, int)
int Vect_get_line_type(struct Map_info *, int)
Get line type.
struct boxlist * Vect_new_boxlist(int)
Creates and initializes a struct boxlist.
int Vect_get_area_boundaries(struct Map_info *, int, struct ilist *)
Creates list of boundaries for given area.
const char * Vect_get_full_name(struct Map_info *)
Get fully qualified name of vector map.
int Vect_get_area_points(struct Map_info *, int, struct line_pnts *)
Returns polygon array of points (outer ring) of given area.
int Vect_build_nat(struct Map_info *, int)
Build topology.
void Vect_destroy_list(struct ilist *)
Frees all memory associated with a struct ilist, including the struct itself.
void Vect_destroy_cats_struct(struct line_cats *)
Frees all memory associated with line_cats structure, including the struct itself.
int Vect_check_line_breaks(struct Map_info *, int, struct Map_info *)
Check for and count intersecting lines, do not break.
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.
int Vect_point_in_area_outer_ring(double, double, struct Map_info *, int, struct bound_box *)
Determines if a point (X,Y) is inside an area outer ring. Islands are not considered.
int Vect_line_alive(struct Map_info *, int)
Check if feature is alive or dead (topological level required)
plus_t Vect_get_num_primitives(struct Map_info *, int)
Get number of primitives in vector map.
int Vect_get_area_box(struct Map_info *, int, struct bound_box *)
Get bounding box of area.
int Vect_select_areas_by_box(struct Map_info *, const struct bound_box *, struct boxlist *)
Select areas with bounding boxes by box.
int Vect_build_ogr(struct Map_info *, int)
Build pseudo-topology (simple features) for OGR layer.
off_t Vect_write_line(struct Map_info *, int, const struct line_pnts *, const struct line_cats *)
Writes a new feature.
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
int Vect_select_lines_by_box(struct Map_info *, const struct bound_box *, int, struct boxlist *)
Select lines with bounding boxes by box.
int Vect_open_sidx(struct Map_info *, int)
Open spatial index file ('sidx')
int Vect_get_area_centroid(struct Map_info *, int)
Returns centroid id for given area.
const char * Vect_get_name(struct Map_info *)
Get name of vector map.
int Vect_line_prune(struct line_pnts *)
Remove duplicate points, i.e. zero length segments.
struct line_cats * Vect_new_cats_struct(void)
Creates and initializes line_cats structure.
int Vect_get_line_areas(struct Map_info *, int, int *, int *)
Get area id on the left and right side of the boundary.
int Vect_find_area(struct Map_info *, double, double)
Find the nearest area.
int Vect_get_isle_area(struct Map_info *, int)
Returns area id for isle.
int Vect_box_copy(struct bound_box *, const struct bound_box *)
Copy box B to box A.
#define GV_BUILD_NONE
Topology levels - nothing to build.
#define GV_FORMAT_POSTGIS
PostGIS format.
#define GV_POINT
Feature types used in memory on run time (may change)
#define GV_SIDX_ELEMENT
Native format, spatial index.
#define LEVEL_1
Vector level - without topology.
#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_MODE_WRITE
Write vector map open mode.
#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_FORMAT_OGR_DIRECT
OGR format (direct access)
#define PORT_DOUBLE_MAX
Limits for portable types.
#define GV_TOPO_ELEMENT
Native format, topology file.
#define GV_FORMAT_OGR
OGR format.
#define GV_FORMAT_NATIVE
Geometry data formats supported by lib Don't change GV_FORMAT_* values, this order is hardcoded in li...
void dig_spidx_free_nodes(struct Plus_head *)
Free spatial index for nodes.
void dig_spidx_free_areas(struct Plus_head *)
Reset spatial index for areas.
int dig_add_isle(struct Plus_head *, int, plus_t *, struct bound_box *)
Allocate space for new island and create boundary info from array.
int dig__byte_order_out(void)
Get byte order.
int dig_area_add_isle(struct Plus_head *, int, int)
Add isle to area if does not exist yet.
void dig_free_plus_nodes(struct Plus_head *)
Free Plus->Node structure.
int dig_Wr_spidx(struct gvfile *, struct Plus_head *)
Write spatial index to file.
void dig_free_plus_isles(struct Plus_head *)
Free Plus->Isle structure.
int dig_area_del_isle(struct Plus_head *, int, int)
Delete isle from area.
void dig_init_portable(struct Port_info *, int)
Set Port_info structure to byte order of file.
int dig_dump_spidx(FILE *, const struct Plus_head *)
Dump spatial index.
void dig_cidx_sort(struct Plus_head *)
int dig_add_area(struct Plus_head *, int, plus_t *, struct bound_box *)
Allocate space for new area and create boundary info from array.
void dig_cidx_free(struct Plus_head *)
void dig_spidx_free_lines(struct Plus_head *)
Free spatial index for lines.
plus_t dig_line_get_area(struct Plus_head *, plus_t, int)
Get area number on line side.
int dig_cidx_init(struct Plus_head *)
Initialize Plus_head structure (cidx)
void dig_free_plus_lines(struct Plus_head *)
Free Plus->Line structure.
int dig_find_area_poly(struct line_pnts *, double *)
int dig_build_area_with_line(struct Plus_head *, plus_t, int, plus_t **)
Build topo for area from lines.
void dig_spidx_free_isles(struct Plus_head *)
Reset spatial index for isles.
void dig_file_init(struct gvfile *file)
Initialize gvfile structure.
void dig_free_plus_areas(struct Plus_head *)
Free Plus->Area structure.
int dig_write_plus_file(struct gvfile *, struct Plus_head *)
Writes topo structure to topo file.
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 temporary
Temporary map flag.
struct dig_head head
Header info.
struct bound_box box
Region (bbox) constraint.
int support_updated
Support files were updated.
char * name
Map name (for 4.0)
int format
Map format (native, ogr, postgis)
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.
plus_t left
Volume number to the left, negative for hole.
plus_t E[3]
Array of edges.
plus_t right
Volume number to the right, negative for hole.
plus_t volume
Volume number, negative for duplicate kernel.
Basic topology-related info.
struct gvfile spidx_fp
Spatial index file pointer.
plus_t n_klines
Current number of kernels.
int Spidx_built
Spatial index built?
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.
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 spidx_with_z
2D/3D spatial index
plus_t n_clines
Current number of centroids.
int cidx_up_to_date
Category index to be updated.
struct Version_info topo
Version info for topology file.
plus_t n_isles
Current number of isles.
struct Port_info spidx_port
Portability information for spatial index.
struct bound_box box
Bounding box of features.
struct P_isle ** Isle
Array of isles.
struct P_node ** Node
Array of nodes.
struct Port_info port
Portability information.
plus_t n_areas
Current number of areas.
int built
Highest level of topology currently available.
plus_t n_flines
Current number of faces.
plus_t n_llines
Current number of lines.
List of bounding boxes with id.
struct bound_box * box
Array of bounding boxes.
int n_values
Number of items in the list.
int with_z
2D/3D vector data
FILE * file
File descriptor.
int n_values
Number of values in the list.
int * value
Array of values.
Feature geometry info - coordinates.
int n_points
Number of points.
int Vect__get_area_points(struct Map_info *Map, const plus_t *lines, int n_lines, struct line_pnts *BPoints)
Get area boundary points (internal use only)
char * Vect__get_path(char *path, struct Map_info *Map)
Get map directory name (internal use only)
char * Vect__get_element_path(char *file_path, struct Map_info *Map, const char *element)
Get map element full path (internal use only)