I wrote a processing scrip for QGIS 2.18 to create a multi-distance buffer rings using the haversine formula. Unfortunately, it no longer works after I updated to QGIS 3.4.5. I've tried updating the script wherever I can but I can't figure out how to fix the part of the code where it writes the buffers to a shapefile.
Here's my code:
from math import *
from qgis.core import *
from qgis.utils import iface
from PyQt5.QtCore import *
from PyQt5.QtGui import *
layer = iface.activeLayer()
for feat in layer.selectedFeatures():
geom = feat.geometry()
start_x = geom.asPoint().x()
start_y = geom.asPoint().y()
sides = 64
radius = 6378137.0 # meters
create layer
vl = QgsVectorLayer("Polygon", "Distance Buffers", "memory")
pr = vl.dataProvider()
changes are only possible when editing the layer
vl.startEditing()
add fields
pr.addAttributes([QgsField("Distance", QVariant.Int), QgsField("Label", QVariant.String)])
distance = [250, 500, 1000, 2000, 3000, 4000, 5000, 10000, 15000, 20000, 25000, 30000, 40000, 50000]
for i in range(len(distance)):
points = []
dist = distance[i]
degrees = 0
while degrees <= 360:
degrees = degrees + 360 / sides
start_lon = start_x * pi / 180
start_lat = start_y * pi / 180
bearing = degrees * pi / 180
end_lat = asin((sin(start_lat) * cos(dist / radius)) + (cos(start_lat) * sin(dist / radius) * cos(bearing)))
end_lon = start_lon + atan2(sin(bearing) * sin(dist / radius) * cos(start_lat),
cos(dist / radius) - (sin(start_lat) * sin(end_lat)))
points.append(QgsPointXY(end_lon * 180 / pi, end_lat * 180 / pi))
fet_name = str(distance[i])
if distance[i] < 1000:
label = str(distance[i]) + "m"
else:
label = str(distance[i]/1000) + "km"
# add a feature
fet = QgsFeature()
geometry = QgsGeometry.fromPolygonXY([points])
fet.setGeometry(geometry)
fet.setAttributes([fet_name,label])
pr.addFeatures([fet])
commit to stop editing the layer
vl.commitChanges()
update layer's extent when new features have been added
because change of extent in provider is not propagated to the layer
vl.updateExtents()
myDir = QgsProject.instance().readPath("./")
file_name = 'Distance Buffers' + '.shp'
ShapefileDir = myDir + "/Shapefiles/" + file_name
_writer = QgsVectorFileWriter.writeAsVectorFormat(vl, ShapefileDir, "utf-8", None, "ESRI Shapefile")
At the last line of the code I get this error:
Traceback (most recent call last): File "C:/PROGRA~1/QGIS3~1.4/apps/qgis-ltr/./python/plugins\processing\script\ScriptEditorDialog.py", line 227, in runAlgorithm exec(self.editor.text(), d) File "", line 68, in TypeError: QgsVectorFileWriter.writeAsVectorFormat(): arguments did not match any overloaded call: overload 1: argument 4 has unexpected type 'NoneType' overload 2: argument 4 has unexpected type 'NoneType' overload 3: argument 3 has unexpected type 'str'
Based on the QGIS 3.0 documentation, I think writeAsVectorFormat now takes the following arguments: writeAsVectorFormat(layer: QgsVectorLayer, fileName: str, options: QgsVectorFileWriter.SaveVectorOptions, newFilename: str = ‘’) but I can't figure out how to set the SaveVectorOptions.
Can someone show me how this is done with this script, or with any other working examples?
dataProvider, so you don't need to usestartEditingandcommitChanges. – etrimaille Feb 26 '19 at 13:28