📄 plugin.cpp
字号:
/*************************************************************************** plugin.cpp Plugin to draw scale bar on mapFunctions:-------------------begin : Jun 1, 2004copyright : (C) 2004 by Peter Breweremail : sbr00pwb@users.sourceforge.net ***************************************************************************//*************************************************************************** * * * 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. * * * ***************************************************************************//* $Id: plugin.cpp 7741 2007-12-07 13:32:47Z timlinux $ */// includes#include "qgisinterface.h"#include "qgisgui.h"#include "qgsmapcanvas.h"#include "qgsmaplayer.h"#include "qgsmaptopixel.h"#include "qgspoint.h"#include "qgsproject.h"#include "plugin.h"#include <QPainter>#include <QAction>#include <QPen>#include <QPolygon>#include <QString>#include <QFontMetrics>#include <QFont>#include <QColor>#include <QMenu>//non qt includes#include <iostream>#include <cmath>//the gui subclass#include "plugingui.h"// xpm for creating the toolbar icon#include "icon.xpm"//#ifdef _MSC_VER#define round(x) ((x) >= 0 ? floor((x)+0.5) : floor((x)-0.5))#endifstatic const char * const ident_ = "$Id: plugin.cpp 7741 2007-12-07 13:32:47Z timlinux $";static const QString name_ = QObject::tr("ScaleBar");static const QString description_ = QObject::tr("Draws a scale bar");static const QString version_ = QObject::tr("Version 0.1");static const QgisPlugin::PLUGINTYPE type_ = QgisPlugin::UI;/** * Constructor for the plugin. The plugin is passed a pointer to the main app * and an interface object that provides access to exposed functions in QGIS. * @param qgis Pointer to the QGIS main window * @param _qI Pointer to the QGIS interface object */QgsScaleBarPlugin::QgsScaleBarPlugin(QgisInterface * theQgisInterFace): QgisPlugin(name_,description_,version_,type_), qGisInterface(theQgisInterFace){ mPlacementLabels << tr("Bottom Left") << tr("Top Left") << tr("Top Right") << tr("Bottom Right"); mPlacementIndex = 1; mStyleLabels << tr("Tick Down") << tr("Tick Up") << tr("Bar") << tr("Box"); mPreferredSize = 30; mStyleIndex = 0; mEnabled = true; mSnapping = true; mColour = Qt::black;}QgsScaleBarPlugin::~QgsScaleBarPlugin(){}/* * Initialize the GUI interface for the plugin */void QgsScaleBarPlugin::initGui(){ // Create the action for tool myQActionPointer = new QAction(QIcon(icon), tr("&Scale Bar"), this); myQActionPointer->setWhatsThis(tr("Creates a scale bar that is displayed on the map canvas")); // Connect the action to the run connect(myQActionPointer, SIGNAL(activated()), this, SLOT(run())); //render the scale bar each time the map is rendered connect(qGisInterface->getMapCanvas(), SIGNAL(renderComplete(QPainter *)), this, SLOT(renderScaleBar(QPainter *))); //this resets this plugin up if a project is loaded connect(qGisInterface->getMainWindow(), SIGNAL(projectRead()), this, SLOT(projectRead())); // Add the icon to the toolbar qGisInterface->addToolBarIcon(myQActionPointer); qGisInterface->addPluginMenu(tr("&Decorations"), myQActionPointer);}void QgsScaleBarPlugin::projectRead(){#ifdef QGISDEBUG std::cout << "+++++++++ scalebar plugin - project read slot called...." << std::endl;#endif //default text to start with - try to fetch it from qgsproject mPreferredSize = QgsProject::instance()->readNumEntry("ScaleBar","/PreferredSize",30); mStyleIndex = QgsProject::instance()->readNumEntry("ScaleBar","/Style",0); mPlacementIndex = QgsProject::instance()->readNumEntry("ScaleBar","/Placement",2); mEnabled = QgsProject::instance()->readBoolEntry("ScaleBar","/Enabled",true); mSnapping = QgsProject::instance()->readBoolEntry("ScaleBar","/Snapping",true); int myRedInt = QgsProject::instance()->readNumEntry("ScaleBar","/ColorRedPart",0); int myGreenInt = QgsProject::instance()->readNumEntry("ScaleBar","/ColorGreenPart",0); int myBlueInt = QgsProject::instance()->readNumEntry("ScaleBar","/ColorBluePart",0); mColour = QColor(myRedInt,myGreenInt,myBlueInt);}//method defined in interfacevoid QgsScaleBarPlugin::help(){ //implement me!}// Slot called when the menu item is activatedvoid QgsScaleBarPlugin::run(){ QgsScaleBarPluginGui *myPluginGui=new QgsScaleBarPluginGui(qGisInterface->getMainWindow(), QgisGui::ModalDialogFlags); myPluginGui->setAttribute(Qt::WA_DeleteOnClose); myPluginGui->setPreferredSize(mPreferredSize); myPluginGui->setSnapping(mSnapping); myPluginGui->setPlacementLabels(mPlacementLabels); myPluginGui->setPlacement(mPlacementIndex); myPluginGui->setEnabled(mEnabled); myPluginGui->setStyleLabels(mStyleLabels); myPluginGui->setStyle(mStyleIndex); myPluginGui->setColour(mColour); connect(myPluginGui, SIGNAL(changePreferredSize(int)), this, SLOT(setPreferredSize(int))); connect(myPluginGui, SIGNAL(changeSnapping(bool)), this, SLOT(setSnapping(bool))); connect(myPluginGui, SIGNAL(changePlacement(int)), this, SLOT(setPlacement(int))); connect(myPluginGui, SIGNAL(changeEnabled(bool)), this, SLOT(setEnabled(bool))); connect(myPluginGui, SIGNAL(changeStyle(int)), this, SLOT(setStyle(int))); connect(myPluginGui, SIGNAL(changeColour(QColor)), this, SLOT(setColour(QColor))); connect(myPluginGui, SIGNAL(refreshCanvas()), this, SLOT(refreshCanvas())); myPluginGui->show(); //set the map units in the spin box int myUnits=qGisInterface->getMapCanvas()->mapUnits(); switch (myUnits) { case 0: myPluginGui->getSpinSize()->setSuffix(tr(" metres/km")); break; case 1: myPluginGui->getSpinSize()->setSuffix(tr(" feet/miles")); break; case 2: myPluginGui->getSpinSize()->setSuffix(tr(" degrees")); break; default: std::cout << "Error: not picked up map units - actual value = " << myUnits << std::endl; };}void QgsScaleBarPlugin::refreshCanvas(){ qGisInterface->getMapCanvas()->refresh();}// Actual drawing of Scale Barvoid QgsScaleBarPlugin::renderScaleBar(QPainter * theQPainter){ int myBufferSize=1; //softcode this later //Get canvas dimensions int myCanvasHeight = theQPainter->device()->height(); int myCanvasWidth = theQPainter->device()->width(); //Get map units per pixel. This can be negative at times (to do with //projections) and that just confuses the rest of the code in this //function, so force to a positive number. double myMuppDouble = std::abs(qGisInterface->getMapCanvas()->mupp()); // Exit if the canvas width is 0 or layercount is 0 or QGIS will freeze int myLayerCount=qGisInterface->getMapCanvas()->layerCount(); if (!myLayerCount || !myCanvasWidth || !myMuppDouble) return; //Large if statement which determines whether to render the scale bar if (mEnabled) { // Hard coded sizes int myMajorTickSize=8; int myTextOffsetX=3; double myActualSize=mPreferredSize; int myMargin=20; //Calculate size of scale bar for preferred number of map units double myScaleBarWidth = mPreferredSize / myMuppDouble; //If scale bar is very small reset to 1/4 of the canvas wide if (myScaleBarWidth < 30) { myScaleBarWidth = myCanvasWidth / 4; // pixels myActualSize = myScaleBarWidth * myMuppDouble; // map units }; //if scale bar is more than half the canvas wide keep halving until not while (myScaleBarWidth > myCanvasWidth/3) { myScaleBarWidth = myScaleBarWidth /3; }; myActualSize = myScaleBarWidth * myMuppDouble; // Work out the exponent for the number - e.g, 1234 will give 3, // and .001234 will give -3 double myPowerOf10 = floor(log10(myActualSize)); // snap to integer < 10 times power of 10 if (mSnapping) { double scaler = pow(10.0, myPowerOf10); myActualSize = round(myActualSize / scaler) * scaler; myScaleBarWidth = myActualSize / myMuppDouble; } //Get type of map units and set scale bar unit label text QGis::units myMapUnits=qGisInterface->getMapCanvas()->mapUnits(); QString myScaleBarUnitLabel; switch (myMapUnits) { case QGis::METERS: if (myActualSize > 1000.0) { myScaleBarUnitLabel=tr(" km"); myActualSize = myActualSize/1000; } else if (myActualSize < 0.01) { myScaleBarUnitLabel=tr(" mm"); myActualSize = myActualSize*1000; } else if (myActualSize < 0.1) { myScaleBarUnitLabel=tr(" cm"); myActualSize = myActualSize*100; } else myScaleBarUnitLabel=tr(" m"); break; case QGis::FEET: if (myActualSize > 5280.0) //5280 feet to the mile { myScaleBarUnitLabel=tr(" miles"); myActualSize = myActualSize/5280; } else if (myActualSize == 5280.0) //5280 feet to the mile { myScaleBarUnitLabel=tr(" mile"); myActualSize = myActualSize/5280; } else if (myActualSize < 1) { myScaleBarUnitLabel=tr(" inches"); myActualSize = myActualSize*12; } else if (myActualSize == 1.0) { myScaleBarUnitLabel=tr(" foot"); } else { myScaleBarUnitLabel=tr(" feet"); } break; case QGis::DEGREES: if (myActualSize == 1.0) myScaleBarUnitLabel=tr(" degree"); else myScaleBarUnitLabel=tr(" degrees"); break; case QGis::UNKNOWN: myScaleBarUnitLabel=tr(" unknown"); default: std::cout << "Error: not picked up map units - actual value = " << myMapUnits << std::endl; }; //Set font and calculate width of unit label int myFontSize = 10; //we use this later for buffering QFont myFont( "helvetica", myFontSize ); theQPainter->setFont(myFont); QFontMetrics myFontMetrics( myFont ); double myFontWidth = myFontMetrics.width( myScaleBarUnitLabel ); double myFontHeight = myFontMetrics.height(); //Set the maximum label QString myScaleBarMaxLabel=QString::number(myActualSize); //Calculate total width of scale bar and label double myTotalScaleBarWidth = myScaleBarWidth + myFontWidth; //determine the origin of scale bar depending on placement selected int myOriginX=myMargin; int myOriginY=myMargin; switch (mPlacementIndex) { case 0: // Bottom Left myOriginX=myMargin; myOriginY=myCanvasHeight - myMargin; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -