Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
review Export geometry info tool, sync with master
  • Loading branch information
alexbruy committed Oct 4, 2012
1 parent 1a67b91 commit a6418d6
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 111 deletions.
234 changes: 126 additions & 108 deletions python/plugins/sextante/ftools/ExportGeometryInfo.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
6 changes: 3 additions & 3 deletions python/plugins/sextante/ftools/FToolsUtils.py
Expand Up @@ -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):
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit a6418d6

Please sign in to comment.