Det händer inte bara saker med gränssnitt och funktioner i QGIS 3. Nej, vi som jobbar med skript, plugin, uttryck och funktioner, måste också börja anpassa oss till lite nytt.
Det här blir inte heltäckande, utan mer en dokumentation av lite experiment och efterforskande om framför allt Python uttryck som kan bli användbara i QGIS 3. Men innan du kastar dig in i Python så bör du läsa hela inlägget till slutet.
En del saker är naturliga förändringar, exempelvis så är det Python 3 som är grunden, vilket man behöver förhålla sig till. Sedan är det andra förändringar som påverkar en del, exempelvis att det går att ha flera kartor (canvas) i ett projekt.
Det senare innebär exempelvis att för att ta reda på utsträckningen på den karta som visas kan man använda:
iface.mapCanvases()[0].extent()
Detta uttryck kan man sedan använda med xMinimum(), xMaximum(), yMinimum() och yMaximum() för att få koordinater som exempelvis kan kombineras för att ta reda på hörnkoordinater för kartfönstret. Har man flera kartfönster så är det indexsiffran som skall ändras. Det går exempelvis att använda ovanstående i en funktion för att bygga geometrier i geometrigeneratorn, exempelvis en polygon som alltid täcker canvasytan. Användbart exempelvis om man vill ha ett blandningslager med gradientformfyllning som vinjett.
I inläggen tidigare har jag försökt jobba med kartans utsträckning (extent) i layouten, men då hette det ”canvas”. Numera finns inte canvas så då får man leta efter vad det heter i stället för att hitta till värden för xMaximum() etc för kartan i layouten.
Jag har lyckats leta mig fram till hur jag kan identifiera ”rätt” layout med dess namn.
my_layout = QgsProject.instance().layoutManager().layoutByName('layout_name')
Sedan kan jag lista alla objekt i layouten med my_layout.items(). Om jag sedan manuellt räknar vilket objekt som är den karta jag är intresserad av så kan jag anropa just detta objekt, följt av .extent().xMaximum() och liknande. Men det borde finnas ett enklare sätt att enbart iterera över QgsLayout. Dokumentationen på https://qgis.org/api/index.html är inte så lätt att läsa när man inte riktigt vet vad man letar efter och sökfunktionen är ”sådär”. Desto bättre är att jag nu även hittat den NYA dokumentationen för API på http://python.qgis.org/api/index.html. Denna skall bli spännande att utforska för att se om den är enklare att använda, men det har jag inte hunnit ännu.
Jag vet att allt med ”composer” ersatts av QgsLayout och QgsLayoutItem, men därifrån till att förstå exakt hur API’t fungerar är steget långt.
Efter lite googlande har jag hittat en något enklare lösning, vilket omfattar referenskartan. Med nedanstående kod kan jag hämta utsträckningen för den karta som är angiven som referenskarta i layouten.
my_layout.referenceMap().extent()
Om detta är det bästa sättet eller inte att hämta hörnkoordinater för en karta vet jag inte, men det fungerar tills vidare i alla fall.
Jag kan nu modifiera Alexandre Netos funktioner från tidigare, så att de även fungera i QGIS 3.
Vill du prova så har jag den modifierade funktionen på github: https://raw.githubusercontent.com/klakar/QGIS_resources/master/collections/Geosupportsystem/python/expressions/userfunctions.py
Spara den i den nya katalogen .local/share/QGIS/QGIS3/profiles/default/python/expressions så kommer du åt funktionerna map_x_min(layout_title) med flera bland uttrycken.
Den enklare vägen
Efter ett tips från Nyall Dawson så visade det sig att alla Pythonfunktioner ovan är helt onödiga i QGIS3!
Här finns det nämligen nya inbyggda funktioner i uttrycksbyggaren, som bygger på kartans ”Item ID”. Kartan refereras med:
map_get(map, key)
Variabeln ”map” i uttrycket ovan identifieras med ”item_variables(’item_id’)”.
Variabeln ”key” i uttrycket byts sedan mot exempelvis:
- map_extent
- map_extent_center
- map_crs
- map_scale
- map_rotate
Vill man därför skriva ut skalan för en karta med Item ID ”map” så använder man följande uttryck i textfältet:
[% to_int(map_get(item_variables('map'), 'map_scale')) %]
Resultatet är ett decimaltal, vilket kan krångla lite, därför använder jag ”to_int()” funktionen för att avrunda till heltal.
Om jag nu vill bygga upp en etikett med hörnkoordinater för en karta med Item ID ”map” så kan det se ut såhär:
E [% to_int(x_min(map_get( item_variables('map'),'map_extent')))%] N [% to_int(y_min(map_get( item_variables('map'),'map_extent')))%]
Alltså inte längre något behov av en funktion i Python, men uttrycket blir lite mer omständligt.
Nu behöver jag göra om mina Pythonfunktioner så att jag kan använda några av dessa nya variabler på ett mer effektivt sätt.
0 svar på ”Pythonfunktioner i QGIS 3”