2

I am wanting to pull some data from an OData endpoint, and create layers based on the content, with a Python script.

I have grabbed the data and formatted it, but can't find the correct function to create the geometry from it.

Data is structurally the same as Sample GeoJSON

Where I am stuck is the line

geometry = QgsGeometry.fromGeoJson(json.dumps(feature['geometry']))

as there is no ".fromGeoJSON" function.

Is there a function in another class, or do I need to convert to WKT or something else first?

Relevant code section below.

# Create a layer for each feature
for feature in layerData["features"]:
layer_name = f"Layer_{feature['properties']['anomaly']}"

# Create a memory layer with polygon geometry type
layer = QgsVectorLayer('Polygon?crs=EPSG:4326', layer_name, 'memory')

# Define fields based on properties
fields = QgsFields()
for key, value in feature['properties'].items():
    field = QgsField(key, QVariant.String)
    fields.append(field)

layer.dataProvider().addAttributes(fields)
layer.updateFields()

# Add the feature to the layer
print(feature['geometry']['coordinates'])
geometry = QgsGeometry.fromGeoJson(json.dumps(feature['geometry']))
new_feature = QgsFeature()
new_feature.setGeometry(geometry)

for key, value in feature['properties'].items():
    new_feature.setAttribute(key, value)

layer.dataProvider().addFeature(new_feature)

# Add the layer to the project
QgsProject.instance().addMapLayer(layer)

1 Answer 1

2

What you are looking for is QgsJsonUtils.geometryFromGeoJson. However, you should be able to save some lines of code by creating a vector layer directly from the GeoJSON string:

layer = QgsVectorLayer(json.dumps(layerData), layer_name, 'memory')

Then, to create a separate layer for each feature you can use the Split Vector Layer algorithm native:splitvectorlayer, passing 'anomaly' as the field to split by.

2
  • The method "geometyFromGeoJson" is not present in my install (QGIS v3.32.2 & Python 3.9.5) despite it showing in the docs. The other alternative you suggested takes a file path as its first argument, AFIK there is no way to pass an object (or array of objects) directly. Commented Jan 21 at 10:18
  • No, the first argument is a JSON string, dumped from a JSON object. I've used it directly with a json http response and it works
    – Andre Geo
    Commented Jan 22 at 11:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.