Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Added new vector algorithms
  • Loading branch information
volaya committed Nov 12, 2012
1 parent 6bbe81b commit da42b5d
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 12 deletions.
18 changes: 10 additions & 8 deletions python/plugins/sextante/algs/EquivalentNumField.py
Expand Up @@ -33,7 +33,7 @@
from PyQt4 import QtGui
from sextante.parameters.ParameterTableField import ParameterTableField

class AutoincrementalField(GeoAlgorithm):
class EquivalentNumField(GeoAlgorithm):

INPUT = "INPUT"
OUTPUT = "OUTPUT"
Expand All @@ -43,12 +43,13 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/../images/toolbox.png")

def processAlgorithm(self, progress):
field_index = self.getParameterValue(self.FIELD)
fieldname = self.getParameterValue(self.FIELD)
output = self.getOutputFromName(self.OUTPUT)
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(self.INPUT))
vprovider = vlayer.dataProvider()
field_index = vprovider.fieldNameIndex(fieldname)
allAttrs = vprovider.attributeIndexes()
vprovider.select( allAttrs )
vprovider.select(allAttrs)
fields = vprovider.fields()
fields[len(fields)] = QgsField("NUM_FIELD", QVariant.Int)
writer = output.getVectorWriter(fields, vprovider.geometryType(), vprovider.crs() )
Expand All @@ -62,24 +63,25 @@ def processAlgorithm(self, progress):
progress.setPercentage(int((100 * nElement)/nFeat))
nElement += 1
atMap = inFeat.attributeMap()
clazz = atMap[field_index]
if not clazz in classes.keys:
clazz = atMap[field_index].toString()
if clazz not in classes:
classes[clazz] = len(classes.keys())
while vprovider.nextFeature(inFeat):
progress.setPercentage(int((100 * nElement)/nFeat))
nElement += 1
inGeom = inFeat.geometry()
outFeat.setGeometry( inGeom )
atMap = inFeat.attributeMap()
clazz = atMap[field_index].toString()
outFeat.setAttributeMap( atMap )
outFeat.addAttribute( len(vprovider.fields()), QVariant(nElement) )
outFeat.addAttribute( len(vprovider.fields()), QVariant(classes[clazz]) )
writer.addFeature( outFeat )
del writer

def defineCharacteristics(self):
self.name = "Add autoincremental field"
self.name = "Create equivalent numerical field"
self.group = "Algorithms for vector layers"
self.addParameter(ParameterVector(self.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY))
self.addParameter(ParameterTableField(self.FIELD, "Unique ID Field", self.INPUT))
self.addParameter(ParameterTableField(self.FIELD, "Class field", self.INPUT))
self.addOutput(OutputVector(self.OUTPUT, "Output layer"))

3 changes: 2 additions & 1 deletion python/plugins/sextante/algs/SextanteAlgorithmProvider.py
Expand Up @@ -16,6 +16,7 @@
* *
***************************************************************************
"""
from sextante.algs.EquivalentNumField import EquivalentNumField

__author__ = 'Victor Olaya'
__date__ = 'August 2012'
Expand All @@ -38,7 +39,7 @@ class SextanteAlgorithmProvider(AlgorithmProvider):
def __init__(self):
AlgorithmProvider.__init__(self)
self.alglist = [AddTableField(), FieldsCalculator(), SaveSelectedFeatures(),
AutoincrementalField(), Explode(), FieldsPyculator()]
AutoincrementalField(), Explode(), FieldsPyculator(), EquivalentNumField()]

def initializeSettings(self):
AlgorithmProvider.initializeSettings(self)
Expand Down
5 changes: 3 additions & 2 deletions python/plugins/sextante/ftools/FToolsAlgorithmProvider.py
Expand Up @@ -17,6 +17,7 @@
***************************************************************************
"""
from sextante.ftools.PointsInPolygonWeighted import PointsInPolygonWeighted
from sextante.ftools.PointsInPolygonUnique import PointsInPolygonUnique

