Guest User

Untitled

a guest
Feb 23rd, 2018
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.83 KB | None | 0 0
  1. import arcpy
  2. import numpy
  3. import math
  4.  
  5. def AddGeometryAttributes(fc, geomProperties, lUnit, aUnit, cs):
  6. """-------------------------------------------------------------------------
  7. Tool: Add Geometry Attributes (Data Management Tools)
  8. Source Name: AddGeometryAttributes.py
  9. Version: ArcGIS 10.2.1
  10. Author: Esri, Inc.
  11. Usage: arcpy.AddGeometryAttributes_management(
  12. Input_Features,
  13. Geometry_Properties,
  14. {Length_Unit},
  15. {Area_Unit},
  16. {Coordinate_System})
  17. Required Arguments: Input Features
  18. Geometry Properties
  19. Optional Arguments: Length Unit
  20. Area Unit
  21. Coordinate System
  22. Description: Adds attribute fields to the input features containing
  23. measurements and coordinate properties of the feature
  24. geometries (for example, length or area).
  25. Updated: Not yet.
  26. ------------------------------------------------------------------------"""
  27.  
  28. desc = arcpy.Describe(fc)
  29. hasZ, hasM = desc.hasZ, desc.hasM
  30. if cs:
  31. sr = arcpy.SpatialReference()
  32. sr.loadFromString(cs)
  33. try:
  34. srMetersPerUnit = sr.metersPerUnit
  35. except:
  36. srMetersPerUnit = 1
  37. else:
  38. try:
  39. srMetersPerUnit = desc.spatialReference.metersPerUnit
  40. except:
  41. srMetersPerUnit = 1
  42. shapeDict = {"POINT":1,
  43. "MULTIPOINT":1.5,
  44. "POLYLINE":2,
  45. "POLYGON":3,}
  46. shapeDim = shapeDict[str(desc.shapeType).upper()]
  47. del desc
  48.  
  49. fields = CreateOutputFields(fc, geomProperties, hasZ, hasM)
  50.  
  51. arcpy.SetProgressor("STEP", arcpy.GetIDMessage(86174), 0,
  52. int(arcpy.GetCount_management(fc).getOutput(0)), 1)
  53.  
  54. hasNulls = False
  55. # Calculate geometry properties into new fields
  56. with arcpy.da.UpdateCursor(fc,fields + ["SHAPE@"],"",cs) as ucur:
  57. ucurFields = ucur.fields
  58. global ucurFields
  59. for row in ucur:
  60. global row
  61. geom = row[ucurFields.index("SHAPE@")]
  62. if geom:
  63. if shapeDim == 1:
  64. if "POINT_X_Y_Z_M" in geomProperties:
  65. Update("POINT_X", geom.firstPoint.X)
  66. Update("POINT_Y", geom.firstPoint.Y)
  67. if hasZ:
  68. Update("POINT_Z", geom.firstPoint.Z)
  69. if hasM:
  70. Update("POINT_M", geom.firstPoint.M)
  71. if shapeDim>1:
  72. if "PART_COUNT" in geomProperties:
  73. Update("PART_COUNT", geom.partCount)
  74. if "CENTROID" in geomProperties:
  75. Update("CENTROID_X", geom.trueCentroid.X)
  76. Update("CENTROID_Y", geom.trueCentroid.Y)
  77. if hasZ:
  78. Update("CENTROID_Z", geom.trueCentroid.Z)
  79. if hasM:
  80. Update("CENTROID_M", geom.trueCentroid.M)
  81. if "EXTENT" in geomProperties:
  82. Update("EXT_MIN_X", geom.extent.XMin)
  83. Update("EXT_MIN_Y", geom.extent.YMin)
  84. Update("EXT_MAX_X", geom.extent.XMax)
  85. Update("EXT_MAX_Y", geom.extent.YMax)
  86. if shapeDim>=2:
  87. if "POINT_COUNT" in geomProperties:
  88. Update("PNT_COUNT", geom.pointCount)
  89. if "LINE_START_MID_END" in geomProperties:
  90. Update("START_X", geom.firstPoint.X)
  91. Update("START_Y", geom.firstPoint.Y)
  92. if shapeDim ==2:
  93. midPoint = geom.positionAlongLine(0.5,
  94. True).firstPoint
  95. else:
  96. line = arcpy.Polyline(geom.getPart(0), "#",
  97. hasZ, hasM)
  98. if line.length > 0:
  99. midPoint = line.positionAlongLine(0.5,
  100. True).firstPoint
  101. else:
  102. hasNulls = True
  103. del line
  104. Update("MID_X", midPoint.X)
  105. Update("MID_Y", midPoint.Y)
  106. Update("END_X", geom.lastPoint.X)
  107. Update("END_Y", geom.lastPoint.Y)
  108. if hasZ:
  109. Update("START_Z", geom.firstPoint.Z)
  110. Update("MID_Z", midPoint.Z)
  111. Update("END_Z", geom.lastPoint.Z)
  112. if hasM:
  113. Update("START_M", geom.firstPoint.M)
  114. Update("MID_M", midPoint.M)
  115. Update("END_M", geom.lastPoint.M)
  116. del midPoint
  117. if "CENTROID_INSIDE" in geomProperties:
  118. Update("INSIDE_X", geom.centroid.X)
  119. Update("INSIDE_Y", geom.centroid.Y)
  120. if hasZ:
  121. Update("INSIDE_Z", geom.centroid.Z)
  122. if hasM:
  123. Update("INSIDE_M", geom.centroid.M)
  124. if shapeDim==2:
  125. if "LINE_BEARING" in geomProperties:
  126. lat1 = geom.firstPoint.Y
  127. lon1 = geom.firstPoint.X
  128. lat2 = geom.lastPoint.Y
  129. lon2 = geom.lastPoint.X
  130. Update("BEARING", (90 - math.degrees(math.atan2(lat2-lat1, lon2-lon1))) % 360)
  131. del lat1, lon1, lat2, lon2
  132. if "LENGTH" in geomProperties:
  133. Update("LENGTH", ConvertFromMeters("LINEAR",
  134. geom.length,
  135. lUnit,
  136. srMetersPerUnit))
  137. if "LENGTH_3D" in geomProperties:
  138. Update("LENGTH_3D", ConvertFromMeters("LINEAR",
  139. geom.length3D,
  140. lUnit,
  141. srMetersPerUnit))
  142. if "LENGTH_GEODESIC" in geomProperties:
  143. Update("LENGTH_GEO", ConvertFromMeters("LINEAR",
  144. geom.getLength("PRESERVE_SHAPE"),
  145. lUnit,
  146. srMetersPerUnit))
  147. if shapeDim==3:
  148. if "PERIMETER_LENGTH" in geomProperties:
  149. Update("PERIMETER", ConvertFromMeters("LINEAR",
  150. geom.length,
  151. lUnit,
  152. srMetersPerUnit))
  153. if "AREA" in geomProperties:
  154. Update("POLY_AREA", ConvertFromMeters("AREA",
  155. geom.area,
  156. aUnit,
  157. srMetersPerUnit))
  158. if "AREA_GEODESIC" in geomProperties:
  159. Update("AREA_GEO", ConvertFromMeters("AREA",
  160. geom.getArea("PRESERVE_SHAPE"),
  161. aUnit,
  162. srMetersPerUnit))
  163. if "PERIMETER_LENGTH_GEODESIC" in geomProperties:
  164. Update("PERIM_GEO", ConvertFromMeters("LINEAR",
  165. geom.getLength("PRESERVE_SHAPE"),
  166. lUnit,
  167. srMetersPerUnit))
  168. ucur.updateRow(row)
  169. else:
  170. hasNulls = True
  171. arcpy.SetProgressorPosition()
  172. if hasNulls:
  173. arcpy.AddIDMessage("WARNING", 957)
  174.  
  175. def CreateOutputFields(fc, geomProperties, hasZ, hasM):
  176. propDict = {"POINT_X_Y_Z_M": ["POINT_X",
  177. "POINT_Y",
  178. "POINT_Z",
  179. "POINT_M"],
  180. "PART_COUNT": ["PART_COUNT"],
  181. "CENTROID": ["CENTROID_X",
  182. "CENTROID_Y",
  183. "CENTROID_Z",
  184. "CENTROID_M"],
  185. "EXTENT": ["EXT_MIN_X",
  186. "EXT_MIN_Y",
  187. "EXT_MAX_X",
  188. "EXT_MAX_Y"],
  189. "POINT_COUNT": ["PNT_COUNT"],
  190. "LINE_START_MID_END": ["START_X",
  191. "START_Y",
  192. "START_Z",
  193. "START_M",
  194. "MID_X",
  195. "MID_Y",
  196. "MID_Z",
  197. "MID_M",
  198. "END_X",
  199. "END_Y",
  200. "END_Z",
  201. "END_M"],
  202. "LINE_BEARING": ["BEARING"],
  203. "CENTROID_INSIDE": ["INSIDE_X",
  204. "INSIDE_Y",
  205. "INSIDE_Z",
  206. "INSIDE_M"],
  207. "LENGTH": ["LENGTH"],
  208. "Shape_Length": ["Shape_Length"],
  209. "AREA": ["Shape_Area"],
  210. "LENGTH_GEODESIC": ["LENGTH_GEO"],
  211. "Shape_Area": ["AREA_GEO"],
  212. "LENGTH_3D": ["LENGTH_3D"],
  213. "PERIMETER_LENGTH_GEODESIC":["PERIM_GEO"],
  214. }
  215. if not hasZ:
  216. propDict["POINT_X_Y_Z_M"].remove("POINT_Z")
  217. propDict["CENTROID"].remove("CENTROID_Z")
  218. propDict["CENTROID_INSIDE"].remove("INSIDE_Z")
  219. propDict["LINE_START_MID_END"].remove("START_Z")
  220. propDict["LINE_START_MID_END"].remove("MID_Z")
  221. propDict["LINE_START_MID_END"].remove("END_Z")
  222. if not hasM:
  223. propDict["POINT_X_Y_Z_M"].remove("POINT_M")
  224. propDict["CENTROID"].remove("CENTROID_M")
  225. propDict["CENTROID_INSIDE"].remove("INSIDE_M")
  226. propDict["LINE_START_MID_END"].remove("START_M")
  227. propDict["LINE_START_MID_END"].remove("MID_M")
  228. propDict["LINE_START_MID_END"].remove("END_M")
  229.  
  230. addList = []
  231. geomPropertiesList = []
  232. currentFields = [field.name for field in arcpy.ListFields(fc)]
  233. for prop in geomProperties:
  234. for field in propDict[prop.upper()]:
  235. geomPropertiesList.append(field)
  236. if field not in currentFields:
  237. addList.append(field)
  238. else:
  239. arcpy.AddIDMessage("WARNING", 1097, field)
  240.  
  241. if addList:
  242. narray = numpy.array([], numpy.dtype([("_ID", numpy.int)] +
  243. [(n, numpy.float) for n in addList]))
  244. arcpy.da.ExtendTable(fc, "OID@", narray, "_ID")
  245.  
  246. return geomPropertiesList
  247.  
  248. def ConvertFromMeters(type, value, unit, metersPerUnit):
  249. if not unit:
  250. return value
  251. else:
  252. distanceUnitInfo = {"METERS": 1.0,
  253. "FEET_US": 0.304800609601219,
  254. "NAUTICAL_MILES": 1852.0,
  255. "MILES_US": 1609.34721869444,
  256. "KILOMETERS": 1000.0,
  257. "YARDS": 0.914401828803658,}
  258.  
  259. areaUnitInfo = {"ACRES": 4046.86,
  260. "HECTARES": 10000.0,
  261. "SQUARE_METERS": 1.0,
  262. "SQUARE_FEET_US": 0.09290341161327473,
  263. "SQUARE_NAUTICAL_MILES": 3429904.0,
  264. "SQUARE_MILES_US": 2589998.4703195295,
  265. "SQUARE_KILOMETERS": 1000000.0,
  266. "SQUARE_YARDS": 0.8361307045194741,}
  267. if type == "LINEAR":
  268. return (value*metersPerUnit)/distanceUnitInfo[unit]
  269. if type == "AREA":
  270. return (value*math.pow(metersPerUnit,2))/areaUnitInfo[unit]
  271.  
  272. def Update(field, value):
  273. if value:
  274. if not math.isnan(value):
  275. row[ucurFields.index(field)] = value
  276.  
  277. #run the script
  278. if __name__ == '__main__':
  279. # Get Parameters
  280. fc = arcpy.GetParameterAsText(0)
  281. if arcpy.GetParameterAsText(1).find(";") > -1:
  282. geomProperties = arcpy.GetParameterAsText(1).upper().split(";")
  283. else:
  284. geomProperties = [arcpy.GetParameterAsText(1).upper()]
  285. lUnit = arcpy.GetParameterAsText(2)
  286. aUnit = arcpy.GetParameterAsText(3)
  287. cs = arcpy.GetParameterAsText(4)
  288. if not cs:
  289. cs = arcpy.env.outputCoordinateSystem
  290.  
  291. # Run the main script
  292. AddGeometryAttributes(fc, geomProperties, lUnit, aUnit, cs)
Add Comment
Please, Sign In to add comment