The MinisterNewsSearchReports & PublicationsContacts
Government of British Columbia Ministry Home

BC Digital Road Atlas Database Model


Introduction

A presentation titled "Managing Space, Time and Conflation Issues in a Geospatial Road Database" was presented at the GeoTec2003 conference in Vancouver. The related paper can be downloaded from here.

The BC Digital Road Atlas (BCDRA) database provides information, current and historical, for roads in British Columbia. Before diving into the tables inside the database, a few key concepts need to be discussed.


This diagram demonstrates the important topological concepts used by the datamodel.

The roads are represented by a series of small lines, each called a road segment (about 200,000 in the DRA). The segment end points (called intersections) of each of these road segments are shown in magenta. Each of these linear road segments is given a unique number called rd_segment_id, as shown in the image. The individual line segments themselves are uninteresting and homogeneous, meaning that no signifigant events occur on the segment like an intersection, speed limit change, or name change. Spatial datatypes in the database allow for storage and retrieval of point, line and polygon features. These structures are provided by the PostGIS spatial extension to the PostgreSQL database.

Temporal changes are also stored in the database, which is why there are so many admit_date, retire_date, and most_recent columns in the database. Lets look at a simple example - rd_segment_id 165599, in the above diagram, has its speed limit changed from 50 km/h to 60 km/h on 2001-09-06. The speed limit is recorded in the speed column of the road_nav table.

Prior to the change, we'll see a row in road_nav that looks like:

rd_segment_id...speed...admit_dateretire_datemost_recent
165599 50 1997-05-01NULLtrue

When the change is made, we'll retire this row and insert a new row. The result looks like:

rd_segment_id...speed...admit_dateretire_datemost_recent
165599 50 1997-05-012001-09-06false
165599 60 2001-09-06NULLtrue

So, the admit_date is the date when that information first became valid, and the retire_date is when that information became obsolete. Most_recent is a convenience so you can easily access information that is most up-to-date.

Lets assume that this road segment undergoes several changes:

rd_segment_id...speed...admit_dateretire_datemost_recent
165599 50 1997-05-012001-09-06false
165599 60 2001-09-062001-10-01false
165599 65 2001-10-012001-11-01false
165599 70 2001-11-01NULLtrue

So, to find the speed limit on 2001-10-15, we would do this search:

SELECT * FROM road_nav WHERE rd_segment_id=165599 AND
admit_date <= '2001-10-15' AND
(not(retire_date < '2001-10-15') or retire_date = NULL)

Meaning, return rows that where admitted before our date (reject data about future events), and were not retired before our date (reject data that was superceeded).

There are some cases when this becomes more tricky. This occurs when a road segment undergoes a significant topological change - like splitting in two or its endpoints moving.

Here's an example of road segment 16874 being split into 25000 and 25001 to accomidate a new road (25002).

rd_segment_id...speed...admit_dateretire_datemost_recent
16874  50 1997-05-012001-09-06false
25000  50 2001-09-06NULLtrue
25001 50 2001-09-06NULLtrue
25002 50 2001-09-06NULLtrue

So, direct segment-to-segment tracking is not upheld. Although this appears to be a major problem, in practice its not because most user queries will still work. For example, 'What was the speed on 2001-10-15 for the 2100 block of 34th avenue?'.

Directional adjectives (left,right,to,and from) are used in this model. These are refering to how the road segment was digitized - from the first point to the last point.



Overview of Data Model

larger version


Road Segment
The road_segment table contains the topological details of each of the line segments. The actual geometry of the segment is in the geometry table.
ColumnDescription
rd_segment_idUniversal road segment identifier
from_intersectionReference to a road_intersection entry defining the first point in the segment.
to_intersectionReference to a road_intersection entry defining the last point in the segment.
mslinkReference to GISI's unique road segment identifier


Road Info
The Road Info tables contain information about the road segments like speed, presence of stop signs at the end points, speed bumps, and grade. Each road segment will have an entry in these tables.

The road_nav table

ColumnDescription
rd_segment_idUniversal road segment identifier
lane_leftOn a two way road, the number of lanes to the left of the dividing line. On a one way road, the number of lanes to the left of the center line (rounded down).
lane_rightOn a two way road, the number of lanes to the right of the dividing line. On a one way road, the number of lanes to the right of the center line (rounded up).
exit_angleBearing (degrees) of the line connecting the last two points of the road segment.
entry_angleBearing (degrees) of the line connecting the first two points of the road segment.
travector_direction"F" - One Way travel (From ->To direction)
"R" - One Way travel (To ->From direction)
"B" - Two Way travel
lengthLength of the road segment (meters)
speedSpeed limit on the road segment (km/h)
from_stopInformation about the From Point
codeMeaning
nullno restriction
CCul de Sac
DDead End
LTraffic Light
OOverpass
RRoundabout
SStop Sign
UUnderpass
YYield Sign
to_stopInformation about the To Point (see above)
railway_crossingTotal number of railway crossings on the road segment
accessableGISI accessable code

