Added the unique value marker renderer

git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@2004 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
larsl 2004-09-13 19:34:06 +00:00
parent 337b75aa41
commit 4e6172bba3
13 changed files with 855 additions and 21 deletions

View File

@ -1,8 +1,11 @@
QGIS Change Log
ChangeLog,v 1.183 2004/09/12 16:40:43 larsl Exp
ChangeLog,v 1.184 2004/09/13 19:34:04 larsl Exp
------------------------------------------------------------------------------
Version 0.5 'Bandit' .... development version
2004-09-13 [larsl] 0.4.0devel31
** Added the unique value marker renderer
2004-09-12 [larsl] 0.4.0devel30
** Scale down SVG symbols
** Display rasters without geotransform info as "1 pixel = 1 unit"

View File

@ -1,6 +1,6 @@
dnl Process this file with autoconf to produce a configure script.
dnl configure.in,v 1.185 2004/09/12 16:40:43 larsl Exp
dnl configure.in,v 1.186 2004/09/13 19:34:05 larsl Exp
@ -26,7 +26,7 @@ dnl ---------------------------------------------------------------------------
MAJOR_VERSION=0
MINOR_VERSION=4
MICRO_VERSION=0
EXTRA_VERSION=30
EXTRA_VERSION=31
if test $EXTRA_VERSION -eq 0; then
VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}
else

View File

@ -91,7 +91,9 @@ headers = qgis.h \
qgssymbol.h \
qgssymbologyutils.h \
qgsuniquevalrenderer.h \
qgsuvalmarenderer.h \
qgsuvaldialog.h \
qgsuvalmadialog.h \
qgsvectorlayer.h \
splashscreen.h \
qgisapp.h \
@ -128,6 +130,7 @@ qgis_UIC = qgisappbase.ui \
qgssimadialogbase.ui \
qgssisydialogbase.ui \
qgsuvaldialogbase.ui \
qgsuvalmadialogbase.ui \
qgslabeldialogbase.ui \
qgsprojectpropertiesbase.ui
@ -181,6 +184,7 @@ qgis_MOC = qgisapp.moc.cpp \
qgssimadialog.moc.cpp \
qgssisydialog.moc.cpp \
qgsuvaldialog.moc.cpp \
qgsuvalmadialog.moc.cpp \
qgsvectorlayer.moc.cpp \
splashscreen.moc.cpp \
qgsprojectproperties.moc.cpp \
@ -244,7 +248,9 @@ qgis_SOURCES = main.cpp \
qgssymbol.cpp \
qgssymbologyutils.cpp \
qgsuniquevalrenderer.cpp \
qgsuvalmarenderer.cpp \
qgsuvaldialog.cpp \
qgsuvalmadialog.cpp \
qgsvectorlayer.cpp \
splashscreen.cpp \
qgsscalecalculator.cpp \

View File

@ -37,6 +37,7 @@
#include "qgsgraduatedsymrenderer.h"
#include "qgscontinuouscolrenderer.h"
#include "qgsuniquevalrenderer.h"
#include "qgsuvalmarenderer.h"
#include "qgssimarenderer.h"
#include "qgssimadialog.h"
#include "qgslegenditem.h"
@ -47,6 +48,7 @@
#include "qgsgrasydialog.h"
#include "qgscontcoldialog.h"
#include "qgsuvaldialog.h"
#include "qgsuvalmadialog.h"
#include "qobjectlist.h"
#include "qgsgramadialog.h"
#include "qgslabelattributes.h"
@ -94,6 +96,7 @@ bufferRenderer(layer->
{
legendtypecombobox->insertItem(tr("Single Marker"));
legendtypecombobox->insertItem(tr("Graduated Marker"));
legendtypecombobox->insertItem(tr("Unique Value Marker"));
}
QVBoxLayout *layout = new QVBoxLayout( labelOptionsFrame );
@ -147,6 +150,9 @@ void QgsDlgVectorLayerProperties::alterLayerDialog(const QString & string)
} else if(string == tr("Unique Value"))
{
bufferRenderer = new QgsUniqueValRenderer();
} else if(string == tr("Unique Value Marker"))
{
bufferRenderer = new QgsUValMaRenderer();
}
bufferRenderer->initializeSymbology(layer, this);
@ -177,6 +183,7 @@ void QgsDlgVectorLayerProperties::apply()
QgsSiMaDialog* smdialog = dynamic_cast < QgsSiMaDialog * >(layer->rendererDialog());
QgsGraMaDialog* gmdialog = dynamic_cast< QgsGraMaDialog * >(layer->rendererDialog());
QgsUValDialog* udialog = dynamic_cast< QgsUValDialog * > (layer->rendererDialog());
QgsUValMaDialog* umdialog = dynamic_cast< QgsUValMaDialog * > (layer->rendererDialog());
if (sdialog)
{
@ -200,6 +207,10 @@ void QgsDlgVectorLayerProperties::apply()
{
udialog->apply();
}
else if(umdialog)
{
umdialog->apply();
}
rendererDirty = false;
}

View File

@ -12,7 +12,7 @@ email : sherman at mrcc.com
* (at your option) any later version. *
* *
***************************************************************************/
/* qgsprojectio.cpp,v 1.52 2004/08/27 21:23:40 mhugent Exp */
/* qgsprojectio.cpp,v 1.53 2004/09/13 19:34:05 larsl Exp */
#include <iostream>
#include <fstream>
#include <qfiledialog.h>
@ -36,6 +36,7 @@ email : sherman at mrcc.com
#include "qgsgraduatedsymrenderer.h"
#include "qgscontinuouscolrenderer.h"
#include "qgsuniquevalrenderer.h"
#include "qgsuvalmarenderer.h"
#include "qgssymbologyutils.h"
#include "qgssisydialog.h"
#include "qgssimadialog.h"
@ -269,6 +270,7 @@ std::list<QString> QgsProjectIo::read(QString path)
QDomNode singlemarkernode = node.namedItem("singlemarker");
QDomNode graduatedmarkernode = node.namedItem("graduatedmarker");
QDomNode uniquevaluenode = node.namedItem("uniquevalue");
QDomNode uniquevaluemarkernode = node.namedItem("uniquevaluemarker");
QgsRenderer* renderer;
@ -302,6 +304,11 @@ std::list<QString> QgsProjectIo::read(QString path)
renderer = new QgsUniqueValRenderer();
renderer->readXML(uniquevaluenode,*dbl);
}
else if(!uniquevaluemarkernode.isNull())
{
renderer = new QgsUValMaRenderer();
renderer->readXML(uniquevaluemarkernode,*dbl);
}
// Label
dbl->setLabelOn ( (bool) node.namedItem("label").toElement().text().toInt() );

View File

@ -27,6 +27,8 @@
#include "qgslegenditem.h"
#include "qgssvgcache.h"
#include <qapplication.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qfiledialog.h>
#include <qimage.h>
#include <qpushbutton.h>
@ -59,10 +61,9 @@ QgsSiMaDialog::QgsSiMaDialog(QgsVectorLayer* vectorlayer): QgsSiMaDialogBase(),
{
double scalefactor=sy->scaleFactor();
mScaleSpin->setValue((int)(scalefactor*100.0));
QString svgfile=sy->picture();
mSelectedMarker=sy->picture();
pmPreview->setPixmap(QgsSVGCache::instance().
getPixmap(svgfile, scalefactor));
pmPreview->setName(svgfile);
getPixmap(mSelectedMarker, scalefactor));
}
else
{
@ -103,7 +104,7 @@ void QgsSiMaDialog::apply()
#endif
QgsMarkerSymbol* ms= new QgsMarkerSymbol();
QString string(pmPreview->name());
QString string(mSelectedMarker);
#ifdef QGISDEBUG
qWarning(string);
#endif
@ -182,15 +183,46 @@ void QgsSiMaDialog::apply()
mVectorLayer->triggerRepaint();
}
void QgsSiMaDialog::setMarker(const QString& file, double scaleFactor) {
QFile f(file);
QFileInfo fi(f);
if (fi.exists()) {
// set the directory
mCurrentDir = fi.dir().path() + "/";
visualizeMarkers(mCurrentDir);
mDirectoryEdit->setText(mCurrentDir);
QIconViewItem* item = mIconView->findItem(fi.fileName(), Qt::ExactMatch);
if (item) {
// set the picture
mIconView->setSelected(item, true);
// set the scale factor
mScaleSpin->setValue(scaleFactor * 100.0);
}
}
emit settingsChanged();
}
const QString& QgsSiMaDialog::getPicture() const {
return mSelectedMarker;
}
double QgsSiMaDialog::getScaleFactor() const {
return mScaleSpin->value() / 100.0;
}
void QgsSiMaDialog::mIconView_selectionChanged(QIconViewItem * theIconViewItem)
{
QString svgfile=mCurrentDir+theIconViewItem->text();
pmPreview->setName(svgfile);
mSelectedMarker=mCurrentDir+theIconViewItem->text();
//draw the SVG-Image on the button
double scalefactor=mScaleSpin->value()/100.0;
pmPreview->setPixmap(QgsSVGCache::instance().
getPixmap(svgfile, scalefactor));
getPixmap(mSelectedMarker, scalefactor));
emit settingsChanged();
}
void QgsSiMaDialog::mScaleSpin_valueChanged( int theSize)
@ -199,15 +231,15 @@ void QgsSiMaDialog::mScaleSpin_valueChanged( int theSize)
std::cout << "mScaleSpin_valueChanged(" << theSize << ") " << std::endl;
#endif
//draw the SVG-Image on the button
QString svgfile(pmPreview->name());
if(!svgfile.isEmpty())
if(!mSelectedMarker.isEmpty())
{
//user enters scaling factor as a percentage
double scalefactor=mScaleSpin->value()/100.0;
pmPreview->setPixmap(QgsSVGCache::instance().
getPixmap(svgfile, scalefactor));
getPixmap(mSelectedMarker, scalefactor));
}
emit settingsChanged();
}
void QgsSiMaDialog::mBrowseDirectoriesButton_clicked()

