📄 plugin.cpp
字号:
/*************************************************************************** plugin.cpp Import tool for various worldmap analysis output filesFunctions:-------------------begin : Jan 21, 2004copyright : (C) 2004 by Tim Suttonemail : tim@linfiniti.com ***************************************************************************//*************************************************************************** * * * 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 7982 2008-01-16 10:27:02Z homann $ */// includes#include "qgisinterface.h"#include "qgisgui.h"#include "qgscoordinatetransform.h"#include "qgsmaplayer.h"#include "plugin.h"#include "qgsproject.h"#include "qgslogger.h"#include "qgsmapcanvas.h"#include "qgsmaprender.h"#include "qgsapplication.h"// qt includes#include <QPainter>#include <QMenu>#include <QDir>//non qt includes#include <iostream>#include <cmath>#include <cassert>//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))#endif//static const char * const ident_ = "$Id: plugin.cpp 7982 2008-01-16 10:27:02Z homann $";static const QString name_ = QObject::tr("NorthArrow");static const QString description_ = QObject::tr("Displays a north arrow overlayed onto the map");static const QString version_ = QObject::tr("Version 0.1");static const QgisPlugin::PLUGINTYPE type_ = QgisPlugin::UI;const double QgsNorthArrowPlugin::PI = 3.14159265358979323846;// const double QgsNorthArrowPlugin::DEG2RAD = 0.0174532925199433;const double QgsNorthArrowPlugin::TOL = 1e-8;/** * 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 */QgsNorthArrowPlugin::QgsNorthArrowPlugin(QgisInterface * theQgisInterFace): QgisPlugin(name_,description_,version_,type_), qGisInterface(theQgisInterFace){ mRotationInt=0; mAutomatic=true; mPlacementLabels << tr("Bottom Left") << tr("Top Left") << tr("Top Right") << tr("Bottom Right");}QgsNorthArrowPlugin::~QgsNorthArrowPlugin(){} /* * Initialize the GUI interface for the plugin */void QgsNorthArrowPlugin::initGui(){ // Create the action for tool myQActionPointer = new QAction(QIcon(icon), tr("&North Arrow"), this); myQActionPointer->setWhatsThis(tr("Creates a north arrow that is displayed on the map canvas")); // Connect the action to the run connect(myQActionPointer, SIGNAL(activated()), this, SLOT(run())); //render the arrow each time the map is rendered connect(qGisInterface->getMapCanvas(), SIGNAL(renderComplete(QPainter *)), this, SLOT(renderNorthArrow(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 & appropriate menu qGisInterface->addToolBarIcon(myQActionPointer); qGisInterface->addPluginMenu(tr("&Decorations"), myQActionPointer); projectRead(); refreshCanvas();}void QgsNorthArrowPlugin::projectRead(){ QgsDebugMsg("+++++++++ north arrow plugin - project read slot called...."); //default text to start with - try to fetch it from qgsproject mRotationInt = QgsProject::instance()->readNumEntry("NorthArrow","/Rotation",0); mPlacementIndex = QgsProject::instance()->readNumEntry("NorthArrow","/Placement",0); mEnable = QgsProject::instance()->readBoolEntry("NorthArrow","/Enabled",true); mAutomatic = QgsProject::instance()->readBoolEntry("NorthArrow","/Automatic",true);}//method defined in interfacevoid QgsNorthArrowPlugin::help(){ //implement me!}// Slot called when the buffer menu item is activatedvoid QgsNorthArrowPlugin::run(){ QgsNorthArrowPluginGui *myPluginGui = new QgsNorthArrowPluginGui(qGisInterface->getMainWindow(), QgisGui::ModalDialogFlags); myPluginGui->setAttribute(Qt::WA_DeleteOnClose); //overides function by the same name created in .ui myPluginGui->setRotation(mRotationInt); myPluginGui->setPlacementLabels(mPlacementLabels); myPluginGui->setPlacement(mPlacementIndex); myPluginGui->setEnabled(mEnable); myPluginGui->setAutomatic(mAutomatic); //listen for when the layer has been made so we can draw it connect(myPluginGui, SIGNAL(rotationChanged(int)), this, SLOT(rotationChanged(int))); connect(myPluginGui, SIGNAL(changePlacement(int)), this, SLOT(setPlacement(int))); connect(myPluginGui, SIGNAL(enableAutomatic(bool)), this, SLOT(setAutomatic(bool))); connect(myPluginGui, SIGNAL(enableNorthArrow(bool)), this, SLOT(setEnabled(bool))); connect(myPluginGui, SIGNAL(needToRefresh()), this, SLOT(refreshCanvas())); myPluginGui->show();}//! Refresh the map display using the mapcanvas exported via the plugin interfacevoid QgsNorthArrowPlugin::refreshCanvas(){ qGisInterface->getMapCanvas()->refresh();}void QgsNorthArrowPlugin::renderNorthArrow(QPainter * theQPainter){ //Large IF statement controlled by enable check box if (mEnable) { if (theQPainter->isActive()) { QgsDebugMsg("Rendering north arrow on active painter"); } else { QgsDebugMsg("Rendering north arrow on INactive painter!!!"); } QPixmap myQPixmap; //to store the north arrow image in QString myFileNameQString = QDir::cleanPath( QgsApplication::pkgDataPath() + "/images/north_arrows/default.png" ); QgsDebugMsg("Trying to load " + myFileNameQString); if (myQPixmap.load(myFileNameQString)) { double centerXDouble = myQPixmap.width()/2; double centerYDouble = myQPixmap.height()/2; //save the current canvas rotation theQPainter->save(); // //work out how to shift the image so that it rotates // properly about its center //(x cos a + y sin a - x, -x sin a + y cos a - y) // // could move this call to somewhere else so that it is only // called when the projection or map extent changes if (mAutomatic) calculateNorthDirection(); double myRadiansDouble = mRotationInt * PI / 180.0; int xShift = static_cast<int>(( (centerXDouble * cos(myRadiansDouble)) + (centerYDouble * sin(myRadiansDouble)) ) - centerXDouble); int yShift = static_cast<int>(( (-centerXDouble * sin(myRadiansDouble)) + (centerYDouble * cos(myRadiansDouble)) ) - centerYDouble); // need width/height of paint device int myHeight = theQPainter->device()->height(); int myWidth = theQPainter->device()->width(); QgsDebugMsg("Rendering north arrow at " + mPlacementLabels.at(mPlacementIndex)); //Determine placement of label from form combo box switch (mPlacementIndex) { case 0: // Bottom Left theQPainter->translate(0,myHeight-myQPixmap.height()); break; case 1: // Top Left //no need to translate for TL corner because we're already at the origin theQPainter->translate(0, 0); break; case 2: // Top Right theQPainter->translate(myWidth-myQPixmap.width(),0); break; case 3: // Bottom Right theQPainter->translate(myWidth-myQPixmap.width(), myHeight-myQPixmap.height()); break; default: QgsDebugMsg("Unable to determine where to put north arrow so defaulting to top left"); } //rotate the canvas by the north arrow rotation amount theQPainter->rotate( mRotationInt ); //Now we can actually do the drawing, and draw a smooth north arrow even when rotated theQPainter->setRenderHint(QPainter::SmoothPixmapTransform); theQPainter->drawPixmap(xShift,yShift,myQPixmap); //unrotate the canvas again theQPainter->restore(); } else { QFont myQFont("time", 12, QFont::Bold); theQPainter->setFont(myQFont); theQPainter->setPen(Qt::black); theQPainter->drawText(10, 20, QString(tr("North arrow pixmap not found"))); } }}// Unload the plugin by cleaning up the GUIvoid QgsNorthArrowPlugin::unload(){ // remove the GUI qGisInterface->removePluginMenu(tr("&Decorations"), myQActionPointer); qGisInterface->removeToolBarIcon(myQActionPointer); // remove the northarrow from the canvas disconnect(qGisInterface->getMapCanvas(), SIGNAL(renderComplete(QPainter *)), this, SLOT(renderNorthArrow(QPainter *))); refreshCanvas(); delete myQActionPointer;}void QgsNorthArrowPlugin::rotationChanged(int theInt){ mRotationInt = theInt; QgsProject::instance()->writeEntry("NorthArrow","/Rotation", mRotationInt );}//! set placement of north arrowvoid QgsNorthArrowPlugin::setPlacement(int placementIndex){ mPlacementIndex = placementIndex; QgsProject::instance()->writeEntry("NorthArrow","/Placement", mPlacementIndex);}void QgsNorthArrowPlugin::setEnabled(bool theBool){ mEnable = theBool; QgsProject::instance()->writeEntry("NorthArrow","/Enabled", mEnable );}void QgsNorthArrowPlugin::setAutomatic(bool theBool){ mAutomatic = theBool; QgsProject::instance()->writeEntry("NorthArrow","/Automatic", mAutomatic ); if (mAutomatic) calculateNorthDirection();}bool QgsNorthArrowPlugin::calculateNorthDirection(){ QgsMapCanvas& mapCanvas = *(qGisInterface->getMapCanvas()); bool goodDirn = false; if (mapCanvas.layerCount() > 0) { QgsSpatialRefSys outputSRS = mapCanvas.mapRender()->destinationSrs(); if (outputSRS.isValid() && !outputSRS.geographicFlag()) { // Use a geographic SRS to get lat/long to work out direction QgsSpatialRefSys ourSRS; ourSRS.createFromProj4("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"); assert(ourSRS.isValid()); QgsCoordinateTransform transform(outputSRS, ourSRS); QgsRect extent = mapCanvas.extent(); QgsPoint p1(extent.center()); // A point a bit above p1. XXX assumes that y increases up!! // May need to involve the maptopixel transform if this proves // to be a problem. QgsPoint p2(p1.x(), p1.y() + extent.height() * 0.25); // project p1 and p2 to geographic coords try { p1 = transform.transform(p1); p2 = transform.transform(p2); } catch (QgsException &e) { UNUSED(e); // just give up QgsDebugMsg("Transformation error, quitting"); return false; } // Work out the value of the initial heading one takes to go // from point p1 to point p2. The north direction is then that // many degrees anti-clockwise or vertical. // Take some care to not divide by zero, etc, and ensure that we // get sensible results for all possible values for p1 and p2. goodDirn = true; double angle = 0.0; // convert to radians for the equations below p1.multiply(PI/180.0); p2.multiply(PI/180.0); double y = sin(p2.x() - p1.x()) * cos(p2.y()); double x = cos(p1.y()) * sin(p2.y()) - sin(p1.y()) * cos(p2.y()) * cos(p2.x()-p1.x()); if (y > 0.0) { if (x > TOL) angle = atan(y/x); else if (x < -TOL) angle = PI - atan(-y/x); else angle = 0.5 * PI; } else if (y < 0.0) { if (x > TOL) angle = -atan(-y/x); else if (x < -TOL) angle = atan(y/x) - PI; else angle = 1.5 * PI; } else { if (x > TOL) angle = 0.0; else if (x < -TOL) angle = PI; else { angle = 0.0; // p1 = p2 goodDirn = false; } } // And set the angle of the north arrow. Perhaps do something // different if goodDirn = false. mRotationInt = static_cast<int>(round(fmod(360.0-angle*180.0/PI, 360.0))); } else { // For geographic SRS and for when there are no layers, set the // direction back to the default mRotationInt = 0; } } return goodDirn;}/** * Required extern functions needed for every plugin * These functions can be called prior to creating an instance * of the plugin class */// Class factory to return a new instance of the plugin classQGISEXTERN QgisPlugin * classFactory(QgisInterface * theQgisInterfacePointer){ return new QgsNorthArrowPlugin(theQgisInterfacePointer);}// Return the name of the plugin - note that we do not user class members as// the class may not yet be insantiated when this method is called.QGISEXTERN QString name(){ return name_;}// Return the descriptionQGISEXTERN QString description(){ return description_;}// Return the type (either UI or MapLayer plugin)QGISEXTERN int type(){ return type_;}// Return the version number for the pluginQGISEXTERN QString version(){ return version_;}// Delete ourselfQGISEXTERN void unload(QgisPlugin * thePluginPointer){ delete thePluginPointer;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -