GRASS 8 Programmer's Manual 8.6.0dev(2026)-ba898e78d7
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 <inttypes.h>
21#include <stdlib.h>
22
23#include <grass/gis.h>
24#include <grass/vector.h>
25#include <grass/glocale.h>
26
27#include <ogr_api.h>
28
29/*!
30 \brief This structure keeps info about geometry parts above current
31 geometry, path to current geometry in the feature. First 'part' number
32 however is feature id */
33struct geom_parts {
34 int *part;
35 int a_parts;
36 int n_parts;
37};
38
39static void init_parts(struct geom_parts *);
40static void reset_parts(struct geom_parts *);
41static void free_parts(struct geom_parts *);
42static void add_part(struct geom_parts *, int);
43static void del_part(struct geom_parts *);
44static void add_parts_to_offset(struct Format_info_offset *,
45 struct geom_parts *);
46static int add_line(struct Plus_head *, struct Format_info_offset *, int,
47 struct line_pnts *, int, struct geom_parts *);
48
49#ifdef HAVE_POSTGRES
50#include "pg_local_proto.h"
51
52static int add_geometry_pg(struct Plus_head *, struct Format_info_pg *,
53 struct feat_parts *, int, int, int,
54 struct geom_parts *);
55static void build_pg(struct Map_info *, int);
56#endif
57
58static int add_geometry_ogr(struct Plus_head *, struct Format_info_ogr *,
59 OGRGeometryH, int, int, struct geom_parts *);
60
61static void build_ogr(struct Map_info *, int);
62
63/*!
64 \brief Init parts
65 */
66void init_parts(struct geom_parts *parts)
67{
68 G_zero(parts, sizeof(struct geom_parts));
69}
70
71/*!
72 \brief Reset parts
73 */
74void reset_parts(struct geom_parts *parts)
75{
76 parts->n_parts = 0;
77}
78
79/*!
80 \brief Free parts
81 */
82void free_parts(struct geom_parts *parts)
83{
84 G_free(parts->part);
85 G_zero(parts, sizeof(struct geom_parts));
86}
87
88/*!
89 \brief Add new part number to parts
90 */
91void add_part(struct geom_parts *parts, int part)
92{
93 if (parts->a_parts == parts->n_parts) {
94 parts->a_parts += 10;
95 parts->part =
96 (int *)G_realloc((void *)parts->part, parts->a_parts * sizeof(int));
97 }
98 parts->part[parts->n_parts] = part;
99 parts->n_parts++;
100}
101
102/*!
103 \brief Remove last part
104 */
105void del_part(struct geom_parts *parts)
106{
107 parts->n_parts--;
108}
109
110/*!
111 \brief Add parts to offset
112 */
113void add_parts_to_offset(struct Format_info_offset *offset,
114 struct geom_parts *parts)
115{
116 int i, j;
117
118 if (offset->array_num + parts->n_parts >= offset->array_alloc) {
119 offset->array_alloc += parts->n_parts + 1000;
120 offset->array =
121 (int *)G_realloc(offset->array, offset->array_alloc * sizeof(int));
122 }
123 j = offset->array_num;
124 for (i = 0; i < parts->n_parts; i++) {
125 G_debug(4, "add offset %d", parts->part[i]);
126 offset->array[j] = parts->part[i];
127 j++;
128 }
129 offset->array_num += parts->n_parts;
130}
131
132/*!
133 \brief Add line to support structures
134 */
135int add_line(struct Plus_head *plus, struct Format_info_offset *offset,
136 int type, struct line_pnts *Points, int FID,
137 struct geom_parts *parts)
138{
139 int line;
140 long offset_value;
141 struct bound_box box;
142
143 if (type != GV_CENTROID) {
144 /* beginning in the offset array */
145 offset_value = offset->array_num;
146 }
147 else {
148 /* TODO : could be used to statore category ? */
149 /* because centroids are read from topology, not from layer */
151 }
152
153 G_debug(4, "Register line: FID = %d offset = %ld", FID, offset_value);
154 dig_line_box(Points, &box);
155 line = dig_add_line(plus, type, Points, &box, offset_value);
156 G_debug(4, "Line registered with line = %d", line);
157
158 /* Set box */
159 if (line == 1)
160 Vect_box_copy(&(plus->box), &box);
161 else
162 Vect_box_extend(&(plus->box), &box);
163
164 if (type != GV_BOUNDARY) {
165 dig_cidx_add_cat(plus, 1, (int)FID, line, type);
166 }
167 else {
168 dig_cidx_add_cat(plus, 0, 0, line, type);
169 }
170
171 /* because centroids are read from topology, not from layer */
172 if (type != GV_CENTROID)
173 add_parts_to_offset(offset, parts);
174
175 return line;
176}
177
178#ifdef HAVE_POSTGRES
179/*!
180 \brief Recursively add geometry (PostGIS) to topology
181 */
182int add_geometry_pg(struct Plus_head *plus, struct Format_info_pg *pg_info,
183 struct feat_parts *fparts, int ipart, int FID, int build,
184 struct geom_parts *parts)
185{
186 int line, i, idx, area, isle, outer_area, ret;
187 int lines[1];
188 double area_size, x, y;
190 struct bound_box box;
191 struct Format_info_offset *offset;
192 struct line_pnts *line_i;
193
194 ftype = fparts->ftype[ipart];
195
196 G_debug(4, "add_geometry_pg() FID = %d ftype = %d", FID, ftype);
197
198 offset = &(pg_info->offset);
199
200 outer_area = 0;
201
202 switch (ftype) {
203 case SF_POINT:
204 G_debug(4, "Point");
205 line_i = pg_info->cache.lines[fparts->idx[ipart]];
206 add_line(plus, offset, GV_POINT, line_i, FID, parts);
207 break;
208 case SF_LINESTRING:
209 G_debug(4, "LineString");
210 line_i = pg_info->cache.lines[fparts->idx[ipart]];
211 add_line(plus, offset, GV_LINE, line_i, FID, parts);
212 break;
213 case SF_POLYGON:
214 G_debug(4, "Polygon");
215
216 /* register boundaries */
217 idx = fparts->idx[ipart];
218 for (i = 0; i < fparts->nlines[ipart]; i++) {
219 line_i = pg_info->cache.lines[idx++];
220 G_debug(4, "part %d", i);
221 add_part(parts, i);
222 line = add_line(plus, offset, GV_BOUNDARY, line_i, FID, parts);
223 del_part(parts);
224
225 if (build < GV_BUILD_AREAS)
226 continue;
227
228 /* add area (each inner ring is also area) */
229 dig_line_box(line_i, &box);
231
232 if (area_size > 0) /* area clockwise */
233 lines[0] = line;
234 else
235 lines[0] = -line;
236
237 area = dig_add_area(plus, 1, lines, &box);
238
239 /* each area is also isle */
240 lines[0] = -lines[0]; /* island is counter clockwise */
241
242 isle = dig_add_isle(plus, 1, lines, &box);
243
245 continue;
246
247 if (i == 0) { /* outer ring */
248 outer_area = area;
249 }
250 else { /* inner ring */
251 struct P_isle *Isle;
252
253 Isle = plus->Isle[isle];
254 Isle->area = outer_area;
255
257 }
258 }
259
260 if (build >= GV_BUILD_CENTROIDS) {
261 /* create virtual centroid */
263 (const struct line_pnts *)
264 pg_info->cache.lines[fparts->idx[ipart]],
265 (const struct line_pnts **)&pg_info->cache
266 .lines[fparts->idx[ipart]] +
267 1,
268 fparts->nlines[ipart] - 1, &x, &y);
269 if (ret < -1) {
270 G_warning(_("Unable to calculate centroid for area %d"),
271 outer_area);
272 }
273 else {
274 struct P_area *Area;
275 struct P_topo_c *topo;
276 struct P_line *Line;
277 struct line_pnts *line_c;
278
279 G_debug(4, " Centroid: %f, %f", x, y);
281 Vect_append_point(line_c, x, y, 0.0);
282 line = add_line(plus, offset, GV_CENTROID, line_c, FID, parts);
283
284 Line = plus->Line[line];
285 topo = (struct P_topo_c *)Line->topo;
286 topo->area = outer_area;
287
288 /* register centroid to area */
289 Area = plus->Area[outer_area];
290 Area->centroid = line;
292 }
293 }
294 break;
295 default:
296 G_warning(_("Feature type %d not supported"), ftype);
297 break;
298 }
299
300 return 0;
301}
302
303/*!
304 \brief Build pseudo-topology for PostGIS layers
305 */
306void build_pg(struct Map_info *Map, int build)
307{
308 int iFeature, ipart, fid, nrecords, npoints;
309 char *wkb_data;
310
311 struct Format_info_pg *pg_info;
312
313 struct feat_parts fparts;
314 struct geom_parts parts;
315
316 pg_info = &(Map->fInfo.pg);
317
318 /* initialize data structures */
319 init_parts(&parts);
320 G_zero(&fparts, sizeof(struct feat_parts));
321
322 /* get all features */
323 if (Vect__open_cursor_next_line_pg(pg_info, TRUE, Map->plus.built) != 0)
324 return;
325
326 /* scan records */
327 npoints = 0;
328 nrecords = PQntuples(pg_info->res);
329 G_debug(4, "build_pg(): nrecords = %d", nrecords);
330 G_message(_("Registering primitives..."));
331 for (iFeature = 0; iFeature < nrecords; iFeature++) {
332 /* get feature id */
333 fid = atoi(PQgetvalue(pg_info->res, iFeature, 1));
334 if (fid < 1)
335 continue; /* PostGIS Topology: skip features with negative
336 * fid (isles, universal face, ...) */
337
338 wkb_data = PQgetvalue(pg_info->res, iFeature, 0);
339
340 G_progress(iFeature + 1, 1e4);
341
342 /* cache feature (lines) */
343 if (SF_NONE == Vect__cache_feature_pg(wkb_data, FALSE, FALSE,
344 &(pg_info->cache), &fparts)) {
345 G_warning(_("Feature %d without geometry skipped"), iFeature + 1);
346 continue;
347 }
348
349 /* register all parts */
350 reset_parts(&parts);
351 add_part(&parts, fid);
352 for (ipart = 0; ipart < fparts.n_parts; ipart++) {
353 if (fparts.nlines[ipart] < 1) {
354 G_warning(_("Feature %d without geometry skipped"), fid);
355 continue;
356 }
357
358 npoints += pg_info->cache.lines[ipart]->n_points;
359
360 G_debug(4, "Feature: fid = %d part = %d", fid, ipart);
361
362 if (fparts.n_parts > 1)
364 add_geometry_pg(&(Map->plus), pg_info, &fparts, ipart, fid, build,
365 &parts);
366 if (fparts.n_parts > 1)
367 del_part(&parts);
368 }
369
370 /* read next feature from cache */
371 pg_info->cache.lines_next = 0;
372 }
373 G_progress(1, 1);
374
375 G_message(n_("One primitive registered", "%d primitives registered",
376 Map->plus.n_lines),
377 Map->plus.n_lines);
378 G_message(n_("One vertex registered", "%" PRId64 " vertices registered",
379 (int64_t)npoints),
380 (int64_t)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", "%" PRId64 " vertices registered",
666 (int64_t)npoints),
667 (int64_t)npoints);
668
669 if (nskipped > 0)
670 G_warning(n_("One feature without geometry skipped",
671 "%d features without geometry skipped", nskipped),
672 nskipped);
673
674 Map->plus.built = GV_BUILD_BASE;
675
676 free_parts(&parts);
677}
678
679/*!
680 \brief Build pseudo-topology (for simple features) - internal use only
681
682 See Vect_build_ogr() and Vect_build_pg() for implementation issues.
683
684 Build levels:
685 - GV_BUILD_NONE
686 - GV_BUILD_BASE
687 - GV_BUILD_ATTACH_ISLES
688 - GV_BUILD_CENTROIDS
689 - GV_BUILD_ALL
690
691 \param Map pointer to Map_info structure
692 \param build build level
693
694 \return 1 on success
695 \return 0 on error
696 */
698{
699 struct Plus_head *plus;
700
701 plus = &(Map->plus);
702
703 /* check if upgrade or downgrade */
705 /* -> downgrade */
707 return 1;
708 }
709
710 /* -> upgrade */
711 if (plus->built < GV_BUILD_BASE) {
712 if (Map->format == GV_FORMAT_OGR ||
713 Map->format == GV_FORMAT_OGR_DIRECT) {
714 build_ogr(Map, build);
715 }
716 else if (Map->format == GV_FORMAT_POSTGIS) {
717#ifdef HAVE_POSTGRES
718 build_pg(Map, build);
719#else
720 G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
721#endif
722 }
723 else {
724 G_fatal_error(_("%s: Native format unsupported"),
725 "Vect__build_sfa()");
726 }
727 }
728
729 plus->built = build;
730
731 return 1;
732}
733
734/*!
735 \brief Dump feature index to file
736
737 \param Map pointer to Map_info struct
738 \param out file for output (stdout/stderr for example)
739
740 \return 1 on success
741 \return 0 on error
742 */
744{
745 int i;
746 const struct Format_info_offset *offset;
747
748 if (Map->format != GV_FORMAT_OGR && Map->format != GV_FORMAT_POSTGIS) {
749 G_warning(_("Feature index is built only for non-native formats. "
750 "Nothing to dump."));
751 return 0;
752 }
753
754 if (Map->format == GV_FORMAT_OGR)
755 offset = &(Map->fInfo.ogr.offset);
756 else
757 offset = &(Map->fInfo.pg.offset);
758
759 fprintf(out, "---------- FEATURE INDEX DUMP ----------\n");
760
761 fprintf(out, "format: %s\n", Vect_maptype_info(Map));
762 if (Vect_maptype(Map) == GV_FORMAT_POSTGIS && Map->fInfo.pg.toposchema_name)
763 fprintf(out, "topology: PostGIS\n");
764 else
765 fprintf(out, "topology: pseudo\n");
766 fprintf(out, "feature type: %s\n", Vect_get_finfo_geometry_type(Map));
767 fprintf(out,
768 "number of features: %d\n\noffset : value (fid or part idx):\n",
770 for (i = 0; i < offset->array_num; i++) {
771 fprintf(out, "%6d : %d\n", i, offset->array[i]);
772 }
773
774 return 1;
775}
int Vect__build_sfa(struct Map_info *Map, int build)
Build pseudo-topology (for simple features) - internal use only.
Definition build_sfa.c:697
int Vect_fidx_dump(struct Map_info *Map, FILE *out)
Dump feature index to file.
Definition build_sfa.c:743
#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:77
#define FALSE
Definition gis.h:81
#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