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"));
42 static int (*Build_array[]) () = {
79 int area, isle, n_lines;
89 G_debug(3,
"Vect_build_line_area() line = %d, side = %d", iline, side);
98 G_debug(3,
" area/isle = %d -> skip", area);
104 G_debug(3,
" n_lines = %d", n_lines);
106 G_debug(3,
" unable to build area with line %d", iline);
116 G_warning(
_(
"Area of size = 0.0 (less than 4 vertices) ignored"));
126 G_debug(3,
" area/isle size = %f", area_size);
134 G_debug(3,
" -> area %d", area);
137 else if (area_size < 0) {
142 G_debug(3,
" -> isle %d", isle);
156 static int sort_by_size(
const void *a,
const void *
b)
158 BOX_SIZE *as = (BOX_SIZE *)a;
159 BOX_SIZE *bs = (BOX_SIZE *)b;
161 if (as->size < bs->size)
164 return (as->size > bs->size);
179 int i, j, line, sel_area, area, poly;
188 static BOX_SIZE *size_list;
189 static int alloc_size_list = 0;
197 G_debug(3,
"Vect_isle_find_area () island = %d", isle);
201 G_warning(
_(
"Request to find area outside nonexistent isle"));
207 alloc_size_list = 10;
208 size_list =
G_malloc(alloc_size_list *
sizeof(BOX_SIZE));
211 Isle = plus->
Isle[isle];
212 line = abs(Isle->
lines[0]);
213 Line = plus->
Line[line];
215 Node = plus->
Node[topo->
N1];
234 if (alloc_size_list < List->n_values) {
236 size_list =
G_realloc(size_list, alloc_size_list *
sizeof(BOX_SIZE));
240 for (i = 0; i < List->
n_values; i++) {
241 abox = &List->
box[i];
243 if (box->
E > abox->
E || box->
W < abox->
W || box->
N > abox->
N ||
245 G_debug(3,
" isle not completely inside area box");
249 List->
id[j] = List->
id[i];
250 List->
box[j] = List->
box[i];
251 size_list[j].i = List->
id[j];
252 size_list[j].box = List->
box[j];
253 size_list[j].size = (abox->
N - abox->
S) * (abox->
E - abox->
W);
261 if (size_list[1].size < size_list[0].size) {
262 size_list[0].i = List->
id[1];
263 size_list[1].i = List->
id[0];
264 size_list[0].box = List->
box[1];
265 size_list[1].box = List->
box[0];
269 qsort(size_list, List->
n_values,
sizeof(BOX_SIZE), sort_by_size);
273 for (i = 0; i < List->
n_values; i++) {
274 area = size_list[i].i;
277 Area = plus->
Area[area];
280 if (abs(Isle->
lines[0]) == abs(Area->
lines[0])) {
281 G_debug(3,
" area inside isolated isle");
292 abox = &size_list[i].box;
294 if (box->
E > abox->
E || box->
W < abox->
W || box->
N > abox->
N ||
296 G_debug(3,
" isle not completely inside area box");
301 G_debug(3,
" poly = %d", poly);
322 G_debug(1,
"slow version of Vect_isle_find_area()");
332 G_debug(3,
" first area size = %f (n points = %d)",
333 cur_size, APoints->n_points);
343 G_debug(3,
" area size = %f (n points = %d)", size,
346 if (size > 0 && size < cur_size) {
352 G_warning(
_(
"Larger bbox but smaller area!!!"));
355 G_debug(3,
"sel_area = %d cur_size = %f", sel_area, cur_size);
360 G_debug(3,
"Island %d in area %d", isle, sel_area);
363 G_debug(3,
"Island %d is not in area", isle);
387 G_debug(3,
"Vect_attach_isle(): isle = %d", isle);
392 G_debug(3,
"\tisle = %d -> area outside = %d", isle, area);
394 Isle = plus->
Isle[isle];
395 if (Isle->
area > 0) {
396 G_debug(3,
"Attempt to attach isle %d to more areas " 397 "(=>topology is not clean)", isle);
424 G_debug(3,
"Vect_attach_isles()");
434 for (i = 0; i < List->
n_values; i++) {
445 if (box->
W < abox.
W && box->
E > abox.
E &&
446 box->
S < abox.
S && box->
N > abox.
N) {
447 G_debug(3,
"Outer area is fully inside search box");
498 static int first = 1;
506 G_debug(3,
"Vect_attach_centroids()");
517 for (i = 0; i < List->
n_values; i++) {
520 Line = plus->
Line[centr];
531 if (box->
W < abox.
W && box->
E > abox.
E &&
532 box->
S < abox.
S && box->
N > abox.
N) {
533 G_debug(3,
"Centroid's area is fully inside search box");
548 G_debug(3,
"\tcentroid %d is in area %d", centr, area);
552 G_debug(3,
"\tfirst centroid -> attach to area");
559 G_debug(3,
"\tduplicate centroid -> do not attach to area");
597 int nerrors, n_zero_lines, n_zero_boundaries;
607 G_message(
_(
"Checking for topological errors..."));
613 n_zero_lines = n_zero_boundaries = 0;
615 for (line = 1; line <= nlines; line++) {
642 G_warning(
_(
"Number of lines of length zero: %d"), n_zero_lines);
643 if (n_zero_boundaries)
644 G_warning(
_(
"Number of boundaries of length zero: %d"), n_zero_boundaries);
653 G_warning(
_(
"Number of boundary intersections: %d"), nerrors);
658 for (line = 1; line <= nlines; line++) {
670 G_debug(3,
"line = %d left = %d right = %d", line,
677 G_warning(
_(
"Skipping further checks because of incorrect boundaries"));
684 for (area = 1; area <= nareas; area++) {
692 for (i = 0; i < List->
n_values; i++) {
693 line = List->
value[i];
772 for (line = 1; line <= plus->
n_lines; line++) {
773 Line = plus->
Line[line];
787 for (line = 1; line <= plus->
n_lines; line++) {
788 Line = plus->
Line[line];
852 G_debug(3,
"Vect_build(): build = %d", build);
866 G_fatal_error(
_(
"Unable to open spatial index file for vector map <%s>"),
872 G_message(
_(
"Building topology for vector map <%s>..."),
883 ret = ((*Build_array[Map->
format]) (Map, build));
916 int line, nlines, area, nareas, err_boundaries, err_centr_out,
917 err_centr_dupl, err_nocentr;
924 err_boundaries = err_centr_out = err_centr_dupl = 0;
925 for (line = 1; line <= nlines; line++) {
926 Line = Plus->
Line[line];
933 G_debug(3,
"line = %d left = %d right = %d", line,
943 else if (topo->
area < 0)
950 for (area = 1; area <= nareas; area++) {
964 G_message(
_(
"Number of areas without centroid: %d"),
969 G_warning(
_(
"Number of centroids exceeds number of areas: %d > %d"),
973 G_warning(
_(
"Number of incorrect boundaries: %d"),
977 G_warning(
_(
"Number of centroids outside area: %d"),
981 G_warning(
_(
"Number of duplicate centroids: %d"), err_centr_dupl);
1005 G_debug(1,
"Vect_save_topo()");
1008 plus = &(Map->
plus);
1014 G_warning(
_(
"Unable to create topo file for vector map <%s>"), Map->
name);
1042 int i, j, line, isle;
1051 plus = &(Map->
plus);
1053 fprintf(out,
"---------- TOPOLOGY DUMP ----------\n");
1055 fprintf(out,
"Topology format: ");
1057 fprintf(out,
"native");
1060 fprintf(out,
"PostGIS");
1063 fprintf(out,
"pseudo (simple features)");
1065 fprintf(out,
" @ OGR");
1067 fprintf(out,
" @ PostgreSQL");
1075 fprintf(out,
"N,S,E,W,T,B: %f, %f, %f, %f, %f, %f\n", box.
N, box.
S,
1076 box.
E, box.
W, box.
T, box.
B);
1081 fprintf(out,
"Nodes (%d nodes, alive + dead):\n", plus->
n_nodes);
1082 for (i = 1; i <= plus->
n_nodes; i++) {
1086 Node = plus->
Node[i];
1087 fprintf(out,
"node = %d, n_lines = %d, xyz = %f, %f, %f\n", i,
1089 for (j = 0; j < Node->
n_lines; j++) {
1090 line = Node->
lines[j];
1091 Line = plus->
Line[abs(line)];
1095 fprintf(out,
" line = %3d, type = %d, angle = %f (%.4f)\n", line,
1103 fprintf(out,
"Lines (%d lines, alive + dead):\n", plus->
n_lines);
1104 for (i = 1; i <= plus->
n_lines; i++) {
1108 Line = plus->
Line[i];
1110 fprintf(out,
"line = %d, type = %d, offset = %lu\n",
1116 fprintf(out,
"line = %d, type = %d, offset = %lu, area = %d\n",
1122 fprintf(out,
"line = %d, type = %d, offset = %lu, n1 = %d, n2 = %d\n",
1129 fprintf(out,
"line = %d, type = %d, offset = %lu, n1 = %d, n2 = %d, " 1130 "left = %d, right = %d\n",
1137 fprintf(out,
"line = %d, type = %d, offset = %lu, e1 = %d, e2 = %d, " 1138 "e3 = %d, left = %d, right = %d\n",
1139 i, Line->
type, (
unsigned long)Line->
offset, topo->
E[0],
1145 fprintf(out,
"line = %d, type = %d, offset = %lu, volume = %d",
1153 fprintf(out,
"Areas (%d areas, alive + dead):\n", plus->
n_areas);
1154 for (i = 1; i <= plus->
n_areas; i++) {
1158 Area = plus->
Area[i];
1160 fprintf(out,
"area = %d, n_lines = %d, n_isles = %d centroid = %d\n",
1163 for (j = 0; j < Area->
n_lines; j++) {
1164 line = Area->
lines[j];
1165 Line = plus->
Line[abs(line)];
1166 fprintf(out,
" line = %3d\n", line);
1168 for (j = 0; j < Area->
n_isles; j++) {
1169 isle = Area->
isles[j];
1170 fprintf(out,
" isle = %3d\n", isle);
1177 fprintf(out,
"Islands (%d islands, alive + dead):\n", plus->
n_isles);
1178 for (i = 1; i <= plus->
n_isles; i++) {
1182 Isle = plus->
Isle[i];
1184 fprintf(out,
"isle = %d, n_lines = %d area = %d\n", i, Isle->
n_lines,
1187 for (j = 0; j < Isle->
n_lines; j++) {
1188 line = Isle->
lines[j];
1189 Line = plus->
Line[abs(line)];
1190 fprintf(out,
" line = %3d\n", line);
1210 if (Map->
level < 2) {
1212 "vector map is not opened at topology level 2"));
1231 G_debug(3,
"Vect_build_sidx_from_topo(): name=%s",
1234 G_warning(
_(
"%s is no longer supported"),
"Vect_build_sidx_from_topo()");
1252 G_debug(1,
"Vect_save_spatial_index()");
1254 plus = &(Map->
plus);
1257 G_warning(
_(
"Spatial index not available, can not be saved"));
1265 G_debug(1,
"Open sidx: %s", file_path);
1269 G_warning(
_(
"Unable to create spatial index file for vector map <%s>"),
1278 G_warning(
_(
"Error writing out spatial index file"));
1306 fprintf(out,
"---------- SPATIAL INDEX DUMP ----------\n");
int Vect_get_area_box(const struct Map_info *, int, struct bound_box *)
Get bounding box of area.
int Vect_build_pg(struct Map_info *, int)
Build topology for PostGIS layer.
int Spidx_new
Build new spatial index.
plus_t n_areas
Current number of areas.
plus_t right
Volume number to the right, negative for hole.
char * name
Map name (for 4.0)
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void dig_spidx_free_areas(struct Plus_head *)
Reset spatial index for areas.
int built
Highest level of topology currently available.
plus_t area
Area number, negative for duplicate centroid.
int Vect_select_areas_by_box(struct Map_info *, const struct bound_box *, struct boxlist *)
Select areas with bounding boxes by box.
char * Vect__get_element_path(char *file_path, const struct Map_info *Map, const char *element)
Get map element full path (internal use only)
void dig_init_portable(struct Port_info *, int)
Set Port_info structure to byte order of file.
plus_t n_klines
Current number of kernels.
int Vect_get_built(const struct Map_info *Map)
Return current highest built level (part)
int dig_dump_spidx(FILE *, const struct Plus_head *)
Dump spatial index.
off_t offset
Offset in coor file for line.
int Vect_build_nat(struct Map_info *, int)
Build topology.
int Vect_select_isles_by_box(struct Map_info *, const struct bound_box *, struct boxlist *)
Select isles with bounding boxes by box.
#define GV_FORMAT_NATIVE
Geometry data formats supported by lib Don't change GV_FORMAT_* values, this order is hardcoded in li...
struct P_line ** Line
Array of vector geometries.
int spidx_with_z
2D/3D spatial index
int Vect_box_copy(struct bound_box *, const struct bound_box *)
Copy box B to box A.
plus_t Vect_get_num_lines(const struct Map_info *)
Fetch number of features (points, lines, boundaries, centroids) in vector map.
int Vect_get_area_centroid(const struct Map_info *, int)
Returns centroid id for given area.
int with_z
2D/3D vector data
plus_t n_plines
Current number of points.
int Vect_point_in_area_outer_ring(double, double, const struct Map_info *, int, struct bound_box *)
Determines if a point (X,Y) is inside an area outer ring. Islands are not considered.
plus_t right
Area number to the right, negative for isle.
#define GV_BUILD_BASE
Topology levels - basic level (without areas and isles)
struct P_area ** Area
Array of areas.
int Vect__get_area_points(const struct Map_info *Map, const plus_t *lines, int n_lines, struct line_pnts *BPoints)
Get area boundary points (internal use only)
struct P_node ** Node
Array of nodes.
void dig_free_plus_nodes(struct Plus_head *)
Free Plus->Node structure.
plus_t dig_line_get_area(struct Plus_head *, plus_t, int)
Get area number on line side.
int dig_line_box(const struct line_pnts *, struct bound_box *)
void dig_cidx_free(struct Plus_head *)
int n_points
Number of points.
int dig_area_add_isle(struct Plus_head *, int, int)
Add isle to area if does not exist yet.
#define GV_FORMAT_OGR
OGR format.
int dig_add_isle(struct Plus_head *, int, plus_t *, struct bound_box *)
Allocate space for new island and create boundary info from array.
plus_t n_lines
Number of attached lines (size of lines, angle)
int n_values
Number of values in the list.
int Vect_check_line_breaks(struct Map_info *, int, struct Map_info *)
Check for and count intersecting lines, do not break.
#define GV_TOPO_ELEMENT
Native format, topology file.
plus_t left
Area number to the left, negative for isle.
struct Format_info fInfo
Format info for non-native formats.
int Vect_save_topo(struct Map_info *Map)
Save topology file for vector map.
struct P_isle ** Isle
Array of isles.
plus_t * lines
List of connected lines.
plus_t * isles
1st generation interior islands
plus_t n_isles
Current number of isles.
plus_t centroid
Number of first centroid within area.
int Vect_line_prune(struct line_pnts *)
Remove duplicate points, i.e. zero length segments.
double Vect_line_length(const struct line_pnts *)
Calculate line length, 3D-length in case of 3D vector line.
int dig_Wr_spidx(struct gvfile *, struct Plus_head *)
Write spatial index to file.
plus_t n_lines
Number of boundary lines.
int Vect_open_sidx(struct Map_info *, int)
Open spatial index file ('sidx')
int Vect_attach_isles(struct Map_info *Map, const struct bound_box *box)
(Re)Attach isles in given bounding box to areas
int Spidx_built
Spatial index built?
int n_values
Number of items in the list.
#define GV_POINT
Feature types used in memory on run time (may change)
int Vect_attach_centroids(struct Map_info *Map, const struct bound_box *box)
(Re)Attach centroids in given bounding box to areas
struct bound_box * box
Array of bounding boxes.
void dig_cidx_sort(struct Plus_head *)
#define GV_BUILD_NONE
Topology levels - nothing to build.
#define LEVEL_1
Vector level - without topology.
void dig_spidx_free_nodes(struct Plus_head *)
Free spatial index for nodes.
int Vect_build_ogr(struct Map_info *, int)
Build pseudo-topology (simple features) for OGR layer.
plus_t n_lines
Current number of lines.
int Vect_isle_find_area(struct Map_info *Map, int isle, const struct bound_box *box)
Find area outside island.
plus_t Vect_get_num_primitives(const struct Map_info *, int)
Get number of primitives in vector map.
int dig_write_plus_file(struct gvfile *, struct Plus_head *)
Writes topo structure to topo file.
struct Port_info port
Portability information.
void G_message(const char *,...) __attribute__((format(printf
double z
Z coordinate (used only for 3D data)
void dig_spidx_free_isles(struct Plus_head *)
Reset spatial index for isles.
int cidx_up_to_date
Category index to be updated.
int Vect_select_lines_by_box(struct Map_info *, const struct bound_box *, int, struct boxlist *)
Select lines with bounding boxes by box.
Feature geometry info - coordinates.
int with_z
2D/3D vector data
plus_t * lines
List of boundary lines.
struct gvfile spidx_fp
Spatial index file pointer.
int dig_cidx_init(struct Plus_head *)
Initialize Plus_head structure (cidx)
FILE * G_fopen_new(const char *, const char *)
Open a new database file.
Basic topology-related info.
int Vect_sidx_dump(const struct Map_info *Map, FILE *out)
Dump spatial index to file.
int Vect_save_sidx(struct Map_info *Map)
Save spatial index file for vector map.
int Vect_build(struct Map_info *Map)
Build topology for vector map.
#define GV_BUILD_AREAS
Topology levels - build areas.
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_from_topo(const struct Map_info *Map)
Create spatial index from topology if necessary (not longer supported)
void Vect_destroy_list(struct ilist *)
Frees all memory associated with a struct ilist, including the struct itself.
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
void Vect_destroy_cats_struct(struct line_cats *)
Frees all memory associated with line_cats structure, including the struct itself.
void * topo
Topology info.
float * angles
List of angles of connected lines.
off_t Vect_write_line(struct Map_info *, int, const struct line_pnts *, const struct line_cats *)
Writes a new feature.
plus_t * lines
List of boundary lines.
#define GV_FORMAT_OGR_DIRECT
OGR format (direct access)
struct Plus_head plus
Plus info (topology, version, ...)
int Vect_get_area_boundaries(const struct Map_info *, int, struct ilist *)
Creates list of boundaries for given area.
plus_t E[3]
Array of edges.
void dig_file_init(struct gvfile *file)
Initialize gvfile strcuture.
plus_t Vect_get_num_areas(const struct Map_info *)
Get number of areas in vector map.
int Vect_area_alive(const struct Map_info *, int)
Check if area is alive or dead (topological level required)
Topological feature - node.
struct bound_box box
Bounding box of features.
int dig_add_area(struct Plus_head *, int, plus_t *, struct bound_box *)
Allocate space for new area and create boundary info from array.
struct dig_head head
Header info.
plus_t n_flines
Current number of faces.
plus_t n_isles
Number of islands inside.
plus_t left
Volume number to the left, negative for hole.
int Vect_get_isle_area(const struct Map_info *, int)
Returns area id for isle.
int Vect_attach_isle(struct Map_info *Map, int isle, const struct bound_box *box)
(Re)Attach isle to area
int Vect_find_area(struct Map_info *, double, double)
Find the nearest area.
int support_updated
Support files were updated.
int Vect_topo_check(struct Map_info *Map, struct Map_info *Err)
Extensive tests for correct topology.
#define PORT_DOUBLE_MAX
Limits for portable types.
#define GV_FORMAT_POSTGIS
PostGIS format.
plus_t n_llines
Current number of lines.
FILE * file
File descriptor.
struct ilist * Vect_new_list(void)
Creates and initializes a struct ilist.
struct line_cats * Vect_new_cats_struct(void)
Creates and initializes line_cats structure.
int dig__byte_order_out()
Get byte order.
int temporary
Temporary map flag.
const char * Vect_get_full_name(const struct Map_info *)
Get fully qualified name of vector map.
#define LEVEL_2
Vector level - with 2D topology.
List of bounding boxes with id.
void G_warning(const char *,...) __attribute__((format(printf
void dig_spidx_free_lines(struct Plus_head *)
Free spatial index for lines.
struct Port_info spidx_port
Portability information for spatial index.
int Vect_line_alive(const struct Map_info *, int)
Check if feature is alive or dead (topological level required)
int Vect_topo_dump(const struct Map_info *Map, FILE *out)
Dump topology to file.
plus_t n_clines
Current number of centroids.
int format
Map format (native, ogr, postgis)
#define GV_BUILD_CENTROIDS
Topology levels - assign centroids to areas.
int dig_area_del_isle(struct Plus_head *, int, int)
Delete isle from area.
#define GV_BUILD_ALL
Topology levels - build everything (currently same as GV_BUILD_CENTROIDS)
plus_t volume
Volume number, negative for duplicate kernel.
#define GV_MODE_WRITE
Write vector map open mode.
char * Vect__get_path(char *path, const struct Map_info *Map)
Get map directory name (internal use only)
int * value
Array of values.
int dig_build_area_with_line(struct Plus_head *, plus_t, int, plus_t **)
Build topo for area from lines.
void Vect__build_downgrade(struct Map_info *Map, int build)
Downgrade build level (for internal use only)
struct boxlist * Vect_new_boxlist(int)
Creates and initializes a struct boxlist.
#define GV_SIDX_ELEMENT
Native format, spatial index.
void dig_free_plus_isles(struct Plus_head *)
Free Plus->Isle structure.
plus_t n_blines
Current number of boundaries.
void Vect_destroy_line_struct(struct line_pnts *)
Frees all memory associated with a line_pnts structure, including the structure itself.
int Vect_get_area_points(const struct Map_info *, int, struct line_pnts *)
Returns polygon array of points (outer ring) of given area.
void void G_verbose_message(const char *,...) __attribute__((format(printf
plus_t n_lines
Number of boundary lines.
int Vect_read_line(const struct Map_info *, struct line_pnts *, struct line_cats *, int)
Read vector feature (topological level required)
plus_t area
Area it exists w/in, if any.
const char * Vect_get_name(const struct Map_info *)
Get name of vector map.
int G_debug(int, const char *,...) __attribute__((format(printf
int Vect_build_sidx(struct Map_info *Map)
Create spatial index if necessary.
int Vect_build_partial(struct Map_info *Map, int build)
Build partial topology for vector map.
int Vect_get_line_areas(const struct Map_info *, int, int *, int *)
Get area id on the left and right side of the boundary.
void dig_free_plus_areas(struct Plus_head *)
Free Plus->Area structure.
void dig_free_plus_lines(struct Plus_head *)
Free Plus->Line structure.
int Vect_get_line_type(const struct Map_info *, int)
Get line type.
plus_t n_nodes
Current number of topological features derived from vector geometries.
int dig_find_area_poly(struct line_pnts *, double *)