Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
fix encoding related bugs in writer class
review Sum Line Length tool, add number of lines to output (implement #4712)
  • Loading branch information
alexbruy committed Oct 4, 2012
1 parent 653326b commit e2a9c16
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 60 deletions.
4 changes: 2 additions & 2 deletions python/plugins/sextante/core/AlgorithmProvider.py
Expand Up @@ -71,7 +71,7 @@ def getSupportedOutputVectorLayerExtensions(self):
formats = QgsVectorFileWriter.supportedFiltersAndFormats()
extensions = ["shp"]#shp is the default, should be the first
for extension in formats.keys():
extension = str(extension)
extension = unicode(extension)
extension = extension[extension.find('*.') + 2:]
extension = extension[:extension.find(" ")]
if extension.lower() != "shp":
Expand All @@ -83,4 +83,4 @@ def getSupportedOutputTableExtensions(self):
return ["dbf"]

def supportsNonFileBasedOutput(self):
return False
return False
2 changes: 1 addition & 1 deletion python/plugins/sextante/core/SextanteVectorWriter.py
Expand Up @@ -34,7 +34,7 @@ def __init__(self, fileName, encoding, fields, geometryType, crs, options=None):
formats = QgsVectorFileWriter.supportedFiltersAndFormats()
OGRCodes = {}
for key, value in formats.items():
extension = str(key)
extension = unicode(key)
extension = extension[extension.find('*.') + 2:]
extension = extension[:extension.find(" ")]
OGRCodes[extension] = value
Expand Down
49 changes: 49 additions & 0 deletions python/plugins/sextante/ftools/FToolsUtils.py
@@ -0,0 +1,49 @@
from PyQt4.QtCore import *

from qgis.core import *

def createSpatialIndex(provider):
ft = QgsFeature()
idx = QgsSpatialIndex()
provider.rewind()
provider.select()
while provider.nextFeature( ft ):
idx.insertFeature( ft )
return idx

def createUniqueFieldName(fieldName, fieldList):
shortName = fieldName[:10]

if len(fieldList) == 0:
return shortName

if shortName not in fieldList:
return shortName

shortName = fieldName[:8] + "_1"
changed = True
while changed:
changed = False
for n in fieldList:
if n == shortName:
# create unique field name
num = int(shortName[-1:])
if num < 9:
shortName = shortName[:8] + "_" + str(num + 1)
else:
shortName = shortName[:7] + "_" + str(num + 1)

changed = True

return shortName

def findOrCreateField(layer, fieldList, fieldName, fieldLen = 24, fieldPrec = 15):
idx = layer.fieldNameIndex(fieldName)
if idx == -1:
idx = len(fieldList)
if idx == max(fieldList.keys()):
idx += 1
fn = createUniqueFieldName(fieldName, fieldList)
field = QgsField(fn, QVariant.Double, "", fieldLen, fieldPrec)
fieldList[idx] = field
return idx, fieldList
134 changes: 77 additions & 57 deletions python/plugins/sextante/ftools/SumLines.py
@@ -1,90 +1,110 @@
from sextante.core.GeoAlgorithm import GeoAlgorithm
import os.path

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

from qgis.core import *
from sextante.parameters.ParameterVector import ParameterVector

from sextante.core.GeoAlgorithm import GeoAlgorithm
from sextante.core.QGisLayers import QGisLayers
from sextante.outputs.OutputVector import OutputVector
from sextante.core.SextanteLog import SextanteLog
from sextante.ftools import ftools_utils

from sextante.parameters.ParameterVector import ParameterVector
from sextante.parameters.ParameterString import ParameterString
from sextante.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from sextante.outputs.OutputVector import OutputVector

from sextante.ftools import FToolsUtils as utils

class SumLines(GeoAlgorithm):

LINES = "LINES"
POLYGONS = "POLYGONS"
FIELD = "FIELD"
LEN_FIELD = "LEN_FIELD"
COUNT_FIELD = "COUNT_FIELD"
OUTPUT = "OUTPUT"

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

def defineCharacteristics(self):
self.name = "Sum line lengths"
self.group = "Analysis tools"

self.addParameter(ParameterVector(self.LINES, "Lines", ParameterVector.VECTOR_TYPE_LINE))
self.addParameter(ParameterVector(self.POLYGONS, "Polygons", ParameterVector.VECTOR_TYPE_POLYGON))
self.addParameter(ParameterString(self.LEN_FIELD, "Lines length field name", "LENGTH"))
self.addParameter(ParameterString(self.COUNT_FIELD, "Lines count field name", "COUNT"))

self.addOutput(OutputVector(self.OUTPUT, "Result"))

def processAlgorithm(self, progress):
inField = self.getParameterValue(SumLines.FIELD)
lineLayer = QGisLayers.getObjectFromUri(self.getParameterValue(SumLines.LINES))
polyLayer = QGisLayers.getObjectFromUri(self.getParameterValue(SumLines.POLYGONS))
settings = QSettings()
encoding = settings.value( "/UI/encoding", "System" ).toString()

lineLayer = QGisLayers.getObjectFromUri(self.getParameterValue(self.LINES))
polyLayer = QGisLayers.getObjectFromUri(self.getParameterValue(self.POLYGONS))
lengthFieldName = self.getParameterValue(self.LEN_FIELD)
countFieldName = self.getParameterValue(self.COUNT_FIELD)

output = self.getOutputValue(self.OUTPUT)

polyProvider = polyLayer.dataProvider()
lineProvider = lineLayer.dataProvider()
if polyProvider.crs() <> lineProvider.crs():
if polyProvider.crs() != lineProvider.crs():
SextanteLog.addToLog(SextanteLog.LOG_WARNING,
"CRS warning!Warning: Input layers have non-matching CRS.\nThis may cause unexpected results.")
allAttrs = polyProvider.attributeIndexes()
polyProvider.select(allAttrs)
allAttrs = lineProvider.attributeIndexes()
lineProvider.select(allAttrs)
fieldList = ftools_utils.getFieldList(polyLayer)
index = polyProvider.fieldNameIndex(unicode(inField))
if index == -1:
index = polyProvider.fieldCount()
field = QgsField(unicode(inField), QVariant.Double, "real", 24, 15, self.tr("length field"))
fieldList[index] = field
sRs = polyProvider.crs()
inFeat = QgsFeature()
inFeatB = QgsFeature()
"CRS warning: Input layers have non-matching CRS. This may cause unexpected results.")

idxLength, fieldList = utils.findOrCreateField(polyLayer, polyLayer.pendingFields(), lengthFieldName)
idxCount, fieldList = utils.findOrCreateField(polyLayer, fieldList, countFieldName)

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

spatialIndex = utils.createSpatialIndex(lineProvider)

lineProvider.rewind()
lineProvider.select()

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

ftLine = QgsFeature()
ftPoly = QgsFeature()
outFeat = QgsFeature()
inGeom = QgsGeometry()
outGeom = QgsGeometry()
distArea = QgsDistanceArea()
lineProvider.rewind()
start = 15.00
add = 85.00 / polyProvider.featureCount()
writer = self.getOutputFromName(SumLines.OUTPUT).getVectorWriter(fieldList, polyProvider.geometryType(), sRs)
spatialIndex = ftools_utils.createIndex( lineProvider )
while polyProvider.nextFeature(inFeat):
inGeom = QgsGeometry(inFeat.geometry())
atMap = inFeat.attributeMap()
lineList = []

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

while polyLayer.nextFeature(ftPoly):
inGeom = QgsGeometry(ftPoly.geometry())
atMap = ftPoly.attributeMap()
count = 0
length = 0
#(check, lineList) = lineLayer.featuresInRectangle(inGeom.boundingBox(), True, False)
#lineLayer.select(inGeom.boundingBox(), False)
#lineList = lineLayer.selectedFeatures()
lineList = spatialIndex.intersects(inGeom.boundingBox())
if len(lineList) > 0: check = 0
else: check = 1
if check == 0:
for i in lineList:
lineProvider.featureAtId( int( i ), inFeatB , True, allAttrs )
tmpGeom = QgsGeometry( inFeatB.geometry() )
hasIntersections = False
lines = spatialIndex.intersects(inGeom.boundingBox())
if len(lines) > 0:
hasIntersections = True

if hasIntersections:
for i in lines:
lineProvider.featureAtId(int(i), ftLine)
tmpGeom = QgsGeometry(ftLine.geometry())
if inGeom.intersects(tmpGeom):
outGeom = inGeom.intersection(tmpGeom)
length = length + distArea.measure(outGeom)
length += distArea.measure(outGeom)
count += 1

outFeat.setGeometry(inGeom)
outFeat.setAttributeMap(atMap)
outFeat.addAttribute(index, QVariant(length))
outFeat.addAttribute(idxLength, QVariant(length))
outFeat.addAttribute(idxCount, QVariant(count))
writer.addFeature(outFeat)
start = start + add
progress.setPercentage(start)
del writer

current += 1
progress.setPercentage(int(current * total))

def defineCharacteristics(self):
self.name = "Sum line lengths"
self.group = "Analysis tools"
self.addParameter(ParameterVector(SumLines.LINES, "Lines", ParameterVector.VECTOR_TYPE_LINE))
self.addParameter(ParameterVector(SumLines.POLYGONS, "Polygons", ParameterVector.VECTOR_TYPE_POLYGON))
self.addParameter(ParameterString(SumLines.FIELD, "Output field name", "LENGTH"))
self.addOutput(OutputVector(SumLines.OUTPUT, "Result"))

del writer

0 comments on commit e2a9c16

Please sign in to comment.