OpenSportMap
OpenSportMap is a proposal for a database layer for OSM containing sports and recreation activity plans and recordings.
Here database layer refers to geographic data stored outside the main OSM database, typically because the data is not part of the base map but is intended to be shown on top of it. A proposed implementation of database layers is to just use a new instance of the OSM server. There is some discussion at the following link:
http://blog.jochentopf.com/2012-09-23-multiple-layers-for-osm.html
The specific data stored in this OSM layer would be GPS traces of sports and recreation activities or routes and plans for such activities. The server would be public and accessible to any client applications for collecting data and for displaying/analyzing the data.
Additionally, the data would be available for use in improving the OSM map, including refining trail networks and improving classification of things such as cycling routes on the street network.
There are numerous products on the market that serve the recreation tacking function, such as MotionBased (later GarminConnect), AllSportGPS, BonesInMotion, Trimble Outdoors, MapMyRun/Bike/..., NokiaSportsTracker, AllTrails, Strava and more. The OpenSportMap version would have the benefit of being open data that is freely accessible through a well known API and it would carry the weight of the OSM name. It would also have the added benefit of improving the OSM map.
Tagging
The stored tracks would be encoded as ways of a limited length, combined using a relation. In addition, other annotations would be allowed, such as points of interest. The type of relation is rec_event. Additionally it is broken into two main tayps, an episode, which is a GPS record of an actual event, and a plan, which is a composed trace of a route or other plan for an event.
Rec_event Relation
This is an example of XML for an rec_event relation.
<?xml version="1.0" encoding="UTF-8"?>
<osm version='0.6' generator='OpenSportTracker Android v1.4'>
...
<relation id='1370729' timestamp='2011-12-02T12:16:49Z' uid='300999' user='someone' visible='true' version='8' changeset='10016221'>
<member type='node' ref='1098227410' role='start' />
<member type='way' ref='1370727' role='track' />
<member type='way' ref='1370728' role='track' />
<member type='way' ref='1370725' role='track' />
<member type='way' ref='1370726' role='track' />
<member type='node' ref='1098227411' role='end' />
<member type='node' ref='1098227411' role='annotation' />
<member type='way' ref='1370726' role='annotation' />
<member type='relation' ref='1370726' role='annotation' />
<tag k='type' v='rec_event' />
<tag k='event' v='episode' />
<tag k='device' v='Samsung Galaxy S III'/>
<tag k='user:display' v='Bill Johnson' />
<tag k='activity' v='biking' />
<tag k='timestamp' v='2011-12-02T12:16:49Z' />
<tag k='name' v='Training Ride' />
<tag k='duration' v='81234.122' />
<tag k='distance' v='53901.12' >
</relation>
...
</osm>
Members
These are roles for the rec_event relation.
Relation Tags
These are tags for the rec_event relations. Note that in addition to the keys, some data is stored on the event relation itself, including the user and the client software.
Key | Description | Example value(s) |
---|---|---|
type=* | The type of relation - rec_event | type=rec_event |
event=* | The type of event. Values: episode (recorded event), plan | event=episode, event=plan |
device=* | The hardware device that generated the data | device=Samsung Galaxy S III |
user:display=* | Display name for user. The user name and id are stored on the relation object. | user:display="Bill Johnson" |
activity=* | The activity that was recorded. | activity=biking,activity=multi,activity=triathlon |
activities=* | For events with multiple activity types, the list of individual activities should be tagged. Additionally individual tracks should be labeled for activity type. | activities=swimming;biking;running |
timestamp=* | The start time of the event (typically used only on episodes) | timestamp=2011-12-02T12:16:49Z |
name=* | name of given to the event | name=Training Ride |
duration=* | The duration of the event (typically used only on episodes) | duration=81234.122 |
active_time=* | This tag allows for storing active time as opposed to just the duration (typically used only on episodes) | active_time=71234.122 |
rest_time=* | This tag allows for storing inactive time (typically used only on episodes) | rest_time=10000.000 |
distance=* | The distance of the event. This value can be derived but the tag should be added for easy access. | distance=53901.12 |
duration:biking=* | In the case of events with multiple activities, the time can be broken down by activity. (typically used only on episodes) | duration:biking=81234.122 |
distance:biking=* | In the case of events with multiple activities the distance can be broken down by activity. | distance:biking=53901.12 |
Track Way
Key | Description | Example value(s) |
---|---|---|
type=* | The type of way - event_track | type=event_track |
activity=* | The activity that was recorded. This should only be added to the track if the event of which the track is a part includes multiple activities. | activity=biking |
inactive=* | This tag should be used if the total duration of the track was inactive or rest time. If inactive and active time are tracked, the ways should be split so each is composed solely of active time or inactive time. | inactive=* |
Track Node
This tagging is used for the nodes in the track ways and also in the start and end nodes.
Key | Description | Example value(s) |
---|---|---|
time=* | This is one method of adding the timing to an event, typically an episode. | time=2011-12-02T12:16:49.321Z |
time:rel=* | This is an alternate method of specifying timing for an event. This gives the relative time into an event. The time does not have to be relative to the start time. The start node will also have a relative time labeled that does not have to be 0. This is suggested for cases where the user does not want to give an absolute time for privacy reasons or for plan events in order to give suggested pacing. | time:rel=1231.435 |
Generalization to Other Uses
The same layer concept can be used for many other cases of geographic data to be displayed on top of the map.
A prime example is a service similar to Google MyMap. OpenStreetMap can have a similar service that lets users create their own map data and store it in an alternate database layer.
There are other examples of data that is currently in the main OSM database that may be more appropriate to a separate layer. One possible example is transit routes.
A Single Annotation Database Layer
It would be possible to have a single database (or in other words a single database layer) to house this annotation data. The OpenSportMap data described here would be located in rec_event relations. Transit routes for a given transit company may be in a transit route relation. Migratory patterns of English Swallows could also be contained in a characteristic relation.
The annotations could be plotted as overlays on the OSM map, with the desired data types displayed based on their parent relation types, much as typical GIS data is plotted.
Combining the annotations in a single service would need a different name, maybe (jokingly) OSRI or OrcGIS Online.