Skip to content

Outputs

The Output_writer class is the base class for writing to different dataformats.

Output_Writer

Source code in python\engine\outputs.py
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
class Output_Writer:

    logger = get_logger()

    def postgis(layer, connection, dbname, schema, tablename, overwrite=True):
        """
        A function that exports a QgsVectorLayer into a Postgis database.

        Parameters
        ----------
        layer : QgsVectorLayer
            The QgsVectorLayer to be exported into Postgis

        connection : str
            The name of the connection object in the settings file

        dbname : str
            The database name

        schema : str
            Schema name

        tablename : str
            The name of the table that will be imported

        overwrite : str
            Defaults to True. Should the resulting table in Postgis be overwritten if it exists. If set to False, then it will append the data.
        """

        logger.info(f'Exporting {str(layer.featureCount())} features to Postgis')

        try:
            config = get_config()
            dbConnection = config['DatabaseConnections'][connection]
            logger.info('Creating temporary folder in Temp folder')
            tmp_path = f'{config["TempFolder"]}postgis_layer_{str(randrange(1000))}.geojson'
            options = QgsVectorFileWriter.SaveVectorOptions()
            options.driverName = 'GeoJSON'
            QgsVectorFileWriter.writeAsVectorFormatV3(layer, tmp_path, QgsProject.instance().transformContext(), options)
            logger.info('Temporary layer created')

            # ogr2ogr parameters
            table = f'-nln "{schema}.{tablename}"'
            ogrconnection = f'PG:"host={dbConnection["host"]} port={dbConnection["port"]} dbname={dbname} schemas={schema} user={dbConnection["user"]} password={dbConnection["password"]}"'
            ogr2ogrstring = f'{config["QGIS_bin_folder"]}/ogr2ogr.exe -f "PostgreSQL" {ogrconnection} {tmp_path} {table}'
            if overwrite:
                ogr2ogrstring = f'{ogr2ogrstring} -overwrite'
            logger.info(f'Writing to PostGIS database {dbname}')
            run = subprocess.run(ogr2ogrstring, capture_output=True)
            os.remove(tmp_path)
            logger.info('Temporary layer removed')
            logger.info('Export to PostGIS completed')

        except Exception as error:
            logger.error("An error occured exporting to Postgis")
            logger.error(f'{type(error).__name__}{str(error)}')
            logger.critical("Program terminated")
            script_failed()

    def geopackage(layer, layername, geopackage, overwrite):
        """
        A function that writes a QgsVectorLayer to a Geopackage file. 

        Parameters
        ----------
        layer : QgsVectorLayer
            The QgsVectorLayer that is to be written to the geopackage

        layername : String
            The name of the layer in the geopackage file

        geopackage : String
            The full path for the geopackage to be created

        overwrite : Boolean

            Specify wheather the writer will overwrite existing geopackage or append layer. Boolean True/False

        """

        logger.info(f'Writing {str(layer.featureCount())} features to geopackage : {geopackage}')
        try:
            layer.setName(layername)
            parameter = {'LAYERS': [layer],
                    'OUTPUT': geopackage,
                    'OVERWRITE': overwrite,
                    'SAVE_STYLES': False,
                    'SAVE_METADATA': False,
                    'SELECTED_FEATURES_ONLY': False}
            processing.run("native:package", parameter)
            logger.info(f'Parameters: {str(parameter)}')
            logger.info("Export to Geopackage completed")
        except Exception as error:
            logger.error("An error occured exporting layer to geopackage")
            logger.error(f'{type(error).__name__}{str(error)}')
            logger.critical("Program terminated")
            script_failed()

    def file(layer, path, format):
        """_summary_

        Parameters
        ----------
        layer : QgsVectorLayer
            The QgsVectorLayer that is to be written to a file

        path : _type_
            The full path for the file to be created

        format : _type_
            The driver type used to write the data to the file. 
        """

        logger.info(f'Writing {str(layer.featureCount())} features to: {path}')
        try:
            QgsVectorFileWriter.writeAsVectorFormat(layer, path, "utf-8", layer.crs(), format)
            logger.info("Export completed")
        except Exception as error:
            logger.error("An error occured exporting layer")
            logger.error(f'{type(error).__name__}{str(error)}')
            logger.critical("Program terminated")
            script_failed()

    def textfile(file, list,  newline):
        """
        Create an output file from a list of lines. 

        Parameters
        ----------
        file : Path and filename
            The file to be created.

        list : List
            List of lines to be written to the file.

        newline : Boolean
            If true, a newline character will be added to the end of each line.
        """
        logger.info("Creating text file: " + file)
        try:
            with open(file, 'w', encoding="utf-8") as f:
                for line in list:
                    if newline == True:
                        f.write(line + '\\n')
                    else:
                        f.write(line)
            logger.info("File created")
        except Exception as error:
            logger.error("An error occured creating file")
            logger.error(f'{type(error).__name__}{str(error)}')
            logger.critical("Program terminated")
            script_failed()

    def mssql(layer, connection, driver, schema, table, overwrite, geom_type, geom_name, ogr2ogr_params):
        """
        A function that exports a QgsVectorLayer into a MSSQL database using ogr2ogr.
        The function writes the data to a temporary geojson file, that is then importet to the database with ogr2ogr.

        Parameters
        ----------
        layer : QgsVectorLayer
            The QgsVectorLayer that is to be written to a file.

        connection : String
            The name of a connection from the settings.json file.

        driver : String (Optional)
            The driver used for writing to the database.
            Default value is : 'SQL Server'.

        schema : String
            The target schema.

        table : String
            The target table.

        overwrite : Boolean
            Overwrite or append.

        geom_type : String
            Geometry type. One of geometry/geography.

        geom_name : String
            Name of the geometry coloumn.

        ogr2ogr_params : String
            Extra parameters for ogr2ogr besides the default.
        """

        try:
            config = get_config()
            logger.info(f'Exporting {layer} to MSSQL Server')
            dbconnection = config['DatabaseConnections'][connection]
            conn = copy.copy(dbconnection)
            conn['password'] = 'xxxxxxx'
            logger.info(f'Connection: {str(conn)}')
            logger.info(f'Creating temporary layer in Temp folder')
            tmp_path = f'{config["TempFolder"]}mssql_layer_{str(randrange(1000))}.geojson'
            options = QgsVectorFileWriter.SaveVectorOptions()
            options.driverName = 'GeoJSON'
            QgsVectorFileWriter.writeAsVectorFormatV3(layer, tmp_path, QgsProject.instance().transformContext(), options)
            logger.info('Temporary layer created')

            ## ogr2ogr parameters
            table = f'-nln "{schema}.{table}"'
            geometry = f'-lco "GEOM_TYPE={geom_type}" -lco "GEOM_NAME={geom_name}"'

            if driver != '':
                mssql_driver = driver
            else:
                 mssql_driver = 'SQL Server'

            if dbconnection['user'] == '' and dbconnection['password'] == '':
                ogrconnection = f"MSSQL:server={dbconnection['host']};driver={mssql_driver};database={dbconnection['databasename']};trusted_connection=yes;"
            else:
                ogrconnection = f"MSSQL:server={dbconnection['host']};driver=SQL Server;database={dbconnection['databasename']};uid={dbconnection['user']};pwd={dbconnection['password']}"

            if overwrite == True:
                ow = '-overwrite'
            else:
                ow = ''

            if ogr2ogr_params != '':
                ep = ' ' + ogr2ogr_params
            else:
                ep = ''

            ogr2ogrstring = f'{config["QGIS_bin_folder"]}/ogr2ogr.exe --config MSSQLSPATIAL_USE_BCP FALSE -f "MSSQLSpatial" "{ogrconnection}" "{tmp_path}" {geometry} {table} -lco UPLOAD_GEOM_FORMAT=wkt {ep}  {ow}'
            logger.info(f'Writing to MSSQL database {dbconnection["databasename"]}, {table}')
            ogr2ogrstring.join(' -progress')
            run = subprocess.run(ogr2ogrstring, stderr=subprocess.STDOUT)
            if run.stdout:
                logger.info(run.stdout)
            os.remove(tmp_path)
            logger.info(f'Export to MSSQL completed')

        except Exception as error:
            try:
                os.remove(tmp_path)
            except:
                pass

            logger.error("An error occured exporting to MSSQL")
            logger.error(f'{type(error).__name__}{str(error)}')
            logger.critical("Program terminated")
            script_failed()

    def filegdb(layer, layername, path):
        """
        A function that export a QgsVectorLayer into an ESRI File

        Parameters
        ----------
        layer : QgsVectorLayer
            The layer that is to be written to an ESRI File GeoDatabase
        path : str
            The full path for the ESRI File Geodatabase to be created
        layername : str
            The name of the resulting layer in the ESRI File Geodatabase
        """

        logger.info(f'Writing {str(layer.featureCount())} features to: {path}')
        try:
            options = QgsVectorFileWriter.SaveVectorOptions()
            options.driverName = 'OpenFileGDB'
            options.layerName = layername
            QgsVectorFileWriter.writeAsVectorFormatV3(layer, path, QgsProject.instance().transformContext(), options)
        except Exception as error:
            logger.error("An error occured exporting layer to ESRI File Geodatabase")
            logger.error(f'{type(error).__name__}{str(error)}')
            logger.critical("Program terminated")
            script_failed()

