252 changes: 145 additions & 107 deletions doc/INSTALL.html

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions doc/SPONSORS
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Please consider sponsoring the development of QuantumGIS.
See: http://qgis.org/en/sponsorship.html

SILVER
State of Vorarlberg, Austria (11.2011)|http://www.vorarlberg.at/
Kanton Solothurn, Switzerland (4.2011)|http://www.agi.so.ch/

BRONZE
Expand Down
73 changes: 45 additions & 28 deletions doc/osx.t2t
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ In this approach I will try to avoid as much as possible building dependencies
from source and rather use frameworks wherever possible.

The base system here is Mac OS X 10.4 (__Tiger__), with a single architecture
build. Included are notes for building on Mac OS X 10.5 (__Leopard__) and 10.6
(__Snow Leopard__). Make sure to read each section completely before typing
the first command you see.
build. Included are notes for building on Mac OS X 10.5 (__Leopard__), 10.6
(__Snow Leopard__) and 10.7 (__Lion__).
Make sure to read each section completely before typing the first command you see.

__General note on Terminal usage:__ When I say "cd" to a folder in a Terminal,
it means type "cd " (without the quotes, make sure to type a space after) and
Expand Down Expand Up @@ -38,10 +38,12 @@ You need a minimum of Qt-4.4.0. I suggest getting the latest. There is no need
for the full Qt SDK, so save yourself some download time and get the frameworks
only.

__Snow Leopard note:__ If you are building on Snow Leopard, you will need to
decide between 32-bit support in the older, Qt Carbon branch, or 64-bit
__Snow Leopard+ note:__ If you are building on Snow Leopard+, you will need to
decide between 32-bit support in the older Qt Carbon branch, or 64-bit
support in the Qt Cocoa branch. Appropriate installers are available for both
as of Qt-4.5.2. Qt 4.6+ is recommended for Cocoa.
as of Qt-4.5.2, though they stopped making Carbon packages at Qt 4.7.4.
Qt 4.6+ is recommended for Cocoa.
Starting with Lion, Carbon may not work properly, if at all.

__PPC note:__ The readymade Qt Cocoa installers don't include PPC support, you'd
have to compile Qt yourself. But, there appear to be issues with Qt Cocoa on
Expand Down Expand Up @@ -106,8 +108,8 @@ have problems and you are on your own with those.

=== Additional Dependencies: Expat ===

__Snow Leopard note:__ Snow Leopard includes a usable expat, so this step is
not necessary on Snow Leopard.
__Snow Leopard+ note:__ Snow Leopard includes a usable expat, so this step is
not necessary on Snow Leopard or Lion.

Get the expat sources:

Expand All @@ -124,10 +126,10 @@ sudo make install

=== Additional Dependencies: Python ===

__Leopard and Snow Leopard note:__ Leopard and Snow Leopard include a usable
Python 2.5 and 2.6, respectively. So there is no need to install Python on
Leopard and Snow Leopard. You can still install Python from python.org if
preferred.
__Leopard+ note:__ Starting with Leopard a usable Python is included
in the system. This Python 2.5, 2.6 and 2.7, respectively for Leo, Snow and Lion.
So there is no need to install Python on Leopard and newer.
You can still install Python from python.org if preferred.

If installing from python.org, make sure you install at least the latest Python
2.x from
Expand Down Expand Up @@ -164,12 +166,13 @@ python configure.py -n -d /Library/Python/2.5/site-packages -b /usr/local/bin \
-e /usr/local/include -v /usr/local/share/sip -s MacOSX10.5.sdk
```

__Snow Leopard system Python__
__Snow Leopard+ system Python__

Similar to Leopard, you should install outside the system Python path.
Also, you need to specify the architecture you want (requires at least SIP
4.9), and make sure to run the versioned python binary (this one responds to
the 'arch' command, 'python' does not).
Substitute '2.7' for python version and 10.7 for SDK version below for Lion.

If you are using 32-bit Qt (Qt Carbon):

Expand Down Expand Up @@ -219,12 +222,13 @@ More configuration is needed to install outside the system path:
python configure.py -d /Library/Python/2.5/site-packages -b /usr/local/bin
```

__Snow Leopard system Python__
__Snow Leopard+ system Python__

Similar to Leopard, you should install outside the system Python path.
Also, you need to specify the architecture you want (requires at least PyQt 4.6),
and make sure to run the versioned python binary (this one responds to the
'arch' command, which is important for pyuic4, 'python' does not).
Substitute '2.7' for python version and 10.7 for SDK version below for Lion.

If you are using 32-bit Qt (Qt Carbon):

Expand Down Expand Up @@ -304,7 +308,7 @@ sudo make install

Make sure to use the qwt install path from the Qwt build above.

__Snow Leopard note__
__Snow Leopard+ note__

If using Qt Carbon, you need to specify which architectures to build, otherwise
it will default to a combination that does not work (ie x86_64 for a Carbon Qt).
Expand All @@ -319,21 +323,18 @@ python configure.py --extra-cflags="-arch i386" --extra-cxxflags="-arch i386" \

=== Additional Dependencies: Bison ===

__Leopard and Snow Leopard note:__ Leopard and Snow Leopard include Bison 2.3,
so this step can be skipped on Leopard and Snow Leopard.

The version of bison available by default on Mac OS X 10.4 is too old so you
need to get a more recent one on your system. Download at least version 2.3 from:
The version of bison available by default on Mac OS X is too old so you
need to get a more recent one on your system. Download at least version 2.4 from:

```
ftp.gnu.org/gnu/bison/
```

Now build and install it to a prefix of /usr/local.ďż˝ Double-click the source
Now build and install it to a prefix of /usr/local. Double-click the source
tarball to unpack it, then cd to the source folder and:

```
./configure --prefix=/usr/local
./configure --disable-dependency-tracking CFLAGS=-Os
make
sudo make install
```
Expand All @@ -346,8 +347,9 @@ http://www.cmake.org/cmake/resources/software.html

Binary installers are available for OS X, but they are not recommended
(2.4 versions install in /usr instead of /usr/local, and 2.6+ versions are a
strange application). Instead, download the source, double-click the source
tarball, then cd to the source folder and:
strange application). Instead, download the source.
NOTE: 2.8.5 is broken for detecting part of Qt. Fixed in 2.8.6.
Double-click the source tarball, then cd to the source folder and:

```
./bootstrap --docdir=/share/doc/CMake --mandir=/share/man
Expand Down Expand Up @@ -378,17 +380,18 @@ CMake supports out of source build so we will create a 'build' dir for the
build process. OS X uses ${HOME}/Applications as a standard user app folder (it
gives it the system app folder icon). If you have the correct permissions you
may want to build straight into your /Applications folder. The instructions
below assume you are building into a pre-existing ${HOME}/Applications directory.
below assume you are building into a ${HOME}/Applications directory.
In a Terminal cd to the qgis source folder previously downloaded, then:

```
mkdir build
cd build
cmake -D CMAKE_INSTALL_PREFIX=~/Applications \
-D CMAKE_BUILD_TYPE=MinSizeRel \
-D WITH_INTERNAL_SPATIALITE=FALSE -D WITH_MAPSERVER=TRUE \
-D WITH_INTERNAL_SPATIALITE=FALSE \
-D QWT_LIBRARY=/usr/local/qwt-5.2.1-svn/lib/libqwt.dylib \
-D QWT_INCLUDE_DIR=/usr/local/qwt-5.2.1-svn/include \
-D BISON_EXECUTABLE=/usr/local/bin/bison \
..
```

Expand All @@ -402,10 +405,11 @@ path and version as required):
```
cmake -D CMAKE_INSTALL_PREFIX=~/Applications -D CMAKE_BUILD_TYPE=Release \
-D CMAKE_BUILD_TYPE=MinSizeRel \
-D WITH_INTERNAL_SPATIALITE=FALSE -D WITH_MAPSERVER=TRUE \
-D WITH_INTERNAL_SPATIALITE=FALSE \
-D QWT_LIBRARY=/usr/local/qwt-5.2.1-svn/lib/libqwt.dylib \
-D QWT_INCLUDE_DIR=/usr/local/qwt-5.2.1-svn/include \
-D GRASS_PREFIX=/user/local/grass-6.4.1 \
-D BISON_EXECUTABLE=/usr/local/bin/bison \
..
```

Expand All @@ -422,13 +426,26 @@ sudo chmod +x /usr/local/bin/python32

cmake -D CMAKE_INSTALL_PREFIX=~/Applications -D \
-D CMAKE_BUILD_TYPE=MinSizeRel \
-D WITH_INTERNAL_SPATIALITE=FALSE -D WITH_MAPSERVER=TRUE \
-D WITH_INTERNAL_SPATIALITE=FALSE \
-D QWT_LIBRARY=/usr/local/qwt-5.2.1-svn/lib/libqwt.dylib \
-D QWT_INCLUDE_DIR=/usr/local/qwt-5.2.1-svn/include \
-D BISON_EXECUTABLE=/usr/local/bin/bison \
-D CMAKE_OSX_ARCHITECTURES=i386 -D PYTHON_EXECUTABLE=/usr/local/bin/python32 \
..
```

The Qgis Mapserver feature requires fastcgi support. This is included in
Leopard and Snow Leopard, but was dropped at Lion. To build the Mapserver
component on Leopard and Snow, add the followling line before the last line in
the above configuration:

```
-D WITH_MAPSERVER=TRUE \
```

On Lion you are on your own to figure out how to install libfcgi and add fcgi
support to the system Apache. Not recommended for the average user.

__Bundling note:__ Older Qt versions may have problems with some Qt plugins and
Qgis. The way to handle this is to bundle Qt inside the Qgis application. You
can do this now or wait to see if there are immediate crashes when running Qgis.
Expand Down
2,532 changes: 1,360 additions & 1,172 deletions i18n/qgis_de.ts

Large diffs are not rendered by default.

8,051 changes: 5,031 additions & 3,020 deletions i18n/qgis_fr.ts

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions i18n/qgis_it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1807,7 +1807,7 @@ http://trac.faunalia.it/GdalTools-plugin</source>
<translation>GDAL Tools (noto anche come Raster Tools) è un plugin per QuantumGIS che facilita l&apos;utilizzo di GDAL, fornendo un&apos;interfaccia grafica semplificata per i programmi più utilizzati.

Il plugin è sviluppato da Faunalia (http://faunalia.it) in collaborazione con GIS-lab (http://gis-lab.info).
Icone realizzare da Robert Szczepanek.
Icone realizzate da Robert Szczepanek.
Si ringrazia Silvio Grosso per la sponsorizzazione.

Aiutateci a testare il plugin, informandoci sui eventuali bug, migliorando il codice o supportandoci economicamente.
Expand Down Expand Up @@ -14793,7 +14793,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../src/plugins/delimited_text/qgsdelimitedtextpluginguibase.ui" line="275"/>
<source>Start import at row</source>
<translation>Inizia l&apos;importazione dalla colonna</translation>
<translation>Inizia l&apos;importazione dalla riga</translation>
</message>
<message>
<location filename="../src/plugins/delimited_text/qgsdelimitedtextpluginguibase.ui" line="293"/>
Expand Down Expand Up @@ -22434,7 +22434,7 @@ Può essere o un problema della propria connessione di rete o sul lato del serve
<message>
<location filename="../src/app/qgsmaptoolsimplify.cpp" line="302"/>
<source>This feature cannot be simplified. Check if feature has enough vertices to be simplified.</source>
<translation>Questa geometria non può essere semplificata. Verificare se la geometria ha abbastanza vertifici per la semplificazione.</translation>
<translation>Questa geometria non può essere semplificata. Verificare se la geometria ha abbastanza vertici per la semplificazione.</translation>
</message>
</context>
<context>
Expand Down
39,597 changes: 39,597 additions & 0 deletions i18n/qgis_no.ts

Large diffs are not rendered by default.

Binary file modified images/splash/splash.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/splash/splash.xcf.bz2
Binary file not shown.
57 changes: 18 additions & 39 deletions mac/cmake/1qt.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -14,45 +14,19 @@ SET (QT_FWVER @QT_VERSION_MAJOR@)

# build list of Qt frameworks to bundle

SET (QTLISTQG QtCore QtGui phonon)
SET (PYQTLIST Qt QtCore QtGui phonon)
IF (@QT_USE_QTXML@)
SET (QTLISTQG ${QTLISTQG} QtXml)
SET (PYQTLIST ${PYQTLIST} QtXml)
ENDIF (@QT_USE_QTXML@)
IF (@QT_USE_QTNETWORK@)
SET (QTLISTQG ${QTLISTQG} QtNetwork)
SET (PYQTLIST ${PYQTLIST} QtNetwork)
ENDIF (@QT_USE_QTNETWORK@)
IF (@QT_USE_QTSVG@)
SET (QTLISTQG ${QTLISTQG} QtSvg)
SET (PYQTLIST ${PYQTLIST} QtSvg)
ENDIF (@QT_USE_QTSVG@)
IF (@QT_USE_QTSQL@)
SET (QTLISTQG ${QTLISTQG} QtSql)
SET (PYQTLIST ${PYQTLIST} QtSql)
ENDIF (@QT_USE_QTSQL@)
IF (@QT_USE_QTWEBKIT@)
SET (QTLISTQG ${QTLISTQG} QtWebKit)
SET (PYQTLIST ${PYQTLIST} QtWebKit)
# see if it links QtDBus
EXECUTE_PROCESS (COMMAND otool -L @QT_QTWEBKIT_LIBRARY@/QtWebKit
OUTPUT_VARIABLE QTWEBKIT_DBUS)
IF (QTWEBKIT_DBUS MATCHES ".*QtDBus.framework.*")
SET (QTLISTQG ${QTLISTQG} QtDBus)
ENDIF ()
# see if it links QtXmlPatterns
EXECUTE_PROCESS (COMMAND otool -L @QT_QTWEBKIT_LIBRARY@/QtWebKit
OUTPUT_VARIABLE QTWEBKIT_XMLP)
IF (QTWEBKIT_XMLP MATCHES ".*QtXmlPatterns.framework.*")
SET (QTLISTQG ${QTLISTQG} QtXmlPatterns)
SET (PYQTLIST ${PYQTLIST} QtXmlPatterns)
ENDIF ()
ENDIF (@QT_USE_QTWEBKIT@)
IF (@OSGEARTH_FOUND@)
SET (QTLISTQG ${QTLISTQG} QtOpenGL)
SET (PYQTLIST ${PYQTLIST} QtOpenGL)
ENDIF (@OSGEARTH_FOUND@)
# core list, includes dependencies
SET (QTLISTQG QtCore QtGui phonon QtXml QtNetwork QtSvg QtSql QtWebKit QtXmlPatterns)
SET (PYQTLIST Qt QtCore QtGui phonon QtXml QtNetwork QtSvg QtSql QtWebKit QtXmlPatterns)
# see if QtWebKit links QtDBus
EXECUTE_PROCESS (COMMAND otool -L @QT_QTWEBKIT_LIBRARY@/QtWebKit
OUTPUT_VARIABLE QTWEBKIT_DBUS)
IF (QTWEBKIT_DBUS MATCHES ".*QtDBus.framework.*")
SET (QTLISTQG ${QTLISTQG} QtDBus)
ENDIF ()
# additional Qt may be needed by plugins
SET (QTLISTQG ${QTLISTQG} QtMultimedia QtOpenGL)
SET (PYQTLIST ${PYQTLIST} QtMultimedia QtOpenGL)

MYMESSAGE ("Qt list: ${QTLISTQG}")

# symlinks when only @executable_path used
Expand Down Expand Up @@ -89,6 +63,10 @@ FOREACH (QTC cn;jp;kr;tw)
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QT_PLUGINS_DIR@/codecs/libq${QTC}codecs.dylib" "${QAPPDIRC}/PlugIns/codecs/libq${QTC}codecs.dylib")
ENDIF ()
ENDFOREACH (QTC)
EXECUTE_PROCESS (COMMAND mkdir -p "${QAPPDIRC}/PlugIns/sqldrivers")
IF (NOT EXISTS "${QAPPDIRC}/PlugIns/sqldrivers/libqsqlite.dylib")
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QT_PLUGINS_DIR@/sqldrivers/libqsqlite.dylib" "${QAPPDIRC}/PlugIns/sqldrivers/libqsqlite.dylib")
ENDIF ()

# Qwt
# assumes shared libraries
Expand Down Expand Up @@ -192,6 +170,7 @@ FOREACH (QFW ${QTLISTQG})
FOREACH (QC cn;jp;kr;tw)
INSTALLNAMETOOL_CHANGE (${QFW_CHG} ${QFW_CHG_TO} "${QAPPDIRC}/PlugIns/codecs/libq${QC}codecs.dylib")
ENDFOREACH (QC)
INSTALLNAMETOOL_CHANGE (${QFW_CHG} ${QFW_CHG_TO} "${QAPPDIRC}/PlugIns/sqldrivers/libqsqlite.dylib")
# qt fw
IF (@OSX_HAVE_LOADERPATH@)
SET (QFW_CHG_TO "${ATLOADER}/../../../${LIBPOST}")
Expand Down
4 changes: 4 additions & 0 deletions ms-windows/osgeo4w/package-nightly.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ echo ALL_BUILD: %DATE% %TIME%>>%LOG% 2>&1
%DEVENV% qgis%VERSION%.sln /Project ALL_BUILD /Build %BUILDCONF% /Out %LOG%>>%LOG% 2>&1
if errorlevel 1 goto error

echo RUN_TESTS: %DATE% %TIME%>>%LOG% 2>&1
%DEVENV% qgis%VERSION%.sln /Project RUN_TESTS /Build %BUILDCONF% /Out %LOG%>>%LOG% 2>&1
if errorlevel 1 echo "TESTS WERE NOT SUCCESSFUL."

echo INSTALL: %DATE% %TIME%>>%LOG% 2>&1
%DEVENV% qgis%VERSION%.sln /Project INSTALL /Build %BUILDCONF% /Out %LOG%>>%LOG% 2>&1
if errorlevel 1 goto error
Expand Down
7 changes: 6 additions & 1 deletion python/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
ADD_SUBDIRECTORY(plugins)


SET (PYTHON_OUTPUT_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/python)
SET (QGIS_PYTHON_OUTPUT_DIRECTORY ${PYTHON_OUTPUT_DIRECTORY}/qgis)

Expand Down Expand Up @@ -99,6 +98,12 @@ SET (QGIS_PYTHON_DIR ${PYTHON_SITE_PACKAGES_DIR}/qgis)

ADD_CUSTOM_TARGET(compile_python_files ALL)

ADD_CUSTOM_COMMAND(TARGET compile_python_files
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${QGIS_PYTHON_OUTPUT_DIRECTORY}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

FOREACH(file __init__.py utils.py console.py)
ADD_CUSTOM_COMMAND(TARGET compile_python_files
POST_BUILD
Expand Down
1 change: 1 addition & 0 deletions python/core/core.sip
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
%Include qgsuniquevaluerenderer.sip
%Include qgsattributeaction.sip
%Include qgsvectordataprovider.sip
%Include qgsvectorfieldsymbollayer.sip
%Include qgsvectorfilewriter.sip
%Include qgsvectorlayer.sip
%Include qgsvectorlayerimport.sip
Expand Down
60 changes: 60 additions & 0 deletions python/core/qgsvectorfieldsymbollayer.sip
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
class QgsVectorFieldSymbolLayer: QgsMarkerSymbolLayerV2
{
%TypeHeaderCode
#include <qgsvectorfieldsymbollayer.h>
%End
public:
enum VectorFieldType
{
Cartesian = 0,
Polar,
Height
};

enum AngleOrientation
{
ClockwiseFromNorth = 0,
CounterclockwiseFromEast
};

enum AngleUnits
{
Degrees = 0,
Radians
};

QgsVectorFieldSymbolLayer();
~QgsVectorFieldSymbolLayer();

static QgsSymbolLayerV2* create( const QgsStringMap& properties );

QString layerType() const;

bool setSubSymbol( QgsSymbolV2* symbol );
QgsSymbolV2* subSymbol();

void renderPoint( const QPointF& point, QgsSymbolV2RenderContext& context );
void startRender( QgsSymbolV2RenderContext& context );
void stopRender( QgsSymbolV2RenderContext& context );

QgsSymbolLayerV2* clone() const;
QgsStringMap properties() const;

void drawPreviewIcon( QgsSymbolV2RenderContext& context, QSize size );

QSet<QString> usedAttributes() const;

//setters and getters
void setXAttribute( const QString& attribute );
QString xAttribute() const;
void setYAttribute( const QString& attribute );
QString yAttribute() const;
void setScale( double s );
double scale() const;
void setVectorFieldType( VectorFieldType type );
VectorFieldType vectorFieldType() const;
void setAngleOrientation( AngleOrientation orientation );
AngleOrientation angleOrientation() const;
void setAngleUnits( AngleUnits units );
AngleUnits angleUnits() const;
};
17 changes: 14 additions & 3 deletions python/core/symbology-ng-core.sip
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,16 @@ class QgsSymbolLayerV2
%ConvertToSubClassCode
switch (sipCpp->type())
{
case QgsSymbolV2::Marker: sipClass = sipClass_QgsMarkerSymbolLayerV2; break;
case QgsSymbolV2::Marker:
if( sipCpp->layerType() == "VectorField" )
{
sipClass = sipClass_QgsVectorFieldSymbolLayer;
}
else
{
sipClass = sipClass_QgsMarkerSymbolLayerV2;
}
break;
case QgsSymbolV2::Line: sipClass = sipClass_QgsLineSymbolLayerV2; break;
case QgsSymbolV2::Fill: sipClass = sipClass_QgsFillSymbolLayerV2; break;
default: sipClass = 0; break;
Expand Down Expand Up @@ -630,6 +639,9 @@ class QgsSymbolV2RenderContext
void setFeature( const QgsFeature* f );
const QgsFeature* feature() const;

void setLayer( const QgsVectorLayer* layer );
const QgsVectorLayer* layer() const;

// Color used for selections
static QColor selectionColor();

Expand Down Expand Up @@ -708,8 +720,7 @@ public:
//! delete layer at specified index and set a new one
bool changeSymbolLayer(int index, QgsSymbolLayerV2* layer /Transfer/);


void startRender(QgsRenderContext& context);
void startRender( QgsRenderContext& context, const QgsVectorLayer* layer = 0 );
void stopRender(QgsRenderContext& context);

void setColor(const QColor& color);
Expand Down
11 changes: 11 additions & 0 deletions python/plugins/GdalTools/GdalTools.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,12 @@ def initGui( self ):
QObject.connect( self.nearBlack, SIGNAL( "triggered()" ), self.doNearBlack )
self.analysisMenu.addAction( self.nearBlack )

if self.GdalVersion >= "1.7":
self.fillNodata = QAction( QIcon(":/icons/fillnodata.png"), QCoreApplication.translate( "GdalTools", "Fill nodata" ), self.iface.mainWindow() )
self.fillNodata.setStatusTip( QCoreApplication.translate( "GdalTools", "Fill raster regions by interpolation from edges") )
QObject.connect( self.fillNodata, SIGNAL( "triggered()" ), self.doFillNodata )
self.analysisMenu.addAction( self.fillNodata )

if self.GdalVersion >= "1.6":
self.proximity = QAction( QIcon(":/icons/proximity.png"), QCoreApplication.translate( "GdalTools", "Proximity (Raster distance)" ), self.iface.mainWindow() )
self.proximity.setStatusTip( QCoreApplication.translate( "GdalTools", "Produces a raster proximity map") )
Expand Down Expand Up @@ -295,6 +301,11 @@ def doNearBlack( self ):
d = NearBlack( self.iface )
self.runToolDialog( d )

def doFillNodata( self ):
from tools.doFillNodata import GdalToolsDialog as FillNodata
d = FillNodata( self.iface )
self.runToolDialog( d )

def doWarp( self ):
from tools.doWarp import GdalToolsDialog as Warp
d = Warp( self.iface )
Expand Down
Binary file added python/plugins/GdalTools/icons/fillnodata.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions python/plugins/GdalTools/resources.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<file>icons/about.png</file>
<file>icons/dem.png</file>
<file>icons/projection-export.png</file>
<file>icons/fillnodata.png</file>
<file>icons/edit.png</file>
<file>icons/reset.png</file>
</qresource>
Expand Down
215 changes: 215 additions & 0 deletions python/plugins/GdalTools/tools/doFillNodata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
# -*- coding: utf-8 -*-
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *

from ui_widgetFillNodata import Ui_GdalToolsWidget as Ui_Widget
from widgetBatchBase import GdalToolsBaseBatchWidget as BaseBatchWidget
import GdalTools_utils as Utils

import os.path

class GdalToolsDialog( QWidget, Ui_Widget, BaseBatchWidget ):
def __init__( self, iface ):
QWidget.__init__( self )
self.iface = iface

self.setupUi( self )
BaseBatchWidget.__init__( self, self.iface, "gdal_fillnodata.py" )

self.inSelector.setType( self.inSelector.FILE_LAYER )
self.outSelector.setType( self.outSelector.FILE )
self.maskSelector.setType( self.maskSelector.FILE )

self.progressBar.setValue(0)
self.progressBar.hide()
self.formatLabel.hide()
self.formatCombo.hide()

self.outputFormat = Utils.fillRasterOutputFormat()

self.setParamsStatus(
[
( self.inSelector, SIGNAL( "filenameChanged()" ) ),
( self.outSelector, SIGNAL( "filenameChanged()" ) ),
( self.maskSelector, SIGNAL( "filenameChanged()" ), self.maskCheck ),
( self.distanceSpin, SIGNAL( "valueChanged( int )" ), self.distanceCheck ),
( self.smoothSpin, SIGNAL( "valueChanged( int )" ), self.smoothCheck ),
( self.bandSpin, SIGNAL( "valueChanged( int )" ), self.bandCheck ),
( self.nomaskCheck, SIGNAL( "stateChanged( int )" ) )
]
)

self.connect( self.inSelector, SIGNAL( "selectClicked()" ), self.fillInputFile )
self.connect( self.outSelector, SIGNAL( "selectClicked()" ), self.fillOutputFile)
self.connect( self.maskSelector, SIGNAL( "selectClicked()" ), self.fillMaskFile)
self.connect( self.batchCheck, SIGNAL( "stateChanged( int )" ), self.switchToolMode )

# add raster filters to combo
self.formatCombo.addItems( Utils.FileFilter.allRastersFilter().split( ";;" ) )


def switchToolMode( self ):
self.setCommandViewerEnabled( not self.batchCheck.isChecked() )
self.progressBar.setVisible( self.batchCheck.isChecked() )
self.formatLabel.setVisible( self.batchCheck.isChecked() )
self.formatCombo.setVisible( self.batchCheck.isChecked() )

self.inSelector.setType( self.inSelector.FILE if self.batchCheck.isChecked() else self.inSelector.FILE_LAYER )
self.outSelector.clear()

if self.batchCheck.isChecked():
self.inFileLabel = self.label.text()
self.outFileLabel = self.label_1.text()
self.label.setText( QCoreApplication.translate( "GdalTools", "&Input directory" ) )
self.label_1.setText( QCoreApplication.translate( "GdalTools", "&Output directory" ) )

QObject.disconnect( self.inSelector, SIGNAL( "selectClicked()" ), self.fillInputFile )
QObject.disconnect( self.outSelector, SIGNAL( "selectClicked()" ), self.fillOutputFile )

QObject.connect( self.inSelector, SIGNAL( "selectClicked()" ), self. fillInputDir )
QObject.connect( self.outSelector, SIGNAL( "selectClicked()" ), self.fillOutputDir )
else:
self.label.setText( self.inFileLabel )
self.label_1.setText( self.outFileLabel )

QObject.disconnect( self.inSelector, SIGNAL( "selectClicked()" ), self.fillInputDir )
QObject.disconnect( self.outSelector, SIGNAL( "selectClicked()" ), self.fillOutputDir )

QObject.connect( self.inSelector, SIGNAL( "selectClicked()" ), self.fillInputFile )
QObject.connect( self.outSelector, SIGNAL( "selectClicked()" ), self.fillOutputFile )

def fillInputFile( self ):
lastUsedFilter = Utils.FileFilter.lastUsedRasterFilter()
inputFile = Utils.FileDialog.getOpenFileName( self,
self.tr( "Select the files to analyse" ),
Utils.FileFilter.allRastersFilter(),
lastUsedFilter )
if inputFile.isEmpty():
return
Utils.FileFilter.setLastUsedRasterFilter( lastUsedFilter )
self.inSelector.setFilename( inputFile )

def fillOutputFile( self ):
lastUsedFilter = Utils.FileFilter.lastUsedRasterFilter()
outputFile = Utils.FileDialog.getSaveFileName( self, self.tr( "Select the raster file to save the results to" ), Utils.FileFilter.allRastersFilter(), lastUsedFilter )
if outputFile.isEmpty():
return
Utils.FileFilter.setLastUsedRasterFilter( lastUsedFilter )

self.outputFormat = Utils.fillRasterOutputFormat( lastUsedFilter, outputFile )
self.outSelector.setFilename( outputFile )

def fillMaskFile( self ):
lastUsedFilter = Utils.FileFilter.lastUsedRasterFilter()
inputFile = Utils.FileDialog.getOpenFileName( self,
self.tr( "Select the files to analyse" ),
Utils.FileFilter.allRastersFilter(),
lastUsedFilter )
if inputFile.isEmpty():
return
Utils.FileFilter.setLastUsedRasterFilter( lastUsedFilter )
self.maskSelector.setFilename( inputFile )

def fillInputDir( self ):
inputDir = Utils.FileDialog.getExistingDirectory( self, self.tr( "Select the input directory with files" ))
if inputDir.isEmpty():
return
self.inSelector.setFilename( inputDir )

def fillOutputDir( self ):
outputDir = Utils.FileDialog.getExistingDirectory( self, self.tr( "Select the output directory to save the results to" ) )
if outputDir.isEmpty():
return
self.outSelector.setFilename( outputDir )

def getArguments(self):
arguments = QStringList()
maskFile = self.maskSelector.filename()
if self.distanceCheck.isChecked() and self.distanceSpin.value() != 0:
arguments << "-md"
arguments << self.distanceSpin.text()
if self.smoothCheck.isChecked() and self.smoothSpin.value() != 0:
arguments << "-si"
arguments << str( self.smoothSpin.value() )
if self.bandCheck.isChecked() and self.bandSpin.value() != 0:
arguments << "-b"
arguments << str( self.bandSpin.value() )
if self.maskCheck.isChecked() and not maskFile.isEmpty():
arguments << "-mask"
arguments << maskFile
if self.nomaskCheck.isChecked():
arguments << "-nomask"
if self.isBatchEnabled():
if self.formatCombo.currentIndex() != 0:
arguments << "-of"
arguments << Utils.fillRasterOutputFormat( self.formatCombo.currentText() )
return arguments
else:
outputFn = self.getOutputFileName()
if not outputFn.isEmpty():
arguments << "-of"
arguments << self.outputFormat
arguments << self.getInputFileName()
arguments << outputFn
return arguments

def onLayersChanged( self ):
self.inSelector.setLayers( Utils.LayerRegistry.instance().getRasterLayers() )

def getInputFileName(self):
return self.inSelector.filename()

def getOutputFileName(self):
return self.outSelector.filename()

def addLayerIntoCanvas(self, fileInfo):
self.iface.addRasterLayer(fileInfo.filePath())

def isBatchEnabled(self):
return self.batchCheck.isChecked()

def setProgressRange(self, maximum):
self.progressBar.setRange(0, maximum)

def updateProgress(self, index, total):
if index < total:
self.progressBar.setValue( index + 1 )
else:
self.progressBar.setValue( 0 )

def batchRun(self):
exts = self.formatCombo.currentText().remove( QRegExp('^.*\(') ).remove( QRegExp('\).*$') ).split( " " )
if not exts.isEmpty() and exts != "*" and exts != "*.*":
outExt = exts[ 0 ].remove( "*" )
else:
outExt = ".tif"

self.base.enableRun( False )
self.base.setCursor( Qt.WaitCursor )

inDir = self.getInputFileName()
outDir = self.getOutputFileName()

extensions = Utils.getRasterExtensions()
workDir = QDir( inDir )
workDir.setFilter( QDir.Files | QDir.NoSymLinks | QDir.NoDotAndDotDot )
workDir.setNameFilters( extensions )
files = workDir.entryList()

self.inFiles = []
self.outFiles = []

for f in files:
self.inFiles.append( inDir + "/" + f )
if outDir != None:
outFile = f.replace( QRegExp( "\.[a-zA-Z0-9]{2,4}" ), outExt )
self.outFiles.append( outDir + "/" + outFile )

self.errors = QStringList()
self.batchIndex = 0
self.batchTotal = len( self.inFiles )
self.setProgressRange( self.batchTotal )

self.runItem( self.batchIndex, self.batchTotal )
33 changes: 22 additions & 11 deletions python/plugins/GdalTools/tools/doProjection.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,6 @@ def __init__( self, iface ):
self.connect( self.batchCheck, SIGNAL( "stateChanged( int )" ), self.switchToolMode )
self.connect( self.recurseCheck, SIGNAL( "stateChanged( int )" ), self.enableRecurse )

#QObject.disconnect( self.base.buttonBox.button( QDialogButtonBox.Ok ), SIGNAL( "clicked()" ), self.onRun )
#QObject.connect( self.base.buttonBox.button( QDialogButtonBox.Ok ), SIGNAL( "clicked()" ), self.checkLayer )

def switchToolMode( self ):
self.setCommandViewerEnabled( not self.batchCheck.isChecked() )
self.progressBar.setVisible( self.batchCheck.isChecked() )
Expand Down Expand Up @@ -102,11 +99,32 @@ def getArguments( self ):
inputFn = self.getInputFileName()
arguments << inputFn
self.tempFile = QString( inputFn )
self.needOverwrite = False
if not self.tempFile.isEmpty():
self.tempFile = self.tempFile.replace( QRegExp( "\.[a-zA-Z]{2,4}$" ), ".tif" ).append( ".tmp" )
if self.tempFile.toLower().contains( QRegExp( "\.tif{1,2}" ) ):
self.tempFile = self.tempFile.replace( QRegExp( "\.[a-zA-Z]{2,4}$" ), ".tif" ).append( ".tmp" )
self.needOverwrite = True
else:
self.tempFile = self.tempFile.replace( QRegExp( "\.[a-zA-Z]{2,4}$" ), ".tif" )
arguments << self.tempFile
return arguments

def finished( self ):
outFn = self.getOutputFileName()
if self.needOverwrite:
oldFile = QFile( outFn )
newFile = QFile( self.tempFile )
if oldFile.remove():
newFile.rename( outFn )

fileInfo = QFileInfo( outFn )
if fileInfo.exists():
if self.base.loadCheckBox.isChecked():
self.addLayerIntoCanvas( fileInfo )
QMessageBox.information( self, self.tr( "Finished" ), self.tr( "Processing completed." ) )
else:
QMessageBox.warning( self, self.tr( "Warning" ), self.tr( "%1 not created." ).arg( outFn ) )

def getInputFileName(self):
return self.inSelector.filename()

Expand Down Expand Up @@ -149,10 +167,3 @@ def updateProgress(self, index, total):
self.progressBar.setValue(index + 1)
else:
self.progressBar.setValue(0)

def finished( self ):
oldFile = QFile( self.getInputFileName() )
newFile = QFile( self.tempFile )
if oldFile.remove():
newFile.rename( self.getInputFileName() )

159 changes: 159 additions & 0 deletions python/plugins/GdalTools/tools/widgetFillNodata.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GdalToolsWidget</class>
<widget class="QWidget" name="GdalToolsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>368</width>
<height>300</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Fill Nodata</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="batchCheck">
<property name="text">
<string>Batch mode (for processing whole directory)</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>&amp;Input Layer</string>
</property>
<property name="buddy">
<cstring>inSelector</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="GdalToolsInOutSelector" name="inSelector" native="true"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_1">
<property name="text">
<string>&amp;Output file</string>
</property>
<property name="buddy">
<cstring>outSelector</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="GdalToolsInOutSelector" name="outSelector" native="true"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="formatLabel">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="text">
<string>Output format</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="formatCombo">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="distanceCheck">
<property name="text">
<string>Search distance</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="distanceSpin">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000000</number>
</property>
<property name="value">
<number>100</number>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="smoothCheck">
<property name="text">
<string>Smooth iterations</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="smoothSpin">
<property name="minimum">
<number>0</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="bandCheck">
<property name="text">
<string>Band to operate on</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QSpinBox" name="bandSpin">
<property name="minimum">
<number>1</number>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="maskCheck">
<property name="text">
<string>Validity mask</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="GdalToolsInOutSelector" name="maskSelector" native="true"/>
</item>
<item row="8" column="0" colspan="2">
<widget class="QCheckBox" name="nomaskCheck">
<property name="text">
<string>Do not use the default validity mask</string>
</property>
</widget>
</item>
<item row="9" column="0" colspan="2">
<widget class="QProgressBar" name="progressBar"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>GdalToolsInOutSelector</class>
<extends>QWidget</extends>
<header>inOutSelector</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
Empty file modified python/plugins/fTools/__init__.py
100755 → 100644
Empty file.
32 changes: 25 additions & 7 deletions python/plugins/fTools/fTools.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
import doIntersectLines, doSelectByLocation, doVectorSplit, doMeanCoords
import doPointDistance, doPointsInPolygon, doRandom, doRandPoints, doRegPoints
import doSpatialJoin, doSubsetSelect, doSumLines, doVectorGrid, doMergeShapes
import doValidate, doSimplify, doDefineProj
import doValidate, doSimplify, doDefineProj, doSpatialIndex

class fToolsPlugin:
def __init__(self,iface):
Expand Down Expand Up @@ -103,6 +103,7 @@ def updateThemeIcons(self, theme):
self.voronoi.setIcon(QIcon(self.getThemeIcon("voronoi.png")))
self.extNodes.setIcon(QIcon(self.getThemeIcon("extract_nodes.png")))
self.simplify.setIcon(QIcon(self.getThemeIcon("simplify.png")))
self.densify.setIcon(QIcon(self.getThemeIcon("densify.png")))
self.multiToSingle.setIcon(QIcon(self.getThemeIcon("multi_to_single.png")))
self.singleToMulti.setIcon(QIcon(self.getThemeIcon("single_to_multi.png")))
self.polysToLines.setIcon(QIcon(self.getThemeIcon("to_lines.png")))
Expand All @@ -113,6 +114,7 @@ def updateThemeIcons(self, theme):
self.spatJoin.setIcon(QIcon(self.getThemeIcon("join_location.png")))
self.splitVect.setIcon(QIcon(self.getThemeIcon("split_layer.png")))
self.mergeShapes.setIcon(QIcon(self.getThemeIcon("merge_shapes.png")))
self.spatialIndex.setIcon(QIcon(self.getThemeIcon("spatial_index.png")))

def initGui(self):
if int(self.QgisVersion) < 1:
Expand Down Expand Up @@ -167,19 +169,22 @@ def initGui(self):
self.voronoi = QAction(QCoreApplication.translate("fTools", "Voronoi Polygons"),self.iface.mainWindow())
self.extNodes = QAction(QCoreApplication.translate("fTools", "Extract nodes"),self.iface.mainWindow())
self.simplify = QAction(QCoreApplication.translate("fTools", "Simplify geometries"),self.iface.mainWindow())
self.densify = QAction(QCoreApplication.translate("fTools", "Densify geometries"),self.iface.mainWindow())
self.multiToSingle = QAction(QCoreApplication.translate("fTools", "Multipart to singleparts"),self.iface.mainWindow())
self.singleToMulti = QAction(QCoreApplication.translate("fTools", "Singleparts to multipart"),self.iface.mainWindow())
self.polysToLines = QAction(QCoreApplication.translate("fTools", "Polygons to lines"),self.iface.mainWindow())
self.linesToPolys = QAction(QCoreApplication.translate("fTools", "Lines to polygons"),self.iface.mainWindow())
self.conversionMenu.addActions([self.checkGeom, self.compGeo, self.centroids, self.delaunay, self.voronoi,
self.simplify, self.multiToSingle, self.singleToMulti, self.polysToLines, self.linesToPolys, self.extNodes])
self.simplify, self.densify, self.multiToSingle, self.singleToMulti, self.polysToLines, self.linesToPolys,
self.extNodes])

self.dataManageMenu = QMenu(QCoreApplication.translate("fTools", "&Data Management Tools"))
self.define = QAction(QCoreApplication.translate("fTools", "Define current projection"), self.iface.mainWindow())
self.spatJoin = QAction(QCoreApplication.translate("fTools", "Join attributes by location"), self.iface.mainWindow())
self.splitVect = QAction(QCoreApplication.translate("fTools", "Split vector layer"), self.iface.mainWindow())
self.mergeShapes = QAction(QCoreApplication.translate("fTools", "Merge shapefiles to one"), self.iface.mainWindow())
self.dataManageMenu.addActions([self.define, self.spatJoin, self.splitVect, self.mergeShapes])
self.spatialIndex = QAction(QCoreApplication.translate("fTools", "Create spatial index"), self.iface.mainWindow())
self.dataManageMenu.addActions([self.define, self.spatJoin, self.splitVect, self.mergeShapes, self.spatialIndex])
self.updateThemeIcons("theme")

self.menu.addMenu(self.analysisMenu)
Expand Down Expand Up @@ -222,7 +227,8 @@ def initGui(self):
QObject.connect(self.multiToSingle, SIGNAL("triggered()"), self.domultiToSingle)
QObject.connect(self.singleToMulti, SIGNAL("triggered()"), self.dosingleToMulti)
QObject.connect(self.checkGeom, SIGNAL("triggered()"), self.docheckGeom)
QObject.connect(self.simplify, SIGNAL("triggered()"), self.dosimplify)
QObject.connect(self.simplify, SIGNAL("triggered()"), self.doSimplify)
QObject.connect(self.densify, SIGNAL("triggered()"), self.doDensify)
QObject.connect(self.centroids, SIGNAL("triggered()"), self.docentroids)
QObject.connect(self.delaunay, SIGNAL("triggered()"), self.dodelaunay)
QObject.connect(self.voronoi, SIGNAL("triggered()"), self.dovoronoi)
Expand All @@ -235,12 +241,19 @@ def initGui(self):
QObject.connect(self.spatJoin, SIGNAL("triggered()"), self.dospatJoin)
QObject.connect(self.splitVect, SIGNAL("triggered()"), self.dosplitVect)
QObject.connect(self.mergeShapes, SIGNAL("triggered()"), self.doMergeShapes)
QObject.connect(self.spatialIndex, SIGNAL("triggered()"), self.doSpatIndex)

def unload(self):
pass

def dosimplify(self):
d = doSimplify.Dialog(self.iface)
def doSimplify(self):
d = doSimplify.Dialog(self.iface, 1)
d.show()
d.exec_()

def doDensify(self):
d = doSimplify.Dialog(self.iface, 2)
d.show()
d.exec_()

def dopolysToLines(self):
Expand Down Expand Up @@ -319,7 +332,7 @@ def docentroids(self):
def dodelaunay(self):
d = doGeometry.GeometryDialog(self.iface, 8)
d.exec_()

def dovoronoi(self):
d = doGeometry.GeometryDialog(self.iface, 10)
d.exec_()
Expand Down Expand Up @@ -390,5 +403,10 @@ def dospatJoin(self):

def doMergeShapes(self):
d = doMergeShapes.Dialog(self.iface)
d.show()
d.exec_()

def doSpatIndex(self):
d = doSpatialIndex.Dialog(self.iface)
d.show()
d.exec_()
Empty file modified python/plugins/fTools/tools/doDefineProj.py
100755 → 100644
Empty file.
6 changes: 4 additions & 2 deletions python/plugins/fTools/tools/doGeometry.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,9 @@ def manageGui(self):
self.cmbField.setVisible( False )
self.field_label.setVisible( False )
self.resize( 381, 100 )
myList = []
self.populateLayers()

def populateLayers( self ):
self.inShape.clear()
if self.myFunction == 3 or self.myFunction == 6:
myList = ftools_utils.getLayerNames( [ QGis.Polygon, QGis.Line ] )
Expand All @@ -176,7 +178,6 @@ def manageGui(self):
else:
myList = ftools_utils.getLayerNames( [ QGis.Point, QGis.Line, QGis.Polygon ] )
self.inShape.addItems( myList )
return

#1: Singleparts to multipart
#2: Multipart to singleparts
Expand Down Expand Up @@ -241,6 +242,7 @@ def runFinishedFromThread( self, success ):
if addToTOC == QMessageBox.Yes:
if not ftools_utils.addShapeToCanvas( unicode( self.shapefileName ) ):
QMessageBox.warning( self, self.tr("Geoprocessing"), self.tr( "Error loading output shapefile:\n%1" ).arg( unicode( self.shapefileName ) ))
self.populateLayers()
else:
QMessageBox.warning( self, self.tr("Geometry"), self.tr( "Error writing output shapefile." ) )

Expand Down
80 changes: 49 additions & 31 deletions python/plugins/fTools/tools/doGeoprocessing.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,20 @@ def manageGui( self ):
elif self.myFunction == 7: # Symetrical difference
self.label_2.setText( self.tr( "Difference layer" ) )
self.setWindowTitle( self.tr( "Symetrical difference" ) )
self.useSelectedA.hide()
self.useSelectedB.hide()
elif self.myFunction == 8: # Clip
self.label_2.setText( self.tr( "Clip layer" ) )
self.setWindowTitle( self.tr( "Clip" ) )
else: # Union
self.label_2.setText( self.tr( "Union layer" ) )
self.setWindowTitle( self.tr( "Union" ) )
self.useSelectedA.hide()
self.useSelectedB.hide()
self.resize(381, 100)
self.populateLayers()

def populateLayers( self ):
myListA = []
myListB = []
self.inShapeA.clear()
Expand All @@ -195,7 +202,6 @@ def manageGui( self ):
myListB = ftools_utils.getLayerNames( [ QGis.Point, QGis.Line, QGis.Polygon ] )
self.inShapeA.addItems( myListA )
self.inShapeB.addItems( myListB )
return

#1: Buffer
#2: Convex Hull
Expand Down Expand Up @@ -257,6 +263,7 @@ def runFinishedFromThread( self, results ):
if addToTOC == QMessageBox.Yes:
if not ftools_utils.addShapeToCanvas( unicode( self.shapefileName ) ):
QMessageBox.warning( self, self.tr("Geoprocessing"), self.tr( "Error loading output shapefile:\n%1" ).arg( unicode( self.shapefileName ) ))
self.populateLayers()

def runStatusFromThread( self, status ):
self.progressBar.setValue( status )
Expand Down Expand Up @@ -1061,33 +1068,40 @@ def union( self ):
vproviderB = self.vlayerB.dataProvider()
allAttrsB = vproviderB.attributeIndexes()
vproviderB.select( allAttrsB )

# check for crs compatibility
crsA = vproviderA.crs()
crsB = vproviderB.crs()
if not crsA.isValid() or not crsB.isValid():
crs_match = None
else:
crs_match = crsA == crsB

fields = ftools_utils.combineVectorFields( self.vlayerA, self.vlayerB )
longNames = ftools_utils.checkFieldNameLength( fields )
if not longNames.isEmpty():
message = QString( 'Following field names are longer than 10 characters:\n%1' ).arg( longNames.join( '\n' ) )
return GEOS_EXCEPT, FEATURE_EXCEPT, crs_match, message
writer = QgsVectorFileWriter( self.myName, self.myEncoding,
fields, vproviderA.geometryType(), vproviderA.crs() )

writer = QgsVectorFileWriter( self.myName, self.myEncoding, fields,
vproviderA.geometryType(), vproviderA.crs() )
if writer.hasError():
return GEOS_EXCEPT, FEATURE_EXCEPT, crs_match, writer.errorMessage()

inFeatA = QgsFeature()
inFeatB = QgsFeature()
outFeat = QgsFeature()
indexA = ftools_utils.createIndex( vproviderB )
indexB = ftools_utils.createIndex( vproviderA )

nFeat = vproviderA.featureCount() * vproviderB.featureCount()
nElement = 0
self.emit( SIGNAL( "runStatus(PyQt_PyObject)" ), 0)
self.emit( SIGNAL( "runRange(PyQt_PyObject)" ), ( 0, nFeat ) )

vproviderA.rewind()
count = 0
nElement = 0

while vproviderA.nextFeature( inFeatA ):
self.emit( SIGNAL( "runStatus(PyQt_PyObject)" ), nElement )
nElement += 1
Expand All @@ -1102,10 +1116,9 @@ def union( self ):
outFeat.setAttributeMap( atMapA )
writer.addFeature( outFeat )
except:
FEATURE_EXCEPT = False
# this really shouldn't happen, as we
# this really shouldn't happen, as we
# haven't edited the input geom at all
# continue
FEATURE_EXCEPT = False
else:
for id in intersects:
count += 1
Expand All @@ -1116,49 +1129,48 @@ def union( self ):
if geom.intersects( tmpGeom ):
found = True
int_geom = geom.intersection( tmpGeom )

if int_geom is None:
GEOS_EXCEPT = False
# There was a problem creating the intersection
GEOS_EXCEPT = False
int_geom = QgsGeometry()
else:
int_geom = QgsGeometry(int_geom)

if diff_geom.intersects( tmpGeom ):
diff_geom = diff_geom.difference( tmpGeom )
if diff_geom is None:
# It's possible there was an error here?
diff_geom = QgsGeometry()
else:
diff_geom = QgsGeometry(diff_geom)

if int_geom.wkbType() == 0:
# intersection produced different geomety types
# intersection produced different geomety types
temp_list = int_geom.asGeometryCollection()
for i in temp_list:
if i.type() == geom.type():
int_geom = QgsGeometry( i )
try:
outFeat.setGeometry( int_geom )
outFeat.setAttributeMap( ftools_utils.combineVectorAttributes( atMapA, atMapB ) )
# print int_geom.wkbType()
writer.addFeature( outFeat )
except Exception, err:
# print str(err)
FEATURE_EXCEPT = False
# else:
# # this only happends if the bounding box
# # intersects, but the geometry doesn't
# try:
# outFeat.setGeometry( geom )
# outFeat.setAttributeMap( atMapA )
# print geom.wkbType()
# writer.addFeature( outFeat )
# except:
## # also shoudn't ever happen
# FEATURE_EXCEPT = False
# pass
else:
# this only happends if the bounding box
# intersects, but the geometry doesn't
try:
outFeat.setGeometry( geom )
outFeat.setAttributeMap( atMapA )
writer.addFeature( outFeat )
except:
# also shoudn't ever happen
FEATURE_EXCEPT = False
except Exception, err:
# print str(err)
GEOS_EXCEPT = False
found = False

if found:
try:
if diff_geom.wkbType() == 0:
Expand All @@ -1168,51 +1180,57 @@ def union( self ):
diff_geom = QgsGeometry( i )
outFeat.setGeometry( diff_geom )
outFeat.setAttributeMap( atMapA )
# print diff_geom.wkbType()
writer.addFeature( outFeat )
except Exception, err:
# print str(err)
FEATURE_EXCEPT = False
# continue

length = len( vproviderA.fields().values() )
vproviderB.rewind()

while vproviderB.nextFeature( inFeatA ):
add = False
geom = QgsGeometry( inFeatA.geometry() )
diff_geom = QgsGeometry( geom )
atMap = inFeatA.attributeMap().values()
atMap = dict( zip( range( length, length + len( atMap ) ), atMap ) )
intersects = indexB.intersects( geom.boundingBox() )

if len(intersects) < 1:
try:
outFeat.setGeometry( geom )
outFeat.setAttributeMap( atMap )
writer.addFeature( outFeat )
except Exception, err:
# print str(err)
FEATURE_EXCEPT = False
else:
for id in intersects:
vproviderA.featureAtId( int( id ), inFeatB , True, allAttrsA )
atMapB = inFeatB.attributeMap()
tmpGeom = QgsGeometry( inFeatB.geometry() )

try:
if diff_geom.intersects( tmpGeom ):
add = True
diff_geom = QgsGeometry( diff_geom.difference( tmpGeom ) )
else:
# this only happends if the bounding box
# intersects, but the geometry doesn't
outFeat.setGeometry( diff_geom )
outFeat.setAttributeMap( atMap )
print geom.wkbType()
writer.addFeature( outFeat )
except Exception, err:
# print str(err)
add = False
GEOS_EXCEPT = False

if add:
try:
outFeat.setGeometry( diff_geom )
outFeat.setAttributeMap( atMapB )
writer.addFeature( outFeat )
except Exception, err:
# print str(err)
FEATURE_EXCEPT = False
# continue

self.emit( SIGNAL( "runStatus(PyQt_PyObject)" ), nElement )
nElement += 1
del writer
Expand Down
8 changes: 6 additions & 2 deletions python/plugins/fTools/tools/doIntersectLines.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,13 @@ def __init__(self, iface):
QObject.connect(self.inLine2, SIGNAL("currentIndexChanged(QString)"), self.update2)
self.setWindowTitle( self.tr("Line intersections") )
self.buttonOk = self.buttonBox_2.button( QDialogButtonBox.Ok )
# populate layer list
self.progressBar.setValue(0)
mapCanvas = self.iface.mapCanvas()
self.populateLayers()

def populateLayers( self ):
layers = ftools_utils.getLayerNames([QGis.Line])
self.inLine1.clear()
self.inLine2.clear()
self.inLine1.addItems(layers)
self.inLine2.addItems(layers)

Expand Down Expand Up @@ -92,6 +95,7 @@ def accept(self):
if addToTOC == QMessageBox.Yes:
if not ftools_utils.addShapeToCanvas( unicode( outPath ) ):
QMessageBox.warning( self, self.tr("Geoprocessing"), self.tr( "Error loading output shapefile:\n%1" ).arg( unicode( outPath ) ))
self.populateLayers()
self.progressBar.setValue(0)
self.buttonOk.setEnabled( True )

Expand Down
10 changes: 7 additions & 3 deletions python/plugins/fTools/tools/doMeanCoords.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,15 @@ def __init__(self, iface, function):
QObject.connect(self.toolOut, SIGNAL("clicked()"), self.outFile)
QObject.connect(self.inShape, SIGNAL("currentIndexChanged(QString)"), self.update)
self.buttonOk = self.buttonBox_2.button( QDialogButtonBox.Ok )

# populate layer list
self.progressBar.setValue(0)
mapCanvas = self.iface.mapCanvas()
self.populateLayers()

def populateLayers( self ):
layers = ftools_utils.getLayerNames([QGis.Point, QGis.Line, QGis.Polygon])
QObject.disconnect(self.inShape, SIGNAL("currentIndexChanged(QString)"), self.update)
self.inShape.clear()
self.inShape.addItems(layers)
QObject.connect(self.inShape, SIGNAL("currentIndexChanged(QString)"), self.update)

def updateUi(self):
if self.function == 1:
Expand Down Expand Up @@ -96,6 +99,7 @@ def accept(self):
if addToTOC == QMessageBox.Yes:
vlayer = QgsVectorLayer(outPath, unicode(outName), "ogr")
QgsMapLayerRegistry.instance().addMapLayer(vlayer)
self.populateLayers()
self.progressBar.setValue(0)
self.buttonOk.setEnabled( True )

Expand Down
Empty file modified python/plugins/fTools/tools/doMergeShapes.py
100755 → 100644
Empty file.
Empty file modified python/plugins/fTools/tools/doPointDistance.py
100755 → 100644
Empty file.
12 changes: 8 additions & 4 deletions python/plugins/fTools/tools/doPointsInPolygon.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,18 @@ def __init__(self, iface):
QObject.connect(self.toolOut, SIGNAL("clicked()"), self.outFile)
self.setWindowTitle(self.tr("Count Points in Polygon"))
self.buttonOk = self.buttonBox_2.button( QDialogButtonBox.Ok )
# populate layer list
self.progressBar.setValue(0)
mapCanvas = self.iface.mapCanvas()
self.populateLayers()

def populateLayers( self ):
layers = ftools_utils.getLayerNames([QGis.Polygon])
self.inPolygon.clear()
self.inPolygon.addItems(layers)

self.inPoint.clear()
layers = ftools_utils.getLayerNames([QGis.Point])
self.inPoint.addItems(layers)

def accept(self):
self.buttonOk.setEnabled( False )
if self.inPolygon.currentText() == "":
Expand Down Expand Up @@ -79,6 +83,7 @@ def accept(self):
if addToTOC == QMessageBox.Yes:
self.vlayer = QgsVectorLayer(outPath, unicode(outName), "ogr")
QgsMapLayerRegistry.instance().addMapLayer(self.vlayer)
self.populateLayers()
self.progressBar.setValue(0)
self.buttonOk.setEnabled( True )

Expand Down Expand Up @@ -112,7 +117,6 @@ def compute(self, inPoly, inPts, inField, outPath, progressBar):
if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName):
return
writer = QgsVectorFileWriter(self.shapefileName, self.encoding, fieldList, polyProvider.geometryType(), sRs)
#writer = QgsVectorFileWriter(outPath, "UTF-8", fieldList, polyProvider.geometryType(), sRs)
inFeat = QgsFeature()
inFeatB = QgsFeature()
outFeat = QgsFeature()
Expand Down
10 changes: 8 additions & 2 deletions python/plugins/fTools/tools/doRandPoints.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,14 @@ def __init__(self, iface):
self.progressBar.setValue(0)
self.setWindowTitle(self.tr("Random Points"))
self.buttonOk = self.buttonBox_2.button( QDialogButtonBox.Ok )
self.mapCanvas = self.iface.mapCanvas()
self.populateLayers()

def populateLayers( self ):
layers = ftools_utils.getLayerNames([QGis.Polygon, "Raster"])
QObject.disconnect(self.inShape, SIGNAL("currentIndexChanged(QString)"), self.update)
self.inShape.clear()
self.inShape.addItems(layers)
QObject.connect(self.inShape, SIGNAL("currentIndexChanged(QString)"), self.update)

# If input layer is changed, update field list
def update(self, inputLayer):
Expand Down Expand Up @@ -123,6 +128,7 @@ def accept(self):
if addToTOC == QMessageBox.Yes:
self.vlayer = QgsVectorLayer(outPath, unicode(outName), "ogr")
QgsMapLayerRegistry.instance().addMapLayer(self.vlayer)
self.populateLayers()
self.progressBar.setValue(0)
self.buttonOk.setEnabled( True )

Expand Down Expand Up @@ -208,7 +214,7 @@ def randomize(self, inLayer, outPath, minimum, design, value):
points = self.vectorRandom(int(value), inLayer,
ext.xMinimum(), ext.xMaximum(), ext.yMinimum(), ext.yMaximum())
else: points = self.loopThruPolygons(inLayer, value, design)
crs = self.mapCanvas.mapRenderer().destinationSrs()
crs = self.iface.mapCanvas().mapRenderer().destinationSrs()
if not crs.isValid(): crs = None
fields = { 0 : QgsField("ID", QVariant.Int) }
check = QFile(self.shapefileName)
Expand Down
Empty file modified python/plugins/fTools/tools/doRandom.py
100755 → 100644
Empty file.
9 changes: 7 additions & 2 deletions python/plugins/fTools/tools/doRegPoints.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ def __init__(self, iface):
self.buttonOk = self.buttonBox_2.button( QDialogButtonBox.Ok )
self.progressBar.setValue(0)
self.mapCanvas = self.iface.mapCanvas()
self.populateLayers()

def populateLayers( self ):
layers = ftools_utils.getLayerNames("all")
self.inShape.clear()
self.inShape.addItems(layers)

def accept(self):
Expand Down Expand Up @@ -89,6 +93,7 @@ def accept(self):
if addToTOC == QMessageBox.Yes:
self.vlayer = QgsVectorLayer(outPath, unicode(outName), "ogr")
QgsMapLayerRegistry.instance().addMapLayer(self.vlayer)
self.populateLayers()
self.progressBar.setValue(0)
self.buttonOk.setEnabled( True )

Expand All @@ -98,7 +103,7 @@ def outFile(self):
if self.shapefileName is None or self.encoding is None:
return
self.outShape.setText( QString( self.shapefileName ) )

# Generate list of random points
def simpleRandom(self, n, bound, xmin, xmax, ymin, ymax):
seed()
Expand All @@ -109,7 +114,7 @@ def simpleRandom(self, n, bound, xmin, xmax, ymin, ymax):
if pGeom.intersects(bound):
points.append(pGeom)
i = i + 1
return points
return points

def regularize(self, bound, outPath, offset, value, gridType, inset, crs):
area = bound.width() * bound.height()
Expand Down
Empty file modified python/plugins/fTools/tools/doSelectByLocation.py
100755 → 100644
Empty file.
313 changes: 249 additions & 64 deletions python/plugins/fTools/tools/doSimplify.py

Large diffs are not rendered by default.

223 changes: 223 additions & 0 deletions python/plugins/fTools/tools/doSpatialIndex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
# -*- coding: utf-8 -*-

"""
***************************************************************************
doSpatialIndex.py - build spatial index for vector layers or files
--------------------------------------
Date : 11-Nov-2011
Copyright : (C) 2011 by Alexander Bruy
Email : alexander dot bruy at gmail dot com
***************************************************************************
* *
* 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. *
* *
***************************************************************************
"""

from PyQt4.QtCore import *
from PyQt4.QtGui import *

from qgis.core import *
from qgis.gui import *

import ftools_utils

from ui_frmSpatialIndex import Ui_Dialog

class Dialog( QDialog, Ui_Dialog ):
def __init__( self, iface ):
QDialog.__init__( self )
self.setupUi( self )
self.iface = iface

self.workThread = None

self.btnOk = self.buttonBox.button( QDialogButtonBox.Ok )
self.btnClose = self.buttonBox.button( QDialogButtonBox.Close )

QObject.connect( self.chkExternalFiles, SIGNAL( "stateChanged( int )" ), self.toggleExternalFiles )
QObject.connect( self.btnSelectFiles, SIGNAL( "clicked()" ), self.selectFiles )
QObject.connect( self.lstLayers, SIGNAL( "itemSelectionChanged()" ), self.updateLayerList )
QObject.connect( self.btnSelectAll, SIGNAL( "clicked()" ), self.selectAll )
QObject.connect( self.btnSelectNone, SIGNAL( "clicked()" ), self.selectNone )
QObject.connect( self.btnClearList, SIGNAL( "clicked()" ), self.clearList )

self.manageGui()

def manageGui( self ):
self.btnSelectFiles.setEnabled( False )
self.btnClearList.setEnabled( False )

self.fillLayersList()

def fillLayersList( self ):
self.lstLayers.clear()
layers = ftools_utils.getLayerNames( [ QGis.Line, QGis.Point, QGis.Polygon ] )
for lay in layers:
source = ftools_utils.getVectorLayerByName( lay ).source()
item = QListWidgetItem( lay, self.lstLayers )
item.setData( Qt.UserRole, source )
item.setData( Qt.ToolTipRole, source )

def toggleExternalFiles( self ):
if self.chkExternalFiles.isChecked():
self.btnSelectFiles.setEnabled( True )
self.btnClearList.setEnabled( True )
self.btnSelectAll.setEnabled( False )
self.btnSelectNone.setEnabled( False )

self.lstLayers.clear()
self.lstLayers.setSelectionMode( QAbstractItemView.NoSelection )
self.layers = []
else:
self.btnSelectFiles.setEnabled( False )
self.btnClearList.setEnabled( False )
self.btnSelectAll.setEnabled( True )
self.btnSelectNone.setEnabled( True )

self.fillLayersList()
self.lstLayers.setSelectionMode( QAbstractItemView.ExtendedSelection )
self.updateLayerList()

def updateLayerList( self ):
self.layers = []
selection = self.lstLayers.selectedItems()
for item in selection:
self.layers.append( item.text() )

def selectFiles( self ):
filters = QgsProviderRegistry.instance().fileVectorFilters()
( files, self.encoding ) = ftools_utils.openDialog( self, filtering = filters, dialogMode = "MultipleFiles" )
if files is None:
return

self.layers.extend( [ unicode( f ) for f in files ] )
self.lstLayers.addItems( files )

def selectAll( self ):
self.lstLayers.selectAll()

def selectNone( self ):
self.lstLayers.clearSelection()

def clearList( self ):
self.layers = []
self.lstLayers.clear()

def accept( self ):
QApplication.setOverrideCursor( Qt.WaitCursor )
self.btnOk.setEnabled( False )

self.workThread = SpatialIdxThread( self.layers, self.chkExternalFiles.isChecked() )
self.progressBar.setRange( 0, len( self.layers ) )

QObject.connect( self.workThread, SIGNAL( "layerProcessed()" ), self.layerProcessed )
QObject.connect( self.workThread, SIGNAL( "processFinished( PyQt_PyObject )" ), self.processFinished )
QObject.connect( self.workThread, SIGNAL( "processInterrupted()" ), self.processInterrupted )

self.btnClose.setText( self.tr( "Cancel" ) )
QObject.disconnect( self.buttonBox, SIGNAL( "rejected()" ), self.reject )
QObject.connect( self.btnClose, SIGNAL( "clicked()" ), self.stopProcessing )

self.workThread.start()

def layerProcessed( self ):
self.progressBar.setValue( self.progressBar.value() + 1 )

def processInterrupted( self ):
self.restoreGui()

def processFinished( self, errors ):
self.stopProcessing()
self.restoreGui()

if not errors.isEmpty():
msg = QString( "Processing of the following layers/files ended with error:<br><br>" ).append( errors.join( "<br>" ) )
QErrorMessage( self ).showMessage( msg )

QMessageBox.information( self, self.tr( "Finished" ), self.tr( "Processing completed." ) )

def stopProcessing( self ):
if self.workThread != None:
self.workThread.stop()
self.workThread = None

def restoreGui( self ):
self.progressBar.setValue( 0 )
QApplication.restoreOverrideCursor()
QObject.connect( self.buttonBox, SIGNAL( "rejected()" ), self.reject )
self.btnClose.setText( self.tr( "Close" ) )
self.btnOk.setEnabled( True )

if self.chkExternalFiles.isChecked():
self.clearList()

class SpatialIdxThread( QThread ):
def __init__( self, layers, isFiles ):
QThread.__init__( self, QThread.currentThread() )
self.layers = layers
self.isFiles = isFiles

self.mutex = QMutex()
self.stopMe = 0

self.errors = QStringList()

def run( self ):
self.mutex.lock()
self.stopMe = 0
self.mutex.unlock()

interrupted = False

if self.isFiles:
for layer in self.layers:
vl = QgsVectorLayer( layer, "tmp", "ogr" )
provider = vl.dataProvider()
if provider.capabilities() & QgsVectorDataProvider.CreateSpatialIndex:
if not provider.createSpatialIndex():
self.errors.append( layer )
else:
self.errors.append( layer )

self.emit( SIGNAL( "layerProcessed()" ) )

self.mutex.lock()
s = self.stopMe
self.mutex.unlock()
if s == 1:
interrupted = True
break
else:
for layer in self.layers:
vl = ftools_utils.getVectorLayerByName( layer )
provider = vl.dataProvider()
if provider.capabilities() & QgsVectorDataProvider.CreateSpatialIndex:
if not provider.createSpatialIndex():
self.errors.append( layer )
else:
self.errors.append( layer )

self.emit( SIGNAL( "layerProcessed()" ) )

self.mutex.lock()
s = self.stopMe
self.mutex.unlock()
if s == 1:
interrupted = True
break

if not interrupted:
self.emit( SIGNAL( "processFinished( PyQt_PyObject )" ), self.errors )
else:
self.emit( SIGNAL( "processInterrupted()" ) )

def stop( self ):
self.mutex.lock()
self.stopMe = 1
self.mutex.unlock()

QThread.wait( self )
Empty file modified python/plugins/fTools/tools/doSpatialJoin.py
100755 → 100644
Empty file.
Empty file modified python/plugins/fTools/tools/doSubsetSelect.py
100755 → 100644
Empty file.
10 changes: 7 additions & 3 deletions python/plugins/fTools/tools/doSumLines.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,17 @@ def __init__(self, iface):
QObject.connect(self.toolOut, SIGNAL("clicked()"), self.outFile)
self.setWindowTitle(self.tr("Sum line lengths"))
self.buttonOk = self.buttonBox_2.button( QDialogButtonBox.Ok )
# populate layer list
self.progressBar.setValue(0)
mapCanvas = self.iface.mapCanvas()
self.populateLayers()

def populateLayers( self ):
layers = ftools_utils.getLayerNames([QGis.Line])
self.inPoint.clear()
self.inPoint.addItems(layers)
layers = ftools_utils.getLayerNames([QGis.Polygon])
self.inPolygon.clear()
self.inPolygon.addItems(layers)

def accept(self):
self.buttonOk.setEnabled( False )
if self.inPolygon.currentText() == "":
Expand Down Expand Up @@ -79,6 +82,7 @@ def accept(self):
if addToTOC == QMessageBox.Yes:
self.vlayer = QgsVectorLayer(outPath, unicode(outName), "ogr")
QgsMapLayerRegistry.instance().addMapLayer(self.vlayer)
self.populateLayers()
self.progressBar.setValue(0)
self.buttonOk.setEnabled( True )

Expand Down
9 changes: 7 additions & 2 deletions python/plugins/fTools/tools/doVectorGrid.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ def __init__(self, iface):
self.xMax.setValidator(QDoubleValidator(self.xMax))
self.yMin.setValidator(QDoubleValidator(self.yMin))
self.yMax.setValidator(QDoubleValidator(self.yMax))
self.populateLayers()

def populateLayers( self ):
self.inShape.clear()
layermap = QgsMapLayerRegistry.instance().mapLayers()
for name, layer in layermap.iteritems():
self.inShape.addItem( unicode( layer.name() ) )
Expand All @@ -64,12 +68,12 @@ def updateLayer( self ):
mLayer = ftools_utils.getMapLayerByName( unicode( mLayerName ) )
boundBox = mLayer.extent()
self.updateExtents( boundBox )

def updateCanvas( self ):
canvas = self.iface.mapCanvas()
boundBox = canvas.extent()
self.updateExtents( boundBox )

def updateExtents( self, boundBox ):
self.xMin.setText( unicode( boundBox.xMinimum() ) )
self.yMin.setText( unicode( boundBox.yMinimum() ) )
Expand Down Expand Up @@ -100,6 +104,7 @@ def accept(self):
addToTOC = QMessageBox.question(self, self.tr("Generate Vector Grid"), self.tr("Created output shapefile:\n%1\n\nWould you like to add the new layer to the TOC?").arg(unicode(self.shapefileName)), QMessageBox.Yes, QMessageBox.No, QMessageBox.NoButton)
if addToTOC == QMessageBox.Yes:
ftools_utils.addShapeToCanvas( self.shapefileName )
self.populateLayers()
self.progressBar.setValue( 0 )
self.buttonOk.setEnabled( True )

Expand Down
Empty file modified python/plugins/fTools/tools/doVectorSplit.py
100755 → 100644
Empty file.
Empty file modified python/plugins/fTools/tools/doVisual.py
100755 → 100644
Empty file.
15 changes: 6 additions & 9 deletions python/plugins/fTools/tools/frmSimplify.ui
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
Expand Down Expand Up @@ -35,7 +32,7 @@
</widget>
</item>
<item>
<widget class="QCheckBox" name="useSelectionCheck">
<widget class="QCheckBox" name="chkUseSelection">
<property name="text">
<string>Use only selected features</string>
</property>
Expand All @@ -44,14 +41,14 @@
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_2">
<widget class="QLabel" name="lblTolerance">
<property name="text">
<string>Simplify tolerance</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="toleranceSpin">
<widget class="QDoubleSpinBox" name="spnTolerance">
<property name="decimals">
<number>4</number>
</property>
Expand All @@ -71,14 +68,14 @@
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="writeShapefileCheck">
<widget class="QCheckBox" name="chkWriteShapefile">
<property name="text">
<string>Save to new file</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="outputFileEdit">
<widget class="QLineEdit" name="edOutputFile">
<property name="enabled">
<bool>false</bool>
</property>
Expand All @@ -97,7 +94,7 @@
</layout>
</item>
<item>
<widget class="QCheckBox" name="addToCanvasCheck">
<widget class="QCheckBox" name="chkAddToCanvas">
<property name="enabled">
<bool>false</bool>
</property>
Expand Down
127 changes: 127 additions & 0 deletions python/plugins/fTools/tools/frmSpatialIndex.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>351</width>
<height>272</height>
</rect>
</property>
<property name="windowTitle">
<string>Build spatial index</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="chkExternalFiles">
<property name="text">
<string>Select files from disk</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnSelectFiles">
<property name="text">
<string>Select files...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QListWidget" name="lstLayers">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="btnSelectAll">
<property name="text">
<string>Select all</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnSelectNone">
<property name="text">
<string>Select none</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnClearList">
<property name="text">
<string>Clear list</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QProgressBar" name="progressBar">
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
Empty file modified python/plugins/fTools/tools/ftools_utils.py
100755 → 100644
Empty file.
Empty file modified python/plugins/fTools/tools/voronoi.py
100755 → 100644
Empty file.
13 changes: 12 additions & 1 deletion python/plugins/plugin_installer/installer_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ def setIface(qgisIface):

# Repositories: (name, url, possible depreciated url)
officialRepo = ("QGIS Official Repository", "http://pyqgis.org/repo/official","")
officialRepo2 = ("QGIS Official Repository 2", "http://plugins.qgis.org/plugins","")
contribRepo = ("QGIS Contributed Repository", "http://pyqgis.org/repo/contributed","")
authorRepos = [("Aaron Racicot's Repository", "http://qgisplugins.z-pulley.com", ""),
("Barry Rowlingson's Repository", "http://www.maths.lancs.ac.uk/~rowlings/Qgis/Plugins/plugins.xml", ""),
Expand All @@ -83,7 +84,8 @@ def setIface(qgisIface):
("Martin Dobias' Sandbox", "http://mapserver.sk/~wonder/qgis/plugins-sandbox.xml", ""),
("Marco Hugentobler's Repository","http://karlinapp.ethz.ch/python_plugins/python_plugins.xml", ""),
("Sourcepole Repository", "http://build.sourcepole.ch/qgis/plugins.xml", ""),
("Volkan Kepoglu's Repository","http://ggit.metu.edu.tr/~volkan/plugins.xml", "")]
#("Volkan Kepoglu's Repository","http://ggit.metu.edu.tr/~volkan/plugins.xml", "")
]



