-
-
Save ewsterrenburg/b579e1f6c053050112a2e89f9811408d to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*- | |
import json | |
from PyQt5.QtGui import QColor, QFont | |
from qgis.core import QgsPalLayerSettings, QgsTextFormat | |
from qgis.core import QgsTextBufferSettings, QgsVectorLayerSimpleLabeling | |
def turnOnLabels(layer, expression): | |
layer_settings = QgsPalLayerSettings() | |
text_format = QgsTextFormat() | |
text_format.setFont(QFont("Arial", 10)) | |
text_format.setSize(10) | |
buffer_settings = QgsTextBufferSettings() | |
buffer_settings.setEnabled(True) | |
buffer_settings.setSize(0.10) | |
buffer_settings.setColor(QColor("black")) | |
text_format.setBuffer(buffer_settings) | |
layer_settings.setFormat(text_format) | |
layer_settings.fieldName = expression | |
layer_settings.isExpression = True | |
# Line below is the original version | |
# Can't figure out anymore what the exact meaning of the magic 4 is... | |
# Could be replaced with a proper placement if required | |
# layer_settings.placement = 4 | |
layer_settings.enabled = True | |
layer_settings = QgsVectorLayerSimpleLabeling(layer_settings) | |
layer.setLabelsEnabled(True) | |
layer.setLabeling(layer_settings) | |
layer.triggerRepaint() | |
input_file_path = unicode(r"C:\Users\NL01031\Downloads\Annotations.json") | |
groupName ="Annotations" | |
project = QgsProject.instance() | |
root = project.layerTreeRoot() | |
group = root.addGroup(groupName) | |
# not the most elegant way to allow for longer descriptions, yet | |
# good enough for now. | |
# (for adding the fields in a more elegant way: https://anitagraser.com/pyqgis-101-introduction-to-qgis-python-programming-for-non-programmers/pyqgis101-creating-editing-a-new-vector-layer/ ) | |
lineLayer = QgsVectorLayer("linestring?crs=epsg:4326&field=id:string(36)&field=title:string&field=description:string(10000)&index=yes", "PolyLines", "memory") | |
project.addMapLayer(lineLayer, False) | |
group.addLayer(lineLayer) | |
pointLayer = QgsVectorLayer("point?crs=epsg:4326&field=id:string(36)&field=title:string&field=description:string(10000)&field=textvalue:string&&index=yes", "Points", "memory") | |
project.addMapLayer(pointLayer, False) | |
group.addLayer(pointLayer) | |
polygonLayer = QgsVectorLayer("polygon?crs=epsg:4326&field=id:string(36)&field=title:string&field=description:string(10000)&index=yes", "Polygons", "memory") | |
project.addMapLayer(polygonLayer, False) | |
group.addLayer(polygonLayer) | |
annotationFile = open(input_file_path) | |
annotations = json.loads(annotationFile.read()) | |
features = annotations['features'] | |
for feature in features: | |
attributeId = feature['properties']['id'] | |
attributeTitle = feature['properties']['title'] | |
try: | |
attributeDescription = feature['properties']['description'] | |
except KeyError: | |
attributeDescription = None | |
subParts = feature['features'] | |
for subPart in subParts: | |
featureType = subPart['geometry']['type'] | |
if featureType == 'LineString': | |
vertices = [] | |
for coord in subPart['geometry']['coordinates']: | |
vertex = QgsPoint(coord[0], coord[1]) | |
vertices.append(vertex) | |
geom = QgsGeometry.fromPolyline(vertices) | |
feat = QgsFeature(lineLayer.fields()) | |
elif featureType == 'Point': | |
coord = subPart['geometry']['coordinates'] | |
pointXY = QgsPointXY(coord[0], coord[1]) | |
geom = QgsGeometry.fromPointXY(pointXY) | |
feat = QgsFeature(pointLayer.fields()) | |
try: | |
attributeTextValue = subPart['properties']['valueText'] | |
except KeyError: | |
attributeTextValue = '' | |
feat.setAttribute('textvalue', attributeTextValue) | |
elif featureType == 'Polygon': | |
vertices = [] | |
if len(subPart['geometry']['coordinates']) == 0: | |
iface.messageBar().pushMessage("Warning", f"Polygon without vertices encountered for feature with id {attributeId}.", level=Qgis.Warning) | |
continue | |
for coord in subPart['geometry']['coordinates'][0]: | |
vertex = QgsPointXY(coord[0], coord[1]) | |
vertices.append(vertex) | |
geom = QgsGeometry.fromPolygonXY([vertices]) | |
geom.addRing(vertices) | |
feat = QgsFeature(polygonLayer.fields()) | |
feat.setGeometry(geom) | |
feat.setAttribute('id', attributeId) | |
feat.setAttribute('title', attributeTitle) | |
feat.setAttribute('description', attributeDescription) | |
if featureType == 'LineString': | |
(res, outFeats) = lineLayer.dataProvider().addFeatures([feat]) | |
elif featureType == 'Point': | |
(res, outFeats) = pointLayer.dataProvider().addFeatures([feat]) | |
elif featureType == 'Polygon': | |
(res, outFeats) = polygonLayer.dataProvider().addFeatures([feat]) | |
turnOnLabels(pointLayer, '"title" || \' - \' || "textvalue"') | |
turnOnLabels(lineLayer, '"title"') | |
turnOnLabels(polygonLayer, '"title"') |
@alex-myp made some changes, now it should also work with your dataset.
@ewsterrenburg thanks for the quick changes, my data is loading in QGIS now without issues. Appreciate the help with this, keep up the good work :)
Good morning! Appreciate for the code as JSON cannot be loaded directly in QGIS. I would like to inquire how to do it in the python console? What are the things I need to change in the code to be able to run them in the console? sorry another newbie in python. Thanks in advance!
@roelsantiago
Should be as simple as:
- Download this script
- Open the Python console
- Choose "Show editor"
- Open the script
- Change to path to where your json file is located
- Run
Success. great guide! Just a follow up, I notice in the python console, there's an option to "Add script Toolbox" Can this be implemented? then simply run the tools in the same manner like running a buffer? Big thanks!
@roelsantiago There's a few minor differences, yet indeed it can be implemented (in fact, this gist originally started as a plugin)
I included the improvements the current version and made it available here
https://drive.google.com/file/d/1vpJbGGb9Dq3U00u5rJ1bN5YGrcmg6BF3/view?usp=sharing
Thanks for the update! Tested the plugin in QGIS 3.32 and works perfectly fine.
@alex-myp Thanks for your upload.
The good news: with some minor changes I'm able to see the large majority of your features.
The bad news: