Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I'm running a query to return the total length of some bike paths, from OpenStreetMap. Compared to the known actual length of these paths, they're all a bit too big - something like 10-30%.

I know it may not be possible to down the exact reason, but any possible explanations would be greatly appreciated - I'm new to GIS and could have a basic misunderstanding.

The database is PostGIS with OSM extracts loaded in using Osm2pgsql in 'slim' mode. The routes are OSM relations which osm2pgsql converts into a series of lines, for each way with the given relation. My query looks like this:

select route_name,concat(to_char(sum(st_length(way)/1000.0), 'FM99990D0'), 'km') 
from planet_osm_line 
where route_name like '%Rail Trail' and (tags::hstore -> 'state') is null 
group by route_name 
order by sum(st_length(way)); 

Some selected results:

              route_name              | concat 
--------------------------------------+---------

 Old Beechy Rail Trail                | 60.4km
 Great Southern Rail Trail            | 68.5km
 Ballarat-Skipton Rail Trail          | 72.2km
 East Gippsland Rail Trail            | 123.4km
 Murray to Mountains Rail Trail       | 142.5km
 Goulburn River Country Rail Trail    | 170.4km

Actual distances are:

Old Beechy: 46km
Great Southern: 49km
Ballarat-Skipton: 56km
East Gippsland: 94km
Murray to Mountains: 116km
Goulburn River Country: 134km

What could account for this discrepancy? (If anything, I was expecting the numbers to be too low, representing missing data in OSM. But they're all too high.)

EDIT Now that I actually do the calculation, it's more like 25-40% too high.

Here's the osm2pgsql command:

osm2pgsql  --database gis_aus --slim --create --username ubuntu --hstore --hstore-match-only --number-processes 8 [australia-latest.osm.pbf][2]

i

More info

I just measured the distance of this dead straight, flat road: http://www.openstreetmap.org/browse/way/138890161

Google Maps says 8.144km. PostGIS/OSM/st_length says 10.126km. Pretty big discrepancy.

share|improve this question
1  
What projection are you using? –  BradHards Jun 18 '13 at 6:35
    
I'm not specifying one in osm2pgsql. The data is from here: download.geofabrik.de/australia-oceania/australia.html (Does that answer your question?) –  Steve Bennett Jun 18 '13 at 6:38
    
We also don't know how the distances were calculated. Who calculated the distances on the website? How were OSM data collected? Does the OSM data contain z-values? Elevation alone might account for the discrepancy. Though, I don't know if st_length accounts for elevation values. –  Fezter Jun 18 '13 at 6:40
    
I think the trail distances from the website are fairly accurate (although sometimes there are discrepancies in exactly which bits of trail are counted). There's no elevation in the OSM data. OSM data is almost all traced from aerial imagery (usually Bing), sometimes with reference to a GPS track as well. –  Steve Bennett Jun 18 '13 at 6:42
    
Most of these trails are also fairly flat (hence, minimal elevation distortion), with grades less than 2%. Could the curvature of the earth be in play? –  Steve Bennett Jun 18 '13 at 6:44
show 1 more comment

3 Answers

up vote 5 down vote accepted

You are not using geodesic functions to calculate the length, which means that for a point there is an error factor of:

cos( LATITUDE * pi() / 180 )

If you then multiply the calculated lenght by the error factor you should obtain a value pretty close to the actual trail length. For instance the Old Beechy Rail Trail is close to Melbourne, which has a latitude of ~ 37° which means:

cos( 37 * pi() / 180 ) ~ 0.798635510047293

in turn:

60 * 0.798635510047293 = 47.91 Km

which, depending on your needs and given the brutal rounding of Melbourne's lat that I took in the calculations, could be considered close enough to the reported official length of 46 Km.

This question has very useful information on the topic of geodesic measurements.

share|improve this answer
    
Thanks. To make sure I understand: the error is that the number from Google Maps or on the website is a curve over the surface of the earth, while the number from st_length() is a flat line across a projected map surface? Is this st_length() value of any use without the geodesic correction? –  Steve Bennett Jun 18 '13 at 7:03
2  
Ok, with a bit of trial and error, replacing st_length(way) with st_length(st_transform(way,4326)::geography gives the right answer. –  Steve Bennett Jun 18 '13 at 7:18
1  
How can you solve this with an error factor when the error depends on the direction of the line/distance? north<->south distances have no error but west<->east do. –  Nicklas Avén Jun 18 '13 at 7:30
1  
@Nicklas is right: the cosine calculation only provides a bound on the amount of relative error. A perfectly north-south route will have its length accurately estimated even when no projection is used. –  whuber Jun 18 '13 at 13:10
add comment

Replacing st_length with st_transform(way,4326)::geography solves the geodetic distance problem - thanks unicoletti!.

 Old Beechy Rail Trail                | 47.2km
 Great Southern Rail Trail            | 53.5km
 Ballarat-Skipton Rail Trail          | 57.2km
 High Country Rail Trail              | 63.7km
 East Gippsland Rail Trail            | 97.6km
 Murray to Mountains Rail Trail       | 114.5km
 Goulburn River Country Rail Trail    | 135.8km

Sweet!

share|improve this answer
add comment

ST_Length, when called on a geometry, reports in units of the spatial reference system. For EPSG:900913/EPSG:3857, the units are in Mercator meters, not in meters. At all points on the globe, a Mercator meter is at most 1 real meter. To do this there are two possible fixes

  • Transform to an appropriate projection for your area. UTM, state plane and albers are all common selections.

  • cast to geography. ST_Length(geography) returns the length in units of meters. Internally this picks an appropriate projection, transforms into it, and measures the distance.

A very minor source of error can be the spheroid vs sphere, and great circle differences. These should not matter for a trail where it is not just one line with two points.

As Mercator meters and meters differ only by a scaling factor based on latitude and the scaling factor is the same in both the N/S and E/W direction, it is possible to convert between the two, based on the latitude of the object. Obviously this is subject to error for objects that span a considerable north/south distance, and it's easier to get wrong than the above methods.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.