-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix encoding related bugs in writer class
review Sum Line Length tool, add number of lines to output (implement #4712)
- Loading branch information
Showing
4 changed files
with
129 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |