⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qgscomposermap.cpp

📁 一个非常好的GIS开源新版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************                         qgscomposermap.cpp                             -------------------    begin                : January 2005    copyright            : (C) 2005 by Radim Blazek    email                : blazek@itc.it ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************/#include "qgscomposermap.h"#include "qgscoordinatetransform.h"#include "qgsmapcanvas.h"#include "qgsmaplayer.h"#include "qgsmaptopixel.h"#include "qgsproject.h"#include "qgsmaprender.h"#include "qgsvectorlayer.h"#include "qgslabel.h"#include "qgslabelattributes.h"#include <QGraphicsScene>#include <QGraphicsRectItem>#include <QPainter>#include <iostream>#include <cmath>// round isn't defined by default in msvc#ifdef _MSC_VER #define round(x)  ((x) >= 0 ? floor((x)+0.5) : floor((x)-0.5))#endifQgsComposerMap::QgsComposerMap ( QgsComposition *composition, int id, int x, int y, int width, int height )    : QWidget(), QGraphicsRectItem(0,0,width,height,0){std::cout << "QgsComposerMap::QgsComposerMap()" << std::endl;    setupUi(this);    mComposition = composition;    mId = id;    mMapCanvas = mComposition->mapCanvas();    mName = QString(tr("Map %1").arg(mId));    init();    recalculate();    // Add to scene    mComposition->canvas()->addItem(this);    QGraphicsRectItem::setPos(x, y);    QGraphicsRectItem::show();    writeSettings();}QgsComposerMap::QgsComposerMap ( QgsComposition *composition, int id )    : QGraphicsRectItem(0,0,10,10,0){    setupUi(this);    mComposition = composition;    mId = id;    mMapCanvas = mComposition->mapCanvas();    mName = QString(tr("Map %1").arg(mId));    init();    readSettings();    recalculate();    // Add to scene    mComposition->canvas()->addItem(this);    QGraphicsRectItem::show();}void QgsComposerMap::init (){    mNumCachedLayers = 0;    mSelected = false;    mUserExtent = mMapCanvas->extent();    mDrawing = false;    // Cache    mCacheUpdated = false;    // Calculate    mCalculateComboBox->insertItem( tr("Extent (calculate scale)"), Scale );    mCalculateComboBox->insertItem( tr("Scale (calculate extent)"), Extent );    mCalculate = Scale;    setPlotStyle ( QgsComposition::Preview );        // Preview style    mPreviewMode = Cache;    mPreviewModeComboBox->insertItem ( tr("Cache"), Cache );    mPreviewModeComboBox->insertItem ( tr("Render"), Render );    mPreviewModeComboBox->insertItem ( tr("Rectangle"), Rectangle );    mPreviewModeComboBox->setCurrentItem ( Cache );    mWidthScale = 1.0 / mComposition->scale();    mSymbolScale = 0.5;    mFontScale = 1.0;    mFrame = true;    QGraphicsRectItem::setZValue(20);    connect ( mMapCanvas, SIGNAL(layersChanged()), this, SLOT(mapCanvasChanged()) );}QgsComposerMap::~QgsComposerMap(){     std::cerr << "QgsComposerMap::~QgsComposerMap" << std::endl;}/* This function is called by paint() and cache() to render the map.  It does not override any functionsfrom QGraphicsItem. */void QgsComposerMap::draw ( QPainter *painter, QgsRect &extent, QgsMapToPixel *transform){  mMapCanvas->freeze(true);  // necessary ?  int nlayers = mMapCanvas->layerCount();    QgsCoordinateTransform* ct;  for ( int i = nlayers - 1; i >= 0; i-- ) {    QgsMapLayer *layer = mMapCanvas->getZpos(i);    //if ( !layer->visible() ) continue;    if (mMapCanvas->projectionsEnabled())    {      ct = new QgsCoordinateTransform(layer->srs(), mMapCanvas->mapRender()->destinationSrs());    }    else    {      ct = NULL;    }    if ( layer->type() == QgsMapLayer::VECTOR ) {      QgsVectorLayer *vector = dynamic_cast <QgsVectorLayer*> (layer);      double widthScale = mWidthScale;      double symbolScale = mSymbolScale;//TODO: attempt to scale cache lines and point symbols to be larger as we zoom in/*    if(creating cache pixmap)      {        widthScale *= (cachePixmap.width / map.rect.width);        symbolScale *= (cachePixmap.width / map.rect.width);      }*/      QgsRect r1, r2;      r1 = extent;      // TODO: revisit later and make this QgsMapRender-aware [MD]      // bool split = layer->projectExtent(r1, r2);      bool split = false;            vector->draw( painter, r1, transform, ct, FALSE, widthScale, symbolScale);      if ( split )      {        vector->draw( painter, r2, transform, ct, FALSE, widthScale, symbolScale);      }    } else {       // raster      if ( plotStyle() == QgsComposition::Print || plotStyle() == QgsComposition::Postscript ) {        // we have to rescale the raster to get requested resolution                      // calculate relation between composition point size and requested resolution (in mm)        double multip = (1. / mComposition->scale()) / (25.4 / mComposition->resolution()) ;                      double sc = mExtent.width() / (multip*QGraphicsRectItem::rect().width());                      QgsMapToPixel trans ( sc, multip*QGraphicsRectItem::rect().height(), mExtent.yMin(), mExtent.xMin() );                      painter->save();        painter->scale( 1./multip, 1./multip);        layer->draw( painter, extent, &trans, ct, FALSE);                      painter->restore();      }       else       {        layer->draw( painter, extent, transform, ct, FALSE);      }    }        delete ct;  }      // Draw vector labels  for ( int i = nlayers - 1; i >= 0; i-- ) {    QgsMapLayer *layer = mMapCanvas->getZpos(i);    if (mMapCanvas->projectionsEnabled())    {      ct = new QgsCoordinateTransform(layer->srs(), mMapCanvas->mapRender()->destinationSrs());    }    else    {      ct = NULL;    }//    if ( !layer->visible() ) continue; //this doesn't work with the newer map layer code    if ( layer->type() == QgsMapLayer::VECTOR ) {      QgsVectorLayer *vector = dynamic_cast <QgsVectorLayer*> (layer);      if ( vector->labelOn() ) {        double fontScale = 25.4 * mFontScale * mComposition->scale() / 72;        if ( plotStyle() == QgsComposition::Postscript )         {          //fontScale = QgsComposition::psFontScaleFactor() * 72.0 / mComposition->resolution();          // TODO          // This is not completely correct because fonts written to postscript          // should use size metrics.ascent() * 72.0 / mComposition->resolution();          // We could add a factor for metrics.ascent()/size but it is variable          // Add a parrameter in drawLables() ?          QFont tempFont;          tempFont.setFamily(vector->label()->layerAttributes()->family());          double size = vector->label()->layerAttributes()->size();          size = 25.4 * size / 72;          tempFont.setPointSizeF(size);          QFontMetricsF tempMetrics(tempFont);          fontScale = tempMetrics.ascent() * 72.0 / mComposition->resolution();          //std::cout << "fontScale: " << fontScale << std::endl;          fontScale *= mFontScale;          //divide out the font size, since it will be multiplied back in when drawing the labels          fontScale /= vector->label()->layerAttributes()->size();        }        vector->drawLabels (  painter, extent, transform, ct, fontScale );      }          delete ct;    }  }      mMapCanvas->freeze(false);}void QgsComposerMap::setUserExtent ( QgsRect const & rect ){    mUserExtent = rect;    recalculate();        QGraphicsRectItem::update();    QGraphicsRectItem::scene()->update();}void QgsComposerMap::cache ( void ){    std::cout << "QgsComposerMap::cache()" << std::endl;    // Create preview on some reasonable size. It was slow with cca 1500x1500 points on 2x1.5GHz     // Note: The resolution should also respect the line widths, it means that     //       1 pixel in cache should have ia similar size as 1 pixel in canvas    //       but it can result in big cache -> limit    int w = (int)(QGraphicsRectItem::rect().width() * mComposition->viewScale());    w = w < 1000 ? w : 1000; //limit the cache pixmap to 1000 pixels wide    int h = (int) ( mExtent.height() * w / mExtent.width() );    // It can happen that extent is not initialised well -> check     if ( h < 1 || h > 10000 ) h = w;     std::cout << "extent = " << mExtent.width() <<  " x " << mExtent.height() << std::endl;    std::cout << "cache = " << w <<  " x " << h << std::endl;    mCacheExtent = QgsRect ( mExtent );    double scale = mExtent.width() / w;    mCacheExtent.setXmax ( mCacheExtent.xMin() + w * scale );    mCacheExtent.setYmax ( mCacheExtent.yMin() + h * scale );          mCachePixmap.resize( w, h );    // WARNING: ymax in QgsMapToPixel is device height!!!    QgsMapToPixel transform(scale, h, mCacheExtent.yMin(), mCacheExtent.xMin() );//somthing about this transform isn't really what we want.../*Ideally, the cache pixmap wouldn't behave the same as the map canvas.* zooming in should make the lines become thicker, and symbols larger, rather than just* redrawing them to be n pixels wide.* We also want to make sure that changing the composition's resolution has the desired effect * on both the cache, screen render, and print.*/    std::cout << "transform = " << transform.showParameters().toLocal8Bit().data() << std::endl;        mCachePixmap.fill(QColor(255,255,255));    QPainter p(&mCachePixmap);        draw( &p, mCacheExtent, &transform);    p.end();    mNumCachedLayers = mMapCanvas->layerCount();    mCacheUpdated = true;}void QgsComposerMap::paint ( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget){  if ( mDrawing ) return;   mDrawing = true;  std::cout << "QgsComposerMapt::paint mPlotStyle = " << plotStyle()             << " mPreviewMode = " << mPreviewMode << std::endl;      if ( plotStyle() == QgsComposition::Preview &&  mPreviewMode == Cache ) { // Draw from cache    std::cout << "use cache" << std::endl;    if ( !mCacheUpdated || mMapCanvas->layerCount() != mNumCachedLayers )     {      cache();    }      // Scale so that the cache fills the map rectangle    double scale = 1.0 * QGraphicsRectItem::rect().width() / mCachePixmap.width();    std::cout << "scale = " << scale << std::endl;      painter->save();    painter->translate(0, 0); //do we need this?    painter->scale(scale,scale);    // Note: drawing only a visible part of the pixmap doesn't make it much faster    painter->drawPixmap(0,0, mCachePixmap);    painter->restore();  }   else if ( (plotStyle() == QgsComposition::Preview && mPreviewMode == Render) ||             plotStyle() == QgsComposition::Print ||            plotStyle() == QgsComposition::Postscript )   {    std::cout << "render" << std::endl;      double scale = mExtent.width() / QGraphicsRectItem::rect().width();    QgsMapToPixel transform(scale, QGraphicsRectItem::rect().height(), mExtent.yMin(), mExtent.xMin() );    painter->save();    painter->translate(0, 0); //do we need this?    // TODO: Qt4 appears to force QPainter::CoordDevice - need to check if this is actually valid.    painter->setClipRect (QRectF( 0, 0, QGraphicsRectItem::rect().width(), QGraphicsRectItem::rect().height() ));    draw( painter, mExtent, &transform);    painter->restore();  }   // Draw frame around  if ( mFrame ) {    QPen pen(QColor(0,0,0));    pen.setWidthF(0.6*mComposition->scale());    painter->setPen( pen );    painter->setBrush( Qt::NoBrush );    painter->setRenderHint(QPainter::Antialiasing, true); //turn on antialiasing for drawing the box    painter->save();    painter->translate(0, 0);//do we need this?    painter->drawRect (QRectF( 0, 0, QGraphicsRectItem::rect().width(), QGraphicsRectItem::rect().height() ));    painter->restore();  }  // Show selected / Highlight  if ( mSelected && plotStyle() == QgsComposition::Preview ) {    painter->setPen( mComposition->selectionPen() );    painter->setBrush( mComposition->selectionBrush() );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -