Combination of lines and points

This exercise involves the combination of features of types line and point. The operations are:

Evaluation of the distance between points and lines and identification of the type of the lines closer to a set of points

We want to evaluate the distance from schools (in the schools map) to the roads network (in the roadsmajor map):

Set the current region to match the census map:

> g.region vect=census

and display the roads network in black and the Schools in red

> d.erase

> d.vect map=roadsmajor@PERMANENT

> d.vect map=schools@PERMANENT color=red size=6 icon=basic/pushpin


Schools and roads network
The minimum distances from the schools to the major roads are evaluated and displayed. The upload parameter is set to dist to indicate that the distance is to be evaluated, the column parameter sets the name of the column (dist in this example) of the column of the table that will contain the distances, the -p flag specifies that the output must be sent to the terminal:

> v.distance from=schools@PERMANENT to=roadsmajor@PERMANENT from_type=point to_type=point,line,area from_layer=1 to_layer=1 dmax=-1 upload=dist column=dist -p

outputs:

from_cat|dist
1|1454.506020
2|2584.598633
3|1171.909010
...
167|188.893351
v.distance complete.

where the first column reports the category of each point in the schools map and the second column the distance to the nearest road in the roadsmajor map.

In a similar way, it is possible to identify the type of the road closer to each point: the upload parameter is now set to to_attr to indicate that we now want to find an attribute of the nearest line, the to_column parameter is set to ROAD_NAME to select the column of the roadsmajor table containing the attribute to be extracted, the column parameter identifies the name (ROAD_NAME in this case) of the column that will register the road's name, the -p flag specifies that the output must be sent to the terminal:

> v.distance from=schools@PERMANENT to=roadsmajor@PERMANENT from_type=point to_type=point,line,area from_layer=1 to_layer=1 dmax=-1 upload=to_attr column=ROAD_NAME to_column=ROAD_NAME -p

shows:

from_cat|ROAD_NAME
1|I-40
2|NC-54
3|US-1
4|I-40
...
167|NC-98
v.distance complete.

If you want to display the segments identifying the minimum distance between the schools (in the schools map) from the road network (roadsmajor map), the output parameter must be specified, indicating the name of the new vector map where such segments are saved

> v.distance from=schools@PERMANENT to=roadsmajor@PERMANENT output=schools_to_roads from_type=point to_type=point,line,area from_layer=1 to_layer=1 dmax=-1 upload=dist column=dist -p --overwrite

and display the segments in green, without erasing the monitor:

> d.vect schools_to_roads color=green


Distances between schools and the road network

Evaluation of the distance between points and lines and identification of the type of the lines closer to a set of points with addition of this information to the database

The distances and the roads' names which have been identified in the previous operations can be saved in the database, instead of sent to the terminal as before. Two columns must be added to the table, where the distances and the roads' names will be inserted: since the schools map is in the PERMANENT location, it is read-only and its table cannot be modified. For this reason, the following procedures are applied only to the schools inside the Census sections with population>700 inhabitants, in the schools_census_pop_700 map created in the Combination of areas with points exercise, which, being in the current mapset, can be modified.

First of all, add the columns to the schools_census_pop_700 table, if they already exist (for example because you have already done this exercise) db.execute issues an error, but it can be safely ignored:

> echo "ALTER TABLE schools_census_pop_700 ADD COLUMN road_name varchar(30)" | db.execute

> echo "ALTER TABLE schools_census_pop_700 ADD COLUMN dist double" | db.execute

the road_name column is of type varchar and will contain the string identifying the roads' names, the dist column is of type double and will contain the distances.
Alternatively, the columns can be added using v.db.addcol module.
With the following command, the type of the nearest road is inserted in the road_name column of the schools_census_pop_700 table, the upload parameter is set to to_attr to indicate that we want now to find an attribute of the nearest line, the to_column parameter is set to ROAD_NAME to select the column of the roadsmajor table containing the attribute to be extracted, the column parameter identifies the name (road_name in this case) of the column that will register the road's name. The -p flag, which specifies that the output must be sent to the terminal, is not set this time:

> v.distance from=schools_census_pop_700 to=roadsmajor@PERMANENT from_type=point to_type=point,line,area from_layer=1 to_layer=1 dmax=-1 upload=to_attr column=road_name to_column=ROAD_NAME