file(layer, path, format)

summary

Parameters

layer : QgsVectorLayer The QgsVectorLayer that is to be written to a file

type

The full path for the file to be created

type

The driver type used to write the data to the file.

Source code in python\engine\outputs.py
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
def file(layer, path, format):
    """_summary_

    Parameters
    ----------
    layer : QgsVectorLayer
        The QgsVectorLayer that is to be written to a file

    path : _type_
        The full path for the file to be created

    format : _type_
        The driver type used to write the data to the file. 
    """

    logger.info(f'Writing {str(layer.featureCount())} features to: {path}')
    try:
        QgsVectorFileWriter.writeAsVectorFormat(layer, path, "utf-8", layer.crs(), format)
        logger.info("Export completed")
    except Exception as error:
        logger.error("An error occured exporting layer")
        logger.error(f'{type(error).__name__}{str(error)}')
        logger.critical("Program terminated")
        script_failed()

filegdb(layer, layername, path)

A function that export a QgsVectorLayer into an ESRI File

Parameters

layer : QgsVectorLayer The layer that is to be written to an ESRI File GeoDatabase path : str The full path for the ESRI File Geodatabase to be created layername : str The name of the resulting layer in the ESRI File Geodatabase

Source code in python\engine\outputs.py
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
def filegdb(layer, layername, path):
    """
    A function that export a QgsVectorLayer into an ESRI File

    Parameters
    ----------
    layer : QgsVectorLayer
        The layer that is to be written to an ESRI File GeoDatabase
    path : str
        The full path for the ESRI File Geodatabase to be created
    layername : str
        The name of the resulting layer in the ESRI File Geodatabase
    """

    logger.info(f'Writing {str(layer.featureCount())} features to: {path}')
    try:
        options = QgsVectorFileWriter.SaveVectorOptions()
        options.driverName = 'OpenFileGDB'
        options.layerName = layername
        QgsVectorFileWriter.writeAsVectorFormatV3(layer, path, QgsProject.instance().transformContext(), options)
    except Exception as error:
        logger.error("An error occured exporting layer to ESRI File Geodatabase")
        logger.error(f'{type(error).__name__}{str(error)}')
        logger.critical("Program terminated")
        script_failed()

