@@ -120,11 +120,10 @@ def inFile(self):
120
120
self .outShape .clear ()
121
121
fileDialog = QFileDialog ()
122
122
fileDialog .setConfirmOverwrite (False )
123
- outName = fileDialog .getOpenFileName (self , self .tr ("Join Table" ), "." , "DBase Files (*.dbf)" )
123
+ outName = fileDialog .getOpenFileName (self , self .tr ("Join Table" ), "." , "Tables (*.dbf *.csv )" )
124
124
fileCheck = QFile (outName )
125
125
if fileCheck .exists ():
126
126
filePath = QFileInfo (outName ).absoluteFilePath ()
127
- if filePath .right (4 ).toLower () != ".dbf" : filePath = filePath + ".dbf"
128
127
if not outName .isEmpty ():
129
128
self .inTable .clear ()
130
129
self .inTable .insert (filePath )
@@ -135,13 +134,18 @@ def inFile(self):
135
134
def updateTableFields (self ):
136
135
if self .inTable .text () != "" :
137
136
filePath = self .inTable .text ()
138
- f = open ( unicode ( filePath ), 'rb' )
139
- table = list ( self . dbfreader ( f ) )
140
- f . close ()
137
+ joinInfo = QFileInfo ( filePath )
138
+ joinPath = joinInfo . absoluteFilePath ( )
139
+ joinName = joinInfo . completeBaseName ()
141
140
self .joinField .clear ()
142
- for i in table [0 ]:
143
- self .joinField .addItem (unicode (i ))
144
- table = None
141
+ changedLayer = QgsVectorLayer (joinPath , joinName , 'ogr' )
142
+ try :
143
+ changedField = ftools_utils .getFieldList (changedLayer )
144
+ except :
145
+ QMessageBox .warning (self , self .tr ("Join Attributes" ), self .tr ("Unable to read input table!" ))
146
+ return
147
+ for i in changedField :
148
+ self .joinField .addItem (unicode (changedField [i ].name ()))
145
149
146
150
def compute (self , inName , inField , joinName , joinField , outName , keep , useTable , progressBar ):
147
151
layer1 = ftools_utils .getVectorLayerByName (inName )
@@ -151,21 +155,18 @@ def compute(self, inName, inField, joinName, joinField, outName, keep, useTable,
151
155
fieldList1 = ftools_utils .getFieldList (layer1 ).values ()
152
156
index1 = provider1 .fieldNameIndex (inField )
153
157
if useTable :
154
- f = open (unicode (joinName ), 'rb' )
155
- table = list (self .dbfreader (f ))
156
- f .close ()
157
- (fieldList2 , index2 ) = self .createFieldList (table , joinField )
158
- table = table [2 :]
159
- func = lambda x : (unicode (type (x )) != "<type 'str'>" and QVariant (float (x ))) or (QVariant (x ))
160
- table = map (lambda f : map (func , f ), table )
161
-
158
+ joinInfo = QFileInfo (joinName )
159
+ joinPath = joinInfo .absoluteFilePath ()
160
+ joinName = joinInfo .completeBaseName ()
161
+ layer2 = QgsVectorLayer (joinPath , joinName , 'ogr' )
162
+ useTable = False
162
163
else :
163
164
layer2 = ftools_utils .getVectorLayerByName (joinName )
164
- provider2 = layer2 .dataProvider ()
165
- allAttrs = provider2 .attributeIndexes ()
166
- provider2 .select (allAttrs )
167
- fieldList2 = ftools_utils .getFieldList (layer2 )
168
- index2 = provider2 .fieldNameIndex (joinField )
165
+ provider2 = layer2 .dataProvider ()
166
+ allAttrs = provider2 .attributeIndexes ()
167
+ provider2 .select (allAttrs , QgsRectangle (), False , False )
168
+ fieldList2 = ftools_utils .getFieldList (layer2 )
169
+ index2 = provider2 .fieldNameIndex (joinField )
169
170
fieldList2 = self .testForUniqueness (fieldList1 , fieldList2 .values ())
170
171
seq = range (0 , len (fieldList1 ) + len (fieldList2 ))
171
172
fieldList1 .extend (fieldList2 )
@@ -192,21 +193,8 @@ def compute(self, inName, inField, joinName, joinField, outName, keep, useTable,
192
193
outFeat .setAttributeMap (atMap1 )
193
194
outFeat .setGeometry (inGeom )
194
195
none = True
195
- if useTable :
196
- for i in table :
197
- #sequence = range(0, len(table[0]))
198
- #atMap2 = dict(zip(sequence, i))
199
- if atMap1 [index1 ].toString ().trimmed () == i [index2 ].toString ().trimmed ():
200
- count = count + 1
201
- none = False
202
- atMap = atMap1 .values ()
203
- atMap2 = i
204
- atMap .extend (atMap2 )
205
- atMap = dict (zip (seq , atMap ))
206
- break
207
- else :
208
- provider2 .rewind ()
209
- while provider2 .nextFeature (joinFeat ):
196
+ provider2 .select (allAttrs , QgsRectangle (), False , False )
197
+ while provider2 .nextFeature (joinFeat ):
210
198
atMap2 = joinFeat .attributeMap ()
211
199
if atMap1 [index1 ] == atMap2 [index2 ]:
212
200
none = False
@@ -259,55 +247,3 @@ def testForUniqueness(self, fieldList1, fieldList2):
259
247
j = ftools_utils .createUniqueFieldName (j )
260
248
changed = True
261
249
return fieldList2
262
-
263
- def dbfreader (self , f ):
264
- """Returns an iterator over records in a Xbase DBF file.
265
-
266
- The first row returned contains the field names.
267
- The second row contains field specs: (type, size, decimal places).
268
- Subsequent rows contain the data records.
269
- If a record is marked as deleted, it is skipped.
270
-
271
- File should be opened for binary reads.
272
-
273
- """
274
- numrec , lenheader = struct .unpack ('<xxxxLH22x' , f .read (32 ))
275
- numfields = (lenheader - 33 ) // 32
276
-
277
- fields = []
278
- for fieldno in xrange (numfields ):
279
- name , typ , size , deci = struct .unpack ('<11sc4xBB14x' , f .read (32 ))
280
- name = name .replace ('\0 ' , '' ) # eliminate NULs from string
281
- fields .append ((name , typ , size , deci ))
282
- yield [field [0 ] for field in fields ]
283
- yield [tuple (field [1 :]) for field in fields ]
284
-
285
- terminator = f .read (1 )
286
- assert terminator == '\r '
287
-
288
- fields .insert (0 , ('DeletionFlag' , 'C' , 1 , 0 ))
289
- fmt = '' .join (['%ds' % fieldinfo [2 ] for fieldinfo in fields ])
290
- fmtsiz = struct .calcsize (fmt )
291
- for i in xrange (numrec ):
292
- record = struct .unpack (fmt , f .read (fmtsiz ))
293
- if record [0 ] != ' ' :
294
- continue # deleted record
295
- result = []
296
- for (name , typ , size , deci ), value in itertools .izip (fields , record ):
297
- if name == 'DeletionFlag' :
298
- continue
299
- if typ == "N" :
300
- value = value .replace ('\0 ' , '' ).lstrip ()
301
- if value == '' :
302
- value = 0
303
- elif deci :
304
- value = decimal .Decimal (value )
305
- else :
306
- value = int (value )
307
- elif typ == 'D' :
308
- y , m , d = int (value [:4 ]), int (value [4 :6 ]), int (value [6 :8 ])
309
- value = datetime .date (y , m , d )
310
- elif typ == 'L' :
311
- value = (value in 'YyTt' and 'T' ) or (value in 'NnFf' and 'F' ) or '?'
312
- result .append (value )
313
- yield result
0 commit comments