[Qgis-developer] Re: composer redesign branch

Marco Hugentobler marco.hugentobler at karto.baug.ethz.ch
Fri Mar 7 03:46:48 EST 2008


Hi Steven,

Many thanks for pointing this out. I was not aware that QgsGraphicsScene 
always has mm units.

It would be a possibility that QGIS main map also switches to mm units. In 
this case QgsMapCanvasMap would determine the scale factor to transform pixel 
to mm and configure a QgsMapRenderContext containing this factor. I think it 
is not necessary that QgsSymbol knows its units. Higher level classes that 
configure the rendering context could do this and just pass the scale factor.

The other way round would be that QGIS main canvas still has pixel units and 
print composer queries dpi of the map image and scales its widths and sizes 
to achieve wysiwyg. In my opinion, the global mm approach seems more general.

Regards,
Marco




Am Donnerstag 06 März 2008 01:08:46 schrieb Steven Bell:
> After thinking and looking at the code a little, I definitely didn't
> explain that very well...
>
> As you know, what you see in the main editing canvas is not always what you
> get in the composer.  Likewise,what you see when using the cache preview in
> the composer is not what you get when you render.
>
> The root of the problem is that QGIS does all of its drawing in canvas
> units, so when you switch canvases, you change how things look.  The map
> composer uses millimeters - one QGraphicsScene unit is one mm.
> Printers and PDF output both work with millimeters this way.  If I make a
> QGraphicsRectItem with a size of 10mm square, it will come out 10mm square.
> If the pen width is 1 scene unit (and isn't scaled), it will come out 1 mm
> wide.
>
> Note that when the composer map cache pixmap is drawn, the sizes are all in
> pixels again.  Thus, as the resolution of the cache image changes, the line
> widths and symbol sizes all change.  This has caused a lot of confusion,
> because although the rendered preview matches the rendered output, the
> cached preview does not.
>
> I'm not completely clear on what the DPI setting in the composer actually
> does when doing a vector output such as SVG or Postscript.  Changing that
> setting doesn't seem to affect them, but the vector output code does
> reference it.  I think the SVG generator needs to know something about the
> size/dpi so that rasterizers/renderers can render them properly.
>
> What I did in the composer redesign branch was add an enum, mScaleType,
> which tells the renderer what units the size is in.  The renderer sets a
> size scale, which is dependent on the scale type, size, and current mupp
> (map units per pixel).  Also, rather than setting a pointer to a pixmap, it
> sets a pointer to a symbol renderer which will always render the symbol
> with a size of 1.  QgsVectorLayer's drawFeature( ) method scales the
> painter by the size scale and calls the symbolRenderer's render( ) method.
>
> Since this appears to be much slower than the current code, we probably
> need to do some context-dependent caching.
>
> In the rendering context, we would need to include some information about
> whether we were rendering in screen units or paper units.  Perhaps more
> correctly, we would like to know the output DPI, which will be one
> (system-dependent) thing for the editing canvas, 25.4 for the composer
> canvas, and some variable for the composer map cache.  Because of the way
> the physical output is handled, I don't think we need to know or care what
> the printer's DPI is.
>
> This should enable the removal of the symbol/line width/text scale options
> in the composer.  This also allows us to use the QgsMapRender class to
> render the map, rather than having a bunch of almost-duplicate code.  The
> code currently in composer_redesign uses QgsMapRender, but I haven't taken
> the time to remove the scale boxes in the map control pane.
>
> Let me know if this still isn't clear.  I haven't completely sorted it all
> out, either. :-)
>
> Steven
>
>
> On Wed, Mar 5, 2008 at 4:09 AM, Marco Hugentobler <
>
> marco.hugentobler at karto.baug.ethz.ch> wrote:
> > Hi Steven,
> >
> > > I would remove symbolScale and widthScale in favor of defining the
> >
> > widths
> >
> > > in terms of concrete units, whether pixels, millimeters, or map units.
> >
> > It would be good for me if you could explain this idea in more detail as
> > I'm
> > still not sure my understanding is correct.
> >
> > Do you mean that QgsSymbol should have its own pen width and stroke
> > width? They would be specified e.g. in mm instead of pixels and when the
> > symbol is
> > applied, transformed to pixels according to the ouput device dpi?
> >
> >
> > The idea that i had was to just work on pixel level with one scalefactor
> > (mResolutionRatio). So if e.g. a printer has a resolution of screen dpi *
> > 2,
> > then mResolutionRatio would be 2 and all the width values for QPen,
> > QBrush and also width/height for images would be scaled by factor 2.
> > Caching pixmaps
> > would only be alloud if mResolutionRatio is 1.
> >
> > I think that would be doable without many code changes. But it is not as
> > generic and clean as working with real units (e.g. mm) in the qgis core.
> >
> > Regards,
> > Marco
> >
> > Am Dienstag 04 März 2008 17:26:08 schrieb Steven Bell:
> > > > So my suggestion is to have the rendering context somehow like this:
> > > >
> > > > class QgsMapRenderContext
> > > > {
> > > >        QgsMapToPixel mMapToPixel;
> > > >        QgsCoordinateTransform mCoordTransform;
> > > >        QgsRect mExtent;
> > > >        bool drawEditingInformation;
> > > >        bool mRenderingStopped;
> > > >        double mResolutionRatio;
> > > > };
> > > >
> > > > The resolution ratio is usually 1, except when drawing to a different
> > > > paint
> > > > device (like QPrinter). I hope it will allow to consider for
> > > > different line
> > > > width / symbol sizes on these output devices.
> > > >
> > > >
> > > >From what I understand, QgsMapToPixel basically holds the information
> >
> > that
> >
> > > mResolutionRatio would contain.
> > >
> > > Martin already mentioned this, but the rendering context needs to have
> >
> > some
> >
> > > way to tell the renderer whether to use maximum-resolution vector ouput
> >
> > or
> >
> > > cached pixmaps.  I would also add something about what the output units
> > > are, whether pixels or millimeters.  Both of the above might be done
> > > together with an "are we printing to ps/pdf/svg" bool.
> > >
> > > I would remove symbolScale and widthScale in favor of defining the
> >
> > widths
> >
> > > in terms of concrete units, whether pixels, millimeters, or map units.
> > > This is what I have attempted to do in the current composer_redesign
> >
> > code.
> >
> > > One of the major problems is that printed millimeters are treated as
> > > the same as screen pixels, rather than a separate but similar type of
> > > measurement.
> > >
> > > I hope this makes sense.  Let me know if I need to clarify anything.
> > > Steven
> >
> > --
> > Dr. Marco Hugentobler
> > Institute of Cartography
> > ETH Zurich
> > Technical Advisor QGIS Project Steering Committee



-- 
Dr. Marco Hugentobler
Institute of Cartography
ETH Zurich
Technical Advisor QGIS Project Steering Committee


More information about the Qgis-developer mailing list