Building on recipes from the two answers here and here, you can try the script below. You will need to edit at least a couple of lines. Depending on how you installed QGIS (whether you used the standalone installer or OsGeo4W installer) your QgsApplication
prefix path and the path to the processing plugin may be different from what I used in the script.
Also, you will need to edit the in_folder
and out_folder
paths to match your own file system.
import sys
import os
from qgis.core import (QgsApplication, QgsVectorLayer)
from qgis.analysis import QgsNativeAlgorithms
# See https://gis.stackexchange.com/a/155852/4972 for details about the prefix
QgsApplication.setPrefixPath('C:/OSGeo4W/apps/qgis', True)
qgs = QgsApplication([], False)
qgs.initQgis()
# Append the path where processing plugin can be found
sys.path.append('C:\\OSGeo4W\\apps\\qgis\\python\\plugins')
import processing
from processing.core.Processing import Processing
Processing.initialize()
QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())
in_folder = 'C:\\Users\\Ben\\Desktop\\TEMP\\txt_files'
out_folder = 'C:\\Users\\Ben\\Desktop\\TEMP\\kml_files'
def save_as_kml(in_file, save_location):
out_layer = os.path.join(save_location, f'{in_file.name.replace(".txt", ".kml")}')
uri = 'file:///{}?delimiter={}&crs=epsg:4326&xField={}&yField={}'.format(in_file.path, '\\t','X', 'Y')
vlayer = QgsVectorLayer(uri, os.path.basename(in_file), 'delimitedtext')
paths = processing.run("qgis:pointstopath",
{'INPUT':vlayer,
'CLOSE_PATH':True,
'ORDER_FIELD':'Sort',
'GROUP_FIELD':'',
'DATE_FORMAT':'',
'OUTPUT':'TEMPORARY_OUTPUT'})
processing.run("native:polygonize",
{'INPUT':paths['OUTPUT'],
'KEEP_FIELDS':False,
'OUTPUT':out_layer})
src_dir = os.scandir(in_folder)
for file in src_dir:
if file.name.endswith('.txt'):
save_as_kml(file, out_folder)
I'm not sure how you run your standalone scripts, but if you have trouble, here is how I do it:
Save the script above as a .py file (e.g. save_as_kml.py)
Next, create a batch file with the following content:
@echo off
SET OSGEO4W_ROOT=C:\OSGeo4W
call "%OSGEO4W_ROOT%"\bin\o4w_env.bat
@echo off
path %PATH%;%OSGEO4W_ROOT%\apps\qgis\bin
path %PATH%;C:\OSGeo4W\apps\Qt5\bin
path %PATH%;C:\OSGeo4W\apps\Python39\Scripts
set QGIS_PREFIX_PATH=%OSGEO4W_ROOT:\=/%/apps/qgis
set GDAL_FILENAME_IS_UTF8=YES
rem Set VSI cache to be used as buffer, see #6448
set VSI_CACHE=TRUE
set VSI_CACHE_SIZE=1000000
set PYTHONPATH=%PYTHONPATH%;%OSGEO4W_ROOT%\apps\qgis\python
set PYTHONHOME=%OSGEO4W_ROOT%\apps\Python39
set QT_PLUGIN_PATH=%OSGEO4W_ROOT%\apps\qgis\qtplugins;%OSGEO4W_ROOT%\apps\qt5\plugins
cmd.exe
Again, the OSGEO4W_ROOT may be different than mine depending on your installation, just make sure it points to your main installation directory which contains the bin folder.
Save the batch file in the same location as your .py file. Then you can just double click the batch to launch it and, at the prompt, type: python save_as_kml.py
to run your script.
Best Answer
Thanks to @detlev for the idea of looking at the layer source:
iface.activeLayer().dataProvider().dataSourceUri()
gives
u'/vsigzip/J:\\GIS\\Data\\OSMM\\6417514-NH2708-5i6.gz|layername=TopographicArea'
It turns out that GML files are stored in a virtual file system vsigzip (http://erouault.blogspot.co.uk/2012/05/new-gdal-virtual-file-system-to-read.html)
so a (slightly bodged) solution is