2

I have several line Shapefiles, each displays a hiking trails and they all have a disastrous chaos in their attribute table (let us call the fields A,B, C,D and they are not equal in the tables). The name of the shapefile is the name of trail (nameA.shp etc.).

I'd like to clean the attribute table automatically to have the name of the shapefile as a new field "name" and if there are more than one object, the should be named like "nameA1; nameA2; and so on).

I started to this by hand but it takes hours. Any ideas?

I need this step to finally merge all shapefiles to a single one without losing the name of the trails.

I use QGIS las palma on a Mac.

edit 01.06.2017 This is the script after I ran it:

Python Console 
Use iface to access QGIS API interface or Type help(iface) for more info
import os
from glob import glob
from PyQt4.QtCore import QVariant
files = []
#CHANGE NR1 --> THE PATH
start_dir = r"/Users/Kevin_privat/Desktop/Shapedateien Test"
pattern = "*.shp"
for dirpath, dirnames, filenames in os.walk(start_dir):
    files.extend(glob(os.path.join(dirpath,pattern))) 
#CHANGE NR2 --> THE COORDINATE SYSTEM AND LAYER NAME
all_lines = QgsVectorLayer('LineString?crs=EPSG:4326‘, "all_my_lines", "memory")
  File "<input>", line 1
    all_lines = QgsVectorLayer('LineString?crs=EPSG:4326â, "all_my_lines", "memory")
                                                                                     ^
SyntaxError: EOL while scanning string literal
all_lines_pr = all_lines.dataProvider()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'all_lines' is not defined
all_lines_pr.addAttributes([QgsField('new_id', QVariant.Double)])
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'all_lines_pr' is not defined
all_lines.updateFields()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'all_lines' is not defined
for i in files:
    os.path.basename(i)
    linelayer = QgsVectorLayer(i, os.path.basename(i), "ogr")
    features_linelayer = linelayer.getFeatures()
    lines_list = []
    for feature in features_linelayer:
        new_feature = QgsFeature()
        new_feature.setGeometry(feature.geometry())
        new_feature.setAttributes([os.path.basename(i)+'_'+str(feature.id())])
        lines_list.append(new_feature)
    all_lines_pr.addFeatures(lines_list)
QgsMapLayerRegistry.instance().addMapLayer(all_lines)
  File "<input>", line 12
    QgsMapLayerRegistry.instance().addMapLayer(all_lines)
                      ^
SyntaxError: invalid syntax
4

I made a small script which you can execute in the python-console in QGIS. I've tested this with 4 line-shapefiles in different folders and it worked pretty good (using Windows7).

EDIT: occupied a mac for a moment, works as well

import os
from glob import glob
from PyQt4.QtCore import QVariant

files = []

#CHANGE NR1 --> THE PATH
start_dir = r"/Users/admin/Desktop/lineshapes"
pattern = "*.shp"

for dirpath, dirnames, filenames in os.walk(start_dir):
    files.extend(glob(os.path.join(dirpath,pattern))) 

#CHANGE NR2 --> THE COORDINATE SYSTEM AND LAYER NAME
all_lines = QgsVectorLayer('LineString?crs=EPSG:25833', "all_my_lines", "memory")
all_lines_pr = all_lines.dataProvider()
all_lines_pr.addAttributes([QgsField('new_id', QVariant.Double)])
all_lines.updateFields()

for i in files:
    os.path.basename(i)
    linelayer = QgsVectorLayer(i, os.path.basename(i), "ogr")
    features_linelayer = linelayer.getFeatures()
    lines_list = []
    for feature in features_linelayer:
        new_feature = QgsFeature()
        new_feature.setGeometry(feature.geometry())
        new_feature.setAttributes([os.path.basename(i)+'_'+str(feature.id())])
        lines_list.append(new_feature)
    all_lines_pr.addFeatures(lines_list)
QgsMapLayerRegistry.instance().addMapLayer(all_lines)
  • thank you for the script. Do I have to change something for my qgis project e.g. names or paths? – Kevin May 29 '17 at 17:07
  • yes, I marked it in the script. you have to change the folderpath, where you have all your shapefiles and you should specify the coordinate system you are using (here I use EPSG 25833) – AndreasK May 29 '17 at 18:05
  • I still can't make it. I changed the start_dir-path and the EPSG. I tried it with two Shapefiles from which I know that the CRS is WGS84 (EPSG 4326). The last lines after I ran the script are in red, they come directly after your coding: File "<input>", line 12 QgsMapLayerRegistry.instance().addMapLayer(all_lines) ^ SyntaxError: invalid syntax – Kevin May 31 '17 at 10:16
  • Hmm, I'm sorry for that. Maybe something wrong with the indentation? Can You post your changes? I made a little mistake in the start_dir, added an "r" to avoid any escape sequences. – AndreasK May 31 '17 at 12:33
1

u open table A, u add your additionnal field, u open the "field calculator", u choose "update existing field" and add a formula like 'tableA' || $id. If I got you right that should do the job ...

  • this works great for one table after the other. Is there any chance to do this for multiple layers at once? I have around 250 layers and hope I do not have to open every single attribute table. – Kevin May 29 '17 at 6:23
  • How chaotic are your table structures ? Are fields varying in size and type among the 250 layers ? If so i don't see how u can prepare them before merging unless u're ready to drop some information. – snaileater May 29 '17 at 7:30
  • They have between one and 7 seven fields and between one and 4 objects. Most of the fields are empty, in the end I'd only need the names and the lengths (which can be calculated easily) in one shapefile. – Kevin May 29 '17 at 8:16
  • I don't see how this can be done without writing a small python script. – AndreasK May 29 '17 at 10:08
  • Using the command line ogr2ogr (and the right switches...) i think there must be a way to "batch" retrieve the trail name (the field name must be the same in all table i guess...) and its geometry and append the result of all your shape layers in one resulting file. Look for ogr2ogr in the search engine. – snaileater May 29 '17 at 11:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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