AW: [Qgis-developer] Re: composer redesign branch

Hugentobler Marco marco.hugentobler at karto.baug.ethz.ch
Sun Mar 9 10:49:58 EDT 2008


Hi Steven,

>Just to clarify, QGraphicsScene by itself doesn't have any particular
>units.  The composer treats scene units as millimeters, but I don't think
>there's anything special about millimeters in particular.

Ah, ok.
Then it would probably make sense that the main map does the same as the composer? Then everything in QGIS would be mm and hopefully no problems with differen line widths any more.

>I'm a little confused as to why you wouldn't put the units in QgsSymbol.  I
>see it as an attribute just like size or color.  In theory, we might want a
>uniqueValueRenderer which renders different objects with different scale
>types.  This seems harder to do if a higher-level class is doing the
>scaling.

Looking at the code in the composer branch (see code snipsets below), it seems to me that the only different behaviour of a renderer according to the symbol scale type is that scalefactor is used for PAPER_UNITS and MAP_UNITS and not for PIXELS. Is this correct?
Therefore I was thinking that there is some redundancy between SymbolScaleType and scale factor, as scale factor 1 would mean pixel and scale factor != 1 PAPER_UNITS or MAP_UNITS. 
Ok, the rendering of different scale types in one map is not possible without the scale unit. Tough I don't think it is desirable in many cases. Anyway, it is just one member variable and probably a detail.

Regards,
Marco


from QgsSymbol.h
typedef enum {PIXELS, PAPER_UNITS, MAP_UNITS} SymbolScaleType;

from QgsSingleSymbolRenderer.cpp
void QgsSingleSymbolRenderer::renderFeature(QPainter * p, QgsFeature & f, QgsSymbolRenderer*& renderer,
           double* scalefactor, bool selected, double mupp)//was double widthScale
{
...
if(mSymbol->scaleType() == QgsSymbol::PIXELS){
        *scalefactor = (double)mSymbol->pointSize();
      }
      else{
        *scalefactor = (double)mSymbol->pointSize()/mupp;
      }



-----Ursprüngliche Nachricht-----
Von: Steven Bell [mailto:botsnlinux at gmail.com]
Gesendet: Fr 07.03.2008 15:53
An: Hugentobler  Marco
Cc: qgis-developer at lists.osgeo.org
Betreff: Re: [Qgis-developer] Re: composer redesign branch
 
Just to clarify, QGraphicsScene by itself doesn't have any particular
units.  The composer treats scene units as millimeters, but I don't think
there's anything special about millimeters in particular.
I'm a little confused as to why you wouldn't put the units in QgsSymbol.  I
see it as an attribute just like size or color.  In theory, we might want a
uniqueValueRenderer which renders different objects with different scale
types.  This seems harder to do if a higher-level class is doing the
scaling.
Steven

On Fri, Mar 7, 2008 at 2:46 AM, Marco Hugentobler <
marco.hugentobler at karto.baug.ethz.ch> wrote:

> 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