Merge pull request #3126 from manisandro/globe
Revived globe, compatible with OsgEarth 2.7
@ -96,6 +96,9 @@ FIND_OSGEARTH_LIBRARY( OSGEARTHSYMBOLOGY_LIBRARY_DEBUG osgEarthSymbologyd )
|
||||
FIND_OSGEARTH_LIBRARY( OSGEARTHQT_LIBRARY osgEarthQt )
|
||||
FIND_OSGEARTH_LIBRARY( OSGEARTHQT_LIBRARY_DEBUG osgEarthQtd )
|
||||
|
||||
FIND_OSGEARTH_LIBRARY( OSGEARTHANNOTATION_LIBRARY osgEarthAnnotation )
|
||||
FIND_OSGEARTH_LIBRARY( OSGEARTHANNOTATION_LIBRARY_DEBUG osgEarthAnnotationd )
|
||||
|
||||
|
||||
SET( OSGEARTH_FOUND "NO" )
|
||||
IF( OSGEARTH_LIBRARY AND OSGEARTH_INCLUDE_DIR )
|
||||
|
@ -522,6 +522,7 @@
|
||||
<file>themes/default/symbologyRemove.svg</file>
|
||||
<file>themes/default/symbologyUp.png</file>
|
||||
<file>themes/default/symbologyUp.svg</file>
|
||||
<file>themes/default/sync_views.svg</file>
|
||||
<file>themes/default/text.png</file>
|
||||
<file>themes/default/tracking.png</file>
|
||||
<file>themes/default/transformed.png</file>
|
||||
|
151
images/themes/default/sync_views.svg
Normal file
@ -0,0 +1,151 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="sync_views.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4158">
|
||||
<stop
|
||||
style="stop-color:#0000ff;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4160" />
|
||||
<stop
|
||||
style="stop-color:#0000a9;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4162" />
|
||||
</linearGradient>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Mend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Mend"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4171"
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.6) rotate(180) translate(0,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Mend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Mend-8"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4171-2"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="scale(-0.6,-0.6)" />
|
||||
</marker>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4158"
|
||||
id="radialGradient4178"
|
||||
cx="7.9999766"
|
||||
cy="1040.8622"
|
||||
fx="7.9999766"
|
||||
fy="1040.8622"
|
||||
r="6.9999766"
|
||||
gradientTransform="matrix(1,0,0,0.49999621,0,520.43504)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4158"
|
||||
id="radialGradient4178-3"
|
||||
cx="7.9999766"
|
||||
cy="1040.8622"
|
||||
fx="7.9999766"
|
||||
fy="1040.8622"
|
||||
r="6.9999766"
|
||||
gradientTransform="matrix(-1,0,0,0.49999621,16,527.43502)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="18.5"
|
||||
inkscape:cx="0.59568033"
|
||||
inkscape:cy="10.721345"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:snap-bbox-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="829"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4136" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1036.3622)">
|
||||
<g
|
||||
id="g4865">
|
||||
<path
|
||||
style="fill:url(#radialGradient4178);fill-opacity:1;fill-rule:evenodd;stroke:#0000a9;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 1.5,1040.8622 0,1 8,0 0,2 5,-3 -5,-3 0,2 -8,0 z"
|
||||
id="path4156"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccc" />
|
||||
<path
|
||||
style="fill:url(#radialGradient4178-3);fill-opacity:1;fill-rule:evenodd;stroke:#0000a9;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 14.5,1047.8622 0,1 -7.9999996,0 0,2 -5,-3 5,-3 0,2 7.9999996,0 z"
|
||||
id="path4156-7"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccc" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.0 KiB |
@ -24,6 +24,7 @@
|
||||
%Include qgsaggregatecalculator.sip
|
||||
%Include qgsattributeaction.sip
|
||||
%Include qgsattributetableconfig.sip
|
||||
%Include qgsbillboardregistry.sip
|
||||
%Include qgsbrowsermodel.sip
|
||||
%Include qgsclipper.sip
|
||||
%Include qgscolorscheme.sip
|
||||
@ -103,6 +104,7 @@
|
||||
%Include qgsowsconnection.sip
|
||||
%Include qgspaintenginehack.sip
|
||||
%Include qgspallabeling.sip
|
||||
%Include qgsplugininterface.sip
|
||||
%Include qgspluginlayer.sip
|
||||
%Include qgspluginlayerregistry.sip
|
||||
%Include qgspoint.sip
|
||||
|
56
python/core/qgsbillboardregistry.sip
Normal file
@ -0,0 +1,56 @@
|
||||
/** Billboard items stored in the QgsBillBoardRegistry */
|
||||
class QgsBillBoardItem
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <qgsbillboardregistry.h>
|
||||
%End
|
||||
public:
|
||||
QImage image; /* The image of the billboard */
|
||||
QgsPoint worldPos; /* The WGS84 world position of the billboard */
|
||||
QString layerId; /* The layer which the image is part of, if any */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The QgsBillBoardRegistry class stores images which should
|
||||
* be displayed as billboards in the globe plugin.
|
||||
* Map canvas items and layers may decide to add items which should
|
||||
* be drawn as billboards in the globe.
|
||||
*
|
||||
* Retreive the instance pointer to a QgsBillBoardRegistry for a
|
||||
* project via QgsProject::instance()->billboardRegistry().
|
||||
*/
|
||||
class QgsBillBoardRegistry : public QObject
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <qgsbillboardregistry.h>
|
||||
%End
|
||||
public:
|
||||
/**
|
||||
* @brief Adds a billboard to the registry
|
||||
* @param parent The parent (i.e. a QgsMapLayer or a QgsMapCanvasItem) which is creating the billboard
|
||||
* @param image The billboard image
|
||||
* @param worldPos The geo position of the image, in WGS84
|
||||
* @param layerId The id of the layer to which the item belongs, if any
|
||||
*/
|
||||
void addItem( void* parent, const QImage& image, const QgsPoint& worldPos, const QString& layerId = QString() );
|
||||
/**
|
||||
* @brief Removes all billboards which were created by the specified parent
|
||||
* @param parent The parent
|
||||
*/
|
||||
void removeItem( void* parent );
|
||||
|
||||
/**
|
||||
* @brief Retreive all registered billboard items
|
||||
* @return List of registered billboard items
|
||||
*/
|
||||
QList<QgsBillBoardItem*> items() const;
|
||||
|
||||
signals:
|
||||
/** Emitted when an item is added to the registry */
|
||||
void itemAdded( QgsBillBoardItem* item );
|
||||
/** Emitted when an item is removed from the registry */
|
||||
void itemRemoved( QgsBillBoardItem* item );
|
||||
|
||||
private:
|
||||
QgsBillBoardRegistry( QObject* parent = 0 );
|
||||
};
|
@ -66,6 +66,11 @@ class QgsMapSettings
|
||||
//! @note added in 2.8
|
||||
void setLayerStyleOverrides( const QMap<QString, QString>& overrides );
|
||||
|
||||
//! Get custom rendering flags, separated by ';'. Layers might honour these to alter their rendering.
|
||||
const QString& customRenderFlags() const;
|
||||
//! Set custom rendering flags, separated by ';'. Layers might honour these to alter their rendering.
|
||||
void setCustomRenderFlags( const QString& customRenderFlags );
|
||||
|
||||
//! sets whether to use projections for this layer set
|
||||
void setCrsTransformEnabled( bool enabled );
|
||||
//! returns true if projections are enabled for this layer set
|
||||
|
28
python/core/qgsplugininterface.sip
Normal file
@ -0,0 +1,28 @@
|
||||
/***************************************************************************
|
||||
qgsplugininterface.sip
|
||||
--------------------------------------
|
||||
Date : 21.8.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Trivial base class for plugin interfaces
|
||||
*/
|
||||
class QgsPluginInterface : QObject
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include "qgsplugininterface.h"
|
||||
%End
|
||||
|
||||
protected:
|
||||
/** Should only be instantiated from subclasses */
|
||||
QgsPluginInterface( QObject* parent = 0 );
|
||||
};
|
@ -275,6 +275,11 @@ class QgsProject : QObject
|
||||
|
||||
QgsRelationManager* relationManager() const;
|
||||
|
||||
/** Return the project's billboard manager instance pointer
|
||||
* @note added in QGIS 2.16
|
||||
*/
|
||||
QgsBillBoardRegistry* billboardRegistry() const;
|
||||
|
||||
/** Return pointer to the root (invisible) node of the project's layer tree
|
||||
* @note added in 2.4
|
||||
*/
|
||||
|
@ -74,7 +74,7 @@ class QgsRectangle
|
||||
//! return true when rectangle contains a point
|
||||
bool contains( const QgsPoint &p ) const;
|
||||
//! expand the rectangle so that covers both the original rectangle and the given rectangle
|
||||
void combineExtentWith( QgsRectangle *rect );
|
||||
void combineExtentWith( const QgsRectangle& rect );
|
||||
//! expand the rectangle so that covers both the original rectangle and the given point
|
||||
void combineExtentWith( double x, double y );
|
||||
//! test if rectangle is empty.
|
||||
|
@ -102,6 +102,7 @@
|
||||
%Include qgsmaplayeractionregistry.sip
|
||||
%Include qgsmaplayercombobox.sip
|
||||
%Include qgsmaplayermodel.sip
|
||||
%Include qgsmaplayerpropertiesfactory.sip
|
||||
%Include qgsmaplayerproxymodel.sip
|
||||
%Include qgsmapmouseevent.sip
|
||||
%Include qgsmapoverviewcanvas.sip
|
||||
@ -155,6 +156,7 @@
|
||||
%Include qgsunitselectionwidget.sip
|
||||
%Include qgsuserinputdockwidget.sip
|
||||
%Include qgsvariableeditorwidget.sip
|
||||
%Include qgsvectorlayerpropertiespage.sip
|
||||
%Include qgsvectorlayertools.sip
|
||||
%Include qgsvertexmarker.sip
|
||||
|
||||
|
@ -279,6 +279,12 @@ class QgisInterface : QObject
|
||||
/** Unregister a previously registered action. (e.g. when plugin is going to be unloaded) */
|
||||
virtual bool unregisterMainWindowAction( QAction* action ) = 0;
|
||||
|
||||
/** Register a new tab in the vector layer properties dialog */
|
||||
virtual void registerMapLayerPropertiesFactory( QgsMapLayerPropertiesFactory* factory ) = 0;
|
||||
|
||||
/** Unregister a previously registered tab in the layer properties dialog */
|
||||
virtual void unregisterMapLayerPropertiesFactory( QgsMapLayerPropertiesFactory* factory ) = 0;
|
||||
|
||||
// @todo is this deprecated in favour of QgsContextHelp?
|
||||
/** Open a url in the users browser. By default the QGIS doc directory is used
|
||||
* as the base for the URL. To open a URL that is not relative to the installed
|
||||
|
32
python/gui/qgsmaplayerpropertiesfactory.sip
Normal file
@ -0,0 +1,32 @@
|
||||
/** \ingroup gui
|
||||
* \note added in 2.1
|
||||
*/
|
||||
class QgsMapLayerPropertiesFactory
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <qgsmaplayerpropertiesfactory.h>
|
||||
%End
|
||||
|
||||
public:
|
||||
/** Constructor */
|
||||
QgsMapLayerPropertiesFactory();
|
||||
|
||||
/** Destructor */
|
||||
virtual ~QgsMapLayerPropertiesFactory();
|
||||
|
||||
/**
|
||||
* @brief Create a new properties page
|
||||
* @param layer The layer for which to create the page
|
||||
* @param parent The parent widget
|
||||
* @return The new properties page instance
|
||||
*/
|
||||
virtual QgsVectorLayerPropertiesPage* createVectorLayerPropertiesPage( QgsVectorLayer* layer, QWidget* parent ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Creates the QListWidgetItem for the properties page
|
||||
* @param layer The layer for which to create the item
|
||||
* @param view The parent QListView
|
||||
* @return The QListWidgetItem for the properties page
|
||||
*/
|
||||
virtual QListWidgetItem* createVectorLayerPropertiesItem( QgsVectorLayer* layer, QListWidget* view ) = 0;
|
||||
};
|
21
python/gui/qgsvectorlayerpropertiespage.sip
Normal file
@ -0,0 +1,21 @@
|
||||
/** \ingroup gui
|
||||
* \note added in 2.1
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Base class for custom vector layer property pages
|
||||
*/
|
||||
class QgsVectorLayerPropertiesPage : QWidget
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <qgsvectorlayerpropertiespage.h>
|
||||
%End
|
||||
|
||||
public:
|
||||
/** Constructor */
|
||||
explicit QgsVectorLayerPropertiesPage( QWidget *parent = 0 );
|
||||
|
||||
public slots:
|
||||
/** Apply changes */
|
||||
virtual void apply() = 0;
|
||||
};
|
@ -8810,6 +8810,16 @@ void QgisApp::openURL( QString url, bool useQgisDocDirectory )
|
||||
#endif
|
||||
}
|
||||
|
||||
void QgisApp::registerMapLayerPropertiesFactory( QgsMapLayerPropertiesFactory* factory )
|
||||
{
|
||||
mMapLayerPropertiesFactories << factory;
|
||||
}
|
||||
|
||||
void QgisApp::unregisterMapLayerPropertiesFactory( QgsMapLayerPropertiesFactory* factory )
|
||||
{
|
||||
mMapLayerPropertiesFactories.removeAll( factory );
|
||||
}
|
||||
|
||||
/** Get a pointer to the currently selected map layer */
|
||||
QgsMapLayer *QgisApp::activeLayer()
|
||||
{
|
||||
@ -11021,6 +11031,10 @@ void QgisApp::showLayerProperties( QgsMapLayer *ml )
|
||||
#else
|
||||
QgsVectorLayerProperties *vlp = new QgsVectorLayerProperties( vlayer, this );
|
||||
#endif
|
||||
foreach ( QgsMapLayerPropertiesFactory* factory, mMapLayerPropertiesFactories )
|
||||
{
|
||||
vlp->addPropertiesPageFactory( factory );
|
||||
}
|
||||
|
||||
if ( vlp->exec() )
|
||||
{
|
||||
|
@ -56,6 +56,7 @@ class QgsLayerTreeMapCanvasBridge;
|
||||
class QgsLayerTreeView;
|
||||
class QgsMapCanvas;
|
||||
class QgsMapLayer;
|
||||
class QgsMapLayerPropertiesFactory;
|
||||
class QgsMapTip;
|
||||
class QgsMapTool;
|
||||
class QgsMapToolAdvancedDigitizing;
|
||||
@ -501,6 +502,12 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
|
||||
|
||||
void parseVersionInfo( QNetworkReply* reply, int& latestVersion, QStringList& versionInfo );
|
||||
|
||||
/** Register a new tab in the layer properties dialog */
|
||||
void registerMapLayerPropertiesFactory( QgsMapLayerPropertiesFactory* factory );
|
||||
|
||||
/** Unregister a previously registered tab in the layer properties dialog */
|
||||
void unregisterMapLayerPropertiesFactory( QgsMapLayerPropertiesFactory* factory );
|
||||
|
||||
public slots:
|
||||
void layerTreeViewDoubleClicked( const QModelIndex& index );
|
||||
//! Make sure the insertion point for new layers is up-to-date with the current item in layer tree view
|
||||
@ -1745,6 +1752,8 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
|
||||
|
||||
QgsSnappingUtils* mSnappingUtils;
|
||||
|
||||
QList<QgsMapLayerPropertiesFactory*> mMapLayerPropertiesFactories;
|
||||
|
||||
QDateTime mProjectLastModified;
|
||||
|
||||
QgsWelcomePage* mWelcomePage;
|
||||
|
@ -475,6 +475,16 @@ bool QgisAppInterface::unregisterMainWindowAction( QAction* action )
|
||||
return QgsShortcutsManager::instance()->unregisterAction( action );
|
||||
}
|
||||
|
||||
void QgisAppInterface::registerMapLayerPropertiesFactory( QgsMapLayerPropertiesFactory* factory )
|
||||
{
|
||||
qgis->registerMapLayerPropertiesFactory( factory );
|
||||
}
|
||||
|
||||
void QgisAppInterface::unregisterMapLayerPropertiesFactory( QgsMapLayerPropertiesFactory* factory )
|
||||
{
|
||||
qgis->unregisterMapLayerPropertiesFactory( factory );
|
||||
}
|
||||
|
||||
//! Menus
|
||||
Q_DECL_DEPRECATED QMenu *QgisAppInterface::fileMenu() { return qgis->projectMenu(); }
|
||||
QMenu *QgisAppInterface::projectMenu() { return qgis->projectMenu(); }
|
||||
|
@ -288,6 +288,12 @@ class APP_EXPORT QgisAppInterface : public QgisInterface
|
||||
/** Unregister a previously registered action. (e.g. when plugin is going to be unloaded. */
|
||||
virtual bool unregisterMainWindowAction( QAction* action ) override;
|
||||
|
||||
/** Register a new tab in the layer properties dialog */
|
||||
virtual void registerMapLayerPropertiesFactory( QgsMapLayerPropertiesFactory* factory ) override;
|
||||
|
||||
/** Unregister a previously registered tab in the layer properties dialog */
|
||||
virtual void unregisterMapLayerPropertiesFactory( QgsMapLayerPropertiesFactory* factory ) override;
|
||||
|
||||
/** Accessors for inserting items into menus and toolbars.
|
||||
* An item can be inserted before any existing action.
|
||||
*/
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "qgslabel.h"
|
||||
#include "qgsgenericprojectionselector.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsmaplayerpropertiesfactory.h"
|
||||
#include "qgsmaplayerregistry.h"
|
||||
#include "qgsmaplayerstyleguiutils.h"
|
||||
#include "qgspluginmetadata.h"
|
||||
@ -44,6 +45,7 @@
|
||||
#include "qgsloadstylefromdbdialog.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsvectorlayerproperties.h"
|
||||
#include "qgsvectorlayerpropertiespage.h"
|
||||
#include "qgsconfig.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
#include "qgsquerybuilder.h"
|
||||
@ -323,6 +325,19 @@ void QgsVectorLayerProperties::setLabelCheckBox()
|
||||
labelCheckBox->setCheckState( Qt::Checked );
|
||||
}
|
||||
|
||||
void QgsVectorLayerProperties::addPropertiesPageFactory( QgsMapLayerPropertiesFactory* factory )
|
||||
{
|
||||
QListWidgetItem* item = factory->createVectorLayerPropertiesItem( mLayer, mOptionsListWidget );
|
||||
if ( item )
|
||||
{
|
||||
mOptionsListWidget->addItem( item );
|
||||
|
||||
QgsVectorLayerPropertiesPage* page = factory->createVectorLayerPropertiesPage( mLayer, this );
|
||||
mLayerPropertiesPages << page;
|
||||
mOptionsStackedWidget->addWidget( page );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsVectorLayerProperties::insertField()
|
||||
{
|
||||
// Convert the selected field to an expression and
|
||||
@ -606,6 +621,12 @@ void QgsVectorLayerProperties::apply()
|
||||
//apply diagram settings
|
||||
diagramPropertiesDialog->apply();
|
||||
|
||||
// apply all plugin dialogs
|
||||
foreach ( QgsVectorLayerPropertiesPage* page, mLayerPropertiesPages )
|
||||
{
|
||||
page->apply();
|
||||
}
|
||||
|
||||
//layer title and abstract
|
||||
mLayer->setShortName( mLayerShortNameLineEdit->text() );
|
||||
mLayer->setTitle( mLayerTitleLineEdit->text() );
|
||||
|
@ -42,6 +42,8 @@ class QgsLabelingWidget;
|
||||
class QgsDiagramProperties;
|
||||
class QgsFieldsProperties;
|
||||
class QgsRendererV2PropertiesDialog;
|
||||
class QgsMapLayerPropertiesFactory;
|
||||
class QgsVectorLayerPropertiesPage;
|
||||
|
||||
class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private Ui::QgsVectorLayerPropertiesBase
|
||||
{
|
||||
@ -74,6 +76,9 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
|
||||
@return false in case of a non-existing attribute.*/
|
||||
bool deleteAttribute( int attr );
|
||||
|
||||
/** Adds a properties page factory to the vector layer properties dialog. */
|
||||
void addPropertiesPageFactory( QgsMapLayerPropertiesFactory *factory );
|
||||
|
||||
public slots:
|
||||
|
||||
/** Insert a field in the expression text for the map tip **/
|
||||
@ -190,6 +195,9 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
|
||||
//! List of joins of a layer at the time of creation of the dialog. Used to return joins to previous state if dialog is cancelled
|
||||
QList< QgsVectorJoinInfo > mOldJoins;
|
||||
|
||||
//! A list of additional pages provided by plugins
|
||||
QList<QgsVectorLayerPropertiesPage*> mLayerPropertiesPages;
|
||||
|
||||
/** Previous layer style. Used to reset style to previous state if new style
|
||||
* was loaded but dialog is cancelled */
|
||||
QgsMapLayerStyle mOldStyle;
|
||||
|
@ -81,6 +81,7 @@ SET(QGIS_CORE_SRCS
|
||||
qgsactionmanager.cpp
|
||||
qgsaggregatecalculator.cpp
|
||||
qgsattributetableconfig.cpp
|
||||
qgsbillboardregistry.cpp
|
||||
qgsbrowsermodel.cpp
|
||||
qgscachedfeatureiterator.cpp
|
||||
qgscacheindex.cpp
|
||||
@ -167,6 +168,7 @@ SET(QGIS_CORE_SRCS
|
||||
qgspallabeling.cpp
|
||||
qgspluginlayer.cpp
|
||||
qgspluginlayerregistry.cpp
|
||||
qgsplugininterface.cpp
|
||||
qgspoint.cpp
|
||||
qgspointlocator.cpp
|
||||
qgsproject.cpp
|
||||
@ -449,6 +451,7 @@ ENDIF(NOT MSVC)
|
||||
|
||||
SET(QGIS_CORE_MOC_HDRS
|
||||
qgsapplication.h
|
||||
qgsbillboardregistry.h
|
||||
qgsbrowsermodel.h
|
||||
qgscontexthelp.h
|
||||
qgscoordinatetransform.h
|
||||
@ -479,6 +482,7 @@ SET(QGIS_CORE_MOC_HDRS
|
||||
qgsofflineediting.h
|
||||
qgsowsconnection.h
|
||||
qgspluginlayer.h
|
||||
qgsplugininterface.h
|
||||
qgspointlocator.h
|
||||
qgsproject.h
|
||||
qgsrelationmanager.h
|
||||
|
@ -3706,7 +3706,7 @@ QgsRectangle QgsDxfExport::dxfExtent() const
|
||||
else
|
||||
{
|
||||
QgsRectangle layerExtent = layerIt->first->extent();
|
||||
extent.combineExtentWith( &layerExtent );
|
||||
extent.combineExtentWith( layerExtent );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ QgsRectangle QgsCircularStringV2::calculateBoundingBox() const
|
||||
else
|
||||
{
|
||||
QgsRectangle segmentBox = segmentBoundingBox( QgsPointV2( mX[i], mY[i] ), QgsPointV2( mX[i + 1], mY[i + 1] ), QgsPointV2( mX[i + 2], mY[i + 2] ) );
|
||||
bbox.combineExtentWith( &segmentBox );
|
||||
bbox.combineExtentWith( segmentBox );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ QgsRectangle QgsCompoundCurveV2::calculateBoundingBox() const
|
||||
for ( int i = 1; i < mCurves.size(); ++i )
|
||||
{
|
||||
QgsRectangle curveBox = mCurves.at( i )->boundingBox();
|
||||
bbox.combineExtentWith( &curveBox );
|
||||
bbox.combineExtentWith( curveBox );
|
||||
}
|
||||
return bbox;
|
||||
}
|
||||
|
@ -336,7 +336,7 @@ QgsRectangle QgsGeometryCollectionV2::calculateBoundingBox() const
|
||||
for ( int i = 1; i < mGeometries.size(); ++i )
|
||||
{
|
||||
QgsRectangle geomBox = mGeometries.at( i )->boundingBox();
|
||||
bbox.combineExtentWith( &geomBox );
|
||||
bbox.combineExtentWith( geomBox );
|
||||
}
|
||||
return bbox;
|
||||
}
|
||||
|
42
src/core/qgsbillboardregistry.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
/***************************************************************************
|
||||
qgsbillboardregistry.cpp
|
||||
------------------------
|
||||
begin : February 2016
|
||||
copyright : (C) 2016 by Sandro Mani
|
||||
email : smani@sourcepole.ch
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* 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 "qgsbillboardregistry.h"
|
||||
|
||||
void QgsBillBoardRegistry::addItem( void* parent, const QImage &image, const QgsPoint &worldPos , const QString &layerId )
|
||||
{
|
||||
QMap<void*, QgsBillBoardItem*>::iterator it = mItems.find( parent );
|
||||
if ( it == mItems.end() )
|
||||
{
|
||||
it = mItems.insert( parent, new QgsBillBoardItem );
|
||||
}
|
||||
it.value()->image = image;
|
||||
it.value()->worldPos = worldPos;
|
||||
it.value()->layerId = layerId;
|
||||
emit itemAdded( it.value() );
|
||||
}
|
||||
|
||||
void QgsBillBoardRegistry::removeItem( void* parent )
|
||||
{
|
||||
emit itemRemoved( mItems[parent] );
|
||||
delete mItems.take( parent );
|
||||
}
|
||||
|
||||
QList<QgsBillBoardItem*> QgsBillBoardRegistry::items() const
|
||||
{
|
||||
return mItems.values();
|
||||
}
|
82
src/core/qgsbillboardregistry.h
Normal file
@ -0,0 +1,82 @@
|
||||
/***************************************************************************
|
||||
qgsbillboardregistry.h
|
||||
----------------------
|
||||
begin : February 2016
|
||||
copyright : (C) 2016 by Sandro Mani
|
||||
email : smani@sourcepole.ch
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSBILLBOARDREGISTRY_H
|
||||
#define QGSBILLBOARDREGISTRY_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QImage>
|
||||
#include "qgspoint.h"
|
||||
|
||||
class QgsMapCanvasItem;
|
||||
|
||||
/** Billboard items stored in the QgsBillBoardRegistry */
|
||||
class CORE_EXPORT QgsBillBoardItem
|
||||
{
|
||||
public:
|
||||
QImage image; /* The image of the billboard */
|
||||
QgsPoint worldPos; /* The WGS84 world position of the billboard */
|
||||
QString layerId; /* The layer which the image is part of, if any */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The QgsBillBoardRegistry class stores images which should
|
||||
* be displayed as billboards in the globe plugin.
|
||||
* Map canvas items and layers may decide to add items which should
|
||||
* be drawn as billboards in the globe.
|
||||
*
|
||||
* Retreive the instance pointer to a QgsBillBoardRegistry for a
|
||||
* project via QgsProject::instance()->billboardRegistry().
|
||||
*/
|
||||
class CORE_EXPORT QgsBillBoardRegistry : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* @brief Adds a billboard to the registry
|
||||
* @param parent The parent (i.e. a QgsMapLayer or a QgsMapCanvasItem) which is creating the billboard
|
||||
* @param image The billboard image
|
||||
* @param worldPos The geo position of the image, in WGS84
|
||||
* @param layerId The id of the layer to which the item belongs, if any
|
||||
*/
|
||||
void addItem( void* parent, const QImage& image, const QgsPoint& worldPos, const QString& layerId = QString() );
|
||||
/**
|
||||
* @brief Removes all billboards which were created by the specified parent
|
||||
* @param parent The parent
|
||||
*/
|
||||
void removeItem( void* parent );
|
||||
|
||||
/**
|
||||
* @brief Retreive all registered billboard items
|
||||
* @return List of registered billboard items
|
||||
*/
|
||||
QList<QgsBillBoardItem*> items() const;
|
||||
|
||||
signals:
|
||||
/** Emitted when an item is added to the registry */
|
||||
void itemAdded( QgsBillBoardItem* item );
|
||||
/** Emitted when an item is removed from the registry */
|
||||
void itemRemoved( QgsBillBoardItem* item );
|
||||
|
||||
private:
|
||||
friend class QgsProject; // Only QgsProject is allowed to construct this class
|
||||
QgsBillBoardRegistry( QObject* parent = 0 ) : QObject( parent ) {}
|
||||
|
||||
QMap<void*, QgsBillBoardItem*> mItems;
|
||||
};
|
||||
|
||||
#endif // QGSBILLBOARDREGISTRY_H
|
@ -114,6 +114,11 @@ class CORE_EXPORT QgsMapSettings
|
||||
//! @note added in 2.8
|
||||
void setLayerStyleOverrides( const QMap<QString, QString>& overrides );
|
||||
|
||||
//! Get custom rendering flags, separated by ';'. Layers might honour these to alter their rendering.
|
||||
const QString& customRenderFlags() const { return mCustomRenderFlags; }
|
||||
//! Set custom rendering flags, separated by ';'. Layers might honour these to alter their rendering.
|
||||
void setCustomRenderFlags( const QString& customRenderFlags ) { mCustomRenderFlags = customRenderFlags; }
|
||||
|
||||
//! sets whether to use projections for this layer set
|
||||
void setCrsTransformEnabled( bool enabled );
|
||||
//! returns true if projections are enabled for this layer set
|
||||
@ -290,6 +295,7 @@ class CORE_EXPORT QgsMapSettings
|
||||
|
||||
QStringList mLayers;
|
||||
QMap<QString, QString> mLayerStyleOverrides;
|
||||
QString mCustomRenderFlags;
|
||||
QgsExpressionContext mExpressionContext;
|
||||
|
||||
bool mProjectionsEnabled;
|
||||
|
0
src/core/qgsplugininterface.cpp
Normal file
33
src/core/qgsplugininterface.h
Normal file
@ -0,0 +1,33 @@
|
||||
/***************************************************************************
|
||||
qgsplugininterface.h
|
||||
--------------------------------------
|
||||
Date : 21.8.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSPLUGININTERFACE_H
|
||||
#define QGSPLUGININTERFACE_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
/**
|
||||
* @brief Trivial base class for plugin interfaces
|
||||
*/
|
||||
class CORE_EXPORT QgsPluginInterface : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
/** Should only be instantiated from subclasses */
|
||||
QgsPluginInterface( QObject* parent = 0 ) : QObject( parent ) {}
|
||||
};
|
||||
|
||||
#endif // QGSPLUGININTERFACE_H
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "qgsproject.h"
|
||||
|
||||
#include "qgsbillboardregistry.h"
|
||||
#include "qgsdatasourceuri.h"
|
||||
#include "qgsexception.h"
|
||||
#include "qgslayertree.h"
|
||||
@ -361,6 +362,7 @@ QgsProject::QgsProject()
|
||||
, mBadLayerHandler( new QgsProjectBadLayerDefaultHandler() )
|
||||
, mRelationManager( new QgsRelationManager( this ) )
|
||||
, mRootGroup( new QgsLayerTreeGroup )
|
||||
, mBillboardRegistry( new QgsBillBoardRegistry( this ) )
|
||||
{
|
||||
clear();
|
||||
|
||||
|
@ -41,6 +41,7 @@ class QDomDocument;
|
||||
class QDomElement;
|
||||
class QDomNode;
|
||||
|
||||
class QgsBillBoardRegistry;
|
||||
class QgsLayerTreeGroup;
|
||||
class QgsLayerTreeRegistryBridge;
|
||||
class QgsMapLayer;
|
||||
@ -323,6 +324,11 @@ class CORE_EXPORT QgsProject : public QObject
|
||||
|
||||
QgsRelationManager* relationManager() const;
|
||||
|
||||
/** Return the project's billboard manager instance pointer
|
||||
* @note added in QGIS 2.16
|
||||
*/
|
||||
QgsBillBoardRegistry* billboardRegistry() const { return mBillboardRegistry; }
|
||||
|
||||
/** Return pointer to the root (invisible) node of the project's layer tree
|
||||
* @note added in 2.4
|
||||
*/
|
||||
@ -487,6 +493,8 @@ class CORE_EXPORT QgsProject : public QObject
|
||||
|
||||
QgsLayerTreeRegistryBridge* mLayerTreeRegistryBridge;
|
||||
|
||||
QgsBillBoardRegistry* mBillboardRegistry;
|
||||
|
||||
//! map of transaction group: QPair( providerKey, connString ) -> transactionGroup
|
||||
QMap< QPair< QString, QString>, QgsTransactionGroup*> mTransactionGroups;
|
||||
|
||||
|
@ -194,14 +194,14 @@ bool QgsRectangle::contains( const QgsPoint &p ) const
|
||||
ymin <= p.y() && p.y() <= ymax;
|
||||
}
|
||||
|
||||
void QgsRectangle::combineExtentWith( QgsRectangle * rect )
|
||||
void QgsRectangle::combineExtentWith( const QgsRectangle &rect )
|
||||
{
|
||||
|
||||
xmin = (( xmin < rect->xMinimum() ) ? xmin : rect->xMinimum() );
|
||||
xmax = (( xmax > rect->xMaximum() ) ? xmax : rect->xMaximum() );
|
||||
xmin = (( xmin < rect.xMinimum() ) ? xmin : rect.xMinimum() );
|
||||
xmax = (( xmax > rect.xMaximum() ) ? xmax : rect.xMaximum() );
|
||||
|
||||
ymin = (( ymin < rect->yMinimum() ) ? ymin : rect->yMinimum() );
|
||||
ymax = (( ymax > rect->yMaximum() ) ? ymax : rect->yMaximum() );
|
||||
ymin = (( ymin < rect.yMinimum() ) ? ymin : rect.yMinimum() );
|
||||
ymax = (( ymax > rect.yMaximum() ) ? ymax : rect.yMaximum() );
|
||||
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ class CORE_EXPORT QgsRectangle
|
||||
//! return true when rectangle contains a point
|
||||
bool contains( const QgsPoint &p ) const;
|
||||
//! expand the rectangle so that covers both the original rectangle and the given rectangle
|
||||
void combineExtentWith( QgsRectangle *rect );
|
||||
void combineExtentWith( const QgsRectangle& rect );
|
||||
//! expand the rectangle so that covers both the original rectangle and the given point
|
||||
void combineExtentWith( double x, double y );
|
||||
//! test if rectangle is empty.
|
||||
|
@ -717,7 +717,7 @@ QgsRectangle QgsVectorLayer::boundingBoxOfSelected()
|
||||
if ( !fet.constGeometry() || fet.constGeometry()->isEmpty() )
|
||||
continue;
|
||||
r = fet.constGeometry()->boundingBox();
|
||||
retval.combineExtentWith( &r );
|
||||
retval.combineExtentWith( r );
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -732,7 +732,7 @@ QgsRectangle QgsVectorLayer::boundingBoxOfSelected()
|
||||
if ( fet.constGeometry() )
|
||||
{
|
||||
r = fet.constGeometry()->boundingBox();
|
||||
retval.combineExtentWith( &r );
|
||||
retval.combineExtentWith( r );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1000,7 +1000,7 @@ QgsRectangle QgsVectorLayer::extent()
|
||||
if ( mDataProvider->featureCount() != 0 )
|
||||
{
|
||||
QgsRectangle r = mDataProvider->extent();
|
||||
rect.combineExtentWith( &r );
|
||||
rect.combineExtentWith( r );
|
||||
}
|
||||
|
||||
if ( mEditBuffer )
|
||||
@ -1010,7 +1010,7 @@ QgsRectangle QgsVectorLayer::extent()
|
||||
if ( it->constGeometry() )
|
||||
{
|
||||
QgsRectangle r = it->constGeometry()->boundingBox();
|
||||
rect.combineExtentWith( &r );
|
||||
rect.combineExtentWith( r );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1026,7 +1026,7 @@ QgsRectangle QgsVectorLayer::extent()
|
||||
if ( fet.constGeometry() && fet.constGeometry()->type() != QGis::UnknownGeometry )
|
||||
{
|
||||
QgsRectangle bb = fet.constGeometry()->boundingBox();
|
||||
rect.combineExtentWith( &bb );
|
||||
rect.combineExtentWith( bb );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -239,6 +239,7 @@ SET(QGIS_GUI_SRCS
|
||||
qgsmaplayeractionregistry.cpp
|
||||
qgsmaplayercombobox.cpp
|
||||
qgsmaplayermodel.cpp
|
||||
qgsmaplayerpropertiesfactory.cpp
|
||||
qgsmaplayerproxymodel.cpp
|
||||
qgsmapmouseevent.cpp
|
||||
qgsmapoverviewcanvas.cpp
|
||||
@ -292,6 +293,7 @@ SET(QGIS_GUI_SRCS
|
||||
qgsunitselectionwidget.cpp
|
||||
qgsuserinputdockwidget.cpp
|
||||
qgsvariableeditorwidget.cpp
|
||||
qgsvectorlayerpropertiespage.cpp
|
||||
qgsvertexmarker.cpp
|
||||
)
|
||||
|
||||
@ -431,6 +433,7 @@ SET(QGIS_GUI_MOC_HDRS
|
||||
qgsunitselectionwidget.h
|
||||
qgsuserinputdockwidget.h
|
||||
qgsvariableeditorwidget.h
|
||||
qgsvectorlayerpropertiespage.h
|
||||
|
||||
raster/qgsmultibandcolorrendererwidget.h
|
||||
raster/qgspalettedrendererwidget.h
|
||||
|
@ -617,7 +617,7 @@ void QgsRelationReferenceWidget::highlightFeature( QgsFeature f, CanvasExtent ca
|
||||
QgsRectangle extent = mCanvas->extent();
|
||||
if ( !extent.contains( featBBox ) )
|
||||
{
|
||||
extent.combineExtentWith( &featBBox );
|
||||
extent.combineExtentWith( featBBox );
|
||||
extent.scale( 1.1 );
|
||||
mCanvas->setExtent( extent );
|
||||
mCanvas->refresh();
|
||||
|
@ -242,7 +242,7 @@ void QgsLayerTreeViewDefaultActions::zoomToLayers( QgsMapCanvas* canvas, const Q
|
||||
if ( canvas->hasCrsTransformEnabled() )
|
||||
layerExtent = canvas->mapSettings().layerExtentToOutputExtent( layer, layerExtent );
|
||||
|
||||
extent.combineExtentWith( &layerExtent );
|
||||
extent.combineExtentWith( layerExtent );
|
||||
}
|
||||
|
||||
if ( extent.isNull() )
|
||||
|
@ -34,6 +34,7 @@ class QgsLayerTreeView;
|
||||
class QgsLegendInterface;
|
||||
class QgsMapCanvas;
|
||||
class QgsMapLayer;
|
||||
class QgsMapLayerPropertiesFactory;
|
||||
class QgsMessageBar;
|
||||
class QgsPluginManagerInterface;
|
||||
class QgsRasterLayer;
|
||||
@ -328,6 +329,12 @@ class GUI_EXPORT QgisInterface : public QObject
|
||||
/** Unregister a previously registered action. (e.g. when plugin is going to be unloaded) */
|
||||
virtual bool unregisterMainWindowAction( QAction* action ) = 0;
|
||||
|
||||
/** Register a new tab in the vector layer properties dialog */
|
||||
virtual void registerMapLayerPropertiesFactory( QgsMapLayerPropertiesFactory* factory ) = 0;
|
||||
|
||||
/** Unregister a previously registered tab in the layer properties dialog */
|
||||
virtual void unregisterMapLayerPropertiesFactory( QgsMapLayerPropertiesFactory* factory ) = 0;
|
||||
|
||||
// @todo is this deprecated in favour of QgsContextHelp?
|
||||
/** Open a url in the users browser. By default the QGIS doc directory is used
|
||||
* as the base for the URL. To open a URL that is not relative to the installed
|
||||
|
@ -1177,7 +1177,7 @@ void QgsMapCanvas::zoomToFeatureIds( QgsVectorLayer* layer, const QgsFeatureIds&
|
||||
return;
|
||||
}
|
||||
QgsRectangle r = mapSettings().layerExtentToOutputExtent( layer, geom->boundingBox() );
|
||||
rect.combineExtentWith( &r );
|
||||
rect.combineExtentWith( r );
|
||||
featureCount++;
|
||||
}
|
||||
|
||||
|
24
src/gui/qgsmaplayerpropertiesfactory.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
/***************************************************************************
|
||||
qgslayeroptionsfactory.cpp
|
||||
--------------------------------------
|
||||
Date : 9.7.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 "qgsmaplayerpropertiesfactory.h"
|
||||
|
||||
QgsMapLayerPropertiesFactory::QgsMapLayerPropertiesFactory()
|
||||
{
|
||||
}
|
||||
|
||||
QgsMapLayerPropertiesFactory::~QgsMapLayerPropertiesFactory()
|
||||
{
|
||||
}
|
52
src/gui/qgsmaplayerpropertiesfactory.h
Normal file
@ -0,0 +1,52 @@
|
||||
/***************************************************************************
|
||||
qgslayeroptionsfactory.h
|
||||
--------------------------------------
|
||||
Date : 9.7.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSLAYERPROPERTIESFACTORY_H
|
||||
#define QGSLAYERPROPERTIESFACTORY_H
|
||||
|
||||
#include <QListWidgetItem>
|
||||
|
||||
#include "qgsvectorlayerpropertiespage.h"
|
||||
|
||||
/**
|
||||
* @brief Factory class for creating custom map layer property pages
|
||||
*/
|
||||
class GUI_EXPORT QgsMapLayerPropertiesFactory
|
||||
{
|
||||
public:
|
||||
/** Constructor */
|
||||
QgsMapLayerPropertiesFactory();
|
||||
|
||||
/** Destructor */
|
||||
virtual ~QgsMapLayerPropertiesFactory();
|
||||
|
||||
/**
|
||||
* @brief Create a new properties page
|
||||
* @param layer The layer for which to create the page
|
||||
* @param parent The parent widget
|
||||
* @return The new properties page instance
|
||||
*/
|
||||
virtual QgsVectorLayerPropertiesPage* createVectorLayerPropertiesPage( QgsVectorLayer* layer, QWidget* parent ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Creates the QListWidgetItem for the properties page
|
||||
* @param layer The layer for which to create the item
|
||||
* @param view The parent QListView
|
||||
* @return The QListWidgetItem for the properties page
|
||||
*/
|
||||
virtual QListWidgetItem* createVectorLayerPropertiesItem( QgsVectorLayer* layer, QListWidget* view ) = 0;
|
||||
};
|
||||
|
||||
#endif // QGSLAYERPROPERTIESFACTORY_H
|
@ -558,7 +558,7 @@ void QgsRubberBand::updateRect()
|
||||
}
|
||||
else
|
||||
{
|
||||
r.combineExtentWith( &rect );
|
||||
r.combineExtentWith( rect );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
22
src/gui/qgsvectorlayerpropertiespage.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
/***************************************************************************
|
||||
qgsvectorlayerpropertiespage.cpp
|
||||
--------------------------------------
|
||||
Date : 8.7.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 "qgsvectorlayerpropertiespage.h"
|
||||
|
||||
QgsVectorLayerPropertiesPage::QgsVectorLayerPropertiesPage( QWidget *parent ) :
|
||||
QWidget( parent )
|
||||
{
|
||||
}
|
||||
|
38
src/gui/qgsvectorlayerpropertiespage.h
Normal file
@ -0,0 +1,38 @@
|
||||
/***************************************************************************
|
||||
qgsvectorlayerpropertiespage.h
|
||||
--------------------------------------
|
||||
Date : 8.7.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSVECTORLAYERPROPERTIESPAGE_H
|
||||
#define QGSVECTORLAYERPROPERTIESPAGE_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QgsVectorLayer;
|
||||
|
||||
/**
|
||||
* @brief Base class for custom vector layer property pages
|
||||
*/
|
||||
class GUI_EXPORT QgsVectorLayerPropertiesPage : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/** Constructor */
|
||||
explicit QgsVectorLayerPropertiesPage( QWidget *parent = 0 );
|
||||
|
||||
public slots:
|
||||
/** Apply changes */
|
||||
virtual void apply() = 0;
|
||||
};
|
||||
|
||||
#endif // QGSVECTORLAYERPROPERTIESPAGE_H
|
@ -1,102 +1,103 @@
|
||||
# set path to additional CMake modules
|
||||
SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules ${CMAKE_MODULE_PATH})
|
||||
IF (KEEP_GLOBE_CXX_FLAGS)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_OLD}")
|
||||
ENDIF()
|
||||
|
||||
FIND_PACKAGE(OSG REQUIRED)
|
||||
FIND_PACKAGE(OSGEARTH REQUIRED)
|
||||
FIND_PACKAGE(Threads)
|
||||
IF(QT5_BUILD)
|
||||
FIND_PACKAGE(Qt5OpenGL REQUIRED)
|
||||
ENDIF(QT5_BUILD)
|
||||
|
||||
IF(HAVE_OSGEARTH_CHILD_SPACING)
|
||||
ADD_DEFINITIONS(-DHAVE_OSGEARTH_CHILD_SPACING)
|
||||
ENDIF(HAVE_OSGEARTH_CHILD_SPACING)
|
||||
|
||||
IF(OSGEARTH_ELEVATION_QUERY)
|
||||
ADD_DEFINITIONS(-DHAVE_OSGEARTH_ELEVATION_QUERY)
|
||||
ENDIF(OSGEARTH_ELEVATION_QUERY)
|
||||
|
||||
########################################################
|
||||
# Files
|
||||
|
||||
SET (globe_plugin_SRCS
|
||||
globe_plugin.cpp
|
||||
qgsosgearthtilesource.cpp
|
||||
globe_plugin_dialog.cpp
|
||||
)
|
||||
IF (NOT HAVE_OSGEARTHQT)
|
||||
SET(globe_plugin_SRCS
|
||||
${globe_plugin_SRCS}
|
||||
osgEarthQt/ViewerWidget.cpp
|
||||
osgEarthUtil/Controls.cpp
|
||||
)
|
||||
ENDIF (NOT HAVE_OSGEARTHQT)
|
||||
|
||||
SET (globe_plugin_UIS
|
||||
globe_plugin_dialog_guibase.ui
|
||||
)
|
||||
|
||||
SET (globe_plugin_MOC_HDRS
|
||||
globe_plugin.h
|
||||
globe_plugin_dialog.h
|
||||
SET (GLOBE_PLUGIN_SRCS
|
||||
globe_plugin.cpp
|
||||
qgsglobetilesource.cpp
|
||||
qgsglobeplugindialog.cpp
|
||||
qgsglobeinterface.cpp
|
||||
qgsglobevectorlayerproperties.cpp
|
||||
qgsglobefeatureidentify.cpp
|
||||
qgsglobefrustumhighlight.cpp
|
||||
qgsglobewidget.cpp
|
||||
)
|
||||
|
||||
SET (globe_plugin_RCCS globe_plugin.qrc)
|
||||
SET (GLOBE_PLUGIN_UIS
|
||||
qgsglobeplugindialog.ui
|
||||
qgsglobevectorlayerpropertiespage.ui
|
||||
)
|
||||
|
||||
SET (GLOBE_PLUGIN_MOC_HDRS
|
||||
globe_plugin.h
|
||||
qgsglobeplugindialog.h
|
||||
qgsglobeinterface.h
|
||||
qgsglobevectorlayerproperties.h
|
||||
qgsglobetilesource.h
|
||||
qgsglobewidget.h
|
||||
)
|
||||
|
||||
SET (GLOBE_PLUGIN_HDRS
|
||||
qgsglobeinterface.h
|
||||
qgsglobevectorlayerproperties.h
|
||||
qgsglobefeatureidentify.h
|
||||
qgsglobefrustumhighlight.h
|
||||
)
|
||||
|
||||
SET (GLOBE_PLUGIN_RCCS globe_plugin.qrc)
|
||||
|
||||
########################################################
|
||||
# Build
|
||||
|
||||
QT4_WRAP_UI (globe_plugin_UIS_H ${globe_plugin_UIS})
|
||||
IF(WIN32)
|
||||
ADD_DEFINITIONS("\"-DGLOBE_EXPORT=${DLLEXPORT}\"")
|
||||
ELSE(WIN32)
|
||||
ADD_DEFINITIONS("-DGLOBE_EXPORT=")
|
||||
ENDIF(WIN32)
|
||||
|
||||
QT4_WRAP_CPP (globe_plugin_MOC_SRCS ${globe_plugin_MOC_HDRS})
|
||||
QT4_WRAP_UI (GLOBE_PLUGIN_UIS_H ${GLOBE_PLUGIN_UIS})
|
||||
|
||||
QT4_ADD_RESOURCES(globe_plugin_RCC_SRCS ${globe_plugin_RCCS})
|
||||
QT4_WRAP_CPP (GLOBE_PLUGIN_MOC_SRCS ${GLOBE_PLUGIN_MOC_HDRS})
|
||||
|
||||
ADD_LIBRARY (globeplugin MODULE ${globe_plugin_SRCS} ${globe_plugin_MOC_SRCS} ${globe_plugin_RCC_SRCS} ${globe_plugin_UIS_H})
|
||||
QT4_ADD_RESOURCES(GLOBE_PLUGIN_RCC_SRCS ${GLOBE_PLUGIN_RCCS})
|
||||
|
||||
INCLUDE_DIRECTORIES(SYSTEM
|
||||
${Qt5OpenGL_INCLUDE_DIRS}
|
||||
${OSGEARTH_INCLUDE_DIR}
|
||||
${OSG_INCLUDE_DIR}
|
||||
${GEOS_INCLUDE_DIR}
|
||||
)
|
||||
ADD_LIBRARY (globeplugin SHARED ${GLOBE_PLUGIN_SRCS} ${GLOBE_PLUGIN_MOC_SRCS} ${GLOBE_PLUGIN_RCC_SRCS} ${GLOBE_PLUGIN_UIS_H} ${GLOBE_PLUGIN_HDRS})
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
../../core ../../core/geometry ../../core/raster
|
||||
${OSGEARTH_INCLUDE_DIR}
|
||||
${OSG_INCLUDE_DIR}
|
||||
${GEOS_INCLUDE_DIR}
|
||||
${SIP_INCLUDE_DIR}
|
||||
../../core
|
||||
../../core/geometry
|
||||
../../core/raster
|
||||
../../core/symbology-ng
|
||||
../../gui
|
||||
..
|
||||
)
|
||||
|
||||
SET (OSGEARTH_LIBS
|
||||
${OSGEARTH_LIBRARY}
|
||||
${OSGEARTHFEATURES_LIBRARY}
|
||||
${OSGEARTHUTIL_LIBRARY}
|
||||
)
|
||||
IF (HAVE_OSGEARTHQT)
|
||||
SET(OSGEARTH_LIBS
|
||||
${OSGEARTH_LIBS}
|
||||
${OSGEARTHQT_LIBRARY}
|
||||
)
|
||||
ENDIF (HAVE_OSGEARTHQT)
|
||||
TARGET_LINK_LIBRARIES(globeplugin
|
||||
qgis_core
|
||||
qgis_gui
|
||||
${QT_QTOPENGL_LIBRARY}
|
||||
${Qt5OpenGL_LIBRARIES}
|
||||
${OSGDB_LIBRARY}
|
||||
${OSGGA_LIBRARY}
|
||||
${OSGUTIL_LIBRARY}
|
||||
${OSG_LIBRARY}
|
||||
${OSGQT_LIBRARY}
|
||||
${OSGVIEWER_LIBRARY}
|
||||
${OSGEARTH_LIBS}
|
||||
${OSGEARTH_LIBRARY}
|
||||
${OSGEARTHANNOTATION_LIBRARY}
|
||||
${OSGEARTHFEATURES_LIBRARY}
|
||||
${OSGEARTHUTIL_LIBRARY}
|
||||
${OSGEARTHSYMBOLOGY_LIBRARY}
|
||||
${OSGEARTHQT_LIBRARY}
|
||||
${OPENTHREADS_LIBRARY}
|
||||
)
|
||||
|
||||
IF (WITH_BINDINGS)
|
||||
# Restore default CXX flags (without visibility=hidden, which breaks python bindings)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_OLD}")
|
||||
ADD_SUBDIRECTORY(python)
|
||||
ENDIF (WITH_BINDINGS)
|
||||
ADD_SUBDIRECTORY(featuresource)
|
||||
|
||||
########################################################
|
||||
# Install
|
||||
|
@ -0,0 +1,11 @@
|
||||
# Required Vars:
|
||||
# ${LIB_NAME}
|
||||
# ${LIB_PUBLIC_HEADERS}
|
||||
|
||||
SET(INSTALL_INCDIR include)
|
||||
|
||||
# FIXME: Do not run for OS X framework
|
||||
INSTALL(
|
||||
FILES ${LIB_PUBLIC_HEADERS}
|
||||
DESTINATION ${INSTALL_INCDIR}/osgEarthDrivers/${LIB_NAME}
|
||||
)
|
361
src/plugins/globe/CMakeModules/OsgEarthMacroUtils.cmake
Normal file
@ -0,0 +1,361 @@
|
||||
#######################################################################################################
|
||||
# macro to detect osg version and setup variables accordingly
|
||||
#######################################################################################################
|
||||
MACRO(DETECT_OSG_VERSION)
|
||||
|
||||
OPTION(APPEND_OPENSCENEGRAPH_VERSION "Append the OSG version number to the osgPlugins directory" ON)
|
||||
|
||||
# detect if osgversion can be found
|
||||
FIND_PROGRAM(OSG_VERSION_EXE NAMES osgversion)
|
||||
IF(OSG_VERSION_EXE AND NOT OPENSCENEGRAPH_MAJOR_VERSION AND NOT OPENSCENEGRAPH_MINOR_VERSION AND NOT OPENSCENEGRAPH_PATCH_VERSION)
|
||||
#MESSAGE("OSGVERSION IS AT ${OSG_VERSION_EXE}")
|
||||
# get parameters out of the osgversion
|
||||
EXECUTE_PROCESS(COMMAND ${OSG_VERSION_EXE} --major-number OUTPUT_VARIABLE OPENSCENEGRAPH_MAJOR_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
EXECUTE_PROCESS(COMMAND ${OSG_VERSION_EXE} --minor-number OUTPUT_VARIABLE OPENSCENEGRAPH_MINOR_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
EXECUTE_PROCESS(COMMAND ${OSG_VERSION_EXE} --patch-number OUTPUT_VARIABLE OPENSCENEGRAPH_PATCH_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
EXECUTE_PROCESS(COMMAND ${OSG_VERSION_EXE} Matrix::value_type OUTPUT_VARIABLE OSG_USE_FLOAT_MATRIX OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
EXECUTE_PROCESS(COMMAND ${OSG_VERSION_EXE} Plane::value_type OUTPUT_VARIABLE OSG_USE_FLOAT_PLANE OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
EXECUTE_PROCESS(COMMAND ${OSG_VERSION_EXE} BoundingSphere::value_type OUTPUT_VARIABLE OSG_USE_FLOAT_BOUNDINGSPHERE OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
EXECUTE_PROCESS(COMMAND ${OSG_VERSION_EXE} BoundingBox::value_type OUTPUT_VARIABLE OSG_USE_FLOAT_BOUNDINGBOX OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
# setup version numbers if we have osgversion
|
||||
SET(OPENSCENEGRAPH_MAJOR_VERSION "${OPENSCENEGRAPH_MAJOR_VERSION}" CACHE STRING "OpenSceneGraph major version number")
|
||||
SET(OPENSCENEGRAPH_MINOR_VERSION "${OPENSCENEGRAPH_MINOR_VERSION}" CACHE STRING "OpenSceneGraph minor version number")
|
||||
SET(OPENSCENEGRAPH_PATCH_VERSION "${OPENSCENEGRAPH_PATCH_VERSION}" CACHE STRING "OpenSceneGraph patch version number")
|
||||
SET(OPENSCENEGRAPH_SOVERSION "${OPENSCENEGRAPH_SOVERSION}" CACHE STRING "OpenSceneGraph so version number")
|
||||
|
||||
# just debug info
|
||||
#MESSAGE(STATUS "Detected OpenSceneGraph v${OPENSCENEGRAPH_VERSION}.")
|
||||
|
||||
# setup float and double definitions
|
||||
IF(OSG_USE_FLOAT_MATRIX MATCHES "float")
|
||||
ADD_DEFINITIONS(-DOSG_USE_FLOAT_MATRIX)
|
||||
ENDIF(OSG_USE_FLOAT_MATRIX MATCHES "float")
|
||||
IF(OSG_USE_FLOAT_PLANE MATCHES "float")
|
||||
ADD_DEFINITIONS(-DOSG_USE_FLOAT_PLANE)
|
||||
ENDIF(OSG_USE_FLOAT_PLANE MATCHES "float")
|
||||
IF(OSG_USE_FLOAT_BOUNDINGSPHERE MATCHES "double")
|
||||
ADD_DEFINITIONS(-DOSG_USE_DOUBLE_BOUNDINGSPHERE)
|
||||
ENDIF(OSG_USE_FLOAT_BOUNDINGSPHERE MATCHES "double")
|
||||
IF(OSG_USE_FLOAT_BOUNDINGBOX MATCHES "double")
|
||||
ADD_DEFINITIONS(-DOSG_USE_DOUBLE_BOUNDINGBOX)
|
||||
ENDIF(OSG_USE_FLOAT_BOUNDINGBOX MATCHES "double")
|
||||
|
||||
ENDIF(OSG_VERSION_EXE AND NOT OPENSCENEGRAPH_MAJOR_VERSION AND NOT OPENSCENEGRAPH_MINOR_VERSION AND NOT OPENSCENEGRAPH_PATCH_VERSION)
|
||||
|
||||
#Initialize the version numbers to being empty. If they were set by osgversion, they will be left alone
|
||||
SET(OPENSCENEGRAPH_MAJOR_VERSION "" CACHE STRING "OpenSceneGraph major version number")
|
||||
SET(OPENSCENEGRAPH_MINOR_VERSION "" CACHE STRING "OpenSceneGraph minor version number")
|
||||
SET(OPENSCENEGRAPH_PATCH_VERSION "" CACHE STRING "OpenSceneGraph patch version number")
|
||||
SET(OPENSCENEGRAPH_SOVERSION "" CACHE STRING "OpenSceneGraph so version number")
|
||||
|
||||
if (OPENSCENEGRAPH_MAJOR_VERSION AND NOT OPENSCENEGRAPH_MINOR_VERSION STREQUAL "" AND NOT OPENSCENEGRAPH_PATCH_VERSION STREQUAL "")
|
||||
SET(OPENSCENEGRAPH_VERSION ${OPENSCENEGRAPH_MAJOR_VERSION}.${OPENSCENEGRAPH_MINOR_VERSION}.${OPENSCENEGRAPH_PATCH_VERSION})
|
||||
else (OPENSCENEGRAPH_MAJOR_VERSION AND NOT OPENSCENEGRAPH_MINOR_VERSION STREQUAL "" AND NOT OPENSCENEGRAPH_PATCH_VERSION STREQUAL "")
|
||||
#MESSAGE("osgversion was found at ${OSG_VERSION_EXE} but failed to run")
|
||||
SET(OPENSCENEGRAPH_VERSION)
|
||||
endif (OPENSCENEGRAPH_MAJOR_VERSION AND NOT OPENSCENEGRAPH_MINOR_VERSION STREQUAL "" AND NOT OPENSCENEGRAPH_PATCH_VERSION STREQUAL "")
|
||||
|
||||
MARK_AS_ADVANCED(OPENSCENEGRAPH_VERSION)
|
||||
|
||||
|
||||
IF (APPEND_OPENSCENEGRAPH_VERSION AND OPENSCENEGRAPH_VERSION)
|
||||
SET(OSG_PLUGINS "osgPlugins-${OPENSCENEGRAPH_VERSION}" CACHE STRING "" FORCE)
|
||||
MESSAGE(STATUS "Plugins will be installed under osgPlugins-${OPENSCENEGRAPH_VERSION} directory.")
|
||||
else (APPEND_OPENSCENEGRAPH_VERSION AND OPENSCENEGRAPH_VERSION)
|
||||
SET(OSG_PLUGINS CACHE STRING "" FORCE)
|
||||
ENDIF(APPEND_OPENSCENEGRAPH_VERSION AND OPENSCENEGRAPH_VERSION)
|
||||
|
||||
MARK_AS_ADVANCED(OSG_PLUGINS)
|
||||
|
||||
#MESSAGE("OSG_PLUGINS=${OSG_PLUGINS}")
|
||||
|
||||
ENDMACRO(DETECT_OSG_VERSION)
|
||||
|
||||
|
||||
|
||||
#######################################################################################################
|
||||
# macro for linking libraries that come from Findxxxx commands, so there is a variable that contains the
|
||||
# full path of the library name. in order to differentiate release and debug, this macro get the
|
||||
# NAME of the variables, so the macro gets as arguments the target name and the following list of parameters
|
||||
# is intended as a list of variable names each one containing the path of the libraries to link to
|
||||
# The existance of a variable name with _DEBUG appended is tested and, in case it' s value is used
|
||||
# for linking to when in debug mode
|
||||
# the content of this library for linking when in debugging
|
||||
#######################################################################################################
|
||||
|
||||
|
||||
MACRO(LINK_WITH_VARIABLES TRGTNAME)
|
||||
FOREACH(varname ${ARGN})
|
||||
IF(${varname}_DEBUG)
|
||||
TARGET_LINK_LIBRARIES(${TRGTNAME} optimized "${${varname}}" debug "${${varname}_DEBUG}")
|
||||
ELSE(${varname}_DEBUG)
|
||||
TARGET_LINK_LIBRARIES(${TRGTNAME} "${${varname}}" )
|
||||
ENDIF(${varname}_DEBUG)
|
||||
ENDFOREACH(varname)
|
||||
ENDMACRO(LINK_WITH_VARIABLES TRGTNAME)
|
||||
|
||||
MACRO(LINK_INTERNAL TRGTNAME)
|
||||
IF(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 4)
|
||||
TARGET_LINK_LIBRARIES(${TRGTNAME} ${ARGN})
|
||||
ELSE(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 4)
|
||||
FOREACH(LINKLIB ${ARGN})
|
||||
IF(MSVC AND OSG_MSVC_VERSIONED_DLL)
|
||||
#when using versioned names, the .dll name differ from .lib name, there is a problem with that:
|
||||
#CMake 2.4.7, at least seem to use PREFIX instead of IMPORT_PREFIX for computing linkage info to use into projects,
|
||||
# so we full path name to specify linkage, this prevent automatic inferencing of dependencies, so we add explicit depemdencies
|
||||
#to library targets used
|
||||
TARGET_LINK_LIBRARIES(${TRGTNAME} optimized "${OUTPUT_LIBDIR}/${LINKLIB}${CMAKE_RELEASE_POSTFIX}.lib" debug "${OUTPUT_LIBDIR}/${LINKLIB}${CMAKE_DEBUG_POSTFIX}.lib")
|
||||
ADD_DEPENDENCIES(${TRGTNAME} ${LINKLIB})
|
||||
ELSE(MSVC AND OSG_MSVC_VERSIONED_DLL)
|
||||
TARGET_LINK_LIBRARIES(${TRGTNAME} optimized "${LINKLIB}${CMAKE_RELEASE_POSTFIX}" debug "${LINKLIB}${CMAKE_DEBUG_POSTFIX}")
|
||||
ENDIF(MSVC AND OSG_MSVC_VERSIONED_DLL)
|
||||
ENDFOREACH(LINKLIB)
|
||||
ENDIF(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 4)
|
||||
ENDMACRO(LINK_INTERNAL TRGTNAME)
|
||||
|
||||
MACRO(LINK_EXTERNAL TRGTNAME)
|
||||
FOREACH(LINKLIB ${ARGN})
|
||||
TARGET_LINK_LIBRARIES(${TRGTNAME} "${LINKLIB}" )
|
||||
ENDFOREACH(LINKLIB)
|
||||
ENDMACRO(LINK_EXTERNAL TRGTNAME)
|
||||
|
||||
|
||||
#######################################################################################################
|
||||
# macro for common setup of core libraries: it links OPENGL_LIBRARIES in undifferentiated mode
|
||||
#######################################################################################################
|
||||
|
||||
MACRO(LINK_CORELIB_DEFAULT CORELIB_NAME)
|
||||
LINK_EXTERNAL(${CORELIB_NAME} ${OPENGL_LIBRARIES})
|
||||
LINK_WITH_VARIABLES(${CORELIB_NAME} OPENTHREADS_LIBRARY)
|
||||
IF(OSGEARTH_SONAMES)
|
||||
SET_TARGET_PROPERTIES(${CORELIB_NAME} PROPERTIES VERSION ${OSGEARTH_VERSION} SOVERSION ${OSGEARTH_SOVERSION})
|
||||
ENDIF(OSGEARTH_SONAMES)
|
||||
ENDMACRO(LINK_CORELIB_DEFAULT CORELIB_NAME)
|
||||
|
||||
|
||||
#######################################################################################################
|
||||
# macro for common setup of plugins, examples and applications it expect some variables to be set:
|
||||
# either within the local CMakeLists or higher in hierarchy
|
||||
# TARGET_NAME is the name of the folder and of the actually .exe or .so or .dll
|
||||
# TARGET_TARGETNAME is the name of the target , this get buit out of a prefix, if present and TARGET_TARGETNAME
|
||||
# TARGET_SRC are the sources of the target
|
||||
# TARGET_H are the eventual headers of the target
|
||||
# TARGET_LIBRARIES are the libraries to link to that are internal to the project and have d suffix for debug
|
||||
# TARGET_EXTERNAL_LIBRARIES are external libraries and are not differentiated with d suffix
|
||||
# TARGET_LABEL is the label IDE should show up for targets
|
||||
##########################################################################################################
|
||||
|
||||
MACRO(SETUP_LINK_LIBRARIES)
|
||||
######################################################################
|
||||
#
|
||||
# This set up the libraries to link to, it assumes there are two variable: one common for a group of examples or plagins
|
||||
# kept in the variable TARGET_COMMON_LIBRARIES and an example or plugin specific kept in TARGET_ADDED_LIBRARIES
|
||||
# they are combined in a single list checked for unicity
|
||||
# the suffix ${CMAKE_DEBUG_POSTFIX} is used for differentiating optimized and debug
|
||||
#
|
||||
# a second variable TARGET_EXTERNAL_LIBRARIES hold the list of libraries not differentiated between debug and optimized
|
||||
##################################################################################
|
||||
SET(TARGET_LIBRARIES ${TARGET_COMMON_LIBRARIES})
|
||||
|
||||
FOREACH(LINKLIB ${TARGET_ADDED_LIBRARIES})
|
||||
SET(TO_INSERT TRUE)
|
||||
FOREACH (value ${TARGET_COMMON_LIBRARIES})
|
||||
IF (${value} STREQUAL ${LINKLIB})
|
||||
SET(TO_INSERT FALSE)
|
||||
ENDIF (${value} STREQUAL ${LINKLIB})
|
||||
ENDFOREACH (value ${TARGET_COMMON_LIBRARIES})
|
||||
IF(TO_INSERT)
|
||||
LIST(APPEND TARGET_LIBRARIES ${LINKLIB})
|
||||
ENDIF(TO_INSERT)
|
||||
ENDFOREACH(LINKLIB)
|
||||
|
||||
# FOREACH(LINKLIB ${TARGET_LIBRARIES})
|
||||
# TARGET_LINK_LIBRARIES(${TARGET_TARGETNAME} optimized ${LINKLIB} debug "${LINKLIB}${CMAKE_DEBUG_POSTFIX}")
|
||||
# ENDFOREACH(LINKLIB)
|
||||
LINK_INTERNAL(${TARGET_TARGETNAME} ${TARGET_LIBRARIES})
|
||||
|
||||
FOREACH(LINKLIB ${TARGET_EXTERNAL_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES(${TARGET_TARGETNAME} ${LINKLIB})
|
||||
ENDFOREACH(LINKLIB)
|
||||
IF(TARGET_LIBRARIES_VARS)
|
||||
LINK_WITH_VARIABLES(${TARGET_TARGETNAME} ${TARGET_LIBRARIES_VARS})
|
||||
ENDIF(TARGET_LIBRARIES_VARS)
|
||||
ENDMACRO(SETUP_LINK_LIBRARIES)
|
||||
|
||||
############################################################################################
|
||||
# this is the common set of command for all the plugins
|
||||
|
||||
|
||||
MACRO(SETUP_PLUGIN PLUGIN_NAME)
|
||||
|
||||
SET(TARGET_NAME ${PLUGIN_NAME} )
|
||||
|
||||
#MESSAGE("in -->SETUP_PLUGIN<-- ${TARGET_NAME}-->${TARGET_SRC} <--> ${TARGET_H}<--")
|
||||
|
||||
SOURCE_GROUP( "Header Files" FILES ${TARGET_H} )
|
||||
|
||||
## we have set up the target label and targetname by taking into account global prfix (osgdb_)
|
||||
|
||||
IF(NOT TARGET_TARGETNAME)
|
||||
SET(TARGET_TARGETNAME "${TARGET_DEFAULT_PREFIX}${TARGET_NAME}")
|
||||
ENDIF(NOT TARGET_TARGETNAME)
|
||||
IF(NOT TARGET_LABEL)
|
||||
SET(TARGET_LABEL "${TARGET_DEFAULT_LABEL_PREFIX} ${TARGET_NAME}")
|
||||
ENDIF(NOT TARGET_LABEL)
|
||||
|
||||
# here we use the command to generate the library
|
||||
|
||||
IF (DYNAMIC_OSGEARTH)
|
||||
ADD_LIBRARY(${TARGET_TARGETNAME} MODULE ${TARGET_SRC} ${TARGET_H})
|
||||
ELSE (DYNAMIC_OSGEARTH)
|
||||
ADD_LIBRARY(${TARGET_TARGETNAME} STATIC ${TARGET_SRC} ${TARGET_H})
|
||||
ENDIF(DYNAMIC_OSGEARTH)
|
||||
|
||||
#not sure if needed, but for plugins only msvc need the d suffix
|
||||
IF(NOT MSVC)
|
||||
IF(NOT UNIX)
|
||||
SET_TARGET_PROPERTIES(${TARGET_TARGETNAME} PROPERTIES DEBUG_POSTFIX "")
|
||||
ENDIF(NOT UNIX)
|
||||
ENDIF(NOT MSVC)
|
||||
SET_TARGET_PROPERTIES(${TARGET_TARGETNAME} PROPERTIES PROJECT_LABEL "${TARGET_LABEL}")
|
||||
|
||||
SETUP_LINK_LIBRARIES()
|
||||
|
||||
#the installation path are differentiated for win32 that install in bib versus other architecture that install in lib${LIB_POSTFIX}/${VPB_PLUGINS}
|
||||
IF(WIN32)
|
||||
INSTALL(TARGETS ${TARGET_TARGETNAME} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib/${OSG_PLUGINS} LIBRARY DESTINATION bin/${OSG_PLUGINS} )
|
||||
|
||||
#Install to the OSG_DIR as well
|
||||
IF(OSGEARTH_INSTALL_TO_OSG_DIR AND OSG_DIR)
|
||||
INSTALL(TARGETS ${TARGET_TARGETNAME} RUNTIME DESTINATION ${OSG_DIR}/bin/${OSG_PLUGINS} LIBRARY DESTINATION ${OSG_DIR}/bin/${OSG_PLUGINS} )
|
||||
ENDIF(OSGEARTH_INSTALL_TO_OSG_DIR AND OSG_DIR)
|
||||
|
||||
ELSE(WIN32)
|
||||
INSTALL(TARGETS ${TARGET_TARGETNAME} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib${LIB_POSTFIX}/${OSG_PLUGINS} LIBRARY DESTINATION lib${LIB_POSTFIX}/${OSG_PLUGINS} )
|
||||
|
||||
#Install to the OSG_DIR as well
|
||||
IF(OSGEARTH_INSTALL_TO_OSG_DIR AND OSG_DIR)
|
||||
INSTALL(TARGETS ${TARGET_TARGETNAME} RUNTIME DESTINATION ${OSG_DIR}/bin LIBRARY DESTINATION lib${LIB_POSTFIX}/bin)
|
||||
ENDIF(OSGEARTH_INSTALL_TO_OSG_DIR AND OSG_DIR)
|
||||
|
||||
ENDIF(WIN32)
|
||||
|
||||
#finally, set up the solution folder -gw
|
||||
SET_PROPERTY(TARGET ${TARGET_TARGETNAME} PROPERTY FOLDER "Plugins")
|
||||
|
||||
ENDMACRO(SETUP_PLUGIN)
|
||||
|
||||
|
||||
#################################################################################################################
|
||||
# this is the macro for example and application setup
|
||||
###########################################################
|
||||
|
||||
MACRO(SETUP_EXE IS_COMMANDLINE_APP)
|
||||
#MESSAGE("in -->SETUP_EXE<-- ${TARGET_NAME}-->${TARGET_SRC} <--> ${TARGET_H}<--")
|
||||
IF(NOT TARGET_TARGETNAME)
|
||||
SET(TARGET_TARGETNAME "${TARGET_DEFAULT_PREFIX}${TARGET_NAME}")
|
||||
ENDIF(NOT TARGET_TARGETNAME)
|
||||
IF(NOT TARGET_LABEL)
|
||||
SET(TARGET_LABEL "${TARGET_DEFAULT_LABEL_PREFIX} ${TARGET_NAME}")
|
||||
ENDIF(NOT TARGET_LABEL)
|
||||
|
||||
IF(${IS_COMMANDLINE_APP})
|
||||
|
||||
ADD_EXECUTABLE(${TARGET_TARGETNAME} ${TARGET_SRC} ${TARGET_H})
|
||||
|
||||
ELSE(${IS_COMMANDLINE_APP})
|
||||
|
||||
IF(APPLE)
|
||||
# SET(MACOSX_BUNDLE_LONG_VERSION_STRING "${VIRTUALPLANETBUILDER_MAJOR_VERSION}.${VIRTUALPLANETBUILDER_MINOR_VERSION}.${VIRTUALPLANETBUILDER_PATCH_VERSION}")
|
||||
# Short Version is the "marketing version". It is the version
|
||||
# the user sees in an information panel.
|
||||
SET(MACOSX_BUNDLE_SHORT_VERSION_STRING "${OSGEARTH_MAJOR_VERSION}.${OSGEARTH_MINOR_VERSION}.${OSGEARTH_PATCH_VERSION}")
|
||||
# Bundle version is the version the OS looks at.
|
||||
SET(MACOSX_BUNDLE_BUNDLE_VERSION "${OSGEARTH_MAJOR_VERSION}.${OSGEARTH_MINOR_VERSION}.${OSGEARTH__PATCH_VERSION}")
|
||||
SET(MACOSX_BUNDLE_GUI_IDENTIFIER "org.osgearth.${TARGET_TARGETNAME}" )
|
||||
SET(MACOSX_BUNDLE_BUNDLE_NAME "${TARGET_NAME}" )
|
||||
# SET(MACOSX_BUNDLE_ICON_FILE "myicon.icns")
|
||||
# SET(MACOSX_BUNDLE_COPYRIGHT "")
|
||||
# SET(MACOSX_BUNDLE_INFO_STRING "Info string, localized?")
|
||||
ENDIF(APPLE)
|
||||
|
||||
IF(WIN32)
|
||||
IF (REQUIRE_WINMAIN_FLAG)
|
||||
SET(PLATFORM_SPECIFIC_CONTROL WIN32)
|
||||
ENDIF(REQUIRE_WINMAIN_FLAG)
|
||||
ENDIF(WIN32)
|
||||
|
||||
IF(APPLE)
|
||||
IF(VPB_BUILD_APPLICATION_BUNDLES)
|
||||
SET(PLATFORM_SPECIFIC_CONTROL MACOSX_BUNDLE)
|
||||
ENDIF(VPB_BUILD_APPLICATION_BUNDLES)
|
||||
ENDIF(APPLE)
|
||||
|
||||
ADD_EXECUTABLE(${TARGET_TARGETNAME} ${PLATFORM_SPECIFIC_CONTROL} ${TARGET_SRC} ${TARGET_H})
|
||||
|
||||
ENDIF(${IS_COMMANDLINE_APP})
|
||||
|
||||
SET_TARGET_PROPERTIES(${TARGET_TARGETNAME} PROPERTIES PROJECT_LABEL "${TARGET_LABEL}")
|
||||
SET_TARGET_PROPERTIES(${TARGET_TARGETNAME} PROPERTIES OUTPUT_NAME ${TARGET_NAME})
|
||||
SET_TARGET_PROPERTIES(${TARGET_TARGETNAME} PROPERTIES DEBUG_OUTPUT_NAME "${TARGET_NAME}${CMAKE_DEBUG_POSTFIX}")
|
||||
SET_TARGET_PROPERTIES(${TARGET_TARGETNAME} PROPERTIES RELEASE_OUTPUT_NAME "${TARGET_NAME}${CMAKE_RELEASE_POSTFIX}")
|
||||
SET_TARGET_PROPERTIES(${TARGET_TARGETNAME} PROPERTIES RELWITHDEBINFO_OUTPUT_NAME "${TARGET_NAME}${CMAKE_RELWITHDEBINFO_POSTFIX}")
|
||||
SET_TARGET_PROPERTIES(${TARGET_TARGETNAME} PROPERTIES MINSIZEREL_OUTPUT_NAME "${TARGET_NAME}${CMAKE_MINSIZEREL_POSTFIX}")
|
||||
|
||||
SETUP_LINK_LIBRARIES()
|
||||
|
||||
ENDMACRO(SETUP_EXE)
|
||||
|
||||
# Takes optional second argument (is_commandline_app?) in ARGV1
|
||||
MACRO(SETUP_APPLICATION APPLICATION_NAME)
|
||||
|
||||
SET(TARGET_NAME ${APPLICATION_NAME} )
|
||||
|
||||
IF(${ARGC} GREATER 1)
|
||||
SET(IS_COMMANDLINE_APP ${ARGV1})
|
||||
ELSE(${ARGC} GREATER 1)
|
||||
SET(IS_COMMANDLINE_APP 0)
|
||||
ENDIF(${ARGC} GREATER 1)
|
||||
|
||||
SETUP_EXE(${IS_COMMANDLINE_APP})
|
||||
|
||||
INSTALL(TARGETS ${TARGET_TARGETNAME} RUNTIME DESTINATION bin )
|
||||
#Install to the OSG_DIR as well
|
||||
IF(OSGEARTH_INSTALL_TO_OSG_DIR AND OSG_DIR)
|
||||
INSTALL(TARGETS ${TARGET_TARGETNAME} RUNTIME DESTINATION ${OSG_DIR}/bin)
|
||||
ENDIF(OSGEARTH_INSTALL_TO_OSG_DIR AND OSG_DIR)
|
||||
|
||||
SET_PROPERTY(TARGET ${TARGET_TARGETNAME} PROPERTY FOLDER "Samples")
|
||||
|
||||
ENDMACRO(SETUP_APPLICATION)
|
||||
|
||||
MACRO(SETUP_COMMANDLINE_APPLICATION APPLICATION_NAME)
|
||||
|
||||
SETUP_APPLICATION(${APPLICATION_NAME} 1)
|
||||
|
||||
ENDMACRO(SETUP_COMMANDLINE_APPLICATION)
|
||||
|
||||
# Takes optional second argument (is_commandline_app?) in ARGV1
|
||||
MACRO(SETUP_EXAMPLE EXAMPLE_NAME)
|
||||
|
||||
SET(TARGET_NAME ${EXAMPLE_NAME} )
|
||||
|
||||
IF(${ARGC} GREATER 1)
|
||||
SET(IS_COMMANDLINE_APP ${ARGV1})
|
||||
ELSE(${ARGC} GREATER 1)
|
||||
SET(IS_COMMANDLINE_APP 0)
|
||||
ENDIF(${ARGC} GREATER 1)
|
||||
|
||||
SETUP_EXE(${IS_COMMANDLINE_APP})
|
||||
|
||||
INSTALL(TARGETS ${TARGET_TARGETNAME} RUNTIME DESTINATION share/OpenSceneGraph/bin )
|
||||
|
||||
ENDMACRO(SETUP_EXAMPLE)
|
||||
|
||||
|
||||
MACRO(SETUP_COMMANDLINE_EXAMPLE EXAMPLE_NAME)
|
||||
|
||||
SETUP_EXAMPLE(${EXAMPLE_NAME} 1)
|
||||
|
||||
ENDMACRO(SETUP_COMMANDLINE_EXAMPLE)
|
50
src/plugins/globe/featuresource/CMakeLists.txt
Normal file
@ -0,0 +1,50 @@
|
||||
###################################################
|
||||
# osgEarth plugin
|
||||
###################################################
|
||||
|
||||
SET(OSGEARTH_PLUGIN_PREFIX "")
|
||||
SET(LIB_POSTFIX ${LIB_SUFFIX})
|
||||
SET(DYNAMIC_OSGEARTH "ON" )
|
||||
SET(OSGEARTH_USER_DEFINED_DYNAMIC_OR_STATIC "SHARED")
|
||||
|
||||
# SET(CMAKE_SHARED_MODULE_PREFIX ${OSGEARTH_PLUGIN_PREFIX})
|
||||
SET(TARGET_DEFAULT_PREFIX "osgdb_")
|
||||
SET(TARGET_DEFAULT_LABEL_PREFIX "Plugin")
|
||||
|
||||
INCLUDE( OsgEarthMacroUtils )
|
||||
|
||||
SET(TARGET_SRC
|
||||
qgsglobefeaturesource.cpp
|
||||
)
|
||||
|
||||
SET (TARGET_MOC_HDRS
|
||||
qgsglobefeaturesource.h
|
||||
)
|
||||
|
||||
SET(TARGET_HDRS
|
||||
qgsglobefeaturecursor.h
|
||||
qgsglobefeatureoptions.h
|
||||
qgsglobefeatureutils.h
|
||||
)
|
||||
|
||||
QT4_WRAP_CPP(TARGET_MOC_SRCS ${TARGET_MOC_HDRS})
|
||||
|
||||
SET(TARGET_SRC ${TARGET_SRC} ${TARGET_MOC_SRCS})
|
||||
|
||||
SET(TARGET_COMMON_LIBRARIES ${TARGET_COMMON_LIBRARIES}
|
||||
qgis_core
|
||||
qgis_gui
|
||||
${OSGDB_LIBRARY}
|
||||
${OSG_LIBRARY}
|
||||
${OSGEARTH_LIBRARY}
|
||||
${OSGEARTHFEATURES_LIBRARY}
|
||||
${OSGEARTHSYMBOLOGY_LIBRARY}
|
||||
${OSGEARTHUTIL_LIBRARY}
|
||||
${OPENTHREADS_LIBRARY}
|
||||
)
|
||||
SETUP_PLUGIN(osgearth_feature_qgis)
|
||||
|
||||
# to install public driver includes:
|
||||
SET(LIB_NAME feature_qgis)
|
||||
SET(LIB_PUBLIC_HEADERS ${TARGET_HDRS} ${TARGET_MOC_HDRS})
|
||||
INCLUDE(ModuleInstallOsgEarthDriverIncludes OPTIONAL)
|
66
src/plugins/globe/featuresource/qgsglobefeaturecursor.h
Normal file
@ -0,0 +1,66 @@
|
||||
/***************************************************************************
|
||||
qgsglobefeaturecursor.h
|
||||
--------------------------------------
|
||||
Date : 11.7.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSGLOBEFEATURECURSOR_H
|
||||
#define QGSGLOBEFEATURECURSOR_H
|
||||
|
||||
#include <osgEarthFeatures/FeatureCursor>
|
||||
#include <qgsfeature.h>
|
||||
#include <qgsfeatureiterator.h>
|
||||
#include <qgsvectorlayer.h>
|
||||
|
||||
#include "qgsglobefeatureutils.h"
|
||||
|
||||
|
||||
class QgsGlobeFeatureCursor : public osgEarth::Features::FeatureCursor
|
||||
{
|
||||
public:
|
||||
QgsGlobeFeatureCursor( QgsVectorLayer* layer, const QgsFeatureIterator& iterator )
|
||||
: mIterator( iterator )
|
||||
, mLayer( layer )
|
||||
{
|
||||
mIterator.nextFeature( mFeature );
|
||||
}
|
||||
|
||||
bool hasMore() const override
|
||||
{
|
||||
return mFeature.isValid();
|
||||
}
|
||||
|
||||
osgEarth::Features::Feature* nextFeature() override
|
||||
{
|
||||
if ( mFeature.isValid() )
|
||||
{
|
||||
osgEarth::Features::Feature *feat = QgsGlobeFeatureUtils::featureFromQgsFeature( mLayer, mFeature );
|
||||
mIterator.nextFeature( mFeature );
|
||||
return feat;
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsDebugMsg( "WARNING: Returning NULL feature to osgEarth" );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QgsFeatureIterator mIterator;
|
||||
QgsVectorLayer* mLayer;
|
||||
// Cached feature which will be returned next.
|
||||
// Always contains the next feature which will be returned
|
||||
// (Because hasMore() needs to know if we are able to return a next feature)
|
||||
QgsFeature mFeature;
|
||||
};
|
||||
|
||||
#endif // QGSGLOBEFEATURECURSOR_H
|
81
src/plugins/globe/featuresource/qgsglobefeatureoptions.h
Normal file
@ -0,0 +1,81 @@
|
||||
/* -*-c++-*- */
|
||||
/*
|
||||
* osgEarth is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef QGSGLOBEFEATUREOPTIONS_H
|
||||
#define QGSGLOBEFEATUREOPTIONS_H
|
||||
|
||||
#include <osgEarth/Common>
|
||||
#include <osgEarthFeatures/FeatureSource>
|
||||
|
||||
class QgsVectorLayer;
|
||||
|
||||
class QgsGlobeFeatureOptions : public osgEarth::Features::FeatureSourceOptions // NO EXPORT; header only
|
||||
{
|
||||
private:
|
||||
template <class T>
|
||||
class RefPtr : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
RefPtr( T* ptr ) : mPtr( ptr ) {}
|
||||
T* ptr() { return mPtr; }
|
||||
|
||||
private:
|
||||
T* mPtr;
|
||||
};
|
||||
|
||||
public:
|
||||
QgsGlobeFeatureOptions( const ConfigOptions& opt = ConfigOptions() )
|
||||
: osgEarth::Features::FeatureSourceOptions( opt )
|
||||
{
|
||||
// Call the driver declared as "osgearth_feature_qgis"
|
||||
setDriver( "qgis" );
|
||||
fromConfig( _conf );
|
||||
}
|
||||
|
||||
osgEarth::Config getConfig() const override
|
||||
{
|
||||
osgEarth::Config conf = osgEarth::Features::FeatureSourceOptions::getConfig();
|
||||
conf.updateIfSet( "layerId", mLayerId );
|
||||
conf.updateNonSerializable( "layer", new RefPtr< QgsVectorLayer >( mLayer ) );
|
||||
return conf;
|
||||
}
|
||||
|
||||
osgEarth::optional<std::string>& layerId() { return mLayerId; }
|
||||
const osgEarth::optional<std::string>& layerId() const { return mLayerId; }
|
||||
|
||||
QgsVectorLayer* layer() const { return mLayer; }
|
||||
void setLayer( QgsVectorLayer* layer ) { mLayer = layer; }
|
||||
|
||||
protected:
|
||||
void mergeConfig( const osgEarth::Config& conf ) override
|
||||
{
|
||||
osgEarth::Features::FeatureSourceOptions::mergeConfig( conf );
|
||||
fromConfig( conf );
|
||||
}
|
||||
|
||||
private:
|
||||
void fromConfig( const osgEarth::Config& conf )
|
||||
{
|
||||
conf.getIfSet( "layerId", mLayerId );
|
||||
RefPtr< QgsVectorLayer > *layer_ptr = conf.getNonSerializable< RefPtr< QgsVectorLayer > >( "layer" );
|
||||
mLayer = layer_ptr ? layer_ptr->ptr() : 0;
|
||||
}
|
||||
|
||||
osgEarth::optional<std::string> mLayerId;
|
||||
QgsVectorLayer* mLayer;
|
||||
};
|
||||
|
||||
#endif // QGSGLOBEFEATUREOPTIONS_H
|
||||
|
145
src/plugins/globe/featuresource/qgsglobefeaturesource.cpp
Normal file
@ -0,0 +1,145 @@
|
||||
#include <osgDB/ReaderWriter>
|
||||
#include <osgDB/FileNameUtils>
|
||||
|
||||
#include <qgsfeature.h>
|
||||
#include <qgsfeatureiterator.h>
|
||||
#include <qgsgeometry.h>
|
||||
#include <qgslogger.h>
|
||||
#include <qgsrectangle.h>
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
#include "qgsglobefeaturecursor.h"
|
||||
#include "qgsglobefeatureutils.h"
|
||||
#include "qgsglobefeaturesource.h"
|
||||
|
||||
|
||||
QgsGlobeFeatureSource::QgsGlobeFeatureSource( const QgsGlobeFeatureOptions& options ) :
|
||||
mOptions( options ),
|
||||
mLayer( 0 ),
|
||||
mProfile( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
void QgsGlobeFeatureSource::initialize( const osgDB::Options* dbOptions )
|
||||
{
|
||||
Q_UNUSED( dbOptions )
|
||||
mLayer = mOptions.layer();
|
||||
|
||||
connect( mLayer, SIGNAL( attributeValueChanged( QgsFeatureId, int, QVariant ) ), this, SLOT( attributeValueChanged( QgsFeatureId, int, QVariant ) ) );
|
||||
connect( mLayer, SIGNAL( geometryChanged( QgsFeatureId, QgsGeometry& ) ), this, SLOT( geometryChanged( QgsFeatureId, QgsGeometry& ) ) );
|
||||
|
||||
// create the profile
|
||||
osgEarth::SpatialReference* ref = osgEarth::SpatialReference::create( mLayer->crs().toWkt().toStdString() );
|
||||
if ( 0 == ref )
|
||||
{
|
||||
std::cout << "Cannot find the spatial reference" << std::endl;
|
||||
return;
|
||||
}
|
||||
QgsRectangle ext = mLayer->extent();
|
||||
osgEarth::GeoExtent geoext( ref, ext.xMinimum(), ext.yMinimum(), ext.xMaximum(), ext.yMaximum() );
|
||||
mProfile = new osgEarth::Features::FeatureProfile( geoext );
|
||||
mSchema = QgsGlobeFeatureUtils::schemaForFields( mLayer->pendingFields() );
|
||||
}
|
||||
|
||||
osgEarth::Features::FeatureCursor* QgsGlobeFeatureSource::createFeatureCursor( const osgEarth::Symbology::Query& query )
|
||||
{
|
||||
QgsFeatureRequest request;
|
||||
|
||||
if ( query.expression().isSet() )
|
||||
{
|
||||
QgsDebugMsg( QString( "Ignoring query expression '%1'" ). arg( query.expression().value().c_str() ) );
|
||||
}
|
||||
|
||||
if ( query.bounds().isSet() )
|
||||
{
|
||||
QgsRectangle bounds( query.bounds()->xMin(), query.bounds()->yMin(), query.bounds()->xMax(), query.bounds()->yMax() );
|
||||
request.setFilterRect( bounds );
|
||||
}
|
||||
|
||||
QgsFeatureIterator it = mLayer->getFeatures( request );
|
||||
return new QgsGlobeFeatureCursor( mLayer, it );
|
||||
}
|
||||
|
||||
osgEarth::Features::Feature* QgsGlobeFeatureSource::getFeature( osgEarth::Features::FeatureID fid )
|
||||
{
|
||||
QgsFeature feat;
|
||||
mLayer->getFeatures( QgsFeatureRequest().setFilterFid( fid ) ).nextFeature( feat );
|
||||
osgEarth::Features::Feature* feature = QgsGlobeFeatureUtils::featureFromQgsFeature( mLayer, feat );
|
||||
FeatureMap_t::iterator it = mFeatures.find( fid );
|
||||
if ( it == mFeatures.end() )
|
||||
{
|
||||
mFeatures.insert( std::make_pair( fid, osg::observer_ptr<osgEarth::Features::Feature>( feature ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
it->second = osg::observer_ptr<osgEarth::Features::Feature>( feature );
|
||||
}
|
||||
return feature;
|
||||
}
|
||||
|
||||
osgEarth::Features::Geometry::Type QgsGlobeFeatureSource::getGeometryType() const
|
||||
{
|
||||
switch ( mLayer->geometryType() )
|
||||
{
|
||||
case QGis::Point:
|
||||
return osgEarth::Features::Geometry::TYPE_POINTSET;
|
||||
|
||||
case QGis::Line:
|
||||
return osgEarth::Features::Geometry::TYPE_LINESTRING;
|
||||
|
||||
case QGis::Polygon:
|
||||
return osgEarth::Features::Geometry::TYPE_POLYGON;
|
||||
|
||||
default:
|
||||
return osgEarth::Features::Geometry::TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
return osgEarth::Features::Geometry::TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
int QgsGlobeFeatureSource::getFeatureCount() const
|
||||
{
|
||||
return mLayer->featureCount();
|
||||
}
|
||||
|
||||
void QgsGlobeFeatureSource::attributeValueChanged( const QgsFeatureId& featureId, int idx, const QVariant& value )
|
||||
{
|
||||
FeatureMap_t::iterator it = mFeatures.find( featureId );
|
||||
if ( it != mFeatures.end() )
|
||||
{
|
||||
osgEarth::Features::Feature* feature = it->second.get();
|
||||
QgsGlobeFeatureUtils::setFeatureField( feature, mLayer->pendingFields().at( idx ), value );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGlobeFeatureSource::geometryChanged( const QgsFeatureId& featureId, QgsGeometry& geometry )
|
||||
{
|
||||
FeatureMap_t::iterator it = mFeatures.find( featureId );
|
||||
if ( it != mFeatures.end() )
|
||||
{
|
||||
osgEarth::Features::Feature* feature = it->second.get();
|
||||
feature->setGeometry( QgsGlobeFeatureUtils::geometryFromQgsGeometry( geometry ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class QgsGlobeFeatureSourceFactory : public osgEarth::Features::FeatureSourceDriver
|
||||
{
|
||||
public:
|
||||
QgsGlobeFeatureSourceFactory()
|
||||
{
|
||||
supportsExtension( "osgearth_feature_qgis", "QGIS feature driver for osgEarth" );
|
||||
}
|
||||
|
||||
virtual osgDB::ReaderWriter::ReadResult readObject( const std::string& file_name, const osgDB::Options* options ) const override
|
||||
{
|
||||
// this function seems to be called for every plugin
|
||||
// we declare supporting the special extension "osgearth_feature_qgis"
|
||||
if ( !acceptsExtension( osgDB::getLowerCaseFileExtension( file_name ) ) )
|
||||
return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED;
|
||||
|
||||
return osgDB::ReaderWriter::ReadResult( new QgsGlobeFeatureSource( getFeatureSourceOptions( options ) ) );
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_OSGPLUGIN( osgearth_feature_qgis, QgsGlobeFeatureSourceFactory )
|
48
src/plugins/globe/featuresource/qgsglobefeaturesource.h
Normal file
@ -0,0 +1,48 @@
|
||||
#ifndef QGSGLOBEFEATURESOURCE_H
|
||||
#define QGSGLOBEFEATURESOURCE_H
|
||||
|
||||
#include <osgEarthFeatures/FeatureSource>
|
||||
#include <QObject>
|
||||
|
||||
#include "qgsglobefeatureoptions.h"
|
||||
#include "qgsfeature.h"
|
||||
|
||||
class QgsGlobeFeatureSource : public QObject, public osgEarth::Features::FeatureSource
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QgsGlobeFeatureSource( const QgsGlobeFeatureOptions& options = osgEarth::Features::ConfigOptions() );
|
||||
|
||||
osgEarth::Features::FeatureCursor* createFeatureCursor( const osgEarth::Symbology::Query& query = osgEarth::Symbology::Query() ) override;
|
||||
|
||||
int getFeatureCount() const override;
|
||||
osgEarth::Features::Feature* getFeature( osgEarth::Features::FeatureID fid ) override;
|
||||
osgEarth::Features::Geometry::Type getGeometryType() const override;
|
||||
|
||||
QgsVectorLayer* layer() const { return mLayer; }
|
||||
|
||||
const char* className() const override { return "QGISFeatureSource"; }
|
||||
const char* libraryName() const override { return "QGIS"; }
|
||||
|
||||
void initialize( const osgDB::Options* dbOptions );
|
||||
|
||||
protected:
|
||||
const osgEarth::Features::FeatureProfile* createFeatureProfile() override { return mProfile; }
|
||||
const osgEarth::Features::FeatureSchema& getSchema() const override { return mSchema; }
|
||||
|
||||
~QgsGlobeFeatureSource() {}
|
||||
|
||||
private:
|
||||
QgsGlobeFeatureOptions mOptions;
|
||||
QgsVectorLayer* mLayer;
|
||||
osgEarth::Features::FeatureProfile* mProfile;
|
||||
osgEarth::Features::FeatureSchema mSchema;
|
||||
typedef std::map<osgEarth::Features::FeatureID, osg::observer_ptr<osgEarth::Features::Feature> > FeatureMap_t;
|
||||
FeatureMap_t mFeatures;
|
||||
|
||||
private slots:
|
||||
void attributeValueChanged( const QgsFeatureId&featureId, int idx, const QVariant &value );
|
||||
void geometryChanged( const QgsFeatureId&featureId, QgsGeometry&geometry );
|
||||
};
|
||||
|
||||
#endif // QGSGLOBEFEATURESOURCE_H
|
254
src/plugins/globe/featuresource/qgsglobefeatureutils.h
Normal file
@ -0,0 +1,254 @@
|
||||
/***************************************************************************
|
||||
qgsglobefeatureutils.h
|
||||
--------------------------------------
|
||||
Date : 11.7.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSGLOBEFEATUREUTILS_H
|
||||
#define QGSGLOBEFEATUREUTILS_H
|
||||
|
||||
#include <osgEarthFeatures/Feature>
|
||||
#include <osg/ValueObject>
|
||||
|
||||
#include <qgsfield.h>
|
||||
#include <qgsgeometry.h>
|
||||
#include <qgsmultipointv2.h>
|
||||
#include <qgsmultilinestringv2.h>
|
||||
#include <qgsmultipolygonv2.h>
|
||||
#include <qgspolygonv2.h>
|
||||
#include <qgslinestringv2.h>
|
||||
#include <qgsvectorlayer.h>
|
||||
|
||||
class QgsGlobeFeatureUtils
|
||||
{
|
||||
public:
|
||||
static inline QgsPointV2 qgsPointFromPoint( const osg::Vec3d& pt )
|
||||
{
|
||||
return QgsPointV2( QgsWKBTypes::PointZ, pt.x(), pt.y(), pt.z() );
|
||||
}
|
||||
|
||||
static inline osg::Vec3d pointFromQgsPoint( const QgsPointV2& pt )
|
||||
{
|
||||
return osg::Vec3d( pt.x(), pt.y(), pt.z() );
|
||||
}
|
||||
|
||||
static inline osgEarth::Features::LineString* lineStringFromQgsLineString( const QgsLineStringV2* lineString )
|
||||
{
|
||||
QgsLineStringV2* linearString = lineString->curveToLine();
|
||||
osgEarth::Features::LineString* retLineString = new osgEarth::Features::LineString();
|
||||
for ( int iVtx = 0, nVtx = linearString->vertexCount(); iVtx < nVtx; ++iVtx )
|
||||
{
|
||||
retLineString->push_back( pointFromQgsPoint( linearString->vertexAt( QgsVertexId( 0, 0, iVtx ) ) ) );
|
||||
}
|
||||
delete linearString;
|
||||
return retLineString;
|
||||
}
|
||||
|
||||
static inline osgEarth::Features::Polygon* polygonFromQgsPolygon( const QgsPolygonV2* polygon )
|
||||
{
|
||||
QgsPolygonV2* linearPolygon = polygon->toPolygon();
|
||||
// a ring for osg earth is open (first point != last point)
|
||||
// an outer ring is oriented CCW, an inner ring is oriented CW
|
||||
osgEarth::Features::Polygon* retPoly = new osgEarth::Features::Polygon();
|
||||
|
||||
// the outer ring
|
||||
for ( int iVtx = 0, nVtx = linearPolygon->vertexCount( 0, 0 ); iVtx < nVtx; ++iVtx )
|
||||
{
|
||||
retPoly->push_back( pointFromQgsPoint( linearPolygon->vertexAt( QgsVertexId( 0, 0, iVtx ) ) ) );
|
||||
}
|
||||
retPoly->rewind( osgEarth::Symbology::Ring::ORIENTATION_CCW );
|
||||
|
||||
for ( int iRing = 1, nRings = linearPolygon->ringCount( 0 ); iRing < nRings; ++iRing )
|
||||
{
|
||||
osgEarth::Features::Ring* innerRing = new osgEarth::Features::Ring();
|
||||
for ( int iVtx = 0, nVtx = linearPolygon->vertexCount( 0, iRing ); iVtx < nVtx; ++iVtx )
|
||||
{
|
||||
innerRing->push_back( pointFromQgsPoint( linearPolygon->vertexAt( QgsVertexId( 0, iRing, iVtx ) ) ) );
|
||||
}
|
||||
innerRing->rewind( osgEarth::Symbology::Ring::ORIENTATION_CW );
|
||||
retPoly->getHoles().push_back( osg::ref_ptr<osgEarth::Features::Ring>( innerRing ) );
|
||||
}
|
||||
delete linearPolygon;
|
||||
return retPoly;
|
||||
}
|
||||
|
||||
static inline osgEarth::Features::Geometry* geometryFromQgsGeometry( const QgsGeometry& geom )
|
||||
{
|
||||
#if 0
|
||||
// test srid
|
||||
std::cout << "geom = " << &geom << std::endl;
|
||||
std::cout << "wkb = " << geom.asWkb() << std::endl;
|
||||
uint32_t srid;
|
||||
memcpy( &srid, geom.asWkb() + 2 + sizeof( void* ), sizeof( uint32_t ) );
|
||||
std::cout << "srid = " << srid << std::endl;
|
||||
#endif
|
||||
|
||||
switch ( QgsWKBTypes::flatType( geom.geometry()->wkbType() ) )
|
||||
{
|
||||
case QgsWKBTypes::Point:
|
||||
{
|
||||
osgEarth::Features::PointSet* pointSet = new osgEarth::Features::PointSet();
|
||||
pointSet->push_back( pointFromQgsPoint( *static_cast<QgsPointV2*>( geom.geometry() ) ) );
|
||||
return pointSet;
|
||||
}
|
||||
|
||||
case QGis::WKBMultiPoint:
|
||||
{
|
||||
osgEarth::Features::PointSet* pointSet = new osgEarth::Features::PointSet();
|
||||
QgsMultiPointV2* multiPoint = static_cast<QgsMultiPointV2*>( geom.geometry() );
|
||||
for ( int i = 0, n = multiPoint->numGeometries(); i < n; ++i )
|
||||
{
|
||||
pointSet->push_back( pointFromQgsPoint( *static_cast<QgsPointV2*>( multiPoint->geometryN( i ) ) ) );
|
||||
}
|
||||
return pointSet;
|
||||
}
|
||||
|
||||
case QgsWKBTypes::LineString:
|
||||
case QgsWKBTypes::CircularString:
|
||||
case QgsWKBTypes::CompoundCurve:
|
||||
{
|
||||
return lineStringFromQgsLineString( static_cast<QgsLineStringV2*>( geom.geometry() ) );
|
||||
}
|
||||
|
||||
case QgsWKBTypes::MultiLineString:
|
||||
{
|
||||
osgEarth::Features::MultiGeometry* multiGeometry = new osgEarth::Features::MultiGeometry();
|
||||
QgsMultiLineStringV2* multiLineString = static_cast<QgsMultiLineStringV2*>( geom.geometry() );
|
||||
for ( int i = 0, n = multiLineString->numGeometries(); i < n; ++i )
|
||||
{
|
||||
multiGeometry->getComponents().push_back( lineStringFromQgsLineString( static_cast<QgsLineStringV2*>( multiLineString->geometryN( i ) ) ) );
|
||||
}
|
||||
return multiGeometry;
|
||||
}
|
||||
|
||||
case QgsWKBTypes::Polygon:
|
||||
case QgsWKBTypes::CurvePolygon:
|
||||
{
|
||||
return polygonFromQgsPolygon( static_cast<QgsPolygonV2*>( geom.geometry() ) );
|
||||
}
|
||||
|
||||
case QgsWKBTypes::MultiPolygon:
|
||||
{
|
||||
osgEarth::Features::MultiGeometry* multiGeometry = new osgEarth::Features::MultiGeometry();
|
||||
QgsMultiPolygonV2* multiPolygon = static_cast<QgsMultiPolygonV2*>( geom.geometry() );
|
||||
for ( int i = 0, n = multiPolygon->numGeometries(); i < n; ++i )
|
||||
{
|
||||
multiGeometry->getComponents().push_back( polygonFromQgsPolygon( static_cast<QgsPolygonV2*>( multiPolygon->geometryN( i ) ) ) );
|
||||
}
|
||||
return multiGeometry;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static osgEarth::Features::Feature* featureFromQgsFeature( QgsVectorLayer* layer, QgsFeature& feat )
|
||||
{
|
||||
osgEarth::Features::Geometry* nGeom = geometryFromQgsGeometry( *feat.geometry() );
|
||||
osgEarth::Features::Feature* retFeat = new osgEarth::Features::Feature( nGeom, 0, osgEarth::Style(), feat.id() );
|
||||
|
||||
const QgsFields& fields = layer->pendingFields();
|
||||
const QgsAttributes& attrs = feat.attributes();
|
||||
|
||||
for ( int idx = 0, numFlds = fields.size(); idx < numFlds; ++idx )
|
||||
{
|
||||
setFeatureField( retFeat, fields.at( idx ), attrs[idx] );
|
||||
}
|
||||
retFeat->setUserValue( "qgisLayerId", layer->id().toStdString() );
|
||||
|
||||
return retFeat;
|
||||
}
|
||||
|
||||
static void setFeatureField( osgEarth::Features::Feature* feature, const QgsField& field, const QVariant& value )
|
||||
{
|
||||
std::string name = field.name().toStdString();
|
||||
switch ( field.type() )
|
||||
{
|
||||
case QVariant::Bool:
|
||||
if ( !value.isNull() )
|
||||
feature->set( name, value.toBool() );
|
||||
else
|
||||
feature->setNull( name, osgEarth::Features::ATTRTYPE_BOOL );
|
||||
|
||||
break;
|
||||
|
||||
case QVariant::Int:
|
||||
case QVariant::UInt:
|
||||
case QVariant::LongLong:
|
||||
case QVariant::ULongLong:
|
||||
if ( !value.isNull() )
|
||||
feature->set( name, value.toInt() );
|
||||
else
|
||||
feature->setNull( name, osgEarth::Features::ATTRTYPE_INT );
|
||||
|
||||
break;
|
||||
|
||||
case QVariant::Double:
|
||||
if ( !value.isNull() )
|
||||
feature->set( name, value.toDouble() );
|
||||
else
|
||||
feature->setNull( name, osgEarth::Features::ATTRTYPE_DOUBLE );
|
||||
|
||||
break;
|
||||
|
||||
case QVariant::Char:
|
||||
case QVariant::String:
|
||||
default:
|
||||
if ( !value.isNull() )
|
||||
feature->set( name, value.toString().toStdString() );
|
||||
else
|
||||
feature->setNull( name, osgEarth::Features::ATTRTYPE_STRING );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static osgEarth::Features::FeatureSchema schemaForFields( const QgsFields& fields )
|
||||
{
|
||||
osgEarth::Features::FeatureSchema schema;
|
||||
|
||||
for ( int idx = 0, numFlds = fields.size(); idx < numFlds; ++idx )
|
||||
{
|
||||
const QgsField& fld = fields.at( idx );
|
||||
std::string name = fld.name().toStdString();
|
||||
|
||||
switch ( fld.type() )
|
||||
{
|
||||
case QVariant::Bool:
|
||||
schema.insert( std::make_pair( name, osgEarth::Features::ATTRTYPE_BOOL ) );
|
||||
break;
|
||||
|
||||
case QVariant::Int:
|
||||
case QVariant::UInt:
|
||||
case QVariant::LongLong:
|
||||
case QVariant::ULongLong:
|
||||
schema.insert( std::make_pair( name, osgEarth::Features::ATTRTYPE_INT ) );
|
||||
break;
|
||||
|
||||
case QVariant::Double:
|
||||
schema.insert( std::make_pair( name, osgEarth::Features::ATTRTYPE_DOUBLE ) );
|
||||
break;
|
||||
|
||||
case QVariant::Char:
|
||||
case QVariant::String:
|
||||
default:
|
||||
schema.insert( std::make_pair( name, osgEarth::Features::ATTRTYPE_STRING ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return schema;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // QGSGLOBEFEATUREUTILS_H
|
@ -19,171 +19,165 @@
|
||||
#ifndef QGS_GLOBE_PLUGIN_H
|
||||
#define QGS_GLOBE_PLUGIN_H
|
||||
|
||||
#include "qgsconfig.h"
|
||||
#include "qgisplugin.h"
|
||||
#include "qgsosgearthtilesource.h"
|
||||
#include "globe_plugin_dialog.h"
|
||||
#include <qgisplugin.h>
|
||||
#include <QObject>
|
||||
#include <osgViewer/Viewer>
|
||||
#include <osgEarth/MapNode>
|
||||
#include <osgEarth/ImageLayer>
|
||||
#include <osgEarthUtil/EarthManipulator>
|
||||
#ifndef HAVE_OSGEARTHQT //use backported controls if osgEarth <= 2.1
|
||||
#define USE_BACKPORTED_CONTROLS
|
||||
#endif
|
||||
#ifdef USE_BACKPORTED_CONTROLS
|
||||
#include "osgEarthUtil/Controls"
|
||||
using namespace osgEarth::Util::Controls21;
|
||||
#else
|
||||
#include <osgEarthUtil/Controls>
|
||||
using namespace osgEarth::Util::Controls;
|
||||
#endif
|
||||
#ifdef HAVE_OSGEARTH_ELEVATION_QUERY
|
||||
#include <osgEarth/ElevationQuery>
|
||||
#include <osgEarthUtil/ObjectLocator>
|
||||
#else
|
||||
#include <osgEarthUtil/ElevationManager>
|
||||
#include <osgEarthUtil/ObjectPlacer>
|
||||
#endif
|
||||
#include <osg/ref_ptr>
|
||||
#include <osgEarth/Version>
|
||||
|
||||
#if 0
|
||||
#include <iostream>
|
||||
#endif
|
||||
#include "qgsglobeinterface.h"
|
||||
#include "qgsglobeplugindialog.h"
|
||||
#include "qgsrectangle.h"
|
||||
|
||||
class QAction;
|
||||
class QToolBar;
|
||||
class QgisInterface;
|
||||
class QDateTime;
|
||||
class QDockWidget;
|
||||
class QgsAnnotationItem;
|
||||
class QgsBillBoardItem;
|
||||
class QgsGlobeAnnotation;
|
||||
class QgsGlobeLayerPropertiesFactory;
|
||||
class QgsGlobeInterface;
|
||||
class QgsGlobePluginDialog;
|
||||
class QgsGlobeWidget;
|
||||
class QgsMapLayer;
|
||||
class QgsPoint;
|
||||
class QgsRectangle;
|
||||
class QgsGlobeFrustumHighlightCallback;
|
||||
class QgsGlobeFeatureIdentifyCallback;
|
||||
class QgsGlobeTileSource;
|
||||
class QgsGlobeVectorLayerConfig;
|
||||
|
||||
namespace osgEarth { namespace QtGui { class ViewerWidget; } }
|
||||
namespace osgEarth { namespace Util { class SkyNode; class VerticalScale; } }
|
||||
namespace osg
|
||||
{
|
||||
class Group;
|
||||
class Vec3d;
|
||||
}
|
||||
namespace osgViewer { class Viewer; }
|
||||
|
||||
class GlobePlugin : public QObject, public QgisPlugin
|
||||
namespace osgEarth
|
||||
{
|
||||
class GeoPoint;
|
||||
class GeoExtent;
|
||||
class ImageLayer;
|
||||
class MapNode;
|
||||
namespace Annotation { class PlaceNode; }
|
||||
namespace QtGui { class ViewerWidget; }
|
||||
namespace Util
|
||||
{
|
||||
class FeatureHighlightCallback;
|
||||
class FeatureQueryTool;
|
||||
class SkyNode;
|
||||
class VerticalScale;
|
||||
namespace Controls
|
||||
{
|
||||
class Control;
|
||||
class ControlEventHandler;
|
||||
class LabelControl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class GLOBE_EXPORT GlobePlugin : public QObject, public QgisPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GlobePlugin( QgisInterface* theQgisInterface );
|
||||
virtual ~GlobePlugin();
|
||||
GlobePlugin( QgisInterface* theQgisInterface );
|
||||
~GlobePlugin();
|
||||
|
||||
public slots:
|
||||
//! offer an interface for python plugins
|
||||
virtual QgsPluginInterface* pluginInterface();
|
||||
//! init the gui
|
||||
virtual void initGui() override;
|
||||
//! Show the dialog box
|
||||
void run();
|
||||
//! Show the settings dialog box
|
||||
void settings();
|
||||
//! Reset globe
|
||||
void reset();
|
||||
//! unload the plugin
|
||||
void unload() override;
|
||||
//! show the help document
|
||||
void help();
|
||||
|
||||
//! Called when a new set of image layers has been received
|
||||
void imageLayersChanged();
|
||||
//! Called when a new set of elevation layers has been received
|
||||
void elevationLayersChanged();
|
||||
//! Set a different base map (QString::null will disable the base map)
|
||||
void setBaseMap( QString url );
|
||||
//! Called when the extents of the map change
|
||||
void setSkyParameters( bool enabled, const QDateTime& dateTime, bool autoAmbience );
|
||||
//! Called when the extents of the map change
|
||||
void extentsChanged();
|
||||
//! Sync globe extent to mapCanavas
|
||||
void syncExtent();
|
||||
#if OSGEARTH_VERSION_GREATER_OR_EQUAL( 2, 5, 0 )
|
||||
//! Set vertical scale
|
||||
void setVerticalScale( double scale );
|
||||
#endif
|
||||
//! Enable or disable frustum highlight
|
||||
void enableFrustumHighlight( bool statu );
|
||||
//! Enable or disable feature identification
|
||||
void enableFeatureIdentification( bool status );
|
||||
|
||||
//! called when a project has been read successfully
|
||||
void projectReady();
|
||||
//! called when a new project has been created successfully
|
||||
void blankProjectReady();
|
||||
//! called when the globe window is closed
|
||||
void setGlobeNotRunning();
|
||||
//! set the globe coordinates of a user right-click on the globe
|
||||
void setSelectedCoordinates( osg::Vec3d coords );
|
||||
void setSelectedCoordinates( const osg::Vec3d& coords );
|
||||
//! get a coordinates vector
|
||||
osg::Vec3d getSelectedCoordinates();
|
||||
//! prints the ccordinates in a QMessageBox
|
||||
void showSelectedCoordinates();
|
||||
//! emits signal with current mouse coordinates
|
||||
void showCurrentCoordinates( double lon, double lat );
|
||||
void showCurrentCoordinates( const osgEarth::GeoPoint &geoPoint );
|
||||
//! get longitude of user right click
|
||||
double getSelectedLon();
|
||||
double getSelectedLon() const { return mSelectedLon; }
|
||||
//! get latitude of user right click
|
||||
double getSelectedLat();
|
||||
double getSelectedLat() const { return mSelectedLat; }
|
||||
//! get elevation of user right click
|
||||
double getSelectedElevation();
|
||||
|
||||
//! Place an OSG model on the globe
|
||||
void placeNode( osg::Node* node, double lat, double lon, double alt = 0.0 );
|
||||
double getSelectedElevation() { return mSelectedElevation; }
|
||||
|
||||
//! Get the OSG viewer
|
||||
osgViewer::Viewer* osgViewer() { return mOsgViewer; }
|
||||
//! Get OSG map node
|
||||
osgEarth::MapNode* mapNode() { return mMapNode; }
|
||||
|
||||
//! Recursive copy folder
|
||||
static void copyFolder( QString sourceFolder, QString destFolder );
|
||||
QgisInterface* qgisIface() const { return mQGisIface; }
|
||||
|
||||
public slots:
|
||||
void run();
|
||||
void updateLayers();
|
||||
void showSettings();
|
||||
void syncExtent();
|
||||
|
||||
private:
|
||||
//! Set HTTP proxy settings
|
||||
void setupProxy();
|
||||
//! Setup map
|
||||
void setupMap();
|
||||
//! Setup map controls
|
||||
void setupControls();
|
||||
|
||||
private://! Checks if the globe is open
|
||||
//! Pointer to the QGIS interface object
|
||||
QgisInterface *mQGisIface;
|
||||
//!pointer to the qaction for this plugin
|
||||
QAction * mQActionPointer;
|
||||
//!pointer to the qaction for this plugin
|
||||
QAction * mQActionSettingsPointer;
|
||||
QAction * mQActionUnload;
|
||||
//! OSG Viewer
|
||||
osgViewer::Viewer* mOsgViewer;
|
||||
//! QT viewer widget
|
||||
|
||||
QAction* mActionToggleGlobe;
|
||||
osgEarth::QtGui::ViewerWidget* mViewerWidget;
|
||||
//! Settings Dialog
|
||||
QgsGlobePluginDialog *mSettingsDialog;
|
||||
//! OSG root node
|
||||
osg::Group* mRootNode;
|
||||
//! Map node
|
||||
osgEarth::MapNode* mMapNode;
|
||||
//! Base layer
|
||||
osg::ref_ptr<osgEarth::ImageLayer> mBaseLayer;
|
||||
//! Sky node
|
||||
osg::ref_ptr<osgEarth::Util::SkyNode> mSkyNode;
|
||||
#if OSGEARTH_VERSION_GREATER_OR_EQUAL( 2, 5, 0 )
|
||||
osg::ref_ptr<osgEarth::Util::VerticalScale> mVerticalScale;
|
||||
#endif
|
||||
//! QGIS maplayer
|
||||
osgEarth::ImageLayer* mQgisMapLayer;
|
||||
//! Tile source
|
||||
osgEarth::Drivers::QgsOsgEarthTileSource* mTileSource;
|
||||
//! Control Canvas
|
||||
ControlCanvas* mControlCanvas;
|
||||
#ifdef HAVE_OSGEARTH_ELEVATION_QUERY
|
||||
//! Elevation manager
|
||||
osgEarth::ElevationQuery* mElevationManager;
|
||||
//! Object placer
|
||||
osgEarth::Util::ObjectLocator* mObjectPlacer;
|
||||
#else
|
||||
//! Elevation manager
|
||||
osgEarth::Util::ElevationManager* mElevationManager;
|
||||
//! Object placer
|
||||
osgEarth::Util::ObjectPlacer* mObjectPlacer;
|
||||
#endif
|
||||
//! tracks if the globe is open
|
||||
bool mIsGlobeRunning;
|
||||
//! coordinates of the right-clicked point on the globe
|
||||
QgsGlobeWidget* mDockWidget;
|
||||
QgsGlobePluginDialog* mSettingsDialog;
|
||||
|
||||
QgsGlobeInterface mGlobeInterface;
|
||||
QString mBaseLayerUrl;
|
||||
QList<QgsGlobePluginDialog::LayerDataSource> mImagerySources;
|
||||
QList<QgsGlobePluginDialog::LayerDataSource> mElevationSources;
|
||||
double mSelectedLat, mSelectedLon, mSelectedElevation;
|
||||
|
||||
#if 0
|
||||
std::streambuf *mCoutRdBuf, *mCerrRdBuf;
|
||||
osg::ref_ptr<osgViewer::Viewer> mOsgViewer;
|
||||
osg::ref_ptr<osgEarth::MapNode> mMapNode;
|
||||
osg::ref_ptr<osg::Group> mRootNode;
|
||||
osg::ref_ptr<osgEarth::Util::SkyNode> mSkyNode;
|
||||
osg::ref_ptr<osgEarth::ImageLayer> mBaseLayer;
|
||||
osg::ref_ptr<osgEarth::ImageLayer> mQgisMapLayer;
|
||||
osg::ref_ptr<QgsGlobeTileSource> mTileSource;
|
||||
QMap<QString, QgsRectangle> mLayerExtents;
|
||||
osg::ref_ptr<osgEarth::Util::VerticalScale> mVerticalScale;
|
||||
|
||||
//! Creates additional pages in the layer properties for adjusting 3D properties
|
||||
QgsGlobeLayerPropertiesFactory* mLayerPropertiesFactory;
|
||||
osg::ref_ptr<QgsGlobeFrustumHighlightCallback> mFrustumHighlightCallback;
|
||||
osg::ref_ptr<QgsGlobeFeatureIdentifyCallback> mFeatureQueryToolIdentifyCb;
|
||||
// TODO: How to port highlight to 2.7.0?
|
||||
#if OSGEARTH_VERSION_LESS_THAN(2, 7, 0)
|
||||
osg::ref_ptr<osgEarth::Util::FeatureHighlightCallback> mFeatureQueryToolHighlightCb;
|
||||
#endif
|
||||
osg::ref_ptr<osgEarth::Util::FeatureQueryTool> mFeatureQueryTool;
|
||||
osg::ref_ptr<osgEarth::Util::Controls::LabelControl> mStatsLabel;
|
||||
|
||||
osg::Group* mAnnotationsGroup;
|
||||
QMap<QString, QMap<QgsBillBoardItem*, osg::ref_ptr<osgEarth::Annotation::PlaceNode> > > mAnnotations;
|
||||
|
||||
void setupProxy();
|
||||
void addControl( osgEarth::Util::Controls::Control* control, int x, int y, int w, int h, osgEarth::Util::Controls::ControlEventHandler* handler );
|
||||
void addImageControl( const std::string &imgPath, int x, int y, osgEarth::Util::Controls::ControlEventHandler* handler = 0 );
|
||||
void addModelLayer( QgsVectorLayer* mapLayer , QgsGlobeVectorLayerConfig *layerConfig );
|
||||
void setupControls();
|
||||
void applyProjectSettings();
|
||||
|
||||
private slots:
|
||||
void setGlobeEnabled( bool enabled );
|
||||
void reset();
|
||||
void projectRead();
|
||||
void applySettings();
|
||||
void layerChanged( QgsMapLayer* mapLayer = 0 );
|
||||
void addBillboard( QgsBillBoardItem* item );
|
||||
void removeBillboard( QgsBillBoardItem* item );
|
||||
void refreshQGISMapLayer( QgsRectangle rect = QgsRectangle() );
|
||||
void updateTileStats( int queued, int tot );
|
||||
|
||||
signals:
|
||||
//! emits current mouse position
|
||||
@ -192,82 +186,4 @@ class GlobePlugin : public QObject, public QgisPlugin
|
||||
void newCoordinatesSelected( const QgsPoint & p );
|
||||
};
|
||||
|
||||
class FlyToExtentHandler : public osgGA::GUIEventHandler
|
||||
{
|
||||
public:
|
||||
explicit FlyToExtentHandler( GlobePlugin* globe ) : mGlobe( globe ) { }
|
||||
|
||||
bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa ) override;
|
||||
|
||||
private:
|
||||
GlobePlugin* mGlobe;
|
||||
};
|
||||
|
||||
// An event handler that will print out the coordinates at the clicked point
|
||||
#ifdef HAVE_OSGEARTH_ELEVATION_QUERY
|
||||
#else
|
||||
class QueryCoordinatesHandler : public osgGA::GUIEventHandler
|
||||
{
|
||||
public:
|
||||
QueryCoordinatesHandler( GlobePlugin* globe, osgEarth::Util::ElevationManager* elevMan,
|
||||
const osgEarth::SpatialReference* mapSRS )
|
||||
: mGlobe( globe ), _mapSRS( mapSRS ), _elevMan( elevMan ) { }
|
||||
|
||||
bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa );
|
||||
|
||||
virtual osg::Vec3d getCoords( float x, float y, osgViewer::View* view, bool getElevation = false );
|
||||
|
||||
private:
|
||||
GlobePlugin* mGlobe;
|
||||
osg::ref_ptr<const SpatialReference> _mapSRS;
|
||||
osg::ref_ptr<osgEarth::Util::ElevationManager> _elevMan;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
class KeyboardControlHandler : public osgGA::GUIEventHandler
|
||||
{
|
||||
public:
|
||||
explicit KeyboardControlHandler( osgEarth::Util::EarthManipulator* manip ) : _manip( manip ) { }
|
||||
|
||||
bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa ) override;
|
||||
|
||||
private:
|
||||
osg::observer_ptr<osgEarth::Util::EarthManipulator> _manip;
|
||||
};
|
||||
|
||||
|
||||
namespace osgEarth
|
||||
{
|
||||
namespace Util
|
||||
{
|
||||
#ifdef USE_BACKPORTED_CONTROLS
|
||||
namespace Controls21
|
||||
#else
|
||||
namespace Controls
|
||||
#endif
|
||||
{
|
||||
class NavigationControlHandler : public ControlEventHandler
|
||||
{
|
||||
public:
|
||||
virtual void onMouseDown( class Control* control, int mouseButtonMask ) { Q_UNUSED( control ); Q_UNUSED( mouseButtonMask ); }
|
||||
virtual void onClick( class Control* control, int mouseButtonMask, const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa ) { Q_UNUSED( control ); Q_UNUSED( mouseButtonMask ); Q_UNUSED( ea ); Q_UNUSED( aa ); }
|
||||
virtual void onClick( class Control* control, int mouseButtonMask ) override { Q_UNUSED( control ); Q_UNUSED( mouseButtonMask ); }
|
||||
};
|
||||
|
||||
class NavigationControl : public ImageControl
|
||||
{
|
||||
public:
|
||||
explicit NavigationControl( osg::Image* image = nullptr ) : ImageControl( image ), _mouse_down_event( nullptr ) {}
|
||||
|
||||
protected:
|
||||
virtual bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, ControlContext& cx ) override;
|
||||
|
||||
private:
|
||||
osg::ref_ptr<const osgGA::GUIEventAdapter> _mouse_down_event;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // QGS_GLOBE_PLUGIN_H
|
||||
|
@ -1,6 +1,6 @@
|
||||
<RCC>
|
||||
<qresource prefix="/globe/" >
|
||||
<qresource prefix="/globe">
|
||||
<file alias="globe.png">images/globe.png</file>
|
||||
<file alias="icon.svg">images/icon.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
|
@ -1,700 +0,0 @@
|
||||
/***************************************************************************
|
||||
* globe_plugin_dialog.cpp - settings dialog for the globe plugin
|
||||
* --------------------------------------
|
||||
* Date : 11-Nov-2010
|
||||
* Copyright : (C) 2010 by Marco Bernasocchi
|
||||
* Email : marco at bernawebdesign.ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 "globe_plugin_dialog.h"
|
||||
#include "globe_plugin.h"
|
||||
|
||||
#include <qgsapplication.h>
|
||||
#include <qgsproject.h>
|
||||
#include <qgsmaplayerregistry.h>
|
||||
#include <qgsmaplayer.h>
|
||||
#include <qgslogger.h>
|
||||
#include <qgscontexthelp.h>
|
||||
#include <QtAlgorithms>
|
||||
#include <QtDebug>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QSettings>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include <QVariant>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkReply>
|
||||
|
||||
#include <osg/DisplaySettings>
|
||||
|
||||
//constructor
|
||||
QgsGlobePluginDialog::QgsGlobePluginDialog( QWidget* parent, GlobePlugin* globe, Qt::WindowFlags fl )
|
||||
: QDialog( parent, fl )
|
||||
, mGlobe( globe )
|
||||
{
|
||||
setupUi( this );
|
||||
|
||||
mBaseLayerComboBox->addItem( "Readymap: NASA BlueMarble Imagery", "http://readymap.org/readymap/tiles/1.0.0/1/" );
|
||||
mBaseLayerComboBox->addItem( "Readymap: NASA BlueMarble with land removed, only ocean", "http://readymap.org/readymap/tiles/1.0.0/2/" );
|
||||
mBaseLayerComboBox->addItem( "Readymap: High resolution insets from various locations around the world Austin, TX; Kandahar, Afghanistan; Bagram, Afghanistan; Boston, MA; Washington, DC", "http://readymap.org/readymap/tiles/1.0.0/3/" );
|
||||
mBaseLayerComboBox->addItem( "Readymap: Global Land Cover Facility 15m Landsat", "http://readymap.org/readymap/tiles/1.0.0/6/" );
|
||||
mBaseLayerComboBox->addItem( "Readymap: NASA BlueMarble + Landsat + Ocean Masking Layer", "http://readymap.org/readymap/tiles/1.0.0/7/" );
|
||||
mBaseLayerComboBox->addItem( "[Custom]" );
|
||||
|
||||
loadStereoConfig(); //values from settings, default values from OSG
|
||||
setStereoConfig(); //overwrite with values from QSettings
|
||||
updateStereoDialog(); //update the dialog gui
|
||||
loadVideoSettings();
|
||||
loadMapSettings();
|
||||
|
||||
elevationPath->setText( QDir::homePath() );
|
||||
}
|
||||
|
||||
//destructor
|
||||
QgsGlobePluginDialog::~QgsGlobePluginDialog()
|
||||
{
|
||||
}
|
||||
|
||||
QString QgsGlobePluginDialog::openRasterFile()
|
||||
{
|
||||
//see http://www.gdal.org/formats_list.html
|
||||
QString filter = tr( "GDAL files" ) + " (*.dem *.tif *.tiff *.jpg *.jpeg *.asc);;"
|
||||
+ tr( "DEM files" ) + " (*.dem);;"
|
||||
+ tr( "All files" ) + " (*.*)";
|
||||
QString path = QFileDialog::getOpenFileName( this,
|
||||
tr( "Open raster file" ),
|
||||
QDir::homePath(),
|
||||
filter );
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
bool QgsGlobePluginDialog::validateResource( QString type, QString uri, QString &error )
|
||||
{
|
||||
if ( "Raster" == type )
|
||||
{
|
||||
QFileInfo file( uri );
|
||||
if ( file.isFile() && file.isReadable() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
error = tr( "Invalid Path: The file is either unreadable or does not exist" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QNetworkAccessManager *manager = new QNetworkAccessManager( this );
|
||||
QNetworkRequest request;
|
||||
request.setUrl( QUrl( uri ) );
|
||||
QNetworkReply *reply = manager->get( request );
|
||||
|
||||
//wait for response syncronously
|
||||
QEventLoop eLoop;
|
||||
connect( manager, SIGNAL( finished( QNetworkReply * ) ),
|
||||
&eLoop, SLOT( quit() ) );
|
||||
eLoop.exec( QEventLoop::ExcludeUserInputEvents );
|
||||
|
||||
if ( QNetworkReply::HostNotFoundError != reply->error() )
|
||||
//FIXME:should be the following line but reply->error() always give "unknown error"
|
||||
//if (QNetworkReply::NoError == reply->error())
|
||||
{
|
||||
QByteArray data = reply->readAll();
|
||||
QString req( data );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
error = tr( "Invalid URL: " ) + reply->errorString();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::showMessageBox( QString text )
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText( text );
|
||||
msgBox.exec();
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_buttonBox_accepted()
|
||||
{
|
||||
setStereoConfig();
|
||||
saveStereoConfig();
|
||||
|
||||
saveElevationDatasources();
|
||||
saveVideoSettings();
|
||||
saveMapSettings();
|
||||
accept();
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_buttonBox_rejected()
|
||||
{
|
||||
loadStereoConfig();
|
||||
setStereoConfig();
|
||||
readElevationDatasources();
|
||||
reject();
|
||||
}
|
||||
|
||||
//ELEVATION
|
||||
void QgsGlobePluginDialog::on_elevationCombo_currentIndexChanged( QString type )
|
||||
{
|
||||
elevationPath->setEnabled( true );
|
||||
if ( "Raster" == type )
|
||||
{
|
||||
elevationActions->setCurrentIndex( 0 );
|
||||
elevationPath->setText( QDir::homePath() );
|
||||
}
|
||||
else if ( "Worldwind" == type )
|
||||
{
|
||||
elevationActions->setCurrentIndex( 1 );
|
||||
elevationPath->setText( "http://tileservice.worldwindcentral.com/getTile?bmng.topo.bathy.200401" );
|
||||
elevationPath->setEnabled( false );
|
||||
}
|
||||
else if ( "TMS" == type )
|
||||
{
|
||||
elevationActions->setCurrentIndex( 1 );
|
||||
elevationPath->setText( "http://readymap.org/readymap/tiles/1.0.0/9/" );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_elevationBrowse_clicked()
|
||||
{
|
||||
QString newPath = openRasterFile();
|
||||
if ( ! newPath.isEmpty() )
|
||||
{
|
||||
elevationPath->setText( newPath );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_elevationAdd_clicked()
|
||||
{
|
||||
QString errorText;
|
||||
bool validationResult = validateResource( elevationCombo->currentText(), elevationPath->text(), errorText );
|
||||
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText( errorText );
|
||||
msgBox.setInformativeText( tr( "Do you want to add the datasource anyway?" ) );
|
||||
msgBox.setIcon( QMessageBox::Warning );
|
||||
msgBox.setStandardButtons( QMessageBox::Ok | QMessageBox::Cancel );
|
||||
msgBox.setDefaultButton( QMessageBox::Cancel );
|
||||
|
||||
if ( validationResult || msgBox.exec() == QMessageBox::Ok )
|
||||
{
|
||||
int i = elevationDatasourcesWidget->rowCount();
|
||||
QTableWidgetItem *type = new QTableWidgetItem( elevationCombo->currentText() );
|
||||
QTableWidgetItem *uri = new QTableWidgetItem( elevationPath->text() );
|
||||
QTableWidgetItem* cache = new QTableWidgetItem();
|
||||
//cache->setCheckState(( elevationCombo->currentText() == "Worldwind" ) ? Qt::Checked : Qt::Unchecked ); //worldwind_cache will be active
|
||||
elevationDatasourcesWidget->setRowCount( 1 + i );
|
||||
elevationDatasourcesWidget->setItem( i, 0, type );
|
||||
elevationDatasourcesWidget->setItem( i, 1, cache );
|
||||
elevationDatasourcesWidget->setItem( i, 2, uri );
|
||||
elevationDatasourcesWidget->setCurrentItem( type, QItemSelectionModel::Clear );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_elevationRemove_clicked()
|
||||
{
|
||||
elevationDatasourcesWidget->removeRow( elevationDatasourcesWidget->currentRow() );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_elevationUp_clicked()
|
||||
{
|
||||
moveRow( elevationDatasourcesWidget, true );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_elevationDown_clicked()
|
||||
{
|
||||
moveRow( elevationDatasourcesWidget, false );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_mBaseLayerComboBox_currentIndexChanged( int index )
|
||||
{
|
||||
QVariant url = mBaseLayerComboBox->itemData( index );
|
||||
if ( url.isValid() )
|
||||
{
|
||||
mBaseLayerURL->setEnabled( false );
|
||||
mBaseLayerURL->setText( url.toString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
mBaseLayerURL->setEnabled( true );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::moveRow( QTableWidget* widget, bool up )
|
||||
{
|
||||
//moves QTableWidget row up or down
|
||||
if ( widget->selectedItems().count() > 0 )
|
||||
{
|
||||
const int sourceRow = widget->currentItem()->row();
|
||||
const int destRow = ( up ? sourceRow - 1 : sourceRow + 1 );
|
||||
if ( destRow >= 0 && destRow < widget->rowCount() )
|
||||
{
|
||||
// take whole rows
|
||||
QList<QTableWidgetItem*> sourceItems = takeRow( widget, sourceRow );
|
||||
QList<QTableWidgetItem*> destItems = takeRow( widget, destRow );
|
||||
|
||||
// set back in reverse order
|
||||
setRow( widget, sourceRow, destItems );
|
||||
setRow( widget, destRow, sourceItems );
|
||||
widget->selectRow( destRow );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QList<QTableWidgetItem*> QgsGlobePluginDialog::takeRow( QTableWidget* widget, int row )
|
||||
{
|
||||
// takes and returns the whole row
|
||||
QList<QTableWidgetItem*> rowItems;
|
||||
for ( int col = 0; col < widget->columnCount(); ++col )
|
||||
{
|
||||
rowItems << widget->takeItem( row, col );
|
||||
}
|
||||
return rowItems;
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::setRow( QTableWidget* widget, int row, const QList<QTableWidgetItem*>& rowItems )
|
||||
{
|
||||
// sets the whole row
|
||||
for ( int col = 0; col < widget->columnCount(); ++col )
|
||||
{
|
||||
widget->setItem( row, col, rowItems.at( col ) );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::resetElevationDatasources()
|
||||
{
|
||||
elevationDatasourcesWidget->clearContents();
|
||||
elevationDatasourcesWidget->setRowCount( 1 );
|
||||
elevationDatasourcesWidget->setItem( 0, 0, new QTableWidgetItem( "TMS" ) );
|
||||
elevationDatasourcesWidget->setItem( 0, 1, new QTableWidgetItem() );
|
||||
//elevationDatasourcesWidget->item( 0, 1 )->setCheckState( Qt::Unchecked );
|
||||
elevationDatasourcesWidget->setItem( 0, 2, new QTableWidgetItem( "http://readymap.org/readymap/tiles/1.0.0/9/" ) );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::readElevationDatasources()
|
||||
{
|
||||
// clear the widget
|
||||
elevationDatasourcesWidget->clearContents();
|
||||
elevationDatasourcesWidget->setRowCount( 0 );
|
||||
int keysCount = QgsProject::instance()->subkeyList( "Globe-Plugin", "/elevationDatasources/" ).count();
|
||||
for ( int i = 0; i < keysCount; ++i )
|
||||
{
|
||||
QString iNum;
|
||||
iNum.setNum( i );
|
||||
QTableWidgetItem *type = new QTableWidgetItem(
|
||||
QgsProject::instance()->readEntry( "Globe-Plugin", "/elevationDatasources/L" + iNum + "/type" ) );
|
||||
QTableWidgetItem *uri = new QTableWidgetItem(
|
||||
QgsProject::instance()->readEntry( "Globe-Plugin", "/elevationDatasources/L" + iNum + "/uri" ) );
|
||||
//bool cache = QgsProject::instance()->readBoolEntry( "Globe-Plugin", "/elevationDatasources/L" + iNum + "/cache" );
|
||||
|
||||
elevationDatasourcesWidget->setRowCount( 1 + i );
|
||||
elevationDatasourcesWidget->setItem( i, 0, type );
|
||||
QTableWidgetItem* chkBoxItem = new QTableWidgetItem();
|
||||
//chkBoxItem->setCheckState( cache ? Qt::Checked : Qt::Unchecked );
|
||||
elevationDatasourcesWidget->setItem( i, 1, chkBoxItem );
|
||||
elevationDatasourcesWidget->setItem( i, 2, uri );
|
||||
}
|
||||
|
||||
#if OSGEARTH_VERSION_GREATER_OR_EQUAL( 2, 5, 0 )
|
||||
double scale = QgsProject::instance()->readDoubleEntry( "Globe-Plugin", "/verticalScale", 1 );
|
||||
mTxtVerticalScale->setValue( scale );
|
||||
mGlobe->setVerticalScale( scale );
|
||||
#endif
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::saveElevationDatasources()
|
||||
{
|
||||
bool somethingChanged = false;
|
||||
int keysCount = QgsProject::instance()->subkeyList( "Globe-Plugin", "/elevationDatasources/" ).count();
|
||||
int rowsCount = elevationDatasourcesWidget->rowCount();
|
||||
|
||||
for ( int i = 0; i < rowsCount; ++i )
|
||||
{
|
||||
QString iNum;
|
||||
iNum.setNum( i );
|
||||
QString typeKey = QgsProject::instance()->readEntry( "Globe-Plugin", "/elevationDatasources/L" + iNum + "/type" );
|
||||
QString uriKey = QgsProject::instance()->readEntry( "Globe-Plugin", "/elevationDatasources/L" + iNum + "/uri" );
|
||||
bool cacheKey = QgsProject::instance()->readBoolEntry( "Globe-Plugin", "/elevationDatasources/L" + iNum + "/cache" );
|
||||
|
||||
QString type = elevationDatasourcesWidget->item( i, 0 )->text();
|
||||
QString uri = elevationDatasourcesWidget->item( i, 2 )->text();
|
||||
bool cache = elevationDatasourcesWidget->item( i, 1 )->checkState();
|
||||
|
||||
if ( typeKey != type || uriKey != uri || cacheKey != cache )
|
||||
{
|
||||
somethingChanged = true;
|
||||
QgsProject::instance()->writeEntry( "Globe-Plugin", "/elevationDatasources/L" + iNum + "/type", type );
|
||||
QgsProject::instance()->writeEntry( "Globe-Plugin", "/elevationDatasources/L" + iNum + "/uri", uri );
|
||||
QgsProject::instance()->writeEntry( "Globe-Plugin", "/elevationDatasources/L" + iNum + "/cache", cache );
|
||||
QgsDebugMsg( "editing at " + iNum );
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsDebugMsg( "nothing to do at " + iNum );
|
||||
}
|
||||
}
|
||||
|
||||
if ( keysCount > rowsCount )
|
||||
{
|
||||
//elminate superfluous keys
|
||||
somethingChanged = true;
|
||||
for ( int i = rowsCount; i < keysCount; ++i )
|
||||
{
|
||||
QString iNum;
|
||||
iNum.setNum( i );
|
||||
QgsDebugMsg( "deleting " + iNum );
|
||||
QgsProject::instance()->removeEntry( "Globe-Plugin", "/elevationDatasources/L" + iNum + "/" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( somethingChanged )
|
||||
{
|
||||
QgsDebugMsg( "emitting elevationDatasourcesChanged" );
|
||||
emit elevationDatasourcesChanged();
|
||||
}
|
||||
|
||||
#if OSGEARTH_VERSION_GREATER_OR_EQUAL( 2, 5, 0 )
|
||||
double scale = mTxtVerticalScale->value();
|
||||
mGlobe->setVerticalScale( scale );
|
||||
QgsProject::instance()->writeEntry( "Globe-Plugin", "/verticalScale", scale );
|
||||
#endif
|
||||
}
|
||||
//END ELEVATION
|
||||
|
||||
//MODEL
|
||||
QList<QgsVectorLayer*> QgsGlobePluginDialog::pointLayers()
|
||||
{
|
||||
QList<QgsVectorLayer*> list;
|
||||
QMap< QString, QgsMapLayer *> layers = QgsMapLayerRegistry::instance()->mapLayers();
|
||||
QMapIterator<QString, QgsMapLayer *> it( layers );
|
||||
while ( it.hasNext() )
|
||||
{
|
||||
it.next();
|
||||
QgsMapLayer* layer = it.value();
|
||||
if ( layer->type() == QgsMapLayer::VectorLayer )
|
||||
{
|
||||
QgsVectorLayer* vectorLayer = static_cast<QgsVectorLayer*>( layer );
|
||||
if ( vectorLayer->geometryType() == QGis::Point )
|
||||
{
|
||||
list.append( vectorLayer );
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::updatePointLayers()
|
||||
{
|
||||
modelLayerCombo->clear();
|
||||
QList<QgsVectorLayer*> layers = pointLayers();
|
||||
QListIterator<QgsVectorLayer*> it( layers );
|
||||
while ( it.hasNext() )
|
||||
{
|
||||
QgsVectorLayer* layer = it.next();
|
||||
modelLayerCombo->addItem( layer->name() );
|
||||
}
|
||||
}
|
||||
|
||||
QgsVectorLayer* QgsGlobePluginDialog::modelLayer()
|
||||
{
|
||||
QList<QgsVectorLayer*> layers = pointLayers();
|
||||
return ( modelLayerCombo->currentIndex() == -1 ) ? nullptr : layers.at( modelLayerCombo->currentIndex() );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_modelBrowse_clicked()
|
||||
{
|
||||
//see http://www.openscenegraph.org/projects/osg/wiki/Support/UserGuides/Plugins
|
||||
QString path = QFileDialog::getOpenFileName( this,
|
||||
tr( "Open 3D model file" ),
|
||||
QDir::homePath(),
|
||||
tr( "Model files" ) + " (*.3dc *.asc *.3ds *.ac *.bsp *.dae *.dw *.dxf *.fbx *.gem *.geo *.iv *.wrl *.ive *.logo *.lwo *.lw *.geo *.lws *.md2 *.obj *.ogr *.flt *.osg *.shp *.stl *.sta *.wrl *.x);;"
|
||||
+ tr( "All files" ) + " (*.*)"
|
||||
);
|
||||
|
||||
if ( ! path.isEmpty() )
|
||||
{
|
||||
modelPathLineEdit->setText( path );
|
||||
}
|
||||
}
|
||||
//END MODEL
|
||||
|
||||
//STEREO
|
||||
void QgsGlobePluginDialog::on_resetStereoDefaults_clicked()
|
||||
{
|
||||
//http://www.openscenegraph.org/projects/osg/wiki/Support/UserGuides/StereoSettings
|
||||
comboStereoMode->setCurrentIndex( comboStereoMode->findText( "OFF" ) );
|
||||
screenDistance->setValue( 0.5 );
|
||||
screenHeight->setValue( 0.26 );
|
||||
screenWidth->setValue( 0.325 );
|
||||
eyeSeparation->setValue( 0.06 );
|
||||
splitStereoHorizontalSeparation->setValue( 42 );
|
||||
splitStereoVerticalSeparation->setValue( 42 );
|
||||
splitStereoHorizontalEyeMapping->setCurrentIndex( 0 );
|
||||
splitStereoVerticalEyeMapping->setCurrentIndex( 0 );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_comboStereoMode_currentIndexChanged( QString value )
|
||||
{
|
||||
Q_UNUSED( value );
|
||||
setStereoMode();
|
||||
updateStereoDialog();
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_eyeSeparation_valueChanged( double value )
|
||||
{
|
||||
osg::DisplaySettings::instance()->setEyeSeparation( value );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_screenDistance_valueChanged( double value )
|
||||
{
|
||||
osg::DisplaySettings::instance()->setScreenDistance( value );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_screenWidth_valueChanged( double value )
|
||||
{
|
||||
osg::DisplaySettings::instance()->setScreenWidth( value );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_screenHeight_valueChanged( double value )
|
||||
{
|
||||
osg::DisplaySettings::instance()->setScreenHeight( value );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_splitStereoHorizontalSeparation_valueChanged( int value )
|
||||
{
|
||||
osg::DisplaySettings::instance()->setSplitStereoHorizontalSeparation( value );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_splitStereoVerticalSeparation_valueChanged( int value )
|
||||
{
|
||||
osg::DisplaySettings::instance()->setSplitStereoVerticalSeparation( value );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_splitStereoHorizontalEyeMapping_currentIndexChanged( int value )
|
||||
{
|
||||
osg::DisplaySettings::instance()->setSplitStereoHorizontalEyeMapping(
|
||||
( osg::DisplaySettings::SplitStereoHorizontalEyeMapping ) value );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_splitStereoVerticalEyeMapping_currentIndexChanged( int value )
|
||||
{
|
||||
osg::DisplaySettings::instance()->setSplitStereoVerticalEyeMapping(
|
||||
( osg::DisplaySettings::SplitStereoVerticalEyeMapping ) value );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::loadStereoConfig()
|
||||
{
|
||||
comboStereoMode->setCurrentIndex( comboStereoMode->findText( settings.value( "/Plugin-Globe/stereoMode",
|
||||
"OFF" ).toString() ) );
|
||||
screenDistance->setValue( settings.value( "/Plugin-Globe/screenDistance",
|
||||
osg::DisplaySettings::instance()->getScreenDistance() ).toDouble() );
|
||||
screenWidth->setValue( settings.value( "/Plugin-Globe/screenWidth",
|
||||
osg::DisplaySettings::instance()->getScreenWidth() ).toDouble() );
|
||||
screenHeight->setValue( settings.value( "/Plugin-Globe/screenHeight",
|
||||
osg::DisplaySettings::instance()->getScreenHeight() ).toDouble() );
|
||||
eyeSeparation->setValue( settings.value( "/Plugin-Globe/eyeSeparation",
|
||||
osg::DisplaySettings::instance()->getEyeSeparation() ).toDouble() );
|
||||
splitStereoHorizontalSeparation->setValue( settings.value( "/Plugin-Globe/splitStereoHorizontalSeparation",
|
||||
osg::DisplaySettings::instance()->getSplitStereoHorizontalSeparation() ).toInt() );
|
||||
splitStereoVerticalSeparation->setValue( settings.value( "/Plugin-Globe/splitStereoVerticalSeparation",
|
||||
osg::DisplaySettings::instance()->getSplitStereoVerticalSeparation() ).toInt() );
|
||||
splitStereoHorizontalEyeMapping->setCurrentIndex( settings.value( "/Plugin-Globe/splitStereoHorizontalEyeMapping",
|
||||
osg::DisplaySettings::instance()->getSplitStereoHorizontalEyeMapping() ).toInt() );
|
||||
splitStereoVerticalEyeMapping->setCurrentIndex( settings.value( "/Plugin-Globe/splitStereoVerticalEyeMapping",
|
||||
osg::DisplaySettings::instance()->getSplitStereoVerticalEyeMapping() ).toInt() );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::setStereoMode()
|
||||
{
|
||||
//http://www.openscenegraph.org/projects/osg/wiki/Support/UserGuides/StereoSettings
|
||||
//http://www.openscenegraph.org/documentation/OpenSceneGraphReferenceDocs/a00181.html
|
||||
|
||||
QString stereoMode = comboStereoMode->currentText();
|
||||
if ( "OFF" == stereoMode )
|
||||
{
|
||||
osg::DisplaySettings::instance()->setStereo( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::DisplaySettings::instance()->setStereo( true );
|
||||
|
||||
if ( "ANAGLYPHIC" == stereoMode )
|
||||
{
|
||||
osg::DisplaySettings::instance()->setStereoMode( osg::DisplaySettings::ANAGLYPHIC );
|
||||
}
|
||||
else if ( "VERTICAL_SPLIT" == stereoMode )
|
||||
{
|
||||
osg::DisplaySettings::instance()->setStereoMode( osg::DisplaySettings::VERTICAL_SPLIT );
|
||||
}
|
||||
else if ( "HORIZONTAL_SPLIT" == stereoMode )
|
||||
{
|
||||
osg::DisplaySettings::instance()->setStereoMode( osg::DisplaySettings::HORIZONTAL_SPLIT );
|
||||
}
|
||||
else if ( "QUAD_BUFFER" == stereoMode )
|
||||
{
|
||||
osg::DisplaySettings::instance()->setStereoMode( osg::DisplaySettings::QUAD_BUFFER );
|
||||
}
|
||||
else
|
||||
{
|
||||
//should never get here
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText( "This stereo mode has not been implemented yet. Defaulting to ANAGLYPHIC" );
|
||||
msgBox.exec();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::loadVideoSettings()
|
||||
{
|
||||
mAntiAliasingGroupBox->setChecked( settings.value( "/Plugin-Globe/anti-aliasing", false ).toBool() );
|
||||
mAANumSamples->setValidator( new QIntValidator( mAANumSamples ) );
|
||||
mAANumSamples->setText( settings.value( "/Plugin-Globe/anti-aliasing-level", "" ).toString() );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::saveVideoSettings()
|
||||
{
|
||||
settings.setValue( "/Plugin-Globe/anti-aliasing", mAntiAliasingGroupBox->isChecked() );
|
||||
settings.setValue( "/Plugin-Globe/anti-aliasing-level", mAANumSamples->text() );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::loadMapSettings()
|
||||
{
|
||||
mBaseLayerGroupBox->setChecked( settings.value( "/Plugin-Globe/baseLayerEnabled", true ).toBool() );
|
||||
QString mapUrl = settings.value( "/Plugin-Globe/baseLayerURL", "http://readymap.org/readymap/tiles/1.0.0/7/" ).toString();
|
||||
int urlIndex = mBaseLayerComboBox->findData( mapUrl );
|
||||
|
||||
if ( urlIndex != -1 )
|
||||
{
|
||||
mBaseLayerComboBox->setCurrentIndex( urlIndex );
|
||||
}
|
||||
else
|
||||
{
|
||||
mBaseLayerComboBox->setCurrentIndex( mBaseLayerComboBox->findData( QVariant() ) );
|
||||
}
|
||||
|
||||
mBaseLayerURL->setText( mapUrl );
|
||||
|
||||
mSkyGroupBox->setChecked( settings.value( "/Plugin-Globe/skyEnabled", false ).toBool() );
|
||||
mSkyAutoAmbient->setChecked( settings.value( "/Plugin-Globe/skyAutoAmbient", false ).toBool() );
|
||||
mSkyDateTime->setDateTime( settings.value( "/Plugin-Globe/skyDateTime", QDateTime() ).toDateTime() );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::saveMapSettings()
|
||||
{
|
||||
settings.setValue( "/Plugin-Globe/baseLayerEnabled", mBaseLayerGroupBox->isChecked() );
|
||||
settings.setValue( "/Plugin-Globe/baseLayerURL", mBaseLayerURL->text() );
|
||||
|
||||
// Let globe update the current view
|
||||
if ( mBaseLayerGroupBox->isChecked() )
|
||||
{
|
||||
mGlobe->setBaseMap( mBaseLayerURL->text() );
|
||||
}
|
||||
else
|
||||
{
|
||||
mGlobe->setBaseMap( QString::null );
|
||||
}
|
||||
|
||||
settings.setValue( "/Plugin-Globe/skyEnabled", mSkyGroupBox->isChecked() );
|
||||
settings.setValue( "/Plugin-Globe/skyAutoAmbient", mSkyAutoAmbient->isChecked() );
|
||||
settings.setValue( "/Plugin-Globe/skyDateTime", mSkyDateTime->dateTime() );
|
||||
|
||||
// Adjust sky of a running globe viewer
|
||||
mGlobe->setSkyParameters( mSkyGroupBox->isChecked(), mSkyDateTime->dateTime(), mSkyAutoAmbient->isChecked() );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::setStereoConfig()
|
||||
{
|
||||
osgViewer::Viewer* viewer = mGlobe->osgViewer();
|
||||
if ( viewer )
|
||||
{
|
||||
viewer->getDatabasePager()->clear();
|
||||
//SETTING THE VALUES IN THE OEGearth instance
|
||||
setStereoMode();
|
||||
osg::DisplaySettings::instance()->setScreenDistance( screenDistance->value() );
|
||||
osg::DisplaySettings::instance()->setScreenWidth( screenWidth->value() );
|
||||
osg::DisplaySettings::instance()->setScreenHeight( screenHeight->value() );
|
||||
osg::DisplaySettings::instance()->setEyeSeparation( eyeSeparation->value() );
|
||||
osg::DisplaySettings::instance()->setSplitStereoHorizontalSeparation( splitStereoHorizontalSeparation->value() );
|
||||
osg::DisplaySettings::instance()->setSplitStereoVerticalSeparation( splitStereoVerticalSeparation->value() );
|
||||
osg::DisplaySettings::instance()->setSplitStereoHorizontalEyeMapping(
|
||||
( osg::DisplaySettings::SplitStereoHorizontalEyeMapping ) splitStereoHorizontalEyeMapping->currentIndex() );
|
||||
osg::DisplaySettings::instance()->setSplitStereoVerticalEyeMapping(
|
||||
( osg::DisplaySettings::SplitStereoVerticalEyeMapping ) splitStereoVerticalEyeMapping->currentIndex() );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::saveStereoConfig()
|
||||
{
|
||||
settings.setValue( "/Plugin-Globe/stereoMode", comboStereoMode->currentText() );
|
||||
settings.setValue( "/Plugin-Globe/screenDistance", screenDistance->value() );
|
||||
settings.setValue( "/Plugin-Globe/screenWidth", screenWidth->value() );
|
||||
settings.setValue( "/Plugin-Globe/screenHeight", screenHeight->value() );
|
||||
settings.setValue( "/Plugin-Globe/eyeSeparation", eyeSeparation->value() );
|
||||
settings.setValue( "/Plugin-Globe/splitStereoHorizontalSeparation", splitStereoHorizontalSeparation->value() );
|
||||
settings.setValue( "/Plugin-Globe/splitStereoVerticalSeparation", splitStereoVerticalSeparation->value() );
|
||||
settings.setValue( "/Plugin-Globe/splitStereoHorizontalEyeMapping", splitStereoHorizontalEyeMapping->currentIndex() );
|
||||
settings.setValue( "/Plugin-Globe/splitStereoVerticalEyeMapping", splitStereoVerticalEyeMapping->currentIndex() );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::updateStereoDialog()
|
||||
{
|
||||
QString stereoMode = comboStereoMode->currentText();
|
||||
screenDistance->setEnabled( true );
|
||||
screenHeight->setEnabled( true );
|
||||
screenWidth->setEnabled( true );
|
||||
eyeSeparation->setEnabled( true );
|
||||
splitStereoHorizontalSeparation->setEnabled( false );
|
||||
splitStereoVerticalSeparation->setEnabled( false );
|
||||
splitStereoHorizontalEyeMapping->setEnabled( false );
|
||||
splitStereoVerticalEyeMapping->setEnabled( false );
|
||||
|
||||
if ( "OFF" == stereoMode )
|
||||
{
|
||||
screenDistance->setEnabled( false );
|
||||
screenHeight->setEnabled( false );
|
||||
screenWidth->setEnabled( false );
|
||||
eyeSeparation->setEnabled( false );
|
||||
}
|
||||
else if ( "ANAGLYPHIC" == stereoMode )
|
||||
{
|
||||
//nothing to do
|
||||
}
|
||||
else if ( "VERTICAL_SPLIT" == stereoMode )
|
||||
{
|
||||
splitStereoVerticalSeparation->setEnabled( true );
|
||||
splitStereoVerticalEyeMapping->setEnabled( true );
|
||||
}
|
||||
else if ( "HORIZONTAL_SPLIT" == stereoMode )
|
||||
{
|
||||
splitStereoHorizontalSeparation->setEnabled( true );
|
||||
splitStereoHorizontalEyeMapping->setEnabled( true );
|
||||
}
|
||||
else if ( "QUAD_BUFFER" == stereoMode )
|
||||
{
|
||||
//nothing to do
|
||||
}
|
||||
else
|
||||
{
|
||||
//should never get here
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText( "This stereo mode has not been implemented yet." );
|
||||
msgBox.exec();
|
||||
}
|
||||
}
|
||||
//END STEREO
|
@ -1,104 +0,0 @@
|
||||
/***************************************************************************
|
||||
globe_plugin_dialog.h - settings dialog for the globe plugin
|
||||
--------------------------------------
|
||||
Date : 11-Nov-2010
|
||||
Copyright : (C) 2010 by Marco Bernasocchi
|
||||
Email : marco at bernawebdesign.ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#ifndef QGIS_GLOBE_PLUGIN_DIALOG_H
|
||||
#define QGIS_GLOBE_PLUGIN_DIALOG_H
|
||||
|
||||
#include <ui_globe_plugin_dialog_guibase.h>
|
||||
#include <QDialog>
|
||||
#include <QSettings>
|
||||
#include <QCheckBox>
|
||||
#include <osgViewer/Viewer>
|
||||
#include "qgscontexthelp.h"
|
||||
#include <qgsproject.h>
|
||||
#include <qgsvectorlayer.h>
|
||||
|
||||
class GlobePlugin;
|
||||
|
||||
class QgsGlobePluginDialog: public QDialog, private Ui::QgsGlobePluginDialogGuiBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsGlobePluginDialog( QWidget * parent, GlobePlugin* globe, Qt::WindowFlags fl = 0 );
|
||||
~QgsGlobePluginDialog();
|
||||
void resetElevationDatasources();
|
||||
void readElevationDatasources();
|
||||
QTableWidget *elevationDatasources() { return elevationDatasourcesWidget; }
|
||||
void updatePointLayers();
|
||||
QgsVectorLayer* modelLayer();
|
||||
QString modelPath() { return modelPathLineEdit->text(); }
|
||||
|
||||
private:
|
||||
QString openRasterFile();
|
||||
void updateStereoDialog();
|
||||
bool validateResource( QString type, QString uri, QString& error );
|
||||
void saveElevationDatasources();
|
||||
void moveRow( QTableWidget* widget, bool up );
|
||||
QList<QTableWidgetItem*> takeRow( QTableWidget* widget, int row );
|
||||
void setRow( QTableWidget* widget, int row, const QList< QTableWidgetItem* >& rowItems );
|
||||
void showMessageBox( QString text );
|
||||
QList<QgsVectorLayer*> pointLayers();
|
||||
//! Set osg/DisplaySettings
|
||||
void setStereoConfig();
|
||||
//! Init dialog from settings using defaults from osg/DisplaySettings
|
||||
void loadStereoConfig();
|
||||
//! Save settings
|
||||
void saveStereoConfig();
|
||||
//! Handle stereoMode
|
||||
void setStereoMode();
|
||||
void loadVideoSettings();
|
||||
void saveVideoSettings();
|
||||
void loadMapSettings();
|
||||
void saveMapSettings();
|
||||
|
||||
private slots:
|
||||
void on_buttonBox_accepted();
|
||||
void on_buttonBox_rejected();
|
||||
|
||||
//STEREO
|
||||
void on_comboStereoMode_currentIndexChanged( QString value );
|
||||
void on_eyeSeparation_valueChanged( double value );
|
||||
void on_screenDistance_valueChanged( double value );
|
||||
void on_screenWidth_valueChanged( double value );
|
||||
void on_screenHeight_valueChanged( double value );
|
||||
void on_splitStereoHorizontalSeparation_valueChanged( int value );
|
||||
void on_splitStereoVerticalSeparation_valueChanged( int value );
|
||||
void on_splitStereoHorizontalEyeMapping_currentIndexChanged( int value );
|
||||
void on_splitStereoVerticalEyeMapping_currentIndexChanged( int value );
|
||||
void on_resetStereoDefaults_clicked();
|
||||
|
||||
//MODEL
|
||||
void on_modelBrowse_clicked();
|
||||
|
||||
//ELEVATION
|
||||
void on_elevationCombo_currentIndexChanged( QString type );
|
||||
void on_elevationBrowse_clicked();
|
||||
void on_elevationAdd_clicked();
|
||||
void on_elevationRemove_clicked();
|
||||
void on_elevationUp_clicked();
|
||||
void on_elevationDown_clicked();
|
||||
|
||||
//MAP
|
||||
void on_mBaseLayerComboBox_currentIndexChanged( int index );
|
||||
|
||||
signals:
|
||||
void elevationDatasourcesChanged();
|
||||
|
||||
private:
|
||||
GlobePlugin* mGlobe;
|
||||
QSettings settings;
|
||||
};
|
||||
|
||||
#endif // QGIS_GLOBE_PLUGIN_DIALOG_H
|
@ -1,782 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QgsGlobePluginDialogGuiBase</class>
|
||||
<widget class="QDialog" name="QgsGlobePluginDialogGuiBase">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1407</width>
|
||||
<height>534</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Globe Settings</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset>
|
||||
<normaloff>../../.designer/backup</normaloff>../../.designer/backup</iconset>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="2" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Map</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="mBaseLayerGroupBox">
|
||||
<property name="title">
|
||||
<string>Base Layer</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>URL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="mBaseLayerComboBox"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="mBaseLayerURL"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="mSkyGroupBox">
|
||||
<property name="title">
|
||||
<string>Sky</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Date / Time (UTC)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QDateTimeEdit" name="mSkyDateTime">
|
||||
<property name="displayFormat">
|
||||
<string>dd.MM.yyyy HH:mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="mSkyAutoAmbient">
|
||||
<property name="text">
|
||||
<string>Auto ambient</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="elevation">
|
||||
<attribute name="title">
|
||||
<string>Elevation</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_7">
|
||||
<item row="6" column="1">
|
||||
<widget class="QDoubleSpinBox" name="mTxtVerticalScale"/>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Vertical Scale</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="elevationUp">
|
||||
<property name="text">
|
||||
<string>Up</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="elevationDown">
|
||||
<property name="text">
|
||||
<string>Down</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="elevationAdd">
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="elevationRemove">
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>URL/File</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>elevationPath</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="elevationPath">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="elevationActions">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="elevationIsLocal">
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="elevationBrowse">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>27</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="elevationIsRemote">
|
||||
<layout class="QGridLayout" name="gridLayout_6"/>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QTableWidget" name="elevationDatasourcesWidget">
|
||||
<property name="acceptDrops">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="tabKeyNavigation">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="dragEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="dragDropOverwriteMode">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::NoDragDrop</enum>
|
||||
</property>
|
||||
<property name="defaultDropAction">
|
||||
<enum>Qt::IgnoreAction</enum>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="showGrid">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="gridStyle">
|
||||
<enum>Qt::SolidLine</enum>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="rowCount">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderCascadingSectionResizes">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderDefaultSectionSize">
|
||||
<number>100</number>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderHighlightSections">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderShowSortIndicator" stdset="0">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Type</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Cache</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Path</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Type</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>elevationCombo</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="elevationCombo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Raster</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>TMS</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="video">
|
||||
<attribute name="title">
|
||||
<string>Video</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_8">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="mAntiAliasingGroupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Anti Aliasing</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Samples</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="mAANumSamples">
|
||||
<property name="placeholderText">
|
||||
<string>[Leave empty for maximum]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string><i>Changing video settings requires a restart of the globe plugin</i></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="model">
|
||||
<attribute name="title">
|
||||
<string>Model</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Point Layer</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>modelLayerCombo</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>3D Model</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>modelPathLineEdit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLineEdit" name="modelPathLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QPushButton" name="modelBrowse">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>27</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QComboBox" name="modelLayerCombo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="stereo">
|
||||
<attribute name="title">
|
||||
<string>Stereo</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="comboStereoModeLabel">
|
||||
<property name="text">
|
||||
<string>Stereo Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="screenDistanceLabel">
|
||||
<property name="text">
|
||||
<string>Screen distance (m)</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>screenDistance</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QDoubleSpinBox" name="screenDistance">
|
||||
<property name="accelerated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="screenWidthLabel">
|
||||
<property name="text">
|
||||
<string>Screen width (m)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<widget class="QDoubleSpinBox" name="screenWidth">
|
||||
<property name="accelerated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0" colspan="2">
|
||||
<widget class="QLabel" name="splitStereoHorizontalSeparationLabel">
|
||||
<property name="text">
|
||||
<string>Split stereo horizontal separation (px)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0" colspan="2">
|
||||
<widget class="QLabel" name="splitStereoVerticalSeparationLabel">
|
||||
<property name="text">
|
||||
<string>Split stereo vertical separation (px)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="0" colspan="2">
|
||||
<widget class="QLabel" name="splitStereoVerticalEyeMappingLabel">
|
||||
<property name="text">
|
||||
<string>Split stereo vertical eye mapping</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="2">
|
||||
<widget class="QComboBox" name="splitStereoVerticalEyeMapping">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">LEFT_EYE_TOP_VIEWPORT</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">LEFT_EYE_BOTTOM_VIEWPORT</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QDoubleSpinBox" name="screenHeight">
|
||||
<property name="accelerated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="screenHeightLabel">
|
||||
<property name="text">
|
||||
<string>Screen height (m)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="2">
|
||||
<widget class="QSpinBox" name="splitStereoVerticalSeparation">
|
||||
<property name="accelerated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="2">
|
||||
<widget class="QSpinBox" name="splitStereoHorizontalSeparation">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="accelerated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QComboBox" name="comboStereoMode">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">OFF</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">ANAGLYPHIC</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">QUAD_BUFFER</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">HORIZONTAL_SPLIT</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">VERTICAL_SPLIT</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="eyeSeparationLabel">
|
||||
<property name="text">
|
||||
<string>Eye separation (m)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QDoubleSpinBox" name="eyeSeparation">
|
||||
<property name="readOnly">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::UpDownArrows</enum>
|
||||
</property>
|
||||
<property name="accelerated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.001000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="2">
|
||||
<widget class="QPushButton" name="resetStereoDefaults">
|
||||
<property name="text">
|
||||
<string>Reset to defaults</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<widget class="QLabel" name="splitStereoHorizontalEyeMappingLabel">
|
||||
<property name="text">
|
||||
<string>Split stereo horizontal eye mapping</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="2">
|
||||
<widget class="QComboBox" name="splitStereoHorizontalEyeMapping">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">LEFT_EYE_LEFT_VIEWPORT</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">LEFT_EYE_RIGHT_VIEWPORT</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<tabstops>
|
||||
<tabstop>comboStereoMode</tabstop>
|
||||
<tabstop>eyeSeparation</tabstop>
|
||||
<tabstop>screenDistance</tabstop>
|
||||
<tabstop>screenWidth</tabstop>
|
||||
<tabstop>screenHeight</tabstop>
|
||||
<tabstop>splitStereoHorizontalSeparation</tabstop>
|
||||
<tabstop>splitStereoHorizontalEyeMapping</tabstop>
|
||||
<tabstop>splitStereoVerticalSeparation</tabstop>
|
||||
<tabstop>splitStereoVerticalEyeMapping</tabstop>
|
||||
<tabstop>resetStereoDefaults</tabstop>
|
||||
<tabstop>buttonBox</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>QgsGlobePluginDialogGuiBase</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>446</x>
|
||||
<y>529</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>481</x>
|
||||
<y>297</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>QgsGlobePluginDialogGuiBase</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>387</x>
|
||||
<y>529</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>281</x>
|
||||
<y>339</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
BIN
src/plugins/globe/images/gui/button-background-single.png
Normal file
After Width: | Height: | Size: 314 B |
Before Width: | Height: | Size: 311 B After Width: | Height: | Size: 218 B |
BIN
src/plugins/globe/images/gui/settings.png
Normal file
After Width: | Height: | Size: 429 B |
Before Width: | Height: | Size: 272 B After Width: | Height: | Size: 201 B |
Before Width: | Height: | Size: 180 B After Width: | Height: | Size: 160 B |
143
src/plugins/globe/images/icon.svg
Normal file
@ -0,0 +1,143 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2996"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="icon.svg">
|
||||
<defs
|
||||
id="defs2998">
|
||||
<linearGradient
|
||||
id="linearGradient3948">
|
||||
<stop
|
||||
style="stop-color:#14c412;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3950" />
|
||||
<stop
|
||||
style="stop-color:#2fa92d;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3952" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3860">
|
||||
<stop
|
||||
style="stop-color:#cfddee;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3862" />
|
||||
<stop
|
||||
style="stop-color:#6793cd;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3864" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3860"
|
||||
id="radialGradient3870"
|
||||
cx="42.630283"
|
||||
cy="18.727272"
|
||||
fx="42.630283"
|
||||
fy="18.727272"
|
||||
r="31.787046"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-0.79604311,0,0,-1,87.02645,34.545452)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3948"
|
||||
id="linearGradient3954"
|
||||
x1="1.8088502"
|
||||
y1="29.950056"
|
||||
x2="62.28172"
|
||||
y2="29.950056"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11"
|
||||
inkscape:cx="30.353097"
|
||||
inkscape:cy="32.680944"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1028"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="867"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata3001">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<path
|
||||
style="opacity:1;fill:url(#radialGradient3870);fill-opacity:1;fill-rule:evenodd;stroke:#326fcb;stroke-width:2.66500000000000004;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-linejoin:round"
|
||||
d="m 62.363635,32.454544 c 0,16.819581 -13.63496,30.454546 -30.454545,30.454546 -16.819581,0 -30.4545465,-13.634965 -30.4545465,-30.454546 0,-16.819581 13.6349655,-30.4545464 30.4545465,-30.4545464 16.819585,0 30.454545,13.6349654 30.454545,30.4545464 z"
|
||||
id="path3036"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
id="g3941"
|
||||
style="fill:url(#linearGradient3954);fill-opacity:1">
|
||||
<path
|
||||
sodipodi:nodetypes="csszszssssssssssc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3807"
|
||||
d="m 12.454545,53.090909 c 1.274253,-0.234239 0.987012,-1.887258 1.167988,-3.342749 0.14498,-1.165998 0.94868,-2.074964 0.426375,-2.997098 C 13.206543,45.26386 10.665333,45.173915 10.090909,44.727273 9.5164846,44.28063 6.2081861,39.649018 4.2602054,38.122499 2.7215555,36.916749 2.4418971,38.844949 2.1818184,38 1.9217398,37.155052 1.3372634,30.593092 3.1337285,24.323806 3.5115035,23.00545 7.1602709,22.238388 7.515887,20.991567 7.8164462,19.93778 6.145546,20.97674 6.5045705,19.949524 6.9292731,18.734395 8.5422106,18.772373 8.9712963,17.539473 9.3487965,16.454795 7.2886825,16.299144 7.3366292,14.911299 c 0.047818,-1.384128 2.5672416,-2.909759 3.0101188,-3.832106 0.501632,-1.044709 3.989113,1.131964 4.453467,0.186338 1.360061,-2.7696803 3.77755,-2.9357004 4.238968,-4.6431458 C 20.135902,2.5640536 9.8124841,10.776552 9.5555349,11.098355 -5.3352534,29.747591 5.3140435,47.482146 8.153283,51.536495 c 0.8794239,1.255791 2.256379,1.571058 4.301262,1.554414 z"
|
||||
style="fill:url(#linearGradient3954);stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="zssszzsszsssssssssszssssszszzzsssssszzzzssz"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3809"
|
||||
d="m 27.636364,21.090909 c 0.780036,-0.268848 3.841437,-0.393949 5.865311,0.466598 1.560421,0.663488 1.932626,2.226274 3.705311,2.820447 1.73958,0.583077 1.719271,-1.07816 3.166476,-0.925882 1.979473,0.208285 5.200248,1.909349 5.626538,-0.04298 0.42629,-1.952329 -3.482539,-1.564576 -3.636364,-1.954546 -0.153825,-0.38997 -0.907464,-2.20096 -1.367687,-2.219935 -0.792951,-0.0327 0.05341,1.647316 -0.882662,1.834095 -0.870354,0.173666 -3.564327,-3.908646 -3.749651,-4.114159 -0.185324,-0.205513 -3.658196,-1.030126 0.01227,1.393627 0.660651,0.436254 1.06746,1.248195 0.99089,1.616479 -0.0805,0.387187 -1.377987,-0.797843 -2.012248,-1.182769 -0.568931,-0.345277 -1.250482,-2.173596 -2.841505,-1.6363 -2.980321,1.006469 -4.410452,3.689536 -6.306909,4.235529 -1.803183,0.519139 -2.182124,-2.658666 -1.606749,-3.390722 0.731477,-0.930665 5.771549,0.199111 2.985466,-2.11817 -1.634495,-1.359465 0.951504,-1.857968 2.952757,-2.427455 0.540886,-0.153917 1.479538,-2.697608 2.652906,-2.949768 0.92167,-0.19807 1.977272,1.678944 2.534156,1.538303 2.61531,-0.660493 3.627299,-0.856397 4.138969,-1.669664 C 40.375306,9.5503696 38.831377,9.3355454 38.64865,8.1414392 38.536654,7.4095538 39.959296,6.3562427 38.992557,6.2706175 37.822051,6.1669445 37.22735,10.955693 35.695763,11.099921 34.674286,11.196113 33.201042,9.9657489 32.225228,9.5607789 29.616386,8.4780901 31.824133,7.6684294 34.175191,6.3965729 c 1.748176,-0.9457141 2.377964,-1.780523 6.370263,-1.6693002 3.992299,0.1112228 8.320174,2.5394347 11.552346,4.9160824 3.077189,2.2626879 4.273435,3.9476669 5.674927,5.9475539 1.401492,1.999888 2.5305,4.587181 3.589725,7.834384 1.059224,3.247202 1.320981,5.502969 0.155378,7.463313 -1.165603,1.960344 -1.125444,7.239011 -1.704848,2.703117 -0.687643,-5.383243 -2.822899,-4.992543 -3.649927,-5.46511 -1.684387,-0.962463 -2.790222,-0.440248 -1.184328,0.59583 2.066408,1.333188 -1.199397,3.659878 -2.461262,4.238816 -4.151366,1.904629 -2.566664,-0.580367 -3.554528,-2.528722 -1.266813,-2.498526 -6.400697,-10.413787 -1.731214,0.204992 2.00796,4.56626 6.0178,4.429608 5.495549,5.726108 -0.522251,1.2965 -2.494318,0.151757 -4.636363,5.454545 -2.142044,5.302788 0.550185,7.981654 -6.636364,12.590909 -7.186548,4.609255 -7.004448,-12.805096 -7.103729,-14.598635 -0.09928,-1.793539 -4.961949,-2.510136 -8.446558,-1.524932 -2.274119,0.642963 -5.891641,-5.638639 -5.73453,-7.377525 0.418624,-4.633269 6.6866,-9.548242 7.466636,-9.81709 z"
|
||||
style="opacity:1;fill:url(#linearGradient3954);fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="zsszszsz"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3807-9"
|
||||
d="m 26.626118,12.261844 c 0.506237,-0.183147 -0.826308,1.374667 0.633897,1.236797 1.156344,-0.10918 2.903225,-0.302237 2.38092,-1.224371 -0.842365,-1.487202 -1.264763,-0.94766 -1.480726,-1.978334 -0.215963,-1.0306751 -1.366307,-1.8392743 -1.537059,0.148182 -0.05106,0.594306 -1.615575,0.735346 -1.822054,1.161566 -0.206478,0.42622 -0.210556,1.244186 0.150041,1.3492 0.388335,0.113093 1.168743,-0.509893 1.674981,-0.69304 z"
|
||||
style="opacity:1;fill:url(#linearGradient3954);fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="zzzz"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3807-9-7"
|
||||
d="M 23.212662,6.8486211 C 24.138782,6.4601476 22.794749,5.6960066 21.162652,6.771003 19.530555,7.8459993 20.48825,7.5611724 20.862716,7.6702259 21.237182,7.7792794 22.286543,7.2370945 23.212662,6.8486211 z"
|
||||
style="opacity:1;fill:url(#linearGradient3954);fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="zzzz"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3807-9-1"
|
||||
d="m 49.173839,50.447542 c 1.593614,0.222363 0.694273,-0.948645 2.250125,-4.038377 1.555851,-3.089731 -1.088018,-0.634888 -1.762048,0.59816 -0.674029,1.233047 -2.081692,3.217854 -0.488077,3.440217 z"
|
||||
style="opacity:1;fill:url(#linearGradient3954);fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
</g>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3858"
|
||||
d="m 62.363635,32.454544 c 0,16.819581 -13.63496,30.454546 -30.454545,30.454546 -16.819581,0 -30.4545465,-13.634965 -30.4545465,-30.454546 0,-16.819581 13.6349655,-30.4545464 30.4545465,-30.4545464 16.819585,0 30.454545,13.6349654 30.454545,30.4545464 z"
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#326fcb;stroke-width:2.66500000000000004;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-linejoin:round" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 9.7 KiB |
@ -1,92 +0,0 @@
|
||||
/* -*-c++-*- */
|
||||
/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
|
||||
* Copyright 2008-2012 Pelican Mapping
|
||||
* http://osgearth.org
|
||||
*
|
||||
* osgEarth is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef OSGEARTHQT_COMMON_H
|
||||
#define OSGEARTHQT_COMMON_H 1
|
||||
|
||||
#include <osgEarth/Common>
|
||||
//#include <osgEarthAnnotation/AnnotationNode>
|
||||
#include <osgViewer/Viewer>
|
||||
|
||||
// define USE_DEPRECATED_API is used to include in API which is being phased out
|
||||
// if you can compile your apps with this turned off you are
|
||||
// well placed for compatibility with future versions.
|
||||
#define USE_DEPRECATED_API
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( disable : 4244 )
|
||||
#pragma warning( disable : 4251 )
|
||||
#pragma warning( disable : 4267 )
|
||||
#pragma warning( disable : 4275 )
|
||||
#pragma warning( disable : 4290 )
|
||||
#pragma warning( disable : 4786 )
|
||||
#pragma warning( disable : 4305 )
|
||||
#pragma warning( disable : 4996 )
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined( __BCPLUSPLUS__) || defined( __MWERKS__)
|
||||
# if defined( OSGEARTHQT_LIBRARY_STATIC )
|
||||
# define OSGEARTHQT_EXPORT
|
||||
# elif defined( OSGEARTHQT_LIBRARY )
|
||||
# define OSGEARTHQT_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define OSGEARTHQT_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
#else
|
||||
# define OSGEARTHQT_EXPORT
|
||||
#endif
|
||||
|
||||
// set up define for whether member templates are supported by VisualStudio compilers.
|
||||
#ifdef _MSC_VER
|
||||
# if (_MSC_VER >= 1300)
|
||||
# define __STL_MEMBER_TEMPLATES
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Define NULL pointer value */
|
||||
|
||||
#ifndef NULL
|
||||
#ifdef __cplusplus
|
||||
#define NULL 0
|
||||
#else
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef OSG_MIN_VERSION_REQUIRED
|
||||
#define OSG_MIN_VERSION_REQUIRED(MAJOR, MINOR, PATCH) ((OPENSCENEGRAPH_MAJOR_VERSION>MAJOR) || (OPENSCENEGRAPH_MAJOR_VERSION==MAJOR && (OPENSCENEGRAPH_MINOR_VERSION>MINOR || (OPENSCENEGRAPH_MINOR_VERSION==MINOR && OPENSCENEGRAPH_PATCH_VERSION>=PATCH))))
|
||||
#endif
|
||||
|
||||
#ifndef OSG_VERSION_LESS_THAN
|
||||
#define OSG_VERSION_LESS_THAN(MAJOR, MINOR, PATCH) ((OPENSCENEGRAPH_MAJOR_VERSION<MAJOR) || (OPENSCENEGRAPH_MAJOR_VERSION==MAJOR && (OPENSCENEGRAPH_MINOR_VERSION<MINOR || (OPENSCENEGRAPH_MINOR_VERSION==MINOR && OPENSCENEGRAPH_PATCH_VERSION<PATCH))))
|
||||
#endif
|
||||
|
||||
/**
|
||||
\namespace osgEarthQt
|
||||
*/
|
||||
|
||||
namespace osgEarth { namespace QtGui {
|
||||
|
||||
//typedef std::vector< osg::ref_ptr<osgEarth::Annotation::AnnotationNode> > AnnotationVector;
|
||||
typedef std::vector< osg::ref_ptr<osgViewer::View> > ViewVector;
|
||||
|
||||
} }
|
||||
|
||||
#endif // OSGEARTHQT_COMMON_H
|
||||
|
@ -1,91 +0,0 @@
|
||||
/* -*-c++-*- */
|
||||
/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
|
||||
* Copyright 2008-2012 Pelican Mapping
|
||||
* http://osgearth.org
|
||||
*
|
||||
* osgEarth is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef OSGEARTHQT_VIEWERWIDGET_H
|
||||
#define OSGEARTHQT_VIEWERWIDGET_H 1
|
||||
|
||||
//#include <osgEarthQt/Common>
|
||||
#include "Common"
|
||||
|
||||
#include <osgEarth/Map>
|
||||
|
||||
#include <osgQt/GraphicsWindowQt>
|
||||
#include <osgViewer/ViewerBase>
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
#undef OSGEARTHQT_EXPORT
|
||||
#define OSGEARTHQT_EXPORT
|
||||
|
||||
namespace osgEarth { namespace QtGui
|
||||
{
|
||||
using namespace osgEarth;
|
||||
|
||||
/**
|
||||
* Qt widget that encapsulates an osgViewer::Viewer.
|
||||
*/
|
||||
class OSGEARTHQT_EXPORT ViewerWidget : public osgQt::GLWidget
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructs a new ViewerWidget, creating an underlying viewer.
|
||||
* @param[in ] scene Scene graph to attach to the viewer (optional)
|
||||
*/
|
||||
explicit ViewerWidget(osg::Node* scene = 0);
|
||||
|
||||
/**
|
||||
* Constructs a new ViewerWidget, attaching an existing viewer.
|
||||
* @param[in ] viewer Viewer to attach to this widget. The widget will install
|
||||
* a new camera in the viewer. (NOTE: this widget does not take
|
||||
* ownership of the Viewer. You are still respsonsile for its
|
||||
* destruction)
|
||||
*/
|
||||
explicit ViewerWidget(osgViewer::ViewerBase* viewer);
|
||||
|
||||
/**
|
||||
* Access the underlying viewer.
|
||||
*/
|
||||
osgViewer::ViewerBase* getViewer() { return _viewer.get(); }
|
||||
|
||||
/**
|
||||
* Populates the incoming collection with the views comprising this viewer.
|
||||
*/
|
||||
template<typename T>
|
||||
void getViews( T& views ) const {
|
||||
osgViewer::ViewerBase::Views temp;
|
||||
_viewer->getViews(temp);
|
||||
views.insert(views.end(), temp.begin(), temp.end());
|
||||
}
|
||||
|
||||
virtual ~ViewerWidget();
|
||||
|
||||
protected:
|
||||
|
||||
QTimer _timer;
|
||||
|
||||
void createViewer();
|
||||
void reconfigure( osgViewer::View* );
|
||||
void installFrameTimer();
|
||||
void paintEvent( QPaintEvent* );
|
||||
|
||||
osg::observer_ptr<osgViewer::ViewerBase> _viewer;
|
||||
osg::ref_ptr<osg::GraphicsContext> _gc;
|
||||
};
|
||||
} }
|
||||
|
||||
#endif // OSGEARTHQT_VIEWERWIDGET_H
|
@ -1,167 +0,0 @@
|
||||
/* -*-c++-*- */
|
||||
/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
|
||||
* Copyright 2008-2012 Pelican Mapping
|
||||
* http://osgearth.org
|
||||
*
|
||||
* osgEarth is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
//#include <osgEarthQt/ViewerWidget>
|
||||
#include "ViewerWidget"
|
||||
|
||||
#include <osgEarthUtil/EarthManipulator>
|
||||
|
||||
#include <osgGA/StateSetManipulator>
|
||||
#include <osgQt/GraphicsWindowQt>
|
||||
#include <osgViewer/Viewer>
|
||||
#include <osgViewer/ViewerEventHandlers>
|
||||
|
||||
#include <QtGui>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtGui/QWidget>
|
||||
|
||||
using namespace osgEarth;
|
||||
using namespace osgEarth::QtGui;
|
||||
|
||||
|
||||
ViewerWidget::ViewerWidget(osg::Node* scene)
|
||||
{
|
||||
// create a new viewer (a simple osgViewer::Viewer)
|
||||
createViewer();
|
||||
|
||||
// attach the scene graph provided by the user
|
||||
if (scene)
|
||||
{
|
||||
dynamic_cast<osgViewer::Viewer*>(_viewer.get())->setSceneData( scene );
|
||||
}
|
||||
|
||||
// start up the paint event timer.
|
||||
installFrameTimer();
|
||||
}
|
||||
|
||||
ViewerWidget::ViewerWidget(osgViewer::ViewerBase* viewer) :
|
||||
_viewer( viewer )
|
||||
{
|
||||
if ( !_viewer.valid() )
|
||||
{
|
||||
// create a viewer if the user passed in NULL
|
||||
createViewer();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// reconfigure all the viewer's views to use a Qt graphics context.
|
||||
osgViewer::ViewerBase::Views views;
|
||||
getViews( views );
|
||||
for( osgViewer::ViewerBase::Views::iterator v = views.begin(); v != views.end(); ++v )
|
||||
{
|
||||
reconfigure( *v );
|
||||
}
|
||||
|
||||
// disable event setting on the viewer.
|
||||
viewer->setKeyEventSetsDone(0);
|
||||
viewer->setQuitEventSetsDone(false);
|
||||
}
|
||||
|
||||
// start up the paint event timer.
|
||||
installFrameTimer();
|
||||
}
|
||||
|
||||
ViewerWidget::~ViewerWidget()
|
||||
{
|
||||
_timer.stop();
|
||||
if ( _viewer.valid() )
|
||||
{
|
||||
_viewer->stopThreading();
|
||||
_viewer = 0L;
|
||||
}
|
||||
|
||||
OE_DEBUG << "ViewerWidget::DTOR" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void ViewerWidget::installFrameTimer()
|
||||
{
|
||||
// start the frame timer.
|
||||
connect(&_timer, SIGNAL(timeout()), this, SLOT(update()));
|
||||
_timer.start(15);
|
||||
}
|
||||
|
||||
|
||||
void ViewerWidget::createViewer()
|
||||
{
|
||||
// creates a simple basic viewer.
|
||||
osgViewer::Viewer* viewer = new osgViewer::Viewer();
|
||||
|
||||
viewer->setThreadingModel(osgViewer::Viewer::DrawThreadPerContext);
|
||||
viewer->setCameraManipulator(new osgEarth::Util::EarthManipulator());
|
||||
|
||||
viewer->addEventHandler(new osgViewer::StatsHandler());
|
||||
viewer->addEventHandler(new osgGA::StateSetManipulator());
|
||||
viewer->addEventHandler(new osgViewer::ThreadingHandler());
|
||||
|
||||
viewer->setKeyEventSetsDone(0);
|
||||
viewer->setQuitEventSetsDone(false);
|
||||
|
||||
reconfigure( viewer );
|
||||
|
||||
_viewer = viewer;
|
||||
}
|
||||
|
||||
void ViewerWidget::reconfigure( osgViewer::View* view )
|
||||
{
|
||||
if ( !_gc.valid() )
|
||||
{
|
||||
// create the Qt graphics context if necessary; it will be shared across all views.
|
||||
osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();
|
||||
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits(ds);
|
||||
|
||||
traits->readDISPLAY();
|
||||
if (traits->displayNum<0) traits->displayNum = 0;
|
||||
|
||||
traits->windowName = "osgEarthViewerQt";
|
||||
traits->windowDecoration = false;
|
||||
traits->x = x();
|
||||
traits->y = y();
|
||||
traits->width = width();
|
||||
traits->height = height();
|
||||
traits->doubleBuffer = true;
|
||||
traits->inheritedWindowData = new osgQt::GraphicsWindowQt::WindowData(this);
|
||||
|
||||
_gc = new osgQt::GraphicsWindowQt( traits.get() );
|
||||
}
|
||||
|
||||
// reconfigure this view's camera to use the Qt GC if necessary.
|
||||
osg::Camera* camera = view->getCamera();
|
||||
if ( camera->getGraphicsContext() != _gc.get() )
|
||||
{
|
||||
camera->setGraphicsContext( _gc.get() );
|
||||
if ( !camera->getViewport() )
|
||||
{
|
||||
camera->setViewport(new osg::Viewport(0, 0, _gc->getTraits()->width, _gc->getTraits()->height));
|
||||
}
|
||||
camera->setProjectionMatrixAsPerspective(
|
||||
30.0f, camera->getViewport()->width()/camera->getViewport()->height(), 1.0f, 10000.0f );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ViewerWidget::paintEvent(QPaintEvent* e)
|
||||
{
|
||||
Q_UNUSED( e );
|
||||
if (_viewer->getRunFrameScheme() == osgViewer::ViewerBase::CONTINUOUS ||
|
||||
_viewer->checkNeedToDoFrame() )
|
||||
{
|
||||
_viewer->frame();
|
||||
}
|
||||
}
|
@ -1,693 +0,0 @@
|
||||
/* -*-c++-*- */
|
||||
/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
|
||||
* Copyright 2008-2010 Pelican Mapping
|
||||
* http://osgearth.org
|
||||
*
|
||||
* osgEarth is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef OSGEARTHUTIL_CONTROLS
|
||||
#define OSGEARTHUTIL_CONTROLS
|
||||
|
||||
#define HAVE_OSGEARTH_CHILD_SPACING 1
|
||||
|
||||
#include <osgEarthUtil/Common>
|
||||
#include <osgEarth/Common>
|
||||
#include <osg/Drawable>
|
||||
#include <osg/Geode>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/MixinVector>
|
||||
#include <osgGA/GUIEventHandler>
|
||||
#include <osgViewer/View>
|
||||
#include <osgText/Font>
|
||||
#include <osgText/Text>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <qglobal.h>
|
||||
|
||||
#undef OSGEARTHUTIL_EXPORT
|
||||
#define OSGEARTHUTIL_EXPORT
|
||||
|
||||
/**
|
||||
* Controls - A simple 2D UI toolkit.
|
||||
*
|
||||
* Controls are 2D interface components that automatically layout to fit their containers.
|
||||
* The support layout containers, margins and padding, alignment/justification, and docking.
|
||||
* Controls are a quick and easy way to add "HUD" components to a scene. Just create a
|
||||
* ControlSurface and add it to a View's scene. Then create and add Controls to that
|
||||
* surface.
|
||||
*/
|
||||
namespace osgEarth { namespace Util { namespace Controls21
|
||||
{
|
||||
using namespace osgEarth;
|
||||
|
||||
typedef std::vector< osg::ref_ptr<osg::Drawable> > DrawableList;
|
||||
|
||||
typedef std::map< class Control*, osg::Geode* > GeodeTable;
|
||||
|
||||
// holds 4-sided gutter dimensions (for margins and padding) .. no-export, header-only.
|
||||
struct Gutter
|
||||
{
|
||||
Gutter()
|
||||
: _top(0), _right(0), _bottom(0), _left(0) { }
|
||||
Gutter( float top, float right, float bottom, float left )
|
||||
: _top(top), _right(right), _bottom(bottom), _left(left) { }
|
||||
Gutter( float y, float x )
|
||||
: _top(y), _right(x), _bottom(y), _left(x) { }
|
||||
explicit Gutter( float all )
|
||||
: _top(all), _right(all), _bottom(all), _left(all) { }
|
||||
bool operator !=( const Gutter& rhs ) const {
|
||||
return top() != rhs.top() || right() != rhs.right() || bottom() != rhs.bottom() || left() != rhs.left(); }
|
||||
|
||||
float top() const { return _top; }
|
||||
float left() const { return _left; }
|
||||
float right() const { return _right; }
|
||||
float bottom() const { return _bottom; }
|
||||
|
||||
float x() const { return _left + _right; }
|
||||
float y() const { return _top + _bottom; }
|
||||
|
||||
osg::Vec2f size() const { return osg::Vec2f(x(), y()); }
|
||||
|
||||
osg::Vec2f offset() const { return osg::Vec2f( _left, _top ); }
|
||||
|
||||
private:
|
||||
float _top, _right, _bottom, _left;
|
||||
};
|
||||
|
||||
// internal state class
|
||||
struct ControlContext
|
||||
{
|
||||
ControlContext() : _viewContextID(~0), _view(0), _frameStamp(0) { }
|
||||
osg::View* _view;
|
||||
osg::ref_ptr<const osg::Viewport> _vp;
|
||||
unsigned int _viewContextID;
|
||||
std::queue< osg::ref_ptr<class Control> > _active;
|
||||
const osg::FrameStamp* _frameStamp;
|
||||
};
|
||||
|
||||
// base class for control events
|
||||
class ControlEventHandler : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
/** Click event. */
|
||||
virtual void onClick( class Control* control ) { Q_UNUSED(control); }
|
||||
|
||||
/** Click event with mouse button mask (see osgGA::GUIEventAdapter::MouseButtonMask) */
|
||||
virtual void onClick( class Control* control, int mouseButtonMask ) { Q_UNUSED( mouseButtonMask ); onClick(control); }
|
||||
|
||||
/** Click event with click position (negative values mean you're in the left/top padding) */
|
||||
virtual void onClick( class Control* control, const osg::Vec2f& pos, int mouseButtonMask ) { Q_UNUSED( pos); onClick(control, mouseButtonMask); }
|
||||
|
||||
/** Value events */
|
||||
virtual void onValueChanged( class Control* control, bool value ) { Q_UNUSED( control ); Q_UNUSED( value ); }
|
||||
virtual void onValueChanged( class Control* control, double value ) { Q_UNUSED( control ); Q_UNUSED( value );}
|
||||
virtual void onValueChanged( class Control* control, float value ) { Q_UNUSED( control ); Q_UNUSED( value );}
|
||||
virtual void onValueChanged( class Control* control, int value ) { Q_UNUSED( control ); Q_UNUSED( value ); }
|
||||
virtual void onValueChanged( class Control* control, const osg::Vec3f& value ) { Q_UNUSED( control ); Q_UNUSED( value ); }
|
||||
virtual void onValueChanged( class Control* control, const osg::Vec2f& value ) { Q_UNUSED( control ); Q_UNUSED( value ); }
|
||||
virtual void onValueChanged( class Control* control, const osg::Vec3d& value ) { Q_UNUSED( control ); Q_UNUSED( value ); }
|
||||
virtual void onValueChanged( class Control* control, const osg::Vec2d& value ) { Q_UNUSED( control ); Q_UNUSED( value ); }
|
||||
virtual void onValueChanged( class Control* control, const std::string& value ) { Q_UNUSED( control ); Q_UNUSED( value ); }
|
||||
virtual void onValueChanged( class Control* control, void* value ) { Q_UNUSED( control ); Q_UNUSED( value ); }
|
||||
};
|
||||
|
||||
typedef std::list< osg::ref_ptr<ControlEventHandler> > ControlEventHandlerList;
|
||||
|
||||
/**
|
||||
* Base class for all controls. You can actually use a Control directly and it
|
||||
* will just render as a rectangle.
|
||||
*/
|
||||
class OSGEARTHUTIL_EXPORT Control : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
enum Alignment
|
||||
{
|
||||
ALIGN_NONE, ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT, ALIGN_TOP, ALIGN_BOTTOM
|
||||
};
|
||||
|
||||
enum Dock
|
||||
{
|
||||
DOCK_NONE, DOCK_LEFT, DOCK_RIGHT, DOCK_TOP, DOCK_BOTTOM, DOCK_FILL
|
||||
};
|
||||
|
||||
public:
|
||||
Control();
|
||||
|
||||
void setX( float value );
|
||||
const osgEarth::optional<float>& x() const { return _x; }
|
||||
void clearX() { _x.unset(); dirty(); }
|
||||
|
||||
void setY( float value );
|
||||
const osgEarth::optional<float>& y() const { return _y; }
|
||||
void clearY() { _y.unset(); dirty(); }
|
||||
|
||||
void setPosition( float x, float y );
|
||||
|
||||
void setWidth( float value );
|
||||
const osgEarth::optional<float>& width() const { return _width; }
|
||||
void clearWidth() { _width.unset(); dirty(); }
|
||||
|
||||
void setHeight( float value );
|
||||
const osgEarth::optional<float>& height() const { return _height; }
|
||||
void clearHeight() { _height.unset(); dirty(); }
|
||||
|
||||
void setSize( float w, float h );
|
||||
|
||||
void setMargin( const Gutter& value );
|
||||
const Gutter& margin() const { return _margin; }
|
||||
|
||||
// space between container and its content
|
||||
void setPadding( const Gutter& value );
|
||||
void setPadding( float globalValue );
|
||||
const Gutter& padding() const { return _padding; }
|
||||
|
||||
void setVertAlign( const Alignment& value );
|
||||
const optional<Alignment>& vertAlign() const { return _valign; }
|
||||
|
||||
void setHorizAlign( const Alignment& value );
|
||||
const optional<Alignment>& horizAlign() const { return _halign; }
|
||||
|
||||
void setHorizFill( bool value, float minWidth =0.0f );
|
||||
bool horizFill() const { return _hfill; }
|
||||
|
||||
void setVertFill( bool value, float minHeight =0.0f );
|
||||
bool vertFill() const { return _vfill; }
|
||||
|
||||
void setVisible( bool value );
|
||||
bool visible() const { return _visible; }
|
||||
|
||||
void setForeColor( const osg::Vec4f& value );
|
||||
void setForeColor( float r, float g, float b, float a ) { setForeColor( osg::Vec4f(r,g,b,a) ); }
|
||||
const osgEarth::optional<osg::Vec4f> foreColor() const { return _foreColor; }
|
||||
void clearForeColor() { _foreColor.unset(); dirty(); }
|
||||
|
||||
void setBackColor( const osg::Vec4f& value );
|
||||
void setBackColor( float r, float g, float b, float a ) { setBackColor( osg::Vec4f(r,g,b,a) ); }
|
||||
const osgEarth::optional<osg::Vec4f>& backColor() const { return _backColor; }
|
||||
void clearBackColor() { _backColor.unset(); dirty(); }
|
||||
|
||||
void setActiveColor( const osg::Vec4f& value );
|
||||
void setActiveColor( float r, float g, float b, float a ) { setActiveColor( osg::Vec4f(r,g,b,a) ); }
|
||||
const osgEarth::optional<osg::Vec4f>& activeColor() const { return _activeColor; }
|
||||
void clearActiveColor() { _activeColor.unset(); dirty(); }
|
||||
|
||||
bool getParent( osg::ref_ptr<Control>& out ) const;
|
||||
|
||||
void setActive( bool value );
|
||||
bool getActive() const { return _active; }
|
||||
|
||||
void setAbsorbEvents( bool value ) { _absorbEvents = value; }
|
||||
bool getAbsorbEvents() const { return _absorbEvents; }
|
||||
|
||||
void addEventHandler( ControlEventHandler* handler );
|
||||
|
||||
public:
|
||||
|
||||
// mark the control as dirty so that it will regenerate on the next pass.
|
||||
virtual void dirty();
|
||||
bool isDirty() const { return _dirty; }
|
||||
|
||||
virtual void calcSize( const ControlContext& context, osg::Vec2f& out_size );
|
||||
virtual void calcFill( const ControlContext& context ) { Q_UNUSED( context ); }
|
||||
virtual void calcPos ( const ControlContext& context, const osg::Vec2f& cursor, const osg::Vec2f& parentSize );
|
||||
virtual void draw ( const ControlContext& context, DrawableList& out_drawables );
|
||||
|
||||
// actual rendering region on the control surface
|
||||
const osg::Vec2f& renderPos() const { return _renderPos; }
|
||||
const osg::Vec2f& renderSize() const { return _renderSize; }
|
||||
|
||||
// does the control contain the point?
|
||||
bool intersects( float x, float y ) const;
|
||||
|
||||
void setParent( class Control* c ) { _parent = c; }
|
||||
|
||||
protected:
|
||||
bool _dirty;
|
||||
osg::Vec2f _renderPos; // rendering position (includes padding offset)
|
||||
osg::Vec2f _renderSize; // rendering size (includes padding)
|
||||
|
||||
// adjusts renderpos for alignment.
|
||||
void align();
|
||||
|
||||
friend class ControlCanvas;
|
||||
friend class Container;
|
||||
|
||||
virtual bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, ControlContext& cx );
|
||||
|
||||
ControlEventHandlerList _eventHandlers;
|
||||
|
||||
private:
|
||||
osgEarth::optional<float> _x, _y, _width, _height;
|
||||
Gutter _margin;
|
||||
Gutter _padding;
|
||||
bool _visible;
|
||||
optional<Alignment> _valign, _halign;
|
||||
optional<osg::Vec4f> _backColor, _foreColor, _activeColor;
|
||||
bool _active;
|
||||
bool _absorbEvents;
|
||||
bool _hfill, _vfill;
|
||||
osg::observer_ptr<Control> _parent;
|
||||
osg::ref_ptr<osg::Geometry> _geom;
|
||||
};
|
||||
|
||||
typedef std::vector< osg::ref_ptr<Control> > ControlVector;
|
||||
|
||||
|
||||
/**
|
||||
* Control that contains a raster image
|
||||
*/
|
||||
class OSGEARTHUTIL_EXPORT ImageControl : public Control
|
||||
{
|
||||
public:
|
||||
explicit ImageControl( osg::Image* image =0L );
|
||||
|
||||
void setImage( osg::Image* image );
|
||||
osg::Image* getImage() const { return _image.get(); }
|
||||
|
||||
/** Rotates the image. */
|
||||
void setRotation( float rotation_deg );
|
||||
float getRotation() const { return osg::RadiansToDegrees(_rotation_rad); }
|
||||
|
||||
/** Tells the control to fix its minimum size to account to rotation. Otherwise the
|
||||
control will auto-size its width/height based on the rotation angle. */
|
||||
void setFixSizeForRotation( bool value );
|
||||
bool getFixSizeForRotation() const { return _fixSizeForRot; }
|
||||
|
||||
public: // Control
|
||||
virtual void calcSize( const ControlContext& context, osg::Vec2f& out_size );
|
||||
virtual void draw( const ControlContext& cx, DrawableList& out );
|
||||
|
||||
private:
|
||||
osg::ref_ptr<osg::Image> _image;
|
||||
float _rotation_rad;
|
||||
bool _fixSizeForRot;
|
||||
};
|
||||
|
||||
/**
|
||||
* A control that provides a horizontal sliding value controller.
|
||||
*/
|
||||
class OSGEARTHUTIL_EXPORT HSliderControl : public Control
|
||||
{
|
||||
public:
|
||||
HSliderControl( float min = 0.0f, float max = 100.0f, float value = 50.0f );
|
||||
|
||||
void setMin( float min, bool notify =true );
|
||||
float getMin() const { return _min; }
|
||||
|
||||
void setMax( float max, bool notify =true );
|
||||
float getMax() const { return _max; }
|
||||
|
||||
void setValue( float value, bool notify =true );
|
||||
float getValue() const { return _value; }
|
||||
|
||||
public: // Control
|
||||
//virtual void calcSize( const ControlContext& context, osg::Vec2f& out_size );
|
||||
virtual void draw( const ControlContext& cx, DrawableList& out );
|
||||
|
||||
protected:
|
||||
virtual bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, ControlContext& cx );
|
||||
|
||||
void fireValueChanged();
|
||||
|
||||
private:
|
||||
float _min, _max, _value;
|
||||
};
|
||||
|
||||
/**
|
||||
* A check box toggle.
|
||||
*/
|
||||
class OSGEARTHUTIL_EXPORT CheckBoxControl : public Control
|
||||
{
|
||||
public:
|
||||
explicit CheckBoxControl( bool checked = false );
|
||||
CheckBoxControl( bool checked, ControlEventHandler* callback );
|
||||
|
||||
void setValue( bool value );
|
||||
bool getValue() const { return _value; }
|
||||
|
||||
public:
|
||||
virtual void draw( const ControlContext& cx, DrawableList& out );
|
||||
|
||||
protected:
|
||||
virtual bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, ControlContext& cx );
|
||||
|
||||
void fireValueChanged();
|
||||
|
||||
private:
|
||||
bool _value;
|
||||
};
|
||||
|
||||
typedef std::vector< osg::ref_ptr<Control> > ControlList;
|
||||
|
||||
/**
|
||||
* A control that renders a simple rectangular border for a container.
|
||||
* This is also the base class for all Frame objects.
|
||||
*/
|
||||
class OSGEARTHUTIL_EXPORT Frame : public ImageControl
|
||||
{
|
||||
public:
|
||||
Frame();
|
||||
|
||||
public: // Control
|
||||
virtual void calcPos ( const ControlContext& context, const osg::Vec2f& cursor, const osg::Vec2f& parentSize );
|
||||
virtual void draw( const ControlContext& context, DrawableList& drawables );
|
||||
};
|
||||
|
||||
/**
|
||||
* A Frame with nice rounded corners.
|
||||
*/
|
||||
class OSGEARTHUTIL_EXPORT RoundedFrame : public Frame
|
||||
{
|
||||
public:
|
||||
RoundedFrame();
|
||||
|
||||
public:
|
||||
virtual void draw( const ControlContext& cx, DrawableList& drawables );
|
||||
};
|
||||
|
||||
/**
|
||||
* Container is a control that houses child controls. This is the base class for
|
||||
* all containers. (It is abstract so cannot be used directly)
|
||||
* Containers are control, so you can nest them in other containers.
|
||||
*/
|
||||
class OSGEARTHUTIL_EXPORT Container : public Control
|
||||
{
|
||||
public:
|
||||
Container();
|
||||
|
||||
// the Frame connected to this container. can be NULL for no frame.
|
||||
void setFrame( Frame* frame );
|
||||
Frame* getFrame() const { return _frame.get(); }
|
||||
|
||||
// space between children
|
||||
void setChildSpacing( float value );
|
||||
float childSpacing() const { return _spacing; }
|
||||
|
||||
// horiz alignment to set on children (that do not already have alignment explicity set)
|
||||
void setChildHorizAlign( Alignment align );
|
||||
const optional<Alignment>& childHorizAlign() const { return _childhalign; }
|
||||
|
||||
// vert alignment to set on children (that do not already have alignment explicity set)
|
||||
void setChildVertAlign( Alignment align );
|
||||
const optional<Alignment>& childVertAlign() const { return _childvalign; }
|
||||
|
||||
// default add function.
|
||||
virtual void addControl( Control* control, int index =-1 ) =0;
|
||||
|
||||
// default multiple-add function.
|
||||
virtual void addControls( const ControlVector& controls );
|
||||
|
||||
// access to the child list.
|
||||
virtual const ControlList& children() const =0;
|
||||
|
||||
// clear the controls list.
|
||||
virtual void clearControls() =0;
|
||||
|
||||
public:
|
||||
virtual void calcSize( const ControlContext& context, osg::Vec2f& out_size );
|
||||
virtual void calcFill( const ControlContext& context );
|
||||
virtual void calcPos ( const ControlContext& context, const osg::Vec2f& cursor, const osg::Vec2f& parentSize );
|
||||
virtual void draw( const ControlContext& context, DrawableList& drawables );
|
||||
|
||||
protected:
|
||||
virtual bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, ControlContext& cx );
|
||||
|
||||
void applyChildAligns();
|
||||
|
||||
//void setChildRenderSize( Control* child, float w, float h ) { child->_renderSize.set( w, h ); }
|
||||
float& renderWidth(Control* child) { return child->_renderSize.x(); }
|
||||
float& renderHeight(Control* child) { return child->_renderSize.y(); }
|
||||
|
||||
private:
|
||||
osg::ref_ptr<Frame> _frame;
|
||||
float _spacing;
|
||||
optional<Alignment> _childhalign;
|
||||
optional<Alignment> _childvalign;
|
||||
|
||||
ControlList& mutable_children() { return const_cast<ControlList&>(children()); }
|
||||
};
|
||||
|
||||
/**
|
||||
* Container that stacks controls vertically.
|
||||
*/
|
||||
class OSGEARTHUTIL_EXPORT VBox : public Container
|
||||
{
|
||||
public:
|
||||
VBox();
|
||||
|
||||
public: // Container
|
||||
virtual void addControl( Control* control, int index =-1 );
|
||||
virtual const ControlList& children() const { return _controls; }
|
||||
virtual void clearControls();
|
||||
|
||||
public: // Control
|
||||
virtual void calcSize( const ControlContext& context, osg::Vec2f& out_size );
|
||||
virtual void calcFill( const ControlContext& context );
|
||||
virtual void calcPos ( const ControlContext& context, const osg::Vec2f& cursor, const osg::Vec2f& parentSize );
|
||||
virtual void draw( const ControlContext& context, DrawableList& drawables );
|
||||
|
||||
private:
|
||||
ControlList _controls;
|
||||
};
|
||||
|
||||
/**
|
||||
* Container that stacks controls horizontally.
|
||||
*/
|
||||
class OSGEARTHUTIL_EXPORT HBox : public Container
|
||||
{
|
||||
public:
|
||||
HBox();
|
||||
|
||||
public: // Container
|
||||
virtual void addControl( Control* control, int index =-1 );
|
||||
virtual const ControlList& children() const { return _controls; }
|
||||
virtual void clearControls();
|
||||
|
||||
public: // Control
|
||||
virtual void calcSize( const ControlContext& context, osg::Vec2f& out_size );
|
||||
virtual void calcFill( const ControlContext& context );
|
||||
virtual void calcPos ( const ControlContext& context, const osg::Vec2f& cursor, const osg::Vec2f& parentSize );
|
||||
virtual void draw( const ControlContext& context, DrawableList& drawables );
|
||||
|
||||
private:
|
||||
ControlList _controls;
|
||||
};
|
||||
|
||||
/**
|
||||
* Container that organizes its children in a grid.
|
||||
*/
|
||||
class OSGEARTHUTIL_EXPORT Grid : public Container
|
||||
{
|
||||
public:
|
||||
Grid();
|
||||
|
||||
void setControl( int col, int row, Control* control );
|
||||
|
||||
unsigned getNumRows() const { return _rows.size(); }
|
||||
unsigned getNumColumns() const { return _colWidths.size(); }
|
||||
|
||||
public: // Container
|
||||
virtual void addControl( Control* control, int index =-1 );
|
||||
virtual const ControlList& children() const { return _children; }
|
||||
virtual void clearControls();
|
||||
|
||||
// adds the controls as a row at the bottom of the grid.
|
||||
virtual void addControls( const ControlVector& controls );
|
||||
|
||||
public: // Control
|
||||
virtual void calcSize( const ControlContext& context, osg::Vec2f& out_size );
|
||||
virtual void calcFill( const ControlContext& context );
|
||||
virtual void calcPos ( const ControlContext& context, const osg::Vec2f& cursor, const osg::Vec2f& parentSize );
|
||||
virtual void draw( const ControlContext& context, DrawableList& drawables );
|
||||
|
||||
private:
|
||||
typedef std::vector< osg::ref_ptr<Control> > Row;
|
||||
typedef std::vector< Row > RowVector;
|
||||
RowVector _rows;
|
||||
ControlList _children;
|
||||
|
||||
osg::ref_ptr<Control>& cell(int col, int row);
|
||||
void expandToInclude(int cols, int rows);
|
||||
|
||||
std::vector<float> _rowHeights, _colWidths;
|
||||
};
|
||||
|
||||
class OSGEARTHUTIL_EXPORT RefNodeVector :
|
||||
public osg::Referenced,
|
||||
public osg::MixinVector<osg::Node*> { };
|
||||
|
||||
/**
|
||||
* A control wrapped in a node that you can place anywhere in the scene
|
||||
* graph. Its scene location will control its 2D screen position, and it
|
||||
* can participate in conflict resolution.
|
||||
*/
|
||||
class OSGEARTHUTIL_EXPORT ControlNode : public osg::Node
|
||||
{
|
||||
public:
|
||||
/** Constructs a new control node with an embedded control. */
|
||||
ControlNode( Control* control, float priority =0.0f );
|
||||
|
||||
/** The control encaspulated in this node */
|
||||
Control* getControl() const { return _control.get(); }
|
||||
|
||||
/** The draw priority of this control */
|
||||
float getPriority() const { return _priority; }
|
||||
|
||||
/** The point (in screen-space, relative to the lower-left of the control) that should anchor to the scene */
|
||||
optional<osg::Vec2f>& anchorPoint() { return _anchor; }
|
||||
const optional<osg::Vec2f>& anchorPoint() const { return _anchor; }
|
||||
|
||||
|
||||
public: // osg::Node overrides
|
||||
|
||||
virtual void traverse( osg::NodeVisitor& nv );
|
||||
|
||||
virtual osg::BoundingSphere computeBound() const;
|
||||
|
||||
protected:
|
||||
|
||||
struct PerViewData
|
||||
{
|
||||
PerViewData();
|
||||
bool _obscured;
|
||||
float _visibleTime;
|
||||
osg::Vec3f _screenPos;
|
||||
unsigned _visitFrame;
|
||||
osg::ref_ptr<osg::Uniform> _uniform;
|
||||
osg::observer_ptr<osg::Camera> _canvas;
|
||||
};
|
||||
typedef std::map<osg::View*,PerViewData> PerViewDataMap;
|
||||
|
||||
PerViewDataMap _perViewData;
|
||||
osg::ref_ptr<Control> _control;
|
||||
float _priority;
|
||||
optional<osg::Vec2f> _anchor;
|
||||
|
||||
PerViewData& getData( osg::View* view ) { return _perViewData[view]; }
|
||||
|
||||
friend class ControlNodeBin;
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal class that renders ControlNode objects found in the scene graph.
|
||||
* There is no need to instantiate or access this object directly.
|
||||
*/
|
||||
class OSGEARTHUTIL_EXPORT ControlNodeBin : public osg::Group
|
||||
{
|
||||
public:
|
||||
ControlNodeBin();
|
||||
|
||||
/** Registers a control node with this bin. */
|
||||
void addNode( ControlNode* node );
|
||||
|
||||
/** Whether to fade-in controls when they appear in view (default=true) */
|
||||
void setFading( bool value );
|
||||
|
||||
private:
|
||||
typedef std::pair<float, osg::ref_ptr<ControlNode> > ControlNodePair;
|
||||
typedef std::multimap<float, osg::ref_ptr<ControlNode> > ControlNodeCollection;
|
||||
ControlNodeCollection _controlNodes;
|
||||
|
||||
typedef std::pair<Control*, ControlNodeCollection::iterator> ControlIndexPair;
|
||||
typedef std::map<Control*, ControlNodeCollection::iterator> ControlIndex;
|
||||
ControlIndex _index;
|
||||
|
||||
typedef std::map<ControlNode*, osg::MatrixTransform*> RenderNodeTable;
|
||||
typedef std::pair<ControlNode*, osg::MatrixTransform*> RenderNodePair;
|
||||
RenderNodeTable _renderNodes;
|
||||
|
||||
osg::ref_ptr<osg::Group> _group;
|
||||
std::vector<osg::BoundingBox> _taken;
|
||||
bool _sortingEnabled;
|
||||
bool _sortByDistance;
|
||||
bool _fading;
|
||||
|
||||
friend class ControlCanvas;
|
||||
friend class ControlNode;
|
||||
|
||||
void draw( const ControlContext& context, bool newContext, int bin );
|
||||
osg::Group* getControlGroup() const { return _group.get(); }
|
||||
};
|
||||
|
||||
/**
|
||||
* Associates controls with an OSG View.
|
||||
*/
|
||||
class OSGEARTHUTIL_EXPORT ControlCanvas : public osg::Camera
|
||||
{
|
||||
public:
|
||||
/** Accesses the control canvas attached the the specified view. */
|
||||
static ControlCanvas* get( osg::View* view, bool installCanvasInSceneData =false );
|
||||
|
||||
public:
|
||||
/** adds a top-level control to this surface. */
|
||||
void addControl( Control* control );
|
||||
|
||||
/** removes a top-level control. */
|
||||
void removeControl( Control* control );
|
||||
|
||||
/** gets the top-most control that intersects the specified position. */
|
||||
Control* getControlAtMouse( float x, float y ) const;
|
||||
|
||||
/** Toggles whether ControlNodes are allowed to overlap. */
|
||||
void setAllowControlNodeOverlap( bool value );
|
||||
|
||||
public:
|
||||
// internal- no need to call directly
|
||||
void update( const osg::FrameStamp* frameStamp );
|
||||
|
||||
// internal - no need to call directly
|
||||
void setControlContext( const ControlContext& );
|
||||
|
||||
public:
|
||||
virtual void traverse( osg::NodeVisitor& nv ); // override
|
||||
|
||||
virtual ~ControlCanvas();
|
||||
|
||||
/**
|
||||
* Constructs a new canvas and attaches it to a view. Call
|
||||
* getOrCreateControlCanvas(view) to create one.
|
||||
*/
|
||||
explicit ControlCanvas( osgViewer::View* view );
|
||||
|
||||
protected:
|
||||
|
||||
ControlList _controls;
|
||||
GeodeTable _geodeTable;
|
||||
ControlContext _context;
|
||||
bool _contextDirty;
|
||||
|
||||
osg::ref_ptr<ControlNodeBin> _controlNodeBin;
|
||||
|
||||
private:
|
||||
friend struct ControlCanvasEventHandler;
|
||||
friend class ControlNode;
|
||||
|
||||
ControlCanvas( osgViewer::View* view, bool registerCanvas );
|
||||
void init( osgViewer::View* view, bool registerCanvas );
|
||||
|
||||
bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa );
|
||||
|
||||
// a static registry of canvases in the scene graph.
|
||||
typedef std::map<osg::View*, ControlCanvas*> ViewCanvasMap;
|
||||
static ViewCanvasMap _viewCanvasMap;
|
||||
static OpenThreads::Mutex _viewCanvasMapMutex;
|
||||
|
||||
/** Accesses the priority rendering bin for this canvas. */
|
||||
ControlNodeBin* getControlNodeBin() { return _controlNodeBin.get(); }
|
||||
};
|
||||
|
||||
|
||||
} } } // namespace osgEarth::Util::Controls
|
||||
|
||||
#endif // OSGEARTHUTIL_CONTROLS
|
38
src/plugins/globe/python/CMakeLists.txt
Normal file
@ -0,0 +1,38 @@
|
||||
SET (PYTHON_OUTPUT_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/python)
|
||||
|
||||
SET (QGIS_GLOBE_PYTHON_OUTPUT_DIRECTORY ${PYTHON_OUTPUT_DIRECTORY}/qgis)
|
||||
|
||||
SET (QGIS_GLOBE_PYTHON_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
SET (QGIS_GLOBE_INCLUDE_DIRECTORY {CMAKE_CURRENT_SOURCE_DIR}/..)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${PYTHON_INCLUDE_PATH}
|
||||
${SIP_INCLUDE_DIR}
|
||||
..
|
||||
../../../core
|
||||
)
|
||||
|
||||
IF(WIN32)
|
||||
IF(MSVC)
|
||||
ADD_DEFINITIONS("-DGLOBE_EXPORT=${DLLIMPORT}")
|
||||
ENDIF(MSVC)
|
||||
ENDIF(WIN32)
|
||||
|
||||
|
||||
SET(SIP_INCLUDES ${SIP_INCLUDES} ${QGIS_GLOBE_PYTHON_DIRECTORY})
|
||||
|
||||
SET(SIP_DISABLE_FEATURES ${SIP_DISABLE_FEATURES} QSETINT_CONVERSION)
|
||||
SET(SIP_DISABLE_FEATURES ${SIP_DISABLE_FEATURES} QSETTYPE_CONVERSION)
|
||||
SET(SIP_DISABLE_FEATURES ${SIP_DISABLE_FEATURES} QVECTORINT_CONVERSION)
|
||||
IF(NOT ENABLE_QT5)
|
||||
SET(SIP_DISABLE_FEATURES ${SIP_DISABLE_FEATURES} QT5_SUPPORT)
|
||||
ENDIF(NOT ENABLE_QT5)
|
||||
|
||||
# globe module
|
||||
SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${QGIS_GLOBE_PYTHON_OUTPUT_DIRECTORY})
|
||||
SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${QGIS_GLOBE_PYTHON_OUTPUT_DIRECTORY})
|
||||
FILE(GLOB_RECURSE sip_files_globe *.sip)
|
||||
SET(SIP_EXTRA_FILES_DEPEND ${sip_files_globe})
|
||||
SET(SIP_EXTRA_OPTIONS ${PYQT_SIP_FLAGS} -o -a ${CMAKE_BINARY_DIR}/python/qgis.globe.api)
|
||||
GENERATE_SIP_PYTHON_MODULE_CODE(qgis.globe globe.sip cpp_files)
|
||||
BUILD_SIP_PYTHON_MODULE(qgis.globe globe.sip ${cpp_files} "" globeplugin)
|
24
src/plugins/globe/python/__init__.py
Executable file
@ -0,0 +1,24 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
***************************************************************************
|
||||
__init__.py
|
||||
---------------------
|
||||
Date : Aug 2013
|
||||
Copyright : (C) 2013 by Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************
|
||||
"""
|
||||
|
||||
__author__ = 'Matthias Kuhn'
|
||||
__date__ = 'August 2013'
|
||||
__copyright__ = '(C) 2013, Matthias Kuhn'
|
||||
# This will get replaced with a git SHA1 when you do a git archive
|
||||
__revision__ = '$Format:%H$'
|
22
src/plugins/globe/python/globe.sip
Normal file
@ -0,0 +1,22 @@
|
||||
%Import QtCore/QtCoremod.sip
|
||||
%Import QtGui/QtGuimod.sip
|
||||
|
||||
%Import gui/gui.sip
|
||||
%Import core/core.sip
|
||||
|
||||
//%Import osgEarth/Symbology/Symbology.sip
|
||||
//%Import osgEarth/Features/Features.sip
|
||||
|
||||
%Import osg/osg/osg.sip
|
||||
%Import osg/osgViewer/osgViewer.sip
|
||||
|
||||
%Module(name=qgis.globe,
|
||||
version=0,
|
||||
keyword_arguments="Optional")
|
||||
|
||||
%If(WS_WIN)
|
||||
typedef void XEvent;
|
||||
%End
|
||||
|
||||
//%Include qgsglobefeatureutils.sip
|
||||
%Include qgsglobeinterface.sip
|
16
src/plugins/globe/python/qgsglobefeatureutils.sip
Normal file
@ -0,0 +1,16 @@
|
||||
class QgsGlobeFeatureUtils
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <qgsglobefeatureutils.h>
|
||||
%End
|
||||
public:
|
||||
static inline QgsPointV2 qgsPointFromPoint( const osg::Vec3d& pt );
|
||||
static inline osg::Vec3d pointFromQgsPoint( const QgsPointV2& pt );
|
||||
static inline osgEarth::Features::LineString* lineStringFromQgsLineString( const QgsLineStringV2* lineString );
|
||||
static inline osgEarth::Features::Polygon* polygonFromQgsPolygon( const QgsPolygonV2* polygon );
|
||||
static inline osgEarth::Features::Geometry* geometryFromQgsGeometry( const QgsGeometry& geom );
|
||||
static osgEarth::Features::Feature* featureFromQgsFeature( QgsVectorLayer* layer, QgsFeature& feat );
|
||||
static void setFeatureField( osgEarth::Features::Feature* feature, const QgsField& field, const QVariant& value );
|
||||
static osgEarth::Features::FeatureSchema schemaForFields( const QgsFields& fields );
|
||||
};
|
||||
|
44
src/plugins/globe/python/qgsglobeinterface.sip
Normal file
@ -0,0 +1,44 @@
|
||||
/***************************************************************************
|
||||
qgsglobeinterface.sip
|
||||
--------------------------------------
|
||||
Date : 22.8.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
class QgsGlobeInterface : QObject
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include "qgsglobeinterface.h"
|
||||
%End
|
||||
|
||||
// Provide converter code
|
||||
// Attention: qgis.globe has to be imported before this interface
|
||||
// is requested the first time. In case this is not done,
|
||||
// the converter code will not be executed and this will be treated as
|
||||
// a (useless) QgsPluginInterface object instead.
|
||||
%ConvertToSubClassCode
|
||||
if ( sipCpp->inherits( sipName_QgsGlobeInterface ) )
|
||||
sipType = sipType_QgsGlobeInterface;
|
||||
else
|
||||
sipType = NULL;
|
||||
%End
|
||||
|
||||
|
||||
public:
|
||||
osgViewer::Viewer* osgViewer();
|
||||
// osgEarth::MapNode* mapNode();
|
||||
void syncExtent();
|
||||
void enableFrustumHighlight( bool status );
|
||||
void enableFeatureIdentification( bool status );
|
||||
private:
|
||||
// Instances will only be created from the globe plugin itself
|
||||
QgsGlobeInterface();
|
||||
};
|
85
src/plugins/globe/qgsglobefeatureidentify.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
/***************************************************************************
|
||||
qgsglobefeatureidentify.cpp
|
||||
--------------------------------------
|
||||
Date : 27.10.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 "qgsglobefeatureidentify.h"
|
||||
#include "qgsmapcanvas.h"
|
||||
#include "featuresource/qgsglobefeaturesource.h"
|
||||
|
||||
#include <qgsmaplayerregistry.h>
|
||||
#include <qgsrubberband.h>
|
||||
#include <qgsvectorlayer.h>
|
||||
#include <osg/ValueObject>
|
||||
#include <osgEarth/Registry>
|
||||
|
||||
QgsGlobeFeatureIdentifyCallback::QgsGlobeFeatureIdentifyCallback( QgsMapCanvas* mapCanvas )
|
||||
: mCanvas( mapCanvas ), mRubberBand( new QgsRubberBand( mapCanvas, QGis::Polygon ) )
|
||||
{
|
||||
QColor color( Qt::green );
|
||||
color.setAlpha( 190 );
|
||||
|
||||
mRubberBand->setColor( color );
|
||||
}
|
||||
|
||||
QgsGlobeFeatureIdentifyCallback::~QgsGlobeFeatureIdentifyCallback()
|
||||
{
|
||||
mCanvas->scene()->removeItem( mRubberBand );
|
||||
delete mRubberBand;
|
||||
}
|
||||
|
||||
#if OSGEARTH_VERSION_LESS_THAN(2, 7, 0)
|
||||
void QgsGlobeFeatureIdentifyCallback::onHit( osgEarth::Features::FeatureSourceIndexNode* index, osgEarth::Features::FeatureID fid, const EventArgs& /*args*/ )
|
||||
{
|
||||
QgsGlobeFeatureSource* globeSource = dynamic_cast<QgsGlobeFeatureSource*>( index->getFeatureSource() );
|
||||
if ( globeSource )
|
||||
{
|
||||
QgsVectorLayer* lyr = globeSource->layer();
|
||||
|
||||
#else
|
||||
void QgsGlobeFeatureIdentifyCallback::onHit( osgEarth::ObjectID id )
|
||||
{
|
||||
osgEarth::Features::FeatureIndex* index = osgEarth::Registry::objectIndex()->get<osgEarth::Features::FeatureIndex>( id );
|
||||
osgEarth::Features::Feature* feature = index->getFeature( id );
|
||||
osgEarth::Features::FeatureID fid = feature->getFID();
|
||||
std::string layerId;
|
||||
if ( feature->getUserValue( "qgisLayerId", layerId ) )
|
||||
{
|
||||
QgsVectorLayer* lyr = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( QString::fromStdString( layerId ) ) );
|
||||
#endif
|
||||
if ( lyr )
|
||||
{
|
||||
QgsFeature feat;
|
||||
lyr->getFeatures( QgsFeatureRequest().setFilterFid( fid ) ).nextFeature( feat );
|
||||
|
||||
if ( feat.isValid() )
|
||||
mRubberBand->setToGeometry( feat.geometry(), lyr );
|
||||
else
|
||||
mRubberBand->reset( QGis::Polygon );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsDebugMsg( "Clicked feature was not on a QGIS layer" );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if OSGEARTH_VERSION_LESS_THAN(2, 7, 0)
|
||||
void QgsGlobeFeatureIdentifyCallback::onMiss( const EventArgs &/*args*/ )
|
||||
#else
|
||||
void QgsGlobeFeatureIdentifyCallback::onMiss()
|
||||
#endif
|
||||
{
|
||||
mRubberBand->reset( QGis::Polygon );
|
||||
}
|
48
src/plugins/globe/qgsglobefeatureidentify.h
Normal file
@ -0,0 +1,48 @@
|
||||
/***************************************************************************
|
||||
qgsglobefeatureidentify.h
|
||||
--------------------------------------
|
||||
Date : 27.10.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSGLOBEFEATUREIDENTIFY_H
|
||||
#define QGSGLOBEFEATUREIDENTIFY_H
|
||||
|
||||
#include <osgEarth/Version>
|
||||
#include <osgEarthUtil/FeatureQueryTool>
|
||||
|
||||
class QgsMapCanvas;
|
||||
class QgsRubberBand;
|
||||
|
||||
#if OSGEARTH_VERSION_LESS_THAN(2, 7, 0)
|
||||
class QgsGlobeFeatureIdentifyCallback : public osgEarth::Util::FeatureQueryTool::Callback
|
||||
#else
|
||||
class QgsGlobeFeatureIdentifyCallback : public osgEarth::Picker::Callback
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
QgsGlobeFeatureIdentifyCallback( QgsMapCanvas* mapCanvas );
|
||||
~QgsGlobeFeatureIdentifyCallback();
|
||||
|
||||
#if OSGEARTH_VERSION_LESS_THAN(2, 7, 0)
|
||||
void onHit( osgEarth::Features::FeatureSourceIndexNode* index, osgEarth::Features::FeatureID fid, const EventArgs& args ) override;
|
||||
void onMiss( const EventArgs &args ) override;
|
||||
#else
|
||||
void onHit( osgEarth::ObjectID id ) override;
|
||||
void onMiss() override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
QgsMapCanvas* mCanvas;
|
||||
QgsRubberBand* mRubberBand;
|
||||
};
|
||||
|
||||
#endif // QGSGLOBEFEATUREIDENTIFY_H
|
59
src/plugins/globe/qgsglobefrustumhighlight.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
/***************************************************************************
|
||||
qgsglobefrustumhighlight.cpp
|
||||
--------------------------------------
|
||||
Date : 27.10.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 <qgsrubberband.h>
|
||||
#include <qgsmapcanvas.h>
|
||||
#include <qgsmaprenderer.h>
|
||||
#include <osg/View>
|
||||
#include <osgEarth/SpatialReference>
|
||||
#include <osgEarth/Terrain>
|
||||
|
||||
#include "qgsglobefrustumhighlight.h"
|
||||
|
||||
QgsGlobeFrustumHighlightCallback::QgsGlobeFrustumHighlightCallback( osg::View* view, osgEarth::Terrain* terrain, QgsMapCanvas* mapCanvas, QColor color )
|
||||
: osg::NodeCallback()
|
||||
, mView( view )
|
||||
, mTerrain( terrain )
|
||||
, mRubberBand( new QgsRubberBand( mapCanvas, QGis::Polygon ) )
|
||||
, mSrs( osgEarth::SpatialReference::create( mapCanvas->mapRenderer()->destinationCrs().toWkt().toStdString() ) )
|
||||
{
|
||||
mRubberBand->setColor( color );
|
||||
}
|
||||
|
||||
QgsGlobeFrustumHighlightCallback::~QgsGlobeFrustumHighlightCallback()
|
||||
{
|
||||
delete mRubberBand;
|
||||
}
|
||||
|
||||
void QgsGlobeFrustumHighlightCallback::operator()( osg::Node*, osg::NodeVisitor* )
|
||||
{
|
||||
const osg::Viewport::value_type &width = mView->getCamera()->getViewport()->width();
|
||||
const osg::Viewport::value_type &height = mView->getCamera()->getViewport()->height();
|
||||
|
||||
osg::Vec3d corners[4];
|
||||
|
||||
mTerrain->getWorldCoordsUnderMouse( mView, 0, 0, corners[0] );
|
||||
mTerrain->getWorldCoordsUnderMouse( mView, 0, height - 1, corners[1] );
|
||||
mTerrain->getWorldCoordsUnderMouse( mView, width - 1, height - 1, corners[2] );
|
||||
mTerrain->getWorldCoordsUnderMouse( mView, width - 1, 0, corners[3] );
|
||||
|
||||
mRubberBand->reset( QGis::Polygon );
|
||||
for ( int i = 0; i < 4; i++ )
|
||||
{
|
||||
osg::Vec3d localCoords;
|
||||
mSrs->transformFromWorld( corners[i], localCoords );
|
||||
mRubberBand->addPoint( QgsPoint( localCoords.x(), localCoords.y() ) );
|
||||
}
|
||||
}
|
44
src/plugins/globe/qgsglobefrustumhighlight.h
Normal file
@ -0,0 +1,44 @@
|
||||
/***************************************************************************
|
||||
qgsglobefrustumhighlight.h
|
||||
--------------------------------------
|
||||
Date : 27.10.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSGLOBEFRUSTUMHIGHLIGHT_H
|
||||
#define QGSGLOBEFRUSTUMHIGHLIGHT_H
|
||||
|
||||
#include <osg/NodeCallback>
|
||||
|
||||
class QgsRubberBand;
|
||||
namespace osg { class View; }
|
||||
namespace osgEarth
|
||||
{
|
||||
class Terrain;
|
||||
class SpatialReference;
|
||||
}
|
||||
|
||||
struct QgsGlobeFrustumHighlightCallback : public osg::NodeCallback
|
||||
{
|
||||
public:
|
||||
QgsGlobeFrustumHighlightCallback( osg::View* view, osgEarth::Terrain* terrain, QgsMapCanvas* mapCanvas, QColor color );
|
||||
~QgsGlobeFrustumHighlightCallback();
|
||||
|
||||
void operator()( osg::Node*, osg::NodeVisitor* ) override;
|
||||
|
||||
private:
|
||||
osg::View* mView;
|
||||
osgEarth::Terrain* mTerrain;
|
||||
QgsRubberBand* mRubberBand;
|
||||
osgEarth::SpatialReference* mSrs;
|
||||
};
|
||||
|
||||
#endif // QGSGLOBEFRUSTUMHIGHLIGHT_H
|
48
src/plugins/globe/qgsglobeinterface.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
/***************************************************************************
|
||||
qgsglobeinterface.cpp
|
||||
--------------------------------------
|
||||
Date : 22.8.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 "qgsglobeinterface.h"
|
||||
#include "globe_plugin.h"
|
||||
|
||||
QgsGlobeInterface::QgsGlobeInterface( GlobePlugin* const globe, QObject* parent )
|
||||
: QgsPluginInterface( parent )
|
||||
, mGlobe( globe )
|
||||
{
|
||||
}
|
||||
|
||||
osgViewer::Viewer* QgsGlobeInterface::osgViewer()
|
||||
{
|
||||
return mGlobe->osgViewer();
|
||||
}
|
||||
|
||||
osgEarth::MapNode* QgsGlobeInterface::mapNode()
|
||||
{
|
||||
return mGlobe->mapNode();
|
||||
}
|
||||
|
||||
void QgsGlobeInterface::syncExtent()
|
||||
{
|
||||
mGlobe->syncExtent();
|
||||
}
|
||||
|
||||
void QgsGlobeInterface::enableFrustumHighlight( bool status )
|
||||
{
|
||||
mGlobe->enableFrustumHighlight( status );
|
||||
}
|
||||
|
||||
void QgsGlobeInterface::enableFeatureIdentification( bool status )
|
||||
{
|
||||
mGlobe->enableFeatureIdentification( status );
|
||||
}
|
46
src/plugins/globe/qgsglobeinterface.h
Normal file
@ -0,0 +1,46 @@
|
||||
/***************************************************************************
|
||||
qgsglobeinterface.h
|
||||
--------------------------------------
|
||||
Date : 22.8.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSGLOBEINTERFACE_H
|
||||
#define QGSGLOBEINTERFACE_H
|
||||
|
||||
#include <QObject>
|
||||
#include "qgsplugininterface.h"
|
||||
|
||||
class GlobePlugin;
|
||||
class QDateTime;
|
||||
namespace osgViewer { class Viewer; }
|
||||
namespace osgEarth { class MapNode; }
|
||||
|
||||
class GLOBE_EXPORT QgsGlobeInterface : public QgsPluginInterface
|
||||
{
|
||||
public:
|
||||
QgsGlobeInterface( GlobePlugin* const globe, QObject* parent = 0 );
|
||||
|
||||
osgViewer::Viewer* osgViewer();
|
||||
|
||||
osgEarth::MapNode* mapNode();
|
||||
|
||||
void syncExtent();
|
||||
|
||||
void enableFrustumHighlight( bool status );
|
||||
|
||||
void enableFeatureIdentification( bool status );
|
||||
|
||||
private:
|
||||
GlobePlugin* mGlobe;
|
||||
};
|
||||
|
||||
#endif // QGSGLOBEINTERFACE_H
|
532
src/plugins/globe/qgsglobeplugindialog.cpp
Normal file
@ -0,0 +1,532 @@
|
||||
/***************************************************************************
|
||||
* qgsglobeplugindialog.cpp - settings dialog for the globe plugin
|
||||
* --------------------------------------
|
||||
* Date : 11-Nov-2010
|
||||
* Copyright : (C) 2010 by Marco Bernasocchi
|
||||
* Email : marco at bernawebdesign.ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 "qgsglobeplugindialog.h"
|
||||
#include "globe_plugin.h"
|
||||
|
||||
#include <qgsapplication.h>
|
||||
#include <qgsnetworkaccessmanager.h>
|
||||
#include <qgsproject.h>
|
||||
#include <qgslogger.h>
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QInputDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkReply>
|
||||
#include <QMenu>
|
||||
#include <QSettings>
|
||||
#include <QTimer>
|
||||
|
||||
#include <osg/DisplaySettings>
|
||||
#include <osgViewer/Viewer>
|
||||
#include <osgEarth/Version>
|
||||
#include <osgEarthUtil/EarthManipulator>
|
||||
|
||||
QgsGlobePluginDialog::QgsGlobePluginDialog( QWidget* parent, Qt::WFlags fl )
|
||||
: QDialog( parent, fl )
|
||||
{
|
||||
setupUi( this );
|
||||
|
||||
QMenu* addImageryMenu = new QMenu( this );
|
||||
|
||||
QMenu* tmsImageryMenu = new QMenu( this );
|
||||
tmsImageryMenu->addAction( "Readymap: NASA BlueMarble Imagery", this, SLOT( addTMSImagery() ) )->setData( "http://readymap.org/readymap/tiles/1.0.0/1/" );
|
||||
tmsImageryMenu->addAction( "Readymap: NASA BlueMarble, ocean only", this, SLOT( addTMSImagery() ) )->setData( "http://readymap.org/readymap/tiles/1.0.0/2/" );
|
||||
tmsImageryMenu->addAction( "Readymap: High resolution insets from various world locations", this, SLOT( addTMSImagery() ) )->setData( "http://readymap.org/readymap/tiles/1.0.0/3/" );
|
||||
tmsImageryMenu->addAction( "Readymap: Global Land Cover Facility 15m Landsat", this, SLOT( addTMSImagery() ) )->setData( "http://readymap.org/readymap/tiles/1.0.0/6/" );
|
||||
tmsImageryMenu->addAction( "Readymap: NASA BlueMarble + Landsat + Ocean Masking Layer", this, SLOT( addTMSImagery() ) )->setData( "http://readymap.org/readymap/tiles/1.0.0/7/" );
|
||||
tmsImageryMenu->addAction( tr( "Custom..." ), this, SLOT( addCustomTMSImagery() ) );
|
||||
addImageryMenu->addAction( tr( "TMS" ) )->setMenu( tmsImageryMenu );
|
||||
|
||||
QMenu* wmsImageryMenu = new QMenu( this );
|
||||
wmsImageryMenu->addAction( tr( "Custom..." ), this, SLOT( addCustomWMSImagery() ) );
|
||||
addImageryMenu->addAction( tr( "WMS" ) )->setMenu( wmsImageryMenu );
|
||||
|
||||
QMenu* fileImageryMenu = new QMenu( this );
|
||||
// fileImageryMenu->addAction("world.tif", this, SLOT(addRasterImagery()));
|
||||
fileImageryMenu->addAction( tr( "Custom..." ), this, SLOT( addCustomRasterImagery() ) );
|
||||
addImageryMenu->addAction( tr( "Raster" ) )->setMenu( fileImageryMenu );
|
||||
|
||||
mAddImageryButton->setMenu( addImageryMenu );
|
||||
|
||||
|
||||
QMenu* addElevationMenu = new QMenu( this );
|
||||
|
||||
QMenu* tmsElevationMenu = new QMenu( this );
|
||||
tmsElevationMenu->addAction( "Readymap: SRTM 90m Elevation Data", this, SLOT( addTMSElevation() ) )->setData( "http://readymap.org/readymap/tiles/1.0.0/9/" );
|
||||
tmsElevationMenu->addAction( tr( "Custom..." ), this, SLOT( addCustomTMSElevation() ) );
|
||||
addElevationMenu->addAction( tr( "TMS" ) )->setMenu( tmsElevationMenu );
|
||||
|
||||
QMenu* fileElevationMenu = new QMenu( this );
|
||||
fileElevationMenu->addAction( tr( "Custom..." ), this, SLOT( addCustomRasterElevation() ) );
|
||||
addElevationMenu->addAction( tr( "Raster" ) )->setMenu( fileElevationMenu );
|
||||
|
||||
mAddElevationButton->setMenu( addElevationMenu );
|
||||
|
||||
|
||||
comboBoxStereoMode->addItem( "OFF", -1 );
|
||||
comboBoxStereoMode->addItem( "ANAGLYPHIC", osg::DisplaySettings::ANAGLYPHIC );
|
||||
comboBoxStereoMode->addItem( "QUAD_BUFFER", osg::DisplaySettings::ANAGLYPHIC );
|
||||
comboBoxStereoMode->addItem( "HORIZONTAL_SPLIT", osg::DisplaySettings::HORIZONTAL_SPLIT );
|
||||
comboBoxStereoMode->addItem( "VERTICAL_SPLIT", osg::DisplaySettings::VERTICAL_SPLIT );
|
||||
|
||||
lineEditAASamples->setValidator( new QIntValidator( lineEditAASamples ) );
|
||||
|
||||
#if OSGEARTH_VERSION_LESS_THAN( 2, 5, 0 )
|
||||
mSpinBoxVerticalScale->setVisible( false );
|
||||
#endif
|
||||
|
||||
connect( checkBoxSkyAutoAmbient, SIGNAL( toggled( bool ) ), horizontalSliderMinAmbient, SLOT( setEnabled( bool ) ) );
|
||||
connect( buttonBox->button( QDialogButtonBox::Apply ), SIGNAL( clicked( bool ) ), this, SLOT( apply() ) );
|
||||
|
||||
restoreSavedSettings();
|
||||
readProjectSettings();
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::restoreSavedSettings()
|
||||
{
|
||||
QSettings settings;
|
||||
|
||||
// Video settings
|
||||
comboBoxStereoMode->setCurrentIndex( comboBoxStereoMode->findText( settings.value( "/Plugin-Globe/stereoMode", "OFF" ).toString() ) );
|
||||
spinBoxStereoScreenDistance->setValue( settings.value( "/Plugin-Globe/spinBoxStereoScreenDistance",
|
||||
osg::DisplaySettings::instance()->getScreenDistance() ).toDouble() );
|
||||
spinBoxStereoScreenWidth->setValue( settings.value( "/Plugin-Globe/spinBoxStereoScreenWidth",
|
||||
osg::DisplaySettings::instance()->getScreenWidth() ).toDouble() );
|
||||
spinBoxStereoScreenHeight->setValue( settings.value( "/Plugin-Globe/spinBoxStereoScreenHeight",
|
||||
osg::DisplaySettings::instance()->getScreenHeight() ).toDouble() );
|
||||
spinBoxStereoEyeSeparation->setValue( settings.value( "/Plugin-Globe/spinBoxStereoEyeSeparation",
|
||||
osg::DisplaySettings::instance()->getEyeSeparation() ).toDouble() );
|
||||
spinBoxSplitStereoHorizontalSeparation->setValue( settings.value( "/Plugin-Globe/spinBoxSplitStereoHorizontalSeparation",
|
||||
osg::DisplaySettings::instance()->getSplitStereoHorizontalSeparation() ).toInt() );
|
||||
spinBoxSplitStereoVerticalSeparation->setValue( settings.value( "/Plugin-Globe/spinBoxSplitStereoVerticalSeparation",
|
||||
osg::DisplaySettings::instance()->getSplitStereoVerticalSeparation() ).toInt() );
|
||||
comboBoxSplitStereoHorizontalEyeMapping->setCurrentIndex( settings.value( "/Plugin-Globe/comboBoxSplitStereoHorizontalEyeMapping",
|
||||
osg::DisplaySettings::instance()->getSplitStereoHorizontalEyeMapping() ).toInt() );
|
||||
comboBoxSplitStereoVerticalEyeMapping->setCurrentIndex( settings.value( "/Plugin-Globe/comboBoxSplitStereoVerticalEyeMapping",
|
||||
osg::DisplaySettings::instance()->getSplitStereoVerticalEyeMapping() ).toInt() );
|
||||
groupBoxAntiAliasing->setChecked( settings.value( "/Plugin-Globe/anti-aliasing", false ).toBool() );
|
||||
lineEditAASamples->setText( settings.value( "/Plugin-Globe/anti-aliasing-level", "" ).toString() );
|
||||
|
||||
// Advanced
|
||||
sliderScrollSensitivity->setValue( settings.value( "/Plugin-Globe/scrollSensitivity", 20 ).toInt() );
|
||||
checkBoxInvertScroll->setChecked( settings.value( "/Plugin-Globe/invertScrollWheel", 0 ).toInt() );
|
||||
checkBoxFrustumHighlighting->setChecked( settings.value( "/Plugin-Globe/frustum-highlighting", false ).toBool() );
|
||||
checkBoxFeatureIdentification->setChecked( settings.value( "/Plugin-Globe/feature-identification", false ).toBool() );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_buttonBox_accepted()
|
||||
{
|
||||
apply();
|
||||
accept();
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_buttonBox_rejected()
|
||||
{
|
||||
restoreSavedSettings();
|
||||
readProjectSettings();
|
||||
reject();
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::apply()
|
||||
{
|
||||
QSettings settings;
|
||||
|
||||
// Video settings
|
||||
settings.setValue( "/Plugin-Globe/stereoMode", comboBoxStereoMode->currentText() );
|
||||
settings.setValue( "/Plugin-Globe/stereoScreenDistance", spinBoxStereoScreenDistance->value() );
|
||||
settings.setValue( "/Plugin-Globe/stereoScreenWidth", spinBoxStereoScreenWidth->value() );
|
||||
settings.setValue( "/Plugin-Globe/stereoScreenHeight", spinBoxStereoScreenHeight->value() );
|
||||
settings.setValue( "/Plugin-Globe/stereoEyeSeparation", spinBoxStereoEyeSeparation->value() );
|
||||
settings.setValue( "/Plugin-Globe/SplitStereoHorizontalSeparation", spinBoxSplitStereoHorizontalSeparation->value() );
|
||||
settings.setValue( "/Plugin-Globe/SplitStereoVerticalSeparation", spinBoxSplitStereoVerticalSeparation->value() );
|
||||
settings.setValue( "/Plugin-Globe/SplitStereoHorizontalEyeMapping", comboBoxSplitStereoHorizontalEyeMapping->currentIndex() );
|
||||
settings.setValue( "/Plugin-Globe/SplitStereoVerticalEyeMapping", comboBoxSplitStereoVerticalEyeMapping->currentIndex() );
|
||||
settings.setValue( "/Plugin-Globe/anti-aliasing", groupBoxAntiAliasing->isChecked() );
|
||||
settings.setValue( "/Plugin-Globe/anti-aliasing-level", lineEditAASamples->text() );
|
||||
|
||||
// Advanced settings
|
||||
settings.setValue( "/Plugin-Globe/scrollSensitivity", sliderScrollSensitivity->value() );
|
||||
settings.setValue( "/Plugin-Globe/invertScrollWheel", checkBoxInvertScroll->checkState() );
|
||||
settings.setValue( "/Plugin-Globe/frustum-highlighting", checkBoxFrustumHighlighting->isChecked() );
|
||||
settings.setValue( "/Plugin-Globe/feature-identification", checkBoxFeatureIdentification->isChecked() );
|
||||
|
||||
writeProjectSettings();
|
||||
|
||||
// Apply stereo settings
|
||||
int stereoMode = comboBoxStereoMode->itemData( comboBoxStereoMode->currentIndex() ).toInt();
|
||||
if ( stereoMode == -1 )
|
||||
{
|
||||
osg::DisplaySettings::instance()->setStereo( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::DisplaySettings::instance()->setStereo( true );
|
||||
osg::DisplaySettings::instance()->setStereoMode(
|
||||
static_cast<osg::DisplaySettings::StereoMode>( stereoMode ) );
|
||||
osg::DisplaySettings::instance()->setEyeSeparation( spinBoxStereoEyeSeparation->value() );
|
||||
osg::DisplaySettings::instance()->setScreenDistance( spinBoxStereoScreenDistance->value() );
|
||||
osg::DisplaySettings::instance()->setScreenWidth( spinBoxStereoScreenWidth->value() );
|
||||
osg::DisplaySettings::instance()->setScreenHeight( spinBoxStereoScreenHeight->value() );
|
||||
osg::DisplaySettings::instance()->setSplitStereoVerticalSeparation(
|
||||
spinBoxSplitStereoVerticalSeparation->value() );
|
||||
osg::DisplaySettings::instance()->setSplitStereoVerticalEyeMapping(
|
||||
static_cast<osg::DisplaySettings::SplitStereoVerticalEyeMapping>(
|
||||
comboBoxSplitStereoVerticalEyeMapping->currentIndex() ) );
|
||||
osg::DisplaySettings::instance()->setSplitStereoHorizontalSeparation(
|
||||
spinBoxSplitStereoHorizontalSeparation->value() );
|
||||
osg::DisplaySettings::instance()->setSplitStereoHorizontalEyeMapping(
|
||||
static_cast<osg::DisplaySettings::SplitStereoHorizontalEyeMapping>(
|
||||
comboBoxSplitStereoHorizontalEyeMapping->currentIndex() ) );
|
||||
}
|
||||
|
||||
emit settingsApplied();
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::readProjectSettings()
|
||||
{
|
||||
// Imagery settings
|
||||
mImageryTreeView->clear();
|
||||
foreach ( const LayerDataSource& ds, getImageryDataSources() )
|
||||
{
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem( QStringList() << ds.type << ds.uri );
|
||||
item->setFlags( item->flags() & ~Qt::ItemIsDropEnabled );
|
||||
mImageryTreeView->addTopLevelItem( item );
|
||||
}
|
||||
mImageryTreeView->resizeColumnToContents( 0 );
|
||||
|
||||
// Elevation settings
|
||||
mElevationTreeView->clear();
|
||||
foreach ( const LayerDataSource& ds, getElevationDataSources() )
|
||||
{
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem( QStringList() << ds.type << ds.uri );
|
||||
item->setFlags( item->flags() & ~Qt::ItemIsDropEnabled );
|
||||
mElevationTreeView->addTopLevelItem( item );
|
||||
}
|
||||
mElevationTreeView->resizeColumnToContents( 0 );
|
||||
|
||||
#if OSGEARTH_VERSION_GREATER_OR_EQUAL( 2, 5, 0 )
|
||||
mSpinBoxVerticalScale->setValue( QgsProject::instance()->readDoubleEntry( "Globe-Plugin", "/verticalScale", 1 ) );
|
||||
#endif
|
||||
|
||||
// Map settings
|
||||
groupBoxSky->setChecked( QgsProject::instance()->readBoolEntry( "Globe-Plugin", "/skyEnabled", true ) );
|
||||
dateTimeEditSky->setDateTime( QDateTime::fromString( QgsProject::instance()->readEntry( "Globe-Plugin", "/skyDateTime", QDateTime::currentDateTime().toString() ) ) );
|
||||
checkBoxSkyAutoAmbient->setChecked( QgsProject::instance()->readBoolEntry( "Globe-Plugin", "/skyAutoAmbient", true ) );
|
||||
horizontalSliderMinAmbient->setValue( QgsProject::instance()->readDoubleEntry( "Globe-Plugin", "/skyMinAmbient", 30. ) );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::writeProjectSettings()
|
||||
{
|
||||
// Imagery settings
|
||||
QgsProject::instance()->removeEntry( "Globe-Plugin", "/imageryDatasources/" );
|
||||
for ( int row = 0, nRows = mImageryTreeView->topLevelItemCount(); row < nRows; ++row )
|
||||
{
|
||||
QTreeWidgetItem* item = mImageryTreeView->topLevelItem( row );
|
||||
QString key = QString( "/imageryDatasources/L%1" ).arg( row );
|
||||
QgsProject::instance()->writeEntry( "Globe-Plugin", key + "/type", item->text( 0 ) );
|
||||
QgsProject::instance()->writeEntry( "Globe-Plugin", key + "/uri", item->text( 1 ) );
|
||||
}
|
||||
|
||||
// Elevation settings
|
||||
QgsProject::instance()->removeEntry( "Globe-Plugin", "/elevationDatasources/" );
|
||||
for ( int row = 0, nRows = mElevationTreeView->topLevelItemCount(); row < nRows; ++row )
|
||||
{
|
||||
QTreeWidgetItem* item = mElevationTreeView->topLevelItem( row );
|
||||
QString key = QString( "/elevationDatasources/L%1" ).arg( row );
|
||||
QgsProject::instance()->writeEntry( "Globe-Plugin", key + "/type", item->text( 0 ) );
|
||||
QgsProject::instance()->writeEntry( "Globe-Plugin", key + "/uri", item->text( 1 ) );
|
||||
}
|
||||
|
||||
#if OSGEARTH_VERSION_GREATER_OR_EQUAL( 2, 5, 0 )
|
||||
QgsProject::instance()->writeEntry( "Globe-Plugin", "/verticalScale", mSpinBoxVerticalScale->value() );
|
||||
#endif
|
||||
|
||||
// Map settings
|
||||
QgsProject::instance()->writeEntry( "Globe-Plugin", "/skyEnabled/", groupBoxSky->isChecked() );
|
||||
QgsProject::instance()->writeEntry( "Globe-Plugin", "/skyDateTime/", dateTimeEditSky->dateTime().toString() );
|
||||
QgsProject::instance()->writeEntry( "Globe-Plugin", "/skyAutoAmbient/", checkBoxSkyAutoAmbient->isChecked() );
|
||||
QgsProject::instance()->writeEntry( "Globe-Plugin", "/skyMinAmbient/", horizontalSliderMinAmbient->value() );
|
||||
}
|
||||
|
||||
bool QgsGlobePluginDialog::validateRemoteUri( const QString& uri, QString& errMsg ) const
|
||||
{
|
||||
QUrl url( uri );
|
||||
QgsNetworkAccessManager* nam = QgsNetworkAccessManager::instance();
|
||||
QNetworkReply* reply = nullptr;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
QNetworkRequest req( url );
|
||||
req.setRawHeader( "User-Agent" , "Wget/1.13.4" );
|
||||
reply = nam->get( req );
|
||||
QTimer timer;
|
||||
QEventLoop loop;
|
||||
QObject::connect( &timer, SIGNAL( timeout() ), &loop, SLOT( quit() ) );
|
||||
QObject::connect( reply, SIGNAL( finished() ), &loop, SLOT( quit() ) );
|
||||
timer.setSingleShot( true );
|
||||
timer.start( 500 );
|
||||
loop.exec();
|
||||
if ( reply->isRunning() )
|
||||
{
|
||||
// Timeout
|
||||
reply->close();
|
||||
delete reply;
|
||||
errMsg = tr( "Timeout" );
|
||||
return false;
|
||||
}
|
||||
|
||||
QUrl redirectUrl = reply->attribute( QNetworkRequest::RedirectionTargetAttribute ).toUrl();
|
||||
if ( redirectUrl.isValid() && url != redirectUrl )
|
||||
{
|
||||
delete reply;
|
||||
url = redirectUrl;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
errMsg = reply->error() == QNetworkReply::NoError ? QString() : reply->errorString();
|
||||
delete reply;
|
||||
return errMsg.isEmpty();
|
||||
}
|
||||
|
||||
/// MAP ///////////////////////////////////////////////////////////////////////
|
||||
|
||||
void QgsGlobePluginDialog::addImagery( const QString& type, const QString& uri )
|
||||
{
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem( QStringList() << type << uri );
|
||||
item->setFlags( item->flags() & ~Qt::ItemIsDropEnabled );
|
||||
mImageryTreeView->addTopLevelItem( item );
|
||||
mImageryTreeView->resizeColumnToContents( 0 );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::addTMSImagery()
|
||||
{
|
||||
addImagery( "TMS", qobject_cast<QAction*>( QObject::sender() )->data().toString() );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::addCustomTMSImagery()
|
||||
{
|
||||
QString url = QInputDialog::getText( this, tr( "Add TMS Imagery" ), tr( "TMS URL:" ) );
|
||||
if ( !url.isEmpty() )
|
||||
{
|
||||
QString validationError;
|
||||
if ( !validateRemoteUri( url, validationError ) )
|
||||
{
|
||||
QMessageBox::warning( this, tr( "Invalid URL" ), validationError );
|
||||
}
|
||||
else
|
||||
{
|
||||
addImagery( "TMS", url );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::addCustomWMSImagery()
|
||||
{
|
||||
QString url = QInputDialog::getText( this, tr( "Add WMS Imagery" ), tr( "URL:" ) );
|
||||
if ( !url.isEmpty() )
|
||||
{
|
||||
QString validationError;
|
||||
if ( !validateRemoteUri( url, validationError ) )
|
||||
{
|
||||
QMessageBox::warning( this, tr( "Invalid URL" ), validationError );
|
||||
}
|
||||
else
|
||||
{
|
||||
addImagery( "WMS", url );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::addRasterImagery()
|
||||
{
|
||||
addImagery( "Raster", qobject_cast<QAction*>( QObject::sender() )->data().toString() );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::addCustomRasterImagery()
|
||||
{
|
||||
QString filename = QFileDialog::getOpenFileName( this, tr( "Add Raster Imagery" ) );
|
||||
if ( !filename.isEmpty() )
|
||||
{
|
||||
addImagery( "Raster", filename );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::addElevation( const QString& type, const QString& uri )
|
||||
{
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem( QStringList() << type << uri );
|
||||
item->setFlags( item->flags() & ~Qt::ItemIsDropEnabled );
|
||||
mElevationTreeView->addTopLevelItem( item );
|
||||
mElevationTreeView->resizeColumnToContents( 0 );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::addTMSElevation()
|
||||
{
|
||||
addElevation( "TMS", qobject_cast<QAction*>( QObject::sender() )->data().toString() );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::addCustomTMSElevation()
|
||||
{
|
||||
QString url = QInputDialog::getText( this, tr( "Add TMS Elevation" ), tr( "TMS URL:" ) );
|
||||
if ( !url.isEmpty() )
|
||||
{
|
||||
QString validationError;
|
||||
if ( !validateRemoteUri( url, validationError ) )
|
||||
{
|
||||
QMessageBox::warning( this, tr( "Invalid URL" ), validationError );
|
||||
}
|
||||
else
|
||||
{
|
||||
addElevation( "TMS", url );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::addCustomRasterElevation()
|
||||
{
|
||||
QString filename = QFileDialog::getOpenFileName( this, tr( "Add Raster Elevation" ) );
|
||||
if ( !filename.isEmpty() )
|
||||
{
|
||||
addElevation( "Raster", filename );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_mRemoveImageryButton_clicked()
|
||||
{
|
||||
delete mImageryTreeView->currentItem();
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_mRemoveElevationButton_clicked()
|
||||
{
|
||||
delete mElevationTreeView->currentItem();
|
||||
}
|
||||
|
||||
QList<QgsGlobePluginDialog::LayerDataSource> QgsGlobePluginDialog::getImageryDataSources() const
|
||||
{
|
||||
int keysCount = QgsProject::instance()->subkeyList( "Globe-Plugin", "/imageryDatasources/" ).count();
|
||||
QList<LayerDataSource> datasources;
|
||||
for ( int i = 0; i < keysCount; ++i )
|
||||
{
|
||||
QString key = QString( "/imageryDatasources/L%1" ).arg( i );
|
||||
LayerDataSource datasource;
|
||||
datasource.type = QgsProject::instance()->readEntry( "Globe-Plugin", key + "/type" );
|
||||
datasource.uri = QgsProject::instance()->readEntry( "Globe-Plugin", key + "/uri" );
|
||||
datasources.append( datasource );
|
||||
}
|
||||
return datasources;
|
||||
}
|
||||
|
||||
QList<QgsGlobePluginDialog::LayerDataSource> QgsGlobePluginDialog::getElevationDataSources() const
|
||||
{
|
||||
int keysCount = QgsProject::instance()->subkeyList( "Globe-Plugin", "/elevationDatasources/" ).count();
|
||||
QList<LayerDataSource> datasources;
|
||||
for ( int i = 0; i < keysCount; ++i )
|
||||
{
|
||||
QString key = QString( "/elevationDatasources/L%1" ).arg( i );
|
||||
LayerDataSource datasource;
|
||||
datasource.type = QgsProject::instance()->readEntry( "Globe-Plugin", key + "/type" );
|
||||
datasource.uri = QgsProject::instance()->readEntry( "Globe-Plugin", key + "/uri" );
|
||||
datasources.append( datasource );
|
||||
}
|
||||
return datasources;
|
||||
}
|
||||
|
||||
double QgsGlobePluginDialog::getVerticalScale() const
|
||||
{
|
||||
return mSpinBoxVerticalScale->value();
|
||||
}
|
||||
|
||||
bool QgsGlobePluginDialog::getSkyEnabled() const
|
||||
{
|
||||
return QgsProject::instance()->readBoolEntry( "Globe-Plugin", "/skyEnabled", true );
|
||||
}
|
||||
|
||||
QDateTime QgsGlobePluginDialog::getSkyDateTime() const
|
||||
{
|
||||
return QDateTime::fromString( QgsProject::instance()->readEntry( "Globe-Plugin", "/skyDateTime", QDateTime::currentDateTime().toString() ) );
|
||||
}
|
||||
|
||||
bool QgsGlobePluginDialog::getSkyAutoAmbience() const
|
||||
{
|
||||
return QgsProject::instance()->readBoolEntry( "Globe-Plugin", "/skyAutoAmbient", true );
|
||||
}
|
||||
|
||||
double QgsGlobePluginDialog::getSkyMinAmbient() const
|
||||
{
|
||||
return QgsProject::instance()->readDoubleEntry( "Globe-Plugin", "/skyMinAmbient", 30. ) / 100.;
|
||||
}
|
||||
|
||||
/// ADVANCED //////////////////////////////////////////////////////////////////
|
||||
|
||||
float QgsGlobePluginDialog::getScrollSensitivity() const
|
||||
{
|
||||
return sliderScrollSensitivity->value() / 10;
|
||||
}
|
||||
|
||||
bool QgsGlobePluginDialog::getInvertScrollWheel() const
|
||||
{
|
||||
return checkBoxInvertScroll->checkState();
|
||||
}
|
||||
|
||||
bool QgsGlobePluginDialog::getFrustumHighlighting() const
|
||||
{
|
||||
return checkBoxFrustumHighlighting->isChecked();
|
||||
}
|
||||
|
||||
bool QgsGlobePluginDialog::getFeatureIdenification() const
|
||||
{
|
||||
return checkBoxFeatureIdentification->isChecked();
|
||||
}
|
||||
|
||||
/// STEREO ////////////////////////////////////////////////////////////////////
|
||||
void QgsGlobePluginDialog::on_pushButtonStereoResetDefaults_clicked()
|
||||
{
|
||||
//http://www.openscenegraph.org/projects/osg/wiki/Support/UserGuides/StereoSettings
|
||||
comboBoxStereoMode->setCurrentIndex( comboBoxStereoMode->findText( "OFF" ) );
|
||||
spinBoxStereoScreenDistance->setValue( 0.5 );
|
||||
spinBoxStereoScreenHeight->setValue( 0.26 );
|
||||
spinBoxStereoScreenWidth->setValue( 0.325 );
|
||||
spinBoxStereoEyeSeparation->setValue( 0.06 );
|
||||
spinBoxSplitStereoHorizontalSeparation->setValue( 42 );
|
||||
spinBoxSplitStereoVerticalSeparation->setValue( 42 );
|
||||
comboBoxSplitStereoHorizontalEyeMapping->setCurrentIndex( 0 );
|
||||
comboBoxSplitStereoVerticalEyeMapping->setCurrentIndex( 0 );
|
||||
}
|
||||
|
||||
void QgsGlobePluginDialog::on_comboBoxStereoMode_currentIndexChanged( int index )
|
||||
{
|
||||
//http://www.openscenegraph.org/projects/osg/wiki/Support/UserGuides/StereoSettings
|
||||
//http://www.openscenegraph.org/documentation/OpenSceneGraphReferenceDocs/a00181.html
|
||||
|
||||
int stereoMode = comboBoxStereoMode->itemData( index ).toInt();
|
||||
bool stereoEnabled = stereoMode != -1;
|
||||
bool verticalSplit = stereoMode == osg::DisplaySettings::VERTICAL_SPLIT;
|
||||
bool horizontalSplit = stereoMode == osg::DisplaySettings::HORIZONTAL_SPLIT;
|
||||
|
||||
spinBoxStereoScreenDistance->setEnabled( stereoEnabled );
|
||||
spinBoxStereoScreenHeight->setEnabled( stereoEnabled );
|
||||
spinBoxStereoScreenWidth->setEnabled( stereoEnabled );
|
||||
spinBoxStereoEyeSeparation->setEnabled( stereoEnabled );
|
||||
spinBoxSplitStereoHorizontalSeparation->setEnabled( stereoEnabled && horizontalSplit );
|
||||
comboBoxSplitStereoHorizontalEyeMapping->setEnabled( stereoEnabled && horizontalSplit );
|
||||
spinBoxSplitStereoVerticalSeparation->setEnabled( stereoEnabled && verticalSplit );
|
||||
comboBoxSplitStereoVerticalEyeMapping->setEnabled( stereoEnabled && verticalSplit );
|
||||
}
|
83
src/plugins/globe/qgsglobeplugindialog.h
Normal file
@ -0,0 +1,83 @@
|
||||
/***************************************************************************
|
||||
qgsglobeplugindialog.h - settings dialog for the globe plugin
|
||||
--------------------------------------
|
||||
Date : 11-Nov-2010
|
||||
Copyright : (C) 2010 by Marco Bernasocchi
|
||||
Email : marco at bernawebdesign.ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#ifndef QGSGLOBEPLUGINDIALOG_H
|
||||
#define QGSGLOBEPLUGINDIALOG_H
|
||||
|
||||
#include <ui_qgsglobeplugindialog.h>
|
||||
#include <QDialog>
|
||||
|
||||
class GlobePlugin;
|
||||
class QgsVectorLayer;
|
||||
|
||||
class QgsGlobePluginDialog: public QDialog, private Ui::QgsGlobePluginDialogGuiBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QgsGlobePluginDialog( QWidget * parent = 0, Qt::WFlags fl = 0 );
|
||||
|
||||
struct LayerDataSource
|
||||
{
|
||||
QString uri;
|
||||
QString type;
|
||||
bool operator==( const LayerDataSource& other ) { return uri == other.uri && type == other.type; }
|
||||
bool operator!=( const LayerDataSource& other ) { return uri != other.uri || type != other.type; }
|
||||
};
|
||||
void readProjectSettings();
|
||||
|
||||
QString getBaseLayerUrl() const;
|
||||
bool getSkyEnabled() const;
|
||||
QDateTime getSkyDateTime() const;
|
||||
bool getSkyAutoAmbience() const;
|
||||
double getSkyMinAmbient() const;
|
||||
float getScrollSensitivity() const;
|
||||
bool getInvertScrollWheel() const;
|
||||
QList<LayerDataSource> getImageryDataSources() const;
|
||||
QList<LayerDataSource> getElevationDataSources() const;
|
||||
double getVerticalScale() const;
|
||||
bool getFrustumHighlighting() const;
|
||||
bool getFeatureIdenification() const;
|
||||
|
||||
signals:
|
||||
void settingsApplied();
|
||||
|
||||
private:
|
||||
void restoreSavedSettings();
|
||||
void writeProjectSettings();
|
||||
bool validateRemoteUri( const QString &uri , QString &errMsg ) const;
|
||||
|
||||
private slots:
|
||||
void apply();
|
||||
void on_buttonBox_accepted();
|
||||
void on_buttonBox_rejected();
|
||||
|
||||
void on_comboBoxStereoMode_currentIndexChanged( int index );
|
||||
void on_pushButtonStereoResetDefaults_clicked();
|
||||
|
||||
void on_mRemoveImageryButton_clicked();
|
||||
void on_mRemoveElevationButton_clicked();
|
||||
|
||||
void addImagery( const QString &type, const QString &uri );
|
||||
void addTMSImagery();
|
||||
void addCustomTMSImagery();
|
||||
void addCustomWMSImagery();
|
||||
void addRasterImagery();
|
||||
void addCustomRasterImagery();
|
||||
void addElevation( const QString &type, const QString &uri );
|
||||
void addTMSElevation();
|
||||
void addCustomTMSElevation();
|
||||
void addCustomRasterElevation();
|
||||
};
|
||||
|
||||
#endif // QGSGLOBEPLUGINDIALOG_H
|
665
src/plugins/globe/qgsglobeplugindialog.ui
Normal file
@ -0,0 +1,665 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QgsGlobePluginDialogGuiBase</class>
|
||||
<widget class="QDialog" name="QgsGlobePluginDialogGuiBase">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>748</width>
|
||||
<height>519</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Globe Settings</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset>
|
||||
<normaloff>../../.designer/backup</normaloff>../../.designer/backup</iconset>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="2" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tabMap">
|
||||
<attribute name="title">
|
||||
<string>Map</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="2" column="0">
|
||||
<widget class="QGroupBox" name="groupBoxSky">
|
||||
<property name="title">
|
||||
<string>Sk&y</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelDateTime">
|
||||
<property name="text">
|
||||
<string>Date / Time (UTC):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QDateTimeEdit" name="dateTimeEditSky">
|
||||
<property name="displayFormat">
|
||||
<string>dd.MM.yyyy HH:mm</string>
|
||||
</property>
|
||||
<property name="calendarPopup">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="checkBoxSkyAutoAmbient">
|
||||
<property name="text">
|
||||
<string>Ambient lighting</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSlider" name="horizontalSliderMinAmbient">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedControls">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::NoTicks</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="mImageryGroupBox">
|
||||
<property name="title">
|
||||
<string>Imagery</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="mImageryTreeView">
|
||||
<property name="dragEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::InternalMove</enum>
|
||||
</property>
|
||||
<property name="indentation">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="allColumnsShowFocus">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="columnCount">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="headerDefaultSectionSize">
|
||||
<number>50</number>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">1</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">2</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mAddImageryButton">
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::InstantPopup</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mRemoveImageryButton">
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<spacer name="verticalSpacerMapTab">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="mElevationGroupBox">
|
||||
<property name="title">
|
||||
<string>Elevation</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelVerticalScale">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Vertical scale:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QDoubleSpinBox" name="mSpinBoxVerticalScale">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QTreeWidget" name="mElevationTreeView">
|
||||
<property name="dragEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::InternalMove</enum>
|
||||
</property>
|
||||
<property name="indentation">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="allColumnsShowFocus">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="columnCount">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="headerDefaultSectionSize">
|
||||
<number>50</number>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">1</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">2</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mAddElevationButton">
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::InstantPopup</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mRemoveElevationButton">
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabVideo">
|
||||
<attribute name="title">
|
||||
<string>Video</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_8">
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="groupBoxAntiAliasing">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Anti Aliasing</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelAASamples">
|
||||
<property name="text">
|
||||
<string>Samples</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEditAASamples">
|
||||
<property name="placeholderText">
|
||||
<string>[Leave empty for maximum]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="labelVideoInfo">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><span style=" font-style:italic;">Change requires a restart of the globe plugin</span></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<spacer name="verticalSpacerVideoTab">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Stereo</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelStereoMode">
|
||||
<property name="text">
|
||||
<string>Stereo Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="comboBoxStereoMode"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelEyeSeparation">
|
||||
<property name="text">
|
||||
<string>Eye separation (m)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinBoxStereoEyeSeparation">
|
||||
<property name="readOnly">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::UpDownArrows</enum>
|
||||
</property>
|
||||
<property name="accelerated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.001000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelScreenDistance">
|
||||
<property name="text">
|
||||
<string>Screen distance (m)</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinBoxStereoScreenDistance</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinBoxStereoScreenDistance">
|
||||
<property name="accelerated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelScreenWidth">
|
||||
<property name="text">
|
||||
<string>Screen width (m)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinBoxStereoScreenWidth">
|
||||
<property name="accelerated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="labelScreenHeight">
|
||||
<property name="text">
|
||||
<string>Screen height (m)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinBoxStereoScreenHeight">
|
||||
<property name="accelerated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="labelSplitStereoHorizontalSeparation">
|
||||
<property name="text">
|
||||
<string>Split stereo horizontal separation (px)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxSplitStereoHorizontalSeparation">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="accelerated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="labelSplitStereoHorizontalEyeMapping">
|
||||
<property name="text">
|
||||
<string>Split stereo horizontal eye mapping</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="comboBoxSplitStereoHorizontalEyeMapping">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">LEFT_EYE_LEFT_VIEWPORT</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">LEFT_EYE_RIGHT_VIEWPORT</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="labelSplitStereoVerticalSeparation">
|
||||
<property name="text">
|
||||
<string>Split stereo vertical separation (px)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxSplitStereoVerticalSeparation">
|
||||
<property name="accelerated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="labelBoxSplitStereoVerticalEyeMapping">
|
||||
<property name="text">
|
||||
<string>Split stereo vertical eye mapping</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QComboBox" name="comboBoxSplitStereoVerticalEyeMapping">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">LEFT_EYE_TOP_VIEWPORT</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">LEFT_EYE_BOTTOM_VIEWPORT</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QPushButton" name="pushButtonStereoResetDefaults">
|
||||
<property name="text">
|
||||
<string>Reset to defaults</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabAdvanced">
|
||||
<attribute name="title">
|
||||
<string>Advanced</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBoxScrolling">
|
||||
<property name="title">
|
||||
<string>Scrolling</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_9">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelScollSensitivity">
|
||||
<property name="text">
|
||||
<string>Sensitivity:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSlider" name="sliderScrollSensitivity">
|
||||
<property name="minimum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="checkBoxInvertScroll">
|
||||
<property name="text">
|
||||
<string>Invert scroll wheel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxFeatureIdentification">
|
||||
<property name="text">
|
||||
<string>Enable feature identification</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxFrustumHighlighting">
|
||||
<property name="text">
|
||||
<string>Enable frustum highlighting</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacerAdvancedTab">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<tabstops>
|
||||
<tabstop>buttonBox</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
301
src/plugins/globe/qgsglobetilesource.cpp
Normal file
@ -0,0 +1,301 @@
|
||||
/***************************************************************************
|
||||
qgsglobetilesource.cpp
|
||||
---------------------
|
||||
begin : August 2010
|
||||
copyright : (C) 2010 by Pirmin Kalberer
|
||||
(C) 2015 Sandro Mani
|
||||
email : pka at sourcepole dot ch
|
||||
smani at sourcepole dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 <osgEarth/Registry>
|
||||
#include <osgEarth/ImageUtils>
|
||||
|
||||
#include "qgscrscache.h"
|
||||
#include "qgsglobetilesource.h"
|
||||
#include "qgscoordinatetransform.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsmapcanvas.h"
|
||||
#include "qgsmaprenderercustompainterjob.h"
|
||||
#include "qgsmaprendererparalleljob.h"
|
||||
|
||||
QgsGlobeTileStatistics* QgsGlobeTileStatistics::s_instance = 0;
|
||||
|
||||
QgsGlobeTileStatistics::QgsGlobeTileStatistics() : mTileCount( 0 ), mQueueTileCount( 0 )
|
||||
{
|
||||
s_instance = this;
|
||||
}
|
||||
|
||||
void QgsGlobeTileStatistics::updateTileCount( int change )
|
||||
{
|
||||
mMutex.lock();
|
||||
mTileCount += change;
|
||||
emit changed( mQueueTileCount, mTileCount );
|
||||
mMutex.unlock();
|
||||
}
|
||||
|
||||
void QgsGlobeTileStatistics::updateQueueTileCount( int num )
|
||||
{
|
||||
mMutex.lock();
|
||||
mQueueTileCount = num;
|
||||
emit changed( mQueueTileCount, mTileCount );
|
||||
mMutex.unlock();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
QgsGlobeTileImage::QgsGlobeTileImage( QgsGlobeTileSource* tileSource, const QgsRectangle& tileExtent, int tileSize , int tileLod )
|
||||
: osg::Image()
|
||||
, mTileSource( tileSource )
|
||||
, mTileExtent( tileExtent )
|
||||
, mTileSize( tileSize )
|
||||
, mImageUpdatePending( false )
|
||||
, mLod( tileLod )
|
||||
{
|
||||
#ifdef GLOBE_SHOW_TILE_STATS
|
||||
QgsGlobeTileStatistics::instance()->updateTileCount( + 1 );
|
||||
#endif
|
||||
mTileData = new unsigned char[mTileSize * mTileSize * 4];
|
||||
std::memset( mTileData, 0, mTileSize * mTileSize * 4 );
|
||||
#if 0
|
||||
setImage( mTileSize, mTileSize, 1, 4, // width, height, depth, internal_format
|
||||
GL_BGRA, GL_UNSIGNED_BYTE,
|
||||
mTileData, osg::Image::NO_DELETE );
|
||||
|
||||
mLastUpdateTime = osgEarth::DateTime().asTimeStamp();
|
||||
mTileSource->mTileUpdateManager.addTile( const_cast<QgsGlobeTileImage*>( this ) );
|
||||
mDpi = 72;
|
||||
mImageUpdatePending = true;
|
||||
#else
|
||||
QImage qImage( mTileData, mTileSize, mTileSize, QImage::Format_ARGB32_Premultiplied );
|
||||
QPainter painter( &qImage );
|
||||
QgsMapRendererCustomPainterJob job( createSettings( qImage.logicalDpiX(), mTileSource->mLayerSet ), &painter );
|
||||
job.renderSynchronously();
|
||||
|
||||
setImage( mTileSize, mTileSize, 1, 4, // width, height, depth, internal_format
|
||||
GL_BGRA, GL_UNSIGNED_BYTE,
|
||||
mTileData, osg::Image::NO_DELETE );
|
||||
flipVertical();
|
||||
mDpi = qImage.logicalDpiX();
|
||||
mLastUpdateTime = osgEarth::DateTime().asTimeStamp();
|
||||
#endif
|
||||
}
|
||||
|
||||
QgsGlobeTileImage::~QgsGlobeTileImage()
|
||||
{
|
||||
mTileSource->mTileUpdateManager.removeTile( this );
|
||||
delete[] mTileData;
|
||||
#ifdef GLOBE_SHOW_TILE_STATS
|
||||
QgsGlobeTileStatistics::instance()->updateTileCount( -1 );
|
||||
#endif
|
||||
}
|
||||
|
||||
bool QgsGlobeTileImage::requiresUpdateCall() const
|
||||
{
|
||||
if ( mLastUpdateTime < mTileSource->mLastModifiedTime )
|
||||
{
|
||||
mLastUpdateTime = mTileSource->mLastModifiedTime;
|
||||
if ( !mTileExtent.intersects( mTileSource->mLastUpdateExtent ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
mTileSource->mTileUpdateManager.addTile( const_cast<QgsGlobeTileImage*>( this ) );
|
||||
mImageUpdatePending = true;
|
||||
return true;
|
||||
}
|
||||
return mImageUpdatePending;
|
||||
}
|
||||
|
||||
QgsMapSettings QgsGlobeTileImage::createSettings( int dpi , const QStringList &layerSet ) const
|
||||
{
|
||||
QgsMapSettings settings;
|
||||
settings.setBackgroundColor( QColor( Qt::transparent ) );
|
||||
settings.setDestinationCrs( QgsCRSCache::instance()->crsByAuthId( GEO_EPSG_CRS_AUTHID ) );
|
||||
settings.setCrsTransformEnabled( true );
|
||||
settings.setExtent( mTileExtent );
|
||||
settings.setLayers( layerSet );
|
||||
settings.setFlag( QgsMapSettings::DrawEditingInfo, false );
|
||||
settings.setFlag( QgsMapSettings::DrawLabeling, false );
|
||||
settings.setFlag( QgsMapSettings::DrawSelection, false );
|
||||
settings.setMapUnits( QGis::Degrees );
|
||||
settings.setOutputSize( QSize( mTileSize, mTileSize ) );
|
||||
settings.setOutputImageFormat( QImage::Format_ARGB32_Premultiplied );
|
||||
settings.setOutputDpi( dpi );
|
||||
settings.setCustomRenderFlags( "globe" );
|
||||
return settings;
|
||||
}
|
||||
|
||||
void QgsGlobeTileImage::update( osg::NodeVisitor * )
|
||||
{
|
||||
if ( !mUpdatedImage.isNull() )
|
||||
{
|
||||
QgsDebugMsg( QString( "Updating earth tile image: %1" ).arg( mTileExtent.toString( 5 ) ) );
|
||||
std::memcpy( mTileData, mUpdatedImage.bits(), mTileSize * mTileSize * 4 );
|
||||
setImage( mTileSize, mTileSize, 1, 4, // width, height, depth, internal_format
|
||||
GL_BGRA, GL_UNSIGNED_BYTE,
|
||||
mTileData, osg::Image::NO_DELETE );
|
||||
flipVertical();
|
||||
mUpdatedImage = QImage();
|
||||
mImageUpdatePending = false;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
QgsGlobeTileUpdateManager::QgsGlobeTileUpdateManager( QObject* parent )
|
||||
: QObject( parent ), mCurrentTile( 0 ), mRenderer( 0 )
|
||||
{
|
||||
connect( this, SIGNAL( startRendering() ), this, SLOT( start() ) );
|
||||
connect( this, SIGNAL( cancelRendering() ), this, SLOT( cancel() ) );
|
||||
}
|
||||
|
||||
QgsGlobeTileUpdateManager::~QgsGlobeTileUpdateManager()
|
||||
{
|
||||
#ifdef GLOBE_SHOW_TILE_STATS
|
||||
QgsGlobeTileStatistics::instance()->updateQueueTileCount( 0 );
|
||||
#endif
|
||||
mTileQueue.clear();
|
||||
mCurrentTile = 0;
|
||||
if ( mRenderer )
|
||||
{
|
||||
mRenderer->cancel();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGlobeTileUpdateManager::addTile( QgsGlobeTileImage *tile )
|
||||
{
|
||||
if ( !mTileQueue.contains( tile ) )
|
||||
{
|
||||
mTileQueue.append( tile );
|
||||
#ifdef GLOBE_SHOW_TILE_STATS
|
||||
QgsGlobeTileStatistics::instance()->updateQueueTileCount( mTileQueue.size() );
|
||||
#endif
|
||||
qSort( mTileQueue.begin(), mTileQueue.end(), QgsGlobeTileImage::lodSort );
|
||||
}
|
||||
emit startRendering();
|
||||
}
|
||||
|
||||
void QgsGlobeTileUpdateManager::removeTile( QgsGlobeTileImage *tile )
|
||||
{
|
||||
if ( mCurrentTile == tile )
|
||||
{
|
||||
mCurrentTile = 0;
|
||||
if ( mRenderer )
|
||||
emit cancelRendering();
|
||||
}
|
||||
else if ( mTileQueue.contains( tile ) )
|
||||
{
|
||||
mTileQueue.removeAll( tile );
|
||||
#ifdef GLOBE_SHOW_TILE_STATS
|
||||
QgsGlobeTileStatistics::instance()->updateQueueTileCount( mTileQueue.size() );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGlobeTileUpdateManager::start()
|
||||
{
|
||||
if ( mRenderer == 0 && !mTileQueue.isEmpty() )
|
||||
{
|
||||
mCurrentTile = mTileQueue.takeFirst();
|
||||
#ifdef GLOBE_SHOW_TILE_STATS
|
||||
QgsGlobeTileStatistics::instance()->updateQueueTileCount( mTileQueue.size() );
|
||||
#endif
|
||||
mRenderer = new QgsMapRendererParallelJob( mCurrentTile->createSettings( mCurrentTile->dpi(), mLayerSet ) );
|
||||
connect( mRenderer, SIGNAL( finished() ), this, SLOT( renderingFinished() ) );
|
||||
mRenderer->start();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGlobeTileUpdateManager::cancel()
|
||||
{
|
||||
if ( mRenderer )
|
||||
mRenderer->cancel();
|
||||
}
|
||||
|
||||
void QgsGlobeTileUpdateManager::renderingFinished()
|
||||
{
|
||||
if ( mCurrentTile )
|
||||
{
|
||||
QImage image = mRenderer->renderedImage();
|
||||
mCurrentTile->setUpdatedImage( image );
|
||||
mCurrentTile = 0;
|
||||
}
|
||||
mRenderer->deleteLater();
|
||||
mRenderer = 0;
|
||||
start();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
QgsGlobeTileSource::QgsGlobeTileSource( QgsMapCanvas* canvas, const osgEarth::TileSourceOptions& options )
|
||||
: TileSource( options )
|
||||
, mCanvas( canvas )
|
||||
, mLastModifiedTime( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
osgEarth::TileSource::Status QgsGlobeTileSource::initialize( const osgDB::Options* /*dbOptions*/ )
|
||||
{
|
||||
setProfile( osgEarth::Registry::instance()->getGlobalGeodeticProfile() );
|
||||
mLastModifiedTime = osgEarth::DateTime().asTimeStamp();
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
osg::Image* QgsGlobeTileSource::createImage( const osgEarth::TileKey& key, osgEarth::ProgressCallback* progress )
|
||||
{
|
||||
Q_UNUSED( progress );
|
||||
|
||||
int tileSize = getPixelsPerTile();
|
||||
if ( tileSize <= 0 )
|
||||
{
|
||||
return osgEarth::ImageUtils::createEmptyImage();
|
||||
}
|
||||
|
||||
double xmin, ymin, xmax, ymax;
|
||||
key.getExtent().getBounds( xmin, ymin, xmax, ymax );
|
||||
QgsRectangle tileExtent( xmin, ymin, xmax, ymax );
|
||||
|
||||
QgsDebugMsg( QString( "Create earth tile image: %1" ).arg( tileExtent.toString( 5 ) ) );
|
||||
return new QgsGlobeTileImage( this, tileExtent, getPixelsPerTile(), key.getLOD() );
|
||||
}
|
||||
|
||||
bool QgsGlobeTileSource::hasDataInExtent( const osgEarth::GeoExtent &extent ) const
|
||||
{
|
||||
osgEarth::Bounds bounds = extent.bounds();
|
||||
QgsRectangle requestExtent( bounds.xMin(), bounds.yMin(), bounds.xMax(), bounds.yMax() );
|
||||
return requestExtent.intersects( mViewExtent );
|
||||
}
|
||||
|
||||
bool QgsGlobeTileSource::hasData( const osgEarth::TileKey& key ) const
|
||||
{
|
||||
const osgEarth::GeoExtent& tileExtent = key.getExtent();
|
||||
QgsRectangle rect( tileExtent.xMin(), tileExtent.yMin(), tileExtent.xMax(), tileExtent.yMax() );
|
||||
return rect.intersects( mViewExtent );
|
||||
}
|
||||
|
||||
void QgsGlobeTileSource::refresh( const QgsRectangle& updateExtent )
|
||||
{
|
||||
osgEarth::TimeStamp old = mLastModifiedTime;
|
||||
mLastModifiedTime = osgEarth::DateTime().asTimeStamp();
|
||||
mTileUpdateManager.updateLayerSet( mLayerSet );
|
||||
mLastUpdateExtent = updateExtent;
|
||||
QgsDebugMsg( QString( "Updated QGIS map layer modified time from %1 to %2" ).arg( old ).arg( mLastModifiedTime ) );
|
||||
mViewExtent = QgsCoordinateTransformCache::instance()->transform( mCanvas->mapSettings().destinationCrs().authid(), GEO_EPSG_CRS_AUTHID )->transform( mCanvas->fullExtent() );
|
||||
}
|
||||
|
||||
void QgsGlobeTileSource::setLayerSet( const QStringList &layerSet )
|
||||
{
|
||||
mLayerSet = layerSet;
|
||||
}
|
||||
|
||||
const QStringList& QgsGlobeTileSource::layerSet() const
|
||||
{
|
||||
return mLayerSet;
|
||||
}
|
138
src/plugins/globe/qgsglobetilesource.h
Normal file
@ -0,0 +1,138 @@
|
||||
/***************************************************************************
|
||||
qgsglobetilesource.h
|
||||
---------------------
|
||||
begin : August 2010
|
||||
copyright : (C) 2010 by Pirmin Kalberer
|
||||
(C) 2015 Sandro Mani
|
||||
email : pka at sourcepole dot ch
|
||||
smani at sourcepole dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSGLOBETILESOURCE_H
|
||||
#define QGSGLOBETILESOURCE_H
|
||||
|
||||
#include <osgEarth/TileSource>
|
||||
#include <osg/ImageStream>
|
||||
#include <QImage>
|
||||
#include <QStringList>
|
||||
#include <QLabel>
|
||||
#include <QMutex>
|
||||
#include "qgsrectangle.h"
|
||||
|
||||
//#define GLOBE_SHOW_TILE_STATS
|
||||
|
||||
class QgsCoordinateTransform;
|
||||
class QgsMapCanvas;
|
||||
class QgsMapRenderer;
|
||||
class QgsMapSettings;
|
||||
class QgsGlobeTileSource;
|
||||
class QgsMapRendererParallelJob;
|
||||
|
||||
class QgsGlobeTileStatistics : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QgsGlobeTileStatistics();
|
||||
~QgsGlobeTileStatistics() { s_instance = 0; }
|
||||
static QgsGlobeTileStatistics* instance() { return s_instance; }
|
||||
void updateTileCount( int change );
|
||||
void updateQueueTileCount( int change );
|
||||
signals:
|
||||
void changed( int queued, int tot );
|
||||
private:
|
||||
static QgsGlobeTileStatistics* s_instance;
|
||||
QMutex mMutex;
|
||||
int mTileCount;
|
||||
int mQueueTileCount;
|
||||
};
|
||||
|
||||
int getTileCount();
|
||||
|
||||
class QgsGlobeTileImage : public osg::Image
|
||||
{
|
||||
public:
|
||||
QgsGlobeTileImage( QgsGlobeTileSource* tileSource, const QgsRectangle& tileExtent, int tileSize, int tileLod );
|
||||
~QgsGlobeTileImage();
|
||||
bool requiresUpdateCall() const;
|
||||
QgsMapSettings createSettings( int dpi, const QStringList &layerSet ) const;
|
||||
void setUpdatedImage( const QImage& image ) { mUpdatedImage = image; }
|
||||
int dpi() const { return mDpi; }
|
||||
|
||||
void update( osg::NodeVisitor * );
|
||||
|
||||
static bool lodSort( const QgsGlobeTileImage* lhs, const QgsGlobeTileImage* rhs ) { return lhs->mLod > rhs->mLod; }
|
||||
|
||||
private:
|
||||
QgsGlobeTileSource* mTileSource;
|
||||
QgsRectangle mTileExtent;
|
||||
mutable osgEarth::TimeStamp mLastUpdateTime;
|
||||
int mTileSize;
|
||||
unsigned char* mTileData;
|
||||
mutable bool mImageUpdatePending;
|
||||
int mLod;
|
||||
int mDpi;
|
||||
QImage mUpdatedImage;
|
||||
};
|
||||
|
||||
class QgsGlobeTileUpdateManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QgsGlobeTileUpdateManager( QObject* parent = 0 );
|
||||
~QgsGlobeTileUpdateManager();
|
||||
void updateLayerSet( const QStringList& layerSet ) { mLayerSet = layerSet; }
|
||||
void addTile( QgsGlobeTileImage* tile );
|
||||
void removeTile( QgsGlobeTileImage* tile );
|
||||
|
||||
signals:
|
||||
void startRendering();
|
||||
void cancelRendering();
|
||||
|
||||
private:
|
||||
QStringList mLayerSet;
|
||||
QList<QgsGlobeTileImage*> mTileQueue;
|
||||
QgsGlobeTileImage* mCurrentTile;
|
||||
QgsMapRendererParallelJob* mRenderer;
|
||||
|
||||
private slots:
|
||||
void start();
|
||||
void cancel();
|
||||
void renderingFinished();
|
||||
};
|
||||
|
||||
class QgsGlobeTileSource : public osgEarth::TileSource
|
||||
{
|
||||
public:
|
||||
QgsGlobeTileSource( QgsMapCanvas* canvas, const osgEarth::TileSourceOptions& options = osgEarth::TileSourceOptions() );
|
||||
Status initialize( const osgDB::Options *dbOptions ) override;
|
||||
osg::Image* createImage( const osgEarth::TileKey& key, osgEarth::ProgressCallback* progress );
|
||||
osg::HeightField* createHeightField( const osgEarth::TileKey &/*key*/, osgEarth::ProgressCallback* /*progress*/ ) { return 0; }
|
||||
bool hasDataInExtent( const osgEarth::GeoExtent &extent ) const override;
|
||||
bool hasData( const osgEarth::TileKey& key ) const override;
|
||||
|
||||
bool isDynamic() const { return true; }
|
||||
osgEarth::TimeStamp getLastModifiedTime() const { return mLastModifiedTime; }
|
||||
|
||||
void refresh( const QgsRectangle &updateExtent );
|
||||
void setLayerSet( const QStringList& layerSet );
|
||||
const QStringList &layerSet() const;
|
||||
|
||||
private:
|
||||
friend class QgsGlobeTileImage;
|
||||
|
||||
QgsMapCanvas* mCanvas;
|
||||
osgEarth::TimeStamp mLastModifiedTime;
|
||||
QgsRectangle mViewExtent;
|
||||
QgsRectangle mLastUpdateExtent;
|
||||
QStringList mLayerSet;
|
||||
QgsGlobeTileUpdateManager mTileUpdateManager;
|
||||
};
|
||||
|
||||
#endif // QGSGLOBETILESOURCE_H
|
288
src/plugins/globe/qgsglobevectorlayerproperties.cpp
Normal file
@ -0,0 +1,288 @@
|
||||
/***************************************************************************
|
||||
qgsglobevectorlayerpropertiespage.cpp
|
||||
--------------------------------------
|
||||
Date : 9.7.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 <qgsproject.h>
|
||||
#include <qgsvectorlayer.h>
|
||||
#include "qgsglobevectorlayerproperties.h"
|
||||
|
||||
#include <osgEarth/Version>
|
||||
|
||||
Q_DECLARE_METATYPE( QgsGlobeVectorLayerConfig* )
|
||||
|
||||
QgsGlobeVectorLayerConfig* QgsGlobeVectorLayerConfig::getConfig( QgsVectorLayer* layer )
|
||||
{
|
||||
QgsGlobeVectorLayerConfig* layerConfig = layer->property( "globe-config" ).value<QgsGlobeVectorLayerConfig*>();
|
||||
if ( !layerConfig )
|
||||
{
|
||||
layerConfig = new QgsGlobeVectorLayerConfig( layer );
|
||||
layer->setProperty( "globe-config", QVariant::fromValue<QgsGlobeVectorLayerConfig*>( layerConfig ) );
|
||||
}
|
||||
return layerConfig;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
QgsGlobeVectorLayerPropertiesPage::QgsGlobeVectorLayerPropertiesPage( QgsVectorLayer* layer, QWidget *parent )
|
||||
: QgsVectorLayerPropertiesPage( parent )
|
||||
, mLayer( layer )
|
||||
{
|
||||
setupUi( this );
|
||||
|
||||
// Populate combo boxes
|
||||
comboBoxRenderingMode->addItem( tr( "Rasterized" ), QgsGlobeVectorLayerConfig::RenderingModeRasterized );
|
||||
comboBoxRenderingMode->addItem( tr( "Model (Simple)" ), QgsGlobeVectorLayerConfig::RenderingModeModelSimple );
|
||||
comboBoxRenderingMode->addItem( tr( "Model (Advanced)" ), QgsGlobeVectorLayerConfig::RenderingModeModelAdvanced );
|
||||
comboBoxRenderingMode->setItemData( 0, tr( "Rasterize the layer to a texture, and drape it on the terrain" ), Qt::ToolTipRole );
|
||||
comboBoxRenderingMode->setItemData( 1, tr( "Render the layer features as models" ), Qt::ToolTipRole );
|
||||
comboBoxRenderingMode->setCurrentIndex( -1 );
|
||||
|
||||
comboBoxAltitudeClamping->addItem( tr( "None" ), static_cast<int>( osgEarth::Symbology::AltitudeSymbol::CLAMP_NONE ) );
|
||||
comboBoxAltitudeClamping->addItem( tr( "Terrain" ), static_cast<int>( osgEarth::Symbology::AltitudeSymbol::CLAMP_TO_TERRAIN ) );
|
||||
comboBoxAltitudeClamping->addItem( tr( "Relative" ), static_cast<int>( osgEarth::Symbology::AltitudeSymbol::CLAMP_RELATIVE_TO_TERRAIN ) );
|
||||
comboBoxAltitudeClamping->addItem( tr( "Absolute" ), static_cast<int>( osgEarth::Symbology::AltitudeSymbol::CLAMP_ABSOLUTE ) );
|
||||
comboBoxAltitudeClamping->setItemData( 0, tr( "Do not clamp Z values to the terrain (but still apply the offset, if applicable)" ), Qt::ToolTipRole );
|
||||
comboBoxAltitudeClamping->setItemData( 1, tr( "Sample the terrain under the point, and set the feature's Z to the terrain height, ignoring the feature's original Z value" ), Qt::ToolTipRole );
|
||||
comboBoxAltitudeClamping->setItemData( 2, tr( "Sample the terrain under the point, and add the terrain height to the feature's original Z value" ), Qt::ToolTipRole );
|
||||
comboBoxAltitudeClamping->setItemData( 3, tr( "The feature's Z value describes its height above \"height zero\", which is typically the ellipsoid or MSL" ), Qt::ToolTipRole );
|
||||
comboBoxAltitudeClamping->setCurrentIndex( -1 );
|
||||
|
||||
comboBoxAltitudeTechnique->addItem( tr( "Map" ), static_cast<int>( osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_MAP ) );
|
||||
comboBoxAltitudeTechnique->addItem( tr( "Drape" ), static_cast<int>( osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_DRAPE ) );
|
||||
comboBoxAltitudeTechnique->addItem( tr( "GPU" ), static_cast<int>( osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_GPU ) );
|
||||
comboBoxAltitudeTechnique->addItem( tr( "Scene" ), static_cast<int>( osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_SCENE ) );
|
||||
comboBoxAltitudeTechnique->setItemData( 0, tr( "Clamp geometry to the map model's elevation data" ), Qt::ToolTipRole );
|
||||
comboBoxAltitudeTechnique->setItemData( 1, tr( "Clamp geometry to the terrain's scene graph" ), Qt::ToolTipRole );
|
||||
comboBoxAltitudeTechnique->setItemData( 2, tr( "Clamp geometry to the terrain as they are rendered by the GPU" ), Qt::ToolTipRole );
|
||||
comboBoxAltitudeTechnique->setItemData( 3, tr( "Clamp geometry at draw time using projective texturing" ), Qt::ToolTipRole );
|
||||
comboBoxAltitudeTechnique->setCurrentIndex( -1 );
|
||||
|
||||
comboBoxAltitudeBinding->addItem( tr( "Vertex" ), static_cast<int>( osgEarth::Symbology::AltitudeSymbol::BINDING_VERTEX ) );
|
||||
comboBoxAltitudeBinding->addItem( tr( "Centroid" ), static_cast<int>( osgEarth::Symbology::AltitudeSymbol::BINDING_CENTROID ) );
|
||||
comboBoxAltitudeBinding->setItemData( 0, tr( "Clamp every vertex independently" ), Qt::ToolTipRole );
|
||||
comboBoxAltitudeBinding->setItemData( 1, tr( "Clamp to the centroid of the entire geometry" ), Qt::ToolTipRole );
|
||||
comboBoxAltitudeBinding->setCurrentIndex( -1 );
|
||||
|
||||
// Connect signals (setCurrentIndex(-1) above ensures the signal is called when the current values are set below)
|
||||
connect( comboBoxRenderingMode, SIGNAL( currentIndexChanged( int ) ), this, SLOT( showRenderingModeWidget( int ) ) );
|
||||
connect( comboBoxAltitudeClamping, SIGNAL( currentIndexChanged( int ) ), this, SLOT( onAltitudeClampingChanged( int ) ) );
|
||||
connect( comboBoxAltitudeTechnique, SIGNAL( currentIndexChanged( int ) ), this, SLOT( onAltituteTechniqueChanged( int ) ) );
|
||||
|
||||
// Set values
|
||||
QgsGlobeVectorLayerConfig* layerConfig = QgsGlobeVectorLayerConfig::getConfig( mLayer );
|
||||
|
||||
comboBoxRenderingMode->setCurrentIndex( comboBoxRenderingMode->findData( static_cast<int>( layerConfig->renderingMode ) ) );
|
||||
|
||||
comboBoxAltitudeClamping->setCurrentIndex( comboBoxAltitudeClamping->findData( static_cast<int>( layerConfig->altitudeClamping ) ) );
|
||||
comboBoxAltitudeTechnique->setCurrentIndex( comboBoxAltitudeTechnique->findData( static_cast<int>( layerConfig->altitudeTechnique ) ) );
|
||||
comboBoxAltitudeBinding->setCurrentIndex( comboBoxAltitudeBinding->findData( static_cast<int>( layerConfig->altitudeBinding ) ) );
|
||||
|
||||
spinBoxAltitudeOffset->setValue( layerConfig->verticalOffset );
|
||||
spinBoxAltitudeScale->setValue( layerConfig->verticalScale );
|
||||
spinBoxAltitudeResolution->setValue( layerConfig->clampingResolution );
|
||||
|
||||
groupBoxExtrusion->setChecked( layerConfig->extrusionEnabled );
|
||||
labelExtrusionHeight->setText( layerConfig->extrusionHeight );
|
||||
checkBoxExtrusionFlatten->setChecked( layerConfig->extrusionFlatten );
|
||||
spinBoxExtrusionWallGradient->setValue( layerConfig->extrusionWallGradient );
|
||||
|
||||
#if OSGEARTH_VERSION_LESS_THAN(2, 7, 0)
|
||||
groupBoxLabelingEnabled->setChecked( layerConfig->labelingEnabled );
|
||||
checkBoxLabelingDeclutter->setChecked( layerConfig->labelingDeclutter );
|
||||
#else
|
||||
#pragma message("TODO: labeling broken with osgEarth 2.7")
|
||||
groupBoxLabelingEnabled->setChecked( false );
|
||||
checkBoxLabelingDeclutter->setChecked( false );
|
||||
groupBoxLabelingEnabled->setVisible( false );
|
||||
checkBoxLabelingDeclutter->setVisible( false );
|
||||
#endif
|
||||
|
||||
checkBoxLighting->setChecked( layerConfig->lightingEnabled );
|
||||
}
|
||||
|
||||
void QgsGlobeVectorLayerPropertiesPage::apply()
|
||||
{
|
||||
QgsGlobeVectorLayerConfig* layerConfig = QgsGlobeVectorLayerConfig::getConfig( mLayer );
|
||||
|
||||
layerConfig->renderingMode = static_cast<QgsGlobeVectorLayerConfig::RenderingMode>( comboBoxRenderingMode->itemData( comboBoxRenderingMode->currentIndex() ).toInt() );
|
||||
layerConfig->altitudeClamping = static_cast<osgEarth::Symbology::AltitudeSymbol::Clamping>( comboBoxAltitudeClamping->itemData( comboBoxAltitudeClamping->currentIndex() ).toInt() );
|
||||
layerConfig->altitudeTechnique = static_cast<osgEarth::Symbology::AltitudeSymbol::Technique>( comboBoxAltitudeTechnique->itemData( comboBoxAltitudeTechnique->currentIndex() ).toInt() );
|
||||
layerConfig->altitudeBinding = static_cast<osgEarth::Symbology::AltitudeSymbol::Binding>( comboBoxAltitudeBinding->itemData( comboBoxAltitudeBinding->currentIndex() ).toInt() );
|
||||
|
||||
layerConfig->verticalOffset = spinBoxAltitudeOffset->value();
|
||||
layerConfig->verticalScale = spinBoxAltitudeScale->value();
|
||||
layerConfig->clampingResolution = spinBoxAltitudeResolution->value();
|
||||
|
||||
layerConfig->extrusionEnabled = groupBoxExtrusion->isChecked();
|
||||
layerConfig->extrusionHeight = labelExtrusionHeight->text();
|
||||
layerConfig->extrusionFlatten = checkBoxExtrusionFlatten->isChecked();
|
||||
layerConfig->extrusionWallGradient = spinBoxExtrusionWallGradient->value();
|
||||
|
||||
layerConfig->labelingEnabled = groupBoxLabelingEnabled->isChecked();
|
||||
layerConfig->labelingDeclutter = checkBoxLabelingDeclutter->isChecked();
|
||||
|
||||
layerConfig->lightingEnabled = checkBoxLighting->isChecked();
|
||||
|
||||
emit layerSettingsChanged( mLayer );
|
||||
}
|
||||
|
||||
void QgsGlobeVectorLayerPropertiesPage::onAltitudeClampingChanged( int index )
|
||||
{
|
||||
osgEarth::Symbology::AltitudeSymbol::Clamping clamping = static_cast<osgEarth::Symbology::AltitudeSymbol::Clamping>( comboBoxAltitudeClamping->itemData( index ).toInt() );
|
||||
|
||||
bool terrainClamping = clamping == osgEarth::Symbology::AltitudeSymbol::CLAMP_TO_TERRAIN;
|
||||
labelAltitudeTechnique->setVisible( terrainClamping );
|
||||
comboBoxAltitudeTechnique->setVisible( terrainClamping );
|
||||
onAltituteTechniqueChanged( comboBoxAltitudeTechnique->currentIndex() );
|
||||
}
|
||||
|
||||
void QgsGlobeVectorLayerPropertiesPage::onAltituteTechniqueChanged( int index )
|
||||
{
|
||||
osgEarth::Symbology::AltitudeSymbol::Clamping clamping = static_cast<osgEarth::Symbology::AltitudeSymbol::Clamping>( comboBoxAltitudeClamping->itemData( comboBoxAltitudeClamping->currentIndex() ).toInt() );
|
||||
osgEarth::Symbology::AltitudeSymbol::Technique technique = static_cast<osgEarth::Symbology::AltitudeSymbol::Technique>( comboBoxAltitudeTechnique->itemData( index ).toInt() );
|
||||
|
||||
bool mapTechnique = technique == osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_MAP && clamping == osgEarth::Symbology::AltitudeSymbol::CLAMP_TO_TERRAIN;
|
||||
labelAltitudeBinding->setVisible( mapTechnique );
|
||||
comboBoxAltitudeBinding->setVisible( mapTechnique );
|
||||
labelAltitudeResolution->setVisible( mapTechnique );
|
||||
spinBoxAltitudeResolution->setVisible( mapTechnique );
|
||||
}
|
||||
|
||||
void QgsGlobeVectorLayerPropertiesPage::showRenderingModeWidget( int index )
|
||||
{
|
||||
stackedWidgetRenderingMode->setCurrentIndex( index != 0 );
|
||||
bool advanced = index == 2;
|
||||
groupBoxAltitude->setVisible( advanced );
|
||||
checkBoxLighting->setVisible( advanced );
|
||||
checkBoxExtrusionFlatten->setVisible( advanced );
|
||||
if ( !advanced )
|
||||
{
|
||||
comboBoxAltitudeClamping->setCurrentIndex( comboBoxAltitudeClamping->findData( static_cast<int>( osgEarth::Symbology::AltitudeSymbol::CLAMP_TO_TERRAIN ) ) );
|
||||
comboBoxAltitudeTechnique->setCurrentIndex( comboBoxAltitudeTechnique->findData( static_cast<int>( osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_GPU ) ) );
|
||||
spinBoxAltitudeResolution->setValue( 0 );
|
||||
spinBoxAltitudeOffset->setValue( 0 );
|
||||
spinBoxAltitudeScale->setValue( 0 );
|
||||
checkBoxExtrusionFlatten->setChecked( false );
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
QgsGlobeLayerPropertiesFactory::QgsGlobeLayerPropertiesFactory( QObject *parent )
|
||||
: QObject( parent )
|
||||
{
|
||||
connect( QgsProject::instance(), SIGNAL( readMapLayer( QgsMapLayer*, QDomElement ) ), this, SLOT( readGlobeVectorLayerConfig( QgsMapLayer*, QDomElement ) ) );
|
||||
connect( QgsProject::instance(), SIGNAL( writeMapLayer( QgsMapLayer*, QDomElement&, QDomDocument& ) ), this, SLOT( writeGlobeVectorLayerConfig( QgsMapLayer*, QDomElement&, QDomDocument& ) ) );
|
||||
}
|
||||
|
||||
QgsVectorLayerPropertiesPage* QgsGlobeLayerPropertiesFactory::createVectorLayerPropertiesPage( QgsVectorLayer* layer, QWidget* parent )
|
||||
{
|
||||
QgsGlobeVectorLayerPropertiesPage* propsPage = new QgsGlobeVectorLayerPropertiesPage( layer, parent );
|
||||
connect( propsPage, SIGNAL( layerSettingsChanged( QgsMapLayer* ) ), this, SIGNAL( layerSettingsChanged( QgsMapLayer* ) ) );
|
||||
return propsPage;
|
||||
}
|
||||
|
||||
QListWidgetItem* QgsGlobeLayerPropertiesFactory::createVectorLayerPropertiesItem( QgsVectorLayer* layer, QListWidget* view )
|
||||
{
|
||||
Q_UNUSED( layer );
|
||||
return new QListWidgetItem( QIcon( ":/globe/icon.svg" ), tr( "Globe" ), view );
|
||||
}
|
||||
|
||||
void QgsGlobeLayerPropertiesFactory::readGlobeVectorLayerConfig( QgsMapLayer* mapLayer, const QDomElement& elem )
|
||||
{
|
||||
if ( dynamic_cast<QgsVectorLayer*>( mapLayer ) )
|
||||
{
|
||||
QgsVectorLayer* vLayer = static_cast<QgsVectorLayer*>( mapLayer );
|
||||
QgsGlobeVectorLayerConfig* config = QgsGlobeVectorLayerConfig::getConfig( vLayer );
|
||||
|
||||
QDomElement globeElem = elem.firstChildElement( "globe" );
|
||||
if ( !globeElem.isNull() )
|
||||
{
|
||||
QDomElement renderingModeElem = globeElem.firstChildElement( "renderingMode" );
|
||||
config->renderingMode = static_cast<QgsGlobeVectorLayerConfig::RenderingMode>( renderingModeElem.attribute( "mode" ).toInt() );
|
||||
|
||||
QDomElement modelRenderingElem = globeElem.firstChildElement( "modelRendering" );
|
||||
if ( !modelRenderingElem.isNull() )
|
||||
{
|
||||
QDomElement altitudeElem = modelRenderingElem.firstChildElement( "altitude" );
|
||||
config->altitudeClamping = static_cast<osgEarth::Symbology::AltitudeSymbol::Clamping>( altitudeElem.attribute( "clamping" ).toInt() );
|
||||
config->altitudeTechnique = static_cast<osgEarth::Symbology::AltitudeSymbol::Technique>( altitudeElem.attribute( "technique" ).toInt() );
|
||||
config->altitudeBinding = static_cast<osgEarth::Symbology::AltitudeSymbol::Binding>( altitudeElem.attribute( "binding" ).toInt() );
|
||||
config->verticalOffset = altitudeElem.attribute( "verticalOffset" ).toFloat();
|
||||
config->verticalScale = altitudeElem.attribute( "verticalScale" ).toFloat();
|
||||
config->clampingResolution = altitudeElem.attribute( "clampingResolution" ).toFloat();
|
||||
|
||||
QDomElement extrusionElem = modelRenderingElem.firstChildElement( "extrusion" );
|
||||
config->extrusionEnabled = extrusionElem.attribute( "enabled" ).toInt() == 1;
|
||||
config->extrusionHeight = extrusionElem.attribute( "height", QString( "10" ) ).trimmed();
|
||||
if ( config->extrusionHeight.isEmpty() )
|
||||
config->extrusionHeight = "10";
|
||||
config->extrusionFlatten = extrusionElem.attribute( "flatten" ).toInt() == 1;
|
||||
config->extrusionWallGradient = extrusionElem.attribute( "wall-gradient" ).toDouble();
|
||||
|
||||
QDomElement labelingElem = modelRenderingElem.firstChildElement( "labeling" );
|
||||
config->labelingEnabled = labelingElem.attribute( "enabled", "0" ).toInt() == 1;
|
||||
config->labelingField = labelingElem.attribute( "field" );
|
||||
config->labelingDeclutter = labelingElem.attribute( "declutter", "1" ).toInt() == 1;
|
||||
|
||||
config->lightingEnabled = modelRenderingElem.attribute( "lighting", "1" ).toInt() == 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsGlobeLayerPropertiesFactory::writeGlobeVectorLayerConfig( QgsMapLayer* mapLayer, QDomElement& elem, QDomDocument& doc )
|
||||
{
|
||||
if ( dynamic_cast<QgsVectorLayer*>( mapLayer ) )
|
||||
{
|
||||
QgsVectorLayer* vLayer = static_cast<QgsVectorLayer*>( mapLayer );
|
||||
QgsGlobeVectorLayerConfig* config = QgsGlobeVectorLayerConfig::getConfig( vLayer );
|
||||
|
||||
QDomElement globeElem = doc.createElement( "globe" );
|
||||
|
||||
QDomElement renderingModeElem = doc.createElement( "renderingMode" );
|
||||
renderingModeElem.setAttribute( "mode", config->renderingMode );
|
||||
globeElem.appendChild( renderingModeElem );
|
||||
|
||||
QDomElement modelRenderingElem = doc.createElement( "modelRendering" );
|
||||
|
||||
QDomElement altitudeElem = doc.createElement( "altitude" );
|
||||
altitudeElem.setAttribute( "clamping", config->altitudeClamping );
|
||||
altitudeElem.setAttribute( "technique", config->altitudeTechnique );
|
||||
altitudeElem.setAttribute( "binding", config->altitudeBinding );
|
||||
altitudeElem.setAttribute( "verticalOffset", config->verticalOffset );
|
||||
altitudeElem.setAttribute( "verticalScale", config->verticalScale );
|
||||
altitudeElem.setAttribute( "clampingResolution", config->clampingResolution );
|
||||
modelRenderingElem.appendChild( altitudeElem );
|
||||
|
||||
QDomElement extrusionElem = doc.createElement( "extrusion" );
|
||||
extrusionElem.setAttribute( "enabled", config->extrusionEnabled );
|
||||
extrusionElem.setAttribute( "height", config->extrusionHeight );
|
||||
extrusionElem.setAttribute( "flatten", config->extrusionFlatten );
|
||||
extrusionElem.setAttribute( "wall-gradient", config->extrusionWallGradient );
|
||||
modelRenderingElem.appendChild( extrusionElem );
|
||||
|
||||
QDomElement labelingElem = doc.createElement( "labeling" );
|
||||
labelingElem.setAttribute( "enabled", config->labelingEnabled );
|
||||
labelingElem.setAttribute( "field", config->labelingField );
|
||||
labelingElem.setAttribute( "declutter", config->labelingDeclutter );
|
||||
modelRenderingElem.appendChild( labelingElem );
|
||||
|
||||
modelRenderingElem.setAttribute( "lighting", config->lightingEnabled );
|
||||
|
||||
globeElem.appendChild( modelRenderingElem );
|
||||
|
||||
elem.appendChild( globeElem );
|
||||
}
|
||||
}
|
121
src/plugins/globe/qgsglobevectorlayerproperties.h
Normal file
@ -0,0 +1,121 @@
|
||||
/***************************************************************************
|
||||
qgsglobevectorlayerproperties.h
|
||||
--------------------------------------
|
||||
Date : 9.7.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSGLOBEVECTORLAYERPROPERTIES_H
|
||||
#define QGSGLOBEVECTORLAYERPROPERTIES_H
|
||||
|
||||
#include "ui_qgsglobevectorlayerpropertiespage.h"
|
||||
#include <qgsmaplayerpropertiesfactory.h>
|
||||
#include <osgEarthSymbology/AltitudeSymbol>
|
||||
|
||||
class QgsGlobeVectorLayerConfig;
|
||||
class QgsMapLayer;
|
||||
class QDomDocument;
|
||||
class QDomElement;
|
||||
class QListWidgetItem;
|
||||
|
||||
struct QgsGlobeVectorLayerConfig : public QObject
|
||||
{
|
||||
public:
|
||||
enum RenderingMode
|
||||
{
|
||||
RenderingModeRasterized,
|
||||
RenderingModeModelSimple,
|
||||
RenderingModeModelAdvanced
|
||||
};
|
||||
|
||||
QgsGlobeVectorLayerConfig( QObject* parent = 0 )
|
||||
: QObject( parent )
|
||||
, renderingMode( RenderingModeRasterized )
|
||||
, altitudeClamping( osgEarth::Symbology::AltitudeSymbol::CLAMP_TO_TERRAIN )
|
||||
, altitudeTechnique( osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_DRAPE )
|
||||
, altitudeBinding( osgEarth::Symbology::AltitudeSymbol::BINDING_VERTEX )
|
||||
, verticalOffset( 0.0 )
|
||||
, verticalScale( 0.0 )
|
||||
, clampingResolution( 0.0 )
|
||||
, extrusionEnabled( false )
|
||||
, extrusionHeight( "10" )
|
||||
, extrusionFlatten( false )
|
||||
, extrusionWallGradient( 0.5 )
|
||||
, labelingEnabled( false )
|
||||
, labelingDeclutter( false )
|
||||
, lightingEnabled( true )
|
||||
{
|
||||
}
|
||||
|
||||
RenderingMode renderingMode;
|
||||
osgEarth::Symbology::AltitudeSymbol::Clamping altitudeClamping;
|
||||
osgEarth::Symbology::AltitudeSymbol::Technique altitudeTechnique;
|
||||
osgEarth::Symbology::AltitudeSymbol::Binding altitudeBinding;
|
||||
|
||||
float verticalOffset;
|
||||
float verticalScale;
|
||||
float clampingResolution;
|
||||
|
||||
bool extrusionEnabled;
|
||||
QString extrusionHeight;
|
||||
bool extrusionFlatten;
|
||||
float extrusionWallGradient;
|
||||
|
||||
bool labelingEnabled;
|
||||
QString labelingField;
|
||||
bool labelingDeclutter;
|
||||
|
||||
bool lightingEnabled;
|
||||
|
||||
static QgsGlobeVectorLayerConfig* getConfig( QgsVectorLayer* layer );
|
||||
};
|
||||
|
||||
|
||||
class QgsGlobeVectorLayerPropertiesPage : public QgsVectorLayerPropertiesPage, private Ui::QgsGlobeVectorLayerPropertiesPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QgsGlobeVectorLayerPropertiesPage( QgsVectorLayer* layer, QWidget *parent = 0 );
|
||||
|
||||
public slots:
|
||||
virtual void apply();
|
||||
|
||||
private slots:
|
||||
void onAltitudeClampingChanged( int index );
|
||||
void onAltituteTechniqueChanged( int index );
|
||||
void showRenderingModeWidget( int index );
|
||||
|
||||
signals:
|
||||
void layerSettingsChanged( QgsMapLayer* );
|
||||
|
||||
private:
|
||||
QgsVectorLayer* mLayer;
|
||||
};
|
||||
|
||||
|
||||
class QgsGlobeLayerPropertiesFactory : public QObject, public QgsMapLayerPropertiesFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QgsGlobeLayerPropertiesFactory( QObject* parent = 0 );
|
||||
QgsVectorLayerPropertiesPage* createVectorLayerPropertiesPage( QgsVectorLayer* layer, QWidget* parent ) override;
|
||||
QListWidgetItem* createVectorLayerPropertiesItem( QgsVectorLayer* layer, QListWidget* view ) override;
|
||||
|
||||
signals:
|
||||
void layerSettingsChanged( QgsMapLayer* layer );
|
||||
|
||||
private slots:
|
||||
void readGlobeVectorLayerConfig( QgsMapLayer* mapLayer, const QDomElement &elem );
|
||||
void writeGlobeVectorLayerConfig( QgsMapLayer* mapLayer, QDomElement& elem, QDomDocument& doc );
|
||||
};
|
||||
|
||||
#endif // QGSGLOBEVECTORLAYERPROPERTIES_H
|
272
src/plugins/globe/qgsglobevectorlayerpropertiespage.ui
Normal file
@ -0,0 +1,272 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QgsGlobeVectorLayerPropertiesPage</class>
|
||||
<widget class="QgsVectorLayerPropertiesPage" name="QgsGlobeVectorLayerPropertiesPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>446</width>
|
||||
<height>580</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QStackedWidget" name="stackedWidgetRenderingMode">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="pageRasterized">
|
||||
<layout class="QVBoxLayout" name="verticalLayout"/>
|
||||
</widget>
|
||||
<widget class="QWidget" name="pageModel">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBoxAltitude">
|
||||
<property name="title">
|
||||
<string>Altitude</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelAltitudeClamping">
|
||||
<property name="toolTip">
|
||||
<string>Terrain following behaviour</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clamping</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="comboBoxAltitudeClamping">
|
||||
<property name="toolTip">
|
||||
<string>Terrain following behavior</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelAltitudeTechnique">
|
||||
<property name="toolTip">
|
||||
<string>Terrain following technique</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Technique</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelAltitudeBinding">
|
||||
<property name="toolTip">
|
||||
<string>Granulatiry at which to sample the terrain</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Binding</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelAltitudeResolution">
|
||||
<property name="toolTip">
|
||||
<string>Elevation data resolution at which to sample terrain height</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Resolution</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="labelAltitudeOffset">
|
||||
<property name="toolTip">
|
||||
<string>Vertical offset to apply to geometry Z</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Offset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="labelAltitudeScale">
|
||||
<property name="toolTip">
|
||||
<string>Scale factor to apply to geometry Z</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Scale</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="comboBoxAltitudeTechnique">
|
||||
<property name="toolTip">
|
||||
<string>Terrain following technique</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="comboBoxAltitudeBinding">
|
||||
<property name="toolTip">
|
||||
<string>Granulatiry at which to sample the terrain</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinBoxAltitudeResolution">
|
||||
<property name="toolTip">
|
||||
<string>Elevation data resolution at which to sample terrain height</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinBoxAltitudeOffset">
|
||||
<property name="toolTip">
|
||||
<string>Vertical offset to apply to geometry Z</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinBoxAltitudeScale">
|
||||
<property name="toolTip">
|
||||
<string>Scale factor to apply to geometry Z</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBoxExtrusion">
|
||||
<property name="title">
|
||||
<string>E&xtrusion</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelExtrusionHeight_2">
|
||||
<property name="text">
|
||||
<string>Height [m]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="labelExtrusionHeight">
|
||||
<property name="toolTip">
|
||||
<string>Extrusion height, either a numeric value, or a field expression</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelExtrusionWallGradient">
|
||||
<property name="text">
|
||||
<string>Wall gradient</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinBoxExtrusionWallGradient">
|
||||
<property name="toolTip">
|
||||
<string>Wall coloring gradient</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.500000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="checkBoxExtrusionFlatten">
|
||||
<property name="toolTip">
|
||||
<string>Whether the top cap of the extruded geometry should be flat</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Flatten</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBoxLabelingEnabled">
|
||||
<property name="title">
|
||||
<string>Enable &labeling</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="checkBoxLabelingDeclutter">
|
||||
<property name="text">
|
||||
<string>Declutter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxLighting">
|
||||
<property name="text">
|
||||
<string>Lighting</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelRenderingMode">
|
||||
<property name="text">
|
||||
<string>Rendering mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="comboBoxRenderingMode">
|
||||
<property name="toolTip">
|
||||
<string>Rendering method for the layer</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QgsVectorLayerPropertiesPage</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>qgsvectorlayerpropertiespage.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
153
src/plugins/globe/qgsglobewidget.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
/***************************************************************************
|
||||
qgsglobewidget.cpp
|
||||
---------------------
|
||||
begin : August 2010
|
||||
copyright : (C) 2016 Sandro Mani
|
||||
email : smani at sourcepole dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 "qgsglobewidget.h"
|
||||
#include "qgsmapcanvas.h"
|
||||
#include "qgsmaplayer.h"
|
||||
#include "qgsmaplayerregistry.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsrasterlayer.h"
|
||||
#include "qgisinterface.h"
|
||||
#include "layertree/qgslayertree.h"
|
||||
|
||||
#include <QContextMenuEvent>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QMenu>
|
||||
#include <QToolButton>
|
||||
|
||||
QgsGlobeWidget::QgsGlobeWidget( QgisInterface* iface, QWidget *parent )
|
||||
: QDockWidget( tr( "Globe" ), parent ), mQgisIface( iface )
|
||||
{
|
||||
setWindowTitle( tr( "Globe" ) );
|
||||
|
||||
QToolButton* layerSelectionButton = new QToolButton( this );
|
||||
layerSelectionButton->setAutoRaise( true );
|
||||
layerSelectionButton->setText( tr( "Layers" ) );
|
||||
layerSelectionButton->setPopupMode( QToolButton::InstantPopup );
|
||||
mLayerSelectionMenu = new QMenu( layerSelectionButton );
|
||||
layerSelectionButton->setMenu( mLayerSelectionMenu );
|
||||
|
||||
QToolButton* syncButton = new QToolButton( this );
|
||||
syncButton->setAutoRaise( true );
|
||||
syncButton->setToolTip( tr( "Sync extent" ) );
|
||||
syncButton->setIcon( QIcon( ":/images/themes/default/sync_views.svg" ) );
|
||||
syncButton->setIconSize( QSize( 16, 16 ) );
|
||||
connect( syncButton, SIGNAL( clicked() ), this, SIGNAL( syncExtent() ) );
|
||||
|
||||
QToolButton* refreshButton = new QToolButton( this );
|
||||
refreshButton->setAutoRaise( true );
|
||||
refreshButton->setToolTip( tr( "Reload scene" ) );
|
||||
refreshButton->setIcon( QIcon( ":/images/themes/default/mActionRefresh.png" ) );
|
||||
refreshButton->setIconSize( QSize( 16, 16 ) );
|
||||
connect( refreshButton, SIGNAL( clicked() ), this, SIGNAL( refresh() ) );
|
||||
|
||||
QToolButton* settingsButton = new QToolButton( this );
|
||||
settingsButton->setAutoRaise( true );
|
||||
settingsButton->setToolTip( tr( "Globe settings" ) );
|
||||
settingsButton->setIcon( QIcon( ":/images/themes/default/mActionOptions.svg" ) );
|
||||
settingsButton->setIconSize( QSize( 16, 16 ) );
|
||||
connect( settingsButton, SIGNAL( clicked() ), this, SIGNAL( showSettings() ) );
|
||||
|
||||
QToolButton* closeButton = new QToolButton( this );
|
||||
closeButton->setAutoRaise( true );
|
||||
closeButton->setIcon( QIcon( ":/images/themes/default/mActionRemove.svg" ) );
|
||||
closeButton->setIconSize( QSize( 12, 12 ) );
|
||||
closeButton->setToolTip( tr( "Close" ) );
|
||||
connect( closeButton, SIGNAL( clicked( bool ) ), this, SLOT( deleteLater() ) );
|
||||
|
||||
QWidget* titleWidget = new QWidget( this );
|
||||
titleWidget->setObjectName( "globeTitleWidget" );
|
||||
titleWidget->setLayout( new QHBoxLayout() );
|
||||
titleWidget->layout()->addWidget( layerSelectionButton );
|
||||
titleWidget->layout()->addWidget( syncButton );
|
||||
titleWidget->layout()->addWidget( refreshButton );
|
||||
titleWidget->layout()->addWidget( settingsButton );
|
||||
static_cast<QHBoxLayout*>( titleWidget->layout() )->addWidget( new QWidget( this ), 1 ); // spacer
|
||||
titleWidget->layout()->addWidget( new QLabel( tr( "Globe" ) ) );
|
||||
static_cast<QHBoxLayout*>( titleWidget->layout() )->addWidget( new QWidget( this ), 1 ); // spacer
|
||||
titleWidget->layout()->addWidget( closeButton );
|
||||
titleWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
|
||||
|
||||
setTitleBarWidget( titleWidget );
|
||||
setMinimumSize( 128, 128 );
|
||||
setAttribute( Qt::WA_DeleteOnClose );
|
||||
|
||||
connect( mQgisIface->mapCanvas(), SIGNAL( layersChanged() ), this, SLOT( updateLayerSelectionMenu() ) );
|
||||
connect( QgsMapLayerRegistry::instance(), SIGNAL( layersAdded( QList<QgsMapLayer*> ) ), this, SLOT( updateLayerSelectionMenu() ) );
|
||||
connect( QgsMapLayerRegistry::instance(), SIGNAL( layerRemoved( QString ) ), this, SLOT( updateLayerSelectionMenu() ) );
|
||||
|
||||
updateLayerSelectionMenu();
|
||||
}
|
||||
|
||||
void QgsGlobeWidget::updateLayerSelectionMenu()
|
||||
{
|
||||
QStringList prevLayers;
|
||||
QStringList prevDisabledLayers;
|
||||
QStringList prevEnabledLayers;
|
||||
foreach ( QAction* action, mLayerSelectionMenu->actions() )
|
||||
{
|
||||
prevLayers.append( action->data().toString() );
|
||||
if ( !action->isChecked() )
|
||||
{
|
||||
prevDisabledLayers.append( action->data().toString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
prevEnabledLayers.append( action->data().toString() );
|
||||
}
|
||||
}
|
||||
|
||||
mLayerSelectionMenu->clear();
|
||||
QString heightmap = QgsProject::instance()->readEntry( "Heightmap", "layer" );
|
||||
// Use layerTreeRoot to get layers ordered as in the layer tree
|
||||
foreach ( QgsLayerTreeLayer* layerTreeLayer, QgsProject::instance()->layerTreeRoot()->findLayers() )
|
||||
{
|
||||
QgsMapLayer* layer = layerTreeLayer->layer();
|
||||
if ( !layer )
|
||||
continue;
|
||||
QAction* layerAction = new QAction( layer->name(), mLayerSelectionMenu );
|
||||
layerAction->setData( layer->id() );
|
||||
// Check if was not previously unchecked, unless it is a new layer with url=http in datasource
|
||||
layerAction->setCheckable( true );
|
||||
bool wasUnchecked = prevDisabledLayers.contains( layer->id() );
|
||||
bool isNew = !prevLayers.contains( layer->id() );
|
||||
bool isRemote = layer->source().contains( "url=http" );
|
||||
bool isHeightmap = layer->id() == heightmap;
|
||||
layerAction->setChecked( !wasUnchecked && !( isNew && ( isRemote || isHeightmap ) ) );
|
||||
connect( layerAction, SIGNAL( toggled( bool ) ), this, SIGNAL( layersChanged() ) );
|
||||
mLayerSelectionMenu->addAction( layerAction );
|
||||
}
|
||||
if ( prevEnabledLayers != getSelectedLayers() )
|
||||
emit layersChanged();
|
||||
}
|
||||
|
||||
QStringList QgsGlobeWidget::getSelectedLayers() const
|
||||
{
|
||||
QStringList selectedLayers;
|
||||
foreach ( QAction* layerAction, mLayerSelectionMenu->actions() )
|
||||
{
|
||||
if ( layerAction->isChecked() )
|
||||
{
|
||||
selectedLayers.append( layerAction->data().toString() );
|
||||
}
|
||||
}
|
||||
return selectedLayers;
|
||||
}
|
||||
|
||||
void QgsGlobeWidget::contextMenuEvent( QContextMenuEvent * e )
|
||||
{
|
||||
e->accept();
|
||||
}
|
43
src/plugins/globe/qgsglobewidget.h
Normal file
@ -0,0 +1,43 @@
|
||||
/***************************************************************************
|
||||
qgsglobewidget.h
|
||||
---------------------
|
||||
begin : August 2010
|
||||
copyright : (C) 2016 Sandro Mani
|
||||
email : smani at sourcepole dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 <QDockWidget>
|
||||
|
||||
class QgisInterface;
|
||||
class QgsGlobePlugin;
|
||||
class QMenu;
|
||||
|
||||
class QgsGlobeWidget : public QDockWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QgsGlobeWidget( QgisInterface *iface, QWidget* parent = 0 );
|
||||
QStringList getSelectedLayers() const;
|
||||
|
||||
signals:
|
||||
void layersChanged();
|
||||
void showSettings();
|
||||
void refresh();
|
||||
void syncExtent();
|
||||
|
||||
private:
|
||||
QgisInterface* mQgisIface;
|
||||
QMenu* mLayerSelectionMenu;
|
||||
|
||||
void contextMenuEvent( QContextMenuEvent * e ) override;
|
||||
|
||||
private slots:
|
||||
void updateLayerSelectionMenu();
|
||||
};
|
@ -1,225 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgsosgearthtilesource.cpp
|
||||
---------------------
|
||||
begin : August 2010
|
||||
copyright : (C) 2010 by Pirmin Kalberer
|
||||
email : pka at sourcepole dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 <osgEarth/TileSource>
|
||||
#include <osgEarth/Registry>
|
||||
#include <osgEarth/ImageUtils>
|
||||
|
||||
#include <osg/Notify>
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/FileUtils>
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgDB/WriteFile>
|
||||
|
||||
#include "qgsosgearthtilesource.h"
|
||||
|
||||
#include <qgsapplication.h>
|
||||
#include <qgslogger.h>
|
||||
#include <qgisinterface.h>
|
||||
#include <qgsmapcanvas.h>
|
||||
|
||||
#ifdef USE_RENDERER
|
||||
#include <qgsmaprenderer.h>
|
||||
#else
|
||||
#include <qgsmaprendererjob.h>
|
||||
#endif
|
||||
|
||||
#include <QFile>
|
||||
#include <QImage>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
using namespace osgEarth;
|
||||
using namespace osgEarth::Drivers;
|
||||
|
||||
|
||||
QgsOsgEarthTileSource::QgsOsgEarthTileSource( QgisInterface* theQgisInterface, const TileSourceOptions& options )
|
||||
: TileSource( options )
|
||||
, mQGisIface( theQgisInterface )
|
||||
, mCoordTransform( 0 )
|
||||
#ifdef USE_RENDERER
|
||||
, mMapRenderer( 0 )
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
void QgsOsgEarthTileSource::initialize( const std::string& referenceURI, const Profile* overrideProfile )
|
||||
{
|
||||
Q_UNUSED( referenceURI );
|
||||
Q_UNUSED( overrideProfile );
|
||||
|
||||
setProfile( osgEarth::Registry::instance()->getGlobalGeodeticProfile() );
|
||||
|
||||
QgsCoordinateReferenceSystem destCRS;
|
||||
destCRS.createFromOgcWmsCrs( GEO_EPSG_CRS_AUTHID );
|
||||
|
||||
QgsMapCanvas *c = mQGisIface->mapCanvas();
|
||||
if ( c->mapSettings().destinationCrs().authid().compare( GEO_EPSG_CRS_AUTHID, Qt::CaseInsensitive ) != 0 )
|
||||
{
|
||||
// FIXME: crs from canvas or first layer?
|
||||
QgsCoordinateReferenceSystem srcCRS( c->mapSettings().destinationCrs() );
|
||||
QgsDebugMsg( QString( "transforming from %1 to %2" ).arg( srcCRS.authid() ).arg( destCRS.authid() ) );
|
||||
mCoordTransform = new QgsCoordinateTransform( srcCRS, destCRS );
|
||||
}
|
||||
else
|
||||
{
|
||||
mCoordTransform = 0;
|
||||
}
|
||||
|
||||
#ifdef USE_RENDERER
|
||||
mMapRenderer = new QgsMapRenderer();
|
||||
mMapRenderer->setDestinationCrs( destCRS );
|
||||
mMapRenderer->setProjectionsEnabled( true );
|
||||
mMapRenderer->setOutputUnits( c->mapRenderer()->outputUnits() );
|
||||
mMapRenderer->setMapUnits( QGis::Degrees );
|
||||
#else
|
||||
mMapSettings.setDestinationCrs( destCRS );
|
||||
mMapSettings.setCrsTransformEnabled( true );
|
||||
mMapSettings.setMapUnits( QGis::Degrees );
|
||||
#endif
|
||||
}
|
||||
|
||||
osg::Image* QgsOsgEarthTileSource::createImage( const TileKey& key, ProgressCallback* progress )
|
||||
{
|
||||
QString kname = key.str().c_str();
|
||||
kname.replace( '/', '_' );
|
||||
|
||||
Q_UNUSED( progress );
|
||||
|
||||
//Get the extents of the tile
|
||||
int tileSize = getPixelsPerTile();
|
||||
if ( tileSize <= 0 )
|
||||
{
|
||||
QgsDebugMsg( "Tile size too small." );
|
||||
return ImageUtils::createEmptyImage();
|
||||
}
|
||||
|
||||
QgsRectangle viewExtent = mQGisIface->mapCanvas()->fullExtent();
|
||||
if ( mCoordTransform )
|
||||
{
|
||||
QgsDebugMsg( QString( "vext0:%1" ).arg( viewExtent.toString( 5 ) ) );
|
||||
viewExtent = mCoordTransform->transformBoundingBox( viewExtent );
|
||||
}
|
||||
|
||||
QgsDebugMsg( QString( "vext1:%1" ).arg( viewExtent.toString( 5 ) ) );
|
||||
|
||||
double xmin, ymin, xmax, ymax;
|
||||
key.getExtent().getBounds( xmin, ymin, xmax, ymax );
|
||||
QgsRectangle tileExtent( xmin, ymin, xmax, ymax );
|
||||
|
||||
QgsDebugMsg( QString( "text0:%1" ).arg( tileExtent.toString( 5 ) ) );
|
||||
if ( !viewExtent.intersects( tileExtent ) )
|
||||
{
|
||||
QgsDebugMsg( QString( "earth tile key:%1 ext:%2: NO INTERSECT" ).arg( kname ).arg( tileExtent.toString( 5 ) ) );
|
||||
return ImageUtils::createEmptyImage();
|
||||
}
|
||||
|
||||
#ifdef USE_RENDERER
|
||||
QImage *qImage = createQImage( tileSize, tileSize );
|
||||
if ( !qImage )
|
||||
{
|
||||
QgsDebugMsg( QString( "earth tile key:%1 ext:%2: EMPTY IMAGE" ).arg( kname ).arg( tileExtent.toString( 5 ) ) );
|
||||
return ImageUtils::createEmptyImage();
|
||||
}
|
||||
|
||||
mMapRenderer->setLayerSet( mQGisIface->mapCanvas()->mapRenderer()->layerSet() );
|
||||
mMapRenderer->setOutputSize( QSize( tileSize, tileSize ), qImage->logicalDpiX() );
|
||||
mMapRenderer->setExtent( tileExtent );
|
||||
|
||||
QPainter thePainter( qImage );
|
||||
mMapRenderer->render( &thePainter );
|
||||
#else
|
||||
mMapSettings.setLayers( mQGisIface->mapCanvas()->mapSettings().layers() );
|
||||
mMapSettings.setOutputSize( QSize( tileSize, tileSize ) );
|
||||
mMapSettings.setOutputDpi( QgsApplication::desktop()->logicalDpiX() );
|
||||
mMapSettings.setExtent( tileExtent );
|
||||
mMapSettings.setBackgroundColor( QColor( 0, 0, 0, 0 ) );
|
||||
|
||||
QgsMapRendererSequentialJob job( mMapSettings );
|
||||
job.start();
|
||||
job.waitForFinished();
|
||||
|
||||
QImage *qImage = new QImage( job.renderedImage() );
|
||||
if ( !qImage )
|
||||
{
|
||||
QgsDebugMsg( QString( "earth tile key:%1 ext:%2: EMPTY IMAGE" ).arg( kname ).arg( tileExtent.toString( 5 ) ) );
|
||||
return ImageUtils::createEmptyImage();
|
||||
}
|
||||
|
||||
Q_ASSERT( qImage->logicalDpiX() == QgsApplication::desktop()->logicalDpiX() );
|
||||
Q_ASSERT( qImage->format() == QImage::Format_ARGB32_Premultiplied );
|
||||
#endif
|
||||
|
||||
QgsDebugMsg( QString( "earth tile key:%1 ext:%2" ).arg( kname ).arg( tileExtent.toString( 5 ) ) );
|
||||
#if 0
|
||||
qImage->save( QString( "/tmp/tile-%1.png" ).arg( kname ) );
|
||||
#endif
|
||||
|
||||
osg::ref_ptr<osg::Image> image = new osg::Image;
|
||||
|
||||
//The pixel format is always RGBA to support transparency
|
||||
image->setImage( tileSize, tileSize, 1, 4, // width, height, depth, pixelFormat?
|
||||
GL_BGRA, GL_UNSIGNED_BYTE, //Why not GL_RGBA - Qt bug?
|
||||
qImage->bits(),
|
||||
osg::Image::NO_DELETE, 1 );
|
||||
|
||||
image->flipVertical();
|
||||
|
||||
//Create a transparent image if we don't have an image
|
||||
if ( !image.valid() )
|
||||
{
|
||||
QgsDebugMsg( "image is invalid" );
|
||||
return ImageUtils::createEmptyImage();
|
||||
}
|
||||
|
||||
QgsDebugMsg( "returning image" );
|
||||
return image.release();
|
||||
}
|
||||
|
||||
QImage* QgsOsgEarthTileSource::createQImage( int width, int height ) const
|
||||
{
|
||||
if ( width < 0 || height < 0 )
|
||||
return 0;
|
||||
|
||||
QImage *qImage = 0;
|
||||
|
||||
//is format jpeg?
|
||||
bool jpeg = false;
|
||||
//transparent parameter
|
||||
bool transparent = true;
|
||||
|
||||
//use alpha channel only if necessary because it slows down performance
|
||||
if ( transparent && !jpeg )
|
||||
{
|
||||
qImage = new QImage( width, height, QImage::Format_ARGB32_Premultiplied );
|
||||
qImage->fill( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
qImage = new QImage( width, height, QImage::Format_RGB32 );
|
||||
qImage->fill( qRgb( 255, 255, 255 ) );
|
||||
}
|
||||
|
||||
if ( !qImage )
|
||||
return 0;
|
||||
|
||||
//apply DPI parameter if present.
|
||||
#if 0
|
||||
int dpm = dpi / 0.0254;
|
||||
qImage->setDotsPerMeterX( dpm );
|
||||
qImage->setDotsPerMeterY( dpm );
|
||||
#endif
|
||||
return qImage;
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgsosgearthtilesource.h
|
||||
---------------------
|
||||
begin : August 2010
|
||||
copyright : (C) 2010 by Pirmin Kalberer
|
||||
email : pka at sourcepole dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef OSGEARTH_DRIVER_QGIS_DRIVEROPTIONS
|
||||
#define OSGEARTH_DRIVER_QGIS_DRIVEROPTIONS 1
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
class QgisInterface;
|
||||
class QgsMapRenderer;
|
||||
class QgsCoordinateTransform;
|
||||
class QImage;
|
||||
|
||||
#include <osgEarth/Common>
|
||||
#include <osgEarth/TileSource>
|
||||
|
||||
#define USE_RENDERER
|
||||
|
||||
#ifndef USE_RENDERER
|
||||
#include "qgsmapsettings.h"
|
||||
#endif
|
||||
|
||||
using namespace osgEarth;
|
||||
|
||||
namespace osgEarth
|
||||
{
|
||||
namespace Drivers
|
||||
{
|
||||
class QgsOsgEarthTileSource : public TileSource
|
||||
{
|
||||
public:
|
||||
QgsOsgEarthTileSource( QgisInterface* theQgisInterface, const TileSourceOptions& options = TileSourceOptions() );
|
||||
|
||||
void initialize( const std::string& referenceURI, const Profile* overrideProfile = nullptr );
|
||||
|
||||
osg::Image* createImage( const TileKey& key, ProgressCallback* progress ) override;
|
||||
|
||||
virtual osg::HeightField* createHeightField( const TileKey &key, ProgressCallback* progress ) override
|
||||
{
|
||||
Q_UNUSED( key );
|
||||
Q_UNUSED( progress );
|
||||
//NI
|
||||
OE_WARN << "[QGIS] Driver does not support heightfields" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual std::string getExtension() const override
|
||||
{
|
||||
//All QGIS tiles are in JPEG format
|
||||
return "jpg";
|
||||
}
|
||||
|
||||
virtual bool supportsPersistentCaching() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
QImage* createQImage( int width, int height ) const;
|
||||
|
||||
//! Pointer to the QGIS interface object
|
||||
QgisInterface *mQGisIface;
|
||||
QgsCoordinateTransform *mCoordTransform;
|
||||
#ifndef USE_RENDERER
|
||||
QgsMapSettings mMapSettings;
|
||||
#else
|
||||
QgsMapRenderer *mMapRenderer;
|
||||
#endif
|
||||
};
|
||||
}
|
||||
} // namespace osgEarth::Drivers
|
||||
|
||||
#endif // OSGEARTH_DRIVER_QGIS_DRIVEROPTIONS
|
||||
|
20
src/plugins/globe/qgsosgfeature.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
/***************************************************************************
|
||||
qgsosgfeature.cpp
|
||||
--------------------------------------
|
||||
Date : 11.7.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 "qgsosgfeature.h"
|
||||
|
||||
QgsOsgFeature::QgsOsgFeature()
|
||||
{
|
||||
}
|
25
src/plugins/globe/qgsosgfeature.h
Normal file
@ -0,0 +1,25 @@
|
||||
/***************************************************************************
|
||||
qgsosgfeature.h
|
||||
--------------------------------------
|
||||
Date : 11.7.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSOSGFEATURE_H
|
||||
#define QGSOSGFEATURE_H
|
||||
|
||||
class QgsOsgFeature : public Feature
|
||||
{
|
||||
public:
|
||||
QgsOsgFeature();
|
||||
};
|
||||
|
||||
#endif // QGSOSGFEATURE_H
|
@ -458,7 +458,7 @@ QgsRectangle QgsInterpolationDialog::boundingBoxOfLayers()
|
||||
}
|
||||
else
|
||||
{
|
||||
combinedLayerExtent.combineExtentWith( ¤tLayerExtent );
|
||||
combinedLayerExtent.combineExtentWith( currentLayerExtent );
|
||||
}
|
||||
}
|
||||
return combinedLayerExtent;
|
||||
|
@ -1171,7 +1171,7 @@ ErrorList topolTest::checkOverlapWithLayer( double tolerance, QgsVectorLayer* la
|
||||
{
|
||||
QgsRectangle r = bb;
|
||||
QgsRectangle r2 = g2->boundingBox();
|
||||
r.combineExtentWith( &r2 );
|
||||
r.combineExtentWith( r2 );
|
||||
|
||||
QScopedPointer<QgsGeometry> conflictGeom( g1->intersection( g2 ) );
|
||||
// could this for some reason return NULL?
|
||||
|
@ -474,7 +474,7 @@ void QgsDelimitedTextProvider::scanFile( bool buildIndexes )
|
||||
mNumberFeatures++;
|
||||
if ( geom->isMultipart() ) mWkbType = type;
|
||||
QgsRectangle bbox( geom->boundingBox() );
|
||||
mExtent.combineExtentWith( &bbox );
|
||||
mExtent.combineExtentWith( bbox );
|
||||
}
|
||||
if ( buildSpatialIndex )
|
||||
{
|
||||
@ -797,7 +797,7 @@ void QgsDelimitedTextProvider::rescanFile()
|
||||
else
|
||||
{
|
||||
QgsRectangle bbox( f.constGeometry()->boundingBox() );
|
||||
mExtent.combineExtentWith( &bbox );
|
||||
mExtent.combineExtentWith( bbox );
|
||||
}
|
||||
if ( buildSpatialIndex ) mSpatialIndex->insertFeature( f );
|
||||
}
|
||||
|
@ -1256,7 +1256,7 @@ bool QgsWmsProvider::calculateExtent()
|
||||
}
|
||||
else
|
||||
{
|
||||
mLayerExtent.combineExtentWith( &extent );
|
||||
mLayerExtent.combineExtentWith( extent );
|
||||
}
|
||||
|
||||
firstLayer = false;
|
||||
|
@ -725,7 +725,7 @@ void QgsServerProjectParser::combineExtentAndCrsOfGroupChildren( QDomElement& gr
|
||||
}
|
||||
else
|
||||
{
|
||||
combinedBBox.combineExtentWith( &bbox );
|
||||
combinedBBox.combineExtentWith( bbox );
|
||||
}
|
||||
}
|
||||
|
||||
|