Expand Down Expand Up @@ -199,6 +201,9 @@ def addKnownRepos(self):
if presentURLs.count(officialRepo[1]) == 0:
settings.setValue(officialRepo[0]+"/url", QVariant(officialRepo[1]))
settings.setValue(officialRepo[0]+"/enabled", QVariant(True))
if presentURLs.count(officialRepo2[1]) == 0:
settings.setValue(officialRepo2[0]+"/url", QVariant(officialRepo2[1]))
settings.setValue(officialRepo2[0]+"/enabled", QVariant(True))
if presentURLs.count(contribRepo[1]) == 0:
settings.setValue(contribRepo[0]+"/url", QVariant(contribRepo[1]))
settings.setValue(contribRepo[0]+"/enabled", QVariant(True))
Expand Down Expand Up @@ -323,6 +328,7 @@ def load(self):
settings.beginGroup(reposGroup)
# first, update repositories in QSettings if needed
officialRepoPresent = False
officialRepo2Present = False
for key in settings.childGroups():
url = settings.value(key+"/url", QVariant()).toString()
if url == contribRepo[1]:
Expand All @@ -331,11 +337,16 @@ def load(self):
settings.setValue(key+"/valid", QVariant(True)) # unlock any other repo
if url == officialRepo[1]:
officialRepoPresent = True
if url == officialRepo2[1]:
officialRepoPresent = True
for authorRepo in authorRepos:
if url == authorRepo[2]:
settings.setValue(key+"/url", QVariant(authorRepo[1])) # correct a depreciated url
if not officialRepoPresent:
settings.setValue(officialRepo[0]+"/url", QVariant(officialRepo[1]))
if not officialRepo2Present:
settings.setValue(officialRepo2[0]+"/url", QVariant(officialRepo2[1]))


