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 usestartEditing
andcommitChanges
.