Zverik / Nik4

Mapnik to image export
Do What The F*ck You Want To Public License
123 stars 23 forks source link

scale_factor is misused? #20

Closed OnkelTem closed 8 years ago

OnkelTem commented 8 years ago

Привет, Зверик :)

I may be totally wrong but from my observations current implementation of scale_factor doesn't seem to work as expected.

Let's take an example invocation:

nik4.py -b 36.6481408595 55.9508668696 36.8974386671 56.127082206 -z 15 osm.xml out.png

This generates an image with dimensions 5809x7350 with unscaled features.

So I'm gonna get use of documented scale_factor which is implemented in Nik4 as --factor parameter:

nik4.py -b 36.6481408595 55.9508668696 36.8974386671 56.127082206 -z 15 --factor 2 osm.xml out.png

and I get a double-sized image: 11618x14701. Yet, labels (and the rest) are very tiny — which is pretty expected as the scale_factor is not enough. But increasing it up to 6 or more leads to even bigger images which requires --tiles to be used - which is not an option. This happens also if the target is set to PDF.

After brief code review I saw that scale_factor variable takes part in calculating map scale and the size of the resulting image. Which made me think that it is sorta misused: the only actual purpose of scale_factor — is to scale features. So I'd expect my image to be of the same 5809x7350 size but with scaled text and features.

In attempt to figure out an alternative approach of doing things I patched Nik4 by adding an additional parameter --factor2 which is then passed to mapnik.render() directly. As I expected the image size was preserved (5809x7350) and the features were scaled. But this was not flawless, as lot of features began to disappear :(

For example, this rule from placenames.mss:

#placenames-small::hamlet {
  [place = 'hamlet'],
  [place = 'locality'],
  [place = 'neighbourhood'],
  [place = 'isolated_dwelling'],
  [place = 'farm'] {
    [zoom >= 15] {
      text-name: "[name]";
      text-size: 19;
      text-fill: @placenames;
      text-face-name: @book-fonts;
      text-halo-radius: 1.5;
      text-halo-fill: rgba(255,255,255,0.6);
      text-wrap-width: 45;
      text-min-distance: 10;
    }
    /* ... */
  }
}

is not triggered at all at -z 15 and I had to change it to [zoom >= 12] { to get those features back.

Well, any ideas? Че делать-та?

Zverik commented 8 years ago

Why can't you use --ppi for a precide control of scaling?

OnkelTem commented 8 years ago

There's not real difference - use ppi or factor — in both cases the map is scaled while I'm seeking for a way to scale features only.

Let's see:

nik4.py -b 36.6481408595 55.9508668696 36.8974386671 56.127082206 -z 15 --ppi 300 osm.xml out.pdf

First, that same message:

Exception: Image size exceeds mapnik limit (24312 > 16384), use --tiles

while I don't like tiles. Second — this way I'll get features scaled by 3.30 factor according to:

    # ppi and scale factor are the same thing
    if options.ppi:
        ppmm = options.ppi / 25.4
        scale_factor = options.ppi / 90.7 # ≈ 3.30
    else:
       ...

But is this scaling enough? Let's see. Initially we have a screen with 90 dpi and our eye is located at 35-40cm from the image (screen). Now we replace the screen with paper "with" 300 dpi, and thus should increase dpi 3.3 times—that's ok. Now we'd like to hang the map on a wall to contemplate it from 1.5 meters and thus features must be scaled 4 times more, so that overall scale_factor should be 13.

Zverik commented 8 years ago

Discussed on the IRC. Nik4 tries hard to preserve relative dimensions, so it protects from changing scale_factor apart from ppi. You can either change line 264 locally, or use nik2img, which doesn't have any checks.