[GIS] Tiling GeoJSON data

geojsonogrqgis-processingtilestachetiling

I have a GeoJSON dataset of the following format (LineString features):

{
  "type": "FeatureCollection",
  "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },

  "features": [
    { "type": "Feature", "properties": { "id": 433775, "clazz": 72, "flags": 7, "source": 26697, "target": 48416, "kmh": 10, "time": 1 }, "geometry": { "type": "LineString", "coordinates": [ [ 13.3782144, 52.516451399999973, 0.0 ], [ 13.3782407, 52.5163161, 0.0 ] ] } },
    { /* [... around 13k features ...] */ },
    { "type": "Feature", "properties": { "id": 377768, "clazz": 51, "flags": 7, "source": 270569, "target": 270570, "kmh": 5, "time": 600 }, "geometry": { "type": "LineString", "coordinates": [ [ 13.388153799999985, 52.492538299999971, 0.0 ], [ 13.3881033, 52.4924441, 0.0 ] ] } }
  ]
}

For a research project I need this featureset to be cut into tiles of different zoom levels.

  • without generalization / simplification of geometries
  • without caching and writing results to new GeoJSON files on disk

I had a look at geojson-vt by mapbox and it seams it only generates the tiles on the fly, but I need them on the disk for further processing and investigation.

Is that possible? If so, how?


Updates:

  • I'm on ArchLinux, command line tools like ogr2ogr or any C/C++ tools would be the best, regarding speed.
  • I already tried tilestache but it is totally broken and not well maintainted. Couldn't get it running.
  • Input aswell as output should be GeoJSON (or any vector format).
  • I'm talking about tiles a la Google Maps. The zoom factor for the resulting tiles should be 12, 13 or 14.

The result should be something like this:

./12/2200/1343.json
./12/2200/1344.json
[...]
./14/8800/5372.json
./14/8800/5373.json

A collection of GeoJSON tiles cut from the original vector data.

Best Answer

I've written my own geojson map tiler driver in ruby. it's a quick and dirty ruby script to create geojson tiles from a postgis database using gdal/ogr. I could not find out how to cut the geojson directly, so I imported the json into a postgis database and exported them using ogr.

ogr is supposed to read geojson but I could not get the driver to work directly. maybe someone else can figure out how. here is how it worked for me using postgis:

requires

  • ruby > 1.9.3, but ruby > 2.0.0 recommended
  • gdal/ogr > 2.0.0, the script utilizes the system command ogr2ogr
  • postgresql > 9.0.0, with postgis > 2.0.0 extension installed

usage

setup environment

#!/usr/bin/env ruby

require 'mkmf'
require 'fileutils'
require './tiler/geojson.rb'

geojson_tiler = Tiler::GeoJson.new

set up working directory

geojson_tiler.set_basedir "/path/to/my/tiles"

enable verbose verbose output if desired

geojson_tiler.debug true

setup postgis database connection and sql query to retrieve geodataset

connection = "'PG:host=localhost dbname=distance user=qwertyu password=asdfghj'"
sql_query = "'SELECT id,flags,kmh,geom_way_web_mercator,time FROM streets WHERE time <= 600 ORDER BY time ASC'"
geojson_tiler.setup_db connection, sql_query

write full tile stack for zoom levels 0, 1, 2 and 3

(0..3).each do |zoom|
  geojson_tiler.write_tiles zoom
end

or write partial tile stack for zoom level 8 in range x: 136..138 and y: 82..84

geojson_tiler.write_tiles 8, 136, 138, 82, 84

syntax is zoom, xmin, xmax, ymin, ymax

result

is a full or partial stack of geojson tiles:

/path/to/my/tiles/0/0/0.json
/path/to/my/tiles/1/0/0.json
/path/to/my/tiles/1/0/1.json
/path/to/my/tiles/1/1/0.json
/path/to/my/tiles/1/1/1.json
/path/to/my/tiles/2/0/0.json
/path/to/my/tiles/2/0/1.json
/path/to/my/tiles/2/0/2.json
/path/to/my/tiles/2/0/3.json
/path/to/my/tiles/2/1/0.json
/path/to/my/tiles/2/1/1.json
/path/to/my/tiles/2/1/2.json
/path/to/my/tiles/2/1/3.json
/path/to/my/tiles/2/2/0.json
/path/to/my/tiles/2/2/1.json
/path/to/my/tiles/2/2/2.json
/path/to/my/tiles/2/2/3.json
/path/to/my/tiles/2/3/0.json
/path/to/my/tiles/2/3/1.json
/path/to/my/tiles/2/3/2.json
/path/to/my/tiles/2/3/3.json
/path/to/my/tiles/3/0/0.json
/path/to/my/tiles/3/0/1.json
/path/to/my/tiles/3/0/2.json
/path/to/my/tiles/3/0/3.json
/path/to/my/tiles/3/0/4.json
/path/to/my/tiles/3/0/5.json
/path/to/my/tiles/3/0/6.json
/path/to/my/tiles/3/0/7.json
/path/to/my/tiles/3/1/0.json
/path/to/my/tiles/3/1/1.json
/path/to/my/tiles/3/1/2.json
/path/to/my/tiles/3/1/3.json
/path/to/my/tiles/3/1/4.json
/path/to/my/tiles/3/1/5.json
/path/to/my/tiles/3/1/6.json
/path/to/my/tiles/3/1/7.json
/path/to/my/tiles/3/2/0.json
/path/to/my/tiles/3/2/1.json
/path/to/my/tiles/3/2/2.json
/path/to/my/tiles/3/2/3.json
/path/to/my/tiles/3/2/4.json
/path/to/my/tiles/3/2/5.json
/path/to/my/tiles/3/2/6.json
/path/to/my/tiles/3/2/7.json
/path/to/my/tiles/3/3/0.json
/path/to/my/tiles/3/3/1.json
/path/to/my/tiles/3/3/2.json
/path/to/my/tiles/3/3/3.json
/path/to/my/tiles/3/3/4.json
/path/to/my/tiles/3/3/5.json
/path/to/my/tiles/3/3/6.json
/path/to/my/tiles/3/3/7.json
/path/to/my/tiles/3/4/0.json
/path/to/my/tiles/3/4/1.json
/path/to/my/tiles/3/4/2.json
/path/to/my/tiles/3/4/3.json
/path/to/my/tiles/3/4/4.json
/path/to/my/tiles/3/4/5.json
/path/to/my/tiles/3/4/6.json
/path/to/my/tiles/3/4/7.json
/path/to/my/tiles/3/5/0.json
/path/to/my/tiles/3/5/1.json
/path/to/my/tiles/3/5/2.json
/path/to/my/tiles/3/5/3.json
/path/to/my/tiles/3/5/4.json
/path/to/my/tiles/3/5/5.json
/path/to/my/tiles/3/5/6.json
/path/to/my/tiles/3/5/7.json
/path/to/my/tiles/3/6/0.json
/path/to/my/tiles/3/6/1.json
/path/to/my/tiles/3/6/2.json
/path/to/my/tiles/3/6/3.json
/path/to/my/tiles/3/6/4.json
/path/to/my/tiles/3/6/5.json
/path/to/my/tiles/3/6/6.json
/path/to/my/tiles/3/6/7.json
/path/to/my/tiles/3/7/0.json
/path/to/my/tiles/3/7/1.json
/path/to/my/tiles/3/7/2.json
/path/to/my/tiles/3/7/3.json
/path/to/my/tiles/3/7/4.json
/path/to/my/tiles/3/7/5.json
/path/to/my/tiles/3/7/6.json
/path/to/my/tiles/3/7/7.json
/path/to/my/tiles/8/136/82.json
/path/to/my/tiles/8/136/83.json
/path/to/my/tiles/8/136/84.json
/path/to/my/tiles/8/137/82.json
/path/to/my/tiles/8/137/83.json
/path/to/my/tiles/8/137/84.json
/path/to/my/tiles/8/138/82.json
/path/to/my/tiles/8/138/83.json
/path/to/my/tiles/8/138/84.json
Related Question