Blog

QGIS-Plugin für schnelle Anpassung des Kartenstils

Symbologie und Schriftgröße einer QGIS-Karte mit wenigen Klicks ändern, anstatt für viele Kategorien jedes einzelne Symbol (und jede Symbolebene) oder viele regelbasierte Labels zu ändern.

Screenshot Adjust Style
QGIS Plugin Adjust Style

Das Aussehen einer Karte in QGIS zu ändern, kann viel Arbeit bedeuten: Farbe und Liniendicke zahlreicher Symbole – die oft aus mehreren Symbolebenen bestehen – und die Schriftart / -größe verschiedener regelbasierter Beschriftungen müssen geändert werden, und jeder Schritt erfordert eine Menge Mausklicks. Vielleicht sähe es besser aus, wenn alle Straßen etwas breiter wären? Die Schriftgröße der Beschriftungen ein wenig größer? Wie wäre es, eine Schriftart, die in vielen Beschriftungsregeln verwendet wird, durch eine andere zu ersetzen? Oder eine einfarbig blaue Karte in eine pinke Karte zu verwandeln?

Ich habe ein Python-Plugin geschrieben, um all dies schnell und konsistent mit ein paar Klicks zu erledigen:

  • Farbe aller Symbole (einschließlich Farbverläufe und einer beliebigen Anzahl von Symbolebenen) und Beschriftungen mithilfe des HSV-Farbmodells (hue, saturation, value) ändern (Farbton bzw. Farbkreis drehen, Sättigung und Helligkeit ändern)
  • Liniendicken aller Symbole ändern (incl. Polygonränder)
  • Schriftgröße aller Beschriftungen ändern
  • Eine in Beschriftungen verwendete Schriftart überall durch eine andere Schriftart ersetzen
  • Stile aller Ebenen in einen Ordner speichern bzw. aus einem Ordner laden.
  • … und all das für alle Ebenen, für alle gewählten Ebenen oder für die aktive Ebene.

Installieren

Das Plugin ist im QGIS Plugins Repository und kann direkt von QGIS installiert werden (Menü: Erweiterungen > Erweiterungen verwalten und installieren).

Alternativ den Ordner mit dem Source Code in den Plugin-Ordner von QGIS kopieren (oder mit Git klonen) und das Plugin in QGIS aktivieren (Menü: Erweiterungen > Erweiterungen verwalten und installieren).

Verwendung

Das Plugin vom Menü oder dem Toolbar starten, auf der rechten Seite des Hauptfensters öffnet sich ein Werkzeugkasten. Als Erstes die Ebenen wählen, die angepasst werden sollen. Mögliche Auswahl:

  • Aktive Ebene
  • Gewählte Ebenen
  • Sichtbare Ebenen
  • Alle Ebenen

Farbe ändern

Das Anpassen von Farben funktioniert im HSV-Farbmodell. Das bedeutet, dass der Farbton der HSV-Farben wie ein Farbrad gedreht werden kann: Einfach den Winkel der Drehung einstellen und auf „OK“ klicken. Das Farbgitter oberhalb des Schiebereglers dient als Vorschau.

Um Sättigung und Farbwert (= Helligkeit) einzustellen, klicken Sie auf die entsprechenden Plus- und Minus-Buttons. Vorsichtig: Die Plus- und Minus-Schaltflächen können nicht verwendet werden, um bereits vorgenommene Änderungen rückgängig zu machen, da die Werte der Sättigung und des HSV-Werts im Intervall von 0 bis 255 bleiben und jede Farbe, die an diesen Grenzen ankommt, nicht im gleichen Maß zurückgeschoben werden kann. Es empfiehlt sich, die Ebenenstile zu speichern, bevor Sie diese Schaltflächen verwenden!

Liniendicke

Die Liniendicke aller Symbole (Linien und Ränder von Polygonen und Punktmarkern) wird bei Klicks auf die Plus-/Minusbuttons um ± 5 % geändert.

Beschriftungen

Hinweis: Die Änderung der Farbe einer Ebene ändert auch die Farbe der Beschriftungen (Text, Puffer, Hintergrund).

Schriftgröße: Die Plus-/Minusbuttons ändern die Schriftgröße überall um ± 5 %.

Schrift ersetzen: Eine im Projekt verwendete Schriftart überall durch eine beliebige Schriftart ersetzen.

