Sign up ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I'm trying to render a map to paper using Mapnik at a specific scale (such as 1:50k), but can't yet figure out how. So far I'm just using map.zoom_to_box:

map.zoom_to_box (mapnik.Envelope (101.5,3.2,102,3.3))

and play with MaxScaleDenominator and MinScaleDenominator in the styling rules..

But when done this way, I can only guess-work the map scale by adjusting the bounding box over and over, which is hard to obtain the exact 1:50k scale that I wanted.. I've also found this: map.scale_denominator() and map.scale(), but I think these are used only to display the map scale - not setting it..

Is there anyone here who can help me?

share|improve this question
Hi Haziq, welcome to the forums. I'm not a Mapnik user so I haven't tested this, but here's a post regarding the same issue in OpenLayers, which might also be applicable? –  Stephen Lead Sep 17 '12 at 3:22
Interesting syntax usages.. Don't know whether they'll work with Mapnik or not, so I'll try them on. Thanks @StephenLead! –  user8723 Sep 17 '12 at 9:47
@StephenLead My python's a little rusty, so I can't get those to work with Mapnik.. –  user8723 Sep 17 '12 at 11:24

2 Answers 2

This post should answer your question. Basically you should do a bit of math based on the resolution at which you want to print.

share|improve this answer
I've already delved into this blog post: that's where I got the idea on how to get the exact numbers for the scale. The problem is I don't where to plug-in that calculated scale-denominater value.. Thx for trying @gomatteo ! –  user8723 Sep 17 '12 at 10:01
up vote 3 down vote accepted

I think I've found a workaround to my problem, but it's not a neat one. Basically:

  1. I used print map.scale_denominator() to figure out the scale of my current selection bounding box
  2. map.pan_and_zoom(+x,+y,z) to pan and zoom to the area that I wanted
  3. Used print map.envelope(). This will give out the current bounding box used after panning: Box2d(minlong,minlat,maxlong,maxlat)
  4. Adjust map.pan_and_zoom(+x,+y,z) z-values to zoom until map.scale_denominator() printout the scale value I wanted (50k)
  5. When the map is panned at the right location, I just read the current map.envelope() values and transfer them into the map.zoom_to_box as the new bounding box. I'll comment out map.pan_and_zoom(+x,+y,z) when I'm done.

The overall code will look something like this:

map = mapnik.Map (3000, 3000)
mapnik.load_map (map, "mapDefinition.xml")
map.zoom_to_box (mapnik.Envelope (101.789315885,3.1540902527,101.977962094,3.3427364622))
mapnik.render_to_file (map,"map.png")
print map.scale_denominator(), map.scale()
print map.envelope()

Like I said - messy. But it gets the job done.

share|improve this answer
Thanks for this. This "guessing" process can be easily automated, but it's a huge hack. Is there really no better way?! –  kontextify Dec 26 '14 at 7:49
There should be (still waiting for a better answer). I haven't been using Mapnik for a while, and I've long stopped researching for a better answer. Maybe you should take a look at TileMill or Mapbox Studio, and see how they do it. –  user8723 Dec 26 '14 at 8:23

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.