Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Restore text to float algorithm
And add test
  • Loading branch information
nyalldawson committed Jul 27, 2017
1 parent ab70e05 commit 95be6d1
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 49 deletions.
5 changes: 3 additions & 2 deletions python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py
Expand Up @@ -110,6 +110,7 @@
from .SpatialiteExecuteSQL import SpatialiteExecuteSQL
from .SumLines import SumLines
from .SymmetricalDifference import SymmetricalDifference
from .TextToFloat import TextToFloat
from .Translate import Translate
from .Union import Union
from .UniqueValues import UniqueValues
Expand All @@ -127,7 +128,6 @@
# from .SelectByLocation import SelectByLocation
# from .SpatialJoin import SpatialJoin
# from .DeleteDuplicateGeometries import DeleteDuplicateGeometries
# from .TextToFloat import TextToFloat
# from .GridLine import GridLine
# from .Gridify import Gridify
# from .HubDistancePoints import HubDistancePoints
Expand Down Expand Up @@ -192,7 +192,7 @@ def getAlgs(self):
# SelectByLocation(),
# ExtractByLocation(),
# SpatialJoin(),
# DeleteDuplicateGeometries(), TextToFloat(),
# DeleteDuplicateGeometries(),
# GridLine(), Gridify(), HubDistancePoints(),
# HubDistanceLines(), HubLines(),
# GeometryConvert(), FieldsCalculator(),
Expand Down Expand Up @@ -295,6 +295,7 @@ def getAlgs(self):
SpatialiteExecuteSQL(),
SumLines(),
SymmetricalDifference(),
TextToFloat(),
Translate(),
Union(),
UniqueValues(),
Expand Down
85 changes: 38 additions & 47 deletions python/plugins/processing/algs/qgis/TextToFloat.py
Expand Up @@ -26,65 +26,56 @@
__revision__ = '$Format:%H$'

from qgis.PyQt.QtCore import QVariant
from qgis.core import (QgsApplication,
QgsField,
QgsFeatureSink,
QgsProcessingUtils)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.core.parameters import ParameterVector
from processing.core.parameters import ParameterTableField
from processing.core.outputs import OutputVector


class TextToFloat(QgisAlgorithm):
INPUT = 'INPUT'
from qgis.core import (QgsField,
QgsProcessingParameterField)
from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm


class TextToFloat(QgisFeatureBasedAlgorithm):

FIELD = 'FIELD'
OUTPUT = 'OUTPUT'

def group(self):
return self.tr('Vector table tools')

def __init__(self):
super().__init__()
self.field_name = None
self.field_idx = -1

def initAlgorithm(self, config=None):
self.addParameter(ParameterVector(self.INPUT,
self.tr('Input Layer')))
self.addParameter(ParameterTableField(self.FIELD,
self.tr('Text attribute to convert to float'),
self.INPUT, ParameterTableField.DATA_TYPE_STRING))
self.addOutput(OutputVector(self.OUTPUT, self.tr('Float from text')))
def initParameters(self, config=None):
self.addParameter(QgsProcessingParameterField(self.FIELD,
self.tr('Text attribute to convert to float'),
parentLayerParameterName='INPUT',
type=QgsProcessingParameterField.String
))

def name(self):
return 'texttofloat'

def displayName(self):
return self.tr('Text to float')

def processAlgorithm(self, parameters, context, feedback):
layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
fieldName = self.getParameterValue(self.FIELD)
idx = layer.fields().lookupField(fieldName)

fields = layer.fields()
fields[idx] = QgsField(fieldName, QVariant.Double, '', 24, 15)

writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, layer.wkbType(), layer.crs(), context)

features = QgsProcessingUtils.getFeatures(layer, context)

total = 100.0 / layer.featureCount() if layer.featureCount() else 0
for current, f in enumerate(features):
value = f[idx]
try:
if '%' in value:
f[idx] = float(value.replace('%', '')) / 100.0
else:
f[idx] = float(value)
except:
f[idx] = None

writer.addFeature(f, QgsFeatureSink.FastInsert)
feedback.setProgress(int(current * total))

del writer
def outputName(self):
return self.tr('Float from text')

def outputFields(self, inputFields):
self.field_idx = inputFields.lookupField(self.field_name)
if self.field_idx >= 0:
inputFields[self.field_idx] = QgsField(self.field_name, QVariant.Double, '', 24, 15)
return inputFields

def prepareAlgorithm(self, parameters, context, feedback):
self.field_name = self.parameterAsString(parameters, self.FIELD, context)
return True

