def testAddMultipleFeatures(self): # test adding multiple features to an edit buffer layer = createEmptyLayer() self.assertTrue(layer.startEditing()) self.assertEqual(layer.editBuffer().addedFeatures(), {}) self.assertFalse(layer.editBuffer().isFeatureAdded(1)) self.assertFalse(layer.editBuffer().isFeatureAdded(3)) # add two features f1 = QgsFeature(layer.fields(), 1) f1.setGeometry(QgsGeometry.fromPoint(QgsPointXY(1, 2))) f1.setAttributes(["test", 123]) f2 = QgsFeature(layer.fields(), 2) f2.setGeometry(QgsGeometry.fromPoint(QgsPointXY(2, 4))) f2.setAttributes(["test2", 246]) self.assertTrue(layer.addFeatures([f1, f2])) # test contents of buffer added = layer.editBuffer().addedFeatures() new_feature_ids = list(added.keys()) self.assertEqual(added[new_feature_ids[0]]['fldtxt'], 'test2') self.assertEqual(added[new_feature_ids[0]]['fldint'], 246) self.assertEqual(added[new_feature_ids[1]]['fldtxt'], 'test') self.assertEqual(added[new_feature_ids[1]]['fldint'], 123) self.assertTrue(layer.editBuffer().isFeatureAdded(new_feature_ids[0])) self.assertTrue(layer.editBuffer().isFeatureAdded(new_feature_ids[1]))
def testEquals(self): myPointA = QgsGeometry.fromPoint(QgsPoint(1, 1)) myPointB = QgsGeometry.fromPoint(QgsPoint(1, 1)) equalsGeom = QgsGeometry.equals(myPointA, myPointB) myMessage = ('Expected:\n%s\nGot:\n%s\n' % ("True", equalsGeom)) assert equalsGeom == True, myMessage
def testWFSPointsMultipleEdits(self): """ Adds some points, then check. Modify 2 points, then checks and clear all """ layer_name = 'test_point' layer = self._getLayer(layer_name) wfs_layer = self._getWFSLayer(layer_name) feat1 = QgsFeature(wfs_layer.pendingFields()) feat1['id'] = 11 feat1['name'] = 'name 11' feat1.setGeometry(QgsGeometry.fromPoint(QgsPoint(9, 45))) feat2 = QgsFeature(wfs_layer.pendingFields()) feat2.setGeometry(QgsGeometry.fromPoint(QgsPoint(9.5, 45.5))) feat2['id'] = 12 feat2['name'] = 'name 12' old_features = [feat1, feat2] # Change feat1 and feat2 new_feat1 = QgsFeature(wfs_layer.pendingFields()) new_feat1['id'] = 121 new_feat1['name'] = 'name 121' new_feat1.setGeometry(QgsGeometry.fromPoint(QgsPoint(10, 46))) new_feat2 = QgsFeature(wfs_layer.pendingFields()) new_feat2['id'] = 122 new_feat2['name'] = 'name 122' new_feat2.setGeometry(QgsGeometry.fromPoint(QgsPoint(10.5, 47))) new_features = [new_feat1, new_feat2] self._testLayer(wfs_layer, layer, old_features, new_features)
def testProxyFeatureSink(self): fields = QgsFields() fields.append(QgsField('fldtxt', QVariant.String)) fields.append(QgsField('fldint', QVariant.Int)) store = QgsFeatureStore(fields, QgsCoordinateReferenceSystem()) proxy = QgsProxyFeatureSink(store) self.assertEqual(proxy.destinationSink(), store) self.assertEqual(len(store), 0) f = QgsFeature() f.setAttributes(["test", 123]) f.setGeometry(QgsGeometry.fromPoint(QgsPointXY(100, 200))) proxy.addFeature(f) self.assertEqual(len(store), 1) self.assertEqual(store.features()[0]['fldtxt'], 'test') f2 = QgsFeature() f2.setAttributes(["test2", 457]) f2.setGeometry(QgsGeometry.fromPoint(QgsPointXY(200, 200))) f3 = QgsFeature() f3.setAttributes(["test3", 888]) f3.setGeometry(QgsGeometry.fromPoint(QgsPointXY(300, 200))) proxy.addFeatures([f2, f3]) self.assertEqual(len(store), 3) self.assertEqual(store.features()[1]['fldtxt'], 'test2') self.assertEqual(store.features()[2]['fldtxt'], 'test3')
def testDeleteMultipleFeatures(self): # test deleting multiple features from an edit buffer # make a layer with two features layer = createEmptyLayer() self.assertTrue(layer.startEditing()) # add two features f1 = QgsFeature(layer.fields(), 1) f1.setGeometry(QgsGeometry.fromPoint(QgsPointXY(1, 2))) f1.setAttributes(["test", 123]) self.assertTrue(layer.addFeature(f1)) f2 = QgsFeature(layer.fields(), 2) f2.setGeometry(QgsGeometry.fromPoint(QgsPointXY(2, 4))) f2.setAttributes(["test2", 246]) self.assertTrue(layer.addFeature(f2)) layer.commitChanges() layer.startEditing() self.assertEqual(layer.editBuffer().deletedFeatureIds(), []) self.assertFalse(layer.editBuffer().isFeatureDeleted(1)) self.assertFalse(layer.editBuffer().isFeatureDeleted(2)) # delete features layer.deleteFeatures([1, 2]) # test contents of buffer self.assertEqual(set(layer.editBuffer().deletedFeatureIds()), set([1, 2])) self.assertTrue(layer.editBuffer().isFeatureDeleted(1)) self.assertTrue(layer.editBuffer().isFeatureDeleted(2))
def calculateSquare(self, point): ''' point in layer coordinates(QgsPoint) ''' mapCrs = self.canvas.mapSettings().destinationCrs() utmCrs = QgsCoordinateReferenceSystem() utmCrs.createFromProj4(self.proj4Utm(point)) ctFwd = QgsCoordinateTransform(mapCrs, utmCrs) ctBwd = QgsCoordinateTransform(utmCrs, mapCrs) pointGeom = QgsGeometry.fromPoint(point) pointGeom.transform(ctFwd) pointUtm = QgsPoint(pointGeom.asPoint()) # calculate d d = self.diagonal/(2*(2**0.5)) l = pointUtm.x() - d b = pointUtm.y() - d r = pointUtm.x() + d t = pointUtm.y() + d p1 = QgsGeometry.fromPoint(QgsPoint(l, b)) p2 = QgsGeometry.fromPoint(QgsPoint(r, b)) p3 = QgsGeometry.fromPoint(QgsPoint(r, t)) p4 = QgsGeometry.fromPoint(QgsPoint(l, t)) p1.transform(ctBwd) p2.transform(ctBwd) p3.transform(ctBwd) p4.transform(ctBwd) mapPol = [p1.asPoint(), p2.asPoint(), p3.asPoint(), p4.asPoint(), p1.asPoint()] return mapPol
def testBuffer(self): myPoint = QgsGeometry.fromPoint(QgsPoint(1, 1)) bufferGeom = myPoint.buffer(10, 5) myMessage = ('Expected:\n%s\nGot:\n%s\n' % (QGis.Polygon, bufferGeom.type())) assert bufferGeom.wkbType() == QGis.WKBPolygon, myMessage myTestPoint = QgsGeometry.fromPoint(QgsPoint(3, 3)) assert bufferGeom.intersects(myTestPoint)
def test_updateFeatures(self): ol, offline_layer = self._testInit() # Edit feature 2 feat2 = self._getFeatureByAttribute(offline_layer, 'name', "'name 2'") self.assertTrue(offline_layer.startEditing()) self.assertTrue(offline_layer.changeAttributeValue(feat2.id(), offline_layer.fieldNameIndex('name'), 'name 2 edited')) self.assertTrue(offline_layer.changeGeometry(feat2.id(), QgsGeometry.fromPoint(QgsPoint(33.0, 60.0)))) self.assertTrue(offline_layer.commitChanges()) feat2 = self._getFeatureByAttribute(offline_layer, 'name', "'name 2 edited'") self.assertTrue(ol.isOfflineProject()) # Sync ol.synchronize() sleep(2) # Does anybody know why the sleep is needed? Is that a threaded WFS consequence? online_layer = list(self.registry.mapLayers().values())[0] self.assertTrue(online_layer.isValid()) self.assertFalse(online_layer.name().find('(offline)') > -1) self.assertEqual(len([f for f in online_layer.getFeatures()]), len(TEST_FEATURES)) # Check that data have changed in the backend (raise exception if not found) feat2 = self._getFeatureByAttribute(self._getLayer('test_point'), 'name', "'name 2 edited'") feat2 = self._getFeatureByAttribute(online_layer, 'name', "'name 2 edited'") self.assertEqual(feat2.geometry().asPoint().toString(), QgsPoint(33.0, 60.0).toString()) # Check that all other features have not changed layer = self._getLayer('test_point') self.assertTrue(self._compareFeature(layer, TEST_FEATURES[1 - 1])) self.assertTrue(self._compareFeature(layer, TEST_FEATURES[3 - 1])) self.assertTrue(self._compareFeature(layer, TEST_FEATURES[4 - 1])) # Test for regression on double sync (it was a SEGFAULT) # goes offline ol = QgsOfflineEditing() offline_layer = list(self.registry.mapLayers().values())[0] # Edit feature 2 feat2 = self._getFeatureByAttribute(offline_layer, 'name', "'name 2 edited'") self.assertTrue(offline_layer.startEditing()) self.assertTrue(offline_layer.changeAttributeValue(feat2.id(), offline_layer.fieldNameIndex('name'), 'name 2')) self.assertTrue(offline_layer.changeGeometry(feat2.id(), QgsGeometry.fromPoint(TEST_FEATURES[1][2]))) # Edit feat 4 feat4 = self._getFeatureByAttribute(offline_layer, 'name', "'name 4'") self.assertTrue(offline_layer.changeAttributeValue(feat4.id(), offline_layer.fieldNameIndex('name'), 'name 4 edited')) self.assertTrue(offline_layer.commitChanges()) # Sync ol.synchronize() # Does anybody knows why the sleep is needed? Is that a threaded WFS consequence? sleep(1) online_layer = list(self.registry.mapLayers().values())[0] layer = self._getLayer('test_point') # Check that data have changed in the backend (raise exception if not found) feat4 = self._getFeatureByAttribute(layer, 'name', "'name 4 edited'") feat4 = self._getFeatureByAttribute(online_layer, 'name', "'name 4 edited'") feat2 = self._getFeatureByAttribute(layer, 'name', "'name 2'") feat2 = self._getFeatureByAttribute(online_layer, 'name', "'name 2'") # Check that all other features have not changed layer = self._getLayer('test_point') self.assertTrue(self._compareFeature(layer, TEST_FEATURES[1 - 1])) self.assertTrue(self._compareFeature(layer, TEST_FEATURES[2 - 1])) self.assertTrue(self._compareFeature(layer, TEST_FEATURES[3 - 1]))
def legend_test(self): self.mAtlasMap.setAtlasDriven(True) self.mAtlasMap.setAtlasScalingMode(QgsComposerMap.Auto) self.mAtlasMap.setAtlasMargin(0.10) # add a point layer ptLayer = QgsVectorLayer("Point?crs=epsg:4326&field=attr:int(1)&field=label:string(20)", "points", "memory") pr = ptLayer.dataProvider() f1 = QgsFeature(1) f1.initAttributes(2) f1.setAttribute(0, 1) f1.setAttribute(1, "Test label 1") f1.setGeometry(QgsGeometry.fromPoint(QgsPointXY(-0.638, 48.954))) f2 = QgsFeature(2) f2.initAttributes(2) f2.setAttribute(0, 2) f2.setAttribute(1, "Test label 2") f2.setGeometry(QgsGeometry.fromPoint(QgsPointXY(-1.682, 48.550))) pr.addFeatures([f1, f2]) # categorized symbology r = QgsCategorizedSymbolRenderer("attr", [QgsRendererCategory(1, QgsMarkerSymbol.createSimple({"color": "255,0,0"}), "red"), QgsRendererCategory(2, QgsMarkerSymbol.createSimple({"color": "0,0,255"}), "blue")]) ptLayer.setRenderer(r) QgsProject.instance().addMapLayer(ptLayer) # add the point layer to the map settings layers = self.layers layers = [ptLayer] + layers self.mAtlasMap.setLayers(layers) self.mOverview.setLayers(layers) # add a legend legend = QgsComposerLegend(self.mComposition) legend.moveBy(200, 100) # sets the legend filter parameter legend.setComposerMap(self.mAtlasMap) legend.setLegendFilterOutAtlas(True) self.mComposition.addComposerLegend(legend) self.mAtlas.beginRender() self.mAtlas.prepareForFeature(0) self.mLabel1.adjustSizeToText() checker = QgsCompositionChecker('atlas_legend', self.mComposition) myTestResult, myMessage = checker.testComposition() assert myTestResult self.mAtlas.endRender() # restore state self.mAtlasMap.setLayers([layers[1]]) self.mComposition.removeComposerItem(legend) QgsProject.instance().removeMapLayer(ptLayer.id())
def createJoinLayer(): joinLayer = QgsVectorLayer("Point?field=x:string&field=y:integer&field=z:integer", "joinlayer", "memory") pr = joinLayer.dataProvider() f1 = QgsFeature() f1.setAttributes([QVariant("foo"), QVariant(123), QVariant(321)]) f1.setGeometry(QgsGeometry.fromPoint(QgsPoint(1,1))) f2 = QgsFeature() f2.setAttributes([QVariant("bar"), QVariant(456), QVariant(654)]) f2.setGeometry(QgsGeometry.fromPoint(QgsPoint(2,2))) assert pr.addFeatures([f1, f2]) assert joinLayer.pendingFeatureCount() == 2 return joinLayer
def testAddFeatures(self): # test adding features to an edit buffer layer = createEmptyLayer() self.assertTrue(layer.startEditing()) self.assertEqual(layer.editBuffer().addedFeatures(), {}) self.assertFalse(layer.editBuffer().isFeatureAdded(1)) self.assertFalse(layer.editBuffer().isFeatureAdded(3)) # add two features f1 = QgsFeature(layer.fields(), 1) f1.setGeometry(QgsGeometry.fromPoint(QgsPointXY(1, 2))) f1.setAttributes(["test", 123]) self.assertTrue(layer.addFeature(f1)) f2 = QgsFeature(layer.fields(), 2) f2.setGeometry(QgsGeometry.fromPoint(QgsPointXY(2, 4))) f2.setAttributes(["test2", 246]) self.assertTrue(layer.addFeature(f2)) # test contents of buffer added = layer.editBuffer().addedFeatures() new_feature_ids = list(added.keys()) self.assertEqual(added[new_feature_ids[0]]['fldtxt'], 'test2') self.assertEqual(added[new_feature_ids[0]]['fldint'], 246) self.assertEqual(added[new_feature_ids[1]]['fldtxt'], 'test') self.assertEqual(added[new_feature_ids[1]]['fldint'], 123) self.assertTrue(layer.editBuffer().isFeatureAdded(new_feature_ids[0])) self.assertTrue(layer.editBuffer().isFeatureAdded(new_feature_ids[1])) # check if error in case adding not adaptable geometry # eg. a Multiline in a Line layer = createEmptyLinestringLayer() self.assertTrue(layer.startEditing()) self.assertEqual(layer.editBuffer().addedFeatures(), {}) self.assertFalse(layer.editBuffer().isFeatureAdded(1)) self.assertFalse(layer.editBuffer().isFeatureAdded(3)) # add a features with a multi line geometry of not touched lines => # cannot be forced to be linestring multiline = [ [QgsPointXY(1, 1), QgsPointXY(2, 2)], [QgsPointXY(3, 3), QgsPointXY(4, 4)], ] f1 = QgsFeature(layer.fields(), 1) f1.setGeometry(QgsGeometry.fromMultiPolyline(multiline)) f1.setAttributes(["test", 123]) self.assertTrue(layer.addFeatures([f1])) self.assertFalse(layer.commitChanges())
def createReferencingLayer(): layer = QgsVectorLayer("Point?field=fldtxt:string&field=foreignkey:integer", "referencinglayer", "memory") pr = layer.dataProvider() f1 = QgsFeature() f1.setFields(layer.pendingFields()) f1.setAttributes(["test1", 123]) f1.setGeometry(QgsGeometry.fromPoint(QgsPoint(100, 200))) f2 = QgsFeature() f2.setFields(layer.pendingFields()) f2.setAttributes(["test2", 123]) f2.setGeometry(QgsGeometry.fromPoint(QgsPoint(101, 201))) assert pr.addFeatures([f1, f2]) return layer
def _exportAndCreateConflictWithNulls(): layer = checkoutLayer(tests._lastRepo, "points", None) idx = layer.dataProvider().fieldNameIndex("n") features = list(layer.getFeatures()) with edit(layer): layer.changeGeometry(features[0].id(), QgsGeometry.fromPoint(QgsPoint(123, 456))) layer.changeAttributeValue(features[0].id(), idx, None) filename = tempFilename("gpkg") tests._lastRepo.checkoutlayer(filename, "points") layer2 = loadLayerNoCrsDialog(filename, "points2", "ogr") features2 = list(layer2.getFeatures()) with edit(layer2): layer2.changeGeometry(features[0].id(), QgsGeometry.fromPoint(QgsPoint(124, 457))) layer2.changeAttributeValue(features2[0].id(), idx, None) _, _, conflicts, _ = tests._lastRepo.importgeopkg(layer2, "master", "message", "me", "*****@*****.**", True)
def test_SetGeometry(self): feat = QgsFeature() feat.setGeometry(QgsGeometry.fromPoint(QgsPoint(123, 456))) myGeometry = feat.geometry() myExpectedGeometry = "!None" myMessage = "\nExpected: %s\nGot: %s" % (myExpectedGeometry, myGeometry) assert myGeometry is not None, myMessage
def processAlgorithm(self, progress): source = self.getParameterValue(self.INPUT) vlayer = dataobjects.getObjectFromUri(source) output = self.getOutputFromName(self.OUTPUT) vprovider = vlayer.dataProvider() fields = vprovider.fields() writer = output.getVectorWriter(fields, QGis.WKBPoint, self.crs) xfieldindex = vlayer.fieldNameIndex(self.getParameterValue(self.XFIELD)) yfieldindex = vlayer.fieldNameIndex(self.getParameterValue(self.YFIELD)) crsId = self.getParameterValue(self.TARGET_CRS) targetCrs = QgsCoordinateReferenceSystem() targetCrs.createFromUserInput(crsId) self.crs = targetCrs outFeat = QgsFeature() nElement = 0 features = vector.features(vlayer) nFeat = len(features) for feature in features: nElement += 1 progress.setPercentage(nElement * 100 / nFeat) attrs = feature.attributes() try: x = float(attrs[xfieldindex]) y = float(attrs[yfieldindex]) except: continue pt = QgsPoint(x, y) outFeat.setGeometry(QgsGeometry.fromPoint(pt)) outFeat.setAttributes(attrs) writer.addFeature(outFeat) del writer
def extract_nodes( self ): vprovider = self.vlayer.dataProvider() writer = QgsVectorFileWriter( self.myName, self.myEncoding, vprovider.fields(), QGis.WKBPoint, vprovider.crs() ) inFeat = QgsFeature() outFeat = QgsFeature() inGeom = QgsGeometry() outGeom = QgsGeometry() nFeat = vprovider.featureCount() nElement = 0 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0 ) self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, nFeat ) ) fit = vprovider.getFeatures() while fit.nextFeature( inFeat ): nElement += 1 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), nElement ) inGeom = inFeat.geometry() atMap = inFeat.attributes() pointList = ftools_utils.extractPoints( inGeom ) outFeat.setAttributes( atMap ) for i in pointList: outFeat.setGeometry( outGeom.fromPoint( i ) ) writer.addFeature( outFeat ) del writer return True
def processAlgorithm(self, parameters, context, feedback): if parameters[self.INPUT] == parameters[self.HUBS]: raise QgsProcessingException( self.tr('Same layer given for both hubs and spokes')) point_source = self.parameterAsSource(parameters, self.INPUT, context) hub_source = self.parameterAsSource(parameters, self.HUBS, context) fieldName = self.parameterAsString(parameters, self.FIELD, context) units = self.UNITS[self.parameterAsEnum(parameters, self.UNIT, context)] fields = point_source.fields() fields.append(QgsField('HubName', QVariant.String)) fields.append(QgsField('HubDist', QVariant.Double)) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.Point, point_source.sourceCrs()) index = QgsSpatialIndex(hub_source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([]).setDestinationCrs(point_source.sourceCrs()))) distance = QgsDistanceArea() distance.setSourceCrs(point_source.sourceCrs()) distance.setEllipsoid(context.project().ellipsoid()) # Scan source points, find nearest hub, and write to output file features = point_source.getFeatures() total = 100.0 / point_source.featureCount() if point_source.featureCount() else 0 for current, f in enumerate(features): if feedback.isCanceled(): break if not f.hasGeometry(): sink.addFeature(f, QgsFeatureSink.FastInsert) continue src = f.geometry().boundingBox().center() neighbors = index.nearestNeighbor(src, 1) ft = next(hub_source.getFeatures(QgsFeatureRequest().setFilterFid(neighbors[0]).setSubsetOfAttributes([fieldName], hub_source.fields()).setDestinationCrs(point_source.sourceCrs()))) closest = ft.geometry().boundingBox().center() hubDist = distance.measureLine(src, closest) if units != self.LAYER_UNITS: hub_dist_in_desired_units = distance.convertLengthMeasurement(hubDist, units) else: hub_dist_in_desired_units = hubDist attributes = f.attributes() attributes.append(ft[fieldName]) attributes.append(hub_dist_in_desired_units) feat = QgsFeature() feat.setAttributes(attributes) feat.setGeometry(QgsGeometry.fromPoint(src)) sink.addFeature(feat, QgsFeatureSink.FastInsert) feedback.setProgress(int(current * total)) return {self.OUTPUT: dest_id}
def testIndex(self): idx = QgsSpatialIndex() fid = 0 for y in range(5, 15, 5): for x in range(5, 25, 5): ft = QgsFeature() ft.setFeatureId(fid) ft.setGeometry(QgsGeometry.fromPoint(QgsPoint(x, y))) idx.insertFeature(ft) fid += 1 # intersection test rect = QgsRectangle(7.0, 3.0, 17.0, 13.0) fids = idx.intersects(rect) myExpectedValue = 4 myValue = len(fids) myMessage = 'Expected: %s Got: %s' % (myExpectedValue, myValue) self.assertEqual(myValue, myExpectedValue, myMessage) fids.sort() myMessage = ('Expected: %s\nGot: %s\n' % ([1, 2, 5, 6], fids)) assert fids == [1, 2, 5, 6], myMessage # nearest neighbor test fids = idx.nearestNeighbor(QgsPoint(8.75, 6.25), 3) myExpectedValue = 0 myValue = len(fids) myMessage = 'Expected: %s Got: %s' % (myExpectedValue, myValue) fids.sort() myMessage = ('Expected: %s\nGot: %s\n' % ([0, 1, 5], fids)) assert fids == [0, 1, 5], myMessage
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context) fields = layer.fields() fields.append(QgsField('node_index', QVariant.Int)) fields.append(QgsField('distance', QVariant.Double)) fields.append(QgsField('angle', QVariant.Double)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.Point, layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, f in enumerate(features): input_geometry = f.geometry() if not input_geometry: writer.addFeature(f) else: points = vector.extractPoints(input_geometry) for i, point in enumerate(points): distance = input_geometry.distanceToVertex(i) angle = math.degrees(input_geometry.angleAtVertex(i)) attrs = f.attributes() attrs.append(i) attrs.append(distance) attrs.append(angle) output_feature = QgsFeature() output_feature.setAttributes(attrs) output_feature.setGeometry(QgsGeometry.fromPoint(point)) writer.addFeature(output_feature) feedback.setProgress(int(current * total)) del writer
def testSettingFeature(self): """ test that feature is set when item moves """ a = QgsTextAnnotation() a.setFrameSize(QSizeF(300, 200)) a.setFrameOffsetFromReferencePoint(QPointF(40, 50)) a.setHasFixedMapPosition(True) a.setMapPosition(QgsPointXY(12, 34)) a.setMapPositionCrs(QgsCoordinateReferenceSystem(4326)) canvas = QgsMapCanvas() canvas.setDestinationCrs(QgsCoordinateReferenceSystem(4326)) canvas.setFrameStyle(0) canvas.resize(600, 400) canvas.setExtent(QgsRectangle(10, 30, 20, 35)) i = QgsMapCanvasAnnotationItem(a, canvas) # NOQA layer = QgsVectorLayer("Point?crs=EPSG:4326&field=station:string&field=suburb:string", 'test', "memory") canvas.setLayers([layer]) f = QgsFeature(layer.fields()) f.setGeometry(QgsGeometry.fromPoint(QgsPointXY(14, 31))) f.setValid(True) f.setAttributes(['hurstbridge', 'somewhere']) self.assertTrue(layer.dataProvider().addFeatures([f])) a.setMapLayer(layer) self.assertFalse(a.associatedFeature().isValid()) a.setMapPosition(QgsPointXY(14, 31)) self.assertTrue(a.associatedFeature().isValid()) self.assertEqual(a.associatedFeature().attributes()[0], 'hurstbridge') a.setMapPosition(QgsPointXY(17, 31)) self.assertFalse(a.associatedFeature().isValid())
def _create_points(self): """Create points for testing""" point_layer = QgsVectorLayer('Point?crs=EPSG:4326', 'points', 'memory') point_provider = point_layer.dataProvider() point_provider.addAttributes([QgsField('X', QVariant.Double)]) point_provider.addAttributes([QgsField('Y', QVariant.Double)]) x_index = point_provider.fieldNameIndex('X') y_index = point_provider.fieldNameIndex('Y') point_layer.startEditing() for x in [10.0, 20.0, 30.0]: for y in [10.0, 20.0, 30.0]: feature = QgsFeature() feature.initAttributes(2) feature.setAttribute(x_index, x) feature.setAttribute(y_index, y) # noinspection PyCallByClass geom = QgsGeometry.fromPoint(QgsPoint(x, y)) feature.setGeometry(geom) _ = point_layer.dataProvider().addFeatures([feature]) point_layer.commitChanges() return point_layer
def _write_grid_shapefile(self, path, x_min, y_min, x_max, y_max, x_off, y_off): x_off = self._x_off y_off = self._y_off x_min = floor(x_min / x_off) * x_off x_max = ceil(x_max / x_off) * x_off y_min = floor(y_min / y_off) * y_off y_max = ceil(y_max / y_off) * y_off xtotal = int((x_max - x_min) / x_off) ytotal = int((y_max - y_min) / y_off) logAPICall.log('x_min %f x_max %f y_min %f y_max %f x_off %f y_off %f xtotal %d, ytotal %d' % (x_min, x_max, y_min, y_max, x_off, y_off, xtotal, ytotal), logAPICall.DEBUG_L2) writer = QgsVectorFileWriter(path, "utf-8", self._fields, QGis.WKBPoint, self._crs, "ESRI Shapefile") f = QgsFeature() for x in range(xtotal): for y in range(ytotal): lon = x_min + (x * x_off) + (x_off/2.0) lat = y_min + (y * y_off) + (y_off/2.0) f.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon, lat))) f.addAttribute(0, QVariant(lon)) f.addAttribute(1, QVariant(lat)) writer.addFeature(f) del writer
def postionupdated(self, position, info): if not self.logging or not self.layer or not self.layerprovider: return feature = QgsFeature() feature.setFields(self.fields) for field in self.fields: name = field.name() if name == 'time': value = self.gps.gpsinfo('utcDateTime').toString(Qt.ISODate) elif name == 'localtime': value = QDateTime.currentDateTime().toString(Qt.ISODate) elif name == 'user': value = getpass.getuser() else: try: value = self.gps.gpsinfo(name) except AttributeError: continue feature[name] = value geom = QgsGeometry.fromPoint(position) feature.setGeometry(geom) self.featurecache.append(feature) if len(self.featurecache) > 5: self.layerprovider.addFeatures(self.featurecache) self.featurecache = []
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT)) fields = layer.fields() fields.append(QgsField("node_index", QVariant.Int)) fields.append(QgsField("distance", QVariant.Double)) fields.append(QgsField("angle", QVariant.Double)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.Point, layer.crs()) 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: points = vector.extractPoints(input_geometry) for i, point in enumerate(points): distance = input_geometry.distanceToVertex(i) angle = math.degrees(input_geometry.angleAtVertex(i)) attrs = f.attributes() attrs.append(i) attrs.append(distance) attrs.append(angle) output_feature = QgsFeature() output_feature.setAttributes(attrs) output_feature.setGeometry(QgsGeometry.fromPoint(point)) writer.addFeature(output_feature) progress.setPercentage(int(current * total)) del writer
def test_InvalidOperations(self): layer = createLayerWithOnePoint() layer.startEditing() # ADD FEATURE newF1 = QgsFeature() assert not layer.addFeature(newF1) # need attributes like the layer has # DELETE FEATURE assert not layer.deleteFeature(-333) # we do not check for existence of the feature id if it's # not newly added feature #assert not layer.deleteFeature(333) # CHANGE GEOMETRY assert not layer.changeGeometry( -333, QgsGeometry.fromPoint(QgsPoint(1, 1))) # CHANGE VALUE assert not layer.changeAttributeValue(-333, 0, 1) assert not layer.changeAttributeValue(1, -1, 1) # ADD ATTRIBUTE assert not layer.addAttribute(QgsField()) # DELETE ATTRIBUTE assert not layer.deleteAttribute(-1)
def processAlgorithm(self, progress): source = self.getParameterValue(self.INPUT) vlayer = dataobjects.getObjectFromUri(source) output = self.getOutputFromName(self.OUTPUT) fields = vlayer.fields() writer = output.getVectorWriter(fields, QgsWkbTypes.Point, self.crs) xfieldindex = vlayer.fieldNameIndex(self.getParameterValue(self.XFIELD)) yfieldindex = vlayer.fieldNameIndex(self.getParameterValue(self.YFIELD)) crsId = self.getParameterValue(self.TARGET_CRS) targetCrs = QgsCoordinateReferenceSystem() targetCrs.createFromUserInput(crsId) self.crs = targetCrs outFeat = QgsFeature() features = vector.features(vlayer) total = 100.0 / len(features) for current, feature in enumerate(features): progress.setPercentage(int(current * total)) attrs = feature.attributes() try: x = float(attrs[xfieldindex]) y = float(attrs[yfieldindex]) except: continue pt = QgsPoint(x, y) outFeat.setGeometry(QgsGeometry.fromPoint(pt)) outFeat.setAttributes(attrs) writer.addFeature(outFeat) del writer
def create_layer(self, data): display_name = 'some-layer' uri = 'Point?crs=epsg:4326&index=yes&uuid=%s' % uuid.uuid4() vlayer = QgsVectorLayer(uri, display_name, 'memory') QgsMapLayerRegistry.instance().addMapLayer(vlayer) provider = vlayer.dataProvider() vlayer.startEditing() provider.addAttributes([ QgsField('population_density', QtCore.QVariant.Double), ]) features = [] for x, y, density in data: feat = QgsFeature() geom = QgsGeometry.fromPoint(QgsPoint(x, y)) feat.setGeometry(geom) feat.setAttributes([density]) features.append(feat) provider.addFeatures(features) vlayer.commitChanges() vlayer.updateExtents() self.canvas.setExtent(vlayer.extent()) cl = QgsMapCanvasLayer(vlayer) self.canvas.setLayerSet([cl]) vlayer.triggerRepaint()
def displayUTM(self): ''' Show UTM location on the canvas when set it in the relative tab ''' X = self.dlg.txtCoordX.text() if not X: message = "Coordinate X not specified" self.iface.messageBar().pushMessage(message, QgsMessageBar.WARNING, 5) return Y = self.dlg.txtCoordY.text() if not Y: message = "Coordinate Y not specified" self.iface.messageBar().pushMessage(message, QgsMessageBar.WARNING, 5) return # check if coordinates are within the interval valX = self.validateX() if not valX: message = "Coordinate X is out of the valid interval. It should be between "+str(self.xMinVal)+" and "+str(self.xMaxVal) self.iface.messageBar().pushMessage(message, QgsMessageBar.WARNING, 5) return valY = self.validateY() if not valY: message = "Coordinate Y is out of the valid interval, It should be between "+str(self.yMinVal)+" and "+str(self.yMaxVal) self.iface.messageBar().pushMessage(message, QgsMessageBar.WARNING, 5) return geom = QgsGeometry.fromPoint(QgsPoint(float(X), float(Y))) message = 'X: {}\nY: {}'.format(X,Y) # display annotation with message at a specified position self.displayAnnotation(geom, message)
def testRenameAttributes(self): layer = QgsVectorLayer("Point", "test", "memory") provider = layer.dataProvider() res = provider.addAttributes( [QgsField("name", QVariant.String), QgsField("age", QVariant.Int), QgsField("size", QVariant.Double)] ) layer.updateFields() assert res, "Failed to add attributes" ft = QgsFeature() ft.setGeometry(QgsGeometry.fromPoint(QgsPoint(10, 10))) ft.setAttributes(["Johny", 20, 0.3]) res, t = provider.addFeatures([ft]) # bad rename self.assertFalse(provider.renameAttributes({-1: "not_a_field"})) self.assertFalse(provider.renameAttributes({100: "not_a_field"})) # already exists self.assertFalse(provider.renameAttributes({1: "name"})) # rename one field self.assertTrue(provider.renameAttributes({1: "this_is_the_new_age"})) self.assertEqual(provider.fields().at(1).name(), "this_is_the_new_age") layer.updateFields() fet = next(layer.getFeatures()) self.assertEqual(fet.fields()[1].name(), "this_is_the_new_age") # rename two fields self.assertTrue(provider.renameAttributes({1: "mapinfo_is_the_stone_age", 2: "super_size"})) self.assertEqual(provider.fields().at(1).name(), "mapinfo_is_the_stone_age") self.assertEqual(provider.fields().at(2).name(), "super_size") layer.updateFields() fet = next(layer.getFeatures()) self.assertEqual(fet.fields()[1].name(), "mapinfo_is_the_stone_age") self.assertEqual(fet.fields()[2].name(), "super_size")
def prepare_ordered_marker(self, coords, idx): """ Try to display nice marker on a point layer, showing the order of the path computed by OSRM. """ self.tsp_marker_lr = QgsVectorLayer( "Point?crs=epsg:4326&field=id:integer" "&field=TSP_nb:integer(20)&field=Origin_nb:integer(20)", "tsp_markers_osrm{}".format(self.nb_route), "memory") symbol = QgsSymbolV2.defaultSymbol(self.tsp_marker_lr.geometryType()) symbol.setSize(4.5) symbol.setColor(QtGui.QColor("yellow")) ordered_pts = \ [coords[i["waypoint_index"]] for i in self.parsed['waypoints']] print("ordered_pts : ", ordered_pts) features = [] for nb, pt in enumerate(ordered_pts): ft = QgsFeature() ft.setGeometry(QgsGeometry.fromPoint(QgsPoint(pt))) ft.setAttributes([nb, nb + 1, coords.index(pt)]) features.append(ft) self.tsp_marker_lr.dataProvider().addFeatures(features) pal_lyr = QgsPalLayerSettings() pal_lyr.readFromLayer(self.tsp_marker_lr) pal_lyr.enabled = True pal_lyr.fieldName = 'TSP_nb' pal_lyr.placement= QgsPalLayerSettings.OverPoint pal_lyr.setDataDefinedProperty(QgsPalLayerSettings.Size,True,True,'12','') pal_lyr.writeToLayer(self.tsp_marker_lr) self.tsp_marker_lr.setRendererV2(QgsSingleSymbolRendererV2(symbol)) QgsMapLayerRegistry.instance().addMapLayer(self.tsp_marker_lr)
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) strategy = self.parameterAsEnum(parameters, self.STRATEGY, context) minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE, context) expression = QgsExpression( self.parameterAsString(parameters, self.EXPRESSION, context)) if expression.hasParserError(): raise ProcessingException(expression.parserErrorString()) expressionContext = self.createExpressionContext(parameters, context) if not expression.prepare(expressionContext): raise ProcessingException( self.tr('Evaluation error: {0}').format( expression.evalErrorString())) fields = QgsFields() fields.append(QgsField('id', QVariant.Int, '', 10, 0)) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.Point, source.sourceCrs()) da = QgsDistanceArea() da.setSourceCrs(source.sourceCrs()) da.setEllipsoid(context.project().ellipsoid()) total = 100.0 / source.featureCount() if source.featureCount() else 0 for current, f in enumerate(source.getFeatures()): if feedback.isCanceled(): break expressionContext.setFeature(f) value = expression.evaluate(expressionContext) if expression.hasEvalError(): feedback.pushInfo( self.tr('Evaluation error for feature ID {}: {}').format( f.id(), expression.evalErrorString())) continue fGeom = f.geometry() bbox = fGeom.boundingBox() if strategy == 0: pointCount = int(value) else: pointCount = int(round(value * da.measureArea(fGeom))) if pointCount == 0: feedback.pushInfo( "Skip feature {} as number of points for it is 0.") continue index = QgsSpatialIndex() points = dict() nPoints = 0 nIterations = 0 maxIterations = pointCount * 200 total = 100.0 / pointCount if pointCount else 1 random.seed() while nIterations < maxIterations and nPoints < pointCount: if feedback.isCanceled(): break rx = bbox.xMinimum() + bbox.width() * random.random() ry = bbox.yMinimum() + bbox.height() * random.random() p = QgsPointXY(rx, ry) geom = QgsGeometry.fromPoint(p) if geom.within(fGeom) and \ vector.checkMinDistance(p, index, minDistance, points): f = QgsFeature(nPoints) f.initAttributes(1) f.setFields(fields) f.setAttribute('id', nPoints) f.setGeometry(geom) sink.addFeature(f, QgsFeatureSink.FastInsert) index.insertFeature(f) points[nPoints] = p nPoints += 1 feedback.setProgress(int(nPoints * total)) nIterations += 1 if nPoints < pointCount: feedback.pushInfo( self.tr('Could not generate requested number of random ' 'points. Maximum number of attempts exceeded.')) feedback.setProgress(0) return {self.OUTPUT: dest_id}
def testDateTimeWriteShapefile(self): """Check writing date and time fields to an ESRI shapefile.""" ml = QgsVectorLayer( ('Point?crs=epsg:4326&field=id:int&' 'field=date_f:date&field=time_f:time&field=dt_f:datetime'), 'test', 'memory') self.assertTrue(ml.isValid()) provider = ml.dataProvider() self.assertIsNotNone(provider) ft = QgsFeature() ft.setGeometry(QgsGeometry.fromPoint(QgsPointXY(10, 10))) ft.setAttributes([ 1, QDate(2014, 3, 5), QTime(13, 45, 22), QDateTime(QDate(2014, 3, 5), QTime(13, 45, 22)) ]) res, features = provider.addFeatures([ft]) self.assertTrue(res) self.assertTrue(features) dest_file_name = os.path.join(str(QDir.tempPath()), 'datetime.shp') crs = QgsCoordinateReferenceSystem() crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile') self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message) # Open result and check created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name), 'test', 'ogr') fields = created_layer.dataProvider().fields() self.assertEqual( fields.at(fields.indexFromName('date_f')).type(), QVariant.Date) # shapefiles do not support time types, result should be string self.assertEqual( fields.at(fields.indexFromName('time_f')).type(), QVariant.String) # shapefiles do not support datetime types, result should be string self.assertEqual( fields.at(fields.indexFromName('dt_f')).type(), QVariant.String) f = next(created_layer.getFeatures(QgsFeatureRequest())) date_idx = created_layer.fields().lookupField('date_f') self.assertIsInstance(f.attributes()[date_idx], QDate) self.assertEqual(f.attributes()[date_idx], QDate(2014, 3, 5)) time_idx = created_layer.fields().lookupField('time_f') # shapefiles do not support time types self.assertIsInstance(f.attributes()[time_idx], str) self.assertEqual(f.attributes()[time_idx], '13:45:22') # shapefiles do not support datetime types datetime_idx = created_layer.fields().lookupField('dt_f') self.assertIsInstance(f.attributes()[datetime_idx], str) self.assertEqual( f.attributes()[datetime_idx], QDateTime(QDate(2014, 3, 5), QTime(13, 45, 22)).toString("yyyy/MM/dd hh:mm:ss.zzz"))
def doCheck(self, method, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT_LAYER, context) (valid_output_sink, valid_output_dest_id) = self.parameterAsSink(parameters, self.VALID_OUTPUT, context, source.fields(), source.wkbType(), source.sourceCrs()) valid_count = 0 invalid_fields = source.fields() invalid_fields.append(QgsField('_errors', QVariant.String, 'string', 255)) (invalid_output_sink, invalid_output_dest_id) = self.parameterAsSink(parameters, self.INVALID_OUTPUT, context, invalid_fields, source.wkbType(), source.sourceCrs()) invalid_count = 0 error_fields = QgsFields() error_fields.append(QgsField('message', QVariant.String, 'string', 255)) (error_output_sink, error_output_dest_id) = self.parameterAsSink(parameters, self.ERROR_OUTPUT, context, error_fields, QgsWkbTypes.Point, source.sourceCrs()) error_count = 0 features = source.getFeatures(QgsFeatureRequest(), QgsProcessingFeatureSource.FlagSkipGeometryValidityChecks) total = 100.0 / source.featureCount() if source.featureCount() else 0 for current, inFeat in enumerate(features): if feedback.isCanceled(): break geom = inFeat.geometry() attrs = inFeat.attributes() valid = True if not geom.isNull() and not geom.isEmpty(): errors = list(geom.validateGeometry(method)) 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()]) if error_output_sink: error_output_sink.addFeature(errFeat, QgsFeatureSink.FastInsert) 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: if valid_output_sink: valid_output_sink.addFeature(outFeat, QgsFeatureSink.FastInsert) valid_count += 1 else: if invalid_output_sink: invalid_output_sink.addFeature(outFeat, QgsFeatureSink.FastInsert) invalid_count += 1 feedback.setProgress(int(current * total)) results = { self.VALID_COUNT: valid_count, self.INVALID_COUNT: invalid_count, self.ERROR_COUNT: error_count } if valid_output_sink: results[self.VALID_OUTPUT] = valid_output_dest_id if invalid_output_sink: results[self.INVALID_OUTPUT] = invalid_output_dest_id if error_output_sink: results[self.ERROR_OUTPUT] = error_output_dest_id return results
# add fields pr.addAttributes([ QgsField("name", QVariant.String), QgsField("age", QVariant.Int), QgsField("size", QVariant.Double) ]) vl.updateFields() # tell the vector layer to fetch changes from the provider infos = [[10, 10, "John", 24, 1.73], [40, -60, "Paul", 29, 1.86], [60, 5, "George", 34, 1.69], [0, 45, "Ringo", 73, 1.75]] # add features for i in infos: fet = QgsFeature() fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(i[0], i[1]))) fet.setAttributes(i[2:5]) pr.addFeatures([fet]) # update layer's extent when new features have been added # because change of extent in provider is not propagated to the layer vl.updateExtents() QgsMapLayerRegistry.instance().addMapLayer(vl) highlight = QgsHighlight(iface.mapCanvas(), QgsGeometry.fromPoint(QgsPoint(0, 47)), vl) highlight.setBuffer(1.5) highlight.setColor(QColor('black')) highlight.setFillColor(QColor('blue')) highlight.setWidth(0.5)
def processAlgorithm(self, parameters, context, feedback): if parameters[self.INPUT] == parameters[self.HUBS]: raise QgsProcessingException( self.tr('Same layer given for both hubs and spokes')) point_source = self.parameterAsSource(parameters, self.INPUT, context) hub_source = self.parameterAsSource(parameters, self.HUBS, context) fieldName = self.parameterAsString(parameters, self.FIELD, context) units = self.UNITS[self.parameterAsEnum(parameters, self.UNIT, context)] fields = point_source.fields() fields.append(QgsField('HubName', QVariant.String)) fields.append(QgsField('HubDist', QVariant.Double)) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.Point, point_source.sourceCrs()) index = QgsSpatialIndex( hub_source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes( []).setDestinationCrs(point_source.sourceCrs()))) distance = QgsDistanceArea() distance.setSourceCrs(point_source.sourceCrs()) distance.setEllipsoid(context.project().ellipsoid()) # Scan source points, find nearest hub, and write to output file features = point_source.getFeatures() total = 100.0 / point_source.featureCount( ) if point_source.featureCount() else 0 for current, f in enumerate(features): if feedback.isCanceled(): break if not f.hasGeometry(): sink.addFeature(f, QgsFeatureSink.FastInsert) continue src = f.geometry().boundingBox().center() neighbors = index.nearestNeighbor(src, 1) ft = next( hub_source.getFeatures(QgsFeatureRequest().setFilterFid( neighbors[0]).setSubsetOfAttributes( [fieldName], hub_source.fields()).setDestinationCrs( point_source.sourceCrs()))) closest = ft.geometry().boundingBox().center() hubDist = distance.measureLine(src, closest) if units != self.LAYER_UNITS: hub_dist_in_desired_units = distance.convertLengthMeasurement( hubDist, units) else: hub_dist_in_desired_units = hubDist attributes = f.attributes() attributes.append(ft[fieldName]) attributes.append(hub_dist_in_desired_units) feat = QgsFeature() feat.setAttributes(attributes) feat.setGeometry(QgsGeometry.fromPoint(src)) sink.addFeature(feat, QgsFeatureSink.FastInsert) feedback.setProgress(int(current * total)) return {self.OUTPUT: dest_id}
def do_operation(self): """ perform create mapping scheme operation """ # input/output verification already performed during set input/ouput zone_layer = self.inputs[0].value zone_field = self.inputs[1].value fp_layer = self.inputs[2].value # merge with zone to get assignment tmp_join = 'joined_%s' % get_unique_filename() tmp_join_file = '%s%s.shp' % (self._tmp_dir, tmp_join) analyzer = QgsOverlayAnalyzer() try: analyzer.intersection(fp_layer, zone_layer, tmp_join_file) tmp_join_layer = load_shapefile_verify(tmp_join_file, tmp_join, [zone_field]) except AssertionError as err: raise OperatorError(str(err), self.__class__) except Exception as err: raise OperatorError(str(err), self.__class__) fields = { 0: QgsField(self._lon_field, QVariant.Double), 1: QgsField(self._lat_field, QVariant.Double), 2: QgsField(zone_field, QVariant.String), } zone_idx = layer_field_index(tmp_join_layer, zone_field) fp_layername = 'fpc_%s' % get_unique_filename() fp_file = '%s%s.shp' % (self._tmp_dir, fp_layername) try: writer = QgsVectorFileWriter(fp_file, "utf-8", fields, QGis.WKBPoint, self._crs, "ESRI Shapefile") f = QgsFeature() for _f in layer_features(tmp_join_layer): centroid = _f.geometry().centroid().asPoint() lon = centroid.x() lat = centroid.y() zone_str = str(_f.attributeMap()[zone_idx].toString()).upper() f.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon, lat))) f.addAttribute(0, QVariant(lon)) f.addAttribute(1, QVariant(lat)) f.addAttribute(2, QVariant(zone_str)) writer.addFeature(f) del writer except Exception as err: logAPICall.log(err, logAPICall.ERROR) remove_shapefile(fp_file) raise OperatorError("error creating joined grid: %s" % err, self.__class__) # load shapefile as layer fp_layer = load_shapefile(fp_file, fp_layername) if not fp_layer: raise OperatorError( 'Error loading footprint centroid file' % (fp_file), self.__class__) # clean up del tmp_join_layer remove_shapefile(tmp_join_file) self.outputs[0].value = fp_layer self.outputs[1].value = fp_file
def create_shapefile_full_layer_data_provider(path, name, srid, attributes, types, values, coords): """ Creates a shapefile using the Shapefile Data Provider Parameters ---------- path : `str` folder where the shapefile is to be saved name : `str` name of the shapefile srid : `str` CRS of the newly created shapefile attributes: array_like list of attribute (field) names types : array_like list of types (field) types, in sync with the `attributes` parameter values : array_like coordinates and attribute data, one array for each feature (F, C + A), F for features, C for coordinates and A for attribute data coords : array_like indices of the coordinate values within the `values` array Returns ------- vl : `QgsVectorLayer` the newly-created layer """ # create new layer with given attributes filename = path + "/" + name + ".shp" # create an instance of vector file writer, which will create the vector file. writer = None options = QgsVectorFileWriter.SaveVectorOptions() options.driverName = "ESRI Shapefile" options.fileEncoding = 'utf-8' if len(coords) == 2: type = 'point' writer = QgsVectorFileWriter.create(filename, QgsFields(), QgsWkbTypes.Point, srid, QgsCoordinateTransformContext(), options) elif len(coords) == 4: type = 'line' writer = QgsVectorFileWriter.create(filename, QgsFields(), QgsWkbTypes.LineString, srid, QgsCoordinateTransformContext(), options) if writer.hasError() != QgsVectorFileWriter.NoError: print("Error when creating shapefile: ", writer.hasError()) return None del writer # open the newly created file vl = QgsVectorLayer(filename, name, "ogr") pr = vl.dataProvider() # create the required fields for i, attr in enumerate(attributes): pr.addAttributes([QgsField(attr, types[i])]) vl.commitChanges() # add features by iterating the values feat = QgsFeature() for i, val in enumerate(values): # add geometry try: if type == 'point': geometry = QgsGeometry.fromPoint([QgsPoint(float(val[coords[0]]), float(val[coords[1]]))]) elif type == 'line': geometry = QgsGeometry.fromPolyline([QgsPoint(float(val[coords[0]]), float(val[coords[1]])), QgsPoint(float(val[coords[2]]), float(val[coords[3]]))]) feat.setGeometry(geometry) except: pass # add attributes attrs = [] for j, attr in enumerate(attributes): attrs.append(val[j]) feat.setAttributes(attrs) pr.addFeature(feat) vl.updateExtents() vl = QgsVectorLayer(filename, name, "ogr") if not vl.isValid(): raise IOError("Layer could not be created") return None return vl
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.INPUT), context) hSpacing = self.getParameterValue(self.HSPACING) vSpacing = self.getParameterValue(self.VSPACING) if hSpacing <= 0 or vSpacing <= 0: raise GeoAlgorithmExecutionException( self.tr('Invalid grid spacing: {0}/{1}').format( hSpacing, vSpacing)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.fields(), layer.wkbType(), layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, f in enumerate(features): geom = f.geometry() geomType = geom.wkbType() if geomType == QgsWkbTypes.Point: points = self._gridify([geom.asPoint()], hSpacing, vSpacing) newGeom = QgsGeometry.fromPoint(points[0]) elif geomType == QgsWkbTypes.MultiPoint: points = self._gridify(geom.aMultiPoint(), hSpacing, vSpacing) newGeom = QgsGeometry.fromMultiPoint(points) elif geomType == QgsWkbTypes.LineString: points = self._gridify(geom.asPolyline(), hSpacing, vSpacing) if len(points) < 2: QgsMessageLog.logMessage( self.tr( 'Failed to gridify feature with FID {0}').format( f.id()), self.tr('Processing'), QgsMessageLog.INFO) newGeom = None else: newGeom = QgsGeometry.fromPolyline(points) elif geomType == QgsWkbTypes.MultiLineString: polyline = [] for line in geom.asMultiPolyline(): points = self._gridify(line, hSpacing, vSpacing) if len(points) > 1: polyline.append(points) if len(polyline) <= 0: QgsMessageLog.logMessage( self.tr( 'Failed to gridify feature with FID {0}').format( f.id()), self.tr('Processing'), QgsMessageLog.INFO) newGeom = None else: newGeom = QgsGeometry.fromMultiPolyline(polyline) elif geomType == QgsWkbTypes.Polygon: polygon = [] for line in geom.asPolygon(): points = self._gridify(line, hSpacing, vSpacing) if len(points) > 1: polygon.append(points) if len(polygon) <= 0: QgsMessageLog.logMessage( self.tr( 'Failed to gridify feature with FID {0}').format( f.id()), self.tr('Processing'), QgsMessageLog.INFO) newGeom = None else: newGeom = QgsGeometry.fromPolygon(polygon) elif geomType == QgsWkbTypes.MultiPolygon: multipolygon = [] for polygon in geom.asMultiPolygon(): newPolygon = [] for line in polygon: points = self._gridify(line, hSpacing, vSpacing) if len(points) > 2: newPolygon.append(points) if len(newPolygon) > 0: multipolygon.append(newPolygon) if len(multipolygon) <= 0: QgsMessageLog.logMessage( self.tr( 'Failed to gridify feature with FID {0}').format( f.id()), self.tr('Processing'), QgsMessageLog.INFO) newGeom = None else: newGeom = QgsGeometry.fromMultiPolygon(multipolygon) if newGeom is not None: feat = QgsFeature() feat.setGeometry(newGeom) feat.setAttributes(f.attributes()) writer.addFeature(feat) feedback.setProgress(int(current * total)) del writer
def test_updateFeatures(self): ol, offline_layer = self._testInit() # Edit feature 2 feat2 = self._getFeatureByAttribute(offline_layer, 'name', "'name 2'") self.assertTrue(offline_layer.startEditing()) self.assertTrue( offline_layer.changeAttributeValue( feat2.id(), offline_layer.fields().lookupField('name'), 'name 2 edited')) self.assertTrue( offline_layer.changeGeometry( feat2.id(), QgsGeometry.fromPoint(QgsPoint(33.0, 60.0)))) self.assertTrue(offline_layer.commitChanges()) feat2 = self._getFeatureByAttribute(offline_layer, 'name', "'name 2 edited'") self.assertTrue(ol.isOfflineProject()) # Sync ol.synchronize() sleep(2) # Does anybody know why the sleep is needed? Is that a threaded WFS consequence? online_layer = list(self.registry.mapLayers().values())[0] self.assertTrue(online_layer.isValid()) self.assertFalse(online_layer.name().find('(offline)') > -1) self.assertEqual(len([f for f in online_layer.getFeatures()]), len(TEST_FEATURES)) # Check that data have changed in the backend (raise exception if not found) feat2 = self._getFeatureByAttribute(self._getLayer('test_point'), 'name', "'name 2 edited'") feat2 = self._getFeatureByAttribute(online_layer, 'name', "'name 2 edited'") self.assertEqual(feat2.geometry().asPoint().toString(), QgsPoint(33.0, 60.0).toString()) # Check that all other features have not changed layer = self._getLayer('test_point') self.assertTrue(self._compareFeature(layer, TEST_FEATURES[1 - 1])) self.assertTrue(self._compareFeature(layer, TEST_FEATURES[3 - 1])) self.assertTrue(self._compareFeature(layer, TEST_FEATURES[4 - 1])) # Test for regression on double sync (it was a SEGFAULT) # goes offline ol = QgsOfflineEditing() offline_layer = list(self.registry.mapLayers().values())[0] # Edit feature 2 feat2 = self._getFeatureByAttribute(offline_layer, 'name', "'name 2 edited'") self.assertTrue(offline_layer.startEditing()) self.assertTrue( offline_layer.changeAttributeValue( feat2.id(), offline_layer.fields().lookupField('name'), 'name 2')) self.assertTrue( offline_layer.changeGeometry( feat2.id(), QgsGeometry.fromPoint(TEST_FEATURES[1][2]))) # Edit feat 4 feat4 = self._getFeatureByAttribute(offline_layer, 'name', "'name 4'") self.assertTrue( offline_layer.changeAttributeValue( feat4.id(), offline_layer.fields().lookupField('name'), 'name 4 edited')) self.assertTrue(offline_layer.commitChanges()) # Sync ol.synchronize() # Does anybody knows why the sleep is needed? Is that a threaded WFS consequence? sleep(1) online_layer = list(self.registry.mapLayers().values())[0] layer = self._getLayer('test_point') # Check that data have changed in the backend (raise exception if not found) feat4 = self._getFeatureByAttribute(layer, 'name', "'name 4 edited'") feat4 = self._getFeatureByAttribute(online_layer, 'name', "'name 4 edited'") feat2 = self._getFeatureByAttribute(layer, 'name', "'name 2'") feat2 = self._getFeatureByAttribute(online_layer, 'name', "'name 2'") # Check that all other features have not changed layer = self._getLayer('test_point') self.assertTrue(self._compareFeature(layer, TEST_FEATURES[1 - 1])) self.assertTrue(self._compareFeature(layer, TEST_FEATURES[2 - 1])) self.assertTrue(self._compareFeature(layer, TEST_FEATURES[3 - 1]))
def processAlgorithm(self, feedback): layer = dataobjects.getObjectFromUri(self.getParameterValue( self.INPUT)) hSpacing = self.getParameterValue(self.HSPACING) vSpacing = self.getParameterValue(self.VSPACING) if hSpacing <= 0 or vSpacing <= 0: raise GeoAlgorithmExecutionException( self.tr('Invalid grid spacing: %s/%s' % (hSpacing, vSpacing))) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.fields(), layer.wkbType(), 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 == QgsWkbTypes.Point: points = self._gridify([geom.asPoint()], hSpacing, vSpacing) newGeom = QgsGeometry.fromPoint(points[0]) elif geomType == QgsWkbTypes.MultiPoint: points = self._gridify(geom.aMultiPoint(), hSpacing, vSpacing) newGeom = QgsGeometry.fromMultiPoint(points) elif geomType == QgsWkbTypes.LineString: points = self._gridify(geom.asPolyline(), hSpacing, vSpacing) if len(points) < 2: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self.tr('Failed to gridify feature with FID %s' % f.id())) newGeom = None else: newGeom = QgsGeometry.fromPolyline(points) elif geomType == QgsWkbTypes.MultiLineString: polyline = [] for line in geom.asMultiPolyline(): points = self._gridify(line, hSpacing, vSpacing) if len(points) > 1: polyline.append(points) if len(polyline) <= 0: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self.tr('Failed to gridify feature with FID %s' % f.id())) newGeom = None else: newGeom = QgsGeometry.fromMultiPolyline(polyline) elif geomType == QgsWkbTypes.Polygon: polygon = [] for line in geom.asPolygon(): points = self._gridify(line, hSpacing, vSpacing) if len(points) > 1: polygon.append(points) if len(polygon) <= 0: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self.tr('Failed to gridify feature with FID %s' % f.id())) newGeom = None else: newGeom = QgsGeometry.fromPolygon(polygon) elif geomType == QgsWkbTypes.MultiPolygon: multipolygon = [] for polygon in geom.asMultiPolygon(): newPolygon = [] for line in polygon: points = self._gridify(line, hSpacing, vSpacing) if len(points) > 2: newPolygon.append(points) if len(newPolygon) > 0: multipolygon.append(newPolygon) if len(multipolygon) <= 0: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self.tr('Failed to gridify feature with FID %s' % f.id())) newGeom = None else: newGeom = QgsGeometry.fromMultiPolygon(multipolygon) if newGeom is not None: feat = QgsFeature() feat.setGeometry(newGeom) feat.setAttributes(f.attributes()) writer.addFeature(feat) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, progress): radius = self.getParameterValue(self.DISTANCE) horizontal = self.getParameterValue(self.HORIZONTAL) output = self.getOutputFromName(self.OUTPUT_LAYER) layer = dataobjects.getObjectFromUri( 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()]) progress.setPercentage(int(current * total)) current = 0 total = 100.0 / len(duplicates) progress.setPercentage(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 progress.setPercentage(int(current * total)) 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, QGis.WKBPoint, 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
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString( 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 {0} to {1}').format( 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 {0} to {1}').format( 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 {0} to {1}').format( 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 {0} to {1}').format( 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 {0} to {1}').format( 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 {0} to {1}').format( geomType, newType)) feedback.setProgress(int(current * total)) del writer
def do_operation(self): """ perform create mapping scheme operation """ # input/output verification already performed during set input/ouput zone_layer = self.inputs[0].value zone_field = self.inputs[1].value count_field = self.inputs[2].value grid_layer = self.inputs[3].value zone_stats = {} zone_count_stats = {} gid_idx = layer_field_index(zone_layer, self._gid_field) count_idx = layer_field_index(zone_layer, count_field) for _f in layer_features(zone_layer): gid = _f.attributeMap()[gid_idx].toString() zone_stats[gid] = 0 zone_count_stats[gid] = _f.attributeMap()[count_idx].toDouble()[0] # create storage for temporary output data use_grid_db = grid_layer.dataProvider().featureCount( ) > MAX_FEATURES_IN_MEMORY if False: tmp_grid_db_file = '%sdb_%s.db' % (self._tmp_dir, get_unique_filename()) grid_points = bsddb.btopen(tmp_grid_db_file, 'c') else: grid_points = {} # merge to create stats tmp_join = 'joined_%s' % get_unique_filename() tmp_join_file = '%s%s.shp' % (self._tmp_dir, tmp_join) analyzer = QgsOverlayAnalyzer() try: analyzer.intersection(grid_layer, zone_layer, tmp_join_file) tmp_join_layer = load_shapefile_verify(tmp_join_file, tmp_join, [zone_field, count_field]) except AssertionError as err: raise OperatorError(str(err), self.__class__) except Exception as err: raise OperatorError(str(err), self.__class__) stats = layer_multifields_stats(tmp_join_layer, [zone_field, count_field]) if stats == False: raise OperatorError( "error creating statistic based on input files", self.__class__) zone_idx = layer_field_index(tmp_join_layer, zone_field) count_idx = layer_field_index(tmp_join_layer, count_field) lon_idx = layer_field_index(tmp_join_layer, self._lon_field) lat_idx = layer_field_index(tmp_join_layer, self._lat_field) gid_idx = layer_field_index(tmp_join_layer, self._gid_field) try: for _f in layer_features(tmp_join_layer): lon = _f.attributeMap()[lon_idx].toDouble()[0] lat = _f.attributeMap()[lat_idx].toDouble()[0] zone_str = str(_f.attributeMap()[zone_idx].toString()).upper() count_val = _f.attributeMap()[count_idx].toDouble()[0] gid = _f.attributeMap()[gid_idx].toString() # update stats zone_stats[gid] += 1 grid_points[self._make_key(zone_str, gid, lon, lat)] = 1 except Exception as err: raise OperatorError("error processing joined layer: " % err, self.__class__) # test for zones without a grid point assigned count_idx = layer_field_index(zone_layer, count_field) gid_idx = layer_field_index(zone_layer, self._gid_field) zone_idx = layer_field_index(zone_layer, zone_field) _x_off, _y_off = self._x_off / 2.0, self._y_off / 2.0 try: for _f in layer_features(zone_layer): centroid = _f.geometry().centroid().asPoint() zone_str = str(_f.attributeMap()[zone_idx].toString()).upper() count_val = _f.attributeMap()[count_idx].toDouble()[0] gid = _f.attributeMap()[gid_idx].toString() if zone_stats[gid] == 0: # get lower left corner lon = int(centroid.x() / DEFAULT_GRID_SIZE) * self._x_off + _x_off lat = int( centroid.y() / self._y_off) * self._y_off + _y_off #self._write_feature(writer, f, lon, lat, zone_str, count_val) zone_stats[gid] += 1 grid_points[self._make_key(zone_str, gid, lon, lat)] = 1 except Exception as err: raise OperatorError("error processing missing points: " % err, self.__class__) # output result fields = { 0: QgsField(self._lon_field, QVariant.Double), 1: QgsField(self._lat_field, QVariant.Double), 2: QgsField(zone_field, QVariant.String), 3: QgsField(count_field, QVariant.Double) } grid_layername = 'grid_%s' % (get_unique_filename()) grid_file = '%s%s.shp' % (self._tmp_dir, grid_layername) try: f = QgsFeature() writer = QgsVectorFileWriter(grid_file, "utf-8", fields, QGis.WKBPoint, self._crs, "ESRI Shapefile") for key, value in grid_points.iteritems(): [zone, zone_gid, lon, lat] = self._parse_key(key) f.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon, lat))) """ f.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon, lat))) f.addAttribute(0, QVariant(lon)) f.addAttribute(1, QVariant(lat)) f.addAttribute(2, QVariant(zone_str)) f.addAttribute(3, QVariant(count_val / total_features)) writer.addFeature(f) """ value = float( value) / zone_stats[zone_gid] * zone_count_stats[zone_gid] #grid_points[key] = value self._write_feature(writer, f, lon, lat, zone, value) del writer except Exception as err: raise OperatorError("error creating joined grid file: " % err, self.__class__) # load result layer grid_layer = load_shapefile(grid_file, grid_layername) if not grid_layer: raise OperatorError('Error loading joined grid file' % (grid_file), self.__class__) # clean up del tmp_join_layer remove_shapefile(tmp_join_file) self.outputs[0].value = grid_layer self.outputs[1].value = grid_file
def processAlgorithm(self, feedback): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.VECTOR)) pointCount = float(self.getParameterValue(self.POINT_NUMBER)) minDistance = float(self.getParameterValue(self.MIN_DISTANCE)) fields = QgsFields() fields.append(QgsField('id', QVariant.Int, '', 10, 0)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, QgsWkbTypes.Point, layer.crs()) nPoints = 0 nIterations = 0 maxIterations = pointCount * 200 featureCount = layer.featureCount() total = 100.0 / pointCount index = QgsSpatialIndex() points = dict() da = QgsDistanceArea() request = QgsFeatureRequest() random.seed() while nIterations < maxIterations and nPoints < pointCount: # pick random feature fid = random.randint(0, featureCount - 1) f = next(layer.getFeatures(request.setFilterFid(fid).setSubsetOfAttributes([]))) fGeom = f.geometry() if fGeom.isMultipart(): lines = fGeom.asMultiPolyline() # pick random line lineId = random.randint(0, len(lines) - 1) vertices = lines[lineId] else: vertices = fGeom.asPolyline() # pick random segment if len(vertices) == 2: vid = 0 else: vid = random.randint(0, len(vertices) - 2) startPoint = vertices[vid] endPoint = vertices[vid + 1] length = da.measureLine(startPoint, endPoint) dist = length * random.random() if dist > minDistance: d = dist / (length - dist) rx = (startPoint.x() + d * endPoint.x()) / (1 + d) ry = (startPoint.y() + d * endPoint.y()) / (1 + d) # generate random point pnt = QgsPoint(rx, ry) geom = QgsGeometry.fromPoint(pnt) if vector.checkMinDistance(pnt, index, minDistance, points): f = QgsFeature(nPoints) f.initAttributes(1) f.setFields(fields) f.setAttribute('id', nPoints) f.setGeometry(geom) writer.addFeature(f) index.insertFeature(f) points[nPoints] = pnt nPoints += 1 feedback.setProgress(int(nPoints * total)) nIterations += 1 if nPoints < pointCount: ProcessingLog.addToLog(ProcessingLog.LOG_INFO, self.tr('Can not generate requested number of random points. ' 'Maximum number of attempts exceeded.')) del writer
def testFromPoint(self): myPoint = QgsGeometry.fromPoint(QgsPoint(10, 10)) myMessage = ('Expected:\n%s\nGot:\n%s\n' % (QGis.WKBPoint, myPoint.type())) assert myPoint.wkbType() == QGis.WKBPoint, myMessage
def canvasReleaseEvent(self, event): if not self.mouse_clicked: return if event.button() == Qt.LeftButton: self.mouse_clicked = False # Find first available ID for Tanks tank_eid = NetworkUtils.find_next_id(self.params.tanks_vlay, Tank.prefix) # TODO: softcode curve = self.data_dock.cbo_tank_curve.itemData( self.data_dock.cbo_tank_curve.currentIndex()) if curve is not None: tank_curve_id = curve.id else: tank_curve_id = None elev = 0 if self.elev is None and self.params.dem_rlay is not None: self.iface.messageBar().pushMessage( Parameters.plug_in_name, 'Elevation value not available: element elevation set to 0.', QgsMessageBar.WARNING, 5) # TODO: softcode else: elev = self.elev diameter = float(self.data_dock.txt_tank_diameter.text()) deltaz = float(self.data_dock.txt_tank_deltaz.text()) level_init = float(self.data_dock.txt_tank_level_init.text()) level_min = float(self.data_dock.txt_tank_level_min.text()) level_max = float(self.data_dock.txt_tank_level_max.text()) vol_min = float(self.data_dock.txt_tank_vol_min.text()) tank_desc = self.data_dock.txt_tank_desc.text() tank_tag = self.data_dock.cbo_tank_tag.currentText() # No links snapped: create a new stand-alone tank if self.snapped_feat_id is None: NodeHandler.create_new_tank(self.params, self.mouse_pt, tank_eid, tank_curve_id, diameter, elev, deltaz, level_init, level_min, level_max, vol_min, tank_desc, tank_tag) # A link has been snapped else: # Get the snapped pipe and split it request = QgsFeatureRequest().setFilterFid( self.snapped_feat_id) feats = list(self.params.pipes_vlay.getFeatures(request)) if len(feats) > 0: snapped_pipe = QgsFeature(feats[0]) (start_node_ft, end_node_ft) = NetworkUtils.find_start_end_nodes( self.params, snapped_pipe.geometry()) if start_node_ft is None or end_node_ft is None: self.iface.messageBar().pushMessage( Parameters.plug_in_name, 'The pipe is missing the start or end nodes. Cannot add a new tank along the pipe.', QgsMessageBar.WARNING, 5) # TODO: softcode return # Check that the snapped point on line is distant enough from start/end nodes if start_node_ft.geometry().distance(QgsGeometry.fromPoint(self.snapped_vertex)) > self.params.min_dist and\ end_node_ft.geometry().distance(QgsGeometry.fromPoint(self.snapped_vertex)) > self.params.min_dist: LinkHandler.split_pipe(self.params, snapped_pipe, self.snapped_vertex) # New node on existing line NodeHandler.create_new_tank( self.params, self.snapped_vertex, tank_eid, tank_curve_id, diameter, self.elev, deltaz, level_init, level_min, level_max, vol_min, tank_desc, tank_tag) # Replace pipe start node with new tank elif start_node_ft.geometry().distance( QgsGeometry.fromPoint(self.snapped_vertex)) <= 0: # Delete junction NodeHandler.delete_node(self.params, self.params.junctions_vlay, start_node_ft, False) # New node on existing line NodeHandler.create_new_tank( self.params, self.snapped_vertex, tank_eid, tank_curve_id, diameter, self.elev, deltaz, level_init, level_min, level_max, vol_min, tank_desc, tank_tag) # Replace pipe end node with new tank elif end_node_ft.geometry().distance( QgsGeometry.fromPoint(self.snapped_vertex)) <= 0: # Delete junction NodeHandler.delete_node(self.params, self.params.junctions_vlay, end_node_ft, False) # New node on existing line NodeHandler.create_new_tank( self.params, self.snapped_vertex, tank_eid, tank_curve_id, diameter, self.elev, deltaz, level_init, level_min, level_max, vol_min, tank_desc, tank_tag) else: self.iface.messageBar().pushMessage( Parameters.plug_in_name, 'The selected position is too close to a junction: cannon create the tank.', QgsMessageBar.WARNING, 5) # TODO: softcode
def doCheck(self, feedback): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_LAYER)) settings = QSettings() method = int(settings.value(settings_method_key, 1)) valid_output = self.getOutputFromName(self.VALID_OUTPUT) valid_fields = layer.fields() valid_writer = valid_output.getVectorWriter(valid_fields, layer.wkbType(), layer.crs()) valid_count = 0 invalid_output = self.getOutputFromName(self.INVALID_OUTPUT) invalid_fields = layer.fields().toList() + [ QgsField(name='_errors', type=QVariant.String, len=255) ] invalid_writer = invalid_output.getVectorWriter( invalid_fields, layer.wkbType(), layer.crs()) invalid_count = 0 error_output = self.getOutputFromName(self.ERROR_OUTPUT) error_fields = [ QgsField(name='message', type=QVariant.String, len=255) ] error_writer = error_output.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.isNull() and not geom.isEmpty(): 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 feedback.setProgress(int(current * total)) del valid_writer del invalid_writer del error_writer if valid_count == 0: valid_output.open = False if invalid_count == 0: invalid_output.open = False if error_count == 0: error_output.open = False
def geometry(self): if self.geom.type() == QGis.Point: x = float(self.xedit.text()) y = float(self.yedit.text()) return QgsGeometry.fromPoint(QgsPoint(x, y))
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_VECTOR)) rasterPath = unicode(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(), QGis.WKBPoint, layer.crs()) outFeature = QgsFeature() outFeature.setFields(fields) point = QgsPoint() 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) for row in xrange(startRow, endRow + 1): for col in xrange(startColumn, endColumn + 1): (x, y) = raster.pixelToMap(row, col, geoTransform) point.setX(x) point.setY(y) if geom.contains(point): outFeature.setGeometry(QgsGeometry.fromPoint(point)) outFeature['id'] = fid outFeature['poly_id'] = polyId outFeature['point_id'] = pointId fid += 1 pointId += 1 writer.addFeature(outFeature) pointId = 0 polyId += 1 progress.setPercentage(int(current * total)) del writer
def importPhotos(self): if exifread.__version__ == '2.0.0': self.importError.emit( self.tr('Found exifread {}, but plugin requires exifread ' '1.x or >= 2.0.1.'.format(exifread.__version__))) return if self.append: layer = self._openShapefile() else: layer = self._newShapefile() if layer is None: self.importError.emit(self.tr('Unable to open or create layer.')) return provider = layer.dataProvider() fields = layer.pendingFields() photos = [] for root, dirs, files in os.walk(self.directory): photos.extend(os.path.join(root, fName) for fName in files if fName.lower().endswith(('.jpg', '.jpeg'))) if not self.recurse: break if len(photos) == 0: self.importError.emit(self.tr('No images found in directory.')) return total = 100.0 / len(photos) ft = QgsFeature() ft.setFields(fields) for count, fName in enumerate(photos): with open(fName, 'rb') as imgFile: tags = exifread.process_file(imgFile, details=False) if not tags.viewkeys() & {'GPS GPSLongitude', 'GPS GPSLatitude'}: self.importMessage.emit( self.tr('Skipping file {}: ' 'there are no GPS tags in it.'.format(fName))) self.photoProcessed.emit(int(count * total)) continue # Start processing tags longitude, latitude = self._extractCoordinates(tags) if longitude is None: self.importMessage.emit( self.tr('Skipping file {}: ' 'there are no GPS fix data.'.format(fName))) self.photoProcessed.emit(int(count * total)) continue altitude = self._extractAltitude(tags) north, azimuth = self._extractDirection(tags) gpsDate = self._extracrGPSDateTime(tags) imgDate = self._extractImageDateTime(tags) del tags # Write feature to layer ft.setGeometry( QgsGeometry.fromPoint(QgsPoint(longitude, latitude))) ft['filepath'] = fName ft['filename'] = os.path.basename(fName) ft['longitude'] = longitude ft['latitude'] = latitude ft['altitude'] = altitude ft['north'] = north ft['azimuth'] = azimuth ft['gps_date'] = gpsDate ft['img_date'] = imgDate provider.addFeatures([ft]) self.photoProcessed.emit(int(count * total)) self.importFinished.emit()
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( 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) progress.setPercentage(int(current * total)) del writer
def crater_center(self, crater, lat, lon): center_point = QgsPoint( float(crater.attributes()[lon]), float(crater.attributes()[lat]), ) return QgsGeometry.fromPoint(center_point)
def points_along_line(layerout, startpoint, endpoint, distance, label, layer, selected_only=True, force=False, fo_fila=False, divide=0, decimal=2): """Adding Points along the line """ crs = layer.crs().authid() # TODO check for virtual or shapelayer and set virt_layer according to it shape = False if shape: # define fields for feature attributes. A list of QgsField objects is needed fields = [ QgsField("first", QVariant.Int), QgsField("second", QVariant.String) ] # create an instance of vector file writer, which will create the vector file. # Arguments: # 1. path to new file (will fail if exists already) # 2. encoding of the attributes # 3. field map # 4. geometry type - from WKBTYPE enum # 5. layer's spatial reference (instance of # QgsCoordinateReferenceSystem) - optional # 6. driver name for the output file writer = QgsVectorFileWriter("my_shapes.shp", "CP1250", fields, Qgis.WKBPoint, crs, "ESRI Shapefile") if writer.hasError() != QgsVectorFileWriter.NoError: # fix_print_with_import print("Error when creating shapefile: ", writer.hasError()) # add a feature fet = QgsFeature() fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(10, 10))) fet.setAttributes([1, "text"]) writer.addFeature(fet) # delete the writer to flush features to disk (optional) del writer layer_type = "Shapefile" # TODO Add Shapefile functionality here else: layer_type = "memory" virt_layer = QgsVectorLayer("Point?crs=%s" % crs, layerout, layer_type) provider = virt_layer.dataProvider() virt_layer.startEditing() # actually writes attributes units = layer.crs().mapUnits() unitname = QgsUnitTypes.toString(units) provider.addAttributes([ QgsField("fid", QVariant.Int), QgsField("cng" + unitname, QVariant.Double) ]) def get_features(): """Getting the features """ if selected_only: return layer.selectedFeatures() else: return layer.getFeatures() # Loop through all (selected) features for feature in get_features(): geom = feature.geometry() # Add feature ID of selected feature fid = feature.id() if not geom: QgsMessageLog.logMessage("No geometry", "QChainage") continue features = create_points_at(startpoint, endpoint, distance, geom, fid, force, fo_fila, divide) provider.addFeatures(features) virt_layer.updateExtents() proj = QgsProject.instance() proj.addMapLayers([virt_layer]) virt_layer.commitChanges() virt_layer.reload() # generic labeling properties if label: virt_layer.setCustomProperty("labeling", "pal") virt_layer.setCustomProperty("labeling/enabled", "true") virt_layer.setCustomProperty("labeling/fieldName", "cng") virt_layer.setCustomProperty("labeling/fontSize", "10") virt_layer.setCustomProperty("labeling/multiLineLabels", "true") virt_layer.setCustomProperty("labeling/formatNumbers", "true") virt_layer.setCustomProperty("labeling/decimals", decimal) virt_layer.setCustomProperty("labeling/Size", "5") # symbol = QgsMarkerSymbol.createSimple({"name": "capital"}) # virt_layer.setRenderer(QgsSingleSymbolRenderer(symbol)) virt_layer.triggerRepaint() return
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, QgsWkbTypes.Point, layer.crs()) da = QgsDistanceArea() features = vector.features(layer) for current, f in enumerate(features): fGeom = f.geometry() bbox = fGeom.boundingBox() if strategy == 0: pointCount = int(value) else: pointCount = int(round(value * da.measureArea(fGeom))) 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): 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 accept(self): layer = self.inputMapLayerComboBox.currentLayer() if not layer: self.iface.messageBar().pushMessage("", "No Valid Layer", level=QgsMessageBar.WARNING, duration=4) pointname = self.pointsNameLineEdit.text() linename = self.lineNameLineEdit.text() startXcol = self.startXFieldComboBox.currentIndex( ) # Returns -1 if none selected startYcol = self.startYFieldComboBox.currentIndex() endXcol = self.endXFieldComboBox.currentIndex() endYcol = self.endYFieldComboBox.currentIndex() startUseGeom = self.startCheckBox.isChecked() endUseGeom = self.endCheckBox.isChecked() inCRS = self.inputQgsProjectionSelectionWidget.crs() outCRS = self.outputQgsProjectionSelectionWidget.crs() lineType = self.lineTypeComboBox.currentIndex() showStart = self.showStartCheckBox.isChecked() showEnd = self.showEndCheckBox.isChecked() if (startUseGeom == False) and (startXcol == -1 or startYcol == -1): self.iface.messageBar().pushMessage( "", "Must specify valid starting point columns", level=QgsMessageBar.WARNING, duration=4) return if (endUseGeom == False) and (endXcol == -1 or endYcol == -1): self.iface.messageBar().pushMessage( "", "Must specify valid ending point columns", level=QgsMessageBar.WARNING, duration=4) return # Get the field names for the input layer. The will be copied to the output layers fields = layer.pendingFields() # Create the points and line output layers lineLayer = QgsVectorLayer("LineString?crs={}".format(outCRS.authid()), linename, "memory") pline = lineLayer.dataProvider() pline.addAttributes(fields) lineLayer.updateFields() if showStart or showEnd: pointLayer = QgsVectorLayer("Point?crs={}".format(outCRS.authid()), pointname, "memory") ppoint = pointLayer.dataProvider() ppoint.addAttributes(fields) pointLayer.updateFields() transform = QgsCoordinateTransform(inCRS, outCRS) if inCRS != epsg4326: transto4326 = QgsCoordinateTransform(inCRS, epsg4326) if outCRS != epsg4326: transfrom4326 = QgsCoordinateTransform(epsg4326, outCRS) iter = layer.getFeatures() num_features = 0 num_bad = 0 maxseglen = settings.maxSegLength * 1000.0 maxSegments = settings.maxSegments for feature in iter: num_features += 1 try: if startUseGeom == True: ptStart = feature.geometry().asPoint() else: ptStart = QgsPoint(float(feature[startXcol]), float(feature[startYcol])) if endUseGeom == True: ptEnd = feature.geometry().asPoint() else: ptEnd = QgsPoint(float(feature[endXcol]), float(feature[endYcol])) # Create a new Line Feature fline = QgsFeature() if lineType == 0: # Geodesic # If the input is not 4326 we need to convert it to that and then back to the output CRS if inCRS != epsg4326: # Convert to 4326 ptStart = transto4326.transform(ptStart) ptEnd = transto4326.transform(ptEnd) pts = [ptStart] l = self.geod.InverseLine(ptStart.y(), ptStart.x(), ptEnd.y(), ptEnd.x()) if l.s13 > maxseglen: n = int(math.ceil(l.s13 / maxseglen)) if n > maxSegments: n = maxSegments seglen = l.s13 / n for i in range(1, n): s = seglen * i g = l.Position( s, Geodesic.LATITUDE | Geodesic.LONGITUDE | Geodesic.LONG_UNROLL) pts.append(QgsPoint(g['lon2'], g['lat2'])) pts.append(ptEnd) if outCRS != epsg4326: # Convert each point to the output CRS for x, pt in enumerate(pts): pts[x] = transfrom4326.transform(pt) fline.setGeometry(QgsGeometry.fromPolyline(pts)) elif lineType == 1: # Great Circle # If the input is not 4326 we need to convert it to that and then back to the output CRS if inCRS != epsg4326: # Convert to 4326 ptStart = transto4326.transform(ptStart) ptEnd = transto4326.transform(ptEnd) pts = LatLon.getPointsOnLine( ptStart.y(), ptStart.x(), ptEnd.y(), ptEnd.x(), settings.maxSegLength * 1000.0, # Put it in meters settings.maxSegments + 1) if outCRS != epsg4326: # Convert each point to the output CRS for x, pt in enumerate(pts): pts[x] = transfrom4326.transform(pt) fline.setGeometry(QgsGeometry.fromPolyline(pts)) else: # Simple line '''Transform the starting and end points if the input CRS and the output CRS are not the same and then create a 2 point polyline''' if inCRS != outCRS: ptStart = transform.transform(ptStart) ptEnd = transform.transform(ptEnd) fline.setGeometry( QgsGeometry.fromPolyline([ptStart, ptEnd])) fline.setAttributes(feature.attributes()) pline.addFeatures([fline]) # Add two point features if showStart: fpoint = QgsFeature() fpoint.setGeometry(QgsGeometry.fromPoint(ptStart)) fpoint.setAttributes(feature.attributes()) ppoint.addFeatures([fpoint]) if showEnd: fpoint = QgsFeature() fpoint.setGeometry(QgsGeometry.fromPoint(ptEnd)) fpoint.setAttributes(feature.attributes()) ppoint.addFeatures([fpoint]) except: num_bad += 1 pass lineLayer.updateExtents() QgsMapLayerRegistry.instance().addMapLayer(lineLayer) if showStart or showEnd: pointLayer.updateExtents() QgsMapLayerRegistry.instance().addMapLayer(pointLayer) if num_bad != 0: self.iface.messageBar().pushMessage( "", "{} out of {} features failed".format(num_bad, num_features), level=QgsMessageBar.WARNING, duration=3) self.close()
def processAlgorithm(self, feedback): layerPoints = dataobjects.getLayerFromString( self.getParameterValue(self.POINTS)) layerHubs = dataobjects.getLayerFromString( self.getParameterValue(self.HUBS)) fieldName = self.getParameterValue(self.FIELD) 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.Point, layerPoints.crs()) index = vector.spatialindex(layerHubs) distance = QgsDistanceArea() distance.setSourceCrs(layerPoints.crs()) 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.fromPoint(src)) writer.addFeature(feat) feedback.setProgress(int(current * total)) del writer
def WPT2Layer(self): mapUnits = define._canvas.mapUnits() if define._mapCrs == None: if mapUnits == QGis.Meters: resultLayer = QgsVectorLayer("Point?crs=EPSG:32633", "WPT_" + self.surfaceType.replace(" ", "_").replace("-", "_"), "memory") else: resultLayer = QgsVectorLayer("Point?crs=EPSG:4326", "WPT_" + self.surfaceType.replace(" ", "_").replace("-", "_"), "memory") else: resultLayer = QgsVectorLayer("Point?crs=%s"%define._mapCrs.authid (), "WPT_" + self.surfaceType.replace(" ", "_").replace("-", "_"), "memory") shpPath = "" if define.obstaclePath != None: shpPath = define.obstaclePath elif define.xmlPath != None: shpPath = define.xmlPath else: shpPath = define.appPath er = QgsVectorFileWriter.writeAsVectorFormat(resultLayer, shpPath + "/" + "RnavTurningSegmentAnalyserWpt" + ".shp", "utf-8", resultLayer.crs()) resultLayer = QgsVectorLayer(shpPath + "/" + "RnavTurningSegmentAnalyserWpt" + ".shp", "WPT_RnavTurningSegmentAnalyser", "ogr") fieldName = "CATEGORY" resultLayer.dataProvider().addAttributes( [QgsField(fieldName, QVariant.String)] ) resultLayer.startEditing() fields = resultLayer.pendingFields() i = 1 feature = QgsFeature() feature.setFields(fields) feature.setGeometry(QgsGeometry.fromPoint (self.parametersPanel.pnlWaypoint1.Point3d)) feature.setAttribute(fieldName, "Waypoint1") pr = resultLayer.dataProvider() pr.addFeatures([feature]) # resultLayer.addFeature(feature) feature.setGeometry(QgsGeometry.fromPoint (self.parametersPanel.pnlWaypoint2.Point3d)) feature.setAttribute(fieldName, "Waypoint2") pr = resultLayer.dataProvider() pr.addFeatures([feature]) # resultLayer.addFeature(feature) resultLayer.commitChanges() renderCatFly = None if self.parametersPanel.cmbType1.SelectedIndex == 1: '''FlyOver''' symbolFlyOver = QgsSymbolV2.defaultSymbol(resultLayer.geometryType()) symbolFlyOver.deleteSymbolLayer(0) svgSymLayer = QgsSvgMarkerSymbolLayerV2("Resource/flyover.svg", 10.0, 0.0) symbolFlyOver.appendSymbolLayer(svgSymLayer) renderCatFly = QgsRendererCategoryV2(0, symbolFlyOver,"Fly Over") elif self.parametersPanel.cmbType1.SelectedIndex == 0: '''FlyBy''' symbolFlyBy = QgsSymbolV2.defaultSymbol(resultLayer.geometryType()) symbolFlyBy.deleteSymbolLayer(0) svgSymLayer = QgsSvgMarkerSymbolLayerV2("Resource/flyby.svg", 10.0, 0.0) symbolFlyBy.appendSymbolLayer(svgSymLayer) renderCatFly = QgsRendererCategoryV2(0, symbolFlyBy,"Fly By") else: return None WPT_EXPRESION = "CASE WHEN \"CATEGORY\" = 'Waypoint1' THEN 0 " + \ "END" symRenderer = QgsCategorizedSymbolRendererV2(WPT_EXPRESION, [renderCatFly]) resultLayer.setRendererV2(symRenderer) return resultLayer