GRASS 8 Programmer's Manual 8.6.0dev(2026)-4bb960b182
Loading...
Searching...
No Matches
build_sfa.c
Go to the documentation of this file.
1/*!
2 \file lib/vector/Vlib/build_sfa.c
3
4 \brief Vector library - Building pseudo-topology for simple feature access
5
6 Higher level functions for reading/writing/manipulating vectors.
7
8 Line offset is
9 - centroids : FID
10 - other types : index of the first record (which is FID) in offset array.
11
12 SPDX-FileCopyrightText: 2001-2012 GRASS Development Team
13 SPDX-License-Identifier: GPL-2.0-or-later
14
15 \author Radim Blazek
16 \author Piero Cavalieri
17 \author Various updates for GRASS 7 by Martin Landa <landa.martin gmail.com>
18 */
19
20#include <stdlib.h>
21
22#include <grass/gis.h>
23#include <grass/vector.h>
24#include <grass/glocale.h>
25
26#include <ogr_api.h>
27
28/*!
29 \brief This structure keeps info about geometry parts above current
30 geometry, path to current geometry in the feature. First 'part' number
31 however is feature id */
32struct geom_parts {
33 int *part;
34 int a_parts;
35 int n_parts;
36};
37
38static void init_parts(struct geom_parts *);
39static void reset_parts(struct geom_parts *);
40static void free_parts(struct geom_parts *);
41static void add_part(struct geom_parts *, int);
42static void del_part(struct geom_parts *);
43static void add_parts_to_offset(struct Format_info_offset *,
44 struct geom_parts *);
45static int add_line(struct Plus_head *, struct Format_info_offset *, int,
46 struct line_pnts *, int, struct geom_parts *);
47
48#ifdef HAVE_POSTGRES
49#include "pg_local_proto.h"
50
51static int add_geometry_pg(struct Plus_head *, struct Format_info_pg *,
52 struct feat_parts *, int, int, int,
53 struct geom_parts *);
54static void build_pg(struct Map_info *, int);
55#endif
56
57static int add_geometry_ogr(struct Plus_head *, struct Format_info_ogr *,
58 OGRGeometryH, int, int, struct geom_parts *);
59
60static void build_ogr(struct Map_info *, int);
61
62/*!
63 \brief Init parts
64 */
65void init_parts(struct geom_parts *parts)
66{
67 G_zero(parts, sizeof(struct geom_parts));
68}
69
70/*!
71 \brief Reset parts
72 */
73void reset_parts(struct geom_parts *parts)
74{
75 parts->n_parts = 0;
76}
77
78/*!
79 \brief Free parts
80 */
81void free_parts(struct geom_parts *parts)
82{
83 G_free(parts->part);
84 G_zero(parts, sizeof(struct geom_parts));
85}
86
87/*!
88 \brief Add new part number to parts
89 */
90void add_part(struct geom_parts *parts, int part)
91{
92 if (parts->a_parts == parts->n_parts) {
93 parts->a_parts += 10;
94 parts->part =
95 (int *)G_realloc((void *)parts->part, parts->a_parts * sizeof(int));
96 }
97 parts->part[parts->n_parts] = part;
98 parts->n_parts++;
99}
100
101/*!
102 \brief Remove last part
103 */
104void del_part(struct geom_parts *parts)
105{
106 parts->n_parts--;
107}
108
109/*!
110 \brief Add parts to offset
111 */
112void add_parts_to_offset(struct Format_info_offset *offset,
113 struct geom_parts *parts)
114{
115 int i, j;
116
117 if (offset->array_num + parts->n_parts >= offset->array_alloc) {
118 offset->array_alloc += parts->n_parts + 1000;
119 offset->array =
120 (int *)G_realloc(offset->array, offset->array_alloc * sizeof(int));
121 }
122 j = offset->array_num;
123 for (i = 0; i < parts->n_parts; i++) {
124 G_debug(4, "add offset %d", parts->part[i]);
125 offset->array[j] = parts->part[i];
126 j++;
127 }
128 offset->array_num += parts->n_parts;
129}
130
131/*!
132 \brief Add line to support structures
133 */
134int add_line(struct Plus_head *plus, struct Format_info_offset *offset,
135 int type, struct line_pnts *Points, int FID,
136 struct geom_parts *parts)
137{
138 int line;
139 long offset_value;
140 struct bound_box box;
141
142 if (type != GV_CENTROID) {
143 /* beginning in the offset array */
144 offset_value = offset->array_num;
145 }
146 else {
147 /* TODO : could be used to statore category ? */
148 /* because centroids are read from topology, not from layer */
150 }
151
152 G_debug(4, "Register line: FID = %d offset = %ld", FID, offset_value);
153 dig_line_box(Points, &box);
154 line = dig_add_line(plus, type, Points, &box, offset_value);
155 G_debug(4, "Line registered with line = %d", line);
156
157 /* Set box */
158 if (line == 1)
159 Vect_box_copy(&(plus->box), &box);
160 else
161 Vect_box_extend(&(plus->box), &box);
162
163 if (type != GV_BOUNDARY) {
164 dig_cidx_add_cat(plus, 1, (int)FID, line, type);
165 }
166 else {
167 dig_cidx_add_cat(plus, 0, 0, line, type);
168 }
169
170 /* because centroids are read from topology, not from layer */
171 if (type != GV_CENTROID)
172 add_parts_to_offset(offset, parts);
173
174 return line;
175}
176
177#ifdef HAVE_POSTGRES
178/*!
179 \brief Recursively add geometry (PostGIS) to topology
180 */
181int add_geometry_pg(struct Plus_head *plus, struct Format_info_pg *pg_info,
182 struct feat_parts *fparts, int ipart, int FID, int build,
183 struct geom_parts *parts)
184{
185 int line, i, idx, area, isle, outer_area, ret;
186 int lines[1];
187 double area_size, x, y;
189 struct bound_box box;
190 struct Format_info_offset *offset;
191 struct line_pnts *line_i;
192
193 ftype = fparts->ftype[ipart];
194
195 G_debug(4, "add_geometry_pg() FID = %d ftype = %d", FID, ftype);
196
197 offset = &(pg_info->offset);
198
199 outer_area = 0;
200
201 switch (ftype) {
202 case SF_POINT:
203 G_debug(4, "Point");
204 line_i = pg_info->cache.lines[fparts->idx[ipart]];
205 add_line(plus, offset, GV_POINT, line_i, FID, parts);
206 break;
207 case SF_LINESTRING:
208 G_debug(4, "LineString");
209 line_i = pg_info->cache.lines[fparts->idx[ipart]];
210 add_line(plus, offset, GV_LINE, line_i, FID, parts);
211 break;
212 case SF_POLYGON:
213 G_debug(4, "Polygon");
214
215 /* register boundaries */
216 idx = fparts->idx[ipart];
217 for (i = 0; i < fparts->nlines[ipart]; i++) {
218 line_i = pg_info->cache.lines[idx++];
219 G_debug(4, "part %d", i);
220 add_part(parts, i);
221 line = add_line(plus, offset, GV_BOUNDARY, line_i, FID, parts);
222 del_part(parts);
223
224 if (build < GV_BUILD_AREAS)
225 continue;
226
227 /* add area (each inner ring is also area) */
228 dig_line_box(line_i, &box);
230
231 if (area_size > 0) /* area clockwise */
232 lines[0] = line;
233 else
234 lines[0] = -line;
235
236 area = dig_add_area(plus, 1, lines, &box);
237
238 /* each area is also isle */
239 lines[0] = -lines[0]; /* island is counter clockwise */
240
241 isle = dig_add_isle(plus, 1, lines, &box);
242
244 continue;
245
246 if (i == 0) { /* outer ring */
247 outer_area = area;
248 }
249 else { /* inner ring */
250 struct P_isle *Isle;
251
252 Isle = plus->Isle[isle];
253 Isle->area = outer_area;
254
256 }
257 }
258
259 if (build >= GV_BUILD_CENTROIDS) {
260 /* create virtual centroid */
262 (const struct line_pnts *)
263 pg_info->cache.lines[fparts->idx[ipart]],
264 (const struct line_pnts **)&pg_info->cache
265 .lines[fparts->idx[ipart]] +
266 1,
267 fparts->nlines[ipart] - 1, &x, &y);
268 if (ret < -1) {
269 G_warning(_("Unable to calculate centroid for area %d"),
270 outer_area);
271 }
272 else {
273 struct P_area *Area;
274 struct P_topo_c *topo;
275 struct P_line *Line;
276 struct line_pnts *line_c;
277
278 G_debug(4, " Centroid: %f, %f", x, y);
280 Vect_append_point(line_c, x, y, 0.0);
281 line = add_line(plus, offset, GV_CENTROID, line_c, FID, parts);
282
283 Line = plus->Line[line];
284 topo = (struct P_topo_c *)Line->topo;
285 topo->area = outer_area;
286
287 /* register centroid to area */
288 Area = plus->Area[outer_area];
289 Area->centroid = line;
291 }
292 }
293 break;
294 default:
295 G_warning(_("Feature type %d not supported"), ftype);
296 break;
297 }
298
299 return 0;
300}
301
302/*!
303 \brief Build pseudo-topology for PostGIS layers
304 */
305void build_pg(struct Map_info *Map, int build)
306{
307 int iFeature, ipart, fid, nrecords, npoints;
308 char *wkb_data;
309
310 struct Format_info_pg *pg_info;
311
312 struct feat_parts fparts;
313 struct geom_parts parts;
314
315 pg_info = &(Map->fInfo.pg);
316
317 /* initialize data structures */
318 init_parts(&parts);
319 G_zero(&fparts, sizeof(struct feat_parts));
320
321 /* get all features */
322 if (Vect__open_cursor_next_line_pg(pg_info, TRUE, Map->plus.built) != 0)
323 return;
324
325 /* scan records */
326 npoints = 0;
327 nrecords = PQntuples(pg_info->res);
328 G_debug(4, "build_pg(): nrecords = %d", nrecords);
329 G_message(_("Registering primitives..."));
330 for (iFeature = 0; iFeature < nrecords; iFeature++) {
331 /* get feature id */
332 fid = atoi(PQgetvalue(pg_info->res, iFeature, 1));
333 if (fid < 1)
334 continue; /* PostGIS Topology: skip features with negative
335 * fid (isles, universal face, ...) */
336
337 wkb_data = PQgetvalue(pg_info->res, iFeature, 0);
338
339 G_progress(iFeature + 1, 1e4);
340
341 /* cache feature (lines) */
342 if (SF_NONE == Vect__cache_feature_pg(wkb_data, FALSE, FALSE,
343 &(pg_info->cache), &fparts)) {
344 G_warning(_("Feature %d without geometry skipped"), iFeature + 1);
345 continue;
346 }
347
348 /* register all parts */
349 reset_parts(&parts);
350 add_part(&parts, fid);
351 for (ipart = 0; ipart < fparts.n_parts; ipart++) {
352 if (fparts.nlines[ipart] < 1) {
353 G_warning(_("Feature %d without geometry skipped"), fid);
354 continue;
355 }
356
357 npoints += pg_info->cache.lines[ipart]->n_points;
358
359 G_debug(4, "Feature: fid = %d part = %d", fid, ipart);
360
361 if (fparts.n_parts > 1)
363 add_geometry_pg(&(Map->plus), pg_info, &fparts, ipart, fid, build,
364 &parts);
365 if (fparts.n_parts > 1)
366 del_part(&parts);
367 }
368
369 /* read next feature from cache */
370 pg_info->cache.lines_next = 0;
371 }
372 G_progress(1, 1);
373
374 G_message(n_("One primitive registered", "%d primitives registered",
375 Map->plus.n_lines),
376 Map->plus.n_lines);
377 G_message(n_("One vertex registered", "%d vertices registered", npoints),
378 npoints);
379
380 Map->plus.built = GV_BUILD_BASE;
381
382 PQclear(pg_info->res);
383 pg_info->res = NULL;
384
385 /* free allocated space */
386 free_parts(&parts);
387}
388#endif /* HAVE_POSTGRES */
389
390/*!
391 \brief Recursively add geometry (OGR) to topology
392 */
393int add_geometry_ogr(struct Plus_head *plus, struct Format_info_ogr *ogr_info,
394 OGRGeometryH hGeom, int FID, int build,
395 struct geom_parts *parts)
396{
397 int i, ret, npoints, line;
398 int area, isle, outer_area;
399 int lines[1];
400 double area_size, x, y;
401 int eType, nRings, iPart, nParts, nPoints;
402
403 struct bound_box box;
404 struct P_line *Line;
405 struct Format_info_offset *offset;
406
408
409 G_debug(4, "add_geometry_ogr() FID = %d", FID);
410
411 offset = &(ogr_info->offset);
412
413 /* allocate space in cache */
414 if (!ogr_info->cache.lines) {
415 ogr_info->cache.lines_alloc = 1;
416 ogr_info->cache.lines =
417 (struct line_pnts **)G_malloc(sizeof(struct line_pnts *));
418
419 ogr_info->cache.lines_types = (int *)G_malloc(sizeof(int));
420 ogr_info->cache.lines[0] = Vect_new_line_struct();
421 ogr_info->cache.lines_types[0] = -1;
422 }
423
424 npoints = outer_area = 0;
426 G_debug(4, "OGR type = %d", eType);
427
428 switch (eType) {
429 case wkbPoint:
430 G_debug(4, "Point");
431
432 ogr_info->cache.lines_types[0] = GV_POINT;
433 Vect_reset_line(ogr_info->cache.lines[0]);
434 Vect_append_point(ogr_info->cache.lines[0], OGR_G_GetX(hGeom, 0),
436 add_line(plus, offset, GV_POINT, ogr_info->cache.lines[0], FID, parts);
437 npoints += ogr_info->cache.lines[0]->n_points;
438 break;
439
440 case wkbLineString:
441 G_debug(4, "LineString");
442
443 ogr_info->cache.lines_types[0] = GV_LINE;
445 Vect_reset_line(ogr_info->cache.lines[0]);
446 for (i = 0; i < nPoints; i++) {
447 Vect_append_point(ogr_info->cache.lines[0], OGR_G_GetX(hGeom, i),
449 }
450 add_line(plus, offset, GV_LINE, ogr_info->cache.lines[0], FID, parts);
451 npoints += ogr_info->cache.lines[0]->n_points;
452 break;
453
454 case wkbPolygon:
455 G_debug(4, "Polygon");
456
458 G_debug(4, "Number of rings: %d", nRings);
459
460 /* alloc space for islands if needed */
461 if (nRings > ogr_info->cache.lines_alloc) {
462 ogr_info->cache.lines_alloc += nRings;
463 ogr_info->cache.lines = (struct line_pnts **)G_realloc(
464 ogr_info->cache.lines,
465 ogr_info->cache.lines_alloc * sizeof(struct line_pnts *));
466 ogr_info->cache.lines_types =
467 (int *)G_realloc(ogr_info->cache.lines_types,
468 ogr_info->cache.lines_alloc * sizeof(int));
469
470 for (i = ogr_info->cache.lines_alloc - nRings;
471 i < ogr_info->cache.lines_alloc; i++) {
472 ogr_info->cache.lines[i] = Vect_new_line_struct();
473 ogr_info->cache.lines_types[i] = -1;
474 }
475 }
476
477 /* go through rings */
478 for (iPart = 0; iPart < nRings; iPart++) {
479 ogr_info->cache.lines_types[iPart] = GV_BOUNDARY;
482 G_debug(4, " ring %d : nPoints = %d", iPart, nPoints);
483
484 Vect_reset_line(ogr_info->cache.lines[iPart]);
485 for (i = 0; i < nPoints; i++) {
486 Vect_append_point(ogr_info->cache.lines[iPart],
488 OGR_G_GetZ(hRing, i));
489 }
490 npoints += ogr_info->cache.lines[iPart]->n_points;
491
492 /* register boundary */
494 line = add_line(plus, offset, GV_BOUNDARY,
495 ogr_info->cache.lines[iPart], FID, parts);
496 del_part(parts);
497
498 if (build < GV_BUILD_AREAS)
499 continue;
500
501 /* add area (each inner ring is also area) */
502 dig_line_box(ogr_info->cache.lines[iPart], &box);
504
505 if (area_size > 0) /* area clockwise */
506 lines[0] = line;
507 else
508 lines[0] = -line;
509
510 area = dig_add_area(plus, 1, lines, &box);
511
512 /* each area is also isle */
513 lines[0] = -lines[0]; /* island is counter clockwise */
514
515 isle = dig_add_isle(plus, 1, lines, &box);
516
518 continue;
519
520 if (iPart == 0) { /* outer ring */
521 outer_area = area;
522 }
523 else { /* inner ring */
524 struct P_isle *Isle;
525
526 Isle = plus->Isle[isle];
527 Isle->area = outer_area;
528
530 }
531 }
532
533 if (build >= GV_BUILD_CENTROIDS) {
534 /* create virtual centroid */
536 (const struct line_pnts *)ogr_info->cache.lines[0],
537 (const struct line_pnts **)ogr_info->cache.lines + 1,
538 nRings - 1, &x, &y);
539 if (ret < -1) {
540 G_warning(_("Unable to calculate centroid for area %d"),
541 outer_area);
542 }
543 else {
544 struct P_area *Area;
545 struct P_topo_c *topo;
546
547 G_debug(4, " Centroid: %f, %f", x, y);
548 Vect_reset_line(ogr_info->cache.lines[0]);
549 Vect_append_point(ogr_info->cache.lines[0], x, y, 0.0);
550 line = add_line(plus, offset, GV_CENTROID,
551 ogr_info->cache.lines[0], FID, parts);
552
553 Line = plus->Line[line];
554 topo = (struct P_topo_c *)Line->topo;
555 topo->area = outer_area;
556
557 /* register centroid to area */
558 Area = plus->Area[outer_area];
559 Area->centroid = line;
560 }
561 }
562 break;
563
564 case wkbMultiPoint:
566 case wkbMultiPolygon:
569 G_debug(4, "%d geoms -> next level", nParts);
570
571 /* alloc space for parts if needed */
572 if (nParts > ogr_info->cache.lines_alloc) {
573 ogr_info->cache.lines_alloc += nParts;
574 ogr_info->cache.lines = (struct line_pnts **)G_realloc(
575 ogr_info->cache.lines,
576 ogr_info->cache.lines_alloc * sizeof(struct line_pnts *));
577 ogr_info->cache.lines_types =
578 (int *)G_realloc(ogr_info->cache.lines_types,
579 ogr_info->cache.lines_alloc * sizeof(int));
580
581 for (i = ogr_info->cache.lines_alloc - nParts;
582 i < ogr_info->cache.lines_alloc; i++) {
583 ogr_info->cache.lines[i] = Vect_new_line_struct();
584 ogr_info->cache.lines_types[i] = -1;
585 }
586 }
587
588 /* go through all parts */
589 for (i = 0; i < nParts; i++) {
590 add_part(parts, i);
592 npoints +=
593 add_geometry_ogr(plus, ogr_info, hGeom2, FID, build, parts);
594 del_part(parts);
595 }
596 break;
597
598 default:
599 G_warning(_("OGR feature type %d not supported"), eType);
600 break;
601 }
602
603 return npoints;
604}
605
606void build_ogr(struct Map_info *Map, int build)
607{
608 int iFeature, FID, npoints, nskipped;
609
611
614
615 struct geom_parts parts;
616
617 ogr_info = &(Map->fInfo.ogr);
618
619 /* initialize data structures */
620 init_parts(&parts);
621
622 /* Note: Do not use OGR_L_GetFeatureCount (it may scan all features) */
624 if (ogr_info->where)
625 /* set attribute filter if where sql statement defined */
627 npoints = iFeature = nskipped = 0;
628 G_message(_("Registering primitives..."));
629 while ((hFeature = OGR_L_GetNextFeature(ogr_info->layer)) != NULL) {
630 G_debug(3, " Feature %d", iFeature);
631
633
635 if (hGeom == NULL) {
636 G_debug(3, "Feature %d without geometry skipped", iFeature);
638 nskipped++;
639 continue;
640 }
641
643 if (FID == OGRNullFID) {
644 G_debug(3, "OGR feature %d without ID skipped", iFeature);
646 nskipped++;
647 continue;
648 }
649 G_debug(4, " FID = %d", FID);
650
651 reset_parts(&parts);
652 add_part(&parts, FID);
653 npoints +=
654 add_geometry_ogr(&(Map->plus), ogr_info, hGeom, FID, build, &parts);
655
657 } /* while */
658 G_progress(1, 1);
659
660 G_message(n_("One primitive registered", "%d primitives registered",
661 Map->plus.n_lines),
662 Map->plus.n_lines);
663 G_message(n_("One vertex registered", "%d vertices registered", npoints),
664 npoints);
665
666 if (nskipped > 0)
667 G_warning(n_("One feature without geometry skipped",
668 "%d features without geometry skipped", nskipped),
669 nskipped);
670
671 Map->plus.built = GV_BUILD_BASE;
672
673 free_parts(&parts);
674}
675
676/*!
677 \brief Build pseudo-topology (for simple features) - internal use only
678
679 See Vect_build_ogr() and Vect_build_pg() for implementation issues.
680
681 Build levels:
682 - GV_BUILD_NONE
683 - GV_BUILD_BASE
684 - GV_BUILD_ATTACH_ISLES
685 - GV_BUILD_CENTROIDS
686 - GV_BUILD_ALL
687
688 \param Map pointer to Map_info structure
689 \param build build level
690
691 \return 1 on success
692 \return 0 on error
693 */
695{
696 struct Plus_head *plus;
697
698 plus = &(Map->plus);
699
700 /* check if upgrade or downgrade */
702 /* -> downgrade */
704 return 1;
705 }
706
707 /* -> upgrade */
708 if (plus->built < GV_BUILD_BASE) {
709 if (Map->format == GV_FORMAT_OGR ||
710 Map->format == GV_FORMAT_OGR_DIRECT) {
711 build_ogr(Map, build);
712 }
713 else if (Map->format == GV_FORMAT_POSTGIS) {
714#ifdef HAVE_POSTGRES
715 build_pg(Map, build);
716#else
717 G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
718#endif
719 }
720 else {
721 G_fatal_error(_("%s: Native format unsupported"),
722 "Vect__build_sfa()");
723 }
724 }
725
726 plus->built = build;
727
728 return 1;
729}
730
731/*!
732 \brief Dump feature index to file
733
734 \param Map pointer to Map_info struct
735 \param out file for output (stdout/stderr for example)
736
737 \return 1 on success
738 \return 0 on error
739 */
741{
742 int i;
743 const struct Format_info_offset *offset;
744
745 if (Map->format != GV_FORMAT_OGR && Map->format != GV_FORMAT_POSTGIS) {
746 G_warning(_("Feature index is built only for non-native formats. "
747 "Nothing to dump."));
748 return 0;
749 }
750
751 if (Map->format == GV_FORMAT_OGR)
752 offset = &(Map->fInfo.ogr.offset);
753 else
754 offset = &(Map->fInfo.pg.offset);
755
756 fprintf(out, "---------- FEATURE INDEX DUMP ----------\n");
757
758 fprintf(out, "format: %s\n", Vect_maptype_info(Map));
759 if (Vect_maptype(Map) == GV_FORMAT_POSTGIS && Map->fInfo.pg.toposchema_name)
760 fprintf(out, "topology: PostGIS\n");
761 else
762 fprintf(out, "topology: pseudo\n");
763 fprintf(out, "feature type: %s\n", Vect_get_finfo_geometry_type(Map));
764 fprintf(out,
765 "number of features: %d\n\noffset : value (fid or part idx):\n",
767 for (i = 0; i < offset->array_num; i++) {
768 fprintf(out, "%6d : %d\n", i, offset->array[i]);
769 }
770
771 return 1;
772}
int Vect__build_sfa(struct Map_info *Map, int build)
Build pseudo-topology (for simple features) - internal use only.
Definition build_sfa.c:694
int Vect_fidx_dump(struct Map_info *Map, FILE *out)
Dump feature index to file.
Definition build_sfa.c:740
#define NULL
Definition ccmath.h:32
void G_zero(void *, int)
Zero out a buffer, buf, of length i.
Definition gis/zero.c:21
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:145
#define G_realloc(p, n)
Definition defs/gis.h:138
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
void G_progress(long, int)
Print progress info messages.
Definition percent.c:156
#define G_malloc(n)
Definition defs/gis.h:136
void G_message(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
void Vect_destroy_line_struct(struct line_pnts *)
Frees all memory associated with a line_pnts structure, including the structure itself.
Definition line.c:75
plus_t Vect_get_num_lines(struct Map_info *)
Fetch number of features (points, lines, boundaries, centroids) in vector map.
Definition level_two.c:73
int Vect_get_point_in_poly_isl(const struct line_pnts *, const struct line_pnts **, int, double *, double *)
Get point inside polygon but outside the islands specifiled in IPoints.
Definition Vlib/poly.c:545
void Vect__build_downgrade(struct Map_info *, int)
Downgrade build level (for internal use only)
Definition build.c:765
int Vect_box_extend(struct bound_box *, const struct bound_box *)
Extend box A by box B.
const char * Vect_maptype_info(struct Map_info *)
Gets vector map format (as string)
int Vect_maptype(struct Map_info *)
Gets vector map format.
const char * Vect_get_finfo_geometry_type(struct Map_info *)
Get geometry type as string (relevant only for non-native formats)
void Vect_reset_line(struct line_pnts *)
Reset line.
Definition line.c:127
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
Definition line.c:43
int Vect_append_point(struct line_pnts *, double, double, double)
Appends one point to the end of a line.
Definition line.c:146
int Vect_box_copy(struct bound_box *, const struct bound_box *)
Copy box B to box A.
#define GV_CENTROID
SF_FeatureType
Simple feature types.
@ SF_POLYGON
@ SF_NONE
@ SF_LINESTRING
@ SF_POINT
#define GV_FORMAT_POSTGIS
PostGIS format.
Definition dig_defines.h:89
#define GV_LINE
#define GV_POINT
Feature types used in memory on run time (may change)
#define GV_BOUNDARY
#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_AREAS
Topology levels - build areas.
#define GV_BUILD_CENTROIDS
Topology levels - assign centroids to areas.
#define GV_FORMAT_OGR_DIRECT
OGR format (direct access)
Definition dig_defines.h:87
#define GV_FORMAT_OGR
OGR format.
Definition dig_defines.h:85
int dig_add_isle(struct Plus_head *, int, plus_t *, struct bound_box *)
Allocate space for new island and create boundary info from array.
Definition plus_area.c:703
int dig_area_add_isle(struct Plus_head *, int, int)
Add isle to area if does not exist yet.
Definition plus_area.c:265
int dig_cidx_add_cat(struct Plus_head *, int, int, int, int)
int dig_add_area(struct Plus_head *, int, plus_t *, struct bound_box *)
Allocate space for new area and create boundary info from array.
Definition plus_area.c:187
int dig_find_area_poly(struct line_pnts *, double *)
Definition diglib/poly.c:94
int dig_add_line(struct Plus_head *, int, const struct line_pnts *, const struct bound_box *, off_t)
Add new line to Plus_head structure.
Definition plus_line.c:133
int dig_line_box(const struct line_pnts *, struct bound_box *)
#define TRUE
Definition gis.h:75
#define FALSE
Definition gis.h:79
#define n_(strs, strp, num)
Definition glocale.h:11
#define _(str)
Definition glocale.h:10
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.
Definition read_pg.c:777
int Vect__open_cursor_next_line_pg(struct Format_info_pg *pg_info, int fetch_all, int built_level)
Create select cursor for sequential access (internal use only)
Definition read_pg.c:1251
Data structure used for building pseudo-topology.
int * array
Offset list.
int array_alloc
Space allocated for offset list.
int array_num
Number of items in offset list.
Non-native format info (OGR)
Non-native format info (PostGIS)
Vector map info.
Area (topology) info.
Isle (topology) info.
plus_t area
Area it exists w/in, if any.
Vector geometry.
void * topo
Topology info.
Centroid topology.
Basic topology-related info.
struct P_line ** Line
Array of vector geometries.
struct P_area ** Area
Array of areas.
struct bound_box box
Bounding box of features.
struct P_isle ** Isle
Array of isles.
int built
Highest level of topology currently available.
Bounding box.
Definition dig_structs.h:62
Feature geometry info - coordinates.
double * y
Array of Y coordinates.
double * x
Array of X coordinates.
void add_part(SYMBOL *s, SYMBPART *p)
Definition symbol/read.c:68
#define x