def processFeature(self, feature, feedback):
value = feature[self.field_idx]
try:
if '%' in value:
feature[self.field_idx] = float(value.replace('%', '')) / 100.0
else:
feature[self.field_idx] = float(value)
except:
feature[self.field_idx] = None
return feature
53 changes: 53 additions & 0 deletions python/plugins/processing/tests/testdata/custom/text_to_float.gml
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ogr.maptools.org/ text_to_float.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>1</gml:X><gml:Y>1</gml:Y></gml:coord>
<gml:coord><gml:X>5</gml:X><gml:Y>3</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:text_to_float fid="points.0">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>1,1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>1</ogr:id>
<ogr:id2>2</ogr:id2>
<ogr:text_float>1</ogr:text_float>
</ogr:text_to_float>
</gml:featureMember>
<gml:featureMember>
<ogr:text_to_float fid="points.1">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>3,3</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>2</ogr:id>
<ogr:id2>1</ogr:id2>
<ogr:text_float>1.1</ogr:text_float>
</ogr:text_to_float>
</gml:featureMember>
<gml:featureMember>
<ogr:text_to_float fid="points.2">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>2,2</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>3</ogr:id>
<ogr:id2>0</ogr:id2>
<ogr:text_float>5%</ogr:text_float>
</ogr:text_to_float>
</gml:featureMember>
<gml:featureMember>
<ogr:text_to_float fid="points.3">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>5,2</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>4</ogr:id>
<ogr:id2>2</ogr:id2>
<ogr:text_float>notfloat</ogr:text_float>
</ogr:text_to_float>
</gml:featureMember>
<gml:featureMember>
<ogr:text_to_float fid="points.4">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>4,1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>5</ogr:id>
<ogr:id2>1</ogr:id2>
</ogr:text_to_float>
</gml:featureMember>
</ogr:FeatureCollection>
44 changes: 44 additions & 0 deletions python/plugins/processing/tests/testdata/custom/text_to_float.xsd
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://ogr.maptools.org/" xmlns:ogr="http://ogr.maptools.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" elementFormDefault="qualified" version="1.0">
<xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd"/>
<xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:_FeatureCollection"/>
<xs:complexType name="FeatureCollectionType">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureCollectionType">
<xs:attribute name="lockId" type="xs:string" use="optional"/>
<xs:attribute name="scope" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="text_to_float" type="ogr:text_to_float_Type" substitutionGroup="gml:_Feature"/>
<xs:complexType name="text_to_float_Type">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence>
<xs:element name="geometryProperty" type="gml:PointPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
<xs:element name="id" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:totalDigits value="10"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="id2" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:totalDigits value="10"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="text_float" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="255"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
@@ -0,0 +1,31 @@
<GMLFeatureClassList>
<GMLFeatureClass>
<Name>text_to_float</Name>
<ElementPath>text_to_float</ElementPath>
<!--POINT-->
<GeometryType>1</GeometryType>
<SRSName>EPSG:4326</SRSName>
<DatasetSpecificInfo>
<FeatureCount>5</FeatureCount>
<ExtentXMin>1.00000</ExtentXMin>
<ExtentXMax>5.00000</ExtentXMax>
<ExtentYMin>1.00000</ExtentYMin>
<ExtentYMax>3.00000</ExtentYMax>
</DatasetSpecificInfo>
<PropertyDefn>
<Name>id</Name>
<ElementPath>id</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>id2</Name>
<ElementPath>id2</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>text_float</Name>
<ElementPath>text_float</ElementPath>
<Type>Real</Type>
</PropertyDefn>
</GMLFeatureClass>
</GMLFeatureClassList>
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=""
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>1</gml:X><gml:Y>1</gml:Y></gml:coord>
<gml:coord><gml:X>5</gml:X><gml:Y>3</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:text_to_float fid="points.0">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>1,1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>1</ogr:id>
<ogr:id2>2</ogr:id2>
<ogr:text_float>1.000000000000000</ogr:text_float>
</ogr:text_to_float>
</gml:featureMember>
<gml:featureMember>
<ogr:text_to_float fid="points.1">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>3,3</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>2</ogr:id>
<ogr:id2>1</ogr:id2>
<ogr:text_float>1.100000000000000</ogr:text_float>
</ogr:text_to_float>
</gml:featureMember>
<gml:featureMember>
<ogr:text_to_float fid="points.2">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>2,2</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>3</ogr:id>
<ogr:id2>0</ogr:id2>
<ogr:text_float>0.050000000000000</ogr:text_float>
</ogr:text_to_float>
</gml:featureMember>
<gml:featureMember>
<ogr:text_to_float fid="points.3">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>5,2</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>4</ogr:id>
<ogr:id2>2</ogr:id2>
</ogr:text_to_float>
</gml:featureMember>
<gml:featureMember>
<ogr:text_to_float fid="points.4">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>4,1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>5</ogr:id>
<ogr:id2>1</ogr:id2>
</ogr:text_to_float>
</gml:featureMember>
</ogr:FeatureCollection>
12 changes: 12 additions & 0 deletions python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
Expand Up @@ -1107,6 +1107,18 @@ tests:
name: expected/add_geometry_pointz.gml
type: vector

- algorithm: qgis:texttofloat
name: Text to float
params:
FIELD: 'text_float'
INPUT:
name: custom/text_to_float.gml
type: vector
results:
OUTPUT:
name: expected/text_to_float.gml
type: vector

- algorithm: qgis:countpointsinpolygon
name: Count points in polygon
params:
Expand Down

0 comments on commit 95be6d1

Please sign in to comment.