node-mapnik
node-mapnik copied to clipboard
Variable geometry outputs
I've been playing around with geometries derived from Mapnik data sources today, specifically water features in http://c.tiles.mapbox.com/v3/mapbox.mapbox-streets-v4/14/2624/6324.vector.pbf (I'm seeing how feasible it is to pass them through GEOS (via node-geos) to union them.)
I think I'm running into the "non-OGC geometries" that @springmeyer mentioned at NACIS, but I'm also seeing some other strange behavior.
This is what's being output when calling tile.toGeoJSON('water'):

http://geojson.io/#id=gist:anonymous/beec31122f0cdabc9432&map=15/37.9009/-122.3328
This is closer to what I'd expect. These features were created by calling JSON.parse(feature.toJSON()) on each of the features yielded by the tile DataSource and merging them together into a FeatureCollection.

http://geojson.io/#id=gist:anonymous/31d6cce70778e6e82e2b&map=15/37.9009/-122.3328
Here's an adjacent tile showing the repeated vertices at (0,0) (in local coordinates). This seemed related to #179, but upgrading to 2.3.x didn't change the output at all.

http://geojson.io/#id=gist:anonymous/b25231ddffd74f941f68&map=15/37.9182/-122.3328
There also appear to be at least 3 distinct ways that geometries are generated from the vector tiles:
feature.toJSON()(in mapnik-vector-tile), which usesmapnik::vector::tile_featureset.next()and Mapnik's Spirit-based GeoJSON generator (and outputs strings)tile.toGeoJSON()(in node-mapnik), which seems to re-implement parts oftile_featuresetslightly differently (per the above images) and handle re-projection (and outputs Objects)tile.toJSON()(in node-mapnik), which appears to use raw geometries (retaining local coordinates) and assembles them into a tree of Objects for all layers present
Is one of these preferable to the others (should I find the time and should it be sensible to attempt some consolidation)?
(This is where the non-OGC geometry part rears its head.) The GeoJSON objects generated by tile.toGeoJSON() are almost usable by GEOS (geom.buffer(0.0) fixes the topological errors, but the (0,0) vertices mean that incorrect inputs are correctly unioned together to create incorrect output).
GeoJSON objects generated by feature.toJSON() are invalid according to GEOS--polygon rings don't repeat the initial coordinates and I've seen them contain a single point (GEOS wants 0 or >= 3 points in a ring). However, projecting and mangling them after generation does produce correct output, so I suspect that doing the same at the appropriate place in Mapnik may "fix" it.
Pointers, thoughts?
The vertex in the top-left (present in the first feature of each tile) doesn't make sense either..
Can you explain a little more about your use-case? How exactly will unioned water geometries help you/how are they a problem right now? Supporting working with vector tile geometries in an OGC/GEOS environment should be doable eventually, but certainly is not an intended use case right now - most importantly our clipping algorithm - agg::conv_clip_polygon does not produce OGC geometries and by design leaves an outer ring 1px outside of each water tile. When I'm back from holiday I can provide more details about why its this way currently.
I don't have a specific use-case or problem I'm trying to fix (and the unioned water geometries are more of a red herring, though I chose them because they're polygons and there are relatively few of them)--this is more an experiment to see whether/how data tiles can be reconstituted and if there are interesting things worth doing with them (geometry manipulation, initially). (Postgres foreign data wrappers, nosql storage, meta tiling for labels, etc. come to mind.)
It actually works surprisingly well now (esp. since I can hack around the edges), despite not being an intended use-case.
Once you're back, I'm definitely curious to hear more, but there's no rush.