mirror of
https://github.com/qgis/QGIS.git
synced 2025-11-22 00:14:55 -05:00
review Export geometry info tool, sync with master
This commit is contained in:
parent
1a67b91c4c
commit
a6418d6502
@ -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 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() )
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
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)
|
||||
|
||||
|
||||
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"))
|
||||
#=========================================================
|
||||
|
||||
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):
|
||||
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()
|
||||
|
||||
current = 0
|
||||
total = 100.0 / float(provider.featureCount())
|
||||
|
||||
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 )
|
||||
|
||||
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:
|
||||
measure = QgsDistanceArea()
|
||||
|
||||
if method == 2:
|
||||
measure.setSourceCrs(crs)
|
||||
measure.setEllipsoid(ellips)
|
||||
measure.setProjectionsEnabled(True)
|
||||
|
||||
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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user