[GRASS5] Nested vector islands, and incorrect left/right poly id's for island edges...

David D Gray ddgray at armadce.demon.co.uk
Tue Jan 22 15:19:42 EST 2002


Eric G. Miller wrote:

> It appears that GRASS doesn't write correct information for
> left/right adjaceny for edges of areas nested more than
> one polygon deep.  That is: If polygon 1, contains polygon
> 2, and polygon 2 contains polygon 3, the lines comprising
> polygon 3 will have polygon 1 written as the adjacent area
> for either left or right, when I would think it should be
> polygon 2.
> 


Yes I would have thought so.


> I was trying to work up a way to do the following:
> 
>   Given an area with N islands/holes.  Create a set of
>   interior boundaries such that islands/holes that
>   share one or more edges are combined into a single
>   boundary (with interior edges being dropped).
> 


I don't quite understand how islands can share edges. I thought in the 
earlier posting you meant that an edge of an island can be the same as 
that of an (outer) ring. If two 'islands' share a boundary, then they 
are actually the constituent cells of an island, not the island itself. 
If the build routine is creating islands within a polygon that abut, 
then that is a bug.

I have recently been developing a terminology that helps to create a 
more formal link between the intuitive notions and the topological and 
geometric concepts in common circulation.

Four concepts:

Holes <-------------------------> Hulls

   |                                  |

  |                                  |
  |                                  |
  |                                  |
  |                                  |

Islands <-------------------------> Cells



Holes and hulls are defined in relation to an individual polygon. In 
practical terms, a polygon is the interior of a fully connected open 
subspace of the whole, union'd with its closure. Without going into that 
too deeply, it can be thought of as the boundary, but purely in terms of 
a limiting bound to the interior, with no conception of edges, nodes 
etc. Exterior boundaries (only one) consitutes the 'hull' and interior 
boundaries the 'holes'. You can tell if its a hole or a hull by tracknig 
from an arbitrary interior point to a boundary point on the subject 
boundary. Then track right, and follow the boundary round to its 
starting point  (we've dropped to geometrical operations here). If the 
boundary is traversed clockwise it is a hull; if anti-clockwise it is a 
hole.

Islands and cells are defined in relation to the boundary system of a 
coverage, which really is a network with some constraints. You start at 
a node or track from an arbitrary point to a node, and continue 
tracking, always following the right-most link at each node, until you 
get back to the starting point. If you circulate clockwise, it is a 
cell, and if anti-clockwise, it's an island. An 'island' is the boundary 
  set of a subspace whose interior is an 'aggregate' of cells, union'd 
with that interior. A 'cell' is a subspace whose interior union'd with 
the cell boundary co-incides with a polygon. If an island has only a 
single cell it is a 'simple island' (though it can have islands of its 
own), and is also a cell in its own right.

The first set of definitions is similar in structure to the kind of 
polygon coverage that is found in shapefiles for examples, while the 
latter is like that found in GRASS, Arc/Info etc.

This is quite detailed, as it ties in to formal topological theory, but 
it's useful for us as it highlights some important areas - how the 
different kinds of coverage that are used relate to different aspects of 
the topology of the coverage, polygons relate to interior sets, 
'topological' coverages to boundary sets. There's also the practical 
trick of tracking right or left to distinguish inner and outer components.


> I tried to write a little program that iterated through
> areas, and their islands, reporting the lines for all
> and the reported line left/right indices.  That's when
> I discovered, I was getting islands where none of the
> edges reported being adjacent to their immediate parent.
> 
> I guess, next I'll try using nodes instead of edges.  If
> anyone familiar with the guts of the vector libraries
> (Radim, David ?) wants to point me in the right direction,
> I'd appreciate it...
> 


I haven't tried this yet - I'll look now and see if I can confirm this 
bug. We have to sort that out priority A1 if there is, and then I think 
that should solve the problem.

David


> Attached:  area_report.c & Gmakefile
> 
> 
> 
> ------------------------------------------------------------------------
> 
> #include <stdio.h>
> #include <stdlib.h>
> #include "gis.h"
> #include "Vect.h"
> 
> int main (int argc, char **argv)
> {
> 	struct Option *opt_map;
> 	struct Map_info map;
> 	char *mapset;
> 	int i, j, k, att;
> 	int isle_area;
> 	P_AREA *area;
> 	P_LINE *line;
> 	P_ISLE *isle;
> 	
> 	opt_map = G_define_option();
> 	opt_map->key = "map";
> 	opt_map->required = YES;
> 	opt_map->gisprompt = "dig,old,vector";
> 
> 	G_gisinit(argv[0]);
> 
> 	if (G_parser (argc, argv))
> 		exit (EXIT_FAILURE);
> 
> 	if (NULL == (mapset = G_find_file2 ("dig", opt_map->answer, "")))
> 		G_fatal_error ("Vector map [%s] not found!", opt_map->answer);
> 
> 	if (V2_open_old (&map, opt_map->answer, mapset))
> 		G_fatal_error ("Couldn't open vector map at level 2!");
> 
> 	for (i = 1; i <= map.n_areas; i++)
> 	{
> 		fprintf (stdout, "Area %d {\n", i);
> 		att = V2_area_att (&map, i);
> 		fprintf (stdout, "  dig_att = %d\n", att);
> 		
> 		V2_get_area (&map, i, &area);
> 
> 		fprintf (stdout, "  lines {\n");
> 		for (j = 0; j < area->n_lines; j++) 
> 		{
> 			line = &(map.Line[abs(area->lines[j])]);
> 			fprintf (stdout, "    line %d, left %d, right %d\n",
> 					area->lines[j],
> 					line->left, line->right);
> 		}
> 		fprintf (stdout, "  }\n");
> 
> 		for (j = 0; j < area->n_isles; j++)
> 		{
> 			fprintf (stdout, "  Island %d {\n", area->isles[j]);
> 			isle = &(map.Isle[area->isles[j]]);
> 			fprintf (stdout, "    Lines {\n");
> 			for (k = 0; k < isle->n_lines; k++)
> 			{
> 				line = &(map.Line[abs(isle->lines[k])]);
> 				fprintf (stdout, "      Line %d, LeftArea %d, RightArea %d\n",
> 						isle->lines[k],
> 						line->left,
> 						line->right);
> 			}
> 			if (i == abs(line->left)) 
> 				isle_area = abs(line->right);
> 			else if (i == abs(line->right))
> 				isle_area = abs(line->left);
> 			else 
> 				isle_area = -1;
> 			
> 			fprintf (stdout, "    } = Area %d\n  }\n", isle_area );
> 		}
> 		
> 		fprintf (stdout, "}\n");
> 	}
> 			
> 			
> 			
> 	return 	0;
> }
> 
> 






More information about the grass-dev mailing list