4

I am trying to execute this code,

import osgeo.ogr

def findPoints(geometry, results):
    for i in range(geometry.GetPointCount()):
        x,y,z = geometry.GetPoint(i)
    if results['north'] == None or results['north'][1] < y:
        results['north'] = (x,y)
    if results['south'] == None or results['south'][1] > y:
        results['south'] = (x,y)
    for i in range(geometry.GetGeometryCount()):
        findPoints(geometry.GetGeometryRef(i), results)

shapefile = osgeo.ogr.Open("../../Data/tl_2009_us_state/tl_2009_us_state.shp")
layer = shapefile.GetLayer(0)
feature = layer.GetFeature(53)
geometry = feature.GetGeometryRef()

results = {'north' : None,
           'south' : None}

findPoints(geometry, results)

and I am constantly receiving this error,

Traceback (most recent call last):
  File "identify_northsouth_point.py", line 22, in <module>
    findPoints(geometry, results)
  File "identify_northsouth_point.py", line 8, in findPoints
    results['north'] = (x,y)
UnboundLocalError: local variable 'x' referenced before assignment

I have tried global and nonlocal, but it does not work. Since I am not gettin any input from outside the function, so I anyways would not require global or nonlocal.

Sam007
  • 8,397
  • 4
  • 24
  • 34
  • Are those `if`s indented properly? Do you really want to check only the last point, and can `GetPointCount()` return 0? – Wooble Apr 30 '12 at 18:01

7 Answers7

6

The error message states that the variable x has no value. Since it is assigned (repeatedly) in your for loop, this means that your for loop is not executing even once. And the only way this can happen is if geometry.GetPointCount() returns 0. Therefore, this is what must be happening. Add a print geometry.GetPointCount() to confirm.

Do you intend for the if statements to be inside the loop, so that they are executed for each point in the geometry, and will not be executed at all when the geometry has 0 points? If so, indent them properly.

kindall
  • 178,883
  • 35
  • 278
  • 309
1

I think you may mean to have those if statements indented under the for loop. As your code stands, it will always operate only on the last point, or (I imagine what is causing your current error) in the case where you have no points, will never set x, y, z as the for loop will have nothing to iterate over.

Silas Ray
  • 25,682
  • 5
  • 48
  • 63
1

I had the same problem. I was defining functions (using def) and declare the variable before def and hade this problem, simply I just moved the declaration into the function and it's solved.

iammgt
  • 43
  • 1
  • 10
0

As a quick "diagnostic" test, can you try to initialize x, y and z before the for loop and see if that fixes your specific error?

The way it stands now, if your for-loop doesn't execute for some reason, x, y and z don't get created and assigned to and therefore will cause the error you get later when an attempt is made to use them.

Also, should your two if-statements be folded in under the for loop?

Levon
  • 138,105
  • 33
  • 200
  • 191
0

The problem is in the first two lines of your function - in fact, you have several problems there.

x, y and z are defined within the for loop. If geometry.GetPointCount() is 0, that loop will never be entered, so those variables will not be assigned. That's presumably what's happening here, hence the error message.

On the other hand, if that expression is more than 0, then x, y and z will be redefined every time through that loop, which seems more than a little pointless - they will end up having just the value from the last time through.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
0
x,y,z = geometry.GetPoint(i)

Is never getting executed in findPoints()

This is because geometry.GetPointCount() is returning 0 thus the for loop is never executed.

Joel Cornett
  • 24,192
  • 9
  • 66
  • 88
0

I had the same problem as the examples are from an eBook which seems not to indent correctly in some places. The function should look like this:

def findPoints(geometry, results):
    for i in range(geometry.GetPointCount()):
        x,y,z = geometry.GetPoint(i)
        if results['north'] == None or results['north'][1] < y:
            results['north'] = (x,y)
        if results['south'] == None or results['south'][1] > y:
            results['south'] = (x,y)
    for i in range(geometry.GetGeometryCount()):
        findPoints(geometry.GetGeometryRef(i), results)
TsvGis
  • 622
  • 2
  • 10
  • 23