for key in settings.childGroups():
self.mRepositories[key] = {}
Expand Down
28 changes: 27 additions & 1 deletion python/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import glob
import os.path
import re

import ConfigParser

#######################
# ERROR HANDLING
Expand Down Expand Up @@ -72,29 +72,55 @@ def initInterface(pointer):
# list of plugins in plugin directory and home plugin directory
available_plugins = []

# dictionary of plugins providing metadata in a text file (metadata.txt)
# key = plugin package name, value = config parser instance
plugins_metadata_parser = {}

def findPlugins(path):
""" for internal use: return list of plugins in given path """
plugins = []
for plugin in glob.glob(path + "/*"):
if os.path.isdir(plugin) and os.path.exists(os.path.join(plugin, '__init__.py')):
plugins.append( os.path.basename(plugin) )
return plugins

def _checkMetadataFile(pluginpath, plugin):
""" Check whether there exists a metadata.txt file.
That is now a preferred way to store plugin's metadata """
metadataFile = os.path.join(pluginpath, plugin, 'metadata.txt')
if not os.path.exists(metadataFile):
return None
cp = ConfigParser.ConfigParser()
res = cp.read(metadataFile)
if len(res) == 0:
return None # reading of metadata file failed
return cp

def updateAvailablePlugins():
""" go thrgouh the plugin_paths list and find out what plugins are available """
# merge the lists
plugins = []
metadata_parser = {}
for pluginpath in plugin_paths:
for p in findPlugins(pluginpath):
if p not in plugins:
plugins.append(p)
cp = _checkMetadataFile(pluginpath, p)
if cp: metadata_parser[p] = cp