__author__ = 'Victor Olaya'
__date__ = 'August 2012'
Expand Down Expand Up @@ -77,8 +78,8 @@ class FToolsAlgorithmProvider(AlgorithmProvider):

def __init__(self):
AlgorithmProvider.__init__(self)
self.alglist = [SumLines(), PointsInPolygon(), PointsInPolygonWeighted(), BasicStatisticsStrings(),
BasicStatisticsNumbers(), NearestNeighbourAnalysis(),
self.alglist = [SumLines(), PointsInPolygon(), PointsInPolygonWeighted(), PointsInPolygonUnique(),
BasicStatisticsStrings(), BasicStatisticsNumbers(), NearestNeighbourAnalysis(),
MeanCoords(), LinesIntersection(), UniqueValues(), PointDistance(),
# data management
ReprojectLayer(),
Expand Down
130 changes: 130 additions & 0 deletions python/plugins/sextante/ftools/PointsInPolygonUnique.py
@@ -0,0 +1,130 @@
# -*- coding: utf-8 -*-

"""
***************************************************************************
PointsInPolygon.py
---------------------
Date : August 2012
Copyright : (C) 2012 by Victor Olaya
Email : volayaf 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 sextante.parameters.ParameterTableField import ParameterTableField

__author__ = 'Victor Olaya'
__date__ = 'August 2012'
__copyright__ = '(C) 2012, Victor Olaya'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'

import os.path

from PyQt4 import QtGui
from PyQt4.QtCore import *

from qgis.core import *

from sextante.core.GeoAlgorithm import GeoAlgorithm
from sextante.core.QGisLayers import QGisLayers
from sextante.core.SextanteLog import SextanteLog

from sextante.parameters.ParameterVector import ParameterVector
from sextante.parameters.ParameterString import ParameterString

from sextante.outputs.OutputVector import OutputVector

from sextante.ftools import FToolsUtils as utils


class PointsInPolygonUnique(GeoAlgorithm):

POLYGONS = "POLYGONS"
POINTS = "POINTS"
OUTPUT = "OUTPUT"
FIELD = "FIELD"
CLASSFIELD = "CLASSFIELD"

def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/sum_points.png")

def defineCharacteristics(self):
self.name = "Count unique points in polygon"
self.group = "Analysis tools"
self.addParameter(ParameterVector(self.POLYGONS, "Polygons", ParameterVector.VECTOR_TYPE_POLYGON))
self.addParameter(ParameterVector(self.POINTS, "Points", ParameterVector.VECTOR_TYPE_POINT))
self.addParameter(ParameterTableField(self.CLASSFIELD, "Class field", self.POINTS))
self.addParameter(ParameterString(self.FIELD, "Count field name", "NUMPOINTS"))
self.addOutput(OutputVector(self.OUTPUT, "Result"))

def processAlgorithm(self, progress):
polyLayer = QGisLayers.getObjectFromUri(self.getParameterValue(self.POLYGONS))
pointLayer = QGisLayers.getObjectFromUri(self.getParameterValue(self.POINTS))
fieldName = self.getParameterValue(self.FIELD)
classFieldName = self.getParameterValue(self.CLASSFIELD)

output = self.getOutputValue(self.OUTPUT)

polyProvider = polyLayer.dataProvider()
pointProvider = pointLayer.dataProvider()
if polyProvider.crs() != pointProvider.crs():
SextanteLog.addToLog(SextanteLog.LOG_WARNING,
"CRS warning: Input layers have non-matching CRS. This may cause unexpected results.")

classFieldIndex = pointProvider.fieldNameIndex(classFieldName)
idxCount, fieldList = utils.findOrCreateField(polyLayer, polyLayer.pendingFields(), fieldName)

writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fieldList,
polyProvider.geometryType(), polyProvider.crs())

spatialIndex = utils.createSpatialIndex(pointProvider)

pointProvider.rewind()
pointProvider.select()

allAttrs = polyLayer.pendingAllAttributesList()
polyLayer.select(allAttrs)

ftPoly = QgsFeature()
ftPoint = QgsFeature()
outFeat = QgsFeature()
geom = QgsGeometry()

current = 0
total = float(polyProvider.featureCount())
hasIntersections = False

while polyLayer.nextFeature(ftPoly):
geom = ftPoly.geometry()
atMap = ftPoly.attributeMap()

classes = []
hasIntersections = False
points = spatialIndex.intersects(geom.boundingBox())
if len(points) > 0:
hasIntersections = True

if hasIntersections:
for i in points:
pointLayer.featureAtId(int(i), ftPoint, True, True)
tmpGeom = QgsGeometry(ftPoint.geometry())
if geom.contains(tmpGeom):
clazz = ftPoint.attributeMap()[classFieldIndex].toString()
if not clazz in classes:
classes.append(clazz)

outFeat.setGeometry(geom)
outFeat.setAttributeMap(atMap)
outFeat.addAttribute(idxCount, QVariant(len(classes)))
writer.addFeature(outFeat)

current += 1
progress.setPercentage(current / total)

del writer
2 changes: 1 addition & 1 deletion python/plugins/sextante/ftools/PointsInPolygonWeighted.py
Expand Up @@ -111,7 +111,7 @@ def processAlgorithm(self, progress):

if hasIntersections:
for i in points:
pointLayer.featureAtId(int(i), ftPoint, True, False)
pointLayer.featureAtId(int(i), ftPoint, True, True)
tmpGeom = QgsGeometry(ftPoint.geometry())
if geom.contains(tmpGeom):
try:
Expand Down
@@ -0,0 +1,61 @@
#Definition of inputs and outputs
#==================================
##input=vector
##class_field=field input
##value_field=field input
##output=output vector

#Algorithm body
#==================================
from sextante.core.QGisLayers import QGisLayers
from qgis.core import *
from PyQt4.QtCore import *
from sextante.core.SextanteVectorWriter import SextanteVectorWriter

# "input" contains the location of the selected layer.
# We get the actual object, so we can get its bounds
layer = QGisLayers.getObjectFromUri(input)
provider = layer.dataProvider()
allAttrs = provider.attributeIndexes()
provider.select( allAttrs )
fields = provider.fields()
fields[len(fields)] = QgsField("UNIQ_COUNT", QVariant.Int)
writer = SextanteVectorWriter(output, None, fields, provider.geometryType(), provider.crs() )

# Fields are defined by their names, but QGIS needs the index for the attributes map
class_field_index = provider.fieldNameIndex(class_field)
value_field_index = provider.fieldNameIndex(value_field)

inFeat = QgsFeature()
outFeat = QgsFeature()
inGeom = QgsGeometry()
nFeat = provider.featureCount()
nElement = 0
classes = {}

#Iterate over input layer to count unique values in each class
while provider.nextFeature(inFeat):
#Printing a number to the console to indicate progress
print int((50 * nElement)/nFeat)
nElement += 1
atMap = inFeat.attributeMap()
clazz = atMap[class_field_index].toString()
value = atMap[value_field_index].toString()
if clazz not in classes:
classes[clazz] = []
if value not in classes[clazz]:
classes[clazz].append(value)

# Create output vector layer with additional attribute
while provider.nextFeature(inFeat):
print int((500 * nElement)/nFeat)
nElement += 1
inGeom = inFeat.geometry()
outFeat.setGeometry( inGeom )
atMap = inFeat.attributeMap()
clazz = atMap[class_field_index].toString()
outFeat.setAttributeMap( atMap )
outFeat.addAttribute( len(provider.fields()), QVariant(len(classes[clazz])))
writer.addFeature( outFeat )

del writer

0 comments on commit da42b5d

Please sign in to comment.