geopackage(layer, layername, geopackage, overwrite)

A function that writes a QgsVectorLayer to a Geopackage file.

Parameters

layer : QgsVectorLayer The QgsVectorLayer that is to be written to the geopackage

String

The name of the layer in the geopackage file

String

The full path for the geopackage to be created

overwrite : Boolean

Specify wheather the writer will overwrite existing geopackage or append layer. Boolean True/False
Source code in python\engine\outputs.py
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
def geopackage(layer, layername, geopackage, overwrite):
    """
    A function that writes a QgsVectorLayer to a Geopackage file. 

    Parameters
    ----------
    layer : QgsVectorLayer
        The QgsVectorLayer that is to be written to the geopackage

    layername : String
        The name of the layer in the geopackage file

    geopackage : String
        The full path for the geopackage to be created

    overwrite : Boolean

        Specify wheather the writer will overwrite existing geopackage or append layer. Boolean True/False

    """

    logger.info(f'Writing {str(layer.featureCount())} features to geopackage : {geopackage}')
    try:
        layer.setName(layername)
        parameter = {'LAYERS': [layer],
                'OUTPUT': geopackage,
                'OVERWRITE': overwrite,
                'SAVE_STYLES': False,
                'SAVE_METADATA': False,
                'SELECTED_FEATURES_ONLY': False}
        processing.run("native:package", parameter)
        logger.info(f'Parameters: {str(parameter)}')
        logger.info("Export to Geopackage completed")
    except Exception as error:
        logger.error("An error occured exporting layer to geopackage")
        logger.error(f'{type(error).__name__}{str(error)}')
        logger.critical("Program terminated")
        script_failed()

mssql(layer, connection, driver, schema, table, overwrite, geom_type, geom_name, ogr2ogr_params)

A function that exports a QgsVectorLayer into a MSSQL database using ogr2ogr. The function writes the data to a temporary geojson file, that is then importet to the database with ogr2ogr.

Parameters

layer : QgsVectorLayer The QgsVectorLayer that is to be written to a file.

String

The name of a connection from the settings.json file.

String (Optional)

The driver used for writing to the database. Default value is : 'SQL Server'.

String

The target schema.

String

The target table.

Boolean

Overwrite or append.

String

Geometry type. One of geometry/geography.

String

Name of the geometry coloumn.

String

Extra parameters for ogr2ogr besides the default.

Source code in python\engine\outputs.py
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
def mssql(layer, connection, driver, schema, table, overwrite, geom_type, geom_name, ogr2ogr_params):
    """
    A function that exports a QgsVectorLayer into a MSSQL database using ogr2ogr.
    The function writes the data to a temporary geojson file, that is then importet to the database with ogr2ogr.

    Parameters
    ----------
    layer : QgsVectorLayer
        The QgsVectorLayer that is to be written to a file.

    connection : String
        The name of a connection from the settings.json file.

    driver : String (Optional)
        The driver used for writing to the database.
        Default value is : 'SQL Server'.

    schema : String
        The target schema.

    table : String
        The target table.

    overwrite : Boolean
        Overwrite or append.

    geom_type : String
        Geometry type. One of geometry/geography.

    geom_name : String
        Name of the geometry coloumn.

    ogr2ogr_params : String
        Extra parameters for ogr2ogr besides the default.
    """

    try:
        config = get_config()
        logger.info(f'Exporting {layer} to MSSQL Server')
        dbconnection = config['DatabaseConnections'][connection]
        conn = copy.copy(dbconnection)
        conn['password'] = 'xxxxxxx'
        logger.info(f'Connection: {str(conn)}')
        logger.info(f'Creating temporary layer in Temp folder')
        tmp_path = f'{config["TempFolder"]}mssql_layer_{str(randrange(1000))}.geojson'
        options = QgsVectorFileWriter.SaveVectorOptions()
        options.driverName = 'GeoJSON'
        QgsVectorFileWriter.writeAsVectorFormatV3(layer, tmp_path, QgsProject.instance().transformContext(), options)
        logger.info('Temporary layer created')

        ## ogr2ogr parameters
        table = f'-nln "{schema}.{table}"'
        geometry = f'-lco "GEOM_TYPE={geom_type}" -lco "GEOM_NAME={geom_name}"'

        if driver != '':
            mssql_driver = driver
        else:
             mssql_driver = 'SQL Server'

        if dbconnection['user'] == '' and dbconnection['password'] == '':
            ogrconnection = f"MSSQL:server={dbconnection['host']};driver={mssql_driver};database={dbconnection['databasename']};trusted_connection=yes;"
        else:
            ogrconnection = f"MSSQL:server={dbconnection['host']};driver=SQL Server;database={dbconnection['databasename']};uid={dbconnection['user']};pwd={dbconnection['password']}"

        if overwrite == True:
            ow = '-overwrite'
        else:
            ow = ''

        if ogr2ogr_params != '':
            ep = ' ' + ogr2ogr_params
        else:
            ep = ''

        ogr2ogrstring = f'{config["QGIS_bin_folder"]}/ogr2ogr.exe --config MSSQLSPATIAL_USE_BCP FALSE -f "MSSQLSpatial" "{ogrconnection}" "{tmp_path}" {geometry} {table} -lco UPLOAD_GEOM_FORMAT=wkt {ep}  {ow}'
        logger.info(f'Writing to MSSQL database {dbconnection["databasename"]}, {table}')
        ogr2ogrstring.join(' -progress')
        run = subprocess.run(ogr2ogrstring, stderr=subprocess.STDOUT)
        if run.stdout:
            logger.info(run.stdout)
        os.remove(tmp_path)
        logger.info(f'Export to MSSQL completed')

    except Exception as error:
        try:
            os.remove(tmp_path)
        except:
            pass

        logger.error("An error occured exporting to MSSQL")
        logger.error(f'{type(error).__name__}{str(error)}')
        logger.critical("Program terminated")
        script_failed()