global available_plugins
available_plugins = plugins
global plugins_metadata_parser
plugins_metadata_parser = metadata_parser


def pluginMetadata(packageName, fct):
""" fetch metadata from a plugin """
try:
# try to use values from metadata.txt if available
if plugins_metadata_parser.has_key(packageName):
return plugins_metadata_parser[packageName].get('general', fct)
# otherwise fall back to old method, using __init__.py
package = sys.modules[packageName]
return getattr(package, fct)()
except:
Expand Down
137 changes: 136 additions & 1 deletion resources/symbology-ng-style.xml
Original file line number Diff line number Diff line change
Expand Up @@ -654,5 +654,140 @@
</layer>
</symbol>
</symbols>
<colorramps/>
<colorramps>
<colorramp type="gradient" name="Blues">
<prop k="color1" v="247,251,255,255"/>
<prop k="color2" v="8,48,107,255"/>
<prop k="stops" v="0.13;222,235,247,255:0.26;198,219,239,255:0.39;158,202,225,255:0.52;107,174,214,255:0.65;66,146,198,255:0.78;33,113,181,255:0.9;8,81,156,255"/>
</colorramp>
<colorramp type="gradient" name="BrBG">
<prop k="color1" v="166,97,26,255"/>
<prop k="color2" v="1,133,113,255"/>
<prop k="stops" v="0.25;223,194,125,255:0.5;245,245,245,255:0.75;128,205,193,255"/>
</colorramp>
<colorramp type="gradient" name="BuGn">
<prop k="color1" v="237,248,251,255"/>
<prop k="color2" v="0,109,44,255"/>
<prop k="stops" v="0.25;178,226,226,255:0.5;102,194,164,255:0.75;44,162,95,255"/>
</colorramp>
<colorramp type="gradient" name="BuPu">
<prop k="color1" v="237,248,251,255"/>
<prop k="color2" v="129,15,124,255"/>
<prop k="stops" v="0.25;179,205,227,255:0.5;140,150,198,255:0.75;136,86,167,255"/>
</colorramp>
<colorramp type="gradient" name="GnBu">
<prop k="color1" v="240,249,232,255"/>
<prop k="color2" v="8,104,172,255"/>
<prop k="stops" v="0.25;186,228,188,255:0.5;123,204,196,255:0.75;67,162,202,255"/>
</colorramp>
<colorramp type="gradient" name="Greens">
<prop k="color1" v="247,252,245,255"/>
<prop k="color2" v="0,68,27,255"/>
<prop k="stops" v="0.13;229,245,224,255:0.26;199,233,192,255:0.39;161,217,155,255:0.52;116,196,118,255:0.65;65,171,93,255:0.78;35,139,69,255:0.9;0,109,44,255"/>
</colorramp>
<colorramp type="gradient" name="Greys">
<prop k="color1" v="250,250,250,255"/>
<prop k="color2" v="5,5,5,255"/>
</colorramp>
<colorramp type="gradient" name="OrRd">
<prop k="color1" v="254,240,217,255"/>
<prop k="color2" v="179,0,0,255"/>
<prop k="stops" v="0.25;253,204,138,255:0.5;252,141,89,255:0.75;227,74,51,255"/>
</colorramp>
<colorramp type="gradient" name="Oranges">
<prop k="color1" v="255,245,235,255"/>
<prop k="color2" v="127,39,4,255"/>
<prop k="stops" v="0.13;254,230,206,255:0.26;253,208,162,255:0.39;253,174,107,255:0.52;253,141,60,255:0.65;241,105,19,255:0.78;217,72,1,255:0.9;166,54,3,255"/>
</colorramp>
<colorramp type="gradient" name="PRGn">
<prop k="color1" v="123,50,148,255"/>
<prop k="color2" v="0,136,55,255"/>
<prop k="stops" v="0.25;194,165,207,255:0.5;247,247,247,255:0.75;166,219,160,255"/>
</colorramp>
<colorramp type="gradient" name="PiYG">
<prop k="color1" v="208,28,139,255"/>
<prop k="color2" v="77,172,38,255"/>
<prop k="stops" v="0.25;241,182,218,255:0.5;247,247,247,255:0.75;184,225,134,255"/>
</colorramp>
<colorramp type="gradient" name="PuBu">
<prop k="color1" v="241,238,246,255"/>
<prop k="color2" v="4,90,141,255"/>
<prop k="stops" v="0.25;189,201,225,255:0.5;116,169,207,255:0.75;43,140,190,255"/>
</colorramp>
<colorramp type="gradient" name="PuBuGn">
<prop k="color1" v="246,239,247,255"/>
<prop k="color2" v="1,108,89,255"/>
<prop k="stops" v="0.25;189,201,225,255:0.5;103,169,207,255:0.75;28,144,153,255"/>
</colorramp>
<colorramp type="gradient" name="PuOr">
<prop k="color1" v="230,97,1,255"/>
<prop k="color2" v="94,60,153,255"/>
<prop k="stops" v="0.25;253,184,99,255:0.5;247,247,247,255:0.75;178,171,210,255"/>
</colorramp>
<colorramp type="gradient" name="PuRd">
<prop k="color1" v="241,238,246,255"/>
<prop k="color2" v="152,0,67,255"/>
<prop k="stops" v="0.25;215,181,216,255:0.5;223,101,176,255:0.75;221,28,119,255"/>
</colorramp>
<colorramp type="gradient" name="Purples">
<prop k="color1" v="252,251,253,255"/>
<prop k="color2" v="63,0,125,255"/>
<prop k="stops" v="0.13;239,237,245,255:0.26;218,218,235,255:0.39;188,189,220,255:0.52;158,154,200,255:0.65;128,125,186,255:0.75;106,81,163,255:0.9;84,39,143,255"/>
</colorramp>
<colorramp type="gradient" name="RdBu">
<prop k="color1" v="202,0,32,255"/>
<prop k="color2" v="5,113,176,255"/>
<prop k="stops" v="0.25;244,165,130,255:0.5;247,247,247,255:0.75;146,197,222,255"/>
</colorramp>
<colorramp type="gradient" name="RdGy">
<prop k="color1" v="202,0,32,255"/>
<prop k="color2" v="64,64,64,255"/>
<prop k="stops" v="0.25;244,165,130,255:0.5;255,255,255,255:0.75;186,186,186,255"/>
</colorramp>
<colorramp type="gradient" name="RdPu">
<prop k="color1" v="254,235,226,255"/>
<prop k="color2" v="122,1,119,255"/>
<prop k="stops" v="0.25;251,180,185,255:0.5;247,104,161,255:0.75;197,27,138,255"/>
</colorramp>
<colorramp type="gradient" name="RdYlBu">
<prop k="color1" v="215,25,28,255"/>
<prop k="color2" v="44,123,182,255"/>
<prop k="stops" v="0.25;253,174,97,255:0.5;255,255,191,255:0.75;171,217,233,255"/>
</colorramp>
<colorramp type="gradient" name="RdYlGn">
<prop k="color1" v="215,25,28,255"/>
<prop k="color2" v="26,150,65,255"/>
<prop k="stops" v="0.25;253,174,97,255:0.5;255,255,192,255:0.75;166,217,106,255"/>
</colorramp>
<colorramp type="gradient" name="Reds">
<prop k="color1" v="255,245,240,255"/>
<prop k="color2" v="103,0,13,255"/>
<prop k="stops" v="0.13;254,224,210,255:0.26;252,187,161,255:0.39;252,146,114,255:0.52;251,106,74,255:0.65;239,59,44,255:0.78;203,24,29,255:0.9;165,15,21,255"/>
</colorramp>
<colorramp type="gradient" name="Spectral">
<prop k="color1" v="215,25,28,255"/>
<prop k="color2" v="43,131,186,255"/>
<prop k="stops" v="0.25;253,174,97,255:0.5;255,255,191,255:0.75;171,221,164,255"/>
</colorramp>
<colorramp type="gradient" name="YlGn">
<prop k="color1" v="255,255,204,255"/>
<prop k="color2" v="0,104,55,255"/>
<prop k="stops" v="0.25;194,230,153,255:0.5;120,198,121,255:0.75;49,163,84,255"/>
</colorramp>
<colorramp type="gradient" name="YlGnBu">
<prop k="color1" v="255,255,204,255"/>
<prop k="color2" v="37,52,148,255"/>
<prop k="stops" v="0.25;161,218,180,255:0.5;65,182,196,255:0.75;44,127,184,255"/>
</colorramp>
<colorramp type="gradient" name="YlOrBr">
<prop k="color1" v="255,255,212,255"/>
<prop k="color2" v="153,52,4,255"/>
<prop k="stops" v="0.25;254,217,142,255:0.5;254,153,41,255:0.75;217,95,14,255"/>
</colorramp>
<colorramp type="gradient" name="YlOrRd">
<prop k="color1" v="255,255,178,255"/>
<prop k="color2" v="189,0,38,255"/>
<prop k="stops" v="0.25;254,204,92,255:0.5;253,141,60,255:0.75;240,59,32,255"/>
</colorramp>
</colorramps>
</qgis_style>
4 changes: 4 additions & 0 deletions scripts/remove_svn_conflict_files.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@
for FILE in `find . -name *.orig`; do echo "Deleting reject: $FILE"; rm -i $FILE; done
for FILE in `find . -name *.rej`; do echo "Deleting reject: $FILE"; rm -i $FILE; done
for FILE in `find . -name *.tmp | grep -v "\.svn"`; do echo "Deleting reject: $FILE"; rm -i $FILE; done
#rm $(git status | grep orig | awk '{print $2}')
#rm $(git status | grep LOCAL | awk '{print $2}')
#rm $(git status | grep REMOTE | awk '{print $2}')
#
18 changes: 15 additions & 3 deletions scripts/update_ts_files.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@ trap cleanup EXIT

