2

I am trying to convert a dlm50 NAS file of Rheinlandpfalz (Germany) to shapefile. With ogr2ogr this repeadetly converts Polygons to Lines and whole layers are missing. If I import it into QGIS and use the validate algorithm it works fine though (ogr convert format still fails).

Importing them in QGIS gives a pop-up where I can chose all layers I want to import. I don't find a way to do this in a python script though. Yes I can open them with QgsVectorLayer and ogr driver but I receive one object, which can't be used properly. I had also problems with this with OSM-files and spatialite files which have failed to load with the spatialite driver but succeded with ogr import (may have been to big?).

I know I should try to convert the dlm50 file to PostGIS but it will be the same driver for reading and I am generally interested if I miss something and the import of such files is possible somehow in a standalone python script (not in QGIS Python console). It should also be possible to work with such files without the need to preliminary convert them to other formats?!

So how can I import layers of multiple layer files like NAS/OSM/Spatialite in a standalone python script?

3
  • Do you know the PostNAS project? I tested the data lvermgeo.rlp.de/fileadmin/lvermgeo/testdaten/geotopographie/… with GeoTKF (gis.makobo.de/geotkf). This Programm also works with OGR2OGR. The result (the shapes) seems to be correct. Jan 20, 2017 at 16:58
  • Sadly no. The NAS-files contain multi-geometry layers and thus typically only polygons are exported and point and line layers are not. This can be solved in ogr with -where "OGR_GEOMETRY=\'Point\'"' /LineString syntax. With Polygon for some reason it doesn't work though. And also without this syntax Polygons are repeatedly exported as Line features. (Might be cause he finds a Line feature first and interprets Polygons as Lines thereafter? ogrinfo reports it as Geometry: Unknown (any))
    – gilla
    Feb 3, 2017 at 13:31
  • Have you tested GeoTKF? If this works, then it also works with OGR Feb 3, 2017 at 17:26

1 Answer 1

4

If you want to load all tables from a Spatialite database having a geometry_column, then the following code makes the Job. It uses SQLITE metadata to retrieve the tables and names, which can be loaded as a layer into QGIS.

import sqlite3

# connect to SQLITE database
database = '//vmapl1//VMapL1_125.sl3'
con = sqlite3.connect(database)
cursor = con.cursor()

# select tables having a geometry column
cursor.execute("SELECT f_table_name FROM geometry_columns;")

# retrieve all tables
layernames = cursor.fetchall()

# iterate over all tables and construct layers
for layername in layernames:
    layername = str(layername[0])
    layer = QgsVectorLayer(str.format('%s|layername=%s' % (database, layername)), layername, 'ogr')

    # add layers to legend
    QgsMapLayerRegistry.instance().addMapLayer(layer)

# close db Connection
con.close()

To use OGR to read other formats, like XML-formatted NAS files, a very similar approach may be helpful:

import ogr

# database is the XML file
database = 'E:\\0_Drucken\\e_ben_monzel_dlm50.xml'

# use OGR to get the metadata of the database, like number and names of layers
ds = ogr.Open(database)
layercount = ds.GetLayerCount()
layernames = {i: ds.GetLayerByIndex(i).GetName() for i in range(layercount)}

# import each layer into QGIS
for index, layername in layernames.items():
    layer = QgsVectorLayer(str.format('%s|layerid=%d' % (database, index)), layername, 'ogr')
    QgsMapLayerRegistry.instance().addMapLayer(layer)

This approach has been tested with NAS test data from LVermGeo RLP.

3
  • Very nice approach! Sadly only working for spatialite data. I was wondering if NAS/OSM files could also in some way be loaded like this because when I hover over the layernames in QGIS it says: 'filepath|layername=layername|geometrytype=Polygon' (e.g.). I thought maybe it would be working with uri syntax but I can't find the right approach. Thank you for the nice approach for spatialite though!
    – gilla
    Feb 3, 2017 at 13:39
  • 1
    @gilla are you using XML files like the example from lvermgeo.rlp.de? If so, ogr python module should be used. I would extend the answer
    – Detlev
    Feb 3, 2017 at 17:19
  • Marvelous, exactly what I was searching for! One addition with '%s|layername=%s|geometrytype=%s' % (database, layername, geometrytype) you can also differ between Polygons/Lines/Points as it is done in QGIS and as it is needed to convert correctly to Shapefiles.
    – gilla
    Feb 9, 2017 at 21:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.