View File

@ -37,7 +37,10 @@ public:
~QgsSiMaDialog();
static QString defaultDir();
void apply();
void setMarker(const QString& file, double scaleFactor);
const QString& getPicture() const;
double getScaleFactor() const;
protected:
QgsVectorLayer* mVectorLayer;
QString mCurrentDir;
@ -54,6 +57,9 @@ private:
/**Renders the SVG pictures of directory to mIconView*/
void visualizeMarkers(QString directory);
void mScaleSpin_valueChanged( int theSize);
signals:
void settingsChanged();
};
#endif

View File

@ -1,4 +1,4 @@
<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
<class>QgsSiMaDialogBase</class>
<widget class="QDialog">
<property name="name">
@ -9,7 +9,7 @@
<x>0</x>
<y>0</y>
<width>496</width>
<height>343</height>
<height>345</height>
</rect>
</property>
<property name="caption">
@ -201,6 +201,9 @@
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="alignment">
<set>AlignCenter</set>
</property>
</widget>
</widget>
</grid>
@ -230,9 +233,6 @@
<slot>mBrowseDirectoriesButton_clicked()</slot>
</connection>
</connections>
<includes>
<include location="local" impldecl="in implementation">qgssimadialogbase.ui.h</include>
</includes>
<slots>
<slot>mScaleSpin_valueChanged( int )</slot>
<slot>mIconView_selectionChanged( QIconViewItem * )</slot>

347
src/qgsuvalmadialog.cpp Normal file
View File

@ -0,0 +1,347 @@
/***************************************************************************
qgsuvalmadialog.cpp - unique value marker dialog
-------------------
begin : September 2004
copyright : (C) 2004 by Lars Luthman
email : larsl@users.sourceforge.net
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsuvalmadialog.h"
#include "qgsdataprovider.h"
#include "qgsvectorlayer.h"
#include "qgsdlgvectorlayerproperties.h"
#include "qgsfeature.h"
#include "qgsfeatureattribute.h"
#include "qgssimadialog.h"
#include "qgssymbol.h"
#include "qgsmarkersymbol.h"
#include "qgssvgcache.h"
#include "qgsrenderitem.h"
#include "qgsuvalmarenderer.h"
#include <qwidgetstack.h>
#include <qlistbox.h>
#include <qcombobox.h>
#include <qpainter.h>
#include <cassert>
#include <list>
QgsUValMaDialog::QgsUValMaDialog(QgsVectorLayer* vl): QgsUValMaDialogBase(), mVectorLayer(vl), madialog(vl)
{
setSizeGripEnabled(true);
//find out the fields of mVectorLayer
QgsDataProvider *provider;
if (provider = mVectorLayer->getDataProvider())
{
std::vector < QgsField > &fields = provider->fields();
QString str;
for (std::vector < QgsField >::iterator it = fields.begin(); it != fields.end(); ++it)
{
str = (*it).name();
str = str.left(1).upper() + str.right(str.length() - 1); //make the first letter uppercase
mClassificationComboBox->insertItem(str);
}
}
else
{
qWarning("Warning, data provider is null in QgsUValDialog::QgsUValDialog");
return;
}
QObject::connect(mClassificationComboBox, SIGNAL(activated(int)), this, SLOT(changeClassificationAttribute(int)));
QObject::connect(mClassBreakBox, SIGNAL(selectionChanged()), this, SLOT(changeCurrentValue()));
QObject::connect(&madialog, SIGNAL(settingsChanged()), this, SLOT(applySymbologyChanges()));
mSymbolWidgetStack->addWidget(&madialog);
mSymbolWidgetStack->raiseWidget(&madialog);
//restore settings if unique value renderer was read from a project file
QgsUValMaRenderer *renderer;
//initial settings, use the buffer of the propertiesDialog if possible. If this is not possible, use the renderer of the vectorlayer directly
if (mVectorLayer->propertiesDialog())
{
renderer = dynamic_cast < QgsUValMaRenderer * >(mVectorLayer->propertiesDialog()->getBufferRenderer());
}
else
{
renderer = dynamic_cast < QgsUValMaRenderer * >(mVectorLayer->renderer());
}
if (renderer)
{
mClassBreakBox->clear();
std::list<int>::iterator iter=renderer->classificationAttributes().begin();
int classattr=*iter;
mClassificationComboBox->setCurrentItem(classattr);
mClassBreakBox->setCurrentItem(0);
changeClassificationAttribute(classattr);
}
}
QgsUValMaDialog::~QgsUValMaDialog()
{
for(std::map<QString,QgsRenderItem*>::iterator it=mValues.begin();it!=mValues.end();++it)
{
delete it->second;
it->second = NULL;
}
}
void QgsUValMaDialog::apply()
{
//font tor the legend text
QFont f("arial", 10, QFont::Normal);
QFontMetrics fm(f);
int symbolheight = 15; //height of an area where a symbol is painted
int symbolwidth = 15; //width of an area where a symbol is painted
int rowheight = (fm.height() > symbolheight) ? fm.height() : symbolheight; //height of a row in the symbology part
int topspace = 5;
int bottomspace = 5;
int leftspace = 5;
int rightspace = 5;
int rowspace = 5;
int wordspace = 5; //space between graphics/word
int widestvalue = 0;
int valuewidth;
//find out the width of the widest label and of the broadest value string
int maxlabelwidth=0;
int maxvaluewidth=0;
for(std::map<QString,QgsRenderItem*>::iterator it=mValues.begin();it!=mValues.end();++it)
{
int currentlabelwidth=fm.width(it->second->label());
if(currentlabelwidth>maxlabelwidth)
{
maxlabelwidth=currentlabelwidth;
}
int currentvwidth=fm.width(it->second->value());
if(currentvwidth>maxvaluewidth)
{
maxvaluewidth=currentvwidth;
}
}
QgsUValMaRenderer *renderer = dynamic_cast < QgsUValMaRenderer * >(mVectorLayer->renderer());
//go through mValues and add the entries to the renderer
int pixheight = topspace+2*fm.height()+rowspace;
if(renderer)
{
renderer->clearValues();
for(std::map<QString,QgsRenderItem*>::iterator it=mValues.begin();it!=mValues.end();++it)
{
QgsMarkerSymbol* symbol =
dynamic_cast<QgsMarkerSymbol*>(it->second->getSymbol());
QgsMarkerSymbol* newsymbol=new QgsMarkerSymbol();
newsymbol->setPicture(symbol->picture());
newsymbol->setScaleFactor(symbol->scaleFactor());
QgsRenderItem* ritem=new QgsRenderItem(newsymbol,it->first,"");
renderer->insertValue(it->first,ritem);
//find out the width of the string
valuewidth = fm.width(it->first);
if(valuewidth>widestvalue) {
widestvalue=valuewidth;
}
// add to the total height
QPixmap pm = QgsSVGCache::instance().
getPixmap(symbol->picture(), symbol->scaleFactor());
pixheight += ((rowheight > pm.height() ? rowheight : pm.height()) +
rowspace);
// find out the width of the symbols
if (pm.width() > symbolwidth)
symbolwidth = pm.width();
}
renderer->setClassificationField(mClassificationComboBox->currentItem());
}
else
{
#ifdef QGISDEBUG
qWarning("Warning, typecast failed in qgsuvaldialog.cpp, l. 61");
#endif
}
//render the legend item
QPixmap *pix = mVectorLayer->legendPixmap();
QString name;
QString field=mClassificationComboBox->currentText();
int fieldwidth=fm.width(field);
if(fieldwidth>widestvalue)
{
widestvalue=fieldwidth;
}
if (mVectorLayer->propertiesDialog())
{
name = mVectorLayer->propertiesDialog()->displayName();
}
else
{
name = "";
}
int namewidth=fm.width(name);
int pixwidth;
if(namewidth>widestvalue)
{
if(namewidth>(symbolwidth+wordspace+widestvalue+maxlabelwidth))
{
pixwidth = leftspace+wordspace+namewidth+rightspace;
}
else
{
pixwidth = leftspace+2*wordspace+symbolwidth+maxlabelwidth+widestvalue+rightspace;
}
}
else
{
pixwidth = leftspace+2*wordspace+symbolwidth+widestvalue+maxlabelwidth+rightspace;
}
pixheight += bottomspace;
pix->resize(pixwidth,pixheight);
pix->fill();
QPainter p(pix);
p.setFont(f);
//draw the layer name and the name of the classification field into the pixmap
p.drawText(leftspace, topspace + fm.height(), name);
p.drawText(leftspace, topspace + 2 * fm.height(), field);
// draw symbols and values for the different classes
int intermheight=topspace+2*fm.height()+rowspace;
int currentheight = intermheight;
for(std::map<QString,QgsRenderItem*>::iterator it=mValues.begin();it!=mValues.end();++it)
{
QgsMarkerSymbol* sym =
dynamic_cast<QgsMarkerSymbol*>(it->second->getSymbol());
QPixmap pm = QgsSVGCache::instance().getPixmap(sym->picture(),
sym->scaleFactor());
p.drawPixmap(leftspace + (symbolwidth - pm.width()) / 2,
currentheight, pm);
p.setPen(Qt::black);
p.drawText(leftspace+symbolwidth+wordspace, currentheight + rowheight,
it->first);
p.drawText(leftspace+symbolwidth+2*wordspace+widestvalue,
currentheight + rowheight, it->second->label());
currentheight += (rowheight > pm.height() ? rowheight : pm.height()) +
rowspace;
}
mVectorLayer->updateItemPixmap();
mVectorLayer->triggerRepaint();
}
void QgsUValMaDialog::changeClassificationAttribute(int nr)
{
#ifdef QGISDEBUG
qWarning("in changeClassificationAttribute, nr is: "+QString::number(nr));
#endif
//delete old entries
for(std::map<QString,QgsRenderItem*>::iterator it=mValues.begin();it!=mValues.end();++it)
{
delete it->second;
}
mValues.clear();
QgsDataProvider *provider = mVectorLayer->getDataProvider();
if (provider)
{
QString value;
std::list<int> attlist;
attlist.push_back(nr);
std::vector < QgsFeatureAttribute > vec;
QgsMarkerSymbol* symbol;
QgsRenderItem* ritemptr;
provider->reset();
QgsFeature* f;
//go through all the features and insert their value into the map and into mClassBreakBox
mClassBreakBox->clear();
while((f=provider->getNextFeature(attlist)))
{
vec = f->attributeMap();
value=vec[0].fieldValue();
if(mValues.find(value)==mValues.end())
{
symbol=new QgsMarkerSymbol();
ritemptr=new QgsRenderItem(symbol,"","");
mValues.insert(std::make_pair(value,ritemptr));
}
delete f;
}
//set symbology for all QgsSiMaDialogs
QColor thecolor;
double number=0;
double frac;
for(std::map<QString,QgsRenderItem*>::iterator it=mValues.begin();it!=mValues.end();++it)
{
// set all markers to svg/symbol/Cross4.svg with scale factor from
// 0.4 to 1.0
const double minSize = 0.4, maxSize = 1.0;
frac=number/mValues.size();
mClassBreakBox->insertItem(it->first);
QgsMarkerSymbol* sym =
dynamic_cast<QgsMarkerSymbol*>(it->second->getSymbol());
assert(sym != NULL);
sym->setPicture(QString(PKGDATAPATH) + "/svg/symbol/Cross4.svg");
sym->setScaleFactor(minSize + (maxSize - minSize) * frac);
++number;
}
}
mClassBreakBox->setCurrentItem(0);
}
void QgsUValMaDialog::changeCurrentValue()
{
QListBoxItem* item=mClassBreakBox->selectedItem();
QString value=item->text();
std::map<QString,QgsRenderItem*>::iterator it=mValues.find(value);
if(it!=mValues.end())
{
QgsMarkerSymbol* ms =
dynamic_cast<QgsMarkerSymbol*>(it->second->getSymbol());
assert(ms != NULL);
madialog.setMarker(ms->picture(), ms->scaleFactor());
}
else
{
//no entry found
}
}
void QgsUValMaDialog::applySymbologyChanges()
{
QListBoxItem* item=mClassBreakBox->selectedItem();
QString value=item->text();
std::map<QString,QgsRenderItem*>::iterator it=mValues.find(value);
if(it!=mValues.end())
{
QgsMarkerSymbol* ms = dynamic_cast<QgsMarkerSymbol*>(it->second->
getSymbol());
assert(ms != NULL);
std::cerr<<"madialog.getPicture() = "<<madialog.getPicture()<<std::endl;
ms->setPicture(madialog.getPicture());
ms->setScaleFactor(madialog.getScaleFactor());
}
}

59
src/qgsuvalmadialog.h Normal file
View File

@ -0,0 +1,59 @@
/***************************************************************************
qgsuvalmadialog.h - unique value marker dialog
-------------------
begin : September 2004
copyright : (C) 2004 by Lars Luthman
email : larsl@users.sourceforge.net
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSUVALMADIALOG_H
#define QGSUVALMADIALOG_H
#ifdef WIN32
#include "qgsuvalmadialogbase.h"
#else
#include "qgsuvalmadialogbase.uic.h"
#endif
#include "qgssimadialog.h"
#include <map>
class QgsVectorLayer;
class QgsRenderItem;
class QgsUValMaDialog: public QgsUValMaDialogBase
{
Q_OBJECT
public:
QgsUValMaDialog(QgsVectorLayer* vl);
~QgsUValMaDialog();
public slots:
void apply();
protected:
/**Pointer to the associated vector layer*/
QgsVectorLayer* mVectorLayer;
/**Set to store the already entered values*/
std::map<QString,QgsRenderItem*> mValues;
QgsSiMaDialog madialog;
/**Value for which symbology settings are displayed*/
QString currentValue;
protected slots:
/**Set new attribut for classification*/
void changeClassificationAttribute(int nr);
/**Changes the display of the single symbol dialog*/
void changeCurrentValue();
/**Writes changes in the single symbol dialog to the corresponding QgsSymbol*/
void applySymbologyChanges();
};
#endif

View File

@ -0,0 +1,90 @@
<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
<class>QgsUValMaDialogBase</class>
<widget class="QDialog">
<property name="name">
<cstring>QgsUValMaDialogBase</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>281</height>
</rect>
</property>
<property name="caption">
<string>Form1</string>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QLabel" row="0" column="0">
<property name="name">
<cstring>mClassVarLabel</cstring>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="text">
<string>Classification Field:</string>
</property>
</widget>
<widget class="QComboBox" row="0" column="1" rowspan="1" colspan="2">
<property name="name">
<cstring>mClassificationComboBox</cstring>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</widget>
<spacer row="0" column="3">
<property name="name">
<cstring>spacer7</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>210</width>
<height>21</height>
</size>
</property>
</spacer>
<widget class="QWidgetStack" row="1" column="0" rowspan="1" colspan="2">
<property name="name">
<cstring>mSymbolWidgetStack</cstring>
</property>
<widget class="QWidget">
<property name="name">
<cstring>WStackPage</cstring>
</property>
<attribute name="id">
<number>0</number>
</attribute>
</widget>
</widget>
<widget class="QListBox" row="1" column="2" rowspan="1" colspan="2">
<item>
<property name="text">
<string>New Item</string>
</property>
</item>
<property name="name">
<cstring>mClassBreakBox</cstring>
</property>
</widget>
</grid>
</widget>
<layoutdefaults spacing="6" margin="11"/>
</UI>

