python-mapnik
python-mapnik copied to clipboard
Postgis: Empty map when using Python API instead of XML
Hi,
I have the following xml file:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Map[]>
<Map srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over" background-color="#b8dee6">
<Style name="water" filter-mode="first">
<Rule>
<PolygonSymbolizer fill="#1d4bd2" />
</Rule>
</Style>
<Style name="water-outline" filter-mode="first">
<Rule>
<LineSymbolizer stroke="#000000" stroke-width="3" stroke-linejoin="round" />
</Rule>
</Style>
<Layer name="water"
srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over">
<StyleName>water-outline</StyleName>
<StyleName>water</StyleName>
<Datasource>
<Parameter name="type"><![CDATA[postgis]]></Parameter>
<Parameter name="table"><![CDATA[(SELECT geometry, class FROM layer_water(!bbox!, z(!scale_denominator!))) as t]]></Parameter>
<Parameter name="geometry_field"><![CDATA[geometry]]></Parameter>
<Parameter name="extent"><![CDATA[1469505.29396, 6898879.19163, 1480562.84361, 6909936.74128]]></Parameter>
<Parameter name="dbname"><![CDATA[openmaptiles]]></Parameter>
<Parameter name="host"><![CDATA[localhost]]></Parameter>
<Parameter name="port"><![CDATA[5433]]></Parameter>
<Parameter name="user"><![CDATA[openmaptiles]]></Parameter>
<Parameter name="password"><![CDATA[openmaptiles]]></Parameter>
<Parameter name="srid"><![CDATA[900913]]></Parameter>
<Parameter name="extent_from_subquery"><![CDATA[true]]></Parameter>
</Datasource>
</Layer>
</Map>
It renders perfectly:
merc = Projection('+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over')
box2d = Box2d(*data['bbox'])
box2d = box2d.forward(merc)
x, y = data['publish_extent']
srs = merc.params()
m = Map(x, y, srs)
m.zoom_to_box(box2d)
load_map(m, '/home/oliver/mapnik/Water_postgis_subquery.xml')
filename = create_unique_filename(suffix='.png')
render_to_file(m, filename, 'png')
filename = create_unique_filename(suffix='.svg')
surface = cairo.SVGSurface(filename, m.width, m.height)
render(m, surface)
surface.finish()
However, it renders an empty map when I try to use the Python API:
m.background = Color('steelblue')
s = Style()
r = Rule()
polygon_symbolizer = PolygonSymbolizer()
polygon_symbolizer.fill = Color('#1d4bd2')
r.symbols.append(polygon_symbolizer)
line_symbolizer = LineSymbolizer()
line_symbolizer.stroke = Color('#000000')
line_symbolizer.stroke_width = 3
line_symbolizer.stroke_linejoin = 'round'
r.symbols.append(line_symbolizer)
s.rules.append(r)
m.append_style('Water', s)
ds = PostGIS(
host='localhost',
port='5433',
user='openmaptiles',
password='openmaptiles',
dbname='openmaptiles',
srid=900913,
table='(SELECT geometry, class FROM layer_water(!bbox!, z(!scale_denominator!))) as t',
geometry_field='geometry',
extent=', '.join(map(str, [box2d.minx, box2d.miny, box2d.maxx, box2d.maxy])),
extent_from_subquery=True
)
layer = Layer('water')
layer.datasource = ds
layer.styles.append('Water')
m.layers.append(layer)
It caused me headaches almost two days before I tried the xml way. And I can't spot the difference. The hardcoded extent string in the xml is exactly the same as returned by box2d, so that's not the culprit I think.
What do I miss here?
@oliverbienert This happened to me before. I think you have to set the layer.srs.
layer.datasource = ds
layer.srs = "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over"
layer.styles.append('Water')
m.layers.append(layer)
For example this.
Thank you for spotting this! It's obvious, once you know it, isn't? In the xml, I actually did set the layer's srs. I'll try if that works for me in the next couple of days.