CODE

interpretation

remark

0 or null

always

 

1

Restricted in some way

 

> 1

Restricted in some way

Future usage, linked to specific or general lookups

The road_usages table

ColumnDescription
rd_segment_idUniversal road segment identifier
usage Reserved for future use
travel_timeReserved for future use
disast_routetrue if GISI indicated this was a disaster route.
truck_routetrue if GISI indicated this was a truck route.
rd_net_classNTDB/CTI road classification
codemeaning
1Highway
2Main
3Secondary
4Street
9Unknown

The road_specifications table

ColumnDescription
rd_segment_idUniversal road segment identifier
max_gradeThe MAX_GRADE column indicates an approximation of steepest grade recorded for a segment. The units are in road percent (100*height/length)
max_heightIf a value is present, it represents the tallest vehicle (meters) that can drive the segment
max_weightA value indicates a limit on the maximum weight (metric tons) permitted for the segment
max_widthIf a value is present, it represents the widest vehicle (meters) that can drive the segment
is_dividedThis boolean value is set to true if the road segment is a divided road.
speedbumpsThe total number of speed bumps on the road segment
structure_idReference to road_name rd_structure_id
surface_typeThree possibilities: 'paved', 'loose', or 'boat'
rd_class
freeway controlled access, typically divided carraigeway
highway a primary or secondary provincial highway, may be single or multilane each way
arterial a thoroughfare with a generally large traffic capacity, generally multilane each way
collector a road to collect traffic from areas and/or to cross town with the general right of way, generally one lane each way
local local, residential roads
strata residential roads with potential public restriction, trailer parks, first nations, strata
lane Alleyways
ramp ramps for highway access, or turning lanes
restricted a restricted road, generally not accessible to the general public
recreation a road to access back country or recreation sites, commonly formerly resource roads
resource a road for resource extraction
ferry a crossing made by public or private ferry boat
rd_subclass
Freeway controlled access, typically divided carraigeway
highway_major a primary provincial highway
highway_minor a non primary provincial highway
arterial_major a major thoroughfare with a generally large traffic capacity, more than 2 lanes
arterial_minor a thoroughfare with medium traffic capacity, 2 lanes (one each way)
collector_major a road to feed traffic within town with right of way, more than 2 lanes
collector_minor a road to feed areas of local traffic, one lane each way
Local local, residential roads, full public access
Strata residential roads with potential public restriction, trailer parks, first nations, strata
Lane Alleyways
Ramp ramps for highway access, or turning lanes
Restricted a restricted road, generally not accessible to the general public, such as industrial sites
Recreation a road to access back country or recreation sites, commonly formerly resource roads
Resource a road for resource extraction
ferry a crossing made by public or private ferry boat


Road Infrastructure

The ric table

The ric table describes road infrastructure component entities.
ColumnDescription
ric_idUniversal road infrastructure component identifier
rd_name_idReference to road_name representing the RIC. Note that valid road structure types for RICs are bridge, causeway, overpass, snowshed, tunnel, underpass, viaduct
ric_sourceThe source of RIC data, currently either GISI or NTDB.
centroidFor NTDB RICs this is NULL. For GISI rics, this is the length-weighted centroid of the midpoints of each ric road segment (approximate middle of the ric).

The ric_rd_segment table

This table used to define which segments are RICs. For NTDB rics that are added into the dataset, they can be portions of road segments. As a result we used a percentage offset technique to cut them into the network.
ColumnDescription
ric_rd_segment_idTable ric road segment identifier
ric_idUniversal road infrastructure component identifier
rd_segment_idUniversal road segment identifier
from_percentPercentage of the length of the road segment that the start of the RIC (endpoint closest to road FROM node) is located from the FROM end of the road segment. For GISI RICs this is always 0.
to_percentPercentage of the length of the road segment that the end of the RIC (endpoint closest to road TO node) is located from the TO end of the road segment. For GISI RICs this is always 100.

The ric_ntdb_geom table

This table stores the NTDB bridge/tunnel line segments that are close to the GISI network, and it is an internal table used to build up additional information in the ric and ric_rd_segment tables. NTDB RICs were buffered to 3m and intersected with the DRA roads to supplement bridge, snowshed and tunnel locations. Note that NTDB RICs entries are ignored if they are duplicates of a GISI RIC location.
ColumnDescription
ric_idUniversal road infrastructure component identifier
ric_structureStructure type: Bridge or Tunnel
lineargeometryPostGIS line string geometry representing the spatial location of the NTDB RIC in BC Albers NAD83 projection


Street Address

The address_component table

