Fairfax County, Virginia/Roads

From OpenStreetMap Wiki
Jump to: navigation, search

This will be a page to organize efforts to correct and update all roads in Fairfax County. In particular this will focus on the possibility of synchronizing Fairfax County Department of Transportation road centerline data with OSM.

Fairfax County DOT RCL

The road centerline (RCL) data from the county has rich metadata, including road classification, route number, speed limit, bridges, and more. The data can be downloaded from http://www.fairfaxcounty.gov/maps/metadata.htm (direct link to ZIP containing Shapefiles), and is considered in the public domain (per phone and email conversations by User:Joshdoe with the Fairfax County GIS and FCDOT offices). The data was last updated 2011/10/17. No mass import is planned, rather this data will be used to enhance the existing roadway in OSM through a manual process, perhaps supported by future conflation tools. The quality of this data is quite high, as it is used by county emergency services, tax collections, etc. Changes are updated within weeks or months, and the spatial accuracy seems to be within about 5 meters (often much better).

Replacing TIGER data

There is an effort underway to replace all unedited TIGER data in the county with this data. This is a tedious and meticulous process using JOSM that takes quite a bit of experience to perform correctly. If interested please leave a message on the talk page or claim a school in the table below.

Some notes from the first few areas (work in progress):

  • Open latest OSM data and county data in JOSM
  • Oftentimes highway=secondary and above roads will be edited, but large subdivisions of highway=residential may be totally unedited and have version 1 and user DaveHansenTiger (nodes will have user woodpeck_fixbot)
    • In this case, delete the roads in the subdivision, ensuring to check for added intersections (driveways, paths), or edited nodes (highway=turning_circle), and select the relevant ways in the county layer, and merging to the OSM layer (Ctrl+Shift+M), then join to existing ways with the join tool (j) or merge tool (m)
Elementary school User Finished Notes
Clifton User:Joshdoe 2011-12-11
Deer Park User:Joshdoe 2012-01-04
Fairview User:Joshdoe 2011-12-09
Fort Belvoir User:Joshdoe 2011-12-27
Gunston User:Joshdoe 2012-01-04
Hayfield User:JoshDoe 2011-12-26

Fields

There are two columns for the field names. The ESRI GeoDatabase direct from Fairfax County DOT has the full names, while the Shapefile available online from the Fairfax County GIS office has the shortened names (limitation of the format).