PATH=$QTDIR/bin:$PATH

if type qmake-qt4 >/dev/null 2>&1; then
QMAKE=qmake-qt4
else
QMAKE=qmake
fi

if type lupdate-qt4 >/dev/null 2>&1; then
LUPDATE=lupdate-qt4
else
LUPDATE=lupdate
fi

exclude=
opts=
while (( $# > 0 )); do
Expand Down Expand Up @@ -89,22 +101,22 @@ for i in \
do
[ -f "$i" ] && mv "$i" "$i.save"
done
qmake -project -o qgis_ts.pro -nopwd src python i18n
$QMAKE -project -o qgis_ts.pro -nopwd src python i18n
if [ -n "$add" ]; then
for i in $add; do
echo "Adding translation for $i"
echo "TRANSLATIONS += i18n/qgis_$i.ts" >> qgis_ts.pro
done
fi
echo Updating translations
lupdate$opts -verbose qgis_ts.pro
$LUPDATE$opts -verbose qgis_ts.pro

if [ -n "$add" ]; then
for i in $add; do
if [ -f i18n/qgis_$i.ts ]; then
git add i18n/qgis_$i.ts
else
echo "Translaiton for $i was not added"
echo "Translation for $i was not added"
exit 1
fi
done
Expand Down
1 change: 0 additions & 1 deletion src/analysis/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../core/
${CMAKE_CURRENT_SOURCE_DIR}/../core/renderer
${CMAKE_CURRENT_SOURCE_DIR}/../core/spatialindex
${CMAKE_CURRENT_SOURCE_DIR}/../core/raster
interpolation
${PROJ_INCLUDE_DIR}
Expand Down
52 changes: 34 additions & 18 deletions src/analysis/network/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,43 @@ SET(QGIS_NETWORK_ANALYSIS_MOC_HDRS

QT4_WRAP_CPP(QGIS_NETWORK_ANALYSIS_MOC_SRCS ${QGIS_NETWORK_ANALYSIS_MOC_HDRS})

# install headers

SET(QGIS_NETWORK_ANALYSIS_HDRS
qgsgraph.h
qgsgraphbuilderintr.h
qgsgraphbuilder.h
qgsarcproperter.h
qgsdistancearcproperter.h
qgsgraphdirector.h
qgslinevectorlayerdirector.h
qgsgraphanalyzer.h )

INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}../../core/
${CMAKE_CURRENT_SOURCE_DIR}../../core/spatialindex
${PROJ_INCLUDE_DIR}
${GEOS_INCLUDE_DIR}
${GDAL_INCLUDE_DIR}
)


#############################################################
# qgis_analysis library

ADD_LIBRARY(qgis_networkanalysis SHARED ${QGIS_NETWORK_ANALYSIS_SRCS} ${QGIS_NETWORK_ANALYSIS_MOC_SRCS} )
ADD_LIBRARY(qgis_networkanalysis SHARED ${QGIS_NETWORK_ANALYSIS_SRCS} ${QGIS_NETWORK_ANALYSIS_MOC_SRCS} ${QGIS_NETWORK_ANALYSIS_HDRS})

ADD_DEPENDENCIES(qgis_networkanalysis qgis_core)
SET_TARGET_PROPERTIES(qgis_networkanalysis PROPERTIES
VERSION ${COMPLETE_VERSION}
SOVERSION ${COMPLETE_VERSION}
PUBLIC_HEADER "${QGIS_NETWORK_ANALYSIS_HDRS};${QGIS_NETWORK_ANALYSIS_MOC_HDRS}"
CLEAN_DIRECT_OUTPUT 1
FRAMEWORK 1
FRAMEWORK_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}"
MACOSX_FRAMEWORK_INFO_PLIST "${CMAKE_SOURCE_DIR}/mac/framework.info.plist.in"
MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${COMPLETE_VERSION}
MACOSX_FRAMEWORK_IDENTIFIER org.qgis.qgis_networkanalysis)

