File: vectorlib_topology.dox

package info (click to toggle)
grass 8.4.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 277,040 kB
  • sloc: ansic: 460,798; python: 227,732; cpp: 42,026; sh: 11,262; makefile: 7,007; xml: 3,637; sql: 968; lex: 520; javascript: 484; yacc: 450; asm: 387; perl: 157; sed: 25; objc: 6; ruby: 4
file content (450 lines) | stat: -rw-r--r-- 13,708 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
/*! \page vlibTopology Topology

by GRASS Development Team (https://grass.osgeo.org)

\tableofcontents

\section vlibTopoManagement Vector library topology management

Topology general characteristics:

- geometry and attributes are stored separately
   (don't read both if it is not necessary - usually it is not)
- the format is topological (areas build from boundaries)
- currently only 2D topology is supported

Topology is written for native GRASS vector format; in case of
linked OGR sources (see <tt>v.external</tt> module), only
pseudo-topology (boundaries constructed from polygons) is written.

The following rules apply to the vector data:

- Boundaries should not cross each other (i.e., boundaries which would
  cross must be split at their intersection to form distict boundaries).
  On the contrary, lines can cross each other, e.g. bridges over rivers.
- Lines and boundaries share nodes only if their endpoints are identical.
  Lines or boundaries can be forced to share a common node by snapping
  them together. This is particularly important since nodes
  are not represented in the coor file, but only implicitly as
  endpoints of lines and boundaries.
- Common area boundaries should appear only once (i.e., should not be
  double digitized).
- Areas must be explicitly closed. This means that it must be possible
  to complete each area by following one or more boundaries that are
  connected by common nodes, and that such tracings result in closed
  areas.
- It is recommended that area features and linear features be placed
  in separate layers. However if area features and linear features
  must appear in one layer, common boundaries should be digitized only
  once. For example, a boundary that is also a line (e.g., a road which
  is also a field boundary), should be digitized as a boundary to
  complete the area(s), and a boundary which is functionally also a line
  should be labeled as a line by a distinct category number.

Vector map topology can be cleaned at user level by <tt>v.clean</tt>
command.

\subsection vlibTopoFileFormat Topo file format specification

Topo file is read by Vect_open_topo().

\subsubsection vlibTopoFileHead Header

<i>Note:</i> <tt>plus</tt> is an instance of \ref Plus_head data structure.

<table border="1" style="border-collapse: collapse" cellpadding="5">
<tr><td><b>Name</b></td><td><b>Type</b></td><td><b>Number</b></td><td><b>Description</b></td></tr>

<tr><td>plus->Version_Major </td><td>C</td><td>1</td><td>file version (major)</td></tr>
<tr><td>plus->Version_Minor </td><td>C</td><td>1</td><td>file version (minor)</td></tr>
<tr><td>plus->Back_Major</td><td>C</td><td>1</td><td>supported from GRASS version (major)</td></tr>
<tr><td>plus->Back_Minor</td><td>C</td><td>1</td><td>supported from GRASS version (minor)</td></tr>

<tr><td>plus->port->byte_order</td><td>C</td><td>1</td><td>little or big endian
                  flag; files are written in machine native order but
                  files in both little and big endian order may be
                  readl; zero for little endian</td></tr>

<tr><td>plus->head_size</td><td>L</td><td>1</td><td>header size</td></tr>

<tr><td>plus->with_z</td><td>C</td><td>1</td><td>2D or 3D flag; zero for 2D</td></tr>

<tr><td>plus->box</td><td>D</td><td>6</td><td>Bounding box coordinates (N,S,E,W,T,B)</td></tr>

<tr><td>plus->n_nodes, plus->n_lines, etc.</td><td>I</td><td>7</td><td>Number of
nodes, edges, lines, areas, isles, volumes and holes</td></tr>

<tr><td>plus->n_plines, plus->n_llines, etc.</td><td>I</td><td>7</td><td>Number of
points, lines, boundaries, centroids, faces and kernels</td></tr>

<tr><td>plus->Node_offset, plus->Edge_offset,
etc.</td><td>L</td><td>7</td><td>Offset value for nodes, edges, lines,
areas, isles, volumes and holes</td></tr>

<tr><td>plus->coor_size</td><td>L</td><td>1</td><td>File size</td></tr>
</table>

\subsubsection vlibTopoFileBody Body (nodes, lines, areas, isles)

<b>Nodes</b>

For each node (plus->n_nodes):

<table border="1" style="border-collapse: collapse" cellpadding="5">
<tr><td><b>Name</b></td><td><b>Type</b></td><td><b>Number</b></td><td><b>Description</b></td></tr>
<tr><td>n_lines</td><td>I</td><td>1</td><td>Number of lines (0 for dead node)</td></tr>
<tr><td>lines</td><td>I</td><td>n_lines</td><td>Line ids (negative id for line which ends at the node)</td></tr>
<tr><td>angles</td><td>D</td><td>n_lines</td><td>Angle value</td></tr>
<tr><td>n_edges</td><td>I</td><td>1</td><td>Reserved for edges (only for <tt>with_z</tt>)</td></tr>
<tr><td>x,y</td><td>D</td><td>2</td><td>Coordinate pair (2D)</td></tr>
<tr><td>z</td><td>D</td><td>1</td><td>Only for <tt>with_z</tt> (3D)</td></tr>
</table>

See \ref P_node data structure.

<b>Lines</b>

For each line (plus->n_lines):

<table border="1" style="border-collapse: collapse" cellpadding="5">
<tr><td><b>Name</b></td><td><b>Type</b></td><td><b>Number</b></td><td><b>Description</b></td></tr>
<tr><td>feature type</td><td>C</td><td>1</td><td>0 for dead line</td></tr>
<tr><td>offset</td><td>L</td><td>1</td><td>Line offset</td></tr>
<tr><td>N1</td><td>I</td><td>1</td><td>Start node id (only if feature type is GV_LINE or GV_BOUNDARY)</td></tr>
<tr><td>N2</td><td>I</td><td>1</td><td>End node id (only if feature type is GV_LINE or GV_BOUNDARY)</td></tr>
<tr><td>left</td><td>I</td><td>1</td><td>Left area id for feature type GV_BOUNDARY / Area id for feature type GV_CENTROID</td></tr>
<tr><td>right</td><td>I</td><td>1</td><td>Right area id (for feature type GV_BOUNDARY)</td></tr>
<tr><td>vol</td><td>I</td><td>1</td><td>Reserved for kernel (volume number, for feature type GV_KERNEL)</td></tr>
</table>

See \ref P_line data structure.

<b>Areas</b>

For each area (plus->n_areas):

<table border="1" style="border-collapse: collapse" cellpadding="5">
<tr><td><b>Name</b></td><td><b>Type</b></td><td><b>Number</b></td><td><b>Description</b></td></tr>
<tr><td>n_lines</td><td>I</td><td>1</td><td>number of boundaries</td></tr>
<tr><td>lines</td><td>I</td><td>n_lines</td><td>Line ids forming exterior boundary (clockwise order, negative id for backward direction)</td></tr>
<tr><td>n_isles</td><td>I</td><td>1</td><td>Number of isles</td></tr>
<tr><td>isles</td><td>I</td><td>n_isles</td><td>Isle ids</td></tr>
<tr><td>centroid</td><td>I</td><td>1</td><td>Centroid id</td></tr>
</table>

See \ref P_area data structure.

<b>Isles</b>

For each isle (plus->n_isle):

<table border="1" style="border-collapse: collapse" cellpadding="5">
<tr><td><b>Name</b></td><td><b>Type</b></td><td><b>Number</b></td><td><b>Description</b></td></tr>
<tr><td>n_lines</td><td>I</td><td>1</td><td>number of boundaries</td></tr>
<tr><td>lines</td><td>I</td><td>n_lines</td><td>Line ids forming exterior boundary (counter-clockwise order, negative id for backward direction)</td></tr>
<tr><td>area</td><td>I</td><td>1</td><td>Outer area id</td></tr>
</table>

See \ref P_isle data structure.

\subsection vlibTopoLevels Topology levels

The vector library defines more <i>topology levels</i> (only for level
of access 2):

- GV_BUILD_NONE
- GV_BUILD_BASE
- GV_BUILD_AREAS
- GV_BUILD_ATTACH_ISLES
- GV_BUILD_CENTROIDS
- GV_BUILD_ALL

<i>Note:</i> Only the geometry type GV_BOUNDARY is used to build
areas. The geometry type GV_LINE cannot form an area.

\subsection vlibTopoExamples Topology examples

<b>Points</b>

\verbatim
One point (nodes: 0, lines: 1, areas: 0, isles: 0)

    + L1
\endverbatim

Line L1 (see \ref P_line)

\verbatim
line = 1, type = 1 (GV_POINT)
\endverbatim

<b>Lines</b>

\verbatim
One line (nodes: 2, lines: 1, areas: 0, isles: 0)


   +----L1----+
   N1         N2
\endverbatim

%Node N1 (see \ref P_node)

\verbatim
node = 1, n_lines = 1, xyz = 634624.746450, 223557.302231, 0.000000
  line =   1, type = 2 (GV_LINE), angle = -0.436257
\endverbatim

%Node N2 (see \ref P_node)

\verbatim
node = 2, n_lines = 1, xyz = 638677.484787, 221667.849899, 0.000000
  line =  -1, type = 2 (GV_LINE), angle = 2.705335
\endverbatim

Line L1 (see \ref P_line)

\verbatim
line = 1, type = 2 (GV_LINE), n1 = 1, n2 = 2
\endverbatim

<b>Areas without holes</b>

\verbatim
Two lines (nodes: 1, lines: 2, areas: 1, isles: 1)

          +N1
         /   \
        /     \
       /       \
      /   +L2   \
     /           \
    -------L1------
\endverbatim

%Node N1 (see \ref P_node)

\verbatim
node = 1, n_lines = 2, xyz = 635720.081136, 225063.387424, 0.000000
  line =   1, type = 4 (GV_BOUNDARY), angle = -2.245537
  line =  -1, type = 4 (GV_BOUNDARY), angle = -0.842926
\endverbatim

Line L1 (see \ref P_line)

\verbatim
line = 1, type = 4 (GV_BOUNDARY), n1 = 1, n2 = 1, left = 1, right = -1
\endverbatim

Line L2 (see \ref P_line)

\verbatim
line = 2, type = 8 (GV_CENTROID), area = 1
\endverbatim

Area A1 (see \ref P_area)

\verbatim
area = 1, n_lines = 1, n_isles = 0 centroid = 2
  line =  -1
\endverbatim

Isle I1 (see \ref P_isle)

\verbatim
isle = 1, n_lines = 1 area = 0
  line =   1
\endverbatim

<b>Areas with holes</b>

\verbatim
Three lines (nodes: 2, lines: 3, areas: 2, isles: 2)

             +N1
            / \
           /   \
          /     \
         /       \
        /    +L2  \
       /           \
      /   +N2       \
     /   /\          \
    /   /  \          \
   /   /    \          \
  /    ---L3--          \
 /                       \
------------L1-------------
\endverbatim

%Node N1 (see \ref P_node)

\verbatim
node = 1, n_lines = 2, xyz = 635720.081136, 225063.387424, 0.000000
  line =   1, type = 4 (GV_BOUNDARY), angle = -2.245537
  line =  -1, type = 4 (GV_BOUNDARY), angle = -0.842926
\endverbatim

%Node N2 (see \ref P_node)

\verbatim
node = 2, n_lines = 2, xyz = 636788.032454, 223173.935091, 0.000000
  line =   3, type = 4 (GV_BOUNDARY), angle = -2.245537
  line =  -3, type = 4 (GV_BOUNDARY), angle = -0.866302
\endverbatim

Line L1 (see \ref P_line)

\verbatim
line = 1, type = 4 (GV_BOUNDARY), n1 = 1, n2 = 1, left = 1, right = -1
\endverbatim

Line L2 (see \ref P_line)

\verbatim
line = 2, type = 8 (GV_CENTROID), area = 1
\endverbatim

Line L3 (see \ref P_line)

\verbatim
line = 3, type = 4 (GV_BOUNDARY), n1 = 3, n2 = 3, left = 2, right = -2
\endverbatim

Area A1 (see \ref P_area)

\verbatim
area = 1, n_lines = 1, n_isles = 1 centroid = 2
  line =  -1
  isle =   2
\endverbatim

Area A2 (see \ref P_area)

\verbatim
area = 2, n_lines = 1, n_isles = 0 centroid = 0
  line =  -3
\endverbatim

Isle I1 (see \ref P_isle)

\verbatim
isle = 1, n_lines = 1 area = 0
  line =   1
\endverbatim

Isle I2 (see \ref P_isle)

\verbatim
isle = 2, n_lines = 1 area = 1
  line =   3
\endverbatim

<b>Example 1</b>

A polygon may be formed by many boundaries (several connected primitives).
One boundary is shared by adjacent areas.

\verbatim
+--1--+--5--+
|     |     |
2  A  4  B  6
|     |     |
+--3--+--7--+

1,2,3,4,5,6,7 = 7 boundaries (primitives)
A,B = 2 areas
A+B = 1 isle
\endverbatim

<b>Example 2</b>

This is handled correctly in GRASS: A can be filled, B filled differently.

\verbatim
+---------+
|    A    |
+-----+   |
|  B  |   |
+-----+   |
|         |
+---------+

A, B = 2 areas
A+B  = 1 isle
\endverbatim

In GRASS, whenever an 'inner' ring touches the boundary of an outside
area, even in one point, it is no longer an 'inner' ring (isle in
GRASS topology), it is simply another area. A, B above can never be
exported from GRASS as polygon A with inner ring B because there are
only 2 areas A and B and one island formed by A and B together.

<b>Example 3</b>

This is handled correctly in GRASS: Areas A1, A2, and A3 can be filled differently.

\verbatim
+---------------------+
|  A1                 |
+   +------+------+   |
|   |  A2  |  A3  |   |
+   +------+------+   |
|          I1         |
+---------------------+

A1,A2,A3 = 3 areas
A1,A2+A3 = 2 isles
\endverbatim

In GRASS, whenever an 'inner' ring does not touch the boundary of an
outside area, also not in one point, it is an 'inner' ring (isle). The
areas A2 and A3 form a single isle I1 located within area A1. The size
of isle I1 is subtracted from the size of area A1 when calculating
the size of area A1. Any centroids falling into isle I1 are excluded
when searching for a centroid that can be attached to area A1. A1
above can be exported from GRASS as polygon A1 with inner ring I1.

<b>Example 4</b>

<tt>v.in.ogr/v.clean</tt> can identify dangles and change the type
from boundary to line (in TIGER data for example). Distinction
between line and boundary isn't important only for dangles. Example:

\verbatim
+-----+-----+
|     .     |
|     .     |
+.....+.....+
|     .     |
|  x  .     |
+-----+-----+

----  road + boundary of one parcel => type boundary
....  road => type line
x     parcel centroid (identifies whole area)
\endverbatim

Because lines are not used to build areas, we have only one
area/centroid, instead of 4 which would be necessary in TIGER.

\subsection vlibTopoMemory Topology memory management

Topology is generated for all kinds of vector types.  Memory is not
released by default. The programmer can force the library to release
the memory by using Vect_set_release_support(). But: The programmer
cannot run Vect_set_release_support() in mid process because all
vectors are needed in the spatial index, which is needed to build topology.

Topology is also necessary for points in case of a vector network
because the graph is built using topology information about lines
and points.

The topology structure does not only store the topology but also
the 'line' bounding box and line offset in coor file (index).
The existing spatial index is using line ID in 'topology' structure
to identify lines in 'coor' file. Currently it is not possible to build
spatial index without topology.


*/