Skip to content

Commit 48e9f42

Browse files
committedMar 21, 2013
review and cleanup Convex Hull tool, also move some common routines to
utils module and update other algs accordingly
1 parent 11d567c commit 48e9f42

File tree

3 files changed

+151
-141
lines changed

3 files changed

+151
-141
lines changed
 

‎python/plugins/sextante/algs/ftools/ConvexHull.py

Lines changed: 114 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -23,144 +23,159 @@
2323
# This will get replaced with a git SHA1 when you do a git archive
2424
__revision__ = '$Format:%H$'
2525

26-
from sextante.core.GeoAlgorithm import GeoAlgorithm
2726
from PyQt4.QtCore import *
2827
from PyQt4.QtGui import *
28+
2929
from qgis.core import *
30-
from sextante.parameters.ParameterVector import ParameterVector
30+
31+
from sextante.core.GeoAlgorithm import GeoAlgorithm
3132
from sextante.core.QGisLayers import QGisLayers
32-
from sextante.outputs.OutputVector import OutputVector
33-
from sextante.algs.ftools import FToolsUtils as utils
3433
from sextante.core.SextanteLog import SextanteLog
34+
35+
from sextante.parameters.ParameterVector import ParameterVector
3536
from sextante.parameters.ParameterTableField import ParameterTableField
3637
from sextante.parameters.ParameterSelection import ParameterSelection
3738

39+
from sextante.outputs.OutputVector import OutputVector
40+
41+
from sextante.algs.ftools import FToolsUtils as utils
42+
3843
class ConvexHull(GeoAlgorithm):
3944

4045
INPUT = "INPUT"
4146
OUTPUT = "OUTPUT"
4247
FIELD = "FIELD"
4348
METHOD = "METHOD"
44-
METHODS = ["Create single minimum convex hull", "Create convex hulls based on field"]
49+
METHODS = ["Create single minimum convex hull",
50+
"Create convex hulls based on field"
51+
]
4552

4653
#===========================================================================
4754
# def getIcon(self):
4855
# return QtGui.QIcon(os.path.dirname(__file__) + "/icons/convex_hull.png")
4956
#===========================================================================
5057

58+
def defineCharacteristics(self):
59+
self.name = "Convex hull"
60+
self.group = "Vector geometry tools"
61+
self.addParameter(ParameterVector(ConvexHull.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY))
62+
self.addParameter(ParameterTableField(ConvexHull.FIELD, "Field", ConvexHull.INPUT))
63+
self.addParameter(ParameterSelection(ConvexHull.METHOD, "Method", ConvexHull.METHODS))
64+
self.addOutput(OutputVector(ConvexHull.OUTPUT, "Convex hull"))
65+
5166
def processAlgorithm(self, progress):
5267
useField = (self.getParameterValue(ConvexHull.METHOD) == 1)
53-
field = self.getParameterValue(ConvexHull.FIELD)
54-
vlayerA = QGisLayers.getObjectFromUri(self.getParameterValue(ConvexHull.INPUT))
68+
fieldName = self.getParameterValue(ConvexHull.FIELD)
69+
layer = QGisLayers.getObjectFromUri(self.getParameterValue(ConvexHull.INPUT))
70+
5571
GEOS_EXCEPT = True
5672
FEATURE_EXCEPT = True
57-
vproviderA = vlayerA.dataProvider()
58-
#allAttrsA = vproviderA.attributeIndexes()
59-
#vproviderA.select(allAttrsA)
60-
fields = [QgsField("ID", QVariant.Int),
61-
QgsField("Area", QVariant.Double),
62-
QgsField("Perim", QVariant.Double)]
63-
writer = self.getOutputFromName(ConvexHull.OUTPUT).getVectorWriter(fields, QGis.WKBPolygon, vproviderA.crs())
64-
inFeat = QgsFeature()
73+
74+
index = layer.fieldNameIndex(fieldName)
75+
fType = layer.pendingFields()[index].type()
76+
f = QgsField("value")
77+
f.setType(QVariant.String)
78+
f.setLength(255)
79+
if useField:
80+
if fType == QVariant.Int:
81+
f.setType(QVariant.Int)
82+
f.setLength(20)
83+
elif fType == QVariant.Double:
84+
f.setType(QVariant.Double)
85+
f.setLength(20)
86+
f.setPrecision(6)
87+
else:
88+
f.setType(QVariant.String)
89+
f.setLength(255)
90+
91+
fields = [QgsField("id", QVariant.Int, "", 20),
92+
f,
93+
QgsField("area", QVariant.Double, "", 20, 6),
94+
QgsField("perim", QVariant.Double, "", 20, 6)
95+
]
96+
97+
writer = self.getOutputFromName(ConvexHull.OUTPUT).getVectorWriter(fields, QGis.WKBPolygon, layer.dataProvider().crs())
98+
6599
outFeat = QgsFeature()
66100
inGeom = QgsGeometry()
67101
outGeom = QgsGeometry()
68-
nElement = 0
69-
index = vproviderA.fieldNameIndex(field)
70102

