Fairfax Connector

From OpenStreetMap Wiki
Jump to navigation Jump to search

The Fairfax Connector is the bus system for Fairfax County, Virginia.

The Fairfax County Department of Transportation has recently provided a Personal GeoDatabase file containing 4,024 bus stops and 65 bus routes. The data has been given without restriction, other than to link to Fairfax Connector's website on the Contributors page, and to add source=* and source:url=* tags on the imported data. The data is quite comprehensive and detailed, including such information as the presence, owner, type, lighting, and construction of shelters, benches, and more.

There is a list and description of fields on this page.

Importing

I have requested review of this import of bus stops on imports@ (here[1]) and MappingDC (here).

  • Update: Comments focused on whether or not to use name=* at all. Pending further discussions, I plan to put this name-like information into description=*.

The file was provided as a Personal GeoDatabase file, which was then converted in QGIS on a Windows machine to a SQLite file to maintain long attribute names. An ogr2osm translation file was written, and data converted to an .osm.xml file. The SQLite file, shapefile, ogr2osm translation file, and resulting .osm.xml file is contained in the following zip:

There are only around 200 bus stops in OSM at the moment, so a manual merge process is planned using JOSM

Reproduced here is the ogr2osm translation file. See Fairfax Connector/Field information for details on the attributes present.

def translateAttributes(attrs):
    if not attrs:
        return

    tags = {}

    # tags common to all nodes
    tags.update({'source': 'Fairfax Connector'})
    tags.update({'source:url': 'http://www.fairfaxconnector.com'})
    tags.update({'highway': 'bus_stop'})
    tags.update({'public_transport': 'platform'})

    # tags with simple assignment (handle dups manually)
    tags.update({'ffx:stopid': attrs['stopid']})

    # name is complicated, most stops don't have real names, they're just based
    # off the street and nearest cross street
    # FIXME: this doesn't work completely! check for empty strings
    # FIXME: expand abbreviations?
    tags.update({'name': capwords(attrs['on_street'] + ' @ ' +
                                  attrs['at_street'])})

    # handle shelter attribute and varying capitalization
    v = attrs['shelter']
    if v.lower() in ['yes', 'no']:
        tags.update({'shelter': v.lower()})

    # there are several attrs which describe the presence of benches
    keys = ['bench', 'benchinshelter1', 'benchinshelter2',
            'benchinshelter3']
    for k in keys:
        if attrs[k].lower() == 'yes':
            tags.update({'bench': 'yes'})
            break

    # FIXME: should we consider overhead street lighting as lit? maybe have a
    # distance cutoff?
    # FIXME: should we set lit=no?
    keys = ['shelterinteriorlite1', 'shelterinteriorlite2',
            'shelterinteriorlite3', 'overheadstlighting']
    for k in keys:
        if attrs[k].lower() == 'yes':
            tags.update({'lit': 'yes'})
            break

    # consider all shelters for ADA compliance (wheelchair=yes)
    # FIXME: should I set wheelchair=no?
    keys = ['shelterada1', 'shelterada2', 'shelterada3']
    for k in keys:
        if attrs[k].lower() == 'yes':
            tags.update({'wheelchair' :'yes'})
            break

    return tags

See also

External links