Saturday, 11 January 2020

qgis - QgsVectorFileWriter creating empty shapefile and invalid GEOJson


A script I wrote recently as an answer here was written and was working in QGIS 2.14.?, but now that I've updated to 2.18.3, the script is not working.


I'm not getting any error messages saying anything isn't working correctly, it is just creating an output point layer with 0 features. I'm saving the shapefile to file, and the shape files are not empty. The .dbf file is about 500Mb and the .shp file is about 10Mb, but when loaded in QGIS there are no features. EDIT more details on saving as a shapefile. Similar to saving as a GEOJson, when the script initially creates the shapefile it loads in with 0 features. If I close and reopen QGIS, the shapefile changes and if I load it again, then all of my expected features are there.



I tried outputting to different formats like GEOJson, and with GEOJson it created a perfectly valid .geojson file, but it left out the closing bracket for the features object and it left out the closing curly brace for the whole geojson file. I manually added in the closing bracket and curly brace and was able to load the geojson file into QGIS and everything looks correct from that point on. EDIT More details on saving as GEOJson. When I run the script the file is missing the closing bracket and curly brace, so it fails to load the layer, but if I close QGIS, then the file changes and if I open it again, then the closing bracket and closing curly brace have been added. It's as if QGIS is somehow preventing QgsVectorFileWriter from finalizing the file for some reason.


I've also tried completely reinstalling QGIS from the OSGeo4W 64bit installer (I'm using this installer instead of the standalone QGIS installer because I need the FileGDB libraries)


I tried to reproduce the error with a simpler script, so I took the example scripts here and tried to run those. Unfortunately (or fortunately depending on your perspective) those very simple scripts worked to generate valid shapefiles and geojson files.


So, why is the QgsVectorFileWriter failing to write out valid shape files and geojson files in my script?


The script from the answer linked above is copied below for convenience.


##measure_layer=vector
##output_layer=output vector

from qgis.core import *
from qgis.utils import *

from PyQt4.QtCore import *
from PyQt4.QtGui import *

def cleanUp(writer):
del writer
iface.messageBar().clearWidgets()

def addVertices( linestring, writer, inputFeature ):
type = linestring.geometryType()
if type == "MultiLineString" and linestring.isMeasure():

geomCount = linestring.numGeometries()
for i in range(0, geomCount):
line = linestring.geometryN(i)
addVertices(line, writer, inputFeature)
elif type == "LineString" and linestring.isMeasure():
vertexCount = linestring.vertexCount()
for i in range(0,vertexCount):
v = linestring.pointN(i)
feature = QgsFeature(fields)
m_value = v.m()

feature.setGeometry( QgsGeometry.fromPoint( QgsPoint(v.x(), v.y()) ) )
attributes = inputFeature.attributes()
attributes.append(m_value)
feature.setAttributes(attributes)
writer.addFeature(feature)
else:
cleanUp(writer)
raise ValueError("Input layer must be a linestring or multilinestring and contain M-values")
return


iface.messageBar().clearWidgets()
progressMessageBar = iface.messageBar()

progress = QProgressBar()
progress.setMaximum(100)
progressMessageBar.pushWidget(progress)

inlayer = processing.getObject(measure_layer)
provider = inlayer.dataProvider()
fields = provider.fields()

fields.append( QgsField("MValue", QVariant.Double) )
writer = QgsVectorFileWriter(output_layer, 'UTF-8', fields, QGis.WKBPoint , inlayer.crs())

features = inlayer.getFeatures()
featureCount = inlayer.featureCount()
featureIndex = 0

for f in features:
percent = (featureIndex/float(featureCount)) * 100
progress.setValue(percent)

g = f.geometry()
lines = g.geometry()
addVertices(lines, writer, f)
featureIndex +=1

cleanUp(writer)

Answer



For some reason QGIS is not happy with the cleanUp function


def cleanUp(writer):
del writer

iface.messageBar().clearWidgets()

Removing the cleanUp function and replacing instances of cleanUp(writer) with


del writer
iface.messageBar().clearWidgets()

fixes the output problems described above.


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...