71-
features = QGisLayers.features(vlayerA)
72-
nFeat = len(features)
103+
current = 0
73104

105+
fid = 0
106+
val = ""
74107
if useField:
75-
unique = utils.getUniqueValues(vproviderA, index)
76-
nFeat = nFeat * len(unique)
77-
for i in unique:
78-
hull = []
79-
first = True
80-
outID = 0
81-
#vproviderA.select(allAttrsA)
82-
features = QGisLayers.features(vlayerA)
83-
for inFeat in features:
84-
atMap = inFeat.attributes()
85-
idVar = atMap[ index ]
86-
if idVar.toString().trimmed() == i.toString().trimmed():
87-
if first:
88-
outID = idVar
89-
first = False
90-
inGeom = QgsGeometry(inFeat.geometry())
91-
points = utils.extractPoints(inGeom)
92-
hull.extend(points)
93-
nElement += 1
94-
progress.setPercentage(int(nElement / nFeat * 100))
95-
if len(hull) >= 3:
96-
tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull))
97-
try:
98-
outGeom = tmpGeom.convexHull()
99-
outFeat.setGeometry(outGeom)
100-
(area, perim) = self.simpleMeasure(outGeom)
101-
outFeat.addAttribute(0, QVariant(outID))
102-
outFeat.addAttribute(1, QVariant(area))
103-
outFeat.addAttribute(2, QVariant(perim))
104-
writer.addFeature(outFeat)
105-
except:
106-
GEOS_EXCEPT = False
107-
continue
108+
unique = layer.uniqueValues(index)
109+
total = 100.0 / float(layer.featureCount() * len (unique))
110+
111+
for i in unique:
112+
hull = []
113+
first = True
114+
features = QGisLayers.features(layer)
115+
for f in features:
116+
idVar = f.attribute(fieldName)
117+
if idVar.toString().trimmed() == i.toString().trimmed():
118+
if first:
119+
val = idVar
120+
first = False
121+
inGeom = QgsGeometry(f.geometry())
122+
points = utils.extractPoints(inGeom)
123+
hull.extend(points)
124+
current += 1
125+
progress.setPercentage(int(current * total))
126+
127+
if len(hull) >= 3:
128+
tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull))
129+
try:
130+
outGeom = tmpGeom.convexHull()
131+
(area, perim) = utils.simpleMeasure(outGeom)
132+
outFeat.setGeometry(outGeom)
133+
outFeat.setAttributes([QVariant(fid),
134+
QVariant(val),
135+
QVariant(area),
136+
QVariant(perim)
137+
])
138+
#~ outFeat.setAttribute("id", QVariant(fid))
139+
#~ outFeat.setAttribute("value", QVariant(val))
140+
#~ outFeat.setAttribute("area", QVariant(area))
141+
#~ outFeat.setAttribute("perim", QVariant(perim))
142+
writer.addFeature(outFeat)
143+
except:
144+
GEOS_EXCEPT = False
145+
continue
146+
fid += 1
108147
else:
109148
hull = []
110-
#vproviderA.select(allAttrsA)
111-
features = QGisLayers.features(vlayerA)
112-
for inFeat in features:
113-
inGeom = QgsGeometry(inFeat.geometry())
114-
points = utils.extractPoints(inGeom)
115-
hull.extend(points)
116-
nElement += 1
117-
progress.setPercentage(int(nElement / nFeat * 100))
149+
total = 100.0 / float(layer.featureCount())
150+
features = QGisLayers.features(layer)
151+
for f in features:
152+
inGeom = QgsGeometry(f.geometry())
153+
points = utils.extractPoints(inGeom)
154+
hull.extend(points)
155+
current += 1
156+
progress.setPercentage(int(current * total))
157+
118158
tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull))
119159
try:
120-
outGeom = tmpGeom.convexHull()
121-
outFeat.setGeometry(outGeom)
122-
(area, perim) = self.simpleMeasure(outGeom)
123-
#outFeat.addAttribute(0, QVariant("1"))
124-
#outFeat.addAttribute(1, QVariant(area))
125-
#outFeat.addAttribute(2, QVariant(perim))
126-
writer.addFeature(outFeat)
160+
outGeom = tmpGeom.convexHull()
161+
(area, perim) = utils.simpleMeasure(outGeom)
162+
outFeat.setGeometry(outGeom)
163+
outFeat.setAttributes([QVariant(0),
164+
QVariant("all"),
165+
QVariant(area),
166+
QVariant(perim)
167+
])
168+
#print outFeat.setAttribute("id", QVariant(0))
169+
#print outFeat.setAttribute("value", QVariant("all"))
170+
#print outFeat.setAttribute("area", QVariant(area))
171+
#print outFeat.setAttribute("perim", QVariant(perim))
172+
writer.addFeature(outFeat)
127173
except:
128-
GEOS_EXCEPT = False
174+
GEOS_EXCEPT = False
129175

