|
1 |
| -from sextante.core.GeoAlgorithm import GeoAlgorithm |
2 | 1 | import os.path
|
| 2 | + |
3 | 3 | from PyQt4 import QtGui
|
4 | 4 | from PyQt4.QtCore import *
|
5 |
| -from PyQt4.QtGui import * |
| 5 | + |
6 | 6 | from qgis.core import *
|
7 |
| -from sextante.parameters.ParameterVector import ParameterVector |
| 7 | + |
| 8 | +from sextante.core.GeoAlgorithm import GeoAlgorithm |
8 | 9 | from sextante.core.QGisLayers import QGisLayers
|
| 10 | + |
| 11 | +from sextante.parameters.ParameterVector import ParameterVector |
| 12 | +from sextante.parameters.ParameterSelection import ParameterSelection |
| 13 | + |
9 | 14 | from sextante.outputs.OutputVector import OutputVector
|
10 | 15 |
|
| 16 | +from sextante.ftools import FToolsUtils as utils |
| 17 | + |
11 | 18 | class ExportGeometryInfo(GeoAlgorithm):
|
12 | 19 |
|
13 | 20 | INPUT = "INPUT"
|
| 21 | + METHOD = "CALC_METHOD" |
14 | 22 | OUTPUT = "OUTPUT"
|
15 | 23 |
|
| 24 | + CALC_METHODS = ["Layer CRS", |
| 25 | + "Project CRS", |
| 26 | + "Ellipsoidal" |
| 27 | + ] |
| 28 | + |
16 | 29 | def getIcon(self):
|
17 | 30 | return QtGui.QIcon(os.path.dirname(__file__) + "/icons/export_geometry.png")
|
18 | 31 |
|
| 32 | + def defineCharacteristics(self): |
| 33 | + self.name = "Export/Add geometry columns" |
| 34 | + self.group = "Geometry tools" |
| 35 | + |
| 36 | + self.addParameter(ParameterVector(self.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY)) |
| 37 | + self.addParameter(ParameterSelection(self.METHOD, "Calculate using", self.CALC_METHODS, 0)) |
| 38 | + |
| 39 | + self.addOutput(OutputVector(self.OUTPUT, "Output layer")) |
| 40 | + |
| 41 | + |
19 | 42 | def processAlgorithm(self, progress):
|
20 |
| - vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(ExportGeometryInfo.INPUT)) |
21 |
| - vprovider = vlayer.dataProvider() |
22 |
| - allAttrs = vprovider.attributeIndexes() |
23 |
| - vprovider.select( allAttrs ) |
24 |
| - ( fields, index1, index2 ) = self.checkGeometryFields(vlayer) |
25 |
| - writer = self.getOutputFromName(ExportGeometryInfo.OUTPUT).getVectorWriter(fields, vprovider.geometryType(), vprovider.crs() ) |
| 43 | + layer = QGisLayers.getObjectFromUri(self.getParameterValue(self.INPUT)) |
| 44 | + method = self.getParameterValue(self.METHOD) |
| 45 | + |
| 46 | + output = self.getOutputValue(self.OUTPUT) |
| 47 | + |
| 48 | + provider = layer.dataProvider() |
| 49 | + geometryType = layer.geometryType() |
| 50 | + |
| 51 | + layer.select(layer.pendingAllAttributesList()) |
| 52 | + |
| 53 | + idx1 = -1 |
| 54 | + idx2 = -1 |
| 55 | + fields = layer.pendingFields() |
| 56 | + |
| 57 | + if geometryType == QGis.Polygon: |
| 58 | + idx1, fields = utils.findOrCreateField(layer, fields, "area", 21, 6) |
| 59 | + idx2, fields = utils.findOrCreateField(layer, fields, "perimeter", 21, 6) |
| 60 | + elif geometryType == QGis.Line: |
| 61 | + idx1, fields = utils.findOrCreateField(layer, fields, "length", 21, 6) |
| 62 | + idx2 = idx1 |
| 63 | + else: |
| 64 | + idx1, fields = utils.findOrCreateField(layer, fields, "xcoord", 21, 6) |
| 65 | + idx2, fields = utils.findOrCreateField(layer, fields, "ycoord", 21, 6) |
| 66 | + |
| 67 | + writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, |
| 68 | + provider.geometryType(), provider.crs()) |
| 69 | + |
| 70 | + ellips = None |
| 71 | + crs = None |
| 72 | + coordTransform = None |
| 73 | + |
| 74 | + # calculate with: |
| 75 | + # 0 - layer CRS |
| 76 | + # 1 - project CRS |
| 77 | + # 2 - ellipsoidal |
| 78 | + if method == 2: |
| 79 | + settings = QSettings() |
| 80 | + ellips = settings.value("/qgis/measure/ellipsoid", "WGS84").toString() |
| 81 | + crs = layer.crs().srsid() |
| 82 | + elif method == 1: |
| 83 | + mapCRS = QGisLayers.iface.mapCanvas().mapRenderer().destinationCrs() |
| 84 | + layCRS = layer.crs() |
| 85 | + coordTransform = QgsCoordinateTransform(layCRS, mapCRS) |
| 86 | + |
26 | 87 | inFeat = QgsFeature()
|
27 | 88 | outFeat = QgsFeature()
|
28 | 89 | inGeom = QgsGeometry()
|
29 |
| - nFeat = vprovider.featureCount() |
30 |
| - nElement = 0 |
31 |
| - while vprovider.nextFeature(inFeat): |
32 |
| - progress.setPercentage(int(nElement/nFeat * 100)) |
33 |
| - nElement += 1 |
34 |
| - inGeom = inFeat.geometry() |
35 |
| - ( attr1, attr2 ) = self.simpleMeasure( inGeom ) |
36 |
| - outFeat.setGeometry( inGeom ) |
37 |
| - atMap = inFeat.attributeMap() |
38 |
| - outFeat.setAttributeMap( atMap ) |
39 |
| - outFeat.addAttribute( index1, QVariant( attr1 ) ) |
40 |
| - outFeat.addAttribute( index2, QVariant( attr2 ) ) |
41 |
| - writer.addFeature( outFeat ) |
42 |
| - del writer |
43 | 90 |
|
| 91 | + current = 0 |
| 92 | + total = 100.0 / float(provider.featureCount()) |
44 | 93 |
|
45 |
| - def simpleMeasure( self, inGeom ): |
46 |
| - if inGeom.wkbType() in (QGis.WKBPoint, QGis.WKBPoint25D): |
47 |
| - pt = QgsPoint() |
48 |
| - pt = inGeom.asPoint() |
49 |
| - attr1 = pt.x() |
50 |
| - attr2 = pt.y() |
51 |
| - elif inGeom.wkbType() in (QGis.WKBMultiPoint, QGis.WKBMultiPoint25D): |
52 |
| - pt = inGeom.asMultiPoint() |
53 |
| - attr1 = pt[ 0 ].x() |
54 |
| - attr2 = pt[ 0 ].y() |
55 |
| - else: |
56 |
| - measure = QgsDistanceArea() |
57 |
| - attr1 = measure.measure(inGeom) |
58 |
| - if inGeom.type() == QGis.Polygon: |
59 |
| - attr2 = self.perimMeasure( inGeom, measure ) |
60 |
| - else: |
61 |
| - attr2 = attr1 |
62 |
| - return ( attr1, attr2 ) |
63 |
| - |
64 |
| - def perimMeasure( self, inGeom, measure ): |
65 |
| - value = 0.00 |
66 |
| - if inGeom.isMultipart(): |
67 |
| - poly = inGeom.asMultiPolygon() |
68 |
| - for k in poly: |
69 |
| - for j in k: |
70 |
| - value = value + measure.measureLine( j ) |
71 |
| - else: |
72 |
| - poly = inGeom.asPolygon() |
73 |
| - for k in poly: |
74 |
| - value = value + measure.measureLine( k ) |
75 |
| - return value |
| 94 | + while layer.nextFeature(inFeat): |
| 95 | + inGeom = inFeat.geometry() |
| 96 | + |
| 97 | + if method == 1: |
| 98 | + inGeom.transform(coordTransform) |
| 99 | + |
| 100 | + (attr1, attr2) = self.simpleMeasure(inGeom, method, ellips, crs) |
| 101 | + |
| 102 | + outFeat.setGeometry(inGeom) |
| 103 | + atMap = inFeat.attributeMap() |
| 104 | + outFeat.setAttributeMap(atMap) |
| 105 | + outFeat.addAttribute(idx1, QVariant(attr1)) |
| 106 | + outFeat.addAttribute(idx2, QVariant(attr2)) |
| 107 | + writer.addFeature( outFeat ) |
76 | 108 |
|
77 |
| - def checkForField( self, L, e ): |
78 |
| - e = QString( e ).toLower() |
79 |
| - fieldRange = range( 0,len( L ) ) |
80 |
| - for item in fieldRange: |
81 |
| - if L[ item ].toLower() == e: |
82 |
| - return True, item |
83 |
| - return False, len( L ) |
84 |
| - |
85 |
| - def checkGeometryFields( self, vlayer ): |
86 |
| - vprovider = vlayer.dataProvider() |
87 |
| - nameList = [] |
88 |
| - fieldList = vprovider.fields() |
89 |
| - geomType = vlayer.geometryType() |
90 |
| - for i in fieldList.keys(): |
91 |
| - nameList.append( fieldList[ i ].name().toLower() ) |
92 |
| - if geomType == QGis.Polygon: |
93 |
| - plp = "Poly" |
94 |
| - ( found, index1 ) = self.checkForField( nameList, "AREA" ) |
95 |
| - if not found: |
96 |
| - field = QgsField( "AREA", QVariant.Double, "double", 21, 6, "Polygon area" ) |
97 |
| - index1 = len( fieldList.keys() ) |
98 |
| - fieldList[ index1 ] = field |
99 |
| - ( found, index2 ) = self.checkForField( nameList, "PERIMETER" ) |
100 |
| - |
101 |
| - if not found: |
102 |
| - field = QgsField( "PERIMETER", QVariant.Double, "double", 21, 6, "Polygon perimeter" ) |
103 |
| - index2 = len( fieldList.keys() ) |
104 |
| - fieldList[ index2 ] = field |
105 |
| - elif geomType == QGis.Line: |
106 |
| - plp = "Line" |
107 |
| - (found, index1) = self.checkForField(nameList, "LENGTH") |
108 |
| - if not found: |
109 |
| - field = QgsField("LENGTH", QVariant.Double, "double", 21, 6, "Line length" ) |
110 |
| - index1 = len(fieldList.keys()) |
111 |
| - fieldList[index1] = field |
112 |
| - index2 = index1 |
| 109 | + current += 1 |
| 110 | + progress.setPercentage(int(current * total)) |
| 111 | + |
| 112 | + del writer |
| 113 | + |
| 114 | + def simpleMeasure(self, geom, method, ellips, crs): |
| 115 | + if geom.wkbType() in [QGis.WKBPoint, QGis.WKBPoint25D]: |
| 116 | + pt = geom.asPoint() |
| 117 | + attr1 = pt.x() |
| 118 | + attr2 = pt.y() |
| 119 | + elif geom.wkbType() in [QGis.WKBMultiPoint, QGis.WKBMultiPoint25D]: |
| 120 | + pt = inGeom.asMultiPoint() |
| 121 | + attr1 = pt[0].x() |
| 122 | + attr2 = pt[0].y() |
113 | 123 | else:
|
114 |
| - plp = "Point" |
115 |
| - (found, index1) = self.checkForField(nameList, "XCOORD") |
116 |
| - if not found: |
117 |
| - field = QgsField("XCOORD", QVariant.Double, "double", 21, 6, "Point x coordinate" ) |
118 |
| - index1 = len(fieldList.keys()) |
119 |
| - fieldList[index1] = field |
120 |
| - (found, index2) = self.checkForField(nameList, "YCOORD") |
121 |
| - if not found: |
122 |
| - field = QgsField("YCOORD", QVariant.Double, "double", 21, 6, "Point y coordinate" ) |
123 |
| - index2 = len(fieldList.keys()) |
124 |
| - fieldList[index2] = field |
125 |
| - return (fieldList, index1, index2) |
| 124 | + measure = QgsDistanceArea() |
126 | 125 |
|
| 126 | + if method == 2: |
| 127 | + measure.setSourceCrs(crs) |
| 128 | + measure.setEllipsoid(ellips) |
| 129 | + measure.setProjectionsEnabled(True) |
127 | 130 |
|
128 |
| - def defineCharacteristics(self): |
129 |
| - self.name = "Export/Add geometry columns" |
130 |
| - self.group = "Geometry tools" |
131 |
| - self.addParameter(ParameterVector(ExportGeometryInfo.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY)) |
132 |
| - self.addOutput(OutputVector(ExportGeometryInfo.OUTPUT, "Output layer")) |
133 |
| - #========================================================= |
| 131 | + attr1 = measure.measure(geom) |
| 132 | + if geom.type() == QGis.Polygon: |
| 133 | + attr2 = self.perimMeasure(geom, measure) |
| 134 | + else: |
| 135 | + attr2 = attr1 |
| 136 | + |
| 137 | + return (attr1, attr2) |
| 138 | + |
| 139 | + def perimMeasure(self, geom, measure): |
| 140 | + value = 0.0 |
| 141 | + if geom.isMultipart(): |
| 142 | + polygons = geom.asMultiPolygon() |
| 143 | + for p in polygons: |
| 144 | + for line in p: |
| 145 | + value += measure.measureLine(line) |
| 146 | + else: |
| 147 | + poly = geom.asPolygon() |
| 148 | + for r in poly: |
| 149 | + value += measure.measureLine(r) |
| 150 | + |
| 151 | + return value |
0 commit comments