Now the distance to the nearest road is set in the dist column of the schools_census_pop_700 table, the upload parameter is set to dist to indicate that the distance is to be evaluated, the column parameter sets the name of the column (dist in this example) of the column of the table that will contain the distances (again, the -p is not set):

> v.distance from=schools_census_pop_700 to=roadsmajor@PERMANENT from_type=point to_type=point,line,area from_layer=1 to_layer=1 dmax=-1 upload=dist column=dist

Display the new schools_census_pop_700 table:

> echo "select * from schools_census_pop_700"|db.select

reporting

cat|TAG|NAMESHORT|NAMELONG|CORECAPACI|MOBILEUNIT|MOBILECAPA|GLEVEL|LOGRADE|HIGRADE|CALENDAR|HASBASE| ISMAGNET|PHONE|ADDRNUMBER|ADDRPREFIX|ADDRROOT|ADDRTYPE|ADDRSUFFIX|ADDRCITY|ADDRZIPCOD|SPED|STATUS| NODEID|CAPACITYTO|ESL|BOARDDIS2|PROJ_CAP|NOTES|road_name|distt
5|304|ADAMS|ADAMS ELEMENTARY|722|9|0|E|||Y|||4603431|805||Cary Towne Blvd|||Cary|27511||E|369.1|830|Y|9|853|2|I-40|1204.854388
11|318|ATHENS DR|ATHENS DRIVE HIGH|1735|7||H|||T|||2334050|1420||Athens Dr|||Raleigh|27606||H|136.0|1792|Y|5|1792||I-440|770.749434
14|528|MARY E PHILLIPS|MARY E PHILLIPS HIGH|144|0||S|||T|||8567710|1923||Milburnie Rd|||Raleigh|27610||O|076.0|144|N|4|0|||2575.206341
80|626|YATES MILL|YATES MILL POND ELEMENTARY|586|0||E|||T|||2334244|5993||Yates Mill Pond Rd|||Raleigh|27606||E|422.2|563|Y|5|563||I-40|2061.869202

The name of the nearest road and its distance are associated to each school in the last two columns.

Creation of points along a line with given mutual distance

A new vector map is created, containing a set of points with given maximum mutual distance, along the railroad in the railroads map. The distance is given as "maximum distance" because further points are inserted in any case when the direction of the line changes: if you need to insert point at an exact distance form the beginning of the line, use the v.segment module.

Erase the monitor and display the railroad:

> d.erase

> d.vect map=railroads@PERMANENT

and create new points in the railroads_points map, with a maximum distance of 1000 m (as indicated by the dmax parameter) along the railroad in the railroads map:

> v.to.points input=railroads@PERMANENT type=point,line,boundary,centroid output=railroads_points llayer=1 dmax=1000 --overwrite

and display, without erasing the monitor:

> d.vect map=railroads_points color=red size=5 icon=basic/circle


Points at a given mutual distance of 1000 m along the railroad
Usually, the table of the input map is connected to the new map on the first layer. In this case, the railroads map has no table connected, therefore neither the railroads_points map has one on the first layer. On the second layer however, a new table is connected to the new map, with two columns: the lcat column indicating the category of the line in the input map (railroads in this case) where the point overlays, and the along column, reporting the progressive distance of the point from the beginning of the line. This new table has the same name of the output map with the "_2" suffix.
Display this table with:

> echo "select * from railroads_points_2"|db.select

which writes to the terminal (only the first five lines of the output are shown below)

cat|lcat|along
1|1|0
2|1|933.355945
3|1|1866.71189
4|1|2800.067836
...

It is possible to create points only on the lines' vertexes (direction changes) with the -v flag:

> v.to.points input=railroads@PERMANENT type=point,line,boundary,centroid output=railroads_points llayer=1 dmax=1000 -v --overwrite

display the result:

> d.erase

> d.vect railroads

> d.vect map=railroads_points color=red size=5 icon=basic/circle


Points of direction change on the railroad track

Creation of points and lines along a line with given distance from the line's initial point

This procedure creates point or segments along a line with given category: in the case of points, the distance from the start of the line must be provided, in the case of segments, the distance of the starting and ending points must be given. You must necessarily know which is the starting point and the category of the line you are working on: this can be easily displayed using the dir and cat options in the display parameter of the d.vect module:

In this example the railroad segment with category 3235 is selected:

> d.erase

> d.vect railroads

> d.vect railroads display=cat,dir width=2 where="cat=3235"

In the first step, the railroads_segment_point is created, containing a point with category 1 along the line with category 3235 and with distance of 300 m from the beginning of this line

> echo "P 1 3235 300"|v.segment input=railroads@PERMANENT output=railroads_segment_point llayer=1 --overwrite

Then the railroads_segment_line map is created, containing a segment with category 2 along the line with category 3235 and with starting point at 1500 m and ending point at 3000 m from the beginning of this line.

> echo "L 2 3235 1500 3000"|v.segment input=railroads@PERMANENT output=railroads_segment_line llayer=1 --overwrite

Display the result, without erasing the monitor; the points is red

> d.vect map=railroads_segment_point color=red size=5 icon=basic/circle

and the segment is green

> d.vect map=railroads_segment_line color=green


Point e segment along the the line with category 3235
To get an unique map containing both the point and the segment, the v.patch module can be used to merge the two maps:

> v.patch input=railroads_segment_line,railroads_segment_point output=railroads_segment --overwrite

Now all the points and the lines are red (it is possible to choose different colors, using the type parameter of the d.vect module)

> d.erase

> d.vect railroads

> d.vect map=railroads_segment color=red size=5 icon=basic/circle


Point e segment along the the line with category 3235 in a single vector map

Division of a line into segments

It is possible to split a line into segments of given maximum length using the v.split module. In this procedure, the lines in the railroads map are divided into 100 m long segments, creating the railroads_split_length map:

> v.split input=railroads@PERMANENT output=railroads_split_length length=100 --overwrite

Display the result using the option -c which assigns a random color to each category to differentiate the different segments:

> d.erase

> d.vect -c map=railroads_split_length color=red


Segments of 100 m length along the railroad
it is also possible to verify that the number of segments is changed: in the original railroads map:

> v.to.db map=railroads type=point,line,boundary,centroid layer=1 qlayer=1 option=count units=meters column=length -p

returns

cat|count
1|1
2|1
3|1
...

while in the railroads_split_length map

> v.to.db map=railroads_split_length type=point,line,boundary,centroid layer=1 qlayer=1 option=count units=meters column=length -p

cat|count
1|113
2|30
3|2
...

the number of segments has increased.

Moreover, it is possible to split a line into segments with a fixed maximum number of vertexes: the number of consecutive vertexes that each segment must contains is given (2 vertexes means only straight segments). Obviously, the lower the number of vertexes in each segment, the higher the number of segments and vice versa. In the following example the line in the railroads map is divided into segments with 10 or fewer vertexes, creating the railroads_split_num map:

> v.split input=railroads@PERMANENT output=railroads_split_num vertices=10 --overwrite

Display the result using the option -c which assigns a random color to each category to highlight the different segments:

> d.erase

> d.vect -c map=railroads_split_num color=red


Segments of 10 vertexes along the railroad

As expected, only the lines with 10 vertexes or more are split. On the first layer, segments have the same category of the lines that have generated them, so no difference is visible. As we have done before, it is also possible to verify that the number of segments for each category has changed: for the input railroads map

> v.to.db map=railroads type=point,line,boundary,centroid layer=1 qlayer=1 option=count units=meters column=length -p

returns, as before

cat|count
1|1
2|1
3|1
...

and for the railroads_split_num map

> v.to.db map=railroads_split_num type=point,line,boundary,centroid layer=1 qlayer=1 option=count units=meters column=length -p

cat|count
1|14
2|1
3|1

Alternatively, it is possible to assign different categories to each segment on the second layer and to display them with different colors (because now they have different categories). A second layer with categories starting from 1 with step 1 is added:

> v.category input=railroads_split_num output=railroads_split_num_cat type=point,line,boundary,centroid,area option=add cat=1 layer=2 step=1 --overwrite

Display:

> d.erase

> d.vect -c map=railroads_split_num_cat layer=2 llayer=2 color=red


Segments of 10 vertexes along the railroad, colors are given using categories on the second layer

The longer segments have been divided into shorter segments.

The script performing these operations is geoprocessing_NC_linee_punti.sh.