ColumnDescription
rd_segment_idUniversal road segment identifier
address_leftA GISI code representing how the left-side addresses are ordered on the block
N Not addressed or unknown
E Standard Even parity, addresses increase in the vector direction
O Standard Odd parity, addresses increase in the vector direction
C Continuous numbering, (e.g. 1,2,3,4…), increasing in vector direction
e Even parity, but decreasing in vector direction
o Odd parity, but decreasing in vector direction
c Continuous numbering, but decreasing in vector direction
S Special addressing, other than the above
address_rightA GISI code representing how the right-side addresses are ordered on the block (see above for codes)
from_leftThe address number at the left side/from end of the segment (null if none exists)
to_leftThe address number at the left side/to end of the segment (null if none exists)
from_rightThe address number at the right side/from end of the segment (null if none exists)
to_rightThe address number at the right side/to end of the segment (null if none exists)
single_addressFor strata road segments this is the address number of the strata, while the from/to addresses in the fields above become the unit numbers. For non-strata segments, this value is set to 0

The road_name table

This table stores each unique road name found in BC. Name information is stored as a default name as well as in pieces so that the name can be rebuilt in a customizable manner.
ColumnDescription
name_idUniversal road name identifier
full_nameThe default DRA full name that combines all name components into a standard road name format. In most cases we have built it in the following order: prefix pretype name type suffix structure
rd_nameOnly the road name itself (e.g. Granville, Main, Elm)
rd_type_idReference to a type representing the road's type
rd_prefixReference to a directional representing the road's prefix
rd_pretype_idReference to a type representing the road's pretype
rd_prefixReference to a directional representing the road's suffix
rd_structure_idReference to a type representing the road's structure

The suffixes table

The eight standard road directionals are stored in this table along with a 'none' entry. French directionals could be added at a later date if necessary.
ColumnDescription
suffixDirectional abbreviation (N, NE, E, SE, S, SW, W, NW, blank)
suffix_nameThe full name for the directional, including 'None' for a blank suffix entry

The rd_types table

This table stores the unique road types that exist for BC roads. These are used for identifying road pretypes, types and structures and for building up custom road names.
ColumnDescription
type_idUniversal type identifier
type_nameThe full type name
type_abbrThe standard type abbreviation used in DRA road name identification
type_icbcThe type name used by ICBC
type_versadexThe type name used by Versadex clients
type_ecommThe four-character type name used by EComm for the PRC/Altaris software
is_structureBoolean which indicates whether or not this type is a valid ICBC structure
is_ricThis field is true if the entry is a DRA RIC type

The gisi_rd_types table

This is an internally used table required at load time only. It standardizes the various pretypes/types/structures that GISI delivers in the drops into the standard entries in the
rd_types table
ColumnDescription
gisi_type_idUnique identifier
gisi_type_nameThe type name in GISI's drop
type_idUniversal type identifier that represents the GISI type name

The road_segment_names table

There is at least one entry in this table (primary name) for each road segment as well as any number of alias names (currently at most 3 exist for any segment). The aliases are extracted from GISI's ALIAS fields as well as the HWY_RTE (highway number) column.
ColumnDescription
rseg_name_idUnique identifier
rd_segment_idUniversal road segment identifier
rd_name_idReference to road_name
rd_name_is_primaryBoolean field set to true if the road name is the primary road name. Set to false if it is an alias name


Road Intersections

The road_intersection table

Each spatially distinct segment end node is stored in this table as an identifier and a single point in Lat/Long NAD83. Every road segment will have its from and to nodes mapped to an intersection in this table.
ColumnDescription
intersection_idUniversal intersection identifier
pointgeometrySpatial point field containing the location of the intersection/end point

The projected_intersection table

Although the GISI data is two-dimensional, there are attributes that we can use to provide some semblance of height separation. If we consider the
road_nav FROM_STOP and TO_STOP attributes (specifically the overpass/underpass cases) along with the road segment this attributes is associated with, then we can assign height 'levels' to the intersection.
ColumnDescription
projected_intersection_idUnique identifier
intersection_idUniversal intersection identifier
rd_segment_idUniversal road segment identifier
levelHeight level at road crossing: 0 = underpass/at ground level ; 1 = overpass/above ground level

The highway_exit table

Highway exit points are associated with an intersection and occur at the junction between a highway and an offramp or crossroad. This data set was compiled externally to the GISI roads data from various sources: BCAA, paper maps, MoTH, Refractions Research.
ColumnDescription
exit_idUnique identifier
intersection_idUniversal intersection identifier
exit_numThe posted highway exit number
entered_byName of the operator who entered or updated the table entry
hwy_idUniversal highway identifier


Zone Info

The road_meta table

