Skip to content
Permalink
Browse files

review Export geometry info tool, sync with master

  • Loading branch information
alexbruy committed Oct 4, 2012
1 parent 1a67b91 commit a6418d6502ddb13330cbec37a4a5ce47741cf229
Showing with 129 additions and 111 deletions.
  1. +126 −108 python/plugins/sextante/ftools/ExportGeometryInfo.py
  2. +3 −3 python/plugins/sextante/ftools/FToolsUtils.py
@@ -1,133 +1,151 @@
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.parameters.ParameterVector import ParameterVector
from sextante.parameters.ParameterSelection import ParameterSelection

from sextante.outputs.OutputVector import OutputVector

from sextante.ftools import FToolsUtils as utils

class ExportGeometryInfo(GeoAlgorithm):

INPUT = "INPUT"
METHOD = "CALC_METHOD"
OUTPUT = "OUTPUT"

CALC_METHODS = ["Layer CRS",
"Project CRS",
"Ellipsoidal"
]

def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/export_geometry.png")

def defineCharacteristics(self):
self.name = "Export/Add geometry columns"
self.group = "Geometry tools"

self.addParameter(ParameterVector(self.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY))
self.addParameter(ParameterSelection(self.METHOD, "Calculate using", self.CALC_METHODS, 0))

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


def processAlgorithm(self, progress):
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(ExportGeometryInfo.INPUT))
vprovider = vlayer.dataProvider()
allAttrs = vprovider.attributeIndexes()
vprovider.select( allAttrs )
( fields, index1, index2 ) = self.checkGeometryFields(vlayer)
writer = self.getOutputFromName(ExportGeometryInfo.OUTPUT).getVectorWriter(fields, vprovider.geometryType(), vprovider.crs() )
layer = QGisLayers.getObjectFromUri(self.getParameterValue(self.INPUT))
method = self.getParameterValue(self.METHOD)

output = self.getOutputValue(self.OUTPUT)

provider = layer.dataProvider()
geometryType = layer.geometryType()

layer.select(layer.pendingAllAttributesList())

idx1 = -1
idx2 = -1
fields = layer.pendingFields()

if geometryType == QGis.Polygon:
idx1, fields = utils.findOrCreateField(layer, fields, "area", 21, 6)
idx2, fields = utils.findOrCreateField(layer, fields, "perimeter", 21, 6)
elif geometryType == QGis.Line:
idx1, fields = utils.findOrCreateField(layer, fields, "length", 21, 6)
idx2 = idx1
else:
idx1, fields = utils.findOrCreateField(layer, fields, "xcoord", 21, 6)
idx2, fields = utils.findOrCreateField(layer, fields, "ycoord", 21, 6)

writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields,
provider.geometryType(), provider.crs())

ellips = None
crs = None
coordTransform = None

# calculate with:
# 0 - layer CRS
# 1 - project CRS
# 2 - ellipsoidal
if method == 2:
settings = QSettings()
ellips = settings.value("/qgis/measure/ellipsoid", "WGS84").toString()
crs = layer.crs().srsid()
elif method == 1:
mapCRS = QGisLayers.iface.mapCanvas().mapRenderer().destinationCrs()
layCRS = layer.crs()
coordTransform = QgsCoordinateTransform(layCRS, mapCRS)

inFeat = QgsFeature()
outFeat = QgsFeature()
inGeom = QgsGeometry()
nFeat = vprovider.featureCount()
nElement = 0
while vprovider.nextFeature(inFeat):
progress.setPercentage(int(nElement/nFeat * 100))
nElement += 1
inGeom = inFeat.geometry()
( attr1, attr2 ) = self.simpleMeasure( inGeom )
outFeat.setGeometry( inGeom )
atMap = inFeat.attributeMap()
outFeat.setAttributeMap( atMap )
outFeat.addAttribute( index1, QVariant( attr1 ) )
outFeat.addAttribute( index2, QVariant( attr2 ) )
writer.addFeature( outFeat )
del writer

current = 0
total = 100.0 / float(provider.featureCount())

def simpleMeasure( self, inGeom ):
if inGeom.wkbType() in (QGis.WKBPoint, QGis.WKBPoint25D):
pt = QgsPoint()
pt = inGeom.asPoint()
attr1 = pt.x()
attr2 = pt.y()
elif inGeom.wkbType() in (QGis.WKBMultiPoint, QGis.WKBMultiPoint25D):
pt = inGeom.asMultiPoint()
attr1 = pt[ 0 ].x()
attr2 = pt[ 0 ].y()
else:
measure = QgsDistanceArea()
attr1 = measure.measure(inGeom)
if inGeom.type() == QGis.Polygon:
attr2 = self.perimMeasure( inGeom, measure )
else:
attr2 = attr1
return ( attr1, attr2 )

def perimMeasure( self, inGeom, measure ):
value = 0.00
if inGeom.isMultipart():
poly = inGeom.asMultiPolygon()
for k in poly:
for j in k:
value = value + measure.measureLine( j )
else:
poly = inGeom.asPolygon()
for k in poly:
value = value + measure.measureLine( k )
return value
while layer.nextFeature(inFeat):
inGeom = inFeat.geometry()

if method == 1:
inGeom.transform(coordTransform)

(attr1, attr2) = self.simpleMeasure(inGeom, method, ellips, crs)

outFeat.setGeometry(inGeom)
atMap = inFeat.attributeMap()
outFeat.setAttributeMap(atMap)
outFeat.addAttribute(idx1, QVariant(attr1))
outFeat.addAttribute(idx2, QVariant(attr2))
writer.addFeature( outFeat )

def checkForField( self, L, e ):
e = QString( e ).toLower()
fieldRange = range( 0,len( L ) )
for item in fieldRange:
if L[ item ].toLower() == e:
return True, item
return False, len( L )

def checkGeometryFields( self, vlayer ):
vprovider = vlayer.dataProvider()
nameList = []
fieldList = vprovider.fields()
geomType = vlayer.geometryType()
for i in fieldList.keys():
nameList.append( fieldList[ i ].name().toLower() )
if geomType == QGis.Polygon:
plp = "Poly"
( found, index1 ) = self.checkForField( nameList, "AREA" )
if not found:
field = QgsField( "AREA", QVariant.Double, "double", 21, 6, "Polygon area" )
index1 = len( fieldList.keys() )
fieldList[ index1 ] = field
( found, index2 ) = self.checkForField( nameList, "PERIMETER" )

if not found:
field = QgsField( "PERIMETER", QVariant.Double, "double", 21, 6, "Polygon perimeter" )
index2 = len( fieldList.keys() )
fieldList[ index2 ] = field
elif geomType == QGis.Line:
plp = "Line"
(found, index1) = self.checkForField(nameList, "LENGTH")
if not found:
field = QgsField("LENGTH", QVariant.Double, "double", 21, 6, "Line length" )
index1 = len(fieldList.keys())
fieldList[index1] = field
index2 = index1
current += 1
progress.setPercentage(int(current * total))

del writer

def simpleMeasure(self, geom, method, ellips, crs):
if geom.wkbType() in [QGis.WKBPoint, QGis.WKBPoint25D]:
pt = geom.asPoint()
attr1 = pt.x()
attr2 = pt.y()
elif geom.wkbType() in [QGis.WKBMultiPoint, QGis.WKBMultiPoint25D]:
pt = inGeom.asMultiPoint()
attr1 = pt[0].x()
attr2 = pt[0].y()
else:
plp = "Point"
(found, index1) = self.checkForField(nameList, "XCOORD")
if not found:
field = QgsField("XCOORD", QVariant.Double, "double", 21, 6, "Point x coordinate" )
index1 = len(fieldList.keys())
fieldList[index1] = field
(found, index2) = self.checkForField(nameList, "YCOORD")
if not found:
field = QgsField("YCOORD", QVariant.Double, "double", 21, 6, "Point y coordinate" )
index2 = len(fieldList.keys())
fieldList[index2] = field
return (fieldList, index1, index2)
measure = QgsDistanceArea()

if method == 2:
measure.setSourceCrs(crs)
measure.setEllipsoid(ellips)
measure.setProjectionsEnabled(True)

def defineCharacteristics(self):
self.name = "Export/Add geometry columns"
self.group = "Geometry tools"
self.addParameter(ParameterVector(ExportGeometryInfo.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY))
self.addOutput(OutputVector(ExportGeometryInfo.OUTPUT, "Output layer"))
#=========================================================
attr1 = measure.measure(geom)
if geom.type() == QGis.Polygon:
attr2 = self.perimMeasure(geom, measure)
else:
attr2 = attr1

return (attr1, attr2)

def perimMeasure(self, geom, measure):
value = 0.0
if geom.isMultipart():
polygons = geom.asMultiPolygon()
for p in polygons:
for line in p:
value += measure.measureLine(line)
else:
poly = geom.asPolygon()
for r in poly:
value += measure.measureLine(r)

return value
@@ -7,8 +7,8 @@ def createSpatialIndex(provider):
idx = QgsSpatialIndex()
provider.rewind()
provider.select()
while provider.nextFeature( ft ):
idx.insertFeature( ft )
while provider.nextFeature(ft):
idx.insertFeature(ft)
return idx

def createUniqueFieldName(fieldName, fieldList):
@@ -37,7 +37,7 @@ def createUniqueFieldName(fieldName, fieldList):

return shortName

def findOrCreateField(layer, fieldList, fieldName, fieldLen = 24, fieldPrec = 15):
def findOrCreateField(layer, fieldList, fieldName, fieldLen=24, fieldPrec=15):
idx = layer.fieldNameIndex(fieldName)
if idx == -1:
idx = len(fieldList)

0 comments on commit a6418d6

Please sign in to comment.
You can’t perform that action at this time.