BeyondTracks
an OpenStreetMap Case Study
beyondtracks.com
I joined OpenStreetMap in 2010
unlike many other maps,
so I used it as a map,
but ultimately it was just a map
it didn't say how long walks were,
it didn't show me photos,
or the climb,
it was just a map
built on top of OpenStreetMap data
OSM stores paths, but route=hiking only for well defined existing routes
looking towards storing key waypoints only as source
CI/CD
nightly job or on push
walk .osm sources
OSM Australia Extract
SRTM1 - 30m DEM
Flickr Photos
PostgreSQL PostGIS
+
JSON + GeoJSON
}
tippecanoe
Mapbox Vector Tiles
.osm's to GeoJSON
ogr2ogr GeoJSON into PostgreSQL
raster2pgsql to load SRTM1 as PostGIS raster
osm2pgsql to load australia.osm.pbf into PostGIS
Elevation
-- create an elevation profile as an array with fixed distances between points
CREATE OR REPLACE FUNCTION elevation_profile(geom geometry, num_points integer) RETURNS integer[] AS $$
DECLARE
-- number of points in linestring
profile integer[] DEFAULT '{}';
BEGIN
FOR i in 0..(num_points - 1) LOOP
profile := array_append(profile, round(ST_Z(ST_LineInterpolatePoint(geom, i::double precision / (num_points - 1))))::integer);
END LOOP;
RETURN profile;
END;
$$ LANGUAGE plpgsql;
-- calculate cumulative elevation gain/loss
CREATE OR REPLACE FUNCTION cumulative_elevation(geom geometry, cent text) RETURNS integer AS $$
DECLARE
-- number of points in linestring
num_points integer;
-- previous and current points
prev geometry;
cur geometry;
-- keeping track of cumulative ascent and descent
cumulative_ascent double precision DEFAULT 0;
cumulative_descent double precision DEFAULT 0;
-- used as a local variable
delta_z double precision;
BEGIN
SELECT ST_NumPoints(geom) INTO num_points;
-- start from 2 so we can always get the previous point
FOR i in 2..num_points LOOP
SELECT ST_PointN(geom,i-1) INTO prev;
SELECT ST_PointN(geom,i) INTO cur;
delta_z := ST_Z(cur) - ST_Z(prev);
IF delta_z < 0 THEN
cumulative_ascent := cumulative_ascent + abs(delta_z);
ELSE
cumulative_descent := cumulative_descent + abs(delta_z);
END IF;
END LOOP;
-- return cumulative cent
IF cent = 'ascent' THEN
RETURN CAST(cumulative_ascent AS integer);
ELSIF cent = 'descent' THEN
RETURN CAST(cumulative_descent AS integer);
ELSE
RETURN null;
END IF;
END;
$$ LANGUAGE plpgsql;
Map Matching
Key:sac_scale
Key:trail_visibility
excellent
good
intermediate
bad
horrible
no
Key:ladder
Key:safety_rope
Key:rungs
Key:surface
sand
other unpaved
paved
affects
-
walk difficulty rating
-
time estimate
but also shown as general information
Linear Referencing
ST_LineLocatePoint
ST_Length(ST_LineSubstring)
Determine how far along the walk features are
For key features like amenity=drinking_water and amenity=toilets this affects how we determine walk "accessibility".
Chronologically Ordered Photos
Sunrise & Sunset times
https://github.com/mourner/suncalc
Weather Forecast
darksky.net
National Park Alerts
Bushfire Alerts
NSW RFS - CC BY 3.0 AU
https://github.com/beyondtracks/nsw-rfs-majorincidents-geojson
ACT ESA - CC BY 4.0
https://github.com/beyondtracks/act-esa-incidents-geojson
Questions?
beyondtracks.com
BeyondTracks: an OpenStreetMap Case Study
By Andrew Harvey
BeyondTracks: an OpenStreetMap Case Study
- 95