British Columbia road and path character scores =============================================== Every road and path in British Columbia that our models can score, with its traffic comfort, surface, remoteness and grade. One row per OpenStreetMap way. 528,742 rows, one per OpenStreetMap way, 30 columns. The CSV is about 96 MB; the .csv.gz is about 20 MB and holds exactly the same bytes uncompressed. PRELIMINARY — working data, subject to revision. Published 2026-07-26 by BC Cycle Tourism Society. Questions, corrections, or collaborations: heather@bccycletourism.ca https://bccycletourism.ca/research/ Licence: Open Database Licence (ODbL) 1.0, with the attribution © OpenStreetMap contributors. Every row here is an OpenStreetMap way and carries its OpenStreetMap identifier, which makes this a derivative database rather than a work of our own, so it is share-alike whether we would have chosen that or not. Use it, redistribute it, build on it. If you publish a database derived from it, that database has to carry the same licence. Suggested citation: BC Cycle Tourism Society (2026). British Columbia road and path character scores [data set]. Version 2026-07-26. https://bccycletourism.ca/research/ Contains information from OpenStreetMap, © OpenStreetMap contributors, available under the Open Database Licence (ODbL) 1.0. https://opendatacommons.org/licenses/odbl/1-0/ READ THIS BEFORE USING assumed_speed_kmh OR assumed_traffic_adt --------------------------------------------------------------- assumed_speed_kmh and assumed_traffic_adt are modelling inputs, not measurements. They are assigned from a way's OpenStreetMap classification and are what the comfort model reasons with, so they tell you why a way was classified as it was. They are not counts taken on that road, and on a separated path they are meaningless: the map deliberately does not show them for exactly that reason. Do not report them as traffic data. Scores versus gradients ----------------------- Five columns are 0-to-1 scores rather than physical quantities: remoteness, remoteness_max, grade, grade_fwd, and grade_rev. In particular grade is a difficulty score, NOT a gradient — on the map its bands are flat below 0.2, easy to 0.4, moderate to 0.6, hard to 0.8, brutal above. The actual gradients are max_grad_fwd_100 and max_grad_rev_100, given as fractions, so 0.077 means 7.7%. Blank cells ----------- A blank cell means we could not measure that thing, not that it is zero. Traffic comfort is blank on about a quarter of the rows: those are mostly paths and tracks where the classifier declines to guess rather than invent a road class. Grade is blank where grade_not_measured is TRUE. Names ----- About 42% of these ways carry a name, which is a fact about OpenStreetMap rather than a gap in this file: most minor paths, tracks, and residential connectors have never been named. A blank name is not a failed lookup. How much to trust these ----------------------- These scores are computed, not ridden. Nobody has checked them road by road. We have calibrated them most carefully in Metro Vancouver, so expect rougher edges elsewhere in the province, and everything is derived from OpenStreetMap and public land cover and elevation data, so where those sources have gaps we have gaps too. All of it is preliminary and will keep changing as we improve the models. What is not in this file ------------------------ Three of the seven scores on the character map are not in this file: flow, quiet, and scenic. Those are computed on roughly 100 metre slices of a way rather than on the whole way, and rolling them up to one number per way needs a choice we are not ready to defend. Ask if you want them: heather@bccycletourism.ca How every score is computed, with every rule and threshold and an unsoftened list of limitations: https://bccycletourism.ca/research/files/character_map_methodology.pdf The interactive map these scores drive, where you can click any road and see why it scored what it did: https://bccycletourism.ca/research/character-map/ COLUMN GUIDE ============ osm_id OpenStreetMap way identifier, 'w' followed by the numeric id. The join key, and stable enough to look up at openstreetmap.org/way/. name The way's OpenStreetMap name where it has one. Often blank; see the note on names below. highway The way's OpenStreetMap highway tag: what kind of road or path it is. lat [degrees] Latitude of a point partway along the way, so you can find it on a map. Not a centroid. lon [degrees] Longitude of the same point. length_m [m] Length of the way. traffic_comfort How much motor traffic the way shares, and what stands between a rider and it, as one of eight classes. C1 separated paths, or slow streets with few cars; C2 sharing light traffic, or bike lanes on calm roads; C3 sharing busier traffic, or bike lanes on busy roads; C4 fast or heavy traffic, a painted line at most; C5 highway-speed traffic (60+ km/h), a painted line at most; C6 fast highway traffic (70+ km/h), a painted line at most; plus BACKCOUNTRY (bare track, beyond traffic data) and FORBIDDEN (cycling not permitted), which sit off the ladder. The ladder is adapted from HUB Cycling's bikeway classification; the labels are our own. A class describes the conditions, not how good the riding is. Blank where the model declines to classify. facility The cycling facility the comfort class was reasoned from, e.g. SHARED, SEPARATED, PATH. assumed_speed_kmh [km/h] Assumed motor traffic speed. A MODELLING INPUT assigned from the way's classification, not a measurement. See the note below before using it. assumed_traffic_adt [vehicles/day] Assumed average daily motor traffic. A MODELLING INPUT, not a count. See the note below before using it. surface [0-4] How rough the way is underfoot: 0 paved, 1 smooth unpaved, 2 loose, 3 chunky, 4 near-mountain-bike. The character map calls this Surface; the model and the methodology report call it ruggedness. surface_confidence 'tagged' where OpenStreetMap states the surface, otherwise our inference. Treat inferred values as a best guess. surface_signal Which tag or rule produced the surface value. remoteness [0-1] How far the way is from the next place to buy food, as a score. Higher is more remote. A way is sampled at several points; this is the MEDIAN of those samples. Each sample scores the mean distance to the three nearest food stores in our BC Bike Stops directory, on a curve centred at 10 km. Distances are straight lines, which understates real riding distance and is plain wrong across water. remoteness_max [0-1] The score at the most remote sampled point on the way, where remoteness is the median. A big gap between the two means the way passes through somewhere much emptier than its overall score suggests. store_km_1 [km] Straight-line distance to the nearest food store, measured at the representative sample point (the one whose score is the median) rather than averaged along the way. store_km_2 [km] Distance to the second nearest, at the same point. store_km_3 [km] Distance to the third nearest, at the same point. The score is driven by the mean of these three, not by the nearest alone. remoteness_confidence 'single_source' where one shop is effectively carrying the score (the second nearest store is more than three times the first plus 5 km away), so losing that one shop would change the answer a lot. 'ok' otherwise. This is not a measure of how many stores exist. remoteness_samples [count] How many points along the way were sampled and scored. NOT a count of stores: every sample looks at exactly three. grade [0-1] Climbing difficulty in the harder direction, as a SCORE AND NOT A GRADIENT: the steady grind combined with the steepest short pitch. The map's bands are flat below 0.2, easy to 0.4, moderate to 0.6, hard to 0.8, brutal above. grade_fwd [0-1] The same score riding the way in the direction it is drawn in OpenStreetMap. grade_rev [0-1] The same score riding it the other way. ascent_fwd_m [m] Total climbing in the drawn direction. Divide by length for metres per kilometre. ascent_rev_m [m] Total climbing the other way. max_grad_fwd_100 [fraction] Steepest 100 m pitch in the drawn direction, AS A FRACTION: 0.077 means 7.7%. max_grad_rev_100 [fraction] Steepest 100 m pitch the other way, as a fraction. bridged [0/1] 1 where the way is a bridge or tunnel. grade_not_measured [TRUE/FALSE] TRUE where we could not measure climbing at all, because the way is a bridge or tunnel and our elevation data holds the ground beneath it rather than the deck. The grade columns are blank on these. TRUE is not flat. grade_signal Which rule produced the grade score. The research here uses AI assistance (Claude models, Anthropic) for data collection, analysis, and writing. Feel free to ask for more details if you are interested.