130176
del writer
131177

132178
if not GEOS_EXCEPT:
133179
SextanteLog.addToLog(SextanteLog.LOG_WARNING, "Geometry exception while computing convex hull")
134180
if not FEATURE_EXCEPT:
135181
SextanteLog.addToLog(SextanteLog.LOG_WARNING, "Feature exception while computing convex hull")
136-
137-
def simpleMeasure(self, inGeom):
138-
measure = QgsDistanceArea()
139-
attr1 = measure.measure(inGeom)
140-
if inGeom.type() == QGis.Polygon:
141-
attr2 = self.perimMeasure(inGeom, measure)
142-
else:
143-
attr2 = attr1
144-
return (attr1, attr2)
145-
146-
def perimMeasure(self, inGeom, measure):
147-
value = 0.00
148-
if inGeom.isMultipart():
149-
poly = inGeom.asMultiPolygon()
150-
for k in poly:
151-
for j in k:
152-
value = value + measure.measureLine(j)
153-
else:
154-
poly = inGeom.asPolygon()
155-
for k in poly:
156-
value = value + measure.measureLine(k)
157-
return value
158-
159-
def defineCharacteristics(self):
160-
self.name = "Convex hull"
161-
self.group = "Vector geometry tools"
162-
self.addParameter(ParameterVector(ConvexHull.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY))
163-
self.addParameter(ParameterTableField(ConvexHull.FIELD, "Field", ConvexHull.INPUT))
164-
self.addParameter(ParameterSelection(ConvexHull.METHOD, "Method", ConvexHull.METHODS))
165-
self.addOutput(OutputVector(ConvexHull.OUTPUT, "Convex hull"))
166-
#=========================================================

‎python/plugins/sextante/algs/ftools/ExportGeometryInfo.py

Lines changed: 8 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,19 @@
2424
__revision__ = '$Format:%H$'
2525

2626
from PyQt4.QtCore import *
27+
2728
from qgis.core import *
29+
2830
from sextante.core.GeoAlgorithm import GeoAlgorithm
2931
from sextante.core.QGisLayers import QGisLayers
32+
3033
from sextante.parameters.ParameterVector import ParameterVector
3134
from sextante.parameters.ParameterSelection import ParameterSelection
35+
3236
from sextante.outputs.OutputVector import OutputVector
3337

38+
from sextante.algs.ftools import FToolsUtils as utils
39+
3440
class ExportGeometryInfo(GeoAlgorithm):
3541

3642
INPUT = "INPUT"
@@ -56,7 +62,6 @@ def defineCharacteristics(self):
5662

5763
self.addOutput(OutputVector(self.OUTPUT, "Output layer"))
5864

