New answers tagged

1

When you are stuck, you should look at QGIS API documentation, PyQGIS documentation and Python tests directory from QGIS repository e.g https://github.com/qgis/QGIS/tree/master/tests/src/python For the first two links for your use cases, you should look at classes containing QgsLayout string (by doing a textual search) You may wonder how I've guessed I ...


1

Based on my reading of the manual I would say that it is good practice to use the names of the parameters if any are missing, so: iface.addVectorLayer("vector_path",baseName="vector_name",providerKey="ogr")


0

You can find below a way to get the nearest edge for a layer and verify the result is what you expect (by comparing input point and output point) from qgis.core import ( QgsFeature, QgsGeometry, QgsPointXY, QgsProject, QgsSnappingUtils, QgsVectorLayer, ) # Current layer yourlayer = iface.activeLayer() # New snappingUtils ...


1

I was running into this problem and here is how I solved it... Do a search for 'resources.qrc'. I found it in the plugin that I had just created with QGIS plugin builder. Then, make sure to edit the batch file described above to point to the absolute path of resources.qrc. This solved my problem.


4

You should use QgsProcessingParameterVectorLayer as input in initAlgorithm method and use self.parameterAsVectorLayer to get the layer reference in processAlgorithm method. Then you can use methods and properties of QgsVectorLayer class. This is a sample script which gets a vector layer you specified, adds/populates a field and returns the layer itself. ...


3

You can use the Proximity tool in the Processing Toolbox | GDAL | Raster Analysis: Proximity (raster distance) Generates a raster proximity map indicating the distance from the center of each pixel to the center of the nearest pixel identified as a target pixel. Target pixels are those in the source raster for which the raster pixel value is in the ...


0

Depending of your requirements, you may want to use a QgsLayoutItemLabel or a QgsLayoutItemHtml. To illustrate, we use QgsLayoutItemLabel. For QgsLayoutItemHtml, you may look at this existing question and its answers from qgis.core import QgsLayoutItemLabel, QgsLayoutPoint, QgsLayoutSize from qgis.PyQt.QtCore import Qt project = QgsProject.instance() ...


0

Although in the layout, I suggested changing legend block position or reduce the map canvas to avoid overlay, a recipe to make some changes to your fonts in the legend project = QgsProject.instance() manager = project.layoutManager() layout = manager.layoutByName('demo') # I start from an existing QgsLayoutItemLegend named "legend1" # here. You may create ...


2

You need to add below content (tested) label_settings.isExpression = True The QgsPalLayerSettings doc for fieldName states the following QString QgsPalLayerSettings::fieldName Name of field (or an expression) to use for label text. If fieldName is an expression, then isExpression should be set to true.


5

On the one hand, QgsMapCanvas is a class. You can always create new canvas objects from it (as you did already in your second attempt). On the other hand, iface.mapCanvas() is an instance, an object of the class QgsMapCanvas. iface.mapCanvas() is initialized when you load QGIS app with GUI (Python should be enabled to use it), and refers to the main canvas ...


0

I did not find it. There is a "cleared" signal in QgsProject but fires after the project is closed. QgsMapLayer has a "willBeDeleted" signal but also fires after system prompts the save dialog.


1

The part where you were directly stucked should be related to the following newGrid = QgsLayoutItemMapGrid ('My new grid', referenceMap) referenceMap.grids().addGrid(newGrid) You can find below a long correction if you want to use existing grid (if already in your layout) or by adding a new grid project = QgsProject.instance() manager = project....


3

I would like to share the solution I found to integrate PyCharm and PyQGIS in an effective way to run standalone scripts: Setup: Windows 10 QGIS 3.10.4 installed in c:\Program Files\QGIS 3.10 PyCharm 2020.1.1 installed in c:\Program Files\JetBrains\PyCharm Community Edition 2020.1.1\bin\pycharm64.exe I can start PyCharm from a batch file (e.g., ...


2

This is how I found a solution: At shell I run: export QT_QPA_PLATFORM=offscreen Then, at a python script I did this: import os from qgis.core import * os.environ["QT_QPA_PLATFORM"] = "offscreen" QgsApplication.setPrefixPath("/usr", False) qgs = QgsApplication([], False) qgs.initQgis() This solution is based on another answer I found here After this ...


0

I eventually ended using first option, parsing the cur.fetchall() method. Here's the way I did it. I'm sure it's not the most elegant way, but it satisfied my needs. def addAtts(layer, attName, varType): layer.dataProvider().addAttributes([QgsField(attName, varType)]) layer.updateFields() def conversion(pg_type): if pg_type== 25: ...


1

It's possible to set the configuration from PyQGIS although it has been a bit annoying to look at the C code to find the keys to write in the QGIS project file (https://github.com/qgis/QGIS/blob/9a0a1297c2e585cdbc3dbeeb64f5792024a451f9/src/app/qgsprojectproperties.cpp#L1479) You can find below a recipe. After running it, you will be able to see if it works ...


1

Look at layout.referenceMap().atlasMargin(QgsLayoutObject.OriginalValue) # Get current value. # You can replace above QgsLayoutObject.OriginalValue with QgsLayoutObject.EvaluatedValue # if using an expression instead of a fixed value layout.referenceMap().setAtlasMargin(yourvalue) # Set current value


1

Replace the part QgsApplication.processingRegistry().addProvider(VisibilityProvider()) with the following visibilityProvider = VisibilityProvider() visibilityProvider.setActive(True) QgsApplication.processingRegistry().addProvider(visibilityProvider) FYI, deduced from https://github.com/zoran-cuckovic/QGIS-visibility-analysis/blob/master/...


0

The approach that works in my testing context (PS: I have thrown away the QgsProcessingUtils, not needed or I missed something) This answer was an addition to solve the part you were stucked Seems good, but the display name in the layers panel remains stubbornly 'Extracted (attribute)'. I've used the file world_map.gpkg always present will all QGIS ...


0

That kind of works. I tried: layer = QgsProcessingUtils.mapLayerFromString(format(extracted['OUTPUT']), context ) feedback.pushInfo('\nLayer name is initially {}'. format(layer.name())) layer.setName('my_layer') feedback.pushInfo('\nLayer name is now {}'. format(layer.name())) The first pushInfo call produces: 'The name of the layer ...


0

If I understood correctly the problem, you need to use the QgsMapLayer.setName() function (documentation here). So, taking your code, you should be able to set the layer display name with: layer.setName("LayerDisplayName") Hope this helps.


1

For the expression, you should use the following if( file_exists(attribute(@atlas_feature, 'pict')), attribute(@atlas_feature, 'pict'), '/tmp/fallback.png' ) For manipulating expressions, you should use from qgis.core import QgsProject, QgsLayoutItemPicture project = QgsProject.instance() manager = project.layoutManager() layout = manager....


2

To know about startup.py, look at https://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/intro.html#run-python-code-when-qgis-starts Now, you know more, to load automatically at each startup, in startup.py, do from qgis.utils import iface browserModel = iface.browserModel() dirs = ['U:\dir1', 'U:\dir2', 'U:\dir3', 'U:\dir4'] for dir in dirs: ...


2

Because 3d is not part of the "native" plugins you load when executing PyQGIS in standalone (or the namespace of the functions will be native:tessellate instead of 3d:tessellate When you look at the code, you see that you would need a Qgs3DAlgorithms https://github.com/qgis/QGIS/blob/3b3c7d8012407e14fb24b684bb8a623836202f4a/src/process/qgsprocess.cpp#L174 ...


0

You can take a look at the bottom part sample from https://webgeodatavore.github.io/pyqgis-samples/gui-group/QgsAttributeTableView.html for a solution (disclosure: I'm the author of the content) You may also look at https://webgeodatavore.github.io/pyqgis-samples/gui-group/QgsMapLayerComboBox.html for a component to select layers Both samples are ...


7

Use this script: from PyQt5.QtCore import QVariant # layers polygon_lyr = QgsProject.instance().mapLayersByName("Polygons")[0] point_lyr = QgsProject.instance().mapLayersByName("Points")[0] # index number of "class" field field_index = point_lyr.fields().indexFromName('class') # unique class names unique_classes = point_lyr.uniqueValues(field_index) ...


1

I understand your issue but within a plugin, it will not be an issue in fact. To avoid reinstanciating the GUI, there is already a mecanism to run some part of the code once. You will find below screenshots to position your sample code (PS: I've made some modifications e.g replacing iface with self.iface due to plugin context) and checking it works. My ...


1

For the map canvas, you need to reuse the code from https://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/canvas.html#embedding-map-canvas in your standalone application to create your own canvas and sync it with the layers from your QgsProject instance in your script. With your newly canvas, you will be able to get the reference to the canvas and ...


1

native:reprojectlayer is executed as child algorithm. PyQGIS states in [%qgis_install_dir%\python\plugins\processing\tools\general.py:108] that: for child algorithms, we disable to default post-processing step where layer ownership is transferred from the context to the caller. In this case, we NEED the ownership to remain with the context, so that ...


1

QGIS tools run based on C++ and not Python, as MrXsquared and marcelo pointed me out. Still, you don't need to know any programming language to use the tools. The GUI is sufficient for many tasks. In addition the "syntax" of the field calculator is explained quite well. Still, learning Python can be sensible, especially if you need to accomplish very ...


0

Case a) You make an intersect between the bounding box from your track so it will return all polygons that intersect your line bounding box. So, that's why you get "wrong" results. Using index is a good way to reduce the number of results but then you need for each feature id from find_result to filter your polygon features with exact geometry using ...


2

Try: vlayer = QgsProject.instance().mapLayersByName('New scratch layer')[0] rlayer = QgsProject.instance().mapLayersByName('nh_62_3')[0] centroids = [g.geometry().centroid() for g in vlayer.getFeatures()] #Create a point layer from polygon centroids vl = QgsVectorLayer("Point?crs={}&index=yes".format(vlayer.crs().authid()), "myLayer", "memory") ...


2

I think you are looking for the function QgsVectorLayer.renameAttribute(index, newName) documentation is here. And here is a minimal code example to change an attribute from old_name to new_name: lyr = iface.activeLayer() idx_to_change = lyr.fields().names().index(old_name) lyr.startEditing() lyr.renameAttribute(idx_to_change , new_name) lyr.updateFields(...


0

With some help: here and here and thanks to a friend, I've found a solution ! Here it goes: import os from PyQt5.QtCore import QVariant from qgis.core import QgsVectorLayer,QgsField,QgsProject #Etape 1: édition de mon shapefile avec ajout des colonnes à remplir selon expression de l'étape 2 v1= QgsVectorLayer("E:/Stage/Modele_SIG/Etape_3/Données/...


1

edit(layer) may cause trouble in a "standalone" script, I got an error name 'edit' is not defined so I found another way. I made this example with an activeLayer() : layer = iface.activeLayer() # Open editing session layer.startEditing() # Rename field for field in layer.fields(): if field.name() == 'oldName': idx = layer.fields()....


1

The updated recipe for QGIS 3.x from qgis.core import QgsLayoutItemLegend, QgsLegendRenderer, QgsLegendStyle, QgsProject project = QgsProject.instance() manager = project.layoutManager() layout = manager.layoutByName('print1') # Your layout name # If only one legend within the layout layoutItemLegend = [i for i in layout.items() if isinstance(i, ...


1

German pointed out already that QgsFeatureRequest.setSubsetOfAttributes([li_required_idx]) returns None for any attribute not in li_required_idx. With some list comprehension it is possible to get li_attr equal to li_fields in the following code: lyr = iface.activeLayer() li_required_fields = ["POP_EST", "NAME_RU", "POP_DENSITY"] request = QgsFeatureRequest(...


0

Ok never mind; It's right here in the source code line 91: self.statistics = [ ('count', self.tr('count')), ('unique', self.tr('unique')), ('min', self.tr('min')), ('max', self.tr('max')), ('range', self.tr('range')), ('sum', self.tr('sum')), ('mean', self.tr('mean')), ('median', self.tr('median')), ('stddev', self.tr('...


3

when you set a temporary output for the 'native:reprojectlayer' algorithm, the OUTPUT is already a QgsMapLayer (in this case a vector) whose extent you can check. parametros = {'INPUT' : 'C:/Users/.../someshapefile.shp', 'OUTPUT' : 'TEMPORARY_OUTPUT', 'TARGET_CRS' : QgsCoordinateReferenceSystem('EPSG:5344') } output = processing....


0

Here is an updated version for QGIS3. Note that I hardcoded CRS and result directory. To get help for other CRS options you can run in Python Console: import processing processing.algorithmHelp('native:mergevectorlayers') Merge layers with same name script: import processing grouped_layers_by_name = {} distinct_layer_names = set() project_layers = ...


1

Probably you have two Pythons on your machine, one was installed with QGIS, and you install another independent of your QGIS. If you start your Python from the OSGeo4W shell the enviromnet will be set to QGIS (e.g. qgis.core is on the Python path). If you would like to use colour modul in QGIS you have to install it through the OSGeo4W shell or you can ...


4

Processing adds the Selected features only checkbox if you use a QgsProcessingParameterFeatureSource as input parameter, but it does not add the checkbox if you use a QgsProcessingParameterVectorLayer. Compare: Therefore, in your script, instead of using QgsProcessingParameterFeatureSource as input parameter type, use QgsProcessingParameterVectorLayer. ...


7

NULL is defined in qgis.core from qgis.core import NULL with edit(layer): for feature in layer.selectedFeatures(): feature.setAttribute('distance', NULL) layer.updateFeature(feature)


0

For QGIS 3 it will be layer.deselect(feature_id_here) https://qgis.org/pyqgis/3.10/core/QgsVectorLayer.html?highlight=deselect#qgis.core.QgsVectorLayer.deselect


0

Here is my results with UI and standalone script (perhaps something wrong with your input parameters): import os import sys import qgis.core OSGeo_folder = r'C:\OSGeo4W64' qgis.core.QgsApplication.setPrefixPath(os.path.join(OSGeo_folder, r'apps\qgis'), True) qgs = qgis.core.QgsApplication([], False) qgs.initQgis() sys.path.append(os.path.join(OSGeo_folder,...


2

No results by using different 'Distance Coefficients' is because layer_data has not 'setDistanceCoefficient' method. Desired method is in idw_interpolator. So, by using same code in your previous question about QgsIDWInterpolator, I had to add only one code line: . . . idw_interpolator.setDistanceCoefficient(10) . . . in following code: layer = iface....


0

Here is the updated Syntax for QGIS 3 / PyQGIS 3 from @Josephs answer: for layer in QgsProject.instance().mapLayers().values(): layer.setProviderEncoding(u'UTF-8') layer.dataProvider().setEncoding(u'UTF-8') print (layer.name(), layer.dataProvider().encoding())


1

Im not sure about the measurements (coordinate system in degrees, distance in meters) but the results doesnt look unreasonable: layer = iface.activeLayer() #https://gis.stackexchange.com/questions/266360/pyqgis-when-we-search-based-on-the-distance-between-two-points-is-the-measurem distance = QgsDistanceArea() distance.setEllipsoid('WGS84') ...


1

because data source parsing depends of provider you have to: QgsProviderRegistry.instance().decodeUri( layer.providerType(), layer.dataProvider().dataSourceUri() ) so in case of a file based provider you have decoded = QgsProviderRegistry.instance().decodeUri( layer.providerType(), layer.dataProvider().dataSourceUri() ) decoded['path']


3

So here is a Python solution to find the nearest point to the endpoints of the lines. In my sample I have a MultiPolyline layer with attributes: l_id (unique identifier), start_p and end_p integer. And a Point layer with an id attribute which I filled by $id (so the id attribute of the points are the same as the featureID), it make the solution simpler. # ...


Top 50 recent answers are included