Question

This code will be for use with polygon data that has raster cell counts appended to it. For example, if the raster is land cover, there will be a column for each land cover type and the corresponding cell count within each polygon. This output comes from the Geospatial Modelling Environment, as Tabulate Raster keeps crashing on the large shapefiles I am using. Ultimately I want an area value, not a cell count, which is what the code below will achieve.

So the code will loop through shapefile attributes, pull out the original count fields, then create new fields based on a user input (loop though AddField using user input name + raster values to get new field names), and then loop through the original field's values and calculate a user-specified area value for the new fields. Essentially I am trying to automate an Add Field, Calculate Field model that I usually Batch Process in Model Builder.

I am having trouble figuring out the proper logic for calculating the new fields. As it is written now, it gets the original field with the for-loop, but only the last original field values end up being used, and only the last new field is populated. I need the loop to take the first original field and put it in it's corresponding new field, such that:

If origFields = ('NLCDV1', 'NLCDV2'...) and addedFields = ('KM2_LC1', 'KM2_LC2'...) Then the addField calculation would end up with the appropriate value: 'KM2_LC1' = convert (where convert = !NLCDV1! * cell) 'KM2_LC2' = convert (convert = !NLCDV2! * cell) and so on for all the values that may exist.

#User inputs the desired final units, loop through to find the desired units and calculates the new fields.
unit = arcpy.GetParameterAsText(7) #Must be: SqMeter, SqKm, Acres, Hectares, SqMi, or SqFt.

#User must know original units of raster, must be in Meters or Foot_US!!!
for field in origFields:

  if rastunit == "Meter":
    #To make square meters final area unit.
    if unit == "SqMeter":
      arcpy.CalculateField_management(inputPoly, addField, convert, "PYTHON_9.3")

    #To convert square meters into Square Kilometers.
    elif unit == "SqKm":
      arcpy.CalculateField_management(inputPoly, addField, convertsqmsqkm, "PYTHON_9.3")

    #To convert square meters into Acres.
    elif unit == "Acres":
      arcpy.CalculateField_management(inputPoly, addField, convertsqmac, "PYTHON_9.3")

    #To convert square meters into Hectares.
    elif unit == "Hectares":
      arcpy.CalculateField_management(inputPoly, addField, convertsqmhec, "PYTHON_9.3")

    #To convert square meters into Square Miles.
    elif unit == "SqMi":
      arcpy.CalculateField_management(inputPoly, addField, convertsqmsqmi, "PYTHON_9.3")

    #To convert square meters into Square Feet.
    elif unit == "SqFt":
      arcpy.CalculateField_management(inputPoly, addField, convertsqmsqft, "PYTHON_9.3")
    else:
      print arcpy.AddWarning("Ineligible unit provided.")


  elif rastunit == "Foot_US":
    #To make square feet final area unit.
    if unit == "SqFt":
      arcpy.CalculateField_management(inputPoly, addField, convert, "PYTHON_9.3")

  else:
    print "This raster has the following units:" +rastunit+ ". If not in Foot_US or Meters, please reproject the raster."

I just need to figure out how to get the corresponding original field to match the new added field. I was thinking of using something like zip(origField, addedField, calcs). When I did this, it gave me the following output:

(u'NLCDV1', 'KM2_LC1', '!NLCDV1! * 900.0')
(u'NLCDV2', 'KM2_LC2', '!NLCDV2! * 900.0')
(u'NLCDV3', 'KM2_LC3', '!NLCDV3! * 900.0')
(u'NLCDV4', 'KM2_LC4', '!NLCDV4! * 900.0')
(u'NLCDV5', 'KM2_LC5', '!NLCDV5! * 900.0')
(u'NLCDV7', 'KM2_LC7', '!NLCDV7! * 900.0')
(u'NLCDV8', 'KM2_LC8', '!NLCDV8! * 900.0')
(u'NLCDV9', 'KM2_LC9', '!NLCDV9! * 900.0')

These lines are exactly what I need, but I am not sure if I can use such output to populate the fields, and even if they can be used, I am new to python and very new to zip, so I don't know how to use them.

Any help with the logic would be greatly appreciated, and any suggestions on clean up/re-ordering is welcomed. Like I said, I pretty novice when this is all said in done. Once I have the logic, I will be good to go! Thanks for looking, and sorry if my code is overly complicated (wouldn't be surprised if that is the case).

Était-ce utile?

La solution

I'm (still) not sure I understand what you're asking, but maybe this will help:

origFields = (u'NLCDV1', u'NLCDV2', u'NLCDV3')
addedFields = ('KM2_LC1', 'KM2_LC2', 'KM2_LC3')
calcs = ('!NLCDV1! * 900.0', '!NLCDV2! * 900.0', '!NLCDV3! * 900.0')

for orig, added, calc in zip(origFields, addedFields, calcs):
    print '{!r}, {!r}, {!r}'.format(orig, added, calc)

Output:

u'NLCDV1', 'KM2_LC1', '!NLCDV1! * 900.0'
u'NLCDV2', 'KM2_LC2', '!NLCDV2! * 900.0'
u'NLCDV3', 'KM2_LC3', '!NLCDV3! * 900.0'
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top