59-
6065
def processAlgorithm(self, progress):
6166
layer = QGisLayers.getObjectFromUri(self.getParameterValue(self.INPUT))
6267
method = self.getParameterValue(self.METHOD)
@@ -90,7 +95,7 @@ def processAlgorithm(self, progress):
9095
# 2 - ellipsoidal
9196
if method == 2:
9297
settings = QSettings()
93-
ellips = settings.value("/qgis/measure/ellipsoid", "WGS84").toString()
98+
ellips = QgsProject.instance().readEntry("Measure", "/Ellipsoid", GEO_NONE)[0]
9499
crs = layer.crs().srsid()
95100
elif method == 1:
96101
mapCRS = QGisLayers.iface.mapCanvas().mapRenderer().destinationCrs()
@@ -109,7 +114,7 @@ def processAlgorithm(self, progress):
109114
if method == 1:
110115
inGeom.transform(coordTransform)
111116

112-
(attr1, attr2) = self.simpleMeasure(inGeom, method, ellips, crs)
117+
(attr1, attr2) = utils.simpleMeasure(inGeom, method, ellips, crs)
113118

114119
outFeat.setGeometry(inGeom)
115120
atMap = inFeat.attributes()
@@ -123,42 +128,3 @@ def processAlgorithm(self, progress):
123128
progress.setPercentage(int(current * total))
124129

125130
del writer
126-
127-
def simpleMeasure(self, geom, method, ellips, crs):
128-
if geom.wkbType() in [QGis.WKBPoint, QGis.WKBPoint25D]:
129-
pt = geom.asPoint()
130-
attr1 = pt.x()
131-
attr2 = pt.y()
132-
elif geom.wkbType() in [QGis.WKBMultiPoint, QGis.WKBMultiPoint25D]:
133-
pt = inGeom.asMultiPoint()
134-
attr1 = pt[0].x()
135-
attr2 = pt[0].y()
136-
else:
137-
measure = QgsDistanceArea()
138-
139-
if method == 2:
140-
measure.setSourceCrs(crs)
141-
measure.setEllipsoid(ellips)
142-
measure.setEllipsoidalMode(True)
143-
144-
attr1 = measure.measure(geom)
145-
if geom.type() == QGis.Polygon:
146-
attr2 = self.perimMeasure(geom, measure)
147-
else:
148-
attr2 = None
149-
150-
return (attr1, attr2)
151-
152-
def perimMeasure(self, geom, measure):
153-
value = 0.0
154-
if geom.isMultipart():
155-
polygons = geom.asMultiPolygon()
156-
for p in polygons:
157-
for line in p:
158-
value += measure.measureLine(line)
159-
else:
160-
poly = geom.asPolygon()
161-
for r in poly:
162-
value += measure.measureLine(r)
163-
164-
return value

‎python/plugins/sextante/algs/ftools/FToolsUtils.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,35 @@ def extractPoints( geom ):
9696

9797
return points
9898

99+
def simpleMeasure(geom, method=0, ellips=None, crs=None):
100+
# method defines calculation type:
101+
# 0 - layer CRS
102+
# 1 - project CRS
103+
# 2 - ellipsoidal
104+
if geom.wkbType() in [QGis.WKBPoint, QGis.WKBPoint25D]:
105+
pt = geom.asPoint()
106+
attr1 = pt.x()
107+
attr2 = pt.y()
108+
elif geom.wkbType() in [QGis.WKBMultiPoint, QGis.WKBMultiPoint25D]:
109+
pt = inGeom.asMultiPoint()
110+
attr1 = pt[0].x()
111+
attr2 = pt[0].y()
112+
else:
113+
measure = QgsDistanceArea()
114+
115+
if method == 2:
116+
measure.setSourceCrs(crs)
117+
measure.setEllipsoid(ellips)
118+
measure.setEllipsoidalMode(True)
119+
120+
attr1 = measure.measure(geom)
121+
if geom.type() == QGis.Polygon:
122+
attr2 = measure.measurePerimeter(geom)
123+
else:
124+
attr2 = attr1
125+
126+
return (attr1, attr2)
127+
99128
def getUniqueValues(layer, fieldIndex):
100129
values = []
101130
layer.select([fieldIndex], QgsRectangle(), False)

0 commit comments

Comments
 (0)
Please sign in to comment.