4

How can I sort the features of an ogr layer by the values of a field? I tried naive variations of

def sortlayer(ds, layer, field):
 lname = layer.GetName()
 lsort = ds.ExecuteSQL(b'select * from "{}" order by {}'.format(lname, field))
 ds.DeleteLayer(lname)
 ds.CopyLayer(lsort, lname)

but this either crashed or freezed.

Bonus points for a solution that doesn't change the order of layers in the datasource and/or that doesn't rely on unique layer names.

Actually the datasources are in-memory (memory-driver), and I may have up to 10 layers with up to 10.000 features over all.

Maybe it would be better not to use SQL but create an index as list, and then swap features around in the layer with Layer.GetFeature()/.SetFeature()?

Thanks, Redoute

asked Jun 8, 2013 at 17:26
2
  • Please post your solution as an answer if it solves the problem you had. People can then comment on the answer and upvote it. You can even accept it once it gets some upvotes. Commented Jun 9, 2013 at 20:47
  • @underdark: Done, I really didn't find the answer button last time. :-) Commented Jun 11, 2013 at 9:52

1 Answer 1

2

I followed the second approach now and this seems to work, comments welcome:

def sortlayer(l, fd):
 # fids are unique, fids may be sorted or unsorted, fids may be consecutive or have gaps
 # don't care about semantics, don't touch fids and their order, reuse fids
 fids = []
 vals = []
 l.ResetReading()
 for f in l:
 fid = f.GetFID()
 fids.append(fid)
 vals.append((f.GetField(fd), fid))
 vals.sort()
 # index as dict: {newfid: oldfid, ...}
 ix = {fids[i]: vals[i][1] for i in xrange(len(fids))}
 # swap features around in groups/rings
 for fidstart in ix.keys():
 if fidstart not in ix: continue
 ftmp = l.GetFeature(fidstart)
 fiddst = fidstart
 while True:
 fidsrc = ix.pop(fiddst)
 if fidsrc == fidstart: break
 f = l.GetFeature(fidsrc)
 f.SetFID(fiddst)
 l.SetFeature(f)
 fiddst = fidsrc
 ftmp.SetFID(fiddst)
 l.SetFeature(ftmp)
answered Jun 11, 2013 at 9:50

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.