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
|
import os.path
|
||||||
|
|
||||||
from PyQt4 import QtGui
|
from PyQt4 import QtGui
|
||||||
from PyQt4.QtCore import *
|
from PyQt4.QtCore import *
|
||||||
from PyQt4.QtGui import *
|
|
||||||
from qgis.core 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.core.QGisLayers import QGisLayers
|
||||||
|
|
||||||
|
from sextante.parameters.ParameterVector import ParameterVector
|
||||||
|
from sextante.parameters.ParameterSelection import ParameterSelection
|
||||||
|
|
||||||
from sextante.outputs.OutputVector import OutputVector
|
from sextante.outputs.OutputVector import OutputVector
|
||||||
|
|
||||||
|
from sextante.ftools import FToolsUtils as utils
|
||||||
|
|
||||||
class ExportGeometryInfo(GeoAlgorithm):
|
class ExportGeometryInfo(GeoAlgorithm):
|
||||||
|
|
||||||
INPUT = "INPUT"
|
INPUT = "INPUT"
|
||||||
|
METHOD = "CALC_METHOD"
|
||||||
OUTPUT = "OUTPUT"
|
OUTPUT = "OUTPUT"
|
||||||
|
|
||||||
|
CALC_METHODS = ["Layer CRS",
|
||||||
|
"Project CRS",
|
||||||
|
"Ellipsoidal"
|
||||||
|
]
|
||||||
|
|
||||||
def getIcon(self):
|
def getIcon(self):
|
||||||
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/export_geometry.png")
|
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):
|
def defineCharacteristics(self):
|
||||||
self.name = "Export/Add geometry columns"
|
self.name = "Export/Add geometry columns"
|
||||||
self.group = "Geometry tools"
|
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()
|
idx = QgsSpatialIndex()
|
||||||
provider.rewind()
|
provider.rewind()
|
||||||
provider.select()
|
provider.select()
|
||||||
while provider.nextFeature( ft ):
|
while provider.nextFeature(ft):
|
||||||
idx.insertFeature( ft )
|
idx.insertFeature(ft)
|
||||||
return idx
|
return idx
|
||||||
|
|
||||||
def createUniqueFieldName(fieldName, fieldList):
|
def createUniqueFieldName(fieldName, fieldList):
|
||||||
@ -37,7 +37,7 @@ def createUniqueFieldName(fieldName, fieldList):
|
|||||||
|
|
||||||
return shortName
|
return shortName
|
||||||
|
|
||||||
def findOrCreateField(layer, fieldList, fieldName, fieldLen = 24, fieldPrec = 15):
|
def findOrCreateField(layer, fieldList, fieldName, fieldLen=24, fieldPrec=15):
|
||||||
idx = layer.fieldNameIndex(fieldName)
|
idx = layer.fieldNameIndex(fieldName)
|
||||||
if idx == -1:
|
if idx == -1:
|
||||||
idx = len(fieldList)
|
idx = len(fieldList)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user