FCDOT Field Shortened Field Description Mapping Five most frequent values
AC_L_FROM_ADD Address range (actual) ?
AC_L_TO_ADD Address range (actual) ?
AC_R_FROM_ADD Address range (actual) ?
AC_R_TO_ADD Address range (actual) ?
AUTHORIZE_USE  ? N/A 0 (53056), AUTHORIZE_USE (1)
BRIDGE BRIDGE bridge=yes/no N (52492), Y (561), (3), BRIDGE (1)
CFCC TIGER Census Feature Class Code ? A41 (31543), A61 (9874), A45 (3425), A35 (1845), A25 (1708)
DATA_SOURCE ? 4 (52504), 0 (266), 13 (169), 9 (110), 20 (7)
DIVIDED Only use as reference N/A N, Y
DRAW_SYMBOL Similar to class? N/A 6 (42648), 5 (5021), 4 (2434), 7 (975), 1 (576)
EFF_DATE Date road entered database ? 2007/09/12 0:00:00 (42967), 2008/03/13 0:00:00 (1054), 2006/07/01 0:00:00 (948), 2008/04/25 0:00:00 (793), (762)
FFX_CLASS Fairfax Co specific class? ? LOC (45686), MAA (2819), MEA (1676), MIA (1193), (497)
FULLNAME FULLNAME Name of street name=* OUTLET (1249), PARKING LOT (811), XXOVER (429), LEESBURG PIKE (316), LEE HWY (313)
FX_SOURCE Particular FCDOT source? ? 100 (48089), 500 (2109), 230 (1592), 160 (568), 0 (348)
GATE  ? ? 2, 0, 1
L_JURISDICTION FCDOT/VDOT jurisdiction to left? N/A 4 (49673), 15 (1137), 8 (978), 17 (806), 18 (238)
L_POSTAL_AREA Similar to tiger:zip_left N/A 22003 (2371), 20170 (2064), 22079 (2058), 22101 (1989), 22015 (1868)
LAST_UPDATE Last update ? NULL (26145), 2011/03/17 15:10:04 (662), 2009/07/16 0:00:00 (556), 2011/03/17 15:10:03 (520), 2009/02/20 0:00:00 (484)
LOW_WATER Roads in danger of flooding? ? N (52974), Y (79), (3), LOW_WATER (1)
MAINT_RES Maintenance descriptor? N/A 5 (33125), 0 (19121), 1 (741), 4 (67), 8 (2)
MAR_STREET_NAME_KEY  ? ? 0 (5773), 8041 (315), 8008 (313), 1473 (305), 4621 (295)
ONEWAY ONEWAY oneway=yes N, Y, B
R_JURISDICTION FCDOT/VDOT jurisdiction to right? N/A 4 (49673), 15 (1139), 8 (982), 17 (806), 18 (240)
R_POSTAL_AREA Similar to tiger:zip_right N/A 22003 (2323), 22079 (2056), 20170 (2022), 22101 (1995), 22030 (1870)
ROAD_CLASS ROAD_CLASS Highway class highway=* LOC (41540), TER (4171), SEC (2165), PRI (1773), RMP (1020)
ROUTE_ALIAS ROUTE_ALIA Route number ref=*
RW_NAME N/A OUTLET (1252), PARKING LOT (812), XXOVER (429), LEE (353), LEESBURG (318)
RW_PREFIX N/A NULL (52729), N (134), S (84), E (58), W (51)
RW_SUFFIX N/A NULL (52187), SW (285), SE (219), NE (138), NW (121)
RW_SUFFIX_DIR N/A NULL (52193), WB (221), NB (217), EB (213), SB (212)
RW_TYPE_USPS N/A DR (11475), RD (11011), CT (6532), LN (4987), (4598)
SEGID Unique segment ID ? 378466 (1), 378467 (1), 378464 (1), 378465 (1), 378463 (1)
SPEED_LIMIT_CAR SPEED_LIMI maxspeed=*
STATUS  ? N/A B (52763), A (291), C (2), STATUS (1)
TH_L_FROM_ADD Address range (theoretical) N/A 0 (18704), 6001 (248), 6401 (244), 6101 (233), 6301 (233)
TH_L_TO_ADD Address range (theoretical) N/A 0 (18704), 6399 (216), 6599 (216), 6199 (211), 6699 (208)
TH_R_FROM_ADD Address range (theoretical) N/A 0 (14619), 6400 (254), 6000 (254), 6300 (246), 6100 (244)
TH_R_TO_ADD Address range (theoretical) N/A rerun script
TIME_FACTOR Indication of traffic flow? N/A
TRANS_ID Unique segment ID by FCDOT? ? 500046190 (1), 500046192 (1), 500046193 (1), 500046194 (1), 500046196 (1)
VEHIC_MAX_HEIGHT VEHIC_MAX_ maxheight=*
VEHIC_MAX_LENGTH maxlength=*
VEHIC_MAX_WEIGHT VEHIC_MAX1 maximum weight of vehicles in pounds maxweight=*
VEHIC_MAX_WIDTH VEHIC_MA_1 maxwidth=*
VEHIC_MIN_WIDTH Minimum width?? N/A

ogr2osm translation file

Work in progress. Note the street suffixes are loaded from /Street suffixes.

# ogr2osm translation script to convert Fairfax County, Virginia, USA
# street centerline Shapefile

import string
import re
import csv
 
"""
Caveats and TODO:
Check highway classification for correctness, in particular:
  * highway=service, service=parking_aisle may not always be correct
  * highway=secondary_link may be primary_link, tertiary_link, etc.
  * highway=unclassified may be better tagged as highway=residential
Names that have capitalized letters in the middle of a word need to be
 fixed manually.
Street segments with identical tags should be merged.
 
Added the following to the USPS street suffix list:
CL,CIRCLE
NK,NOOK
CORR,CORRIDOR
CMNS,COMMONS

And remove the following (singular form more common):
PARK,PARKS
PKWY,PARKWAYS
SPUR,SPURS
WALK,WALKS
"""
 
