创建数据驱动的地图并不难,QGIS 可以轻松帮助您创建它。 QGIS 有很多很棒的功能可以从各种数据源创建好的地图。 您可以将图表、图像、文本作为附加元素与布局中的地图一起添加,以丰富您的地图,使其具有仪表板元素。
QGIS 支持 python 脚本来扩展其核心功能。 它给了我们很多优势。 Python 易于使用,有支持性的社区,它有数百个不同的库,这些库在节省执行图像处理、数据可视化、机器学习等特定任务的时间方面非常有用。
在我们的例子中,我们将使用 python 库来处理表格数据并创建图表,这些图表是 Pandas 和 Matplotlib 以及 PyQGIS 本身来访问 QGIS 中的核心功能。 Python 需要自动化整个过程,从读取数据源、过滤和操作数据、创建图表、将它们添加到布局,最后导出到 PDF 文件。
我假设您已经熟悉 QGIS 并且具备非常基本的 Python 编程知识,可以按照本教程进行操作。
对于本教程,我只需要两个图层:作为主题图层的动态数据和底图图层。
earthquakes events from USGS (find the data here : https://earthquake.usgs.gov/earthquakes/search/)
basemap voyager from Carto (https://carto.com/blog/new-voyager-basemap/)
当然,你需要 QGIS,以及一些 python 库:Pandas 和 Matplotlib 要安装在你的计算机上。 我们将在 QGIS 环境中运行这些 python 库。 不幸的是,QGIS 本身并不提供这些库,所以你必须手动安装它们。 如果你需要在 QGIS 环境中安装 python 库的指导,你可以阅读这篇文章。
这个布局模板很像容器,用于安排信息 如图表、地图、标签值 将被显示。 它的布局组成将帮助我们稍后在编写 python 脚本时定义正确的位置来绘制布局信息。
QGIS 布局模板
创建目录以组织本教程的输入和输出文件。
D:\PLAYGROUND\MAP-DASHBOARD
| create_map.py
| LICENSE
| README.md
| utils.py
|
+---data
| Carto-Voyager.xml
| earthquakes_2019.csv
| earthquakes_2019.csvt
| style_gempa.qml
|
+---img
| pyqgis.svg
| report_template_A4.qpt
| usgs-logo.jpg
|
\---report
这部分是关于导入所需的库、定义输入和输出数据、读取数据并加载到画布以及将预定义样式应用于图层。
import pandas as pd
import datetime as dt
from datetime import datetime, timedelta
import matplotlib.pyplot as plt
import matplotlib as mpl
import time
定义输入和输出
path = “D:\playground\map-dashboard”
file_basemap = os.path.join(path,”data\Carto-Voyager.xml”)
file_csv = os.path.join(path,”data\earthquakes_2019.csv”)
style_layer_gempa = os.path.join(path,”data\style_gempa.qml”)
qpt_path = os.path.join(path,”img/report_template_A4.qpt”)
output_pdf = os.path.join(path,”report/report_A4.pdf”)
#CRS definition
wgs84 = QgsCoordinateReferenceSystem(4326)
加载数据到 QGIS 画布
#Add layer to canvas
layer_basemap = iface.addRasterLayer(file_basemap, "", "gdal")
layer_gempa = iface.addVectorLayer(file_csv, "csv", "ogr")
layer_gempa.setCrs(wgs84, True)
#apply style to layer gempa
layer_gempa.loadNamedStyle(style_layer_gempa)
layer_gempa.triggerRepaint()
#Create Pandas DataFrame for statistics
df = pd.read_csv(file_csv,sep=';')
df['datetime'] = pd.to_datetime(df['time'], format='%Y-%m-%dT%H:%M:%S.%fZ') #convert string as datetime format
df2019 = df[(df['datetime']>dt.date(2019,1,1)) & (df['datetime']
我们需要将 csv 文件转换为 pandas 数据框。 Pandas真的很强大,我们会得到更多pandas特性的优势来处理原始数据表。 它还擅长处理大数据。
该图表将根据 pandas 数据框中的数据生成。
###LAYOUT COMPOSING
document = QDomDocument()
project = QgsProject.instance()
composition = QgsPrintLayout(project)layout = QgsLayout(project)
layout.initializeDefaults()
# read template content
# read template content
template_file = open(qpt_path)
#template_content = template_file.read()
#template_file.close()
document.setContent(template_content)
items, ok = layout.loadFromTemplate(document, QgsReadWriteContext(), False)# load layout from template and add to Layout Manager
composition.loadFromTemplate(document, QgsReadWriteContext())
project.layoutManager().addLayout(composition)
layout = project.layoutManager().layoutByName("Report A4")
#add map to layout
map = QgsLayoutItemMap(layout)
map.setRect(20, 20, 20, 20)#get extent from layer gempa
ext = layer_gempa.extent()
map.setExtent(ext)
layout.addLayoutItem(map)
map.setFrameStrokeWidth(QgsLayoutMeasurement(0.2,QgsUnitTypes.LayoutMillimeters))
map.attemptMove(QgsLayoutPoint(9.275, 22, QgsUnitTypes.LayoutMillimeters))
map.attemptResize(QgsLayoutSize(191.118, 88, QgsUnitTypes.LayoutMillimeters))
scale = map.scale()# call functions in utils
sys.path.append(path)
from utils import *# add label max_mag, avg_depth, count_eq
addLabel(layout, str(max_mag), 'Arial', 36, QFont.Bold, False, '#21908d', 0,0, 28.852, 125) #Magnitude label
addLabel(layout, str(round(avg_depth,2)), 'Arial', 36, QFont.Bold, False, '#21908d', 0,0, 93, 125) #Depth label
addLabel(layout, str(count_eq), 'Arial', 36, QFont.Bold, False, '#21908d', 0,0, 156, 125) #Magnitude label# add chart 1
addImage(layout,chart_count_mag,10, 175, 190, 34) #chart1: donut chart dumping point
addImage(layout,chart_avg_depth,10, 237, 190, 34) #chart1: donut chart dumping point# export layout to file
# creats a QgsLayoutExporter object
exporter = QgsLayoutExporter(layout)
settings = exporter.PdfExportSettings()
settings.rasterizeWholeImage = False
#this exports a pdf of the layout object
exporter.exportToPdf(output_pdf, settings)
exporter.exportToImage('D:/playground/map-dashboard/report/report_A4.png', QgsLayoutExporter.ImageExportSettings())
打开 QGIS 并打开 Python 控制台面板或使用快捷键 (Ctrl + Alt + P)。 单击打开脚本按钮以加载您刚刚创建的 python 脚本,然后运行它,就可以得到上面类似仪表盘的布局。
后续考虑把完整资料放出来:https://github.com/gwisnu/map-dashboard
上一篇:点成分享 | 离心机的六点小知识