def __init__(self, inputFC, outputFC=None, caseField=None, orientationOnly=False): #### Create SSDataObject #### ssdo = SSDO.SSDataObject(inputFC, templateFC=outputFC, useChordal=False) cnt = UTILS.getCount(inputFC) ERROR.errorNumberOfObs(cnt, minNumObs=1) fieldList = [ssdo.oidName, "SHAPE@"] caseIsString = False if caseField: fieldList.append(caseField) caseType = ssdo.allFields[caseField].type.upper() caseIsString = caseType == "STRING" #### Initialize Accounting Structures #### xyLenVals = {} sinCosVals = {} #### Open Search Cursor #### try: rows = DA.SearchCursor(inputFC, fieldList, "", ssdo.spatialRefString) except: ARCPY.AddIDMessage("ERROR", 204) raise SystemExit() #### Keep track of Invalid Fields #### badIDs = [] badLengths = [] badRecord = False negativeWeights = False #### Create Progressor #### ARCPY.SetProgressor("step", ARCPY.GetIDMessage(84001), 0, cnt, 1) for row in rows: OID = row[0] shapeInfo = row[1] badRow = row.count(None) try: centroidInfo = shapeInfo.trueCentroid xVal = centroidInfo.X yVal = centroidInfo.Y length = float(shapeInfo.length) firstPoint = shapeInfo.firstPoint lastPoint = shapeInfo.lastPoint if firstPoint == lastPoint: badLengths.append(OID) badRow = True else: firstX = float(firstPoint.X) firstY = float(firstPoint.Y) lastX = float(lastPoint.X) lastY = float(lastPoint.Y) except: badRow = True #### Process Good Records #### if not badRow: #### Case Field #### caseVal = "ALL" if caseField: caseVal = UTILS.caseValue2Print(row[2], caseIsString) #### Get Angle #### numer = lastX - firstX denom = lastY - firstY angle = UTILS.getAngle(numer, denom) #### Adjust for Orientation Only #### if orientationOnly: angle2Degree = UTILS.convert2Degree(angle) if angle2Degree < 180: numer = firstX - lastX denom = firstY - lastY angle = UTILS.getAngle(numer, denom) sinVal = NUM.sin(angle) cosVal = NUM.cos(angle) xyLenVal = (xVal, yVal, length) sinCosVal = (sinVal, cosVal) try: xyLenVals[caseVal].append(xyLenVal) sinCosVals[caseVal].append(sinCosVal) except: xyLenVals[caseVal] = [xyLenVal] sinCosVals[caseVal] = [sinCosVal] else: #### Bad Record #### badRecord = True badIDs.append(OID) ARCPY.SetProgressorPosition() del rows #### Get Set of Bad IDs #### badIDs = list(set(badIDs)) badIDs.sort() badIDs = [str(i) for i in badIDs] #### Process any bad records encountered #### bn = len(badIDs) if badRecord: err = ERROR.reportBadRecords(cnt, bn, badIDs, label=ssdo.oidName) #### Error For Not Enough Observations #### goodRecs = cnt - bn ERROR.errorNumberOfObs(goodRecs, minNumObs=1) #### Report Features With No Length #### badLengths = list(set(badLengths)) badLengths.sort() badLengths = [str(i) for i in badLengths] numBadLengths = len(badLengths) if numBadLengths > 0: ERROR.reportBadLengths(cnt, numBadLengths, badLengths, label=ssdo.oidName) #### Set up for Bad Cases #### badCases = [] cases = xyLenVals.keys() meanCenter = {} dm = {} #### Calculate Mean Center and Standard Distance #### for case in cases: xyLens = xyLenVals[case] numFeatures = len(xyLens) if numFeatures > 0: #### Mean Centers and Lengths #### xyLens = NUM.array(xyLens) meanX, meanY, meanL = NUM.mean(xyLens, 0) #### Sum Sin and Cos #### scVals = NUM.array(sinCosVals[case]) sumSin, sumCos = NUM.sum(scVals, 0) #### Calculate Angle #### radianAngle = UTILS.getAngle(sumSin, sumCos) degreeAngle = UTILS.convert2Degree(radianAngle) #### Get Start and End Points #### halfMeanLen = meanL / 2.0 endX = (halfMeanLen * NUM.sin(radianAngle)) + meanX startX = (2.0 * meanX) - endX endY = (halfMeanLen * NUM.cos(radianAngle)) + meanY startY = (2.0 * meanY) - endY unstandardized = NUM.sqrt(sumSin**2.0 + sumCos**2.0) circVar = 1.0 - (unstandardized / (numFeatures * 1.0)) #### Re-adjust Angle Back towards North #### if orientationOnly: degreeAngle = degreeAngle - 180.0 radianAngle = UTILS.convert2Radians(degreeAngle) #### Populate Results Structure #### meanCenter[case] = (meanX, meanY) dm[case] = [(startX, startY), (endX, endY), meanL, radianAngle, degreeAngle, circVar] #### Sorted Case List #### caseKeys = dm.keys() caseKeys.sort() self.caseKeys = caseKeys #### Set Attributes #### self.ssdo = ssdo self.meanCenter = meanCenter self.dm = dm self.badCases = badCases self.inputFC = inputFC self.outputFC = outputFC self.caseField = caseField self.orientationOnly = orientationOnly self.caseIsString = caseIsString