2010-1-28
Contact:
Jay Farrimond
jay@sabikerides.com
http://www.sabikerides.com/
The SABX file format is an XML-based format intended for use in storing information for bicycle ride maps. It's root element is a rideset, which contains all the information needed to define multiple routes. The spirit of a rideset is that it contains all the variants (usually different distances) of a specific ride from a specific location (or nearby locations). You can abuse this as you see fit. The terms "ride" and "rideset" are used interchangably in this document.
Ride data consists of photos, parking places, turns, segments, stops, points of interest (POIs), rides, and history, as well as some administrative data.
Many of the elements have an "id" attribute. The ids are expected to be unique for each type of element (i.e. all stops have unique ids, all turns have unique ids), but an id might be re-used between types.
The namespace for SABX 1.0 files is http://www.sabikerides.com/sabx/1/0/.
Various odds and ends about the rideset.
Element Name | Type | Description |
---|---|---|
uuid | string | unique identifier for this ride (standard UUID) |
version | positive integer | version of this ride (incremental integer) |
zip_prefix | positive integer | first three digits of the zip code where the ride starts |
ride_type | string | road or mtb (so far) |
title | string | name of the ride |
description | string | describes the ride (can contain paragraphs and links) |
terrain | string | flat, rolling, hilly, mountainous, etc... |
<uuid>bfe4b93d-526c-4dbb-91c3-71c4297475cd</uuid> <version>1</version> <zip_prefix>782</zip_prefix> <ride_type>road</ride_type> <title>Main Plaza - Mission Trail</title> <description><p>Take a historic ride from the Main Plaza in San Antonio to the Mission Trail. View San Antonio and the Missions along the way.</p> </description> <terrain>Flat</terrain>
Cover photo for ride and links to other photos of the ride. There can be multiple links to other photos.
Element Name | Type | Description |
---|---|---|
title | string | title text for cover photo (corresponds to "title" attribute for image element) |
src | URI | URL of cover photo (corresponds to "src" attribute for image element) |
photo | element | additional links for other photo sources (min: 0, max: unbounded) |
Each additional photo link is composed of:
Element Name | Type | Description |
---|---|---|
desc | string | description of link to other photos (corresponds to "desc" attribute of an a element) |
href | URI | URL for link to other photos (corresponds to "href" attribute of an a element) |
<photos> <title></title> <src></src> <photo> <desc></desc> <href></href> </photo> </photos>
Location (lat,lon) and description of where the rides start. There can be multiple instances of parking.
Attribute Name | Type | Description |
---|---|---|
id | string | unique identifier for this parking place (usually sequentially numbered) |
Element Name | Type | Description |
---|---|---|
description | string | describes the parking place (can contain paragraphs and links) |
lat | decimal | latitude of parking place (in degrees) |
lon | decimal | longitude of parking place (in degrees, west being negative) |
<parking id='4'> <description>You're on your own in downtown San Antonio. Parking is available, but it's so varied that there's no way I can tell you where to park.</description> <lat>29.4247617</lat> <lon>-98.4930004</lon> </parking>
Stops and POIs define points (lat,lon) of note along the rides.
Stops tell where there are places to stop (duh!) for refreshments or rest. There can be 0 or more stops for a ride.
Attribute Name | Type | Description |
---|---|---|
id | string | unique identifier for this stop (usually sequentially numbered) |
Element Name | Type | Description |
---|---|---|
type | string | what kind of a stop is this? common examples are "convenience store", "gas station", "restaurant", etc... |
description | string | describes the stop (can contain paragraphs and links) |
lat | decimal | latitude of stop (in degrees) |
lon | decimal | longitude of stop (in degrees, west being negative) |
<stop id='9'> <type>mission</type> <description>Mission Concepcion has water and restrooms in the park headquarters building.</description> <lat>29.3897387</lat> <lon>-98.491712</lon> </stop>
POIs note places of interest along the ride. POIs can be landmarks, hazards, etc...
Attribute Name | Type | Description |
---|---|---|
id | string | unique identifier for this POI (usually sequentially numbered) |
Element Name | Type | Description |
---|---|---|
description | string | describes the POI (can contain paragraphs and links) |
lat | decimal | latitude of POI (in degrees) |
lon | decimal | longitude of POI (in degrees, west being negative) |
<poi id='10050'> <description>Mission Concepcion</description> <lat>29.390316667</lat> <lon>-98.491733333</lon> </poi>
Turns and segments compliment each other. Turns connect segments, and segments connect turns. Each ride starts with a turn and ends with a segment. The first turn tells you how to proceed from parking onto the first segment, so parking is an implied one-point first segment. It is also implied that the last segment ends at the end of the ride, quite often back where you parked.
Turns connect segments. They tell the names of the segments they connect, give the turn cue, and give commentary about the turn.
Attribute Name | Type | Description |
---|---|---|
id | string | unique identifier for this turn (usually sequentially numbered) |
Element Name | Type | Description |
---|---|---|
fromto | string | what this turn connects, generally of the form "STREET_X to STREET_Y" |
cue | string | what to do at this turn, for instance "LEFT onto STREET_Y" |
comments | string | additional information about the turn |
<turn id='5'> <fromto>parking to Main Plaza</fromto> <cue>SOUTH on Main Plaza</cue> <comments>Head South from the starting spot.</comments> </turn>
Each segment is a part of a road or multiple roads, since often the same road will change names as you go along it, and sometimes a road will have turns in it but maintain the same name through the turns. A segment names and describes the road, tells what it connects, gives various statistics about it, and contains the waypoints (lat,lon) that define its geometry.
Attribute Name | Type | Description |
---|---|---|
id | string | unique identifier for this segment (usually sequentially numbered) |
Element Name | Type | Description |
---|---|---|
road | string | name of this road |
fromto | string | what this segment connects, generally of the form "STREET_X to STREET_Y" |
comments | string | additional information about the segment |
lanes | string | minimum number of lanes (doesn't count turning lane) |
shoulder | string | minimum width of shoulder (I use fantasy bike widths, and do it in fractions) |
traffic | string | light, moderate, heavy, etc... |
speed | string | maximum speed limit on the road |
waypoint | element | a set of (lat,lon) waypoints defines the geometry of this segment |
For a stop or POI to be included in a ride, it must be referenced by one of the waypoints for that ride. This lets the ride know where in the ride these occur. It works this way since a stop or a POI might not be exactly on the ride, but somewhere near it. This specifies the waypoint that is nearist to it.
It is assumed that the very last waypoint in a segment is omitted. When segments are combined for a ride, it as assumed that each segment's last waypoint is actually the first waypoint of the following segment. In this way all segments are connected.
Each waypoint consists of the following information:
Attribute Name | Type | Description |
---|---|---|
id | string | unique identifier for this waypoint (usually sequentially numbered) |
stop | string | space-delimited list of ids of stops near this point (optional) |
poi | string | space-delimited list of ids of POIs near this point (optional) |
Element Name | Type | Description |
---|---|---|
lat | decimal | latitude of waypoint (in degrees) |
lon | decimal | longitude of waypoint (in degrees, west being negative) |
ele | decimal | recorded elevation of this waypoint (in meters) |
usgs | decimal | what the USGS thinks the elevation of this waypoint is (in meters) |
<segment id='5'> <road>Main Plaza</road> <fromto>parking to Market St.</fromto> <comments>Take off from Main Plaza next to the food and juice stand. You should probably push your bike through the plaza until you get to Market St.</comments> <lanes>1</lanes> <shoulder>0</shoulder> <traffic>Moderate</traffic> <speed>30</speed> <waypoint id='277'> <lat>29.42475</lat> <lon>-98.4930398</lon> <ele>184.23</ele> <usgs>197.490249634</usgs> </waypoint> <waypoint id='278' stop='9' poi='10052 10053'> <lat>29.4246934</lat> <lon>-98.4930739</lon> <ele>185.19</ele> <usgs>197.745498657</usgs> </waypoint> </segment>
Rides define the different routes in the rideset. Each has a description, a parking place, and various turns and segments. Parking places, turns, and segments are stored as references to the real entities, allowing for re-use. The convention is that there are turn,segment pairs that define the geometry of the route. This is specified by listing alternately turn, segment, turn, segment, etc... There is no final turn. It's implied that the final segment ends at the stoping place.
Attribute Name | Type | Description |
---|---|---|
id | string | unique identifier for this ride (usually sequentially numbered) |
Element Name | Type | Description |
---|---|---|
description | string | describes the route (can contain paragraphs and links) |
parking_ref | element | reference to id of parking place for this route |
turn_ref | element | reference to id of a turn for this route |
segment_ref | element | reference to id of a segment for this route |
Each parking_ref is an empty element that has an "id" attribute.
Attribute Name | Type | Description |
---|---|---|
id | string | unique identifier of the parking place for this ride |
Each turn_ref is an empty element that has an "id" attribute.
Attribute Name | Type | Description |
---|---|---|
id | string | unique identifier of a turn for this ride |
Each segment_ref is an empty element that has an "id" attribute.
Attribute Name | Type | Description |
---|---|---|
id | string | unique identifier of a segment this ride |
<ride id='1'> <description>The short ride goes to Mission Concepcion, then turns around and returns.</description> <parking_ref id='4' /> <turn_ref id='5' /> <segment_ref id='5' /> <turn_ref id='6' /> <segment_ref id='6' /> <turn_ref id='7' /> <segment_ref id='7' /> <turn_ref id='8' /> <segment_ref id='8' /> <turn_ref id='10' /> <segment_ref id='10' /> <turn_ref id='11' /> <segment_ref id='11' /> <turn_ref id='12' /> <segment_ref id='12' /> <turn_ref id='13' /> <segment_ref id='13' /> </ride>
This is the history of the rideset document. It consists of updates detailing all the changes made to it over time.
Element Name | Type | Description |
---|---|---|
update | element | there should be an update for each version of the file as it evolves |
Each update contains the following:
Element Name | Type | Description |
---|---|---|
version | positive integer | version of the update that corresponds to the version of document (last update always corresponds to current version of document) |
date | date | XSD compliant date (YYYY-MM-DD) of the update |
description | string | description of the change (can contain paragraphs and links) |
<history> <update> <version>1</version> <date>2009-10-19</date> <description>Created.</description> </update> </history>
There is a Python library for working with SABX 1.0 files called sabx10.