Digitizing Area Features
Digitizing area features with attributes
GIS users with experience creating and editing non-topological shapefiles sometimes encounter problems when adding attributes to area features in the GRASS digitizer v.digit. This section will attempt to offer a few tips and clear up this issue. Much has already been written explaining the strict topological vector model which GRASS uses. Please read first:
- from the wiki Vector FAQ GRASS6 and Vector Data
- and from the manual pages vectorintro
When creating a polygon shapefile, after the user finishes clicking around the perimeter of the polygon, GIS software applications will often pop up a window with all the attribute columns available and the user enters values for that polygon. In the non-topological shapefile format, the area boundary and the enclosed polygon are one and the same. Thus the boundary attributes also refer to the enclosed area. In the shapefile diagram below the labels A-1, A-2, A-3 are taken from the polygon attribute table. This fact might seem so obvious to shapefile users that they would wonder why it needs mentioning.
In the strict topological model used in GRASS, this is not the case. In a GRASS vector the surrounding boundary, and its enclosed area are two separate entities, which have two separate rows in the accompanying attribute table. The boundary is made up of line segments, and the area is represented by its centroid – a point within the closed boundary. (Centroids should be placed only within closed boundaries.) A line segment which is part of the boundary enclosing an area does not “belong” to that area, rather it often is common to two adjacent areas. In the GRASS vector diagram below, boundary B-1 separates areas A-1 and A-2. Boundaries B-3 and B-8 separate between areas A-1 and A-3. Furthermore, the boundary of area A-2 is composed of B-1, B-2 and B-5. Obviously it would not make sense to attach area attributes to any boundary, so instead the area centroids serve to connect to the attribute table rows holding the area attributes. Thus, the labels B-1, B-2, etc. come from the vector attribute table (line features) and the A-1, A-2 labels, also from the attribute table, are centroid features. Using the GRASS digitizer, v.digit, care needs to be taken to attach attributes to the correct features.
First, it's worth pointing out that when using v.in.ogr to import a polygon shapefile into GRASS, steps are automatically taken to insure that the resulting vector gets the attributes as expected. (This behind-the-scenes procedure might actually fool naive users into believing that GRASS vectors are just like polygon shapefiles).
- Polygons are imported as boundary lines
- These lines are split at intersections, and all overlapping boundaries are removed (topologically cleaned)
- Centroids are placed in each closed boundary
- The centroids are given a cat value, and attributes from the original shapefile are inserted into the attached database
Following are suggestions for adding attributes when using the GRASS digitizer, which more or less duplicate the above process. Detailed explanations of the v.digit interface can be found both in the GRASS (Book) and the GDF Hannover (tutorial). The new wxGUI digitizer has a good manual page at: wxGUI.Vector_Digitizing_Tool.
The process that users should follow when manually creating area vectors with v.digit will produce boundaries with no attributes, and a centroid connected thru its cat value to the area attributes. First, in the v.digit interface, use the settings dialog to set up the attribute table as required by the data, and choose an appropriate snapping tolerance. Also in the settings dialog, under the Attributes tab, there is a drop down list to choose Category Mode (how the cat values will be chosen). For digitizing boundaries, it is possible to choose “No category” since, as explained above, the boundary lines themselves might not require any attributes. Next digitize boundaries, being careful to
- close boundaries which delineate areas.
- never digitize the boundary between adjacent areas twice
- be sure to enter a node at every intersection of two boundary lines (no crossing boundaries without an intersection node)
Now, back in the Settings->Attributes window, reset the Category Mode to “Next not used”, and begin to digitize centroids for each area. After marking the location for a centroid, enter all attribute data into the table relevant to that area. And that's it.
A Special Case
There are situations where attributes need to be attached also to the boundary lines. For example: in a project mapping out species distribution, the boundaries might have an attribute value indicating the rate of spread of a species across a border. In this case, the boundaries will get a cat value (optionally defined as a separate GRASS "layer", with a separate database connection). While digitizing, the user will enter values into the attribute table relevant to each boundary. But still, centroids need to be digitized, and attributes entered for each centroid which are relevant to the areas.
Another Special Case
In some situations a single boundary line exactly encompasses an area, with no adjacent areas. (In other words, each area is an “isle” in GRASS terminology.) An example might be a vector map of water bodies. Obviously no water body touches any other. And the perimeter is one continuous line. Users might want the attribute table to be attached to both the area and the boundary - perhaps to display the length of the perimeter along the perimeter rather than at the centroid. In order to achieve this, boundaries will be digitized with a cat value, and the centroids will be forced to use that same cat value as the boundary. This is done as follows.
While working on the boundary, the user should take note of its category value. Next, before marking the centroid, the user will switch the Category Mode to “Manual entry”. Now she digitizes the centroid for that closed boundary and manually types in the same cat value as the surrounding boundary. This creates two vector features: a boundary line and a centroid, with identical category values, and thus a single row in the database. So all attributes are common to both the boundary and the centroid (area).
The GRASS tool for adding missing centroids to closed boundaries is v.centroids. It is important to realize that the centroids will be created with category values that have no connection to the enclosing boundaries. If you run v.centroids on a vector that already has closed boundary lines with attribute values, these attribute values will not be attached to the area enclosed, since the new centroids will be assigned some new category value. This point is explained in the v.centroids manual page.
Specific instructions for digitizing areas
I found this issue to be not that well documented, so here's a specific method for digitizing areas:
An area comprises two primitives - a boundary and a centroid. The boundary has no attributes; the centroid holds the attributes (if any).
To create an area, a two step process is needed. First, a boundary is defined, then a centroid added. You can batch them - define all the boundaries then add the centroids. I don't know the rules for overlapping areas though - might be better to do those separately.
In this example, you have some existing map layers (for example a layer showing some parks as areas and a layer showing roads) and you want to create a new area by manually digitizing an area based on the existing map layers (eg you want to digitize an area bounded by some specific streets near a park).
These steps create a new map, give it an attribute table, link the attribute table to the map, and open the new map in v.digit displaying the existing layer/s:
v.in.ascii -e output=newmapname echo 'create table newmapname (cat integer, DAY date)' | db.execute v.db.connect -o map=newmapname table=newmapname v.digit map=newmapname bgcmd="d.vect map=existingmap1 type=area fcolor=green; d.vect map=existingmap2"
You can create as many attribute fields as you want within the () area, using whatever field types are allowable for the database type you're using. If you're using an 'external' database type like mysql, you can also just create a cat field in this step and use regular mysql commands or tools to add additional fields to the table if that's easier.
In the window that opens, zoom the the relevant area, then click the 'Digitize new boundary' button. IMPORTANT: Before doing anything else, CHANGE MODE TO 'No Category'. Use the tool to define the boundary of the area, and right-click to close the boundary. If the boundary is successfully closed, the boundary line will turn bright green. If not, it'll remain grey. Easiest fix is to click the 'move vertex' button, move one of the vertices back a bit, then using the 'create new boundary' tool, join the two red crosses. This almost always works, for some reason I can never get the original boundary to join properly. The 'settings' tool also lets you change snapping distance, but altering that hasn't helped me much yet. If the boundary isn't bright green after all this, it isn't closed and the next step won't work.
Select the 'Digitize new centroid' tool. IMPORTANT: Before continuing, CHANGE MODE BACK TO 'Next not used'. Use the tool to select somewhere inside the boundary. The attributes window will open, and you can fill in any area attributes you've created columns for.
You've now created a new area with attributes. Yay.
Click 'Save and exit'. You're done.