GeoJSON for the steps of San Francisco

I keep playing with this dataset of all the steps of San Francisco from OpenStreetMap. I made a GeoJSON file with all the steps of San Francisco. It’s a snap to add to a Web map with Leaflet. A few thoughts:

GeoJSON is a good format for geodata when you’re working cross-language. PostGIS can emit it, Python and Javascript can easily parse it, Leaflet can easily draw it. Half the time I just get a string from PostGIS and never even parse it in Python, just pass it along.

The Python geojson library doesn’t really help very much. If you’re using geopy already to work with geodata, then maybe it’s helpful. But if you’re just building up arbitrary JSON blobs with some geodata it’s not needed.

The world could use a GeoJSON validator. Extra credit if it rendered the GeoJSON blob on a map, wouldn’t be too hard. I should set this up as a web service.

JSON float precision continues to contribute to file bloat; Python’s default 15 digits precision translates to subatomic location positioning. Fortunately in Python 2.7 it’s pretty easy to round off numbers, you just have to do it.

The GeoJSON format I settled on was a FeatureCollection. Each feature has the name, length (in metres), and OSM ID of one set of steps. Then two geometries: the centroid of the steps and the path of the steps. Example:

{   "type": "Feature",
    "properties": {
        "id": 8916413,
        "length": 146.58,
        "name": "Harry Street"
    },
    "geometry": {
        "type": "GeometryCollection",
            "geometries": [
            {   "type": "Point",
                "coordinates": [ -122.431219, 37.740099 ],
            },
            {   "type": "LineString",
                "coordinates": [
                    [ -122.430741, 37.740424 ],
                    [ -122.43075,  37.740351 ],
                    [ -122.431759, 37.739803 ]]
            }
]}}

Here’s the SQL query for all the steps I’m using. There’s more Python code than I’d like to collect all these rows and emit the GeoJSON, but I’m not pasting it all here.

select
    planet_osm_line.name,
    ST_Length(planet_osm_line.way) as meters,
    ST_AsGeoJSON(ST_Transform(ST_Centroid(planet_osm_line.way),4326), 6),
    ST_AsGeoJSON(ST_Transform(planet_osm_line.way, 4326), 6),
    planet_osm_line.osm_id
from planet_osm_line
    inner join planet_osm_polygon
    on ST_Intersects(planet_osm_line.way, planet_osm_polygon.way)
where
    planet_osm_polygon.osm_id = '-111968'
    and planet_osm_line.highway = 'steps'
order by meters desc;