6

We have 100's of dgn files. We have successfully "assigned" coordinate system to those dgn files in batch by using "on the fly" + custom CRS. Now we have to save each dgn's geometry (Point, Linestring, Polygon) in WGS84. Manually we can do that. Right Click -> Save Us -> Projection: WGS84 & add suffix "Point, Lines, Areas" to each layer. But this method will take a lot of time to do that. What i would like to do is

1) Based on the File name, the layers has to be batch saved to a respective folder. I have read this and tried. How to batch "Layer save as"-process in QGIS? But it takes the layer name (here: elementsPoints, elementsLineString) instead of the original file name (042641hd). I would like to have 042641hd_Points, 042641hd_Lines etc..

enter image description here

2) While doing so, how to save all the files in WGS84 ?


This code works perfectly. Reading the file name, not the layer name.

 from qgis.core import *
 import os
 pathToFile = "D:\\Dummy\\"
 trs = QgsCoordinateReferenceSystem()
 trs.createFromId(4326)
 layers = iface.legendInterface().layers()
 for layer in layers:
     dgn_pn = layer.dataProvider().dataSourceUri().split('|')[0]
     dgn_fn = os.path.basename(dgn_pn)
     dgn_fn_wo_ext = os.path.splitext(dgn_fn)[0]
     geom_name = {0: 'Points', 1: 'Lines', 2: 'Polygons'}
     geom_type = layer.geometryType()
     newName = dgn_fn_wo_ext + '_' + geom_name[geom_type]
     ret = QgsVectorFileWriter.writeAsVectorFormat(layer,pathToFile + newName,'utf-8',trs,'ESRI Shapefile')
     if ret == QgsVectorFileWriter.NoError:
       print newName + " saved to " + pathToFile + "!"   
2

2 Answers 2

5

You already know the general procedure and have experience with the script How to batch "Layer save as"-process in QGIS?. Consider the line

QgsVectorFileWriter.writeAsVectorFormat(layer, pathToFile + newName, "utf-8", None, "ESRI Shapefile")

You have to change 2 things.

1) To get the original file name add following lines to the top of the loop

import os

for layer in layers:
    # get path to dgn file
    dgn_pn = layer.dataProvider().dataSourceUri().split('|')[0]
    dgn_fn = os.path.basename(dgn_pn)

    # get rid of the file extension
    dgn_fn_wo_ext = os.path.splitext(dgn_fn)[0]

    # define geometry strings and get geometry type of layer
    geom_name = {0: 'Points', 1: 'Lines', 2: 'Polygons'}
    geom_type = layer.geometryType()

    # build the new file name
    newName = dgn_fn_wo_ext + '_' + geom_name[geom_type]

2) To change the coordinate system to WGS84 add to the top of the script

trs = QgsCoordinateReferenceSystem()
trs.createFromId(4326)

To bring it all together change following line:

ret = QgsVectorFileWriter.writeAsVectorFormat(
         layer, 
         pathToFile + newName, 
         'utf-8',
         trs,
         'ESRI Shapefile')
6
  • I don't have experience in coding. Just copied that "Layer save as" code to python console & somehow it worked. I've added your code on top of the for loop. Not working. Just edited my question and copied that. Could you have a look ?
    – joseph_k
    Dec 15, 2015 at 1:22
  • In Python line indentation is meaningful. All lines in the for layer loop have to be indented with 4 blanks. When you have a \ in a string, as in the file path, please double it: \\ otherwise it may give the following character a special meaning.
    – Detlev
    Dec 15, 2015 at 3:03
  • Code works perfectly except, it's still using the layer name and not the file name.
    – joseph_k
    Dec 15, 2015 at 5:40
  • Delete the first line in the for loop since you overwrite the correct new filename with the layer name. That is the mistake.
    – Detlev
    Dec 15, 2015 at 6:21
  • Ah. How stupid. Now working perfectly.Thanks a lot mate.
    – joseph_k
    Dec 15, 2015 at 6:49
1

I have a QGIS project with a lot of KML files in WGS84 in them. I would like to batch save them all to the directories they come from in Lambert72 (EPSG: 31370) as a .shp file. I have cooked up my own little script from the above and some help form Detlev.

from qgis.core import *
import os
pathToFile = "S:\\Meetnetten\\Amfibieen en reptielen\\Vuursalamander\\Transecten 2016\\"
trs = QgsCoordinateReferenceSystem()
trs.createFromId(31370)
suffix = "_Lambert1972_Versie2016-01-04"
prefix = "Transect_Vuursalamander_"
layers = iface.legendInterface().layers()
for layer in layers:
    dgn_pn = layer.dataProvider().dataSourceUri().split('|')[0]
    dgn_fn = os.path.dirname(dgn_pn)
    newName = prefix + layer.name() + suffix + ".shp"
    ret = QgsVectorFileWriter.writeAsVectorFormat(layer, dgn_fn + \\ +  newName,'utf-8',trs,'ESRI Shapefile')
    if ret == QgsVectorFileWriter.NoError:
        print newName + " saved to " + dgn_fn + "!"
5
  • Please do not answer with a new question. Open a new question so we can give an answer. Please give some more Detail on your Problem: are your KML files loaded from different directories, and not from S:\\pathway\` ? You have skipped the line beginning with dgn_pn =`, maybe this is already the solution for your Problem.
    – Detlev
    Jan 4, 2017 at 17:03
  • @Detlev My KML files come indied from seperate folders within the folder S:\\pathway\\. I am quite inexperienced with Python and I assumed all the dgn lines were for the specific question above. Do the dgn_pn and dgn_fn lines only result in adding the pathway to the name of the shape? Since I do not want it in the name, simply for the resulting shapes to be placed in their folders of origin (they are all sub-maps of the pathToFile. Jan 5, 2017 at 9:49
  • dgn_pn in above code contains the complete pathname to the datasource of the layer. I used python function basename() to extract the filename part. Use dirname() to extract the path, and use this instead of pathToFile
    – Detlev
    Jan 5, 2017 at 10:13
  • @Detlev I have added the script as I thought it should be implied but it still saves is to my pathToFile instead of my dgn_fn. I probably implored it totally wrong, sorry for my limited python skills. Jan 5, 2017 at 10:34
  • 1
    You missed the separator in the third last line: dgn_fn + '\\' + newName
    – Detlev
    Jan 5, 2017 at 14:05

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.