-
Notifications
You must be signed in to change notification settings - Fork 5
/
helpers.py
73 lines (51 loc) · 2.23 KB
/
helpers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import json
from qgis.core import (QgsVectorLayer, QgsProject, QgsFeature, QgsGeometry, QgsPointXY, QgsField)
from qgis.PyQt import QtCore
def create_and_add_layer(name, epsg_id=4326):
"""Create a new memory layer, add it to the map and return it."""
mem_layer = QgsVectorLayer("Point?crs=epsg:{id}&index=true".format(id=epsg_id), name, "memory")
QgsProject.instance().addMapLayer(mem_layer)
return mem_layer
def add_features_to_layer(layer, features):
layer.startEditing()
layer.dataProvider().addFeatures(features)
layer.commitChanges()
layer.updateExtents()
layer.triggerRepaint()
# To distinguish sequences from strings
def is_sequence(arg):
return (not hasattr(arg, "strip") and
hasattr(arg, "__getitem__") or
hasattr(arg, "__iter__"))
# Takes data and return a string suitable for a (feature) attribute
# It will be either a standard string, either a serialized JSON object in cas of complex structure
def _get_field_value(o, field_name):
value = o[field_name]
if value:
if is_sequence(value): # Case 1: It's a list/dict
return json.dumps(value, ensure_ascii=False)
else: # Case 2: It's a string
return value
else: # Case 3: missing value
return ''
def add_gbif_occ_to_layer(occurrences, layer):
features = []
dp = layer.dataProvider()
for o in occurrences:
attrs = []
for k in list(o.keys()):
field_index = dp.fieldNameIndex(k)
# Add a layer attribute for each JSON fields(if not already encountered)
if field_index == -1:
dp.addAttributes([QgsField(k, QtCore.QVariant.String)])
attrs.append({'attr': k, 'val': _get_field_value(o, k)})
feat = QgsFeature()
# We should tell the feature which will be its fields
# !! We need a variable !! Don't merge the next two lines !!
myFields = dp.fields()
feat.setFields(myFields)
for d in attrs:
feat.setAttribute(d['attr'], d['val'])
feat.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(o['decimalLongitude'], o['decimalLatitude'])))
features.append(feat)
add_features_to_layer(layer, features)