SET_TARGET_PROPERTIES(qgis_networkanalysis PROPERTIES VERSION ${COMPLETE_VERSION} SOVERSION ${COMPLETE_VERSION})
ADD_DEPENDENCIES(qgis_networkanalysis qgis_core)

TARGET_LINK_LIBRARIES(qgis_networkanalysis
qgis_core
Expand All @@ -47,21 +65,19 @@ IF (APPLE)
SET_TARGET_PROPERTIES(qgis_networkanalysis PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE )
ENDIF (APPLE)

# install

INSTALL(TARGETS qgis_networkanalysis
RUNTIME DESTINATION ${QGIS_BIN_DIR}
LIBRARY DESTINATION ${QGIS_LIB_DIR}
ARCHIVE DESTINATION ${QGIS_LIB_DIR})

ARCHIVE DESTINATION ${QGIS_LIB_DIR}
FRAMEWORK DESTINATION ${QGIS_FW_SUBDIR}
PUBLIC_HEADER DESTINATION ${QGIS_INCLUDE_DIR})

SET(QGIS_NETWORK_ANALYSIS_HDRS
qgsgraph.h
qgsgraphbuilderintr.h
qgsgraphbuilder.h
qgsarcproperter.h
qgsdistancearcproperter.h
qgsgraphdirector.h
qgslinevectorlayerdirector.h
qgsgraphanalyzer.h )
# Mac dev frameworks

