I am trying to build a REST API using Flask and Postgis.

I have a PostGIS table with a GEOM column. Querying the table using ST_AsGeoJSON gives me a MULTIPOLYGON with lat, lon in WGS84.

[('Reykjavíkurborg', '{"type":"MultiPolygon","coordinates":[[[[-21.9793904176809,64.1449965355369],[-21.9793723947542,64.1449939711492],[-21.9793486086784,64.1449948273916],[-21.979313323496,64.1450030433758], ...

Using the TopoJSON Python port I can manage to render the output in D3, which in turn creates an SVG like so:

GEOM => GeoJSON => TopoJSON => D3 => SVG

What I am looking to do is to export a PNG of that polygon. Effectively rendering the image (rasterizing?) but doing that server side rather than client side.

I've come across what seems to be various different ways of doing this.

  1. How to rasterize simple geometry from GeoJSON file using GDAL? This method uses the GDAL library. I can load the GEOM column directly into ogr.Open() but I just get a black image outputted.
  2. Convert geojson to png Original question is asked in Java but at the bottom there's a Python solution. The Python Pillow imaging library is manually used to draw an image but I'm not seeing any transformation of the coordinate system. This seems to be a rather manual way of drawing the image.
  3. Convert ST_Union polygon to PNG file in PostGIS? Using the ST_AsPNG PostGIS function seems intuitively to be the most practical way but I'm having a bit of trouble building that function in Flask. To output the GeoJSON I do this:

    for r in db_session.query(geom.ST_AsGeoJSON()).all():

    but conversely:

    for r in db_session.query(geom.ST_AsRaster()).all():

    gives me an error: No function matches the given name and argument types. You might need to add explicit type casts. (Googling ST_AsRaster + the error result indicates I've got some catching up to do)

  4. Rasterizing shapefiles with GDAL and Python? Here I find unclear the purpose of the ndsm value as it seems to be neither the input nor the output.

So there seems to be more than one way going forward. And my question is: What is the most efficient way of extracting a PostGIS geom and rendering it as a PNG?

Using either builtin PostGIS functions or Python GDAL bindings seems to make the most sense.

Lots of things I don't really understand such as what bands are in raster files.

  • Is gdal_rasterize gdal.org/gdal_rasterize.html an option for you? – user30184 Sep 3 '18 at 20:38
  • 1
    I have no idea about how to implement this in Flask, but, with all possible simplicity, the way to get a PNG from PostGIS geometries is SELECT ST_AsPNG(ST_AsRaster(ST_Union(<geometries>), <x_dimension_in_px>, <y_dimension_in_px));, passing in a unified geometry (there's a similar exampe in the ST_AsRaster docs). note that this might not work yet with Multi geometries! you might also need to enable the GDAL drivers to generate the output: SET postgis.gdal_enabled_drivers = 'ENABLE_ALL'; – ThingumaBob Sep 3 '18 at 21:00
  • as an addition: check this for more options to enable the GDAL drivers (the above method is only per transaction) – ThingumaBob Sep 3 '18 at 21:08
  • Rasterizing probably isn't the most effective solution here. I think you want to fetch a vector geometry from the database (WKT, GeoJSON, etc.) and then render it at the Python level using tools like shapely and matplotlib, e.g. gis.stackexchange.com/questions/143294/… – dbaston Sep 4 '18 at 11:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.