Skip to content
Permalink
Browse files

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 e2a9c16603ba9dd8ae4faf0fc097640875307c90
@@ -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":
@@ -83,4 +83,4 @@ def getSupportedOutputTableExtensions(self):
return ["dbf"]

def supportsNonFileBasedOutput(self):
return False
return False
@@ -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
@@ -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
@@ -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.
You can’t perform that action at this time.