| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8810,6 +8810,16 @@ void QgisApp::openURL( QString url, bool useQgisDocDirectory ) | |
| #endif | ||
| } | ||
|
|
||
| void QgisApp::registerMapLayerPropertiesFactory( QgsMapLayerPropertiesFactory* factory ) | ||
| { | ||
| mMapLayerPropertiesFactories << factory; | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
manisandro
Author
Member
|
||
| } | ||
|
|
||
| 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() ) | ||
| { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 ); | ||
This comment has been minimized.
Sorry, something went wrong.
nyalldawson
Collaborator
|
||
| 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(); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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() | ||
| { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -558,7 +558,7 @@ void QgsRubberBand::updateRect() | |
| } | ||
| else | ||
| { | ||
| r.combineExtentWith( rect ); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 ) | ||
| { | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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} | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| <RCC> | ||
| <qresource prefix="/globe"> | ||
| <file alias="globe.png">images/globe.png</file> | ||
| <file alias="icon.svg">images/icon.svg</file> | ||
| </qresource> | ||
| </RCC> | ||
@manisandro should ownership of factory be transferred here? If so, this is leaky. If not, it would be nice to clarify this in the docs.