Stile speichern und laden

Diese Schaltflächen bieten eine schnelle Möglichkeit, die Stile aller (oder aller ausgewählten) Ebenen zu speichern. Sie müssen nur einen Ordner auswählen. Der Dateiname der QML-Dateien entspricht dem Namen der Ebenen (wobei problematische Sonderzeichen durch Unterstriche ersetzt werden). Wenn es mehrere Ebenen mit demselben Namen gibt, werden dem Dateinamen zur Unterscheidung Indexwerte angehängt.

Wenn die Ebenennamen zweier Projekte übereinstimmen, ist es sogar möglich, die Stile eines Projektes für alle Ebenen direkt im anderen zu laden.

Plugin for quick changes to the symbology of your QGIS map

Adjust the style of your QGIS map with a few clicks instead of altering every single symbol for many categories or a number of label rules.

Screenshot Adjust Style
QGIS Plugin Adjust Style

It can be a lot of work to change the look of a map in QGIS: You have to change the colour and stroke width of numerous symbols — often consisting of several symbol layers — and the font of several label rules, and every step takes a lot of mouse clicks. Maybe you decide that all roads should be a little bit wider? The font size of labels a bit bigger? How about replacing a font that is used in many label rules with another one? Or turn a monochrome blue map into a pink one?

I wrote a python plugin in order to do all this quickly and consistently, with a few clicks. It allows to:

  • adjust color of all symbols (including color ramps and any number of symbol layers) and labels using the HSV color model (rotate hue, change saturation and value)
  • change line thickness (i.e. stroke width of all symbols / symbol borders)
  • change font size of all labels
  • replace a font family used in labels with another font family
  • save / load the styles of all layers at once into/from a given folder
  • … and all this either on all layers at once, only on the active layer or on selected or all visible layers.

Install

The plugin is in the QGIS Plugins Repository and can be installed directly from QGIS (menu: Plugins > Manage and Install Plugins).

Alternatively, copy (or git clone) the folder with the source code into your QGIS plugin folder and enable the plugin in QGIS (menu: Plugins > Manage and Install Plugins).

Usage

Start the plugin from the Plugin menu or the plugin toolbar, a dockwidget opens on the right side of the main window. First, select the layers you want to work on. Possible choices:

  • Active Layer
  • Selected Layers
  • Visible Layers
  • All Layers

Change Colour

Adjusting colours works in the HSV colour model. That means you can rotate the hue of the HSV colours as you would rotate a colour wheel: set the degree of the rotation and hit „OK“. The colour grid above the slider works as a preview.

To adjust saturation and value (= brightness), click on the respective plus and minus buttons. Be careful: You can’t use the plus and minus button to undo the changes already made since the values of saturation and HSV value stay in the interval ranging from 0 to 255 and any colour arriving at these borders can’t be moved back consistently. It is good practice to save the layer styles before using these buttons!

Stroke Width

Change the stroke width of lines and the borders of symbols of polygons and points by ± 5 % with clicks on the plus and minus buttons.

Labels

Note: Changing the colour of layers also changes the colour of labels (text, buffer and background).

Font Size: Use the plus / minus buttons to change the font size of labels by ± 5 %.

Replace Font: Choose the font family to be replaced and select a new font family.

Save and Load Styles

These buttons provide a quick way to save the styles of all (or all selected) layers. You only need to select a folder. The filename of the QML files corresponds to the layer name (with bad characters replaced by underscore). If there are several layers of the same name, you will get several files with an index value appended.

Should even work to save the styles of one project and load them in another one if the layer names match.

How to check if a map feature is within a polygon (e.g. within a country) using Python

Add the region, country etc. to your map features using Geopandas.

In my last post I prepared a geopackage with all peaks of the Alps that can be found on Openstreetmap. But how can I add columns about countries or the corresponding mountain areas? Well, a peak can be on a border and belong to more than one country, but it should only be within one mountain area. This means we need two different approaches. Of course, it is easy to adapt the code to use with any other kind of polygon (region, city, etc.).

The following code is available as Jupyter notebook on GitHub.

The data used in this notebook is © OpenStreetMap contributors under the Open Database License.

Add countries

For this, I downloaded the countries of the area with QuickOSM (key: admin_level, value: 2).

