Skip to content

Commit b49316a

Browse files
committed
Place 3D models on point layer
1 parent 764d002 commit b49316a

File tree

4 files changed

+174
-47
lines changed

4 files changed

+174
-47
lines changed

src/plugins/globe/globe_plugin.cpp

+18-35
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
#include <qgslogger.h>
2828
#include <qgsapplication.h>
2929
#include <qgsmapcanvas.h>
30+
#include <qgsfeature.h>
31+
#include <qgsgeometry.h>
32+
#include <qgspoint.h>
3033

3134
#include <QAction>
3235
#include <QToolBar>
@@ -169,6 +172,7 @@ void GlobePlugin::run()
169172

170173
void GlobePlugin::settings()
171174
{
175+
mSettingsDialog.updatePointLayers();
172176
if( mSettingsDialog.exec() )
173177
{
174178
//viewer stereo settings set by mSettingsDialog and stored in QSettings
@@ -220,45 +224,24 @@ void GlobePlugin::setupMap()
220224
mElevationManager->setMaxTilesToCache( 50 );
221225

222226
mObjectPlacer = new osgEarthUtil::ObjectPlacer( mMapNode );
223-
224-
#if 0
225-
// model placement test
226-
227-
// create simple tree model from primitives
228-
osg::TessellationHints* hints = new osg::TessellationHints();
229-
hints->setDetailRatio( 0.1 );
230-
231-
osg::Cylinder* cylinder = new osg::Cylinder( osg::Vec3( 0 , 0, 5 ), 0.5, 10 );
232-
osg::ShapeDrawable* cylinderDrawable = new osg::ShapeDrawable( cylinder, hints );
233-
cylinderDrawable->setColor( osg::Vec4( 0.5, 0.25, 0.125, 1.0 ) );
234-
osg::Geode* cylinderGeode = new osg::Geode();
235-
cylinderGeode->addDrawable( cylinderDrawable );
236-
237-
osg::Cone* cone = new osg::Cone( osg::Vec3( 0 , 0, 10 ), 4, 10 );
238-
osg::ShapeDrawable* coneDrawable = new osg::ShapeDrawable( cone, hints );
239-
coneDrawable->setColor( osg::Vec4( 0.0, 0.5, 0.0, 1.0 ) );
240-
osg::Geode* coneGeode = new osg::Geode();
241-
coneGeode->addDrawable( coneDrawable );
242-
243-
osg::Group* model = new osg::Group();
244-
model->addChild( cylinderGeode );
245-
model->addChild( coneGeode );
246-
247-
// place models on jittered grid
248-
srand( 23 );
249-
double lat = 47.1786;
250-
double lon = 10.111;
251-
double gridSize = 0.001;
252-
for( int i = 0; i < 10; i++ )
227+
if ( mSettingsDialog.modelLayer() && !mSettingsDialog.modelPath().isEmpty() )
253228
{
254-
for( int j = 0; j < 10; j++ )
229+
osg::Node* model = osgDB::readNodeFile( mSettingsDialog.modelPath().toStdString() );
230+
if ( model )
255231
{
256-
double dx = gridSize * ( rand() / (( double ) RAND_MAX + 1.0 ) - 0.5 );
257-
double dy = gridSize * ( rand() / (( double ) RAND_MAX + 1.0 ) - 0.5 );
258-
placeNode( model, lat + i * gridSize + dx, lon + j * gridSize + dy );
232+
QgsVectorLayer* layer = mSettingsDialog.modelLayer();
233+
QgsAttributeList fetchAttributes;
234+
layer->select( fetchAttributes ); //TODO: select only visible features
235+
QgsFeature feature;
236+
while ( layer->nextFeature( feature ) )
237+
{
238+
QgsPoint point = feature.geometry()->asPoint();
239+
QgsDebugMsg( "placeNode" + point.toString() );
240+
placeNode( model, point.y(), point.x() );
241+
}
259242
}
260243
}
261-
#endif
244+
262245
}
263246

264247
void GlobePlugin::projectReady()

src/plugins/globe/globe_plugin_dialog.cpp

+61-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
#include <qgsapplication.h>
2323
#include <qgsproject.h>
24+
#include <qgsmaplayerregistry.h>
25+
#include <qgsmaplayer.h>
2426
#include <qgslogger.h>
2527
#include <qgscontexthelp.h>
2628
#include <QtAlgorithms>
@@ -55,7 +57,7 @@ QgsGlobePluginDialog::~QgsGlobePluginDialog()
5557
{
5658
}
5759

58-
QString QgsGlobePluginDialog::openFile()
60+
QString QgsGlobePluginDialog::openRasterFile()
5961
{
6062
//see http://www.gdal.org/formats_list.html
6163
const char* filter = "GDAL files (*.dem *.tif *.tiff *.jpg *.jpeg *.asc) \
@@ -161,7 +163,7 @@ void QgsGlobePluginDialog::on_elevationCombo_currentIndexChanged(QString type)
161163

162164
void QgsGlobePluginDialog::on_elevationBrowse_clicked()
163165
{
164-
QString newPath = openFile();
166+
QString newPath = openRasterFile();
165167
if ( ! newPath.isEmpty() )
166168
{
167169
elevationPath->setText( newPath );
@@ -326,6 +328,63 @@ void QgsGlobePluginDialog::saveElevationDatasources()
326328
}
327329
//END ELEVATION
328330

331+
//MODEL
332+
QList<QgsVectorLayer*> QgsGlobePluginDialog::pointLayers()
333+
{
334+
QList<QgsVectorLayer*> list;
335+
QMap< QString, QgsMapLayer *> layers = QgsMapLayerRegistry::instance()->mapLayers();
336+
QMapIterator<QString, QgsMapLayer *> it(layers);
337+
while (it.hasNext())
338+
{
339+
it.next();
340+
QgsMapLayer* layer = it.value();
341+
if (layer->type() == QgsMapLayer::VectorLayer)
342+
{
343+
QgsVectorLayer* vectorLayer = static_cast<QgsVectorLayer*>(layer);
344+
if ( vectorLayer->geometryType() == QGis::Point )
345+
{
346+
list.append( vectorLayer );
347+
}
348+
}
349+
}
350+
return list;
351+
}
352+
353+
void QgsGlobePluginDialog::updatePointLayers()
354+
{
355+
modelLayerCombo->clear();
356+
QList<QgsVectorLayer*> layers = pointLayers();
357+
QListIterator<QgsVectorLayer*> it(layers);
358+
while (it.hasNext())
359+
{
360+
QgsVectorLayer* layer = it.next();
361+
modelLayerCombo->addItem( layer->name() );
362+
}
363+
}
364+
365+
QgsVectorLayer* QgsGlobePluginDialog::modelLayer()
366+
{
367+
QList<QgsVectorLayer*> layers = pointLayers();
368+
return ( modelLayerCombo->currentIndex() == -1 ) ? NULL : layers.at( modelLayerCombo->currentIndex() );
369+
}
370+
371+
void QgsGlobePluginDialog::on_modelBrowse_clicked()
372+
{
373+
//see http://www.openscenegraph.org/projects/osg/wiki/Support/UserGuides/Plugins
374+
const char* filter = "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) \
375+
;;All files (*.*)";
376+
QString path = QFileDialog::getOpenFileName( this,
377+
tr( "Open 3D model file" ),
378+
QDir::homePath (),
379+
tr( filter ) );
380+
381+
if ( ! path.isEmpty() )
382+
{
383+
modelPathLineEdit->setText( path );
384+
}
385+
}
386+
//END MODEL
387+
329388
//STEREO
330389
void QgsGlobePluginDialog::on_resetStereoDefaults_clicked()
331390
{

src/plugins/globe/globe_plugin_dialog.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "qgsosgviewer.h"
2626
#include "qgscontexthelp.h"
2727
#include <qgsproject.h>
28+
#include <qgsvectorlayer.h>
2829

2930
class QgsGlobePluginDialog:public QDialog, private Ui::QgsGlobePluginDialogGuiBase
3031
{
@@ -35,19 +36,22 @@ class QgsGlobePluginDialog:public QDialog, private Ui::QgsGlobePluginDialogGuiBa
3536
~QgsGlobePluginDialog();
3637
void readElevationDatasources();
3738
QTableWidget *elevationDatasources() { return elevationDatasourcesWidget; }
38-
39+
void updatePointLayers();
40+
QgsVectorLayer* modelLayer();
41+
QString modelPath() { return modelPathLineEdit->text(); }
3942
private:
4043
QgsOsgViewer* mViewer;
4144
QSettings settings;
4245
private:
43-
QString openFile();
46+
QString openRasterFile();
4447
void updateStereoDialog();
4548
bool validateResource( QString type, QString uri, QString& error);
4649
void saveElevationDatasources();
4750
void moveRow( QTableWidget* widget, bool up);
4851
QList<QTableWidgetItem*> takeRow( QTableWidget* widget, int row);
4952
void setRow( QTableWidget* widget, int row, const QList< QTableWidgetItem* >& rowItems);
5053
void showMessageBox( QString text);
54+
QList<QgsVectorLayer*> pointLayers();
5155
//! Set osg/DisplaySettings
5256
void setStereoConfig();
5357
//! Init dialog from settings using defaults from osg/DisplaySettings
@@ -73,6 +77,9 @@ class QgsGlobePluginDialog:public QDialog, private Ui::QgsGlobePluginDialogGuiBa
7377
void on_splitStereoVerticalEyeMapping_currentIndexChanged(int value);
7478
void on_resetStereoDefaults_clicked();
7579

80+
//MODEL
81+
void on_modelBrowse_clicked();
82+
7683
//ELEVATION
7784
void on_elevationCombo_currentIndexChanged(QString type);
7885
void on_elevationBrowse_clicked();

src/plugins/globe/globe_plugin_dialog_guibase.ui

+86-8
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
<iconset>
3333
<normaloff>../../.designer/backup</normaloff>../../.designer/backup</iconset>
3434
</property>
35-
<layout class="QVBoxLayout" name="verticalLayout">
36-
<item>
35+
<layout class="QGridLayout" name="gridLayout_3">
36+
<item row="0" column="0">
3737
<widget class="QTabWidget" name="tabWidget">
3838
<property name="currentIndex">
3939
<number>0</number>
@@ -50,6 +50,9 @@
5050
<property name="text">
5151
<string>Type</string>
5252
</property>
53+
<property name="buddy">
54+
<cstring>elevationCombo</cstring>
55+
</property>
5356
</widget>
5457
</item>
5558
<item>
@@ -89,6 +92,9 @@
8992
<property name="text">
9093
<string>URL/File</string>
9194
</property>
95+
<property name="buddy">
96+
<cstring>elevationPath</cstring>
97+
</property>
9298
</widget>
9399
</item>
94100
<item>
@@ -113,7 +119,7 @@
113119
</sizepolicy>
114120
</property>
115121
<property name="currentIndex">
116-
<number>0</number>
122+
<number>1</number>
117123
</property>
118124
<widget class="QWidget" name="elevationIsLocal">
119125
<layout class="QGridLayout" name="gridLayout_5">
@@ -295,6 +301,78 @@
295301
</item>
296302
</layout>
297303
</widget>
304+
<widget class="QWidget" name="model">
305+
<attribute name="title">
306+
<string>Model</string>
307+
</attribute>
308+
<layout class="QGridLayout" name="gridLayout_2">
309+
<item row="0" column="0">
310+
<widget class="QLabel" name="label_11">
311+
<property name="text">
312+
<string>Point Layer</string>
313+
</property>
314+
<property name="buddy">
315+
<cstring>modelLayerCombo</cstring>
316+
</property>
317+
</widget>
318+
</item>
319+
<item row="1" column="0">
320+
<widget class="QLabel" name="label_14">
321+
<property name="text">
322+
<string>3D Model</string>
323+
</property>
324+
<property name="buddy">
325+
<cstring>modelPathLineEdit</cstring>
326+
</property>
327+
</widget>
328+
</item>
329+
<item row="1" column="3">
330+
<widget class="QLineEdit" name="modelPathLineEdit">
331+
<property name="sizePolicy">
332+
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
333+
<horstretch>0</horstretch>
334+
<verstretch>0</verstretch>
335+
</sizepolicy>
336+
</property>
337+
<property name="text">
338+
<string/>
339+
</property>
340+
</widget>
341+
</item>
342+
<item row="1" column="4">
343+
<widget class="QPushButton" name="modelBrowse">
344+
<property name="enabled">
345+
<bool>true</bool>
346+
</property>
347+
<property name="sizePolicy">
348+
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
349+
<horstretch>0</horstretch>
350+
<verstretch>0</verstretch>
351+
</sizepolicy>
352+
</property>
353+
<property name="maximumSize">
354+
<size>
355+
<width>27</width>
356+
<height>16777215</height>
357+
</size>
358+
</property>
359+
<property name="text">
360+
<string>...</string>
361+
</property>
362+
</widget>
363+
</item>
364+
<item row="0" column="3">
365+
<widget class="QComboBox" name="modelLayerCombo">
366+
<property name="sizePolicy">
367+
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
368+
<horstretch>0</horstretch>
369+
<verstretch>0</verstretch>
370+
</sizepolicy>
371+
</property>
372+
</widget>
373+
</item>
374+
</layout>
375+
</widget>
298376
<widget class="QWidget" name="stereo">
299377
<attribute name="title">
300378
<string>Stereo</string>
@@ -515,7 +593,7 @@
515593
</widget>
516594
</widget>
517595
</item>
518-
<item>
596+
<item row="1" column="0">
519597
<widget class="QDialogButtonBox" name="buttonBox">
520598
<property name="standardButtons">
521599
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
@@ -547,8 +625,8 @@
547625
<slot>accept()</slot>
548626
<hints>
549627
<hint type="sourcelabel">
550-
<x>442</x>
551-
<y>460</y>
628+
<x>446</x>
629+
<y>529</y>
552630
</hint>
553631
<hint type="destinationlabel">
554632
<x>481</x>
@@ -563,8 +641,8 @@
563641
<slot>reject()</slot>
564642
<hints>
565643
<hint type="sourcelabel">
566-
<x>383</x>
567-
<y>460</y>
644+
<x>387</x>
645+
<y>529</y>
568646
</hint>
569647
<hint type="destinationlabel">
570648
<x>281</x>

0 commit comments

Comments
 (0)