Skip to content
Permalink
Browse files

Added new vector algorithms

  • Loading branch information
volaya committed Nov 12, 2012
1 parent 6bbe81b commit da42b5d1cc890b16f249dab8a32125d2e0fefc92
@@ -33,7 +33,7 @@
from PyQt4 import QtGui
from sextante.parameters.ParameterTableField import ParameterTableField

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

INPUT = "INPUT"
OUTPUT = "OUTPUT"
@@ -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() )
@@ -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"))

@@ -16,6 +16,7 @@
* *
***************************************************************************
"""
from sextante.algs.EquivalentNumField import EquivalentNumField

__author__ = 'Victor Olaya'
__date__ = 'August 2012'
@@ -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)
@@ -17,6 +17,7 @@
***************************************************************************
"""
from sextante.ftools.PointsInPolygonWeighted import PointsInPolygonWeighted
from sextante.ftools.PointsInPolygonUnique import PointsInPolygonUnique

__author__ = 'Victor Olaya'
__date__ = 'August 2012'
@@ -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(),
@@ -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
@@ -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:
@@ -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.
You can’t perform that action at this time.