2,987 changes: 1,639 additions & 1,348 deletions i18n/qgis_gl_ES.ts

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions i18n/qgis_it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ sono stati ridotti a %2 dopo la semplificazione</translation>
</message>
<message>
<source>Random selection within subsets</source>
<translation>Selezione causale con un sottoinsieme</translation>
<translation>Selezione casuale con un sottoinsieme</translation>
</message>
<message>
<source>Please specify input vector layer</source>
Expand Down Expand Up @@ -3252,7 +3252,8 @@ quando si preme sul bottone Aiuto del dialogo degli strumenti.</translation>
<message>
<location filename="../python/plugins/GdalTools/tools/widgetOverview.ui" line="68"/>
<source>cubic</source>
<translation type="unfinished"></translation>
<translatorcomment>cubico</translatorcomment>
<translation></translation>
</message>
<message>
<location filename="../python/plugins/GdalTools/tools/widgetOverview.ui" line="73"/>
Expand Down Expand Up @@ -4919,7 +4920,8 @@ Ctl (Cmd) increments by 15 deg.</source>
<message>
<location filename="../src/ui/qgisapp.ui" line="1091"/>
<source>Layer Labeling Options</source>
<translation type="unfinished"></translation>
<translatorcomment>Opzioni per l&apos;etichettatura del layer</translatorcomment>
<translation></translation>
</message>
<message>
<location filename="../src/ui/qgisapp.ui" line="1100"/>
Expand Down
55,238 changes: 55,238 additions & 0 deletions i18n/qgis_sr_Cyrl.ts

Large diffs are not rendered by default.

13,998 changes: 8,524 additions & 5,474 deletions i18n/qgis_sr_CS-Latn.ts → i18n/qgis_sr_Latn.ts

Large diffs are not rendered by default.

File renamed without changes
Binary file added images/flags/sr_Latn.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
967 changes: 484 additions & 483 deletions images/images.qrc

Large diffs are not rendered by default.

57 changes: 12 additions & 45 deletions python/core/raster/qgsrasterdataprovider.sip
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ class QgsRasterDataProvider : QgsDataProvider, QgsRasterInterface
/*! Max current value */ ColorInterpretationMax = 17
};

enum IdentifyFormat
{
IdentifyFormatValue,
IdentifyFormatText,
IdentifyFormatHtml,
IdentifyFormatFeature
};

// Progress types
enum RasterProgressType
{
Expand Down Expand Up @@ -135,12 +143,12 @@ class QgsRasterDataProvider : QgsDataProvider, QgsRasterInterface
// TODO: Get the file masks supported by this provider, suitable for feeding into the file open dialog box

/** Returns data type for the band specified by number */
virtual QgsRasterBlock::DataType dataType( int bandNo ) const;
virtual QgsRasterBlock::DataType dataType( int bandNo ) const = 0;

/** Returns source data type for the band specified by number,
* source data type may be shorter than dataType
*/
virtual QgsRasterBlock::DataType srcDataType( int bandNo ) const;
virtual QgsRasterBlock::DataType srcDataType( int bandNo ) const = 0;

/** Returns data type for the band specified by number */
virtual int colorInterpretation( int theBandNo ) const;
Expand Down Expand Up @@ -304,47 +312,9 @@ class QgsRasterDataProvider : QgsDataProvider, QgsRasterInterface
*/
virtual QString metadata() = 0;

/** \brief Identify raster value(s) found on the point position
* @param point coordinates in data source CRS
* @return list of pointers to data blocks for all bands,
* caller is responsible to free the allocated memory,
* readValue() may be used to get values
* @note theBinCount, theMinimun and theMaximum not optional in python bindings
*/
// TODO: Consider QVariant or similar instead of void*
// virtual QMap<int, void *> identify( const QgsPoint & point );
virtual QMap<int, QVariant> identify( const QgsPoint & thePoint, IdentifyFormat theFormat, const QgsRectangle &theExtent = QgsRectangle(), int theWidth = 0, int theHeight = 0 );

/**
* \brief Identify details from a server (e.g. WMS) from the last screen update
*
* \param[in] point The pixel coordinate (as it was displayed locally on screen)
*
* \return A text document containing the return from the WMS server
*
* \note WMS Servers prefer to receive coordinates in image space, therefore
* this function expects coordinates in that format.
*
* \note The arbitraryness of the returned document is enforced by WMS standards
* up to at least v1.3.0
*/
virtual QString identifyAsText( const QgsPoint& point ) = 0;

/**
* \brief Identify details from a server (e.g. WMS) from the last screen update
*
* \param[in] point The pixel coordinate (as it was displayed locally on screen)
*
* \return A html document containing the return from the WMS server
*
* \note WMS Servers prefer to receive coordinates in image space, therefore
* this function expects coordinates in that format.
*
* \note The arbitraryness of the returned document is enforced by WMS standards
* up to at least v1.3.0
*
* \note added in 1.5
*/
virtual QString identifyAsHtml( const QgsPoint& point ) = 0;
QMap<QString, QString> identify( const QgsPoint & thePoint, const QgsRectangle &theExtent = QgsRectangle(), int theWidth = 0, int theHeight = 0 );

/**
* \brief Returns the caption error text for the last error in this provider
Expand Down Expand Up @@ -388,9 +358,6 @@ class QgsRasterDataProvider : QgsDataProvider, QgsRasterInterface
static QString makeTableCell( const QString & value );
static QString makeTableCells( const QStringList & values );

/** \brief Set null value in char */
QByteArray noValueBytes( int theBandNo );

/** Time stamp of data source in the moment when data/metadata were loaded by provider */
virtual QDateTime timestamp() const;

Expand Down
2 changes: 1 addition & 1 deletion python/core/raster/qgsrasteriterator.sip
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class QgsRasterIterator
int currentRow;
int nCols;
int nRows;
void* data; //data (can be in oversampled/undersampled resolution)
QgsRasterBlock *block;
QgsRasterProjector* prj; //raster projector (or 0 if no reprojection is done)
};

Expand Down
14 changes: 7 additions & 7 deletions python/core/raster/qgsrasterlayer.sip
Original file line number Diff line number Diff line change
Expand Up @@ -305,21 +305,21 @@ class QgsRasterLayer : QgsMapLayer
bool hasCompatibleSymbology( const QgsMapLayer& theOther ) const;

/** \brief Identify raster value(s) found on the point position */
bool identify( const QgsPoint & point, QMap<QString, QString>& results /Out/ );
//bool identify( const QgsPoint & point, QMap<QString, QString>& results /Out/ );

/** \brief Identify raster value(s) found on the point position */
bool identifyMap( const QgsPoint & point, QMap<int, QString>& results /Out/ );
%MethodCode
sipRes = sipCpp->identify( *a0, *a1 );
%End
// bool identifyMap( const QgsPoint & point, QMap<int, QString>& results /Out/ );
//%MethodCode
// sipRes = sipCpp->identify( *a0, *a1 );
//%End

/** \brief Identify arbitrary details from the WMS server found on the point position */
QString identifyAsText( const QgsPoint & point );
//QString identifyAsText( const QgsPoint & point );

/** \brief Identify arbitrary details from the WMS server found on the point position
* @note added in 1.5
*/
QString identifyAsHtml( const QgsPoint & point );
//QString identifyAsHtml( const QgsPoint & point );

/** \brief Currently returns always false */
bool isEditable() const;
Expand Down
2 changes: 1 addition & 1 deletion python/gui/raster/qgsmultibandcolorrendererwidget.sip
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ class QgsMultiBandColorRendererWidget: QgsRasterRendererWidget
int selectedBand( int index = 0 );

