# -*- coding: utf-8 -*- #----------------------------------------------------------- # # fTools # Copyright (C) 2008-2011 Carson Farmer # EMAIL: carson.farmer (at) gmail.com # WEB : http://www.ftools.ca/fTools.html # # A collection of data management and analysis tools for vector data # #----------------------------------------------------------- # # licensed under the terms of GNU GPL 2 # # 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. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # #--------------------------------------------------------------------- from PyQt4.QtCore import * from PyQt4.QtGui import * from qgis.core import * import resources_rc import os.path, sys # Set up current path, so that we know where to look for mudules currentPath = os.path.dirname(__file__) sys.path.append(os.path.abspath(os.path.dirname(__file__) + '/tools')) # Multi-function modules import doGeometry, doGeoprocessing, doVisual # Single function modules # TODO: Eliminate the following modules in favour of above multi-function formats import doIntersectLines, doSelectByLocation, doVectorSplit, doMeanCoords import doPointDistance, doPointsInPolygon, doRandom, doRandPoints, doRegPoints import doSpatialJoin, doSubsetSelect, doSumLines, doVectorGrid, doMergeShapes import doValidate, doSimplify, doDefineProj, doSpatialIndex, doEliminate class fToolsPlugin: def __init__(self,iface): self.iface = iface try: self.QgisVersion = unicode(QGis.QGIS_VERSION_INT) except: self.QgisVersion = unicode(QGis.qgisVersion)[0] def getThemeIcon(self, icon): settings = QSettings() pluginPath = os.path.dirname(__file__) themePath = "icons" + QDir.separator() + settings.value("/Themes") + QDir.separator() + icon defaultPath = "icons" + QDir.separator() + "default" + QDir.separator() + icon if QFile.exists(pluginPath + QDir.separator() + themePath): return QIcon(":" + themePath) elif QFile.exists(pluginPath + QDir.separator() + defaultPath): return QIcon(":" + defaultPath) else: return QIcon() def updateThemeIcons(self, theme): self.analysisMenu.setIcon(QIcon(self.getThemeIcon("analysis.png"))) self.distMatrix.setIcon(QIcon(self.getThemeIcon("matrix.png"))) self.sumLines.setIcon(QIcon(self.getThemeIcon("sum_lines.png"))) self.pointsPoly.setIcon(QIcon(self.getThemeIcon("sum_points.png"))) self.compStats.setIcon(QIcon(self.getThemeIcon("basic_statistics.png"))) self.listUnique.setIcon(QIcon(self.getThemeIcon("unique.png"))) self.nearestNeigh.setIcon(QIcon(self.getThemeIcon("neighbour.png"))) self.meanCoords.setIcon(QIcon(self.getThemeIcon("mean.png"))) self.intLines.setIcon(QIcon(self.getThemeIcon("intersections.png"))) self.researchMenu.setIcon(QIcon(self.getThemeIcon("sampling.png"))) self.randSel.setIcon(QIcon(self.getThemeIcon("random_selection.png"))) self.randSub.setIcon(QIcon(self.getThemeIcon("sub_selection.png"))) self.randPoints.setIcon(QIcon(self.getThemeIcon("random_points.png"))) self.regPoints.setIcon(QIcon(self.getThemeIcon("regular_points.png"))) self.vectGrid.setIcon(QIcon(self.getThemeIcon("vector_grid.png"))) self.selectLocation.setIcon(QIcon(self.getThemeIcon("select_location.png"))) self.layerExtent.setIcon(QIcon(self.getThemeIcon("layer_extent.png"))) self.geoMenu.setIcon(QIcon(self.getThemeIcon("geoprocessing.png"))) self.minConvex.setIcon(QIcon(self.getThemeIcon("convex_hull.png"))) self.dynaBuffer.setIcon(QIcon(self.getThemeIcon("buffer.png"))) self.intersect.setIcon(QIcon(self.getThemeIcon("intersect.png"))) self.union.setIcon(QIcon(self.getThemeIcon("union.png"))) self.symDifference.setIcon(QIcon(self.getThemeIcon("sym_difference.png"))) self.clip.setIcon(QIcon(self.getThemeIcon("clip.png"))) self.dissolve.setIcon(QIcon(self.getThemeIcon("dissolve.png"))) self.erase.setIcon(QIcon(self.getThemeIcon("difference.png"))) self.eliminate.setIcon(QIcon(self.getThemeIcon("eliminate.png"))) self.conversionMenu.setIcon(QIcon(self.getThemeIcon("geometry.png"))) self.compGeo.setIcon(QIcon(self.getThemeIcon("export_geometry.png"))) self.checkGeom.setIcon(QIcon(self.getThemeIcon("check_geometry.png"))) self.centroids.setIcon(QIcon(self.getThemeIcon("centroids.png"))) self.delaunay.setIcon(QIcon(self.getThemeIcon("delaunay.png"))) 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"))) self.linesToPolys.setIcon(QIcon(self.getThemeIcon("to_lines.png"))) self.dataManageMenu.setIcon(QIcon(self.getThemeIcon("management.png"))) self.define.setIcon(QIcon(self.getThemeIcon("define_projection.png"))) 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: QMessageBox.warning(self.iface.getMainWindow(), "fTools", QCoreApplication.translate("fTools", "QGIS version detected: ") +unicode(self.QgisVersion)+".xx\n" + QCoreApplication.translate("fTools", "This version of fTools requires at least QGIS version 1.0.0\nPlugin will not be enabled.")) return None QObject.connect(self.iface, SIGNAL("currentThemeChanged (QString)"), self.updateThemeIcons) self.analysisMenu = QMenu(QCoreApplication.translate("fTools", "&Analysis Tools")) self.distMatrix = QAction(QCoreApplication.translate("fTools", "Distance matrix"),self.iface.mainWindow()) self.sumLines = QAction(QCoreApplication.translate("fTools", "Sum line lengths"), self.iface.mainWindow()) self.pointsPoly = QAction(QCoreApplication.translate("fTools", "Points in polygon"),self.iface.mainWindow()) self.compStats = QAction(QCoreApplication.translate("fTools", "Basic statistics"),self.iface.mainWindow()) self.listUnique = QAction(QCoreApplication.translate("fTools", "List unique values"),self.iface.mainWindow()) self.nearestNeigh = QAction(QCoreApplication.translate("fTools", "Nearest neighbour analysis"), self.iface.mainWindow()) self.meanCoords = QAction(QCoreApplication.translate("fTools", "Mean coordinate(s)"),self.iface.mainWindow()) self.intLines = QAction(QCoreApplication.translate("fTools", "Line intersections") ,self.iface.mainWindow()) self.analysisMenu.addActions([self.distMatrix, self.sumLines, self.pointsPoly, self.listUnique, self.compStats, self.nearestNeigh, self.meanCoords, self.intLines]) self.researchMenu = QMenu(QCoreApplication.translate("fTools", "&Research Tools")) self.randSel = QAction(QCoreApplication.translate("fTools", "Random selection"),self.iface.mainWindow()) self.randSub = QAction(QCoreApplication.translate("fTools", "Random selection within subsets"),self.iface.mainWindow()) self.randPoints = QAction(QCoreApplication.translate("fTools", "Random points"),self.iface.mainWindow()) self.regPoints = QAction(QCoreApplication.translate("fTools", "Regular points"), self.iface.mainWindow()) self.vectGrid = QAction(QCoreApplication.translate("fTools", "Vector grid"), self.iface.mainWindow()) self.selectLocation = QAction(QCoreApplication.translate("fTools", "Select by location"), self.iface.mainWindow()) self.layerExtent = QAction(QCoreApplication.translate("fTools", "Polygon from layer extent"), self.iface.mainWindow()) self.researchMenu.addActions([self.randSel, self.randSub, self.randPoints, self.regPoints, self.vectGrid, self.selectLocation, self.layerExtent]) self.geoMenu = QMenu(QCoreApplication.translate("fTools", "&Geoprocessing Tools")) self.minConvex = QAction(QCoreApplication.translate("fTools", "Convex hull(s)"),self.iface.mainWindow()) self.dynaBuffer = QAction(QCoreApplication.translate("fTools", "Buffer(s)"),self.iface.mainWindow()) self.intersect = QAction(QCoreApplication.translate("fTools", "Intersect"),self.iface.mainWindow()) self.union = QAction(QCoreApplication.translate("fTools", "Union"),self.iface.mainWindow()) self.symDifference = QAction(QCoreApplication.translate("fTools", "Symetrical difference"),self.iface.mainWindow()) self.clip = QAction(QCoreApplication.translate("fTools", "Clip"),self.iface.mainWindow()) self.dissolve = QAction(QCoreApplication.translate("fTools", "Dissolve"),self.iface.mainWindow()) self.erase = QAction(QCoreApplication.translate("fTools", "Difference"),self.iface.mainWindow()) self.eliminate = QAction( QCoreApplication.translate( "fTools", "Eliminate sliver polygons" ),self.iface.mainWindow() ) self.geoMenu.addActions([self.minConvex, self.dynaBuffer, self.intersect, self.union, self.symDifference, self.clip, self.erase, self.dissolve, self.eliminate]) self.conversionMenu = QMenu(QCoreApplication.translate("fTools", "G&eometry Tools")) self.compGeo = QAction(QCoreApplication.translate("fTools", "Export/Add geometry columns"),self.iface.mainWindow()) self.checkGeom = QAction(QCoreApplication.translate("fTools", "Check geometry validity"),self.iface.mainWindow()) self.centroids = QAction(QCoreApplication.translate("fTools", "Polygon centroids"),self.iface.mainWindow()) self.delaunay = QAction(QCoreApplication.translate("fTools", "Delaunay triangulation"),self.iface.mainWindow()) 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.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.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 = self.iface.vectorMenu() self.menu.addMenu( self.analysisMenu ) self.menu.addMenu( self.researchMenu ) self.menu.addMenu( self.geoMenu ) self.menu.addMenu( self.conversionMenu ) self.menu.addMenu( self.dataManageMenu ) QObject.connect(self.distMatrix, SIGNAL("triggered()"), self.dodistMatrix) QObject.connect(self.sumLines, SIGNAL("triggered()"), self.dosumLines) QObject.connect(self.pointsPoly, SIGNAL("triggered()"), self.dopointsPoly) QObject.connect(self.compStats, SIGNAL("triggered()"), self.docompStats) QObject.connect(self.listUnique, SIGNAL("triggered()"), self.dolistUnique) QObject.connect(self.nearestNeigh, SIGNAL("triggered()"), self.donearestNeigh) QObject.connect(self.meanCoords, SIGNAL("triggered()"), self.domeanCoords) QObject.connect(self.intLines, SIGNAL("triggered()"), self.dointLines) QObject.connect(self.randSel, SIGNAL("triggered()"), self.dorandSel) QObject.connect(self.randSub, SIGNAL("triggered()"), self.dorandSub) QObject.connect(self.randPoints, SIGNAL("triggered()"), self.dorandPoints) QObject.connect(self.regPoints, SIGNAL("triggered()"), self.doregPoints) QObject.connect(self.vectGrid, SIGNAL("triggered()"), self.dovectGrid) QObject.connect(self.selectLocation, SIGNAL("triggered()"), self.doselectLocation) QObject.connect(self.layerExtent, SIGNAL("triggered()"), self.doextent) QObject.connect(self.minConvex, SIGNAL("triggered()"), self.dominConvex) QObject.connect(self.intersect, SIGNAL("triggered()"), self.dointersect) QObject.connect(self.dissolve, SIGNAL("triggered()"), self.dodissolve) QObject.connect(self.symDifference, SIGNAL("triggered()"), self.dosymdifference) QObject.connect(self.erase, SIGNAL("triggered()"), self.doerase) QObject.connect(self.union, SIGNAL("triggered()"), self.dounion) QObject.connect(self.clip, SIGNAL("triggered()"), self.doclip) QObject.connect(self.dynaBuffer, SIGNAL("triggered()"), self.dodynaBuffer) QObject.connect(self.eliminate, SIGNAL("triggered()"), self.doEliminate) 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.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) QObject.connect(self.polysToLines, SIGNAL("triggered()"), self.dopolysToLines) QObject.connect(self.linesToPolys, SIGNAL("triggered()"), self.dolinesToPolys) QObject.connect(self.compGeo, SIGNAL("triggered()"), self.docompGeo) QObject.connect(self.extNodes, SIGNAL("triggered()"), self.doextNodes) QObject.connect(self.define, SIGNAL("triggered()"), self.dodefine) 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): self.menu.removeAction( self.analysisMenu.menuAction() ) self.menu.removeAction( self.researchMenu.menuAction() ) self.menu.removeAction( self.geoMenu.menuAction() ) self.menu.removeAction( self.conversionMenu.menuAction() ) self.menu.removeAction( self.dataManageMenu.menuAction() ) 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): d = doGeometry.GeometryDialog(self.iface, 4) d.exec_() def dolinesToPolys(self): d = doGeometry.GeometryDialog(self.iface, 11) d.exec_() def docheckGeom(self): d = doValidate.ValidateDialog(self.iface) d.show() d.exec_() def domultiToSingle(self): d = doGeometry.GeometryDialog(self.iface, 2) d.exec_() def dosingleToMulti(self): d = doGeometry.GeometryDialog(self.iface, 1) d.exec_() def doselectLocation(self): d = doSelectByLocation.Dialog(self.iface) d.exec_() def domeanCoords(self): d = doMeanCoords.Dialog(self.iface, 1) d.exec_() def dominConvex(self): d = doGeoprocessing.GeoprocessingDialog(self.iface, 2) d.exec_() def dodynaBuffer(self): d = doGeoprocessing.GeoprocessingDialog(self.iface, 1) d.exec_() def dointersect(self): d = doGeoprocessing.GeoprocessingDialog(self.iface, 5) d.exec_() def dodissolve(self): d = doGeoprocessing.GeoprocessingDialog(self.iface, 4) d.exec_() def doerase(self): d = doGeoprocessing.GeoprocessingDialog(self.iface, 3) d.exec_() def dosymdifference(self): d = doGeoprocessing.GeoprocessingDialog(self.iface, 7) d.exec_() def dounion(self): d = doGeoprocessing.GeoprocessingDialog(self.iface, 6) d.exec_() def doclip(self): d = doGeoprocessing.GeoprocessingDialog(self.iface, 8) d.exec_() def donearestNeigh(self): d = doVisual.VisualDialog(self.iface, 4) d.exec_() def dodistMatrix(self): d = doPointDistance.Dialog(self.iface) d.exec_() def docentroids(self): d = doGeometry.GeometryDialog(self.iface, 7) d.exec_() def dodelaunay(self): d = doGeometry.GeometryDialog(self.iface, 8) d.exec_() def dovoronoi(self): d = doGeometry.GeometryDialog(self.iface, 10) d.exec_() def doextent(self): d = doGeometry.GeometryDialog(self.iface, 9) d.exec_() def dosumLines(self): d = doSumLines.Dialog(self.iface) d.exec_() def dopointsPoly(self): d = doPointsInPolygon.Dialog(self.iface) d.show() d.exec_() def dorandSel(self): d = doRandom.Dialog(self.iface) d.exec_() def dorandSub(self): d = doSubsetSelect.Dialog(self.iface) d.exec_() def dorandPoints(self): d = doRandPoints.Dialog(self.iface) d.exec_() def doregPoints(self): d = doRegPoints.Dialog(self.iface) d.exec_() def dovectGrid(self): d = doVectorGrid.Dialog(self.iface) d.exec_() def doextNodes(self): d = doGeometry.GeometryDialog(self.iface, 3) d.exec_() def dointLines(self): d = doIntersectLines.Dialog(self.iface) d.exec_() def dosplitVect(self): d = doVectorSplit.Dialog(self.iface) d.show() d.exec_() def docompGeo(self): d = doGeometry.GeometryDialog(self.iface, 5) d.exec_() def dolistUnique(self): d = doVisual.VisualDialog(self.iface, 2) d.exec_() def docompStats(self): d = doVisual.VisualDialog(self.iface, 3) d.exec_() def dodefine(self): d = doDefineProj.Dialog(self.iface) d.exec_() def dospatJoin(self): d = doSpatialJoin.Dialog(self.iface) d.exec_() def doMergeShapes(self): d = doMergeShapes.Dialog(self.iface) d.show() d.exec_() def doSpatIndex(self): d = doSpatialIndex.Dialog(self.iface) d.show() d.exec_() def doEliminate(self): d = doEliminate.Dialog(self.iface) d.exec_()