Miscellaneous information that describes the road segment is located in this table.
ColumnDescription
rd_segment_idUniversal road segment identifier
positioning_methodThis records the technique used to collect the GISI road segment information. Current values are: CAD, DEFAULT, GPS, ORTHO, ORTHO-CAD, SKETCH, TRIM
data_sourceCurrently always set to 'GISI'. If other data sources are integrated into the model, then we will be able to distinguish them from the GISI data using this field
zone_idUniversal update zone identifier

The zone table

Miscellaneous information that describes the road segment is located in this table.
ColumnDescription
zone_idUniversal zone identifier
regionThe full name of the zone/driving region
gisi_nameThe GISI zone abbreviation
intervalThe number of months between successive updates of this driving zone


Census Info

The census_division table

ColumnDescription
census_idUniversal census division identifier
census_nameThe name of the census division

The road_segment_in_census table

Most road segments in the province are contained inside a single census division -- these are identified by a single row in this table with rd_side_flag 'B'. Some segments have a different census division on their left and right sides; these are identified by two rows in this table.
ColumnDescription
rd_segment_idUniversal road segment identifier
census_idUniversal census division identifier
rd_side_flag
flagdescription
Lleft side census division
Rright side census division
Bboth sides census division


Jurisdiction Info

The jurisdiction table

This table contains the municipalities, regions and province-level jurisdiction breakdowns. Entries are heirarchical and self-referential as we store the parent link as a column in the table.
ColumnDescription
jurisdiction_idUniversal jurisdiction identifier
jurisdiction_nameThe name of the jurisdiction
parent_jur_idA reference to a universal jurisdiction identifier in this table
jurisdiction_type_id
typedescription
1municipality
2region
3province
jurisdiction_sourceThe source of the jurisdiction -- currently only GISI

The road_segment_in_jurisdiction table

The majority of road segments in the province are contained inside a single municipality -- these are identified by a single row in this table with rd_side_code 'B'. Some segments fall on the boundary and have a different municipality on their left and right sides; these are identified by two rows in this table.
ColumnDescription
rd_segment_idUniversal road segment identifier
jurisdiction_idUniversal jurisdiction identifier
rd_side_code
codedescription
Lleft side jurisdiction
Rright side jurisdiction
Bboth sides jurisdiction


Geometry

The geom table

We get to the geom table, the meat of the spatial database [Note: "geometry" is a reserved word in PostGIS]. This is the table where road positions are defined (geographic coordinates) as a series of seqential points combined into a linear feature.
ColumnDescription
rd_segment_idUniversal road segment identifier
lineargeometryLINESTRING PostGIS type that contains road segment positions in geographic coordinates.


Routing

The travel_restriction table

This lookup table contains day and time pairs that get associated with turning restrictions (left, right, straight) at road endpoints. The restrictions for each segment are stored in the road_restriction table described below.
ColumnDescription
travel_restriction_idUniversal travel restriction identifier
dayCharacter code representing day(s) restricted. Allowed values are MF: Monday to Friday, S: Saturday, MS: Monday to Saturday, SS: Sunday to Saturday (all days)
timeTime code indicating time of day for restriction: 0=always, 1=AM rush hour, 2=PM rush hour, 3=AM/PM rush hour
accessablereserved for future use
travel_typereserved for future use

The road_restriction table

Each node (from and to) for each road segment has up to three possible turning restrictions (left, right, straight). These are stored in the six restriction columns; note that most are blank (less than 3% have restrictions)
ColumnDescription
rd_segment_idUniversal road segment identifier
travel_restriction_idUniversal travel restriction identifier
nav_from_turnleft_idFrom turn left universal travel restriction identifier
nav_from_turnright_idFrom turn right universal travel restriction identifier
nav_from_straight_idFrom straight universal travel restriction identifier
nav_to_turnleft_idTo turn left universal travel restriction identifier
nav_to_turnright_idTo turn right universal travel restriction identifier
nav_to_straight_idTo straight universal travel restriction identifier


Highways

The highway table

This table contains a record for each numbered highway in the province. Since the highway_id used is not the highway number, we could actually store multiple rows for the same highway number. This way we could distinguish between highways with the same number but different names (e.g. #17 Patricia Bay and #17 Tsawassen). Currently only a single entry per number is present.
ColumnDescription
hwy_idUniversal highway identifier
hwy_nameFor future use as highway name (e.g. Trans Canada)
hwy_numThe highway number (e.g. 97B)
hwy_classReserved for future use, possibly as the CTI/NTDB main and highway class code

The highway_rd_segment table

Like the ric_rd_segment, the highway_rd_segment table stores those road segments which are highway routes. If a segment has more than one highway number associated with it then this table will store information for each number and their name priority.
ColumnDescription
hwy_rd_segment_idUnique key for the table
rd_segment_idUniversal road segment identifier
hwy_idUniversal highway identifier
hwy_orderThe name ranking order of highway names (1st, 2nd, 3rd, etc.)




Feedback Privacy Disclaimer Copyright Top