public slots:
void loadMinMax( int theBandNo, double theMin, double theMax );
void loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin );
};
2 changes: 2 additions & 0 deletions scripts/tsstat.pl
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
ru => 'Artem Popov',
sk => 'Lubos Balazovic',
sl_SI => 'Jože Detečnik, Dejan Gregor',
sr_Cyrl => 'Goran Ivanković',
sr_Latn => 'Goran Ivanković',
sv => 'Lars Luthman, Magnus Homann, Victor Axbom',
sq_AL => '',
th => 'Man Chao',
Expand Down
4 changes: 2 additions & 2 deletions src/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ SET(QGIS_APP_SRCS
qgsdecorationscalebardialog.cpp
qgsdecorationgrid.cpp
qgsdecorationgriddialog.cpp
qgsembedlayerdialog.cpp
qgsformannotationdialog.cpp
qgshtmlannotationdialog.cpp
qgsdelattrdialog.cpp
Expand Down Expand Up @@ -95,6 +94,7 @@ SET(QGIS_APP_SRCS
qgspluginmanager.cpp
qgspluginmetadata.cpp
qgspluginregistry.cpp
qgsprojectlayergroupdialog.cpp
qgsprojectproperties.cpp
qgsrastercalcdialog.cpp
qgsrasterlayerproperties.cpp
Expand Down Expand Up @@ -189,7 +189,6 @@ SET (QGIS_APP_MOC_HDRS
qgsdelattrdialog.h
qgsdiagramproperties.h
qgsdisplayangle.h
qgsembedlayerdialog.h
qgsfeatureaction.h
qgsfieldcalculator.h
qgsformannotationdialog.h
Expand Down Expand Up @@ -241,6 +240,7 @@ SET (QGIS_APP_MOC_HDRS
qgsoptions.h
qgspastetransformations.h
qgspluginmanager.h
qgsprojectlayergroupdialog.h
qgsprojectproperties.h
qgsrastercalcdialog.h
qgsrasterlayerproperties.h
Expand Down
27 changes: 15 additions & 12 deletions src/app/qgisapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@
#include "qgsdecorationnortharrow.h"
#include "qgsdecorationscalebar.h"
#include "qgsdecorationgrid.h"
#include "qgsembedlayerdialog.h"
#include "qgsencodingfiledialog.h"
#include "qgsexception.h"
#include "qgsfeature.h"
Expand Down Expand Up @@ -156,6 +155,7 @@
#include "qgspoint.h"
#include "qgshandlebadlayers.h"
#include "qgsproject.h"
#include "qgsprojectlayergroupdialog.h"
#include "qgsprojectproperties.h"
#include "qgsproviderregistry.h"
#include "qgspythonrunner.h"
Expand Down Expand Up @@ -5867,30 +5867,33 @@ void QgisApp::addMapLayer( QgsMapLayer *theMapLayer )
void QgisApp::embedLayers()
{
//dialog to select groups/layers from other project files
QgsEmbedLayerDialog d( this );
QgsProjectLayerGroupDialog d( this );
if ( d.exec() == QDialog::Accepted )
{
mMapCanvas->freeze( true );

QString projectFile = d.selectedProjectFile();

//groups
QList< QPair < QString, QString > > groups = d.embeddedGroups();
QList< QPair < QString, QString > >::const_iterator groupIt = groups.constBegin();
QStringList groups = d.selectedGroups();
QStringList::const_iterator groupIt = groups.constBegin();
for ( ; groupIt != groups.constEnd(); ++groupIt )
{
mMapLegend->addEmbeddedGroup( groupIt->first, groupIt->second );
mMapLegend->addEmbeddedGroup( *groupIt, projectFile );
}

//layers
//layer ids
QList<QDomNode> brokenNodes;
QList< QPair< QgsVectorLayer*, QDomElement > > vectorLayerList;

QList< QPair < QString, QString > > layers = d.embeddedLayers();
QList< QPair < QString, QString > >::const_iterator layerIt = layers.constBegin();
for ( ; layerIt != layers.constEnd(); ++layerIt )
QStringList layerIds = d.selectedLayerIds();
QStringList::const_iterator layerIt = layerIds.constBegin();
for ( ; layerIt != layerIds.constEnd(); ++layerIt )
{
QgsProject::instance()->createEmbeddedLayer( layerIt->first, layerIt->second, brokenNodes, vectorLayerList );
QgsProject::instance()->createEmbeddedLayer( *layerIt, projectFile, brokenNodes, vectorLayerList );
}

mMapCanvas->freeze( false );
if ( groups.size() > 0 || layers.size() > 0 )
if ( groups.size() > 0 || layerIds.size() > 0 )
{
mMapCanvas->refresh();
}
Expand Down
41 changes: 32 additions & 9 deletions src/app/qgsmaptoolidentify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <QCursor>
#include <QPixmap>
#include <QStatusBar>
#include <QVariant>

QgsMapToolIdentify::QgsMapToolIdentify( QgsMapCanvas* canvas )
: QgsMapTool( canvas )
Expand Down Expand Up @@ -315,14 +316,14 @@ bool QgsMapToolIdentify::identifyRasterLayer( QgsRasterLayer *layer, int x, int
{
bool res = true;

if ( !layer )
return false;
if ( !layer ) return false;

QgsRasterDataProvider *dprovider = layer->dataProvider();
if ( dprovider && ( dprovider->capabilities() & QgsRasterDataProvider::Identify ) == 0 )
if ( !dprovider || !( dprovider->capabilities() & QgsRasterDataProvider::Identify ) )
{
return false;
}

QMap< QString, QString > attributes, derivedAttributes;
QgsPoint idPoint = mCanvas->getCoordinateTransform()->toMapCoordinates( x, y );
try
{
Expand All @@ -335,8 +336,9 @@ bool QgsMapToolIdentify::identifyRasterLayer( QgsRasterLayer *layer, int x, int
return false;
}

QString type;
if ( !layer->extent().contains( idPoint ) ) return false;

#if 0
if ( layer->providerType() == "wms" )
{
type = tr( "WMS layer" );
Expand Down Expand Up @@ -366,13 +368,34 @@ bool QgsMapToolIdentify::identifyRasterLayer( QgsRasterLayer *layer, int x, int
res = false;
}
}
else
#endif

// TODO: extent, width, heigh are approximated only if layer is reprojected!!!!
// How to do it better? We dont know source resolution used to reproject the layer.

QgsRectangle viewExtent = mCanvas->extent();
if ( mCanvas->hasCrsTransformEnabled() && dprovider->crs() != mCanvas->mapRenderer()->destinationCrs() )
{
type = tr( "Raster" );
res = layer->extent().contains( idPoint ) && layer->identify( idPoint, attributes );
viewExtent = toLayerCoordinates( layer, viewExtent );
}

if ( res )
// cut by layer extent to use possible cache, the same done when drawing
viewExtent = dprovider->extent().intersect( &viewExtent );

double mapUnitsPerPixel = mCanvas->mapUnitsPerPixel();
// Width and height are calculated from not projected extent and we hope that
// are similar to source width and height used to reproject layer for drawing.
int width = mCanvas->extent().width() / mapUnitsPerPixel;
int height = mCanvas->extent().height() / mapUnitsPerPixel;

QMap< QString, QString > attributes, derivedAttributes;

attributes = dprovider->identify( idPoint, viewExtent, width, height );

QString type;
type = tr( "Raster" );

if ( attributes.size() > 0 )
{
derivedAttributes.insert( tr( "(clicked coordinate)" ), idPoint.toString() );
results()->addFeature( layer, type, attributes, derivedAttributes );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsembedlayerdialog.h"
#include "qgsprojectlayergroupdialog.h"
#include "qgsproject.h"
#include "qgisapp.h"
#include "qgsapplication.h"
Expand All @@ -23,56 +23,84 @@
#include <QMessageBox>
#include <QSettings>

QgsEmbedLayerDialog::QgsEmbedLayerDialog( QWidget * parent, Qt::WindowFlags f ): QDialog( parent, f )
QgsProjectLayerGroupDialog::QgsProjectLayerGroupDialog( QWidget * parent, const QString& projectFile, Qt::WindowFlags f ): QDialog( parent, f ),
mShowEmbeddedContent( false )
{
setupUi( this );

QSettings settings;
restoreGeometry( settings.value( "/Windows/EmbedLayer/geometry" ).toByteArray() );

if ( !projectFile.isEmpty() )
{
mProjectFileLineEdit->setText( projectFile );
mProjectFileLabel->hide();
mProjectFileLineEdit->hide();
mBrowseFileToolButton->hide();
mShowEmbeddedContent = true;
changeProjectFile();
}

QObject::connect( mButtonBox, SIGNAL( rejected() ), this, SLOT( reject() ) );
}

QgsEmbedLayerDialog::~QgsEmbedLayerDialog()
QgsProjectLayerGroupDialog::~QgsProjectLayerGroupDialog()
{
QSettings settings;
settings.setValue( "/Windows/EmbedLayer/geometry", saveGeometry() );
}

QList< QPair < QString, QString > > QgsEmbedLayerDialog::embeddedGroups() const
QStringList QgsProjectLayerGroupDialog::selectedGroups() const
{
QList< QPair < QString, QString > > result;

QStringList groups;
QList<QTreeWidgetItem*> items = mTreeWidget->selectedItems();
QList<QTreeWidgetItem*>::iterator itemIt = items.begin();
for ( ; itemIt != items.end(); ++itemIt )
{
if (( *itemIt )->data( 0, Qt::UserRole ).toString() == "group" )
{
result.push_back( qMakePair(( *itemIt )->text( 0 ), mProjectPath ) );
groups.push_back(( *itemIt )->text( 0 ) );
}
}

return result;
return groups;
}

QList< QPair < QString, QString > > QgsEmbedLayerDialog::embeddedLayers() const
QStringList QgsProjectLayerGroupDialog::selectedLayerIds() const
{
QList< QPair < QString, QString > > result;
QStringList layerIds;
QList<QTreeWidgetItem*> items = mTreeWidget->selectedItems();
QList<QTreeWidgetItem*>::iterator itemIt = items.begin();
for ( ; itemIt != items.end(); ++itemIt )
{
if (( *itemIt )->data( 0, Qt::UserRole ).toString() == "layer" )
{
layerIds.push_back(( *itemIt )->data( 0, Qt::UserRole + 1 ).toString() );
}
}
return layerIds;
}

QStringList QgsProjectLayerGroupDialog::selectedLayerNames() const
{
QStringList layerNames;
QList<QTreeWidgetItem*> items = mTreeWidget->selectedItems();
QList<QTreeWidgetItem*>::iterator itemIt = items.begin();
for ( ; itemIt != items.end(); ++itemIt )
{
if (( *itemIt )->data( 0, Qt::UserRole ).toString() == "layer" )
{
result.push_back( qMakePair(( *itemIt )->data( 0, Qt::UserRole + 1 ).toString(), mProjectPath ) );
layerNames.push_back(( *itemIt )->text( 0 ) );
}
}
return result;
return layerNames;
}

QString QgsProjectLayerGroupDialog::selectedProjectFile() const
{
return mProjectFileLineEdit->text();
}

void QgsEmbedLayerDialog::on_mBrowseFileToolButton_clicked()
void QgsProjectLayerGroupDialog::on_mBrowseFileToolButton_clicked()
{
//line edit might emit editingFinished signal when loosing focus
mProjectFileLineEdit->blockSignals( true );
Expand All @@ -90,12 +118,12 @@ void QgsEmbedLayerDialog::on_mBrowseFileToolButton_clicked()
mProjectFileLineEdit->blockSignals( false );
}

void QgsEmbedLayerDialog::on_mProjectFileLineEdit_editingFinished()
void QgsProjectLayerGroupDialog::on_mProjectFileLineEdit_editingFinished()
{
changeProjectFile();
}

void QgsEmbedLayerDialog::changeProjectFile()
void QgsProjectLayerGroupDialog::changeProjectFile()
{
QFile projectFile( mProjectFileLineEdit->text() );
if ( !projectFile.exists() )
Expand All @@ -110,7 +138,7 @@ void QgsEmbedLayerDialog::changeProjectFile()
}

//check we are not embedding from/to the same project
if ( mProjectFileLineEdit->text() == QgsProject::instance()->fileName() )
if ( mProjectFileLineEdit->isVisible() && mProjectFileLineEdit->text() == QgsProject::instance()->fileName() )
{
QMessageBox::critical( 0, tr( "Recursive embeding not possible" ), tr( "It is not possible to embed layers / groups from the current project" ) );
return;
Expand Down Expand Up @@ -155,12 +183,12 @@ void QgsEmbedLayerDialog::changeProjectFile()
mProjectPath = mProjectFileLineEdit->text();
}

void QgsEmbedLayerDialog::addLegendGroupToTreeWidget( const QDomElement& groupElem, QTreeWidgetItem* parent )
void QgsProjectLayerGroupDialog::addLegendGroupToTreeWidget( const QDomElement& groupElem, QTreeWidgetItem* parent )
{
QDomNodeList groupChildren = groupElem.childNodes();
QDomElement currentChildElem;

if ( groupElem.attribute( "embedded" ) == "1" )
if ( !mShowEmbeddedContent && groupElem.attribute( "embedded" ) == "1" )
{
return;
}
Expand Down Expand Up @@ -192,9 +220,9 @@ void QgsEmbedLayerDialog::addLegendGroupToTreeWidget( const QDomElement& groupEl
}
}

void QgsEmbedLayerDialog::addLegendLayerToTreeWidget( const QDomElement& layerElem, QTreeWidgetItem* parent )
void QgsProjectLayerGroupDialog::addLegendLayerToTreeWidget( const QDomElement& layerElem, QTreeWidgetItem* parent )
{
if ( layerElem.attribute( "embedded" ) == "1" )
if ( !mShowEmbeddedContent && layerElem.attribute( "embedded" ) == "1" )
{
return;
}
Expand All @@ -213,7 +241,7 @@ void QgsEmbedLayerDialog::addLegendLayerToTreeWidget( const QDomElement& layerEl
item->setData( 0, Qt::UserRole + 1, layerElem.firstChildElement( "filegroup" ).firstChildElement( "legendlayerfile" ).attribute( "layerid" ) );
}

void QgsEmbedLayerDialog::on_mTreeWidget_itemSelectionChanged()
void QgsProjectLayerGroupDialog::on_mTreeWidget_itemSelectionChanged()
{
mTreeWidget->blockSignals( true );
QList<QTreeWidgetItem*> items = mTreeWidget->selectedItems();
Expand All @@ -226,7 +254,7 @@ void QgsEmbedLayerDialog::on_mTreeWidget_itemSelectionChanged()
mTreeWidget->blockSignals( false );
}

void QgsEmbedLayerDialog::unselectChildren( QTreeWidgetItem* item )
void QgsProjectLayerGroupDialog::unselectChildren( QTreeWidgetItem* item )
{
if ( !item )
{
Expand All @@ -242,7 +270,7 @@ void QgsEmbedLayerDialog::unselectChildren( QTreeWidgetItem* item )
}
}

void QgsEmbedLayerDialog::on_mButtonBox_accepted()
void QgsProjectLayerGroupDialog::on_mButtonBox_accepted()
{
QSettings s;
QFileInfo fi( mProjectPath );
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/***************************************************************************
qgsembedlayerdialog.h
---------------------
qgsprojectlayergroupdialog.h
----------------------------
begin : June 2011
copyright : (C) 2011 by Marco Hugentobler
email : marco dot hugentobler at sourcepole dot ch
Expand All @@ -12,25 +12,27 @@
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSEMBEDLAYERSDIALOG_H
#define QGSEMBEDLAYERSDIALOG_H
#ifndef QGSPROJECTLAYERGROUPDIALOG_H
#define QGSPROJECTLAYERGROUPDIALOG_H

#include "QDialog"
#include "ui_qgsembedlayerdialogbase.h"
#include "ui_qgsprojectlayergroupdialogbase.h"

class QDomElement;

class QgsEmbedLayerDialog: public QDialog, private Ui::QgsEmbedLayerDialogBase
/**A dialog to select layers and groups from a qgs project*/
class QgsProjectLayerGroupDialog: public QDialog, private Ui::QgsProjectLayerGroupDialogBase
{
Q_OBJECT
public:
QgsEmbedLayerDialog( QWidget * parent = 0, Qt::WindowFlags f = 0 );
~QgsEmbedLayerDialog();
/**Constructor. If a project file is given, the groups/layers are displayed directly and the file selection hidden*/
QgsProjectLayerGroupDialog( QWidget * parent = 0, const QString& projectFile = QString(), Qt::WindowFlags f = 0 );
~QgsProjectLayerGroupDialog();

/**Returns name / projectfiles of groups to embed*/
QList< QPair < QString, QString > > embeddedGroups() const;
/**Returns layer id / projectfiles of single layers to embed*/
QList< QPair < QString, QString > > embeddedLayers() const;
QStringList selectedGroups() const;
QStringList selectedLayerIds() const;
QStringList selectedLayerNames() const;
QString selectedProjectFile() const;

private slots:
void on_mBrowseFileToolButton_clicked();
Expand All @@ -44,6 +46,7 @@ class QgsEmbedLayerDialog: public QDialog, private Ui::QgsEmbedLayerDialogBase
void addLegendLayerToTreeWidget( const QDomElement& layerElem, QTreeWidgetItem* parent = 0 );
void unselectChildren( QTreeWidgetItem* item );
QString mProjectPath;
bool mShowEmbeddedContent;
};

#endif // QGSEMBEDLAYERSDIALOG_H
#endif //QGSPROJECTLAYERGROUPDIALOG_H
116 changes: 116 additions & 0 deletions src/app/qgsprojectproperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#include "qgsprojectproperties.h"

//qgis includes
#include "qgisapp.h"
#include "qgscomposer.h"
#include "qgscontexthelp.h"
#include "qgscoordinatetransform.h"
#include "qgslogger.h"
Expand All @@ -27,6 +29,7 @@
#include "qgsmaplayerregistry.h"
#include "qgsmaprenderer.h"
#include "qgsproject.h"
#include "qgsprojectlayergroupdialog.h"
#include "qgsrenderer.h"
#include "qgssnappingdialog.h"
#include "qgsrasterlayer.h"
Expand Down Expand Up @@ -261,6 +264,22 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas* mapCanvas, QWidget *pa

grpWMSList->setChecked( mWMSList->count() > 0 );

//composer restriction for WMS
values = QgsProject::instance()->readListEntry( "WMSComposerList", "/", &ok );
mWMSComposerGroupBox->setChecked( ok );
if ( ok )
{
mComposerListWidget->addItems( values );
}

//layer restriction for WMS
values = QgsProject::instance()->readListEntry( "WMSRestrictedLayers", "/", &ok );
mLayerRestrictionsGroupBox->setChecked( ok );
if ( ok )
{
mLayerRestrictionsListWidget->addItems( values );
}

bool addWktGeometry = QgsProject::instance()->readBoolEntry( "WMSAddWktGeometry", "/" );
mAddWktGeometryCheckBox->setChecked( addWktGeometry );

Expand Down Expand Up @@ -539,6 +558,36 @@ void QgsProjectProperties::apply()
QgsProject::instance()->removeEntry( "WMSCrsList", "/" );
}

//WMS composer restrictions
if ( mWMSComposerGroupBox->isChecked() )
{
QStringList composerTitles;
for ( int i = 0; i < mComposerListWidget->count(); ++i )
{
composerTitles << mComposerListWidget->item( i )->text();
}
QgsProject::instance()->writeEntry( "WMSComposerList", "/", composerTitles );
}
else
{
QgsProject::instance()->removeEntry( "WMSComposerList", "/" );
}

//WMS layer restrictions
if ( mLayerRestrictionsGroupBox->isChecked() )
{
QStringList layerNames;
for ( int i = 0; i < mLayerRestrictionsListWidget->count(); ++i )
{
layerNames << mLayerRestrictionsListWidget->item( i )->text();
}
QgsProject::instance()->writeEntry( "WMSRestrictedLayers", "/", layerNames );
}
else
{
QgsProject::instance()->removeEntry( "WMSRestrictedLayers", "/" );
}

QgsProject::instance()->writeEntry( "WMSAddWktGeometry", "/", mAddWktGeometryCheckBox->isChecked() );

QString maxWidthText = mMaxWidthLineEdit->text();
Expand Down Expand Up @@ -747,6 +796,73 @@ void QgsProjectProperties::on_pbnWMSSetUsedSRS_clicked()
mWMSList->addItems( crsList.values() );
}

void QgsProjectProperties::on_mAddWMSComposerButton_clicked()
{
QSet<QgsComposer*> projectComposers = QgisApp::instance()->printComposers();
QStringList composerTitles;
QSet<QgsComposer*>::const_iterator cIt = projectComposers.constBegin();
for ( ; cIt != projectComposers.constEnd(); ++cIt )
{
composerTitles << ( *cIt )->title();
}

bool ok;
QString name = QInputDialog::getItem( this, tr( "Select print composer" ), tr( "Composer Title" ), composerTitles, 0, false, &ok );
if ( ok )
{
if ( mComposerListWidget->findItems( name, Qt::MatchExactly ).size() < 1 )
{
mComposerListWidget->addItem( name );
}
}
}

void QgsProjectProperties::on_mRemoveWMSComposerButton_clicked()
{
QListWidgetItem* currentItem = mComposerListWidget->currentItem();
if ( currentItem )
{
delete mComposerListWidget->takeItem( mComposerListWidget->row( currentItem ) );
}
}

void QgsProjectProperties::on_mAddLayerRestrictionButton_clicked()
{
QgsProjectLayerGroupDialog d( this, QgsProject::instance()->fileName() );
d.setWindowTitle( tr( "Select restricted layers and groups" ) );
if ( d.exec() == QDialog::Accepted )
{
QStringList layerNames = d.selectedLayerNames();
QStringList::const_iterator layerIt = layerNames.constBegin();
for ( ; layerIt != layerNames.constEnd(); ++layerIt )
{
if ( mLayerRestrictionsListWidget->findItems( *layerIt, Qt::MatchExactly ).size() < 1 )
{
mLayerRestrictionsListWidget->addItem( *layerIt );
}
}

QStringList groups = d.selectedGroups();
QStringList::const_iterator groupIt = groups.constBegin();
for ( ; groupIt != groups.constEnd(); ++groupIt )
{
if ( mLayerRestrictionsListWidget->findItems( *groupIt, Qt::MatchExactly ).size() < 1 )
{
mLayerRestrictionsListWidget->addItem( *groupIt );
}
}
}
}

void QgsProjectProperties::on_mRemoveLayerRestrictionButton_clicked()
{
QListWidgetItem* currentItem = mLayerRestrictionsListWidget->currentItem();
if ( currentItem )
{
delete mLayerRestrictionsListWidget->takeItem( mLayerRestrictionsListWidget->row( currentItem ) );
}
}

void QgsProjectProperties::on_pbnWFSLayersSelectAll_clicked()
{
for ( int i = 0; i < twWFSLayers->rowCount(); i++ )
Expand Down
4 changes: 4 additions & 0 deletions src/app/qgsprojectproperties.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ class QgsProjectProperties : public QDialog, private Ui::QgsProjectPropertiesBas
void on_pbnWMSAddSRS_clicked();
void on_pbnWMSRemoveSRS_clicked();
void on_pbnWMSSetUsedSRS_clicked();
void on_mAddWMSComposerButton_clicked();
void on_mRemoveWMSComposerButton_clicked();
void on_mAddLayerRestrictionButton_clicked();
void on_mRemoveLayerRestrictionButton_clicked();

/*!
* Slots to select/unselect all the WFS layers
Expand Down
13 changes: 10 additions & 3 deletions src/app/qgsrasterlayerproperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1372,7 +1372,15 @@ void QgsRasterLayerProperties::pixelSelected( const QgsPoint& canvasPoint )
if ( mMapCanvas && mPixelSelectorTool )
{
mMapCanvas->unsetMapTool( mPixelSelectorTool );
QMap< int, void *> myPixelMap = mRasterLayer->dataProvider()->identify( mMapCanvas->mapRenderer()->mapToLayerCoordinates( mRasterLayer, canvasPoint ) );

QgsPoint myPoint = mMapCanvas->mapRenderer()->mapToLayerCoordinates( mRasterLayer, canvasPoint );

QgsRectangle myExtent = mMapCanvas->mapRenderer()->mapToLayerCoordinates( mRasterLayer, mMapCanvas->extent() );
double mapUnitsPerPixel = mMapCanvas->mapUnitsPerPixel();
int myWidth = mMapCanvas->extent().width() / mapUnitsPerPixel;
int myHeight = mMapCanvas->extent().height() / mapUnitsPerPixel;

QMap<int, QVariant> myPixelMap = mRasterLayer->dataProvider()->identify( myPoint, QgsRasterDataProvider::IdentifyFormatValue, myExtent, myWidth, myHeight );

QList<int> bands = renderer->usesBands();

Expand All @@ -1383,8 +1391,7 @@ void QgsRasterLayerProperties::pixelSelected( const QgsPoint& canvasPoint )
int bandNo = bands.value( i );
if ( myPixelMap.count( bandNo ) == 1 )
{
void * data = myPixelMap.value( bandNo );
double value = provider->readValue( data, provider->dataType( bandNo ), 0 );
double value = myPixelMap.value( bandNo ).toDouble();
QgsDebugMsg( QString( "value = %1" ).arg( value, 0, 'g', 17 ) );

if ( provider->isNoDataValue( bandNo, value ) )
Expand Down
39 changes: 26 additions & 13 deletions src/app/qgsvectorlayerproperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,19 +195,6 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
mDiagramFrame->setLayout( new QVBoxLayout( mDiagramFrame ) );
mDiagramFrame->layout()->addWidget( diagramPropertiesDialog );

//for each overlay plugin create a new tab
int position;
QList<QgsVectorOverlayPlugin*> overlayPluginList = overlayPlugins();
QList<QgsVectorOverlayPlugin*>::const_iterator it = overlayPluginList.constBegin();

for ( ; it != overlayPluginList.constEnd(); ++it )
{
QgsApplyDialog* d = ( *it )->dialog( lyr );
position = tabWidget->insertTab( tabWidget->count(), qobject_cast<QDialog*>( d ), QgsApplication::getThemeIcon( "propertyicons/diagram.png" ), tr( "Overlay" ) );
tabWidget->setCurrentIndex( position ); //ugly, but otherwise the properties dialog is a mess
mOverlayDialogs.push_back( d );
}

//layer title and abstract
if ( layer )
{
Expand Down Expand Up @@ -266,6 +253,8 @@ void QgsVectorLayerProperties::loadRows()
tblAttributes->setHorizontalHeaderItem( attrPrecCol, new QTableWidgetItem( tr( "Precision" ) ) );
tblAttributes->setHorizontalHeaderItem( attrCommentCol, new QTableWidgetItem( tr( "Comment" ) ) );
tblAttributes->setHorizontalHeaderItem( attrEditTypeCol, new QTableWidgetItem( tr( "Edit widget" ) ) );
tblAttributes->setHorizontalHeaderItem( attrWMSCol, new QTableWidgetItem( "WMS" ) );
tblAttributes->setHorizontalHeaderItem( attrWFSCol, new QTableWidgetItem( "WFS" ) );
tblAttributes->setHorizontalHeaderItem( attrAliasCol, new QTableWidgetItem( tr( "Alias" ) ) );

tblAttributes->horizontalHeader()->setResizeMode( 1, QHeaderView::Stretch );
Expand Down Expand Up @@ -301,6 +290,16 @@ void QgsVectorLayerProperties::setRow( int row, int idx, const QgsField &field )

//set the alias for the attribute
tblAttributes->setItem( row, attrAliasCol, new QTableWidgetItem( layer->attributeAlias( idx ) ) );

//published WMS/WFS attributes
QTableWidgetItem* wmsAttrItem = new QTableWidgetItem();
wmsAttrItem->setCheckState( layer->excludeAttributesWMS().contains( field.name() ) ? Qt::Unchecked : Qt::Checked );
wmsAttrItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
tblAttributes->setItem( row, attrWMSCol, wmsAttrItem );
QTableWidgetItem* wfsAttrItem = new QTableWidgetItem();
wfsAttrItem->setCheckState( layer->excludeAttributesWFS().contains( field.name() ) ? Qt::Unchecked : Qt::Checked );
wfsAttrItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
tblAttributes->setItem( row, attrWFSCol, wfsAttrItem );
}

void QgsVectorLayerProperties::attributeTypeDialog( )
Expand Down Expand Up @@ -757,6 +756,8 @@ void QgsVectorLayerProperties::apply()
layer->enableLabels( labelCheckBox->isChecked() );
layer->setLayerName( displayName() );

QSet<QString> excludeAttributesWMS, excludeAttributesWFS;

for ( int i = 0; i < tblAttributes->rowCount(); i++ )
{
int idx = tblAttributes->item( i, attrIdCol )->text().toInt();
Expand Down Expand Up @@ -815,8 +816,20 @@ void QgsVectorLayerProperties::apply()
case QgsVectorLayer::UuidGenerator:
break;
}

if ( tblAttributes->item( i, attrWMSCol )->checkState() == Qt::Unchecked )
{
excludeAttributesWMS.insert( tblAttributes->item( i, attrNameCol )->text() );
}
if ( tblAttributes->item( i, attrWFSCol )->checkState() == Qt::Unchecked )
{
excludeAttributesWFS.insert( tblAttributes->item( i, attrNameCol )->text() );
}
}

layer->setExcludeAttributesWMS( excludeAttributesWMS );
layer->setExcludeAttributesWFS( excludeAttributesWFS );

if ( layer->isUsingRendererV2() )
{
QgsRendererV2PropertiesDialog* dlg =
Expand Down
2 changes: 2 additions & 0 deletions src/app/qgsvectorlayerproperties.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope
attrCommentCol,
attrEditTypeCol,
attrAliasCol,
attrWMSCol,
attrWFSCol,
attrColCount,
};

Expand Down
46 changes: 46 additions & 0 deletions src/core/qgsvectorlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3236,6 +3236,28 @@ bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage
}
}

//Attributes excluded from WMS and WFS
mExcludeAttributesWMS.clear();
QDomNode excludeWMSNode = node.namedItem( "excludeAttributesWMS" );
if ( !excludeWMSNode.isNull() )
{
QDomNodeList attributeNodeList = excludeWMSNode.toElement().elementsByTagName( "attribute" );
for ( int i = 0; i < attributeNodeList.size(); ++i )
{
mExcludeAttributesWMS.insert( attributeNodeList.at( i ).toElement().text() );
}
}

mExcludeAttributesWFS.clear();
QDomNode excludeWFSNode = node.namedItem( "excludeAttributesWFS" );
if ( !excludeWFSNode.isNull() )
{
QDomNodeList attributeNodeList = excludeWFSNode.toElement().elementsByTagName( "attribute" );
for ( int i = 0; i < attributeNodeList.size(); ++i )
{
mExcludeAttributesWFS.insert( attributeNodeList.at( i ).toElement().text() );
}
}
return true;
}

Expand Down Expand Up @@ -3451,6 +3473,30 @@ bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString&
node.appendChild( aliasElem );
}

//exclude attributes WMS
QDomElement excludeWMSElem = doc.createElement( "excludeAttributesWMS" );
QSet<QString>::const_iterator attWMSIt = mExcludeAttributesWMS.constBegin();
for ( ; attWMSIt != mExcludeAttributesWMS.constEnd(); ++attWMSIt )
{
QDomElement attrElem = doc.createElement( "attribute" );
QDomText attrText = doc.createTextNode( *attWMSIt );
attrElem.appendChild( attrText );
excludeWMSElem.appendChild( attrElem );
}
node.appendChild( excludeWMSElem );

//exclude attributes WFS
QDomElement excludeWFSElem = doc.createElement( "excludeAttributesWFS" );
QSet<QString>::const_iterator attWFSIt = mExcludeAttributesWFS.constBegin();
for ( ; attWFSIt != mExcludeAttributesWFS.constEnd(); ++attWFSIt )
{
QDomElement attrElem = doc.createElement( "attribute" );
QDomText attrText = doc.createTextNode( *attWFSIt );
attrElem.appendChild( attrText );
excludeWFSElem.appendChild( attrElem );
}
node.appendChild( excludeWFSElem );

// add attribute actions
mActions->writeXML( node, doc );

Expand Down
11 changes: 11 additions & 0 deletions src/core/qgsvectorlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,12 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
@note added in version 1.2*/
QString attributeDisplayName( int attributeIndex ) const;

const QSet<QString>& excludeAttributesWMS() const { return mExcludeAttributesWMS; }
void setExcludeAttributesWMS( const QSet<QString>& att ) { mExcludeAttributesWMS = att; }

const QSet<QString>& excludeAttributesWFS() const { return mExcludeAttributesWFS; }
void setExcludeAttributesWFS( const QSet<QString>& att ) { mExcludeAttributesWFS = att; }

/** delete an attribute field (but does not commit it) */
bool deleteAttribute( int attr );

Expand Down Expand Up @@ -966,6 +972,11 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
/**Map that stores the aliases for attributes. Key is the attribute name and value the alias for that attribute*/
QMap< QString, QString > mAttributeAliasMap;

/**Attributes which are not published in WMS*/
QSet<QString> mExcludeAttributesWMS;
/**Attributes which are not published in WFS*/
QSet<QString> mExcludeAttributesWFS;

/** max field index */
int mMaxUpdatedIndex;

Expand Down
8 changes: 0 additions & 8 deletions src/core/raster/qgspalettedrasterrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,6 @@ QgsRasterBlock * QgsPalettedRasterRenderer::block( int bandNo, QgsRectangle con
alphaBlock = inputBlock;
}

//create image
//QImage img( width, height, QImage::Format_ARGB32_Premultiplied );
//if ( img.isNull() )
//{
//QgsDebugMsg( "Could not create QImage" );
//VSIFree( rasterData );
//return 0;
//}
if ( !outputBlock->reset( QgsRasterBlock::ARGB32_Premultiplied, width, height ) )
{
delete inputBlock;
Expand Down
85 changes: 83 additions & 2 deletions src/core/raster/qgsrasterblock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ bool QgsRasterBlock::reset( DataType theDataType, int theWidth, int theHeight, d
if ( typeIsNumeric( theDataType ) )
{
QgsDebugMsg( "Numeric type" );
int tSize = typeSize( theDataType ) / 8;
size_t tSize = typeSize( theDataType );
QgsDebugMsg( QString( "allocate %1 bytes" ).arg( tSize * theWidth * theHeight ) );
mData = QgsMalloc( tSize * theWidth * theHeight );
if ( mData == 0 )
{
Expand Down Expand Up @@ -341,6 +342,36 @@ bool QgsRasterBlock::setColor( size_t index, QRgb color )
return true;
}

bool QgsRasterBlock::setIsNoData( int row, int column )
{
return setIsNoData(( size_t )row*column );
}

bool QgsRasterBlock::setIsNoData( size_t index )
{
return setValue( index, mNoDataValue );
}

bool QgsRasterBlock::setIsNoData()
{
if ( !mData )
{
QgsDebugMsg( "Data block not allocated" );
return false;
}

int dataTypeSize = typeSize( mDataType );
QByteArray noDataByteArray = valueBytes( mDataType, mNoDataValue );

char *nodata = noDataByteArray.data();
for ( size_t i = 0; i < ( size_t )mWidth*mHeight; i++ )
{
memcpy(( char* )mData + i*dataTypeSize, nodata, dataTypeSize );
}

return true;
}

char * QgsRasterBlock::bits( size_t index )
{
// Not testing type to avoid too much overhead because this method is called per pixel
Expand Down Expand Up @@ -481,7 +512,7 @@ QString QgsRasterBlock::printValue( double value )

void * QgsRasterBlock::convert( void *srcData, QgsRasterBlock::DataType srcDataType, QgsRasterBlock::DataType destDataType, size_t size )
{
int destDataTypeSize = typeSize( destDataType ) / 8;
int destDataTypeSize = typeSize( destDataType );
void *destData = QgsMalloc( destDataTypeSize * size );
for ( size_t i = 0; i < size; i++ )
{
Expand All @@ -492,3 +523,53 @@ void * QgsRasterBlock::convert( void *srcData, QgsRasterBlock::DataType srcDataT
}
return destData;
}

QByteArray QgsRasterBlock::valueBytes( DataType theDataType, double theValue )
{
size_t size = QgsRasterBlock::typeSize( theDataType );
QByteArray ba;
ba.resize(( int )size );
char * data = ba.data();
unsigned char uc;
unsigned short us;
short s;
unsigned int ui;
int i;
float f;
double d;
// TODO: define correct data types (typedef) like in GDAL
switch ( theDataType )
{
case QgsRasterBlock::Byte:
uc = ( unsigned char )theValue;
memcpy( data, &uc, size );
break;
case QgsRasterBlock::UInt16:
us = ( unsigned short )theValue;
memcpy( data, &us, size );
break;
case QgsRasterBlock::Int16:
s = ( short )theValue;
memcpy( data, &s, size );
break;
case QgsRasterBlock::UInt32:
ui = ( unsigned int )theValue;
memcpy( data, &ui, size );
break;
case QgsRasterBlock::Int32:
i = ( int )theValue;
memcpy( data, &i, size );
break;
case QgsRasterBlock::Float32:
f = ( float )theValue;
memcpy( data, &f, size );
break;
case QgsRasterBlock::Float64:
d = ( double )theValue;
memcpy( data, &d, size );
break;
default:
QgsDebugMsg( "Data type is not supported" );
}
return ba;
}
33 changes: 26 additions & 7 deletions src/core/raster/qgsrasterblock.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,41 +92,43 @@ class CORE_EXPORT QgsRasterBlock
//bool isValid() const { return mValid; }
bool isEmpty() const;

// Return data type size in bytes
static int typeSize( int dataType )
{
// Modified and extended copy from GDAL
switch ( dataType )
{
case Byte:
return 8;
return 1;

case UInt16:
case Int16:
return 16;
return 2;

case UInt32:
case Int32:
case Float32:
case CInt16:
return 32;
return 4;

case Float64:
case CInt32:
case CFloat32:
return 64;
return 8;

case CFloat64:
return 128;
return 16;

case ARGB32:
case ARGB32_Premultiplied:
return 32;
return 4;

default:
return 0;
}
}

// Data type in bytes
int dataTypeSize( int bandNo ) const
{
Q_UNUSED( bandNo );
Expand Down Expand Up @@ -165,6 +167,9 @@ class CORE_EXPORT QgsRasterBlock
* @return true if value is nodata */
bool isNoDataValue( double value ) const;

// get byte array representing no data value
static QByteArray valueBytes( DataType theDataType, double theValue );

/** \brief Read a single value
* @param row row index
* @param column column index
Expand Down Expand Up @@ -218,6 +223,21 @@ class CORE_EXPORT QgsRasterBlock
* @return true on success */
bool setColor( int row, int column, QRgb color );

/** \brief Set no data on pixel
* @param row row index
* @param column column index
* @return true on success */
bool setIsNoData( int row, int column );

/** \brief Set no data on pixel
* @param index data matrix index
* @return true on success */
bool setIsNoData( size_t index );

/** \brief Set the whole block to no data
* @return true on success */
bool setIsNoData( );

/** \brief Set color on index (indexed line by line)
* @param index data matrix index
* @param color the color to be set, QRgb value
Expand Down Expand Up @@ -289,7 +309,6 @@ class CORE_EXPORT QgsRasterBlock
static QImage::Format imageFormat( QgsRasterBlock::DataType theDataType );
static DataType dataType( QImage::Format theFormat );


// Valid
//bool isValid;

Expand Down
537 changes: 226 additions & 311 deletions src/core/raster/qgsrasterdataprovider.cpp

Large diffs are not rendered by default.

94 changes: 37 additions & 57 deletions src/core/raster/qgsrasterdataprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
class QImage;
class QgsPoint;
class QByteArray;
#include <QVariant>

#define TINY_VALUE std::numeric_limits<double>::epsilon() * 20
#define RASTER_HISTOGRAM_BINS 256
Expand Down Expand Up @@ -68,7 +69,11 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
Histogram = 1 << 5,
Size = 1 << 6, // has fixed source type
Create = 1 << 7, //create new datasets
Remove = 1 << 8 //delete datasets
Remove = 1 << 8, //delete datasets
IdentifyValue = 1 << 9,
IdentifyText = 1 << 10,
IdentifyHtml = 1 << 11,
IdentifyFeature = 1 << 12 // WMS GML -> feature
};

// This is modified copy of GDALColorInterp
Expand All @@ -95,6 +100,17 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
/*! Max current value */ ColorInterpretationMax = 17
};

enum IdentifyFormat
{
IdentifyFormatValue = 0,
IdentifyFormatText = 1,
IdentifyFormatHtml = 1 << 1,
// In future it should be possible to get from GetFeatureInfo (WMS) in GML
// vector features. It is possible to use a user type with QVariant if
// a class is declared with Q_DECLARE_METATYPE
IdentifyFormatFeature = 1 << 2
};

// Progress types
enum RasterProgressType
{
Expand Down Expand Up @@ -179,19 +195,12 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
// TODO: Get the file masks supported by this provider, suitable for feeding into the file open dialog box

/** Returns data type for the band specified by number */
virtual QgsRasterBlock::DataType dataType( int bandNo ) const
{
return srcDataType( bandNo );
}
virtual QgsRasterBlock::DataType dataType( int bandNo ) const = 0;

/** Returns source data type for the band specified by number,
* source data type may be shorter than dataType
*/
virtual QgsRasterBlock::DataType srcDataType( int bandNo ) const
{
Q_UNUSED( bandNo );
return QgsRasterBlock::UnknownDataType;
}
virtual QgsRasterBlock::DataType srcDataType( int bandNo ) const = 0;

/** Returns data type for the band specified by number */
virtual int colorInterpretation( int theBandNo ) const
Expand Down Expand Up @@ -289,15 +298,8 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
virtual void readBlock( int bandNo, QgsRectangle const & viewExtent, int width, int height, void *data )
{ Q_UNUSED( bandNo ); Q_UNUSED( viewExtent ); Q_UNUSED( width ); Q_UNUSED( height ); Q_UNUSED( data ); }

/** read block of data using give extent and size */
// @note not available in python bindings
//virtual void readBlock( int bandNo, QgsRectangle const & viewExtent, int width, int height, QgsCoordinateReferenceSystem theSrcCRS, QgsCoordinateReferenceSystem theDestCRS, void *data );

/** Read block of data using given extent and size. */
// @note not available in python bindings
//virtual void *readBlock( int bandNo, QgsRectangle const & extent, int width, int height );

virtual QgsRasterBlock *block( int bandNo, const QgsRectangle &extent, int width, int height );
virtual QgsRasterBlock *block( int theBandNo, const QgsRectangle &theExtent, int theWidth, int theHeight );

/* Read a value from a data block at a given index. */
virtual double readValue( void *data, int type, int index );
Expand Down Expand Up @@ -444,47 +446,28 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
*/
virtual QString metadata() = 0;

/** \brief Identify raster value(s) found on the point position
* @param point coordinates in data source CRS
* @return list of pointers to data blocks for all bands,
* caller is responsible to free the allocated memory,
* readValue() may be used to get values
* @note theBinCount, theMinimun and theMaximum not optional in python bindings
*/
// TODO: Consider QVariant or similar instead of void*
virtual QMap<int, void *> identify( const QgsPoint & point );

/**
* \brief Identify details from a server (e.g. WMS) from the last screen update
*
* \param[in] point The pixel coordinate (as it was displayed locally on screen)
*
* \return A text document containing the return from the WMS server
*
* \note WMS Servers prefer to receive coordinates in image space, therefore
* this function expects coordinates in that format.
/** \brief Identify raster value(s) found on the point position. The context
* parameters theExtent, theWidth and theHeigh are important to identify
* on the same zoom level as a displayed map and to do effective
* caching (WCS). If context params are not specified the highest
* resolution is used. capabilities() may be used to test if format
* is supported by provider. Values are set to 'no data' or empty string
* if point is outside data source extent.
*
* \note The arbitraryness of the returned document is enforced by WMS standards
* up to at least v1.3.0
* @param thePoint coordinates in data source CRS
* @param theFormat result format
* @param theExtent context extent
* @param theWidth context width
* @param theHeight context height
* @return map of values for all bands, keys are band numbers (from 1), empty
* if failed
*/
virtual QString identifyAsText( const QgsPoint& point ) = 0;
virtual QMap<int, QVariant> identify( const QgsPoint & thePoint, IdentifyFormat theFormat, const QgsRectangle &theExtent = QgsRectangle(), int theWidth = 0, int theHeight = 0 );

/**
* \brief Identify details from a server (e.g. WMS) from the last screen update
*
* \param[in] point The pixel coordinate (as it was displayed locally on screen)
*
* \return A html document containing the return from the WMS server
*
* \note WMS Servers prefer to receive coordinates in image space, therefore
* this function expects coordinates in that format.
*
* \note The arbitraryness of the returned document is enforced by WMS standards
* up to at least v1.3.0
*
* \note added in 1.5
*/
virtual QString identifyAsHtml( const QgsPoint& point ) = 0;

QMap<QString, QString> identify( const QgsPoint & thePoint, const QgsRectangle &theExtent = QgsRectangle(), int theWidth = 0, int theHeight = 0 );

/**
* \brief Returns the caption error text for the last error in this provider
Expand Down Expand Up @@ -528,9 +511,6 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
static QString makeTableCell( const QString & value );
static QString makeTableCells( const QStringList & values );

/** \brief Set null value in char */
QByteArray noValueBytes( int theBandNo );

/** Time stamp of data source in the moment when data/metadata were loaded by provider */
virtual QDateTime timestamp() const { return mTimestamp; }

Expand Down
16 changes: 8 additions & 8 deletions src/core/raster/qgsrasterfilewriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeDataRaster(
{
iter->startRasterRead( i, nCols, nRows, outputExtent );
// TODO: no need to alloc memory, change to readBlock() returning the allocated block
//blockList.push_back( VSIMalloc( dataTypeSize * mMaxTileWidth * mMaxTileHeight ) );
//blockList.push_back( QgsMalloc( dataTypeSize * mMaxTileWidth * mMaxTileHeight ) );
blockList.push_back( 0 );
// TODO - fix segfault here when using tiles+vrt (reported by Etienne)
destProvider->setNoDataValue( i, destNoDataValueList.value( i - 1 ) );
Expand Down Expand Up @@ -373,7 +373,7 @@ QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeDataRaster(
// TODO: this conversion should go to QgsRasterDataProvider::write with additional input data type param
//void *destData = QgsRasterBlock::convert( blockList[i-1], srcProvider->dataType( i ), destDataType, iterCols * iterRows );
//destBlockList.push_back( destData );
//CPLFree( blockList[i-1] );
//QgsFree( blockList[i-1] );
blockList[i-1]->convert( destDataType );
destBlockList.push_back( blockList[i-1] );
}
Expand Down Expand Up @@ -437,11 +437,11 @@ QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeImageRaster( QgsRaste
iter->setMaximumTileWidth( mMaxTileWidth );
iter->setMaximumTileHeight( mMaxTileHeight );

//void* data = VSIMalloc( QgsRasterBlock::typeSize( inputDataType ) / 8 * mMaxTileWidth * mMaxTileHeight );
void* redData = VSIMalloc( mMaxTileWidth * mMaxTileHeight );
void* greenData = VSIMalloc( mMaxTileWidth * mMaxTileHeight );
void* blueData = VSIMalloc( mMaxTileWidth * mMaxTileHeight );
void* alphaData = VSIMalloc( mMaxTileWidth * mMaxTileHeight );
//void* data = QgsMalloc( QgsRasterBlock::typeSize( inputDataType ) * mMaxTileWidth * mMaxTileHeight );
void* redData = QgsMalloc( mMaxTileWidth * mMaxTileHeight );
void* greenData = QgsMalloc( mMaxTileWidth * mMaxTileHeight );
void* blueData = QgsMalloc( mMaxTileWidth * mMaxTileHeight );
void* alphaData = QgsMalloc( mMaxTileWidth * mMaxTileHeight );
QgsRectangle mapRect;
int iterLeft = 0, iterTop = 0, iterCols = 0, iterRows = 0;
int fileIndex = 0;
Expand Down Expand Up @@ -547,7 +547,7 @@ QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeImageRaster( QgsRaste
}

delete destProvider;
CPLFree( redData ); CPLFree( greenData ); CPLFree( blueData ); CPLFree( alphaData );
QgsFree( redData ); QgsFree( greenData ); QgsFree( blueData ); QgsFree( alphaData );

if ( progressDialog )
{
Expand Down
9 changes: 4 additions & 5 deletions src/core/raster/qgsrasteriterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void QgsRasterIterator::startRasterRead( int bandNumber, int nCols, int nRows, c
pInfo.nRows = nRows;
pInfo.currentCol = 0;
pInfo.currentRow = 0;
pInfo.data = 0;
pInfo.block = 0;
pInfo.prj = 0;
mRasterPartInfos.insert( bandNumber, pInfo );
}
Expand Down Expand Up @@ -73,8 +73,8 @@ bool QgsRasterIterator::readNextRasterPart( int bandNumber,
}

//remove last data block
// TODO: data are released somewhere else (check)
//free( pInfo.data );
// TODO: block is released somewhere else (check)
//delete pInfo.block;
pInfo.block = 0;
delete pInfo.prj;
pInfo.prj = 0;
Expand Down Expand Up @@ -129,8 +129,7 @@ void QgsRasterIterator::removePartInfo( int bandNumber )
if ( partIt != mRasterPartInfos.end() )
{
RasterPartInfo& pInfo = partIt.value();
//CPLFree( pInfo.data );
free( pInfo.data );
delete pInfo.block;
delete pInfo.prj;
mRasterPartInfos.remove( bandNumber );
}
Expand Down
1 change: 0 additions & 1 deletion src/core/raster/qgsrasteriterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ class CORE_EXPORT QgsRasterIterator
int currentRow;
int nCols;
int nRows;
void* data; //data (can be in oversampled/undersampled resolution)
QgsRasterBlock *block;
QgsRasterProjector* prj; //raster projector (or 0 if no reprojection is done)
};
Expand Down
6 changes: 4 additions & 2 deletions src/core/raster/qgsrasterlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,7 @@ bool QgsRasterLayer::hasStatistics( int theBandNo )
* @param theResults QMap to hold the pixel values at thePoint for each layer in the raster file
* @return False if WMS layer and true otherwise
*/
#if 0
bool QgsRasterLayer::identify( const QgsPoint& thePoint, QMap<QString, QString>& theResults )
{
theResults.clear();
Expand Down Expand Up @@ -1026,6 +1027,7 @@ QString QgsRasterLayer::identifyAsHtml( const QgsPoint& thePoint )

return mDataProvider->identifyAsHtml( thePoint );
}
#endif

/**
* @note Note implemented yet
Expand Down Expand Up @@ -2819,7 +2821,7 @@ QString QgsRasterLayer::projectionWkt()
#if 0
void *QgsRasterLayer::readData( int bandNo, QgsRasterViewPort *viewPort )
{
int size = mDataProvider->dataTypeSize( bandNo ) / 8;
int size = mDataProvider->dataTypeSize( bandNo );

#if 0
QgsDebugMsg( "calling RasterIO with " +
Expand All @@ -2830,7 +2832,7 @@ void *QgsRasterLayer::readData( int bandNo, QgsRasterViewPort *viewPort )
", dest size: " + QString::number( viewPort->drawableAreaXDim ) +
", " + QString::number( viewPort->drawableAreaYDim ) );
#endif
void *data = VSIMalloc( size * viewPort->drawableAreaXDim * viewPort->drawableAreaYDim );
void *data = QgsMalloc( size * viewPort->drawableAreaXDim * viewPort->drawableAreaYDim );

/* Abort if out of memory */
if ( data == NULL )
Expand Down
8 changes: 4 additions & 4 deletions src/core/raster/qgsrasterlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -474,20 +474,20 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
bool hasCompatibleSymbology( const QgsMapLayer& theOther ) const;

/** \brief Identify raster value(s) found on the point position */
bool identify( const QgsPoint & point, QMap<QString, QString>& results );
//bool identify( const QgsPoint & point, QMap<QString, QString>& results );

/** \brief Identify raster value(s) found on the point position
* @note available in python bindings as identifyMap
*/
bool identify( const QgsPoint & point, QMap<int, QString>& results );
//bool identify( const QgsPoint & point, QMap<int, QString>& results );

/** \brief Identify arbitrary details from the WMS server found on the point position */
QString identifyAsText( const QgsPoint & point );
//QString identifyAsText( const QgsPoint & point );

/** \brief Identify arbitrary details from the WMS server found on the point position
* @note added in 1.5
*/
QString identifyAsHtml( const QgsPoint & point );
//QString identifyAsHtml( const QgsPoint & point );

/** \brief Currently returns always false */
bool isEditable() const;
Expand Down
2 changes: 1 addition & 1 deletion src/core/raster/qgsrasterprojector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ QgsRasterBlock * QgsRasterProjector::block( int bandNo, QgsRectangle const & ex
return outputBlock;
}

size_t pixelSize = QgsRasterBlock::typeSize( mInput->dataType( bandNo ) ) / 8;
size_t pixelSize = QgsRasterBlock::typeSize( mInput->dataType( bandNo ) );

if ( !outputBlock->reset( QgsRasterBlock::ARGB32_Premultiplied, width, height ) )
{
Expand Down
6 changes: 3 additions & 3 deletions src/gui/raster/qgsmultibandcolorrendererwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ QgsMultiBandColorRendererWidget::QgsMultiBandColorRendererWidget( QgsRasterLayer
mMinMaxWidget = new QgsRasterMinMaxWidget( layer, this );
mMinMaxWidget->setExtent( extent );
layout()->addWidget( mMinMaxWidget );
connect( mMinMaxWidget, SIGNAL( load( int, double, double ) ),
this, SLOT( loadMinMax( int, double, double ) ) );
connect( mMinMaxWidget, SIGNAL( load( int, double, double, int ) ),
this, SLOT( loadMinMax( int, double, double, int ) ) );

connect( mRedBandComboBox, SIGNAL( currentIndexChanged( int ) ),
this, SLOT( onBandChanged( int ) ) );
Expand Down Expand Up @@ -191,7 +191,7 @@ void QgsMultiBandColorRendererWidget::onBandChanged( int index )
mMinMaxWidget->setBands( myBands );
}

void QgsMultiBandColorRendererWidget::loadMinMax( int theBandNo, double theMin, double theMax )
void QgsMultiBandColorRendererWidget::loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin )
{
QgsDebugMsg( QString( "theBandNo = %1 theMin = %2 theMax = %3" ).arg( theBandNo ).arg( theMin ).arg( theMax ) );

Expand Down
2 changes: 1 addition & 1 deletion src/gui/raster/qgsmultibandcolorrendererwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class GUI_EXPORT QgsMultiBandColorRendererWidget: public QgsRasterRendererWidget
int selectedBand( int index = 0 );

public slots:
void loadMinMax( int theBandNo, double theMin, double theMax );
void loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin );

private slots:
//void on_mLoadPushButton_clicked();
Expand Down
7 changes: 5 additions & 2 deletions src/mapserver/qgsconfigparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,11 @@ class QgsConfigParser
Default implementation returns an empty map*/
virtual QMap< QString, QMap< int, QString > > layerAliasInfo() const { return QMap< QString, QMap<int, QString> > (); }

/**Returns information about vector attributes with hidden edit type. Key is layer id, value is a set containing the names of the hidden attributes*/
virtual QMap< QString, QSet<QString> > hiddenAttributes() const { return QMap< QString, QSet<QString> >(); }
/**Returns attributes excluded from WMS publication. Key is layer id, value is a set containing the names of the hidden attributes*/
virtual QMap< QString, QSet<QString> > wmsExcludedAttributes() const { return QMap< QString, QSet<QString> >(); }

/**Returns attributes excluded from WFS publication. Key is layer id, value is a set containing the names of the hidden attributes*/
virtual QMap< QString, QSet<QString> > wfsExcludedAttributes() const { return QMap< QString, QSet<QString> >(); }

/**Creates a print composition, usually for a GetPrint request. Replaces map and label parameters*/
QgsComposition* createPrintComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, const QMap< QString, QString >& parameterMap ) const;
Expand Down
246 changes: 218 additions & 28 deletions src/mapserver/qgsprojectparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ QgsProjectParser::QgsProjectParser( QDomDocument* xmlDoc, const QString& filePat
mLegendGroupElements.push_back( groupNodeList.at( i ).toElement() );
}
}

mRestrictedLayers = restrictedLayers();
}
}

Expand Down Expand Up @@ -208,7 +210,7 @@ void QgsProjectParser::describeFeatureType( const QString& aTypeName, QDomElemen

QStringList wfsLayersId = wfsLayers();
QMap< QString, QMap< int, QString > > aliasInfo = layerAliasInfo();
QMap< QString, QSet<QString> > hiddenAttrs = hiddenAttributes();
QMap< QString, QSet<QString> > excludedAttrs = wfsExcludedAttributes();

foreach ( const QDomElement &elem, mProjectLayerElements )
{
Expand All @@ -235,11 +237,11 @@ void QgsProjectParser::describeFeatureType( const QString& aTypeName, QDomElemen
}

//hidden attributes for this layer
QSet<QString> layerHiddenAttributes;
QMap< QString, QSet<QString> >::const_iterator hiddenIt = hiddenAttrs.find( mLayer->id() );
if ( hiddenIt != hiddenAttrs.constEnd() )
QSet<QString> layerExcludedAttributes;
QMap< QString, QSet<QString> >::const_iterator exclIt = excludedAttrs.find( mLayer->id() );
if ( exclIt != excludedAttrs.constEnd() )
{
layerHiddenAttributes = hiddenIt.value();
layerExcludedAttributes = exclIt.value();
}

QString typeName = layer->name();
Expand Down Expand Up @@ -314,7 +316,7 @@ void QgsProjectParser::describeFeatureType( const QString& aTypeName, QDomElemen

QString attributeName = it.value().name();
//skip attribute if it has edit type 'hidden'
if ( layerHiddenAttributes.contains( attributeName ) )
if ( layerExcludedAttributes.contains( attributeName ) )
{
continue;
}
Expand Down Expand Up @@ -367,6 +369,10 @@ void QgsProjectParser::addLayers( QDomDocument &doc,
{
layerElem.setAttribute( "queryable", "1" );
QString name = currentChildElem.attribute( "name" );
if ( mRestrictedLayers.contains( name ) ) //unpublished group
{
continue;
}
QDomElement nameElem = doc.createElement( "Name" );
QDomText nameText = doc.createTextNode( name );
nameElem.appendChild( nameText );
Expand Down Expand Up @@ -434,6 +440,10 @@ void QgsProjectParser::addLayers( QDomDocument &doc,
continue;
}

if ( mRestrictedLayers.contains( currentLayer->name() ) ) //unpublished layer
{
continue;
}
if ( nonIdentifiableLayers.contains( currentLayer->id() ) )
{
layerElem.setAttribute( "queryable", "0" );
Expand Down Expand Up @@ -665,6 +675,12 @@ QList<QgsMapLayer*> QgsProjectParser::mapLayerFromStyle( const QString& lName, c
Q_UNUSED( styleName );
QList<QgsMapLayer*> layerList;

//first check if the layer name refers an unpublished layer / group
if ( mRestrictedLayers.contains( lName ) )
{
return layerList;
}

if ( !mXMLDoc )
{
return layerList;
Expand Down Expand Up @@ -1037,34 +1053,46 @@ QMap< QString, QMap< int, QString > > QgsProjectParser::layerAliasInfo() const
return resultMap;
}

QMap< QString, QSet<QString> > QgsProjectParser::hiddenAttributes() const
QMap< QString, QSet<QString> > QgsProjectParser::wmsExcludedAttributes() const
{
QMap< QString, QSet<QString> > resultMap;
QList<QDomElement>::const_iterator layerIt = mProjectLayerElements.constBegin();
for ( ; layerIt != mProjectLayerElements.constEnd(); ++layerIt )
{
QDomNodeList editTypesList = layerIt->elementsByTagName( "edittypes" );
if ( editTypesList.size() > 0 )
QDomElement excludeWMSElem = layerIt->firstChildElement( "excludeAttributesWMS" );
QDomNodeList attributeNodeList = excludeWMSElem.elementsByTagName( "attribute" );
if ( attributeNodeList.size() > 0 )
{
QSet< QString > hiddenAttributes;
QDomElement editTypesElem = editTypesList.at( 0 ).toElement();
QDomNodeList editTypeList = editTypesElem.elementsByTagName( "edittype" );
for ( int i = 0; i < editTypeList.size(); ++i )
QSet<QString> layerExcludedAttributes;
for ( int i = 0; i < attributeNodeList.size(); ++i )
{
QDomElement editTypeElem = editTypeList.at( i ).toElement();
if ( editTypeElem.attribute( "type" ).toInt() == QgsVectorLayer::Hidden )
{
hiddenAttributes.insert( editTypeElem.attribute( "name" ) );
}
layerExcludedAttributes.insert( attributeNodeList.at( i ).toElement().text() );
}
resultMap.insert( layerId( *layerIt ), layerExcludedAttributes );
}
}
return resultMap;
}

if ( hiddenAttributes.size() > 0 )
/**Returns attributes excluded from WFS publication. Key is layer id, value is a set containing the names of the hidden attributes*/
QMap< QString, QSet<QString> > QgsProjectParser::wfsExcludedAttributes() const
{
QMap< QString, QSet<QString> > resultMap;
QList<QDomElement>::const_iterator layerIt = mProjectLayerElements.constBegin();
for ( ; layerIt != mProjectLayerElements.constEnd(); ++layerIt )
{
QDomElement excludeWMSElem = layerIt->firstChildElement( "excludeAttributesWFS" );
QDomNodeList attributeNodeList = excludeWMSElem.elementsByTagName( "attribute" );
if ( attributeNodeList.size() > 0 )
{
QSet<QString> layerExcludedAttributes;
for ( int i = 0; i < attributeNodeList.size(); ++i )
{
resultMap.insert( layerId( *layerIt ), hiddenAttributes );
layerExcludedAttributes.insert( attributeNodeList.at( i ).toElement().text() );
}
resultMap.insert( layerId( *layerIt ), layerExcludedAttributes );
}
}

return resultMap;
}

Expand Down Expand Up @@ -1440,18 +1468,19 @@ void QgsProjectParser::printCapabilities( QDomElement& parentElement, QDomDocume
return;
}

QDomNodeList composerNodeList = mXMLDoc->elementsByTagName( "Composer" );
if ( composerNodeList.size() < 1 )
QList<QDomElement> composerElemList = publishedComposerElements();
if ( composerElemList.size() < 1 )
{
return;
}

QDomElement composerTemplatesElem = doc.createElement( "ComposerTemplates" );

for ( int i = 0; i < composerNodeList.size(); ++i )
QList<QDomElement>::const_iterator composerElemIt = composerElemList.constBegin();
for ( ; composerElemIt != composerElemList.constEnd(); ++composerElemIt )
{
QDomElement composerTemplateElem = doc.createElement( "ComposerTemplate" );
QDomElement currentComposerElem = composerNodeList.at( i ).toElement();
QDomElement currentComposerElem = *composerElemIt;
if ( currentComposerElem.isNull() )
{
continue;
Expand Down Expand Up @@ -1515,10 +1544,11 @@ QDomElement QgsProjectParser::composerByName( const QString& composerName ) cons
return composerElem;
}

QDomNodeList composerNodeList = mXMLDoc->elementsByTagName( "Composer" );
for ( int i = 0; i < composerNodeList.size(); ++i )
QList<QDomElement> composerElemList = publishedComposerElements();
QList<QDomElement>::const_iterator composerIt = composerElemList.constBegin();
for ( ; composerIt != composerElemList.constEnd(); ++composerIt )
{
QDomElement currentComposerElem = composerNodeList.at( i ).toElement();
QDomElement currentComposerElem = *composerIt;
if ( currentComposerElem.attribute( "title" ) == composerName )
{
return currentComposerElem;
Expand All @@ -1528,6 +1558,50 @@ QDomElement QgsProjectParser::composerByName( const QString& composerName ) cons
return composerElem;
}

QList<QDomElement> QgsProjectParser::publishedComposerElements() const
{
QList<QDomElement> composerElemList;
if ( !mXMLDoc )
{
return composerElemList;
}

QDomNodeList composerNodeList = mXMLDoc->elementsByTagName( "Composer" );

QDomElement propertiesElem = mXMLDoc->documentElement().firstChildElement( "properties" );
QDomElement wmsComposerListElem = propertiesElem.firstChildElement( "WMSComposerList" );
if ( wmsComposerListElem.isNull() )
{
for ( unsigned int i = 0; i < composerNodeList.length(); ++i )
{
composerElemList.push_back( composerNodeList.at( i ).toElement() );
}
return composerElemList;
}

QSet<QString> publishedComposerNames;
QDomNodeList valueList = wmsComposerListElem.elementsByTagName( "value" );
for ( int i = 0; i < valueList.size(); ++i )
{
publishedComposerNames.insert( valueList.at( i ).toElement().text() );
}

//remove unpublished composers from list
QString currentComposerName;
QDomElement currentElem;
for ( int i = 0; i < composerNodeList.size(); ++i )
{
currentElem = composerNodeList.at( i ).toElement();
currentComposerName = currentElem.attribute( "title" );
if ( publishedComposerNames.contains( currentComposerName ) )
{
composerElemList.push_back( currentElem );
}
}

return composerElemList;
}

void QgsProjectParser::serviceCapabilities( QDomElement& parentElement, QDomDocument& doc ) const
{
QDomElement serviceElem = doc.createElement( "Service" );
Expand Down Expand Up @@ -1971,3 +2045,119 @@ void QgsProjectParser::projectLayerMap( QMap<QString, QgsMapLayer*>& layerMap )
}
}
}

QSet<QString> QgsProjectParser::restrictedLayers() const
{
QSet<QString> restrictedLayerSet;

if ( !mXMLDoc )
{
return restrictedLayerSet;
}

//names of unpublished layers / groups
QDomElement propertiesElem = mXMLDoc->documentElement().firstChildElement( "properties" );
if ( !propertiesElem.isNull() )
{
QDomElement wmsLayerRestrictionElem = propertiesElem.firstChildElement( "WMSRestrictedLayers" );
if ( !wmsLayerRestrictionElem.isNull() )
{
QStringList restrictedLayersAndGroups;
QDomNodeList wmsLayerRestrictionValues = wmsLayerRestrictionElem.elementsByTagName( "value" );
for ( int i = 0; i < wmsLayerRestrictionValues.size(); ++i )
{
restrictedLayerSet.insert( wmsLayerRestrictionValues.at( i ).toElement().text() );
}
}
}

//get legend dom element
if ( restrictedLayerSet.size() < 1 || !mXMLDoc )
{
return restrictedLayerSet;
}

QDomElement legendElem = mXMLDoc->documentElement().firstChildElement( "legend" );
if ( legendElem.isNull() )
{
return restrictedLayerSet;
}

//go through all legend groups and insert names of subgroups / sublayers if there is a match
QDomNodeList legendGroupList = legendElem.elementsByTagName( "legendgroup" );
for ( int i = 0; i < legendGroupList.size(); ++i )
{
//get name
QDomElement groupElem = legendGroupList.at( i ).toElement();
QString groupName = groupElem.attribute( "name" );
if ( restrictedLayerSet.contains( groupName ) ) //match: add names of subgroups and sublayers to set
{
//embedded group? -> also get names of subgroups and sublayers from embedded projects
if ( groupElem.attribute( "embedded" ) == "1" )
{
sublayersOfEmbeddedGroup( convertToAbsolutePath( groupElem.attribute( "project" ) ), groupName, restrictedLayerSet );
}
else //local group
{
QDomNodeList subgroupList = groupElem.elementsByTagName( "legendgroup" );
for ( int j = 0; j < subgroupList.size(); ++j )
{
restrictedLayerSet.insert( subgroupList.at( j ).toElement().attribute( "name" ) );
}
QDomNodeList sublayerList = groupElem.elementsByTagName( "legendlayer" );
for ( int k = 0; k < sublayerList.size(); ++k )
{
restrictedLayerSet.insert( sublayerList.at( k ).toElement().attribute( "name" ) );
}
}
}
}
return restrictedLayerSet;
}

void QgsProjectParser::sublayersOfEmbeddedGroup( const QString& projectFilePath, const QString& groupName, QSet<QString>& layerSet )
{
QFile projectFile( projectFilePath );
if ( !projectFile.open( QIODevice::ReadOnly ) )
{
return;
}

QDomDocument xmlDoc;
if ( !xmlDoc.setContent( &projectFile ) )
{
return;
}

//go to legend node
QDomElement legendElem = xmlDoc.documentElement().firstChildElement( "legend" );
if ( legendElem.isNull() )
{
return;
}

//get group node list of embedded project
QDomNodeList groupNodes = legendElem.elementsByTagName( "legendgroup" );
QDomElement groupElem;
for ( int i = 0; i < groupNodes.size(); ++i )
{
groupElem = groupNodes.at( i ).toElement();
if ( groupElem.attribute( "name" ) == groupName )
{
//get all subgroups and sublayers and add to layerSet
QDomElement subElem;
QDomNodeList subGroupList = groupElem.elementsByTagName( "legendgroup" );
for ( int j = 0; j < subGroupList.size(); ++j )
{
subElem = subGroupList.at( j ).toElement();
layerSet.insert( subElem.attribute( "name" ) );
}
QDomNodeList subLayerList = groupElem.elementsByTagName( "legendlayer" );
for ( int j = 0; j < subLayerList.size(); ++j )
{
subElem = subLayerList.at( j ).toElement();
layerSet.insert( subElem.attribute( "name" ) );
}
}
}
}
17 changes: 15 additions & 2 deletions src/mapserver/qgsprojectparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,11 @@ class QgsProjectParser: public QgsConfigParser
Default implementation returns an empty map*/
virtual QMap< QString, QMap< int, QString > > layerAliasInfo() const;

/**Returns a stringlist containing the names of the attributes with hidden edit types*/
virtual QMap< QString, QSet<QString> > hiddenAttributes() const;
/**Returns attributes excluded from WMS publication. Key is layer id, value is a set containing the names of the hidden attributes*/
virtual QMap< QString, QSet<QString> > wmsExcludedAttributes() const;

/**Returns attributes excluded from WFS publication. Key is layer id, value is a set containing the names of the hidden attributes*/
virtual QMap< QString, QSet<QString> > wfsExcludedAttributes() const;

/**Returns map rectangle for the project file*/
QgsRectangle mapRectangle() const;
Expand Down Expand Up @@ -134,6 +137,8 @@ class QgsProjectParser: public QgsConfigParser
QHash< QString, QDomElement > mProjectLayerElementsById;
/**Project layer elements, accessible by layer name*/
QHash< QString, QDomElement > mProjectLayerElementsByName;
/**Names of layers and groups which should not be published*/
QSet<QString> mRestrictedLayers;

/**Creates a maplayer object from <maplayer> element. The layer cash owns the maplayer, so don't delete it
@return the maplayer or 0 in case of error*/
Expand Down Expand Up @@ -169,6 +174,9 @@ class QgsProjectParser: public QgsConfigParser
/**Returns dom element of composer (identified by composer title) or a null element in case of error*/
QDomElement composerByName( const QString& composerName ) const;

/**Returns the composer elements published by this WMS. It is possible to hide composers from the WMS*/
QList<QDomElement> publishedComposerElements() const;

/**Converts a (possibly relative) path to absolute*/
QString convertToAbsolutePath( const QString& file ) const;

Expand All @@ -188,6 +196,11 @@ class QgsProjectParser: public QgsConfigParser
void projectLayerMap( QMap<QString, QgsMapLayer*>& layerMap ) const;

static QString editTypeString( QgsVectorLayer::EditType type );

/**Returns a complete string set with all the restricted layer names (layers/groups that are not to be published)*/
QSet<QString> restrictedLayers() const;
/**Adds sublayers of an embedded group to layer set*/
static void sublayersOfEmbeddedGroup( const QString& projectFilePath, const QString& groupName, QSet<QString>& layerSet );
};

#endif // QGSPROJECTPARSER_H
40 changes: 20 additions & 20 deletions src/mapserver/qgswfsserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format

QStringList wfsLayersId = mConfigParser->wfsLayers();
QMap< QString, QMap< int, QString > > aliasInfo = mConfigParser->layerAliasInfo();
QMap< QString, QSet<QString> > hiddenAttributes = mConfigParser->hiddenAttributes();
QMap< QString, QSet<QString> > excludedAttributes = mConfigParser->wfsExcludedAttributes();

QList<QgsMapLayer*> layerList;
QgsMapLayer* currentLayer = 0;
Expand All @@ -306,12 +306,12 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
layerAliasInfo = aliasIt.value();
}

//hidden attributes for this layer
QSet<QString> layerHiddenAttributes;
QMap< QString, QSet<QString> >::const_iterator hiddenIt = hiddenAttributes.find( currentLayer->id() );
if ( hiddenIt != hiddenAttributes.constEnd() )
//excluded attributes for this layer
QSet<QString> layerExcludedAttributes;
QMap< QString, QSet<QString> >::const_iterator exclIt = excludedAttributes.find( currentLayer->id() );
if ( exclIt != excludedAttributes.constEnd() )
{
layerHiddenAttributes = hiddenIt.value();
layerExcludedAttributes = exclIt.value();
}

//do a select with searchRect and go through all the features
Expand Down Expand Up @@ -455,7 +455,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
if ( fidOk )
{
provider->featureAtId( fid.toInt(), feature, mWithGeom, attrIndexes );
sendGetFeature( request, format, &feature, 0, layerCrs, fields, layerHiddenAttributes );
sendGetFeature( request, format, &feature, 0, layerCrs, fields, layerExcludedAttributes );
}
else if ( filterOk )
{
Expand All @@ -469,13 +469,13 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
{
if ( mFilter->evaluate( feature ) )
{
sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerHiddenAttributes );
sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerExcludedAttributes );
++featureCounter;
}
}
else
{
sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerHiddenAttributes );
sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerExcludedAttributes );
++featureCounter;
}
}
Expand All @@ -487,7 +487,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format

while ( provider->nextFeature( feature ) && featureCounter < maxFeat )
{
sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerHiddenAttributes );
sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerExcludedAttributes );
++featureCounter;
}
}
Expand All @@ -497,7 +497,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
provider->select( attrIndexes, searchRect, mWithGeom, true );
while ( provider->nextFeature( feature ) && featureCounter < maxFeat )
{
sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerHiddenAttributes );
sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerExcludedAttributes );
++featureCounter;
}
}
Expand Down Expand Up @@ -633,7 +633,7 @@ void QgsWFSServer::startGetFeature( QgsRequestHandler& request, const QString& f
fcString = "";
}

void QgsWFSServer::sendGetFeature( QgsRequestHandler& request, const QString& format, QgsFeature* feat, int featIdx, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes ) /*const*/
void QgsWFSServer::sendGetFeature( QgsRequestHandler& request, const QString& format, QgsFeature* feat, int featIdx, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> excludedAttributes ) /*const*/
{
QByteArray result;
if ( format == "GeoJSON" )
Expand All @@ -643,7 +643,7 @@ void QgsWFSServer::sendGetFeature( QgsRequestHandler& request, const QString& fo
fcString += " ";
else
fcString += " ,";
fcString += createFeatureGeoJSON( feat, crs, fields, hiddenAttributes );
fcString += createFeatureGeoJSON( feat, crs, fields, excludedAttributes );
fcString += "\n";

result = fcString.toUtf8();
Expand All @@ -653,7 +653,7 @@ void QgsWFSServer::sendGetFeature( QgsRequestHandler& request, const QString& fo
else
{
QDomDocument gmlDoc;
QDomElement featureElement = createFeatureElem( feat, gmlDoc, crs, fields, hiddenAttributes );
QDomElement featureElement = createFeatureElem( feat, gmlDoc, crs, fields, excludedAttributes );
gmlDoc.appendChild( featureElement );

result = gmlDoc.toByteArray();
Expand Down Expand Up @@ -684,7 +684,7 @@ void QgsWFSServer::endGetFeature( QgsRequestHandler& request, const QString& for
}
}

QString QgsWFSServer::createFeatureGeoJSON( QgsFeature* feat, QgsCoordinateReferenceSystem &, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes ) /*const*/
QString QgsWFSServer::createFeatureGeoJSON( QgsFeature* feat, QgsCoordinateReferenceSystem &, QMap< int, QgsField > fields, QSet<QString> excludedAttributes ) /*const*/
{
QString fStr = "{\"type\": \"Feature\",\n";

Expand All @@ -711,8 +711,8 @@ QString QgsWFSServer::createFeatureGeoJSON( QgsFeature* feat, QgsCoordinateRefer
for ( QgsAttributeMap::const_iterator it = featureAttributes.begin(); it != featureAttributes.end(); ++it )
{
QString attributeName = fields[it.key()].name();
//skip attribute if it has edit type 'hidden'
if ( hiddenAttributes.contains( attributeName ) )
//skip attribute if it is excluded from WFS publication
if ( excludedAttributes.contains( attributeName ) )
{
continue;
}
Expand Down Expand Up @@ -744,7 +744,7 @@ QString QgsWFSServer::createFeatureGeoJSON( QgsFeature* feat, QgsCoordinateRefer
return fStr;
}

QDomElement QgsWFSServer::createFeatureElem( QgsFeature* feat, QDomDocument& doc, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes ) /*const*/
QDomElement QgsWFSServer::createFeatureElem( QgsFeature* feat, QDomDocument& doc, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> excludedAttributes ) /*const*/
{
//gml:FeatureMember
QDomElement featureElement = doc.createElement( "gml:featureMember"/*wfs:FeatureMember*/ );
Expand Down Expand Up @@ -787,8 +787,8 @@ QDomElement QgsWFSServer::createFeatureElem( QgsFeature* feat, QDomDocument& doc
{

QString attributeName = fields[it.key()].name();
//skip attribute if it has edit type 'hidden'
if ( hiddenAttributes.contains( attributeName ) )
//skip attribute if is explicitely excluded from WFS publication
if ( excludedAttributes.contains( attributeName ) )
{
continue;
}
Expand Down
6 changes: 3 additions & 3 deletions src/mapserver/qgswfsserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,14 @@ class QgsWFSServer
protected:

void startGetFeature( QgsRequestHandler& request, const QString& format, QgsCoordinateReferenceSystem& crs, QgsRectangle* rect );
void sendGetFeature( QgsRequestHandler& request, const QString& format, QgsFeature* feat, int featIdx, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes );
void sendGetFeature( QgsRequestHandler& request, const QString& format, QgsFeature* feat, int featIdx, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> excludedAttributes );
void endGetFeature( QgsRequestHandler& request, const QString& format );

//methods to write GeoJSON
QString createFeatureGeoJSON( QgsFeature* feat, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes ) /*const*/;
QString createFeatureGeoJSON( QgsFeature* feat, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> excludedAttributes ) /*const*/;

//methods to write GML2
QDomElement createFeatureElem( QgsFeature* feat, QDomDocument& doc, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes ) /*const*/;
QDomElement createFeatureElem( QgsFeature* feat, QDomDocument& doc, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> excludedAttributes ) /*const*/;

QDomElement createBoxElem( QgsRectangle* box, QDomDocument& doc ) /* const */;
QDomElement createGeometryElem( QgsGeometry* g, QDomDocument& doc ) /*const*/;
Expand Down
25 changes: 13 additions & 12 deletions src/mapserver/qgswmsserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ int QgsWMSServer::getFeatureInfo( QDomDocument& result, QString version )

QStringList nonIdentifiableLayers = mConfigParser->identifyDisabledLayers();
QMap< QString, QMap< int, QString > > aliasInfo = mConfigParser->layerAliasInfo();
QMap< QString, QSet<QString> > hiddenAttributes = mConfigParser->hiddenAttributes();
QMap< QString, QSet<QString> > excludedAttributes = mConfigParser->wmsExcludedAttributes();

//Render context is needed to determine feature visibility for vector layers
QgsRenderContext renderContext;
Expand Down Expand Up @@ -784,16 +784,16 @@ int QgsWMSServer::getFeatureInfo( QDomDocument& result, QString version )
layerAliasInfo = aliasIt.value();
}

//hidden attributes for this layer
QSet<QString> layerHiddenAttributes;
QMap< QString, QSet<QString> >::const_iterator hiddenIt = hiddenAttributes.find( currentLayer->id() );
if ( hiddenIt != hiddenAttributes.constEnd() )
//excluded attributes for this layer
QSet<QString> layerExcludedAttributes;
QMap< QString, QSet<QString> >::const_iterator excludedIt = excludedAttributes.find( currentLayer->id() );
if ( excludedIt != excludedAttributes.constEnd() )
{
layerHiddenAttributes = hiddenIt.value();
layerExcludedAttributes = excludedIt.value();
}

if ( featureInfoFromVectorLayer( vectorLayer, infoPoint, featureCount, result, layerElement, mMapRenderer, renderContext,
layerAliasInfo, layerHiddenAttributes, version, featuresRect ) != 0 )
layerAliasInfo, layerExcludedAttributes, version, featuresRect ) != 0 )
{
continue;
}
Expand Down Expand Up @@ -1141,7 +1141,7 @@ int QgsWMSServer::featureInfoFromVectorLayer( QgsVectorLayer* layer,
QgsMapRenderer* mapRender,
QgsRenderContext& renderContext,
QMap<int, QString>& aliasMap,
QSet<QString>& hiddenAttributes,
QSet<QString>& excludedAttributes,
QString version,
QgsRectangle* featureBBox ) const
{
Expand Down Expand Up @@ -1231,8 +1231,8 @@ int QgsWMSServer::featureInfoFromVectorLayer( QgsVectorLayer* layer,
{

QString attributeName = fields[it.key()].name();
//skip attribute if it has edit type 'hidden'
if ( hiddenAttributes.contains( attributeName ) )
//skip attribute if it is explicitely excluded from WMS publication
if ( excludedAttributes.contains( attributeName ) )
{
continue;
}
Expand Down Expand Up @@ -1298,13 +1298,14 @@ int QgsWMSServer::featureInfoFromRasterLayer( QgsRasterLayer* layer,
{
Q_UNUSED( version );

if ( !infoPoint || !layer )
if ( !infoPoint || !layer || !layer->dataProvider() )
{
return 1;
}

QMap<QString, QString> attributes;
layer->identify( *infoPoint, attributes );
// TODO: use context extent, width height (comes with request) to use WCS cache
attributes = layer->dataProvider()->identify( *infoPoint );

for ( QMap<QString, QString>::const_iterator it = attributes.constBegin(); it != attributes.constEnd(); ++it )
{
Expand Down
2 changes: 1 addition & 1 deletion src/mapserver/qgswmsserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class QgsWMSServer
@param featureBBox the bounding box of the selected features in output CRS
@return 0 in case of success*/
int featureInfoFromVectorLayer( QgsVectorLayer* layer, const QgsPoint* infoPoint, int nFeatures, QDomDocument& infoDocument, QDomElement& layerElement, QgsMapRenderer* mapRender,
QgsRenderContext& renderContext, QMap<int, QString>& aliasMap, QSet<QString>& hiddenAttributes, QString version, QgsRectangle* featureBBox = 0 ) const;
QgsRenderContext& renderContext, QMap<int, QString>& aliasMap, QSet<QString>& excludedAttributes, QString version, QgsRectangle* featureBBox = 0 ) const;
/**Appends feature info xml for the layer to the layer element of the dom document*/
int featureInfoFromRasterLayer( QgsRasterLayer* layer, const QgsPoint* infoPoint, QDomDocument& infoDocument, QDomElement& layerElement, QString version ) const;

Expand Down
163 changes: 74 additions & 89 deletions src/providers/gdal/qgsgdalprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#include "qgsrasterlayer.h"
#include "qgsrasterpyramid.h"

#include "qgspoint.h"

#include <QImage>
#include <QSettings>
#include <QColor>
Expand Down Expand Up @@ -378,10 +380,10 @@ void QgsGdalProvider::readBlock( int theBandNo, QgsRectangle const & theExtent,
QgsDebugMsg( QString( "transform : %1" ).arg( mGeoTransform[i] ) );
}

int dataSize = dataTypeSize( theBandNo ) / 8;
int dataSize = dataTypeSize( theBandNo );

// fill with null values
QByteArray ba = noValueBytes( theBandNo );
QByteArray ba = QgsRasterBlock::valueBytes( dataType( theBandNo ), noDataValue( theBandNo ) );
char *nodata = ba.data();
char *block = ( char * ) theBlock;
for ( int i = 0; i < thePixelWidth * thePixelHeight; i++ )
Expand Down Expand Up @@ -643,10 +645,10 @@ void QgsGdalProvider::readBlock( int theBandNo, QgsRectangle const & theExtent,

myWarpOptions->nBandCount = 1;
myWarpOptions->panSrcBands =
( int * ) CPLMalloc( sizeof( int ) * myWarpOptions->nBandCount );
( int * ) QgsMalloc( sizeof( int ) * myWarpOptions->nBandCount );
myWarpOptions->panSrcBands[0] = theBandNo;
myWarpOptions->panDstBands =
( int * ) CPLMalloc( sizeof( int ) * myWarpOptions->nBandCount );
( int * ) QgsMalloc( sizeof( int ) * myWarpOptions->nBandCount );
myWarpOptions->panDstBands[0] = 1;

// TODO move here progressCallback and use it
Expand Down Expand Up @@ -682,8 +684,8 @@ void QgsGdalProvider::readBlock( int theBandNo, QgsRectangle const & theExtent,
//CPLAssert( myWarpOptions->pTransformerArg != NULL );
myWarpOptions->pfnTransformer = GDALGenImgProjTransform;

myWarpOptions->padfDstNoDataReal = ( double * ) CPLMalloc( myWarpOptions->nBandCount * sizeof( double ) );
myWarpOptions->padfDstNoDataImag = ( double * ) CPLMalloc( myWarpOptions->nBandCount * sizeof( double ) );
myWarpOptions->padfDstNoDataReal = ( double * ) QgsMalloc( myWarpOptions->nBandCount * sizeof( double ) );
myWarpOptions->padfDstNoDataImag = ( double * ) QgsMalloc( myWarpOptions->nBandCount * sizeof( double ) );

myWarpOptions->padfDstNoDataReal[0] = mNoDataValue[theBandNo-1];
myWarpOptions->padfDstNoDataImag[0] = 0.0;
Expand Down Expand Up @@ -826,102 +828,97 @@ int QgsGdalProvider::yBlockSize() const
int QgsGdalProvider::xSize() const { return mWidth; }
int QgsGdalProvider::ySize() const { return mHeight; }

QMap<int, void *> QgsGdalProvider::identify( const QgsPoint & point )
QMap<int, QVariant> QgsGdalProvider::identify( const QgsPoint & thePoint, IdentifyFormat theFormat, const QgsRectangle &theExtent, int theWidth, int theHeight )
{
Q_UNUSED( theFormat );
Q_UNUSED( theExtent );
Q_UNUSED( theWidth );
Q_UNUSED( theHeight );
QgsDebugMsg( "Entered" );
QMap<int, void *> results;
if ( !mExtent.contains( point ) )

QMap<int, QVariant> results;

if ( theFormat != IdentifyFormatValue ) return results;

if ( !extent().contains( thePoint ) )
{
// Outside the raster
for ( int i = 1; i <= GDALGetRasterCount( mGdalDataset ); i++ )
for ( int bandNo = 1; bandNo <= bandCount(); bandNo++ )
{
void * data = VSIMalloc( dataTypeSize( i ) / 8 );
QgsRasterBlock::writeValue( data, dataType( i ), 0, noDataValue( i ) );
results.insert( i, data );
results.insert( bandNo, noDataValue( bandNo ) );
}
return results;
}
else
{
double x = point.x();
double y = point.y();

// Calculate the row / column where the point falls
double xres = ( mExtent.xMaximum() - mExtent.xMinimum() ) / mWidth;
double yres = ( mExtent.yMaximum() - mExtent.yMinimum() ) / mHeight;
QgsRectangle myExtent = theExtent;
if ( myExtent.isEmpty() ) myExtent = extent();

// Offset, not the cell index -> flor
int col = ( int ) floor(( x - mExtent.xMinimum() ) / xres );
int row = ( int ) floor(( mExtent.yMaximum() - y ) / yres );
if ( theWidth == 0 ) theWidth = xSize();
if ( theHeight == 0 ) theHeight = ySize();

// QgsDebugMsg( "row = " + QString::number( row ) + " col = " + QString::number( col ) );
// Calculate the row / column where the point falls
double xres = ( myExtent.width() ) / theWidth;
double yres = ( myExtent.height() ) / theHeight;

for ( int i = 1; i <= GDALGetRasterCount( mGdalDataset ); i++ )
{
GDALRasterBandH gdalBand = GDALGetRasterBand( mGdalDataset, i );
// Offset, not the cell index -> flor
int col = ( int ) floor(( thePoint.x() - myExtent.xMinimum() ) / xres );
int row = ( int ) floor(( myExtent.yMaximum() - thePoint.y() ) / yres );

// QgsDebugMsg( "row = " + QString::number( row ) + " col = " + QString::number( col ) );

int r = 0;
int c = 0;
int width = 1;
int height = 1;
int r = 0;
int c = 0;
int width = 1;
int height = 1;

// GDAL ECW driver in GDAL < 1.9.2 read whole row if single pixel (nYSize == 1)
// was requested which made identify very slow -> use 2x2 matrix
// but other drivers may be optimised for 1x1 -> conditional
// GDAL ECW driver in GDAL < 1.9.2 read whole row if single pixel (nYSize == 1)
// was requested which made identify very slow -> use 2x2 matrix
// but other drivers may be optimised for 1x1 -> conditional
#if !defined(GDAL_VERSION_NUM) || GDAL_VERSION_NUM < 1920
if ( strcmp( GDALGetDriverShortName( GDALGetDatasetDriver( mGdalDataset ) ), "ECW" ) == 0 )
{
width = 2;
height = 2;
if ( col == mWidth - 1 && mWidth > 1 )
{
col--;
c++;
}
if ( row == mHeight - 1 && mHeight > 1 )
{
row--;
r++;
}
}
if ( strcmp( GDALGetDriverShortName( GDALGetDatasetDriver( mGdalDataset ) ), "ECW" ) == 0 )
{
width = 2;
height = 2;
if ( col == mWidth - 1 && mWidth > 1 )
{
col--;
c++;
}
if ( row == mHeight - 1 && mHeight > 1 )
{
row--;
r++;
}
}
#endif
int typeSize = dataTypeSize( i ) / 8;
void * tmpData = VSIMalloc( typeSize * width * height );

CPLErr err = GDALRasterIO( gdalBand, GF_Read, col, row, width, height,
tmpData, width, height,
( GDALDataType ) mGdalDataType[i-1], 0, 0 );
double xMin = myExtent.xMinimum() + col * xres;
double xMax = xMin + xres * width;
double yMax = myExtent.yMaximum() - row * yres;
double yMin = yMax - yres * height;
QgsRectangle pixelExtent( xMin, yMin, xMax, yMax );

if ( err != CPLE_None )
{
QgsLogger::warning( "RasterIO error: " + QString::fromUtf8( CPLGetLastErrorMsg() ) );
}
void * data = VSIMalloc( typeSize );
memcpy( data, ( void* )(( char* )tmpData + ( r*width + c )*typeSize ), typeSize );
results.insert( i, data );
for ( int i = 1; i <= bandCount(); i++ )
{
QgsRasterBlock * myBlock = block( i, pixelExtent, width, height );

CPLFree( tmpData );
if ( !myBlock )
{
results.clear();
return results;
}
}

return results;
}
double value = myBlock->value( r, c );

#if 0
bool QgsGdalProvider::identify( const QgsPoint& thePoint, QMap<QString, QString>& theResults )
{
QMap<int, QString> results;
identify( thePoint, results );
for ( int i = 1; i <= GDALGetRasterCount( mGdalDataset ); i++ )
{
theResults[ generateBandName( i )] = results.value( i );
results.insert( i, value );
}
return true;
return results;
}
#endif

int QgsGdalProvider::capabilities() const
{
int capability = QgsRasterDataProvider::Identify
| QgsRasterDataProvider::IdentifyValue
| QgsRasterDataProvider::ExactResolution
| QgsRasterDataProvider::EstimatedMinimumMaximum
| QgsRasterDataProvider::BuildPyramids
Expand Down Expand Up @@ -1016,18 +1013,6 @@ bool QgsGdalProvider::isValid()
return mValid;
}

QString QgsGdalProvider::identifyAsText( const QgsPoint& point )
{
Q_UNUSED( point );
return QString( "Not implemented" );
}

QString QgsGdalProvider::identifyAsHtml( const QgsPoint& point )
{
Q_UNUSED( point );
return QString( "Not implemented" );
}

QString QgsGdalProvider::lastErrorTitle()
{
return QString( "Not implemented" );
Expand Down Expand Up @@ -1127,7 +1112,7 @@ bool QgsGdalProvider::hasHistogram( int theBandNo,
NULL, NULL );

if ( myHistogramArray )
VSIFree( myHistogramArray );
VSIFree( myHistogramArray ); // use VSIFree because allocated by GDAL

// if there was any error/warning assume the histogram is not valid or non-existent
if ( myError != CE_None )
Expand Down Expand Up @@ -2507,7 +2492,7 @@ QGISEXTERN QString helpCreationOptionsFormat( QString format )
if ( psCOL )
CPLDestroyXMLNode( psCOL );
if ( pszFormattedXML )
CPLFree( pszFormattedXML );
QgsFree( pszFormattedXML );
}
return message;
}
Expand Down
28 changes: 1 addition & 27 deletions src/providers/gdal/qgsgdalprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,33 +121,7 @@ class QgsGdalProvider : public QgsRasterDataProvider, QgsGdalProviderBase
*/
bool isValid();

/** \brief Identify raster value(s) found on the point position */
//bool identify( const QgsPoint & point, QMap<QString, QString>& results );

//bool identify( const QgsPoint & point, QMap<int, QString>& results );

QMap<int, void *> identify( const QgsPoint & point );

/**
* \brief Identify details from a GDAL layer from the last screen update
*
* \param point[in] The pixel coordinate (as it was displayed locally on screen)
*
* \return A text document containing the return from the GDAL layer
*
*/
QString identifyAsText( const QgsPoint& point );

/**
* \brief Identify details from a GDAL layer from the last screen update
*
* \param point[in] The pixel coordinate (as it was displayed locally on screen)
*
* \return A text document containing the return from the GDAL layer
*
* \note added in 1.5
*/
QString identifyAsHtml( const QgsPoint& point );
QMap<int, QVariant> identify( const QgsPoint & thePoint, IdentifyFormat theFormat, const QgsRectangle &theExtent = QgsRectangle(), int theWidth = 0, int theHeight = 0 );

/**
* \brief Returns the caption error text for the last error in this provider
Expand Down
5 changes: 3 additions & 2 deletions src/providers/grass/qgis.g.info.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ int main( int argc, char **argv )

if ( col < 0 || col > window.cols || row < 0 || row > window.rows )
{
fprintf( stdout, "value:out\n" );
//fprintf( stdout, "value:out\n" );
fprintf( stdout, "value:nan\n" );
}
else
{
Expand Down Expand Up @@ -245,7 +246,7 @@ int main( int argc, char **argv )
}
if ( G_is_null_value( ptr, rast_type ) )
{
fprintf( stdout, "value:null\n" );
fprintf( stdout, "value:nan\n" );
}
else
{
Expand Down
Loading