postgis(layer, connection, dbname, schema, tablename, overwrite=True)

A function that exports a QgsVectorLayer into a Postgis database.

Parameters

layer : QgsVectorLayer The QgsVectorLayer to be exported into Postgis

str

The name of the connection object in the settings file

str

The database name

str

Schema name

str

The name of the table that will be imported

str

Defaults to True. Should the resulting table in Postgis be overwritten if it exists. If set to False, then it will append the data.

Source code in python\engine\outputs.py
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
def postgis(layer, connection, dbname, schema, tablename, overwrite=True):
    """
    A function that exports a QgsVectorLayer into a Postgis database.

    Parameters
    ----------
    layer : QgsVectorLayer
        The QgsVectorLayer to be exported into Postgis

    connection : str
        The name of the connection object in the settings file

    dbname : str
        The database name

    schema : str
        Schema name

    tablename : str
        The name of the table that will be imported

    overwrite : str
        Defaults to True. Should the resulting table in Postgis be overwritten if it exists. If set to False, then it will append the data.
    """

    logger.info(f'Exporting {str(layer.featureCount())} features to Postgis')

    try:
        config = get_config()
        dbConnection = config['DatabaseConnections'][connection]
        logger.info('Creating temporary folder in Temp folder')
        tmp_path = f'{config["TempFolder"]}postgis_layer_{str(randrange(1000))}.geojson'
        options = QgsVectorFileWriter.SaveVectorOptions()
        options.driverName = 'GeoJSON'
        QgsVectorFileWriter.writeAsVectorFormatV3(layer, tmp_path, QgsProject.instance().transformContext(), options)
        logger.info('Temporary layer created')

        # ogr2ogr parameters
        table = f'-nln "{schema}.{tablename}"'
        ogrconnection = f'PG:"host={dbConnection["host"]} port={dbConnection["port"]} dbname={dbname} schemas={schema} user={dbConnection["user"]} password={dbConnection["password"]}"'
        ogr2ogrstring = f'{config["QGIS_bin_folder"]}/ogr2ogr.exe -f "PostgreSQL" {ogrconnection} {tmp_path} {table}'
        if overwrite:
            ogr2ogrstring = f'{ogr2ogrstring} -overwrite'
        logger.info(f'Writing to PostGIS database {dbname}')
        run = subprocess.run(ogr2ogrstring, capture_output=True)
        os.remove(tmp_path)
        logger.info('Temporary layer removed')
        logger.info('Export to PostGIS completed')

    except Exception as error:
        logger.error("An error occured exporting to Postgis")
        logger.error(f'{type(error).__name__}{str(error)}')
        logger.critical("Program terminated")
        script_failed()

textfile(file, list, newline)

Create an output file from a list of lines.

Parameters

file : Path and filename The file to be created.

List

List of lines to be written to the file.

Boolean

If true, a newline character will be added to the end of each line.

Source code in python\engine\outputs.py
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
def textfile(file, list,  newline):
    """
    Create an output file from a list of lines. 

    Parameters
    ----------
    file : Path and filename
        The file to be created.

    list : List
        List of lines to be written to the file.

    newline : Boolean
        If true, a newline character will be added to the end of each line.
    """
    logger.info("Creating text file: " + file)
    try:
        with open(file, 'w', encoding="utf-8") as f:
            for line in list:
                if newline == True:
                    f.write(line + '\\n')
                else:
                    f.write(line)
        logger.info("File created")
    except Exception as error:
        logger.error("An error occured creating file")
        logger.error(f'{type(error).__name__}{str(error)}')
        logger.critical("Program terminated")
        script_failed()