def convertUnsupportedFormats(self, progress): i = 0 progress.setText("Converting outputs") for out in self.outputs: if isinstance(out, OutputVector): if out.compatible is not None: layer = dataobjects.getObjectFromUri(out.compatible) if layer is None: # For the case of memory layer, if the # getCompatible method has been called continue provider = layer.dataProvider() writer = out.getVectorWriter(provider.fields(), provider.geometryType(), layer.crs()) features = vector.features(layer) for feature in features: writer.addFeature(feature) elif isinstance(out, OutputRaster): if out.compatible is not None: layer = dataobjects.getObjectFromUri(out.compatible) provider = layer.dataProvider() writer = QgsRasterFileWriter(out.value) format = self.getFormatShortNameFromFilename(out.value) writer.setOutputFormat(format) writer.writeRaster(layer.pipe(), layer.width(), layer.height(), layer.extent(), layer.crs()) elif isinstance(out, OutputTable): if out.compatible is not None: layer = dataobjects.getObjectFromUri(out.compatible) provider = layer.dataProvider() writer = out.getTableWriter(provider.fields()) features = vector.features(layer) for feature in features: writer.addRecord(feature) progress.setPercentage(100 * i / float(len(self.outputs)))
def processAlgorithm(self, progress): filename = self.getParameterValue(self.INPUT) layer = dataobjects.getObjectFromUri(filename) filename = self.getParameterValue(self.INTERSECT) selectLayer = dataobjects.getObjectFromUri(filename) index = vector.spatialindex(layer) output = self.getOutputFromName(self.OUTPUT) writer = output.getVectorWriter(layer.pendingFields(), layer.dataProvider().geometryType(), layer.crs()) geom = QgsGeometry() selectedSet = [] current = 0 features = vector.features(selectLayer) featureCount = len(features) total = 100.0 / float(len(features)) for current,f in enumerate(features): geom = QgsGeometry(f.geometry()) intersects = index.intersects(geom.boundingBox()) for i in intersects: request = QgsFeatureRequest().setFilterFid(i) feat = layer.getFeatures(request).next() tmpGeom = QgsGeometry(feat.geometry()) if geom.intersects(tmpGeom): selectedSet.append(feat.id()) progress.setPercentage(int(current * total)) for i, f in enumerate(vector.features(layer)): if f.id() in selectedSet: writer.addFeature(f) progress.setPercentage(100 * i / float(featureCount)) del writer
def processAlgorithm(self, progress): self.initAlgorithm(progress) self.setExpressionObj() nElement = 0 selectionA = vector.features(self.vlayerA) nFeat = len(selectionA) for self.inFeatA in selectionA: nElement += 1 progress.setPercentage(nElement / float(nFeat) * 100) geom = QgsGeometry(self.inFeatA.geometry()) selectionB = vector.features(self.vlayerB) for self.inFeatB in selectionB: geomTarget = QgsGeometry(self.inFeatB.geometry()) try: if geomTarget.contains(geom): try: self.setOutFeat(geom) except: ProcessingLog.addToLog(ProcessingLog.LOG_INFO, 'Feature geometry error: One or more output features ignored due to invalid geometry.') continue except: break #finalize self.finalizeAlgorithm()
def convertUnsupportedFormats(self, progress): i = 0 progress.setText(self.tr('Converting outputs')) for out in self.outputs: if isinstance(out, OutputVector): if out.compatible is not None: layer = dataobjects.getObjectFromUri(out.compatible) if layer is None: # For the case of memory layer, if the # getCompatible method has been called continue provider = layer.dataProvider() writer = out.getVectorWriter( provider.fields(), provider.geometryType(), layer.crs() ) features = vector.features(layer) for feature in features: writer.addFeature(feature) elif isinstance(out, OutputRaster): if out.compatible is not None: layer = dataobjects.getObjectFromUri(out.compatible) format = self.getFormatShortNameFromFilename(out.value) orgFile = out.compatible destFile = out.value crsid = layer.crs().authid() settings = QSettings() path = unicode(settings.value('/GdalTools/gdalPath', '')) envval = unicode(os.getenv('PATH')) if not path.lower() in envval.lower().split(os.pathsep): envval += '%s%s' % (os.pathsep, path) os.putenv('PATH', envval) command = 'gdal_translate -of %s -a_srs %s %s %s' % (format, crsid, orgFile, destFile) if os.name == 'nt': command = command.split(" ") else: command = [command] proc = subprocess.Popen( command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=False, ) proc.communicate() elif isinstance(out, OutputTable): if out.compatible is not None: layer = dataobjects.getObjectFromUri(out.compatible) provider = layer.dataProvider() writer = out.getTableWriter(provider.fields()) features = vector.features(layer) for feature in features: writer.addRecord(feature) progress.setPercentage(100 * i / float(len(self.outputs)))
def processAlgorithm(self, progress): filename = self.getParameterValue(self.INPUT) inputLayer = dataobjects.getObjectFromUri(filename) method = self.getParameterValue(self.METHOD) filename2 = self.getParameterValue(self.INTERSECT) selectLayer = dataobjects.getObjectFromUri(filename2) predicates = self.getParameterValue(self.PREDICATE) precision = self.getParameterValue(self.PRECISION) oldSelection = set(inputLayer.selectedFeatureIds()) inputLayer.removeSelection() index = vector.spatialindex(inputLayer) if 'disjoint' in predicates: disjoinSet = [] for feat in vector.features(inputLayer): disjoinSet.append(feat.id()) geom = QgsGeometry() selectedSet = [] features = vector.features(selectLayer) total = 100.0 / len(features) for current, f in enumerate(features): geom = vector.snapToPrecision(f.geometry(), precision) bbox = vector.bufferedBoundingBox(geom.boundingBox(), 0.51 * precision) intersects = index.intersects(bbox) request = QgsFeatureRequest().setFilterFids(intersects).setSubsetOfAttributes([]) for feat in inputLayer.getFeatures(request): tmpGeom = vector.snapToPrecision(feat.geometry(), precision) res = False for predicate in predicates: if predicate == 'disjoint': if tmpGeom.intersects(geom): try: disjoinSet.remove(feat.id()) except: pass # already removed else: res = getattr(tmpGeom, predicate)(geom) if res: selectedSet.append(feat.id()) break progress.setPercentage(int(current * total)) if 'disjoint' in predicates: selectedSet = selectedSet + disjoinSet if method == 1: selectedSet = list(oldSelection.union(selectedSet)) elif method == 2: selectedSet = list(oldSelection.difference(selectedSet)) inputLayer.selectByIds(selectedSet) self.setOutputValue(self.OUTPUT, filename)
def processAlgorithm(self, progress): hublayer = dataobjects.getObjectFromUri(self.getParameterValue(self.HUBNAME)) spokelayer = dataobjects.getObjectFromUri(self.getParameterValue(self.SPOKENAME)) hubattr = self.getParameterValue(self.HUBATTRIBUTE) spokeattr = self.getParameterValue(self.SPOKEATTRIBUTE) if hublayer == spokelayer: raise GeoAlgorithmExecutionException ("Same layer given for both hubs and spokes") hubindex = hublayer.dataProvider().fieldNameIndex(hubattr) spokeindex = spokelayer.dataProvider().fieldNameIndex(spokeattr) outfields = spokelayer.pendingFields() output = self.getOutputFromName(self.SAVENAME) out = output.getVectorWriter(outfields, QGis.WKBLineString, spokelayer.crs()) # Scan spoke points linecount = 0 spokepoints = vector.features(spokelayer) i = 0 for spokepoint in spokepoints: i += 1 spokex = spokepoint.geometry().boundingBox().center().x() spokey = spokepoint.geometry().boundingBox().center().y() spokeid = unicode(spokepoint.attributes()[spokeindex]) progress.setPercentage(float(i) / len(spokepoints) * 100) # Scan hub points to find first matching hub hubpoints = vector.features(hublayer) for hubpoint in hubpoints: hubid = unicode(hubpoint.attributes()[hubindex]) if hubid == spokeid: hubx = hubpoint.geometry().boundingBox().center().x() huby = hubpoint.geometry().boundingBox().center().y() # Write line to the output file outfeature = QgsFeature() outfeature.setAttributes(spokepoint.attributes()) polyline = [] polyline.append(QgsPoint(spokex, spokey)) polyline.append(QgsPoint(hubx, huby)) geometry = QgsGeometry() outfeature.setGeometry(geometry.fromPolyline(polyline)) out.addFeature(outfeature) linecount = linecount + 1 break del out if linecount <= 0: raise GeoAlgorithmExecutionException("No spoke/hub matches found to create lines")
def processAlgorithm(self, progress): filename = self.getParameterValue(self.INPUT) layer = dataobjects.getObjectFromUri(filename) filename = self.getParameterValue(self.INTERSECT) selectLayer = dataobjects.getObjectFromUri(filename) predicates = self.getParameterValue(self.PREDICATE) precision = self.getParameterValue(self.PRECISION) index = vector.spatialindex(layer) output = self.getOutputFromName(self.OUTPUT) writer = output.getVectorWriter(layer.fields(), layer.wkbType(), layer.crs()) if 'disjoint' in predicates: disjoinSet = [] for feat in vector.features(layer): disjoinSet.append(feat.id()) selectedSet = [] features = vector.features(selectLayer) total = 100.0 / len(features) for current, f in enumerate(features): geom = vector.snapToPrecision(f.geometry(), precision) bbox = vector.bufferedBoundingBox(geom.boundingBox(), 0.51 * precision) intersects = index.intersects(bbox) request = QgsFeatureRequest().setFilterFids(intersects).setSubsetOfAttributes([]) for feat in layer.getFeatures(request): tmpGeom = vector.snapToPrecision(feat.geometry(), precision) res = False for predicate in predicates: if predicate == 'disjoint': if tmpGeom.intersects(geom): try: disjoinSet.remove(feat.id()) except: pass # already removed else: res = getattr(tmpGeom, predicate)(geom) if res: selectedSet.append(feat.id()) break progress.setPercentage(int(current * total)) if 'disjoint' in predicates: selectedSet = selectedSet + disjoinSet features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): if f.id() in selectedSet: writer.addFeature(f) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) fieldName = self.getParameterValue(self.FIELD) geomType = self.singleToMultiGeom(layer.dataProvider().geometryType()) writer = self.getOutputFromName( self.OUTPUT).getVectorWriter(layer.pendingFields().toList(), geomType, layer.crs()) inFeat = QgsFeature() outFeat = QgsFeature() inGeom = QgsGeometry() outGeom = QgsGeometry() index = layer.fieldNameIndex(fieldName) unique = vector.getUniqueValues(layer, index) current = 0 features = vector.features(layer) total = 100.0 / float(len(features) * len(unique)) if not len(unique) == layer.featureCount(): for i in unique: multi_feature = [] first = True features = vector.features(layer) for inFeat in features: atMap = inFeat.attributes() idVar = atMap[index] if unicode(idVar).strip() == unicode(i).strip(): if first: attrs = atMap first = False inGeom = QgsGeometry(inFeat.geometry()) vType = inGeom.type() feature_list = self.extractAsMulti(inGeom) multi_feature.extend(feature_list) current += 1 progress.setPercentage(int(current * total)) outFeat.setAttributes(attrs) outGeom = QgsGeometry(self.convertGeometry(multi_feature, vType)) outFeat.setGeometry(outGeom) writer.addFeature(outFeat) del writer else: raise GeoAlgorithmExecutionException('Invalid unique ID field')
def processAlgorithm(self, progress): input = self.getParameterValue(self.INPUT_LAYER) input2 = self.getParameterValue(self.INPUT_LAYER_2) output = self.getOutputFromName(self.OUTPUT_LAYER) field = self.getParameterValue(self.TABLE_FIELD) field2 = self.getParameterValue(self.TABLE_FIELD_2) # Layer 1 layer = dataobjects.getObjectFromUri(input) provider = layer.dataProvider() joinField1Index = layer.fieldNameIndex(field) # Layer 2 layer2 = dataobjects.getObjectFromUri(input2) provider2 = layer2.dataProvider() joinField2Index = layer2.fieldNameIndex(field2) # Output outFields = [] outFields.extend(provider.fields()) outFields.extend(provider2.fields()) writer = output.getVectorWriter(outFields, provider.geometryType(), layer.crs()) inFeat = QgsFeature() inFeat2 = QgsFeature() outFeat = QgsFeature() # Create output vector layer with additional attribute features = vector.features(layer) for inFeat in features: inGeom = inFeat.geometry() attrs = inFeat.attributes() joinValue1 = attrs[joinField1Index] features2 = vector.features(layer2) for inFeat2 in features2: # Maybe it should cache this entries... attrs2 = inFeat2.attributes() joinValue2 = attrs2[joinField2Index] if joinValue1 == joinValue2: # Create the new feature outFeat.setGeometry(inGeom) attrs.extend(attrs2) break outFeat.setAttributes(attrs) writer.addFeature(outFeat) del writer
def processAlgorithm(self, progress): input = self.getParameterValue(self.INPUT_LAYER) input2 = self.getParameterValue(self.INPUT_LAYER_2) output = self.getOutputFromName(self.OUTPUT_LAYER) field = self.getParameterValue(self.TABLE_FIELD) field2 = self.getParameterValue(self.TABLE_FIELD_2) # Layer 1 layer = dataobjects.getObjectFromUri(input) provider = layer.dataProvider() joinField1Index = layer.fieldNameIndex(field) # Layer 2 layer2 = dataobjects.getObjectFromUri(input2) provider2 = layer2.dataProvider() joinField2Index = layer2.fieldNameIndex(field2) # Output outFields = vector.combineVectorFields(layer,layer2) writer = output.getVectorWriter(outFields, provider.geometryType(), layer.crs()) inFeat = QgsFeature() inFeat2 = QgsFeature() outFeat = QgsFeature() # Cache attributes of Layer 2 cache = {} features2 = vector.features(layer2) for inFeat2 in features2: attrs2 = inFeat2.attributes() joinValue2 = unicode(attrs2[joinField2Index]) # Put the attributes into the dict if the join key is not contained in the keys of the dict. # Note: This behavior is same as previous behavior of this function, # but different from the attribute cache function of QGIS core. if not joinValue2 in cache: cache[joinValue2] = attrs2 # Create output vector layer with additional attribute features = vector.features(layer) for inFeat in features: outFeat.setGeometry(inFeat.geometry()) attrs = inFeat.attributes() joinValue1 = unicode(attrs[joinField1Index]) attrs.extend(cache.get(joinValue1, [])) outFeat.setAttributes(attrs) writer.addFeature(outFeat) del writer
def processAlgorithm(self, progress): output = self.getOutputFromName(self.OUTPUT) vlayer = \ dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT)) vprovider = vlayer.dataProvider() fields = vprovider.fields() fields.append(QgsField('AUTO', QVariant.Int)) writer = output.getVectorWriter(fields, vprovider.geometryType(), vlayer.crs()) inFeat = QgsFeature() outFeat = QgsFeature() inGeom = QgsGeometry() nElement = 0 features = vector.features(vlayer) nFeat = len(features) for inFeat in features: progress.setPercentage(int(100 * nElement / nFeat)) nElement += 1 inGeom = inFeat.geometry() outFeat.setGeometry(inGeom) attrs = inFeat.attributes() attrs.append(nElement) outFeat.setAttributes(attrs) writer.addFeature(outFeat) del writer
def processAlgorithm(self, progress): fieldType = self.getParameterValue(self.FIELD_TYPE) fieldName = self.getParameterValue(self.FIELD_NAME) fieldLength = self.getParameterValue(self.FIELD_LENGTH) fieldPrecision = self.getParameterValue(self.FIELD_PRECISION) output = self.getOutputFromName(self.OUTPUT_LAYER) layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_LAYER)) fields = layer.fields() fields.append(QgsField(fieldName, self.TYPES[fieldType], '', fieldLength, fieldPrecision)) writer = output.getVectorWriter(fields, layer.wkbType(), layer.crs()) outFeat = QgsFeature() features = vector.features(layer) total = 100.0 / len(features) for current, feat in enumerate(features): progress.setPercentage(int(current * total)) geom = feat.geometry() outFeat.setGeometry(geom) atMap = feat.attributes() atMap.append(None) outFeat.setAttributes(atMap) writer.addFeature(outFeat) del writer
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_LAYER)) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter( layer.fields().toList(), QgsWkbTypes.Point, layer.crs()) features = vector.features(layer) total = 100.0 / len(features) for current, input_feature in enumerate(features): output_feature = input_feature input_geometry = input_feature.geometry() if input_geometry: output_geometry = input_geometry.pointOnSurface() if not output_geometry: raise GeoAlgorithmExecutionException( self.tr('Error calculating point on surface')) output_feature.setGeometry(output_geometry) writer.addFeature(output_feature) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): filename = self.getParameterValue(self.INPUT) layer = dataobjects.getObjectFromUri(filename) method = self.getParameterValue(self.METHOD) features = vector.features(layer) featureCount = len(features) value = int(self.getParameterValue(self.NUMBER)) if method == 0: if value > featureCount: raise GeoAlgorithmExecutionException( self.tr('Selected number is greater than feature count. ' 'Choose a lower value and try again.')) else: if value > 100: raise GeoAlgorithmExecutionException( self.tr("Percentage can't be greater than 100. Set a " "different value and try again.")) value = int(round(value / 100.0000, 4) * featureCount) selran = random.sample(xrange(featureCount), value) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.pendingFields().toList(), layer.wkbType(), layer.crs()) total = 100.0 / featureCount for i, feat in enumerate(features): if i in selran: writer.addFeature(feat) progress.setPercentage(int(i * total)) del writer
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) fieldName = self.getParameterValue(self.FIELD) directory = self.getOutputValue(self.OUTPUT) mkdir(directory) fieldIndex = layer.fieldNameIndex(fieldName) uniqueValues = vector.uniqueValues(layer, fieldIndex) baseName = os.path.join(directory, '{0}_{1}'.format(layer.name(), fieldName)) fields = layer.pendingFields() crs = layer.crs() geomType = layer.wkbType() total = 100.0 / len(uniqueValues) for current, i in enumerate(uniqueValues): fName = u'{0}_{1}.shp'.format(baseName, unicode(i).strip()) writer = vector.VectorWriter(fName, None, fields, geomType, crs) for f in vector.features(layer): if f[fieldName] == i: writer.addFeature(f) del writer progress.setPercentage(int(current * total))
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.fields().toList(), QgsWkbTypes.Polygon, layer.crs() ) outFeat = QgsFeature() features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): outGeomList = [] if f.geometry().isMultipart(): outGeomList = f.geometry().asMultiPolyline() else: outGeomList.append(f.geometry().asPolyline()) polyGeom = self.removeBadLines(outGeomList) if len(polyGeom) != 0: outFeat.setGeometry(QgsGeometry.fromPolygon(polyGeom)) attrs = f.attributes() outFeat.setAttributes(attrs) writer.addFeature(outFeat) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): layerA = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT_A)) layerB = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT_B)) fieldA = self.getParameterValue(self.FIELD_A) fieldB = self.getParameterValue(self.FIELD_B) idxA = layerA.fields().lookupField(fieldA) idxB = layerB.fields().lookupField(fieldB) fieldList = [layerA.fields()[idxA], layerB.fields()[idxB]] writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fieldList, QgsWkbTypes.Point, layerA.crs()) spatialIndex = vector.spatialindex(layerB) outFeat = QgsFeature() features = vector.features(layerA) total = 100.0 / len(features) hasIntersections = False for current, inFeatA in enumerate(features): inGeom = inFeatA.geometry() hasIntersections = False lines = spatialIndex.intersects(inGeom.boundingBox()) engine = None if len(lines) > 0: hasIntersections = True # use prepared geometries for faster intersection tests engine = QgsGeometry.createGeometryEngine(inGeom.geometry()) engine.prepareGeometry() if hasIntersections: request = QgsFeatureRequest().setFilterFids(lines) for inFeatB in layerB.getFeatures(request): tmpGeom = inFeatB.geometry() points = [] attrsA = inFeatA.attributes() attrsB = inFeatB.attributes() if engine.intersects(tmpGeom.geometry()): tempGeom = inGeom.intersection(tmpGeom) if tempGeom.type() == QgsWkbTypes.PointGeometry: if tempGeom.isMultipart(): points = tempGeom.asMultiPoint() else: points.append(tempGeom.asPoint()) for j in points: outFeat.setGeometry(tempGeom.fromPoint(j)) outFeat.setAttributes([attrsA[idxA], attrsB[idxB]]) writer.addFeature(outFeat) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT)) crsId = self.getParameterValue(self.TARGET_CRS) targetCrs = QgsCoordinateReferenceSystem() targetCrs.createFromUserInput(crsId) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.fields().toList(), layer.wkbType(), targetCrs) layerCrs = layer.crs() crsTransform = QgsCoordinateTransform(layerCrs, targetCrs) outFeat = QgsFeature() features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): geom = f.geometry() geom.transform(crsTransform) outFeat.setGeometry(geom) outFeat.setAttributes(f.attributes()) writer.addFeature(outFeat) progress.setPercentage(int(current * total)) del writer self.crs = targetCrs
def __init__(self, name='', description='', options=[], default=None, isSource=False, optional=False): Parameter.__init__(self, name, description, default, optional) isSource = parseBool(isSource) self.options = options if isSource: self.options = [] layer = QgsVectorLayer(options[0], "layer", "ogr") if layer.isValid(): try: index = resolveFieldIndex(layer, options[1]) feats = features(layer) for feature in feats: self.options.append(unicode(feature.attributes()[index])) except ValueError: pass elif isinstance(self.options, basestring): self.options = self.options.split(";") if default is not None: try: self.default = int(default) except: self.default = 0 self.value = self.default
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_LAYER)) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter( layer.fields().toList(), QgsWkbTypes.LineString, layer.crs()) distance = self.getParameterValue(self.DISTANCE) segments = int(self.getParameterValue(self.SEGMENTS)) join_style = self.getParameterValue(self.JOIN_STYLE) + 1 miter_limit = self.getParameterValue(self.MITRE_LIMIT) features = vector.features(layer) total = 100.0 / len(features) for current, input_feature in enumerate(features): output_feature = input_feature input_geometry = input_feature.geometry() if input_geometry: output_geometry = input_geometry.offsetCurve(distance, segments, join_style, miter_limit) if not output_geometry: raise GeoAlgorithmExecutionException( self.tr('Error calculating line offset')) output_feature.setGeometry(output_geometry) writer.addFeature(output_feature) progress.setPercentage(int(current * total)) del writer
def regularMatrix(self, inLayer, inField, targetLayer, targetField, nPoints, progress): index = vector.spatialindex(targetLayer) inIdx = inLayer.fields().lookupField(inField) distArea = QgsDistanceArea() first = True features = vector.features(inLayer) total = 100.0 / len(features) for current, inFeat in enumerate(features): inGeom = inFeat.geometry() inID = str(inFeat.attributes()[inIdx]) featList = index.nearestNeighbor(inGeom.asPoint(), nPoints) if first: first = False data = ['ID'] for i in range(len(featList)): data.append('DIST_{0}'.format(i + 1)) self.writer.addRecord(data) data = [inID] for i in featList: request = QgsFeatureRequest().setFilterFid(i) outFeat = next(targetLayer.getFeatures(request)) outGeom = outFeat.geometry() dist = distArea.measureLine(inGeom.asPoint(), outGeom.asPoint()) data.append(str(float(dist))) self.writer.addRecord(data) progress.setPercentage(int(current * total))
def processAlgorithm(self, progress): inLayer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_LAYER)) inField = self.getParameterValue(self.INPUT_FIELD) targetLayer = dataobjects.getObjectFromUri( self.getParameterValue(self.TARGET_LAYER)) targetField = self.getParameterValue(self.TARGET_FIELD) matType = self.getParameterValue(self.MATRIX_TYPE) nPoints = self.getParameterValue(self.NEAREST_POINTS) outputFile = self.getOutputFromName(self.DISTANCE_MATRIX) if nPoints < 1: nPoints = len(vector.features(targetLayer)) self.writer = outputFile.getTableWriter([]) if matType == 0: # Linear distance matrix self.linearMatrix(inLayer, inField, targetLayer, targetField, matType, nPoints, progress) elif matType == 1: # Standard distance matrix self.regularMatrix(inLayer, inField, targetLayer, targetField, nPoints, progress) elif matType == 2: # Summary distance matrix self.linearMatrix(inLayer, inField, targetLayer, targetField, matType, nPoints, progress)
def processAlgorithm(self, progress): fieldname = self.getParameterValue(self.FIELD) output = self.getOutputFromName(self.OUTPUT) vlayer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) vprovider = vlayer.dataProvider() fieldindex = vlayer.fieldNameIndex(fieldname) fields = vprovider.fields() fields.append(QgsField('NUM_FIELD', QVariant.Int)) writer = output.getVectorWriter(fields, vprovider.geometryType(), vlayer.crs()) outFeat = QgsFeature() classes = {} features = vector.features(vlayer) total = 100.0 / len(features) for current, feature in enumerate(features): progress.setPercentage(int(current * total)) inGeom = feature.geometry() outFeat.setGeometry(inGeom) atMap = feature.attributes() clazz = atMap[fieldindex] if clazz not in classes: classes[clazz] = len(classes.keys()) atMap.append(classes[clazz]) outFeat.setAttributes(atMap) writer.addFeature(outFeat) del writer
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT)) fieldName = self.getParameterValue(self.FIELD) idx = layer.fields().lookupField(fieldName) fields = layer.fields() fields[idx] = QgsField(fieldName, QVariant.Double, '', 24, 15) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, layer.wkbType(), layer.crs()) features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): value = f[idx] try: if '%' in value: f[idx] = float(value.replace('%', '')) / 100.0 else: f[idx] = float(value) except: f[idx] = None writer.addFeature(f) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) idx = layer.fieldNameIndex(self.getParameterValue(self.COLUMN)) fields = layer.pendingFields() fields.remove(idx) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, layer.wkbType(), layer.crs()) features = vector.features(layer) count = len(features) total = 100.0 / float(count) feat = QgsFeature() for count, f in enumerate(features): feat.setGeometry(f.geometry()) attributes = f.attributes() del attributes[idx] feat.setAttributes(attributes) writer.addFeature(feat) progress.setPercentage(int(count * total)) del writer
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_LAYER)) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter( layer.fields(), QgsWkbTypes.Point, layer.crs()) outFeat = QgsFeature() features = vector.features(layer) total = 100.0 / len(features) for current, feat in enumerate(features): inGeom = feat.geometry() attrs = feat.attributes() if inGeom.isEmpty(): outGeom = QgsGeometry(None) else: outGeom = QgsGeometry(inGeom.centroid()) if not outGeom: raise GeoAlgorithmExecutionException( self.tr('Error calculating centroid')) outFeat.setGeometry(outGeom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT)) fields_to_delete = self.getParameterValue(self.COLUMNS).split(';') fields = layer.fields() field_indices = [] # loop through twice - first we need to build up a list of original attribute indices for f in fields_to_delete: index = fields.lookupField(f) field_indices.append(index) # important - make sure we remove from the end so we aren't changing used indices as we go field_indices.sort(reverse=True) # this second time we make a cleaned version of the fields for index in field_indices: fields.remove(index) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, layer.wkbType(), layer.crs()) features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): attributes = f.attributes() for index in field_indices: del attributes[index] f.setAttributes(attributes) writer.addFeature(f) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): """Here is where the processing itself takes place.""" # The first thing to do is retrieve the values of the parameters # entered by the user inputFilename = self.getParameterValue(self.INPUT_LAYER) output = self.getOutputValue(self.OUTPUT_LAYER) # Input layers vales are always a string with its location. # That string can be converted into a QGIS object (a # QgsVectorLayer in this case) using the # processing.getObjectFromUri() method. vectorLayer = dataobjects.getObjectFromUri(inputFilename) # And now we can process # First we create the output layer. The output value entered by # the user is a string containing a filename, so we can use it # directly settings = QSettings() systemEncoding = settings.value('/UI/encoding', 'System') writer = QgsVectorFileWriter(output, systemEncoding, vectorLayer.fields(), vectorLayer.wkbType(), vectorLayer.crs()) # Now we take the features from input layer and add them to the # output. Method features() returns an iterator, considering the # selection that might exist in layer and the configuration that # indicates should algorithm use only selected features or all # of them features = vector.features(vectorLayer) for f in features: writer.addFeature(f)
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT)) interval = self.getParameterValue(self.INTERVAL) isPolygon = layer.geometryType() == QgsWkbTypes.PolygonGeometry writer = self.getOutputFromName( self.OUTPUT).getVectorWriter(layer.fields().toList(), layer.wkbType(), layer.crs()) features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): featGeometry = f.geometry() attrs = f.attributes() newGeometry = self.densifyGeometry(featGeometry, interval, isPolygon) feature = QgsFeature() feature.setGeometry(newGeometry) feature.setAttributes(attrs) writer.addFeature(feature) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) writer = self.getOutputFromName( self.OUTPUT).getVectorWriter(layer.pendingFields().toList(), QGis.WKBPoint, layer.crs()) outFeat = QgsFeature() inGeom = QgsGeometry() outGeom = QgsGeometry() current = 0 features = vector.features(layer) total = 100.0 / float(len(features)) for f in features: inGeom = f.geometry() attrs = f.attributes() points = vector.extractPoints(inGeom) outFeat.setAttributes(attrs) for i in points: outFeat.setGeometry(outGeom.fromPoint(i)) writer.addFeature(outFeat) current += 1 progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString(self.getParameterValue(self.INPUT_LAYER)) fieldName = self.getParameterValue(self.FIELD_NAME) fieldType = self.TYPES[self.getParameterValue(self.FIELD_TYPE)] width = self.getParameterValue(self.FIELD_LENGTH) precision = self.getParameterValue(self.FIELD_PRECISION) newField = self.getParameterValue(self.NEW_FIELD) formula = self.getParameterValue(self.FORMULA) output = self.getOutputFromName(self.OUTPUT_LAYER) fields = layer.fields() if newField: fields.append(QgsField(fieldName, fieldType, '', width, precision)) writer = output.getVectorWriter(fields, layer.wkbType(), layer.crs()) exp = QgsExpression(formula) da = QgsDistanceArea() da.setSourceCrs(layer.crs()) da.setEllipsoidalMode(True) da.setEllipsoid(QgsProject.instance().ellipsoid()) exp.setGeomCalculator(da) exp.setDistanceUnits(QgsProject.instance().distanceUnits()) exp.setAreaUnits(QgsProject.instance().areaUnits()) exp_context = QgsExpressionContext(QgsExpressionContextUtils.globalProjectLayerScopes(layer)) if not exp.prepare(exp_context): raise GeoAlgorithmExecutionException( self.tr('Evaluation error: {0}').format(exp.evalErrorString())) outFeature = QgsFeature() outFeature.initAttributes(len(fields)) outFeature.setFields(fields) error = '' calculationSuccess = True features = vector.features(layer) total = 100.0 / len(features) rownum = 1 for current, f in enumerate(features): rownum = current + 1 exp_context.setFeature(f) exp_context.lastScope().setVariable("row_number", rownum) value = exp.evaluate(exp_context) if exp.hasEvalError(): calculationSuccess = False error = exp.evalErrorString() break else: outFeature.setGeometry(f.geometry()) for fld in f.fields(): outFeature[fld.name()] = f[fld.name()] outFeature[fieldName] = value writer.addFeature(outFeature) feedback.setProgress(int(current * total)) del writer if not calculationSuccess: raise GeoAlgorithmExecutionException( self.tr('An error occurred while evaluating the calculation ' 'string:\n{0}').format(error))
def processAlgorithm(self, progress): layerPoints = dataobjects.getObjectFromUri( self.getParameterValue(self.POINTS)) layerHubs = dataobjects.getObjectFromUri( self.getParameterValue(self.HUBS)) fieldName = self.getParameterValue(self.FIELD) addLines = self.getParameterValue(self.GEOMETRY) units = self.UNITS[self.getParameterValue(self.UNIT)] if layerPoints.source() == layerHubs.source(): raise GeoAlgorithmExecutionException( self.tr('Same layer given for both hubs and spokes')) fields = layerPoints.fields() fields.append(QgsField('HubName', QVariant.String)) fields.append(QgsField('HubDist', QVariant.Double)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, QgsWkbTypes.LineString, layerPoints.crs()) index = vector.spatialindex(layerHubs) distance = QgsDistanceArea() distance.setSourceCrs(layerPoints.crs().srsid()) distance.setEllipsoidalMode(True) # Scan source points, find nearest hub, and write to output file features = vector.features(layerPoints) total = 100.0 / len(features) for current, f in enumerate(features): src = f.geometry().boundingBox().center() neighbors = index.nearestNeighbor(src, 1) ft = next( layerHubs.getFeatures(QgsFeatureRequest().setFilterFid( neighbors[0]).setSubsetOfAttributes([fieldName], layerHubs.fields()))) closest = ft.geometry().boundingBox().center() hubDist = distance.measureLine(src, closest) attributes = f.attributes() attributes.append(ft[fieldName]) if units == 'Feet': attributes.append(hubDist * 3.2808399) elif units == 'Miles': attributes.append(hubDist * 0.000621371192) elif units == 'Kilometers': attributes.append(hubDist / 1000.0) elif units != 'Meters': attributes.append( sqrt( pow(src.x() - closest.x(), 2.0) + pow(src.y() - closest.y(), 2.0))) else: attributes.append(hubDist) feat = QgsFeature() feat.setAttributes(attributes) feat.setGeometry(QgsGeometry.fromPolyline([src, closest])) writer.addFeature(feat) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_LAYER)) fieldName = self.getParameterValue(self.FIELD_NAME) outputFile = self.getOutputValue(self.OUTPUT_HTML_FILE) index = layer.fieldNameIndex(fieldName) sumValue = 0 minValue = 0 maxValue = 0 meanValue = 0 countEmpty = 0 countFilled = 0 isFirst = True values = [] features = vector.features(layer) count = len(features) total = 100.0 / float(count) current = 0 for ft in features: length = float(len(ft.attributes()[index])) if isFirst: minValue = length maxValue = length isFirst = False else: if length < minValue: minValue = length if length > maxValue: maxValue = length if length != 0.00: countFilled += 1 else: countEmpty += 1 values.append(length) sumValue += length current += 1 progress.setPercentage(int(current * total)) n = float(len(values)) if n > 0: meanValue = sumValue / n uniqueValues = vector.getUniqueValuesCount(layer, index) data = [] data.append('Minimum length: ' + unicode(minValue)) data.append('Maximum length: ' + unicode(maxValue)) data.append('Mean length: ' + unicode(meanValue)) data.append('Filled: ' + unicode(countFilled)) data.append('Empty: ' + unicode(countEmpty)) data.append('Count: ' + unicode(count)) data.append('Unique: ' + unicode(uniqueValues)) self.createHTML(outputFile, data) self.setOutputValue(self.MIN_LEN, minValue) self.setOutputValue(self.MAX_LEN, maxValue) self.setOutputValue(self.MEAN_LEN, meanValue) self.setOutputValue(self.FILLED, countFilled) self.setOutputValue(self.EMPTY, countEmpty) self.setOutputValue(self.COUNT, count) self.setOutputValue(self.UNIQUE, uniqueValues)
def processAlgorithm(self, feedback): target = dataobjects.getObjectFromUri( self.getParameterValue(self.TARGET)) join = dataobjects.getObjectFromUri(self.getParameterValue(self.JOIN)) predicates = self.getParameterValue(self.PREDICATE) precision = self.getParameterValue(self.PRECISION) summary = self.getParameterValue(self.SUMMARY) == 1 keep = self.getParameterValue(self.KEEP) == 1 sumList = self.getParameterValue(self.STATS).lower().split(',') targetFields = target.fields() joinFields = join.fields() fieldList = QgsFields() if not summary: joinFields = vector.testForUniqueness(targetFields, joinFields) seq = list(range(len(targetFields) + len(joinFields))) targetFields.extend(joinFields) targetFields = dict(list(zip(seq, targetFields))) else: numFields = {} for j in range(len(joinFields)): if joinFields[j].type() in [ QVariant.Int, QVariant.Double, QVariant.LongLong, QVariant.UInt, QVariant.ULongLong ]: numFields[j] = [] for i in sumList: field = QgsField(i + str(joinFields[j].name()), QVariant.Double, '', 24, 16) fieldList.append(field) field = QgsField('count', QVariant.Double, '', 24, 16) fieldList.append(field) joinFields = vector.testForUniqueness(targetFields, fieldList) targetFields.extend(fieldList) seq = list(range(len(targetFields))) targetFields = dict(list(zip(seq, targetFields))) fields = QgsFields() for f in list(targetFields.values()): fields.append(f) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, target.wkbType(), target.crs()) outFeat = QgsFeature() inFeatB = QgsFeature() inGeom = QgsGeometry() index = vector.spatialindex(join) mapP2 = dict() features = vector.features(join) for f in features: mapP2[f.id()] = QgsFeature(f) features = vector.features(target) total = 100.0 / len(features) for c, f in enumerate(features): atMap1 = f.attributes() outFeat.setGeometry(f.geometry()) inGeom = vector.snapToPrecision(f.geometry(), precision) none = True joinList = [] if inGeom.type() == QgsWkbTypes.PointGeometry: bbox = inGeom.buffer(10, 2).boundingBox() else: bbox = inGeom.boundingBox() bufferedBox = vector.bufferedBoundingBox(bbox, 0.51 * precision) joinList = index.intersects(bufferedBox) if len(joinList) > 0: count = 0 for i in joinList: inFeatB = mapP2[i] inGeomB = vector.snapToPrecision(inFeatB.geometry(), precision) res = False for predicate in predicates: res = getattr(inGeom, predicate)(inGeomB) if res: break if res: count = count + 1 none = False atMap2 = inFeatB.attributes() if not summary: atMap = atMap1 atMap2 = atMap2 atMap.extend(atMap2) atMap = dict(list(zip(seq, atMap))) break else: for j in list(numFields.keys()): numFields[j].append(atMap2[j]) if summary and not none: atMap = atMap1 for j in list(numFields.keys()): for k in sumList: if k == 'sum': atMap.append( sum(self._filterNull(numFields[j]))) elif k == 'mean': try: nn_count = sum(1 for _ in self._filterNull( numFields[j])) atMap.append( sum(self._filterNull(numFields[j])) / nn_count) except ZeroDivisionError: atMap.append(NULL) elif k == 'min': try: atMap.append( min(self._filterNull(numFields[j]))) except ValueError: atMap.append(NULL) elif k == 'median': atMap.append(self._median(numFields[j])) else: try: atMap.append( max(self._filterNull(numFields[j]))) except ValueError: atMap.append(NULL) numFields[j] = [] atMap.append(count) atMap = dict(list(zip(seq, atMap))) if none: outFeat.setAttributes(atMap1) else: outFeat.setAttributes(list(atMap.values())) if keep: writer.addFeature(outFeat) else: if not none: writer.addFeature(outFeat) feedback.setProgress(int(c * total)) del writer
def processAlgorithm(self, feedback): useField = not self.getParameterValue(Dissolve.DISSOLVE_ALL) field_names = self.getParameterValue(Dissolve.FIELD) vlayerA = dataobjects.getObjectFromUri( self.getParameterValue(Dissolve.INPUT)) writer = self.getOutputFromName(Dissolve.OUTPUT).getVectorWriter( vlayerA.fields().toList(), vlayerA.wkbType(), vlayerA.crs()) outFeat = QgsFeature() features = vector.features(vlayerA) total = 100.0 / len(features) if not useField: first = True # we dissolve geometries in blocks using unaryUnion geom_queue = [] for current, inFeat in enumerate(features): feedback.setProgress(int(current * total)) if first: outFeat.setAttributes(inFeat.attributes()) first = False tmpInGeom = inFeat.geometry() if tmpInGeom.isNull() or tmpInGeom.isEmpty(): continue errors = tmpInGeom.validateGeometry() if len(errors) != 0: for error in errors: ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, self.tr('ValidateGeometry()' 'error: One or more ' 'input features have ' 'invalid geometry: ') + error.what()) continue geom_queue.append(tmpInGeom) if len(geom_queue) > 10000: # queue too long, combine it try: temp_output_geometry = QgsGeometry.unaryUnion( geom_queue) geom_queue = [temp_output_geometry] except: raise GeoAlgorithmExecutionException( self.tr('Geometry exception while dissolving')) try: outFeat.setGeometry(QgsGeometry.unaryUnion(geom_queue)) except: raise GeoAlgorithmExecutionException( self.tr('Geometry exception while dissolving')) writer.addFeature(outFeat) else: field_indexes = [ vlayerA.fields().lookupField(f) for f in field_names.split(';') ] attribute_dict = {} geometry_dict = defaultdict(lambda: []) for inFeat in features: attrs = inFeat.attributes() index_attrs = tuple([attrs[i] for i in field_indexes]) tmpInGeom = QgsGeometry(inFeat.geometry()) if tmpInGeom and tmpInGeom.isEmpty(): continue errors = tmpInGeom.validateGeometry() if len(errors) != 0: for error in errors: ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, self.tr('ValidateGeometry() ' 'error: One or more input' 'features have invalid ' 'geometry: ') + error.what()) if not index_attrs in attribute_dict: # keep attributes of first feature attribute_dict[index_attrs] = attrs geometry_dict[index_attrs].append(tmpInGeom) nFeat = len(attribute_dict) nElement = 0 for key, value in list(geometry_dict.items()): outFeat = QgsFeature() nElement += 1 feedback.setProgress(int(nElement * 100 / nFeat)) try: tmpOutGeom = QgsGeometry.unaryUnion(value) except: raise GeoAlgorithmExecutionException( self.tr('Geometry exception while dissolving')) outFeat.setGeometry(tmpOutGeom) outFeat.setAttributes(attribute_dict[key]) writer.addFeature(outFeat) del writer
def doCheck(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_LAYER)) settings = QSettings() method = int(settings.value(settings_method_key, 1)) valid_ouput = self.getOutputFromName(self.VALID_OUTPUT) valid_fields = layer.fields() valid_writer = valid_ouput.getVectorWriter(valid_fields, layer.wkbType(), layer.crs()) valid_count = 0 invalid_ouput = self.getOutputFromName(self.INVALID_OUTPUT) invalid_fields = layer.fields().toList() + [ QgsField(name='_errors', type=QVariant.String, len=255) ] invalid_writer = invalid_ouput.getVectorWriter(invalid_fields, layer.wkbType(), layer.crs()) invalid_count = 0 error_ouput = self.getOutputFromName(self.ERROR_OUTPUT) error_fields = [ QgsField(name='message', type=QVariant.String, len=255) ] error_writer = error_ouput.getVectorWriter(error_fields, QgsWkbTypes.Point, layer.crs()) error_count = 0 features = vector.features(layer) total = 100.0 / len(features) for current, inFeat in enumerate(features): geom = inFeat.geometry() attrs = inFeat.attributes() valid = True if not geom.isEmpty() and not geom.isGeosEmpty(): errors = list(geom.validateGeometry()) if errors: # QGIS method return a summary at the end if method == 1: errors.pop() valid = False reasons = [] for error in errors: errFeat = QgsFeature() error_geom = QgsGeometry.fromPoint(error.where()) errFeat.setGeometry(error_geom) errFeat.setAttributes([error.what()]) error_writer.addFeature(errFeat) error_count += 1 reasons.append(error.what()) reason = "\n".join(reasons) if len(reason) > 255: reason = reason[:252] + '...' attrs.append(reason) outFeat = QgsFeature() outFeat.setGeometry(geom) outFeat.setAttributes(attrs) if valid: valid_writer.addFeature(outFeat) valid_count += 1 else: invalid_writer.addFeature(outFeat) invalid_count += 1 progress.setPercentage(int(current * total)) del valid_writer del invalid_writer del error_writer if valid_count == 0: valid_ouput.open = False if invalid_count == 0: invalid_ouput.open = False if error_count == 0: error_ouput.open = False
def testFeatures(self): ProcessingConfig.initialize() test_data = points() test_layer = QgsVectorLayer(test_data, 'test', 'ogr') # disable check for geometry validity prevInvalidGeoms = ProcessingConfig.getSetting( ProcessingConfig.FILTER_INVALID_GEOMETRIES) ProcessingConfig.setSettingValue( ProcessingConfig.FILTER_INVALID_GEOMETRIES, 0) # test with all features features = vector.features(test_layer) self.assertEqual(len(features), 9) self.assertEqual(set([f.id() for f in features]), set([0, 1, 2, 3, 4, 5, 6, 7, 8])) # test with selected features previous_value = ProcessingConfig.getSetting( ProcessingConfig.USE_SELECTED) ProcessingConfig.setSettingValue(ProcessingConfig.USE_SELECTED, True) test_layer.selectByIds([2, 4, 6]) features = vector.features(test_layer) self.assertEqual(len(features), 3) self.assertEqual(set([f.id() for f in features]), set([2, 4, 6])) # selection, but not using selected features ProcessingConfig.setSettingValue(ProcessingConfig.USE_SELECTED, False) test_layer.selectByIds([2, 4, 6]) features = vector.features(test_layer) self.assertEqual(len(features), 9) self.assertEqual(set([f.id() for f in features]), set([0, 1, 2, 3, 4, 5, 6, 7, 8])) # using selected features, but no selection ProcessingConfig.setSettingValue(ProcessingConfig.USE_SELECTED, True) test_layer.removeSelection() features = vector.features(test_layer) self.assertEqual(len(features), 9) self.assertEqual(set([f.id() for f in features]), set([0, 1, 2, 3, 4, 5, 6, 7, 8])) # test that feature request is honored ProcessingConfig.setSettingValue(ProcessingConfig.USE_SELECTED, False) features = vector.features( test_layer, QgsFeatureRequest().setFilterFids([1, 3, 5])) self.assertEqual(set([f.id() for f in features]), set([1, 3, 5])) # test that feature request is honored when using selections ProcessingConfig.setSettingValue(ProcessingConfig.USE_SELECTED, True) test_layer.selectByIds([2, 4, 6]) features = vector.features( test_layer, QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry)) self.assertTrue(all([not f.hasGeometry() for f in features])) features = vector.features( test_layer, QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry)) self.assertEqual(set([f.id() for f in features]), set([2, 4, 6])) ProcessingConfig.setSettingValue(ProcessingConfig.USE_SELECTED, previous_value) # test exception is raised when filtering invalid geoms #ProcessingConfig.setSettingValue(ProcessingConfig.FILTER_INVALID_GEOMETRIES, 2) #test_layer_invalid_geoms = QgsVectorLayer(invalid_geometries(), 'test', 'ogr') #with self.assertRaises(GeoAlgorithmExecutionException): # features = vector.features(test_layer_invalid_geoms) # feats = [f for f in features] ProcessingConfig.setSettingValue( ProcessingConfig.FILTER_INVALID_GEOMETRIES, prevInvalidGeoms)
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_LAYER)) fieldName = self.getParameterValue(self.FIELD_NAME) outputFile = self.getOutputValue(self.OUTPUT_HTML_FILE) index = layer.fieldNameIndex(fieldName) cvValue = 0 minValue = 0 maxValue = 0 sumValue = 0 meanValue = 0 medianValue = 0 stdDevValue = 0 isFirst = True values = [] features = vector.features(layer) count = len(features) total = 100.0 / float(count) current = 0 for ft in features: if ft.attributes()[index]: value = float(ft.attributes()[index]) if isFirst: minValue = value maxValue = value isFirst = False else: if value < minValue: minValue = value if value > maxValue: maxValue = value values.append(value) sumValue += value current += 1 progress.setPercentage(int(current * total)) # Calculate additional values rValue = maxValue - minValue uniqueValue = vector.getUniqueValuesCount(layer, index) if count > 0: meanValue = sumValue / count if meanValue != 0.00: for v in values: stdDevValue += (v - meanValue) * (v - meanValue) stdDevValue = math.sqrt(stdDevValue / count) cvValue = stdDevValue / meanValue if count > 1: tmp = values tmp.sort() # Calculate median if count % 2 == 0: medianValue = 0.5 * (tmp[(count - 1) / 2] + tmp[count / 2]) else: medianValue = tmp[(count + 1) / 2 - 1] data = [] data.append('Count: ' + unicode(count)) data.append('Unique values: ' + unicode(uniqueValue)) data.append('Minimum value: ' + unicode(minValue)) data.append('Maximum value: ' + unicode(maxValue)) data.append('Range: ' + unicode(rValue)) data.append('Sum: ' + unicode(sumValue)) data.append('Mean value: ' + unicode(meanValue)) data.append('Median value: ' + unicode(medianValue)) data.append('Standard deviation: ' + unicode(stdDevValue)) data.append('Coefficient of Variation: ' + unicode(cvValue)) self.createHTML(outputFile, data) self.setOutputValue(self.COUNT, count) self.setOutputValue(self.UNIQUE, uniqueValue) self.setOutputValue(self.MIN, minValue) self.setOutputValue(self.MAX, maxValue) self.setOutputValue(self.RANGE, rValue) self.setOutputValue(self.SUM, sumValue) self.setOutputValue(self.MEAN, meanValue) self.setOutputValue(self.MEDIAN, medianValue) self.setOutputValue(self.STD_DEV, stdDevValue) self.setOutputValue(self.CV, cvValue)
def processAlgorithm(self, feedback): radius = self.getParameterValue(self.DISTANCE) horizontal = self.getParameterValue(self.HORIZONTAL) output = self.getOutputFromName(self.OUTPUT_LAYER) layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_LAYER)) writer = output.getVectorWriter(layer.fields(), layer.wkbType(), layer.crs()) features = vector.features(layer) total = 100.0 / len(features) duplicates = dict() for current, f in enumerate(features): wkt = f.geometry().exportToWkt() if wkt not in duplicates: duplicates[wkt] = [f.id()] else: duplicates[wkt].extend([f.id()]) feedback.setProgress(int(current * total)) current = 0 total = 100.0 / len(duplicates) feedback.setProgress(0) fullPerimeter = 2 * math.pi for (geom, fids) in list(duplicates.items()): count = len(fids) if count == 1: f = next( layer.getFeatures(QgsFeatureRequest().setFilterFid( fids[0]))) writer.addFeature(f) else: angleStep = fullPerimeter / count if count == 2 and horizontal: currentAngle = math.pi / 2 else: currentAngle = 0 old_point = QgsGeometry.fromWkt(geom).asPoint() request = QgsFeatureRequest().setFilterFids(fids).setFlags( QgsFeatureRequest.NoGeometry) for f in layer.getFeatures(request): sinusCurrentAngle = math.sin(currentAngle) cosinusCurrentAngle = math.cos(currentAngle) dx = radius * sinusCurrentAngle dy = radius * cosinusCurrentAngle new_point = QgsPoint(old_point.x() + dx, old_point.y() + dy) out_feature = QgsFeature() out_feature.setGeometry(QgsGeometry.fromPoint(new_point)) out_feature.setAttributes(f.attributes()) writer.addFeature(out_feature) currentAngle += angleStep current += 1 feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, feedback): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) method = self.getParameterValue(self.METHOD) geometryType = layer.geometryType() fields = layer.fields() export_z = False export_m = False if geometryType == 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 geometryType == 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(layer.wkbType()): export_z = True zName = vector.createUniqueFieldName('zcoord', fields) fields.append(QgsField(zName, QVariant.Double)) if QgsWkbTypes.hasM(layer.wkbType()): export_m = True zName = vector.createUniqueFieldName('mvalue', fields) fields.append(QgsField(zName, QVariant.Double)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields.toList(), layer.wkbType(), layer.crs()) ellips = None crs = None coordTransform = None # Calculate with: # 0 - layer CRS # 1 - project CRS # 2 - ellipsoidal if method == 2: ellips = QgsProject.instance().readEntry('Measure', '/Ellipsoid', 'NONE')[0] crs = layer.crs().srsid() elif method == 1: mapCRS = iface.mapCanvas().mapSettings().destinationCrs() layCRS = layer.crs() coordTransform = QgsCoordinateTransform(layCRS, mapCRS) outFeat = QgsFeature() outFeat.initAttributes(len(fields)) outFeat.setFields(fields) features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): inGeom = f.geometry() if method == 1: inGeom.transform(coordTransform) (attr1, attr2) = vector.simpleMeasure(inGeom, method, ellips, crs) outFeat.setGeometry(inGeom) attrs = f.attributes() attrs.append(attr1) if attr2 is not None: attrs.append(attr2) # add point z/m if export_z: attrs.append(inGeom.geometry().z()) if export_m: attrs.append(inGeom.geometry().m()) outFeat.setAttributes(attrs) writer.addFeature(outFeat) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, feedback): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_VECTOR)) rasterPath = str(self.getParameterValue(self.INPUT_RASTER)) rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly) geoTransform = rasterDS.GetGeoTransform() rasterDS = None fields = QgsFields() fields.append(QgsField('id', QVariant.Int, '', 10, 0)) fields.append(QgsField('line_id', QVariant.Int, '', 10, 0)) fields.append(QgsField('point_id', QVariant.Int, '', 10, 0)) writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter( fields.toList(), QgsWkbTypes.Point, layer.crs()) outFeature = QgsFeature() outFeature.setFields(fields) self.fid = 0 self.lineId = 0 self.pointId = 0 features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): geom = f.geometry() if geom.isMultipart(): lines = geom.asMultiPolyline() for line in lines: for i in range(len(line) - 1): p1 = line[i] p2 = line[i + 1] (x1, y1) = raster.mapToPixel(p1.x(), p1.y(), geoTransform) (x2, y2) = raster.mapToPixel(p2.x(), p2.y(), geoTransform) self.buildLine(x1, y1, x2, y2, geoTransform, writer, outFeature) else: points = geom.asPolyline() for i in range(len(points) - 1): p1 = points[i] p2 = points[i + 1] (x1, y1) = raster.mapToPixel(p1.x(), p1.y(), geoTransform) (x2, y2) = raster.mapToPixel(p2.x(), p2.y(), geoTransform) self.buildLine(x1, y1, x2, y2, geoTransform, writer, outFeature) self.pointId = 0 self.lineId += 1 feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, progress): layerA = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT_A)) layerB = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT_B)) sameLayer = self.getParameterValue(self.INPUT_A) == self.getParameterValue(self.INPUT_B) fieldList = layerA.fields() writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fieldList, QgsWkbTypes.LineString, layerA.crs()) spatialIndex = vector.spatialindex(layerB) outFeat = QgsFeature() features = vector.features(layerA) total = 100.0 / float(len(features)) for current, inFeatA in enumerate(features): inGeom = inFeatA.geometry() attrsA = inFeatA.attributes() outFeat.setAttributes(attrsA) inLines = [inGeom] lines = spatialIndex.intersects(inGeom.boundingBox()) engine = None if len(lines) > 0: # use prepared geometries for faster intersection tests engine = QgsGeometry.createGeometryEngine(inGeom.geometry()) engine.prepareGeometry() if len(lines) > 0: # hasIntersections splittingLines = [] request = QgsFeatureRequest().setFilterFids(lines).setSubsetOfAttributes([]) for inFeatB in layerB.getFeatures(request): # check if trying to self-intersect if sameLayer: if inFeatA.id() == inFeatB.id(): continue splitGeom = inFeatB.geometry() if engine.intersects(splitGeom.geometry()): splittingLines.append(splitGeom) if len(splittingLines) > 0: for splitGeom in splittingLines: splitterPList = vector.extractPoints(splitGeom) outLines = [] split_geom_engine = QgsGeometry.createGeometryEngine(splitGeom.geometry()) split_geom_engine.prepareGeometry() while len(inLines) > 0: inGeom = inLines.pop() inPoints = vector.extractPoints(inGeom) if split_geom_engine.intersects(inGeom.geometry()): try: result, newGeometries, topoTestPoints = inGeom.splitGeometry(splitterPList, False) except: ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, self.tr('Geometry exception while splitting')) result = 1 # splitGeometry: If there are several intersections # between geometry and splitLine, only the first one is considered. if result == 0: # split occurred if inPoints == vector.extractPoints(inGeom): # bug in splitGeometry: sometimes it returns 0 but # the geometry is unchanged outLines.append(inGeom) else: inLines.append(inGeom) for aNewGeom in newGeometries: inLines.append(aNewGeom) else: outLines.append(inGeom) else: outLines.append(inGeom) inLines = outLines for aLine in inLines: if len(aLine.asPolyline()) > 2 or \ (len(aLine.asPolyline()) == 2 and aLine.asPolyline()[0] != aLine.asPolyline()[1]): # sometimes splitting results in lines of zero length outFeat.setGeometry(aLine) writer.addFeature(outFeat) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): layer = self.getParameterValue(self.INPUT_LAYER) mapping = self.getParameterValue(self.FIELDS_MAPPING) output = self.getOutputFromName(self.OUTPUT_LAYER) layer = dataobjects.getObjectFromUri(layer) provider = layer.dataProvider() fields = [] expressions = [] for field_def in mapping: fields.append(QgsField(name=field_def['name'], type=field_def['type'], len=field_def['length'], prec=field_def['precision'])) expression = QgsExpression(field_def['expression']) if expression.hasParserError(): raise GeoAlgorithmExecutionException( self.tr(u'Parser error in expression "{}": {}') .format(unicode(field_def['expression']), unicode(expression.parserErrorString()))) expression.prepare(provider.fields()) if expression.hasEvalError(): raise GeoAlgorithmExecutionException( self.tr(u'Evaluation error in expression "{}": {}') .format(unicode(field_def['expression']), unicode(expression.evalErrorString()))) expressions.append(expression) writer = output.getVectorWriter(fields, provider.geometryType(), layer.crs()) # Create output vector layer with new attributes error = '' calculationSuccess = True inFeat = QgsFeature() outFeat = QgsFeature() features = vector.features(layer) count = len(features) for current, inFeat in enumerate(features): rownum = current + 1 outFeat.setGeometry(inFeat.geometry()) attrs = [] for i in xrange(0, len(mapping)): field_def = mapping[i] expression = expressions[i] expression.setCurrentRowNumber(rownum) value = expression.evaluate(inFeat) if expression.hasEvalError(): calculationSuccess = False error = expression.evalErrorString() break attrs.append(value) outFeat.setAttributes(attrs) writer.addFeature(outFeat) current += 1 progress.setPercentage(100 * current / float(count)) del writer if not calculationSuccess: raise GeoAlgorithmExecutionException( self.tr('An error occurred while evaluating the calculation' ' string:\n') + error)
def processAlgorithm(self, progress): filename = self.getParameterValue(self.INPUT) layer = dataobjects.getObjectFromUri(filename) filename = self.getParameterValue(self.INTERSECT) selectLayer = dataobjects.getObjectFromUri(filename) predicates = self.getParameterValue(self.PREDICATE) precision = self.getParameterValue(self.PRECISION) index = vector.spatialindex(layer) output = self.getOutputFromName(self.OUTPUT) writer = output.getVectorWriter(layer.fields(), layer.wkbType(), layer.crs()) if 'disjoint' in predicates: disjoinSet = [] for feat in vector.features(layer): disjoinSet.append(feat.id()) selectedSet = [] features = vector.features(selectLayer) total = 100.0 / len(features) for current, f in enumerate(features): geom = vector.snapToPrecision(f.geometry(), precision) bbox = vector.bufferedBoundingBox(geom.boundingBox(), 0.51 * precision) intersects = index.intersects(bbox) request = QgsFeatureRequest().setFilterFids( intersects).setSubsetOfAttributes([]) for feat in layer.getFeatures(request): tmpGeom = vector.snapToPrecision(feat.geometry(), precision) res = False for predicate in predicates: if predicate == 'disjoint': if tmpGeom.intersects(geom): try: disjoinSet.remove(feat.id()) except: pass # already removed else: if predicate == 'intersects': res = tmpGeom.intersects(geom) elif predicate == 'contains': res = tmpGeom.contains(geom) elif predicate == 'equals': res = tmpGeom.equals(geom) elif predicate == 'touches': res = tmpGeom.touches(geom) elif predicate == 'overlaps': res = tmpGeom.overlaps(geom) elif predicate == 'within': res = tmpGeom.within(geom) elif predicate == 'crosses': res = tmpGeom.crosses(geom) if res: selectedSet.append(feat.id()) break progress.setPercentage(int(current * total)) if 'disjoint' in predicates: selectedSet = selectedSet + disjoinSet features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): if f.id() in selectedSet: writer.addFeature(f) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT_LAYER)) fieldName = self.getParameterValue(self.FIELD_NAME) fieldType = self.TYPES[self.getParameterValue(self.FIELD_TYPE)] width = self.getParameterValue(self.FIELD_LENGTH) precision = self.getParameterValue(self.FIELD_PRECISION) newField = self.getParameterValue(self.NEW_FIELD) formula = self.getParameterValue(self.FORMULA) output = self.getOutputFromName(self.OUTPUT_LAYER) if output.value == '': ext = output.getDefaultFileExtension(self) output.value = system.getTempFilenameInTempFolder( output.name + '.' + ext) provider = layer.dataProvider() fields = layer.pendingFields() if newField: fields.append(QgsField(fieldName, fieldType, '', width, precision)) writer = output.getVectorWriter(fields, provider.geometryType(), layer.crs()) exp = QgsExpression(formula) da = QgsDistanceArea() da.setSourceCrs(layer.crs().srsid()) da.setEllipsoidalMode( iface.mapCanvas().mapSettings().hasCrsTransformEnabled()) da.setEllipsoid(QgsProject.instance().readEntry( 'Measure', '/Ellipsoid', GEO_NONE)[0]) exp.setGeomCalculator(da) if not exp.prepare(layer.pendingFields()): raise GeoAlgorithmExecutionException( self.tr('Evaluation error: %s' % exp.evalErrorString())) outFeature = QgsFeature() outFeature.initAttributes(len(fields)) outFeature.setFields(fields) error = '' calculationSuccess = True current = 0 features = vector.features(layer) total = 100.0 / len(features) rownum = 1 for current, f in enumerate(features): rownum = current + 1 exp.setCurrentRowNumber(rownum) value = exp.evaluate(f) if exp.hasEvalError(): calculationSuccess = False error = exp.evalErrorString() break else: outFeature.setGeometry(f.geometry()) for fld in f.fields(): outFeature[fld.name()] = f[fld.name()] outFeature[fieldName] = value writer.addFeature(outFeature) progress.setPercentage(int(current * total)) del writer if not calculationSuccess: raise GeoAlgorithmExecutionException( self.tr('An error occured while evaluating the calculation ' 'string:\n%s' % error))
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString(self.getParameterValue(self.POINTS)) weightField = self.getParameterValue(self.WEIGHT) uniqueField = self.getParameterValue(self.UID) if weightField is None: weightIndex = -1 else: weightIndex = layer.fields().lookupField(weightField) if uniqueField is None: uniqueIndex = -1 else: uniqueIndex = layer.fields().lookupField(uniqueField) fieldList = [QgsField('MEAN_X', QVariant.Double, '', 24, 15), QgsField('MEAN_Y', QVariant.Double, '', 24, 15), QgsField('UID', QVariant.String, '', 255)] writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fieldList, QgsWkbTypes.Point, layer.crs() ) features = vector.features(layer) total = 100.0 / len(features) means = {} for current, feat in enumerate(features): feedback.setProgress(int(current * total)) if uniqueIndex == -1: clazz = "Single class" else: clazz = str(feat.attributes()[uniqueIndex]).strip() if weightIndex == -1: weight = 1.00 else: try: weight = float(feat.attributes()[weightIndex]) except: weight = 1.00 if weight < 0: raise GeoAlgorithmExecutionException(self.tr('Negative weight value found. Please fix your data and try again.')) if clazz not in means: means[clazz] = (0, 0, 0) (cx, cy, totalweight) = means[clazz] geom = QgsGeometry(feat.geometry()) geom = vector.extractPoints(geom) for i in geom: cx += i.x() * weight cy += i.y() * weight totalweight += weight means[clazz] = (cx, cy, totalweight) current = 0 total = 100.0 / len(means) for (clazz, values) in list(means.items()): outFeat = QgsFeature() cx = values[0] / values[2] cy = values[1] / values[2] meanPoint = QgsPoint(cx, cy) outFeat.setGeometry(QgsGeometry.fromPoint(meanPoint)) outFeat.setAttributes([cx, cy, clazz]) writer.addFeature(outFeat) current += 1 feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, progress): filename = self.getParameterValue(self.INPUT) inputLayer = dataobjects.getObjectFromUri(filename) method = self.getParameterValue(self.METHOD) filename2 = self.getParameterValue(self.INTERSECT) selectLayer = dataobjects.getObjectFromUri(filename2) predicates = self.getParameterValue(self.PREDICATE) precision = self.getParameterValue(self.PRECISION) oldSelection = set(inputLayer.selectedFeaturesIds()) inputLayer.removeSelection() index = vector.spatialindex(inputLayer) if 'disjoint' in predicates: disjoinSet = [] for feat in vector.features(inputLayer): disjoinSet.append(feat.id()) geom = QgsGeometry() selectedSet = [] features = vector.features(selectLayer) total = 100.0 / len(features) for current, f in enumerate(features): geom = vector.snapToPrecision(f.geometry(), precision) bbox = vector.bufferedBoundingBox(geom.boundingBox(), 0.51 * precision) intersects = index.intersects(bbox) request = QgsFeatureRequest().setFilterFids( intersects).setSubsetOfAttributes([]) for feat in inputLayer.getFeatures(request): tmpGeom = vector.snapToPrecision(feat.geometry(), precision) res = False for predicate in predicates: if predicate == 'disjoint': if tmpGeom.intersects(geom): try: disjoinSet.remove(feat.id()) except: pass # already removed else: if predicate == 'intersects': res = tmpGeom.intersects(geom) elif predicate == 'contains': res = tmpGeom.contains(geom) elif predicate == 'equals': res = tmpGeom.equals(geom) elif predicate == 'touches': res = tmpGeom.touches(geom) elif predicate == 'overlaps': res = tmpGeom.overlaps(geom) elif predicate == 'within': res = tmpGeom.within(geom) elif predicate == 'crosses': res = tmpGeom.crosses(geom) if res: selectedSet.append(feat.id()) break progress.setPercentage(int(current * total)) if 'disjoint' in predicates: selectedSet = selectedSet + disjoinSet if method == 1: selectedSet = list(oldSelection.union(selectedSet)) elif method == 2: selectedSet = list(oldSelection.difference(selectedSet)) inputLayer.selectByIds(selectedSet) self.setOutputValue(self.OUTPUT, filename)
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_VECTOR)) startPoint = self.getParameterValue(self.START_POINT) endPoints = dataobjects.getLayerFromString( self.getParameterValue(self.END_POINTS)) strategy = self.getParameterValue(self.STRATEGY) directionFieldName = self.getParameterValue(self.DIRECTION_FIELD) forwardValue = self.getParameterValue(self.VALUE_FORWARD) backwardValue = self.getParameterValue(self.VALUE_BACKWARD) bothValue = self.getParameterValue(self.VALUE_BOTH) defaultDirection = self.getParameterValue(self.DEFAULT_DIRECTION) bothValue = self.getParameterValue(self.VALUE_BOTH) defaultDirection = self.getParameterValue(self.DEFAULT_DIRECTION) speedFieldName = self.getParameterValue(self.SPEED_FIELD) defaultSpeed = self.getParameterValue(self.DEFAULT_SPEED) tolerance = self.getParameterValue(self.TOLERANCE) fields = QgsFields() fields.append(QgsField('start', QVariant.String, '', 254, 0)) fields.append(QgsField('end', QVariant.String, '', 254, 0)) fields.append(QgsField('cost', QVariant.Double, '', 20, 7)) feat = QgsFeature() feat.setFields(fields) writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter( fields.toList(), QgsWkbTypes.LineString, layer.crs()) tmp = startPoint.split(',') startPoint = QgsPoint(float(tmp[0]), float(tmp[1])) directionField = -1 if directionFieldName is not None: directionField = layer.fields().lookupField(directionFieldName) speedField = -1 if speedFieldName is not None: speedField = layer.fields().lookupField(speedFieldName) director = QgsVectorLayerDirector(layer, directionField, forwardValue, backwardValue, bothValue, defaultDirection) distUnit = iface.mapCanvas().mapSettings().destinationCrs().mapUnits() multiplier = QgsUnitTypes.fromUnitToUnitFactor( distUnit, QgsUnitTypes.DistanceMeters) if strategy == 0: strategy = QgsNetworkDistanceStrategy() else: strategy = QgsNetworkSpeedStrategy(speedField, defaultSpeed, multiplier * 1000.0 / 3600.0) multiplier = 3600 director.addStrategy(strategy) builder = QgsGraphBuilder( iface.mapCanvas().mapSettings().destinationCrs(), True, tolerance) feedback.pushInfo(self.tr('Loading end points...')) request = QgsFeatureRequest() request.setFlags(request.flags() ^ QgsFeatureRequest.SubsetOfAttributes) features = vector.features(endPoints, request) count = len(features) points = [startPoint] for f in features: points.append(f.geometry().asPoint()) feedback.pushInfo(self.tr('Building graph...')) snappedPoints = director.makeGraph(builder, points) feedback.pushInfo(self.tr('Calculating shortest paths...')) graph = builder.graph() idxStart = graph.findVertex(snappedPoints[0]) tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0) route = [] total = 100.0 / count for i in range(1, count + 1): idxEnd = graph.findVertex(snappedPoints[i]) if tree[idxEnd] == -1: msg = self.tr( 'There is no route from start point ({}) to end point ({}).' .format(startPoint.toString(), points[i].toString())) feedback.setProgressText(msg) ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, msg) continue cost = 0.0 current = idxEnd while current != idxStart: cost += graph.edge(tree[current]).cost(0) route.append( graph.vertex(graph.edge(tree[current]).inVertex()).point()) current = graph.edge(tree[current]).outVertex() route.append(snappedPoints[0]) route.reverse() geom = QgsGeometry.fromPolyline(route) feat.setGeometry(geom) feat['start'] = startPoint.toString() feat['end'] = points[i].toString() feat['cost'] = cost / multiplier writer.addFeature(feat) route[:] = [] feedback.setProgress(int(i * total)) del writer
def processAlgorithm(self, feedback): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_VECTOR)) rasterPath = str(self.getParameterValue(self.INPUT_RASTER)) rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly) geoTransform = rasterDS.GetGeoTransform() rasterDS = None fields = QgsFields() fields.append(QgsField('id', QVariant.Int, '', 10, 0)) fields.append(QgsField('poly_id', QVariant.Int, '', 10, 0)) fields.append(QgsField('point_id', QVariant.Int, '', 10, 0)) writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter( fields.toList(), QgsWkbTypes.Point, layer.crs()) outFeature = QgsFeature() outFeature.setFields(fields) fid = 0 polyId = 0 pointId = 0 features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): geom = f.geometry() bbox = geom.boundingBox() xMin = bbox.xMinimum() xMax = bbox.xMaximum() yMin = bbox.yMinimum() yMax = bbox.yMaximum() (startRow, startColumn) = raster.mapToPixel(xMin, yMax, geoTransform) (endRow, endColumn) = raster.mapToPixel(xMax, yMin, geoTransform) # use prepared geometries for faster intersection tests engine = QgsGeometry.createGeometryEngine(geom.geometry()) engine.prepareGeometry() for row in range(startRow, endRow + 1): for col in range(startColumn, endColumn + 1): (x, y) = raster.pixelToMap(row, col, geoTransform) point = QgsPointV2() point.setX(x) point.setY(y) if engine.contains(point): outFeature.setGeometry(QgsGeometry(point)) outFeature['id'] = fid outFeature['poly_id'] = polyId outFeature['point_id'] = pointId fid += 1 pointId += 1 writer.addFeature(outFeature) pointId = 0 polyId += 1 feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, progress): layerA = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_A)) layerB = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_B)) fieldA = self.getParameterValue(self.FIELD_A) fieldB = self.getParameterValue(self.FIELD_B) idxA = layerA.fields().lookupField(fieldA) idxB = layerB.fields().lookupField(fieldB) fieldList = [layerA.fields()[idxA], layerB.fields()[idxB]] writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fieldList, QgsWkbTypes.Point, layerA.crs()) spatialIndex = vector.spatialindex(layerB) outFeat = QgsFeature() features = vector.features(layerA) total = 100.0 / len(features) hasIntersections = False for current, inFeatA in enumerate(features): inGeom = inFeatA.geometry() hasIntersections = False lines = spatialIndex.intersects(inGeom.boundingBox()) engine = None if len(lines) > 0: hasIntersections = True # use prepared geometries for faster intersection tests engine = QgsGeometry.createGeometryEngine(inGeom.geometry()) engine.prepareGeometry() if hasIntersections: request = QgsFeatureRequest().setFilterFids(lines) for inFeatB in layerB.getFeatures(request): tmpGeom = inFeatB.geometry() points = [] attrsA = inFeatA.attributes() attrsB = inFeatB.attributes() if engine.intersects(tmpGeom.geometry()): tempGeom = inGeom.intersection(tmpGeom) if tempGeom.type() == QgsWkbTypes.PointGeometry: if tempGeom.isMultipart(): points = tempGeom.asMultiPoint() else: points.append(tempGeom.asPoint()) for j in points: outFeat.setGeometry(tempGeom.fromPoint(j)) outFeat.setAttributes( [attrsA[idxA], attrsB[idxB]]) writer.addFeature(outFeat) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_LAYER)) fields = layer.fields() fields.append(QgsField('node_pos', QVariant.Int)) fields.append(QgsField('node_index', QVariant.Int)) fields.append(QgsField('distance', QVariant.Double)) fields.append(QgsField('angle', QVariant.Double)) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter( fields, QgsWkbTypes.Point, layer.crs()) node_indices_string = self.getParameterValue(self.NODES) indices = [] for node in node_indices_string.split(','): try: indices.append(int(node)) except: raise GeoAlgorithmExecutionException( self.tr('\'{}\' is not a valid node index').format(node)) features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): input_geometry = f.geometry() if not input_geometry: writer.addFeature(f) else: total_nodes = input_geometry.geometry().nCoordinates() for node in indices: if node < 0: node_index = total_nodes + node else: node_index = node if node_index < 0 or node_index >= total_nodes: continue distance = input_geometry.distanceToVertex(node_index) angle = math.degrees(input_geometry.angleAtVertex(node_index)) output_feature = QgsFeature() attrs = f.attributes() attrs.append(node) attrs.append(node_index) attrs.append(distance) attrs.append(angle) output_feature.setAttributes(attrs) point = input_geometry.vertexAt(node_index) output_feature.setGeometry(QgsGeometry.fromPoint(point)) writer.addFeature(output_feature) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_VECTOR)) startPoints = dataobjects.getLayerFromString( self.getParameterValue(self.START_POINTS)) strategy = self.getParameterValue(self.STRATEGY) travelCost = self.getParameterValue(self.TRAVEL_COST) directionFieldName = self.getParameterValue(self.DIRECTION_FIELD) forwardValue = self.getParameterValue(self.VALUE_FORWARD) backwardValue = self.getParameterValue(self.VALUE_BACKWARD) bothValue = self.getParameterValue(self.VALUE_BOTH) defaultDirection = self.getParameterValue(self.DEFAULT_DIRECTION) bothValue = self.getParameterValue(self.VALUE_BOTH) defaultDirection = self.getParameterValue(self.DEFAULT_DIRECTION) speedFieldName = self.getParameterValue(self.SPEED_FIELD) defaultSpeed = self.getParameterValue(self.DEFAULT_SPEED) tolerance = self.getParameterValue(self.TOLERANCE) fields = QgsFields() fields.append(QgsField('type', QVariant.String, '', 254, 0)) fields.append(QgsField('start', QVariant.String, '', 254, 0)) feat = QgsFeature() feat.setFields(fields) writerPoints = self.getOutputFromName( self.OUTPUT_POINTS).getVectorWriter(fields, QgsWkbTypes.MultiPoint, layer.crs()) writerPolygons = self.getOutputFromName( self.OUTPUT_POLYGON).getVectorWriter(fields, QgsWkbTypes.Polygon, layer.crs()) directionField = -1 if directionFieldName is not None: directionField = layer.fields().lookupField(directionFieldName) speedField = -1 if speedFieldName is not None: speedField = layer.fields().lookupField(speedFieldName) director = QgsVectorLayerDirector(layer, directionField, forwardValue, backwardValue, bothValue, defaultDirection) distUnit = iface.mapCanvas().mapSettings().destinationCrs().mapUnits() multiplier = QgsUnitTypes.fromUnitToUnitFactor( distUnit, QgsUnitTypes.DistanceMeters) if strategy == 0: strategy = QgsNetworkDistanceStrategy() else: strategy = QgsNetworkSpeedStrategy(speedField, defaultSpeed, multiplier * 1000.0 / 3600.0) director.addStrategy(strategy) builder = QgsGraphBuilder( iface.mapCanvas().mapSettings().destinationCrs(), True, tolerance) feedback.pushInfo(self.tr('Loading start points...')) request = QgsFeatureRequest() request.setFlags(request.flags() ^ QgsFeatureRequest.SubsetOfAttributes) features = vector.features(startPoints, request) points = [] for f in features: points.append(f.geometry().asPoint()) feedback.pushInfo(self.tr('Building graph...')) snappedPoints = director.makeGraph(builder, points) feedback.pushInfo(self.tr('Calculating service areas...')) graph = builder.graph() vertices = [] upperBoundary = [] lowerBoundary = [] total = 100.0 / len(snappedPoints) for i, p in enumerate(snappedPoints): idxStart = graph.findVertex(snappedPoints[i]) origPoint = points[i].toString() tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0) for j, v in enumerate(cost): if v > travelCost and tree[j] != -1: vertexId = graph.edge(tree[j]).outVertex() if cost[vertexId] <= travelCost: vertices.append(j) for j in vertices: upperBoundary.append( graph.vertex(graph.edge(tree[j]).inVertex()).point()) lowerBoundary.append( graph.vertex(graph.edge(tree[j]).outVertex()).point()) geomUpper = QgsGeometry.fromMultiPoint(upperBoundary) geomLower = QgsGeometry.fromMultiPoint(lowerBoundary) feat.setGeometry(geomUpper) feat['type'] = 'upper' feat['start'] = origPoint writerPoints.addFeature(feat) feat.setGeometry(geomLower) feat['type'] = 'lower' feat['start'] = origPoint writerPoints.addFeature(feat) upperBoundary.append(origPoint) lowerBoundary.append(origPoint) geomUpper = QgsGeometry.fromMultiPoint(upperBoundary) geomLower = QgsGeometry.fromMultiPoint(lowerBoundary) geom = geomUpper.convexHull() feat.setGeometry(geom) feat['type'] = 'upper' feat['start'] = origPoint writerPolygons.addFeature(feat) geom = geomLower.convexHull() feat.setGeometry(geom) feat['type'] = 'lower' feat['start'] = origPoint writerPolygons.addFeature(feat) vertices[:] = [] upperBoundary[:] = [] lowerBoundary[:] = [] feedback.setProgress(int(i * total)) del writerPoints del writerPolygons
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.VECTOR)) 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, QGis.WKBPoint, layer.dataProvider().crs()) da = QgsDistanceArea() features = vector.features(layer) for current, f in enumerate(features): fGeom = QgsGeometry(f.geometry()) bbox = fGeom.boundingBox() if strategy == 0: pointCount = int(value) else: pointCount = int(round(value * da.measure(fGeom))) 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 = QgsPoint(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 progress.setPercentage(int(nPoints * total)) nIterations += 1 if nPoints < pointCount: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self.tr('Can not generate requested number of random ' 'points. Maximum number of attempts exceeded.')) progress.setPercentage(0) del writer
def processAlgorithm(self, feedback): layers = self.getParameterValue(self.INPUT_DATASOURCES) query = self.getParameterValue(self.INPUT_QUERY) uid_field = self.getParameterValue(self.INPUT_UID_FIELD) geometry_field = self.getParameterValue(self.INPUT_GEOMETRY_FIELD) geometry_type = self.getParameterValue(self.INPUT_GEOMETRY_TYPE) geometry_crs = self.getParameterValue(self.INPUT_GEOMETRY_CRS) df = QgsVirtualLayerDefinition() layerIdx = 1 if layers: for layerSource in layers.split(';'): layer = dataobjects.getObjectFromUri(layerSource) if layer: df.addSource('input{}'.format(layerIdx), layer.id()) layerIdx += 1 if query == '': raise GeoAlgorithmExecutionException( self. tr('Empty SQL. Please enter valid SQL expression and try again.' )) else: df.setQuery(query) if uid_field: df.setUid(uid_field) if geometry_type == 1: # no geometry df.setGeometryWkbType(QgsWkbTypes.NullGeometry) else: if geometry_field: df.setGeometryField(geometry_field) if geometry_type > 1: df.setGeometryWkbType(geometry_type - 1) if geometry_crs: crs = QgsCoordinateReferenceSystem(geometry_crs) if crs.isValid(): df.setGeometrySrid(crs.postgisSrid()) vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual") if not vLayer.isValid(): raise GeoAlgorithmExecutionException( vLayer.dataProvider().error().message()) writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter( vLayer.fields().toList(), # Create a point layer (without any points) if 'no geometry' is chosen vLayer.wkbType() if geometry_type != 1 else 1, vLayer.crs()) features = vector.features(vLayer) total = 100.0 / len(features) outFeat = QgsFeature() for current, inFeat in enumerate(features): outFeat.setAttributes(inFeat.attributes()) if geometry_type != 1: outFeat.setGeometry(inFeat.geometry()) writer.addFeature(outFeat) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, feedback): layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT)) buf = self.getParameterValue(self.BUFFER) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.fields().toList(), QgsWkbTypes.Polygon, layer.crs()) outFeat = QgsFeature() extent = layer.extent() extraX = extent.height() * (buf / 100.0) extraY = extent.width() * (buf / 100.0) height = extent.height() width = extent.width() c = voronoi.Context() pts = [] ptDict = {} ptNdx = -1 features = vector.features(layer) total = 100.0 / len(features) for current, inFeat in enumerate(features): geom = inFeat.geometry() point = geom.asPoint() x = point.x() - extent.xMinimum() y = point.y() - extent.yMinimum() pts.append((x, y)) ptNdx += 1 ptDict[ptNdx] = inFeat.id() feedback.setProgress(int(current * total)) if len(pts) < 3: raise GeoAlgorithmExecutionException( self.tr('Input file should contain at least 3 points. Choose ' 'another file and try again.')) uniqueSet = set(item for item in pts) ids = [pts.index(item) for item in uniqueSet] sl = voronoi.SiteList([voronoi.Site(i[0], i[1], sitenum=j) for (j, i) in enumerate(uniqueSet)]) voronoi.voronoi(sl, c) inFeat = QgsFeature() current = 0 if len(c.polygons) == 0: raise GeoAlgorithmExecutionException( self.tr('There were no polygons created.')) total = 100.0 / len(c.polygons) for (site, edges) in list(c.polygons.items()): request = QgsFeatureRequest().setFilterFid(ptDict[ids[site]]) inFeat = next(layer.getFeatures(request)) lines = self.clip_voronoi(edges, c, width, height, extent, extraX, extraY) geom = QgsGeometry.fromMultiPoint(lines) geom = QgsGeometry(geom.convexHull()) outFeat.setGeometry(geom) outFeat.setAttributes(inFeat.attributes()) writer.addFeature(outFeat) current += 1 feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, progress): """ Based on code by Matthew Perry https://gist.github.com/perrygeo/5667173 """ layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_VECTOR)) rasterPath = unicode(self.getParameterValue(self.INPUT_RASTER)) bandNumber = self.getParameterValue(self.RASTER_BAND) columnPrefix = self.getParameterValue(self.COLUMN_PREFIX) useGlobalExtent = self.getParameterValue(self.GLOBAL_EXTENT) rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly) geoTransform = rasterDS.GetGeoTransform() rasterBand = rasterDS.GetRasterBand(bandNumber) noData = rasterBand.GetNoDataValue() cellXSize = abs(geoTransform[1]) cellYSize = abs(geoTransform[5]) rasterXSize = rasterDS.RasterXSize rasterYSize = rasterDS.RasterYSize rasterBBox = QgsRectangle(geoTransform[0], geoTransform[3] - cellYSize * rasterYSize, geoTransform[0] + cellXSize * rasterXSize, geoTransform[3]) rasterGeom = QgsGeometry.fromRect(rasterBBox) crs = osr.SpatialReference() crs.ImportFromProj4(str(layer.crs().toProj4())) if useGlobalExtent: xMin = rasterBBox.xMinimum() xMax = rasterBBox.xMaximum() yMin = rasterBBox.yMinimum() yMax = rasterBBox.yMaximum() (startColumn, startRow) = mapToPixel(xMin, yMax, geoTransform) (endColumn, endRow) = mapToPixel(xMax, yMin, geoTransform) width = endColumn - startColumn height = endRow - startRow srcOffset = (startColumn, startRow, width, height) srcArray = rasterBand.ReadAsArray(*srcOffset) newGeoTransform = ( geoTransform[0] + srcOffset[0] * geoTransform[1], geoTransform[1], 0.0, geoTransform[3] + srcOffset[1] * geoTransform[5], 0.0, geoTransform[5], ) memVectorDriver = ogr.GetDriverByName('Memory') memRasterDriver = gdal.GetDriverByName('MEM') fields = layer.pendingFields() (idxMin, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'min', 21, 6) (idxMax, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'max', 21, 6) (idxSum, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'sum', 21, 6) (idxCount, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'count', 21, 6) (idxMean, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'mean', 21, 6) (idxStd, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'std', 21, 6) (idxUnique, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'unique', 21, 6) (idxRange, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'range', 21, 6) (idxVar, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'var', 21, 6) (idxMedian, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'median', 21, 6) if hasSciPy: (idxMode, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'mode', 21, 6) writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter( fields.toList(), layer.dataProvider().geometryType(), layer.crs()) outFeat = QgsFeature() outFeat.initAttributes(len(fields)) outFeat.setFields(fields) current = 0 features = vector.features(layer) total = 100.0 / len(features) for f in features: geom = f.geometry() intersectedGeom = rasterGeom.intersection(geom) ogrGeom = ogr.CreateGeometryFromWkt(intersectedGeom.exportToWkt()) if not useGlobalExtent: bbox = intersectedGeom.boundingBox() xMin = bbox.xMinimum() xMax = bbox.xMaximum() yMin = bbox.yMinimum() yMax = bbox.yMaximum() (startColumn, startRow) = mapToPixel(xMin, yMax, geoTransform) (endColumn, endRow) = mapToPixel(xMax, yMin, geoTransform) width = endColumn - startColumn height = endRow - startRow if width == 0 or height == 0: continue srcOffset = (startColumn, startRow, width, height) srcArray = rasterBand.ReadAsArray(*srcOffset) newGeoTransform = ( geoTransform[0] + srcOffset[0] * geoTransform[1], geoTransform[1], 0.0, geoTransform[3] + srcOffset[1] * geoTransform[5], 0.0, geoTransform[5], ) # Create a temporary vector layer in memory memVDS = memVectorDriver.CreateDataSource('out') memLayer = memVDS.CreateLayer('poly', crs, ogr.wkbPolygon) ft = ogr.Feature(memLayer.GetLayerDefn()) ft.SetGeometry(ogrGeom) memLayer.CreateFeature(ft) ft.Destroy() # Rasterize it rasterizedDS = memRasterDriver.Create('', srcOffset[2], srcOffset[3], 1, gdal.GDT_Byte) rasterizedDS.SetGeoTransform(newGeoTransform) gdal.RasterizeLayer(rasterizedDS, [1], memLayer, burn_values=[1]) rasterizedArray = rasterizedDS.ReadAsArray() srcArray = numpy.nan_to_num(srcArray) masked = numpy.ma.MaskedArray( srcArray, mask=numpy.logical_or(srcArray == noData, numpy.logical_not(rasterizedArray))) outFeat.setGeometry(geom) attrs = f.attributes() attrs.insert(idxMin, float(masked.min())) attrs.insert(idxMax, float(masked.max())) attrs.insert(idxSum, float(masked.sum())) attrs.insert(idxCount, int(masked.count())) attrs.insert(idxMean, float(masked.mean())) attrs.insert(idxStd, float(masked.std())) attrs.insert(idxUnique, numpy.unique(masked.compressed()).size) attrs.insert(idxRange, float(masked.max()) - float(masked.min())) attrs.insert(idxVar, float(masked.var())) attrs.insert(idxMedian, float(numpy.ma.median(masked))) if hasSciPy: attrs.insert(idxMode, float(mode(masked, axis=None)[0][0])) outFeat.setAttributes(attrs) writer.addFeature(outFeat) memVDS = None rasterizedDS = None current += 1 progress.setPercentage(int(current * total)) rasterDS = None del writer
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue( self.INPUT)) index = self.getParameterValue(self.TYPE) splitNodes = False if index == 0: newType = QgsWkbTypes.Point elif index == 1: newType = QgsWkbTypes.Point splitNodes = True elif index == 2: newType = QgsWkbTypes.LineString elif index == 3: newType = QgsWkbTypes.MultiLineString elif index == 4: newType = QgsWkbTypes.Polygon else: newType = QgsWkbTypes.Point writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.fields(), newType, layer.crs()) features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): geom = f.geometry() geomType = geom.wkbType() if geomType in [QgsWkbTypes.Point, QgsWkbTypes.Point25D]: if newType == QgsWkbTypes.Point: writer.addFeature(f) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from %s to %s', geomType, newType)) elif geomType in [ QgsWkbTypes.MultiPoint, QgsWkbTypes.MultiPoint25D ]: if newType == QgsWkbTypes.Point and splitNodes: points = geom.asMultiPoint() for p in points: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPoint(p)) writer.addFeature(feat) elif newType == QgsWkbTypes.Point: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(geom.centroid()) writer.addFeature(feat) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from %s to %s', geomType, newType)) elif geomType in [ QgsWkbTypes.LineString, QgsWkbTypes.LineString25D ]: if newType == QgsWkbTypes.Point and splitNodes: points = geom.asPolyline() for p in points: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPoint(p)) writer.addFeature(feat) elif newType == QgsWkbTypes.Point: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(geom.centroid()) writer.addFeature(feat) elif newType == QgsWkbTypes.LineString: writer.addFeature(f) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from %s to %s', geomType, newType)) elif geomType in [ QgsWkbTypes.MultiLineString, QgsWkbTypes.MultiLineString25D ]: if newType == QgsWkbTypes.Point and splitNodes: lines = geom.asMultiPolyline() for line in lines: for p in line: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPoint(p)) writer.addFeature(feat) elif newType == QgsWkbTypes.Point: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(geom.centroid()) writer.addFeature(feat) elif newType == QgsWkbTypes.LineString: lines = geom.asMultiPolyline() for line in lines: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPolyline(line)) writer.addFeature(feat) elif newType == QgsWkbTypes.MultiLineString: writer.addFeature(f) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from %s to %s', geomType, newType)) elif geomType in [QgsWkbTypes.Polygon, QgsWkbTypes.Polygon25D]: if newType == QgsWkbTypes.Point and splitNodes: rings = geom.asPolygon() for ring in rings: for p in ring: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPoint(p)) writer.addFeature(feat) elif newType == QgsWkbTypes.Point: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(geom.centroid()) writer.addFeature(feat) elif newType == QgsWkbTypes.MultiLineString: rings = geom.asPolygon() feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromMultiPolyline(rings)) writer.addFeature(feat) elif newType == QgsWkbTypes.Polygon: writer.addFeature(f) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from %s to %s', geomType, newType)) elif geomType in [ QgsWkbTypes.MultiPolygon, QgsWkbTypes.MultiPolygon25D ]: if newType == QgsWkbTypes.Point and splitNodes: polygons = geom.asMultiPolygon() for polygon in polygons: for line in polygon: for p in line: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPoint(p)) writer.addFeature(feat) elif newType == QgsWkbTypes.Point: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(geom.centroid()) writer.addFeature(feat) elif newType == QgsWkbTypes.LineString: polygons = geom.asMultiPolygon() for polygons in polygons: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPolyline(polygon)) writer.addFeature(feat) elif newType == QgsWkbTypes.Polygon: polygons = geom.asMultiPolygon() for polygon in polygons: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPolygon(polygon)) writer.addFeature(feat) elif newType in [ QgsWkbTypes.MultiLineString, QgsWkbTypes.MultiPolygon ]: writer.addFeature(f) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from %s to %s', geomType, newType)) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): layerA = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_A)) layerB = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_B)) fieldA = self.getParameterValue(self.FIELD_A) fieldB = self.getParameterValue(self.FIELD_B) idxA = layerA.fieldNameIndex(fieldA) idxB = layerB.fieldNameIndex(fieldB) fieldList = [layerA.pendingFields()[idxA], layerB.pendingFields()[idxB]] writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fieldList, QGis.WKBPoint, layerA.dataProvider().crs()) spatialIndex = vector.spatialindex(layerB) inFeatA = QgsFeature() inFeatB = QgsFeature() outFeat = QgsFeature() inGeom = QgsGeometry() tmpGeom = QgsGeometry() features = vector.features(layerA) current = 0 total = 100.0 / float(len(features)) hasIntersections = False for inFeatA in features: inGeom = inFeatA.geometry() hasIntersections = False lines = spatialIndex.intersects(inGeom.boundingBox()) if len(lines) > 0: hasIntersections = True if hasIntersections: for i in lines: request = QgsFeatureRequest().setFilterFid(i) inFeatB = layerB.getFeatures(request).next() tmpGeom = QgsGeometry(inFeatB.geometry()) points = [] attrsA = inFeatA.attributes() attrsB = inFeatB.attributes() if inGeom.intersects(tmpGeom): tempGeom = inGeom.intersection(tmpGeom) if tempGeom.type() == QGis.Point: if tempGeom.isMultipart(): points = tempGeom.asMultiPoint() else: points.append(tempGeom.asPoint()) for j in points: outFeat.setGeometry(tempGeom.fromPoint(j)) outFeat.setAttributes([attrsA[idxA], attrsB[idxB]]) writer.addFeature(outFeat) current += 1 progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): layerA = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_A)) splitLayer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_B)) sameLayer = self.getParameterValue( self.INPUT_A) == self.getParameterValue(self.INPUT_B) fieldList = layerA.fields() writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fieldList, layerA.wkbType(), layerA.crs()) spatialIndex = QgsSpatialIndex() splitGeoms = {} request = QgsFeatureRequest() request.setSubsetOfAttributes([]) for aSplitFeature in vector.features(splitLayer, request): splitGeoms[aSplitFeature.id()] = aSplitFeature.geometry() spatialIndex.insertFeature(aSplitFeature) # honor the case that user has selection on split layer and has setting "use selection" outFeat = QgsFeature() features = vector.features(layerA) if len(features) == 0: total = 100 else: total = 100.0 / float(len(features)) multiGeoms = 0 # how many multi geometries were encountered for current, inFeatA in enumerate(features): inGeom = inFeatA.geometry() if inGeom.isMultipart(): multiGeoms += 1 # MultiGeometries are not allowed because the result of a splitted part cannot be clearly defined: # 1) add both new parts as new features # 2) store one part as a new feature and the other one as part of the multi geometry # 2a) which part should be which, seems arbitrary else: attrsA = inFeatA.attributes() outFeat.setAttributes(attrsA) inGeoms = [inGeom] lines = spatialIndex.intersects(inGeom.boundingBox()) if len(lines) > 0: # has intersection of bounding boxes splittingLines = [] engine = QgsGeometry.createGeometryEngine( inGeom.geometry()) engine.prepareGeometry() for i in lines: try: splitGeom = splitGeoms[i] except: continue # check if trying to self-intersect if sameLayer: if inFeatA.id() == i: continue if engine.intersects(splitGeom.geometry()): splittingLines.append(splitGeom) if len(splittingLines) > 0: for splitGeom in splittingLines: splitterPList = None outGeoms = [] split_geom_engine = QgsGeometry.createGeometryEngine( splitGeom.geometry()) split_geom_engine.prepareGeometry() while len(inGeoms) > 0: inGeom = inGeoms.pop() if split_geom_engine.intersects( inGeom.geometry()): inPoints = vector.extractPoints(inGeom) if splitterPList == None: splitterPList = vector.extractPoints( splitGeom) try: result, newGeometries, topoTestPoints = inGeom.splitGeometry( splitterPList, False) except: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self. tr('Geometry exception while splitting' )) result = 1 # splitGeometry: If there are several intersections # between geometry and splitLine, only the first one is considered. if result == 0: # split occurred if inPoints == vector.extractPoints( inGeom): # bug in splitGeometry: sometimes it returns 0 but # the geometry is unchanged QgsMessageLog.logMessage( "appending") outGeoms.append(inGeom) else: inGeoms.append(inGeom) for aNewGeom in newGeometries: inGeoms.append(aNewGeom) else: QgsMessageLog.logMessage( "appending else") outGeoms.append(inGeom) else: outGeoms.append(inGeom) inGeoms = outGeoms for aGeom in inGeoms: passed = True if QgsWkbTypes.geometryType( aGeom.wkbType() ) == QgsWkbTypes.LineGeometry \ and not QgsWkbTypes.isMultiType(aGeom.wkbType()): passed = len(aGeom.asPolyline()) > 2 if not passed: passed = (len(aGeom.asPolyline()) == 2 and aGeom.asPolyline()[0] != aGeom.asPolyline()[1]) # sometimes splitting results in lines of zero length if passed: outFeat.setGeometry(aGeom) writer.addFeature(outFeat) progress.setPercentage(int(current * total)) if multiGeoms > 0: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self. tr('Feature geometry error: %s input features ignored due to multi-geometry.' ) % str(multiGeoms)) del writer
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue(self.POINTS)) weightField = self.getParameterValue(self.WEIGHT) uniqueField = self.getParameterValue(self.UID) if weightField is None: weightIndex = -1 else: weightIndex = layer.fieldNameIndex(weightField) if uniqueField is None: uniqueIndex = -1 else: uniqueIndex = layer.fieldNameIndex(uniqueField) fieldList = [QgsField('MEAN_X', QVariant.Double, '', 24, 15), QgsField('MEAN_Y', QVariant.Double, '', 24, 15), QgsField('UID', QVariant.String, '', 255)] writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fieldList, QgsWkbTypes.Point, layer.crs() ) features = vector.features(layer) total = 100.0 / len(features) means = {} for current, feat in enumerate(features): progress.setPercentage(int(current * total)) if uniqueIndex == -1: clazz = "Single class" else: clazz = unicode(feat.attributes()[uniqueIndex]).strip() if weightIndex == -1: weight = 1.00 else: try: weight = float(feat.attributes()[weightIndex]) except: weight = 1.00 if clazz not in means: means[clazz] = (0, 0, 0) (cx, cy, totalweight) = means[clazz] geom = QgsGeometry(feat.geometry()) geom = vector.extractPoints(geom) for i in geom: cx += i.x() * weight cy += i.y() * weight totalweight += weight means[clazz] = (cx, cy, totalweight) current = 0 total = 100.0 / len(means) for (clazz, values) in means.iteritems(): outFeat = QgsFeature() cx = values[0] / values[2] cy = values[1] / values[2] meanPoint = QgsPoint(cx, cy) outFeat.setGeometry(QgsGeometry.fromPoint(meanPoint)) outFeat.setAttributes([cx, cy, clazz]) writer.addFeature(outFeat) current += 1 progress.setPercentage(int(current * total)) del writer