2

I have a polygon file buffer_stands.shp with 20 features and I have a line file OSMroads.geojson with 9 features.

I expected the script to loop through the buffers and print out for each buffer loop the the point count of each of the OSMroads. I know it doesn't sound useful, but the script is a simplification of a bigger script.

The outer loop loops all the way through. But the inner loop only loops once. What is causing that and how can I fix it?

import ogr

bufferfn = ogr.Open('buffer_stands.shp')
buffer_lyr = bufferfn.GetLayer()

roadfn  = ogr.Open('OSMroads.geojson')
road_lyr = roadfn.GetLayer()

for buffer_feat in buffer_lyr:
    buffer_geom = buffer_feat.GetGeometryRef()
    print 'buffer'

    for road_feat in road_lyr:
        road_geom = road_feat.GetGeometryRef()
        print road_geom.GetPointCount()

The output looks like this

>>> 
buffer
10
62
17
46
10
28
97
78
121
buffer
buffer
buffer
buffer
buffer
buffer
buffer
buffer
buffer
buffer
buffer
buffer
buffer
buffer
buffer
buffer
buffer
buffer
buffer

It shows the inner loop is running only once.

  • Can you explain a bit more about your data, and what you expect the code to do (in words, at a functional level, not at a code level)? My guess is that there is only one feature in the roads GeoJSON, but since you haven't shown us the data, its difficult to say. – BradHards Nov 6 '13 at 23:02
  • I added some more information. In the roads GeoJSON are nine features. – ustroetz Nov 6 '13 at 23:13
  • OK, I see the problem. The problem is that the roads layer has been "read to the end" already. You need to reset / re-open it, or perhaps just store it in a local list – BradHards Nov 6 '13 at 23:30
  • Yeah, that was the problem. Reading the roads layer inside the outer loop fixed it. – ustroetz Nov 6 '13 at 23:41
2

Use the ogr.Layer.ResetReading() method.

bufferfn = ogr.Open('buffer_stands.shp')
buffer_lyr = bufferfn.GetLayer()

roadfn  = ogr.Open('OSMroads.geojson')
road_lyr = roadfn.GetLayer()

for buffer_feat in buffer_lyr:
    buffer_geom = buffer_feat.GetGeometryRef()
    print 'buffer'

    for road_feat in road_lyr:
        road_geom = road_feat.GetGeometryRef()
        print road_geom.GetPointCount()

    road_lyr.ResetReading() #Read the road layer from the beginning again
  • Nice, wasn't aware of this one – ThomasG77 Nov 7 '13 at 0:02
2

Not really understand what you want to achieve To make it work, just move

roadfn  = ogr.Open('OSMroads.geojson')
road_lyr = roadfn.GetLayer() t

one line before for road_feat in road_lyr: an the loop

The point here is "think of road_lyr as a variable when you loop that empty itself (for memory purpose)"

You can just confirm this by doing:

import ogr

bufferfn = ogr.Open('buffer_stands.shp')
buffer_lyr = bufferfn.GetLayer()

for buffer_feat in buffer_lyr:
    buffer_geom = buffer_feat.GetGeometryRef()
    print 'buffer'

//second loop not working the expected way
for buffer_feat in buffer_lyr:
    buffer_geom = buffer_feat.GetGeometryRef()
    print 'buffer'

Although it will solve the problem, it's not really nice way to do. You'd better take a look on Fiona ( a nice wrapper on top of OGR)

  • Moving the ogr.Open and GetLayer part inside the outer loop fixed the problem. Thanks for pointing out Fiona. I will look into it, since opening up the datasource each loop will slow down the script quite a bit. – ustroetz Nov 6 '13 at 23:17

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.