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