INSTALL(CODE "MESSAGE(\"Installing NETWORK ANALYSIS headers...\")")
INSTALL(FILES ${QGIS_NETWORK_ANALYSIS_HDRS} ${QGIS_NETWORK_ANALYSIS_MOC_HDRS} DESTINATION ${QGIS_INCLUDE_DIR})
IF (APPLE AND QGIS_MACAPP_INSTALL_DEV)
INSTALL(TARGETS qgis_networkanalysis FRAMEWORK DESTINATION ${QGIS_MACAPP_DEV_PREFIX})
INSTALL(CODE "EXECUTE_PROCESS(COMMAND install_name_tool -id \"${QGIS_MACAPP_DEV_PREFIX}/qgis_networkanalysis.framework/Versions/${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}/qgis_networkanalysis\" \"$ENV{DESTDIR}${QGIS_MACAPP_DEV_PREFIX}/qgis_networkanalysis.framework/qgis_networkanalysis\")")
INSTALL(CODE "EXECUTE_PROCESS(COMMAND install_name_tool -change \"${CMAKE_INSTALL_NAME_DIR}/qgis_core.framework/Versions/${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}/qgis_core\" \"${QGIS_MACAPP_DEV_PREFIX}/qgis_core.framework/Versions/${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}/qgis_core\" \"$ENV{DESTDIR}${QGIS_MACAPP_DEV_PREFIX}/qgis_networkanalysis.framework/qgis_networkanalysis\")")
ENDIF (APPLE AND QGIS_MACAPP_INSTALL_DEV)
2 changes: 2 additions & 0 deletions src/analysis/vector/qgsgeometryanalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,14 @@ bool QgsGeometryAnalyzer::centroids( QgsVectorLayer* layer, const QString& shape
{
if ( !layer )
{
QgsDebugMsg( "No layer passed to centroids" );
return false;
}

QgsVectorDataProvider* dp = layer->dataProvider();
if ( !dp )
{
QgsDebugMsg( "No data provider for layer passed to centroids" );
return false;
}

Expand Down
4 changes: 0 additions & 4 deletions src/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -321,16 +321,12 @@ ENDIF (POSTGRES_FOUND)

IF (HAVE_SPATIALITE)
SET (QGIS_APP_SRCS ${QGIS_APP_SRCS}
spatialite/qgsspatialitesourceselect.cpp
spatialite/qgsnewspatialitelayerdialog.cpp
spatialite/qgsspatialitesridsdialog.cpp
spatialite/qgsspatialitetablemodel.cpp
)
SET (QGIS_APP_MOC_HDRS ${QGIS_APP_MOC_HDRS}
spatialite/qgsspatialitesourceselect.h
spatialite/qgsnewspatialitelayerdialog.h
spatialite/qgsspatialitesridsdialog.h
spatialite/qgsspatialitetablemodel.h
)
ENDIF (HAVE_SPATIALITE)

Expand Down
52 changes: 38 additions & 14 deletions src/app/composer/qgscomposertablewidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,35 @@ QgsComposerTableWidget::QgsComposerTableWidget( QgsComposerAttributeTable* table
}
}

//insert composer maps into combo
mLayerComboBox->blockSignals( true );
refreshMapComboBox();

updateGuiElements();
on_mComposerMapComboBox_activated( mComposerMapComboBox->currentIndex() );

if ( mComposerTable )
{
QObject::connect( mComposerTable, SIGNAL( maximumNumerOfFeaturesChanged( int ) ), this, SLOT( setMaximumNumberOfFeatures( int ) ) );
QObject::connect( mComposerTable, SIGNAL( itemChanged ), this, SLOT( updateGuiElements() ) );
}
}

QgsComposerTableWidget::~QgsComposerTableWidget()
{

}

void QgsComposerTableWidget::showEvent( QShowEvent* /* event */ )
{
refreshMapComboBox();
}

void QgsComposerTableWidget::refreshMapComboBox()
{
//save the current entry in case it is still present after refresh
QString saveCurrentComboText = mComposerMapComboBox->currentText();

mComposerMapComboBox->blockSignals( true );
mComposerMapComboBox->clear();
if ( mComposerTable )
{
const QgsComposition* tableComposition = mComposerTable->composition();
Expand All @@ -63,21 +90,18 @@ QgsComposerTableWidget::QgsComposerTableWidget( QgsComposerAttributeTable* table
}
}
}
mLayerComboBox->blockSignals( false );
mComposerMapComboBox->blockSignals( false );

updateGuiElements();
on_mComposerMapComboBox_activated( mComposerMapComboBox->currentIndex() );

if ( mComposerTable )
if ( mComposerMapComboBox->findText( saveCurrentComboText ) == -1 )
{
QObject::connect( mComposerTable, SIGNAL( maximumNumerOfFeaturesChanged( int ) ), this, SLOT( setMaximumNumberOfFeatures( int ) ) );
QObject::connect( mComposerTable, SIGNAL( itemChanged ), this, SLOT( updateGuiElements() ) );
//the former entry is no longer present. Inform the scalebar about the changed composer map
on_mComposerMapComboBox_activated( mComposerMapComboBox->currentIndex() );
}
else
{
//the former entry is still present. Make it the current entry again
mComposerMapComboBox->setCurrentIndex( mComposerMapComboBox->findText( saveCurrentComboText ) );
}
}

QgsComposerTableWidget::~QgsComposerTableWidget()
{

}

void QgsComposerTableWidget::on_mLayerComboBox_currentIndexChanged( int index )
Expand Down
4 changes: 4 additions & 0 deletions src/app/composer/qgscomposertablewidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,15 @@ class QgsComposerTableWidget: public QWidget, private Ui::QgsComposerTableWidget
QgsComposerTableWidget( QgsComposerAttributeTable* table );
~QgsComposerTableWidget();

protected:
void showEvent( QShowEvent * event );

private:
QgsComposerAttributeTable* mComposerTable;

/**Blocks / unblocks the signals of all GUI elements*/
void blockAllSignals( bool b );
void refreshMapComboBox();

private slots:
void on_mLayerComboBox_currentIndexChanged( int index );
Expand Down
9 changes: 7 additions & 2 deletions src/app/legend/qgslegend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1752,7 +1752,12 @@ void QgsLegend::refreshLayerSymbology( QString key, bool expandItem )
}

//store the current item
QModelIndex currentItemIndex( currentIndex() );
QTreeWidgetItem* current = currentItem();
// in case the current item is a child of the layer, use the layer as current item
// because otherwise we would set an invalid item as current item
// (in refreshSymbology the symbology items are removed and new ones are added)
if ( current && current->parent() == theLegendLayer )
current = current->parent();

double widthScale = 1.0;
if ( mMapCanvas && mMapCanvas->map() )
Expand All @@ -1763,7 +1768,7 @@ void QgsLegend::refreshLayerSymbology( QString key, bool expandItem )
theLegendLayer->refreshSymbology( key, widthScale );

//restore the current item again
setCurrentIndex( currentItemIndex );
setCurrentItem( current );
adjustIconSize();
setItemExpanded( theLegendLayer, expandItem );//make sure the symbology items are visible
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/legend/qgslegendlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ void QgsLegendLayer::addToPopupMenu( QMenu& theMenu )
saveSelectionAsAction->setEnabled( false );
}

if ( !vlayer->isEditable() && vlayer->dataProvider()->supportsSubsetString() )
if ( !vlayer->isEditable() && vlayer->dataProvider()->supportsSubsetString() && vlayer->vectorJoins().isEmpty() )
theMenu.addAction( tr( "&Query..." ), QgisApp::instance(), SLOT( layerSubsetString() ) );

//show number of features in legend if requested
Expand Down
105 changes: 25 additions & 80 deletions src/app/qgisapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
#include "qgsmaptip.h"
#include "qgsmergeattributesdialog.h"
#include "qgsmessageviewer.h"
#include "qgsmimedatautils.h"
#include "qgsnewvectorlayerdialog.h"
#include "qgsoptions.h"
#include "qgspastetransformations.h"
Expand Down Expand Up @@ -227,21 +228,19 @@
//
// Conditional Includes
//
#ifdef HAVE_POSTGRESQL
#include "../providers/postgres/qgspgsourceselect.h"
#ifdef HAVE_PGCONFIG
#include <pg_config.h>
#else
#define PG_VERSION "unknown"
#endif
#endif

#include <sqlite3.h>

#ifdef HAVE_SPATIALITE
extern "C"
{
#include <spatialite.h>
}
#include "spatialite/qgsspatialitesourceselect.h"
#include "spatialite/qgsnewspatialitelayerdialog.h"
#endif

Expand Down Expand Up @@ -278,7 +277,7 @@ static void setTitleBarText_( QWidget & qgisApp )
{
QString caption = QgisApp::tr( "Quantum GIS " );

if ( QString( QGis::QGIS_VERSION ).endsWith( "Trunk" ) )
if ( QString( QGis::QGIS_VERSION ).endsWith( "Alpha" ) )
{
caption += QString( "%1" ).arg( QGis::QGIS_DEV_VERSION );
}
Expand Down Expand Up @@ -683,31 +682,18 @@ void QgisApp::dropEvent( QDropEvent *event )
openFile( fileName );
}
}
if ( event->mimeData()->hasFormat( "application/x-vnd.qgis.qgis.uri" ) )
if ( QgsMimeDataUtils::isUriList( event->mimeData() ) )
{
QByteArray encodedData = event->mimeData()->data( "application/x-vnd.qgis.qgis.uri" );
QDataStream stream( &encodedData, QIODevice::ReadOnly );
QString xUri; // extended uri: layer_type:provider_key:uri
while ( !stream.atEnd() )
QgsMimeDataUtils::UriList lst = QgsMimeDataUtils::decodeUriList( event->mimeData() );
foreach( const QgsMimeDataUtils::Uri& u, lst )
{
stream >> xUri;
QgsDebugMsg( xUri );
QRegExp rx( "^([^:]+):([^:]+):([^:]+):(.+)" );
if ( rx.indexIn( xUri ) != -1 )
if ( u.layerType == "vector" )
{
QString layerType = rx.cap( 1 );
QString providerKey = rx.cap( 2 );
QString name = rx.cap( 3 );
QString uri = rx.cap( 4 );
QgsDebugMsg( "type: " + layerType + " key: " + providerKey + " name: " + name + " uri: " + uri );
if ( layerType == "vector" )
{
addVectorLayer( uri, name, providerKey );
}
else if ( layerType == "raster" )
{
addRasterLayer( uri, name, providerKey, QStringList(), QStringList(), QString(), QString() );
}
addVectorLayer( u.uri, u.name, u.providerKey );
}
else if ( u.layerType == "raster" )
{
addRasterLayer( u.uri, u.name, u.providerKey, QStringList(), QStringList(), QString(), QString() );
}
}
}
Expand Down Expand Up @@ -1092,6 +1078,10 @@ void QgisApp::createMenus()
// don't add it yet, wait for a plugin
mDatabaseMenu = new QMenu( tr( "&Database" ) );

// Help menu
// add What's this button to it
QAction* before = mActionHelpAPI;
mHelpMenu->insertAction( before, QWhatsThis::createAction() );
}

void QgisApp::createToolBars()
Expand Down Expand Up @@ -2346,62 +2336,17 @@ void QgisApp::addSpatiaLiteLayer()
}

// show the SpatiaLite dialog

QgsSpatiaLiteSourceSelect *dbs = new QgsSpatiaLiteSourceSelect( this );

mMapCanvas->freeze();

if ( dbs->exec() )
QDialog *dbs = dynamic_cast<QDialog*>( QgsProviderRegistry::instance()->selectWidget( QString( "spatialite" ), this ) );
if ( !dbs )
{
// Let render() do its own cursor management
// QApplication::setOverrideCursor(Qt::WaitCursor);


// repaint the canvas if it was covered by the dialog

// add files to the map canvas
QStringList tables = dbs->selectedTables();

QApplication::setOverrideCursor( Qt::WaitCursor );

// for each selected table, connect to the database and build a canvasitem for it
QStringList::Iterator it = tables.begin();
while ( it != tables.end() )
{
// create the layer
QgsDataSourceURI uri( *it );
QgsVectorLayer *layer = new QgsVectorLayer( uri.uri(), uri.table(), "spatialite" );
if ( layer->isValid() )
{
// register this layer with the central layers registry
QgsMapLayerRegistry::instance()->addMapLayer( layer );
}
else
{
QgsDebugMsg(( *it ) + " is an invalid layer - not loaded" );
QMessageBox::critical( this, tr( "Invalid Layer" ), tr( "%1 is an invalid layer and cannot be loaded." ).arg( *it ) );
delete layer;
}
//qWarning("incrementing iterator");
++it;
}

QApplication::restoreOverrideCursor();

statusBar()->showMessage( mMapCanvas->extent().toString( 2 ) );
QMessageBox::warning( this, tr( "SpatiaLite" ), tr( "Cannot get SpatiaLite select dialog from provider." ) );
return;
}
connect( dbs , SIGNAL( addDatabaseLayers( QStringList const &, QString const & ) ),
this , SLOT( addDatabaseLayers( QStringList const &, QString const & ) ) );
dbs->exec();
delete dbs;

// update UI
qApp->processEvents();

// draw the map
mMapCanvas->freeze( false );
mMapCanvas->refresh();

// Let render() do its own cursor management
// QApplication::restoreOverrideCursor();

} // QgisApp::addSpatiaLiteLayer()
#endif

Expand Down Expand Up @@ -6388,7 +6333,7 @@ void QgisApp::oldProjectVersionWarning( QString oldVersion )
"<p>Version of the project file: %1<br>Current version of QGIS: %2" )
.arg( oldVersion )
.arg( QGis::QGIS_VERSION )
.arg( "<a href=\"https://trac.osgeo.org/qgis\">http://trac.osgeo.org/qgis</a> " )
.arg( "<a href=\"http://hub.qgis.org/projects/quantum-gis\">http://hub.qgis.org/projects/quantum-gis</a> " )
.arg( tr( "<tt>Settings:Options:General</tt>", "Menu path to setting options" ) )
.arg( tr( "Warn me when opening a project file saved with an older version of QGIS" ) )
);
Expand Down
Loading