[processing] Enhance create points layer alg

Clean up code, allow setting z/m columns
This commit is contained in:
Nyall Dawson 2016-11-23 15:44:37 +10:00
parent 3c51a93f6a
commit 489e00df8d
2 changed files with 68 additions and 18 deletions

View File

@ -25,11 +25,9 @@ __copyright__ = '(C) 2013, Victor Olaya'
__revision__ = '$Format:%H$' __revision__ = '$Format:%H$'
from qgis.core import Qgis, QgsWkbTypes from qgis.core import Qgis, QgsWkbTypes, QgsPointV2
from qgis.core import QgsCoordinateReferenceSystem from qgis.core import QgsCoordinateReferenceSystem
from qgis.core import QgsFeature
from qgis.core import QgsGeometry from qgis.core import QgsGeometry
from qgis.core import QgsPoint
from processing.core.GeoAlgorithm import GeoAlgorithm from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.core.parameters import ParameterTable from processing.core.parameters import ParameterTable
from processing.core.parameters import ParameterTableField from processing.core.parameters import ParameterTableField
@ -43,18 +41,25 @@ class PointsLayerFromTable(GeoAlgorithm):
INPUT = 'INPUT' INPUT = 'INPUT'
XFIELD = 'XFIELD' XFIELD = 'XFIELD'
YFIELD = 'YFIELD' YFIELD = 'YFIELD'
ZFIELD = 'ZFIELD'
MFIELD = 'MFIELD'
OUTPUT = 'OUTPUT' OUTPUT = 'OUTPUT'
TARGET_CRS = 'TARGET_CRS' TARGET_CRS = 'TARGET_CRS'
def defineCharacteristics(self): def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Points layer from table') self.name, self.i18n_name = self.trAlgorithm('Create points layer from table')
self.group, self.i18n_group = self.trAlgorithm('Vector creation tools') self.group, self.i18n_group = self.trAlgorithm('Vector creation tools')
self.tags = self.tr('points,create,values,attributes')
self.addParameter(ParameterTable(self.INPUT, self.addParameter(ParameterTable(self.INPUT,
self.tr('Input layer'))) self.tr('Input layer')))
self.addParameter(ParameterTableField(self.XFIELD, self.addParameter(ParameterTableField(self.XFIELD,
self.tr('X field'), self.INPUT, ParameterTableField.DATA_TYPE_ANY)) self.tr('X field'), self.INPUT, ParameterTableField.DATA_TYPE_ANY))
self.addParameter(ParameterTableField(self.YFIELD, self.addParameter(ParameterTableField(self.YFIELD,
self.tr('Y field'), self.INPUT, ParameterTableField.DATA_TYPE_ANY)) self.tr('Y field'), self.INPUT, ParameterTableField.DATA_TYPE_ANY))
self.addParameter(ParameterTableField(self.ZFIELD,
self.tr('Z field'), self.INPUT, datatype=ParameterTableField.DATA_TYPE_ANY, optional=True))
self.addParameter(ParameterTableField(self.MFIELD,
self.tr('M field'), self.INPUT, datatype=ParameterTableField.DATA_TYPE_ANY, optional=True))
self.addParameter(ParameterCrs(self.TARGET_CRS, self.addParameter(ParameterCrs(self.TARGET_CRS,
self.tr('Target CRS'), 'EPSG:4326')) self.tr('Target CRS'), 'EPSG:4326'))
self.addOutput(OutputVector(self.OUTPUT, self.tr('Points from table'), datatype=[dataobjects.TYPE_VECTOR_POINT])) self.addOutput(OutputVector(self.OUTPUT, self.tr('Points from table'), datatype=[dataobjects.TYPE_VECTOR_POINT]))
@ -63,30 +68,58 @@ class PointsLayerFromTable(GeoAlgorithm):
source = self.getParameterValue(self.INPUT) source = self.getParameterValue(self.INPUT)
vlayer = dataobjects.getObjectFromUri(source) vlayer = dataobjects.getObjectFromUri(source)
output = self.getOutputFromName(self.OUTPUT) output = self.getOutputFromName(self.OUTPUT)
fields = vlayer.fields() fields = vlayer.fields()
writer = output.getVectorWriter(fields, QgsWkbTypes.Point, self.crs) x_field_index = fields.lookupField(self.getParameterValue(self.XFIELD))
xfieldindex = vlayer.fields().lookupField(self.getParameterValue(self.XFIELD)) y_field_index = fields.lookupField(self.getParameterValue(self.YFIELD))
yfieldindex = vlayer.fields().lookupField(self.getParameterValue(self.YFIELD)) z_field_index = None
if self.getParameterValue(self.ZFIELD):
z_field_index = fields.lookupField(self.getParameterValue(self.ZFIELD))
m_field_index = None
if self.getParameterValue(self.MFIELD):
m_field_index = fields.lookupField(self.getParameterValue(self.MFIELD))
wkb_type = QgsWkbTypes.Point
if z_field_index is not None:
wkb_type = QgsWkbTypes.addZ(wkb_type)
if m_field_index is not None:
wkb_type = QgsWkbTypes.addM(wkb_type)
crsId = self.getParameterValue(self.TARGET_CRS) crsId = self.getParameterValue(self.TARGET_CRS)
targetCrs = QgsCoordinateReferenceSystem() target_crs = QgsCoordinateReferenceSystem()
targetCrs.createFromUserInput(crsId) target_crs.createFromUserInput(crsId)
self.crs = targetCrs
writer = output.getVectorWriter(fields, wkb_type, target_crs)
outFeat = QgsFeature()
features = vector.features(vlayer) features = vector.features(vlayer)
total = 100.0 / len(features) total = 100.0 / len(features)
for current, feature in enumerate(features): for current, feature in enumerate(features):
progress.setPercentage(int(current * total)) progress.setPercentage(int(current * total))
attrs = feature.attributes() attrs = feature.attributes()
try: try:
x = float(attrs[xfieldindex]) x = float(attrs[x_field_index])
y = float(attrs[yfieldindex]) y = float(attrs[y_field_index])
point = QgsPointV2(x, y)
if z_field_index is not None:
try:
point.addZValue(float(attrs[z_field_index]))
except:
point.addZValue(0.0)
if m_field_index is not None:
try:
point.addMValue(float(attrs[m_field_index]))
except:
point.addMValue(0.0)
feature.setGeometry(QgsGeometry(point))
except: except:
continue pass # no geometry
pt = QgsPoint(x, y)
outFeat.setGeometry(QgsGeometry.fromPoint(pt)) writer.addFeature(feature)
outFeat.setAttributes(attrs)
writer.addFeature(outFeat)
del writer del writer

View File

@ -39,6 +39,7 @@ from processing.core.parameters import (Parameter,
ParameterPoint, ParameterPoint,
ParameterString, ParameterString,
ParameterVector, ParameterVector,
ParameterTable,
ParameterTableField, ParameterTableField,
ParameterSelection, ParameterSelection,
ParameterExpression, ParameterExpression,
@ -631,5 +632,21 @@ class ParameterTableFieldTest(unittest.TestCase):
self.assertTrue(isinstance(result, ParameterTableField)) self.assertTrue(isinstance(result, ParameterTableField))
self.assertTrue(result.optional) self.assertTrue(result.optional)
class ParameterTableTest(unittest.TestCase):
def testScriptCode(self):
parameter = ParameterTable(
'myName', 'myDesc')
code = parameter.getAsScriptCode()
result = getParameterFromString(code)
self.assertTrue(isinstance(result, ParameterTable))
parameter.optional = True
code = parameter.getAsScriptCode()
result = getParameterFromString(code)
self.assertTrue(isinstance(result, ParameterTable))
self.assertTrue(result.optional)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()