Since a peak can belong to several countries, I want one column per country with True/False. Note that this approach is slow.

import pandas as pd
import geopandas as gpd
import os

folder = 'alpinepeaks/'

# Load the peaks geopackage
gdf = gpd.read_file(folder + "peaks.geojson")
gdf.set_index('full_id', inplace=True)

# Get rid of the double Monaco
countries.replace('Monaco (territorial waters)', 'Monaco', inplace=True)
countries = countries.dissolve(by='name:en')

# The last line also sets 'name:en' as index
# That means we only need index + geometry
countries = countries[[ 'geometry']]

# Add a buffer of 50 m to countries 
# (first reproject from WGS84 to UTM) 
# to make sure that peaks on the border really get both countries.
countries = countries.to_crs("EPSG:32634")
countries.geometry = countries.geometry.buffer(50)

# Back to WGS84
countries = countries.to_crs("EPSG:4326")

# I create one column per country with True or False. The loop is slow!
for c in countries.index:
    print('processing', c)
    gdf[c] = gdf['geometry'].within(countries.loc[c].geometry) 

# Save
gdf.to_file(folder + "peaks2.geojson", driver='GeoJSON')

Add mountain area

I assume that a peak is only in one mountain area. This is much faster, as I only add one column.

From openstreetmap I downloaded relations with region:type=mountain_area.

# Open mountain regions geopacke
area = gpd.read_file(folder + 'mountain_region.gpkg')

# I define a function so I don't need to loop over the data frame.
def mountain_area(point):
    for a in area.index:
        if point.within(area.loc[a].geometry):
            return area.loc[a]['name']
    return None

# Map the function
gdf['mountain_area'] = gdf['geometry'].map(mountain_area)

# Save
gdf.to_file(folder + "peaks2.geojson", driver='GeoJSON')


Union of shapefiles without duplicates using python

Union of shapefiles without duplicates using python

How to combine a bunch of shapefiles (or QGIS vector layers) into a single one without dublicates using python with geopandas

I’ve just downloaded a lot of points — all peaks of the Alps — from Openstreetmap using the QuickOSM plugin in QGIS (search key: natural, value: peak). But to avoid connection timeouts, I had to narrow down my area of interest for each request. Now I want to combine the resulting QGIS layers (e.g. as shapefiles) into one layer, without the duplicates. This would be tricky in QGIS, but Python comes to help.

How to combine all these points in one layer without duplicates? (Map data © OpenStreetMap under the Open Database License)

The following code is available as Jupyter notebook on GitHub.

The data used in this notebook is © OpenStreetMap under the Open Database License.

In a second post, I explain how to check if a feature is within a polygon (e.g. within a country or region).

Load all shapefiles into one GeoDataFrame and remove duplicates

import pandas as pd
import geopandas as gpd
import os

folder = 'alpinepeaks/'

# Create a list of all shapefiles
# (Change the code to use other formats such as geopackage)
filelist = []
for file in os.listdir(folder):
    if file.endswith(('.shp')):
        filelist.append(file)

# Read all shapefiles into a single geopandas GeoDataFrame
gdf = gpd.read_file(folder + filelist[0])
gdf.set_index('full_id', inplace=True)

for file in filelist[1:]:
    newgdf = gpd.read_file(folder + file)
    newgdf.set_index('full_id', inplace=True)
    gdf = pd.concat([gdf, newgdf])

# remove duplicates
gdf = gdf[~gdf.index.duplicated(keep='first')]

Clean data

Chances are, we have a lot of useless columns populated mostly by „None“. Let’s only keep data we really care about. This is best done in a jupyter notebook or the python shell, in order to distinguish the data to be dropped.

# First, I remove rows without name (I don't need them)
gdf = gdf[gdf['name'].notna()]

# How many columns do we have?
len(list(gdf.columns))

# List all columns (sorted)
sorted(list(gdf.columns))

# To check for e.g. 'outdoor':
gdf[gdf['outdoor'].notna()].dropna(axis=1) # Only two rows

# Only keep useful columns
useful = ['name', 'prominence', 'ele', 'geometry', 'name_en', 'name_fr', 'name_it','alias', 'alt_name', 'alt_name2', 'sport', 'name_1', 'name_de_AT',
 'name_de_DE']
gdf = gdf[useful]


Save

I save the result as geojson:

gdf.to_file(folder + "peaks.geojson", driver='GeoJSON')

Read on

How to check if a map feature is within a polygon (e.g. within a country) using Python

New book: The Formation of Mountains

This book about orogenesis provides both, a gentle introduction to geology and a detailed explanation of individual mountain ranges and travel destinations.

The processes that create and shape mountains are just as fascinating as the resulting landscapes. This book invites you on a geological journey around the world. Popular travel destinations are explained in detail, making it a kind of guide book for travellers interested in earth sciences. It also unearths many surprises that are not covered in classic textbooks. I wrote it for everyone who likes to be in the mountains, for example, for hiking, mountaineering or climbing. However, the book is also suitable for students of geography and geosciences, especially when preparing for a trip and to look beyond the horizon of one’s own discipline.

Florian Neukirchen
The Formation of Mountains

November 2022, Springer
Hardcover: ISBN 978-3031113840

The book has been published end of November 2022 by Springer and is on sale in bookshops. Ebooks (PDF and kindle) are available from some online bookshops or from Springer Link. By the way, the cover shows Fitz Roy from Laguna de las Tres.

More than 10 years have passed since the first edition of Bewegte Bergwelt was published in German. Since then, geology has evolved; there are new seismic profiles, more accurate age datings and many other interesting studies. The present translation is based on the completely revised, updated and expanded second edition that was published a few weeks ago.

Florian Neukirchen
Bewegte Bergwelt: Gebirge und wie sie entstehen
2nd Edition, completely revised
Springer, October 2022
Hardcover: ISBN 978-3-662-64837-7
Ebooks: PDF, Kindle

The cover of the second German edition shows Mount Everest and Nuptse, seen from Kalar Patthar at sunset.

Die 2. Auflage von Bewegte Bergwelt

Mein Buch über Gebirgsbildung habe ich vollständig überarbeitet, aktualisiert und deutlich erweitert.

Seit Erscheinen der 1. Auflage meines Buchs Bewegte Bergwelt sind bereits mehr als zehn Jahre vergangen. Seither hat sich meine Vorstellung, was ein gutes Buch und gute Didaktik ausmacht, deutlich gewandelt. Auch die Geologie hat sich weiterentwickelt; es gibt neue seismische Profile, neue Datierungen und viele weitere interessante Studien und Diskussionen. Gute Gründe, um das Buch für die Neuauflage gründlich zu überarbeiten. Der Text ist wieder auf dem neuesten Forschungsstand und ich lege nun mehr Wert darauf, bei kontroversen Theorien beide Seiten der Diskussionen darzustellen. Nebenbei habe ich natürlich auch Fehler gefunden und verbessert. Ich habe zudem einige beliebte Reiseziele neu ins Buch aufgenommen, wodurch es auf einen Umfang von über 500 Seiten angewachsen ist.

Florian Neukirchen
Bewegte Bergwelt: Gebirge und wie sie entstehen
2. Auflage, vollständig überarbeitet
Springer, Oktober 2022
Gebunden: ISBN 978-3-662-64837-7
Ebooks: PDF, Kindle

Die wichtigste Zielgruppe sind weiterhin alle, die gerne in den Bergen sind, etwa zum Wandern, Bergsteigen oder Klettern. Das Buch ist aber auch für Studierende der Geografie und der Geowissenschaften geeignet, insbesondere bei der Reisevorbereitung und für einen Blick über den Tellerrand der eigenen Fachrichtung. Spannender als jede Bestandsaufnahme von Gesteinsformationen finde ich, wenn man sich die Vorgänge, die zur Entstehung eines Gebirges beigetragen haben, bildlich vorstellen kann. Die Prozesse, die Berge entstehen lassen und in Form bringen, sind ebenso faszinierend wie die resultierenden Landschaften. Das Buch lädt auf leicht verständliche Weise zu einer geologischen Weltreise ein und fördert dabei auch so manche Überraschung zutage.

Die 2. Auflage ist Anfang Oktober bei Springer erschienen und ist im Buchhandel erhältlich. Ebooks (PDF oder Kindle) gibt es bei diversen Online-Buchhändlern oder bei Springer Link. Das Titelbild zeigt übrigens Mount Everest und Nuptse, aufgenommen bei Sonnenuntergang vom Khalar Patthar.

