本文整理汇总了Python中qgis.core.QgsDistanceArea.measureArea方法的典型用法代码示例。如果您正苦于以下问题:Python QgsDistanceArea.measureArea方法的具体用法?Python QgsDistanceArea.measureArea怎么用?Python QgsDistanceArea.measureArea使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类qgis.core.QgsDistanceArea
的用法示例。
在下文中一共展示了QgsDistanceArea.measureArea方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: testMeasureMultiPolygon
# 需要导入模块: from qgis.core import QgsDistanceArea [as 别名]
# 或者: from qgis.core.QgsDistanceArea import measureArea [as 别名]
def testMeasureMultiPolygon(self):
# +-+-+ +-+-+
# | | | |
# + +-+ +-+ +
# | | | |
# +-+ +-+
polygon = QgsGeometry.fromMultiPolygon(
[
[[QgsPoint(0, 0), QgsPoint(1, 0), QgsPoint(1, 1), QgsPoint(2, 1), QgsPoint(2, 2), QgsPoint(0, 2), QgsPoint(0, 0), ]],
[[QgsPoint(4, 0), QgsPoint(5, 0), QgsPoint(5, 2), QgsPoint(3, 2), QgsPoint(3, 1), QgsPoint(4, 1), QgsPoint(4, 0), ]]
]
)
da = QgsDistanceArea()
area = da.measureArea(polygon)
assert area == 6, 'Expected:\n%f\nGot:\n%f\n' % (6, area)
perimeter = da.measurePerimeter(polygon)
assert perimeter == 16, "Expected:\n%f\nGot:\n%f\n" % (16, perimeter)
示例2: testMeasurePolygonWithHole
# 需要导入模块: from qgis.core import QgsDistanceArea [as 别名]
# 或者: from qgis.core.QgsDistanceArea import measureArea [as 别名]
def testMeasurePolygonWithHole(self):
# +-+-+-+
# | |
# + +-+ +
# | | | |
# + +-+ +
# | |
# +-+-+-+
polygon = QgsGeometry.fromPolygon(
[
[QgsPoint(0, 0), QgsPoint(3, 0), QgsPoint(3, 3), QgsPoint(0, 3), QgsPoint(0, 0)],
[QgsPoint(1, 1), QgsPoint(2, 1), QgsPoint(2, 2), QgsPoint(1, 2), QgsPoint(1, 1)],
]
)
da = QgsDistanceArea()
area = da.measureArea(polygon)
assert area == 8, "Expected:\n%f\nGot:\n%f\n" % (8, area)
# MH150729: Changed behaviour to consider inner rings for perimeter calculation. Therefore, expected result is 16.
perimeter = da.measurePerimeter(polygon)
assert perimeter == 16, "Expected:\n%f\nGot:\n%f\n" % (16, perimeter)
示例3: evaluation
# 需要导入模块: from qgis.core import QgsDistanceArea [as 别名]
# 或者: from qgis.core.QgsDistanceArea import measureArea [as 别名]
def evaluation(self=None, parameters={},feature=None):
from PyQt4.QtCore import QVariant
from qgis.core import QgsDistanceArea, QgsCoordinateReferenceSystem
ar = NULL
per = NULL
id = NULL
flr = NULL
usage = NULL
kind = NULL
da_engine=QgsDistanceArea()
da_engine.setSourceCrs(QgsCoordinateReferenceSystem(int(config.project_crs.split(':')[-1]), QgsCoordinateReferenceSystem.EpsgCrsId))
da_engine.setEllipsoid(config.project_ellipsoid)
da_engine.setEllipsoidalMode(True)
if feature:
geometry = feature.geometry()
#print geometry
ar = da_engine.measureArea(geometry)
per =da_engine.measurePerimeter(geometry)
id = feature[config.building_id_key] #necessary to safe dependency check
flr = feature[u'FLRS_ALK'] # necessary to safe dependency check
usage = feature[u'FUNC_ALK'] # necessary to safe dependency check
kind = feature[u'KIND_ALK'] # necessary to safe dependency check
#print ar
#print per
#print id
return {config.building_id_key: {'type': QVariant.String,
'value': id},
'AREA_ALK': {'type': QVariant.Double,
'value': ar},
'PERI_ALK': {'type': QVariant.Double,
'value': per},
'FLRS_ALK': {'type': QVariant.Double,
'value': flr},
'FUNC_ALK': {'type': QVariant.Double,
'value': usage},
'KIND_ALK': {'type': QVariant.Double,
'value': kind},
}
示例4: processAlgorithm
# 需要导入模块: from qgis.core import QgsDistanceArea [as 别名]
# 或者: from qgis.core.QgsDistanceArea import measureArea [as 别名]
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
strategy = self.parameterAsEnum(parameters, self.STRATEGY, context)
minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE, context)
expression = QgsExpression(self.parameterAsString(parameters, self.EXPRESSION, context))
if expression.hasParserError():
raise QgsProcessingException(expression.parserErrorString())
expressionContext = self.createExpressionContext(parameters, context, source)
expression.prepare(expressionContext)
fields = QgsFields()
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
fields, QgsWkbTypes.Point, source.sourceCrs(), QgsFeatureSink.RegeneratePrimaryKey)
if sink is None:
raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))
da = QgsDistanceArea()
da.setSourceCrs(source.sourceCrs(), context.transformContext())
da.setEllipsoid(context.project().ellipsoid())
total = 100.0 / source.featureCount() if source.featureCount() else 0
current_progress = 0
for current, f in enumerate(source.getFeatures()):
if feedback.isCanceled():
break
if not f.hasGeometry():
continue
current_progress = total * current
feedback.setProgress(current_progress)
expressionContext.setFeature(f)
value = expression.evaluate(expressionContext)
if expression.hasEvalError():
feedback.pushInfo(
self.tr('Evaluation error for feature ID {}: {}').format(f.id(), expression.evalErrorString()))
continue
fGeom = f.geometry()
engine = QgsGeometry.createGeometryEngine(fGeom.constGet())
engine.prepareGeometry()
bbox = fGeom.boundingBox()
if strategy == 0:
pointCount = int(value)
else:
pointCount = int(round(value * da.measureArea(fGeom)))
if pointCount == 0:
feedback.pushInfo("Skip feature {} as number of points for it is 0.".format(f.id()))
continue
index = QgsSpatialIndex()
points = dict()
nPoints = 0
nIterations = 0
maxIterations = pointCount * 200
feature_total = total / pointCount if pointCount else 1
random.seed()
while nIterations < maxIterations and nPoints < pointCount:
if feedback.isCanceled():
break
rx = bbox.xMinimum() + bbox.width() * random.random()
ry = bbox.yMinimum() + bbox.height() * random.random()
p = QgsPointXY(rx, ry)
geom = QgsGeometry.fromPointXY(p)
if engine.contains(geom.constGet()) and \
vector.checkMinDistance(p, index, minDistance, points):
f = QgsFeature(nPoints)
f.initAttributes(1)
f.setFields(fields)
f.setAttribute('id', nPoints)
f.setGeometry(geom)
sink.addFeature(f, QgsFeatureSink.FastInsert)
index.addFeature(f)
points[nPoints] = p
nPoints += 1
feedback.setProgress(current_progress + int(nPoints * feature_total))
nIterations += 1
if nPoints < pointCount:
feedback.pushInfo(self.tr('Could not generate requested number of random '
'points. Maximum number of attempts exceeded.'))
feedback.setProgress(100)
return {self.OUTPUT: dest_id}
示例5: ExportGeometryInfo
# 需要导入模块: from qgis.core import QgsDistanceArea [as 别名]
# 或者: from qgis.core.QgsDistanceArea import measureArea [as 别名]
#.........这里部分代码省略.........
new_fields.append(QgsField('straightdis', QVariant.Double))
new_fields.append(QgsField('sinuosity', QVariant.Double))
else:
new_fields.append(QgsField('xcoord', QVariant.Double))
new_fields.append(QgsField('ycoord', QVariant.Double))
if QgsWkbTypes.hasZ(source.wkbType()):
self.export_z = True
new_fields.append(QgsField('zcoord', QVariant.Double))
if QgsWkbTypes.hasM(source.wkbType()):
self.export_m = True
new_fields.append(QgsField('mvalue', QVariant.Double))
fields = QgsProcessingUtils.combineFields(fields, new_fields)
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
fields, wkb_type, source.sourceCrs())
if sink is None:
raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))
coordTransform = None
# Calculate with:
# 0 - layer CRS
# 1 - project CRS
# 2 - ellipsoidal
self.distance_area = QgsDistanceArea()
if method == 2:
self.distance_area.setSourceCrs(source.sourceCrs(), context.transformContext())
self.distance_area.setEllipsoid(context.project().ellipsoid())
elif method == 1:
coordTransform = QgsCoordinateTransform(source.sourceCrs(), context.project().crs(), context.project())
features = source.getFeatures()
total = 100.0 / source.featureCount() if source.featureCount() else 0
for current, f in enumerate(features):
if feedback.isCanceled():
break
outFeat = f
attrs = f.attributes()
inGeom = f.geometry()
if inGeom:
if coordTransform is not None:
inGeom.transform(coordTransform)
if inGeom.type() == QgsWkbTypes.PointGeometry:
attrs.extend(self.point_attributes(inGeom))
elif inGeom.type() == QgsWkbTypes.PolygonGeometry:
attrs.extend(self.polygon_attributes(inGeom))
else:
attrs.extend(self.line_attributes(inGeom))
# ensure consistent count of attributes - otherwise null
# geometry features will have incorrect attribute length
# and provider may reject them
if len(attrs) < len(fields):
attrs += [NULL] * (len(fields) - len(attrs))
outFeat.setAttributes(attrs)
sink.addFeature(outFeat, QgsFeatureSink.FastInsert)
feedback.setProgress(int(current * total))
return {self.OUTPUT: dest_id}
def point_attributes(self, geometry):
pt = None
if not geometry.isMultipart():
pt = geometry.constGet()
else:
if geometry.numGeometries() > 0:
pt = geometry.geometryN(0)
attrs = []
if pt:
attrs.append(pt.x())
attrs.append(pt.y())
# add point z/m
if self.export_z:
attrs.append(pt.z())
if self.export_m:
attrs.append(pt.m())
return attrs
def line_attributes(self, geometry):
if geometry.isMultipart():
return [self.distance_area.measureLength(geometry)]
else:
curve = geometry.constGet()
p1 = curve.startPoint()
p2 = curve.endPoint()
straight_distance = self.distance_area.measureLine(QgsPointXY(p1), QgsPointXY(p2))
sinuosity = curve.sinuosity()
if math.isnan(sinuosity):
sinuosity = NULL
return [self.distance_area.measureLength(geometry), straight_distance, sinuosity]
def polygon_attributes(self, geometry):
area = self.distance_area.measureArea(geometry)
perimeter = self.distance_area.measurePerimeter(geometry)
return [area, perimeter]
示例6: testAreaMeasureAndUnits
# 需要导入模块: from qgis.core import QgsDistanceArea [as 别名]
# 或者: from qgis.core.QgsDistanceArea import measureArea [as 别名]
def testAreaMeasureAndUnits(self):
"""Test a variety of area measurements in different CRS and ellipsoid modes, to check that the
calculated areas and units are always consistent
"""
da = QgsDistanceArea()
da.setSourceCrs(3452)
da.setEllipsoidalMode(False)
da.setEllipsoid("NONE")
daCRS = QgsCoordinateReferenceSystem()
daCRS = da.sourceCrs()
polygon = QgsGeometry.fromPolygon(
[[
QgsPoint(0, 0), QgsPoint(1, 0), QgsPoint(1, 1), QgsPoint(2, 1), QgsPoint(2, 2), QgsPoint(0, 2), QgsPoint(0, 0),
]]
)
# We check both the measured area AND the units, in case the logic regarding
# ellipsoids and units changes in future
area = da.measureArea(polygon)
units = da.areaUnits()
print(("measured {} in {}".format(area, QgsUnitTypes.toString(units))))
assert ((abs(area - 3.0) < 0.00000001 and units == QgsUnitTypes.AreaSquareDegrees) or
(abs(area - 37176087091.5) < 0.1 and units == QgsUnitTypes.AreaSquareMeters))
da.setEllipsoid("WGS84")
area = da.measureArea(polygon)
units = da.areaUnits()
print(("measured {} in {}".format(area, QgsUnitTypes.toString(units))))
assert ((abs(area - 3.0) < 0.00000001 and units == QgsUnitTypes.AreaSquareDegrees) or
(abs(area - 37176087091.5) < 0.1 and units == QgsUnitTypes.AreaSquareMeters))
da.setEllipsoidalMode(True)
area = da.measureArea(polygon)
units = da.areaUnits()
print(("measured {} in {}".format(area, QgsUnitTypes.toString(units))))
# should always be in Meters Squared
self.assertAlmostEqual(area, 37416879192.9, delta=0.1)
self.assertEqual(units, QgsUnitTypes.AreaSquareMeters)
# test converting the resultant area
area = da.convertAreaMeasurement(area, QgsUnitTypes.AreaSquareMiles)
self.assertAlmostEqual(area, 14446.7378, delta=0.001)
# now try with a source CRS which is in feet
polygon = QgsGeometry.fromPolygon(
[[
QgsPoint(1850000, 4423000), QgsPoint(1851000, 4423000), QgsPoint(1851000, 4424000), QgsPoint(1852000, 4424000), QgsPoint(1852000, 4425000), QgsPoint(1851000, 4425000), QgsPoint(1850000, 4423000)
]]
)
da.setSourceCrs(27469)
da.setEllipsoidalMode(False)
# measurement should be in square feet
area = da.measureArea(polygon)
units = da.areaUnits()
print(("measured {} in {}".format(area, QgsUnitTypes.toString(units))))
self.assertAlmostEqual(area, 2000000, delta=0.001)
self.assertEqual(units, QgsUnitTypes.AreaSquareFeet)
# test converting the resultant area
area = da.convertAreaMeasurement(area, QgsUnitTypes.AreaSquareYards)
self.assertAlmostEqual(area, 222222.2222, delta=0.001)
da.setEllipsoidalMode(True)
# now should be in Square Meters again
area = da.measureArea(polygon)
units = da.areaUnits()
print(("measured {} in {}".format(area, QgsUnitTypes.toString(units))))
self.assertAlmostEqual(area, 184149.37, delta=1.0)
self.assertEqual(units, QgsUnitTypes.AreaSquareMeters)
# test converting the resultant area
area = da.convertAreaMeasurement(area, QgsUnitTypes.AreaSquareYards)
self.assertAlmostEqual(area, 220240.8172549, delta=1.0)
示例7: SizeCalculator
# 需要导入模块: from qgis.core import QgsDistanceArea [as 别名]
# 或者: from qgis.core.QgsDistanceArea import measureArea [as 别名]
class SizeCalculator():
"""Special object to handle size calculation with an output unit."""
def __init__(
self, coordinate_reference_system, geometry_type, exposure_key):
"""Constructor for the size calculator.
:param coordinate_reference_system: The Coordinate Reference System of
the layer.
:type coordinate_reference_system: QgsCoordinateReferenceSystem
:param exposure_key: The geometry type of the layer.
:type exposure_key: qgis.core.QgsWkbTypes.GeometryType
"""
self.calculator = QgsDistanceArea()
self.calculator.setSourceCrs(
coordinate_reference_system,
QgsProject.instance().transformContext()
)
self.calculator.setEllipsoid('WGS84')
if geometry_type == QgsWkbTypes.LineGeometry:
self.default_unit = unit_metres
LOGGER.info('The size calculator is set to use {unit}'.format(
unit=distance_unit[self.calculator.lengthUnits()]))
else:
self.default_unit = unit_square_metres
LOGGER.info('The size calculator is set to use {unit}'.format(
unit=distance_unit[self.calculator.areaUnits()]))
self.geometry_type = geometry_type
self.output_unit = None
if exposure_key:
exposure_definition = definition(exposure_key)
self.output_unit = exposure_definition['size_unit']
def measure_distance(self, point_a, point_b):
"""Measure the distance between two points.
This is added here since QgsDistanceArea object is already called here.
:param point_a: First Point.
:type point_a: QgsPoint
:param point_b: Second Point.
:type point_b: QgsPoint
:return: The distance between input points.
:rtype: float
"""
return self.calculator.measureLine(point_a, point_b)
def measure(self, geometry):
"""Measure the length or the area of a geometry.
:param geometry: The geometry.
:type geometry: QgsGeometry
:return: The geometric size in the expected exposure unit.
:rtype: float
"""
message = 'Size with NaN value : geometry valid={valid}, WKT={wkt}'
feature_size = 0
if geometry.isMultipart():
# Be careful, the size calculator is not working well on a
# multipart.
# So we compute the size part per part. See ticket #3812
for single in geometry.asGeometryCollection():
if self.geometry_type == QgsWkbTypes.LineGeometry:
geometry_size = self.calculator.measureLength(single)
else:
geometry_size = self.calculator.measureArea(single)
if not isnan(geometry_size):
feature_size += geometry_size
else:
LOGGER.debug(message.format(
valid=single.isGeosValid(),
wkt=single.asWkt()))
else:
if self.geometry_type == QgsWkbTypes.LineGeometry:
geometry_size = self.calculator.measureLength(geometry)
else:
geometry_size = self.calculator.measureArea(geometry)
if not isnan(geometry_size):
feature_size = geometry_size
else:
LOGGER.debug(message.format(
valid=geometry.isGeosValid(),
wkt=geometry.asWkt()))
feature_size = round(feature_size)
if self.output_unit:
if self.output_unit != self.default_unit:
feature_size = convert_unit(
feature_size, self.default_unit, self.output_unit)
return feature_size
示例8: testAreaMeasureAndUnits
# 需要导入模块: from qgis.core import QgsDistanceArea [as 别名]
# 或者: from qgis.core.QgsDistanceArea import measureArea [as 别名]
def testAreaMeasureAndUnits(self):
"""Test a variety of area measurements in different CRS and ellipsoid modes, to check that the
calculated areas and units are always consistent
"""
da = QgsDistanceArea()
da.setSourceCrs(QgsCoordinateReferenceSystem.fromSrsId(3452), QgsProject.instance().transformContext())
da.setEllipsoid("NONE")
polygon = QgsGeometry.fromPolygonXY(
[[
QgsPointXY(0, 0), QgsPointXY(1, 0), QgsPointXY(1, 1), QgsPointXY(2, 1), QgsPointXY(2, 2), QgsPointXY(0, 2), QgsPointXY(0, 0),
]]
)
# We check both the measured area AND the units, in case the logic regarding
# ellipsoids and units changes in future
area = da.measureArea(polygon)
units = da.areaUnits()
print(("measured {} in {}".format(area, QgsUnitTypes.toString(units))))
assert ((abs(area - 3.0) < 0.00000001 and units == QgsUnitTypes.AreaSquareDegrees) or
(abs(area - 37176087091.5) < 0.1 and units == QgsUnitTypes.AreaSquareMeters))
da.setEllipsoid("WGS84")
area = da.measureArea(polygon)
units = da.areaUnits()
print(("measured {} in {}".format(area, QgsUnitTypes.toString(units))))
# should always be in Meters Squared
self.assertAlmostEqual(area, 36918093794.121284, delta=0.1)
self.assertEqual(units, QgsUnitTypes.AreaSquareMeters)
# test converting the resultant area
area = da.convertAreaMeasurement(area, QgsUnitTypes.AreaSquareMiles)
self.assertAlmostEqual(area, 14254.155703182701, delta=0.001)
# now try with a source CRS which is in feet
polygon = QgsGeometry.fromPolygonXY(
[[
QgsPointXY(1850000, 4423000), QgsPointXY(1851000, 4423000), QgsPointXY(1851000, 4424000), QgsPointXY(1852000, 4424000), QgsPointXY(1852000, 4425000), QgsPointXY(1851000, 4425000), QgsPointXY(1850000, 4423000)
]]
)
da.setSourceCrs(QgsCoordinateReferenceSystem.fromSrsId(27469), QgsProject.instance().transformContext())
da.setEllipsoid("NONE")
# measurement should be in square feet
area = da.measureArea(polygon)
units = da.areaUnits()
print(("measured {} in {}".format(area, QgsUnitTypes.toString(units))))
self.assertAlmostEqual(area, 2000000, delta=0.001)
self.assertEqual(units, QgsUnitTypes.AreaSquareFeet)
# test converting the resultant area
area = da.convertAreaMeasurement(area, QgsUnitTypes.AreaSquareYards)
self.assertAlmostEqual(area, 222222.2222, delta=0.001)
da.setEllipsoid("WGS84")
# now should be in Square Meters again
area = da.measureArea(polygon)
units = da.areaUnits()
print(("measured {} in {}".format(area, QgsUnitTypes.toString(units))))
self.assertAlmostEqual(area, 185818.59096575077, delta=1.0)
self.assertEqual(units, QgsUnitTypes.AreaSquareMeters)
# test converting the resultant area
area = da.convertAreaMeasurement(area, QgsUnitTypes.AreaSquareYards)
self.assertAlmostEqual(area, 222237.18521272976, delta=1.0)
示例9: processAlgorithm
# 需要导入模块: from qgis.core import QgsDistanceArea [as 别名]
# 或者: from qgis.core.QgsDistanceArea import measureArea [as 别名]
def processAlgorithm(self, parameters, context, feedback):
layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.VECTOR), context)
value = float(self.getParameterValue(self.VALUE))
minDistance = float(self.getParameterValue(self.MIN_DISTANCE))
strategy = self.getParameterValue(self.STRATEGY)
fields = QgsFields()
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.Point, layer.crs(), context)
da = QgsDistanceArea()
features = QgsProcessingUtils.getFeatures(layer, context)
for current, f in enumerate(features):
fGeom = f.geometry()
bbox = fGeom.boundingBox()
if strategy == 0:
pointCount = int(value)
else:
pointCount = int(round(value * da.measureArea(fGeom)))
if pointCount == 0:
feedback.pushInfo("Skip feature {} as number of points for it is 0.")
continue
index = QgsSpatialIndex()
points = dict()
nPoints = 0
nIterations = 0
maxIterations = pointCount * 200
total = 100.0 / pointCount
random.seed()
while nIterations < maxIterations and nPoints < pointCount:
rx = bbox.xMinimum() + bbox.width() * random.random()
ry = bbox.yMinimum() + bbox.height() * random.random()
pnt = QgsPointXY(rx, ry)
geom = QgsGeometry.fromPoint(pnt)
if geom.within(fGeom) and \
vector.checkMinDistance(pnt, index, minDistance, points):
f = QgsFeature(nPoints)
f.initAttributes(1)
f.setFields(fields)
f.setAttribute('id', nPoints)
f.setGeometry(geom)
writer.addFeature(f)
index.insertFeature(f)
points[nPoints] = pnt
nPoints += 1
feedback.setProgress(int(nPoints * total))
nIterations += 1
if nPoints < pointCount:
QgsMessageLog.logMessage(self.tr('Can not generate requested number of random '
'points. Maximum number of attempts exceeded.'), self.tr('Processing'), QgsMessageLog.INFO)
feedback.setProgress(0)
del writer
示例10: ExportGeometryInfo
# 需要导入模块: from qgis.core import QgsDistanceArea [as 别名]
# 或者: from qgis.core.QgsDistanceArea import measureArea [as 别名]
#.........这里部分代码省略.........
return self.tr('Export/Add geometry columns')
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
method = self.parameterAsEnum(parameters, self.METHOD, context)
wkb_type = source.wkbType()
fields = source.fields()
if QgsWkbTypes.geometryType(wkb_type) == QgsWkbTypes.PolygonGeometry:
areaName = vector.createUniqueFieldName('area', fields)
fields.append(QgsField(areaName, QVariant.Double))
perimeterName = vector.createUniqueFieldName('perimeter', fields)
fields.append(QgsField(perimeterName, QVariant.Double))
elif QgsWkbTypes.geometryType(wkb_type) == QgsWkbTypes.LineGeometry:
lengthName = vector.createUniqueFieldName('length', fields)
fields.append(QgsField(lengthName, QVariant.Double))
else:
xName = vector.createUniqueFieldName('xcoord', fields)
fields.append(QgsField(xName, QVariant.Double))
yName = vector.createUniqueFieldName('ycoord', fields)
fields.append(QgsField(yName, QVariant.Double))
if QgsWkbTypes.hasZ(source.wkbType()):
self.export_z = True
zName = vector.createUniqueFieldName('zcoord', fields)
fields.append(QgsField(zName, QVariant.Double))
if QgsWkbTypes.hasM(source.wkbType()):
self.export_m = True
zName = vector.createUniqueFieldName('mvalue', fields)
fields.append(QgsField(zName, QVariant.Double))
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
fields, wkb_type, source.sourceCrs())
coordTransform = None
# Calculate with:
# 0 - layer CRS
# 1 - project CRS
# 2 - ellipsoidal
self.distance_area = QgsDistanceArea()
if method == 2:
self.distance_area.setSourceCrs(source.sourceCrs())
self.distance_area.setEllipsoid(context.project().ellipsoid())
elif method == 1:
coordTransform = QgsCoordinateTransform(source.sourceCrs(), context.project().crs())
features = source.getFeatures()
total = 100.0 / source.featureCount() if source.featureCount() else 0
for current, f in enumerate(features):
if feedback.isCanceled():
break
outFeat = f
attrs = f.attributes()
inGeom = f.geometry()
if inGeom:
if coordTransform is not None:
inGeom.transform(coordTransform)
if inGeom.type() == QgsWkbTypes.PointGeometry:
attrs.extend(self.point_attributes(inGeom))
elif inGeom.type() == QgsWkbTypes.PolygonGeometry:
attrs.extend(self.polygon_attributes(inGeom))
else:
attrs.extend(self.line_attributes(inGeom))
outFeat.setAttributes(attrs)
sink.addFeature(outFeat, QgsFeatureSink.FastInsert)
feedback.setProgress(int(current * total))
return {self.OUTPUT: dest_id}
def point_attributes(self, geometry):
pt = None
if not geometry.isMultipart():
pt = geometry.geometry()
else:
if geometry.numGeometries() > 0:
pt = geometry.geometryN(0)
attrs = []
if pt:
attrs.append(pt.x())
attrs.append(pt.y())
# add point z/m
if self.export_z:
attrs.append(pt.z())
if self.export_m:
attrs.append(pt.m())
return attrs
def line_attributes(self, geometry):
return [self.distance_area.measureLength(geometry)]
def polygon_attributes(self, geometry):
area = self.distance_area.measureArea(geometry)
perimeter = self.distance_area.measurePerimeter(geometry)
return [area, perimeter]