188
src/qgsuvalmarenderer.cpp Normal file
View File

@ -0,0 +1,188 @@
/***************************************************************************
qgsuvalmarenderer.cpp - unique value marker renderer
-------------------
begin : September 2004
copyright : (C) 2004 by Lars Luthman
email : larsl@users.sourceforge.net
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsdlgvectorlayerproperties.h"
#include "qgsuvalmarenderer.h"
#include "qgsuvalmadialog.h"
#include "qgsrenderitem.h"
#include "qgsfeatureattribute.h"
#include "qgsmarkersymbol.h"
#include "qgssvgcache.h"
#include "qgsfeature.h"
#include "qgsvectorlayer.h"
#include "qgssymbologyutils.h"
#include "qgsuvalmadialog.h"
#include <qdom.h>
#include <qpainter.h>
#include <vector>
QgsUValMaRenderer::QgsUValMaRenderer(): mClassificationField(0),mSelectionColor(QColor(255,255,0))
{
}
QgsUValMaRenderer::~QgsUValMaRenderer()
{
for(std::map<QString,QgsRenderItem*>::iterator it=mEntries.begin();it!=mEntries.end();++it)
{
delete it->second;
}
}
void QgsUValMaRenderer::initializeSymbology(QgsVectorLayer* layer, QgsDlgVectorLayerProperties* pr)
{
QgsUValMaDialog *dialog = new QgsUValMaDialog(layer);
if (pr)
{
pr->setBufferDialog(dialog);
}
else
{
layer->setRendererDialog(dialog);
}
}
void QgsUValMaRenderer::renderFeature(QPainter* p, QgsFeature* f,QPicture* pic, double* scalefactor, bool selected)
{
#ifdef QGISDEBUG
qWarning("in QgsUValMaRenderer::renderFeature");
#endif
p->setPen(Qt::NoPen);
p->setBrush(Qt::NoBrush);
std::vector < QgsFeatureAttribute > vec = f->attributeMap();
QString value = vec[0].fieldValue();
#ifdef QGISDEBUG
qWarning("Wert: "+value);
#endif
std::map<QString,QgsRenderItem*>::iterator it=mEntries.find(value);
if(it!=mEntries.end())
{
QgsRenderItem* ritem=it->second;
QgsMarkerSymbol* ms =static_cast<QgsMarkerSymbol*>(ritem->getSymbol());
QPainter painter(pic);
QPixmap pm = QgsSVGCache::instance().getPixmap(ms->picture(),
ms->scaleFactor());
painter.drawPixmap(0, 0, pm);
(*scalefactor) = 1;
if(selected) {
painter.setBrush(QColor(255,255,0));
painter.drawRect(0,0,pm.width(),pm.height());
}
}
else
{
#ifdef QGISDEBUG
qWarning("Warning, no render item found in QgsUValMaRenderer::renderFeature");
#endif
}
}
void QgsUValMaRenderer::readXML(const QDomNode& rnode, QgsVectorLayer& vl)
{
QDomNode classnode = rnode.namedItem("classificationfield");
int classificationfield = classnode.toElement().text().toInt();
this->setClassificationField(classificationfield);
QDomNode renderitemnode = rnode.namedItem("renderitem");
while (!renderitemnode.isNull())
{
QDomNode valuenode = renderitemnode.namedItem("value");
QString value = valuenode.toElement().text();
#ifdef QGISDEBUG
qWarning("readXML, value is "+value);
#endif
QgsMarkerSymbol* msy = new QgsMarkerSymbol();
QDomNode synode = renderitemnode.namedItem("markersymbol");
QString svgpath = "", scalefactor = "";
QDomNode svgnode = synode.namedItem("svgpath");
svgpath = svgnode.toElement().text();
QDomNode scalenode = synode.namedItem("scalefactor");
scalefactor = scalenode.toElement().text();
//create a renderitem and add it to the renderer
msy->setPicture(svgpath);
msy->setScaleFactor(scalefactor.toDouble());
QgsRenderItem *ri = new QgsRenderItem(msy, value, " ");
this->insertValue(value,ri);
renderitemnode = renderitemnode.nextSibling();
}
vl.setRenderer(this);
QgsUValMaDialog *uvalmadialog = new QgsUValMaDialog(&vl);
vl.setRendererDialog(uvalmadialog);
QgsDlgVectorLayerProperties *properties = new QgsDlgVectorLayerProperties(&vl);
vl.setLayerProperties(properties);
properties->setLegendType("Unique Value Marker");
uvalmadialog->apply();
}
void QgsUValMaRenderer::writeXML(std::ofstream& xml)
{
xml << "\t\t<uniquevaluemarker>\n";
xml << "\t\t\t<classificationfield>" << QString::number(this->classificationField()) +
"</classificationfield>\n";
for(std::map<QString,QgsRenderItem*>::iterator it=mEntries.begin();it!=mEntries.end();++it)
{
xml << "\t\t\t<renderitem>\n";
xml << "\t\t\t\t<value>" << it->first << "</value>\n";
xml << "\t\t\t\t<markersymbol>\n";
QgsMarkerSymbol *symbol =
dynamic_cast<QgsMarkerSymbol*>((it->second)->getSymbol());
xml << "\t\t\t\t\t<svgpath>" << symbol->picture() << "</svgpath>\n";
xml << "\t\t\t\t\t<scalefactor>" << symbol->scaleFactor()
<< "</scalefactor>\n";
xml << "\t\t\t\t</markersymbol>\n";
xml << "\t\t\t</renderitem>\n";
}
xml << "\t\t</uniquevaluemarker>\n";
}
void QgsUValMaRenderer::clearValues()
{
for(std::map<QString,QgsRenderItem*>::iterator it=mEntries.begin();it!=mEntries.end();++it)
{
delete it->second;
}
mEntries.clear();
}
QString QgsUValMaRenderer::name()
{
return "Unique Value";
}
std::list<int> QgsUValMaRenderer::classificationAttributes()
{
std::list<int> list;
list.push_back(mClassificationField);
return list;
}
std::map<QString,QgsRenderItem*>& QgsUValMaRenderer::items()
{
return mEntries;
}

85
src/qgsuvalmarenderer.h Normal file
View File

@ -0,0 +1,85 @@
/***************************************************************************
qgsuvalmarenderer.h - unique value marker renderer
-------------------
begin : September 2004
copyright : (C) 2004 by Lars Luthman
email : larsl@users.sourceforge.net
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSUVALMARENDERER_H
#define QGSUVALMARENDERER_H
#include "qgsrenderer.h"
#include <qcolor.h>
#include <map>
class QgsRenderItem;
class QgsUValMaRenderer: public QgsRenderer
{
public:
QgsUValMaRenderer();
~QgsUValMaRenderer();
void initializeSymbology(QgsVectorLayer* layer, QgsDlgVectorLayerProperties* pr=0);
void renderFeature(QPainter* p, QgsFeature* f,QPicture* pic, double* scalefactor, bool selected);
/**Reads the renderer configuration from an XML file
@param rnode the DOM node to read
@param vl the vector layer which will be associated with the renderer*/
void readXML(const QDomNode& rnode, QgsVectorLayer& vl);
/**Writes the contents of the renderer to a configuration file*/
void writeXML(std::ofstream& xml);
/** Returns true, if attribute values are used by the renderer and false otherwise*/
bool needsAttributes();
/**Returns a list with indexes of classification attributes*/
std::list<int> classificationAttributes();
/**Returns the renderers name*/
QString name();
/**Inserts an entry into mEntries. The render items have to be created with the new operator and are automatically destroyed if not needed anymore*/
void insertValue(QString name, QgsRenderItem* item);
/**Removes all entries from mEntries*/
void clearValues();
/**Sets the Field index used for classification*/
void setClassificationField(int field);
/**Returns the index of the classification field*/
int classificationField();
/**Returns the values*/
std::map<QString,QgsRenderItem*>& items();
protected:
/**Field index used for classification*/
int mClassificationField;
/**Entries for the unique values*/
std::map<QString,QgsRenderItem*> mEntries;
/**Colour used to render selected features*/
QColor mSelectionColor;
};
inline bool QgsUValMaRenderer::needsAttributes()
{
return true;
}
inline void QgsUValMaRenderer::insertValue(QString name, QgsRenderItem* item)
{
mEntries.insert(std::make_pair(name,item));
}
inline void QgsUValMaRenderer::setClassificationField(int field)
{
mClassificationField=field;
}
inline int QgsUValMaRenderer::classificationField()
{
return mClassificationField;
}
#endif