Das Buch wurde bei dieser Gelegenheit auch ins Englische übersetzt: The Formation of Mountains erscheint im November, ebenfalls bei Springer. Das Titelbild zeigt Fitz Roy von der Laguna de los Tres.

Florian Neukirchen
The Formation of Mountains

November 2022, Springer
Hardcover: ISBN 978-3031113840

QGIS: Haupt- und Nebengipfel kategorisieren

In OpenStreetMap sehen alle Gipfel gleich aus. Wie kann man sie in QGIS als Haupt- und Nebengipfel klassifizieren?

Haben Sie schon einmal versucht, mit OpenStreetMap-Daten topografische Outdoor-Karten zu zeichnen? Wahrscheinlich ist Ihnen aufgefallen, dass in OpenStreetMap alle Gipfel gleich aussehen, sowohl Haupt- als auch Nebengipfel. Auf OpenStreetMap ist es fast unmöglich, den Hauptgipfel eines Bergmassivs zu finden! Mein QGIS-Plugin Nearest with greater value bietet eine einfache Möglichkeit zur Klassifizierung von Gipfeln, um Haupt- und Nebengipfel unterschiedlich zu zeichnen.

In meinem Beispiel habe ich zunächst alle Gipfel (in OpenStreetMap-Daten: Tag „natural=peak“) in eine separate Ebene extrahiert. Dann habe ich das Plugin nearest with greater value mit ele als „field to compare“ verwendet. Für die Darstellung der Ausgabeebene habe ich eine regelbasierte Symbolisierung verwendet:

  • "neargtdist">10000 für dominante Gipfel (der nächst höhere Gipfel ist >10 km entfernt).
  • ("neargtdist" > 1000) AND ( "neargtdist" <=10000) AND ("name" IS NOT NULL) für Hauptgipfel (der nächst höhere Gipfel ist >1 km entfernt)
  • ELSE für Nebengipfel (schwarze Ringe in der Abbildung).

Ich habe in der Regel für Hauptgipfel "name" IS NOT NULL hinzugefügt. Der Grund sind einige kleinere Hügel in weiten Tälern, die sonst als Hauptgipfel eingestuft werden.

QGIS: Classify and style major and minor summits

In OpenStreetMap, all peaks look the same. How to classify them in QGIS as major and minor peaks?

Did you ever try to draw outdoor topographic maps using OpenStreetMap data? You probably noticed that all peaks look the same on OpenStreetMap, both minor and major summits. On OpenStreetMap, it is nearly impossible to find the main summit of any mountain massif. My QGIS plugin nearest with greater value provides an easy way to classify peaks in order to style major and minor summits differently.

In my example, I first extracted all peaks (in OpenStreetMap data: tag „natural=peak“) into a separate layer. Now I used the plugin nearest with greater value with ele as „field to compare“. In symbology of the output layer, I used rule-based symbology:

  • "neargtdist">10000 for dominant peaks (the next higher peak is >10 km away).
  • ("neargtdist" > 1000) AND ( "neargtdist" <=10000) AND ("name" IS NOT NULL) for major summits (the next higher summit is >1km away)
  • ELSE for minor summits (shown as black rings in the figure).

Note that I added "name" IS NOT NULL for the rule of major summits. The reason are some minor hills in wide valleys that were classified as major summits otherwise.

Assign the correct UTM zone to a project in QGIS with one click

Anyone who regularly opens a GPS track in QGIS or works on a local map often wants to have the map displayed in the UTM system. To do this, you first had to find out the correct UTM zone and search for it in the corresponding dialogue box. The first plugin I wrote for QGIS does it all with a single click on the UTM button (in the plugin toolbar). It’s called ProjectUTM and is already in the QGIS Python Plugins Repository.

In QGIS einem Projekt mit einem Klick die richtige UTM-Zone zuweisen

Wer regelmäßig in QGIS einen GPS-Track öffnet oder an einer lokalen Karte arbeitet, möchte die Karte häufig im UTM-System angezeigt haben. Dazu musste man erstmal die korrekte UTM-Zone herausfinden und diese im entsprechenden Dialogfenster suchen. Mein erstes Plugin, das ich für QGIS geschrieben habe, erledigt das mit einem Klick auf den UTM-Schaltknopf (im Plugin-Toolbar). Es heißt ProjectUTM und ist bereits im QGIS Python Plugins Repository.