Publicerad den Lämna en kommentar

Tanaka stil i QGIS 3

För några år sedan (2015) skrev jag om en teknik med ”belysta” konturer som benämndes ”Tanakakonturer” (länk). När jag nu åter stötte på begreppet och granskade metoden från tidigare, så slog det mig. Mycket av det som krävdes då, går nu att göra direkt med stilsättning i QGIS.

Det finns en sak som jag inte lyckats lösa (ännu), och det är delningen av linjer i segment i stilsättningen. Detta får jag tills vidare göra separat med ett processverktyg.

Skärmbild från 2018-09-28 09-55-39

För att testa i ett mindre område så duger detta gott. Inga nya data behöver skapas för att bygga stilen och skapa stilfilen.

Det som skall göras är att skapa en datadefinierad åsidosättning för linjesegmentens färg, baserat på linjernas riktning.

with_variable( 'az', 360 * azimuth( point_n($geometry, 1), point_n($geometry, 2) ) / (2 * pi()), color_hsl(0,0, scale_linear( abs( if( @az<45, @az+315, @az-45 )-180 ), 0,180,0,100) )
)

Här inleder jag med att skapa en ”lokal” variabel kallad ‘az’ som beräknas genom funktionen azimuth(). Denna funktion tar två punkter som ingångsvärde och beräknar riktningen från den första till den andra punkten. Funktionen point_n() används för att hämta linjens första och andra punkt till detta. Resultatet av azimuth() är ett värde i radianer så detta görs även om till grader.

Variabeln anropas sedan med @az i funktionen color_hsl(). Denna funktion skapar ett färgvärde baserat på nyans, mättnad och luminans. Genom att sätta nyans och mättnad till 0, så kommer luminansvärdet att styra vart på en gråskala färgen hamnar.

Det går inte att använda azimuth värdet direkt då detta är ett värde mellan 0 och 360, så detta värde skalas om med funktionen scale_linear(). Då vägen från ”solsidan” till ”skuggsidan” kan ta vägen till vänster eller till höger med samma typ av övergång, så görs även riktningarna om om från 0 till 360 till från -180 till 180. Absolutbeloppet på detta värde gör att riktningarna hanteras likadant oavsett om de tar vägen till vänster eller höger.

I mitt resultat vill jag att solen skall falla in från uppe till vänster. Därför behöver jag kompensera för detta med lite matte baserat på ett 360 graders varv och vinkeln 45 grader (reduceringen till 180 grader är ännu ej gjord).

Omskalningen från 0-180 med scale_linear() görs till 0-100 då luminansvärde endast kan ha ett värde i det omfånget.

Skärmklipp från 2018-09-28 11:07:38.png

Linjernas tjocklek får anpassas till hur täta de är i kartan och det mjukar upp intrycket om man väljer ”rund” som ändstil på linjesegmenten.

Men vänta lite! Det där ser inte riktigt rätt ut…

Nej, det stämmer. För testerna använde jag lantmäteriets höjdkurvor från terrängkartan, men dessa är inte ritade konsekvent i samma riktning. Några linjer är ritade i ”moturs” när majoriteten är ritade ”medurs” (eller tvärt om, men ni förstår problemet). Det blir därför omöjligt för QGIS att veta om linjen beskriver en höjd eller en grop.

Om jag däremot skapar mina egna höjdkurvor från höjddata i rasterformat så kommer resultatet att se bättre ut.

Skärmklipp från 2018-09-28 11:08:00.png

”Bättre” i just det här fallet är lite relativt då jag använder öppna höjddata med 50m upplösning, så mina genererade kurvor blir inte lika bra som de från Lantmäteriet. Det är däremot bättre avseende vilka segment som ligger på solsida, respektive skuggsida.

Beroende på vad man använder för blandningsläge så kan man sedan uppnå olika effekter med dessa linjer.

Utveckling

Det som återstår är att få till segmenterade höjdkurvor på ett smidigare sätt än att behöva generera dessa i flera steg. Har man linjerna så kan man på sikt använda geometrigeneratorn och ”iterera” över alla brytpunkter i en linje (kommer eventuellt i 3.4). Sedan är jag inte säker på att det kommer att behövas på längre sikt, då det finns stöd för att stilsätta oklippta linjer oregelbundet baserat på m-värden. Kan man generera dessa m-värden med geometrigeneratorn så behövs det kanske ingen klippning. Det vore hur som helst trevligt att kunna tillämpa ”Tanaka” stilen på valfritt linjelager.

Att generera höjdkurvor från raster är också ett steg som skulle kunna automatiseras. Man kan tänka sig ett ST_ContourFromRaster() kommando eller liknande, men något sådant känner jag inte till för närvarande.

Om ett liknande kommando kan skickas till PostGIS, så kan man eventuellt tänka sig att även azimuth kan beräknas av PostGIS. Då skulle väldigt mycket kunna avlastas från QGIS och lagerdefinitionen med stil kunna tillämpas direkt på ett rasterdataset.

Nåja. Det var kul att åter testa Tanakastilen i QGIS och jag var lika förvirrad den här gången som sist när jag försökte reda ut matten i huvudet för det här med vänster- och högervarv. Det är i slutändan inte speciellt stor skillnad mot tidigare metod, annat än att nu finns det stöd för azimuth() direkt i uttrycksbyggaren. Det innebär i praktiken några färre processteg, men det blir lite fler beräkningar i realtid. Skall man skapa en karta/bild för användning i ett annat sammanhang så kan den här metoden vara att föredra, men om det handlar om att bygga ett lager för en webbtjänst, så är det nog bättre att göra så många beräkningar som möjligt i förväg.

Nyhet från Geosupportsystem , orginal inlägg

Lämna ett svar