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 + "!"   
joseph_k
  • 1,441
  • 15
  • 31

2 Answers2

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')
Detlev
  • 4,608
  • 19
  • 26
  • 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 '15 at 01: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 '15 at 03:03
  • Code works perfectly except, it's still using the layer name and not the file name. – joseph_k Dec 15 '15 at 05: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 '15 at 06:21
  • Ah. How stupid. Now working perfectly.Thanks a lot mate. – joseph_k Dec 15 '15 at 06:49
  • @Detlev I am really inexperienced in using Python code. I want something similar: 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. They should be named as they currently are with the suffix:"_Lambert72". Any chance you could edit the code a little for me? – Hannes Ledegen Jan 04 '17 at 15:07
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 + "!"
Hannes Ledegen
  • 825
  • 7
  • 14
  • 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 04 '17 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. – Hannes Ledegen Jan 05 '17 at 09: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 05 '17 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. – Hannes Ledegen Jan 05 '17 at 10:34
  • 1
    You missed the separator in the third last line: dgn_fn + '\\' + newName – Detlev Jan 05 '17 at 14:05