I am trying to make hub lines between two vector files. I succeed manually to do that (in QGIS 3.0) and in a PyQGIS 2.18. But my code doesn't work in PyQGIS 3.0. Here it is:
output = '/home/user/Desktop'
grid = QgsVectorLayer('/home/Desktop/grid.shp',
"cells", "ogr")
sys.path.append('/usr/share/qgis/python/plugins')
from processing.core.Processing import Processing
Processing.initialize()
import processing
processing.algorithmHelp("qgis:hublines")
processing.run('qgis:hublines', grid, 'Province', cities, 'Province', output)
With line processing.algorithmHelp I get that hub lines doesn't exist. But it does in qgis 3.0. Also, I tried to see the list of algorithms name with processing.alglist(), but without success.
UPDATE: I tried now with 'native:hublines' like underdark said. And now I can find algorithm, but it still doesn't work and I dont have error message. Here is my new code:
output = '/home/user/Desktop/output.shp'
cities = QgsVectorLayer('path to the cities',
"cities", "ogr")
grid_data = QgsVectorLayer('path to the grid',"grid", "ogr")
sys.path.append('/usr/share/qgis/python/plugins')
from processing.core.Processing import Processing
Processing.initialize()
import processing
QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())
processing.algorithmHelp("native:hublines")
params = {
'HUBS': grid_data,
'HUB_FIELD': 'Province',
'SPOKES': cities,
'SPOKE_FIELD': 'Province',
'OUTPUT': output
}
processing.run('native:hublines', params)
-
Did you read this post already? gis.stackexchange.com/questions/279874/…Germán Carrillo– Germán Carrillo2018年07月01日 16:13:36 +00:00Commented Jul 1, 2018 at 16:13
-
Yes, I did, but still, I cant find hublines. :/Neven– Neven2018年07月01日 18:08:06 +00:00Commented Jul 1, 2018 at 18:08
-
When I type processing.algorithmHelp("qgis:hublines") I get: Algorithm "qgis:hublines" not found But it does exist in qgis 3.0 and this code work in pyqgis 2.0. So, I suppose that is renamed or something. But I can find it. :/Neven– Neven2018年07月01日 18:16:54 +00:00Commented Jul 1, 2018 at 18:16
-
In the dev version it's "native:hublines"underdark– underdark2018年07月01日 19:56:05 +00:00Commented Jul 1, 2018 at 19:56
-
Thank you for the tip. But still, it doesn't work. I edited my question.Neven– Neven2018年07月01日 21:46:39 +00:00Commented Jul 1, 2018 at 21:46
1 Answer 1
You already have a working script, so I'll make this answer more of a troubleshooting workflow for getting an algorithm to work in pyqgis (in a standalone QGIS application). As you will see from the steps, the process is to make sure it works in the simplest case and add to the complexity in each step.
1. Make sure the algorithm works
Run the algorithm from the Processing Toolbox. Read the documentation and make sure that it produces the expected results from the input data you intend to use. Testing in Processing Toolbox Working algorithm
2. Check the help file for the algorithm
Open the Python Console (Ctrl+Alt+P) and run processing.algorithmHelp("<algorithm ID>")
to check the algorithm help file. You can get the algorithm help file from the Processing Toolbox history panel (Ctrl+Alt+H) - it would be the most recently run algorithm. In this case you would run processing.algorithmHelp("native:hublines")
. Take note of the input and output parameters, and their accepted data types. From the help file you can see that the HUBS
and SPOKES
input parameters can be either a str
for layer source or a QgsVectorLayer
(among other options). HUB_FIELD
and SPOKE_FIELD
can be either a str
or QgsProperty
. OUTPUT
can be various things, including a str
for 'destination vector file'. Note that it does not list a destination directory as an output option.
3. Check that it works from the Python Console
First I'll usually just copy the algorithm instruction from the Processing Toolbox history into the Python Console and make as few changes as possible to get it to run. In this case the instruction is:
processing.run("native:hublines",{
'HUBS':'C:/GIS/hublines/hubs.shp',
'HUB_FIELD':'id',
'HUB_FIELDS'[],
'SPOKES':'C:/GIS/hublines/spokes.shp',
'SPOKE_FIELD':'hubId',
'SPOKE_FIELDS':[],
'OUTPUT':'memory:'
})
There are a couple of things to check. Firstly, if you're in Windows, python often has problems with the path. It's safest to check that the paths use forward slash (/
), not backslash (\
). In this case they do, so that's fine. You can actually run the command as is, and it will work, but you won't be able to check the output. You could either add the output to a variable and load that as a layer, or send the output to a file and check that. In your example you were doing the latter, so we'll take that approach. We know from the previous step that a path to an output shapefile is an acceptable output parameter, so our instruction becomes:
processing.run("native:hublines",{
'HUBS':'C:/GIS/hublines/hubs.shp',
'HUB_FIELD':'id',
'HUB_FIELDS'[],
'SPOKES':'C:/GIS/hublines/spokes.shp',
'SPOKE_FIELD':'hubId',
'SPOKE_FIELDS':[],
'OUTPUT':'C:/GIS/hublines/output.shp'
})
If you run this and check the output directory, you should see output.shp
. You can load this in QGIS and check that it is what you expect. If you get errors at this stage, check the error message in the Python Console for clues as to what the problem could be, and be sure to also check the Processing log (make sure that it's enabled with View> Panels> Log Messages).
4. Generalise to suit your needs
Now you can generalise your to meet the broader needs of your script/standalone program. You might need your inputs to be added via a file picker, or to be in a different format. Now that you know you have a working base instruction, you can make the necessary changes, one at a time so that you can isolate any errors that crop up. You could move this to a script or standalone program, but I find it's still safer to test this in the Python Console. So your final instructions might be:
output = 'C:/GIS/hublines/output.shp'
hubFile = 'C:/GIS/hublines/hubs.shp'
spokeFile = 'C:/GIS/hublines/spokes.shp'
hubs = QgsVectorLayer(hubFile, "hubs", "ogr")
spokes = QgsVectorLayer(spokeFile, "spokes", "ogr")
params = {
'HUBS':hubs,
'HUB_FIELD':'id',
'SPOKES':spokes,
'SPOKE_FIELD':'hubId',
'OUTPUT': output
}
result = processing.run("native:hublines", params)
5. Add additional code to get it to work in your standalone application
Only at this point should you move your code into a standalone application. This question has some great advice on what is required to get it working in standalone mode:
Using QGIS3 Processing algorithms from standalone PyQGIS scripts (outside of GUI)
I haven't tested this in standalone mode, so I won't show what the final code would be, but hopefully this helps with the workflow to get there.
-
I think its really large and detailed answer and it would help a lot of people. Thank you, man, once again. Greetings. :)Neven– Neven2018年07月03日 10:51:11 +00:00Commented Jul 3, 2018 at 10:51