def translateAttributes(attrs):
    if not attrs: return

    # load modified USPS street suffix abbrevation mapping (only once)
    if not getattr(translateAttributes, "street_suffixes", False):
        print "Loading USPS street suffixes"
        translateAttributes.street_suffixes = {}
        csvReader = csv.reader(open('street_suffixes.csv', 'rb'), delimiter=',')
        for row in csvReader:
            translateAttributes.street_suffixes[row[0]] = string.capwords(row[1])

    tags = {}
    fixme = []
 
    # ROAD_CLASS should be defined for every feature
    # not all will have names in OSM
    named = {'LOC': 'unclassified',
             'TER': 'tertiary',
             'SEC': 'secondary',
             'PRI': 'primary'}
    unnamed = {'INT': 'motorway',
               'PRK': 'service', # parking aisle, FIXME: but not always
               'MRG': 'secondary_link', # FIXME: this might be other types of links, flag it?
               'RMP': 'motorway_link',
               'CRS': 'service', # crossover
               'DRV': 'service', # driveway, inc. residential, commercial, etc.
               'HWY': 'fcdot_HWY' # FIXME: possibly a bad value? in one case just a crossover, another should be primary
              }
    if attrs['ROAD_CLASS'] in named:
        tags['highway'] = named[attrs['ROAD_CLASS']]
    elif attrs['ROAD_CLASS'] in unnamed:
        tags['highway'] = unnamed[attrs['ROAD_CLASS']]
    else:
        print "Unknown ROAD_CLASS"
        return null
   
    if attrs['ROAD_CLASS'] == 'PRK':
        tags['service'] = 'parking_aisle'
    elif attrs['ROAD_CLASS'] == 'DRV':
        tags['service'] = 'driveway'
    elif attrs['ROAD_CLASS'] == 'CRS':
        tags['service'] = 'crossover'
   
    # Assemble the name
    if attrs['ROAD_CLASS'] in named and attrs['FULLNAME'] != 'OUTLET' and attrs['FULLNAME'] != 'PIPESTEM':
        name = []
        if attrs['RW_PREFIX']:
            name.append(attrs['RW_PREFIX'])
        if attrs['RW_NAME']:
            name.append(string.capwords(attrs['RW_NAME']))
        if attrs['RW_TYPE_US']:
            name.append(translateAttributes.street_suffixes[attrs['RW_TYPE_US']])
        if attrs['RW_SUFFIX']:
            name.append(attrs['RW_SUFFIX'])
       
        if name:
            tags['name'] = " ".join(name)
        else:
            fixme.append('missing name on highway class that should have a name')
 
    if attrs['BRIDGE'] == 'Y':
        tags['bridge'] = 'yes'
 
    if attrs['ONEWAY'] == 'Y':
        tags['oneway'] = 'yes'
 
    # all roads except the Interstates are state roads, so prefix with SR
    if attrs['ROUTE_ALIA'] and attrs['ROAD_CLASS'] != 'INT':
        tags['ref'] = 'SR %d' % (int(attrs['ROUTE_ALIA']))
    elif attrs['ROAD_CLASS'] == 'INT':
        # interstates aren't given names, but use the name component to set the ref
        m = re.search('^(I|RT)(\d+)', attrs['FULLNAME'])
        if m and m.group(1) == 'I':
            tags['ref'] = 'I %d' % (int(m.group(2)))
        elif m and m.group(1) == 'RT':
            tags['ref'] = 'SR %d' % (int(m.group(2)))
        else:
            fixme.append('motorway without a ref')
 
    if attrs['SPEED_LIMI']:
        tags['maxspeed'] = '%d mph' % (int(attrs['SPEED_LIMI']))   
 
    if float(attrs['VEHIC_MAX_']) > 0:
        tags['maxheight'] = '%.0f in' % (float(attrs['VEHIC_MAX_']))
    if float(attrs['VEHIC_MAX1']) > 0:
        tags['maxweight'] = '%.0f lbs' % (float(attrs['VEHIC_MAX1']))
    if float(attrs['VEHIC_MA_1']) > 0:
        tags['maxwidth'] = '%.0f in' % (float(attrs['VEHIC_MA_1']))
 

    # fix some quirks
    # outlets should be service, not unclassified
    if attrs['FULLNAME'] == 'OUTLET' or attrs['FULLNAME'] == 'PIPESTEM':
        tags['highway'] = 'service'
   
    if fixme:
        tags['fixme'] = ';'.join(fixme)

    return tags